diff --git a/Makefile b/Makefile index 6e5c33f..a180946 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,7 @@ all: - mkdir -p ./build cd libs && $(MAKE) cd src && $(MAKE) - cd plugins && $(MAKE) - cd tools && $(MAKE) - cd resources && $(MAKE) clean: cd libs && $(MAKE) clean cd src && $(MAKE) clean - cd plugins && $(MAKE) clean - cd tools && $(MAKE) clean diff --git a/README.md b/README.md index 59ea4cf..b876396 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,64 @@ -# ![WorldSpawn Logo](icon.png) WorldSpawn -The worlds most opinionated fork of Radiant. +# vmap -The editor we use at Vera Visions to create BSP levels. -It was forked from NetRadiant in June of 2018 and was a result of necessity. +A fork of q3map2, now available as a stand-alone compiler targetting [FTEQW](https://www.fteqw.org/) -We wanted to move away from a proprietary toolchain that had technical issues the developer would not ever get back to us about, so we ended up here. -Use it if you actually want to use the features listed below - note that they require a modified engine as our BSP format is different from standard idTech 3 BSP. -You will not be able to make levels compatible with other games and engines. - -There's plenty of other editors for the first-party id Tech games. -**Please use those instead if you want to use a level editor with actual support, submission for feature requests, etc. - we are only sharing this because that's the best way of preserving software.** - -**Please respect this notice, thank you.** - -![Screenshot](docs/screen.jpg) - -## Editor Changes -- Valve 220 format is used **top to bottom**, **imported & exported**, with texture coords handled internally the same way, including the compiler -- Integration with our **own material format** (no more giant .shader files) -- Support for vertex-color/alpha editing of patches using our new **fixed patch format**, allowing technologies such as **4-way texture blending** and whatever your designers can imagine -- Gracefully deals with duplicate entity attribute key/value pairs, to support features like Source Engine style **Input/Output system** for triggers -- Support for **VVM** (based on IQM) model format in the BSP compiler as well as the editor -- Support for **internal** and external **High-Dynamic-Range lightmaps** in the BSP compiler -- Support for **cubemap aware surfaces** in the BSP compiler -- Support for our patchDef2WS and patchDef3WS curved surfaces in the BSP compiler -- *More bug-fixes than you could possibly imagine* - -## Why -Back then there was no fork of Radiant supporting the 220 format like said program had exported. -We had to make that happen on our own, since then we've expanded and kept changing more to meet our own needs. -On top of that, there's other benefits from working in our own Radiant fork. - -Rapid experimentation and tech development doesn't fit into an editor like GtkRadiant, -which aims to be stable, reliable and support a specific set of games really, really well. - -We can afford to break compat here in order to achieve our goals. It will break, be unstable -and all that jazz at the cost of supporting the greatest and latest of we're working on. - -Some code in here (like the IQM support in the compiler) has made it into other Radiant forks -when we deem it to be mature. However not everything in here is going to be of interest -to other Radiant forks. - -A lot of the changes are specific to our BSP format & engine too. -So tech like per-surface picked and generated environment maps will never make it into other games. -Sorry! +## Compiler Changes +- Improved High-Dynamic-Range lightmaps +- Support for our patchDef2WS and patchDef3WS curved surfaces in the BSP compiler, allowing for 4-way texture blended patches. +- Reads individual material scripts (.mat) instead of large .shader files +- Surfaces are aware which env_cubemap ents they belong to +- light_surface entity support, so you don't have to write map specific materials to override texture light properties +- Handles Half-Life styled point lights, including zhlt_lightflags +- Handles Half-Life styled light_environment entities +- New material keys: vmap_lightLinear, vmap_lightLinearFade +- Support for target-less spotlights +- Explicit support for func_detail, func_detail_illusionary +- Support for misc_prefab (including other .map files) +- vmap_remapMaterial/q3map_remapShader can carry over surface flags now +- Support for entity key: _entsurfaceflags, so surfaces can override their surfaceflags +- Support for entity key: _entcontentflags, so brushes can override their contentflags ## Compiling To compile on a standard GNU/Linux system: -`LDFLAGS=-ldl make -j $(nproc)` +`make` -On BSD you should probably use GNU make right now. The Makefiles are simple enough however. -Clang should also be supported, pass `CC=clang and CXX=clang++` if you want to use it. +On BSD you should probably use GNU make right now. +Clang should also be supported, pass `CC=clang` if you want to use it. On NT you'll have to jump through a lot more hoops, here's the gist: 1. MSYS2: https://www.msys2.org/ -2. in the msys2 shell, enter `pacman -S --needed base-devel git unzip mingw-w64-$(uname -m)-{toolchain,make,gtk2,gtkglext,minizip-git}` +2. in the msys2 shell, enter `pacman -S --needed base-devel git unzip mingw-w64-$(uname -m)-{toolchain,make,minizip-git}` 3. boot into the Mingw64 shell, don't use the stock MSYS2 shell 4. run make and it should build everything, in theory **Please don't contact us about helping you build it on Windows. This is a development tool. This is provided AS-IS.** -It'll compile everything into a subdirectory 'build'. At the end it'll copy files from ./resources into it too. - -In the Nuclide SDK, build_editor.sh will call make with the appropriate flags for Linux/BSD automatically and -move it into Nuclide's ./bin directory. - ## Dependencies * GNU make * gcc-core * gcc-c++ -* gtk2-devel -* gtkglext-devel +* glib2-devel * libxml2-devel * libjpeg8-devel +* libpng-devel * minizip-devel ## Support **As mentioned before, if you need help with this: you're on your own.** -Please use [GtkRadiant](https://github.com/TTimo/GtkRadiant) if you want to make levels for existing games. +## Special Thanks + +The original q3map/2 developers: +- id Software +- Splash Damage +- ydnar +- GtkRadiant team and contributors +- NetRadiant team and contributors + +vmap developers: +- Vera Visions, L.L.C. +- Spike +- Joshua Ashton +- Slartibarty \ No newline at end of file diff --git a/tools/common/aselib.c b/common/aselib.c similarity index 100% rename from tools/common/aselib.c rename to common/aselib.c diff --git a/tools/common/aselib.h b/common/aselib.h similarity index 100% rename from tools/common/aselib.h rename to common/aselib.h diff --git a/tools/common/bspfile.c b/common/bspfile.c similarity index 100% rename from tools/common/bspfile.c rename to common/bspfile.c diff --git a/tools/common/bspfile.h b/common/bspfile.h similarity index 100% rename from tools/common/bspfile.h rename to common/bspfile.h diff --git a/tools/common/cmdlib.c b/common/cmdlib.c similarity index 100% rename from tools/common/cmdlib.c rename to common/cmdlib.c diff --git a/tools/common/cmdlib.h b/common/cmdlib.h similarity index 100% rename from tools/common/cmdlib.h rename to common/cmdlib.h diff --git a/tools/common/imagelib.c b/common/imagelib.c similarity index 100% rename from tools/common/imagelib.c rename to common/imagelib.c diff --git a/tools/common/imagelib.h b/common/imagelib.h similarity index 100% rename from tools/common/imagelib.h rename to common/imagelib.h diff --git a/tools/common/inout.c b/common/inout.c similarity index 100% rename from tools/common/inout.c rename to common/inout.c diff --git a/tools/common/inout.h b/common/inout.h similarity index 100% rename from tools/common/inout.h rename to common/inout.h diff --git a/tools/common/jpeg.c b/common/jpeg.c similarity index 100% rename from tools/common/jpeg.c rename to common/jpeg.c diff --git a/tools/common/l3dslib.c b/common/l3dslib.c similarity index 100% rename from tools/common/l3dslib.c rename to common/l3dslib.c diff --git a/tools/common/l3dslib.h b/common/l3dslib.h similarity index 100% rename from tools/common/l3dslib.h rename to common/l3dslib.h diff --git a/tools/common/matlib.c b/common/matlib.c similarity index 100% rename from tools/common/matlib.c rename to common/matlib.c diff --git a/tools/common/matlib.h b/common/matlib.h similarity index 100% rename from tools/common/matlib.h rename to common/matlib.h diff --git a/tools/common/md4.c b/common/md4.c similarity index 100% rename from tools/common/md4.c rename to common/md4.c diff --git a/tools/common/md4.h b/common/md4.h similarity index 100% rename from tools/common/md4.h rename to common/md4.h diff --git a/tools/common/mutex.c b/common/mutex.c similarity index 100% rename from tools/common/mutex.c rename to common/mutex.c diff --git a/tools/common/mutex.h b/common/mutex.h similarity index 100% rename from tools/common/mutex.h rename to common/mutex.h diff --git a/tools/common/polylib.c b/common/polylib.c similarity index 100% rename from tools/common/polylib.c rename to common/polylib.c diff --git a/tools/common/polylib.h b/common/polylib.h similarity index 100% rename from tools/common/polylib.h rename to common/polylib.h diff --git a/tools/common/polyset.h b/common/polyset.h similarity index 100% rename from tools/common/polyset.h rename to common/polyset.h diff --git a/tools/common/qfiles.h b/common/qfiles.h similarity index 100% rename from tools/common/qfiles.h rename to common/qfiles.h diff --git a/tools/common/qthreads.h b/common/qthreads.h similarity index 100% rename from tools/common/qthreads.h rename to common/qthreads.h diff --git a/tools/common/scriplib.c b/common/scriplib.c similarity index 100% rename from tools/common/scriplib.c rename to common/scriplib.c diff --git a/tools/common/scriplib.h b/common/scriplib.h similarity index 100% rename from tools/common/scriplib.h rename to common/scriplib.h diff --git a/tools/common/surfaceflags.h b/common/surfaceflags.h similarity index 100% rename from tools/common/surfaceflags.h rename to common/surfaceflags.h diff --git a/tools/common/threads.c b/common/threads.c similarity index 100% rename from tools/common/threads.c rename to common/threads.c diff --git a/tools/common/trilib.c b/common/trilib.c similarity index 100% rename from tools/common/trilib.c rename to common/trilib.c diff --git a/tools/common/trilib.h b/common/trilib.h similarity index 100% rename from tools/common/trilib.h rename to common/trilib.h diff --git a/tools/common/vfs.c b/common/vfs.c similarity index 100% rename from tools/common/vfs.c rename to common/vfs.c diff --git a/tools/common/vfs.h b/common/vfs.h similarity index 100% rename from tools/common/vfs.h rename to common/vfs.h diff --git a/icon.png b/icon.png deleted file mode 100644 index 1a2b03b..0000000 Binary files a/icon.png and /dev/null differ diff --git a/libs/Makefile b/libs/Makefile index 3f8f76b..bb0913c 100644 --- a/libs/Makefile +++ b/libs/Makefile @@ -1,52 +1,16 @@ all: - cd cmdlib && $(MAKE) - cd container && $(MAKE) cd ddslib && $(MAKE) - cd debugging && $(MAKE) cd etclib && $(MAKE) cd filematch && $(MAKE) - cd generic && $(MAKE) - cd gtkutil && $(MAKE) cd l_net && $(MAKE) - cd math && $(MAKE) cd mathlib && $(MAKE) - #cd md5lib && $(MAKE) - cd memory && $(MAKE) - cd modulesystem && $(MAKE) - cd os && $(MAKE) cd picomodel && $(MAKE) - cd profile && $(MAKE) - cd script && $(MAKE) - cd signal && $(MAKE) - cd splines && $(MAKE) - cd stream && $(MAKE) - cd string && $(MAKE) - cd uilib && $(MAKE) - cd xml && $(MAKE) clean: - cd cmdlib && $(MAKE) clean - cd container && $(MAKE) clean cd ddslib && $(MAKE) clean - cd debugging && $(MAKE) clean cd etclib && $(MAKE) clean cd filematch && $(MAKE) clean - cd generic && $(MAKE) clean - cd gtkutil && $(MAKE) clean cd l_net && $(MAKE) clean - cd math && $(MAKE) clean cd mathlib && $(MAKE) clean - #cd md5lib && $(MAKE) clean - cd memory && $(MAKE) clean - cd modulesystem && $(MAKE) clean - cd os && $(MAKE) clean cd picomodel && $(MAKE) clean - cd profile && $(MAKE) clean - cd script && $(MAKE) clean - cd signal && $(MAKE) clean - cd splines && $(MAKE) clean - cd stream && $(MAKE) clean - cd string && $(MAKE) clean - cd uilib && $(MAKE) clean - cd xml && $(MAKE) clean diff --git a/libs/_.cpp b/libs/_.cpp deleted file mode 100644 index 8b13789..0000000 --- a/libs/_.cpp +++ /dev/null @@ -1 +0,0 @@ - diff --git a/libs/archivelib.h b/libs/archivelib.h deleted file mode 100644 index 78fc7eb..0000000 --- a/libs/archivelib.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_ARCHIVELIB_H ) -#define INCLUDED_ARCHIVELIB_H - -#include "debugging/debugging.h" -#include "iarchive.h" -#include "stream/filestream.h" -#include "stream/textfilestream.h" -#include "memory/allocator.h" -#include "string/string.h" - -/// \brief A single-byte-reader wrapper around an InputStream. -/// Optimised for reading one byte at a time. -/// Uses a buffer to reduce the number of times the wrapped stream must be read. -template -class SingleByteInputStream -{ -typedef typename InputStreamType::byte_type byte_type; - -InputStreamType& m_inputStream; -byte_type m_buffer[SIZE]; -byte_type* m_cur; -byte_type* m_end; - -public: - -SingleByteInputStream( InputStreamType& inputStream ) : m_inputStream( inputStream ), m_cur( m_buffer + SIZE ), m_end( m_cur ){ -} -bool readByte( byte_type& b ){ - if ( m_cur == m_end ) { - if ( m_end != m_buffer + SIZE ) { - return false; - } - - m_end = m_buffer + m_inputStream.read( m_buffer, SIZE ); - m_cur = m_buffer; - - if ( m_end == m_buffer ) { - return false; - } - } - - b = *m_cur++; - - return true; -} -}; - -/// \brief A binary-to-text wrapper around an InputStream. -/// Converts CRLF or LFCR line-endings to LF line-endings. -template -class BinaryToTextInputStream : public TextInputStream -{ -SingleByteInputStream m_inputStream; -public: -BinaryToTextInputStream( BinaryInputStreamType& inputStream ) : m_inputStream( inputStream ){ -} -std::size_t read( char* buffer, std::size_t length ){ - char* p = buffer; - for (;; ) - { - if ( length != 0 && m_inputStream.readByte( *reinterpret_cast( p ) ) ) { - if ( *p != '\r' ) { - ++p; - --length; - } - } - else - { - return p - buffer; - } - } -} -}; - -/// \brief An ArchiveFile which is stored uncompressed as part of a larger archive file. -class StoredArchiveFile : public ArchiveFile -{ -CopiedString m_name; -FileInputStream m_filestream; -SubFileInputStream m_substream; -FileInputStream::size_type m_size; -public: -typedef FileInputStream::size_type size_type; -typedef FileInputStream::position_type position_type; - -StoredArchiveFile( const char* name, const char* archiveName, position_type position, size_type stream_size, size_type file_size ) - : m_name( name ), m_filestream( archiveName ), m_substream( m_filestream, position, stream_size ), m_size( file_size ){ -} - -static StoredArchiveFile* create( const char* name, const char* archiveName, position_type position, size_type stream_size, size_type file_size ){ - return New().scalar( name, archiveName, position, stream_size, file_size ); -} - -void release(){ - Delete().scalar( this ); -} -size_type size() const { - return m_size; -} -const char* getName() const { - return m_name.c_str(); -} -InputStream& getInputStream(){ - return m_substream; -} -}; - -/// \brief An ArchiveTextFile which is stored uncompressed as part of a larger archive file. -class StoredArchiveTextFile : public ArchiveTextFile -{ -CopiedString m_name; -FileInputStream m_filestream; -SubFileInputStream m_substream; -BinaryToTextInputStream m_textStream; -public: -typedef FileInputStream::size_type size_type; -typedef FileInputStream::position_type position_type; - -StoredArchiveTextFile( const char* name, const char* archiveName, position_type position, size_type stream_size ) - : m_name( name ), m_filestream( archiveName ), m_substream( m_filestream, position, stream_size ), m_textStream( m_substream ){ -} - -static StoredArchiveTextFile* create( const char* name, const char* archiveName, position_type position, size_type stream_size ){ - return New().scalar( name, archiveName, position, stream_size ); -} - -void release(){ - Delete().scalar( this ); -} -const char* getName() const { - return m_name.c_str(); -} -TextInputStream& getInputStream(){ - return m_textStream; -} -}; - -/// \brief An ArchiveFile which is stored as a single file on disk. -class DirectoryArchiveFile : public ArchiveFile -{ -CopiedString m_name; -FileInputStream m_istream; -FileInputStream::size_type m_size; -public: -typedef FileInputStream::size_type size_type; - -DirectoryArchiveFile( const char* name, const char* filename ) - : m_name( name ), m_istream( filename ){ - if ( !failed() ) { - m_istream.seek( 0, FileInputStream::end ); - m_size = m_istream.tell(); - m_istream.seek( 0 ); - } - else - { - m_size = 0; - } -} -bool failed() const { - return m_istream.failed(); -} - -void release(){ - delete this; -} -size_type size() const { - return m_size; -} -const char* getName() const { - return m_name.c_str(); -} -InputStream& getInputStream(){ - return m_istream; -} -}; - -/// \brief An ArchiveTextFile which is stored as a single file on disk. -class DirectoryArchiveTextFile : public ArchiveTextFile -{ -CopiedString m_name; -TextFileInputStream m_inputStream; -public: - -DirectoryArchiveTextFile( const char* name, const char* filename ) - : m_name( name ), m_inputStream( filename ){ -} -bool failed() const { - return m_inputStream.failed(); -} - -void release(){ - delete this; -} -const char* getName() const { - return m_name.c_str(); -} -TextInputStream& getInputStream(){ - return m_inputStream; -} -}; - - -#endif diff --git a/libs/bytestreamutils.h b/libs/bytestreamutils.h deleted file mode 100644 index 8cfd582..0000000 --- a/libs/bytestreamutils.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BYTESTREAMUTILS_H ) -#define INCLUDED_BYTESTREAMUTILS_H - -#include "globaldefs.h" - -#if GDEF_COMPILER_GNU - -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 - -#define __USE_ISOC9X 1 -#define __USE_ISOC99 1 - -#include - -#endif - -#include - -// if C99 is unavailable, fall back to the types most likely to be the right sizes -#if !defined( int16_t ) -typedef signed short int16_t; -#endif -#if !defined( uint16_t ) -typedef unsigned short uint16_t; -#endif -#if !defined( int32_t ) -typedef signed int int32_t; -#endif -#if !defined( uint32_t ) -typedef unsigned int uint32_t; -#endif - - - - -template -inline void istream_read_little_endian( InputStreamType& istream, Type& value ){ - istream.read(reinterpret_cast( &value ), sizeof(Type)); - if (GDEF_ARCH_ENDIAN_BIG) { - std::reverse(reinterpret_cast( &value ), - reinterpret_cast( &value ) + sizeof(Type)); - } -} - -template -inline void istream_read_big_endian( InputStreamType& istream, Type& value ){ - istream.read(reinterpret_cast( &value ), sizeof(Type)); - if (!GDEF_ARCH_ENDIAN_BIG) { - std::reverse(reinterpret_cast( &value ), - reinterpret_cast( &value ) + sizeof(Type)); - } -} - -template -inline void istream_read_byte( InputStreamType& istream, typename InputStreamType::byte_type& b ){ - istream.read( &b, 1 ); -} - - -template -inline int16_t istream_read_int16_le( InputStreamType& istream ){ - int16_t value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline int16_t istream_read_int16_be( InputStreamType& istream ){ - int16_t value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline uint16_t istream_read_uint16_le( InputStreamType& istream ){ - uint16_t value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline uint16_t istream_read_uint16_be( InputStreamType& istream ){ - uint16_t value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline int32_t istream_read_int32_le( InputStreamType& istream ){ - int32_t value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline int32_t istream_read_int32_be( InputStreamType& istream ){ - int32_t value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline uint32_t istream_read_uint32_le( InputStreamType& istream ){ - uint32_t value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline uint32_t istream_read_uint32_be( InputStreamType& istream ){ - uint32_t value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline float istream_read_float32_le( InputStreamType& istream ){ - float value; - istream_read_little_endian( istream, value ); - return value; -} - -template -inline float istream_read_float32_be( InputStreamType& istream ){ - float value; - istream_read_big_endian( istream, value ); - return value; -} - -template -inline typename InputStreamType::byte_type istream_read_byte( InputStreamType& istream ){ - typename InputStreamType::byte_type b; - istream.read( &b, sizeof( typename InputStreamType::byte_type ) ); - return b; -} - -#endif diff --git a/libs/character.h b/libs/character.h deleted file mode 100644 index bc35d3f..0000000 --- a/libs/character.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CHARACTER_H ) -#define INCLUDED_CHARACTER_H - -/// \file -/// \brief Character encoding. - -/// \brief Returns true if \p c is an ASCII character that can be represented with 7 bits. -inline bool char_is_ascii( char c ){ - return ( c & 0x80 ) == 0; -} - -/// \brief Returns true if \p string consists entirely of ASCII characters. -inline bool string_is_ascii( const char* string ){ - while ( *string != '\0' ) - { - if ( !char_is_ascii( *string++ ) ) { - return false; - } - } - return true; -} - -#endif diff --git a/libs/cmdlib.h b/libs/cmdlib.h deleted file mode 100644 index abdc15a..0000000 --- a/libs/cmdlib.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// start of shared cmdlib stuff -// - -#ifndef __CMDLIB__ -#define __CMDLIB__ - -#include "globaldefs.h" -#include - - -// TTimo started adding portability code: -// return true if spawning was successful, false otherwise -// on win32 we have a bCreateConsole flag to create a new console or run inside the current one -//boolean Q_Exec(const char* pCmd, boolean bCreateConsole); -// execute a system command: -// cmd: the command to run -// cmdline: the command line -// NOTE TTimo following are win32 specific: -// execdir: the directory to execute in -// bCreateConsole: spawn a new console or not -// return values; -// if the spawn was fine -// TODO TTimo add functionality to track the process until it dies - -bool Q_Exec( const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole, bool waitfor ); - -// some easy portability crap - - -#define access_owner_read 0400 -#define access_owner_write 0200 -#define access_owner_execute 0100 -#define access_owner_rw_ 0600 -#define access_owner_r_x 0500 -#define access_owner__wx 0300 -#define access_owner_rwx 0700 - -#define access_group_read 0040 -#define access_group_write 0020 -#define access_group_execute 0010 -#define access_group_rw_ 0060 -#define access_group_r_x 0050 -#define access_group__wx 0030 -#define access_group_rwx 0070 - -#define access_others_read 0004 -#define access_others_write 0002 -#define access_others_execute 0001 -#define access_others_rw_ 0006 -#define access_others_r_x 0005 -#define access_others__wx 0003 -#define access_others_rwx 0007 - - -#define access_rwxrwxr_x ( access_owner_rwx | access_group_rwx | access_others_r_x ) -#define access_rwxrwxrwx ( access_owner_rwx | access_group_rwx | access_others_rwx ) - -// Q_mkdir -// returns true if succeeded in creating directory -#if GDEF_OS_WINDOWS -#include -inline bool Q_mkdir( const char* name ){ - return _mkdir( name ) != -1; -} -#else -#include -inline bool Q_mkdir( const char* name ){ - return mkdir( name, access_rwxrwxr_x ) != -1; -} -#endif - - -inline double Sys_DoubleTime( void ){ - return clock() / 1000.0; -} - - - -#endif diff --git a/libs/cmdlib/Makefile b/libs/cmdlib/Makefile deleted file mode 100644 index 235d1e3..0000000 --- a/libs/cmdlib/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - cmdlib.o - -# binary target -../libcmdlib.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -cmdlib.o: cmdlib.cpp - -clean: - -rm -f *.o ../libcmdlib.a diff --git a/libs/cmdlib/cmdlib.cpp b/libs/cmdlib/cmdlib.cpp deleted file mode 100644 index a53a343..0000000 --- a/libs/cmdlib/cmdlib.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// start of shared cmdlib stuff -// - -#include "cmdlib.h" -#include "globaldefs.h" - -#include -#include - -#include "string/string.h" -#include "os/path.h" -#include "container/array.h" - - -#if GDEF_OS_POSIX - -#include -#include -#include - -bool Q_Exec( const char *cmd, char *cmdline, const char *, bool, bool waitfor ){ - char fullcmd[2048]; - char *pCmd; - pid_t pid; -#if GDEF_DEBUG - printf( "Q_Exec damnit\n" ); -#endif - switch ( ( pid = fork() ) ) - { - default: - if ( waitfor ) { - waitpid( pid, NULL, 0 ); - } - break; - case -1: - return true; - break; - case 0: - // always concat the command on linux - if ( cmd ) { - strcpy( fullcmd, cmd ); - } - else{ - fullcmd[0] = '\0'; - } - if ( cmdline ) { - strcat( fullcmd, " " ); - strcat( fullcmd, cmdline ); - } - pCmd = fullcmd; - while ( *pCmd == ' ' ) - pCmd++; -#if GDEF_DEBUG - printf( "Running system...\n" ); - printf( "Command: %s\n", pCmd ); -#endif - system( pCmd ); -#if GDEF_DEBUG - printf( "system() returned\n" ); -#endif - _exit( 0 ); - break; - } - return true; -} - -#elif GDEF_OS_WINDOWS - -#include - -// NOTE TTimo windows is VERY nitpicky about the syntax in CreateProcess -bool Q_Exec( const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole, bool waitfor ){ - PROCESS_INFORMATION ProcessInformation; - STARTUPINFO startupinfo = {0}; - DWORD dwCreationFlags; - GetStartupInfo( &startupinfo ); - if ( bCreateConsole ) { - dwCreationFlags = CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS; - } - else{ - dwCreationFlags = DETACHED_PROCESS | NORMAL_PRIORITY_CLASS; - } - const char *pCmd; - char *pCmdline; - pCmd = cmd; - if ( pCmd ) { - while ( *pCmd == ' ' ) - pCmd++; - } - pCmdline = cmdline; - if ( pCmdline ) { - while ( *pCmdline == ' ' ) - pCmdline++; - } - - if ( CreateProcess( - pCmd, - pCmdline, - NULL, - NULL, - FALSE, - dwCreationFlags, - NULL, - execdir, - &startupinfo, - &ProcessInformation - ) ) { - if ( waitfor ) { - WaitForSingleObject( ProcessInformation.hProcess, INFINITE ); - } - return true; - } - return false; -} - -#endif diff --git a/libs/container/Makefile b/libs/container/Makefile deleted file mode 100644 index 269e838..0000000 --- a/libs/container/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - array.o hashtable.o - -# binary target -../libcontainer.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -array.o: array.cpp array.h cache.h container.h hashfunc.h -hashtable.o: hashtable.cpp hashtable.h stack.h - -clean: - -rm -f *.o ../libcontainer.a diff --git a/libs/container/array.cpp b/libs/container/array.cpp deleted file mode 100644 index 8ce77f5..0000000 --- a/libs/container/array.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "array.h" - -namespace -{ -class Bleh -{ -Array m_array; -public: -Bleh() : m_array( 16 ){ -} -}; - -void testAutoArray(){ - Array array( 32 ); -} -} \ No newline at end of file diff --git a/libs/container/array.h b/libs/container/array.h deleted file mode 100644 index 5de4fe8..0000000 --- a/libs/container/array.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_ARRAY_H ) -#define INCLUDED_CONTAINER_ARRAY_H - -#include "globaldefs.h" -#include -#include - -#include "memory/allocator.h" - -/// \brief An array whose size is variable at run-time. -/// -/// - Resizing the array destroys all the existing elements and invalidates all iterators. -/// - Default-Constructible, Copyable, Assignable. -/// - Compatible with the containers and algorithms in the Standard Template Library (STL) - http://www.sgi.com/tech/stl/ -/// -/// \param Element The type to be stored in the array. Must provide a default-constructor and a copy-constructor. -/// \param Allocator A custom memory-allocator, conforming to the std::allocator interface. -template > -class Array : public Allocator -{ -std::size_t m_size; -Element* m_data; - -Element* construct( std::size_t size ){ -#if 1 - return New( *this ).vector( size ); -#else - return new Element[size]; -#endif -} -template -Element* construct( std::size_t size, const T1& value ){ - return New( *this ).vector( size, value ); -} -void destroy( Element* data, std::size_t size ){ -#if 1 - Delete( *this ).vector( data, size ); -#else - delete[] data; -#endif -} - -public: -typedef Element value_type; -typedef value_type* iterator; -typedef const value_type* const_iterator; - -Array() - : m_size( 0 ), m_data( 0 ){ -} -Array( std::size_t size ) - : m_size( size ), m_data( construct( size ) ){ -} -template -Array( std::size_t size, const T1& value ) - : m_size( size ), m_data( construct( size, value ) ){ -} -Array( const Array& other ) - : Allocator( other ), m_size( other.size() ), m_data( construct( m_size ) ){ - std::copy( other.begin(), other.end(), begin() ); -} -template -Array( Iterator start, Iterator finish ) - : m_size( std::distance( start, finish ) ), m_data( construct( m_size ) ){ - std::copy( start, finish, begin() ); -} -~Array(){ - destroy( m_data, m_size ); -} - -Array& operator=( const Array& other ){ - if ( other.size() == size() ) { - std::copy( other.begin(), other.end(), begin() ); - } - else - { - Array temp( other ); - temp.swap( *this ); - } - return *this; -} - -void swap( Array& other ){ - std::swap( m_size, other.m_size ); - std::swap( m_data, other.m_data ); -} - -iterator begin(){ - return m_data; -} -const_iterator begin() const { - return m_data; -} -iterator end(){ - return m_data + m_size; -} -const_iterator end() const { - return m_data + m_size; -} - -value_type& operator[]( std::size_t index ){ -#if GDEF_DEBUG - ASSERT_MESSAGE( index < size(), "array index out of bounds" ); -#endif - return m_data[index]; -} -const value_type& operator[]( std::size_t index ) const { -#if GDEF_DEBUG - ASSERT_MESSAGE( index < size(), "array index out of bounds" ); -#endif - return m_data[index]; -} -value_type* data(){ - return m_data; -} -const value_type* data() const { - return m_data; -} -std::size_t size() const { - return m_size; -} -bool empty() const { - return m_size == 0; -} - -void resize( std::size_t count ){ - if ( count != size() ) { - Array temp( count ); - temp.swap( *this ); - } -} -void resize( std::size_t count, const value_type& value ){ - if ( count != size() ) { - Array temp( count, value ); - temp.swap( *this ); - } -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -template -inline void swap( Array& self, Array& other ){ - self.swap( other ); -} -} -#endif diff --git a/libs/container/cache.h b/libs/container/cache.h deleted file mode 100644 index 880a7a7..0000000 --- a/libs/container/cache.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_CACHE_H ) -#define INCLUDED_CONTAINER_CACHE_H - -#include -#include "container/hashtable.h" -#include "memory/allocator.h" - -template -class DefaultCreationPolicy -{ -public: -Type* construct( const Parameter& parameter ){ - return New().scalar( parameter ); -} -void destroy( Type* p ){ - Delete().scalar( p ); -} -}; - -template -class SharedValue -{ -typedef Type value_type; -typedef value_type* pointer; -typedef value_type& reference; - -std::size_t m_count; -pointer m_value; - -public: -SharedValue() - : m_count( 0 ), m_value( 0 ){ -} -~SharedValue(){ - ASSERT_MESSAGE( m_count == 0, "destroying a referenced object\n" ); -} -void set( pointer value ){ - m_value = value; -} -pointer get(){ - return m_value; -} -std::size_t increment(){ - return ++m_count; -} -std::size_t decrement(){ - ASSERT_MESSAGE( !empty(), "destroying a non-existent object\n" ); - return --m_count; -} -std::size_t count(){ - return m_count; -} -bool empty(){ - return m_count == 0; -} -reference operator*() const { - ASSERT_NOTNULL( m_value ); - return *m_value; -} -pointer operator->() const { - return &( operator*() ); -} -}; - - - -/// \brief Caches values that are uniquely identified by a key. -/// -/// - Automatically removes objects that are no longer referenced. -/// -/// \param Key Uniquely identifies each element. -/// \param Cached The type to be cached. Must define a constructor that accepts \c Key. -/// \param CreationPolicy Must define 'Cached* construct(const Key&)' and 'void destroy(Cached*)'. The lifetime of the \c Key passed to 'construct' is guaranteed to be longer than the subsequent matched call to 'destroy'. -template, typename CreationPolicy = DefaultCreationPolicy > -class HashedCache : public CreationPolicy -{ -typedef SharedValue Element; -typedef HashTable map_type; - -map_type m_map; - -public: -explicit HashedCache( const CreationPolicy& creation = CreationPolicy() ) - : CreationPolicy( creation ), m_map( 256 ){ -} -~HashedCache(){ - ASSERT_MESSAGE( empty(), "HashedCache::~HashedCache: not empty" ); -} - -typedef typename map_type::iterator iterator; -typedef typename map_type::value_type value_type; - -iterator begin(){ - return m_map.begin(); -} -iterator end(){ - return m_map.end(); -} - -bool empty() const { - return m_map.empty(); -} - -iterator find( const Key& key ){ - return m_map.find( key ); -} - -void capture( iterator i ){ - ( *i ).value.increment(); -} -void release( iterator i ){ - if ( ( *i ).value.decrement() == 0 ) { - CreationPolicy::destroy( ( *i ).value.get() ); - m_map.erase( i ); - } -} - -#if 1 -Element& capture( const Key& key ){ -#if 0 - Element& elem = m_map[key]; - if ( elem.increment() == 1 ) { - elem.set( CreationPolicy::construct( key ) ); - } - return elem; -#else - iterator i = m_map.insert( key, Element() ); - if ( ( *i ).value.increment() == 1 ) { - ( *i ).value.set( CreationPolicy::construct( ( *i ).key ) ); - } - return ( *i ).value; -#endif -} -#else -value_type& capture( const Key& key ){ - iterator i = m_map.find( key ); - if ( i == m_map.end() ) { - i = m_map.insert( key, Element() ); - ( *i ).value.set( CreationPolicy::construct( ( *i ).key ) ); - } - ( *i ).value.increment(); - return ( *i ); -} -#endif -void release( const Key& key ){ - iterator i = m_map.find( key ); - ASSERT_MESSAGE( i != m_map.end(), "releasing a non-existent object\n" ); - release( i ); -} - -void clear(){ - m_map.clear(); -} -}; - - -#endif diff --git a/libs/container/container.h b/libs/container/container.h deleted file mode 100644 index a2d1fec..0000000 --- a/libs/container/container.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_CONTAINER_H ) -#define INCLUDED_CONTAINER_CONTAINER_H - -#include -#include -#include - -#include "generic/static.h" - -/// \brief A single-value container, which can either be empty or full. -template -class Single -{ -Type* m_value; -public: -Single() : m_value( 0 ){ -} -bool empty(){ - return m_value == 0; -} -Type* insert( const Type& other ){ - m_value = new Type( other ); - return m_value; -} -void clear(){ - delete m_value; - m_value = 0; -} -Type& get(){ - //ASSERT_MESSAGE(!empty(), "Single: must be initialised before being accessed"); - return *m_value; -} -const Type& get() const { - //ASSERT_MESSAGE(!empty(), "Single: must be initialised before being accessed"); - return *m_value; -} -}; - - -/// \brief An adaptor to make std::list into a Unique Sequence - which cannot contain the same value more than once. -/// \param Value Uniquely identifies itself. Must provide a copy-constructor and an equality operator. -template -class UnsortedSet -{ -typedef typename std::list Values; -Values m_values; -public: -typedef typename Values::iterator iterator; -typedef typename Values::const_iterator const_iterator; -typedef typename Values::reverse_iterator reverse_iterator; -typedef typename Values::const_reverse_iterator const_reverse_iterator; - -iterator begin(){ - return m_values.begin(); -} -const_iterator begin() const { - return m_values.begin(); -} -iterator end(){ - return m_values.end(); -} -const_iterator end() const { - return m_values.end(); -} -reverse_iterator rbegin(){ - return m_values.rbegin(); -} -const_reverse_iterator rbegin() const { - return m_values.rbegin(); -} -reverse_iterator rend(){ - return m_values.rend(); -} -const_reverse_iterator rend() const { - return m_values.rend(); -} - -bool empty() const { - return m_values.empty(); -} -std::size_t size() const { - return m_values.size(); -} -void clear(){ - m_values.clear(); -} - -void swap( UnsortedSet& other ){ - std::swap( m_values, other.m_values ); -} -iterator insert( const Value& value ){ - ASSERT_MESSAGE( find( value ) == end(), "UnsortedSet::insert: already added" ); - m_values.push_back( value ); - return --end(); -} -void erase( const Value& value ){ - iterator i = find( value ); - ASSERT_MESSAGE( i != end(), "UnsortedSet::erase: not found" ); - m_values.erase( i ); -} -iterator find( const Value& value ){ - return std::find( begin(), end(), value ); -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -template -inline void swap( UnsortedSet& self, UnsortedSet& other ){ - self.swap( other ); -} -} - -/// An adaptor to make std::list into a Unique Associative Sequence - which cannot contain the same value more than once. -/// Key: Uniquely identifies a value. Must provide a copy-constructor and an equality operator. -/// Value: Must provide a copy-constructor. -template -class UnsortedMap -{ -typedef typename std::list< std::pair > Values; -Values m_values; -public: -typedef typename Values::value_type value_type; -typedef typename Values::iterator iterator; -typedef typename Values::const_iterator const_iterator; - -iterator begin(){ - return m_values.begin(); -} -const_iterator begin() const { - return m_values.begin(); -} -iterator end(){ - return m_values.end(); -} -const_iterator end() const { - return m_values.end(); -} - -bool empty() const { - return m_values.empty(); -} -std::size_t size() const { - return m_values.size(); -} -void clear(){ - m_values.clear(); -} - -iterator insert( const value_type& value ){ - ASSERT_MESSAGE( find( value.first ) == end(), "UnsortedMap::insert: already added" ); - m_values.push_back( value ); - return --m_values.end(); -} -void erase( const Key& key ){ - iterator i = find( key ); - ASSERT_MESSAGE( i != end(), "UnsortedMap::erase: not found" ); - erase( i ); -} -void erase( iterator i ){ - m_values.erase( i ); -} -iterator find( const Key& key ){ - for ( iterator i = m_values.begin(); i != m_values.end(); ++i ) - { - if ( ( *i ).first == key ) { - return i; - } - } - return m_values.end(); -} -const_iterator find( const Key& key ) const { - for ( const_iterator i = m_values.begin(); i != m_values.end(); ++i ) - { - if ( ( *i ).first == key ) { - return i; - } - } - return m_values.end(); -} - -Value& operator[]( const Key& key ){ - iterator i = find( key ); - if ( i != end() ) { - return ( *i ).second; - } - - m_values.push_back( Values::value_type( key, Value() ) ); - return m_values.back().second; -} -}; - -/// An adaptor to assert when duplicate values are added, or non-existent values removed from a std::set. -template -class UniqueSet -{ -typedef std::set Values; -Values m_values; -public: -typedef typename Values::iterator iterator; -typedef typename Values::const_iterator const_iterator; -typedef typename Values::reverse_iterator reverse_iterator; -typedef typename Values::const_reverse_iterator const_reverse_iterator; - - -iterator begin(){ - return m_values.begin(); -} -const_iterator begin() const { - return m_values.begin(); -} -iterator end(){ - return m_values.end(); -} -const_iterator end() const { - return m_values.end(); -} -reverse_iterator rbegin(){ - return m_values.rbegin(); -} -const_reverse_iterator rbegin() const { - return m_values.rbegin(); -} -reverse_iterator rend(){ - return m_values.rend(); -} -const_reverse_iterator rend() const { - return m_values.rend(); -} - -bool empty() const { - return m_values.empty(); -} -std::size_t size() const { - return m_values.size(); -} -void clear(){ - m_values.clear(); -} - -void swap( UniqueSet& other ){ - std::swap( m_values, other.m_values ); -} -iterator insert( const Value& value ){ - std::pair result = m_values.insert( value ); - ASSERT_MESSAGE( result.second, "UniqueSet::insert: already added" ); - return result.first; -} -void erase( const Value& value ){ - iterator i = find( value ); - ASSERT_MESSAGE( i != end(), "UniqueSet::erase: not found" ); - m_values.erase( i ); -} -iterator find( const Value& value ){ - return std::find( begin(), end(), value ); -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -template -inline void swap( UniqueSet& self, UniqueSet& other ){ - self.swap( other ); -} -} - -template -class ReferencePair -{ -Type* m_first; -Type* m_second; -public: -ReferencePair() : m_first( 0 ), m_second( 0 ){ -} -void attach( Type& t ){ - ASSERT_MESSAGE( m_first == 0 || m_second == 0, "ReferencePair::insert: pointer already exists" ); - if ( m_first == 0 ) { - m_first = &t; - } - else if ( m_second == 0 ) { - m_second = &t; - } -} -void detach( Type& t ){ - ASSERT_MESSAGE( m_first == &t || m_second == &t, "ReferencePair::erase: pointer not found" ); - if ( m_first == &t ) { - m_first = 0; - } - else if ( m_second == &t ) { - m_second = 0; - } -} -template -void forEach( const Functor& functor ){ - if ( m_second != 0 ) { - functor( *m_second ); - } - if ( m_first != 0 ) { - functor( *m_first ); - } -} -}; - - -#endif diff --git a/libs/container/hashfunc.h b/libs/container/hashfunc.h deleted file mode 100644 index 1a027f9..0000000 --- a/libs/container/hashfunc.h +++ /dev/null @@ -1,402 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_HASHFUNC_H ) -#define INCLUDED_CONTAINER_HASHFUNC_H - -#include -#include "string/string.h" -#include "container/array.h" -typedef unsigned long int ub4; /* unsigned 4-byte quantities */ -typedef unsigned char ub1; - -inline ub1 ub1_as_ub1_nocase( ub1 byte ){ - return std::tolower( byte ); -} - -inline ub4 ub1x4_as_ub4_nocase( const ub1 bytes[4] ){ - ub4 result; - reinterpret_cast( &result )[0] = ub1_as_ub1_nocase( bytes[0] ); - reinterpret_cast( &result )[1] = ub1_as_ub1_nocase( bytes[1] ); - reinterpret_cast( &result )[2] = ub1_as_ub1_nocase( bytes[2] ); - reinterpret_cast( &result )[3] = ub1_as_ub1_nocase( bytes[3] ); - return result; -} - -class ub1_default_traits -{ -public: -static ub1 as_ub1( ub1 byte ){ - return byte; -} -}; - -class ub1_nocase_traits -{ -public: -static ub1 as_ub1( ub1 byte ){ - return ub1_as_ub1_nocase( byte ); -} -}; - -class ub1x4_default_traits -{ -public: -static ub4 as_ub4( const ub1 bytes[4] ){ - return *reinterpret_cast( bytes ); -} -}; - -class ub1x4_nocase_traits -{ -public: -static ub4 as_ub4( const ub1 bytes[4] ){ - return ub1x4_as_ub4_nocase( bytes ); -} -}; - -class ub4_default_traits -{ -public: -static ub4 as_ub4( ub4 i ){ - return i; -} -}; - -class ub4_nocase_traits -{ -public: -static ub4 as_ub4( ub4 i ){ - return ub1x4_as_ub4_nocase( reinterpret_cast( &i ) ); -} -}; - -// lookup2.c -// By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this -// code any way you wish, private, educational, or commercial. It's free. - -#define hashsize( n ) ( (ub4)1 << ( n ) ) -#define hashmask( n ) ( hashsize( n ) - 1 ) - -/* - -------------------------------------------------------------------- - mix -- mix 3 32-bit values reversibly. - For every delta with one or two bit set, and the deltas of all three - high bits or all three low bits, whether the original value of a,b,c - is almost all zero or is uniformly distributed, - * If mix() is run forward or backward, at least 32 bits in a,b,c - have at least 1/4 probability of changing. - * If mix() is run forward, every bit of c will change between 1/3 and - 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) - mix() was built out of 36 single-cycle latency instructions in a - structure that could supported 2x parallelism, like so: - a -= b; - a -= c; x = (c>>13); - b -= c; a ^= x; - b -= a; x = (a<<8); - c -= a; b ^= x; - c -= b; x = (b>>13); - ... - Unfortunately, superscalar Pentiums and Sparcs can't take advantage - of that parallelism. They've also turned some of those single-cycle - latency instructions into multi-cycle latency instructions. Still, - this is the fastest good hash I could find. There were about 2^^68 - to choose from. I only looked at a billion or so. - -------------------------------------------------------------------- - */ -#define mix( a,b,c ) \ - { \ - a -= b; a -= c; a ^= ( c >> 13 ); \ - b -= c; b -= a; b ^= ( a << 8 ); \ - c -= a; c -= b; c ^= ( b >> 13 ); \ - a -= b; a -= c; a ^= ( c >> 12 ); \ - b -= c; b -= a; b ^= ( a << 16 ); \ - c -= a; c -= b; c ^= ( b >> 5 ); \ - a -= b; a -= c; a ^= ( c >> 3 ); \ - b -= c; b -= a; b ^= ( a << 10 ); \ - c -= a; c -= b; c ^= ( b >> 15 ); \ - } - -/* same, but slower, works on systems that might have 8 byte ub4's */ -#define mix2( a,b,c ) \ - { \ - a -= b; a -= c; a ^= ( c >> 13 ); \ - b -= c; b -= a; b ^= ( a << 8 ); \ - c -= a; c -= b; c ^= ( ( b & 0xffffffff ) >> 13 ); \ - a -= b; a -= c; a ^= ( ( c & 0xffffffff ) >> 12 ); \ - b -= c; b -= a; b = ( b ^ ( a << 16 ) ) & 0xffffffff; \ - c -= a; c -= b; c = ( c ^ ( b >> 5 ) ) & 0xffffffff; \ - a -= b; a -= c; a = ( a ^ ( c >> 3 ) ) & 0xffffffff; \ - b -= c; b -= a; b = ( b ^ ( a << 10 ) ) & 0xffffffff; \ - c -= a; c -= b; c = ( c ^ ( b >> 15 ) ) & 0xffffffff; \ - } - -/* - -------------------------------------------------------------------- - hash() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - len : the length of the key, counting by bytes - level : can be any 4-byte value - Returns a 32-bit value. Every bit of the key affects every bit of - the return value. Every 1-bit and 2-bit delta achieves avalanche. - About 36+6len instructions. - - The best hash table sizes are powers of 2. There is no need to do - mod a prime (mod is sooo slow!). If you need less than 32 bits, - use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); - In which case, the hash table should have hashsize(10) elements. - - If you are hashing n strings (ub1 **)k, do it like this: - for (i=0, h=0; i -inline ub4 hash( - const ub1 *k, /* the key */ - ub4 length, /* the length of the key */ - ub4 initval, /* the previous hash, or an arbitrary value */ - const UB1Traits& ub1traits, - const UB4x1Traits& ub4x1traits - ){ - register ub4 a,b,c,len; - - /* Set up the internal state */ - len = length; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = initval; /* the previous hash value */ - - /*---------------------------------------- handle most of the key */ - while ( len >= 12 ) - { - a += ( k[0] + ( ( ub4 ) UB1Traits::as_ub1( k[1] ) << 8 ) + ( ( ub4 ) UB1Traits::as_ub1( k[2] ) << 16 ) + ( ( ub4 ) UB1Traits::as_ub1( k[3] ) << 24 ) ); - b += ( k[4] + ( ( ub4 ) UB1Traits::as_ub1( k[5] ) << 8 ) + ( ( ub4 ) UB1Traits::as_ub1( k[6] ) << 16 ) + ( ( ub4 ) UB1Traits::as_ub1( k[7] ) << 24 ) ); - c += ( k[8] + ( ( ub4 ) UB1Traits::as_ub1( k[9] ) << 8 ) + ( ( ub4 ) UB1Traits::as_ub1( k[10] ) << 16 ) + ( ( ub4 ) UB1Traits::as_ub1( k[11] ) << 24 ) ); - mix( a,b,c ); - k += 12; len -= 12; - } - - /*------------------------------------- handle the last 11 bytes */ - c += length; - switch ( len ) /* all the case statements fall through */ - { - case 11: c += ( ( ub4 ) UB1Traits::as_ub1( k[10] ) << 24 ); - case 10: c += ( ( ub4 ) UB1Traits::as_ub1( k[9] ) << 16 ); - case 9: c += ( ( ub4 ) UB1Traits::as_ub1( k[8] ) << 8 ); - /* the first byte of c is reserved for the length */ - case 8: b += ( ( ub4 ) UB1Traits::as_ub1( k[7] ) << 24 ); - case 7: b += ( ( ub4 ) UB1Traits::as_ub1( k[6] ) << 16 ); - case 6: b += ( ( ub4 ) UB1Traits::as_ub1( k[5] ) << 8 ); - case 5: b += UB1Traits::as_ub1( k[4] ); - case 4: a += ( ( ub4 ) UB1Traits::as_ub1( k[3] ) << 24 ); - case 3: a += ( ( ub4 ) UB1Traits::as_ub1( k[2] ) << 16 ); - case 2: a += ( ( ub4 ) UB1Traits::as_ub1( k[1] ) << 8 ); - case 1: a += UB1Traits::as_ub1( k[0] ); - /* case 0: nothing left to add */ - } - mix( a,b,c ); - /*-------------------------------------------- report the result */ - return c; -} - -/* - -------------------------------------------------------------------- - This works on all machines. hash2() is identical to hash() on - little-endian machines, except that the length has to be measured - in ub4s instead of bytes. It is much faster than hash(). It - requires - -- that the key be an array of ub4's, and - -- that all your machines have the same endianness, and - -- that the length be the number of ub4's in the key - -------------------------------------------------------------------- - */ -template -inline ub4 hash2( - const ub4 *k, /* the key */ - ub4 length, /* the length of the key, in ub4s */ - ub4 initval, /* the previous hash, or an arbitrary value */ - const UB4Traits& ub4traits - ){ - register ub4 a,b,c,len; - - /* Set up the internal state */ - len = length; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = initval; /* the previous hash value */ - - /*---------------------------------------- handle most of the key */ - while ( len >= 3 ) - { - a += UB4Traits::as_ub4( k[0] ); - b += UB4Traits::as_ub4( k[1] ); - c += UB4Traits::as_ub4( k[2] ); - mix( a,b,c ); - k += 3; len -= 3; - } - - /*-------------------------------------- handle the last 2 ub4's */ - c += length; - switch ( len ) /* all the case statements fall through */ - { - /* c is reserved for the length */ - case 2: b += UB4Traits::as_ub4( k[1] ); - case 1: a += UB4Traits::as_ub4( k[0] ); - /* case 0: nothing left to add */ - } - mix( a,b,c ); - /*-------------------------------------------- report the result */ - return c; -} - -typedef ub4 hash_t; - -inline hash_t hash_ub1( const ub1* key, std::size_t len, hash_t previous = 0 ){ - return hash( key, ub4( len ), previous, ub1_default_traits(), ub1x4_default_traits() ); -} - -inline hash_t hash_ub1_nocase( const ub1* key, std::size_t len, hash_t previous = 0 ){ - return hash( key, ub4( len ), previous, ub1_nocase_traits(), ub1x4_nocase_traits() ); -} - -template -inline hash_t hash_ub4( const ub4* key, std::size_t len, const UB4Traits& traits, hash_t previous = 0 ){ - return hash2( key,ub4( len ), previous, traits ); -} - -inline ub4 hash_combine( ub4 left, ub4 right ){ - return hash_ub1( reinterpret_cast( &left ), 4, right ); -} - -template -inline hash_t pod_hash( const POD& pod ){ - return hash_ub1( reinterpret_cast( &pod ), sizeof( POD ) ); -} - -inline hash_t string_hash( const char* string, hash_t previous = 0 ){ - return hash_ub1( reinterpret_cast( string ), string_length( string ), previous ); -} - -inline hash_t string_hash_nocase( const char* string, hash_t previous = 0 ){ - return hash_ub1_nocase( reinterpret_cast( string ), string_length( string ), previous ); -} - -struct RawStringHash -{ - typedef hash_t hash_type; - hash_type operator()( const char* string ) const { - return string_hash( string ); - } -}; - -struct HashString -{ - typedef hash_t hash_type; - hash_type operator()( const CopiedString& string ) const { - return string_hash( string.c_str() ); - } -}; - -struct HashStringNoCase -{ - typedef hash_t hash_type; - hash_type operator()( const CopiedString& string ) const { - return string_hash_nocase( string.c_str() ); - } -}; - -/// \brief Length of a string in ub4. -/// "wibble" (6) gives 2, -/// "and" (3) gives 1, -/// "bleh" (4) gives 2 -inline std::size_t string_length_ub4( const char* string ){ - return ( ( string_length( string ) >> 2 ) + 1 ) << 2; -} - -/// \brief Hashable key type that stores a string as an array of ub4 - making hashing faster. -/// Also caches the 32-bit result of the hash to speed up comparison of keys. -template -class HashKey -{ -Array m_key; -hash_t m_hash; - -void copy( const HashKey& other ){ - std::copy( other.m_key.begin(), other.m_key.end(), m_key.begin() ); - m_hash = other.m_hash; -} -void copy( const char* string ){ - strncpy( reinterpret_cast( m_key.data() ), string, m_key.size() ); - for ( Array::iterator i = m_key.begin(); i != m_key.end(); ++i ) - { - *i = UB4Traits::as_ub4( *i ); - } - m_hash = hash_ub4( m_key.data(), m_key.size(), ub4_default_traits() ); -} -bool equal( const HashKey& other ) const { - return m_hash == other.m_hash && m_key.size() == other.m_key.size() - && std::equal( m_key.begin(), m_key.end(), other.m_key.begin() ); -} - -public: -HashKey( const HashKey& other ) : m_key( other.m_key.size() ){ - copy( other ); -} -HashKey( const char* string ) : m_key( string_length_ub4( string ) ){ - copy( string ); -} -HashKey& operator=( const char* string ){ - m_key.resize( string_length_ub4( string ) ); - copy( string ); - return *this; -} -bool operator==( const HashKey& other ) const { - return equal( other ); -} -bool operator!=( const HashKey& other ) const { - return !equal( other ); -} -hash_t hash() const { - return m_hash; -} -#if 0 -const char* c_str() const { - return reinterpret_cast( m_key.data() ); -} -#endif -}; - -/// \brief Hash function to use with HashKey. -struct HashKeyHasher -{ - typedef hash_t hash_type; - hash_type operator()( const HashKey& key ) const { - return key.hash(); - } -}; - - - -#endif diff --git a/libs/container/hashtable.cpp b/libs/container/hashtable.cpp deleted file mode 100644 index f2e6602..0000000 --- a/libs/container/hashtable.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "hashtable.h" -#include "globaldefs.h" - -#if GDEF_DEBUG || defined( DOXYGEN ) - -#include "hashfunc.h" - -namespace ExampleHashTable -{ -void testStuff(){ - // HashTable example - typedef HashTable MyHashTable; - MyHashTable hashtable; - hashtable["bleh"] = 5; - hashtable.insert( "blah", 17 ); - hashtable["foo"] = 99; - hashtable.insert( "bar", 23 ); - - int bleh = ( *hashtable.find( "bleh" ) ).value; // 5 - int blah = hashtable["blah"]; // 17 - hashtable.erase( "foo" ); - MyHashTable::iterator barIter = hashtable.find( "bar" ); - hashtable.erase( barIter ); - - for ( MyHashTable::iterator i = hashtable.begin(); i != hashtable.end(); ++i ) - { - if ( ( *i ).key != "bleh" ) { - ++hashtable["count"]; // insertion does not invalidate iterators - } - } - // end example -} - -struct Always -{ - Always(){ - testStuff(); - } -} always; -} - -#endif diff --git a/libs/container/hashtable.h b/libs/container/hashtable.h deleted file mode 100644 index 7fa7907..0000000 --- a/libs/container/hashtable.h +++ /dev/null @@ -1,410 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_HASHTABLE_H ) -#define INCLUDED_CONTAINER_HASHTABLE_H - -#include -#include -#include -#include -#include "debugging/debugging.h" - -namespace HashTableDetail -{ -inline std::size_t next_power_of_two( std::size_t size ){ - std::size_t result = 1; - while ( result < size ) - { - result <<= 1; - } - return result; -} - -struct BucketNodeBase -{ - BucketNodeBase* next; - BucketNodeBase* prev; -}; - -inline void list_initialise( BucketNodeBase& self ){ - self.next = self.prev = &self; -} - -inline void list_swap( BucketNodeBase& self, BucketNodeBase& other ){ - BucketNodeBase tmp( self ); - if ( other.next == &other ) { - list_initialise( self ); - } - else - { - self = other; - self.next->prev = self.prev->next = &self; - } - if ( tmp.next == &self ) { - list_initialise( other ); - } - else - { - other = tmp; - other.next->prev = other.prev->next = &other; - } -} - -inline void node_link( BucketNodeBase* node, BucketNodeBase* next ){ - node->next = next; - node->prev = next->prev; - next->prev = node; - node->prev->next = node; -} -inline void node_unlink( BucketNodeBase* node ){ - node->prev->next = node->next; - node->next->prev = node->prev; -} - -template -struct KeyValue -{ - const Key key; - Value value; - - KeyValue( const Key& key_, const Value& value_ ) - : key( key_ ), value( value_ ){ - } -}; - -template -struct BucketNode : public BucketNodeBase -{ - Hash m_hash; - KeyValue m_value; - - BucketNode( Hash hash, const Key& key, const Value& value ) - : m_hash( hash ), m_value( key, value ){ - } - BucketNode* getNext() const { - return static_cast( next ); - } - BucketNode* getPrev() const { - return static_cast( prev ); - } -}; - -template -class BucketIterator -{ -typedef BucketNode Node; -Node* m_node; - -void increment(){ - m_node = m_node->getNext(); -} - -public: -typedef std::forward_iterator_tag iterator_category; -typedef std::ptrdiff_t difference_type; -typedef difference_type distance_type; -typedef KeyValue value_type; -typedef value_type* pointer; -typedef value_type& reference; - -BucketIterator( Node* node ) : m_node( node ){ -} - -Node* node(){ - return m_node; -} - -bool operator==( const BucketIterator& other ) const { - return m_node == other.m_node; -} -bool operator!=( const BucketIterator& other ) const { - return !operator==( other ); -} -BucketIterator& operator++(){ - increment(); - return *this; -} -BucketIterator operator++( int ){ - BucketIterator tmp = *this; - increment(); - return tmp; -} -value_type& operator*() const { - return m_node->m_value; -} -value_type* operator->() const { - return &( operator*() ); -} -}; -} - - -/// A hash-table container which maps keys to values. -/// -/// - Inserting or removing elements does not invalidate iterators. -/// - Inserting or retrieving an element for a given key takes O(1) time on average. -/// - Elements are stored in no particular order. -/// -/// \param Key Uniquely identifies a value. Must provide a copy-constructor. -/// \param Value The value to be stored . Must provide a default-constructor and a copy-constructor. -/// \param Hasher Must provide 'std::size_t operator()(const Key&) const' which always returns the same result if the same argument is given. -/// \param KeyEqual Must provide 'bool operator==(const Key&, const Key&) const' which returns true only if both arguments are equal. -/// -/// \dontinclude container/hashtable.cpp -/// \skipline HashTable example -/// \until end example -template > -class HashTable : private KeyEqual, private Hasher -{ -typedef typename Hasher::hash_type hash_type; -typedef HashTableDetail::KeyValue KeyValue; -typedef HashTableDetail::BucketNode BucketNode; - -inline BucketNode* node_create( hash_type hash, const Key& key, const Value& value ){ - return new BucketNode( hash, key, value ); -} -inline void node_destroy( BucketNode* node ){ - delete node; -} - -typedef BucketNode* Bucket; - -static Bucket* buckets_new( std::size_t count ){ - Bucket* buckets = new Bucket[count]; - std::uninitialized_fill( buckets, buckets + count, Bucket( 0 ) ); - return buckets; -} -static void buckets_delete( Bucket* buckets ){ - delete[] buckets; -} - -std::size_t m_bucketCount; -Bucket* m_buckets; -std::size_t m_size; -HashTableDetail::BucketNodeBase m_list; - -BucketNode* getFirst(){ - return static_cast( m_list.next ); -} -BucketNode* getLast(){ - return static_cast( &m_list ); -} - -public: - -typedef KeyValue value_type; -typedef HashTableDetail::BucketIterator iterator; - -private: - -void initialise(){ - list_initialise( m_list ); -} -hash_type hashKey( const Key& key ){ - return Hasher::operator()( key ); -} - -std::size_t getBucketId( hash_type hash ) const { - return hash & ( m_bucketCount - 1 ); -} -Bucket& getBucket( hash_type hash ){ - return m_buckets[getBucketId( hash )]; -} -BucketNode* bucket_find( Bucket bucket, hash_type hash, const Key& key ){ - std::size_t bucketId = getBucketId( hash ); - for ( iterator i( bucket ); i != end(); ++i ) - { - hash_type nodeHash = i.node()->m_hash; - - if ( getBucketId( nodeHash ) != bucketId ) { - return 0; - } - - if ( nodeHash == hash && KeyEqual::operator()( ( *i ).key, key ) ) { - return i.node(); - } - } - return 0; -} -BucketNode* bucket_insert( Bucket& bucket, BucketNode* node ){ - // link node into list - node_link( node, bucket_next( bucket ) ); - bucket = node; - return node; -} -BucketNode* bucket_next( Bucket& bucket ){ - Bucket* end = m_buckets + m_bucketCount; - for ( Bucket* i = &bucket; i != end; ++i ) - { - if ( *i != 0 ) { - return *i; - } - } - return getLast(); -} - -void buckets_resize( std::size_t count ){ - BucketNode* first = getFirst(); - BucketNode* last = getLast(); - - buckets_delete( m_buckets ); - - m_bucketCount = count; - - m_buckets = buckets_new( m_bucketCount ); - initialise(); - - for ( BucketNode* i = first; i != last; ) - { - BucketNode* node = i; - i = i->getNext(); - bucket_insert( getBucket( ( *node ).m_hash ), node ); - } -} -void size_increment(){ - if ( m_size == m_bucketCount ) { - buckets_resize( m_bucketCount == 0 ? 8 : m_bucketCount << 1 ); - } - ++m_size; -} -void size_decrement(){ - --m_size; -} - -HashTable( const HashTable& other ); -HashTable& operator=( const HashTable& other ); -public: -HashTable() : m_bucketCount( 0 ), m_buckets( 0 ), m_size( 0 ){ - initialise(); -} -HashTable( std::size_t bucketCount ) : m_bucketCount( HashTableDetail::next_power_of_two( bucketCount ) ), m_buckets( buckets_new( m_bucketCount ) ), m_size( 0 ){ - initialise(); -} -~HashTable(){ - for ( BucketNode* i = getFirst(); i != getLast(); ) - { - BucketNode* node = i; - i = i->getNext(); - node_destroy( node ); - } - buckets_delete( m_buckets ); -} - -iterator begin(){ - return iterator( getFirst() ); -} -iterator end(){ - return iterator( getLast() ); -} - -bool empty() const { - return m_size == 0; -} -std::size_t size() const { - return m_size; -} - -/// \brief Returns an iterator pointing to the value associated with \p key if it is contained by the hash-table, else \c end(). -iterator find( const Key& key ){ - hash_type hash = hashKey( key ); - if ( m_bucketCount != 0 ) { - Bucket bucket = getBucket( hash ); - if ( bucket != 0 ) { - BucketNode* node = bucket_find( bucket, hash, key ); - if ( node != 0 ) { - return iterator( node ); - } - } - } - - return end(); -} -/// \brief Adds \p value to the hash-table associated with \p key if it does not exist. -iterator insert( const Key& key, const Value& value ){ - hash_type hash = hashKey( key ); - if ( m_bucketCount != 0 ) { - Bucket& bucket = getBucket( hash ); - if ( bucket != 0 ) { - BucketNode* node = bucket_find( bucket, hash, key ); - if ( node != 0 ) { - return iterator( node ); - } - } - } - - size_increment(); - return iterator( bucket_insert( getBucket( hash ), node_create( hash, key, value ) ) ); -} - -/// \brief Removes the value pointed to by \p i from the hash-table. -/// -/// \p i must be a deferenceable iterator into the hash-table. -void erase( iterator i ){ - Bucket& bucket = getBucket( i.node()->m_hash ); - BucketNode* node = i.node(); - - // if this was the last node in the bucket - if ( bucket == node ) { - bucket = ( node->getNext() == getLast() || &getBucket( node->getNext()->m_hash ) != &bucket ) ? 0 : node->getNext(); - } - - node_unlink( node ); - ASSERT_MESSAGE( node != 0, "tried to erase a non-existent key/value" ); - node_destroy( node ); - - size_decrement(); -} - -/// \brief Returns the value identified by \p key if it is contained by the hash-table, else inserts and returns a new default-constructed value associated with \p key. -Value& operator[]( const Key& key ){ - hash_type hash = hashKey( key ); - if ( m_bucketCount != 0 ) { - Bucket& bucket = getBucket( hash ); - if ( bucket != 0 ) { - BucketNode* node = bucket_find( bucket, hash, key ); - if ( node != 0 ) { - return node->m_value.value; - } - } - } - size_increment(); - return bucket_insert( getBucket( hash ), node_create( hash, key, Value() ) )->m_value.value; -} -/// \brief Removes the value associated with \p key from the hash-table. -void erase( const Key& key ){ - erase( find( key ) ); -} -/// \brief Swaps the contents of the hash-table with \p other. -void swap( HashTable& other ){ - std::swap( m_buckets, other.m_buckets ); - std::swap( m_bucketCount, other.m_bucketCount ); - std::swap( m_size, other.m_size ); - HashTableDetail::list_swap( m_list, other.m_list ); -} -/// \brief Removes all values from the hash-table. -void clear(){ - HashTable tmp; - tmp.swap( *this ); -} -}; - -#endif diff --git a/libs/container/stack.h b/libs/container/stack.h deleted file mode 100644 index 10040a7..0000000 --- a/libs/container/stack.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONTAINER_STACK_H ) -#define INCLUDED_CONTAINER_STACK_H - -#include "memory/allocator.h" -#include - -/// \brief A stack whose storage capacity is variable at run-time. Similar to std::vector. -/// -/// - Pushing or popping elements is a constant-time operation (on average). -/// - The storage capacity of the stack will grow when a new element is added beyond the current capacity. Iterators are invalidated when the storage capacity grows. -/// - DefaultConstructible, Copyable, Assignable. -/// - Compatible with the containers and algorithms in the Standard Template Library (STL) - http://www.sgi.com/tech/stl/ -/// -/// \param Type: The type to be stored in the stack. Must provide a copy-constructor. -template -class Stack : public DefaultAllocator -{ -typedef DefaultAllocator Allocator; - -enum -{ - DEFAULT_CAPACITY = 4, -}; - -typedef Type* pointer; -typedef const Type* const_pointer; - -public: -typedef const_pointer const_iterator; -private: - -pointer m_data; -pointer m_end; -std::size_t m_capacity; - - -void insert( const Type& value ){ - Allocator::construct( m_end++, value ); -} -void insert_overflow( const Type& value ){ - const std::size_t new_capacity = ( m_capacity ) ? m_capacity + m_capacity : std::size_t( DEFAULT_CAPACITY ); - const pointer new_data = Allocator::allocate( new_capacity ); - const pointer new_end = std::copy( m_data, m_end, new_data ); - - destroy(); - Allocator::deallocate( m_data, m_capacity ); - - m_capacity = new_capacity; - m_data = new_data; - m_end = new_end; - insert( value ); -} -void destroy(){ - for ( pointer p = m_data; p != m_end; ++p ) - { - Allocator::destroy( p ); - } -} -void construct( const Stack& other ){ - pointer p = m_data; - for ( const_iterator i = other.begin(); i != other.end(); ++i ) - { - Allocator::construct( p++, *i ); - } -} - -public: - -Stack() : - m_data( 0 ), - m_end( 0 ), - m_capacity( 0 ){ -} -Stack( const Type& value ) : - m_data( 0 ), - m_end( 0 ), - m_capacity( 0 ){ - push( value ); -} -Stack( const Stack& other ) : - DefaultAllocator( other ){ - m_capacity = other.m_capacity; - m_data = Allocator::allocate( m_capacity ); - construct( other ); - m_end = m_data + other.size(); -} -~Stack(){ - destroy(); - Allocator::deallocate( m_data, m_capacity ); -} - -const_iterator begin() const { - return m_data; -} -const_iterator end() const { - return m_end; -} - -bool empty() const { - return end() == begin(); -} -void clear(){ - destroy(); - m_end = m_data; -} - -std::size_t size() const { - return m_end - m_data; -} -Type operator[]( const std::size_t i ) const { - return m_data[i]; -} -/// \brief Pushes \p value onto the stack at the top element. If reserved storage is insufficient for the new element, this will invalidate all iterators. -void push( const Type& value ){ - if ( size() == m_capacity ) { - insert_overflow( value ); - } - else - { - insert( value ); - } -} -/// \brief Removes the top element of the stack. -void pop(){ - Allocator::destroy( --m_end ); -} -/// \brief Returns the top element of the mutable stack. -Type& top(){ - return *( m_end - 1 ); -} -/// \brief Returns the top element of the non-mutable stack. -const Type& top() const { - return *( m_end - 1 ); -} -/// \brief Returns the element below the top element of the mutable stack. -Type& parent(){ - return *( m_end - 2 ); -} -/// \brief Returns the element below the top element of the non-mutable stack. -const Type& parent() const { - return *( m_end - 2 ); -} -/// \brief Swaps the values of this stack and \p other. -void swap( Stack& other ){ - std::swap( m_data, other.m_data ); - std::swap( m_end, other.m_end ); - std::swap( m_capacity, other.m_capacity ); -} -#if 1 // use copy-swap technique -Stack& operator=( const Stack& other ){ - Stack temp( other ); - temp.swap( *this ); - return *this; -} -#else // avoids memory allocation if capacity is already sufficient. -Stack& operator=( const Stack& other ){ - if ( &other != this ) { - destroy(); - - if ( other.size() > m_capacity ) { - Allocator::deallocate( m_data, m_capacity ); - m_capacity = other.m_capacity; - m_data = Allocator::allocate( m_capacity ); - } - m_end = m_data + other.size(); - - construct( other ); - } - return *this; -} -#endif -}; - -/// \brief Returns true if \p self is lexicographically less than \p other. -template -inline bool operator<( const Stack& self, const Stack& other ){ - return std::lexicographical_compare( self.begin(), self.end(), other.begin(), other.end() ); -} - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap(). -template -inline void swap( Stack& self, Stack& other ){ - self.swap( other ); -} -} - -#endif diff --git a/libs/convert.h b/libs/convert.h deleted file mode 100644 index 322e902..0000000 --- a/libs/convert.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONVERT_H ) -#define INCLUDED_CONVERT_H - -/// \file -/// \brief Character encoding conversion. - -#include "debugging/debugging.h" -#include -#include - -#include "character.h" - -/// \brief Returns the number of bytes required to represent \p character in UTF-8 encoding. -inline std::size_t utf8_character_length( const char* character ){ - if ( ( *character & 0xE0 ) == 0xC0 ) { // 110xxxxx - return 2; - } - else if ( ( *character & 0xF0 ) == 0xE0 ) { // 1110xxxx - return 3; - } - else if ( ( *character & 0xF8 ) == 0xF0 ) { // 11110xxx - return 4; - } - else if ( ( *character & 0xFC ) == 0xF8 ) { // 111110xx - return 5; - } - else if ( ( *character & 0xFE ) == 0xFC ) { // 1111110x - return 6; - } - ERROR_MESSAGE( "" ); - return 0; -} - -struct UTF8Character -{ - const char* buffer; - std::size_t length; - UTF8Character() : buffer( 0 ), length( 0 ){ - } - UTF8Character( const char* bytes ) : buffer( bytes ), length( utf8_character_length( bytes ) ){ - } -}; - -inline bool operator<( const UTF8Character& self, const UTF8Character& other ){ - return std::lexicographical_compare( self.buffer, self.buffer + self.length, other.buffer, other.buffer + other.length ); -} - -/// \brief Writes \p c to \p ostream in Hex form. Useful for debugging. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const UTF8Character& c ){ - for ( const char* p = c.buffer; p != c.buffer + c.length; ++p ) - { - ostream << HexChar( *p ); - } - return ostream; -} - - - -/// \brief The character-set encoding for the current C locale. -/// -/// Obtain the global instance with globalCharacterSet(). -class CharacterSet -{ -const char* m_charSet; -public: -CharacterSet(){ - if ( g_get_charset( &m_charSet ) != FALSE ) { - m_charSet = 0; - } -} -bool isUTF8() const { - return m_charSet == 0; -} -const char* get() const { - return m_charSet; -} -}; - -typedef LazyStatic GlobalCharacterSet; - -/// \brief Returns the global instance of CharacterSet. -inline CharacterSet& globalCharacterSet(){ - return GlobalCharacterSet::instance(); -} - - -class UTF8CharacterToExtendedASCII -{ -public: -UTF8Character m_utf8; -char m_c; -UTF8CharacterToExtendedASCII() : m_c( '\0' ){ -} -UTF8CharacterToExtendedASCII( const UTF8Character& utf8, char c ) : m_utf8( utf8 ), m_c( c ){ -} -}; - -inline bool operator<( const UTF8CharacterToExtendedASCII& self, const UTF8CharacterToExtendedASCII& other ){ - return self.m_utf8 < other.m_utf8; -} - -inline std::size_t extended_ascii_to_index( char c ){ - return static_cast( c & 0x7F ); -} - -inline char extended_ascii_for_index( std::size_t i ){ - return static_cast( i | 0x80 ); -} - -/// \brief The active extended-ascii character set encoding. -/// Performs UTF-8 encoding and decoding of extended-ascii characters. -/// -/// Obtain the global instance with globalExtendedASCIICharacterSet(). -class ExtendedASCIICharacterSet -{ -typedef char UTF8CharBuffer[6]; -UTF8CharBuffer m_converted[128]; -UTF8Character m_decodeMap[128]; -UTF8CharacterToExtendedASCII m_encodeMap[128]; -public: -ExtendedASCIICharacterSet(){ - if ( !globalCharacterSet().isUTF8() ) { - GIConv descriptor = g_iconv_open( "UTF-8", globalCharacterSet().get() ); - for ( std::size_t i = 1; i < 128; ++i ) - { - char c = extended_ascii_for_index( i ); - char* inbuf = &c; - gsize inbytesleft = 1; - char* outbuf = m_converted[i]; - gsize outbytesleft = 6; - if ( g_iconv( descriptor, &inbuf, &inbytesleft, &outbuf, &outbytesleft ) != (size_t)( -1 ) ) { - UTF8Character utf8( m_converted[i] ); - m_decodeMap[i] = utf8; - m_encodeMap[i] = UTF8CharacterToExtendedASCII( utf8, c ); - } - } - g_iconv_close( descriptor ); - std::sort( m_encodeMap, m_encodeMap + 128 ); - } -} -/// \brief Prints the (up to) 128 characters in the current extended-ascii character set. -/// Useful for debugging. -void print() const { - globalOutputStream() << "UTF-8 conversion required from charset: " << globalCharacterSet().get() << "\n"; - for ( std::size_t i = 1; i < 128; ++i ) - { - if ( m_decodeMap[i].buffer != 0 ) { - globalOutputStream() << extended_ascii_for_index( i ) << " = " << m_decodeMap[i] << "\n"; - } - } -} -/// \brief Returns \p c decoded from extended-ascii to UTF-8. -/// \p c must be an extended-ascii character. -const UTF8Character& decode( char c ) const { - ASSERT_MESSAGE( !globalCharacterSet().isUTF8(), "locale is utf8, no conversion required" ); - ASSERT_MESSAGE( !char_is_ascii( c ), "decode: ascii character" ); - ASSERT_MESSAGE( m_decodeMap[extended_ascii_to_index( c )].buffer != 0, "decode: invalid character: " << HexChar( c ) ); - return m_decodeMap[extended_ascii_to_index( c )]; -} -/// \brief Returns \p c encoded to extended-ascii from UTF-8. -/// \p c must map to an extended-ascii character. -char encode( const UTF8Character& c ) const { - ASSERT_MESSAGE( !globalCharacterSet().isUTF8(), "locale is utf8, no conversion required" ); - ASSERT_MESSAGE( !char_is_ascii( *c.buffer ), "encode: ascii character" ); - std::pair range - = std::equal_range( m_encodeMap, m_encodeMap + 128, UTF8CharacterToExtendedASCII( c, 0 ) ); - ASSERT_MESSAGE( range.first != range.second, "encode: invalid character: " << c ); - return ( *range.first ).m_c; -} -}; - -typedef LazyStatic GlobalExtendedASCIICharacterSet; - -/// \brief Returns the global instance of ExtendedASCIICharacterSet. -inline ExtendedASCIICharacterSet& globalExtendedASCIICharacterSet(){ - return GlobalExtendedASCIICharacterSet::instance(); -} - -class ConvertUTF8ToLocale -{ -public: -StringRange m_range; -ConvertUTF8ToLocale( const char* string ) : m_range( StringRange( string, string + strlen( string ) ) ){ -} -ConvertUTF8ToLocale( const StringRange& range ) : m_range( range ){ -} -}; - -/// \brief Writes \p convert to \p ostream after encoding each character to extended-ascii from UTF-8. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const ConvertUTF8ToLocale& convert ){ - if ( globalCharacterSet().isUTF8() ) { - return ostream << convert.m_range; - } - - for ( const char* p = convert.m_range.first; p != convert.m_range.last; ) - { - if ( !char_is_ascii( *p ) ) { - UTF8Character c( p ); - ostream << globalExtendedASCIICharacterSet().encode( c ); - p += c.length; - } - else - { - ostream << *p++; - } - } - return ostream; -} - - -class ConvertLocaleToUTF8 -{ -public: -StringRange m_range; -ConvertLocaleToUTF8( const char* string ) : m_range( StringRange( string, string + strlen( string ) ) ){ -} -ConvertLocaleToUTF8( const StringRange& range ) : m_range( range ){ -} -}; - -/// \brief Writes \p convert to \p ostream after decoding each character from extended-ascii to UTF-8. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const ConvertLocaleToUTF8& convert ){ - if ( globalCharacterSet().isUTF8() ) { - return ostream << convert.m_range; - } - - for ( const char* p = convert.m_range.first; p != convert.m_range.last; ++p ) - { - if ( !char_is_ascii( *p ) ) { - UTF8Character c( globalExtendedASCIICharacterSet().decode( *p ) ); - ostream.write( c.buffer, c.length ); - } - else - { - ostream << *p; - } - } - return ostream; -} - - -#endif diff --git a/libs/debugging/Makefile b/libs/debugging/Makefile deleted file mode 100644 index cf3e127..0000000 --- a/libs/debugging/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - debugging.o - -# binary target -../libdebugging.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -debugging.o: debugging.cpp debugging.h - -clean: - -rm -f *.o ../libdebugging.a diff --git a/libs/debugging/debugging.cpp b/libs/debugging/debugging.cpp deleted file mode 100644 index b292840..0000000 --- a/libs/debugging/debugging.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "debugging.h" - -void TEST_ASSERT(){ - ERROR_MESSAGE( "test" ); - ASSERT_NOTNULL( 0 ); -} diff --git a/libs/debugging/debugging.h b/libs/debugging/debugging.h deleted file mode 100644 index 405131d..0000000 --- a/libs/debugging/debugging.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_DEBUGGING_DEBUGGING_H ) -#define INCLUDED_DEBUGGING_DEBUGGING_H - -/// \file -/// \brief Debugging macros for fatal error/assert messages. - -#include "globaldefs.h" -#include "stream/textstream.h" -#include "warnings.h" -#include "generic/static.h" - -#if GDEF_COMPILER_MSVC && ( defined( _M_IX86 ) || defined( _M_AMD64 ) ) -#define DEBUGGER_BREAKPOINT() __asm { int 3 } -#elif GDEF_COMPILER_GNU && __GNUC__ >= 2 && ( defined ( __i386__ ) || defined ( __x86_64__ ) ) -#define DEBUGGER_BREAKPOINT() __asm__ __volatile__ ( "int $03" ) -#else -#include - -#define DEBUGGER_BREAKPOINT() raise( SIGTRAP ); -#endif - -#define STR( x ) #x -#define STR2( x ) STR( x ) -#define FILE_LINE __FILE__ ":" STR2( __LINE__ ) - -#define DEBUG_ASSERTS - -class DebugMessageHandler -{ -public: -virtual TextOutputStream& getOutputStream() = 0; -virtual bool handleMessage() = 0; -}; - -class NullDebugMessageHandler : public NullOutputStream, public DebugMessageHandler -{ -public: -virtual TextOutputStream& getOutputStream(){ - return *this; -} -virtual bool handleMessage(){ - return false; -} -}; - -class DefaultDebugMessageHandler : public DebugMessageHandler -{ -public: -virtual TextOutputStream& getOutputStream(){ - return globalErrorStream(); -} -virtual bool handleMessage(){ -#if GDEF_DEBUG - return false; // send debug-break -#else - return true; -#endif -} -}; - -class DebugMessageHandlerRef : public DefaultDebugMessageHandler -{ -DebugMessageHandler* m_handler; -public: -DebugMessageHandlerRef() - : m_handler( this ){ -} -void setHandler( DebugMessageHandler& handler ){ - m_handler = &handler; -} -DebugMessageHandler& getHandler(){ - return *m_handler; -} -}; - -typedef Static GlobalDebugMessageHandler; - -inline DebugMessageHandler& globalDebugMessageHandler(){ - return GlobalDebugMessageHandler::instance().getHandler(); -} - -#if defined( DEBUG_ASSERTS ) - -/// \brief Sends a \p message to the current debug-message-handler text-output-stream if \p condition evaluates to false. -#define ASSERT_MESSAGE( condition, message ) do { \ - if ( !( condition ) ) \ - { \ - globalDebugMessageHandler().getOutputStream() << FILE_LINE "\nassertion failure: " << message << "\n"; \ - if ( !globalDebugMessageHandler().handleMessage() ) { DEBUGGER_BREAKPOINT(); } \ - }} while ( 0 ) - -/// \brief Sends a \p message to the current debug-message-handler text-output-stream. -#define ERROR_MESSAGE( message ) do { \ - globalDebugMessageHandler().getOutputStream() << FILE_LINE "\nruntime error: " << message << "\n"; \ - if ( !globalDebugMessageHandler().handleMessage() ) { DEBUGGER_BREAKPOINT(); }} while ( 0 ) - -#define ASSERT_NOTNULL( ptr ) ASSERT_MESSAGE( ptr != 0, "pointer \"" #ptr "\" is null" ) -#define ASSERT_TRUE( flag ) ASSERT_MESSAGE( !!(flag) == true, "condition \"" #flag "\" is false" ) - -#else - -#define ASSERT_MESSAGE( condition, message ) -#define ERROR_MESSAGE( message ) -#define ASSERT_NOTNULL( ptr ) - -#endif - -#endif diff --git a/libs/dragplanes.h b/libs/dragplanes.h deleted file mode 100644 index 0988b31..0000000 --- a/libs/dragplanes.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_DRAGPLANES_H ) -#define INCLUDED_DRAGPLANES_H - -#include "selectable.h" -#include "selectionlib.h" -#include "math/aabb.h" -#include "math/line.h" - -// local must be a pure rotation -inline Vector3 translation_to_local( const Vector3& translation, const Matrix4& local ){ - return matrix4_get_translation_vec3( - matrix4_multiplied_by_matrix4( - matrix4_translated_by_vec3( matrix4_transposed( local ), translation ), - local - ) - ); -} - -// local must be a pure rotation -inline Vector3 translation_from_local( const Vector3& translation, const Matrix4& local ){ - return matrix4_get_translation_vec3( - matrix4_multiplied_by_matrix4( - matrix4_translated_by_vec3( local, translation ), - matrix4_transposed( local ) - ) - ); -} - -class DragPlanes -{ -public: -ObservedSelectable m_selectable_right; // +x -ObservedSelectable m_selectable_left; // -x -ObservedSelectable m_selectable_front; // +y -ObservedSelectable m_selectable_back; // -y -ObservedSelectable m_selectable_top; // +z -ObservedSelectable m_selectable_bottom; // -z -AABB m_bounds; - -DragPlanes( const SelectionChangeCallback& onchanged ) : - m_selectable_right( onchanged ), - m_selectable_left( onchanged ), - m_selectable_front( onchanged ), - m_selectable_back( onchanged ), - m_selectable_top( onchanged ), - m_selectable_bottom( onchanged ){ -} -bool isSelected() const { - return m_selectable_right.isSelected() - || m_selectable_left.isSelected() - || m_selectable_front.isSelected() - || m_selectable_back.isSelected() - || m_selectable_top.isSelected() - || m_selectable_bottom.isSelected(); -} -void setSelected( bool selected ){ - m_selectable_right.setSelected( selected ); - m_selectable_left.setSelected( selected ); - m_selectable_front.setSelected( selected ); - m_selectable_back.setSelected( selected ); - m_selectable_top.setSelected( selected ); - m_selectable_bottom.setSelected( selected ); -} -void selectPlanes( const AABB& aabb, Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback, const Matrix4& rotation = g_matrix4_identity ){ - Line line( test.getNear(), test.getFar() ); - Vector3 corners[8]; - aabb_corners_oriented( aabb, rotation, corners ); - - Plane3 planes[6]; - aabb_planes_oriented( aabb, rotation, planes ); - - for ( Vector3* i = corners; i != corners + 8; ++i ) - { - *i = vector3_subtracted( line_closest_point( line, *i ), *i ); - } - - if ( vector3_dot( planes[0].normal(), corners[1] ) > 0 - && vector3_dot( planes[0].normal(), corners[2] ) > 0 - && vector3_dot( planes[0].normal(), corners[5] ) > 0 - && vector3_dot( planes[0].normal(), corners[6] ) > 0 ) { - Selector_add( selector, m_selectable_right ); - selectedPlaneCallback( planes[0] ); - //globalOutputStream() << "right\n"; - } - if ( vector3_dot( planes[1].normal(), corners[0] ) > 0 - && vector3_dot( planes[1].normal(), corners[3] ) > 0 - && vector3_dot( planes[1].normal(), corners[4] ) > 0 - && vector3_dot( planes[1].normal(), corners[7] ) > 0 ) { - Selector_add( selector, m_selectable_left ); - selectedPlaneCallback( planes[1] ); - //globalOutputStream() << "left\n"; - } - if ( vector3_dot( planes[2].normal(), corners[0] ) > 0 - && vector3_dot( planes[2].normal(), corners[1] ) > 0 - && vector3_dot( planes[2].normal(), corners[4] ) > 0 - && vector3_dot( planes[2].normal(), corners[5] ) > 0 ) { - Selector_add( selector, m_selectable_front ); - selectedPlaneCallback( planes[2] ); - //globalOutputStream() << "front\n"; - } - if ( vector3_dot( planes[3].normal(), corners[2] ) > 0 - && vector3_dot( planes[3].normal(), corners[3] ) > 0 - && vector3_dot( planes[3].normal(), corners[6] ) > 0 - && vector3_dot( planes[3].normal(), corners[7] ) > 0 ) { - Selector_add( selector, m_selectable_back ); - selectedPlaneCallback( planes[3] ); - //globalOutputStream() << "back\n"; - } - if ( vector3_dot( planes[4].normal(), corners[0] ) > 0 - && vector3_dot( planes[4].normal(), corners[1] ) > 0 - && vector3_dot( planes[4].normal(), corners[2] ) > 0 - && vector3_dot( planes[4].normal(), corners[3] ) > 0 ) { - Selector_add( selector, m_selectable_top ); - selectedPlaneCallback( planes[4] ); - //globalOutputStream() << "top\n"; - } - if ( vector3_dot( planes[5].normal(), corners[4] ) > 0 - && vector3_dot( planes[5].normal(), corners[5] ) > 0 - && vector3_dot( planes[5].normal(), corners[6] ) > 0 - && vector3_dot( planes[5].normal(), corners[7] ) > 0 ) { - Selector_add( selector, m_selectable_bottom ); - selectedPlaneCallback( planes[5] ); - //globalOutputStream() << "bottom\n"; - } - - m_bounds = aabb; -} -void selectReversedPlanes( const AABB& aabb, Selector& selector, const SelectedPlanes& selectedPlanes, const Matrix4& rotation = g_matrix4_identity ){ - Plane3 planes[6]; - aabb_planes_oriented( aabb, rotation, planes ); - - if ( selectedPlanes.contains( plane3_flipped( planes[0] ) ) ) { - Selector_add( selector, m_selectable_right ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[1] ) ) ) { - Selector_add( selector, m_selectable_left ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[2] ) ) ) { - Selector_add( selector, m_selectable_front ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[3] ) ) ) { - Selector_add( selector, m_selectable_back ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[4] ) ) ) { - Selector_add( selector, m_selectable_top ); - } - if ( selectedPlanes.contains( plane3_flipped( planes[5] ) ) ) { - Selector_add( selector, m_selectable_bottom ); - } -} -AABB evaluateResize( const Vector3& translation ) const { - Vector3 min = m_bounds.origin - m_bounds.extents; - Vector3 max = m_bounds.origin + m_bounds.extents; - if ( m_bounds.extents[0] != 0 ) { - if ( m_selectable_right.isSelected() ) { - max[0] += translation[0]; - //globalOutputStream() << "moving right\n"; - } - if ( m_selectable_left.isSelected() ) { - min[0] += translation[0]; - //globalOutputStream() << "moving left\n"; - } - } - if ( m_bounds.extents[1] != 0 ) { - if ( m_selectable_front.isSelected() ) { - max[1] += translation[1]; - //globalOutputStream() << "moving front\n"; - } - if ( m_selectable_back.isSelected() ) { - min[1] += translation[1]; - //globalOutputStream() << "moving back\n"; - } - } - if ( m_bounds.extents[2] != 0 ) { - if ( m_selectable_top.isSelected() ) { - max[2] += translation[2]; - //globalOutputStream() << "moving top\n"; - } - if ( m_selectable_bottom.isSelected() ) { - min[2] += translation[2]; - //globalOutputStream() << "moving bottom\n"; - } - } - - return AABB( vector3_mid( min, max ), vector3_scaled( vector3_subtracted( max, min ), 0.5 ) ); -} -AABB evaluateResize( const Vector3& translation, const Matrix4& rotation ) const { - AABB aabb( evaluateResize( translation_to_local( translation, rotation ) ) ); - aabb.origin = m_bounds.origin + translation_from_local( aabb.origin - m_bounds.origin, rotation ); - return aabb; -} -Matrix4 evaluateTransform( const Vector3& translation ) const { - AABB aabb( evaluateResize( translation ) ); - Vector3 scale( - m_bounds.extents[0] != 0 ? aabb.extents[0] / m_bounds.extents[0] : 1, - m_bounds.extents[1] != 0 ? aabb.extents[1] / m_bounds.extents[1] : 1, - m_bounds.extents[2] != 0 ? aabb.extents[2] / m_bounds.extents[2] : 1 - ); - - Matrix4 matrix( matrix4_translation_for_vec3( aabb.origin - m_bounds.origin ) ); - matrix4_pivoted_scale_by_vec3( matrix, scale, m_bounds.origin ); - - return matrix; -} -}; - -#endif diff --git a/libs/eclasslib.h b/libs/eclasslib.h deleted file mode 100644 index 2a92fcd..0000000 --- a/libs/eclasslib.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_ECLASSLIB_H ) -#define INCLUDED_ECLASSLIB_H - -#include -#include -#include -#include -#include - -#include "ieclass.h" -#include "irender.h" - -#include "math/vector.h" -#include "string/string.h" - -typedef Vector3 Colour3; - -class ListAttributeType -{ -using ListItem = std::pair; -using ListItems = std::vector; -ListItems m_items; -public: - -typedef ListItems::const_iterator const_iterator; -const_iterator begin() const { - return m_items.begin(); -} -const_iterator end() const { - return m_items.end(); -} - -const ListItem& operator[]( std::size_t i ) const { - return m_items[i]; -} -const_iterator findValue( const char* value ) const { - for ( ListItems::const_iterator i = m_items.begin(); i != m_items.end(); ++i ) - { - if ( string_equal( value, ( *i ).second.c_str() ) ) { - return i; - } - } - return m_items.end(); -} - -void push_back( const char* name, const char* value ){ - m_items.push_back( ListItems::value_type( name, value ) ); -} -}; - -class EntityClassAttribute -{ -public: -CopiedString m_type; -CopiedString m_name; -CopiedString m_value; -CopiedString m_description; -EntityClassAttribute(){ -} -EntityClassAttribute( const char* type, const char* name, const char* value = "", const char* description = "" ) : m_type( type ), m_name( name ), m_value( value ), m_description( description ){ -} -}; - -typedef std::pair EntityClassAttributePair; -typedef std::list EntityClassAttributes; -typedef std::list StringList; - -inline const char* EntityClassAttributePair_getName( const EntityClassAttributePair& attributePair ){ - if ( !string_empty( attributePair.second.m_name.c_str() ) ) { - return attributePair.second.m_name.c_str(); - } - return attributePair.first.c_str(); -} - -inline const char* EntityClassAttributePair_getDescription( const EntityClassAttributePair& attributePair ){ - if ( !string_empty( attributePair.second.m_description.c_str() ) ) { - return attributePair.second.m_description.c_str(); - } - return EntityClassAttributePair_getName( attributePair ); -} - -class EntityClass -{ -public: -CopiedString m_name; -StringList m_parent; -bool fixedsize; -bool unknown; // wasn't found in source -Vector3 mins; -Vector3 maxs; - -Colour3 color; -Shader* m_state_fill; -Shader* m_state_wire; -Shader* m_state_blend; - -CopiedString m_comments; -char flagnames[MAX_FLAGS][32]; - -CopiedString m_modelpath; -CopiedString m_skin; - -void ( *free )( EntityClass* ); - -EntityClassAttributes m_attributes; - -bool inheritanceResolved; -bool sizeSpecified; -bool colorSpecified; - -const char* name() const { - return m_name.c_str(); -} -const char* comments() const { - return m_comments.c_str(); -} -const char* modelpath() const { - return m_modelpath.c_str(); -} -const char* skin() const { - return m_skin.c_str(); -} -}; - -inline const char* EntityClass_valueForKey( const EntityClass& entityClass, const char* key ){ - for ( EntityClassAttributes::const_iterator i = entityClass.m_attributes.begin(); i != entityClass.m_attributes.end(); ++i ) - { - if ( string_equal( key, ( *i ).first.c_str() ) ) { - return ( *i ).second.m_value.c_str(); - } - } - return ""; -} - -inline EntityClassAttributePair& EntityClass_insertAttribute( EntityClass& entityClass, const char* key, const EntityClassAttribute& attribute = EntityClassAttribute() ){ - entityClass.m_attributes.push_back( EntityClassAttributePair( key, attribute ) ); - return entityClass.m_attributes.back(); -} - - -inline void buffer_write_colour_fill( char buffer[128], const Colour3& colour ){ - sprintf( buffer, "(%g %g %g)", colour[0], colour[1], colour[2] ); -} - -inline void buffer_write_colour_wire( char buffer[128], const Colour3& colour ){ - sprintf( buffer, "<%g %g %g>", colour[0], colour[1], colour[2] ); -} - -inline void buffer_write_colour_blend( char buffer[128], const Colour3& colour ){ - sprintf( buffer, "[%g %g %g]", colour[0], colour[1], colour[2] ); -} - -inline Shader* colour_capture_state_fill( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_fill( buffer, colour ); - return GlobalShaderCache().capture( buffer ); -} - -inline void colour_release_state_fill( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_fill( buffer, colour ); - GlobalShaderCache().release( buffer ); -} - -inline Shader* colour_capture_state_wire( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_wire( buffer, colour ); - return GlobalShaderCache().capture( buffer ); -} - -inline void colour_release_state_wire( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_wire( buffer, colour ); - GlobalShaderCache().release( buffer ); -} - -inline Shader* colour_capture_state_blend( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_blend( buffer, colour ); - return GlobalShaderCache().capture( buffer ); -} - -inline void colour_release_state_blend( const Colour3& colour ){ - char buffer[128]; - buffer_write_colour_blend( buffer, colour ); - GlobalShaderCache().release( buffer ); -} - -inline void eclass_capture_state( EntityClass* eclass ){ - eclass->m_state_fill = colour_capture_state_fill( eclass->color ); - eclass->m_state_wire = colour_capture_state_wire( eclass->color ); - eclass->m_state_blend = colour_capture_state_blend( eclass->color ); -} - -inline void eclass_release_state( EntityClass* eclass ){ - colour_release_state_fill( eclass->color ); - colour_release_state_wire( eclass->color ); - colour_release_state_blend( eclass->color ); -} - -// eclass constructor -inline EntityClass* Eclass_Alloc(){ - EntityClass* e = new EntityClass; - - e->fixedsize = false; - e->unknown = false; - memset( e->flagnames, 0, MAX_FLAGS * 32 ); - - e->maxs = Vector3( -1,-1,-1 ); - e->mins = Vector3( 1, 1, 1 ); - - e->free = 0; - - e->inheritanceResolved = true; - e->sizeSpecified = false; - e->colorSpecified = false; - - return e; -} - -// eclass destructor -inline void Eclass_Free( EntityClass* e ){ - eclass_release_state( e ); - - delete e; -} - -inline bool classname_equal( const char* classname, const char* other ){ - return string_equal( classname, other ); -} - -inline EntityClass* EClass_Create( const char* name, const Vector3& colour, const char* comments ){ - EntityClass *e = Eclass_Alloc(); - e->free = &Eclass_Free; - - e->m_name = name; - - e->color = colour; - eclass_capture_state( e ); - - if ( comments ) { - e->m_comments = comments; - } - - return e; -} - -inline EntityClass* EClass_Create_FixedSize( const char* name, const Vector3& colour, const Vector3& mins, const Vector3& maxs, const char* comments ){ - EntityClass *e = Eclass_Alloc(); - e->free = &Eclass_Free; - - e->m_name = name; - - e->color = colour; - eclass_capture_state( e ); - - e->fixedsize = true; - - e->mins = mins; - e->maxs = maxs; - - if ( comments ) { - e->m_comments = comments; - } - - return e; -} - -const Vector3 smallbox[2] = { - Vector3( -8,-8,-8 ), - Vector3( 8, 8, 8 ), -}; - -inline EntityClass *EntityClass_Create_Default( const char *name, bool has_brushes ){ - // create a new class for it - if ( has_brushes ) { - return EClass_Create( name, Vector3( 0.0f, 0.5f, 0.0f ), "Not found in source." ); - } - else - { - return EClass_Create_FixedSize( name, Vector3( 0.0f, 0.5f, 0.0f ), smallbox[0], smallbox[1], "Not found in source." ); - } -} - -#endif diff --git a/libs/entitylib.h b/libs/entitylib.h deleted file mode 100644 index 9371397..0000000 --- a/libs/entitylib.h +++ /dev/null @@ -1,718 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_ENTITYLIB_H ) -#define INCLUDED_ENTITYLIB_H - -#include "ireference.h" -#include "debugging/debugging.h" - -#include "ientity.h" -#include "irender.h" -#include "igl.h" -#include "selectable.h" - -#include "generic/callback.h" -#include "math/vector.h" -#include "math/aabb.h" -#include "undolib.h" -#include "string/pooledstring.h" -#include "generic/referencecounted.h" -#include "scenelib.h" -#include "container/container.h" -#include "eclasslib.h" - -#include -#include - -inline void arrow_draw( const Vector3& origin, const Vector3& direction_forward, const Vector3& direction_left, const Vector3& direction_up ){ - Vector3 endpoint( vector3_added( origin, vector3_scaled( direction_forward, 32.0 ) ) ); - - Vector3 tip1( vector3_added( vector3_added( endpoint, vector3_scaled( direction_forward, -8.0 ) ), vector3_scaled( direction_up, -4.0 ) ) ); - Vector3 tip2( vector3_added( tip1, vector3_scaled( direction_up, 8.0 ) ) ); - Vector3 tip3( vector3_added( vector3_added( endpoint, vector3_scaled( direction_forward, -8.0 ) ), vector3_scaled( direction_left, -4.0 ) ) ); - Vector3 tip4( vector3_added( tip3, vector3_scaled( direction_left, 8.0 ) ) ); - - glBegin( GL_LINES ); - - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( endpoint ) ); - - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip1 ) ); - - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip2 ) ); - - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip3 ) ); - - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip4 ) ); - - glVertex3fv( vector3_to_array( tip1 ) ); - glVertex3fv( vector3_to_array( tip3 ) ); - - glVertex3fv( vector3_to_array( tip3 ) ); - glVertex3fv( vector3_to_array( tip2 ) ); - - glVertex3fv( vector3_to_array( tip2 ) ); - glVertex3fv( vector3_to_array( tip4 ) ); - - glVertex3fv( vector3_to_array( tip4 ) ); - glVertex3fv( vector3_to_array( tip1 ) ); - - glEnd(); -} - -class SelectionIntersection; - -inline void aabb_testselect( const AABB& aabb, SelectionTest& test, SelectionIntersection& best ){ - const IndexPointer::index_type indices[24] = { - 2, 1, 5, 6, - 1, 0, 4, 5, - 0, 1, 2, 3, - 3, 7, 4, 0, - 3, 2, 6, 7, - 7, 6, 5, 4, - }; - - Vector3 points[8]; - aabb_corners( aabb, points ); - test.TestQuads( VertexPointer( reinterpret_cast( points ), sizeof( Vector3 ) ), IndexPointer( indices, 24 ), best ); -} - -inline void aabb_draw_wire( const Vector3 points[8] ){ - unsigned int indices[26] = { - 0, 1, 1, 2, 2, 3, 3, 0, - 4, 5, 5, 6, 6, 7, 7, 4, - 0, 4, 1, 5, 2, 6, 3, 7, - // 0, 6, 1, 7, 2, 4, 3, 5 // X cross - 1, 7 // diagonal line (connect mins to maxs corner) - }; -#if 1 - glVertexPointer( 3, GL_FLOAT, 0, points ); - glDrawElements( GL_LINES, sizeof( indices ) / sizeof( indices[0] ), GL_UNSIGNED_INT, indices ); -#else - glBegin( GL_LINES ); - for ( std::size_t i = 0; i < sizeof( indices ) / sizeof( indices[0] ); ++i ) - { - glVertex3fv( points[indices[i]] ); - } - glEnd(); -#endif -} - -inline void aabb_draw_flatshade( const Vector3 points[8] ){ - glBegin( GL_QUADS ); - - glNormal3fv( vector3_to_array( aabb_normals[0] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); - glVertex3fv( vector3_to_array( points[6] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[1] ) ); - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[2] ) ); - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[3] ) ); - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); - glVertex3fv( vector3_to_array( points[7] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[4] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( points[6] ) ); - glVertex3fv( vector3_to_array( points[7] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[5] ) ); - glVertex3fv( vector3_to_array( points[7] ) ); - glVertex3fv( vector3_to_array( points[6] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); - - glEnd(); -} - -inline void aabb_draw_wire( const AABB& aabb ){ - Vector3 points[8]; - aabb_corners( aabb, points ); - aabb_draw_wire( points ); -} - -inline void aabb_draw_flatshade( const AABB& aabb ){ - Vector3 points[8]; - aabb_corners( aabb, points ); - aabb_draw_flatshade( points ); -} - -inline void aabb_draw_textured( const AABB& aabb ){ - Vector3 points[8]; - aabb_corners( aabb, points ); - - glBegin( GL_QUADS ); - - glNormal3fv( vector3_to_array( aabb_normals[0] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[2] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[1] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[5] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[6] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[1] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[1] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[0] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[4] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[5] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[2] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[0] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[1] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[2] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[3] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[3] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[0] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[3] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[7] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[4] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[4] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[3] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[2] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[6] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[7] ) ); - - glNormal3fv( vector3_to_array( aabb_normals[5] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[7] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[6] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[5] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[4] ) ); - - glEnd(); -} - -inline void aabb_draw_solid( const AABB& aabb, RenderStateFlags state ){ - if ( state & RENDER_TEXTURE ) { - aabb_draw_textured( aabb ); - } - else - { - aabb_draw_flatshade( aabb ); - } -} - -inline void aabb_draw( const AABB& aabb, RenderStateFlags state ){ - if ( state & RENDER_FILL ) { - aabb_draw_solid( aabb, state ); - } - else - { - aabb_draw_wire( aabb ); - } -} - -class RenderableSolidAABB : public OpenGLRenderable -{ -const AABB& m_aabb; -public: -RenderableSolidAABB( const AABB& aabb ) : m_aabb( aabb ){ -} -void render( RenderStateFlags state ) const { - aabb_draw_solid( m_aabb, state ); -} -}; - -class RenderableWireframeAABB : public OpenGLRenderable -{ -const AABB& m_aabb; -public: -RenderableWireframeAABB( const AABB& aabb ) : m_aabb( aabb ){ -} -void render( RenderStateFlags state ) const { - aabb_draw_wire( m_aabb ); -} -}; - - -/// \brief A key/value pair of strings. -/// -/// - Notifies observers when value changes - value changes to "" on destruction. -/// - Provides undo support through the global undo system. -class KeyValue : public EntityKeyValue -{ -typedef UnsortedSet KeyObservers; - -std::size_t m_refcount; -KeyObservers m_observers; -CopiedString m_string; -const char* m_empty; -ObservedUndoableObject m_undo; -static EntityCreator::KeyValueChangedFunc m_entityKeyValueChanged; -public: - -KeyValue( const char* string, const char* empty ) - : m_refcount( 0 ), m_string( string ), m_empty( empty ), m_undo( m_string, UndoImportCaller( *this ) ){ - notify(); -} -~KeyValue(){ - ASSERT_MESSAGE( m_observers.empty(), "KeyValue::~KeyValue: observers still attached" ); -} - -static void setKeyValueChangedFunc( EntityCreator::KeyValueChangedFunc func ){ - m_entityKeyValueChanged = func; -} - -void IncRef(){ - ++m_refcount; -} -void DecRef(){ - if ( --m_refcount == 0 ) { - delete this; - } -} - -void instanceAttach( MapFile* map ){ - m_undo.instanceAttach( map ); -} -void instanceDetach( MapFile* map ){ - m_undo.instanceDetach( map ); -} - -void attach( const KeyObserver& observer ){ - ( *m_observers.insert ( observer ) )( c_str() ); -} -void detach( const KeyObserver& observer ){ - observer( m_empty ); - m_observers.erase( observer ); -} -const char* c_str() const { - if ( string_empty( m_string.c_str() ) ) { - return m_empty; - } - return m_string.c_str(); -} -void assign( const char* other ){ - if ( !string_equal( m_string.c_str(), other ) ) { - m_undo.save(); - m_string = other; - notify(); - } -} - -void notify(){ - m_entityKeyValueChanged(); - KeyObservers::reverse_iterator i = m_observers.rbegin(); - while ( i != m_observers.rend() ) - { - ( *i++ )( c_str() ); - } -} - -void importState( const CopiedString& string ){ - m_string = string; - - notify(); -} -typedef MemberCaller UndoImportCaller; -}; - -/// \brief An unsorted list of key/value pairs. -/// -/// - Notifies observers when a pair is inserted or removed. -/// - Provides undo support through the global undo system. -/// - New keys are appended to the end of the list. -#include "stream/stringstream.h" -class EntityKeyValues : public Entity -{ -public: -typedef KeyValue Value; - -static StringPool& getPool(){ - return Static::instance(); -} -private: -static EntityCreator::KeyValueChangedFunc m_entityKeyValueChanged; -static Counter* m_counter; - -EntityClass* m_eclass; - -class KeyContext {}; -typedef Static KeyPool; -typedef PooledString Key; -typedef SmartPointer KeyValuePtr; -typedef UnsortedMap KeyValues; -KeyValues m_keyValues; - -typedef UnsortedSet Observers; -Observers m_observers; - -ObservedUndoableObject m_undo; -bool m_instanced; - -bool m_observerMutex; - -void notifyInsert( const char* key, Value& value ){ - m_observerMutex = true; - for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) - { - ( *i )->insert( key, value ); - } - m_observerMutex = false; -} -void notifyErase( const char* key, Value& value ){ - m_observerMutex = true; - for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) - { - ( *i )->erase( key, value ); - } - m_observerMutex = false; -} -void forEachKeyValue_notifyInsert(){ - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - notifyInsert( ( *i ).first.c_str(), *( *i ).second ); - } -} -void forEachKeyValue_notifyErase(){ - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - notifyErase( ( *i ).first.c_str(), *( *i ).second ); - } -} - -void insert( const char* key, const KeyValuePtr& keyValue ){ - KeyValues::iterator i = m_keyValues.insert( KeyValues::value_type( key, keyValue ) ); - notifyInsert( key, *( *i ).second ); - - if ( m_instanced ) { - ( *i ).second->instanceAttach( m_undo.map() ); - } -} - -/* see if our key already exists in here */ -void insert( const char* key, const char* value ){ - int dupecheck = 1; - - if (!strncmp(key, "On", 2)) - dupecheck = 0; - - KeyValues::iterator i = m_keyValues.find( key ); - - /* does the key already exist */ - if (i != m_keyValues.end() ) { - /* re-assign only when we're a special field, else pick a new name */ - if (dupecheck) { - ( *i ).second->assign( value ); - printf("[ENTLIB]: dupe found, setting %s to %s\n", key, value); - } else { - bool b = true; - unsigned int num = 0; - StringOutputStream new_key(64); - - /* loop through and generate an enumerated variant */ - do { - /* keep incrementing num until we find a free slot */ - num++; - new_key.clear(); - new_key << key << "#" << Unsigned(num); - i = m_keyValues.find(new_key.c_str()); - - if (i == m_keyValues.end()) { - insert(new_key.c_str(), value); - b = false; - } - } while (b != false); - } - } - else - { - m_undo.save(); - insert( key, KeyValuePtr( new KeyValue( value, EntityClass_valueForKey( *m_eclass, key ) ) ) ); - printf("[ENTLIB]: inserting key %s = %s\n", key, value); - } -} - -void erase( KeyValues::iterator i ){ - if ( m_instanced ) { - ( *i ).second->instanceDetach( m_undo.map() ); - } - - Key key( ( *i ).first ); - KeyValuePtr value( ( *i ).second ); - m_keyValues.erase( i ); - notifyErase( key.c_str(), *value ); -} - -void erase( const char* key ){ - KeyValues::iterator i = m_keyValues.find( key ); - if ( i != m_keyValues.end() ) { - m_undo.save(); - erase( i ); - } -} - -public: -bool m_isContainer; - -EntityKeyValues( EntityClass* eclass ) : - m_eclass( eclass ), - m_undo( m_keyValues, UndoImportCaller( *this ) ), - m_instanced( false ), - m_observerMutex( false ), - m_isContainer( !eclass->fixedsize ){ -} -EntityKeyValues( const EntityKeyValues& other ) : - Entity( other ), - m_eclass( &other.getEntityClass() ), - m_undo( m_keyValues, UndoImportCaller( *this ) ), - m_instanced( false ), - m_observerMutex( false ), - m_isContainer( other.m_isContainer ){ - for ( KeyValues::const_iterator i = other.m_keyValues.begin(); i != other.m_keyValues.end(); ++i ) - { - insert( ( *i ).first.c_str(), ( *i ).second->c_str() ); - } -} -~EntityKeyValues(){ - for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ) - { - // post-increment to allow current element to be removed safely - ( *i++ )->clear(); - } - ASSERT_MESSAGE( m_observers.empty(), "EntityKeyValues::~EntityKeyValues: observers still attached" ); -} - -static void setKeyValueChangedFunc( EntityCreator::KeyValueChangedFunc func ){ - m_entityKeyValueChanged = func; - KeyValue::setKeyValueChangedFunc( func ); -} -static void setCounter( Counter* counter ){ - m_counter = counter; -} - -void importState( const KeyValues& keyValues ){ - for ( KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ) - { - erase( i++ ); - } - - for ( KeyValues::const_iterator i = keyValues.begin(); i != keyValues.end(); ++i ) - { - insert( ( *i ).first.c_str(), ( *i ).second ); - } - - m_entityKeyValueChanged(); -} -typedef MemberCaller UndoImportCaller; - -void attach( Observer& observer ){ - ASSERT_MESSAGE( !m_observerMutex, "observer cannot be attached during iteration" ); - m_observers.insert( &observer ); - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - observer.insert( ( *i ).first.c_str(), *( *i ).second ); - } -} -void detach( Observer& observer ){ - ASSERT_MESSAGE( !m_observerMutex, "observer cannot be detached during iteration" ); - m_observers.erase( &observer ); - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - observer.erase( ( *i ).first.c_str(), *( *i ).second ); - } -} - -void forEachKeyValue_instanceAttach( MapFile* map ){ - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - ( *i ).second->instanceAttach( map ); - } -} -void forEachKeyValue_instanceDetach( MapFile* map ){ - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - ( *i ).second->instanceDetach( map ); - } -} - -void instanceAttach( MapFile* map ){ - if ( m_counter != 0 ) { - m_counter->increment(); - } - - m_instanced = true; - forEachKeyValue_instanceAttach( map ); - m_undo.instanceAttach( map ); -} -void instanceDetach( MapFile* map ){ - if ( m_counter != 0 ) { - m_counter->decrement(); - } - - m_undo.instanceDetach( map ); - forEachKeyValue_instanceDetach( map ); - m_instanced = false; -} - -// entity -EntityClass& getEntityClass() const { - return *m_eclass; -} -void forEachKeyValue( Visitor& visitor ) const { - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - visitor.visit( ( *i ).first.c_str(), ( *i ).second->c_str() ); - } -} -void setKeyValue( const char* key, const char* value ){ - if ( value[0] == '\0' - /*|| string_equal(EntityClass_valueForKey(*m_eclass, key), value)*/ ) { // don't delete values equal to default - erase( key ); - } - else - { - insert( key, value ); - } - m_entityKeyValueChanged(); -} -const char* getKeyValue( const char* key ) const { - KeyValues::const_iterator i = m_keyValues.find( key ); - if ( i != m_keyValues.end() ) { - return ( *i ).second->c_str(); - } - - return EntityClass_valueForKey( *m_eclass, key ); -} -int getKeyEntries( void ) const { - int i = 0; - - for ( KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) - { - i++; - } -} - -bool isContainer() const { - return m_isContainer; -} -}; - -/// \brief A Resource reference with a controlled lifetime. -/// \brief The resource is released when the ResourceReference is destroyed. -class ResourceReference -{ -CopiedString m_name; -Resource* m_resource; -public: -ResourceReference( const char* name ) - : m_name( name ){ - capture(); -} -ResourceReference( const ResourceReference& other ) - : m_name( other.m_name ){ - capture(); -} -ResourceReference& operator=( const ResourceReference& other ){ - ResourceReference tmp( other ); - tmp.swap( *this ); - return *this; -} -~ResourceReference(){ - release(); -} - -void capture(){ - m_resource = GlobalReferenceCache().capture( m_name.c_str() ); -} -void release(){ - GlobalReferenceCache().release( m_name.c_str() ); -} - -const char* getName() const { - return m_name.c_str(); -} -void setName( const char* name ){ - ResourceReference tmp( name ); - tmp.swap( *this ); -} - -void swap( ResourceReference& other ){ - std::swap( m_resource, other.m_resource ); - std::swap( m_name, other.m_name ); -} - -void attach( ModuleObserver& observer ){ - m_resource->attach( observer ); -} -void detach( ModuleObserver& observer ){ - m_resource->detach( observer ); -} - -Resource* get(){ - return m_resource; -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -inline void swap( ResourceReference& self, ResourceReference& other ){ - self.swap( other ); -} -} - -#endif diff --git a/libs/entityxml.h b/libs/entityxml.h deleted file mode 100644 index 89a9406..0000000 --- a/libs/entityxml.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ENTITYXML_H ) -#define INCLUDED_ENTITYXML_H - -#include "ientity.h" -#include "xml/ixml.h" -#include "xml/xmlelement.h" - -class entity_import : public XMLImporter -{ -Entity& m_entity; -public: -entity_import( Entity& entity ) - : m_entity( entity ){ -} -void pushElement( const XMLElement& element ){ - if ( strcmp( element.name(), "epair" ) == 0 ) { - m_entity.setKeyValue( element.attribute( "key" ), element.attribute( "value" ) ); - } -} -void popElement( const char* name ){ -} -std::size_t write( const char* data, std::size_t length ){ - return length; -} -}; - -class entity_export : public XMLExporter -{ -class ExportXMLVisitor : public Entity::Visitor -{ -XMLImporter& m_importer; -public: -ExportXMLVisitor( XMLImporter& importer ) : m_importer( importer ){ -} -void visit( const char* key, const char* value ){ - StaticElement element( "epair" ); - element.insertAttribute( "key", key ); - element.insertAttribute( "value", value ); - m_importer.pushElement( element ); - m_importer.popElement( element.name() ); -} -}; - -const Entity& m_entity; - -public: -entity_export( const Entity& entity ) : m_entity( entity ){ -} -void exportXML( XMLImporter& observer ){ - ExportXMLVisitor visitor( observer ); - - m_entity.forEachKeyValue( visitor ); -} -}; - -inline void entity_copy( Entity& entity, const Entity& other ){ - entity_export exporter( other ); - entity_import importer( entity ); - exporter.exportXML( importer ); -} - -template -class EntityConstruction -{ -public: -typedef EntityClass* type; -static type get( const EntityType& entity ){ - return &entity.getEntity().getEntityClass(); -} -static void copy( EntityType& entity, const EntityType& other ){ - entity_copy( entity.getEntity(), other.getEntity() ); -} -}; - - - -#endif diff --git a/libs/fs_filesystem.h b/libs/fs_filesystem.h deleted file mode 100644 index 5cd42a6..0000000 --- a/libs/fs_filesystem.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_FS_FILESYSTEM_H ) -#define INCLUDED_FS_FILESYSTEM_H - -#include "string/string.h" -#include "os/path.h" - -#include - -inline unsigned int path_get_depth( const char* path ){ - unsigned int depth = 0; - while ( path != 0 && path[0] != '\0' ) - { - path = strchr( path, '/' ); - if ( path != 0 ) { - ++path; - } - ++depth; - } - return depth; -} - -/// \brief A generic unix-style file-system which maps paths to files and directories. -/// Provides average O(log n) find and insert methods. -/// \param file_type The data type which represents a file. -template -class GenericFileSystem -{ -class Path -{ -CopiedString m_path; -unsigned int m_depth; -public: -Path( const char* path ) - : m_path( path ), m_depth( path_get_depth( c_str() ) ){ -} -Path( StringRange range ) - : m_path( range ), m_depth( path_get_depth( c_str() ) ){ -} -bool operator<( const Path& other ) const { - return string_less_nocase( c_str(), other.c_str() ); -} -unsigned int depth() const { - return m_depth; -} -const char* c_str() const { - return m_path.c_str(); -} -}; - -class Entry -{ -file_type* m_file; -public: -Entry() : m_file( 0 ){ -} -Entry( file_type* file ) : m_file( file ){ -} -file_type* file() const { - return m_file; -} -bool is_directory() const { - return file() == 0; -} -}; - -typedef std::map Entries; -Entries m_entries; - -public: -typedef typename Entries::iterator iterator; -typedef typename Entries::value_type value_type; -typedef Entry entry_type; - -iterator begin(){ - return m_entries.begin(); -} -iterator end(){ - return m_entries.end(); -} - -/// \brief Returns the file at \p path. -/// Creates all directories below \p path if they do not exist. -/// O(log n) on average. -entry_type& operator[]( const Path& path ){ - { - const char* end = path_remove_directory( path.c_str() ); - while ( end[0] != '\0' ) - { - Path dir( StringRange( path.c_str(), end ) ); - m_entries.insert( value_type( dir, Entry( 0 ) ) ); - end = path_remove_directory( end ); - } - } - - return m_entries[path]; -} - -/// \brief Returns the file at \p path or end() if not found. -iterator find( const Path& path ){ - return m_entries.find( path ); -} - -iterator begin( const char* root ){ - if ( root[0] == '\0' ) { - return m_entries.begin(); - } - iterator i = m_entries.find( root ); - if ( i == m_entries.end() ) { - return i; - } - return ++i; -} - -/// \brief Performs a depth-first traversal of the file-system subtree rooted at \p root. -/// Traverses the entire tree if \p root is "". -/// Calls \p visitor.file() with the path to each file relative to the filesystem root. -/// Calls \p visitor.directory() with the path to each directory relative to the filesystem root. -template -void traverse( visitor_type visitor, const char* root ){ - unsigned int start_depth = path_get_depth( root ); - unsigned int skip_depth = 0; - for ( iterator i = begin( root ); i != end() && i->first.depth() > start_depth; ++i ) - { - if ( i->first.depth() == skip_depth ) { - skip_depth = 0; - } - if ( skip_depth == 0 ) { - if ( !i->second.is_directory() ) { - visitor.file( i->first.c_str() ); - } - else if ( visitor.directory( i->first.c_str(), i->first.depth() - start_depth ) ) { - skip_depth = i->first.depth(); - } - } - } -} -}; - -#endif diff --git a/libs/fs_path.h b/libs/fs_path.h deleted file mode 100644 index 2baf297..0000000 --- a/libs/fs_path.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_FS_PATH_H ) -#define INCLUDED_FS_PATH_H - -#include "stream/stringstream.h" - -/// \brief A unix-style path string which can be modified at runtime. -/// -/// - Maintains a path ending in a path-separator. -/// - Provides a limited STL-style interface to push and pop file or directory names at the end of the path. -class UnixPath -{ -StringBuffer m_string; - -void check_separator(){ - if ( !empty() && m_string.back() != '/' ) { - m_string.push_back( '/' ); - } -} - -public: -/// \brief Constructs with the directory \p root. -UnixPath( const char* root ) - : m_string( root ){ - check_separator(); -} - -bool empty() const { - return m_string.empty(); -} - -const char* c_str() const { - return m_string.c_str(); -} - -/// \brief Appends the directory \p name. -void push( const char* name ){ - m_string.push_string( name ); - check_separator(); -} -/// \brief Appends the directory [\p first, \p last). -void push( const char* first, const char* last ){ - m_string.push_range( first, last ); - check_separator(); -} -/// \brief Appends the filename \p name. -void push_filename( const char* name ){ - m_string.push_string( name ); -} -/// \brief Removes the last directory or filename appended. -void pop(){ - if ( m_string.back() == '/' ) { - m_string.pop_back(); - } - while ( !empty() && m_string.back() != '/' ) - { - m_string.pop_back(); - } -} -}; - -#endif diff --git a/libs/generic/Makefile b/libs/generic/Makefile deleted file mode 100644 index 45e95c6..0000000 --- a/libs/generic/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - callback.o constant.o object.o static.o - -# binary target -../libgeneric.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -callback.o: callback.cpp callback.h -constant.o: constant.cpp constant.h -object.o: object.cpp object.h -static.o: static.cpp static.h - -clean: - -rm -f *.o ../libgeneric.a diff --git a/libs/generic/arrayrange.h b/libs/generic/arrayrange.h deleted file mode 100644 index e036cf3..0000000 --- a/libs/generic/arrayrange.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_ARRAYRANGE_H ) -#define INCLUDED_GENERIC_ARRAYRANGE_H - -/// \file -/// \brief Macros for automatically converting a compile-time-sized array to a range. - -template -struct ArrayRange -{ - typedef Element* Iterator; - ArrayRange( Iterator first, Iterator last ) - : first( first ), last( last ){ - } - Iterator first; - Iterator last; -}; - -template -inline ArrayRange makeArrayRange( Element* first, Element* last ){ - return ArrayRange( first, last ); -} - -template -struct ArrayConstRange -{ - typedef const Element* Iterator; - ArrayConstRange( Iterator first, Iterator last ) - : first( first ), last( last ){ - } - Iterator first; - Iterator last; -}; - -template -inline ArrayConstRange makeArrayRange( const Element* first, const Element* last ){ - return ArrayConstRange( first, last ); -} - -#define ARRAY_SIZE( array ) ( sizeof( array ) / sizeof( *array ) ) -#define ARRAY_END( array ) ( array + ARRAY_SIZE( array ) ) -#define ARRAY_RANGE( array ) ( makeArrayRange( array, ARRAY_END( array ) ) ) - - -typedef ArrayConstRange StringArrayRange; -#define STRING_ARRAY_RANGE( array ) ( StringArrayRange( array, ARRAY_END( array ) ) ) - -typedef ArrayRange StringRange; - -#endif diff --git a/libs/generic/bitfield.h b/libs/generic/bitfield.h deleted file mode 100644 index f9427aa..0000000 --- a/libs/generic/bitfield.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_BITFIELD_H ) -#define INCLUDED_GENERIC_BITFIELD_H - -/// \file -/// \brief Type safe bitfield. - -/// \brief A bit-field value. -/// -/// - Can be forward-declared when the definition of Enumeration is unknown. -/// - Can only be constructed from valid enumerated values. -/// - Can only be compared and combined with others of the same type. -/// -/// \param Enumeration A type that contains an enum \c Value of the bits that can be set in this field. -template -class BitFieldValue : public Enumeration -{ -unsigned m_value; -protected: -explicit BitFieldValue( unsigned value ) : m_value( value ){ -} -public: -BitFieldValue() : m_value( 0 ){ -} -explicit BitFieldValue( typename Enumeration::Value value ) : m_value( 1 << value ){ -} -unsigned get() const { - return m_value; -} -}; - -template -class BitFieldValueUnsafe : public BitFieldValue -{ -public: -explicit BitFieldValueUnsafe( unsigned value ) : BitFieldValue( value ){ -} -}; - -template -inline bool operator==( BitFieldValue self, BitFieldValue other ){ - return self.get() == other.get(); -} -template -inline bool operator!=( BitFieldValue self, BitFieldValue other ){ - return !operator==( self, other ); -} - -template -inline BitFieldValue operator|( BitFieldValue self, BitFieldValue other ){ - return BitFieldValueUnsafe( self.get() | other.get() ); -} -template -inline BitFieldValue& operator|=( BitFieldValue& self, BitFieldValue other ){ - return self = self | other; -} -template -inline BitFieldValue operator&( BitFieldValue self, BitFieldValue other ){ - return BitFieldValueUnsafe( self.get() & other.get() ); -} -template -inline BitFieldValue& operator&=( BitFieldValue& self, BitFieldValue other ){ - return self = self & other; -} -template -inline BitFieldValue operator~( BitFieldValue self ){ - return BitFieldValueUnsafe( ~self.get() ); -} - - - -inline unsigned int bitfield_enable( unsigned int bitfield, unsigned int mask ){ - return bitfield | mask; -} -inline unsigned int bitfield_disable( unsigned int bitfield, unsigned int mask ){ - return bitfield & ~mask; -} -inline bool bitfield_enabled( unsigned int bitfield, unsigned int mask ){ - return ( bitfield & mask ) != 0; -} - -template -inline BitFieldValue bitfield_enable( BitFieldValue bitfield, BitFieldValue mask ){ - return bitfield | mask; -} -template -inline BitFieldValue bitfield_disable( BitFieldValue bitfield, BitFieldValue mask ){ - return bitfield & ~mask; -} -template -inline bool bitfield_enabled( BitFieldValue bitfield, BitFieldValue mask ){ - return ( bitfield & mask ).get() != 0; -} - -#endif diff --git a/libs/generic/callback.cpp b/libs/generic/callback.cpp deleted file mode 100644 index c6dfeee..0000000 --- a/libs/generic/callback.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "callback.h" -#include "globaldefs.h" - -#if GDEF_DEBUG || defined( DOXYGEN ) - -namespace ExampleMemberCaller -{ -// MemberCaller example -class Integer -{ -public: -int value; - -void printValue() const { - // print this->value here; -} - -void setValue(){ - value = 3; -} -// a typedef to make things more readable -typedef MemberCaller SetValueCaller; -}; - -void example(){ - Integer foo = { 0 }; - - { - Callback bar = ConstMemberCaller( foo ); - - // invoke the callback - bar(); // foo.printValue() - } - - - { - // use the typedef to improve readability - Callback bar = Integer::SetValueCaller( foo ); - - // invoke the callback - bar(); // foo.setValue() - } -} -// end example -} - -namespace ExampleReferenceCaller -{ -// ReferenceCaller example -void Int_printValue( const int& value ){ - // print value here; -} - -void Int_setValue( int& value ){ - value = 3; -} - -// a typedef to make things more readable -typedef ReferenceCaller IntSetValueCaller; - -void example(){ - int foo = 0; - - { - Callback bar = ConstReferenceCaller( foo ); - - // invoke the callback - bar(); // Int_printValue(foo) - } - - - { - // use the typedef to improve readability - Callback bar = IntSetValueCaller( foo ); - - // invoke the callback - bar(); // Int_setValue(foo) - } -} -// end example -} - -#endif - -namespace -{ -class A1 -{ -}; -class A2 -{ -}; -class A3 -{ -}; -class A4 -{ -}; - -class Test -{ -public: -void test0(){ -} -typedef Member Test0; -typedef MemberCaller Test0Caller; -void test0const() const { -} -typedef ConstMember Test0Const; -typedef ConstMemberCaller Test0ConstCaller; -void test1( A1 ){ -} -typedef Member Test1; -typedef MemberCaller Test1Caller; -void test1const( A1 ) const { -} -typedef ConstMember Test1Const; -typedef ConstMemberCaller Test1ConstCaller; -void test2( A1, A2 ){ -} -typedef Member Test2; -void test2const( A1, A2 ) const { -} -typedef ConstMember Test2Const; -void test3( A1, A2, A3 ){ -} -typedef Member Test3; -void test3const( A1, A2, A3 ) const { -} -typedef ConstMember Test3Const; -}; - -void test0free(){ -} -void test1free( A1 ){ -} -void test2free( A1, A2 ){ -} -typedef Function Test2Free; -void test3free( A1, A2, A3 ){ -} -typedef Function Test3Free; - - -void test0( Test& test ){ -} -typedef ReferenceCaller Test0Caller; - -void test0const( const Test& test ){ -} -typedef ConstReferenceCaller Test0ConstCaller; - -void test0p( Test* test ){ -} -typedef PointerCaller Test0PCaller; - -void test0constp( const Test* test ){ -} -typedef ConstPointerCaller Test0ConstPCaller; - -void test1( Test& test, A1 ){ -} -typedef ReferenceCaller Test1Caller; - -void test1const( const Test& test, A1 ){ -} -typedef ConstReferenceCaller Test1ConstCaller; - -void test1p( Test* test, A1 ){ -} -typedef PointerCaller Test1PCaller; - -void test1constp( const Test* test, A1 ){ -} -typedef ConstPointerCaller Test1ConstPCaller; - -void test2( Test& test, A1, A2 ){ -} -typedef Function Test2; - -void test3( Test& test, A1, A2, A3 ){ -} -typedef Function Test3; - -void instantiate(){ - Test test; - const Test& testconst = test; - { - Callback a = makeCallbackF(&test0free); - Callback b = Test::Test0Caller( test ); - b = makeCallback( Test::Test0(), test ); - Callback c = Test::Test0ConstCaller( testconst ); - c = makeCallback( Test::Test0Const(), test ); - Test0Caller{ test }; - Test0ConstCaller{ testconst }; - Test0PCaller{ &test }; - Test0ConstPCaller{ &testconst }; - a(); - bool u = a != b; - } - { - typedef Callback TestCallback1; - TestCallback1 a = makeCallbackF(&test1free); - TestCallback1 b = Test::Test1Caller( test ); - b = makeCallback( Test::Test1(), test ); - TestCallback1 c = Test::Test1ConstCaller( testconst ); - c = makeCallback( Test::Test1Const(), test ); - Test1Caller{ test }; - Test1ConstCaller{ testconst }; - Test1PCaller{ &test }; - Test1ConstPCaller{ &testconst }; - a( A1() ); - bool u = a != b; - } - { - typedef Callback TestCallback2; - TestCallback2 a = makeStatelessCallback( Test2Free() ); - TestCallback2 b = makeCallback( Test2(), test ); - makeCallback( Test::Test2(), test ); - makeCallback( Test::Test2Const(), test ); - a( A1(), A2() ); - bool u = a != b; - } - { - typedef Callback TestCallback3; - TestCallback3 a = makeStatelessCallback( Test3Free() ); - TestCallback3 b = makeCallback( Test3(), test ); - makeCallback( Test::Test3(), test ); - makeCallback( Test::Test3Const(), test ); - a( A1(), A2(), A3() ); - bool u = a != b; - } -} -} diff --git a/libs/generic/callback.h b/libs/generic/callback.h deleted file mode 100644 index 9c16e55..0000000 --- a/libs/generic/callback.h +++ /dev/null @@ -1,349 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_CLOSURE_H ) -#define INCLUDED_GENERIC_CLOSURE_H - -/// \file -/// \brief Type-safe techniques for binding the first argument of an opaque callback. - -#include -#include "functional.h" - -namespace detail { - -template -class CallbackBase { -void *m_environment; -Thunk_ m_thunk; -public: -typedef Thunk_ Thunk; - -CallbackBase(void *environment, Thunk function) : m_environment(environment), m_thunk(function) { -} - -void *getEnvironment() const { - return m_environment; -} - -Thunk getThunk() const { - return m_thunk; -} -}; - -template -inline bool operator==(const CallbackBase &self, const CallbackBase &other) { - return self.getEnvironment() == other.getEnvironment() && self.getThunk() == other.getThunk(); -} - -template -inline bool operator!=(const CallbackBase &self, const CallbackBase &other) { - return !(self == other); -} - -template -inline bool operator<(const CallbackBase &self, const CallbackBase &other) { - return self.getEnvironment() < other.getEnvironment() || - (!(other.getEnvironment() < self.getEnvironment()) && self.getThunk() < other.getThunk()); -} - -} - -namespace detail { - -template -struct ConvertFromOpaque { -}; - -// reference - -template -inline const void *convertToOpaque(const T &t) { - return &t; -} - -template -struct ConvertFromOpaque { - static T const &apply(void *p) { - return *static_cast(p); - } -}; - -template -inline void *convertToOpaque(T &t) { - return &t; -} - -template -struct ConvertFromOpaque { - static T &apply(void *p) { - return *static_cast( p ); - } -}; - -// pointer - -template::value>::type> -inline const void *convertToOpaque(const T *t) { - return t; -} - -template -struct ConvertFromOpaque { - static const T *apply(void *p) { - return static_cast(p); - } -}; - -template::value>::type> -inline void *convertToOpaque(T *t) { - return t; -} - -template -struct ConvertFromOpaque { - static T *apply(void *p) { - return static_cast(p); - } -}; - -// function pointer - -template -inline const void *convertToOpaque(R(*const &t)(Ts ...)) { - return &t; -} - -template -struct ConvertFromOpaque { - using Type = R (*)(Ts...); - - static Type const &apply(void *p) { - return *static_cast(p); - } -}; - -template -inline void *convertToOpaque(R(*&t)(Ts ...)) { - return &t; -} - -template -struct ConvertFromOpaque { - using Type = R (*)(Ts...); - - static Type &apply(void *p) { - return *static_cast(p); - } -}; - -template -class BindFirstOpaqueN; - -template -class BindFirstOpaqueN { -FirstBound firstBound; -public: -explicit BindFirstOpaqueN(FirstBound firstBound) : firstBound(firstBound) { -} - -R operator()(Ts... args) const { - return Caller::call(firstBound, args ...); -} - -FirstBound getBound() const { - return firstBound; -} - -static R thunk(void *environment, Ts... args) { - return thunk_(detail::ConvertFromOpaque::apply(environment), args ...); -} - -static R thunk_(FirstBound environment, Ts... args) { - return Caller::call(environment, args ...); -} - -void *getEnvironment() const { - return const_cast(detail::convertToOpaque(firstBound)); -} -}; - -} - -template -using BindFirstOpaque = detail::BindFirstOpaqueN >; - -/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer. -/// -/// Use with the callback constructors MemberCaller0, ConstMemberCaller0, ReferenceCaller0, ConstReferenceCaller0, PointerCaller0, ConstPointerCaller0 and FreeCaller0. -template -class Callback; - -template -class Callback : public detail::CallbackBase { -using Base = detail::CallbackBase; - -static R nullThunk(void *, Ts...) { -} - -public: -using func = R(Ts ...); - -Callback() : Base(0, nullThunk) { -} - -template -Callback(const BindFirstOpaque &caller) : Base(caller.getEnvironment(), BindFirstOpaque::thunk) { -} - -Callback(void *environment, typename Base::Thunk function) : Base(environment, function) { -} - -R operator()(Ts... args) const { - return Base::getThunk()(Base::getEnvironment(), args ...); -} -}; - -namespace detail { -template -struct Arglist; - -template -struct Arglist { - using type = R(Head, Ts ...); - - template - using unshift = Arglist; - - using shift = Arglist; -}; - -template -struct Arglist { - using type = R(Ts ...); - - template - using unshift = Arglist; -}; - -template -using ArgShift = typename detail::Arglist::shift::type; - -template -using ArgUnshift = typename detail::Arglist::template unshift::type; -} - -template -inline Callback > > makeCallback(const Caller &caller, get_argument callee) { - return BindFirstOpaque(callee); -} - -template -class CallerShiftFirst; - -template -class CallerShiftFirst { -public: -using func = R(FirstArgument, Ts ...); - -static R call(FirstArgument, Ts... args) { - return Caller::call(args ...); -} -}; - -template -inline Callback > makeStatelessCallback(const Caller &caller) { - return makeCallback(CallerShiftFirst, void *> >(), nullptr); -} - -/// \brief Forms a Callback from a non-const Environment reference and a non-const Environment member-function. -template member> -using MemberCaller = BindFirstOpaque >; - -/// \brief Constructs a Callback1 from a non-const \p functor -/// -/// \param Functor Must define \c first_argument_type and \c operator()(first_argument_type). -template -inline Callback > makeCallback(Functor &functor) { - return MemberCaller, &Functor::operator()>(functor); -} - -/// \brief Forms a Callback from a const Environment reference and a const Environment member-function. -template member> -using ConstMemberCaller = BindFirstOpaque >; - -/// \brief Constructs a Callback1 from a const \p functor -/// -/// \param Functor Must define \c first_argument_type and const \c operator()(first_argument_type). -template -inline Callback > makeCallback(const Functor &functor) { - return ConstMemberCaller, &Functor::operator()>(functor); -} - -/// \brief Forms a Callback from a non-const Environment reference and a free function which operates on a non-const Environment reference. -template *func> -using ReferenceCaller = BindFirstOpaque, func> >; - -/// \brief Forms a Callback from a const Environment reference and a free function which operates on a const Environment reference. -template *func> -using ConstReferenceCaller = BindFirstOpaque, func> >; - -/// \brief Forms a Callback from a non-const Environment pointer and a free function which operates on a non-const Environment pointer. -template *func> -using PointerCaller = BindFirstOpaque, func> >; - -/// \brief Forms a Callback from a const Environment pointer and a free function which operates on a const Environment pointer. -template *func> -using ConstPointerCaller = BindFirstOpaque, func> >; - -namespace detail { -template -class FreeCaller : public BindFirstOpaque > > { -public: -FreeCaller() : BindFirstOpaque > >(nullptr) { -} -}; - -template -struct FreeCallerWrapper; - -template -struct FreeCallerWrapper { - using func = R(void *, Ts ...); - - static R call(void *f, Ts... args) { - // ideally, we'd get the implementation of the function type directly. Instead, it's passed in - return reinterpret_cast(f)(args ...); - } -}; -} - -/// \brief Forms a Callback from a free function -template -using FreeCaller = detail::FreeCaller, F>; - -template -inline Callback makeCallbackF(R (*func)(Ts...)) { - void *pVoid = reinterpret_cast(func); - return BindFirstOpaque >(pVoid); -} - -#endif diff --git a/libs/generic/constant.cpp b/libs/generic/constant.cpp deleted file mode 100644 index bcf9b4e..0000000 --- a/libs/generic/constant.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "constant.h" -#include "globaldefs.h" - -#if GDEF_DEBUG || defined( DOXYGEN ) - -namespace ExampleConstant -{ -class Bleh -{ -public: - -STRING_CONSTANT( Name, "Bleh" ); -INTEGER_CONSTANT( Version, 1 ); -}; - -int version = Bleh::Version(); -const char* name = Bleh::Name(); -} - -#endif diff --git a/libs/generic/constant.h b/libs/generic/constant.h deleted file mode 100644 index ab64ec3..0000000 --- a/libs/generic/constant.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_CONSTANT_H ) -#define INCLUDED_GENERIC_CONSTANT_H - -/// \file -/// \brief Language extensions for constants that are guaranteed to be evaluated at compile-time. - -/// \brief A compile-time-constant as a type. -template -struct ConstantWrapper -{ - typedef typename Type::Value Value; - operator Value() const - { - return Type::evaluate(); - } -}; -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const ConstantWrapper& c ){ - return ostream_write( ostream, typename Type::Value( c ) ); -} - -#define TYPE_CONSTANT( name, value, type ) struct name ## _CONSTANT_ { typedef type Value; static Value evaluate() { return value; } }; typedef ConstantWrapper name -#define STRING_CONSTANT( name, value ) TYPE_CONSTANT ( name, value, const char* ) -#define INTEGER_CONSTANT( name, value ) TYPE_CONSTANT ( name, value, int ) -#define UINT_CONSTANT( name, value ) TYPE_CONSTANT ( name, value, unsigned int ) - -STRING_CONSTANT( EmptyString, "" ); - -#endif diff --git a/libs/generic/enumeration.h b/libs/generic/enumeration.h deleted file mode 100644 index 8d6c75e..0000000 --- a/libs/generic/enumeration.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_ENUMERATION_H ) -#define INCLUDED_GENERIC_ENUMERATION_H - -/// \file -/// \brief Type safe enumeration. - -/// \brief An enumerated value. -/// -/// - Can be forward-declared when the definition of Enumeration is unknown. -/// - Can only be constructed from valid enumerated values. -/// - Can only be compared with others of the same type. -/// -/// \param Enumeration A type that contains an enum \c Value of the allowed values of the enumeration. -template -class EnumeratedValue : public Enumeration -{ -typename Enumeration::Value m_value; -public: -explicit EnumeratedValue( typename Enumeration::Value value ) : m_value( value ){ -} -typename Enumeration::Value get() const { - return m_value; -} -}; - -template -inline bool operator==( EnumeratedValue self, EnumeratedValue other ){ - return self.get() == other.get(); -} -template -inline bool operator!=( EnumeratedValue self, EnumeratedValue other ){ - return !operator==( self, other ); -} - -#endif diff --git a/libs/generic/functional.h b/libs/generic/functional.h deleted file mode 100644 index cb618cf..0000000 --- a/libs/generic/functional.h +++ /dev/null @@ -1,214 +0,0 @@ -#if !defined( INCLUDED_FUNCTIONAL_H ) -#define INCLUDED_FUNCTIONAL_H - -#include -#include - -namespace detail { - -template -struct rank : rank { -}; - -template<> -struct rank<0> { -}; - -struct get_func { - - template - struct wrapper { - using type = T; - }; - - template - using func_member = wrapper; - - template - static wrapper > test(rank<2>) { - return {}; - } - - template - struct func_lambda { - using type = typename func_lambda::type; - }; - - template - struct func_lambda { - using type = R(Ts ...); - }; - - template - struct func_lambda { - using type = R(Ts ...); - }; - - template - struct func_lambda { - using type = R(Ts ...); - }; - - template > - static wrapper > test(rank<1>) { - return {}; - } -}; - -template -struct Fn; - -template -struct Fn { - using result_type = R; - - template - using get = typename std::tuple_element >::type; -}; -} - -template -using get_func = typename decltype(detail::get_func::test(detail::rank<2>{}))::type::type; - -template -using get_result_type = typename detail::Fn >::result_type; - -template -using get_argument = typename detail::Fn >::template get; - -namespace detail { - -template -class FunctionN; - -template -class FunctionN { -public: -template -class instance { -public: -using func = R(Ts ...); - -static R call(Ts... args) { - return (f)(args ...); -} -}; -}; - -} - -template -using Function = typename detail::FunctionN::template instance; - -namespace detail { -template -struct MemberFunction; - -template -struct MemberFunction { - using type = R (Object::*)(Ts...); - using type_const = R (Object::*)(Ts...) const; -}; -} - -namespace detail { -template -class MemberN; - -template -class MemberN { -public: -template -class instance { -public: -using func = R(Object &, Ts ...); - -static R call(Object &object, Ts... args) { - return (object.*f)(args ...); -} -}; -}; -} - -template -using MemberFunction = typename detail::MemberFunction::type; - -template func> -using Member = typename detail::MemberN::template instance; - -namespace detail { -template -class ConstMemberN; - -template -class ConstMemberN { -public: -template -class instance { -public: -using func = R(const Object &, Ts ...); - -static R call(const Object &object, Ts... args) { - return (object.*f)(args ...); -} -}; -}; -} - -template -using ConstMemberFunction = typename detail::MemberFunction::type_const; - -template func> -using ConstMember = typename detail::ConstMemberN::template instance; - -// misc - -namespace detail { -template -struct seq { -}; - -template -struct gens : gens { -}; - -template -struct gens<0, S...> { - using type = seq; -}; - -template -using seq_new = typename gens::type; - -template -class FunctorNInvoke; - -template -class FunctorNInvoke { -std::tuple args; - -template -struct caller; - -template -struct caller > { - static inline R call(FunctorNInvoke *self, Functor functor) { - (void) self; - return functor(std::get(self->args)...); - } -}; - -public: -FunctorNInvoke(Ts... args) : args(args ...) { -} - -inline R operator()(Functor functor) { - return caller >::call(this, functor); -} -}; -} - -template -using FunctorInvoke = detail::FunctorNInvoke >; - -#endif diff --git a/libs/generic/object.cpp b/libs/generic/object.cpp deleted file mode 100644 index bbb5610..0000000 --- a/libs/generic/object.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "object.h" - -namespace -{ -class Blah -{ -int i; -public: -Blah(){ - i = 3; -} -}; - -void Test(){ - char storage[sizeof( Blah )]; - constructor( *reinterpret_cast( storage ) ); -} -} \ No newline at end of file diff --git a/libs/generic/object.h b/libs/generic/object.h deleted file mode 100644 index 084f760..0000000 --- a/libs/generic/object.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_OBJECT_H ) -#define INCLUDED_GENERIC_OBJECT_H - -#include "globaldefs.h" - -/// \file -/// \brief Convenience functions (syntactic sugar) to wrap explicit constructor (aka in-place 'new') and destructor calls. -/// -/// Use makeReference() to wrap non-const-reference constructor parameters. - -#if GDEF_COMPILER_MSVC && _MSC_VER > 1000 -#pragma warning(disable:4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized -#endif - -#include - -template -inline void constructor( Type& object ){ - new( &object )Type(); -} - -template -inline void constructor( Type& object, const T1& t1 ){ - new( &object )Type( t1 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2 ){ - new( &object )Type( t1, t2 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3 ){ - new( &object )Type( t1, t2, t3 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4 ){ - new( &object )Type( t1, t2, t3, t4 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5 ){ - new( &object )Type( t1, t2, t3, t4, t5 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6 ){ - new( &object )Type( t1, t2, t3, t4, t5, t6 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7 ){ - new( &object )Type( t1, t2, t3, t4, t5, t6, t7 ); -} - -template -inline void constructor( Type& object, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8 ){ - new( &object )Type( t1, t2, t3, t4, t5, t6, t7, t8 ); -} - -template -inline void destructor( Type& object ){ - object.~Type(); -} - - - -#endif diff --git a/libs/generic/reference.h b/libs/generic/reference.h deleted file mode 100644 index df5a05a..0000000 --- a/libs/generic/reference.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_REFERENCE_H ) -#define INCLUDED_GENERIC_REFERENCE_H - -/// \file -/// \brief Wrappers to allow storing objects in templated containers using 'reference' semantics. - -/// \brief A reference to a mutable object. -/// Has 'reference' semantics, except for \c 'operator==' and \c 'operator.'. -/// \param Type The type of the referenced object. -template -class Reference -{ -Type* m_contained; -public: -explicit Reference( Type& contained ) : m_contained( &contained ){ -} -operator Type&() const -{ - return *m_contained; -} -Type& get() const { - return *m_contained; -} -Type* get_pointer() const { - return m_contained; -} -}; - -template -bool operator<( const Reference& self, const Reference& other ){ - return self.get() < other.get(); -} -template -bool operator==( const Reference& self, const Reference& other ){ - return self.get() == other.get(); -} - -/// \brief construct a reference to a mutable object. -template -inline Reference makeReference( Type& value ){ - return Reference( value ); -} - -/// \brief A reference to a non-mutable object. -/// Has 'reference' semantics, except for \c 'operator==' and \c 'operator.'. -/// \param Type The type of the referenced object. -template -class ConstReference -{ -const Type* m_contained; -public: -explicit ConstReference( const Type& contained ) : m_contained( &contained ){ -} -operator const Type&() const -{ - return *m_contained; -} -const Type& get() const { - return *m_contained; -} -const Type* get_pointer() const { - return m_contained; -} -}; - -template -bool operator<( const ConstReference& self, const ConstReference& other ){ - return self.get() < other.get(); -} -template -bool operator==( const ConstReference& self, const ConstReference& other ){ - return self.get() == other.get(); -} - -/// \brief construct a reference to a non-mutable object. -template -inline ConstReference makeReference( const Type& value ){ - return ConstReference( value ); -} - - -#endif diff --git a/libs/generic/referencecounted.h b/libs/generic/referencecounted.h deleted file mode 100644 index 37abd91..0000000 --- a/libs/generic/referencecounted.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_REFERENCECOUNTED_H ) -#define INCLUDED_GENERIC_REFERENCECOUNTED_H - -/// \file -/// \brief 'smart' pointers and references. - -#include - -template -class IncRefDecRefCounter -{ -public: -void increment( Type& value ){ - value.IncRef(); -} -void decrement( Type& value ){ - value.DecRef(); -} -}; - -/// \brief A smart-pointer that uses a counter stored in the object pointed-to. -template > -class SmartPointer : public Counter -{ -Type* m_value; -public: - -SmartPointer( const SmartPointer& other ) - : m_value( other.m_value ){ - Counter::increment( *m_value ); -} -explicit SmartPointer( Type* value ) - : m_value( value ){ - Counter::increment( *m_value ); -} -~SmartPointer(){ - Counter::decrement( *m_value ); -} -SmartPointer& operator=( const SmartPointer& other ){ - SmartPointer temp( other ); - temp.swap( *this ); - return *this; -} -SmartPointer& operator=( Type* value ){ - SmartPointer temp( value ); - temp.swap( *this ); - return *this; -} -void swap( SmartPointer& other ){ - std::swap( m_value, other.m_value ); -} - -operator Type*() const -{ - return m_value; -} -Type& operator*() const { - return *m_value; -} -Type* operator->() const { - return m_value; -} -Type* get() const { - return m_value; -} -}; - -template -inline bool operator<( const SmartPointer& self, const SmartPointer& other ){ - return self.get() < other.get(); -} -template -inline bool operator==( const SmartPointer& self, const SmartPointer& other ){ - return self.get() == other.get(); -} -template -inline bool operator!=( const SmartPointer& self, const SmartPointer& other ){ - return !::operator==( self, other ); -} - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap(). -template -inline void swap( SmartPointer& self, SmartPointer& other ){ - self.swap( other ); -} -} - - -/// \brief A smart-reference that uses a counter stored in the object pointed-to. -template > -class SmartReference : public Counter -{ -Type* m_value; -public: - -SmartReference( const SmartReference& other ) - : m_value( other.m_value ){ - Counter::increment( *m_value ); -} -explicit SmartReference( Type& value ) - : m_value( &value ){ - Counter::increment( *m_value ); -} -~SmartReference(){ - Counter::decrement( *m_value ); -} -SmartReference& operator=( const SmartReference& other ){ - SmartReference temp( other ); - temp.swap( *this ); - return *this; -} -SmartReference& operator=( Type& value ){ - SmartReference temp( value ); - temp.swap( *this ); - return *this; -} -void swap( SmartReference& other ){ - std::swap( m_value, other.m_value ); -} - -operator Type&() const -{ - return *m_value; -} -Type& get() const { - return *m_value; -} -Type* get_pointer() const { - return m_value; -} -}; - -template -inline bool operator<( const SmartReference& self, const SmartReference& other ){ - return self.get() < other.get(); -} -template -inline bool operator==( const SmartReference& self, const SmartReference& other ){ - return self.get() == other.get(); -} -template -inline bool operator!=( const SmartReference& self, const SmartReference& other ){ - return !::operator==( self, other ); -} - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap(). -template -inline void swap( SmartReference& self, SmartReference& other ){ - self.swap( other ); -} -} - -#endif diff --git a/libs/generic/static.cpp b/libs/generic/static.cpp deleted file mode 100644 index a92246b..0000000 --- a/libs/generic/static.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "static.h" -#include "globaldefs.h" - -#if GDEF_DEBUG || defined( DOXYGEN ) - -namespace ExampleStatic -{ -// Static example -// ---- myclass.h -class MyClass -{ -public: -int value; -MyClass() : value( 3 ){ -} -}; - -typedef Static StaticMyClass; - -// ---- main.cpp -class DynamicInitialisation -{ -public: -DynamicInitialisation(){ - // StaticMyClass::instance() may be invalid here because construction order is undefined -} -}; - -DynamicInitialisation g_dynamicInitialisation; - -void duringMain(){ - int bar = StaticMyClass::instance().value; -} -// end example -} - -namespace ExampleLazyStatic -{ -// LazyStatic example -// ---- myclass.h -class MyClass -{ -public: -int value; -MyClass() : value( 3 ){ -} -// destructor will never be called -}; - -typedef LazyStatic StaticMyClass; - -// ---- main.cpp -class DynamicInitialisation -{ -public: -DynamicInitialisation(){ - int bar = StaticMyClass::instance().value; -} -}; - -DynamicInitialisation g_dynamicInitialisation; - -void duringMain(){ - int bar = StaticMyClass::instance().value; -} -// end example -} - -namespace ExampleSmartStatic -{ -// SmartStatic example -// ---- myclass.h -class MyClass -{ -public: -int value; -MyClass() : value( 3 ){ -} -}; - -typedef CountedStatic StaticMyClass; - -// ---- main.cpp -class DynamicInitialisation -{ -public: -DynamicInitialisation(){ - // StaticMyClass::instance() is invalid before the ref is constructed - SmartStatic ref; - int bar = ref.instance().value; - - SmartStatic ref2; // any number of instances are allowed. -} -}; - -DynamicInitialisation g_dynamicInitialisation; - -void duringMain(){ - int bar = SmartStatic().instance().value; // an instance can be a temporary -} -// end example -} - -#endif diff --git a/libs/generic/static.h b/libs/generic/static.h deleted file mode 100644 index ad501fc..0000000 --- a/libs/generic/static.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_STATIC_H ) -#define INCLUDED_GENERIC_STATIC_H - -/// \file -/// \brief Template techniques for instantiating singletons. - -#include - -class Null -{ -}; - -/// \brief A singleton which is statically initialised. -/// -/// \param Type The singleton object type. -/// \param Type The type distinguishing this instance from others of the same type. -/// -/// \dontinclude generic/static.cpp -/// \skipline Static example -/// \until end example -template -class Static -{ -static Type m_instance; -public: -static Type& instance(){ - return m_instance; -} -}; - -template -Type Static::m_instance; - - -/// \brief A singleton which is lazily initialised. -/// The instance is constructed the first time it is referenced, and is never destroyed. -/// -/// \param Type The singleton object type. -/// \param Type The type distinguishing this instance from others of the same type. -/// -/// \dontinclude generic/static.cpp -/// \skipline LazyStatic example -/// \until end example -template -class LazyStatic -{ -static Type* m_instance; // this will be initialised to 0 by the CRT, according to the c++ standard -public: -static Type& instance(){ - if ( m_instance == 0 ) { - m_instance = new Type; // allocate using 'new' to get the correct alignment - } - return *m_instance; -} -}; - -template -Type * LazyStatic::m_instance; - - -/// \brief A singleton which keeps a count of the number of times it is referenced. -/// -/// The instance is constructed when its reference count changes from 0 to 1 and destroyed when its reference count changes from 1 to 0. -/// Use with SmartStatic. -/// -/// \param Type The singleton object type. -/// \param Type The type distinguishing this instance from others of the same type. -template -class CountedStatic -{ -static std::size_t m_refcount; // this will be initialised to 0 by the CRT, according to the c++ standard -static Type* m_instance; -public: -static Type& instance(){ - return *m_instance; -} -static void capture(){ - if ( ++m_refcount == 1 ) { - m_instance = new Type; // allocate using 'new' to get the correct alignment - } -} -static void release(){ - if ( --m_refcount == 0 ) { - delete m_instance; - } -} -}; - -template -std::size_t CountedStatic::m_refcount; // this will be initialised to 0 by the CRT, according to the c++ standard -template -Type * CountedStatic::m_instance; - -/// \brief A reference to a CountedStatic. -/// Guarantees that CountedStatic will be constructed for the lifetime of this object. -/// -/// \param Type The type parameter of the CountedStatic to reference. -/// \param Type The type distinguishing this instance from others of the same type. -/// -/// \dontinclude generic/static.cpp -/// \skipline SmartStatic example -/// \until end example -template -class SmartStatic -{ -public: -SmartStatic(){ - CountedStatic::capture(); -} -~SmartStatic(){ - CountedStatic::release(); -} -Type& instance(){ - return CountedStatic::instance(); -} -}; - - -#endif diff --git a/libs/generic/vector.h b/libs/generic/vector.h deleted file mode 100644 index ea1e3bd..0000000 --- a/libs/generic/vector.h +++ /dev/null @@ -1,212 +0,0 @@ - -#if !defined( INCLUDED_VECTOR_H ) -#define INCLUDED_VECTOR_H - -#include - -template -class BasicVector2 -{ -Element m_elements[2]; -public: -BasicVector2(){ -} -BasicVector2( const Element& x_, const Element& y_ ){ - x() = x_; - y() = y_; -} - -Element& x(){ - return m_elements[0]; -} -const Element& x() const { - return m_elements[0]; -} -Element& y(){ - return m_elements[1]; -} -const Element& y() const { - return m_elements[1]; -} - -const Element& operator[]( std::size_t i ) const { - return m_elements[i]; -} -Element& operator[]( std::size_t i ){ - return m_elements[i]; -} - -Element* data(){ - return m_elements; -} -const Element* data() const { - return m_elements; -} -}; - -/// \brief A 3-element vector. -template -class BasicVector3 -{ -Element m_elements[3]; -public: - -BasicVector3(){ -} -template -BasicVector3( const BasicVector3& other ){ - x() = static_cast( other.x() ); - y() = static_cast( other.y() ); - z() = static_cast( other.z() ); -} -BasicVector3( const Element& x_, const Element& y_, const Element& z_ ){ - x() = x_; - y() = y_; - z() = z_; -} - -Element& x(){ - return m_elements[0]; -} -const Element& x() const { - return m_elements[0]; -} -Element& y(){ - return m_elements[1]; -} -const Element& y() const { - return m_elements[1]; -} -Element& z(){ - return m_elements[2]; -} -const Element& z() const { - return m_elements[2]; -} - -const Element& operator[]( std::size_t i ) const { - return m_elements[i]; -} -Element& operator[]( std::size_t i ){ - return m_elements[i]; -} - -Element* data(){ - return m_elements; -} -const Element* data() const { - return m_elements; -} -}; - -/// \brief A 4-element vector. -template -class BasicVector4 -{ -Element m_elements[4]; -public: - -BasicVector4(){ -} -BasicVector4( Element x_, Element y_, Element z_, Element w_ ){ - x() = x_; - y() = y_; - z() = z_; - w() = w_; -} -BasicVector4( const BasicVector3& self, Element w_ ){ - x() = self.x(); - y() = self.y(); - z() = self.z(); - w() = w_; -} - -Element& x(){ - return m_elements[0]; -} -const Element& x() const { - return m_elements[0]; -} -Element& y(){ - return m_elements[1]; -} -const Element& y() const { - return m_elements[1]; -} -Element& z(){ - return m_elements[2]; -} -const Element& z() const { - return m_elements[2]; -} -Element& w(){ - return m_elements[3]; -} -const Element& w() const { - return m_elements[3]; -} - -Element index( std::size_t i ) const { - return m_elements[i]; -} -Element& index( std::size_t i ){ - return m_elements[i]; -} -Element operator[]( std::size_t i ) const { - return m_elements[i]; -} -Element& operator[]( std::size_t i ){ - return m_elements[i]; -} - -Element* data(){ - return m_elements; -} -const Element* data() const { - return m_elements; -} -}; - -template -inline BasicVector3 vector3_from_array( const Element* array ){ - return BasicVector3( array[0], array[1], array[2] ); -} - -template -inline Element* vector3_to_array( BasicVector3& self ){ - return self.data(); -} -template -inline const Element* vector3_to_array( const BasicVector3& self ){ - return self.data(); -} - -template -inline Element* vector4_to_array( BasicVector4& self ){ - return self.data(); -} -template -inline const Element* vector4_to_array( const BasicVector4& self ){ - return self.data(); -} - -template -inline BasicVector3& vector4_to_vector3( BasicVector4& self ){ - return *reinterpret_cast*>( vector4_to_array( self ) ); -} -template -inline const BasicVector3& vector4_to_vector3( const BasicVector4& self ){ - return *reinterpret_cast*>( vector4_to_array( self ) ); -} - -/// \brief A 2-element vector stored in single-precision floating-point. -typedef BasicVector2 Vector2; - -/// \brief A 3-element vector stored in single-precision floating-point. -typedef BasicVector3 Vector3; - -/// \brief A 4-element vector stored in single-precision floating-point. -typedef BasicVector4 Vector4; - - -#endif diff --git a/libs/gtkutil/Makefile b/libs/gtkutil/Makefile deleted file mode 100644 index 49015f8..0000000 --- a/libs/gtkutil/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# WorldSpawn Makefile - -GTK_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -GLEXT_CFLAGS=$(shell pkg-config --cflags gtkglext-1.0) -GLIB_CFLAGS=$(shell pkg-config --cflags glib-2.0) - -LIB_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS) $(GLEXT_CFLAGS) -I../../include -I../../libs -DGTK_TARGET=2 -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ -accelerator.o \ -button.o \ -clipboard.o \ -cursor.o \ -dialog.o \ -entry.o \ -filechooser.o \ -frame.o \ -glfont.o \ -glwidget.o \ -image.o \ -menu.o \ -messagebox.o \ -nonmodal.o \ -paned.o \ -toolbar.o \ -widget.o \ -window.o \ -xorrectangle.o - -# binary target -../libgtkutil.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -accelerator.o: accelerator.cpp accelerator.h -button.o: button.cpp button.h -clipboard.o: clipboard.cpp clipboard.h -cursor.o: cursor.cpp cursor.h -dialog.o: dialog.cpp dialog.h -entry.o: entry.cpp entry.h -filechooser.o: filechooser.cpp filechooser.h -frame.o: frame.cpp frame.h -glfont.o: glfont.cpp glfont.h -glwidget.o: glwidget.cpp glwidget.h -image.o: image.cpp image.h -menu.o: menu.cpp menu.h -messagebox.o: messagebox.cpp messagebox.h -nonmodal.o: nonmodal.cpp nonmodal.h -paned.o: paned.cpp paned.h -toolbar.o: toolbar.cpp toolbar.h -widget.o: widget.cpp widget.h -window.o: window.cpp window.h -xorrectangle.o: xorrectangle.cpp xorrectangle.h - -clean: - -rm -f *.o ../libgtkutil.a diff --git a/libs/gtkutil/accelerator.cpp b/libs/gtkutil/accelerator.cpp deleted file mode 100644 index 8bcdb03..0000000 --- a/libs/gtkutil/accelerator.cpp +++ /dev/null @@ -1,609 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "accelerator.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#include "generic/callback.h" -#include "generic/bitfield.h" -#include "string/string.h" - -#include "pointer.h" -#include "closure.h" - -#include - - -const char *global_keys_find(unsigned int key) -{ - const char *s; - if (key == 0) { - return ""; - } - s = gdk_keyval_name(key); - if (!s) { - return ""; - } - return s; -} - -unsigned int global_keys_find(const char *name) -{ - guint k; - if (!name || !*name) { - return 0; - } - k = gdk_keyval_from_name(name); - if (k == GDK_KEY_VoidSymbol) { - return 0; - } - return k; -} - -void accelerator_write(const Accelerator &accelerator, TextOutputStream &ostream) -{ -#if 0 - if ( accelerator.modifiers & GDK_SHIFT_MASK ) { - ostream << "Shift + "; - } - if ( accelerator.modifiers & GDK_MOD1_MASK ) { - ostream << "Alt + "; - } - if ( accelerator.modifiers & GDK_CONTROL_MASK ) { - ostream << "Control + "; - } - - const char* keyName = global_keys_find( accelerator.key ); - if ( !string_empty( keyName ) ) { - ostream << keyName; - } - else - { - ostream << static_cast( accelerator.key ); - } -#endif - ostream << gtk_accelerator_get_label(accelerator.key, accelerator.modifiers); -} - -typedef std::map > AcceleratorMap; -typedef std::set AcceleratorSet; - -bool accelerator_map_insert(AcceleratorMap &acceleratorMap, Accelerator accelerator, const Callback &callback) -{ - if (accelerator.key != 0) { - return acceleratorMap.insert(AcceleratorMap::value_type(accelerator, callback)).second; - } - return true; -} - -bool accelerator_map_erase(AcceleratorMap &acceleratorMap, Accelerator accelerator) -{ - if (accelerator.key != 0) { - AcceleratorMap::iterator i = acceleratorMap.find(accelerator); - if (i == acceleratorMap.end()) { - return false; - } - acceleratorMap.erase(i); - } - return true; -} - -Accelerator accelerator_for_event_key(guint keyval, guint state) -{ - keyval = gdk_keyval_to_upper(keyval); - if (keyval == GDK_KEY_ISO_Left_Tab) { - keyval = GDK_KEY_Tab; - } - return Accelerator(keyval, (GdkModifierType) (state & gtk_accelerator_get_default_mod_mask())); -} - -bool AcceleratorMap_activate(const AcceleratorMap &acceleratorMap, const Accelerator &accelerator) -{ - AcceleratorMap::const_iterator i = acceleratorMap.find(accelerator); - if (i != acceleratorMap.end()) { - (*i).second(); - return true; - } - - return false; -} - -static gboolean accelerator_key_event(ui::Window window, GdkEventKey *event, AcceleratorMap *acceleratorMap) -{ - return AcceleratorMap_activate(*acceleratorMap, accelerator_for_event_key(event->keyval, event->state)); -} - - -AcceleratorMap g_special_accelerators; - - -namespace MouseButton { -enum { - Left = 1 << 0, - Right = 1 << 1, - Middle = 1 << 2, -}; -} - -typedef unsigned int ButtonMask; - -void print_buttons(ButtonMask mask) -{ - globalOutputStream() << "button state: "; - if ((mask & MouseButton::Left) != 0) { - globalOutputStream() << "Left "; - } - if ((mask & MouseButton::Right) != 0) { - globalOutputStream() << "Right "; - } - if ((mask & MouseButton::Middle) != 0) { - globalOutputStream() << "Middle "; - } - globalOutputStream() << "\n"; -} - -ButtonMask ButtonMask_for_event_button(guint button) -{ - switch (button) { - case 1: - return MouseButton::Left; - case 2: - return MouseButton::Middle; - case 3: - return MouseButton::Right; - } - return 0; -} - -bool window_has_accel(ui::Window toplevel) -{ - return g_slist_length(gtk_accel_groups_from_object(G_OBJECT(toplevel))) != 0; -} - -namespace { -bool g_accel_enabled = true; -} - -bool global_accel_enabled() -{ - return g_accel_enabled; -} - - -GClosure *accel_group_add_accelerator(ui::AccelGroup group, Accelerator accelerator, const Callback &callback); - -void accel_group_remove_accelerator(ui::AccelGroup group, Accelerator accelerator); - -AcceleratorMap g_queuedAcceleratorsAdd; -AcceleratorSet g_queuedAcceleratorsRemove; - -void globalQueuedAccelerators_add(Accelerator accelerator, const Callback &callback) -{ - if (!g_queuedAcceleratorsAdd.insert(AcceleratorMap::value_type(accelerator, callback)).second) { - globalErrorStream() << "globalQueuedAccelerators_add: accelerator already queued: " << accelerator << "\n"; - } -} - -void globalQueuedAccelerators_remove(Accelerator accelerator) -{ - if (g_queuedAcceleratorsAdd.erase(accelerator) == 0) { - if (!g_queuedAcceleratorsRemove.insert(accelerator).second) { - globalErrorStream() << "globalQueuedAccelerators_remove: accelerator already queued: " << accelerator - << "\n"; - } - } -} - -void globalQueuedAccelerators_commit() -{ - for (AcceleratorSet::const_iterator i = g_queuedAcceleratorsRemove.begin(); - i != g_queuedAcceleratorsRemove.end(); ++i) { - //globalOutputStream() << "removing: " << (*i).first << "\n"; - accel_group_remove_accelerator(global_accel, *i); - } - g_queuedAcceleratorsRemove.clear(); - for (AcceleratorMap::const_iterator i = g_queuedAcceleratorsAdd.begin(); i != g_queuedAcceleratorsAdd.end(); ++i) { - //globalOutputStream() << "adding: " << (*i).first << "\n"; - accel_group_add_accelerator(global_accel, (*i).first, (*i).second); - } - g_queuedAcceleratorsAdd.clear(); -} - -typedef std::set WindowSet; -WindowSet g_accel_windows; - -bool Buttons_press(ButtonMask &buttons, guint button, guint state) -{ - if (buttons == 0 && bitfield_enable(buttons, ButtonMask_for_event_button(button)) != 0) { - ASSERT_MESSAGE(g_accel_enabled, "Buttons_press: accelerators not enabled"); - g_accel_enabled = false; - for (WindowSet::iterator i = g_accel_windows.begin(); i != g_accel_windows.end(); ++i) { - ui::Window toplevel = *i; - ASSERT_MESSAGE(window_has_accel(toplevel), "ERROR"); - ASSERT_MESSAGE(gtk_widget_is_toplevel(toplevel), "disabling accel for non-toplevel window"); - gtk_window_remove_accel_group(toplevel, global_accel); -#if 0 - globalOutputStream() << reinterpret_cast( toplevel ) << ": disabled global accelerators\n"; -#endif - } - } - buttons = bitfield_enable(buttons, ButtonMask_for_event_button(button)); -#if 0 - globalOutputStream() << "Buttons_press: "; - print_buttons( buttons ); -#endif - return false; -} - -bool Buttons_release(ButtonMask &buttons, guint button, guint state) -{ - if (buttons != 0 && bitfield_disable(buttons, ButtonMask_for_event_button(button)) == 0) { - ASSERT_MESSAGE(!g_accel_enabled, "Buttons_release: accelerators are enabled"); - g_accel_enabled = true; - for (WindowSet::iterator i = g_accel_windows.begin(); i != g_accel_windows.end(); ++i) { - ui::Window toplevel = *i; - ASSERT_MESSAGE(!window_has_accel(toplevel), "ERROR"); - ASSERT_MESSAGE(gtk_widget_is_toplevel(toplevel), "enabling accel for non-toplevel window"); - toplevel.add_accel_group(global_accel); -#if 0 - globalOutputStream() << reinterpret_cast( toplevel ) << ": enabled global accelerators\n"; -#endif - } - globalQueuedAccelerators_commit(); - } - buttons = bitfield_disable(buttons, ButtonMask_for_event_button(button)); -#if 0 - globalOutputStream() << "Buttons_release: "; - print_buttons( buttons ); -#endif - return false; -} - -bool Buttons_releaseAll(ButtonMask &buttons) -{ - Buttons_release(buttons, MouseButton::Left | MouseButton::Middle | MouseButton::Right, 0); - return false; -} - -struct PressedButtons { - ButtonMask buttons; - - PressedButtons() : buttons(0) - { - } -}; - -gboolean PressedButtons_button_press(ui::Widget widget, GdkEventButton *event, PressedButtons *pressed) -{ - if (event->type == GDK_BUTTON_PRESS) { - return Buttons_press(pressed->buttons, event->button, event->state); - } - return FALSE; -} - -gboolean PressedButtons_button_release(ui::Widget widget, GdkEventButton *event, PressedButtons *pressed) -{ - if (event->type == GDK_BUTTON_RELEASE) { - return Buttons_release(pressed->buttons, event->button, event->state); - } - return FALSE; -} - -gboolean PressedButtons_focus_out(ui::Widget widget, GdkEventFocus *event, PressedButtons *pressed) -{ - Buttons_releaseAll(pressed->buttons); - return FALSE; -} - -void PressedButtons_connect(PressedButtons &pressedButtons, ui::Widget widget) -{ - widget.connect("button_press_event", G_CALLBACK(PressedButtons_button_press), &pressedButtons); - widget.connect("button_release_event", G_CALLBACK(PressedButtons_button_release), &pressedButtons); - widget.connect("focus_out_event", G_CALLBACK(PressedButtons_focus_out), &pressedButtons); -} - -PressedButtons g_pressedButtons; - - -#include -#include - -struct PressedKeys { - typedef std::set Keys; - Keys keys; - std::size_t refcount; - - PressedKeys() : refcount(0) - { - } -}; - -AcceleratorMap g_keydown_accelerators; -AcceleratorMap g_keyup_accelerators; - -bool Keys_press(PressedKeys::Keys &keys, guint keyval) -{ - if (keys.insert(keyval).second) { - return AcceleratorMap_activate(g_keydown_accelerators, accelerator_for_event_key(keyval, 0)); - } - return g_keydown_accelerators.find(accelerator_for_event_key(keyval, 0)) != g_keydown_accelerators.end(); -} - -bool Keys_release(PressedKeys::Keys &keys, guint keyval) -{ - if (keys.erase(keyval) != 0) { - return AcceleratorMap_activate(g_keyup_accelerators, accelerator_for_event_key(keyval, 0)); - } - return g_keyup_accelerators.find(accelerator_for_event_key(keyval, 0)) != g_keyup_accelerators.end(); -} - -void Keys_releaseAll(PressedKeys::Keys &keys, guint state) -{ - for (PressedKeys::Keys::iterator i = keys.begin(); i != keys.end(); ++i) { - AcceleratorMap_activate(g_keyup_accelerators, accelerator_for_event_key(*i, state)); - } - keys.clear(); -} - -gboolean PressedKeys_key_press(ui::Widget widget, GdkEventKey *event, PressedKeys *pressedKeys) -{ - //globalOutputStream() << "pressed: " << event->keyval << "\n"; - return event->state == 0 && Keys_press(pressedKeys->keys, event->keyval); -} - -gboolean PressedKeys_key_release(ui::Widget widget, GdkEventKey *event, PressedKeys *pressedKeys) -{ - //globalOutputStream() << "released: " << event->keyval << "\n"; - return Keys_release(pressedKeys->keys, event->keyval); -} - -gboolean PressedKeys_focus_in(ui::Widget widget, GdkEventFocus *event, PressedKeys *pressedKeys) -{ - ++pressedKeys->refcount; - return FALSE; -} - -gboolean PressedKeys_focus_out(ui::Widget widget, GdkEventFocus *event, PressedKeys *pressedKeys) -{ - if (--pressedKeys->refcount == 0) { - Keys_releaseAll(pressedKeys->keys, 0); - } - return FALSE; -} - -PressedKeys g_pressedKeys; - -void GlobalPressedKeys_releaseAll() -{ - Keys_releaseAll(g_pressedKeys.keys, 0); -} - -void GlobalPressedKeys_connect(ui::Window window) -{ - unsigned int key_press_handler = window.connect("key_press_event", G_CALLBACK(PressedKeys_key_press), - &g_pressedKeys); - unsigned int key_release_handler = window.connect("key_release_event", G_CALLBACK(PressedKeys_key_release), - &g_pressedKeys); - g_object_set_data(G_OBJECT(window), "key_press_handler", gint_to_pointer(key_press_handler)); - g_object_set_data(G_OBJECT(window), "key_release_handler", gint_to_pointer(key_release_handler)); - unsigned int focus_in_handler = window.connect("focus_in_event", G_CALLBACK(PressedKeys_focus_in), &g_pressedKeys); - unsigned int focus_out_handler = window.connect("focus_out_event", G_CALLBACK(PressedKeys_focus_out), - &g_pressedKeys); - g_object_set_data(G_OBJECT(window), "focus_in_handler", gint_to_pointer(focus_in_handler)); - g_object_set_data(G_OBJECT(window), "focus_out_handler", gint_to_pointer(focus_out_handler)); -} - -void GlobalPressedKeys_disconnect(ui::Window window) -{ - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "key_press_handler"))); - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "key_release_handler"))); - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "focus_in_handler"))); - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "focus_out_handler"))); -} - - -void special_accelerators_add(Accelerator accelerator, const Callback &callback) -{ - //globalOutputStream() << "special_accelerators_add: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_insert(g_special_accelerators, accelerator, callback)) { - globalErrorStream() << "special_accelerators_add: already exists: " << makeQuoted(accelerator) << "\n"; - } -} - -void special_accelerators_remove(Accelerator accelerator) -{ - //globalOutputStream() << "special_accelerators_remove: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_erase(g_special_accelerators, accelerator)) { - globalErrorStream() << "special_accelerators_remove: not found: " << makeQuoted(accelerator) << "\n"; - } -} - -void keydown_accelerators_add(Accelerator accelerator, const Callback &callback) -{ - //globalOutputStream() << "keydown_accelerators_add: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_insert(g_keydown_accelerators, accelerator, callback)) { - globalErrorStream() << "keydown_accelerators_add: already exists: " << makeQuoted(accelerator) << "\n"; - } -} - -void keydown_accelerators_remove(Accelerator accelerator) -{ - //globalOutputStream() << "keydown_accelerators_remove: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_erase(g_keydown_accelerators, accelerator)) { - globalErrorStream() << "keydown_accelerators_remove: not found: " << makeQuoted(accelerator) << "\n"; - } -} - -void keyup_accelerators_add(Accelerator accelerator, const Callback &callback) -{ - //globalOutputStream() << "keyup_accelerators_add: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_insert(g_keyup_accelerators, accelerator, callback)) { - globalErrorStream() << "keyup_accelerators_add: already exists: " << makeQuoted(accelerator) << "\n"; - } -} - -void keyup_accelerators_remove(Accelerator accelerator) -{ - //globalOutputStream() << "keyup_accelerators_remove: " << makeQuoted(accelerator) << "\n"; - if (!accelerator_map_erase(g_keyup_accelerators, accelerator)) { - globalErrorStream() << "keyup_accelerators_remove: not found: " << makeQuoted(accelerator) << "\n"; - } -} - - -gboolean -accel_closure_callback(ui::AccelGroup group, ui::Widget widget, guint key, GdkModifierType modifiers, gpointer data) -{ - (*reinterpret_cast *>( data ))(); - return TRUE; -} - -GClosure *accel_group_add_accelerator(ui::AccelGroup group, Accelerator accelerator, const Callback &callback) -{ - if (accelerator.key != 0 && gtk_accelerator_valid(accelerator.key, accelerator.modifiers)) { - //globalOutputStream() << "global_accel_connect: " << makeQuoted(accelerator) << "\n"; - GClosure *closure = create_cclosure(G_CALLBACK(accel_closure_callback), callback); - gtk_accel_group_connect(group, accelerator.key, accelerator.modifiers, GTK_ACCEL_VISIBLE, closure); - return closure; - } else { - special_accelerators_add(accelerator, callback); - return 0; - } -} - -void accel_group_remove_accelerator(ui::AccelGroup group, Accelerator accelerator) -{ - if (accelerator.key != 0 && gtk_accelerator_valid(accelerator.key, accelerator.modifiers)) { - //globalOutputStream() << "global_accel_disconnect: " << makeQuoted(accelerator) << "\n"; - gtk_accel_group_disconnect_key(group, accelerator.key, accelerator.modifiers); - } else { - special_accelerators_remove(accelerator); - } -} - -ui::AccelGroup global_accel{ui::New}; - -GClosure *global_accel_group_add_accelerator(Accelerator accelerator, const Callback &callback) -{ - if (!global_accel_enabled()) { - // workaround: cannot add to GtkAccelGroup while it is disabled - //globalOutputStream() << "queued for add: " << accelerator << "\n"; - globalQueuedAccelerators_add(accelerator, callback); - return 0; - } - return accel_group_add_accelerator(global_accel, accelerator, callback); -} - -void global_accel_group_remove_accelerator(Accelerator accelerator) -{ - if (!global_accel_enabled()) { - //globalOutputStream() << "queued for remove: " << accelerator << "\n"; - globalQueuedAccelerators_remove(accelerator); - return; - } - accel_group_remove_accelerator(global_accel, accelerator); -} - -/// \brief Propagates key events to the focus-widget, overriding global accelerators. -static gboolean override_global_accelerators(ui::Window window, GdkEventKey *event, gpointer data) -{ - gboolean b = gtk_window_propagate_key_event(window, event); - return b; -} - -void global_accel_connect_window(ui::Window window) -{ -#if 1 - unsigned int override_handler = window.connect("key_press_event", G_CALLBACK(override_global_accelerators), 0); - g_object_set_data(G_OBJECT(window), "override_handler", gint_to_pointer(override_handler)); - - unsigned int special_key_press_handler = window.connect("key_press_event", G_CALLBACK(accelerator_key_event), - &g_special_accelerators); - g_object_set_data(G_OBJECT(window), "special_key_press_handler", gint_to_pointer(special_key_press_handler)); - - GlobalPressedKeys_connect(window); -#else - unsigned int key_press_handler = window.connect( "key_press_event", G_CALLBACK( accelerator_key_event ), &g_keydown_accelerators ); - unsigned int key_release_handler = window.connect( "key_release_event", G_CALLBACK( accelerator_key_event ), &g_keyup_accelerators ); - g_object_set_data( G_OBJECT( window ), "key_press_handler", gint_to_pointer( key_press_handler ) ); - g_object_set_data( G_OBJECT( window ), "key_release_handler", gint_to_pointer( key_release_handler ) ); -#endif - g_accel_windows.insert(window); - window.add_accel_group(global_accel); -} - -void global_accel_disconnect_window(ui::Window window) -{ -#if 1 - GlobalPressedKeys_disconnect(window); - - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "override_handler"))); - g_signal_handler_disconnect(G_OBJECT(window), - gpointer_to_int(g_object_get_data(G_OBJECT(window), "special_key_press_handler"))); -#else - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "key_press_handler" ) ) ); - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "key_release_handler" ) ) ); -#endif - gtk_window_remove_accel_group(window, global_accel); - std::size_t count = g_accel_windows.erase(window); - ASSERT_MESSAGE(count == 1, "failed to remove accel group\n"); -} - - -GClosure *global_accel_group_find(Accelerator accelerator) -{ - guint numEntries = 0; - GtkAccelGroupEntry *entry = gtk_accel_group_query(global_accel, accelerator.key, accelerator.modifiers, - &numEntries); - if (numEntries != 0) { - if (numEntries != 1) { - char *name = gtk_accelerator_name(accelerator.key, accelerator.modifiers); - globalErrorStream() << "accelerator already in-use: " << name << "\n"; - g_free(name); - } - return entry->closure; - } - return 0; -} - -void global_accel_group_connect(const Accelerator &accelerator, const Callback &callback) -{ - if (accelerator.key != 0) { - global_accel_group_add_accelerator(accelerator, callback); - } -} - -void global_accel_group_disconnect(const Accelerator &accelerator, const Callback &callback) -{ - if (accelerator.key != 0) { - global_accel_group_remove_accelerator(accelerator); - } -} diff --git a/libs/gtkutil/accelerator.h b/libs/gtkutil/accelerator.h deleted file mode 100644 index 2bde656..0000000 --- a/libs/gtkutil/accelerator.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_ACCELERATOR_H ) -#define INCLUDED_GTKUTIL_ACCELERATOR_H - -#include -#include - -#include "generic/callback.h" -#include "property.h" - -// ignore numlock -#define ALLOWED_MODIFIERS ( ~( GDK_MOD2_MASK | GDK_LOCK_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK ) ) - -struct Accelerator { - Accelerator(guint _key) - : key(gdk_keyval_to_upper(_key)), modifiers((GdkModifierType) 0) - { - } - - Accelerator(guint _key, GdkModifierType _modifiers) - : key(gdk_keyval_to_upper(_key)), modifiers((GdkModifierType) (_modifiers & ALLOWED_MODIFIERS)) - { - } - - Accelerator(const Accelerator &src) - : key(gdk_keyval_to_upper(src.key)), modifiers((GdkModifierType) (src.modifiers & ALLOWED_MODIFIERS)) - { - } - - bool operator<(const Accelerator &other) const - { - guint k1 = key; - guint k2 = other.key; - int mod1 = modifiers & ALLOWED_MODIFIERS; - int mod2 = other.modifiers & ALLOWED_MODIFIERS; - return k1 < k2 || (!(k2 < k1) && mod1 < mod2); - } - - bool operator==(const Accelerator &other) const - { - guint k1 = key; - guint k2 = other.key; - int mod1 = modifiers & ALLOWED_MODIFIERS; - int mod2 = other.modifiers & ALLOWED_MODIFIERS; - return k1 == k2 && mod1 == mod2; - } - - Accelerator &operator=(const Accelerator &other) - { - key = other.key; - modifiers = (GdkModifierType) (other.modifiers & ALLOWED_MODIFIERS); - return *this; - } - - guint key; - GdkModifierType modifiers; -}; - -inline Accelerator accelerator_null() -{ - return Accelerator(0, (GdkModifierType) 0); -} - -const char *global_keys_find(unsigned int key); - -unsigned int global_keys_find(const char *name); - -class TextOutputStream; - -void accelerator_write(const Accelerator &accelerator, TextOutputStream &ostream); - -template -TextOutputStreamType &ostream_write(TextOutputStreamType &ostream, const Accelerator &accelerator) -{ - accelerator_write(accelerator, ostream); - return ostream; -} - -void keydown_accelerators_add(Accelerator accelerator, const Callback &callback); - -void keydown_accelerators_remove(Accelerator accelerator); - -void keyup_accelerators_add(Accelerator accelerator, const Callback &callback); - -void keyup_accelerators_remove(Accelerator accelerator); - -void global_accel_connect_window(ui::Window window); - -void global_accel_disconnect_window(ui::Window window); - -void GlobalPressedKeys_releaseAll(); - -extern ui::AccelGroup global_accel; - -GClosure *global_accel_group_find(Accelerator accelerator); - -void global_accel_group_connect(const Accelerator &accelerator, const Callback &callback); - -void global_accel_group_disconnect(const Accelerator &accelerator, const Callback &callback); - - -class Command { -public: -Callback m_callback; -const Accelerator &m_accelerator; - -Command(const Callback &callback, const Accelerator &accelerator) : m_callback(callback), - m_accelerator(accelerator) -{ -} -}; - -class Toggle { -public: -Command m_command; -Callback &)> m_exportCallback; - -Toggle(const Callback &callback, const Accelerator &accelerator, - const Callback &)> &exportCallback) : m_command(callback, accelerator), - m_exportCallback(exportCallback) -{ -} -}; - -class KeyEvent { -public: -const Accelerator &m_accelerator; -Callback m_keyDown; -Callback m_keyUp; - -KeyEvent(const Accelerator &accelerator, const Callback &keyDown, const Callback &keyUp) - : m_accelerator(accelerator), m_keyDown(keyDown), m_keyUp(keyUp) -{ -} -}; - - -struct PressedButtons; - -void PressedButtons_connect(PressedButtons &pressedButtons, ui::Widget widget); - -extern PressedButtons g_pressedButtons; - -#endif diff --git a/libs/gtkutil/button.cpp b/libs/gtkutil/button.cpp deleted file mode 100644 index cc0c59b..0000000 --- a/libs/gtkutil/button.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "button.h" - -#include - -#include "stream/textstream.h" -#include "stream/stringstream.h" -#include "generic/callback.h" - -#include "image.h" -#include "pointer.h" - -void clicked_closure_callback(ui::Widget widget, gpointer data) -{ - (*reinterpret_cast *>( data ))(); -} - -void button_connect_callback(ui::Button button, const Callback &callback) -{ -#if 1 - g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(callback.getThunk()), callback.getEnvironment()); -#else - g_signal_connect_closure( G_OBJECT( button ), "clicked", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), FALSE ); -#endif -} - -void button_connect_callback(ui::ToolButton button, const Callback &callback) -{ -#if 1 - g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(callback.getThunk()), callback.getEnvironment()); -#else - g_signal_connect_closure( G_OBJECT( button ), "clicked", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), FALSE ); -#endif -} - -guint toggle_button_connect_callback(ui::ToggleButton button, const Callback &callback) -{ -#if 1 - guint handler = g_signal_connect_swapped(G_OBJECT(button), "toggled", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -#else - guint handler = g_signal_connect_closure( G_OBJECT( button ), "toggled", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), TRUE ); -#endif - g_object_set_data(G_OBJECT(button), "handler", gint_to_pointer(handler)); - return handler; -} - -guint toggle_button_connect_callback(ui::ToggleToolButton button, const Callback &callback) -{ -#if 1 - guint handler = g_signal_connect_swapped(G_OBJECT(button), "toggled", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -#else - guint handler = g_signal_connect_closure( G_OBJECT( button ), "toggled", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), TRUE ); -#endif - g_object_set_data(G_OBJECT(button), "handler", gint_to_pointer(handler)); - return handler; -} - -void button_set_icon(ui::Button button, const char *icon) -{ - ui::Image image = ui::Image(new_local_image(icon)); - image.show(); - button.add(image); -} - -void toggle_button_set_active_no_signal(ui::ToggleButton button, gboolean active) -{ - //globalOutputStream() << "set active: " << active << "\n"; - guint handler_id = gpointer_to_int(g_object_get_data(G_OBJECT(button), "handler")); - //guint signal_id = g_signal_lookup("toggled", G_OBJECT_TYPE (button)); - //globalOutputStream() << "signal_id: " << signal_id << "\n"; - //guint found = g_signal_handler_find(G_OBJECT(button), G_SIGNAL_MATCH_ID, signal_id, 0, 0, 0, 0); - //globalOutputStream() << " handler found: " << found << "\n"; - g_signal_handler_block(G_OBJECT(button), handler_id); - gtk_toggle_button_set_active(button, active); - g_signal_handler_unblock(G_OBJECT(button), handler_id); -} - -void toggle_button_set_active_no_signal(ui::ToggleToolButton button, gboolean active) -{ - guint handler_id = gpointer_to_int(g_object_get_data(G_OBJECT(button), "handler")); - g_signal_handler_block(G_OBJECT(button), handler_id); - gtk_toggle_tool_button_set_active(button, active); - g_signal_handler_unblock(G_OBJECT(button), handler_id); -} - - -void radio_button_print_state(ui::RadioButton button) -{ - globalOutputStream() << "toggle button: "; - for (GSList *radio = gtk_radio_button_get_group(button); radio != 0; radio = g_slist_next(radio)) { - globalOutputStream() << gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio->data)); - } - globalOutputStream() << "\n"; -} - -ui::ToggleButton radio_button_get_nth(ui::RadioButton radio, int index) -{ - GSList *group = gtk_radio_button_get_group(radio); - return ui::ToggleButton::from(g_slist_nth_data(group, g_slist_length(group) - index - 1)); -} - -void radio_button_set_active(ui::RadioButton radio, int index) -{ - //radio_button_print_state(radio); - gtk_toggle_button_set_active(radio_button_get_nth(radio, index), TRUE); - //radio_button_print_state(radio); -} - -void radio_button_set_active_no_signal(ui::RadioButton radio, int index) -{ - { - for (GSList *l = gtk_radio_button_get_group(radio); l != 0; l = g_slist_next(l)) { - g_signal_handler_block(G_OBJECT(l->data), gpointer_to_int(g_object_get_data(G_OBJECT(l->data), "handler"))); - } - } - radio_button_set_active(radio, index); - { - for (GSList *l = gtk_radio_button_get_group(radio); l != 0; l = g_slist_next(l)) { - g_signal_handler_unblock(G_OBJECT(l->data), - gpointer_to_int(g_object_get_data(G_OBJECT(l->data), "handler"))); - } - } -} - -int radio_button_get_active(ui::RadioButton radio) -{ - //radio_button_print_state(radio); - GSList *group = gtk_radio_button_get_group(radio); - int index = g_slist_length(group) - 1; - for (; group != 0; group = g_slist_next(group)) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(group->data))) { - break; - } else { - index--; - } - } - return index; -} diff --git a/libs/gtkutil/button.h b/libs/gtkutil/button.h deleted file mode 100644 index 908f6a0..0000000 --- a/libs/gtkutil/button.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_BUTTON_H ) -#define INCLUDED_GTKUTIL_BUTTON_H - -#include -#include "generic/callback.h" - -typedef int gint; -typedef gint gboolean; -typedef unsigned int guint; - -void button_connect_callback(ui::Button button, const Callback &callback); - -void button_connect_callback(ui::ToolButton button, const Callback &callback); - -guint toggle_button_connect_callback(ui::ToggleButton button, const Callback &callback); - -guint toggle_button_connect_callback(ui::ToggleToolButton button, const Callback &callback); - -void button_set_icon(ui::Button button, const char *icon); - -void toggle_button_set_active_no_signal(ui::ToggleButton item, gboolean active); - -void toggle_button_set_active_no_signal(ui::ToggleToolButton item, gboolean active); - -void radio_button_set_active(ui::RadioButton radio, int index); - -void radio_button_set_active_no_signal(ui::RadioButton radio, int index); - -int radio_button_get_active(ui::RadioButton radio); - -#endif diff --git a/libs/gtkutil/clipboard.cpp b/libs/gtkutil/clipboard.cpp deleted file mode 100644 index daab030..0000000 --- a/libs/gtkutil/clipboard.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "clipboard.h" - -#include "globaldefs.h" -#include "stream/memstream.h" -#include "stream/textstream.h" - - -/// \file -/// \brief Platform-independent GTK clipboard support. -/// \todo Using GDK_SELECTION_CLIPBOARD fails on win32, so we use the win32 API directly for now. -#if GDEF_OS_WINDOWS - -const char* c_clipboard_format = "RadiantClippings"; - -#include - -void clipboard_copy( ClipboardCopyFunc copy ){ - BufferOutputStream ostream; - copy( ostream ); - - bool bClipped = false; - UINT nClipboard = ::RegisterClipboardFormat( c_clipboard_format ); - if ( nClipboard > 0 ) { - if ( ::OpenClipboard( 0 ) ) { - EmptyClipboard(); - std::size_t length = ostream.size(); - HANDLE h = ::GlobalAlloc( GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, length + sizeof( std::size_t ) ); - if ( h != 0 ) { - char *buffer = reinterpret_cast( ::GlobalLock( h ) ); - *reinterpret_cast( buffer ) = length; - buffer += sizeof( std::size_t ); - memcpy( buffer, ostream.data(), length ); - ::GlobalUnlock( h ); - ::SetClipboardData( nClipboard, h ); - ::CloseClipboard(); - bClipped = true; - } - } - } - - if ( !bClipped ) { - globalOutputStream() << "Unable to register Windows clipboard formats, copy/paste between editors will not be possible\n"; - } -} - -void clipboard_paste( ClipboardPasteFunc paste ){ - UINT nClipboard = ::RegisterClipboardFormat( c_clipboard_format ); - if ( nClipboard > 0 && ::OpenClipboard( 0 ) ) { - if ( IsClipboardFormatAvailable( nClipboard ) ) { - HANDLE h = ::GetClipboardData( nClipboard ); - if ( h ) { - const char *buffer = reinterpret_cast( ::GlobalLock( h ) ); - std::size_t length = *reinterpret_cast( buffer ); - buffer += sizeof( std::size_t ); - BufferInputStream istream( buffer, length ); - paste( istream ); - ::GlobalUnlock( h ); - } - } - ::CloseClipboard(); - } -} - -#else - -#include - -enum { - RADIANT_CLIPPINGS = 23, -}; - -static char RADIANT_CLIPPINGS_STR[] = "RADIANT_CLIPPINGS"; - -static const GtkTargetEntry clipboard_targets[] = { - {RADIANT_CLIPPINGS_STR, 0, RADIANT_CLIPPINGS,}, -}; - -static void clipboard_get(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer data) -{ - std::size_t len = *reinterpret_cast( data ); - const char *buffer = (len != 0) ? reinterpret_cast( data ) + sizeof(std::size_t) : 0; - - GdkAtom type = GDK_NONE; - if (info == clipboard_targets[0].info) { - type = gdk_atom_intern(clipboard_targets[0].target, FALSE); - } - - gtk_selection_data_set(selection_data, type, 8, reinterpret_cast( buffer ), - static_cast( len )); -} - -static void clipboard_clear(GtkClipboard *clipboard, gpointer data) -{ - delete[] reinterpret_cast( data ); -} - -static void clipboard_received(GtkClipboard *clipboard, GtkSelectionData *data, gpointer user_data) -{ - if (gtk_selection_data_get_length(data) < 0) { - globalErrorStream() << "Error retrieving selection\n"; - } else if (strcmp(gdk_atom_name(gtk_selection_data_get_data_type(data)), clipboard_targets[0].target) == 0) { - BufferInputStream istream(reinterpret_cast( gtk_selection_data_get_data(data)), - gtk_selection_data_get_length(data)); - (*reinterpret_cast( user_data ))(istream); - } -} - -void clipboard_copy(ClipboardCopyFunc copy) -{ - GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); - - BufferOutputStream ostream; - copy(ostream); - std::size_t length = ostream.size(); - char *data = new char[length + sizeof(std::size_t)]; - *reinterpret_cast( data ) = length; - memcpy(data + sizeof(std::size_t), ostream.data(), length); - - gtk_clipboard_set_with_data(clipboard, clipboard_targets, 1, clipboard_get, clipboard_clear, data); -} - -ClipboardPasteFunc g_clipboardPasteFunc = 0; - -void clipboard_paste(ClipboardPasteFunc paste) -{ - GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); - - g_clipboardPasteFunc = paste; - gtk_clipboard_request_contents(clipboard, gdk_atom_intern(clipboard_targets[0].target, FALSE), clipboard_received, - &g_clipboardPasteFunc); -} - - -#endif diff --git a/libs/gtkutil/clipboard.h b/libs/gtkutil/clipboard.h deleted file mode 100644 index ab8d48c..0000000 --- a/libs/gtkutil/clipboard.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_CLIPBOARD_H ) -#define INCLUDED_GTKUTIL_CLIPBOARD_H - -class TextOutputStream; - -typedef void ( *ClipboardCopyFunc )(TextOutputStream &); - -void clipboard_copy(ClipboardCopyFunc copy); - -class TextInputStream; - -typedef void ( *ClipboardPasteFunc )(TextInputStream &); - -void clipboard_paste(ClipboardPasteFunc paste); - -#endif diff --git a/libs/gtkutil/closure.h b/libs/gtkutil/closure.h deleted file mode 100644 index f5d7802..0000000 --- a/libs/gtkutil/closure.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_CLOSURE_H ) -#define INCLUDED_GTKUTIL_CLOSURE_H - -#include -#include "generic/callback.h" - -inline void closure_destroy(gpointer data, GClosure *closure) -{ - delete reinterpret_cast *>( data ); -} - -inline GClosure *create_cclosure(GCallback func, const Callback &callback) -{ - return g_cclosure_new(func, new Callback(callback), closure_destroy); -} - -inline GValue GValue_default() -{ - GValue value; - value.g_type = 0; - return value; -} - -inline gint object_get_int_property(GObject *object, const char *property) -{ - GValue gvalue = GValue_default(); - g_value_init(&gvalue, G_TYPE_INT); - g_object_get_property(object, property, &gvalue); - return g_value_get_int(&gvalue); -} - -inline void object_set_int_property(GObject *object, const char *property, gint value) -{ - GValue gvalue = GValue_default(); - g_value_init(&gvalue, G_TYPE_INT); - g_value_set_int(&gvalue, value); - g_object_set_property(object, property, &gvalue); -} - -inline gboolean object_get_boolean_property(GObject *object, const char *property) -{ - GValue gvalue = GValue_default(); - g_value_init(&gvalue, G_TYPE_BOOLEAN); - g_object_get_property(object, property, &gvalue); - return g_value_get_boolean(&gvalue); -} - -inline void object_set_boolean_property(GObject *object, const char *property, gboolean value) -{ - GValue gvalue = GValue_default(); - g_value_init(&gvalue, G_TYPE_BOOLEAN); - g_value_set_boolean(&gvalue, value); - g_object_set_property(object, property, &gvalue); -} - -#endif diff --git a/libs/gtkutil/container.h b/libs/gtkutil/container.h deleted file mode 100644 index a814bfb..0000000 --- a/libs/gtkutil/container.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_CONTAINER_H ) -#define INCLUDED_GTKUTIL_CONTAINER_H - -inline void container_remove_all(ui::Container container) -{ - container.foreach([=](ui::Widget it) mutable { - container.remove(it); - }); -} - -#endif diff --git a/libs/gtkutil/cursor.cpp b/libs/gtkutil/cursor.cpp deleted file mode 100644 index 862df9c..0000000 --- a/libs/gtkutil/cursor.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "cursor.h" - -#include "stream/textstream.h" - -#include -#include -#include - - -GdkCursor *create_blank_cursor() -{ - return gdk_cursor_new(GDK_BLANK_CURSOR); -} - -void blank_cursor(ui::Widget widget) -{ - GdkCursor *cursor = create_blank_cursor(); - gdk_window_set_cursor(gtk_widget_get_window(widget), cursor); - gdk_cursor_unref(cursor); -} - -void default_cursor(ui::Widget widget) -{ - gdk_window_set_cursor(gtk_widget_get_window(widget), 0); -} - - -void Sys_GetCursorPos(ui::Window window, int *x, int *y) -{ - gdk_display_get_pointer(gdk_display_get_default(), 0, x, y, 0); -} - -void Sys_SetCursorPos(ui::Window window, int x, int y) -{ - GdkScreen *screen; - gdk_display_get_pointer(gdk_display_get_default(), &screen, 0, 0, 0); - gdk_display_warp_pointer(gdk_display_get_default(), screen, x, y); -} - -gboolean DeferredMotion::gtk_motion(ui::Widget widget, GdkEventMotion *event, DeferredMotion *self) -{ - self->motion(event->x, event->y, event->state); - return FALSE; -} - -gboolean FreezePointer::motion_delta(ui::Window widget, GdkEventMotion *event, FreezePointer *self) -{ - int current_x, current_y; - Sys_GetCursorPos(widget, ¤t_x, ¤t_y); - int dx = current_x - self->last_x; - int dy = current_y - self->last_y; - int ddx = current_x - self->recorded_x; - int ddy = current_y - self->recorded_y; - self->last_x = current_x; - self->last_y = current_y; - if (dx != 0 || dy != 0) { - //globalOutputStream() << "motion x: " << dx << ", y: " << dy << "\n"; - if (ddx < -32 || ddx > 32 || ddy < -32 || ddy > 32) { - Sys_SetCursorPos(widget, self->recorded_x, self->recorded_y); - self->last_x = self->recorded_x; - self->last_y = self->recorded_y; - } - self->m_function(dx, dy, event->state, self->m_data); - } - return FALSE; -} - -void FreezePointer::freeze_pointer(ui::Window window, FreezePointer::MotionDeltaFunction function, void *data) -{ - ASSERT_MESSAGE(m_function == 0, "can't freeze pointer"); - - const GdkEventMask mask = static_cast( GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK - | GDK_BUTTON_MOTION_MASK - | GDK_BUTTON1_MOTION_MASK - | GDK_BUTTON2_MOTION_MASK - | GDK_BUTTON3_MOTION_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_VISIBILITY_NOTIFY_MASK ); - - GdkCursor *cursor = create_blank_cursor(); - //GdkGrabStatus status = - gdk_pointer_grab(gtk_widget_get_window(window), TRUE, mask, 0, cursor, GDK_CURRENT_TIME); - gdk_cursor_unref(cursor); - - Sys_GetCursorPos(window, &recorded_x, &recorded_y); - - Sys_SetCursorPos(window, recorded_x, recorded_y); - - last_x = recorded_x; - last_y = recorded_y; - - m_function = function; - m_data = data; - - handle_motion = window.connect("motion_notify_event", G_CALLBACK(motion_delta), this); -} - -void FreezePointer::unfreeze_pointer(ui::Window window) -{ - g_signal_handler_disconnect(G_OBJECT(window), handle_motion); - - m_function = 0; - m_data = 0; - - Sys_SetCursorPos(window, recorded_x, recorded_y); - - gdk_pointer_ungrab(GDK_CURRENT_TIME); -} diff --git a/libs/gtkutil/cursor.h b/libs/gtkutil/cursor.h deleted file mode 100644 index 045494d..0000000 --- a/libs/gtkutil/cursor.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_CURSOR_H ) -#define INCLUDED_GTKUTIL_CURSOR_H - -#include - -#include "debugging/debugging.h" - -typedef struct _GdkCursor GdkCursor; -typedef struct _GdkEventMotion GdkEventMotion; - -GdkCursor *create_blank_cursor(); - -void blank_cursor(ui::Widget widget); - -void default_cursor(ui::Widget widget); - -void Sys_GetCursorPos(ui::Window window, int *x, int *y); - -void Sys_SetCursorPos(ui::Window window, int x, int y); - - -class DeferredMotion { -guint m_handler; - -typedef void ( *MotionFunction )(gdouble x, gdouble y, guint state, void *data); - -MotionFunction m_function; -void *m_data; -gdouble m_x; -gdouble m_y; -guint m_state; - -static gboolean deferred(DeferredMotion *self) -{ - self->m_handler = 0; - self->m_function(self->m_x, self->m_y, self->m_state, self->m_data); - return FALSE; -} - -public: -DeferredMotion(MotionFunction function, void *data) : m_handler(0), m_function(function), m_data(data) -{ -} - -void motion(gdouble x, gdouble y, guint state) -{ - m_x = x; - m_y = y; - m_state = state; - if (m_handler == 0) { - m_handler = g_idle_add((GSourceFunc) deferred, this); - } -} - -static gboolean gtk_motion(ui::Widget widget, GdkEventMotion *event, DeferredMotion *self); -}; - -class DeferredMotionDelta { -int m_delta_x; -int m_delta_y; -guint m_motion_handler; - -typedef void ( *MotionDeltaFunction )(int x, int y, void *data); - -MotionDeltaFunction m_function; -void *m_data; - -static gboolean deferred_motion(gpointer data) -{ - reinterpret_cast( data )->m_function( - reinterpret_cast( data )->m_delta_x, - reinterpret_cast( data )->m_delta_y, - reinterpret_cast( data )->m_data - ); - reinterpret_cast( data )->m_motion_handler = 0; - reinterpret_cast( data )->m_delta_x = 0; - reinterpret_cast( data )->m_delta_y = 0; - return FALSE; -} - -public: -DeferredMotionDelta(MotionDeltaFunction function, void *data) : m_delta_x(0), m_delta_y(0), m_motion_handler(0), - m_function(function), m_data(data) -{ -} - -void flush() -{ - if (m_motion_handler != 0) { - g_source_remove(m_motion_handler); - deferred_motion(this); - } -} - -void motion_delta(int x, int y, unsigned int state) -{ - m_delta_x += x; - m_delta_y += y; - if (m_motion_handler == 0) { - m_motion_handler = g_idle_add(deferred_motion, this); - } -} -}; - -class FreezePointer { -unsigned int handle_motion; -int recorded_x, recorded_y, last_x, last_y; - -typedef void ( *MotionDeltaFunction )(int x, int y, unsigned int state, void *data); - -MotionDeltaFunction m_function; -void *m_data; -public: -FreezePointer() : handle_motion(0), m_function(0), m_data(0) -{ -} - -static gboolean motion_delta(ui::Window widget, GdkEventMotion *event, FreezePointer *self); - -void freeze_pointer(ui::Window window, MotionDeltaFunction function, void *data); - -void unfreeze_pointer(ui::Window window); -}; - -#endif diff --git a/libs/gtkutil/dialog.cpp b/libs/gtkutil/dialog.cpp deleted file mode 100644 index 786af87..0000000 --- a/libs/gtkutil/dialog.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dialog.h" - -#include - -#include "button.h" -#include "window.h" - -ui::VBox create_dialog_vbox(int spacing, int border) -{ - auto vbox = ui::VBox(FALSE, spacing); - vbox.show(); - gtk_container_set_border_width(GTK_CONTAINER(vbox), border); - return vbox; -} - -ui::HBox create_dialog_hbox(int spacing, int border) -{ - auto hbox = ui::HBox(FALSE, spacing); - hbox.show(); - gtk_container_set_border_width(GTK_CONTAINER(hbox), border); - return hbox; -} - -ui::Frame create_dialog_frame(const char *label, ui::Shadow shadow) -{ - auto frame = ui::Frame(label); - frame.show(); - gtk_frame_set_shadow_type(frame, (GtkShadowType) shadow); - return frame; -} - -ui::Table -create_dialog_table(unsigned int rows, unsigned int columns, unsigned int row_spacing, unsigned int col_spacing, - int border) -{ - auto table = ui::Table(rows, columns, FALSE); - table.show(); - gtk_table_set_row_spacings(table, row_spacing); - gtk_table_set_col_spacings(table, col_spacing); - gtk_container_set_border_width(GTK_CONTAINER(table), border); - return table; -} - -ui::Button create_dialog_button(const char *label, GCallback func, gpointer data) -{ - auto button = ui::Button(label); - button.dimensions(64, -1); - button.show(); - button.connect("clicked", func, data); - return button; -} - -ui::Window -create_dialog_window(ui::Window parent, const char *title, GCallback func, gpointer data, int default_w, int default_h) -{ - ui::Window window = create_floating_window(title, parent); - gtk_window_set_default_size(window, default_w, default_h); - gtk_window_set_position(window, GTK_WIN_POS_CENTER_ON_PARENT); - window.connect("delete_event", func, data); - - return window; -} - -gboolean modal_dialog_button_clicked(ui::Widget widget, ModalDialogButton *button) -{ - button->m_dialog.loop = false; - button->m_dialog.ret = button->m_value; - return TRUE; -} - -gboolean modal_dialog_delete(ui::Widget widget, GdkEvent *event, ModalDialog *dialog) -{ - dialog->loop = 0; - dialog->ret = eIDCANCEL; - return TRUE; -} - -EMessageBoxReturn modal_dialog_show(ui::Window window, ModalDialog &dialog) -{ - gtk_grab_add(window); - window.show(); - - dialog.loop = true; - while (dialog.loop) { - gtk_main_iteration(); - } - - window.hide(); - gtk_grab_remove(window); - - return dialog.ret; -} - -ui::Button create_modal_dialog_button(const char *label, ModalDialogButton &button) -{ - return create_dialog_button(label, G_CALLBACK(modal_dialog_button_clicked), &button); -} - -ui::Window -create_modal_dialog_window(ui::Window parent, const char *title, ModalDialog &dialog, int default_w, int default_h) -{ - return create_dialog_window(parent, title, G_CALLBACK(modal_dialog_delete), &dialog, default_w, default_h); -} - -ui::Window -create_fixedsize_modal_dialog_window(ui::Window parent, const char *title, ModalDialog &dialog, int width, int height) -{ - auto window = create_modal_dialog_window(parent, title, dialog, width, height); - - gtk_window_set_resizable(window, FALSE); - gtk_window_set_modal(window, TRUE); - gtk_window_set_position(window, GTK_WIN_POS_CENTER); - - window_remove_minmax(window); - - //window.dimensions(width, height); - //gtk_window_set_default_size(window, width, height); - //gtk_window_resize(window, width, height); - //GdkGeometry geometry = { width, height, -1, -1, width, height, -1, -1, -1, -1, GDK_GRAVITY_STATIC, }; - //gtk_window_set_geometry_hints(window, window, &geometry, (GdkWindowHints)(GDK_HINT_POS|GDK_HINT_MIN_SIZE|GDK_HINT_BASE_SIZE)); - - return window; -} - -gboolean dialog_button_ok(ui::Widget widget, ModalDialog *data) -{ - data->loop = false; - data->ret = eIDOK; - return TRUE; -} - -gboolean dialog_button_cancel(ui::Widget widget, ModalDialog *data) -{ - data->loop = false; - data->ret = eIDCANCEL; - return TRUE; -} - -gboolean dialog_button_yes(ui::Widget widget, ModalDialog *data) -{ - data->loop = false; - data->ret = eIDYES; - return TRUE; -} - -gboolean dialog_button_no(ui::Widget widget, ModalDialog *data) -{ - data->loop = false; - data->ret = eIDNO; - return TRUE; -} - -gboolean dialog_delete_callback(ui::Widget widget, GdkEventAny *event, ModalDialog *data) -{ - widget.hide(); - data->loop = false; - return TRUE; -} - -ui::Window create_simple_modal_dialog_window(const char *title, ModalDialog &dialog, ui::Widget contents) -{ - ui::Window window = create_fixedsize_modal_dialog_window(ui::Window{ui::null}, title, dialog); - - auto vbox1 = create_dialog_vbox(8, 4); - window.add(vbox1); - - vbox1.add(contents); - - ui::Alignment alignment = ui::Alignment(0.5, 0.0, 0.0, 0.0); - alignment.show(); - vbox1.pack_start(alignment, FALSE, FALSE, 0); - - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &dialog); - alignment.add(button); - - return window; -} - -RadioHBox RadioHBox_new(StringArrayRange names) -{ - auto hbox = ui::HBox(TRUE, 4); - hbox.show(); - - GSList *group = 0; - auto radio = ui::RadioButton(ui::null); - for (StringArrayRange::Iterator i = names.first; i != names.last; ++i) { - radio = ui::RadioButton::from(gtk_radio_button_new_with_label(group, *i)); - radio.show(); - hbox.pack_start(radio, FALSE, FALSE, 0); - - group = gtk_radio_button_get_group(radio); - } - - return RadioHBox(hbox, radio); -} - - -PathEntry PathEntry_new() -{ - auto frame = ui::Frame(); - frame.show(); - gtk_frame_set_shadow_type(frame, GTK_SHADOW_IN); - - // path entry - auto hbox = ui::HBox(FALSE, 0); - hbox.show(); - - auto entry = ui::Entry(ui::New); - gtk_entry_set_has_frame(entry, FALSE); - entry.show(); - hbox.pack_start(entry, TRUE, TRUE, 0); - - // browse button - auto button = ui::Button(ui::New); - button_set_icon(button, "ellipsis.bmp"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - - frame.add(hbox); - - return PathEntry(frame, entry, button); -} - -void PathEntry_setPath(PathEntry &self, const char *path) -{ - gtk_entry_set_text(self.m_entry, path); -} - -typedef ReferenceCaller PathEntrySetPathCaller; - -void BrowsedPathEntry_clicked(ui::Widget widget, BrowsedPathEntry *self) -{ - self->m_browse(PathEntrySetPathCaller(self->m_entry)); -} - -BrowsedPathEntry::BrowsedPathEntry(const BrowseCallback &browse) : - m_entry(PathEntry_new()), - m_browse(browse) -{ - m_entry.m_button.connect("clicked", G_CALLBACK(BrowsedPathEntry_clicked), this); -} - - -ui::Label DialogLabel_new(const char *name) -{ - auto label = ui::Label(name); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - - return label; -} - -ui::Table DialogRow_new(const char *name, ui::Widget widget) -{ - auto table = ui::Table(1, 3, TRUE); - table.show(); - - gtk_table_set_col_spacings(table, 4); - gtk_table_set_row_spacings(table, 0); - - table.attach(DialogLabel_new(name), {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - table.attach(widget, {1, 3, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - return table; -} - -void DialogVBox_packRow(ui::Box vbox, ui::Widget row) -{ - vbox.pack_start(row, FALSE, FALSE, 0); -} diff --git a/libs/gtkutil/dialog.h b/libs/gtkutil/dialog.h deleted file mode 100644 index 5c246c5..0000000 --- a/libs/gtkutil/dialog.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_DIALOG_H ) -#define INCLUDED_GTKUTIL_DIALOG_H - -#include "generic/callback.h" -#include "generic/arrayrange.h" -#include "qerplugin.h" - -typedef int gint; -typedef gint gboolean; -typedef struct _GdkEventAny GdkEventAny; - - -struct ModalDialog { - ModalDialog() - : loop(true), ret(eIDCANCEL) - { - } - - bool loop; - EMessageBoxReturn ret; -}; - -struct ModalDialogButton { - ModalDialogButton(ModalDialog &dialog, EMessageBoxReturn value) - : m_dialog(dialog), m_value(value) - { - } - - ModalDialog &m_dialog; - EMessageBoxReturn m_value; -}; - -typedef void ( *GCallback )(void); - -typedef void *gpointer; - -ui::Window create_fixedsize_modal_window(ui::Window parent, const char *title, int width, int height); - -ui::Window create_dialog_window(ui::Window parent, const char *title, GCallback func, gpointer data, int default_w = -1, - int default_h = -1); - -ui::Table -create_dialog_table(unsigned int rows, unsigned int columns, unsigned int row_spacing, unsigned int col_spacing, - int border = 0); - -ui::Button create_dialog_button(const char *label, GCallback func, gpointer data); - -ui::VBox create_dialog_vbox(int spacing, int border = 0); - -ui::HBox create_dialog_hbox(int spacing, int border = 0); - -ui::Frame create_dialog_frame(const char *label, ui::Shadow shadow = ui::Shadow::ETCHED_IN); - -ui::Button create_modal_dialog_button(const char *label, ModalDialogButton &button); - -ui::Window create_modal_dialog_window(ui::Window parent, const char *title, ModalDialog &dialog, int default_w = -1, - int default_h = -1); - -ui::Window -create_fixedsize_modal_dialog_window(ui::Window parent, const char *title, ModalDialog &dialog, int width = -1, - int height = -1); - -EMessageBoxReturn modal_dialog_show(ui::Window window, ModalDialog &dialog); - - -gboolean dialog_button_ok(ui::Widget widget, ModalDialog *data); - -gboolean dialog_button_cancel(ui::Widget widget, ModalDialog *data); - -gboolean dialog_button_yes(ui::Widget widget, ModalDialog *data); - -gboolean dialog_button_no(ui::Widget widget, ModalDialog *data); - -gboolean dialog_delete_callback(ui::Widget widget, GdkEventAny *event, ModalDialog *data); - -ui::Window create_simple_modal_dialog_window(const char *title, ModalDialog &dialog, ui::Widget contents); - -class RadioHBox { -public: -ui::HBox m_hbox; -ui::RadioButton m_radio; - -RadioHBox(ui::HBox hbox, ui::RadioButton radio) : - m_hbox(hbox), - m_radio(radio) -{ -} -}; - -RadioHBox RadioHBox_new(StringArrayRange names); - - -class PathEntry { -public: -ui::Frame m_frame; -ui::Entry m_entry; -ui::Button m_button; - -PathEntry(ui::Frame frame, ui::Entry entry, ui::Button button) : - m_frame(frame), - m_entry(entry), - m_button(button) -{ -} -}; - -PathEntry PathEntry_new(); - -class BrowsedPathEntry { -public: -typedef Callback SetPathCallback; -typedef Callback BrowseCallback; - -PathEntry m_entry; -BrowseCallback m_browse; - -BrowsedPathEntry(const BrowseCallback &browse); -}; - -ui::Label DialogLabel_new(const char *name); - -ui::Table DialogRow_new(const char *name, ui::Widget widget); - -void DialogVBox_packRow(ui::Box vbox, ui::Widget row); - - -#endif diff --git a/libs/gtkutil/entry.cpp b/libs/gtkutil/entry.cpp deleted file mode 100644 index 7d2554c..0000000 --- a/libs/gtkutil/entry.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "entry.h" - -#include - -void entry_set_string(ui::Entry entry, const char *string) -{ - gtk_entry_set_text(entry, string); -} - -void entry_set_int(ui::Entry entry, int i) -{ - char buf[32]; - sprintf(buf, "%d", i); - entry_set_string(entry, buf); -} - -void entry_set_float(ui::Entry entry, float f) -{ - char buf[32]; - sprintf(buf, "%g", f); - entry_set_string(entry, buf); -} - -const char *entry_get_string(ui::Entry entry) -{ - return gtk_entry_get_text(entry); -} - -int entry_get_int(ui::Entry entry) -{ - return atoi(entry_get_string(entry)); -} - -double entry_get_float(ui::Entry entry) -{ - return atof(entry_get_string(entry)); -} diff --git a/libs/gtkutil/entry.h b/libs/gtkutil/entry.h deleted file mode 100644 index 067157a..0000000 --- a/libs/gtkutil/entry.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_ENTRY_H ) -#define INCLUDED_GTKUTIL_ENTRY_H - -void entry_set_string(ui::Entry entry, const char *string); - -void entry_set_int(ui::Entry entry, int i); - -void entry_set_float(ui::Entry entry, float f); - -const char *entry_get_string(ui::Entry entry); - -int entry_get_int(ui::Entry entry); - -double entry_get_float(ui::Entry entry); - -#endif diff --git a/libs/gtkutil/filechooser.cpp b/libs/gtkutil/filechooser.cpp deleted file mode 100644 index 5b0898a..0000000 --- a/libs/gtkutil/filechooser.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "filechooser.h" - -#include "ifiletypes.h" - -#include -#include -#include -#include - -#include "string/string.h" -#include "stream/stringstream.h" -#include "container/array.h" -#include "os/path.h" -#include "os/file.h" - -#include "messagebox.h" - - -struct filetype_pair_t { - filetype_pair_t() - : m_moduleName("") - { - } - - filetype_pair_t(const char *moduleName, filetype_t type) - : m_moduleName(moduleName), m_type(type) - { - } - - const char *m_moduleName; - filetype_t m_type; -}; - -class FileTypeList : public IFileTypeList { -struct filetype_copy_t { - filetype_copy_t(const filetype_pair_t &other) - : m_moduleName(other.m_moduleName), m_name(other.m_type.name), m_pattern(other.m_type.pattern) - { - } - - CopiedString m_moduleName; - CopiedString m_name; - CopiedString m_pattern; -}; - -typedef std::list Types; -Types m_types; -public: - -typedef Types::const_iterator const_iterator; - -const_iterator begin() const -{ - return m_types.begin(); -} - -const_iterator end() const -{ - return m_types.end(); -} - -std::size_t size() const -{ - return m_types.size(); -} - -void addType(const char *moduleName, filetype_t type) -{ - m_types.push_back(filetype_pair_t(moduleName, type)); -} -}; - - -class GTKMasks { -const FileTypeList &m_types; -public: -std::vector m_filters; -std::vector m_masks; - -GTKMasks(const FileTypeList &types) : m_types(types) -{ - m_masks.reserve(m_types.size()); - for (FileTypeList::const_iterator i = m_types.begin(); i != m_types.end(); ++i) { - std::size_t len = strlen((*i).m_name.c_str()) + strlen((*i).m_pattern.c_str()) + 3; - StringOutputStream buffer(len + 1); // length + null char - - buffer << (*i).m_name.c_str() << " <" << (*i).m_pattern.c_str() << ">"; - - m_masks.push_back(buffer.c_str()); - } - - m_filters.reserve(m_types.size()); - for (FileTypeList::const_iterator i = m_types.begin(); i != m_types.end(); ++i) { - m_filters.push_back((*i).m_pattern); - } -} - -filetype_pair_t GetTypeForGTKMask(const char *mask) const -{ - std::vector::const_iterator j = m_masks.begin(); - for (FileTypeList::const_iterator i = m_types.begin(); i != m_types.end(); ++i, ++j) { - if (string_equal((*j).c_str(), mask)) { - return filetype_pair_t((*i).m_moduleName.c_str(), - filetype_t((*i).m_name.c_str(), (*i).m_pattern.c_str())); - } - } - return filetype_pair_t(); -} - -}; - -static char g_file_dialog_file[1024]; - -const char * -file_dialog_show(ui::Window parent, bool open, const char *title, const char *path, const char *pattern, bool want_load, - bool want_import, bool want_save) -{ - filetype_t type; - - if (pattern == 0) { - pattern = "*"; - } - - FileTypeList typelist; - GlobalFiletypes().getTypeList(pattern, &typelist, want_load, want_import, want_save); - - GTKMasks masks(typelist); - - if (title == 0) { - title = open ? "Open File" : "Save File"; - } - - ui::Dialog dialog{ui::null}; - if (open) { - dialog = ui::Dialog::from(gtk_file_chooser_dialog_new(title, - parent, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL)); - } else { - dialog = ui::Dialog::from(gtk_file_chooser_dialog_new(title, - parent, - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL)); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "unnamed"); - } - - gtk_window_set_modal(dialog, TRUE); - gtk_window_set_position(dialog, GTK_WIN_POS_CENTER_ON_PARENT); - - // we expect an actual path below, if the path is 0 we might crash - if (path != 0 && !string_empty(path)) { - ASSERT_MESSAGE(path_is_absolute(path), "file_dialog_show: path not absolute: " << makeQuoted(path)); - - Array new_path(strlen(path) + 1); - - // copy path, replacing dir separators as appropriate - Array::iterator w = new_path.begin(); - for (const char *r = path; *r != '\0'; ++r) { - *w++ = (*r == '/') ? G_DIR_SEPARATOR : *r; - } - // remove separator from end of path if required - if (*(w - 1) == G_DIR_SEPARATOR) { - --w; - } - // terminate string - *w = '\0'; - - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), new_path.data()); - } - - // we should add all important paths as shortcut folder... - // gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog), "/tmp/", NULL); - - - for (std::size_t i = 0; i < masks.m_filters.size(); ++i) { - GtkFileFilter *filter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(filter, masks.m_filters[i].c_str()); - gtk_file_filter_set_name(filter, masks.m_masks[i].c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); - } - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - strcpy(g_file_dialog_file, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))); - - if (!string_equal(pattern, "*")) { - GtkFileFilter *filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog)); - if (filter != - 0) { // no filter set? some file-chooser implementations may allow the user to set no filter, which we treat as 'all files' - type = masks.GetTypeForGTKMask(gtk_file_filter_get_name(filter)).m_type; - // last ext separator - const char *extension = path_get_extension(g_file_dialog_file); - // no extension - if (string_empty(extension)) { - strcat(g_file_dialog_file, type.pattern + 1); - } else { - strcpy(g_file_dialog_file + (extension - g_file_dialog_file), type.pattern + 2); - } - } - } - - // convert back to unix format - for (char *w = g_file_dialog_file; *w != '\0'; w++) { - if (*w == '\\') { - *w = '/'; - } - } - } else { - g_file_dialog_file[0] = '\0'; - } - - ui::Widget(dialog).destroy(); - - // don't return an empty filename - if (g_file_dialog_file[0] == '\0') { - return NULL; - } - - return g_file_dialog_file; -} - -char *dir_dialog(ui::Window parent, const char *title, const char *path) -{ - auto dialog = ui::Dialog::from(gtk_file_chooser_dialog_new(title, - parent, - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL)); - - gtk_window_set_modal(dialog, TRUE); - gtk_window_set_position(dialog, GTK_WIN_POS_CENTER_ON_PARENT); - - if (!string_empty(path)) { - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); - } - - char *filename = 0; - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - } - - dialog.destroy(); - - return filename; -} - -const char * -file_dialog(ui::Window parent, bool open, const char *title, const char *path, const char *pattern, bool want_load, - bool want_import, bool want_save) -{ - for (;;) { - const char *file = file_dialog_show(parent, open, title, path, pattern, want_load, want_import, want_save); - - if (open - || !file - || !file_exists(file) - || ui::alert(parent, "The file specified already exists.\nDo you want to replace it?", title, - ui::alert_type::NOYES, ui::alert_icon::Question) == ui::alert_response::YES) { - return file; - } - } -} diff --git a/libs/gtkutil/filechooser.h b/libs/gtkutil/filechooser.h deleted file mode 100644 index e2b2b25..0000000 --- a/libs/gtkutil/filechooser.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_FILECHOOSER_H ) -#define INCLUDED_GTKUTIL_FILECHOOSER_H - -/// \file -/// GTK+ file-chooser dialogs. - -const char *file_dialog(ui::Window parent, bool open, const char *title, const char *path = 0, const char *pattern = 0, - bool want_load = false, bool want_import = false, bool want_save = false); - - -/// \brief Prompts the user to browse for a directory. -/// The prompt window will be transient to \p parent. -/// The directory will initially default to \p path, which must be an absolute path. -/// The returned string is allocated with \c g_malloc and must be freed with \c g_free. -char *dir_dialog(ui::Window parent, const char *title = "Choose Directory", const char *path = ""); - -#endif diff --git a/libs/gtkutil/frame.cpp b/libs/gtkutil/frame.cpp deleted file mode 100644 index 1f289d2..0000000 --- a/libs/gtkutil/frame.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "frame.h" - -#include -#include - -ui::Frame create_framed_widget(ui::Widget widget) -{ - auto frame = ui::Frame(); - frame.show(); - gtk_frame_set_shadow_type(frame, GTK_SHADOW_IN); - frame.add(widget); - widget.show(); - return frame; -} diff --git a/libs/gtkutil/frame.h b/libs/gtkutil/frame.h deleted file mode 100644 index f35f9dc..0000000 --- a/libs/gtkutil/frame.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_FRAME_H ) -#define INCLUDED_GTKUTIL_FRAME_H - -ui::Frame create_framed_widget(ui::Widget widget); - -#endif diff --git a/libs/gtkutil/glfont.cpp b/libs/gtkutil/glfont.cpp deleted file mode 100644 index da0cd4f..0000000 --- a/libs/gtkutil/glfont.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "glfont.h" -#include "globaldefs.h" -#include "igl.h" - -// generic string printing with call lists -class GLFontCallList : public GLFont { -GLuint m_displayList; -int m_pixelHeight; -int m_pixelAscent; -int m_pixelDescent; -public: -GLFontCallList(GLuint displayList, int asc, int desc, int pixelHeight) : m_displayList(displayList), - m_pixelHeight(pixelHeight), - m_pixelAscent(asc), m_pixelDescent(desc) -{ -} - -virtual ~GLFontCallList() -{ - glDeleteLists(m_displayList, 256); -} - -void printString(const char *s) -{ - GlobalOpenGL().m_glListBase(m_displayList); - GlobalOpenGL().m_glCallLists(GLsizei(strlen(s)), GL_UNSIGNED_BYTE, reinterpret_cast( s )); -} - -virtual int getPixelAscent() const -{ - return m_pixelAscent; -} - -virtual int getPixelDescent() const -{ - return m_pixelDescent; -} - -virtual int getPixelHeight() const -{ - return m_pixelHeight; -} -}; - -#if GDEF_OS_WINDOWS -#include -#endif - -#include "debugging/debugging.h" - -// LordHavoc: this is code for direct Xlib bitmap character fetching, as an -// alternative to requiring gtkglarea, it was created due to a lack of this -// package on SuSE 9.x but this package is now commonly shipping in Linux -// distributions so this code may be unnecessary, feel free however to enable -// it when building packages for distros that do not ship with that package, -// or if you just prefer less dependencies... -#if 0 - -#include -#include -#include - -GLFont *glfont_create( const char* font_string ){ - GLuint font_list_base; - XFontStruct *fontInfo; - Display *dpy = GDK_DISPLAY(); - unsigned int i, first, last, firstrow, lastrow; - int maxchars; - int firstbitmap; - - fontInfo = XLoadQueryFont( dpy, "-*-fixed-*-*-*-*-8-*-*-*-*-*-*-*" ); - if ( fontInfo == NULL ) { - // try to load other fonts - fontInfo = XLoadQueryFont( dpy, "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*" ); - - // any font will do ! - if ( fontInfo == NULL ) { - fontInfo = XLoadQueryFont( dpy, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" ); - } - - if ( fontInfo == NULL ) { - ERROR_MESSAGE( "couldn't create font" ); - } - } - - first = (int)fontInfo->min_char_or_byte2; - last = (int)fontInfo->max_char_or_byte2; - firstrow = (int)fontInfo->min_byte1; - lastrow = (int)fontInfo->max_byte1; - /* - * How many chars in the charset - */ - maxchars = 256 * lastrow + last; - font_list_base = glGenLists( maxchars + 1 ); - if ( font_list_base == 0 ) { - ERROR_MESSAGE( "couldn't create font" ); - } - - /* - * Get offset to first char in the charset - */ - firstbitmap = 256 * firstrow + first; - /* - * for each row of chars, call glXUseXFont to build the bitmaps. - */ - - for ( i = firstrow; i <= lastrow; i++ ) - { - glXUseXFont( fontInfo->fid, firstbitmap, last - first + 1, font_list_base + firstbitmap ); - firstbitmap += 256; - } - -/* *height = fontInfo->ascent + fontInfo->descent; - * width = fontInfo->max_bounds.width; */ - return new GLFontCallList( font_list_base, fontInfo->ascent, fontInfo->descent, fontInfo->ascent + fontInfo->descent ); -} - -#elif 0 - -#include - -GLFont *glfont_create( const char* font_string ){ - GLuint font_list_base = glGenLists( 256 ); - gint font_height = 0, font_ascent = 0, font_descent = 0; - - PangoFontDescription* font_desc = pango_font_description_from_string( font_string ); - - PangoFont* font = gdk_gl_font_use_pango_font( font_desc, 0, 256, font_list_base ); - - if ( font == 0 ) { - pango_font_description_free( font_desc ); - font_desc = pango_font_description_from_string( "fixed 8" ); - font = gdk_gl_font_use_pango_font( font_desc, 0, 256, font_list_base ); - } - - if ( font == 0 ) { - pango_font_description_free( font_desc ); - font_desc = pango_font_description_from_string( "courier new 8" ); - font = gdk_gl_font_use_pango_font( font_desc, 0, 256, font_list_base ); - } - - if ( font != 0 ) { - PangoFontMetrics* font_metrics = pango_font_get_metrics( font, 0 ); - - font_ascent = pango_font_metrics_get_ascent( font_metrics ); - font_descent = pango_font_metrics_get_descent( font_metrics ); - font_height = font_ascent + font_descent; - - font_ascent = PANGO_PIXELS( font_ascent ); - font_descent = PANGO_PIXELS( font_descent ); - font_height = PANGO_PIXELS( font_height ); - - pango_font_metrics_unref( font_metrics ); - } - - pango_font_description_free( font_desc ); - - // fix for pango/gtkglext metrix bug - if ( font_height > 256 ) { - font_height = 16; - } - - return new GLFontCallList( font_list_base, font_ascent, font_descent, font_height ); -} -#else - -// new font code ripped from ZeroRadiant - -#include -#include -#include - -class GLFontInternal : public GLFont { -const char *font_string; -int font_height; -int font_ascent; -int font_descent; -int y_offset_bitmap_render_pango_units; -PangoContext *ft2_context; -PangoFontMap *fontmap; - -public: -GLFontInternal(const char *_font_string) : font_string(_font_string) -{ - PangoFontDescription *font_desc; - PangoLayout *layout; - PangoRectangle log_rect; - int font_ascent_pango_units; - int font_descent_pango_units; - -#if !PANGO_VERSION_CHECK(1, 22, 0) - ft2_context = pango_ft2_get_context( 72, 72 ); -#else - fontmap = pango_ft2_font_map_new(); - pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontmap), 72, 72); - ft2_context = pango_font_map_create_context(fontmap); -#endif - - font_desc = pango_font_description_from_string( "Liberation Mono 12" ); - //pango_font_description_set_size(font_desc, 10 * PANGO_SCALE); - pango_context_set_font_description(ft2_context, font_desc); - pango_font_description_free(font_desc); - // TODO fallback to fixed 8, courier new 8 - - layout = pango_layout_new(ft2_context); - -#ifdef FONT_SIZE_WORKAROUND - pango_layout_set_width( layout, -1 ); // -1 no wrapping. All text on one line. - pango_layout_set_text( layout, "The quick brown fox jumped over the lazy sleeping dog's back then sat on a tack.", -1 ); // -1 null-terminated string. -#endif - -#if !PANGO_VERSION_CHECK(1, 22, 0) - PangoLayoutIter *iter; - iter = pango_layout_get_iter( layout ); - font_ascent_pango_units = pango_layout_iter_get_baseline( iter ); - pango_layout_iter_free( iter ); -#else - font_ascent_pango_units = pango_layout_get_baseline(layout); -#endif - pango_layout_get_extents(layout, NULL, &log_rect); - g_object_unref(G_OBJECT(layout)); - font_descent_pango_units = log_rect.height - font_ascent_pango_units; - - font_ascent = PANGO_PIXELS_CEIL(font_ascent_pango_units); - font_descent = PANGO_PIXELS_CEIL(font_descent_pango_units); - font_height = font_ascent + font_descent; - y_offset_bitmap_render_pango_units = (font_ascent * PANGO_SCALE) - font_ascent_pango_units; -} - -virtual ~GLFontInternal() -{ - g_object_unref(G_OBJECT(ft2_context)); - g_object_unref(G_OBJECT(fontmap)); -} - -// Renders the input text at the current location with the current color. -// The X position of the current location is used to place the left edge of the text image, -// where the text image bounds are defined as the logical extents of the line of text. -// The Y position of the current location is used to place the bottom of the text image. -// You should offset the Y position by the amount returned by gtk_glwidget_font_descent() -// if you want to place the baseline of the text image at the current Y position. -// Note: A problem with this function is that if the lower left corner of the text falls -// just a hair outside of the viewport (meaning the current raster position is invalid), -// then no text will be rendered. The solution to this is a very hacky one. You can search -// Google for "glDrawPixels clipping". -virtual void printString(const char *s) -{ - // The idea for this code initially came from the font-pangoft2.c example that comes with GtkGLExt. - - PangoLayout *layout; - PangoRectangle log_rect; - FT_Bitmap bitmap; - unsigned char *begin_bitmap_buffer; - GLfloat color[4]; - GLint previous_unpack_alignment; - GLboolean previous_blend_enabled; - GLint previous_blend_func_src; - GLint previous_blend_func_dst; - GLfloat previous_red_bias; - GLfloat previous_green_bias; - GLfloat previous_blue_bias; - GLfloat previous_alpha_scale; - - layout = pango_layout_new(ft2_context); - pango_layout_set_width(layout, -1); // -1 no wrapping. All text on one line. - pango_layout_set_text(layout, s, -1); // -1 null-terminated string. - pango_layout_get_extents(layout, NULL, &log_rect); - - if (log_rect.width > 0 && log_rect.height > 0) { - bitmap.rows = font_ascent + font_descent; - bitmap.width = PANGO_PIXELS_CEIL(log_rect.width); - bitmap.pitch = -bitmap.width; // Rendering it "upside down" for OpenGL. - begin_bitmap_buffer = (unsigned char *) g_malloc(bitmap.rows * bitmap.width); - memset(begin_bitmap_buffer, 0, bitmap.rows * bitmap.width); - bitmap.buffer = begin_bitmap_buffer + (bitmap.rows - 1) * bitmap.width; // See pitch above. - bitmap.num_grays = 0xff; - bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; - pango_ft2_render_layout_subpixel(&bitmap, layout, -log_rect.x, - y_offset_bitmap_render_pango_units); - GlobalOpenGL().m_glGetFloatv(GL_CURRENT_COLOR, color); - - // Save state. I didn't see any OpenGL push/pop operations for these. - // Question: Is saving/restoring this state necessary? Being safe. - GlobalOpenGL().m_glGetIntegerv(GL_UNPACK_ALIGNMENT, &previous_unpack_alignment); - previous_blend_enabled = GlobalOpenGL().m_glIsEnabled(GL_BLEND); - GlobalOpenGL().m_glGetIntegerv(GL_BLEND_SRC, &previous_blend_func_src); - GlobalOpenGL().m_glGetIntegerv(GL_BLEND_DST, &previous_blend_func_dst); - GlobalOpenGL().m_glGetFloatv(GL_RED_BIAS, &previous_red_bias); - GlobalOpenGL().m_glGetFloatv(GL_GREEN_BIAS, &previous_green_bias); - GlobalOpenGL().m_glGetFloatv(GL_BLUE_BIAS, &previous_blue_bias); - GlobalOpenGL().m_glGetFloatv(GL_ALPHA_SCALE, &previous_alpha_scale); - - GlobalOpenGL().m_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GlobalOpenGL().m_glEnable(GL_BLEND); - GlobalOpenGL().m_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - GlobalOpenGL().m_glPixelTransferf(GL_RED_BIAS, color[0]); - GlobalOpenGL().m_glPixelTransferf(GL_GREEN_BIAS, color[1]); - GlobalOpenGL().m_glPixelTransferf(GL_BLUE_BIAS, color[2]); - GlobalOpenGL().m_glPixelTransferf(GL_ALPHA_SCALE, color[3]); - - GlobalOpenGL().m_glDrawPixels(bitmap.width, bitmap.rows, - GL_ALPHA, GL_UNSIGNED_BYTE, begin_bitmap_buffer); - g_free(begin_bitmap_buffer); - - // Restore state in reverse order of how we set it. - GlobalOpenGL().m_glPixelTransferf(GL_ALPHA_SCALE, previous_alpha_scale); - GlobalOpenGL().m_glPixelTransferf(GL_BLUE_BIAS, previous_blue_bias); - GlobalOpenGL().m_glPixelTransferf(GL_GREEN_BIAS, previous_green_bias); - GlobalOpenGL().m_glPixelTransferf(GL_RED_BIAS, previous_red_bias); - GlobalOpenGL().m_glBlendFunc(previous_blend_func_src, previous_blend_func_dst); - if (!previous_blend_enabled) { - GlobalOpenGL().m_glDisable(GL_BLEND); - } - GlobalOpenGL().m_glPixelStorei(GL_UNPACK_ALIGNMENT, previous_unpack_alignment); - } - - g_object_unref(G_OBJECT(layout)); -} - -virtual int getPixelAscent() const -{ - return font_ascent; -} - -virtual int getPixelDescent() const -{ - return font_descent; -} - -virtual int getPixelHeight() const -{ - return font_height; -} -}; - -GLFont *glfont_create(const char *font_string) -{ - return new GLFontInternal(font_string); -} - -#endif diff --git a/libs/gtkutil/glfont.h b/libs/gtkutil/glfont.h deleted file mode 100644 index e890791..0000000 --- a/libs/gtkutil/glfont.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_GLFONT_H ) -#define INCLUDED_GTKUTIL_GLFONT_H - -typedef unsigned int GLuint; - -class GLFont { -public: -virtual int getPixelHeight() const = 0; - -virtual int getPixelAscent() const = 0; - -virtual int getPixelDescent() const = 0; - -virtual void printString(const char *s) = 0; - -virtual ~GLFont() -{ -} -}; - -GLFont *glfont_create(const char *font_string); -// release with delete - -#endif diff --git a/libs/gtkutil/glwidget.cpp b/libs/gtkutil/glwidget.cpp deleted file mode 100644 index 335581f..0000000 --- a/libs/gtkutil/glwidget.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// OpenGL widget based on GtkGLExt - -#include "glwidget.h" - -#include "igl.h" - -void (*GLWidget_sharedContextCreated)() = 0; - -void (*GLWidget_sharedContextDestroyed)() = 0; - -unsigned int g_context_count = 0; - -ui::GLArea g_shared{ui::null}; - -void _glwidget_context_created(ui::GLArea self, void *data) -{ - if (++g_context_count == 1) { - g_shared = self; - g_object_ref(g_shared._handle); - - glwidget_make_current(g_shared); - GlobalOpenGL().contextValid = true; - - GLWidget_sharedContextCreated(); - } -} - -void _glwidget_context_destroyed(ui::GLArea self, void *data) -{ - if (--g_context_count == 0) { - GlobalOpenGL().contextValid = false; - - GLWidget_sharedContextDestroyed(); - - g_shared.unref(); - g_shared = ui::GLArea(ui::null); - } -} - -void glwidget_destroy_context(ui::GLArea self) -{ -} - -void glwidget_create_context(ui::GLArea self) -{ -} - -#if GTK_TARGET == 3 - -#include - -GdkGLContext *glwidget_context_created(ui::GLArea self) -{ - _glwidget_context_created(self, nullptr); - return gtk_gl_area_get_context(self); -} - -ui::GLArea glwidget_new(bool zbuffer) -{ - auto self = ui::GLArea(GTK_GL_AREA(gtk_gl_area_new())); - gtk_gl_area_set_has_depth_buffer(self, zbuffer); - gtk_gl_area_set_auto_render(self, false); - - self.connect("realize", G_CALLBACK(glwidget_context_created), nullptr); - return self; -} - -bool glwidget_make_current(ui::GLArea self) -{ -// if (!g_context_count) { -// glwidget_context_created(self); -// } - gtk_gl_area_make_current(self); - auto valid = GlobalOpenGL().contextValid; - return true; -} - -void glwidget_swap_buffers(ui::GLArea self) -{ - gtk_gl_area_queue_render(self); -} - -#endif - -#if GTK_TARGET == 2 - -#include -#include - -#include "pointer.h" - -struct config_t { - const char *name; - int *attribs; -}; -typedef const config_t *configs_iterator; - -int config_rgba32[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 16, - GDK_GL_ATTRIB_LIST_NONE, -}; - -const config_t configs[] = { - { - "colour-buffer = 32bpp, depth-buffer = none", - config_rgba32, - }, - { - "colour-buffer = 16bpp, depth-buffer = none", - config_rgba, - } -}; - -GdkGLConfig *glconfig_new() -{ - for (configs_iterator i = configs, end = configs + 2; i != end; ++i) { - if (auto glconfig = gdk_gl_config_new(i->attribs)) { - globalOutputStream() << "OpenGL window configuration: " << i->name << "\n"; - return glconfig; - } - } - globalOutputStream() << "OpenGL window configuration: colour-buffer = auto, depth-buffer = none\n"; - return gdk_gl_config_new_by_mode((GdkGLConfigMode) (GDK_GL_MODE_RGBA | GDK_GL_MODE_DOUBLE)); -} - -int config_rgba32_depth32[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, - 24, - GDK_GL_DEPTH_SIZE, - 32, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba32_depth24[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 24, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba32_depth16[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 16, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba32_depth[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 1, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba_depth16[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 16, - GDK_GL_DEPTH_SIZE, 16, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba_depth[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 16, - GDK_GL_DEPTH_SIZE, 1, - GDK_GL_ATTRIB_LIST_NONE, -}; - -const config_t configs_with_depth[] = -{ - { - "colour-buffer = 32bpp, depth-buffer = 32bpp", - config_rgba32_depth32, - }, - { - "colour-buffer = 32bpp, depth-buffer = 24bpp", - config_rgba32_depth24, - }, - { - "colour-buffer = 32bpp, depth-buffer = 16bpp", - config_rgba32_depth16, - }, - { - "colour-buffer = 32bpp, depth-buffer = auto", - config_rgba32_depth, - }, - { - "colour-buffer = 16bpp, depth-buffer = 16bpp", - config_rgba_depth16, - }, - { - "colour-buffer = auto, depth-buffer = auto", - config_rgba_depth, - }, -}; - -GdkGLConfig *glconfig_new_with_depth() -{ - for (configs_iterator i = configs_with_depth, end = configs_with_depth + 6; i != end; ++i) { - if (auto glconfig = gdk_gl_config_new(i->attribs)) { - globalOutputStream() << "OpenGL window configuration: " << i->name << "\n"; - return glconfig; - } - } - globalOutputStream() << "OpenGL window configuration: colour-buffer = auto, depth-buffer = auto (fallback)\n"; - return gdk_gl_config_new_by_mode((GdkGLConfigMode) (GDK_GL_MODE_RGBA | GDK_GL_MODE_DOUBLE | GDK_GL_MODE_DEPTH)); -} - -int glwidget_context_created(ui::GLArea self, void *data) -{ - _glwidget_context_created(self, data); - return false; -} - -int glwidget_context_destroyed(ui::GLArea self, void *data) -{ - _glwidget_context_destroyed(self, data); - return false; -} - -bool glwidget_enable_gl(ui::GLArea self, ui::Widget root, gpointer data) -{ - if (!root && !gtk_widget_is_gl_capable(self)) { - const auto zbuffer = g_object_get_data(G_OBJECT(self), "zbuffer"); - GdkGLConfig *glconfig = zbuffer ? glconfig_new_with_depth() : glconfig_new(); - ASSERT_MESSAGE(glconfig, "failed to create OpenGL config"); - - const auto share_list = g_shared ? gtk_widget_get_gl_context(g_shared) : nullptr; - gtk_widget_set_gl_capability(self, glconfig, share_list, true, GDK_GL_RGBA_TYPE); - - gtk_widget_realize(self); - if (!g_shared) { - g_shared = self; - } - // free glconfig? - } - return false; -} - -ui::GLArea glwidget_new(bool zbuffer) -{ - auto self = ui::GLArea::from(gtk_drawing_area_new()); - - g_object_set_data(G_OBJECT(self), "zbuffer", gint_to_pointer(zbuffer)); - - self.connect("hierarchy-changed", G_CALLBACK(glwidget_enable_gl), 0); - - self.connect("realize", G_CALLBACK(glwidget_context_created), 0); - self.connect("unrealize", G_CALLBACK(glwidget_context_destroyed), 0); - - return self; -} - -void glwidget_swap_buffers(ui::GLArea self) -{ - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(self); - gdk_gl_drawable_swap_buffers(gldrawable); -} - -bool glwidget_make_current(ui::GLArea self) -{ - GdkGLContext *glcontext = gtk_widget_get_gl_context(self); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(self); - return gdk_gl_drawable_gl_begin(gldrawable, glcontext); -} - -#endif diff --git a/libs/gtkutil/glwidget.h b/libs/gtkutil/glwidget.h deleted file mode 100644 index c0bbff4..0000000 --- a/libs/gtkutil/glwidget.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_GLWIDGET_H ) -#define INCLUDED_GTKUTIL_GLWIDGET_H - -extern void (*GLWidget_sharedContextCreated)(); - -extern void (*GLWidget_sharedContextDestroyed)(); - -ui::GLArea glwidget_new(bool zbuffer); - -void glwidget_create_context(ui::GLArea self); - -void glwidget_destroy_context(ui::GLArea self); - -bool glwidget_make_current(ui::GLArea self); - -void glwidget_swap_buffers(ui::GLArea self); - -#endif diff --git a/libs/gtkutil/idledraw.h b/libs/gtkutil/idledraw.h deleted file mode 100644 index d906f03..0000000 --- a/libs/gtkutil/idledraw.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_IDLEDRAW_H ) -#define INCLUDED_GTKUTIL_IDLEDRAW_H - -#include - -#include "generic/callback.h" - -class IdleDraw { -Callback m_draw; -unsigned int m_handler; - -static gboolean draw(gpointer data) -{ - reinterpret_cast( data )->m_draw(); - reinterpret_cast( data )->m_handler = 0; - return FALSE; -} - -public: -IdleDraw(const Callback &draw) : m_draw(draw), m_handler(0) -{ -} - -~IdleDraw() -{ - if (m_handler != 0) { - g_source_remove(m_handler); - } -} - -void queueDraw() -{ - if (m_handler == 0) { - m_handler = g_idle_add(&draw, this); - } -} - -typedef MemberCaller QueueDrawCaller; - -void flush() -{ - if (m_handler != 0) { - draw(this); - } -} -}; - - -#endif diff --git a/libs/gtkutil/image.cpp b/libs/gtkutil/image.cpp deleted file mode 100644 index 2ccc5f8..0000000 --- a/libs/gtkutil/image.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "image.h" - -#include - -#include "string/string.h" -#include "stream/stringstream.h" -#include "stream/textstream.h" - - -namespace { -CopiedString g_bitmapsPath; -} - -void BitmapsPath_set(const char *path) -{ - g_bitmapsPath = path; -} - -GdkPixbuf *pixbuf_new_from_file_with_mask(const char *filename) -{ - GdkPixbuf *rgb = gdk_pixbuf_new_from_file(filename, 0); - if (rgb == 0) { - return 0; - } else { - GdkPixbuf *rgba = gdk_pixbuf_add_alpha(rgb, FALSE, 255, 0, 255); - g_object_unref(rgb); - return rgba; - } -} - -ui::Image image_new_from_file_with_mask(const char *filename) -{ - GdkPixbuf *rgba = pixbuf_new_from_file_with_mask(filename); - if (rgba == 0) { - return ui::Image(ui::null); - } else { - auto image = ui::Image::from(gtk_image_new_from_pixbuf(rgba)); - g_object_unref(rgba); - return image; - } -} - -ui::Image image_new_missing() -{ - return ui::Image::from(gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_SMALL_TOOLBAR)); -} - -ui::Image new_image(const char *filename) -{ - if (auto image = image_new_from_file_with_mask(filename)) { - return image; - } - return image_new_missing(); -} - -ui::Image new_local_image(const char *filename) -{ - StringOutputStream fullPath(256); - fullPath << g_bitmapsPath.c_str() << filename; - return new_image(fullPath.c_str()); -} diff --git a/libs/gtkutil/image.h b/libs/gtkutil/image.h deleted file mode 100644 index 6604df2..0000000 --- a/libs/gtkutil/image.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_IMAGE_H ) -#define INCLUDED_GTKUTIL_IMAGE_H - -void BitmapsPath_set(const char *path); - -typedef struct _GdkPixbuf GdkPixbuf; - -GdkPixbuf *pixbuf_new_from_file_with_mask(const char *filename); - -ui::Image image_new_from_file_with_mask(const char *filename); - -ui::Image image_new_missing(); - -ui::Image new_image(const char *filename); // filename is full path to image file -ui::Image new_local_image(const char *filename); // filename is relative to local bitmaps path - -#endif diff --git a/libs/gtkutil/menu.cpp b/libs/gtkutil/menu.cpp deleted file mode 100644 index 33c906d..0000000 --- a/libs/gtkutil/menu.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "menu.h" - -#include -#include -#include -#include - -#include "generic/callback.h" - -#include "accelerator.h" -#include "closure.h" -#include "container.h" -#include "pointer.h" - -void menu_add_item(ui::Menu menu, ui::MenuItem item) -{ - menu.add(item); -} - -ui::MenuItem menu_separator(ui::Menu menu) -{ - auto menu_item = ui::MenuItem::from(gtk_menu_item_new()); - menu.add(menu_item); - gtk_widget_set_sensitive(menu_item, FALSE); - menu_item.show(); - return menu_item; -} - -ui::TearoffMenuItem menu_tearoff(ui::Menu menu) -{ - auto menu_item = ui::TearoffMenuItem::from(gtk_tearoff_menu_item_new()); - menu.add(menu_item); -// gtk_widget_set_sensitive(menu_item, FALSE); -- controls whether menu is detachable - menu_item.show(); - return menu_item; -} - -ui::MenuItem new_sub_menu_item_with_mnemonic(const char *mnemonic) -{ - auto item = ui::MenuItem(mnemonic, true); - item.show(); - - auto sub_menu = ui::Menu(ui::New); - gtk_menu_item_set_submenu(item, sub_menu); - - return item; -} - -ui::Menu create_sub_menu_with_mnemonic(ui::MenuShell parent, const char *mnemonic) -{ - auto item = new_sub_menu_item_with_mnemonic(mnemonic); - parent.add(item); - return ui::Menu::from(gtk_menu_item_get_submenu(item)); -} - -ui::Menu create_sub_menu_with_mnemonic(ui::MenuBar bar, const char *mnemonic) -{ - return create_sub_menu_with_mnemonic(ui::MenuShell::from(bar._handle), mnemonic); -} - -ui::Menu create_sub_menu_with_mnemonic(ui::Menu parent, const char *mnemonic) -{ - return create_sub_menu_with_mnemonic(ui::MenuShell::from(parent._handle), mnemonic); -} - -void activate_closure_callback(ui::Widget widget, gpointer data) -{ - (*reinterpret_cast *>( data ))(); -} - -guint menu_item_connect_callback(ui::MenuItem item, const Callback &callback) -{ -#if 1 - return g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -#else - return g_signal_connect_closure( G_OBJECT( item ), "activate", create_cclosure( G_CALLBACK( activate_closure_callback ), callback ), FALSE ); -#endif -} - -guint check_menu_item_connect_callback(ui::CheckMenuItem item, const Callback &callback) -{ -#if 1 - guint handler = g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -#else - guint handler = g_signal_connect_closure( G_OBJECT( item ), "toggled", create_cclosure( G_CALLBACK( activate_closure_callback ), callback ), TRUE ); -#endif - g_object_set_data(G_OBJECT(item), "handler", gint_to_pointer(handler)); - return handler; -} - -ui::MenuItem new_menu_item_with_mnemonic(const char *mnemonic, const Callback &callback) -{ - auto item = ui::MenuItem(mnemonic, true); - item.show(); - menu_item_connect_callback(item, callback); - return item; -} - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Callback &callback) -{ - auto item = new_menu_item_with_mnemonic(mnemonic, callback); - menu.add(item); - return item; -} - -ui::CheckMenuItem new_check_menu_item_with_mnemonic(const char *mnemonic, const Callback &callback) -{ - auto item = ui::CheckMenuItem::from(gtk_check_menu_item_new_with_mnemonic(mnemonic)); - item.show(); - check_menu_item_connect_callback(item, callback); - return item; -} - -ui::CheckMenuItem -create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Callback &callback) -{ - auto item = new_check_menu_item_with_mnemonic(mnemonic, callback); - menu.add(item); - return item; -} - -ui::RadioMenuItem -new_radio_menu_item_with_mnemonic(GSList **group, const char *mnemonic, const Callback &callback) -{ - auto item = ui::RadioMenuItem::from(gtk_radio_menu_item_new_with_mnemonic(*group, mnemonic)); - if (*group == 0) { - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); - } - *group = gtk_radio_menu_item_get_group(item); - item.show(); - check_menu_item_connect_callback(item, callback); - return item; -} - -ui::RadioMenuItem create_radio_menu_item_with_mnemonic(ui::Menu menu, GSList **group, const char *mnemonic, - const Callback &callback) -{ - auto item = new_radio_menu_item_with_mnemonic(group, mnemonic, callback); - menu.add(item); - return item; -} - -void check_menu_item_set_active_no_signal(ui::CheckMenuItem item, gboolean active) -{ - guint handler_id = gpointer_to_int(g_object_get_data(G_OBJECT(item), "handler")); - g_signal_handler_block(G_OBJECT(item), handler_id); - gtk_check_menu_item_set_active(item, active); - g_signal_handler_unblock(G_OBJECT(item), handler_id); -} - - -void radio_menu_item_set_active_no_signal(ui::RadioMenuItem item, gboolean active) -{ - { - for (GSList *l = gtk_radio_menu_item_get_group(item); l != 0; l = g_slist_next(l)) { - g_signal_handler_block(G_OBJECT(l->data), gpointer_to_int(g_object_get_data(G_OBJECT(l->data), "handler"))); - } - } - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), active); - { - for (GSList *l = gtk_radio_menu_item_get_group(item); l != 0; l = g_slist_next(l)) { - g_signal_handler_unblock(G_OBJECT(l->data), - gpointer_to_int(g_object_get_data(G_OBJECT(l->data), "handler"))); - } - } -} - - -void menu_item_set_accelerator(ui::MenuItem item, GClosure *closure) -{ - GtkAccelLabel *accel_label = GTK_ACCEL_LABEL(gtk_bin_get_child(GTK_BIN(item))); - gtk_accel_label_set_accel_closure(accel_label, closure); -} - -void accelerator_name(const Accelerator &accelerator, GString *gstring) -{ - gboolean had_mod = FALSE; - if (accelerator.modifiers & GDK_SHIFT_MASK) { - g_string_append(gstring, "Shift"); - had_mod = TRUE; - } - if (accelerator.modifiers & GDK_CONTROL_MASK) { - if (had_mod) { - g_string_append(gstring, "+"); - } - g_string_append(gstring, "Ctrl"); - had_mod = TRUE; - } - if (accelerator.modifiers & GDK_MOD1_MASK) { - if (had_mod) { - g_string_append(gstring, "+"); - } - g_string_append(gstring, "Alt"); - had_mod = TRUE; - } - - if (had_mod) { - g_string_append(gstring, "+"); - } - if (accelerator.key < 0x80 || (accelerator.key > 0x80 && accelerator.key <= 0xff)) { - switch (accelerator.key) { - case ' ': - g_string_append(gstring, "Space"); - break; - case '\\': - g_string_append(gstring, "Backslash"); - break; - default: - g_string_append_c(gstring, gchar(toupper(accelerator.key))); - break; - } - } else { - gchar *tmp; - - tmp = gtk_accelerator_name(accelerator.key, (GdkModifierType) 0); - if (tmp[0] != 0 && tmp[1] == 0) { - tmp[0] = gchar(toupper(tmp[0])); - } - g_string_append(gstring, tmp); - g_free(tmp); - } -} - -void menu_item_add_accelerator(ui::MenuItem item, Accelerator accelerator) -{ - if (accelerator.key != 0 && gtk_accelerator_valid(accelerator.key, accelerator.modifiers)) { - GClosure *closure = global_accel_group_find(accelerator); - ASSERT_NOTNULL(closure); - menu_item_set_accelerator(item, closure); - } -} - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Command &command) -{ - auto item = create_menu_item_with_mnemonic(menu, mnemonic, command.m_callback); - menu_item_add_accelerator(item, command.m_accelerator); - return item; -} - -void check_menu_item_set_active_callback(void *it, bool enabled) -{ - auto item = ui::CheckMenuItem::from(it); - check_menu_item_set_active_no_signal(item, enabled); -} - -ui::CheckMenuItem create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Toggle &toggle) -{ - auto item = create_check_menu_item_with_mnemonic(menu, mnemonic, toggle.m_command.m_callback); - menu_item_add_accelerator(item, toggle.m_command.m_accelerator); - toggle.m_exportCallback(PointerCaller(item._handle)); - return item; -} diff --git a/libs/gtkutil/menu.h b/libs/gtkutil/menu.h deleted file mode 100644 index 08f8224..0000000 --- a/libs/gtkutil/menu.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_MENU_H ) -#define INCLUDED_GTKUTIL_MENU_H - -#include -#include "generic/callback.h" - -typedef int gint; -typedef gint gboolean; -typedef struct _GSList GSList; - -void menu_add_item(ui::Menu menu, ui::MenuItem item); - -ui::MenuItem menu_separator(ui::Menu menu); - -ui::TearoffMenuItem menu_tearoff(ui::Menu menu); - -ui::MenuItem new_sub_menu_item_with_mnemonic(const char *mnemonic); - -ui::Menu create_sub_menu_with_mnemonic(ui::MenuBar bar, const char *mnemonic); - -ui::Menu create_sub_menu_with_mnemonic(ui::Menu parent, const char *mnemonic); - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Callback &callback); - -ui::CheckMenuItem -create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Callback &callback); - -ui::RadioMenuItem create_radio_menu_item_with_mnemonic(ui::Menu menu, GSList **group, const char *mnemonic, - const Callback &callback); - -class Command; - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Command &command); - -class Toggle; - -ui::CheckMenuItem create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const Toggle &toggle); - - -void check_menu_item_set_active_no_signal(ui::CheckMenuItem item, gboolean active); - -void radio_menu_item_set_active_no_signal(ui::RadioMenuItem item, gboolean active); - -#endif diff --git a/libs/gtkutil/messagebox.cpp b/libs/gtkutil/messagebox.cpp deleted file mode 100644 index ec64271..0000000 --- a/libs/gtkutil/messagebox.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "messagebox.h" - -#include -#include - -#include "dialog.h" -#include "widget.h" - -ui::Widget create_padding(int width, int height) -{ - ui::Alignment widget = ui::Alignment(0.0, 0.0, 0.0, 0.0); - widget.show(); - widget.dimensions(width, height); - return widget; -} - -const char *messagebox_stock_icon(EMessageBoxIcon type) -{ - switch (type) { - default: - case eMB_ICONDEFAULT: - return GTK_STOCK_DIALOG_INFO; - case eMB_ICONERROR: - return GTK_STOCK_DIALOG_ERROR; - case eMB_ICONWARNING: - return GTK_STOCK_DIALOG_WARNING; - case eMB_ICONQUESTION: - return GTK_STOCK_DIALOG_QUESTION; - case eMB_ICONASTERISK: - return GTK_STOCK_DIALOG_INFO; - } -} - -EMessageBoxReturn -gtk_MessageBox(ui::Window parentWindow, const char *text, const char *title, EMessageBoxType type, EMessageBoxIcon icon) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - ModalDialogButton yes_button(dialog, eIDYES); - ModalDialogButton no_button(dialog, eIDNO); - - ui::Window window = create_fixedsize_modal_dialog_window(parentWindow, title, dialog, 400, 100); - - if (parentWindow) { - //window.connect( "delete_event", G_CALLBACK(floating_window_delete_present), parent); - gtk_window_deiconify(parentWindow); - } - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - auto vbox = create_dialog_vbox(8, 8); - window.add(vbox); - - - auto hboxDummy = create_dialog_hbox(0, 0); - vbox.pack_start(hboxDummy, FALSE, FALSE, 0); - - hboxDummy.pack_start(create_padding(0, 50), FALSE, FALSE, 0); // HACK to force minimum height - - auto iconBox = create_dialog_hbox(16, 0); - hboxDummy.pack_start(iconBox, FALSE, FALSE, 0); - - auto image = ui::Image::from(gtk_image_new_from_stock(messagebox_stock_icon(icon), GTK_ICON_SIZE_DIALOG)); - image.show(); - iconBox.pack_start(image, FALSE, FALSE, 0); - - auto label = ui::Label(text); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - gtk_label_set_line_wrap(label, TRUE); - iconBox.pack_start(label, TRUE, TRUE, 0); - - - auto vboxDummy = create_dialog_vbox(0, 0); - vbox.pack_start(vboxDummy, FALSE, FALSE, 0); - - auto alignment = ui::Alignment(0.5, 0.0, 0.0, 0.0); - alignment.show(); - vboxDummy.pack_start(alignment, FALSE, FALSE, 0); - - auto hbox = create_dialog_hbox(8, 0); - alignment.add(hbox); - - vboxDummy.pack_start(create_padding(400, 0), FALSE, FALSE, 0); // HACK to force minimum width - - - if (type == eMB_OK) { - auto button = create_modal_dialog_button("OK", ok_button); - hbox.pack_start(button, TRUE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, (GtkAccelFlags) 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, (GtkAccelFlags) 0); - widget_make_default(button); - button.show(); - - dialog.ret = eIDOK; - } else if (type == eMB_OKCANCEL) { - { - auto button = create_modal_dialog_button("OK", ok_button); - hbox.pack_start(button, TRUE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - widget_make_default(button); - button.show(); - } - - { - auto button = create_modal_dialog_button("OK", cancel_button); - hbox.pack_start(button, TRUE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - button.show(); - } - - dialog.ret = eIDCANCEL; - } else if (type == eMB_YESNOCANCEL) { - { - auto button = create_modal_dialog_button("Yes", yes_button); - hbox.pack_start(button, TRUE, FALSE, 0); - widget_make_default(button); - button.show(); - } - - { - auto button = create_modal_dialog_button("No", no_button); - hbox.pack_start(button, TRUE, FALSE, 0); - button.show(); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - hbox.pack_start(button, TRUE, FALSE, 0); - button.show(); - } - - dialog.ret = eIDCANCEL; - } else if (type == eMB_NOYES) { - { - auto button = create_modal_dialog_button("No", no_button); - hbox.pack_start(button, TRUE, FALSE, 0); - widget_make_default(button); - button.show(); - } - { - auto button = create_modal_dialog_button("Yes", yes_button); - hbox.pack_start(button, TRUE, FALSE, 0); - button.show(); - } - - dialog.ret = eIDNO; - } else /* if (type == eMB_YESNO) */ - { - { - auto button = create_modal_dialog_button("Yes", yes_button); - hbox.pack_start(button, TRUE, FALSE, 0); - widget_make_default(button); - button.show(); - } - - { - auto button = create_modal_dialog_button("No", no_button); - hbox.pack_start(button, TRUE, FALSE, 0); - button.show(); - } - dialog.ret = eIDNO; - } - - modal_dialog_show(window, dialog); - - window.destroy(); - - return dialog.ret; -} diff --git a/libs/gtkutil/messagebox.h b/libs/gtkutil/messagebox.h deleted file mode 100644 index 0935b6e..0000000 --- a/libs/gtkutil/messagebox.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_MESSAGEBOX_H ) -#define INCLUDED_GTKUTIL_MESSAGEBOX_H - -#include "qerplugin.h" - -/// \brief Shows a modal message-box. -EMessageBoxReturn -gtk_MessageBox(ui::Window parent, const char *text, const char *title = "WorldSpawn", EMessageBoxType type = eMB_OK, - EMessageBoxIcon icon = eMB_ICONDEFAULT); - -#endif diff --git a/libs/gtkutil/nonmodal.cpp b/libs/gtkutil/nonmodal.cpp deleted file mode 100644 index 1402a90..0000000 --- a/libs/gtkutil/nonmodal.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "nonmodal.h" - -#include -#include - -gboolean escape_clear_focus_widget(ui::Widget widget, GdkEventKey *event, gpointer data) -{ - if (event->keyval == GDK_KEY_Escape) { - gtk_window_set_focus(widget.window(), NULL); - return TRUE; - } - return FALSE; -} - -void widget_connect_escape_clear_focus_widget(ui::Widget widget) -{ - widget.connect("key_press_event", G_CALLBACK(escape_clear_focus_widget), 0); -} - -gboolean NonModalEntry::focus_in(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self) -{ - self->m_editing = false; - return FALSE; -} - -gboolean NonModalEntry::focus_out(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self) -{ - if (self->m_editing && gtk_widget_get_visible(entry)) { - self->m_apply(); - } - self->m_editing = false; - return FALSE; -} - -gboolean NonModalEntry::changed(ui::Entry entry, NonModalEntry *self) -{ - self->m_editing = true; - return FALSE; -} - -gboolean NonModalEntry::enter(ui::Entry entry, GdkEventKey *event, NonModalEntry *self) -{ - if (event->keyval == GDK_KEY_Return) { - self->m_apply(); - self->m_editing = false; - gtk_window_set_focus(entry.window(), NULL); - return TRUE; - } - return FALSE; -} - -gboolean NonModalEntry::escape(ui::Entry entry, GdkEventKey *event, NonModalEntry *self) -{ - if (event->keyval == GDK_KEY_Escape) { - self->m_cancel(); - self->m_editing = false; - gtk_window_set_focus(entry.window(), NULL); - return TRUE; - } - return FALSE; -} - -void NonModalEntry::connect(ui::Entry entry) -{ - entry.connect("focus_in_event", G_CALLBACK(focus_in), this); - entry.connect("focus_out_event", G_CALLBACK(focus_out), this); - entry.connect("key_press_event", G_CALLBACK(enter), this); - entry.connect("key_press_event", G_CALLBACK(escape), this); - entry.connect("changed", G_CALLBACK(changed), this); -} - -gboolean NonModalSpinner::changed(ui::SpinButton spin, NonModalSpinner *self) -{ - self->m_apply(); - return FALSE; -} - -gboolean NonModalSpinner::enter(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self) -{ - if (event->keyval == GDK_KEY_Return) { - gtk_window_set_focus(spin.window(), NULL); - return TRUE; - } - return FALSE; -} - -gboolean NonModalSpinner::escape(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self) -{ - if (event->keyval == GDK_KEY_Escape) { - self->m_cancel(); - gtk_window_set_focus(spin.window(), NULL); - return TRUE; - } - return FALSE; -} - -void NonModalSpinner::connect(ui::SpinButton spin) -{ - auto adj = ui::Adjustment::from(gtk_spin_button_get_adjustment(spin)); - guint handler = adj.connect("value_changed", G_CALLBACK(changed), this); - g_object_set_data(G_OBJECT(spin), "handler", gint_to_pointer(handler)); - spin.connect("key_press_event", G_CALLBACK(enter), this); - spin.connect("key_press_event", G_CALLBACK(escape), this); -} - -void NonModalRadio::connect(ui::RadioButton radio) -{ - GSList *group = gtk_radio_button_get_group(radio); - for (; group != 0; group = g_slist_next(group)) { - toggle_button_connect_callback(ui::ToggleButton::from(group->data), m_changed); - } -} diff --git a/libs/gtkutil/nonmodal.h b/libs/gtkutil/nonmodal.h deleted file mode 100644 index c09d750..0000000 --- a/libs/gtkutil/nonmodal.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_NONMODAL_H ) -#define INCLUDED_GTKUTIL_NONMODAL_H - -#include -#include "generic/callback.h" - -#include "pointer.h" -#include "button.h" - -gboolean escape_clear_focus_widget(ui::Widget widget, GdkEventKey *event, gpointer data); - -void widget_connect_escape_clear_focus_widget(ui::Widget widget); - -class NonModalEntry { -bool m_editing; -Callback m_apply; -Callback m_cancel; - -static gboolean focus_in(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self); - -static gboolean focus_out(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self); - -static gboolean changed(ui::Entry entry, NonModalEntry *self); - -static gboolean enter(ui::Entry entry, GdkEventKey *event, NonModalEntry *self); - -static gboolean escape(ui::Entry entry, GdkEventKey *event, NonModalEntry *self); - -public: -NonModalEntry(const Callback &apply, const Callback &cancel) : m_editing(false), m_apply(apply), - m_cancel(cancel) -{ -} - -void connect(ui::Entry entry); -}; - - -class NonModalSpinner { -Callback m_apply; -Callback m_cancel; - -static gboolean changed(ui::SpinButton spin, NonModalSpinner *self); - -static gboolean enter(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self); - -static gboolean escape(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self); - -public: -NonModalSpinner(const Callback &apply, const Callback &cancel) : m_apply(apply), m_cancel(cancel) -{ -} - -void connect(ui::SpinButton spin); -}; - - -class NonModalRadio { -Callback m_changed; - -public: -NonModalRadio(const Callback &changed) : m_changed(changed) -{ -} - -void connect(ui::RadioButton radio); -}; - - -#endif diff --git a/libs/gtkutil/paned.cpp b/libs/gtkutil/paned.cpp deleted file mode 100644 index 4e1b5c4..0000000 --- a/libs/gtkutil/paned.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "paned.h" - -#include -#include - -#include "frame.h" - - -class PanedState { -public: -float position; -int size; -}; - -gboolean hpaned_allocate(ui::Widget widget, GtkAllocation *allocation, PanedState *paned) -{ - if (paned->size != allocation->width) { - paned->size = allocation->width; - gtk_paned_set_position(GTK_PANED(widget), static_cast( paned->size * paned->position )); - } - return FALSE; -} - -gboolean vpaned_allocate(ui::Widget widget, GtkAllocation *allocation, PanedState *paned) -{ - if (paned->size != allocation->height) { - paned->size = allocation->height; - gtk_paned_set_position(GTK_PANED(widget), static_cast( paned->size * paned->position )); - } - return FALSE; -} - -gboolean paned_position(ui::Widget widget, gpointer dummy, PanedState *paned) -{ - if (paned->size != -1) { - paned->position = gtk_paned_get_position(GTK_PANED(widget)) / static_cast( paned->size ); - } - return FALSE; -} - -PanedState g_hpaned = {0.5f, -1,}; -PanedState g_vpaned1 = {0.5f, -1,}; -PanedState g_vpaned2 = {0.5f, -1,}; - -ui::HPaned create_split_views(ui::Widget topleft, ui::Widget topright, ui::Widget botleft, ui::Widget botright) -{ - auto hsplit = ui::HPaned(ui::New); - hsplit.show(); - - hsplit.connect("size_allocate", G_CALLBACK(hpaned_allocate), &g_hpaned); - hsplit.connect("notify::position", G_CALLBACK(paned_position), &g_hpaned); - - { - auto vsplit = ui::VPaned(ui::New); - gtk_paned_add1(GTK_PANED(hsplit), vsplit); - vsplit.show(); - - vsplit.connect("size_allocate", G_CALLBACK(vpaned_allocate), &g_vpaned1); - vsplit.connect("notify::position", G_CALLBACK(paned_position), &g_vpaned1); - - gtk_paned_add1(GTK_PANED(vsplit), create_framed_widget(topleft)); - gtk_paned_add2(GTK_PANED(vsplit), create_framed_widget(topright)); - } - { - auto vsplit = ui::VPaned(ui::New); - gtk_paned_add2(GTK_PANED(hsplit), vsplit); - vsplit.show(); - - vsplit.connect("size_allocate", G_CALLBACK(vpaned_allocate), &g_vpaned2); - vsplit.connect("notify::position", G_CALLBACK(paned_position), &g_vpaned2); - - gtk_paned_add1(GTK_PANED(vsplit), create_framed_widget(botleft)); - gtk_paned_add2(GTK_PANED(vsplit), create_framed_widget(botright)); - } - return hsplit; -} diff --git a/libs/gtkutil/paned.h b/libs/gtkutil/paned.h deleted file mode 100644 index 1c80ae6..0000000 --- a/libs/gtkutil/paned.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_GTKUTIL_PANED_H ) -#define INCLUDED_GTKUTIL_PANED_H - -ui::HPaned create_split_views(ui::Widget topleft, ui::Widget topright, ui::Widget botleft, ui::Widget botright); - -#endif diff --git a/libs/gtkutil/pointer.h b/libs/gtkutil/pointer.h deleted file mode 100644 index bfb996c..0000000 --- a/libs/gtkutil/pointer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_POINTER_H ) -#define INCLUDED_GTKUTIL_POINTER_H - -typedef int gint; -typedef void *gpointer; - -#include - -inline gint gpointer_to_int(gpointer p) -{ - return gint(std::size_t(p)); -} - -inline gpointer gint_to_pointer(gint i) -{ - return gpointer(std::size_t(i)); -} - -#endif diff --git a/libs/gtkutil/toolbar.cpp b/libs/gtkutil/toolbar.cpp deleted file mode 100644 index bf60733..0000000 --- a/libs/gtkutil/toolbar.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "toolbar.h" - -#include -#include - -#include "generic/callback.h" - -#include "accelerator.h" -#include "button.h" -#include "image.h" - - -void toolbar_append(ui::Toolbar toolbar, ui::ToolItem button, const char *description) -{ - gtk_widget_show_all(button); - gtk_widget_set_tooltip_text(button, description); - toolbar.add(button); -} - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const Callback &callback) -{ - auto button = ui::ToolButton::from(gtk_tool_button_new(new_local_image(icon), nullptr)); - button_connect_callback(button, callback); - gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), description); - toolbar_append(toolbar, button, description); - return button; -} - -ui::ToggleToolButton toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, - const Callback &callback) -{ - auto button = ui::ToggleToolButton::from(gtk_toggle_tool_button_new()); - toggle_button_connect_callback(button, callback); - gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(button), new_local_image(icon)); - gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), description); - toolbar_append(toolbar, button, description); - return button; -} - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const Command &command) -{ - return toolbar_append_button(toolbar, description, icon, command.m_callback); -} - -void toggle_button_set_active_callback(void *it, bool active) -{ - auto button = ui::ToggleToolButton::from(it); - toggle_button_set_active_no_signal(button, active); -} - -ui::ToggleToolButton -toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, const Toggle &toggle) -{ - auto button = toolbar_append_toggle_button(toolbar, description, icon, toggle.m_command.m_callback); - toggle.m_exportCallback(PointerCaller(button._handle)); - return button; -} diff --git a/libs/gtkutil/toolbar.h b/libs/gtkutil/toolbar.h deleted file mode 100644 index b016ab2..0000000 --- a/libs/gtkutil/toolbar.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_TOOLBAR_H ) -#define INCLUDED_GTKUTIL_TOOLBAR_H - -#include -#include "generic/callback.h" - -class Command; - -class Toggle; - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const Callback &callback); - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const Command &command); - -ui::ToggleToolButton toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, - const Callback &callback); - -ui::ToggleToolButton -toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, const Toggle &toggle); - -#endif diff --git a/libs/gtkutil/widget.cpp b/libs/gtkutil/widget.cpp deleted file mode 100644 index 805a8c5..0000000 --- a/libs/gtkutil/widget.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "widget.h" -#include - -void widget_queue_draw(ui::Widget &widget) -{ - gtk_widget_queue_draw(widget); -} - -void widget_make_default(ui::Widget widget) -{ - gtk_widget_set_can_default(widget, true); - gtk_widget_grab_default(widget); -} - -gboolean ToggleShown::notify_visible(ui::Widget widget, gpointer dummy, ToggleShown *self) -{ - self->update(); - return FALSE; -} - -gboolean ToggleShown::destroy(ui::Widget widget, ToggleShown *self) -{ - self->m_shownDeferred = gtk_widget_get_visible(self->m_widget) != FALSE; - self->m_widget = ui::Widget(ui::null); - return FALSE; -} - -void ToggleShown::update() -{ - m_item.update(); -} - -bool ToggleShown::active() const -{ - if (!m_widget) { - return m_shownDeferred; - } else { - return gtk_widget_get_visible(m_widget) != FALSE; - } -} - -void ToggleShown::exportActive(const Callback &importCallback) -{ - importCallback(active()); -} - -void ToggleShown::set(bool shown) -{ - if (!m_widget) { - m_shownDeferred = shown; - } else { - m_widget.visible(shown); - } -} - -void ToggleShown::toggle() -{ - m_widget.visible(!m_widget.visible()); -} - -void ToggleShown::connect(ui::Widget widget) -{ - m_widget = widget; - m_widget.visible(m_shownDeferred); - m_widget.connect("notify::visible", G_CALLBACK(notify_visible), this); - m_widget.connect("destroy", G_CALLBACK(destroy), this); - update(); -} - -gboolean WidgetFocusPrinter::focus_in(ui::Widget widget, GdkEventFocus *event, WidgetFocusPrinter *self) -{ - globalOutputStream() << self->m_name << " takes focus\n"; - return FALSE; -} - -gboolean WidgetFocusPrinter::focus_out(ui::Widget widget, GdkEventFocus *event, WidgetFocusPrinter *self) -{ - globalOutputStream() << self->m_name << " loses focus\n"; - return FALSE; -} - -void WidgetFocusPrinter::connect(ui::Widget widget) -{ - widget.connect("focus_in_event", G_CALLBACK(focus_in), this); - widget.connect("focus_out_event", G_CALLBACK(focus_out), this); -} diff --git a/libs/gtkutil/widget.h b/libs/gtkutil/widget.h deleted file mode 100644 index f693bc5..0000000 --- a/libs/gtkutil/widget.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_WIDGET_H ) -#define INCLUDED_GTKUTIL_WIDGET_H - -#include -#include -#include -#include "generic/callback.h" -#include "warnings.h" -#include "debugging/debugging.h" -#include "property.h" - -class ToggleItem { -Callback &)> m_exportCallback; -typedef std::list > ImportCallbacks; -ImportCallbacks m_importCallbacks; -public: -ToggleItem(const Callback &)> &exportCallback) : m_exportCallback(exportCallback) -{ -} - -void update() -{ - for (ImportCallbacks::iterator i = m_importCallbacks.begin(); i != m_importCallbacks.end(); ++i) { - m_exportCallback(*i); - } -} - -void addCallback(const Callback &callback) -{ - m_importCallbacks.push_back(callback); - m_exportCallback(callback); -} - -typedef MemberCaller &), &ToggleItem::addCallback> AddCallbackCaller; -}; - -class ToggleShown { -bool m_shownDeferred; - -ToggleShown(const ToggleShown &other); // NOT COPYABLE -ToggleShown &operator=(const ToggleShown &other); // NOT ASSIGNABLE - -static gboolean notify_visible(ui::Widget widget, gpointer dummy, ToggleShown *self); - -static gboolean destroy(ui::Widget widget, ToggleShown *self); - -public: -ui::Widget m_widget; -ToggleItem m_item; - -ToggleShown(bool shown) - : m_shownDeferred(shown), m_widget(ui::null), m_item(ActiveCaller(*this)) -{ -} - -void update(); - -bool active() const; - -void exportActive(const Callback &importCallback); - -typedef MemberCaller &), &ToggleShown::exportActive> ActiveCaller; - -void set(bool shown); - -void toggle(); - -typedef MemberCaller ToggleCaller; - -void connect(ui::Widget widget); -}; - - -void widget_queue_draw(ui::Widget &widget); - -typedef ReferenceCaller WidgetQueueDrawCaller; - - -void widget_make_default(ui::Widget widget); - -class WidgetFocusPrinter { -const char *m_name; - -static gboolean focus_in(ui::Widget widget, GdkEventFocus *event, WidgetFocusPrinter *self); - -static gboolean focus_out(ui::Widget widget, GdkEventFocus *event, WidgetFocusPrinter *self); - -public: -WidgetFocusPrinter(const char *name) : m_name(name) -{ -} - -void connect(ui::Widget widget); -}; - -#endif diff --git a/libs/gtkutil/window.cpp b/libs/gtkutil/window.cpp deleted file mode 100644 index 7084771..0000000 --- a/libs/gtkutil/window.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "window.h" - -#include - -#include "pointer.h" -#include "accelerator.h" - -inline void CHECK_RESTORE(ui::Widget w) -{ - if (gpointer_to_int(g_object_get_data(G_OBJECT(w), "was_mapped")) != 0) { - w.show(); - } -} - -inline void CHECK_MINIMIZE(ui::Widget w) -{ - g_object_set_data(G_OBJECT(w), "was_mapped", gint_to_pointer(gtk_widget_get_visible(w))); - w.hide(); -} - -static gboolean main_window_iconified(ui::Widget widget, GdkEventWindowState *event, gpointer data) -{ - if ((event->changed_mask & (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_WITHDRAWN)) != 0) { - if ((event->new_window_state & (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_WITHDRAWN)) != 0) { - CHECK_MINIMIZE(ui::Widget::from(data)); - } else { - CHECK_RESTORE(ui::Widget::from(data)); - } - } - return FALSE; -} - -unsigned int connect_floating(ui::Window main_window, ui::Window floating) -{ - return main_window.connect("window_state_event", G_CALLBACK(main_window_iconified), floating); -} - -gboolean destroy_disconnect_floating(ui::Window widget, gpointer data) -{ - g_signal_handler_disconnect(G_OBJECT(data), - gpointer_to_int(g_object_get_data(G_OBJECT(widget), "floating_handler"))); - return FALSE; -} - -gboolean floating_window_delete_present(ui::Window floating, GdkEventFocus *event, ui::Window main_window) -{ - if (gtk_window_is_active(floating) || gtk_window_is_active(main_window)) { - gtk_window_present(main_window); - } - return FALSE; -} - -guint connect_floating_window_delete_present(ui::Window floating, ui::Window main_window) -{ - return floating.connect("delete_event", G_CALLBACK(floating_window_delete_present), main_window); -} - -gboolean floating_window_destroy_present(ui::Window floating, ui::Window main_window) -{ - if (gtk_window_is_active(floating) || gtk_window_is_active(main_window)) { - gtk_window_present(main_window); - } - return FALSE; -} - -guint connect_floating_window_destroy_present(ui::Window floating, ui::Window main_window) -{ - return floating.connect("destroy", G_CALLBACK(floating_window_destroy_present), main_window); -} - -ui::Window create_floating_window(const char *title, ui::Window parent) -{ - ui::Window window = ui::Window(ui::window_type::TOP); - gtk_window_set_title(window, title); - - if (parent) { - gtk_window_set_transient_for(window, parent); - connect_floating_window_destroy_present(window, parent); - g_object_set_data(G_OBJECT(window), "floating_handler", gint_to_pointer(connect_floating(parent, window))); - window.connect("destroy", G_CALLBACK(destroy_disconnect_floating), parent); - } - - return window; -} - -void destroy_floating_window(ui::Window window) -{ - window.destroy(); -} - -gint window_realize_remove_sysmenu(ui::Widget widget, gpointer data) -{ - gdk_window_set_decorations(gtk_widget_get_window(widget), (GdkWMDecoration) (GDK_DECOR_ALL | GDK_DECOR_MENU)); - return FALSE; -} - -gboolean persistent_floating_window_delete(ui::Window floating, GdkEvent *event, ui::Window main_window) -{ - floating.hide(); - return TRUE; -} - -ui::Window create_persistent_floating_window(const char *title, ui::Window main_window) -{ - auto window = create_floating_window(title, main_window); - - gtk_widget_set_events(window, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); - - connect_floating_window_delete_present(window, main_window); - window.connect("delete_event", G_CALLBACK(persistent_floating_window_delete), 0); - -#if 0 - if ( g_multimon_globals.m_bStartOnPrimMon && g_multimon_globals.m_bNoSysMenuPopups ) { - window.connect( "realize", G_CALLBACK( window_realize_remove_sysmenu ), 0 ); - } -#endif - - return window; -} - -gint window_realize_remove_minmax(ui::Widget widget, gpointer data) -{ - gdk_window_set_decorations(gtk_widget_get_window(widget), - (GdkWMDecoration) (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE)); - return FALSE; -} - -void window_remove_minmax(ui::Window window) -{ - window.connect("realize", G_CALLBACK(window_realize_remove_minmax), 0); -} - - -ui::ScrolledWindow create_scrolled_window(ui::Policy hscrollbar_policy, ui::Policy vscrollbar_policy, int border) -{ - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - gtk_scrolled_window_set_policy(scr, (GtkPolicyType) hscrollbar_policy, (GtkPolicyType) vscrollbar_policy); - gtk_scrolled_window_set_shadow_type(scr, GTK_SHADOW_IN); - gtk_container_set_border_width(GTK_CONTAINER(scr), border); - return scr; -} - -gboolean window_focus_in_clear_focus_widget(ui::Window widget, GdkEventKey *event, gpointer data) -{ - gtk_window_set_focus(widget, NULL); - return FALSE; -} - -guint window_connect_focus_in_clear_focus_widget(ui::Window window) -{ - return window.connect("focus_in_event", G_CALLBACK(window_focus_in_clear_focus_widget), NULL); -} - -void window_get_position(ui::Window window, WindowPosition &position) -{ - ASSERT_MESSAGE(window, "error saving window position"); - - gtk_window_get_position(window, &position.x, &position.y); - gtk_window_get_size(window, &position.w, &position.h); -} - -void window_set_position(ui::Window window, const WindowPosition &position) -{ - gtk_window_set_gravity(window, GDK_GRAVITY_STATIC); - - GdkScreen *screen = gdk_screen_get_default(); - if (position.x < 0 - || position.y < 0 - || position.x > gdk_screen_get_width(screen) - || position.y > gdk_screen_get_height(screen)) { - gtk_window_set_position(window, GTK_WIN_POS_CENTER_ON_PARENT); - } else { - gtk_window_move(window, position.x, position.y); - } - - gtk_window_set_default_size(window, 800, 600); -} - -void WindowPosition_String::Import(WindowPosition &position, const char *value) -{ - if (sscanf(value, "%d %d %d %d", &position.x, &position.y, &position.w, &position.h) != 4) { - position = WindowPosition(c_default_window_pos); // ensure sane default value for window position - } -} - -void WindowPosition_String::Export(const WindowPosition &self, const Callback &returnz) -{ - char buffer[64]; - sprintf(buffer, "%d %d %d %d", self.x, self.y, self.w, self.h); - returnz(buffer); -} - -void WindowPositionTracker_String::Import(WindowPositionTracker &self, const char *value) -{ - WindowPosition position; - WindowPosition_String::Import(position, value); - self.setPosition(position); -} - -void -WindowPositionTracker_String::Export(const WindowPositionTracker &self, const Callback &returnz) -{ - WindowPosition_String::Export(self.getPosition(), returnz); -} - -gboolean WindowPositionTracker::configure(ui::Widget widget, GdkEventConfigure *event, WindowPositionTracker *self) -{ - self->m_position = WindowPosition(event->x, event->y, event->width, event->height); - return FALSE; -} - -void WindowPositionTracker::sync(ui::Window window) -{ - window_set_position(window, m_position); -} - -void WindowPositionTracker::connect(ui::Window window) -{ - sync(window); - window.connect("configure_event", G_CALLBACK(configure), this); -} - -const WindowPosition &WindowPositionTracker::getPosition() const -{ - return m_position; -} - -void WindowPositionTracker::setPosition(const WindowPosition &position) -{ - m_position = position; -} diff --git a/libs/gtkutil/window.h b/libs/gtkutil/window.h deleted file mode 100644 index 71efed4..0000000 --- a/libs/gtkutil/window.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GTKUTIL_WINDOW_H ) -#define INCLUDED_GTKUTIL_WINDOW_H - -#include - -#include "debugging/debugging.h" -#include "generic/callback.h" -#include "widget.h" - -gboolean window_focus_in_clear_focus_widget(ui::Window widget, GdkEventKey *event, gpointer data); - -guint window_connect_focus_in_clear_focus_widget(ui::Window window); - -unsigned int connect_floating(ui::Window main_window, ui::Window floating); - -ui::Window create_floating_window(const char *title, ui::Window parent); - -void destroy_floating_window(ui::Window window); - -ui::Window create_persistent_floating_window(const char *title, ui::Window main_window); - -gboolean persistent_floating_window_delete(ui::Window floating, GdkEvent *event, ui::Window main_window); - -void window_remove_minmax(ui::Window window); - -ui::ScrolledWindow create_scrolled_window(ui::Policy hscrollbar_policy, ui::Policy vscrollbar_policy, int border = 0); - - -struct WindowPosition { - int x, y, w, h; - - WindowPosition() - { - } - - WindowPosition(int _x, int _y, int _w, int _h) - : x(_x), y(_y), w(_w), h(_h) - { - } -}; - -const WindowPosition c_default_window_pos(50, 25, 400, 300); - -void window_get_position(ui::Window window, WindowPosition &position); - -void window_set_position(ui::Window window, const WindowPosition &position); - -struct WindowPosition_String { - - static void Export(const WindowPosition &self, const Callback &returnz); - - static void Import(WindowPosition &self, const char *value); - -}; - -class WindowPositionTracker { -WindowPosition m_position; - -static gboolean configure(ui::Widget widget, GdkEventConfigure *event, WindowPositionTracker *self); - -public: -WindowPositionTracker() - : m_position(c_default_window_pos) -{ -} - -void sync(ui::Window window); - -void connect(ui::Window window); - -const WindowPosition &getPosition() const; - -//hack -void setPosition(const WindowPosition &position); -}; - - -struct WindowPositionTracker_String { - static void Export(const WindowPositionTracker &self, const Callback &returnz); - - static void Import(WindowPositionTracker &self, const char *value); -}; - -#endif diff --git a/libs/gtkutil/xorrectangle.cpp b/libs/gtkutil/xorrectangle.cpp deleted file mode 100644 index 3bb1510..0000000 --- a/libs/gtkutil/xorrectangle.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "xorrectangle.h" - -#include - -bool XORRectangle::initialised() const -{ - return !!cr; -} - -void XORRectangle::lazy_init() -{ - if (!initialised()) { - cr = gdk_cairo_create(gtk_widget_get_window(m_widget)); - } -} - -void XORRectangle::draw() const -{ - const int x = float_to_integer(m_rectangle.x); - const int y = float_to_integer(m_rectangle.y); - const int w = float_to_integer(m_rectangle.w); - const int h = float_to_integer(m_rectangle.h); - GtkAllocation allocation; - gtk_widget_get_allocation(m_widget, &allocation); - cairo_rectangle(cr, x, -(h) - (y - allocation.height), w, h); - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); - cairo_stroke(cr); -} - -XORRectangle::XORRectangle(ui::GLArea widget) : m_widget(widget), cr(0) -{ -} - -XORRectangle::~XORRectangle() -{ - if (initialised()) { - cairo_destroy(cr); - } -} - -void XORRectangle::set(rectangle_t rectangle) -{ - if (gtk_widget_get_realized(m_widget)) { - lazy_init(); - draw(); - m_rectangle = rectangle; - draw(); - } -} diff --git a/libs/gtkutil/xorrectangle.h b/libs/gtkutil/xorrectangle.h deleted file mode 100644 index 8978ee2..0000000 --- a/libs/gtkutil/xorrectangle.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_XORRECTANGLE_H ) -#define INCLUDED_XORRECTANGLE_H - -#include -#include -#include "math/vector.h" - -class rectangle_t { -public: -rectangle_t() - : x(0), y(0), w(0), h(0) -{ -} - -rectangle_t(float _x, float _y, float _w, float _h) - : x(_x), y(_y), w(_w), h(_h) -{ -} - -float x; -float y; -float w; -float h; -}; - -struct Coord2D { - float x, y; - - Coord2D(float _x, float _y) - : x(_x), y(_y) - { - } -}; - -inline Coord2D coord2d_device2screen(const Coord2D &coord, unsigned int width, unsigned int height) -{ - return Coord2D(((coord.x + 1.0f) * 0.5f) * width, ((coord.y + 1.0f) * 0.5f) * height); -} - -inline rectangle_t rectangle_from_area(const float min[2], const float max[2], unsigned int width, unsigned int height) -{ - Coord2D botleft(coord2d_device2screen(Coord2D(min[0], min[1]), width, height)); - Coord2D topright(coord2d_device2screen(Coord2D(max[0], max[1]), width, height)); - return rectangle_t(botleft.x, botleft.y, topright.x - botleft.x, topright.y - botleft.y); -} - -class XORRectangle { - -rectangle_t m_rectangle; - -ui::GLArea m_widget; -cairo_t *cr; - -bool initialised() const; - -void lazy_init(); - -void draw() const; - -public: -XORRectangle(ui::GLArea widget); - -~XORRectangle(); - -void set(rectangle_t rectangle); -}; - - -#endif diff --git a/libs/imagelib.h b/libs/imagelib.h deleted file mode 100644 index c3e9c1c..0000000 --- a/libs/imagelib.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_IMAGELIB_H ) -#define INCLUDED_IMAGELIB_H - -#include "iimage.h" -#include "iarchive.h" -#include "idatastream.h" -#include - -struct RGBAPixel -{ - unsigned char red, green, blue, alpha; -}; - -class RGBAImage : public Image -{ -RGBAImage( const RGBAImage& other ); -RGBAImage& operator=( const RGBAImage& other ); -public: -RGBAPixel* pixels; -unsigned int width, height; - -RGBAImage( unsigned int _width, unsigned int _height ) - : pixels( new RGBAPixel[_width * _height] ), width( _width ), height( _height ){ -} -~RGBAImage(){ - delete[] pixels; -} - -void release(){ - delete this; -} -byte* getRGBAPixels() const { - return reinterpret_cast( pixels ); -} -unsigned int getWidth() const { - return width; -} -unsigned int getHeight() const { - return height; -} -}; - -class RGBAImageFlags : public RGBAImage -{ -public: -int m_surfaceFlags; -int m_contentFlags; -int m_value; -RGBAImageFlags( unsigned short _width, unsigned short _height, int surfaceFlags, int contentFlags, int value ) : - RGBAImage( _width, _height ), m_surfaceFlags( surfaceFlags ), m_contentFlags( contentFlags ), m_value( value ){ -} - -int getSurfaceFlags() const { - return m_surfaceFlags; -} -int getContentFlags() const { - return m_contentFlags; -} -int getValue() const { - return m_value; -} -}; - - -inline InputStream::byte_type* ArchiveFile_loadBuffer( ArchiveFile& file, std::size_t& length ){ - InputStream::byte_type* buffer = (InputStream::byte_type*)malloc( file.size() + 1 ); - length = file.getInputStream().read( buffer, file.size() ); - buffer[file.size()] = 0; - return buffer; -} - -inline void ArchiveFile_freeBuffer( InputStream::byte_type* buffer ){ - free( buffer ); -} - -class ScopedArchiveBuffer -{ -public: -std::size_t length; -InputStream::byte_type* buffer; - -ScopedArchiveBuffer( ArchiveFile& file ){ - buffer = ArchiveFile_loadBuffer( file, length ); -} -~ScopedArchiveBuffer(){ - ArchiveFile_freeBuffer( buffer ); -} -}; - -class PointerInputStream : public InputStream -{ -const byte* m_read; -public: -PointerInputStream( const byte* pointer ) - : m_read( pointer ){ -} -std::size_t read( byte* buffer, std::size_t length ){ - const byte* end = m_read + length; - while ( m_read != end ) - { - *buffer++ = *m_read++; - } - return length; -} -void seek( std::size_t offset ){ - m_read += offset; -} -const byte* get(){ - return m_read; -} -}; - -#endif diff --git a/libs/instancelib.h b/libs/instancelib.h deleted file mode 100644 index d07fc60..0000000 --- a/libs/instancelib.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_INSTANCELIB_H ) -#define INCLUDED_INSTANCELIB_H - -#include "debugging/debugging.h" - -#include "iscenegraph.h" - -#include "scenelib.h" -#include "generic/reference.h" -#include "generic/callback.h" -#include - -class InstanceSubgraphWalker : public scene::Traversable::Walker -{ -scene::Instantiable::Observer* m_observer; -mutable scene::Path m_path; -mutable Stack m_parent; -public: -InstanceSubgraphWalker( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* parent ) - : m_observer( observer ), m_path( path ), m_parent( parent ){ -} -bool pre( scene::Node& node ) const { - m_path.push( makeReference( node ) ); - scene::Instance* instance = Node_getInstantiable( node )->create( m_path, m_parent.top() ); - m_observer->insert( instance ); - Node_getInstantiable( node )->insert( m_observer, m_path, instance ); - m_parent.push( instance ); - return true; -} -void post( scene::Node& node ) const { - m_path.pop(); - m_parent.pop(); -} -}; - -class UninstanceSubgraphWalker : public scene::Traversable::Walker -{ -scene::Instantiable::Observer* m_observer; -mutable scene::Path m_path; -public: -UninstanceSubgraphWalker( scene::Instantiable::Observer* observer, const scene::Path& parent ) - : m_observer( observer ), m_path( parent ){ -} -bool pre( scene::Node& node ) const { - m_path.push( makeReference( node ) ); - return true; -} -void post( scene::Node& node ) const { - scene::Instance* instance = Node_getInstantiable( node )->erase( m_observer, m_path ); - m_observer->erase( instance ); - delete instance; - m_path.pop(); -} -}; - -class InstanceSet : public scene::Traversable::Observer -{ -typedef std::pair CachePath; - -typedef CachePath key_type; - -typedef std::map InstanceMap; -InstanceMap m_instances; -public: - -typedef InstanceMap::iterator iterator; - -iterator begin(){ - return m_instances.begin(); -} -iterator end(){ - return m_instances.end(); -} - -// traverse observer -void insert( scene::Node& child ){ - for ( iterator i = begin(); i != end(); ++i ) - { - Node_traverseSubgraph( child, InstanceSubgraphWalker( ( *i ).first.first, ( *i ).first.second, ( *i ).second ) ); - ( *i ).second->boundsChanged(); - } -} -void erase( scene::Node& child ){ - for ( iterator i = begin(); i != end(); ++i ) - { - Node_traverseSubgraph( child, UninstanceSubgraphWalker( ( *i ).first.first, ( *i ).first.second ) ); - ( *i ).second->boundsChanged(); - } -} - -// instance -void forEachInstance( const scene::Instantiable::Visitor& visitor ){ - for ( iterator i = begin(); i != end(); ++i ) - { - visitor.visit( *( *i ).second ); - } -} - -void insert( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance ){ - ASSERT_MESSAGE( m_instances.find( key_type( observer, PathConstReference( instance->path() ) ) ) == m_instances.end(), "InstanceSet::insert - element already exists" ); - m_instances.insert( InstanceMap::value_type( key_type( observer, PathConstReference( instance->path() ) ), instance ) ); -} -scene::Instance* erase( scene::Instantiable::Observer* observer, const scene::Path& path ){ - ASSERT_MESSAGE( m_instances.find( key_type( observer, PathConstReference( path ) ) ) != m_instances.end(), "InstanceSet::erase - failed to find element" ); - InstanceMap::iterator i = m_instances.find( key_type( observer, PathConstReference( path ) ) ); - scene::Instance* instance = i->second; - m_instances.erase( i ); - return instance; -} - -void transformChanged(){ - for ( InstanceMap::iterator i = m_instances.begin(); i != m_instances.end(); ++i ) - { - ( *i ).second->transformChanged(); - } -} -typedef MemberCaller TransformChangedCaller; -void boundsChanged(){ - for ( InstanceMap::iterator i = m_instances.begin(); i != m_instances.end(); ++i ) - { - ( *i ).second->boundsChanged(); - } -} -typedef MemberCaller BoundsChangedCaller; -}; - -template -inline void InstanceSet_forEach( InstanceSet& instances, const Functor& functor ){ - for ( InstanceSet::iterator i = instances.begin(), end = instances.end(); i != end; ++i ) - { - functor( *( *i ).second ); - } -} - -template -class InstanceSetEvaluateTransform -{ -public: -static void apply( InstanceSet& instances ){ - InstanceSet_forEach(instances, [&](scene::Instance &instance) { - InstanceTypeCast::cast(instance)->evaluateTransform(); - }); -} -typedef ReferenceCaller::apply> Caller; -}; - -#endif diff --git a/libs/maplib.h b/libs/maplib.h deleted file mode 100644 index 474ce4b..0000000 --- a/libs/maplib.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_MAPLIB_H ) -#define INCLUDED_MAPLIB_H - -#include "nameable.h" -#include "mapfile.h" - -#include "traverselib.h" -#include "transformlib.h" -#include "scenelib.h" -#include "string/string.h" -#include "instancelib.h" -#include "selectionlib.h" -#include "generic/callback.h" - - -class NameableString : public Nameable -{ -CopiedString m_name; -public: -NameableString( const char* name ) - : m_name( name ){ -} - -const char* name() const { - return m_name.c_str(); -} -void attach( const NameCallback& callback ){ -} -void detach( const NameCallback& callback ){ -} -}; - - -class UndoFileChangeTracker : public UndoTracker, public MapFile -{ -std::size_t m_size; -std::size_t m_saved; -typedef void ( UndoFileChangeTracker::*Pending )(); -Pending m_pending; -Callback m_changed; - -public: -UndoFileChangeTracker() : m_size( 0 ), m_saved( MAPFILE_MAX_CHANGES ), m_pending( 0 ){ -} -void print(){ - globalOutputStream() << "saved: " << Unsigned( m_saved ) << " size: " << Unsigned( m_size ) << "\n"; -} - -void push(){ - ++m_size; - m_changed(); - //print(); -} -void pop(){ - --m_size; - m_changed(); - //print(); -} -void pushOperation(){ - if ( m_size < m_saved ) { - // redo queue has been flushed.. it is now impossible to get back to the saved state via undo/redo - m_saved = MAPFILE_MAX_CHANGES; - } - push(); -} -void clear(){ - m_size = 0; - m_changed(); - //print(); -} -void begin(){ - m_pending = Pending( &UndoFileChangeTracker::pushOperation ); -} -void undo(){ - m_pending = Pending( &UndoFileChangeTracker::pop ); -} -void redo(){ - m_pending = Pending( &UndoFileChangeTracker::push ); -} - -void changed(){ - if ( m_pending != 0 ) { - ( ( *this ).*m_pending )(); - m_pending = 0; - } -} - -void save(){ - m_saved = m_size; - m_changed(); -} -bool saved() const { - return m_saved == m_size; -} - -void setChangedCallback( const Callback& changed ){ - m_changed = changed; - m_changed(); -} - -std::size_t changes() const { - return m_size; -} -}; - - -class MapRoot : public scene::Node::Symbiot, public scene::Instantiable, public scene::Traversable::Observer -{ -class TypeCasts -{ -NodeTypeCastTable m_casts; -public: -TypeCasts(){ - NodeStaticCast::install( m_casts ); - NodeContainedCast::install( m_casts ); - NodeContainedCast::install( m_casts ); - NodeContainedCast::install( m_casts ); - NodeContainedCast::install( m_casts ); -} -NodeTypeCastTable& get(){ - return m_casts; -} -}; - -scene::Node m_node; -IdentityTransform m_transform; -TraversableNodeSet m_traverse; -InstanceSet m_instances; -typedef SelectableInstance Instance; -NameableString m_name; -UndoFileChangeTracker m_changeTracker; -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable& get( NullType){ - return m_traverse; -} -TransformNode& get( NullType){ - return m_transform; -} -Nameable& get( NullType){ - return m_name; -} -MapFile& get( NullType){ - return m_changeTracker; -} - -MapRoot( const char* name ) : m_node( this, this, StaticTypeCasts::instance().get() ), m_name( name ){ - m_node.m_isRoot = true; - - m_traverse.attach( this ); - - GlobalUndoSystem().trackerAttach( m_changeTracker ); -} -~MapRoot(){ -} -void release(){ - GlobalUndoSystem().trackerDetach( m_changeTracker ); - - m_traverse.detach( this ); - delete this; -} -scene::Node& node(){ - return m_node; -} - -InstanceCounter m_instanceCounter; -void instanceAttach( const scene::Path& path ){ - if ( ++m_instanceCounter.m_count == 1 ) { - m_traverse.instanceAttach( path_find_mapfile( path.begin(), path.end() ) ); - } -} -void instanceDetach( const scene::Path& path ){ - if ( --m_instanceCounter.m_count == 0 ) { - m_traverse.instanceDetach( path_find_mapfile( path.begin(), path.end() ) ); - } -} - -void insert( scene::Node& child ){ - m_instances.insert( child ); -} -void erase( scene::Node& child ){ - m_instances.erase( child ); -} - -scene::Node& clone() const { - return ( new MapRoot( *this ) )->node(); -} - -scene::Instance* create( const scene::Path& path, scene::Instance* parent ){ - return new Instance( path, parent ); -} -void forEachInstance( const scene::Instantiable::Visitor& visitor ){ - m_instances.forEachInstance( visitor ); -} -void insert( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance ){ - m_instances.insert( observer, path, instance ); - instanceAttach( path ); -} -scene::Instance* erase( scene::Instantiable::Observer* observer, const scene::Path& path ){ - instanceDetach( path ); - return m_instances.erase( observer, path ); -} -}; - -inline void MapRoot_construct(){ -} - -inline void MapRoot_destroy(){ -} - -inline NodeSmartReference NewMapRoot( const char* name ){ - return NodeSmartReference( ( new MapRoot( name ) )->node() ); -} - - -#endif diff --git a/libs/math/Makefile b/libs/math/Makefile deleted file mode 100644 index d9c225b..0000000 --- a/libs/math/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ -_.o - -# binary target -../libmath.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -_.o: _.cpp aabb.h curve.h frustum.h line.h matrix.h pi.h plane.h quaternion.h vector.h - -clean: - -rm -f *.o ../libmath.a diff --git a/libs/math/_.cpp b/libs/math/_.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/libs/math/aabb.h b/libs/math/aabb.h deleted file mode 100644 index 3cc174b..0000000 --- a/libs/math/aabb.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_AABB_H ) -#define INCLUDED_MATH_AABB_H - -/// \file -/// \brief Axis-aligned bounding-box data types and related operations. - -#include "math/matrix.h" -#include "math/plane.h" - -class AABB -{ -public: -Vector3 origin, extents; - -AABB() : origin( 0, 0, 0 ), extents( -1,-1,-1 ){ -} -AABB( const Vector3& origin_, const Vector3& extents_ ) : - origin( origin_ ), extents( extents_ ){ -} -}; - -const float c_aabb_max = FLT_MAX; - -inline bool extents_valid( float f ){ - return f >= 0.0f && f <= c_aabb_max; -} - -inline bool origin_valid( float f ){ - return f >= -c_aabb_max && f <= c_aabb_max; -} - -inline bool aabb_valid( const AABB& aabb ){ - return origin_valid( aabb.origin[0] ) - && origin_valid( aabb.origin[1] ) - && origin_valid( aabb.origin[2] ) - && extents_valid( aabb.extents[0] ) - && extents_valid( aabb.extents[1] ) - && extents_valid( aabb.extents[2] ); -} - -inline AABB aabb_for_minmax( const Vector3& min, const Vector3& max ){ - AABB aabb; - aabb.origin = vector3_mid( min, max ); - aabb.extents = vector3_subtracted( max, aabb.origin ); - return aabb; -} - -template -class AABBExtend -{ -public: -static void apply( AABB& aabb, const Vector3& point ){ - float displacement = point[Index::VALUE] - aabb.origin[Index::VALUE]; - float half_difference = static_cast( 0.5 * ( fabs( displacement ) - aabb.extents[Index::VALUE] ) ); - if ( half_difference > 0.0f ) { - aabb.origin[Index::VALUE] += ( displacement >= 0.0f ) ? half_difference : -half_difference; - aabb.extents[Index::VALUE] += half_difference; - } -} -static void apply( AABB& aabb, const AABB& other ){ - float displacement = other.origin[Index::VALUE] - aabb.origin[Index::VALUE]; - float difference = other.extents[Index::VALUE] - aabb.extents[Index::VALUE]; - if ( fabs( displacement ) > fabs( difference ) ) { - float half_difference = static_cast( 0.5 * ( fabs( displacement ) + difference ) ); - if ( half_difference > 0.0f ) { - aabb.origin[Index::VALUE] += ( displacement >= 0.0f ) ? half_difference : -half_difference; - aabb.extents[Index::VALUE] += half_difference; - } - } - else if ( difference > 0.0f ) { - aabb.origin[Index::VALUE] = other.origin[Index::VALUE]; - aabb.extents[Index::VALUE] = other.extents[Index::VALUE]; - } -} -}; - -inline void aabb_extend_by_point( AABB& aabb, const Vector3& point ){ - AABBExtend< IntegralConstant<0> >::apply( aabb, point ); - AABBExtend< IntegralConstant<1> >::apply( aabb, point ); - AABBExtend< IntegralConstant<2> >::apply( aabb, point ); -} - -inline void aabb_extend_by_point_safe( AABB& aabb, const Vector3& point ){ - if ( aabb_valid( aabb ) ) { - aabb_extend_by_point( aabb, point ); - } - else - { - aabb.origin = point; - aabb.extents = Vector3( 0, 0, 0 ); - } -} - -inline void aabb_extend_by_aabb( AABB& aabb, const AABB& other ){ - AABBExtend< IntegralConstant<0> >::apply( aabb, other ); - AABBExtend< IntegralConstant<1> >::apply( aabb, other ); - AABBExtend< IntegralConstant<2> >::apply( aabb, other ); -} - -inline void aabb_extend_by_aabb_safe( AABB& aabb, const AABB& other ){ - if ( aabb_valid( aabb ) && aabb_valid( other ) ) { - aabb_extend_by_aabb( aabb, other ); - } - else if ( aabb_valid( other ) ) { - aabb = other; - } -} - -inline void aabb_extend_by_vec3( AABB& aabb, const Vector3& extension ){ - vector3_add( aabb.extents, extension ); -} - - - - -template -inline bool aabb_intersects_point_dimension( const AABB& aabb, const Vector3& point ){ - return fabs( point[Index::VALUE] - aabb.origin[Index::VALUE] ) < aabb.extents[Index::VALUE]; -} - -inline bool aabb_intersects_point( const AABB& aabb, const Vector3& point ){ - return aabb_intersects_point_dimension< IntegralConstant<0> >( aabb, point ) - && aabb_intersects_point_dimension< IntegralConstant<1> >( aabb, point ) - && aabb_intersects_point_dimension< IntegralConstant<2> >( aabb, point ); -} - -template -inline bool aabb_intersects_aabb_dimension( const AABB& aabb, const AABB& other ){ - return fabs( other.origin[Index::VALUE] - aabb.origin[Index::VALUE] ) < ( aabb.extents[Index::VALUE] + other.extents[Index::VALUE] ); -} - -inline bool aabb_intersects_aabb( const AABB& aabb, const AABB& other ){ - return aabb_intersects_aabb_dimension< IntegralConstant<0> >( aabb, other ) - && aabb_intersects_aabb_dimension< IntegralConstant<1> >( aabb, other ) - && aabb_intersects_aabb_dimension< IntegralConstant<2> >( aabb, other ); -} - -inline unsigned int aabb_classify_plane( const AABB& aabb, const Plane3& plane ){ - double distance_origin = vector3_dot( plane.normal(), aabb.origin ) + plane.dist(); - - if ( fabs( distance_origin ) < ( fabs( plane.a * aabb.extents[0] ) - + fabs( plane.b * aabb.extents[1] ) - + fabs( plane.c * aabb.extents[2] ) ) ) { - return 1; // partially inside - } - else if ( distance_origin < 0 ) { - return 2; // totally inside - } - return 0; // totally outside -} - -inline unsigned int aabb_oriented_classify_plane( const AABB& aabb, const Matrix4& transform, const Plane3& plane ){ - double distance_origin = vector3_dot( plane.normal(), aabb.origin ) + plane.dist(); - - if ( fabs( distance_origin ) < ( fabs( aabb.extents[0] * vector3_dot( plane.normal(), vector4_to_vector3( transform.x() ) ) ) - + fabs( aabb.extents[1] * vector3_dot( plane.normal(), vector4_to_vector3( transform.y() ) ) ) - + fabs( aabb.extents[2] * vector3_dot( plane.normal(), vector4_to_vector3( transform.z() ) ) ) ) ) { - return 1; // partially inside - } - else if ( distance_origin < 0 ) { - return 2; // totally inside - } - return 0; // totally outside -} - -inline void aabb_corners( const AABB& aabb, Vector3 corners[8] ){ - Vector3 min( vector3_subtracted( aabb.origin, aabb.extents ) ); - Vector3 max( vector3_added( aabb.origin, aabb.extents ) ); - corners[0] = Vector3( min[0], max[1], max[2] ); - corners[1] = Vector3( max[0], max[1], max[2] ); - corners[2] = Vector3( max[0], min[1], max[2] ); - corners[3] = Vector3( min[0], min[1], max[2] ); - corners[4] = Vector3( min[0], max[1], min[2] ); - corners[5] = Vector3( max[0], max[1], min[2] ); - corners[6] = Vector3( max[0], min[1], min[2] ); - corners[7] = Vector3( min[0], min[1], min[2] ); -} - -inline void aabb_corners_oriented( const AABB& aabb, const Matrix4& rotation, Vector3 corners[8] ){ - Vector3 x = vector4_to_vector3( rotation.x() ) * aabb.extents.x(); - Vector3 y = vector4_to_vector3( rotation.y() ) * aabb.extents.y(); - Vector3 z = vector4_to_vector3( rotation.z() ) * aabb.extents.z(); - - corners[0] = aabb.origin + -x + y + z; - corners[1] = aabb.origin + x + y + z; - corners[2] = aabb.origin + x + -y + z; - corners[3] = aabb.origin + -x + -y + z; - corners[4] = aabb.origin + -x + y + -z; - corners[5] = aabb.origin + x + y + -z; - corners[6] = aabb.origin + x + -y + -z; - corners[7] = aabb.origin + -x + -y + -z; -} - -inline void aabb_planes( const AABB& aabb, Plane3 planes[6] ){ - planes[0] = Plane3( g_vector3_axes[0], aabb.origin[0] + aabb.extents[0] ); - planes[1] = Plane3( vector3_negated( g_vector3_axes[0] ), -( aabb.origin[0] - aabb.extents[0] ) ); - planes[2] = Plane3( g_vector3_axes[1], aabb.origin[1] + aabb.extents[1] ); - planes[3] = Plane3( vector3_negated( g_vector3_axes[1] ), -( aabb.origin[1] - aabb.extents[1] ) ); - planes[4] = Plane3( g_vector3_axes[2], aabb.origin[2] + aabb.extents[2] ); - planes[5] = Plane3( vector3_negated( g_vector3_axes[2] ), -( aabb.origin[2] - aabb.extents[2] ) ); -} - -inline void aabb_planes_oriented( const AABB& aabb, const Matrix4& rotation, Plane3 planes[6] ){ - double x = vector3_dot( vector4_to_vector3( rotation.x() ), aabb.origin ); - double y = vector3_dot( vector4_to_vector3( rotation.y() ), aabb.origin ); - double z = vector3_dot( vector4_to_vector3( rotation.z() ), aabb.origin ); - - planes[0] = Plane3( vector4_to_vector3( rotation.x() ), x + aabb.extents[0] ); - planes[1] = Plane3( -vector4_to_vector3( rotation.x() ), -( x - aabb.extents[0] ) ); - planes[2] = Plane3( vector4_to_vector3( rotation.y() ), y + aabb.extents[1] ); - planes[3] = Plane3( -vector4_to_vector3( rotation.y() ), -( y - aabb.extents[1] ) ); - planes[4] = Plane3( vector4_to_vector3( rotation.z() ), z + aabb.extents[2] ); - planes[5] = Plane3( -vector4_to_vector3( rotation.z() ), -( z - aabb.extents[2] ) ); -} - -const Vector3 aabb_normals[6] = { - Vector3( 1, 0, 0 ), - Vector3( 0, 1, 0 ), - Vector3( 0, 0, 1 ), - Vector3( -1, 0, 0 ), - Vector3( 0,-1, 0 ), - Vector3( 0, 0,-1 ), -}; - -const float aabb_texcoord_topleft[2] = { 0, 0 }; -const float aabb_texcoord_topright[2] = { 1, 0 }; -const float aabb_texcoord_botleft[2] = { 0, 1 }; -const float aabb_texcoord_botright[2] = { 1, 1 }; - - -inline AABB aabb_for_oriented_aabb( const AABB& aabb, const Matrix4& transform ){ - return AABB( - matrix4_transformed_point( transform, aabb.origin ), - Vector3( - static_cast( fabs( transform[0] * aabb.extents[0] ) - + fabs( transform[4] * aabb.extents[1] ) - + fabs( transform[8] * aabb.extents[2] ) ), - static_cast( fabs( transform[1] * aabb.extents[0] ) - + fabs( transform[5] * aabb.extents[1] ) - + fabs( transform[9] * aabb.extents[2] ) ), - static_cast( fabs( transform[2] * aabb.extents[0] ) - + fabs( transform[6] * aabb.extents[1] ) - + fabs( transform[10] * aabb.extents[2] ) ) - ) - ); -} - -inline AABB aabb_for_oriented_aabb_safe( const AABB& aabb, const Matrix4& transform ){ - if ( aabb_valid( aabb ) ) { - return aabb_for_oriented_aabb( aabb, transform ); - } - return aabb; -} - -inline AABB aabb_infinite(){ - return AABB( Vector3( 0, 0, 0 ), Vector3( c_aabb_max, c_aabb_max, c_aabb_max ) ); -} - -#endif diff --git a/libs/math/curve.h b/libs/math/curve.h deleted file mode 100644 index b430bf0..0000000 --- a/libs/math/curve.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_CURVE_H ) -#define INCLUDED_MATH_CURVE_H - -/// \file -/// \brief Curve data types and related operations. - -#include "debugging/debugging.h" -#include "container/array.h" -#include - - -template -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 1; // general case not implemented - } -}; - -typedef IntegralConstant<0> Zero; -typedef IntegralConstant<1> One; -typedef IntegralConstant<2> Two; -typedef IntegralConstant<3> Three; -typedef IntegralConstant<4> Four; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 1; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 1 - t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return ( 1 - t ) * ( 1 - t ); - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 2 * ( 1 - t ) * t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return t * t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return ( 1 - t ) * ( 1 - t ) * ( 1 - t ); - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 3 * ( 1 - t ) * ( 1 - t ) * t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return 3 * ( 1 - t ) * t * t; - } -}; - -template<> -struct BernsteinPolynomial -{ - static double apply( double t ){ - return t * t * t; - } -}; - -typedef Array ControlPoints; - -inline Vector3 CubicBezier_evaluate( const Vector3* firstPoint, double t ){ - Vector3 result( 0, 0, 0 ); - double denominator = 0; - - { - double weight = BernsteinPolynomial::apply( t ); - result += vector3_scaled( *firstPoint++, weight ); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply( t ); - result += vector3_scaled( *firstPoint++, weight ); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply( t ); - result += vector3_scaled( *firstPoint++, weight ); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply( t ); - result += vector3_scaled( *firstPoint++, weight ); - denominator += weight; - } - - return result / denominator; -} - -inline Vector3 CubicBezier_evaluateMid( const Vector3* firstPoint ){ - return vector3_scaled( firstPoint[0], 0.125 ) - + vector3_scaled( firstPoint[1], 0.375 ) - + vector3_scaled( firstPoint[2], 0.375 ) - + vector3_scaled( firstPoint[3], 0.125 ); -} - -inline Vector3 CatmullRom_evaluate( const ControlPoints& controlPoints, double t ){ - // scale t to be segment-relative - t *= double(controlPoints.size() - 1); - - // subtract segment index; - std::size_t segment = 0; - for ( std::size_t i = 0; i < controlPoints.size() - 1; ++i ) - { - if ( t <= double(i + 1) ) { - segment = i; - break; - } - } - t -= segment; - - const double reciprocal_alpha = 1.0 / 3.0; - - Vector3 bezierPoints[4]; - bezierPoints[0] = controlPoints[segment]; - bezierPoints[1] = ( segment > 0 ) - ? controlPoints[segment] + vector3_scaled( controlPoints[segment + 1] - controlPoints[segment - 1], reciprocal_alpha * 0.5 ) - : controlPoints[segment] + vector3_scaled( controlPoints[segment + 1] - controlPoints[segment], reciprocal_alpha ); - bezierPoints[2] = ( segment < controlPoints.size() - 2 ) - ? controlPoints[segment + 1] + vector3_scaled( controlPoints[segment] - controlPoints[segment + 2], reciprocal_alpha * 0.5 ) - : controlPoints[segment + 1] + vector3_scaled( controlPoints[segment] - controlPoints[segment + 1], reciprocal_alpha ); - bezierPoints[3] = controlPoints[segment + 1]; - return CubicBezier_evaluate( bezierPoints, t ); -} - -typedef Array Knots; - -inline double BSpline_basis( const Knots& knots, std::size_t i, std::size_t degree, double t ){ - if ( degree == 0 ) { - if ( knots[i] <= t - && t < knots[i + 1] - && knots[i] < knots[i + 1] ) { - return 1; - } - return 0; - } - double leftDenom = knots[i + degree] - knots[i]; - double left = ( leftDenom == 0 ) ? 0 : ( ( t - knots[i] ) / leftDenom ) * BSpline_basis( knots, i, degree - 1, t ); - double rightDenom = knots[i + degree + 1] - knots[i + 1]; - double right = ( rightDenom == 0 ) ? 0 : ( ( knots[i + degree + 1] - t ) / rightDenom ) * BSpline_basis( knots, i + 1, degree - 1, t ); - return left + right; -} - -inline Vector3 BSpline_evaluate( const ControlPoints& controlPoints, const Knots& knots, std::size_t degree, double t ){ - Vector3 result( 0, 0, 0 ); - for ( std::size_t i = 0; i < controlPoints.size(); ++i ) - { - result += vector3_scaled( controlPoints[i], BSpline_basis( knots, i, degree, t ) ); - } - return result; -} - -typedef Array NURBSWeights; - -inline Vector3 NURBS_evaluate( const ControlPoints& controlPoints, const NURBSWeights& weights, const Knots& knots, std::size_t degree, double t ){ - Vector3 result( 0, 0, 0 ); - double denominator = 0; - for ( std::size_t i = 0; i < controlPoints.size(); ++i ) - { - double weight = weights[i] * BSpline_basis( knots, i, degree, t ); - result += vector3_scaled( controlPoints[i], weight ); - denominator += weight; - } - return result / denominator; -} - -inline void KnotVector_openUniform( Knots& knots, std::size_t count, std::size_t degree ){ - knots.resize( count + degree + 1 ); - - std::size_t equalKnots = 1; - - for ( std::size_t i = 0; i < equalKnots; ++i ) - { - knots[i] = 0; - knots[knots.size() - ( i + 1 )] = 1; - } - - std::size_t difference = knots.size() - 2 * ( equalKnots ); - for ( std::size_t i = 0; i < difference; ++i ) - { - knots[i + equalKnots] = Knots::value_type( double(i + 1) * 1.0 / double(difference + 1) ); - } -} - -#endif diff --git a/libs/math/expression.cpp b/libs/math/expression.cpp deleted file mode 100644 index 13f6bfe..0000000 --- a/libs/math/expression.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "expression.h" - -Vector3 testAdded1( const Vector3& a, const Vector3& b ){ - return vector3_added( a, vector3_added( a, b ) ); -} - -Vector3 testAdded2( const Vector3& a, const Vector3& b ){ - return vector3_for_expression( vector_added( vector3_identity( a ), vector_added( vector3_identity( a ), vector3_identity( b ) ) ) ); -} - -Vector3 testMultiplied1( const Vector3& a, const Vector3& b ){ - return vector3_scaled( a, b ); -} - -Vector3 testMultiplied2( const Vector3& a, const Vector3& b ){ - return vector3_for_expression( vector_multiplied( vector3_identity( a ), vector3_identity( b ) ) ); -} - -Vector3 testCross1( const Vector3& a, const Vector3& b ){ - return vector3_cross( a, b ); -} - -Vector3 testCross2( const Vector3& a, const Vector3& b ){ - return vector3_for_expression( vector_cross( vector3_identity( a ), vector3_identity( b ) ) ); -} - -double testDot1( const Vector3& a, const Vector3& b ){ - return vector3_dot( a, b ); -} - -double testDot2( const Vector3& a, const Vector3& b ){ - return float_for_expression( vector_dot( vector3_identity( a ), vector3_identity( b ) ) ); -} - -double testLength1( const Vector3& a ){ - return vector3_length( a ); -} - -double testLength2( const Vector3& a ){ - return float_for_expression( vector_length( vector3_identity( a ) ) ); -} - -Vector3 testNormalised1( const Vector3& a ){ - return vector3_normalised( a ); -} - -Vector3 testNormalised2( const Vector3& a ){ - return vector3_for_expression( vector_normalised( vector3_identity( a ) ) ); -} - -Vector3 testNegated1( const Vector3& a ){ - return vector3_negated( a ); -} - -Vector3 testNegated2( const Vector3& a ){ - return vector3_for_expression( vector_negated( vector3_identity( a ) ) ); -} - -Vector3 testScaled1( const Vector3& a, const double& b ){ - return vector3_scaled( a, b ); -} - -Vector3 testScaled2( const Vector3& a, const double& b ){ - return vector3_for_expression( vector_scaled( vector3_identity( a ), float_literal( b ) ) ); -} - -Vector3 testMatrixMultiplied1( const Vector3& a, const Matrix4& b ){ - return matrix4_transformed_point( b, vector3_added( a, Vector3( 1, 0, 0 ) ) ); -} - -Vector3 testMatrixMultiplied2( const Vector3& a, const Matrix4& b ){ - return vector3_for_expression( - point_multiplied( - vector_added( - vector3_identity( a ), - vector3_literal( Vector3( 1, 0, 0 ) ) - ), - matrix4_identity( b ) - ) - ); -} - -Matrix4 testMatrix4Multiplied1( const Matrix4& a, const Matrix4& b ){ - return matrix4_multiplied_by_matrix4( a, matrix4_multiplied_by_matrix4( a, b ) ); -} - -Matrix4 testMatrix4Multiplied2( const Matrix4& a, const Matrix4& b ){ - return matrix4_for_expression( - matrix4_multiplied( - matrix4_identity( a ), - matrix4_identity( b ) - ) - ); -} - -Matrix4 testMatrix4AffineMultiplied1( const Matrix4& a, const Matrix4& b ){ - return matrix4_affine_multiplied_by_matrix4( a, b ); -} - -Matrix4 testMatrix4AffineMultiplied2( const Matrix4& a, const Matrix4& b ){ - return matrix4_affine_for_expression( - matrix4_multiplied( - matrix4_identity( a ), - matrix4_identity( b ) - ) - ); -} - -Matrix4 testMatrix4MultipliedConstant1( const Matrix4& a ){ - return matrix4_multiplied_by_matrix4( a, g_matrix4_identity ); -} - -Matrix4 testMatrix4MultipliedConstant2( const Matrix4& a ){ - return matrix4_for_expression( - matrix4_multiplied( - matrix4_identity( a ), - matrix4_identity( g_matrix4_identity ) - ) - ); -} -Matrix4 testMatrix4Transposed1( const Matrix4& a ){ - return matrix4_transposed( a ); -} - -Matrix4 testMatrix4Transposed2( const Matrix4& a ){ - return matrix4_for_expression( matrix_transposed( matrix4_identity( a ) ) ); -} - -Vector3 testMulti1( const Matrix4& a, const Vector3& b, const Vector3& c ){ - return vector3_added( matrix4_transformed_point( matrix4_transposed( a ), b ), c ); -} - -Vector3 testMulti2( const Matrix4& a, const Vector3& b, const Vector3& c ){ - return vector3_for_expression( - vector_added( - point_multiplied( - vector3_identity( b ), - matrix_transposed( matrix4_identity( a ) ) - ), - vector3_identity( c ) - ) - ); -} - -template -class TestBinaryFunction -{ -typedef Value ( *Function )( const First&, const Second& ); -Function m_function; -public: - -TestBinaryFunction( Function function ) : m_function( function ){ -} -Value run( const First& first, const Second& second ) const { - return m_function( first, second ); -} -}; - -template -class TestUnaryFunction -{ -typedef Value ( *Function )( const First& ); -Function m_function; -public: - -TestUnaryFunction( Function function ) : m_function( function ){ -} -Value run( const First& first ) const { - return m_function( first ); -} -}; - -class TestAll -{ -public: -TestAll(){ - Vector3 result1 = TestBinaryFunction( testAdded1 ).run( Vector3( 0, 0, 0 ), Vector3( 1, 1, 1 ) ); - Vector3 result2 = TestBinaryFunction( testAdded2 ).run( Vector3( 0, 0, 0 ), Vector3( 1, 1, 1 ) ); - Vector3 result3 = TestBinaryFunction( testMultiplied1 ).run( Vector3( 1, 2, 3 ), Vector3( 2, 1, 0.5f ) ); - Vector3 result4 = TestBinaryFunction( testMultiplied2 ).run( Vector3( 1, 2, 3 ), Vector3( 2, 1, 0.5f ) ); - Vector3 result5 = TestBinaryFunction( testScaled1 ).run( Vector3( 1, 2, 3 ), 2.0 ); - Vector3 result6 = TestBinaryFunction( testScaled2 ).run( Vector3( 1, 2, 3 ), 2.0 ); - Vector3 result7 = TestBinaryFunction( testMatrixMultiplied1 ).run( Vector3( 1, 2, 3 ), matrix4_rotation_for_x_degrees( 90 ) ); - Vector3 result8 = TestBinaryFunction( testMatrixMultiplied2 ).run( Vector3( 1, 2, 3 ), matrix4_rotation_for_x_degrees( 90 ) ); - Vector3 result9 = TestUnaryFunction( testNormalised1 ).run( Vector3( 1, 2, 3 ) ); - Vector3 result10 = TestUnaryFunction( testNormalised2 ).run( Vector3( 1, 2, 3 ) ); -} -} g_testAll; diff --git a/libs/math/expression.h b/libs/math/expression.h deleted file mode 100644 index 17eeace..0000000 --- a/libs/math/expression.h +++ /dev/null @@ -1,552 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_EXPRESSION_H ) -#define INCLUDED_EXPRESSION_H - -#include - -template -class Literal -{ -Value m_value; -public: -typedef Value value_type; - -Literal( const Value& value ) - : m_value( value ){ -} -const value_type& eval() const { - return m_value; -} -}; - -template -inline Literal float_literal( const Value& value ){ - return Literal( value ); -} - -template -inline float float_for_expression( const Expression& expression ){ - return expression.eval(); -} - - -template -class ScalarDivided -{ -First first; -Second second; -public: -typedef typename First::value_type value_type; - -ScalarDivided( const First& first_, const Second& second_ ) : first( first_ ), second( second_ ){ -} -value_type eval() const { - return static_cast( first.eval() / second.eval() ); -} -}; - -template -inline ScalarDivided float_divided( const First& first, const Second& second ){ - return ScalarDivided( first, second ); -} - -template -inline ScalarDivided, First> float_reciprocal( const First& first ){ - typedef typename First::value_type first_value_type; - return ScalarDivided, First>( float_literal( first_value_type( 1.0 ) ), first ); -} - -template -class SquareRoot -{ -First first; -public: -typedef typename First::value_type value_type; - -SquareRoot( const First& first_ ) : first( first_ ){ -} -value_type eval() const { - return static_cast( sqrt( first.eval() ) ); -} -}; - -template -inline SquareRoot float_square_root( const First& first ){ - return SquareRoot( first ); -} - - -template -class BasicVector3Literal -{ -const BasicVector3 m_value; -public: -typedef Element value_type; -typedef IntegralConstant<3> dimension; - -BasicVector3Literal( const BasicVector3& value ) - : m_value( value ){ -} -const value_type& eval( unsigned int i ) const { - return m_value[i]; -} -}; - -template -inline BasicVector3Literal vector3_literal( const BasicVector3& value ){ - return BasicVector3Literal( value ); -} - -typedef BasicVector3Literal Vector3Literal; - -template -class BasicVector3Identity -{ -const BasicVector3& m_value; -public: -typedef Element value_type; -typedef IntegralConstant<3> dimension; - -BasicVector3Identity( const BasicVector3& value ) - : m_value( value ){ -} -const value_type& eval( unsigned int i ) const { - return m_value[i]; -} -}; - -template -inline BasicVector3Identity vector3_identity( const BasicVector3& value ){ - return BasicVector3Identity( value ); -} - -typedef BasicVector3Identity Vector3Identity; - -template -inline BasicVector3 vector3_for_expression( const Expression& expression ){ - return Vector3( expression.eval( 0 ), expression.eval( 1 ), expression.eval( 2 ) ); -} - - -template -class VectorScalar -{ -First first; -Literal second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorScalar( const First& first_, const Second& second_ ) - : first( first_ ), second( second_.eval() ){ -} -value_type eval( unsigned int i ) const { - return Operation::apply( first.eval( i ), second.eval() ); -} -}; - - - -template -class VectorVector -{ -First first; -Second second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorVector( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} -value_type eval( unsigned int i ) const { - return Operation::apply( first.eval( i ), second.eval( i ) ); -} -}; - -template -class Added -{ -public: -typedef First value_type; - -static value_type apply( const First& first, const Second& second ){ - return static_cast( first + second ); -} -}; - -template -inline VectorVector, First, Second> -vector_added( const First& first, const Second& second ){ - typedef typename First::value_type first_value_type; - typedef typename Second::value_type second_value_type; - return VectorVector, First, Second>( first, second ); -} - -template -class Multiplied -{ -public: -typedef First value_type; - -static value_type apply( const First& first, const Second& second ){ - return static_cast( first * second ); -} -}; - -template -inline VectorVector, First, Second> -vector_multiplied( const First& first, const Second& second ){ - typedef typename First::value_type first_value_type; - typedef typename Second::value_type second_value_type; - return VectorVector, First, Second>( first, second ); -} - -template -inline VectorScalar, First, Second> -vector_scaled( const First& first, const Second& second ){ - typedef typename First::value_type first_value_type; - typedef typename Second::value_type second_value_type; - return VectorScalar, First, Second>( first, second ); -} - -template -class Negated -{ -public: -typedef First value_type; - -static value_type apply( const First& first ){ - return -first; -} -}; - -template -class VectorUnary -{ -First first; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorUnary( const First& first_ ) : first( first_ ){ -} -value_type eval( unsigned int i ) const { - return Operation::apply( first.eval( i ) ); -} -}; - -template -inline VectorUnary > -vector_negated( const First& first ){ - typedef typename First::value_type first_value_type; - return VectorUnary >( first ); -} - -template -class VectorCross -{ -First first; -Second second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorCross( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} -value_type eval( unsigned int i ) const { - return first.eval( ( i + 1 ) % 3 ) * second.eval( ( i + 2 ) % 3 ) - first.eval( ( i + 2 ) % 3 ) * second.eval( ( i + 1 ) % 3 ); -} -}; - -template -inline VectorCross -vector_cross( const First& first, const Second& second ){ - return VectorCross( first, second ); -} - - -template -class VectorDot -{ -First first; -Second second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorDot( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} - -template -struct eval_dot -{ - static value_type apply( const First& first, const Second& second ){ - return static_cast( - first.eval( Index::VALUE ) * second.eval( Index::VALUE ) - + eval_dot< IntegralConstant >::apply( first, second ) - ); - } -}; - -template<> -struct eval_dot< IntegralConstant<0> > -{ - static value_type apply( const First& first, const Second& second ){ - return first.eval( 0 ) * second.eval( 0 ); - } -}; - -value_type eval() const { - return eval_dot< IntegralConstant >::apply( first, second ); -} -}; - - -template -inline VectorDot vector_dot( const First& first, const Second& second ){ - return VectorDot( first, second ); -} - -template -class VectorLengthSquared -{ -First first; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -VectorLengthSquared( const First& first_ ) - : first( first_ ){ -} - -static value_type squared( const value_type& value ){ - return value * value; -} - -template -struct eval_squared -{ - static value_type apply( const First& first ){ - return static_cast( - squared( first.eval( Index::VALUE ) ) - + eval_squared< IntegralConstant >::apply( first ) - ); - } -}; - -template<> -struct eval_squared< IntegralConstant<0> > -{ - static value_type apply( const First& first ){ - return squared( first.eval( 0 ) ); - } -}; - -value_type eval() const { - return eval_squared< IntegralConstant >::apply( first ); -} -}; - -template -inline VectorLengthSquared vector_length_squared( const First& first ){ - return VectorLengthSquared( first ); -} - -template -inline SquareRoot< VectorLengthSquared > vector_length( const First& first ){ - return float_square_root( vector_length_squared( first ) ); -} - -#if 1 -template -inline VectorScalar< - Multiplied, - First, - // multiple evaulations of subexpression - ScalarDivided< - Literal, - SquareRoot< - VectorLengthSquared - > - > - > vector_normalised( const First& first ){ - typedef typename First::value_type first_value_type; - return vector_scaled( first, float_reciprocal( vector_length( first ) ) ); -} -#else -template -inline VectorScalar< - Multiplied, - First, - // single evaluation of subexpression - Literal - > -vector_normalised( const First& first ){ - typedef typename First::value_type first_value_type; - return vector_scaled( first, float_literal( static_cast( first_value_type( 1.0 ) / vector_length( first ).eval() ) ) ); -} -#endif - - -class Matrix4Literal -{ -const Matrix4 m_value; -public: -typedef float value_type; -typedef IntegralConstant<4> dimension0; -typedef IntegralConstant<4> dimension1; - -Matrix4Literal( const Matrix4& value ) - : m_value( value ){ -} -const value_type& eval( unsigned int r, unsigned int c ) const { - return m_value[r * 4 + c]; -} -}; - -inline Matrix4Literal matrix4_literal( const Matrix4& value ){ - return Matrix4Literal( value ); -} - -class Matrix4Identity -{ -const Matrix4& m_value; -public: -typedef float value_type; -typedef IntegralConstant<4> dimension0; -typedef IntegralConstant<4> dimension1; - -Matrix4Identity( const Matrix4& value ) - : m_value( value ){ -} -const value_type& eval( unsigned int r, unsigned int c ) const { - return m_value[r * 4 + c]; -} -}; - -inline Matrix4Identity matrix4_identity( const Matrix4& value ){ - return Matrix4Identity( value ); -} - -template -inline Matrix4 matrix4_for_expression( const Expression& expression ){ - return Matrix4( - expression.eval( 0, 0 ), expression.eval( 0, 1 ), expression.eval( 0, 2 ), expression.eval( 0, 3 ), - expression.eval( 1, 0 ), expression.eval( 1, 1 ), expression.eval( 1, 2 ), expression.eval( 1, 3 ), - expression.eval( 2, 0 ), expression.eval( 2, 1 ), expression.eval( 2, 2 ), expression.eval( 2, 3 ), - expression.eval( 3, 0 ), expression.eval( 3, 1 ), expression.eval( 3, 2 ), expression.eval( 3, 3 ) - ); -} - -template -inline Matrix4 matrix4_affine_for_expression( const Expression& expression ){ - return Matrix4( - expression.eval( 0, 0 ), expression.eval( 0, 1 ), expression.eval( 0, 2 ), 0, - expression.eval( 1, 0 ), expression.eval( 1, 1 ), expression.eval( 1, 2 ), 0, - expression.eval( 2, 0 ), expression.eval( 2, 1 ), expression.eval( 2, 2 ), 0, - expression.eval( 3, 0 ), expression.eval( 3, 1 ), expression.eval( 3, 2 ), 1 - ); -} - - -template -class PointMultiplied -{ -const First& first; -const Second& second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension dimension; - -PointMultiplied( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} -value_type eval( unsigned int i ) const { - return static_cast( second.eval( 0, i ) * first.eval( 0 ) - + second.eval( 1, i ) * first.eval( 1 ) - + second.eval( 2, i ) * first.eval( 2 ) - + second.eval( 3, i ) ); -} -}; - -template -inline PointMultiplied point_multiplied( const First& point, const Second& matrix ){ - return PointMultiplied( point, matrix ); -} - -template -class Matrix4Multiplied -{ -const First& first; -const Second& second; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension0 dimension0; -typedef typename First::dimension1 dimension1; - -Matrix4Multiplied( const First& first_, const Second& second_ ) - : first( first_ ), second( second_ ){ -} - -value_type eval( unsigned int r, unsigned int c ) const { - return static_cast( - second.eval( r, 0 ) * first.eval( 0, c ) - + second.eval( r, 1 ) * first.eval( 1, c ) - + second.eval( r, 2 ) * first.eval( 2, c ) - + second.eval( r, 3 ) * first.eval( 3, c ) - ); -} -}; - -template -inline Matrix4Multiplied matrix4_multiplied( const First& first, const Second& second ){ - return Matrix4Multiplied( first, second ); -} - -template -class MatrixTransposed -{ -const First& first; -public: -typedef typename First::value_type value_type; -typedef typename First::dimension0 dimension0; -typedef typename First::dimension1 dimension1; - -MatrixTransposed( const First& first_ ) - : first( first_ ){ -} - -value_type eval( unsigned int r, unsigned int c ) const { - return first.eval( c, r ); -} -}; - -template -inline MatrixTransposed matrix_transposed( const First& first ){ - return MatrixTransposed( first ); -} - -#endif diff --git a/libs/math/frustum.h b/libs/math/frustum.h deleted file mode 100644 index 32b0cdc..0000000 --- a/libs/math/frustum.h +++ /dev/null @@ -1,607 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_FRUSTUM_H ) -#define INCLUDED_MATH_FRUSTUM_H - -/// \file -/// \brief View-frustum data types and related operations. - -#include "generic/enumeration.h" -#include "math/matrix.h" -#include "math/plane.h" -#include "math/aabb.h" -#include "math/line.h" - -inline Matrix4 matrix4_frustum( float left, float right, float bottom, float top, float nearval, float farval ){ - return Matrix4( - static_cast( ( 2 * nearval ) / ( right - left ) ), - 0, - 0, - 0, - 0, - static_cast( ( 2 * nearval ) / ( top - bottom ) ), - 0, - 0, - static_cast( ( right + left ) / ( right - left ) ), - static_cast( ( top + bottom ) / ( top - bottom ) ), - static_cast( -( farval + nearval ) / ( farval - nearval ) ), - -1, - 0, - 0, - static_cast( -( 2 * farval * nearval ) / ( farval - nearval ) ), - 0 - ); -} - - - -typedef unsigned char ClipResult; -const ClipResult c_CLIP_PASS = 0x00; // 000000 -const ClipResult c_CLIP_LT_X = 0x01; // 000001 -const ClipResult c_CLIP_GT_X = 0x02; // 000010 -const ClipResult c_CLIP_LT_Y = 0x04; // 000100 -const ClipResult c_CLIP_GT_Y = 0x08; // 001000 -const ClipResult c_CLIP_LT_Z = 0x10; // 010000 -const ClipResult c_CLIP_GT_Z = 0x20; // 100000 -const ClipResult c_CLIP_FAIL = 0x3F; // 111111 - -template -class Vector4ClipLT -{ -public: -static bool compare( const Vector4& self ){ - return self[Index::VALUE] < self[3]; -} -static double scale( const Vector4& self, const Vector4& other ){ - return ( self[Index::VALUE] - self[3] ) / ( other[3] - other[Index::VALUE] ); -} -}; - -template -class Vector4ClipGT -{ -public: -static bool compare( const Vector4& self ){ - return self[Index::VALUE] > -self[3]; -} -static double scale( const Vector4& self, const Vector4& other ){ - return ( self[Index::VALUE] + self[3] ) / ( -other[3] - other[Index::VALUE] ); -} -}; - -template -class Vector4ClipPolygon -{ -public: -typedef Vector4* iterator; -typedef const Vector4* const_iterator; - -static std::size_t apply( const_iterator first, const_iterator last, iterator out ){ - const_iterator next = first, i = last - 1; - iterator tmp( out ); - bool b0 = ClipPlane::compare( *i ); - while ( next != last ) - { - bool b1 = ClipPlane::compare( *next ); - if ( b0 ^ b1 ) { - *out = vector4_subtracted( *next, *i ); - - double scale = ClipPlane::scale( *i, *out ); - - ( *out )[0] = static_cast( ( *i )[0] + scale * ( ( *out )[0] ) ); - ( *out )[1] = static_cast( ( *i )[1] + scale * ( ( *out )[1] ) ); - ( *out )[2] = static_cast( ( *i )[2] + scale * ( ( *out )[2] ) ); - ( *out )[3] = static_cast( ( *i )[3] + scale * ( ( *out )[3] ) ); - - ++out; - } - - if ( b1 ) { - *out = *next; - ++out; - } - - i = next; - ++next; - b0 = b1; - } - - return out - tmp; -} -}; - -#define CLIP_X_LT_W( p ) ( Vector4ClipLT< IntegralConstant<0> >::compare( p ) ) -#define CLIP_X_GT_W( p ) ( Vector4ClipGT< IntegralConstant<0> >::compare( p ) ) -#define CLIP_Y_LT_W( p ) ( Vector4ClipLT< IntegralConstant<1> >::compare( p ) ) -#define CLIP_Y_GT_W( p ) ( Vector4ClipGT< IntegralConstant<1> >::compare( p ) ) -#define CLIP_Z_LT_W( p ) ( Vector4ClipLT< IntegralConstant<2> >::compare( p ) ) -#define CLIP_Z_GT_W( p ) ( Vector4ClipGT< IntegralConstant<2> >::compare( p ) ) - -inline ClipResult homogenous_clip_point( const Vector4& clipped ){ - ClipResult result = c_CLIP_FAIL; - if ( CLIP_X_LT_W( clipped ) ) { - result &= ~c_CLIP_LT_X; // X < W - } - if ( CLIP_X_GT_W( clipped ) ) { - result &= ~c_CLIP_GT_X; // X > -W - } - if ( CLIP_Y_LT_W( clipped ) ) { - result &= ~c_CLIP_LT_Y; // Y < W - } - if ( CLIP_Y_GT_W( clipped ) ) { - result &= ~c_CLIP_GT_Y; // Y > -W - } - if ( CLIP_Z_LT_W( clipped ) ) { - result &= ~c_CLIP_LT_Z; // Z < W - } - if ( CLIP_Z_GT_W( clipped ) ) { - result &= ~c_CLIP_GT_Z; // Z > -W - } - return result; -} - -/// \brief Clips \p point by canonical matrix \p self. -/// Stores the result in \p clipped. -/// Returns a bitmask indicating which clip-planes the point was outside. -inline ClipResult matrix4_clip_point( const Matrix4& self, const Vector3& point, Vector4& clipped ){ - clipped[0] = point[0]; - clipped[1] = point[1]; - clipped[2] = point[2]; - clipped[3] = 1; - matrix4_transform_vector4( self, clipped ); - return homogenous_clip_point( clipped ); -} - - -inline std::size_t homogenous_clip_triangle( Vector4 clipped[9] ){ - Vector4 buffer[9]; - std::size_t count = 3; - count = Vector4ClipPolygon< Vector4ClipLT< IntegralConstant<0> > >::apply( clipped, clipped + count, buffer ); - count = Vector4ClipPolygon< Vector4ClipGT< IntegralConstant<0> > >::apply( buffer, buffer + count, clipped ); - count = Vector4ClipPolygon< Vector4ClipLT< IntegralConstant<1> > >::apply( clipped, clipped + count, buffer ); - count = Vector4ClipPolygon< Vector4ClipGT< IntegralConstant<1> > >::apply( buffer, buffer + count, clipped ); - count = Vector4ClipPolygon< Vector4ClipLT< IntegralConstant<2> > >::apply( clipped, clipped + count, buffer ); - return Vector4ClipPolygon< Vector4ClipGT< IntegralConstant<2> > >::apply( buffer, buffer + count, clipped ); -} - -/// \brief Transforms and clips the triangle formed by \p p0, \p p1, \p p2 by the canonical matrix \p self. -/// Stores the resulting polygon in \p clipped. -/// Returns the number of points in the resulting polygon. -inline std::size_t matrix4_clip_triangle( const Matrix4& self, const Vector3& p0, const Vector3& p1, const Vector3& p2, Vector4 clipped[9] ){ - clipped[0][0] = p0[0]; - clipped[0][1] = p0[1]; - clipped[0][2] = p0[2]; - clipped[0][3] = 1; - clipped[1][0] = p1[0]; - clipped[1][1] = p1[1]; - clipped[1][2] = p1[2]; - clipped[1][3] = 1; - clipped[2][0] = p2[0]; - clipped[2][1] = p2[1]; - clipped[2][2] = p2[2]; - clipped[2][3] = 1; - - matrix4_transform_vector4( self, clipped[0] ); - matrix4_transform_vector4( self, clipped[1] ); - matrix4_transform_vector4( self, clipped[2] ); - - return homogenous_clip_triangle( clipped ); -} - -inline std::size_t homogenous_clip_line( Vector4 clipped[2] ){ - const Vector4& p0 = clipped[0]; - const Vector4& p1 = clipped[1]; - - // early out - { - ClipResult mask0 = homogenous_clip_point( clipped[0] ); - ClipResult mask1 = homogenous_clip_point( clipped[1] ); - - if ( ( mask0 | mask1 ) == c_CLIP_PASS ) { // both points passed all planes - return 2; - } - - if ( mask0 & mask1 ) { // both points failed any one plane - return 0; - } - } - - { - const bool index = CLIP_X_LT_W( p0 ); - if ( index ^ CLIP_X_LT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[0] - p0[3] ) / ( clip[3] - clip[0] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_X_GT_W( p0 ); - if ( index ^ CLIP_X_GT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[0] + p0[3] ) / ( -clip[3] - clip[0] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_Y_LT_W( p0 ); - if ( index ^ CLIP_Y_LT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[1] - p0[3] ) / ( clip[3] - clip[1] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_Y_GT_W( p0 ); - if ( index ^ CLIP_Y_GT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[1] + p0[3] ) / ( -clip[3] - clip[1] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_Z_LT_W( p0 ); - if ( index ^ CLIP_Z_LT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[2] - p0[3] ) / ( clip[3] - clip[2] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - { - const bool index = CLIP_Z_GT_W( p0 ); - if ( index ^ CLIP_Z_GT_W( p1 ) ) { - Vector4 clip( vector4_subtracted( p1, p0 ) ); - - double scale = ( p0[2] + p0[3] ) / ( -clip[3] - clip[2] ); - - clip[0] = static_cast( p0[0] + scale * clip[0] ); - clip[1] = static_cast( p0[1] + scale * clip[1] ); - clip[2] = static_cast( p0[2] + scale * clip[2] ); - clip[3] = static_cast( p0[3] + scale * clip[3] ); - - clipped[index] = clip; - } - else if ( index == 0 ) { - return 0; - } - } - - return 2; -} - -/// \brief Transforms and clips the line formed by \p p0, \p p1 by the canonical matrix \p self. -/// Stores the resulting line in \p clipped. -/// Returns the number of points in the resulting line. -inline std::size_t matrix4_clip_line( const Matrix4& self, const Vector3& p0, const Vector3& p1, Vector4 clipped[2] ){ - clipped[0][0] = p0[0]; - clipped[0][1] = p0[1]; - clipped[0][2] = p0[2]; - clipped[0][3] = 1; - clipped[1][0] = p1[0]; - clipped[1][1] = p1[1]; - clipped[1][2] = p1[2]; - clipped[1][3] = 1; - - matrix4_transform_vector4( self, clipped[0] ); - matrix4_transform_vector4( self, clipped[1] ); - - return homogenous_clip_line( clipped ); -} - - - - -struct Frustum -{ - Plane3 right, left, bottom, top, back, front; - - Frustum(){ - } - Frustum( const Plane3& _right, - const Plane3& _left, - const Plane3& _bottom, - const Plane3& _top, - const Plane3& _back, - const Plane3& _front ) - : right( _right ), left( _left ), bottom( _bottom ), top( _top ), back( _back ), front( _front ){ - } -}; - -inline Frustum frustum_transformed( const Frustum& frustum, const Matrix4& transform ){ - return Frustum( - plane3_transformed( frustum.right, transform ), - plane3_transformed( frustum.left, transform ), - plane3_transformed( frustum.bottom, transform ), - plane3_transformed( frustum.top, transform ), - plane3_transformed( frustum.back, transform ), - plane3_transformed( frustum.front, transform ) - ); -} - -inline Frustum frustum_inverse_transformed( const Frustum& frustum, const Matrix4& transform ){ - return Frustum( - plane3_inverse_transformed( frustum.right, transform ), - plane3_inverse_transformed( frustum.left, transform ), - plane3_inverse_transformed( frustum.bottom, transform ), - plane3_inverse_transformed( frustum.top, transform ), - plane3_inverse_transformed( frustum.back, transform ), - plane3_inverse_transformed( frustum.front, transform ) - ); -} - -inline bool viewproj_test_point( const Matrix4& viewproj, const Vector3& point ){ - Vector4 hpoint( matrix4_transformed_vector4( viewproj, Vector4( point, 1.0f ) ) ); - if ( fabs( hpoint[0] ) < fabs( hpoint[3] ) - && fabs( hpoint[1] ) < fabs( hpoint[3] ) - && fabs( hpoint[2] ) < fabs( hpoint[3] ) ) { - return true; - } - return false; -} - -inline bool viewproj_test_transformed_point( const Matrix4& viewproj, const Vector3& point, const Matrix4& localToWorld ){ - return viewproj_test_point( viewproj, matrix4_transformed_point( localToWorld, point ) ); -} - -inline Frustum frustum_from_viewproj( const Matrix4& viewproj ){ - return Frustum - ( - plane3_normalised( Plane3( viewproj[ 3] - viewproj[ 0], viewproj[ 7] - viewproj[ 4], viewproj[11] - viewproj[ 8], viewproj[15] - viewproj[12] ) ), - plane3_normalised( Plane3( viewproj[ 3] + viewproj[ 0], viewproj[ 7] + viewproj[ 4], viewproj[11] + viewproj[ 8], viewproj[15] + viewproj[12] ) ), - plane3_normalised( Plane3( viewproj[ 3] + viewproj[ 1], viewproj[ 7] + viewproj[ 5], viewproj[11] + viewproj[ 9], viewproj[15] + viewproj[13] ) ), - plane3_normalised( Plane3( viewproj[ 3] - viewproj[ 1], viewproj[ 7] - viewproj[ 5], viewproj[11] - viewproj[ 9], viewproj[15] - viewproj[13] ) ), - plane3_normalised( Plane3( viewproj[ 3] - viewproj[ 2], viewproj[ 7] - viewproj[ 6], viewproj[11] - viewproj[10], viewproj[15] - viewproj[14] ) ), - plane3_normalised( Plane3( viewproj[ 3] + viewproj[ 2], viewproj[ 7] + viewproj[ 6], viewproj[11] + viewproj[10], viewproj[15] + viewproj[14] ) ) - ); -} - -struct VolumeIntersection -{ - enum Value - { - OUTSIDE, - INSIDE, - PARTIAL - }; -}; - -typedef EnumeratedValue VolumeIntersectionValue; - -const VolumeIntersectionValue c_volumeOutside( VolumeIntersectionValue::OUTSIDE ); -const VolumeIntersectionValue c_volumeInside( VolumeIntersectionValue::INSIDE ); -const VolumeIntersectionValue c_volumePartial( VolumeIntersectionValue::PARTIAL ); - -inline VolumeIntersectionValue frustum_test_aabb( const Frustum& frustum, const AABB& aabb ){ - VolumeIntersectionValue result = c_volumeInside; - - switch ( aabb_classify_plane( aabb, frustum.right ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.left ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.bottom ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.top ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.back ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - switch ( aabb_classify_plane( aabb, frustum.front ) ) - { - case 2: - return c_volumeOutside; - case 1: - result = c_volumePartial; - } - - return result; -} - -inline double plane_distance_to_point( const Plane3& plane, const Vector3& point ){ - return vector3_dot( plane.normal(), point ) + plane.d; -} - -inline double plane_distance_to_oriented_extents( const Plane3& plane, const Vector3& extents, const Matrix4& orientation ){ - return fabs( extents[0] * vector3_dot( plane.normal(), vector4_to_vector3( orientation.x() ) ) ) - + fabs( extents[1] * vector3_dot( plane.normal(), vector4_to_vector3( orientation.y() ) ) ) - + fabs( extents[2] * vector3_dot( plane.normal(), vector4_to_vector3( orientation.z() ) ) ); -} - -/// \brief Return false if \p aabb with \p orientation is partially or completely outside \p plane. -inline bool plane_contains_oriented_aabb( const Plane3& plane, const AABB& aabb, const Matrix4& orientation ){ - double dot = plane_distance_to_point( plane, aabb.origin ); - return !( dot > 0 || -dot < plane_distance_to_oriented_extents( plane, aabb.extents, orientation ) ); -} - -inline VolumeIntersectionValue frustum_intersects_transformed_aabb( const Frustum& frustum, const AABB& aabb, const Matrix4& localToWorld ){ - AABB aabb_world( aabb ); - matrix4_transform_point( localToWorld, aabb_world.origin ); - - if ( plane_contains_oriented_aabb( frustum.right, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.left, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.bottom, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.top, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.back, aabb_world, localToWorld ) - || plane_contains_oriented_aabb( frustum.front, aabb_world, localToWorld ) ) { - return c_volumeOutside; - } - return c_volumeInside; -} - -inline bool plane3_test_point( const Plane3& plane, const Vector3& point ){ - return vector3_dot( point, plane.normal() ) + plane.dist() <= 0; -} - -inline bool plane3_test_line( const Plane3& plane, const Segment& segment ){ - return segment_classify_plane( segment, plane ) == 2; -} - -inline bool frustum_test_point( const Frustum& frustum, const Vector3& point ){ - return !plane3_test_point( frustum.right, point ) - && !plane3_test_point( frustum.left, point ) - && !plane3_test_point( frustum.bottom, point ) - && !plane3_test_point( frustum.top, point ) - && !plane3_test_point( frustum.back, point ) - && !plane3_test_point( frustum.front, point ); -} - -inline bool frustum_test_line( const Frustum& frustum, const Segment& segment ){ - return !plane3_test_line( frustum.right, segment ) - && !plane3_test_line( frustum.left, segment ) - && !plane3_test_line( frustum.bottom, segment ) - && !plane3_test_line( frustum.top, segment ) - && !plane3_test_line( frustum.back, segment ) - && !plane3_test_line( frustum.front, segment ); -} - -inline bool viewer_test_plane( const Vector4& viewer, const Plane3& plane ){ - return ( ( plane.a * viewer[0] ) - + ( plane.b * viewer[1] ) - + ( plane.c * viewer[2] ) - + ( plane.d * viewer[3] ) ) > 0; -} - -inline Vector3 triangle_cross( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){ - return vector3_cross( vector3_subtracted( p1, p0 ), vector3_subtracted( p1, p2 ) ); -} - -inline bool viewer_test_triangle( const Vector4& viewer, const Vector3& p0, const Vector3& p1, const Vector3& p2 ){ - Vector3 cross( triangle_cross( p0, p1, p2 ) ); - return ( ( viewer[0] * cross[0] ) - + ( viewer[1] * cross[1] ) - + ( viewer[2] * cross[2] ) - + ( viewer[3] * 0 ) ) > 0; -} - -inline Vector4 viewer_from_transformed_viewer( const Vector4& viewer, const Matrix4& transform ){ - if ( viewer[3] == 0 ) { - return Vector4( matrix4_transformed_direction( transform, vector4_to_vector3( viewer ) ), 0 ); - } - else - { - return Vector4( matrix4_transformed_point( transform, vector4_to_vector3( viewer ) ), viewer[3] ); - } -} - -inline bool viewer_test_transformed_plane( const Vector4& viewer, const Plane3& plane, const Matrix4& localToWorld ){ -#if 0 - return viewer_test_plane( viewer_from_transformed_viewer( viewer, matrix4_affine_inverse( localToWorld ) ), plane ); -#else - return viewer_test_plane( viewer, plane3_transformed( plane, localToWorld ) ); -#endif -} - -inline Vector4 viewer_from_viewproj( const Matrix4& viewproj ){ - // get viewer pos in object coords - Vector4 viewer( matrix4_transformed_vector4( matrix4_full_inverse( viewproj ), Vector4( 0, 0, -1, 0 ) ) ); - if ( viewer[3] != 0 ) { // non-affine matrix - viewer[0] /= viewer[3]; - viewer[1] /= viewer[3]; - viewer[2] /= viewer[3]; - viewer[3] /= viewer[3]; - } - return viewer; -} - -#endif diff --git a/libs/math/line.h b/libs/math/line.h deleted file mode 100644 index 57d8525..0000000 --- a/libs/math/line.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_LINE_H ) -#define INCLUDED_MATH_LINE_H - -/// \file -/// \brief Line data types and related operations. - -#include "math/vector.h" -#include "math/plane.h" - -/// \brief A line segment defined by a start point and and end point. -class Line -{ -public: -Vector3 start, end; - -Line(){ -} -Line( const Vector3& start_, const Vector3& end_ ) : start( start_ ), end( end_ ){ -} -}; - -inline Vector3 line_closest_point( const Line& line, const Vector3& point ){ - Vector3 v = line.end - line.start; - Vector3 w = point - line.start; - - double c1 = vector3_dot( w,v ); - if ( c1 <= 0 ) { - return line.start; - } - - double c2 = vector3_dot( v,v ); - if ( c2 <= c1 ) { - return line.end; - } - - return Vector3( line.start + v * ( c1 / c2 ) ); -} - - -class Segment -{ -public: -Vector3 origin, extents; - -Segment(){ -} -Segment( const Vector3& origin_, const Vector3& extents_ ) : - origin( origin_ ), extents( extents_ ){ -} -}; - - -inline Segment segment_for_startend( const Vector3& start, const Vector3& end ){ - Segment segment; - segment.origin = vector3_mid( start, end ); - segment.extents = vector3_subtracted( end, segment.origin ); - return segment; -} - -inline unsigned int segment_classify_plane( const Segment& segment, const Plane3& plane ){ - double distance_origin = vector3_dot( plane.normal(), segment.origin ) + plane.dist(); - - if ( fabs( distance_origin ) < fabs( vector3_dot( plane.normal(), segment.extents ) ) ) { - return 1; // partially inside - } - else if ( distance_origin < 0 ) { - return 2; // totally inside - } - return 0; // totally outside -} - - -class Ray -{ -public: -Vector3 origin, direction; - -Ray(){ -} -Ray( const Vector3& origin_, const Vector3& direction_ ) : - origin( origin_ ), direction( direction_ ){ -} -}; - -inline Ray ray_for_points( const Vector3& origin, const Vector3& p2 ){ - return Ray( origin, vector3_normalised( vector3_subtracted( p2, origin ) ) ); -} - -inline void ray_transform( Ray& ray, const Matrix4& matrix ){ - matrix4_transform_point( matrix, ray.origin ); - matrix4_transform_direction( matrix, ray.direction ); -} - -// closest-point-on-line -inline double ray_squared_distance_to_point( const Ray& ray, const Vector3& point ){ - return vector3_length_squared( - vector3_subtracted( - point, - vector3_added( - ray.origin, - vector3_scaled( - ray.direction, - vector3_dot( - vector3_subtracted( point, ray.origin ), - ray.direction - ) - ) - ) - ) - ); -} - -inline double ray_distance_to_plane( const Ray& ray, const Plane3& plane ){ - return -( vector3_dot( plane.normal(), ray.origin ) - plane.dist() ) / vector3_dot( ray.direction, plane.normal() ); -} - -#endif diff --git a/libs/math/matrix.h b/libs/math/matrix.h deleted file mode 100644 index 95ecfac..0000000 --- a/libs/math/matrix.h +++ /dev/null @@ -1,1194 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_MATRIX_H ) -#define INCLUDED_MATH_MATRIX_H - -/// \file -/// \brief Matrix data types and related operations. - -#include "math/vector.h" - -/// \brief A 4x4 matrix stored in single-precision floating-point. -class Matrix4 -{ -float m_elements[16]; -public: - -Matrix4(){ -} -Matrix4( float xx_, float xy_, float xz_, float xw_, - float yx_, float yy_, float yz_, float yw_, - float zx_, float zy_, float zz_, float zw_, - float tx_, float ty_, float tz_, float tw_ ){ - xx() = xx_; - xy() = xy_; - xz() = xz_; - xw() = xw_; - yx() = yx_; - yy() = yy_; - yz() = yz_; - yw() = yw_; - zx() = zx_; - zy() = zy_; - zz() = zz_; - zw() = zw_; - tx() = tx_; - ty() = ty_; - tz() = tz_; - tw() = tw_; -} - -float& xx(){ - return m_elements[0]; -} -const float& xx() const { - return m_elements[0]; -} -float& xy(){ - return m_elements[1]; -} -const float& xy() const { - return m_elements[1]; -} -float& xz(){ - return m_elements[2]; -} -const float& xz() const { - return m_elements[2]; -} -float& xw(){ - return m_elements[3]; -} -const float& xw() const { - return m_elements[3]; -} -float& yx(){ - return m_elements[4]; -} -const float& yx() const { - return m_elements[4]; -} -float& yy(){ - return m_elements[5]; -} -const float& yy() const { - return m_elements[5]; -} -float& yz(){ - return m_elements[6]; -} -const float& yz() const { - return m_elements[6]; -} -float& yw(){ - return m_elements[7]; -} -const float& yw() const { - return m_elements[7]; -} -float& zx(){ - return m_elements[8]; -} -const float& zx() const { - return m_elements[8]; -} -float& zy(){ - return m_elements[9]; -} -const float& zy() const { - return m_elements[9]; -} -float& zz(){ - return m_elements[10]; -} -const float& zz() const { - return m_elements[10]; -} -float& zw(){ - return m_elements[11]; -} -const float& zw() const { - return m_elements[11]; -} -float& tx(){ - return m_elements[12]; -} -const float& tx() const { - return m_elements[12]; -} -float& ty(){ - return m_elements[13]; -} -const float& ty() const { - return m_elements[13]; -} -float& tz(){ - return m_elements[14]; -} -const float& tz() const { - return m_elements[14]; -} -float& tw(){ - return m_elements[15]; -} -const float& tw() const { - return m_elements[15]; -} - -Vector4& x(){ - return reinterpret_cast( xx() ); -} -const Vector4& x() const { - return reinterpret_cast( xx() ); -} -Vector4& y(){ - return reinterpret_cast( yx() ); -} -const Vector4& y() const { - return reinterpret_cast( yx() ); -} -Vector4& z(){ - return reinterpret_cast( zx() ); -} -const Vector4& z() const { - return reinterpret_cast( zx() ); -} -Vector4& t(){ - return reinterpret_cast( tx() ); -} -const Vector4& t() const { - return reinterpret_cast( tx() ); -} - -const float& index( std::size_t i ) const { - return m_elements[i]; -} -float& index( std::size_t i ){ - return m_elements[i]; -} -const float& operator[]( std::size_t i ) const { - return m_elements[i]; -} -float& operator[]( std::size_t i ){ - return m_elements[i]; -} -const float& index( std::size_t r, std::size_t c ) const { - return m_elements[( r << 2 ) + c]; -} -float& index( std::size_t r, std::size_t c ){ - return m_elements[( r << 2 ) + c]; -} -}; - -/// \brief The 4x4 identity matrix. -const Matrix4 g_matrix4_identity( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ); - - -/// \brief Returns true if \p self and \p other are exactly element-wise equal. -inline bool operator==( const Matrix4& self, const Matrix4& other ){ - return self.xx() == other.xx() && self.xy() == other.xy() && self.xz() == other.xz() && self.xw() == other.xw() - && self.yx() == other.yx() && self.yy() == other.yy() && self.yz() == other.yz() && self.yw() == other.yw() - && self.zx() == other.zx() && self.zy() == other.zy() && self.zz() == other.zz() && self.zw() == other.zw() - && self.tx() == other.tx() && self.ty() == other.ty() && self.tz() == other.tz() && self.tw() == other.tw(); -} - -/// \brief Returns true if \p self and \p other are exactly element-wise equal. -inline bool matrix4_equal( const Matrix4& self, const Matrix4& other ){ - return self == other; -} - -/// \brief Returns true if \p self and \p other are element-wise equal within \p epsilon. -inline bool matrix4_equal_epsilon( const Matrix4& self, const Matrix4& other, float epsilon ){ - return float_equal_epsilon( self.xx(), other.xx(), epsilon ) - && float_equal_epsilon( self.xy(), other.xy(), epsilon ) - && float_equal_epsilon( self.xz(), other.xz(), epsilon ) - && float_equal_epsilon( self.xw(), other.xw(), epsilon ) - && float_equal_epsilon( self.yx(), other.yx(), epsilon ) - && float_equal_epsilon( self.yy(), other.yy(), epsilon ) - && float_equal_epsilon( self.yz(), other.yz(), epsilon ) - && float_equal_epsilon( self.yw(), other.yw(), epsilon ) - && float_equal_epsilon( self.zx(), other.zx(), epsilon ) - && float_equal_epsilon( self.zy(), other.zy(), epsilon ) - && float_equal_epsilon( self.zz(), other.zz(), epsilon ) - && float_equal_epsilon( self.zw(), other.zw(), epsilon ) - && float_equal_epsilon( self.tx(), other.tx(), epsilon ) - && float_equal_epsilon( self.ty(), other.ty(), epsilon ) - && float_equal_epsilon( self.tz(), other.tz(), epsilon ) - && float_equal_epsilon( self.tw(), other.tw(), epsilon ); -} - -/// \brief Returns true if \p self and \p other are exactly element-wise equal. -/// \p self and \p other must be affine. -inline bool matrix4_affine_equal( const Matrix4& self, const Matrix4& other ){ - return self[0] == other[0] - && self[1] == other[1] - && self[2] == other[2] - && self[4] == other[4] - && self[5] == other[5] - && self[6] == other[6] - && self[8] == other[8] - && self[9] == other[9] - && self[10] == other[10] - && self[12] == other[12] - && self[13] == other[13] - && self[14] == other[14]; -} - -enum Matrix4Handedness -{ - MATRIX4_RIGHTHANDED = 0, - MATRIX4_LEFTHANDED = 1, -}; - -/// \brief Returns MATRIX4_RIGHTHANDED if \p self is right-handed, else returns MATRIX4_LEFTHANDED. -inline Matrix4Handedness matrix4_handedness( const Matrix4& self ){ - return ( - vector3_dot( - vector3_cross( vector4_to_vector3( self.x() ), vector4_to_vector3( self.y() ) ), - vector4_to_vector3( self.z() ) - ) - < 0.0 - ) ? MATRIX4_LEFTHANDED : MATRIX4_RIGHTHANDED; -} - - - - - -/// \brief Returns \p self post-multiplied by \p other. -inline Matrix4 matrix4_multiplied_by_matrix4( const Matrix4& self, const Matrix4& other ){ - return Matrix4( - other[0] * self[0] + other[1] * self[4] + other[2] * self[8] + other[3] * self[12], - other[0] * self[1] + other[1] * self[5] + other[2] * self[9] + other[3] * self[13], - other[0] * self[2] + other[1] * self[6] + other[2] * self[10] + other[3] * self[14], - other[0] * self[3] + other[1] * self[7] + other[2] * self[11] + other[3] * self[15], - other[4] * self[0] + other[5] * self[4] + other[6] * self[8] + other[7] * self[12], - other[4] * self[1] + other[5] * self[5] + other[6] * self[9] + other[7] * self[13], - other[4] * self[2] + other[5] * self[6] + other[6] * self[10] + other[7] * self[14], - other[4] * self[3] + other[5] * self[7] + other[6] * self[11] + other[7] * self[15], - other[8] * self[0] + other[9] * self[4] + other[10] * self[8] + other[11] * self[12], - other[8] * self[1] + other[9] * self[5] + other[10] * self[9] + other[11] * self[13], - other[8] * self[2] + other[9] * self[6] + other[10] * self[10] + other[11] * self[14], - other[8] * self[3] + other[9] * self[7] + other[10] * self[11] + other[11] * self[15], - other[12] * self[0] + other[13] * self[4] + other[14] * self[8] + other[15] * self[12], - other[12] * self[1] + other[13] * self[5] + other[14] * self[9] + other[15] * self[13], - other[12] * self[2] + other[13] * self[6] + other[14] * self[10] + other[15] * self[14], - other[12] * self[3] + other[13] * self[7] + other[14] * self[11] + other[15] * self[15] - ); -} - -/// \brief Post-multiplies \p self by \p other in-place. -inline void matrix4_multiply_by_matrix4( Matrix4& self, const Matrix4& other ){ - self = matrix4_multiplied_by_matrix4( self, other ); -} - - -/// \brief Returns \p self pre-multiplied by \p other. -inline Matrix4 matrix4_premultiplied_by_matrix4( const Matrix4& self, const Matrix4& other ){ -#if 1 - return matrix4_multiplied_by_matrix4( other, self ); -#else - return Matrix4( - self[0] * other[0] + self[1] * other[4] + self[2] * other[8] + self[3] * other[12], - self[0] * other[1] + self[1] * other[5] + self[2] * other[9] + self[3] * other[13], - self[0] * other[2] + self[1] * other[6] + self[2] * other[10] + self[3] * other[14], - self[0] * other[3] + self[1] * other[7] + self[2] * other[11] + self[3] * other[15], - self[4] * other[0] + self[5] * other[4] + self[6] * other[8] + self[7] * other[12], - self[4] * other[1] + self[5] * other[5] + self[6] * other[9] + self[7] * other[13], - self[4] * other[2] + self[5] * other[6] + self[6] * other[10] + self[7] * other[14], - self[4] * other[3] + self[5] * other[7] + self[6] * other[11] + self[7] * other[15], - self[8] * other[0] + self[9] * other[4] + self[10] * other[8] + self[11] * other[12], - self[8] * other[1] + self[9] * other[5] + self[10] * other[9] + self[11] * other[13], - self[8] * other[2] + self[9] * other[6] + self[10] * other[10] + self[11] * other[14], - self[8] * other[3] + self[9] * other[7] + self[10] * other[11] + self[11] * other[15], - self[12] * other[0] + self[13] * other[4] + self[14] * other[8] + self[15] * other[12], - self[12] * other[1] + self[13] * other[5] + self[14] * other[9] + self[15] * other[13], - self[12] * other[2] + self[13] * other[6] + self[14] * other[10] + self[15] * other[14], - self[12] * other[3] + self[13] * other[7] + self[14] * other[11] + self[15] * other[15] - ); -#endif -} - -/// \brief Pre-multiplies \p self by \p other in-place. -inline void matrix4_premultiply_by_matrix4( Matrix4& self, const Matrix4& other ){ - self = matrix4_premultiplied_by_matrix4( self, other ); -} - -/// \brief returns true if \p transform is affine. -inline bool matrix4_is_affine( const Matrix4& transform ){ - return transform[3] == 0 && transform[7] == 0 && transform[11] == 0 && transform[15] == 1; -} - -/// \brief Returns \p self post-multiplied by \p other. -/// \p self and \p other must be affine. -inline Matrix4 matrix4_affine_multiplied_by_matrix4( const Matrix4& self, const Matrix4& other ){ - return Matrix4( - other[0] * self[0] + other[1] * self[4] + other[2] * self[8], - other[0] * self[1] + other[1] * self[5] + other[2] * self[9], - other[0] * self[2] + other[1] * self[6] + other[2] * self[10], - 0, - other[4] * self[0] + other[5] * self[4] + other[6] * self[8], - other[4] * self[1] + other[5] * self[5] + other[6] * self[9], - other[4] * self[2] + other[5] * self[6] + other[6] * self[10], - 0, - other[8] * self[0] + other[9] * self[4] + other[10] * self[8], - other[8] * self[1] + other[9] * self[5] + other[10] * self[9], - other[8] * self[2] + other[9] * self[6] + other[10] * self[10], - 0, - other[12] * self[0] + other[13] * self[4] + other[14] * self[8] + self[12], - other[12] * self[1] + other[13] * self[5] + other[14] * self[9] + self[13], - other[12] * self[2] + other[13] * self[6] + other[14] * self[10] + self[14], - 1 - ); -} - -/// \brief Post-multiplies \p self by \p other in-place. -/// \p self and \p other must be affine. -inline void matrix4_affine_multiply_by_matrix4( Matrix4& self, const Matrix4& other ){ - self = matrix4_affine_multiplied_by_matrix4( self, other ); -} - -/// \brief Returns \p self pre-multiplied by \p other. -/// \p self and \p other must be affine. -inline Matrix4 matrix4_affine_premultiplied_by_matrix4( const Matrix4& self, const Matrix4& other ){ -#if 1 - return matrix4_affine_multiplied_by_matrix4( other, self ); -#else - return Matrix4( - self[0] * other[0] + self[1] * other[4] + self[2] * other[8], - self[0] * other[1] + self[1] * other[5] + self[2] * other[9], - self[0] * other[2] + self[1] * other[6] + self[2] * other[10], - 0, - self[4] * other[0] + self[5] * other[4] + self[6] * other[8], - self[4] * other[1] + self[5] * other[5] + self[6] * other[9], - self[4] * other[2] + self[5] * other[6] + self[6] * other[10], - 0, - self[8] * other[0] + self[9] * other[4] + self[10] * other[8], - self[8] * other[1] + self[9] * other[5] + self[10] * other[9], - self[8] * other[2] + self[9] * other[6] + self[10] * other[10], - 0, - self[12] * other[0] + self[13] * other[4] + self[14] * other[8] + other[12], - self[12] * other[1] + self[13] * other[5] + self[14] * other[9] + other[13], - self[12] * other[2] + self[13] * other[6] + self[14] * other[10] + other[14], - 1 - ) - ); -#endif -} - -/// \brief Pre-multiplies \p self by \p other in-place. -/// \p self and \p other must be affine. -inline void matrix4_affine_premultiply_by_matrix4( Matrix4& self, const Matrix4& other ){ - self = matrix4_affine_premultiplied_by_matrix4( self, other ); -} - -/// \brief Returns \p point transformed by \p self. -template -inline BasicVector3 matrix4_transformed_point( const Matrix4& self, const BasicVector3& point ){ - return BasicVector3( - static_cast( self[0] * point[0] + self[4] * point[1] + self[8] * point[2] + self[12] ), - static_cast( self[1] * point[0] + self[5] * point[1] + self[9] * point[2] + self[13] ), - static_cast( self[2] * point[0] + self[6] * point[1] + self[10] * point[2] + self[14] ) - ); -} - -/// \brief Transforms \p point by \p self in-place. -template -inline void matrix4_transform_point( const Matrix4& self, BasicVector3& point ){ - point = matrix4_transformed_point( self, point ); -} - -/// \brief Returns \p direction transformed by \p self. -template -inline BasicVector3 matrix4_transformed_direction( const Matrix4& self, const BasicVector3& direction ){ - return BasicVector3( - static_cast( self[0] * direction[0] + self[4] * direction[1] + self[8] * direction[2] ), - static_cast( self[1] * direction[0] + self[5] * direction[1] + self[9] * direction[2] ), - static_cast( self[2] * direction[0] + self[6] * direction[1] + self[10] * direction[2] ) - ); -} - -/// \brief Transforms \p direction by \p self in-place. -template -inline void matrix4_transform_direction( const Matrix4& self, BasicVector3& normal ){ - normal = matrix4_transformed_direction( self, normal ); -} - -/// \brief Returns \p vector4 transformed by \p self. -inline Vector4 matrix4_transformed_vector4( const Matrix4& self, const Vector4& vector4 ){ - return Vector4( - self[0] * vector4[0] + self[4] * vector4[1] + self[8] * vector4[2] + self[12] * vector4[3], - self[1] * vector4[0] + self[5] * vector4[1] + self[9] * vector4[2] + self[13] * vector4[3], - self[2] * vector4[0] + self[6] * vector4[1] + self[10] * vector4[2] + self[14] * vector4[3], - self[3] * vector4[0] + self[7] * vector4[1] + self[11] * vector4[2] + self[15] * vector4[3] - ); -} - -/// \brief Transforms \p vector4 by \p self in-place. -inline void matrix4_transform_vector4( const Matrix4& self, Vector4& vector4 ){ - vector4 = matrix4_transformed_vector4( self, vector4 ); -} - - -/// \brief Transposes \p self in-place. -inline void matrix4_transpose( Matrix4& self ){ - std::swap( self.xy(), self.yx() ); - std::swap( self.xz(), self.zx() ); - std::swap( self.xw(), self.tx() ); - std::swap( self.yz(), self.zy() ); - std::swap( self.yw(), self.ty() ); - std::swap( self.zw(), self.tz() ); -} - -/// \brief Returns \p self transposed. -inline Matrix4 matrix4_transposed( const Matrix4& self ){ - return Matrix4( - self.xx(), - self.yx(), - self.zx(), - self.tx(), - self.xy(), - self.yy(), - self.zy(), - self.ty(), - self.xz(), - self.yz(), - self.zz(), - self.tz(), - self.xw(), - self.yw(), - self.zw(), - self.tw() - ); -} - - -/// \brief Inverts an affine transform in-place. -/// Adapted from Graphics Gems 2. -inline Matrix4 matrix4_affine_inverse( const Matrix4& self ){ - Matrix4 result; - - // determinant of rotation submatrix - double det - = self[0] * ( self[5] * self[10] - self[9] * self[6] ) - - self[1] * ( self[4] * self[10] - self[8] * self[6] ) - + self[2] * ( self[4] * self[9] - self[8] * self[5] ); - - // throw exception here if (det*det < 1e-25) - - // invert rotation submatrix - det = 1.0 / det; - - result[0] = static_cast( ( self[5] * self[10] - self[6] * self[9] ) * det ); - result[1] = static_cast( -( self[1] * self[10] - self[2] * self[9] ) * det ); - result[2] = static_cast( ( self[1] * self[6] - self[2] * self[5] ) * det ); - result[3] = 0; - result[4] = static_cast( -( self[4] * self[10] - self[6] * self[8] ) * det ); - result[5] = static_cast( ( self[0] * self[10] - self[2] * self[8] ) * det ); - result[6] = static_cast( -( self[0] * self[6] - self[2] * self[4] ) * det ); - result[7] = 0; - result[8] = static_cast( ( self[4] * self[9] - self[5] * self[8] ) * det ); - result[9] = static_cast( -( self[0] * self[9] - self[1] * self[8] ) * det ); - result[10] = static_cast( ( self[0] * self[5] - self[1] * self[4] ) * det ); - result[11] = 0; - - // multiply translation part by rotation - result[12] = -( self[12] * result[0] + - self[13] * result[4] + - self[14] * result[8] ); - result[13] = -( self[12] * result[1] + - self[13] * result[5] + - self[14] * result[9] ); - result[14] = -( self[12] * result[2] + - self[13] * result[6] + - self[14] * result[10] ); - result[15] = 1; - - return result; -} - -inline void matrix4_affine_invert( Matrix4& self ){ - self = matrix4_affine_inverse( self ); -} - -/// \brief A compile-time-constant integer. -template -struct IntegralConstant -{ - enum unnamed_ { VALUE = VALUE_ }; -}; - -/// \brief A compile-time-constant row/column index into a 4x4 matrix. -template -class Matrix4Index -{ -public: -typedef IntegralConstant r; -typedef IntegralConstant c; -typedef IntegralConstant<( r::VALUE * 4 ) + c::VALUE> i; -}; - -/// \brief A functor which returns the cofactor of a 3x3 submatrix obtained by ignoring a given row and column of a 4x4 matrix. -/// \param Row Defines the compile-time-constant integers x, y and z with values corresponding to the indices of the three rows to use. -/// \param Col Defines the compile-time-constant integers x, y and z with values corresponding to the indices of the three columns to use. -template -class Matrix4Cofactor -{ -public: -typedef typename Matrix4Index::i xx; -typedef typename Matrix4Index::i xy; -typedef typename Matrix4Index::i xz; -typedef typename Matrix4Index::i yx; -typedef typename Matrix4Index::i yy; -typedef typename Matrix4Index::i yz; -typedef typename Matrix4Index::i zx; -typedef typename Matrix4Index::i zy; -typedef typename Matrix4Index::i zz; -static double apply( const Matrix4& self ){ - return self[xx::VALUE] * ( self[yy::VALUE] * self[zz::VALUE] - self[zy::VALUE] * self[yz::VALUE] ) - - self[xy::VALUE] * ( self[yx::VALUE] * self[zz::VALUE] - self[zx::VALUE] * self[yz::VALUE] ) - + self[xz::VALUE] * ( self[yx::VALUE] * self[zy::VALUE] - self[zx::VALUE] * self[yy::VALUE] ); -} -}; - -/// \brief The cofactor element indices for a 4x4 matrix row or column. -/// \param Element The index of the element to ignore. -template -class Cofactor4 -{ -public: -typedef IntegralConstant<( Element <= 0 ) ? 1 : 0> x; -typedef IntegralConstant<( Element <= 1 ) ? 2 : 1> y; -typedef IntegralConstant<( Element <= 2 ) ? 3 : 2> z; -}; - -/// \brief Returns the determinant of \p self. -inline double matrix4_determinant( const Matrix4& self ){ - return self.xx() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<0> >::apply( self ) - - self.xy() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<1> >::apply( self ) - + self.xz() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<2> >::apply( self ) - - self.xw() * Matrix4Cofactor< Cofactor4<0>, Cofactor4<3> >::apply( self ); -} - -/// \brief Returns the inverse of \p self using the Adjoint method. -/// \todo Throw an exception if the determinant is zero. -inline Matrix4 matrix4_full_inverse( const Matrix4& self ){ - double determinant = 1.0 / matrix4_determinant( self ); - - return Matrix4( - static_cast( Matrix4Cofactor< Cofactor4<0>, Cofactor4<0> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<1>, Cofactor4<0> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<2>, Cofactor4<0> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<3>, Cofactor4<0> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<0>, Cofactor4<1> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<1>, Cofactor4<1> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<2>, Cofactor4<1> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<3>, Cofactor4<1> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<0>, Cofactor4<2> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<1>, Cofactor4<2> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<2>, Cofactor4<2> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<3>, Cofactor4<2> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<0>, Cofactor4<3> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<1>, Cofactor4<3> >::apply( self ) * determinant ), - static_cast( -Matrix4Cofactor< Cofactor4<2>, Cofactor4<3> >::apply( self ) * determinant ), - static_cast( Matrix4Cofactor< Cofactor4<3>, Cofactor4<3> >::apply( self ) * determinant ) - ); -} - -/// \brief Inverts \p self in-place using the Adjoint method. -inline void matrix4_full_invert( Matrix4& self ){ - self = matrix4_full_inverse( self ); -} - - -/// \brief Constructs a pure-translation matrix from \p translation. -inline Matrix4 matrix4_translation_for_vec3( const Vector3& translation ){ - return Matrix4( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - translation[0], translation[1], translation[2], 1 - ); -} - -/// \brief Returns the translation part of \p self. -inline Vector3 matrix4_get_translation_vec3( const Matrix4& self ){ - return vector4_to_vector3( self.t() ); -} - -/// \brief Concatenates \p self with \p translation. -/// The concatenated \p translation occurs before \p self. -inline void matrix4_translate_by_vec3( Matrix4& self, const Vector3& translation ){ - matrix4_multiply_by_matrix4( self, matrix4_translation_for_vec3( translation ) ); -} - -/// \brief Returns \p self Concatenated with \p translation. -/// The concatenated translation occurs before \p self. -inline Matrix4 matrix4_translated_by_vec3( const Matrix4& self, const Vector3& translation ){ - return matrix4_multiplied_by_matrix4( self, matrix4_translation_for_vec3( translation ) ); -} - - -#include "math/pi.h" - -/// \brief Returns \p angle modulated by the range [0, 360). -/// \p angle must be in the range [-360, 360). -inline float angle_modulate_degrees_range( float angle ){ - return static_cast( float_mod_range( angle, 360.0 ) ); -} - -/// \brief Returns \p euler angles converted from radians to degrees. -inline Vector3 euler_radians_to_degrees( const Vector3& euler ){ - return Vector3( - static_cast( radians_to_degrees( euler.x() ) ), - static_cast( radians_to_degrees( euler.y() ) ), - static_cast( radians_to_degrees( euler.z() ) ) - ); -} - -/// \brief Returns \p euler angles converted from degrees to radians. -inline Vector3 euler_degrees_to_radians( const Vector3& euler ){ - return Vector3( - static_cast( degrees_to_radians( euler.x() ) ), - static_cast( degrees_to_radians( euler.y() ) ), - static_cast( degrees_to_radians( euler.z() ) ) - ); -} - - - -/// \brief Constructs a pure-rotation matrix about the x axis from sin \p s and cosine \p c of an angle. -inline Matrix4 matrix4_rotation_for_sincos_x( float s, float c ){ - return Matrix4( - 1, 0, 0, 0, - 0, c, s, 0, - 0,-s, c, 0, - 0, 0, 0, 1 - ); -} - -/// \brief Constructs a pure-rotation matrix about the x axis from an angle in radians. -inline Matrix4 matrix4_rotation_for_x( double x ){ - return matrix4_rotation_for_sincos_x( static_cast( sin( x ) ), static_cast( cos( x ) ) ); -} - -/// \brief Constructs a pure-rotation matrix about the x axis from an angle in degrees. -inline Matrix4 matrix4_rotation_for_x_degrees( float x ){ - return matrix4_rotation_for_x( degrees_to_radians( x ) ); -} - -/// \brief Constructs a pure-rotation matrix about the y axis from sin \p s and cosine \p c of an angle. -inline Matrix4 matrix4_rotation_for_sincos_y( float s, float c ){ - return Matrix4( - c, 0,-s, 0, - 0, 1, 0, 0, - s, 0, c, 0, - 0, 0, 0, 1 - ); -} - -/// \brief Constructs a pure-rotation matrix about the y axis from an angle in radians. -inline Matrix4 matrix4_rotation_for_y( double y ){ - return matrix4_rotation_for_sincos_y( static_cast( sin( y ) ), static_cast( cos( y ) ) ); -} - -/// \brief Constructs a pure-rotation matrix about the y axis from an angle in degrees. -inline Matrix4 matrix4_rotation_for_y_degrees( float y ){ - return matrix4_rotation_for_y( degrees_to_radians( y ) ); -} - -/// \brief Constructs a pure-rotation matrix about the z axis from sin \p s and cosine \p c of an angle. -inline Matrix4 matrix4_rotation_for_sincos_z( float s, float c ){ - return Matrix4( - c, s, 0, 0, - -s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ); -} - -/// \brief Constructs a pure-rotation matrix about the z axis from an angle in radians. -inline Matrix4 matrix4_rotation_for_z( double z ){ - return matrix4_rotation_for_sincos_z( static_cast( sin( z ) ), static_cast( cos( z ) ) ); -} - -/// \brief Constructs a pure-rotation matrix about the z axis from an angle in degrees. -inline Matrix4 matrix4_rotation_for_z_degrees( float z ){ - return matrix4_rotation_for_z( degrees_to_radians( z ) ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (x, y, z). -/*! \verbatim - clockwise rotation around X, Y, Z, facing along axis - 1 0 0 cy 0 -sy cz sz 0 - 0 cx sx 0 1 0 -sz cz 0 - 0 -sx cx sy 0 cy 0 0 1 - - rows of Z by cols of Y - cy*cz -sy*cz+sz -sy*sz+cz - -sz*cy -sz*sy+cz - - .. or something like that.. - - final rotation is Z * Y * X - cy*cz -sx*-sy*cz+cx*sz cx*-sy*sz+sx*cz - -cy*sz sx*sy*sz+cx*cz -cx*-sy*sz+sx*cz - sy -sx*cy cx*cy - - transposed - cy.cz + 0.sz + sy.0 cy.-sz + 0 .cz + sy.0 cy.0 + 0 .0 + sy.1 | - sx.sy.cz + cx.sz + -sx.cy.0 sx.sy.-sz + cx.cz + -sx.cy.0 sx.sy.0 + cx.0 + -sx.cy.1 | - -cx.sy.cz + sx.sz + cx.cy.0 -cx.sy.-sz + sx.cz + cx.cy.0 -cx.sy.0 + 0 .0 + cx.cy.1 | - \endverbatim */ -inline Matrix4 matrix4_rotation_for_euler_xyz( const Vector3& euler ){ -#if 1 - - double cx = cos( euler[0] ); - double sx = sin( euler[0] ); - double cy = cos( euler[1] ); - double sy = sin( euler[1] ); - double cz = cos( euler[2] ); - double sz = sin( euler[2] ); - - return Matrix4( - static_cast( cy * cz ), - static_cast( cy * sz ), - static_cast( -sy ), - 0, - static_cast( sx * sy * cz + cx * -sz ), - static_cast( sx * sy * sz + cx * cz ), - static_cast( sx * cy ), - 0, - static_cast( cx * sy * cz + sx * sz ), - static_cast( cx * sy * sz + -sx * cz ), - static_cast( cx * cy ), - 0, - 0, - 0, - 0, - 1 - ); - -#else - - return matrix4_premultiply_by_matrix4( - matrix4_premultiply_by_matrix4( - matrix4_rotation_for_x( euler[0] ), - matrix4_rotation_for_y( euler[1] ) - ), - matrix4_rotation_for_z( euler[2] ) - ); - -#endif -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (x, y, z). -inline Matrix4 matrix4_rotation_for_euler_xyz_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_xyz( euler_degrees_to_radians( euler ) ); -} - -/// \brief Concatenates \p self with the rotation transform produced by \p euler angles (degrees) in the order (x, y, z). -/// The concatenated rotation occurs before \p self. -inline void matrix4_rotate_by_euler_xyz_degrees( Matrix4& self, const Vector3& euler ){ - matrix4_multiply_by_matrix4( self, matrix4_rotation_for_euler_xyz_degrees( euler ) ); -} - - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (y, z, x). -inline Matrix4 matrix4_rotation_for_euler_yzx( const Vector3& euler ){ - return matrix4_premultiplied_by_matrix4( - matrix4_premultiplied_by_matrix4( - matrix4_rotation_for_y( euler[1] ), - matrix4_rotation_for_z( euler[2] ) - ), - matrix4_rotation_for_x( euler[0] ) - ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (y, z, x). -inline Matrix4 matrix4_rotation_for_euler_yzx_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_yzx( euler_degrees_to_radians( euler ) ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (x, z, y). -inline Matrix4 matrix4_rotation_for_euler_xzy( const Vector3& euler ){ - return matrix4_premultiplied_by_matrix4( - matrix4_premultiplied_by_matrix4( - matrix4_rotation_for_x( euler[0] ), - matrix4_rotation_for_z( euler[2] ) - ), - matrix4_rotation_for_y( euler[1] ) - ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (x, z, y). -inline Matrix4 matrix4_rotation_for_euler_xzy_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_xzy( euler_degrees_to_radians( euler ) ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (y, x, z). -/*! \verbatim - | cy.cz + sx.sy.-sz + -cx.sy.0 0.cz + cx.-sz + sx.0 sy.cz + -sx.cy.-sz + cx.cy.0 | - | cy.sz + sx.sy.cz + -cx.sy.0 0.sz + cx.cz + sx.0 sy.sz + -sx.cy.cz + cx.cy.0 | - | cy.0 + sx.sy.0 + -cx.sy.1 0.0 + cx.0 + sx.1 sy.0 + -sx.cy.0 + cx.cy.1 | - \endverbatim */ -inline Matrix4 matrix4_rotation_for_euler_yxz( const Vector3& euler ){ -#if 1 - - double cx = cos( euler[0] ); - double sx = sin( euler[0] ); - double cy = cos( euler[1] ); - double sy = sin( euler[1] ); - double cz = cos( euler[2] ); - double sz = sin( euler[2] ); - - return Matrix4( - static_cast( cy * cz + sx * sy * -sz ), - static_cast( cy * sz + sx * sy * cz ), - static_cast( -cx * sy ), - 0, - static_cast( cx * -sz ), - static_cast( cx * cz ), - static_cast( sx ), - 0, - static_cast( sy * cz + -sx * cy * -sz ), - static_cast( sy * sz + -sx * cy * cz ), - static_cast( cx * cy ), - 0, - 0, - 0, - 0, - 1 - ); - -#else - - return matrix4_premultiply_by_matrix4( - matrix4_premultiply_by_matrix4( - matrix4_rotation_for_y( euler[1] ), - matrix4_rotation_for_x( euler[0] ) - ), - matrix4_rotation_for_z( euler[2] ) - ); - -#endif -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (y, x, z). -inline Matrix4 matrix4_rotation_for_euler_yxz_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_yxz( euler_degrees_to_radians( euler ) ); -} - -/// \brief Returns \p self concatenated with the rotation transform produced by \p euler angles (degrees) in the order (y, x, z). -/// The concatenated rotation occurs before \p self. -inline Matrix4 matrix4_rotated_by_euler_yxz_degrees( const Matrix4& self, const Vector3& euler ){ - return matrix4_multiplied_by_matrix4( self, matrix4_rotation_for_euler_yxz_degrees( euler ) ); -} - -/// \brief Concatenates \p self with the rotation transform produced by \p euler angles (degrees) in the order (y, x, z). -/// The concatenated rotation occurs before \p self. -inline void matrix4_rotate_by_euler_yxz_degrees( Matrix4& self, const Vector3& euler ){ - self = matrix4_rotated_by_euler_yxz_degrees( self, euler ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (z, x, y). -inline Matrix4 matrix4_rotation_for_euler_zxy( const Vector3& euler ){ -#if 1 - return matrix4_premultiplied_by_matrix4( - matrix4_premultiplied_by_matrix4( - matrix4_rotation_for_z( euler[2] ), - matrix4_rotation_for_x( euler[0] ) - ), - matrix4_rotation_for_y( euler[1] ) - ); -#else - double cx = cos( euler[0] ); - double sx = sin( euler[0] ); - double cy = cos( euler[1] ); - double sy = sin( euler[1] ); - double cz = cos( euler[2] ); - double sz = sin( euler[2] ); - - return Matrix4( - static_cast( cz * cy + sz * sx * sy ), - static_cast( sz * cx ), - static_cast( cz * -sy + sz * sx * cy ), - 0, - static_cast( -sz * cy + cz * sx * sy ), - static_cast( cz * cx ), - static_cast( -sz * -sy + cz * cx * cy ), - 0, - static_cast( cx * sy ), - static_cast( -sx ), - static_cast( cx * cy ), - 0, - 0, - 0, - 0, - 1 - ); -#endif -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degres=es) in the order (z, x, y). -inline Matrix4 matrix4_rotation_for_euler_zxy_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_zxy( euler_degrees_to_radians( euler ) ); -} - -/// \brief Returns \p self concatenated with the rotation transform produced by \p euler angles (degrees) in the order (z, x, y). -/// The concatenated rotation occurs before \p self. -inline Matrix4 matrix4_rotated_by_euler_zxy_degrees( const Matrix4& self, const Vector3& euler ){ - return matrix4_multiplied_by_matrix4( self, matrix4_rotation_for_euler_zxy_degrees( euler ) ); -} - -/// \brief Concatenates \p self with the rotation transform produced by \p euler angles (degrees) in the order (z, x, y). -/// The concatenated rotation occurs before \p self. -inline void matrix4_rotate_by_euler_zxy_degrees( Matrix4& self, const Vector3& euler ){ - self = matrix4_rotated_by_euler_zxy_degrees( self, euler ); -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (radians) in the order (z, y, x). -inline Matrix4 matrix4_rotation_for_euler_zyx( const Vector3& euler ){ -#if 1 - - double cx = cos( euler[0] ); - double sx = sin( euler[0] ); - double cy = cos( euler[1] ); - double sy = sin( euler[1] ); - double cz = cos( euler[2] ); - double sz = sin( euler[2] ); - - return Matrix4( - static_cast( cy * cz ), - static_cast( sx * sy * cz + cx * sz ), - static_cast( cx * -sy * cz + sx * sz ), - 0, - static_cast( cy * -sz ), - static_cast( sx * sy * -sz + cx * cz ), - static_cast( cx * -sy * -sz + sx * cz ), - 0, - static_cast( sy ), - static_cast( -sx * cy ), - static_cast( cx * cy ), - 0, - 0, - 0, - 0, - 1 - ); - -#else - - return matrix4_premultiply_by_matrix4( - matrix4_premultiply_by_matrix4( - matrix4_rotation_for_z( euler[2] ), - matrix4_rotation_for_y( euler[1] ) - ), - matrix4_rotation_for_x( euler[0] ) - ); - -#endif -} - -/// \brief Constructs a pure-rotation matrix from a set of euler angles (degrees) in the order (z, y, x). -inline Matrix4 matrix4_rotation_for_euler_zyx_degrees( const Vector3& euler ){ - return matrix4_rotation_for_euler_zyx( euler_degrees_to_radians( euler ) ); -} - - -/// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (x, y, z). -/// \p self must be affine and orthonormal (unscaled) to produce a meaningful result. -inline Vector3 matrix4_get_rotation_euler_xyz( const Matrix4& self ){ - double a = asin( -self[2] ); - double ca = cos( a ); - - if ( fabs( ca ) > 0.005 ) { // Gimbal lock? - return Vector3( - static_cast( atan2( self[6] / ca, self[10] / ca ) ), - static_cast( a ), - static_cast( atan2( self[1] / ca, self[0] / ca ) ) - ); - } - else // Gimbal lock has occurred - { - return Vector3( - static_cast( atan2( -self[9], self[5] ) ), - static_cast( a ), - 0 - ); - } -} - -/// \brief \copydoc matrix4_get_rotation_euler_xyz(const Matrix4&) -inline Vector3 matrix4_get_rotation_euler_xyz_degrees( const Matrix4& self ){ - return euler_radians_to_degrees( matrix4_get_rotation_euler_xyz( self ) ); -} - -/// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (y, x, z). -/// \p self must be affine and orthonormal (unscaled) to produce a meaningful result. -inline Vector3 matrix4_get_rotation_euler_yxz( const Matrix4& self ){ - double a = asin( self[6] ); - double ca = cos( a ); - - if ( fabs( ca ) > 0.005 ) { // Gimbal lock? - return Vector3( - static_cast( a ), - static_cast( atan2( -self[2] / ca, self[10] / ca ) ), - static_cast( atan2( -self[4] / ca, self[5] / ca ) ) - ); - } - else // Gimbal lock has occurred - { - return Vector3( - static_cast( a ), - static_cast( atan2( self[8], self[0] ) ), - 0 - ); - } -} - -/// \brief \copydoc matrix4_get_rotation_euler_yxz(const Matrix4&) -inline Vector3 matrix4_get_rotation_euler_yxz_degrees( const Matrix4& self ){ - return euler_radians_to_degrees( matrix4_get_rotation_euler_yxz( self ) ); -} - -/// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (z, x, y). -/// \p self must be affine and orthonormal (unscaled) to produce a meaningful result. -inline Vector3 matrix4_get_rotation_euler_zxy( const Matrix4& self ){ - double a = asin( -self[9] ); - double ca = cos( a ); - - if ( fabs( ca ) > 0.005 ) { // Gimbal lock? - return Vector3( - static_cast( a ), - static_cast( atan2( self[8] / ca, self[10] / ca ) ), - static_cast( atan2( self[1] / ca, self[5] / ca ) ) - ); - } - else // Gimbal lock has occurred - { - return Vector3( - static_cast( a ), - 0, - static_cast( atan2( -self[4], self[0] ) ) - ); - } -} - -/// \brief \copydoc matrix4_get_rotation_euler_zxy(const Matrix4&) -inline Vector3 matrix4_get_rotation_euler_zxy_degrees( const Matrix4& self ){ - return euler_radians_to_degrees( matrix4_get_rotation_euler_zxy( self ) ); -} - -/// \brief Calculates and returns a set of euler angles that produce the rotation component of \p self when applied in the order (z, y, x). -/// \p self must be affine and orthonormal (unscaled) to produce a meaningful result. -inline Vector3 matrix4_get_rotation_euler_zyx( const Matrix4& self ){ - double a = asin( self[8] ); - double ca = cos( a ); - - if ( fabs( ca ) > 0.005 ) { // Gimbal lock? - return Vector3( - static_cast( atan2( -self[9] / ca, self[10] / ca ) ), - static_cast( a ), - static_cast( atan2( -self[4] / ca, self[0] / ca ) ) - ); - } - else // Gimbal lock has occurred - { - return Vector3( - 0, - static_cast( a ), - static_cast( atan2( self[1], self[5] ) ) - ); - } -} - -/// \brief \copydoc matrix4_get_rotation_euler_zyx(const Matrix4&) -inline Vector3 matrix4_get_rotation_euler_zyx_degrees( const Matrix4& self ){ - return euler_radians_to_degrees( matrix4_get_rotation_euler_zyx( self ) ); -} - - -/// \brief Rotate \p self by \p euler angles (degrees) applied in the order (x, y, z), using \p pivotpoint. -inline void matrix4_pivoted_rotate_by_euler_xyz_degrees( Matrix4& self, const Vector3& euler, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint ); - matrix4_rotate_by_euler_xyz_degrees( self, euler ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - - -/// \brief Constructs a pure-scale matrix from \p scale. -inline Matrix4 matrix4_scale_for_vec3( const Vector3& scale ){ - return Matrix4( - scale[0], 0, 0, 0, - 0, scale[1], 0, 0, - 0, 0, scale[2], 0, - 0, 0, 0, 1 - ); -} - -/// \brief Calculates and returns the (x, y, z) scale values that produce the scale component of \p self. -/// \p self must be affine and orthogonal to produce a meaningful result. -inline Vector3 matrix4_get_scale_vec3( const Matrix4& self ){ - return Vector3( - static_cast( vector3_length( vector4_to_vector3( self.x() ) ) ), - static_cast( vector3_length( vector4_to_vector3( self.y() ) ) ), - static_cast( vector3_length( vector4_to_vector3( self.z() ) ) ) - ); -} - -/// \brief Scales \p self by \p scale. -inline void matrix4_scale_by_vec3( Matrix4& self, const Vector3& scale ){ - matrix4_multiply_by_matrix4( self, matrix4_scale_for_vec3( scale ) ); -} - -/// \brief Scales \p self by \p scale, using \p pivotpoint. -inline void matrix4_pivoted_scale_by_vec3( Matrix4& self, const Vector3& scale, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint ); - matrix4_scale_by_vec3( self, scale ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - - -/// \brief Transforms \p self by \p translation, \p euler and \p scale. -/// The transforms are combined in the order: scale, rotate-z, rotate-y, rotate-x, translate. -inline void matrix4_transform_by_euler_xyz_degrees( Matrix4& self, const Vector3& translation, const Vector3& euler, const Vector3& scale ){ - matrix4_translate_by_vec3( self, translation ); - matrix4_rotate_by_euler_xyz_degrees( self, euler ); - matrix4_scale_by_vec3( self, scale ); -} - -/// \brief Transforms \p self by \p translation, \p euler and \p scale, using \p pivotpoint. -inline void matrix4_pivoted_transform_by_euler_xyz_degrees( Matrix4& self, const Vector3& translation, const Vector3& euler, const Vector3& scale, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint + translation ); - matrix4_rotate_by_euler_xyz_degrees( self, euler ); - matrix4_scale_by_vec3( self, scale ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - - -#endif diff --git a/libs/math/matrix.h.uncrustify b/libs/math/matrix.h.uncrustify deleted file mode 100644 index e69de29..0000000 diff --git a/libs/math/pi.h b/libs/math/pi.h deleted file mode 100644 index a9f368c..0000000 --- a/libs/math/pi.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_PI_H ) -#define INCLUDED_MATH_PI_H - -/// \file -/// \brief Pi constants and degrees/radians conversion. - -const double c_pi = 3.1415926535897932384626433832795; -const double c_half_pi = c_pi / 2.0; -const double c_2pi = 2.0 * c_pi; -const double c_inv_2pi = 1.0 / c_2pi; - -const double c_DEG2RADMULT = c_pi / 180.0; -const double c_RAD2DEGMULT = 180.0 / c_pi; - -inline double radians_to_degrees( double radians ){ - return radians * c_RAD2DEGMULT; -} -inline double degrees_to_radians( double degrees ){ - return degrees * c_DEG2RADMULT; -} - -#endif diff --git a/libs/math/plane.h b/libs/math/plane.h deleted file mode 100644 index 4027164..0000000 --- a/libs/math/plane.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_PLANE_H ) -#define INCLUDED_MATH_PLANE_H - -/// \file -/// \brief Plane data types and related operations. - -#include "math/matrix.h" - -/// \brief A plane equation stored in double-precision floating-point. -class Plane3 -{ -public: -double a, b, c, d; - -Plane3(){ -} -Plane3( double _a, double _b, double _c, double _d ) - : a( _a ), b( _b ), c( _c ), d( _d ){ -} -template -Plane3( const BasicVector3& normal, double dist ) - : a( normal.x() ), b( normal.y() ), c( normal.z() ), d( dist ){ -} - -BasicVector3& normal(){ - return reinterpret_cast&>( *this ); -} -const BasicVector3& normal() const { - return reinterpret_cast&>( *this ); -} -double& dist(){ - return d; -} -const double& dist() const { - return d; -} -}; - -inline Plane3 plane3_normalised( const Plane3& plane ){ - double rmagnitude = 1.0 / sqrt( plane.a * plane.a + plane.b * plane.b + plane.c * plane.c ); - return Plane3( - plane.a * rmagnitude, - plane.b * rmagnitude, - plane.c * rmagnitude, - plane.d * rmagnitude - ); -} - -inline Plane3 plane3_translated( const Plane3& plane, const Vector3& translation ){ - Plane3 transformed; - transformed.a = plane.a; - transformed.b = plane.b; - transformed.c = plane.c; - transformed.d = -( ( -plane.d * transformed.a + translation.x() ) * transformed.a + - ( -plane.d * transformed.b + translation.y() ) * transformed.b + - ( -plane.d * transformed.c + translation.z() ) * transformed.c ); - return transformed; -} - -inline Plane3 plane3_transformed( const Plane3& plane, const Matrix4& transform ){ - Plane3 transformed; - transformed.a = transform[0] * plane.a + transform[4] * plane.b + transform[8] * plane.c; - transformed.b = transform[1] * plane.a + transform[5] * plane.b + transform[9] * plane.c; - transformed.c = transform[2] * plane.a + transform[6] * plane.b + transform[10] * plane.c; - transformed.d = -( ( -plane.d * transformed.a + transform[12] ) * transformed.a + - ( -plane.d * transformed.b + transform[13] ) * transformed.b + - ( -plane.d * transformed.c + transform[14] ) * transformed.c ); - return transformed; -} - -inline Plane3 plane3_inverse_transformed( const Plane3& plane, const Matrix4& transform ){ - return Plane3 - ( - transform[ 0] * plane.a + transform[ 1] * plane.b + transform[ 2] * plane.c + transform[ 3] * plane.d, - transform[ 4] * plane.a + transform[ 5] * plane.b + transform[ 6] * plane.c + transform[ 7] * plane.d, - transform[ 8] * plane.a + transform[ 9] * plane.b + transform[10] * plane.c + transform[11] * plane.d, - transform[12] * plane.a + transform[13] * plane.b + transform[14] * plane.c + transform[15] * plane.d - ); -} - -inline Plane3 plane3_flipped( const Plane3& plane ){ - return Plane3( vector3_negated( plane.normal() ), -plane.dist() ); -} - -const double c_PLANE_NORMAL_EPSILON = 0.0001f; -const double c_PLANE_DIST_EPSILON = 0.02; - -inline bool plane3_equal( const Plane3& self, const Plane3& other ){ - return vector3_equal_epsilon( self.normal(), other.normal(), c_PLANE_NORMAL_EPSILON ) - && float_equal_epsilon( self.dist(), other.dist(), c_PLANE_DIST_EPSILON ); -} - -inline bool plane3_opposing( const Plane3& self, const Plane3& other ){ - return plane3_equal( self, plane3_flipped( other ) ); -} - -inline bool plane3_valid( const Plane3& self ){ - return float_equal_epsilon( vector3_dot( self.normal(), self.normal() ), 1.0, 0.01 ); -} - -template -inline Plane3 plane3_for_points( const BasicVector3& p0, const BasicVector3& p1, const BasicVector3& p2 ){ - Plane3 self; - self.normal() = vector3_normalised( vector3_cross( vector3_subtracted( p1, p0 ), vector3_subtracted( p2, p0 ) ) ); - self.dist() = vector3_dot( p0, self.normal() ); - return self; -} - -template -inline Plane3 plane3_for_points( const BasicVector3 planepts[3] ){ - return plane3_for_points( planepts[2], planepts[1], planepts[0] ); -} - - -#endif diff --git a/libs/math/quaternion.h b/libs/math/quaternion.h deleted file mode 100644 index 24c6861..0000000 --- a/libs/math/quaternion.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_QUATERNION_H ) -#define INCLUDED_MATH_QUATERNION_H - -/// \file -/// \brief Quaternion data types and related operations. - -#include "math/matrix.h" - -/// \brief A quaternion stored in single-precision floating-point. -typedef Vector4 Quaternion; - -const Quaternion c_quaternion_identity( 0, 0, 0, 1 ); - -inline Quaternion quaternion_multiplied_by_quaternion( const Quaternion& quaternion, const Quaternion& other ){ - return Quaternion( - quaternion[3] * other[0] + quaternion[0] * other[3] + quaternion[1] * other[2] - quaternion[2] * other[1], - quaternion[3] * other[1] + quaternion[1] * other[3] + quaternion[2] * other[0] - quaternion[0] * other[2], - quaternion[3] * other[2] + quaternion[2] * other[3] + quaternion[0] * other[1] - quaternion[1] * other[0], - quaternion[3] * other[3] - quaternion[0] * other[0] - quaternion[1] * other[1] - quaternion[2] * other[2] - ); -} - -inline void quaternion_multiply_by_quaternion( Quaternion& quaternion, const Quaternion& other ){ - quaternion = quaternion_multiplied_by_quaternion( quaternion, other ); -} - -/// \brief Constructs a quaternion which rotates between two points on the unit-sphere, \p from and \p to. -inline Quaternion quaternion_for_unit_vectors( const Vector3& from, const Vector3& to ){ - return Quaternion( vector3_cross( from, to ), static_cast( vector3_dot( from, to ) ) ); -} - -inline Quaternion quaternion_for_axisangle( const Vector3& axis, double angle ){ - angle *= 0.5; - float sa = static_cast( sin( angle ) ); - return Quaternion( axis[0] * sa, axis[1] * sa, axis[2] * sa, static_cast( cos( angle ) ) ); -} - -inline Quaternion quaternion_for_x( double angle ){ - angle *= 0.5; - return Quaternion( static_cast( sin( angle ) ), 0, 0, static_cast( cos( angle ) ) ); -} - -inline Quaternion quaternion_for_y( double angle ){ - angle *= 0.5; - return Quaternion( 0, static_cast( sin( angle ) ), 0, static_cast( cos( angle ) ) ); -} - -inline Quaternion quaternion_for_z( double angle ){ - angle *= 0.5; - return Quaternion( 0, 0, static_cast( sin( angle ) ), static_cast( cos( angle ) ) ); -} - -inline Quaternion quaternion_inverse( const Quaternion& quaternion ){ - return Quaternion( vector3_negated( vector4_to_vector3( quaternion ) ), quaternion[3] ); -} - -inline void quaternion_conjugate( Quaternion& quaternion ){ - quaternion = quaternion_inverse( quaternion ); -} - -inline Quaternion quaternion_normalised( const Quaternion& quaternion ){ - const double n = ( 1.0 / ( quaternion[0] * quaternion[0] + quaternion[1] * quaternion[1] + quaternion[2] * quaternion[2] + quaternion[3] * quaternion[3] ) ); - return Quaternion( - static_cast( quaternion[0] * n ), - static_cast( quaternion[1] * n ), - static_cast( quaternion[2] * n ), - static_cast( quaternion[3] * n ) - ); -} - -inline void quaternion_normalise( Quaternion& quaternion ){ - quaternion = quaternion_normalised( quaternion ); -} - -/// \brief Constructs a pure-rotation matrix from \p quaternion. -inline Matrix4 matrix4_rotation_for_quaternion( const Quaternion& quaternion ){ -#if 0 - const double xx = quaternion[0] * quaternion[0]; - const double xy = quaternion[0] * quaternion[1]; - const double xz = quaternion[0] * quaternion[2]; - const double xw = quaternion[0] * quaternion[3]; - - const double yy = quaternion[1] * quaternion[1]; - const double yz = quaternion[1] * quaternion[2]; - const double yw = quaternion[1] * quaternion[3]; - - const double zz = quaternion[2] * quaternion[2]; - const double zw = quaternion[2] * quaternion[3]; - - return Matrix4( - static_cast( 1 - 2 * ( yy + zz ) ), - static_cast( 2 * ( xy + zw ) ), - static_cast( 2 * ( xz - yw ) ), - 0, - static_cast( 2 * ( xy - zw ) ), - static_cast( 1 - 2 * ( xx + zz ) ), - static_cast( 2 * ( yz + xw ) ), - 0, - static_cast( 2 * ( xz + yw ) ), - static_cast( 2 * ( yz - xw ) ), - static_cast( 1 - 2 * ( xx + yy ) ), - 0, - 0, - 0, - 0, - 1 - ); - -#else - const double x2 = quaternion[0] + quaternion[0]; - const double y2 = quaternion[1] + quaternion[1]; - const double z2 = quaternion[2] + quaternion[2]; - const double xx = quaternion[0] * x2; - const double xy = quaternion[0] * y2; - const double xz = quaternion[0] * z2; - const double yy = quaternion[1] * y2; - const double yz = quaternion[1] * z2; - const double zz = quaternion[2] * z2; - const double wx = quaternion[3] * x2; - const double wy = quaternion[3] * y2; - const double wz = quaternion[3] * z2; - - return Matrix4( - static_cast( 1.0 - ( yy + zz ) ), - static_cast( xy + wz ), - static_cast( xz - wy ), - 0, - static_cast( xy - wz ), - static_cast( 1.0 - ( xx + zz ) ), - static_cast( yz + wx ), - 0, - static_cast( xz + wy ), - static_cast( yz - wx ), - static_cast( 1.0 - ( xx + yy ) ), - 0, - 0, - 0, - 0, - 1 - ); - -#endif -} - -const double c_half_sqrt2 = 0.70710678118654752440084436210485; -const float c_half_sqrt2f = static_cast( c_half_sqrt2 ); - -inline bool quaternion_component_is_90( float component ){ - return ( fabs( component ) - c_half_sqrt2 ) < 0.001; -} - -inline Matrix4 matrix4_rotation_for_quaternion_quantised( const Quaternion& quaternion ){ - if ( quaternion.y() == 0 - && quaternion.z() == 0 - && quaternion_component_is_90( quaternion.x() ) - && quaternion_component_is_90( quaternion.w() ) ) { - return matrix4_rotation_for_sincos_x( ( quaternion.x() > 0 ) ? 1.f : -1.f, 0 ); - } - - if ( quaternion.x() == 0 - && quaternion.z() == 0 - && quaternion_component_is_90( quaternion.y() ) - && quaternion_component_is_90( quaternion.w() ) ) { - return matrix4_rotation_for_sincos_y( ( quaternion.y() > 0 ) ? 1.f : -1.f, 0 ); - } - - if ( quaternion.x() == 0 - && quaternion.y() == 0 - && quaternion_component_is_90( quaternion.z() ) - && quaternion_component_is_90( quaternion.w() ) ) { - return matrix4_rotation_for_sincos_z( ( quaternion.z() > 0 ) ? 1.f : -1.f, 0 ); - } - - return matrix4_rotation_for_quaternion( quaternion ); -} - -inline Quaternion quaternion_for_matrix4_rotation( const Matrix4& matrix4 ){ - Quaternion out; - Matrix4 transposed = matrix4_transposed( matrix4 ); - - /* the monkeys added 1.0 to this for some reason. hint: it's WRONG - eukara */ - double trace = transposed[0] + transposed[5] + transposed[10] + 1.0f; - - if ( trace > 0.0 ) { - double S = 0.5 / sqrt( trace ); - return Quaternion( - static_cast( ( transposed[9] - transposed[6] ) * S ), - static_cast( ( transposed[2] - transposed[8] ) * S ), - static_cast( ( transposed[4] - transposed[1] ) * S ), - static_cast( 0.25 / S ) - ); - } - - if ( transposed[0] >= transposed[5] && transposed[0] >= transposed[10] ) { - double S = 2.0 * sqrt( 1.0 + transposed[0] - transposed[5] - transposed[10] ); - return Quaternion( - static_cast( 0.25 / S ), - static_cast( ( transposed[1] + transposed[4] ) / S ), - static_cast( ( transposed[2] + transposed[8] ) / S ), - static_cast( ( transposed[6] + transposed[9] ) / S ) - ); - } - - if ( transposed[5] >= transposed[0] && transposed[5] >= transposed[10] ) { - double S = 2.0 * sqrt( 1.0 + transposed[5] - transposed[0] - transposed[10] ); - return Quaternion( - static_cast( ( transposed[1] + transposed[4] ) / S ), - static_cast( 0.25 / S ), - static_cast( ( transposed[6] + transposed[9] ) / S ), - static_cast( ( transposed[2] + transposed[8] ) / S ) - ); - } - - double S = 2.0 * sqrt( 1.0 + transposed[10] - transposed[0] - transposed[5] ); - return Quaternion( - static_cast( ( transposed[2] + transposed[8] ) / S ), - static_cast( ( transposed[6] + transposed[9] ) / S ), - static_cast( 0.25 / S ), - static_cast( ( transposed[1] + transposed[4] ) / S ) - ); -} - -/// \brief Returns \p self concatenated with the rotation transform produced by \p rotation. -/// The concatenated rotation occurs before \p self. -inline Matrix4 matrix4_rotated_by_quaternion( const Matrix4& self, const Quaternion& rotation ){ - return matrix4_multiplied_by_matrix4( self, matrix4_rotation_for_quaternion( rotation ) ); -} - -/// \brief Concatenates \p self with the rotation transform produced by \p rotation. -/// The concatenated rotation occurs before \p self. -inline void matrix4_rotate_by_quaternion( Matrix4& self, const Quaternion& rotation ){ - self = matrix4_rotated_by_quaternion( self, rotation ); -} - -/// \brief Rotates \p self by \p rotation, using \p pivotpoint. -inline void matrix4_pivoted_rotate_by_quaternion( Matrix4& self, const Quaternion& rotation, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint ); - matrix4_rotate_by_quaternion( self, rotation ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - -inline Vector3 quaternion_transformed_point( const Quaternion& quaternion, const Vector3& point ){ - double xx = quaternion.x() * quaternion.x(); - double yy = quaternion.y() * quaternion.y(); - double zz = quaternion.z() * quaternion.z(); - double ww = quaternion.w() * quaternion.w(); - - double xy2 = quaternion.x() * quaternion.y() * 2; - double xz2 = quaternion.x() * quaternion.z() * 2; - double xw2 = quaternion.x() * quaternion.w() * 2; - double yz2 = quaternion.y() * quaternion.z() * 2; - double yw2 = quaternion.y() * quaternion.w() * 2; - double zw2 = quaternion.z() * quaternion.w() * 2; - - return Vector3( - static_cast( ww * point.x() + yw2 * point.z() - zw2 * point.y() + xx * point.x() + xy2 * point.y() + xz2 * point.z() - zz * point.x() - yy * point.x() ), - static_cast( xy2 * point.x() + yy * point.y() + yz2 * point.z() + zw2 * point.x() - zz * point.y() + ww * point.y() - xw2 * point.z() - xx * point.y() ), - static_cast( xz2 * point.x() + yz2 * point.y() + zz * point.z() - yw2 * point.x() - yy * point.z() + xw2 * point.y() - xx * point.z() + ww * point.z() ) - ); -} - -/// \brief Constructs a pure-rotation transform from \p axis and \p angle (radians). -inline Matrix4 matrix4_rotation_for_axisangle( const Vector3& axis, double angle ){ - return matrix4_rotation_for_quaternion( quaternion_for_axisangle( axis, angle ) ); -} - -/// \brief Rotates \p self about \p axis by \p angle. -inline void matrix4_rotate_by_axisangle( Matrix4& self, const Vector3& axis, double angle ){ - matrix4_multiply_by_matrix4( self, matrix4_rotation_for_axisangle( axis, angle ) ); -} - -/// \brief Rotates \p self about \p axis by \p angle using \p pivotpoint. -inline void matrix4_pivoted_rotate_by_axisangle( Matrix4& self, const Vector3& axis, double angle, const Vector3& pivotpoint ){ - matrix4_translate_by_vec3( self, pivotpoint ); - matrix4_rotate_by_axisangle( self, axis, angle ); - matrix4_translate_by_vec3( self, vector3_negated( pivotpoint ) ); -} - - -#endif diff --git a/libs/math/vector.h b/libs/math/vector.h deleted file mode 100644 index b4fd92c..0000000 --- a/libs/math/vector.h +++ /dev/null @@ -1,709 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MATH_VECTOR_H ) -#define INCLUDED_MATH_VECTOR_H - -/// \file -/// \brief Vector data types and related operations. - -#include "generic/vector.h" -#include "globaldefs.h" - -#if GDEF_COMPILER_MSVC - -inline int lrint( double flt ){ - int i; - - _asm - { - fld flt - fistp i - }; - - return i; -} - -inline __int64 llrint( double f ){ - return static_cast<__int64>( f + 0.5 ); -} - -#elif GDEF_OS_BSD - -/*inline long lrint( double f ){ - return static_cast( f + 0.5 ); -}*/ - -/*inline long long llrint( double f ){ - return static_cast( f + 0.5 ); -}*/ - -#elif GDEF_COMPILER_GNU - -// lrint is part of ISO C99 -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 - -#define __USE_ISOC9X 1 -#define __USE_ISOC99 1 - -#else -#error "unsupported platform" -#endif - -#include -#include -#include - - -//#include "debugging/debugging.h" - -/// \brief Returns true if \p self is equal to other \p other within \p epsilon. -template -inline bool float_equal_epsilon( const Element& self, const OtherElement& other, const Element& epsilon ){ - return fabs( other - self ) < epsilon; -} - -/// \brief Returns the value midway between \p self and \p other. -template -inline Element float_mid( const Element& self, const Element& other ){ - return Element( ( self + other ) * 0.5 ); -} - -/// \brief Returns \p f rounded to the nearest integer. Note that this is not the same behaviour as casting from float to int. -template -inline int float_to_integer( const Element& f ){ - return lrint( f ); -} - -/// \brief Returns \p f rounded to the nearest multiple of \p snap. -template -inline Element float_snapped( const Element& f, const OtherElement& snap ){ - //return Element(float_to_integer(f / snap) * snap); - if ( snap == 0 ) { - return f; - } - return Element( llrint( f / snap ) * snap ); // llrint has more significant bits -} - -/// \brief Returns true if \p f has no decimal fraction part. -template -inline bool float_is_integer( const Element& f ){ - return f == Element( float_to_integer( f ) ); -} - -/// \brief Returns \p self modulated by the range [0, \p modulus) -/// \p self must be in the range [\p -modulus, \p modulus) -template -inline Element float_mod_range( const Element& self, const ModulusElement& modulus ){ - return Element( ( self < 0.0 ) ? self + modulus : self ); -} - -/// \brief Returns \p self modulated by the range [0, \p modulus) -template -inline Element float_mod( const Element& self, const ModulusElement& modulus ){ - return float_mod_range( Element( fmod( static_cast( self ), static_cast( modulus ) ) ), modulus ); -} - - -template -inline BasicVector2 vector2_added( const BasicVector2& self, const BasicVector2& other ){ - return BasicVector2( - Element( self.x() + other.x() ), - Element( self.y() + other.y() ) - ); -} -template -inline BasicVector2 operator+( const BasicVector2& self, const BasicVector2& other ){ - return vector2_added( self, other ); -} -template -inline void vector2_add( BasicVector2& self, const BasicVector2& other ){ - self.x() += Element( other.x() ); - self.y() += Element( other.y() ); -} -template -inline void operator+=( BasicVector2& self, const BasicVector2& other ){ - vector2_add( self, other ); -} - - -template -inline BasicVector2 vector2_subtracted( const BasicVector2& self, const BasicVector2& other ){ - return BasicVector2( - Element( self.x() - other.x() ), - Element( self.y() - other.y() ) - ); -} -template -inline BasicVector2 operator-( const BasicVector2& self, const BasicVector2& other ){ - return vector2_subtracted( self, other ); -} -template -inline void vector2_subtract( BasicVector2& self, const BasicVector2& other ){ - self.x() -= Element( other.x() ); - self.y() -= lement( other.y() ); -} -template -inline void operator-=( BasicVector2& self, const BasicVector2& other ){ - vector2_subtract( self, other ); -} - - -template -inline BasicVector2 vector2_scaled( const BasicVector2& self, OtherElement other ){ - return BasicVector2( - Element( self.x() * other ), - Element( self.y() * other ) - ); -} -template -inline BasicVector2 operator*( const BasicVector2& self, OtherElement other ){ - return vector2_scaled( self, other ); -} -template -inline void vector2_scale( BasicVector2& self, OtherElement other ){ - self.x() *= Element( other ); - self.y() *= Element( other ); -} -template -inline void operator*=( BasicVector2& self, OtherElement other ){ - vector2_scale( self, other ); -} - - -template -inline BasicVector2 vector2_scaled( const BasicVector2& self, const BasicVector2& other ){ - return BasicVector2( - Element( self.x() * other.x() ), - Element( self.y() * other.y() ) - ); -} -template -inline BasicVector2 operator*( const BasicVector2& self, const BasicVector2& other ){ - return vector2_scaled( self, other ); -} -template -inline void vector2_scale( BasicVector2& self, const BasicVector2& other ){ - self.x() *= Element( other.x() ); - self.y() *= Element( other.y() ); -} -template -inline void operator*=( BasicVector2& self, const BasicVector2& other ){ - vector2_scale( self, other ); -} - -template -inline BasicVector2 vector2_divided( const BasicVector2& self, const BasicVector2& other ){ - return BasicVector2( - Element( self.x() / other.x() ), - Element( self.y() / other.y() ) - ); -} -template -inline BasicVector2 operator/( const BasicVector2& self, const BasicVector2& other ){ - return vector2_divided( self, other ); -} -template -inline void vector2_divide( BasicVector2& self, const BasicVector2& other ){ - self.x() /= Element( other.x() ); - self.y() /= Element( other.y() ); -} -template -inline void operator/=( BasicVector2& self, const BasicVector2& other ){ - vector2_divide( self, other ); -} - - -template -inline BasicVector2 vector2_divided( const BasicVector2& self, OtherElement other ){ - return BasicVector2( - Element( self.x() / other ), - Element( self.y() / other ) - ); -} -template -inline BasicVector2 operator/( const BasicVector2& self, OtherElement other ){ - return vector2_divided( self, other ); -} -template -inline void vector2_divide( BasicVector2& self, OtherElement other ){ - self.x() /= Element( other ); - self.y() /= Element( other ); -} -template -inline void operator/=( BasicVector2& self, OtherElement other ){ - vector2_divide( self, other ); -} - -template -inline double vector2_dot( const BasicVector2& self, const BasicVector2& other ){ - return self.x() * other.x() + self.y() * other.y(); -} - -template -inline double vector2_length_squared( const BasicVector2& self ){ - return vector2_dot( self, self ); -} - -template -inline double vector2_length( const BasicVector2& self ){ - return sqrt( vector2_length_squared( self ) ); -} - -template -inline double vector2_cross( const BasicVector2& self, const BasicVector2& other ){ - return self.x() * other.y() - self.y() * other.x(); -} - -const Vector3 g_vector3_identity( 0, 0, 0 ); -const Vector3 g_vector3_max = Vector3( FLT_MAX, FLT_MAX, FLT_MAX ); -const Vector3 g_vector3_axis_x( 1, 0, 0 ); -const Vector3 g_vector3_axis_y( 0, 1, 0 ); -const Vector3 g_vector3_axis_z( 0, 0, 1 ); - -const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z }; - -template -inline void vector3_swap( BasicVector3& self, BasicVector3& other ){ - std::swap( self.x(), other.x() ); - std::swap( self.y(), other.y() ); - std::swap( self.z(), other.z() ); -} - -template -inline bool vector3_equal( const BasicVector3& self, const BasicVector3& other ){ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); -} -template -inline bool operator==( const BasicVector3& self, const BasicVector3& other ){ - return vector3_equal( self, other ); -} -template -inline bool operator!=( const BasicVector3& self, const BasicVector3& other ){ - return !vector3_equal( self, other ); -} - - -template -inline bool vector3_equal_epsilon( const BasicVector3& self, const BasicVector3& other, Epsilon epsilon ){ - return float_equal_epsilon( self.x(), other.x(), epsilon ) - && float_equal_epsilon( self.y(), other.y(), epsilon ) - && float_equal_epsilon( self.z(), other.z(), epsilon ); -} - - - -template -inline BasicVector3 vector3_added( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.x() + other.x() ), - Element( self.y() + other.y() ), - Element( self.z() + other.z() ) - ); -} -template -inline BasicVector3 operator+( const BasicVector3& self, const BasicVector3& other ){ - return vector3_added( self, other ); -} -template -inline void vector3_add( BasicVector3& self, const BasicVector3& other ){ - self.x() += static_cast( other.x() ); - self.y() += static_cast( other.y() ); - self.z() += static_cast( other.z() ); -} -template -inline void operator+=( BasicVector3& self, const BasicVector3& other ){ - vector3_add( self, other ); -} - -template -inline BasicVector3 vector3_subtracted( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.x() - other.x() ), - Element( self.y() - other.y() ), - Element( self.z() - other.z() ) - ); -} -template -inline BasicVector3 operator-( const BasicVector3& self, const BasicVector3& other ){ - return vector3_subtracted( self, other ); -} -template -inline void vector3_subtract( BasicVector3& self, const BasicVector3& other ){ - self.x() -= static_cast( other.x() ); - self.y() -= static_cast( other.y() ); - self.z() -= static_cast( other.z() ); -} -template -inline void operator-=( BasicVector3& self, const BasicVector3& other ){ - vector3_subtract( self, other ); -} - -template -inline BasicVector3 vector3_scaled( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.x() * other.x() ), - Element( self.y() * other.y() ), - Element( self.z() * other.z() ) - ); -} -template -inline BasicVector3 operator*( const BasicVector3& self, const BasicVector3& other ){ - return vector3_scaled( self, other ); -} -template -inline void vector3_scale( BasicVector3& self, const BasicVector3& other ){ - self.x() *= static_cast( other.x() ); - self.y() *= static_cast( other.y() ); - self.z() *= static_cast( other.z() ); -} -template -inline void operator*=( BasicVector3& self, const BasicVector3& other ){ - vector3_scale( self, other ); -} - -template -inline BasicVector3 vector3_scaled( const BasicVector3& self, const OtherElement& scale ){ - return BasicVector3( - Element( self.x() * scale ), - Element( self.y() * scale ), - Element( self.z() * scale ) - ); -} -template -inline BasicVector3 operator*( const BasicVector3& self, const OtherElement& scale ){ - return vector3_scaled( self, scale ); -} -template -inline void vector3_scale( BasicVector3& self, const OtherElement& scale ){ - self.x() *= static_cast( scale ); - self.y() *= static_cast( scale ); - self.z() *= static_cast( scale ); -} -template -inline void operator*=( BasicVector3& self, const OtherElement& scale ){ - vector3_scale( self, scale ); -} - -template -inline BasicVector3 vector3_divided( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.x() / other.x() ), - Element( self.y() / other.y() ), - Element( self.z() / other.z() ) - ); -} -template -inline BasicVector3 operator/( const BasicVector3& self, const BasicVector3& other ){ - return vector3_divided( self, other ); -} -template -inline void vector3_divide( BasicVector3& self, const BasicVector3& other ){ - self.x() /= static_cast( other.x() ); - self.y() /= static_cast( other.y() ); - self.z() /= static_cast( other.z() ); -} -template -inline void operator/=( BasicVector3& self, const BasicVector3& other ){ - vector3_divide( self, other ); -} - -template -inline BasicVector3 vector3_divided( const BasicVector3& self, const OtherElement& divisor ){ - return BasicVector3( - Element( self.x() / divisor ), - Element( self.y() / divisor ), - Element( self.z() / divisor ) - ); -} -template -inline BasicVector3 operator/( const BasicVector3& self, const OtherElement& divisor ){ - return vector3_divided( self, divisor ); -} -template -inline void vector3_divide( BasicVector3& self, const OtherElement& divisor ){ - self.x() /= static_cast( divisor ); - self.y() /= static_cast( divisor ); - self.z() /= static_cast( divisor ); -} -template -inline void operator/=( BasicVector3& self, const OtherElement& divisor ){ - vector3_divide( self, divisor ); -} - -template -inline double vector3_dot( const BasicVector3& self, const BasicVector3& other ){ - return self.x() * other.x() + self.y() * other.y() + self.z() * other.z(); -} - -template -inline BasicVector3 vector3_mid( const BasicVector3& begin, const BasicVector3& end ){ - return vector3_scaled( vector3_added( begin, end ), 0.5 ); -} - -template -inline BasicVector3 vector3_cross( const BasicVector3& self, const BasicVector3& other ){ - return BasicVector3( - Element( self.y() * other.z() - self.z() * other.y() ), - Element( self.z() * other.x() - self.x() * other.z() ), - Element( self.x() * other.y() - self.y() * other.x() ) - ); -} - -template -inline BasicVector3 vector3_negated( const BasicVector3& self ){ - return BasicVector3( -self.x(), -self.y(), -self.z() ); -} -template -inline BasicVector3 operator-( const BasicVector3& self ){ - return vector3_negated( self ); -} - -template -inline void vector3_negate( BasicVector3& self ){ - self = vector3_negated( self ); -} - -template -inline double vector3_length_squared( const BasicVector3& self ){ - return vector3_dot( self, self ); -} - -template -inline double vector3_length( const BasicVector3& self ){ - return sqrt( vector3_length_squared( self ) ); -} - -template -inline Element float_divided( Element f, Element other ){ - //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor"); - return f / other; -} - -template -inline BasicVector3 vector3_normalised( const BasicVector3& self ){ - return vector3_scaled( self, float_divided( 1.0, vector3_length( self ) ) ); -} - -template -inline void vector3_normalise( BasicVector3& self ){ - self = vector3_normalised( self ); -} - - -template -inline BasicVector3 vector3_snapped( const BasicVector3& self ){ - return BasicVector3( - Element( float_to_integer( self.x() ) ), - Element( float_to_integer( self.y() ) ), - Element( float_to_integer( self.z() ) ) - ); -} -template -inline void vector3_snap( BasicVector3& self ){ - self = vector3_snapped( self ); -} -template -inline BasicVector3 vector3_snapped( const BasicVector3& self, const OtherElement& snap ){ - return BasicVector3( - Element( float_snapped( self.x(), snap ) ), - Element( float_snapped( self.y(), snap ) ), - Element( float_snapped( self.z(), snap ) ) - ); -} -template -inline void vector3_snap( BasicVector3& self, const OtherElement& snap ){ - self = vector3_snapped( self, snap ); -} - -inline Vector3 vector3_for_spherical( double theta, double phi ){ - return Vector3( - static_cast( cos( theta ) * cos( phi ) ), - static_cast( sin( theta ) * cos( phi ) ), - static_cast( sin( phi ) ) - ); -} - - - - -template -inline bool vector4_equal( const BasicVector4& self, const BasicVector4& other ){ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w(); -} -template -inline bool operator==( const BasicVector4& self, const BasicVector4& other ){ - return vector4_equal( self, other ); -} -template -inline bool operator!=( const BasicVector4& self, const BasicVector4& other ){ - return !vector4_equal( self, other ); -} - -template -inline bool vector4_equal_epsilon( const BasicVector4& self, const BasicVector4& other, Element epsilon ){ - return float_equal_epsilon( self.x(), other.x(), epsilon ) - && float_equal_epsilon( self.y(), other.y(), epsilon ) - && float_equal_epsilon( self.z(), other.z(), epsilon ) - && float_equal_epsilon( self.w(), other.w(), epsilon ); -} -template -inline BasicVector4 vector4_mid( const BasicVector4& begin, const BasicVector4& end ){ - return vector4_scaled( vector4_added( begin, end ), 0.5 ); -} - -template -inline BasicVector4 vector4_added( const BasicVector4& self, const BasicVector4& other ){ - return BasicVector4( - float(self.x() + other.x() ), - float(self.y() + other.y() ), - float(self.z() + other.z() ), - float(self.w() + other.w() ) - ); -} -template -inline BasicVector4 operator+( const BasicVector4& self, const BasicVector4& other ){ - return vector4_added( self, other ); -} -template -inline void vector4_add( BasicVector4& self, const BasicVector4& other ){ - self.x() += static_cast( other.x() ); - self.y() += static_cast( other.y() ); - self.z() += static_cast( other.z() ); - self.w() += static_cast( other.w() ); -} -template -inline void operator+=( BasicVector4& self, const BasicVector4& other ){ - vector4_add( self, other ); -} - -template -inline BasicVector4 vector4_subtracted( const BasicVector4& self, const BasicVector4& other ){ - return BasicVector4( - float(self.x() - other.x() ), - float(self.y() - other.y() ), - float(self.z() - other.z() ), - float(self.w() - other.w() ) - ); -} -template -inline BasicVector4 operator-( const BasicVector4& self, const BasicVector4& other ){ - return vector4_subtracted( self, other ); -} -template -inline void vector4_subtract( BasicVector4& self, const BasicVector4& other ){ - self.x() -= static_cast( other.x() ); - self.y() -= static_cast( other.y() ); - self.z() -= static_cast( other.z() ); - self.w() -= static_cast( other.w() ); -} -template -inline void operator-=( BasicVector4& self, const BasicVector4& other ){ - vector4_subtract( self, other ); -} - -template -inline BasicVector4 vector4_scaled( const BasicVector4& self, const BasicVector4& other ){ - return BasicVector4( - float(self.x() * other.x() ), - float(self.y() * other.y() ), - float(self.z() * other.z() ), - float(self.w() * other.w() ) - ); -} -template -inline BasicVector4 operator*( const BasicVector4& self, const BasicVector4& other ){ - return vector4_scaled( self, other ); -} -template -inline void vector4_scale( BasicVector4& self, const BasicVector4& other ){ - self.x() *= static_cast( other.x() ); - self.y() *= static_cast( other.y() ); - self.z() *= static_cast( other.z() ); - self.w() *= static_cast( other.w() ); -} -template -inline void operator*=( BasicVector4& self, const BasicVector4& other ){ - vector4_scale( self, other ); -} - -template -inline BasicVector4 vector4_scaled( const BasicVector4& self, OtherElement scale ){ - return BasicVector4( - float(self.x() * scale), - float(self.y() * scale), - float(self.z() * scale), - float(self.w() * scale) - ); -} -template -inline BasicVector4 operator*( const BasicVector4& self, OtherElement scale ){ - return vector4_scaled( self, scale ); -} -template -inline void vector4_scale( BasicVector4& self, OtherElement scale ){ - self.x() *= static_cast( scale ); - self.y() *= static_cast( scale ); - self.z() *= static_cast( scale ); - self.w() *= static_cast( scale ); -} -template -inline void operator*=( BasicVector4& self, OtherElement scale ){ - vector4_scale( self, scale ); -} - -template -inline BasicVector4 vector4_divided( const BasicVector4& self, OtherElement divisor ){ - return BasicVector4( - float(self.x() / divisor), - float(self.y() / divisor), - float(self.z() / divisor), - float(self.w() / divisor) - ); -} -template -inline BasicVector4 operator/( const BasicVector4& self, OtherElement divisor ){ - return vector4_divided( self, divisor ); -} -template -inline void vector4_divide( BasicVector4& self, OtherElement divisor ){ - self.x() /= divisor; - self.y() /= divisor; - self.z() /= divisor; - self.w() /= divisor; -} -template -inline void operator/=( BasicVector4& self, OtherElement divisor ){ - vector4_divide( self, divisor ); -} - -template -inline double vector4_dot( const BasicVector4& self, const BasicVector4& other ){ - return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w(); -} - -template -inline BasicVector3 vector4_projected( const BasicVector4& self ){ - return vector3_scaled( vector4_to_vector3( self ), 1.0 / self[3] ); -} - -#endif diff --git a/libs/md5lib/md5lib.c b/libs/md5lib/md5lib.c deleted file mode 100644 index d71a36f..0000000 --- a/libs/md5lib/md5lib.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5lib.c,v 1.1 2003/07/18 04:24:39 ydnar Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2003-07-17 ydnar added to gtkradiant project from - http://sourceforge.net/projects/libmd5-rfc/ - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "md5lib.h" /* ydnar */ -#include "globaldefs.h" -#include - -#if GDEF_ARCH_ENDIAN_BIG -#define ARCH_IS_BIG_ENDIAN 1 -#else -#define ARCH_IS_BIG_ENDIAN 0 -#endif -/* ydnar: end */ - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#define BYTE_ORDER ( ARCH_IS_BIG_ENDIAN ? 1 : -1 ) - -#define T_MASK ( ( md5_word_t ) ~0 ) -#define T1 /* 0xd76aa478 */ ( T_MASK ^ 0x28955b87 ) -#define T2 /* 0xe8c7b756 */ ( T_MASK ^ 0x173848a9 ) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ ( T_MASK ^ 0x3e423111 ) -#define T5 /* 0xf57c0faf */ ( T_MASK ^ 0x0a83f050 ) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ ( T_MASK ^ 0x57cfb9ec ) -#define T8 /* 0xfd469501 */ ( T_MASK ^ 0x02b96afe ) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ ( T_MASK ^ 0x74bb0850 ) -#define T11 /* 0xffff5bb1 */ ( T_MASK ^ 0x0000a44e ) -#define T12 /* 0x895cd7be */ ( T_MASK ^ 0x76a32841 ) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ ( T_MASK ^ 0x02678e6c ) -#define T15 /* 0xa679438e */ ( T_MASK ^ 0x5986bc71 ) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ ( T_MASK ^ 0x09e1da9d ) -#define T18 /* 0xc040b340 */ ( T_MASK ^ 0x3fbf4cbf ) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ ( T_MASK ^ 0x16493855 ) -#define T21 /* 0xd62f105d */ ( T_MASK ^ 0x29d0efa2 ) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ ( T_MASK ^ 0x275e197e ) -#define T24 /* 0xe7d3fbc8 */ ( T_MASK ^ 0x182c0437 ) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ ( T_MASK ^ 0x3cc8f829 ) -#define T27 /* 0xf4d50d87 */ ( T_MASK ^ 0x0b2af278 ) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ ( T_MASK ^ 0x561c16fa ) -#define T30 /* 0xfcefa3f8 */ ( T_MASK ^ 0x03105c07 ) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ ( T_MASK ^ 0x72d5b375 ) -#define T33 /* 0xfffa3942 */ ( T_MASK ^ 0x0005c6bd ) -#define T34 /* 0x8771f681 */ ( T_MASK ^ 0x788e097e ) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ ( T_MASK ^ 0x021ac7f3 ) -#define T37 /* 0xa4beea44 */ ( T_MASK ^ 0x5b4115bb ) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ ( T_MASK ^ 0x0944b49f ) -#define T40 /* 0xbebfbc70 */ ( T_MASK ^ 0x4140438f ) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ ( T_MASK ^ 0x155ed805 ) -#define T43 /* 0xd4ef3085 */ ( T_MASK ^ 0x2b10cf7a ) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ ( T_MASK ^ 0x262b2fc6 ) -#define T46 /* 0xe6db99e5 */ ( T_MASK ^ 0x1924661a ) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ ( T_MASK ^ 0x3b53a99a ) -#define T49 /* 0xf4292244 */ ( T_MASK ^ 0x0bd6ddbb ) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ ( T_MASK ^ 0x546bdc58 ) -#define T52 /* 0xfc93a039 */ ( T_MASK ^ 0x036c5fc6 ) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ ( T_MASK ^ 0x70f3336d ) -#define T55 /* 0xffeff47d */ ( T_MASK ^ 0x00100b82 ) -#define T56 /* 0x85845dd1 */ ( T_MASK ^ 0x7a7ba22e ) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ ( T_MASK ^ 0x01d3191f ) -#define T59 /* 0xa3014314 */ ( T_MASK ^ 0x5cfebceb ) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ ( T_MASK ^ 0x08ac817d ) -#define T62 /* 0xbd3af235 */ ( T_MASK ^ 0x42c50dca ) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ ( T_MASK ^ 0x14792c6e ) - - -static void -md5_process( md5_state_t *pms, const md5_byte_t *data /*[64]*/ ){ - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t *X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if ( *( (const md5_byte_t *)&w ) ) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if ( !( ( data - (const md5_byte_t *)0 ) & 3 ) ) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } - else { - /* not aligned */ - memcpy( xbuf, data, 64 ); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; - -#if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -#else -#define xbuf X /* (static only) */ -#endif - for ( i = 0; i < 16; ++i, xp += 4 ) - xbuf[i] = xp[0] + ( xp[1] << 8 ) + ( xp[2] << 16 ) + ( xp[3] << 24 ); - } -#endif - } - -#define ROTATE_LEFT( x, n ) ( ( ( x ) << ( n ) ) | ( ( x ) >> ( 32 - ( n ) ) ) ) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F( x, y, z ) ( ( ( x ) & ( y ) ) | ( ~( x ) & ( z ) ) ) -#define SET( a, b, c, d, k, s, Ti ) \ - t = a + F( b,c,d ) + X[k] + Ti; \ - a = ROTATE_LEFT( t, s ) + b - /* Do the following 16 operations. */ - SET( a, b, c, d, 0, 7, T1 ); - SET( d, a, b, c, 1, 12, T2 ); - SET( c, d, a, b, 2, 17, T3 ); - SET( b, c, d, a, 3, 22, T4 ); - SET( a, b, c, d, 4, 7, T5 ); - SET( d, a, b, c, 5, 12, T6 ); - SET( c, d, a, b, 6, 17, T7 ); - SET( b, c, d, a, 7, 22, T8 ); - SET( a, b, c, d, 8, 7, T9 ); - SET( d, a, b, c, 9, 12, T10 ); - SET( c, d, a, b, 10, 17, T11 ); - SET( b, c, d, a, 11, 22, T12 ); - SET( a, b, c, d, 12, 7, T13 ); - SET( d, a, b, c, 13, 12, T14 ); - SET( c, d, a, b, 14, 17, T15 ); - SET( b, c, d, a, 15, 22, T16 ); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G( x, y, z ) ( ( ( x ) & ( z ) ) | ( ( y ) & ~( z ) ) ) -#define SET( a, b, c, d, k, s, Ti ) \ - t = a + G( b,c,d ) + X[k] + Ti; \ - a = ROTATE_LEFT( t, s ) + b - /* Do the following 16 operations. */ - SET( a, b, c, d, 1, 5, T17 ); - SET( d, a, b, c, 6, 9, T18 ); - SET( c, d, a, b, 11, 14, T19 ); - SET( b, c, d, a, 0, 20, T20 ); - SET( a, b, c, d, 5, 5, T21 ); - SET( d, a, b, c, 10, 9, T22 ); - SET( c, d, a, b, 15, 14, T23 ); - SET( b, c, d, a, 4, 20, T24 ); - SET( a, b, c, d, 9, 5, T25 ); - SET( d, a, b, c, 14, 9, T26 ); - SET( c, d, a, b, 3, 14, T27 ); - SET( b, c, d, a, 8, 20, T28 ); - SET( a, b, c, d, 13, 5, T29 ); - SET( d, a, b, c, 2, 9, T30 ); - SET( c, d, a, b, 7, 14, T31 ); - SET( b, c, d, a, 12, 20, T32 ); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H( x, y, z ) ( ( x ) ^ ( y ) ^ ( z ) ) -#define SET( a, b, c, d, k, s, Ti ) \ - t = a + H( b,c,d ) + X[k] + Ti; \ - a = ROTATE_LEFT( t, s ) + b - /* Do the following 16 operations. */ - SET( a, b, c, d, 5, 4, T33 ); - SET( d, a, b, c, 8, 11, T34 ); - SET( c, d, a, b, 11, 16, T35 ); - SET( b, c, d, a, 14, 23, T36 ); - SET( a, b, c, d, 1, 4, T37 ); - SET( d, a, b, c, 4, 11, T38 ); - SET( c, d, a, b, 7, 16, T39 ); - SET( b, c, d, a, 10, 23, T40 ); - SET( a, b, c, d, 13, 4, T41 ); - SET( d, a, b, c, 0, 11, T42 ); - SET( c, d, a, b, 3, 16, T43 ); - SET( b, c, d, a, 6, 23, T44 ); - SET( a, b, c, d, 9, 4, T45 ); - SET( d, a, b, c, 12, 11, T46 ); - SET( c, d, a, b, 15, 16, T47 ); - SET( b, c, d, a, 2, 23, T48 ); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I( x, y, z ) ( ( y ) ^ ( ( x ) | ~( z ) ) ) -#define SET( a, b, c, d, k, s, Ti ) \ - t = a + I( b,c,d ) + X[k] + Ti; \ - a = ROTATE_LEFT( t, s ) + b - /* Do the following 16 operations. */ - SET( a, b, c, d, 0, 6, T49 ); - SET( d, a, b, c, 7, 10, T50 ); - SET( c, d, a, b, 14, 15, T51 ); - SET( b, c, d, a, 5, 21, T52 ); - SET( a, b, c, d, 12, 6, T53 ); - SET( d, a, b, c, 3, 10, T54 ); - SET( c, d, a, b, 10, 15, T55 ); - SET( b, c, d, a, 1, 21, T56 ); - SET( a, b, c, d, 8, 6, T57 ); - SET( d, a, b, c, 15, 10, T58 ); - SET( c, d, a, b, 6, 15, T59 ); - SET( b, c, d, a, 13, 21, T60 ); - SET( a, b, c, d, 4, 6, T61 ); - SET( d, a, b, c, 11, 10, T62 ); - SET( c, d, a, b, 2, 15, T63 ); - SET( b, c, d, a, 9, 21, T64 ); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -md5_init( md5_state_t *pms ){ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -void -md5_append( md5_state_t *pms, const md5_byte_t *data, int nbytes ){ - const md5_byte_t *p = data; - int left = nbytes; - int offset = ( pms->count[0] >> 3 ) & 63; - md5_word_t nbits = (md5_word_t)( nbytes << 3 ); - - if ( nbytes <= 0 ) { - return; - } - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if ( pms->count[0] < nbits ) { - pms->count[1]++; - } - - /* Process an initial partial block. */ - if ( offset ) { - int copy = ( offset + nbytes > 64 ? 64 - offset : nbytes ); - - memcpy( pms->buf + offset, p, copy ); - if ( offset + copy < 64 ) { - return; - } - p += copy; - left -= copy; - md5_process( pms, pms->buf ); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64 ) - md5_process( pms, p ); - - /* Process a final partial block. */ - if ( left ) { - memcpy( pms->buf, p, left ); - } -} - -void -md5_finish( md5_state_t *pms, md5_byte_t digest[16] ){ - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for ( i = 0; i < 8; ++i ) - data[i] = (md5_byte_t)( pms->count[i >> 2] >> ( ( i & 3 ) << 3 ) ); - /* Pad to 56 bytes mod 64. */ - md5_append( pms, pad, ( ( 55 - ( pms->count[0] >> 3 ) ) & 63 ) + 1 ); - /* Append the length. */ - md5_append( pms, data, 8 ); - for ( i = 0; i < 16; ++i ) - digest[i] = (md5_byte_t)( pms->abcd[i >> 2] >> ( ( i & 3 ) << 3 ) ); -} diff --git a/libs/memory/Makefile b/libs/memory/Makefile deleted file mode 100644 index 410b36f..0000000 --- a/libs/memory/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - allocator.o - -# binary target -../libmemory.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -allocator.o: allocator.cpp allocator.h - -clean: - -rm -f *.o ../libmemory.a diff --git a/libs/memory/allocator.cpp b/libs/memory/allocator.cpp deleted file mode 100644 index 0e4decf..0000000 --- a/libs/memory/allocator.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "memory/allocator.h" - -#include - -template -struct Vector -{ - typedef std::vector > Type; -}; - -namespace -{ -class Bleh -{ -int* m_blah; -public: -Bleh( int* blah ) : m_blah( blah ){ -} -~Bleh(){ - *m_blah = 15; -} -}; - -void TestAllocator(){ - Vector::Type test; - - int i = 0; - test.push_back( Bleh( &i ) ); -} - -void TestNewDelete(){ - { - NamedAllocator allocator( "test" ); - int* p = NamedNew::type( allocator ).scalar(); - //new int(); - NamedDelete::type( allocator ).scalar( p ); - } - - { - int* p = New().scalar( 3 ); - Delete().scalar( p ); - } - - { - int* p = New().scalar( int(15.9) ); - Delete().scalar( p ); - } - - { - int* p = New().vector( 15 ); - // new int[15] - Delete().vector( p, 15 ); - } -} -} \ No newline at end of file diff --git a/libs/memory/allocator.h b/libs/memory/allocator.h deleted file mode 100644 index 845ce14..0000000 --- a/libs/memory/allocator.h +++ /dev/null @@ -1,291 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MEMORY_ALLOCATOR_H ) -#define INCLUDED_MEMORY_ALLOCATOR_H - -#include -#include - -#if 0 - -#define DefaultAllocator std::allocator - -#else - -/// \brief An allocator that uses c++ new/delete. -/// Compliant with the std::allocator interface. -template -class DefaultAllocator -{ -public: - -typedef Type value_type; -typedef value_type* pointer; -typedef const Type* const_pointer; -typedef Type& reference; -typedef const Type& const_reference; -typedef size_t size_type; -typedef ptrdiff_t difference_type; - -template -struct rebind -{ - typedef DefaultAllocator other; -}; - -DefaultAllocator(){ -} -DefaultAllocator( const DefaultAllocator& ){ -} -template DefaultAllocator( const DefaultAllocator& ){ -} -~DefaultAllocator(){ -} - -pointer address( reference instance ) const { - return &instance; -} -const_pointer address( const_reference instance ) const { - return &instance; -} -Type* allocate( size_type size, const void* = 0 ){ - return static_cast( ::operator new( size * sizeof( Type ) ) ); -} -void deallocate( pointer p, size_type ){ - ::operator delete( p ); -} -size_type max_size() const { - return std::size_t( -1 ) / sizeof( Type ); -} -void construct( pointer p, const Type& value ){ - new(p) Type( value ); -} -void destroy( pointer p ){ - p->~Type(); -} -}; - -template -inline bool operator==( const DefaultAllocator&, const DefaultAllocator& ){ - return true; -} -template -inline bool operator==( const DefaultAllocator&, const OtherAllocator& ){ - return false; -} - -#endif - - -template -class NamedAllocator : public DefaultAllocator -{ -typedef DefaultAllocator allocator_type; - -const char* m_name; -public: - -typedef Type value_type; -typedef value_type* pointer; -typedef const Type* const_pointer; -typedef Type& reference; -typedef const Type& const_reference; -typedef size_t size_type; -typedef ptrdiff_t difference_type; - -template -struct rebind -{ - typedef NamedAllocator other; -}; - -explicit NamedAllocator( const char* name ) : DefaultAllocator(), m_name( name ){ -} -NamedAllocator( const NamedAllocator& other ) : DefaultAllocator(), m_name( other.m_name ){ -} -template NamedAllocator( const NamedAllocator& other ) : DefaultAllocator(), m_name( other.m_name ){ -} -~NamedAllocator(){ -} - -pointer address( reference instance ) const { - return allocator_type::address( instance ); -} -const_pointer address( const_reference instance ) const { - return allocator_type::address( instance ); -} -Type* allocate( size_type size, const void* = 0 ){ - return allocator_type::allocate( size ); -} -void deallocate( pointer p, size_type size ){ - allocator_type::deallocate( p, size ); -} -size_type max_size() const { - return allocator_type::max_size(); -} -void construct( pointer p, const Type& value ){ - allocator_type::construct( p, value ); -} -void destroy( pointer p ){ - allocator_type::destroy( p ); -} - -template -bool operator==( const NamedAllocator& other ){ - return true; -} - -// returns true if the allocators are not interchangeable -template -bool operator!=( const NamedAllocator& other ){ - return false; -} -}; - - - -#include -#include "generic/object.h" - - - -template -class DefaultConstruct -{ -public: -void operator()( Type& t ){ - constructor( t ); -} -}; - -template -class Construct -{ -const T1& other; -public: -Construct( const T1& other_ ) : other( other_ ){ -} -void operator()( Type& t ){ - constructor( t, other ); -} -}; - -template -class Destroy -{ -public: -void operator()( Type& t ){ - destructor( t ); -} -}; - -template > -class New : public Allocator -{ -public: -New(){ -} -explicit New( const Allocator& allocator ) : Allocator( allocator ){ -} - -Type* scalar(){ - return new( Allocator::allocate( 1 ) )Type(); -} -template -Type* scalar( const T1& t1 ){ - return new( Allocator::allocate( 1 ) )Type( t1 ); -} -template -Type* scalar( const T1& t1, const T2& t2 ){ - return new( Allocator::allocate( 1 ) )Type( t1, t2 ); -} -template -Type* scalar( const T1& t1, const T2& t2, const T3& t3 ){ - return new( Allocator::allocate( 1 ) )Type( t1, t2, t3 ); -} -template -Type* scalar( const T1& t1, const T2& t2, const T3& t3, const T4& t4 ){ - return new( Allocator::allocate( 1 ) )Type( t1, t2, t3, t4 ); -} -template -Type* scalar( const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5 ){ - return new( Allocator::allocate( 1 ) )Type( t1, t2, t3, t4, t5 ); -} -Type* vector( std::size_t size ){ -#if 1 - Type* p = Allocator::allocate( size ); - std::for_each( p, p + size, DefaultConstruct() ); - return p; -#else - // this does not work with msvc71 runtime - return new( Allocator::allocate( size ) )Type[size]; -#endif -} -template -Type* vector( std::size_t size, const T1& t1 ){ - Type* p = Allocator::allocate( size ); - std::for_each( p, p + size, Construct( t1 ) ); - return p; -} -}; - -template > -class Delete : public Allocator -{ -public: -Delete(){ -} -explicit Delete( const Allocator& allocator ) : Allocator( allocator ){ -} - -void scalar( Type* p ){ - if ( p != 0 ) { - p->~Type(); - Allocator::deallocate( p, 1 ); - } -} -void vector( Type* p, std::size_t size ){ - // '::operator delete' handles null - // 'std::allocator::deallocate' requires non-null - if ( p != 0 ) { - std::for_each( p, p + size, Destroy() ); - Allocator::deallocate( p, size ); - } -} -}; - - -template -class NamedNew -{ -public: -typedef New > type; -}; - -template -class NamedDelete -{ -public: -typedef Delete > type; -}; - -#endif diff --git a/libs/moduleobservers.h b/libs/moduleobservers.h deleted file mode 100644 index 1ee91e2..0000000 --- a/libs/moduleobservers.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODULEOBSERVERS_H ) -#define INCLUDED_MODULEOBSERVERS_H - -#include "debugging/debugging.h" -#include -#include "moduleobserver.h" - -class ModuleObservers -{ -typedef std::set Observers; -Observers m_observers; -public: -~ModuleObservers(){ - ASSERT_MESSAGE( m_observers.empty(), "ModuleObservers::~ModuleObservers: observers still attached" ); -} -void attach( ModuleObserver& observer ){ - ASSERT_MESSAGE( m_observers.find( &observer ) == m_observers.end(), "ModuleObservers::attach: cannot attach observer" ); - m_observers.insert( &observer ); -} -void detach( ModuleObserver& observer ){ - ASSERT_MESSAGE( m_observers.find( &observer ) != m_observers.end(), "ModuleObservers::detach: cannot detach observer" ); - m_observers.erase( &observer ); -} -void realise(){ - for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) - { - ( *i )->realise(); - } -} -void unrealise(){ - for ( Observers::reverse_iterator i = m_observers.rbegin(); i != m_observers.rend(); ++i ) - { - ( *i )->unrealise(); - } -} -}; - -#endif diff --git a/libs/modulesystem/Makefile b/libs/modulesystem/Makefile deleted file mode 100644 index 0eb7f27..0000000 --- a/libs/modulesystem/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - singletonmodule.o - -# binary target -../libmodulesystem.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -singletonmodule.o: singletonmodule.cpp singletonmodule.h moduleregistry.h modulesmap.h - -clean: - -rm -f *.o ../libmodulesystem.a diff --git a/libs/modulesystem/moduleregistry.h b/libs/modulesystem/moduleregistry.h deleted file mode 100644 index abea5a0..0000000 --- a/libs/modulesystem/moduleregistry.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODULESYSTEM_MODULEREGISTRY_H ) -#define INCLUDED_MODULESYSTEM_MODULEREGISTRY_H - -#include "generic/static.h" -#include - -class ModuleRegisterable -{ -public: -virtual void selfRegister() = 0; -}; - -class ModuleRegistryList -{ -typedef std::list RegisterableModules; -RegisterableModules m_modules; -public: -void addModule( ModuleRegisterable& module ){ - m_modules.push_back( &module ); -} -void registerModules() const { - for ( RegisterableModules::const_iterator i = m_modules.begin(); i != m_modules.end(); ++i ) - { - ( *i )->selfRegister(); - } -} -}; - -typedef SmartStatic StaticModuleRegistryList; - - -class StaticRegisterModule : public StaticModuleRegistryList -{ -public: -StaticRegisterModule( ModuleRegisterable& module ){ - StaticModuleRegistryList::instance().addModule( module ); -} -}; - - -#endif diff --git a/libs/modulesystem/modulesmap.h b/libs/modulesystem/modulesmap.h deleted file mode 100644 index a48a083..0000000 --- a/libs/modulesystem/modulesmap.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODULESYSTEM_MODULESMAP_H ) -#define INCLUDED_MODULESYSTEM_MODULESMAP_H - -#include "modulesystem.h" -#include "string/string.h" -#include -#include - -template -class ModulesMap : public Modules -{ -typedef std::map modules_t; -modules_t m_modules; -public: -~ModulesMap(){ - for ( modules_t::iterator i = m_modules.begin(); i != m_modules.end(); ++i ) - { - ( *i ).second->release(); - } -} - -typedef modules_t::const_iterator iterator; - -iterator begin() const { - return m_modules.begin(); -} -iterator end() const { - return m_modules.end(); -} - -void insert( const char* name, Module& module ){ - module.capture(); - if ( globalModuleServer().getError() ) { - module.release(); - globalModuleServer().setError( false ); - } - else - { - m_modules.insert( modules_t::value_type( name, &module ) ); - } -} - -Type* find( const char* name ){ - modules_t::iterator i = m_modules.find( name ); - if ( i != m_modules.end() ) { - return static_cast( Module_getTable( *( *i ).second ) ); - } - return 0; -} - -Type* findModule( const char* name ){ - return find( name ); -} -void foreachModule( const typename Modules::Visitor& visitor ){ - for ( modules_t::iterator i = m_modules.begin(); i != m_modules.end(); ++i ) - { - visitor.visit( ( *i ).first.c_str(), *static_cast( Module_getTable( *( *i ).second ) ) ); - } -} -}; - -template -class InsertModules : public ModuleServer::Visitor -{ -ModulesMap& m_modules; -public: -InsertModules( ModulesMap& modules ) - : m_modules( modules ){ -} -void visit( const char* name, Module& module ) const { - m_modules.insert( name, module ); -} -}; - -template -class ModulesRef -{ -ModulesMap m_modules; -public: -ModulesRef( const char* names ){ - if ( !globalModuleServer().getError() ) { - if ( string_equal( names, "*" ) ) { - InsertModules visitor( m_modules ); - globalModuleServer().foreachModule( typename Type::Name(), typename Type::Version(), visitor ); - } - else - { - StringTokeniser tokeniser( names ); - for (;; ) - { - const char* name = tokeniser.getToken(); - if ( string_empty( name ) ) { - break; - } - Module* module = globalModuleServer().findModule( typename Type::Name(), typename Type::Version(), name ); - if ( module == 0 ) { - globalModuleServer().setError( true ); - globalErrorStream() << "ModulesRef::initialise: type=" << makeQuoted( typename Type::Name() ) << " version=" << makeQuoted( typename Type::Version() ) << " name=" << makeQuoted( name ) << " - not found\n"; - break; - } - else - { - m_modules.insert( name, *module ); - } - } - } - } -} -ModulesMap& get(){ - return m_modules; -} -}; - -#endif diff --git a/libs/modulesystem/singletonmodule.cpp b/libs/modulesystem/singletonmodule.cpp deleted file mode 100644 index 207051a..0000000 --- a/libs/modulesystem/singletonmodule.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "singletonmodule.h" -#include "generic/constant.h" - -class NullType -{ -public: -INTEGER_CONSTANT( Version, 1 ); -STRING_CONSTANT( Name, "" ); -}; - -class NullModule -{ -public: -typedef NullType Type; -STRING_CONSTANT( Name, "" ); -void* getTable(){ - return NULL; -} -}; - -void TEST_SINGLETONMODULE(){ - SingletonModule null; - null.capture(); - null.release(); -} diff --git a/libs/modulesystem/singletonmodule.h b/libs/modulesystem/singletonmodule.h deleted file mode 100644 index 6dd9c52..0000000 --- a/libs/modulesystem/singletonmodule.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODULESYSTEM_SINGLETONMODULE_H ) -#define INCLUDED_MODULESYSTEM_SINGLETONMODULE_H - -#include "modulesystem.h" -#include -#include "debugging/debugging.h" -#include "modulesystem/moduleregistry.h" -#include "generic/reference.h" - -template -class DefaultAPIConstructor -{ -public: -const char* getName(){ - return typename API::Name(); -} - -API* constructAPI( Dependencies& dependencies ){ - return new API; -} -void destroyAPI( API* api ){ - delete api; -} -}; - -template -class DependenciesAPIConstructor -{ -public: -const char* getName(){ - return typename API::Name(); -} - -API* constructAPI( Dependencies& dependencies ){ - return new API( dependencies ); -} -void destroyAPI( API* api ){ - delete api; -} -}; - -class NullDependencies -{ -}; - - -template > -class SingletonModule : public APIConstructor, public Module, public ModuleRegisterable -{ -Dependencies* m_dependencies; -API* m_api; -std::size_t m_refcount; -bool m_dependencyCheck; -bool m_cycleCheck; -public: -typedef typename API::Type Type; - -SingletonModule() - : m_dependencies( 0 ), m_api( 0 ), m_refcount( 0 ), m_dependencyCheck( false ), m_cycleCheck( false ){ -} -explicit SingletonModule( const APIConstructor& constructor ) - : APIConstructor( constructor ), m_dependencies( 0 ), m_api( 0 ), m_refcount( 0 ), m_dependencyCheck( false ), m_cycleCheck( false ){ -} -~SingletonModule(){ - ASSERT_MESSAGE( m_refcount == 0, "module still referenced at shutdown" ); -} - -void selfRegister(){ - globalModuleServer().registerModule( typename Type::Name(), typename Type::Version(), APIConstructor::getName(), *this ); -} - -Dependencies& getDependencies(){ - return *m_dependencies; -} -void* getTable(){ - if ( m_api != 0 ) { - return m_api->getTable(); - } - return 0; -} -void capture(){ - if ( ++m_refcount == 1 ) { - globalOutputStream() << "Module Initialising: '" << typename Type::Name() << "' '" << APIConstructor::getName() << "'\n"; - m_dependencies = new Dependencies(); - m_dependencyCheck = !globalModuleServer().getError(); - if ( m_dependencyCheck ) { - m_api = APIConstructor::constructAPI( *m_dependencies ); - globalOutputStream() << "Module Ready: '" << typename Type::Name() << "' '" << APIConstructor::getName() << "'\n"; - } - else - { - globalOutputStream() << "Module Dependencies Failed: '" << typename Type::Name() << "' '" << APIConstructor::getName() << "'\n"; - } - m_cycleCheck = true; - } - - ASSERT_MESSAGE( m_cycleCheck, "cyclic dependency detected" ); -} -void release(){ - if ( --m_refcount == 0 ) { - if ( m_dependencyCheck ) { - APIConstructor::destroyAPI( m_api ); - } - delete m_dependencies; - } -} -}; - - -#endif diff --git a/libs/os/Makefile b/libs/os/Makefile deleted file mode 100644 index 473f1cc..0000000 --- a/libs/os/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ -_.o - -# binary target -../libos.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -_.o: _.cpp dir.h file.h path.h - -clean: - -rm -f *.o ../libos.a diff --git a/libs/os/_.cpp b/libs/os/_.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/libs/os/dir.h b/libs/os/dir.h deleted file mode 100644 index b199284..0000000 --- a/libs/os/dir.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_OS_DIR_H ) -#define INCLUDED_OS_DIR_H - -/// \file -/// \brief OS directory-listing object. - -#include - -typedef GDir Directory; - -inline bool directory_good( Directory* directory ){ - return directory != 0; -} - -inline Directory* directory_open( const char* name ){ - return g_dir_open( name, 0, 0 ); -} - -inline void directory_close( Directory* directory ){ - g_dir_close( directory ); -} - -inline const char* directory_read_and_increment( Directory* directory ){ - return g_dir_read_name( directory ); -} - -template -void Directory_forEach( const char* path, const Functor& functor ){ - Directory* dir = directory_open( path ); - - if ( directory_good( dir ) ) { - for (;; ) - { - const char* name = directory_read_and_increment( dir ); - if ( name == 0 ) { - break; - } - - functor( name ); - } - - directory_close( dir ); - } -} - - -#endif diff --git a/libs/os/file.h b/libs/os/file.h deleted file mode 100644 index 144627e..0000000 --- a/libs/os/file.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_OS_FILE_H ) -#define INCLUDED_OS_FILE_H - -#include "globaldefs.h" - -/// \file -/// \brief OS file-system querying and manipulation. - -#if GDEF_OS_WINDOWS -#define S_ISDIR( mode ) ( mode & _S_IFDIR ) -#include // _access() -#define access( path, mode ) _access( path, mode ) -#else -#include // access() -#endif - -#include // rename(), remove() -#include // stat() -#include // this is included by stat.h on win32 -#include -#include - -#include "debugging/debugging.h" - -/// \brief Attempts to move the file identified by \p from to \p to and returns true if the operation was successful. -/// -/// The operation will fail unless: -/// - The path \p from identifies an existing file which is accessible for writing. -/// - The directory component of \p from identifies an existing directory which is accessible for writing. -/// - The path \p to does not identify an existing file or directory. -/// - The directory component of \p to identifies an existing directory which is accessible for writing. -inline bool file_move( const char* from, const char* to ){ - ASSERT_MESSAGE( from != 0 && to != 0, "file_move: invalid path" ); - return rename( from, to ) == 0; -} - -/// \brief Attempts to remove the file identified by \p path and returns true if the operation was successful. -/// -/// The operation will fail unless: -/// - The \p path identifies an existing file. -/// - The parent-directory component of \p path identifies an existing directory which is accessible for writing. -inline bool file_remove( const char* path ){ - ASSERT_MESSAGE( path != 0, "file_remove: invalid path" ); - return remove( path ) == 0; -} - -namespace FileAccess -{ -enum Mode -{ - Read = R_OK, - Write = W_OK, - ReadWrite = Read | Write, - Exists = F_OK -}; -} - -/// \brief Returns true if the file or directory identified by \p path exists and/or may be accessed for reading, writing or both, depending on the value of \p mode. -inline bool file_accessible( const char* path, FileAccess::Mode mode ){ - ASSERT_MESSAGE( path != 0, "file_accessible: invalid path" ); - return access( path, static_cast( mode ) ) == 0; -} - -/// \brief Returns true if the file or directory identified by \p path exists and may be opened for reading. -inline bool file_readable( const char* path ){ - return file_accessible( path, FileAccess::Read ); -} - -/// \brief Returns true if the file or directory identified by \p path exists and may be opened for writing. -inline bool file_writeable( const char* path ){ - return file_accessible( path, FileAccess::Write ); -} - -/// \brief Returns true if the file or directory identified by \p path exists. -inline bool file_exists( const char* path ){ - return file_accessible( path, FileAccess::Exists ); -} - -/// \brief Returns true if the file or directory identified by \p path exists and is a directory. -inline bool file_is_directory( const char* path ){ - ASSERT_MESSAGE( path != 0, "file_is_directory: invalid path" ); - struct stat st; - if ( stat( path, &st ) == -1 ) { - return false; - } - return S_ISDIR( st.st_mode ) != 0; -} - -typedef std::size_t FileSize; - -/// \brief Returns the size in bytes of the file identified by \p path, or 0 if the file was not found. -inline FileSize file_size( const char* path ){ - ASSERT_MESSAGE( path != 0, "file_size: invalid path" ); - struct stat st; - if ( stat( path, &st ) == -1 ) { - return 0; - } - return st.st_size; -} - -/// Seconds elapsed since Jan 1, 1970 -typedef std::time_t FileTime; -/// No file can have been modified earlier than this time. -const FileTime c_invalidFileTime = -1; - -/// \brief Returns the time that the file identified by \p path was last modified, or c_invalidFileTime if the file was not found. -inline FileTime file_modified( const char* path ){ - ASSERT_MESSAGE( path != 0, "file_modified: invalid path" ); - struct stat st; - if ( stat( path, &st ) == -1 ) { - return c_invalidFileTime; - } - return st.st_mtime; -} - - - -#endif diff --git a/libs/os/path.h b/libs/os/path.h deleted file mode 100644 index 5b87a4d..0000000 --- a/libs/os/path.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_OS_PATH_H ) -#define INCLUDED_OS_PATH_H - -#include "globaldefs.h" - -/// \file -/// \brief OS file-system path comparison, decomposition and manipulation. -/// -/// - Paths are c-style null-terminated-character-arrays. -/// - Path separators must be forward slashes (unix style). -/// - Directory paths must end in a separator. -/// - Paths must not contain the ascii characters \\ : * ? " < > or |. -/// - Paths may be encoded in UTF-8 or any extended-ascii character set. - -#include "string/string.h" - -#if GDEF_OS_WINDOWS -#define OS_CASE_INSENSITIVE -#endif - -/// \brief Returns true if \p path is lexicographically sorted before \p other. -/// If both \p path and \p other refer to the same file, neither will be sorted before the other. -/// O(n) -inline bool path_less( const char* path, const char* other ){ -#if defined( OS_CASE_INSENSITIVE ) - return string_less_nocase( path, other ); -#else - return string_less( path, other ); -#endif -} - -/// \brief Returns <0 if \p path is lexicographically less than \p other. -/// Returns >0 if \p path is lexicographically greater than \p other. -/// Returns 0 if both \p path and \p other refer to the same file. -/// O(n) -inline int path_compare( const char* path, const char* other ){ -#if defined( OS_CASE_INSENSITIVE ) - return string_compare_nocase( path, other ); -#else - return string_compare( path, other ); -#endif -} - -/// \brief Returns true if \p path and \p other refer to the same file or directory. -/// O(n) -inline bool path_equal( const char* path, const char* other ){ -#if defined( OS_CASE_INSENSITIVE ) - return string_equal_nocase( path, other ); -#else - return string_equal( path, other ); -#endif -} - -/// \brief Returns true if \p path and \p other refer to the same file or directory, case insensitively. -/// O(n) -inline bool path_equal_i( const char* path, const char* other ){ - return string_equal_nocase( path, other ); -} - -/// \brief Returns true if the first \p n bytes of \p path and \p other form paths that refer to the same file or directory. -/// If the paths are UTF-8 encoded, [\p path, \p path + \p n) must be a complete path. -/// O(n) -inline bool path_equal_n( const char* path, const char* other, std::size_t n ){ -#if defined( OS_CASE_INSENSITIVE ) - return string_equal_nocase_n( path, other, n ); -#else - return string_equal_n( path, other, n ); -#endif -} - - -/// \brief Returns true if \p path is a fully qualified file-system path. -/// O(1) -inline bool path_is_absolute( const char* path ){ -#if GDEF_OS_WINDOWS - return path[0] == '/' - || ( path[0] != '\0' && path[1] == ':' ); // local drive -#elif GDEF_OS_POSIX - return path[0] == '/'; -#endif -} - -/// \brief Returns true if \p path is a directory. -/// O(n) -inline bool path_is_directory( const char* path ){ - std::size_t length = strlen( path ); - if ( length > 0 ) { - return path[length - 1] == '/'; - } - return false; -} - -/// \brief Returns a pointer to the first character of the component of \p path following the first directory component. -/// O(n) -inline const char* path_remove_directory( const char* path ){ - const char* first_separator = strchr( path, '/' ); - if ( first_separator != 0 ) { - return ++first_separator; - } - return ""; -} - -/// \brief Returns a pointer to the first character of the filename component of \p path. -/// O(n) -inline const char* path_get_filename_start( const char* path ){ - { - const char* last_forward_slash = strrchr( path, '/' ); - if ( last_forward_slash != 0 ) { - return last_forward_slash + 1; - } - } - - // not strictly necessary,since paths should not contain '\' - { - const char* last_backward_slash = strrchr( path, '\\' ); - if ( last_backward_slash != 0 ) { - return last_backward_slash + 1; - } - } - - return path; -} - -/// \brief Returns a pointer to the character after the end of the filename component of \p path - either the extension separator or the terminating null character. -/// O(n) -inline const char* path_get_filename_base_end( const char* path ){ - const char* last_period = strrchr( path_get_filename_start( path ), '.' ); - return ( last_period != 0 ) ? last_period : path + string_length( path ); -} - -/// \brief Returns the length of the filename component (not including extension) of \p path. -/// O(n) -inline std::size_t path_get_filename_base_length( const char* path ){ - return path_get_filename_base_end( path ) - path; -} - -/// \brief If \p path is a child of \p base, returns the subpath relative to \p base, else returns \p path. -/// O(n) -inline const char* path_make_relative( const char* path, const char* base ){ - const std::size_t length = string_length( base ); - if ( path_equal_n( path, base, length ) ) { - return path + length; - } - return path; -} - -/// \brief Returns a pointer to the first character of the file extension of \p path, or "" if not found. -/// O(n) -inline const char* path_get_extension( const char* path ){ - const char* last_period = strrchr( path_get_filename_start( path ), '.' ); - if ( last_period != 0 ) { - return ++last_period; - } - return ""; -} - -/// \brief Returns true if \p extension is of the same type as \p other. -/// O(n) -inline bool extension_equal( const char* extension, const char* other ){ - return path_equal( extension, other ); -} - -/// \brief Returns true if \p extension is of the same type as \p other, case insensitively. -/// O(n) -inline bool extension_equal_i( const char* extension, const char* other ){ - return path_equal_i( extension, other ); -} - -template -class MatchFileExtension -{ -const char* m_extension; -const Functor& m_functor; -public: -MatchFileExtension( const char* extension, const Functor& functor ) : m_extension( extension ), m_functor( functor ){ -} -void operator()( const char* name ) const { - const char* extension = path_get_extension( name ); - if ( extension_equal( extension, m_extension ) ) { - m_functor( name ); - } -} -}; - -/// \brief A functor which invokes its contained \p functor if the \p name argument matches its \p extension. -template -inline MatchFileExtension matchFileExtension( const char* extension, const Functor& functor ){ - return MatchFileExtension( extension, functor ); -} - -class PathCleaned -{ -public: -const char* m_path; -PathCleaned( const char* path ) : m_path( path ){ -} -}; - -/// \brief Writes \p path to \p ostream with dos-style separators replaced by unix-style separators. -template -TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const PathCleaned& path ){ - const char* i = path.m_path; - for (; *i != '\0'; ++i ) - { - if ( *i == '\\' ) { - ostream << '/'; - } - else - { - ostream << *i; - } - } - return ostream; -} - -class DirectoryCleaned -{ -public: -const char* m_path; -DirectoryCleaned( const char* path ) : m_path( path ){ -} -}; - -/// \brief Writes \p path to \p ostream with dos-style separators replaced by unix-style separators, and appends a separator if necessary. -template -TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const DirectoryCleaned& path ){ - const char* i = path.m_path; - for (; *i != '\0'; ++i ) - { - if ( *i == '\\' ) { - ostream << '/'; - } - else - { - ostream << *i; - } - } - char c = *( i - 1 ); - if ( c != '/' && c != '\\' ) { - ostream << '/'; - } - return ostream; -} - - -#endif diff --git a/libs/pivot.h b/libs/pivot.h deleted file mode 100644 index 93cb354..0000000 --- a/libs/pivot.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PIVOT_H ) -#define INCLUDED_PIVOT_H - -#include "math/matrix.h" - - -inline void billboard_viewplaneOriented( Matrix4& rotation, const Matrix4& world2screen ){ -#if 1 - rotation = g_matrix4_identity; - Vector3 x( vector3_normalised( vector4_to_vector3( world2screen.x() ) ) ); - Vector3 y( vector3_normalised( vector4_to_vector3( world2screen.y() ) ) ); - Vector3 z( vector3_normalised( vector4_to_vector3( world2screen.z() ) ) ); - vector4_to_vector3( rotation.y() ) = Vector3( x.y(), y.y(), z.y() ); - vector4_to_vector3( rotation.z() ) = vector3_negated( Vector3( x.z(), y.z(), z.z() ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); -#else - Matrix4 screen2world( matrix4_full_inverse( world2screen ) ); - - Vector3 near_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( 0, 0, -1, 1 ) - ) - ) - ); - - Vector3 far_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( 0, 0, 1, 1 ) - ) - ) - ); - - Vector3 up( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( 0, 1, -1, 1 ) - ) - ) - ); - - rotation = g_matrix4_identity; - vector4_to_vector3( rotation.y() ) = vector3_normalised( vector3_subtracted( up, near_ ) ); - vector4_to_vector3( rotation.z() ) = vector3_normalised( vector3_subtracted( near_, far_ ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); -#endif -} - -inline void billboard_viewpointOriented( Matrix4& rotation, const Matrix4& world2screen ){ - Matrix4 screen2world( matrix4_full_inverse( world2screen ) ); - -#if 1 - rotation = g_matrix4_identity; - vector4_to_vector3( rotation.y() ) = vector3_normalised( vector4_to_vector3( screen2world.y() ) ); - vector4_to_vector3( rotation.z() ) = vector3_negated( vector3_normalised( vector4_to_vector3( screen2world.z() ) ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); -#else - Vector3 near_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( world2screen[12] / world2screen[15], world2screen[13] / world2screen[15], -1, 1 ) - ) - ) - ); - - Vector3 far_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( world2screen[12] / world2screen[15], world2screen[13] / world2screen[15], 1, 1 ) - ) - ) - ); - - Vector3 up( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4( world2screen[12] / world2screen[15], world2screen[13] / world2screen[15] + 1, -1, 1 ) - ) - ) - ); - - rotation = g_matrix4_identity; - vector4_to_vector3( rotation.y() ) = vector3_normalised( vector3_subtracted( up, near_ ) ); - vector4_to_vector3( rotation.z() ) = vector3_normalised( vector3_subtracted( near_, far_ ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); -#endif -} - - -inline void ConstructObject2Screen( Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device, const Matrix4& device2screen ){ - object2screen = device2screen; - matrix4_multiply_by_matrix4( object2screen, view2device ); - matrix4_multiply_by_matrix4( object2screen, world2view ); - matrix4_multiply_by_matrix4( object2screen, object2world ); -} - -inline void ConstructObject2Device( Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device ){ - object2screen = view2device; - matrix4_multiply_by_matrix4( object2screen, world2view ); - matrix4_multiply_by_matrix4( object2screen, object2world ); -} - -inline void ConstructDevice2Object( Matrix4& device2object, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device ){ - ConstructObject2Device( device2object, object2world, world2view, view2device ); - matrix4_full_invert( device2object ); -} - -//! S = ( Inverse(Object2Screen *post ScaleOf(Object2Screen) ) *post Object2Screen -inline void pivot_scale( Matrix4& scale, const Matrix4& pivot2screen ){ - Matrix4 pre_scale( g_matrix4_identity ); - pre_scale[0] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.x() ) ) ); - pre_scale[5] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.y() ) ) ); - pre_scale[10] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.z() ) ) ); - - scale = pivot2screen; - matrix4_multiply_by_matrix4( scale, pre_scale ); - matrix4_full_invert( scale ); - matrix4_multiply_by_matrix4( scale, pivot2screen ); -} - -// scale by (inverse) W -inline void pivot_perspective( Matrix4& scale, const Matrix4& pivot2screen ){ - scale = g_matrix4_identity; - scale[0] = scale[5] = scale[10] = pivot2screen[15]; -} - -inline void ConstructDevice2Manip( Matrix4& device2manip, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device, const Matrix4& device2screen ){ - Matrix4 pivot2screen; - ConstructObject2Screen( pivot2screen, object2world, world2view, view2device, device2screen ); - - ConstructObject2Device( device2manip, object2world, world2view, view2device ); - - Matrix4 scale; - pivot_scale( scale, pivot2screen ); - matrix4_multiply_by_matrix4( device2manip, scale ); - pivot_perspective( scale, pivot2screen ); - matrix4_multiply_by_matrix4( device2manip, scale ); - - matrix4_full_invert( device2manip ); -} - -inline void Pivot2World_worldSpace( Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){ - manip2world = pivot2world; - - Matrix4 pivot2screen; - ConstructObject2Screen( pivot2screen, pivot2world, modelview, projection, viewport ); - - Matrix4 scale; - pivot_scale( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); - pivot_perspective( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); -} - -inline void Pivot2World_viewpointSpace( Matrix4& manip2world, Vector3& axis, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){ - manip2world = pivot2world; - - Matrix4 pivot2screen; - ConstructObject2Screen( pivot2screen, pivot2world, modelview, projection, viewport ); - - Matrix4 scale; - pivot_scale( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); - - billboard_viewpointOriented( scale, pivot2screen ); - axis = vector4_to_vector3( scale.z() ); - matrix4_multiply_by_matrix4( manip2world, scale ); - - pivot_perspective( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); -} - -inline void Pivot2World_viewplaneSpace( Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){ - manip2world = pivot2world; - - Matrix4 pivot2screen; - ConstructObject2Screen( pivot2screen, pivot2world, modelview, projection, viewport ); - - Matrix4 scale; - pivot_scale( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); - - billboard_viewplaneOriented( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); - - pivot_perspective( scale, pivot2screen ); - matrix4_multiply_by_matrix4( manip2world, scale ); -} - - -#include "renderable.h" -#include "cullable.h" -#include "render.h" - -const Colour4b g_colour_x( 255, 0, 0, 255 ); -const Colour4b g_colour_y( 0, 255, 0, 255 ); -const Colour4b g_colour_z( 0, 0, 255, 255 ); - -class Shader; - -class RenderablePivot : public OpenGLRenderable -{ -VertexBuffer m_vertices; -public: -mutable Matrix4 m_localToWorld; -typedef Static StaticShader; -static Shader* getShader(){ - return StaticShader::instance(); -} - -RenderablePivot(){ - m_vertices.reserve( 6 ); - - m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 0 ), g_colour_x ) ); - m_vertices.push_back( PointVertex( Vertex3f( 16, 0, 0 ), g_colour_x ) ); - - m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 0 ), g_colour_y ) ); - m_vertices.push_back( PointVertex( Vertex3f( 0, 16, 0 ), g_colour_y ) ); - - m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 0 ), g_colour_z ) ); - m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 16 ), g_colour_z ) ); -} - -void render( RenderStateFlags state ) const { - if ( m_vertices.size() == 0 ) { - return; - } - if ( m_vertices.data() == 0 ) { - return; - } - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); - glDrawArrays( GL_LINES, 0, m_vertices.size() ); -} - -void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const { - renderer.PushState(); - - Pivot2World_worldSpace( m_localToWorld, localToWorld, volume.GetModelview(), volume.GetProjection(), volume.GetViewport() ); - - renderer.Highlight( Renderer::ePrimitive, false ); - renderer.SetState( getShader(), Renderer::eWireframeOnly ); - renderer.SetState( getShader(), Renderer::eFullMaterials ); - renderer.addRenderable( *this, m_localToWorld ); - - renderer.PopState(); -} -}; - - - -#endif diff --git a/libs/profile/Makefile b/libs/profile/Makefile deleted file mode 100644 index edb08e3..0000000 --- a/libs/profile/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - file.o profile.o - -# binary target -../libprofile.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -file.o: file.cpp file.h -profile.o: profile.cpp profile.h - -clean: - -rm -f *.o ../libprofile.a diff --git a/libs/profile/file.cpp b/libs/profile/file.cpp deleted file mode 100644 index 9f83393..0000000 --- a/libs/profile/file.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// File class, can be a memory file or a regular disk file. -// Originally from LeoCAD, used with permission from the author. :) -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "file.h" - -#include -#include -#include -#include - -///////////////////////////////////////////////////////////////////////////// -// File construction/destruction - -MemStream::MemStream(){ - m_nGrowBytes = 1024; - m_nPosition = 0; - m_nBufferSize = 0; - m_nFileSize = 0; - m_pBuffer = NULL; - m_bAutoDelete = true; -} - -MemStream::MemStream( size_type nLen ){ - m_nGrowBytes = 1024; - m_nPosition = 0; - m_nBufferSize = 0; - m_nFileSize = 0; - m_pBuffer = NULL; - m_bAutoDelete = true; - - GrowFile( nLen ); -} - -FileStream::FileStream(){ - m_hFile = NULL; - m_bCloseOnDelete = false; -} - -MemStream::~MemStream(){ - if ( m_pBuffer ) { - Close(); - } - - m_nGrowBytes = 0; - m_nPosition = 0; - m_nBufferSize = 0; - m_nFileSize = 0; -} - -FileStream::~FileStream(){ - if ( m_hFile != NULL && m_bCloseOnDelete ) { - Close(); - } -} - -///////////////////////////////////////////////////////////////////////////// -// File operations - -char* MemStream::ReadString( char* pBuf, size_type nMax ){ - int nRead = 0; - unsigned char ch; - - if ( nMax <= 0 ) { - return NULL; - } - if ( m_nPosition >= m_nFileSize ) { - return NULL; - } - - while ( ( --nMax ) ) - { - if ( m_nPosition == m_nFileSize ) { - break; - } - - ch = m_pBuffer[m_nPosition]; - m_nPosition++; - pBuf[nRead++] = ch; - - if ( ch == '\n' ) { - break; - } - } - - pBuf[nRead] = '\0'; - return pBuf; -} - -char* FileStream::ReadString( char* pBuf, size_type nMax ){ - return fgets( pBuf, static_cast( nMax ), m_hFile ); -} - -MemStream::size_type MemStream::read( byte_type* buffer, size_type length ){ - if ( length == 0 ) { - return 0; - } - - if ( m_nPosition > m_nFileSize ) { - return 0; - } - - size_type nRead; - if ( m_nPosition + length > m_nFileSize ) { - nRead = m_nFileSize - m_nPosition; - } - else{ - nRead = length; - } - - memcpy( (unsigned char*)buffer, (unsigned char*)m_pBuffer + m_nPosition, nRead ); - m_nPosition += nRead; - - return nRead; -} - -FileStream::size_type FileStream::read( byte_type* buffer, size_type length ){ - return fread( buffer, 1, length, m_hFile ); -} - -int MemStream::GetChar(){ - if ( m_nPosition > m_nFileSize ) { - return 0; - } - - unsigned char* ret = (unsigned char*)m_pBuffer + m_nPosition; - m_nPosition++; - - return *ret; -} - -int FileStream::GetChar(){ - return fgetc( m_hFile ); -} - -MemStream::size_type MemStream::write( const byte_type* buffer, size_type length ){ - if ( length == 0 ) { - return 0; - } - - if ( m_nPosition + length > m_nBufferSize ) { - GrowFile( m_nPosition + length ); - } - - memcpy( (unsigned char*)m_pBuffer + m_nPosition, (unsigned char*)buffer, length ); - - m_nPosition += size_type( length ); - - if ( m_nPosition > m_nFileSize ) { - m_nFileSize = m_nPosition; - } - - return length; -} - -FileStream::size_type FileStream::write( const byte_type* buffer, size_type length ){ - return fwrite( buffer, 1, length, m_hFile ); -} - -int MemStream::PutChar( int c ){ - if ( m_nPosition + 1 > m_nBufferSize ) { - GrowFile( m_nPosition + 1 ); - } - - unsigned char* bt = (unsigned char*)m_pBuffer + m_nPosition; - *bt = c; - - m_nPosition++; - - if ( m_nPosition > m_nFileSize ) { - m_nFileSize = m_nPosition; - } - - return 1; -} - -/*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */ -void FileStream::printf( const char* s, ... ){ - va_list args; - - va_start( args, s ); - vfprintf( m_hFile, s, args ); - va_end( args ); -} - -/*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */ -void MemStream::printf( const char* s, ... ){ - va_list args; - - char buffer[4096]; - va_start( args, s ); - vsprintf( buffer, s, args ); - va_end( args ); - write( reinterpret_cast( buffer ), strlen( buffer ) ); -} - -int FileStream::PutChar( int c ){ - return fputc( c, m_hFile ); -} - -bool FileStream::Open( const char *filename, const char *mode ){ - m_hFile = fopen( filename, mode ); - m_bCloseOnDelete = true; - - return ( m_hFile != NULL ); -} - -void MemStream::Close(){ - m_nGrowBytes = 0; - m_nPosition = 0; - m_nBufferSize = 0; - m_nFileSize = 0; - if ( m_pBuffer && m_bAutoDelete ) { - free( m_pBuffer ); - } - m_pBuffer = NULL; -} - -void FileStream::Close(){ - if ( m_hFile != NULL ) { - fclose( m_hFile ); - } - - m_hFile = NULL; - m_bCloseOnDelete = false; -} - -int MemStream::Seek( offset_type lOff, int nFrom ){ - size_type lNewPos = m_nPosition; - - if ( nFrom == SEEK_SET ) { - lNewPos = lOff; - } - else if ( nFrom == SEEK_CUR ) { - lNewPos += lOff; - } - else if ( nFrom == SEEK_END ) { - lNewPos = m_nFileSize + lOff; - } - else{ - return -1; - } - - m_nPosition = lNewPos; - - return static_cast( m_nPosition ); -} - -int FileStream::Seek( offset_type lOff, int nFrom ){ - fseek( m_hFile, lOff, nFrom ); - - return ftell( m_hFile ); -} - -MemStream::position_type MemStream::GetPosition() const { - return m_nPosition; -} - -FileStream::position_type FileStream::GetPosition() const { - return ftell( m_hFile ); -} - -void MemStream::GrowFile( size_type nNewLen ){ - if ( nNewLen > m_nBufferSize ) { - // grow the buffer - size_type nNewBufferSize = m_nBufferSize; - - // determine new buffer size - while ( nNewBufferSize < nNewLen ) - nNewBufferSize += m_nGrowBytes; - - // allocate new buffer - unsigned char* lpNew; - if ( m_pBuffer == NULL ) { - lpNew = static_cast( malloc( nNewBufferSize ) ); - } - else{ - lpNew = static_cast( realloc( m_pBuffer, nNewBufferSize ) ); - } - - m_pBuffer = lpNew; - m_nBufferSize = nNewBufferSize; - } -} - -void MemStream::Flush(){ - // Nothing to be done -} - -void FileStream::Flush(){ - if ( m_hFile == NULL ) { - return; - } - - fflush( m_hFile ); -} - -void MemStream::Abort(){ - Close(); -} - -void FileStream::Abort(){ - if ( m_hFile != NULL ) { - // close but ignore errors - if ( m_bCloseOnDelete ) { - fclose( m_hFile ); - } - m_hFile = NULL; - m_bCloseOnDelete = false; - } -} - -void MemStream::SetLength( size_type nNewLen ){ - if ( nNewLen > m_nBufferSize ) { - GrowFile( nNewLen ); - } - - if ( nNewLen < m_nPosition ) { - m_nPosition = nNewLen; - } - - m_nFileSize = nNewLen; -} - -void FileStream::SetLength( size_type nNewLen ){ - fseek( m_hFile, static_cast( nNewLen ), SEEK_SET ); -} - -MemStream::size_type MemStream::GetLength() const { - return m_nFileSize; -} - -FileStream::size_type FileStream::GetLength() const { - size_type nLen, nCur; - - // Seek is a non const operation - nCur = ftell( m_hFile ); - fseek( m_hFile, 0, SEEK_END ); - nLen = ftell( m_hFile ); - fseek( m_hFile, static_cast( nCur ), SEEK_SET ); - - return nLen; -} diff --git a/libs/profile/file.h b/libs/profile/file.h deleted file mode 100644 index fbda1d5..0000000 --- a/libs/profile/file.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// file.h -//////////////////////////////////////////////////// - -#if !defined( INCLUDED_PROFILE_FILE_H ) -#define INCLUDED_PROFILE_FILE_H - -#include "idatastream.h" - -/*! - API for data streams - - Based on an initial implementation by Loki software - modified to be abstracted and shared across modules - - NOTE: why IDataStream and not IStream? because IStream is defined in windows IDL headers - */ - -class IDataStream : public InputStream, public OutputStream -{ -public: -typedef int offset_type; -typedef std::size_t position_type; - -virtual void IncRef() = 0; ///< Increment the number of references to this object -virtual void DecRef() = 0; ///< Decrement the reference count - -virtual position_type GetPosition() const = 0; -virtual int Seek( offset_type lOff, int nFrom ) = 0; - -virtual void SetLength( size_type nNewLen ) = 0; -virtual size_type GetLength() const = 0; - -virtual char* ReadString( char* pBuf, size_type nMax ) = 0; -virtual int GetChar() = 0; - -virtual int PutChar( int c ) = 0; -virtual void printf( const char*, ... ) = 0; ///< completely matches the usual printf behaviour - -virtual void Abort() = 0; -virtual void Flush() = 0; -virtual void Close() = 0; -}; - -#include - -class MemStream : public IDataStream -{ -public: -MemStream(); -MemStream( size_type nLen ); -virtual ~MemStream(); - -int refCount; -void IncRef() { - refCount++; -} -void DecRef() { - refCount--; if ( refCount <= 0 ) { - delete this; - } -} - -protected: -// MemFile specific: -size_type m_nGrowBytes; -size_type m_nPosition; -size_type m_nBufferSize; -size_type m_nFileSize; -unsigned char* m_pBuffer; -bool m_bAutoDelete; -void GrowFile( size_type nNewLen ); - -public: -position_type GetPosition() const; -int Seek( offset_type lOff, int nFrom ); -void SetLength( size_type nNewLen ); -size_type GetLength() const; - -unsigned char* GetBuffer() const -{ - return m_pBuffer; -} - -size_type read( byte_type* buffer, size_type length ); -size_type write( const byte_type* buffer, size_type length ); - -char* ReadString( char* pBuf, size_type nMax ); -int GetChar(); - -int PutChar( int c ); -void printf( const char*, ... ); ///< \todo implement on MemStream - -void Abort(); -void Flush(); -void Close(); -bool Open( const char *filename, const char *mode ); -}; - -class FileStream : public IDataStream -{ -public: -FileStream(); -virtual ~FileStream(); - -int refCount; -void IncRef() { - refCount++; -} -void DecRef() { - refCount--; if ( refCount <= 0 ) { - delete this; - } -} - -protected: -// DiscFile specific: -FILE* m_hFile; -bool m_bCloseOnDelete; - -public: -position_type GetPosition() const; -int Seek( offset_type lOff, int nFrom ); -void SetLength( size_type nNewLen ); -size_type GetLength() const; - -size_type read( byte_type* buffer, size_type length ); -size_type write( const byte_type* buffer, size_type length ); - -char* ReadString( char* pBuf, size_type nMax ); -int GetChar(); - -int PutChar( int c ); -void printf( const char*, ... ); ///< completely matches the usual printf behaviour - -void Abort(); -void Flush(); -void Close(); -bool Open( const char *filename, const char *mode ); -}; - -#endif diff --git a/libs/profile/profile.cpp b/libs/profile/profile.cpp deleted file mode 100644 index c1505e0..0000000 --- a/libs/profile/profile.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Application settings load/save -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "profile.h" - -#include -#include -#include - -#include "file.h" - -#include - -#include "str.h" - - -// ============================================================================= -// Static functions - -bool read_var( const char *filename, const char *section, const char *key, char *value ){ - char line[1024], *ptr; - FILE *rc; - - rc = fopen( filename, "rt" ); - - if ( rc == NULL ) { - return false; - } - - while ( fgets( line, 1024, rc ) != 0 ) - { - // First we find the section - if ( line[0] != '[' ) { - continue; - } - - ptr = strchr( line, ']' ); - *ptr = '\0'; - - if ( strcmp( &line[1], section ) == 0 ) { - while ( fgets( line, 1024, rc ) != 0 ) - { - ptr = strchr( line, '=' ); - - if ( ptr == NULL ) { - // reached the end of the section - fclose( rc ); - return false; - } - *ptr = '\0'; - - // remove spaces - while ( line[strlen( line ) - 1] == ' ' ) - line[strlen( line ) - 1] = '\0'; - - if ( strcmp( line, key ) == 0 ) { - strcpy( value, ptr + 1 ); - fclose( rc ); - - if ( value[strlen( value ) - 1] == 10 || value[strlen( value ) - 1] == 13 || value[strlen( value ) - 1] == 32 ) { - value[strlen( value ) - 1] = 0; - } - - return true; - } - } - } - } - - fclose( rc ); - return false; -} - -bool save_var( const char *filename, const char *section, const char *key, const char *value ){ - char line[1024], *ptr; - MemStream old_rc; - bool found; - FILE *rc; - - rc = fopen( filename, "rb" ); - - if ( rc != NULL ) { - unsigned int len; - void *buf; - - fseek( rc, 0, SEEK_END ); - len = ftell( rc ); - rewind( rc ); - buf = malloc( len ); - fread( buf, len, 1, rc ); - old_rc.write( reinterpret_cast( buf ), len ); - free( buf ); - fclose( rc ); - old_rc.Seek( 0, SEEK_SET ); - } - - // TTimo: changed to binary writing. It doesn't seem to affect linux version, and win32 version was happending a lot of '\n' - rc = fopen( filename, "wb" ); - - if ( rc == NULL ) { - return false; - } - - // First we need to find the section - found = false; - while ( old_rc.ReadString( line, 1024 ) != NULL ) - { - fputs( line, rc ); - - if ( line[0] == '[' ) { - ptr = strchr( line, ']' ); - *ptr = '\0'; - - if ( strcmp( &line[1], section ) == 0 ) { - found = true; - break; - } - } - } - - if ( !found ) { - fputs( "\n", rc ); - fprintf( rc, "[%s]\n", section ); - } - - fprintf( rc, "%s=%s\n", key, value ); - - while ( old_rc.ReadString( line, 1024 ) != NULL ) - { - ptr = strchr( line, '=' ); - - if ( ptr != NULL ) { - *ptr = '\0'; - - if ( strcmp( line, key ) == 0 ) { - break; - } - - *ptr = '='; - fputs( line, rc ); - } - else - { - fputs( line, rc ); - break; - } - } - - while ( old_rc.ReadString( line, 1024 ) != NULL ) - fputs( line, rc ); - - fclose( rc ); - return true; -} - -// ============================================================================= -// Global functions - -bool profile_save_int( const char *filename, const char *section, const char *key, int value ){ - char buf[16]; - sprintf( buf, "%d", value ); - return save_var( filename, section, key, buf ); -} - -bool profile_save_float( const char *filename, const char *section, const char *key, float value ){ - char buf[16]; - sprintf( buf, "%f", value ); - return save_var( filename, section, key, buf ); -} - -bool profile_save_string( const char * filename, const char *section, const char *key, const char *value ){ - return save_var( filename, section, key, value ); -} - -bool profile_save_buffer( const char * rc_path, const char *name, void *buffer, unsigned int size ){ - bool ret = false; - char filename[1024]; - sprintf( filename, "%s/%s.bin", rc_path, name ); - FILE *f; - - f = fopen( filename, "wb" ); - - if ( f != NULL ) { - if ( fwrite( buffer, size, 1, f ) == 1 ) { - ret = true; - } - - fclose( f ); - } - - return ret; -} - -bool profile_load_buffer( const char * rc_path, const char *name, void *buffer, unsigned int *plSize ){ - char filename[1024]; - sprintf( filename, "%s/%s.bin", rc_path, name ); - bool ret = false; - unsigned int len; - FILE *f; - - f = fopen( filename, "rb" ); - - if ( f != NULL ) { - fseek( f, 0, SEEK_END ); - len = ftell( f ); - rewind( f ); - - if ( len > *plSize ) { - len = *plSize; - } - else{ - *plSize = len; - } - - if ( fread( buffer, len, 1, f ) == 1 ) { - ret = true; - } - - fclose( f ); - } - - return ret; -} - -int profile_load_int( const char *filename, const char *section, const char *key, int default_value ){ - char value[1024]; - - if ( read_var( filename, section, key, value ) ) { - return atoi( value ); - } - else{ - return default_value; - } -} - -float profile_load_float( const char *filename, const char *section, const char *key, float default_value ){ - char value[1024]; - - if ( read_var( filename, section, key, value ) ) { - return static_cast( atof( value ) ); - } - else{ - return default_value; - } -} - -char* profile_load_string( const char *filename, const char *section, const char *key, const char *default_value ){ - static Str ret; - char value[1024]; - - if ( read_var( filename, section, key, value ) ) { - ret = value; - } - else{ - ret = default_value; - } - - return (char*)ret.GetBuffer(); -} diff --git a/libs/profile/profile.h b/libs/profile/profile.h deleted file mode 100644 index 493743f..0000000 --- a/libs/profile/profile.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_PROFILE_PROFILE_H ) -#define INCLUDED_PROFILE_PROFILE_H - -// profile functions - kind of utility lib -// they are kind of dumb, they expect to get the path to the .ini file or to the prefs directory when called -// load_buffer and save_buffer expect the path only, theyll build a $(pszName).bin file -bool profile_save_int( const char *filename, const char *section, const char *key, int value ); -bool profile_save_float( const char *filename, const char *section, const char *key, float value ); -bool profile_save_string( const char *filename, const char *section, const char *key, const char *value ); -bool profile_save_buffer( const char *rc_path, const char *pszName, void *pvBuf, unsigned int lSize ); -bool profile_load_buffer( const char *rc_path, const char *pszName, void *pvBuf, unsigned int *plSize ); -int profile_load_int( const char *filename, const char *section, const char *key, int default_value ); -float profile_load_float( const char *filename, const char *section, const char *key, float default_value ); -char* profile_load_string( const char *filename, const char *section, const char *key, const char *default_value ); -// used in the command map code -bool read_var( const char *filename, const char *section, const char *key, char *value ); -bool save_var( const char *filename, const char *section, const char *key, const char *value ); - -#endif diff --git a/libs/property.h b/libs/property.h deleted file mode 100644 index 3b4f81f..0000000 --- a/libs/property.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef INCLUDED_IMPORTEXPORT_H -#define INCLUDED_IMPORTEXPORT_H - -#include "generic/callback.h" -#include "string/string.h" - -template -struct Property { - // todo: just return T, don't use continuation passing style - Callback &returnz)> get; - Callback set; -}; - -// implementation - -template -struct PropertyImpl { - static void Export(const Self &self, const Callback &returnz) { - returnz(self); - } - - static void Import(Self &self, T value) { - self = value; - } -}; - -namespace detail { - -template -using propertyimpl_self = typename std::remove_reference >::type; - -template -using propertyimpl_other = get_argument; - -template -using propertyimpl_other_free = get_argument; - -} - -// adaptor - -template< - class Self, - class T = Self, - class I = PropertyImpl - > -struct PropertyAdaptor { - using Type = Self; - using Other = T; - - using Get = ConstReferenceCaller &), I::Export>; - using Set = ReferenceCaller; -}; - -template< - class T, - class I - > -struct PropertyAdaptorFree { - using Other = T; - - using Get = FreeCaller &), I::Export>; - using Set = FreeCaller; -}; - -// explicit full - -template -Property make_property(typename A::Type &self) { - return {typename A::Get(self), typename A::Set(self)}; -} - -template -Property make_property() { - return {typename A::Get(), typename A::Set()}; -} - -// explicit impl - -template, class T = detail::propertyimpl_other > -using property_impl = PropertyAdaptor; - -template > -Property make_property(Self &self) { - return make_property >(self); -} - -template > -using property_impl_free = PropertyAdaptorFree; - -template > -Property make_property() { - return make_property >(); -} - -// implicit - -template -Property make_property(Self &self) { - return make_property >(self); -} - -// chain - -template -struct make_property_chain_I_1 { - static void ExportThunk(const Callback &self, SRC value) { - PropertyImpl::Export(value, self); - } - - static void Export(const X &self, const Callback &returnz) { - A::Get::thunk_(self, ConstReferenceCaller, void(SRC), ExportThunk>(returnz)); - } - - static void Import(X &self, DST value) { - SRC out; - PropertyImpl::Import(out, value); - A::Set::thunk_(self, out); - } -}; - -template -Property > make_property_chain(detail::propertyimpl_self &it) { - using DST = detail::propertyimpl_other; - using SRC = detail::propertyimpl_self; - using X = detail::propertyimpl_self; - - using A = property_impl; - using I = make_property_chain_I_1; - return make_property >(it); -} - -template -struct make_property_chain_I_2 { - static void ExportThunk(const Callback &self, SRC value) { - PropertyImpl::Export(value, self); - } - - static void Export(const Callback &returnz) { - A::Get::thunk_(nullptr, ConstReferenceCaller, void(SRC), ExportThunk>(returnz)); - } - - static void Import(DST value) { - SRC out; - PropertyImpl::Import(out, value); - A::Set::thunk_(nullptr, out); - } -}; - -template -Property > make_property_chain() { - using DST = detail::propertyimpl_other; - using SRC = detail::propertyimpl_self; - - using A = property_impl_free; - using I = make_property_chain_I_2; - return make_property >(); -} - -// specializations - -template<> -struct PropertyImpl { - static void Export(const CopiedString &self, const Callback &returnz) { - returnz(self.c_str()); - } - - static void Import(CopiedString &self, const char *value) { - self = value; - } -}; - -#endif diff --git a/libs/render.h b/libs/render.h deleted file mode 100644 index 127c6ad..0000000 --- a/libs/render.h +++ /dev/null @@ -1,1209 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_RENDER_H ) -#define INCLUDED_RENDER_H - -/// \file -/// \brief High-level constructs for efficient OpenGL rendering. - -#include "irender.h" -#include "igl.h" - -#include "container/array.h" -#include "math/vector.h" -#include "math/pi.h" - -#include - -typedef unsigned int RenderIndex; -const GLenum RenderIndexTypeID = GL_UNSIGNED_INT; - -/// \brief A resizable buffer of indices. -class IndexBuffer -{ -typedef std::vector Indices; -Indices m_data; -public: -typedef Indices::iterator iterator; -typedef Indices::const_iterator const_iterator; - -iterator begin(){ - return m_data.begin(); -} -const_iterator begin() const { - return m_data.begin(); -} -iterator end(){ - return m_data.end(); -} -const_iterator end() const { - return m_data.end(); -} - -bool empty() const { - return m_data.empty(); -} -std::size_t size() const { - return m_data.size(); -} -const RenderIndex* data() const { - return &( *m_data.begin() ); -} -RenderIndex& operator[]( std::size_t index ){ - return m_data[index]; -} -const RenderIndex& operator[]( std::size_t index ) const { - return m_data[index]; -} -void clear(){ - m_data.clear(); -} -void reserve( std::size_t max_indices ){ - m_data.reserve( max_indices ); -} -void insert( RenderIndex index ){ - m_data.push_back( index ); -} -void swap( IndexBuffer& other ){ - std::swap( m_data, m_data ); -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -inline void swap( IndexBuffer& self, IndexBuffer& other ){ - self.swap( other ); -} -} - -/// \brief A resizable buffer of vertices. -/// \param Vertex The vertex data type. -template -class VertexBuffer -{ -typedef typename std::vector Vertices; -Vertices m_data; -public: -typedef typename Vertices::iterator iterator; -typedef typename Vertices::const_iterator const_iterator; - -iterator begin(){ - return m_data.begin(); -} -iterator end(){ - return m_data.end(); -} -const_iterator begin() const { - return m_data.begin(); -} -const_iterator end() const { - return m_data.end(); -} - -bool empty() const { - return m_data.empty(); -} -RenderIndex size() const { - return RenderIndex( m_data.size() ); -} -const Vertex* data() const { - return &( *m_data.begin() ); -} -Vertex& operator[]( std::size_t index ){ - return m_data[index]; -} -const Vertex& operator[]( std::size_t index ) const { - return m_data[index]; -} - -void clear(){ - m_data.clear(); -} -void reserve( std::size_t max_vertices ){ - m_data.reserve( max_vertices ); -} -void push_back( const Vertex& vertex ){ - m_data.push_back( vertex ); -} -}; - -/// \brief A wrapper around a VertexBuffer which inserts only vertices which have not already been inserted. -/// \param Vertex The vertex data type. Must support operator<, operator== and operator!=. -/// For best performance, quantise vertices before inserting them. -template -class UniqueVertexBuffer -{ -typedef VertexBuffer Vertices; -Vertices& m_data; - -struct bnode -{ - bnode() - : m_left( 0 ), m_right( 0 ){ - } - RenderIndex m_left; - RenderIndex m_right; -}; - -std::vector m_btree; -RenderIndex m_prev0; -RenderIndex m_prev1; -RenderIndex m_prev2; - -RenderIndex find_or_insert( const Vertex& vertex ){ - RenderIndex index = 0; - - while ( 1 ) - { - if ( vertex < m_data[index] ) { - bnode& node = m_btree[index]; - if ( node.m_left != 0 ) { - index = node.m_left; - continue; - } - else - { - node.m_left = RenderIndex( m_btree.size() ); - m_btree.push_back( bnode() ); - m_data.push_back( vertex ); - return RenderIndex( m_btree.size() - 1 ); - } - } - if ( m_data[index] < vertex ) { - bnode& node = m_btree[index]; - if ( node.m_right != 0 ) { - index = node.m_right; - continue; - } - else - { - node.m_right = RenderIndex( m_btree.size() ); - m_btree.push_back( bnode() ); - m_data.push_back( vertex ); - return RenderIndex( m_btree.size() - 1 ); - } - } - - return index; - } -} -public: -UniqueVertexBuffer( Vertices& data ) - : m_data( data ), m_prev0( 0 ), m_prev1( 0 ), m_prev2( 0 ){ -} - -typedef typename Vertices::const_iterator iterator; - -iterator begin() const { - return m_data.begin(); -} -iterator end() const { - return m_data.end(); -} - -std::size_t size() const { - return m_data.size(); -} -const Vertex* data() const { - return &( *m_data.begin() ); -} -Vertex& operator[]( std::size_t index ){ - return m_data[index]; -} -const Vertex& operator[]( std::size_t index ) const { - return m_data[index]; -} - -void clear(){ - m_prev0 = 0; - m_prev1 = 0; - m_prev2 = 0; - m_data.clear(); - m_btree.clear(); -} -void reserve( std::size_t max_vertices ){ - m_data.reserve( max_vertices ); - m_btree.reserve( max_vertices ); -} -/// \brief Returns the index of the element equal to \p vertex. -RenderIndex insert( const Vertex& vertex ){ - if ( m_data.empty() ) { - m_data.push_back( vertex ); - m_btree.push_back( bnode() ); - return 0; - } - - if ( m_data[m_prev0] == vertex ) { - return m_prev0; - } - if ( m_prev1 != m_prev0 && m_data[m_prev1] == vertex ) { - return m_prev1; - } - if ( m_prev2 != m_prev0 && m_prev2 != m_prev1 && m_data[m_prev2] == vertex ) { - return m_prev2; - } - - m_prev2 = m_prev1; - m_prev1 = m_prev0; - m_prev0 = find_or_insert( vertex ); - - return m_prev0; -} -}; - - -/// \brief A 4-byte colour. -struct Colour4b -{ - unsigned char r, g, b, a; - - Colour4b(){ - } - - Colour4b( unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a ) - : r( _r ), g( _g ), b( _b ), a( _a ){ - } -}; - -const Colour4b colour_vertex( 0, 255, 0, 255 ); -const Colour4b colour_selected( 0, 0, 255, 255 ); - -inline bool operator<( const Colour4b& self, const Colour4b& other ){ - if ( self.r != other.r ) { - return self.r < other.r; - } - if ( self.g != other.g ) { - return self.g < other.g; - } - if ( self.b != other.b ) { - return self.b < other.b; - } - if ( self.a != other.a ) { - return self.a < other.a; - } - return false; -} - -inline bool operator==( const Colour4b& self, const Colour4b& other ){ - return self.r == other.r && self.g == other.g && self.b == other.b && self.a == other.a; -} - -inline bool operator!=( const Colour4b& self, const Colour4b& other ){ - return !operator==( self, other ); -} - -/// \brief A 3-float vertex. -struct Vertex3f : public Vector3 -{ - Vertex3f(){ - } - - Vertex3f( float _x, float _y, float _z ) - : Vector3( _x, _y, _z ){ - } -}; - -inline bool operator<( const Vertex3f& self, const Vertex3f& other ){ - if ( self.x() != other.x() ) { - return self.x() < other.x(); - } - if ( self.y() != other.y() ) { - return self.y() < other.y(); - } - if ( self.z() != other.z() ) { - return self.z() < other.z(); - } - return false; -} - -inline bool operator==( const Vertex3f& self, const Vertex3f& other ){ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); -} - -inline bool operator!=( const Vertex3f& self, const Vertex3f& other ){ - return !operator==( self, other ); -} - - -inline Vertex3f vertex3f_from_array( const float* array ){ - return Vertex3f( array[0], array[1], array[2] ); -} - -inline float* vertex3f_to_array( Vertex3f& vertex ){ - return reinterpret_cast( &vertex ); -} - -inline const float* vertex3f_to_array( const Vertex3f& vertex ){ - return reinterpret_cast( &vertex ); -} - -const Vertex3f vertex3f_identity( 0, 0, 0 ); - -inline Vertex3f vertex3f_for_vector3( const Vector3& vector3 ){ - return Vertex3f( vector3.x(), vector3.y(), vector3.z() ); -} - -inline const Vector3& vertex3f_to_vector3( const Vertex3f& vertex ){ - return vertex; -} - -inline Vector3& vertex3f_to_vector3( Vertex3f& vertex ){ - return vertex; -} - - -/// \brief A 3-float normal. -struct Normal3f : public Vector3 -{ - Normal3f(){ - } - - Normal3f( float _x, float _y, float _z ) - : Vector3( _x, _y, _z ){ - } -}; - -inline bool operator<( const Normal3f& self, const Normal3f& other ){ - if ( self.x() != other.x() ) { - return self.x() < other.x(); - } - if ( self.y() != other.y() ) { - return self.y() < other.y(); - } - if ( self.z() != other.z() ) { - return self.z() < other.z(); - } - return false; -} - -inline bool operator==( const Normal3f& self, const Normal3f& other ){ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); -} - -inline bool operator!=( const Normal3f& self, const Normal3f& other ){ - return !operator==( self, other ); -} - - -inline Normal3f normal3f_from_array( const float* array ){ - return Normal3f( array[0], array[1], array[2] ); -} - -inline float* normal3f_to_array( Normal3f& normal ){ - return reinterpret_cast( &normal ); -} - -inline const float* normal3f_to_array( const Normal3f& normal ){ - return reinterpret_cast( &normal ); -} - -inline Normal3f normal3f_for_vector3( const Vector3& vector3 ){ - return Normal3f( vector3.x(), vector3.y(), vector3.z() ); -} - -inline const Vector3& normal3f_to_vector3( const Normal3f& normal ){ - return normal; -} - -inline Vector3& normal3f_to_vector3( Normal3f& normal ){ - return normal; -} - - -/// \brief A 2-float texture-coordinate set. -struct TexCoord2f : public Vector2 -{ - TexCoord2f(){ - } - - TexCoord2f( float _s, float _t ) - : Vector2( _s, _t ){ - } - - float& s(){ - return x(); - } - const float& s() const { - return x(); - } - float& t(){ - return y(); - } - const float& t() const { - return y(); - } -}; - -inline bool operator<( const TexCoord2f& self, const TexCoord2f& other ){ - if ( self.s() != other.s() ) { - return self.s() < other.s(); - } - if ( self.t() != other.t() ) { - return self.t() < other.t(); - } - return false; -} - -inline bool operator==( const TexCoord2f& self, const TexCoord2f& other ){ - return self.s() == other.s() && self.t() == other.t(); -} - -inline bool operator!=( const TexCoord2f& self, const TexCoord2f& other ){ - return !operator==( self, other ); -} - - -inline float* texcoord2f_to_array( TexCoord2f& texcoord ){ - return reinterpret_cast( &texcoord ); -} - -inline const float* texcoord2f_to_array( const TexCoord2f& texcoord ){ - return reinterpret_cast( &texcoord ); -} - -inline const TexCoord2f& texcoord2f_from_array( const float* array ){ - return *reinterpret_cast( array ); -} - -inline TexCoord2f texcoord2f_for_vector2( const Vector2& vector2 ){ - return TexCoord2f( vector2.x(), vector2.y() ); -} - -inline Vector4 colour4f_for_vector4( const Vector4& vector4 ){ - return vector4; -} - -inline const Vector2& texcoord2f_to_vector2( const TexCoord2f& vertex ){ - return vertex; -} - -inline Vector2& texcoord2f_to_vector2( TexCoord2f& vertex ){ - return vertex; -} -inline Vector4& colour4f_to_vector4( Vector4& vertex ){ - return vertex; -} - -/// \brief Returns \p normal rescaled to be unit-length. -inline Normal3f normal3f_normalised( const Normal3f& normal ){ - return normal3f_for_vector3( vector3_normalised( normal3f_to_vector3( normal ) ) ); -} - -enum UnitSphereOctant -{ - UNITSPHEREOCTANT_000 = 0 << 0 | 0 << 1 | 0 << 2, - UNITSPHEREOCTANT_001 = 0 << 0 | 0 << 1 | 1 << 2, - UNITSPHEREOCTANT_010 = 0 << 0 | 1 << 1 | 0 << 2, - UNITSPHEREOCTANT_011 = 0 << 0 | 1 << 1 | 1 << 2, - UNITSPHEREOCTANT_100 = 1 << 0 | 0 << 1 | 0 << 2, - UNITSPHEREOCTANT_101 = 1 << 0 | 0 << 1 | 1 << 2, - UNITSPHEREOCTANT_110 = 1 << 0 | 1 << 1 | 0 << 2, - UNITSPHEREOCTANT_111 = 1 << 0 | 1 << 1 | 1 << 2, -}; - -/// \brief Returns the octant for \p normal indicating the sign of the region of unit-sphere space it lies within. -inline UnitSphereOctant normal3f_classify_octant( const Normal3f& normal ){ - return static_cast( - ( ( normal.x() > 0 ) << 0 ) | ( ( normal.y() > 0 ) << 1 ) | ( ( normal.z() > 0 ) << 2 ) - ); -} - -/// \brief Returns \p normal with its components signs made positive based on \p octant. -inline Normal3f normal3f_fold_octant( const Normal3f& normal, UnitSphereOctant octant ){ - switch ( octant ) - { - case UNITSPHEREOCTANT_000: - return Normal3f( -normal.x(), -normal.y(), -normal.z() ); - case UNITSPHEREOCTANT_001: - return Normal3f( normal.x(), -normal.y(), -normal.z() ); - case UNITSPHEREOCTANT_010: - return Normal3f( -normal.x(), normal.y(), -normal.z() ); - case UNITSPHEREOCTANT_011: - return Normal3f( normal.x(), normal.y(), -normal.z() ); - case UNITSPHEREOCTANT_100: - return Normal3f( -normal.x(), -normal.y(), normal.z() ); - case UNITSPHEREOCTANT_101: - return Normal3f( normal.x(), -normal.y(), normal.z() ); - case UNITSPHEREOCTANT_110: - return Normal3f( -normal.x(), normal.y(), normal.z() ); - case UNITSPHEREOCTANT_111: - return Normal3f( normal.x(), normal.y(), normal.z() ); - } - return Normal3f(); -} - -/// \brief Reverses the effect of normal3f_fold_octant() on \p normal with \p octant. -/// \p normal must have been obtained with normal3f_fold_octant(). -/// \p octant must have been obtained with normal3f_classify_octant(). -inline Normal3f normal3f_unfold_octant( const Normal3f& normal, UnitSphereOctant octant ){ - return normal3f_fold_octant( normal, octant ); -} - -enum UnitSphereSextant -{ - UNITSPHERESEXTANT_XYZ = 0, - UNITSPHERESEXTANT_XZY = 1, - UNITSPHERESEXTANT_YXZ = 2, - UNITSPHERESEXTANT_YZX = 3, - UNITSPHERESEXTANT_ZXY = 4, - UNITSPHERESEXTANT_ZYX = 5, -}; - -/// \brief Returns the sextant for \p normal indicating how to sort its components so that x > y > z. -/// All components of \p normal must be positive. -/// \p normal must be normalised. -inline UnitSphereSextant normal3f_classify_sextant( const Normal3f& normal ){ - return - normal.x() >= normal.y() - ? normal.x() >= normal.z() - ? normal.y() >= normal.z() - ? UNITSPHERESEXTANT_XYZ - : UNITSPHERESEXTANT_XZY - : UNITSPHERESEXTANT_ZXY - : normal.y() >= normal.z() - ? normal.x() >= normal.z() - ? UNITSPHERESEXTANT_YXZ - : UNITSPHERESEXTANT_YZX - : UNITSPHERESEXTANT_ZYX; -} - -/// \brief Returns \p normal with its components sorted so that x > y > z based on \p sextant. -/// All components of \p normal must be positive. -/// \p normal must be normalised. -inline Normal3f normal3f_fold_sextant( const Normal3f& normal, UnitSphereSextant sextant ){ - switch ( sextant ) - { - case UNITSPHERESEXTANT_XYZ: - return Normal3f( normal.x(), normal.y(), normal.z() ); - case UNITSPHERESEXTANT_XZY: - return Normal3f( normal.x(), normal.z(), normal.y() ); - case UNITSPHERESEXTANT_YXZ: - return Normal3f( normal.y(), normal.x(), normal.z() ); - case UNITSPHERESEXTANT_YZX: - return Normal3f( normal.y(), normal.z(), normal.x() ); - case UNITSPHERESEXTANT_ZXY: - return Normal3f( normal.z(), normal.x(), normal.y() ); - case UNITSPHERESEXTANT_ZYX: - return Normal3f( normal.z(), normal.y(), normal.x() ); - } - return Normal3f(); -} - -/// \brief Reverses the effect of normal3f_fold_sextant() on \p normal with \p sextant. -/// \p normal must have been obtained with normal3f_fold_sextant(). -/// \p sextant must have been obtained with normal3f_classify_sextant(). -inline Normal3f normal3f_unfold_sextant( const Normal3f& normal, UnitSphereSextant sextant ){ - return normal3f_fold_sextant( normal, sextant ); -} - -const std::size_t c_quantise_normal = 1 << 6; - -/// \brief All the components of \p folded must be positive and sorted so that x > y > z. -inline Normal3f normal3f_folded_quantised( const Normal3f& folded ){ - // compress - double scale = static_cast( c_quantise_normal ) / ( folded.x() + folded.y() + folded.z() ); - unsigned int zbits = static_cast( folded.z() * scale ); - unsigned int ybits = static_cast( folded.y() * scale ); - - // decompress - return normal3f_normalised( Normal3f( - static_cast( c_quantise_normal - zbits - ybits ), - static_cast( ybits ), - static_cast( zbits ) - ) ); -} - -/// \brief Returns \p normal quantised by compressing and then decompressing its representation. -inline Normal3f normal3f_quantised_custom( const Normal3f& normal ){ - UnitSphereOctant octant = normal3f_classify_octant( normal ); - Normal3f folded = normal3f_fold_octant( normal, octant ); - UnitSphereSextant sextant = normal3f_classify_sextant( folded ); - folded = normal3f_fold_sextant( folded, sextant ); - return normal3f_unfold_octant( normal3f_unfold_sextant( normal3f_folded_quantised( folded ), sextant ), octant ); -} - - - -struct spherical_t -{ - double longditude, latitude; - - spherical_t( double _longditude, double _latitude ) - : longditude( _longditude ), latitude( _latitude ){ - } -}; - -/* - { - theta = 2pi * U; - phi = acos((2 * V) - 1); - - U = theta / 2pi; - V = (cos(phi) + 1) / 2; - } - - longitude = atan(y / x); - latitude = acos(z); - */ -struct uniformspherical_t -{ - double U, V; - - uniformspherical_t( double U_, double V_ ) - : U( U_ ), V( V_ ){ - } -}; - - -inline spherical_t spherical_from_normal3f( const Normal3f& normal ){ - return spherical_t( normal.x() == 0 ? c_pi / 2 : normal.x() > 0 ? atan( normal.y() / normal.x() ) : atan( normal.y() / normal.x() ) + c_pi, acos( normal.z() ) ); -} - -inline Normal3f normal3f_from_spherical( const spherical_t& spherical ){ - return Normal3f( - static_cast( cos( spherical.longditude ) * sin( spherical.latitude ) ), - static_cast( sin( spherical.longditude ) * sin( spherical.latitude ) ), - static_cast( cos( spherical.latitude ) ) - ); -} - -inline uniformspherical_t uniformspherical_from_spherical( const spherical_t& spherical ){ - return uniformspherical_t( spherical.longditude * c_inv_2pi, ( cos( spherical.latitude ) + 1 ) * 0.5 ); -} - -inline spherical_t spherical_from_uniformspherical( const uniformspherical_t& uniformspherical ){ - return spherical_t( c_2pi * uniformspherical.U, acos( ( 2 * uniformspherical.V ) - 1 ) ); -} - -inline uniformspherical_t uniformspherical_from_normal3f( const Normal3f& normal ){ - return uniformspherical_from_spherical( spherical_from_normal3f( normal ) ); - //return uniformspherical_t(atan2(normal.y / normal.x) * c_inv_2pi, (normal.z + 1) * 0.5); -} - -inline Normal3f normal3f_from_uniformspherical( const uniformspherical_t& uniformspherical ){ - return normal3f_from_spherical( spherical_from_uniformspherical( uniformspherical ) ); -} - -/// \brief Returns a single-precision \p component quantised to \p precision. -inline float float_quantise( float component, float precision ){ - return float_snapped( component, precision ); -} - -/// \brief Returns a double-precision \p component quantised to \p precision. -inline double double_quantise( double component, double precision ){ - return float_snapped( component, precision ); -} - -inline spherical_t spherical_quantised( const spherical_t& spherical, float snap ){ - return spherical_t( double_quantise( spherical.longditude, snap ), double_quantise( spherical.latitude, snap ) ); -} - -inline uniformspherical_t uniformspherical_quantised( const uniformspherical_t& uniformspherical, float snap ){ - return uniformspherical_t( double_quantise( uniformspherical.U, snap ), double_quantise( uniformspherical.V, snap ) ); -} - -/// \brief Returns a \p vertex quantised to \p precision. -inline Vertex3f vertex3f_quantised( const Vertex3f& vertex, float precision ){ - return Vertex3f( float_quantise( vertex.x(), precision ), float_quantise( vertex.y(), precision ), float_quantise( vertex.z(), precision ) ); -} - -/// \brief Returns a \p normal quantised to a fixed precision. -inline Normal3f normal3f_quantised( const Normal3f& normal ){ - return normal3f_quantised_custom( normal ); - //return normal3f_from_spherical(spherical_quantised(spherical_from_normal3f(normal), snap)); - //return normal3f_from_uniformspherical(uniformspherical_quantised(uniformspherical_from_normal3f(normal), snap)); - // float_quantise(normal.x, snap), float_quantise(normal.y, snap), float_quantise(normal.y, snap)); -} - -/// \brief Returns a \p texcoord quantised to \p precision. -inline TexCoord2f texcoord2f_quantised( const TexCoord2f& texcoord, float precision ){ - return TexCoord2f( float_quantise( texcoord.s(), precision ), float_quantise( texcoord.t(), precision ) ); -} - -/// \brief Standard vertex type for lines and points. -struct PointVertex -{ - Colour4b colour; - Vertex3f vertex; - - PointVertex(){ - } - PointVertex( Vertex3f _vertex ) - : colour( Colour4b( 255, 255, 255, 255 ) ), vertex( _vertex ){ - } - PointVertex( Vertex3f _vertex, Colour4b _colour ) - : colour( _colour ), vertex( _vertex ){ - } -}; - -inline bool operator<( const PointVertex& self, const PointVertex& other ){ - if ( self.vertex != other.vertex ) { - return self.vertex < other.vertex; - } - if ( self.colour != other.colour ) { - return self.colour < other.colour; - } - return false; -} - -inline bool operator==( const PointVertex& self, const PointVertex& other ){ - return self.colour == other.colour && self.vertex == other.vertex; -} - -inline bool operator!=( const PointVertex& self, const PointVertex& other ){ - return !operator==( self, other ); -} - -/// \brief Standard vertex type for lit/textured meshes. -struct ArbitraryMeshVertex -{ - TexCoord2f texcoord; - Normal3f normal; - Vertex3f vertex; - Normal3f tangent; - Normal3f bitangent; - Vector4 colour; - - ArbitraryMeshVertex() : tangent( 0, 0, 0 ), bitangent( 0, 0, 0 ), colour( 1, 1, 1, 1 ){ - } - ArbitraryMeshVertex( Vertex3f _vertex, Normal3f _normal, TexCoord2f _texcoord ) - : texcoord( _texcoord ), normal( _normal ), vertex( _vertex ), tangent( 0, 0, 0 ), bitangent( 0, 0, 0 ), colour( 1, 1, 1, 1 ){ - } -}; - -inline bool operator<( const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other ){ - if ( self.texcoord != other.texcoord ) { - return self.texcoord < other.texcoord; - } - if ( self.normal != other.normal ) { - return self.normal < other.normal; - } - if ( self.vertex != other.vertex ) { - return self.vertex < other.vertex; - } - return false; -} - -inline bool operator==( const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other ){ - return self.texcoord == other.texcoord && self.normal == other.normal && self.vertex == other.vertex; -} - -inline bool operator!=( const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other ){ - return !operator==( self, other ); -} - -const float c_quantise_vertex = 1.f / static_cast( 1 << 3 ); - -/// \brief Returns \p v with vertex quantised to a fixed precision. -inline PointVertex pointvertex_quantised( const PointVertex& v ){ - return PointVertex( vertex3f_quantised( v.vertex, c_quantise_vertex ), v.colour ); -} - -const float c_quantise_texcoord = 1.f / static_cast( 1 << 8 ); - -/// \brief Returns \p v with vertex, normal and texcoord quantised to a fixed precision. -inline ArbitraryMeshVertex arbitrarymeshvertex_quantised( const ArbitraryMeshVertex& v ){ - return ArbitraryMeshVertex( vertex3f_quantised( v.vertex, c_quantise_vertex ), normal3f_quantised( v.normal ), texcoord2f_quantised( v.texcoord, c_quantise_texcoord ) ); -} - - -/// \brief Sets up the OpenGL colour and vertex arrays for \p array. -inline void pointvertex_gl_array( const PointVertex* array ){ - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &array->colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &array->vertex ); -} - -class RenderablePointArray : public OpenGLRenderable -{ -const Array& m_array; -const GLenum m_mode; -public: -RenderablePointArray( const Array& array, GLenum mode ) - : m_array( array ), m_mode( mode ){ -} -void render( RenderStateFlags state ) const { -#define NV_DRIVER_BUG 1 -#if NV_DRIVER_BUG - glColorPointer( 4, GL_UNSIGNED_BYTE, 0, 0 ); - glVertexPointer( 3, GL_FLOAT, 0, 0 ); - glDrawArrays( GL_TRIANGLE_FAN, 0, 0 ); -#endif - pointvertex_gl_array( m_array.data() ); - glDrawArrays( m_mode, 0, GLsizei( m_array.size() ) ); -} -}; - -class RenderablePointVector : public OpenGLRenderable -{ -std::vector m_vector; -const GLenum m_mode; -public: -RenderablePointVector( GLenum mode ) - : m_mode( mode ){ -} - -void render( RenderStateFlags state ) const { - pointvertex_gl_array( &m_vector.front() ); - glDrawArrays( m_mode, 0, GLsizei( m_vector.size() ) ); -} - -std::size_t size() const { - return m_vector.size(); -} -bool empty() const { - return m_vector.empty(); -} -void clear(){ - m_vector.clear(); -} -void reserve( std::size_t size ){ - m_vector.reserve( size ); -} -void push_back( const PointVertex& point ){ - m_vector.push_back( point ); -} -}; - - -class RenderableVertexBuffer : public OpenGLRenderable -{ -const GLenum m_mode; -const VertexBuffer& m_vertices; -public: -RenderableVertexBuffer( GLenum mode, const VertexBuffer& vertices ) - : m_mode( mode ), m_vertices( vertices ){ -} - -void render( RenderStateFlags state ) const { - pointvertex_gl_array( m_vertices.data() ); - glDrawArrays( m_mode, 0, m_vertices.size() ); -} -}; - -class RenderableIndexBuffer : public OpenGLRenderable -{ -const GLenum m_mode; -const IndexBuffer& m_indices; -const VertexBuffer& m_vertices; -public: -RenderableIndexBuffer( GLenum mode, const IndexBuffer& indices, const VertexBuffer& vertices ) - : m_mode( mode ), m_indices( indices ), m_vertices( vertices ){ -} - -void render( RenderStateFlags state ) const { -#if 1 - pointvertex_gl_array( m_vertices.data() ); - glDrawElements( m_mode, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); -#else - glBegin( m_mode ); - if ( state & RENDER_COLOURARRAY != 0 ) { - for ( std::size_t i = 0; i < m_indices.size(); ++i ) - { - glColor4ubv( &m_vertices[m_indices[i]].colour.r ); - glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); - } - } - else - { - for ( std::size_t i = 0; i < m_indices.size(); ++i ) - { - glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); - } - } - glEnd(); -#endif -} -}; - - -class RemapXYZ -{ -public: -static void set( Vertex3f& vertex, float x, float y, float z ){ - vertex.x() = x; - vertex.y() = y; - vertex.z() = z; -} -}; - -class RemapYZX -{ -public: -static void set( Vertex3f& vertex, float x, float y, float z ){ - vertex.x() = z; - vertex.y() = x; - vertex.z() = y; -} -}; - -class RemapZXY -{ -public: -static void set( Vertex3f& vertex, float x, float y, float z ){ - vertex.x() = y; - vertex.y() = z; - vertex.z() = x; -} -}; - -template -inline void draw_circle( const std::size_t segments, const float radius, PointVertex* vertices, remap_policy remap ){ - const double increment = c_pi / double(segments << 2); - - std::size_t count = 0; - float x = radius; - float y = 0; - while ( count < segments ) - { - PointVertex* i = vertices + count; - PointVertex* j = vertices + ( ( segments << 1 ) - ( count + 1 ) ); - - PointVertex* k = i + ( segments << 1 ); - PointVertex* l = j + ( segments << 1 ); - - PointVertex* m = i + ( segments << 2 ); - PointVertex* n = j + ( segments << 2 ); - PointVertex* o = k + ( segments << 2 ); - PointVertex* p = l + ( segments << 2 ); - - remap_policy::set( i->vertex, x,-y, 0 ); - remap_policy::set( k->vertex,-y,-x, 0 ); - remap_policy::set( m->vertex,-x, y, 0 ); - remap_policy::set( o->vertex, y, x, 0 ); - - ++count; - - { - const double theta = increment * count; - x = static_cast( radius * cos( theta ) ); - y = static_cast( radius * sin( theta ) ); - } - - remap_policy::set( j->vertex, y,-x, 0 ); - remap_policy::set( l->vertex,-x,-y, 0 ); - remap_policy::set( n->vertex,-y, x, 0 ); - remap_policy::set( p->vertex, x, y, 0 ); - } -} - -#if 0 -class PointVertexArrayIterator -{ -PointVertex* m_point; -public: -PointVertexArrayIterator( PointVertex* point ) - : m_point( point ){ -} -PointVertexArrayIterator& operator++(){ - ++m_point; - return *this; -} -PointVertexArrayIterator operator++( int ){ - PointVertexArrayIterator tmp( *this ); - ++m_point; - return tmp; -} -Vertex3f& operator*(){ - return m_point.vertex; -} -Vertex3f* operator->(){ - return &( operator*() ); -} -} - -template 0.000001f ) { - s.x() = -cross.y() / cross.x(); - } - - if ( fabs( cross.x() ) > 0.000001f ) { - t.x() = -cross.z() / cross.x(); - } - } - - { - Vector3 cross( - vector3_cross( - vector3_subtracted( - Vector3( b.vertex.y(), b.texcoord.s(), b.texcoord.t() ), - Vector3( a.vertex.y(), a.texcoord.s(), a.texcoord.t() ) - ), - vector3_subtracted( - Vector3( c.vertex.y(), c.texcoord.s(), c.texcoord.t() ), - Vector3( a.vertex.y(), a.texcoord.s(), a.texcoord.t() ) - ) - ) - ); - - if ( fabs( cross.x() ) > 0.000001f ) { - s.y() = -cross.y() / cross.x(); - } - - if ( fabs( cross.x() ) > 0.000001f ) { - t.y() = -cross.z() / cross.x(); - } - } - - { - Vector3 cross( - vector3_cross( - vector3_subtracted( - Vector3( b.vertex.z(), b.texcoord.s(), b.texcoord.t() ), - Vector3( a.vertex.z(), a.texcoord.s(), a.texcoord.t() ) - ), - vector3_subtracted( - Vector3( c.vertex.z(), c.texcoord.s(), c.texcoord.t() ), - Vector3( a.vertex.z(), a.texcoord.s(), a.texcoord.t() ) - ) - ) - ); - - if ( fabs( cross.x() ) > 0.000001f ) { - s.z() = -cross.y() / cross.x(); - } - - if ( fabs( cross.x() ) > 0.000001f ) { - t.z() = -cross.z() / cross.x(); - } - } -} - -inline void ArbitraryMeshTriangle_sumTangents( ArbitraryMeshVertex& a, ArbitraryMeshVertex& b, ArbitraryMeshVertex& c ){ - Vector3 s, t; - - ArbitraryMeshTriangle_calcTangents( a, b, c, s, t ); - - reinterpret_cast( a.tangent ) += s; - reinterpret_cast( b.tangent ) += s; - reinterpret_cast( c.tangent ) += s; - - reinterpret_cast( a.bitangent ) += t; - reinterpret_cast( b.bitangent ) += t; - reinterpret_cast( c.bitangent ) += t; -} - - -#endif diff --git a/libs/scenelib.h b/libs/scenelib.h deleted file mode 100644 index 0e6428b..0000000 --- a/libs/scenelib.h +++ /dev/null @@ -1,972 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_SCENELIB_H ) -#define INCLUDED_SCENELIB_H - -#include "globaldefs.h" -#include "iscenegraph.h" -#include "iselection.h" - -#include "warnings.h" -#include -#include - -#include "math/aabb.h" -#include "transformlib.h" -#include "generic/callback.h" -#include "generic/reference.h" -#include "container/stack.h" -#include "typesystem.h" - -class Selector; -class SelectionTest; -class VolumeTest; -template class BasicVector3; -typedef BasicVector3 Vector3; -template class BasicVector4; -typedef BasicVector4 Vector4; -class Matrix4; -typedef Vector4 Quaternion; -class AABB; - -class ComponentSelectionTestable -{ -public: -STRING_CONSTANT( Name, "ComponentSelectionTestable" ); - -virtual bool isSelectedComponents() const = 0; -virtual void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ) = 0; -virtual void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ) = 0; -}; - -class ComponentEditable -{ -public: -STRING_CONSTANT( Name, "ComponentEditable" ); - -virtual const AABB& getSelectedComponentsBounds() const = 0; -}; - -class ComponentSnappable -{ -public: -STRING_CONSTANT( Name, "ComponentSnappable" ); - -virtual void snapComponents( float snap ) = 0; -}; - -class Bounded -{ -public: -STRING_CONSTANT( Name, "Bounded" ); - -virtual const AABB& localAABB() const = 0; -}; - -class BrushDoom3 -{ -public: -STRING_CONSTANT( Name, "BrushDoom3" ); - -virtual void setDoom3GroupOrigin( const Vector3& origin ) = 0; -}; - - - - -typedef TypeCastTable NodeTypeCastTable; - -template -class NodeType : public StaticTypeSystemInitialiser -{ -TypeId m_typeId; -public: -typedef typename Type::Name Name; -NodeType() : m_typeId( NODETYPEID_NONE ){ - StaticTypeSystemInitialiser::instance().addInitialiser( InitialiseCaller( *this ) ); -} -void initialise(){ - m_typeId = GlobalSceneGraph().getNodeTypeId( Name() ); -} -typedef MemberCaller, void (), &NodeType::initialise> InitialiseCaller; -TypeId getTypeId(){ -#if GDEF_DEBUG - ASSERT_MESSAGE( m_typeId != NODETYPEID_NONE, "node-type " << makeQuoted( Name() ) << " used before being initialised" ); -#endif - return m_typeId; -} -}; - -template -class StaticNodeType -{ -public: -enum unnamed0 { SIZE = NODETYPEID_MAX }; -static TypeId getTypeId(){ - return Static< NodeType >::instance().getTypeId(); -} -}; - -template -class NodeStaticCast : - public CastInstaller< - StaticNodeType, - StaticCast - > -{ -}; - -template -class NodeContainedCast : - public CastInstaller< - StaticNodeType, - ContainedCast - > -{ -}; - -template -class NodeIdentityCast : - public CastInstaller< - StaticNodeType, - IdentityCast - > -{ -}; - -namespace scene -{ -class Node -{ -public: -enum unnamed0 { eVisible = 0 }; -enum unnamed1 { eHidden = 1 << 0 }; -enum unnamed2 { eFiltered = 1 << 1 }; -enum unnamed3 { eExcluded = 1 << 2 }; - -class Symbiot -{ -public: -virtual void release() = 0; -virtual ~Symbiot(){ -} -}; - -private: -unsigned int m_state; -std::size_t m_refcount; -Symbiot* m_symbiot; -void* m_node; -NodeTypeCastTable& m_casts; - -public: -bool m_isRoot; - -bool isRoot(){ - return m_isRoot; -} -bool isHidden(){ - return (m_state == eHidden) ? 1 : 0; -} - -Node( Symbiot* symbiot, void* node, NodeTypeCastTable& casts ) : - m_state( eVisible ), - m_refcount( 0 ), - m_symbiot( symbiot ), - m_node( node ), - m_casts( casts ), - m_isRoot( false ){ -} -~Node(){ -} - -void IncRef(){ - ASSERT_MESSAGE( m_refcount < ( 1 << 24 ), "Node::decref: uninitialised refcount" ); - ++m_refcount; -} -void DecRef(){ - ASSERT_MESSAGE( m_refcount < ( 1 << 24 ), "Node::decref: uninitialised refcount" ); - if ( --m_refcount == 0 ) { - m_symbiot->release(); - } -} -std::size_t getReferenceCount() const { - return m_refcount; -} - -void* cast( TypeId typeId ) const { - return m_casts.cast( typeId, m_node ); -} - -void enable( unsigned int state ){ - m_state |= state; -} -void disable( unsigned int state ){ - m_state &= ~state; -} -bool visible(){ - return m_state == eVisible; -} -bool excluded(){ - return ( m_state & eExcluded ) != 0; -} -bool operator<( const scene::Node& other ){ - return this < &other; -} -bool operator==( const scene::Node& other ){ - return this == &other; -} -bool operator!=( const scene::Node& other ){ - return this != &other; -} -}; - - -class NullNode : public Node::Symbiot -{ -NodeTypeCastTable m_casts; -Node m_node; -public: -NullNode() : m_node( this, 0, m_casts ){ -} -void release(){ - delete this; -} -scene::Node& node(){ - return m_node; -} -}; -} - -template -class NodeTypeCast -{ -public: -static Type* cast( scene::Node& node ){ - return static_cast( node.cast( StaticNodeType::getTypeId() ) ); -} -static const Type* cast( const scene::Node& node ){ - return static_cast( node.cast( StaticNodeType::getTypeId() ) ); -} -}; - - -inline scene::Instantiable* Node_getInstantiable( scene::Node& node ){ - return NodeTypeCast::cast( node ); -} - -inline scene::Traversable* Node_getTraversable( scene::Node& node ){ - return NodeTypeCast::cast( node ); -} - -inline void Node_traverseSubgraph( scene::Node& node, const scene::Traversable::Walker& walker ){ - if ( walker.pre( node ) ) { - scene::Traversable* traversable = Node_getTraversable( node ); - if ( traversable != 0 ) { - traversable->traverse( walker ); - } - } - walker.post( node ); -} - -inline TransformNode* Node_getTransformNode( scene::Node& node ){ - return NodeTypeCast::cast( node ); -} - - -inline scene::Node& NewNullNode(){ - return ( new scene::NullNode )->node(); -} - -inline void Path_deleteTop( const scene::Path& path ){ - Node_getTraversable( path.parent() )->erase( path.top() ); -} - - - - - -class delete_all : public scene::Traversable::Walker -{ -scene::Node& m_parent; -public: -delete_all( scene::Node& parent ) : m_parent( parent ){ -} -bool pre( scene::Node& node ) const { - return false; -} -void post( scene::Node& node ) const { - Node_getTraversable( m_parent )->erase( node ); -} -}; - -inline void DeleteSubgraph( scene::Node& subgraph ){ - Node_getTraversable( subgraph )->traverse( delete_all( subgraph ) ); -} - - -class EntityUndefined -{ -public: -STRING_CONSTANT( Name, "Entity" ); -}; - -inline bool Node_isEntity( scene::Node& node ){ - return NodeTypeCast::cast( node ) != 0; -} - -template -class EntityWalker : public scene::Graph::Walker -{ -const Functor& functor; -public: -EntityWalker( const Functor& functor ) : functor( functor ){ -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( Node_isEntity( path.top() ) ) { - functor( instance ); - return false; - } - return true; -} -}; - -template -inline const Functor& Scene_forEachEntity( const Functor& functor ){ - GlobalSceneGraph().traverse( EntityWalker( functor ) ); - return functor; -} - -class BrushUndefined -{ -public: -STRING_CONSTANT( Name, "Brush" ); -}; - -inline bool Node_isBrush( scene::Node& node ){ - return NodeTypeCast::cast( node ) != 0; -} - -class PatchUndefined -{ -public: -STRING_CONSTANT( Name, "Patch" ); -}; - -inline bool Node_isPatch( scene::Node& node ){ - return NodeTypeCast::cast( node ) != 0; -} - -inline bool Node_isPrimitive( scene::Node& node ){ -#if 1 - return Node_isBrush( node ) || Node_isPatch( node ); -#else - return !node.isRoot(); -#endif -} - -inline bool Node_isHidden( scene::Node& node ){ - return node.isHidden(); -} - -class ParentBrushes : public scene::Traversable::Walker -{ -scene::Node& m_parent; -public: -ParentBrushes( scene::Node& parent ) - : m_parent( parent ){ -} -bool pre( scene::Node& node ) const { - return false; -} -void post( scene::Node& node ) const { - if ( Node_isPrimitive( node ) ) { - Node_getTraversable( m_parent )->insert( node ); - } -} -}; - -inline void parentBrushes( scene::Node& subgraph, scene::Node& parent ){ - Node_getTraversable( subgraph )->traverse( ParentBrushes( parent ) ); -} - -class HasBrushes : public scene::Traversable::Walker -{ -bool& m_hasBrushes; -public: -HasBrushes( bool& hasBrushes ) - : m_hasBrushes( hasBrushes ){ - m_hasBrushes = true; -} -bool pre( scene::Node& node ) const { - if ( !Node_isPrimitive( node ) ) { - m_hasBrushes = false; - } - return false; -} -}; - -inline bool node_is_group( scene::Node& node ){ - scene::Traversable* traversable = Node_getTraversable( node ); - if ( traversable != 0 ) { - bool hasBrushes = false; - traversable->traverse( HasBrushes( hasBrushes ) ); - return hasBrushes; - } - return false; -} - -typedef TypeCastTable InstanceTypeCastTable; - -template -class InstanceType : public StaticTypeSystemInitialiser -{ -TypeId m_typeId; -public: -typedef typename Type::Name Name; -InstanceType() : m_typeId( INSTANCETYPEID_NONE ){ - StaticTypeSystemInitialiser::instance().addInitialiser( InitialiseCaller( *this ) ); -} -void initialise(){ - m_typeId = GlobalSceneGraph().getInstanceTypeId( Name() ); -} -typedef MemberCaller, void (), &InstanceType::initialise> InitialiseCaller; -TypeId getTypeId(){ -#if GDEF_DEBUG - ASSERT_MESSAGE( m_typeId != INSTANCETYPEID_NONE, "instance-type " << makeQuoted( Name() ) << " used before being initialised" ); -#endif - return m_typeId; -} -}; - -template -class StaticInstanceType -{ -public: -enum unnamed0 { SIZE = INSTANCETYPEID_MAX }; -static TypeId getTypeId(){ - return Static< InstanceType >::instance().getTypeId(); -} -}; - -template -class InstanceStaticCast : - public CastInstaller< - StaticInstanceType, - StaticCast - > -{ -}; - -template -class InstanceContainedCast : - public CastInstaller< - StaticInstanceType, - ContainedCast - > -{ -}; - -template -class InstanceIdentityCast : - public CastInstaller< - StaticInstanceType, - IdentityCast - > -{ -}; - - -inline Selectable* Instance_getSelectable( scene::Instance& instance ); -inline const Selectable* Instance_getSelectable( const scene::Instance& instance ); - -inline Bounded* Instance_getBounded( scene::Instance& instance ); -inline const Bounded* Instance_getBounded( const scene::Instance& instance ); - -namespace scene -{ -class Instance -{ -class AABBAccumulateWalker : public scene::Graph::Walker -{ -AABB& m_aabb; -mutable std::size_t m_depth; -public: -AABBAccumulateWalker( AABB& aabb ) : m_aabb( aabb ), m_depth( 0 ){ -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( m_depth == 1 ) { - aabb_extend_by_aabb_safe( m_aabb, instance.worldAABB() ); - } - return ++m_depth != 2; -} -void post( const scene::Path& path, scene::Instance& instance ) const { - --m_depth; -} -}; - - -class TransformChangedWalker : public scene::Graph::Walker -{ -public: -bool pre( const scene::Path& path, scene::Instance& instance ) const { - instance.transformChangedLocal(); - return true; -} -}; - -class ParentSelectedChangedWalker : public scene::Graph::Walker -{ -public: -bool pre( const scene::Path& path, scene::Instance& instance ) const { - instance.parentSelectedChanged(); - return true; -} -}; - -class ChildSelectedWalker : public scene::Graph::Walker -{ -bool& m_childSelected; -mutable std::size_t m_depth; -public: -ChildSelectedWalker( bool& childSelected ) : m_childSelected( childSelected ), m_depth( 0 ){ - m_childSelected = false; -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( m_depth == 1 && !m_childSelected ) { - m_childSelected = instance.isSelected() || instance.childSelected(); - } - return ++m_depth != 2; -} -void post( const scene::Path& path, scene::Instance& instance ) const { - --m_depth; -} -}; - -Path m_path; -Instance* m_parent; -void* m_instance; -InstanceTypeCastTable& m_casts; - -mutable Matrix4 m_local2world; -mutable AABB m_bounds; -mutable AABB m_childBounds; -mutable bool m_transformChanged; -mutable bool m_transformMutex; -mutable bool m_boundsChanged; -mutable bool m_boundsMutex; -mutable bool m_childBoundsChanged; -mutable bool m_childBoundsMutex; -mutable bool m_isSelected; -mutable bool m_isSelectedChanged; -mutable bool m_childSelected; -mutable bool m_childSelectedChanged; -mutable bool m_parentSelected; -mutable bool m_parentSelectedChanged; -Callback m_childSelectedChangedCallback; -Callback m_transformChangedCallback; - - -void evaluateTransform() const { - if ( m_transformChanged ) { - ASSERT_MESSAGE( !m_transformMutex, "re-entering transform evaluation" ); - m_transformMutex = true; - - m_local2world = ( m_parent != 0 ) ? m_parent->localToWorld() : g_matrix4_identity; - TransformNode* transformNode = Node_getTransformNode( m_path.top() ); - if ( transformNode != 0 ) { - matrix4_multiply_by_matrix4( m_local2world, transformNode->localToParent() ); - } - - m_transformMutex = false; - m_transformChanged = false; - } -} -void evaluateChildBounds() const { - if ( m_childBoundsChanged ) { - ASSERT_MESSAGE( !m_childBoundsMutex, "re-entering bounds evaluation" ); - m_childBoundsMutex = true; - - m_childBounds = AABB(); - - GlobalSceneGraph().traverse_subgraph( AABBAccumulateWalker( m_childBounds ), m_path ); - - m_childBoundsMutex = false; - m_childBoundsChanged = false; - } -} -void evaluateBounds() const { - if ( m_boundsChanged ) { - ASSERT_MESSAGE( !m_boundsMutex, "re-entering bounds evaluation" ); - m_boundsMutex = true; - - m_bounds = childBounds(); - - const Bounded* bounded = Instance_getBounded( *this ); - if ( bounded != 0 ) { - aabb_extend_by_aabb_safe( - m_bounds, - aabb_for_oriented_aabb_safe( bounded->localAABB(), localToWorld() ) - ); - } - - m_boundsMutex = false; - m_boundsChanged = false; - } -} - -Instance( const scene::Instance& other ); -Instance& operator=( const scene::Instance& other ); -public: - -Instance( const scene::Path& path, Instance* parent, void* instance, InstanceTypeCastTable& casts ) : - m_path( path ), - m_parent( parent ), - m_instance( instance ), - m_casts( casts ), - m_local2world( g_matrix4_identity ), - m_transformChanged( true ), - m_transformMutex( false ), - m_boundsChanged( true ), - m_boundsMutex( false ), - m_childBoundsChanged( true ), - m_childBoundsMutex( false ), - m_isSelectedChanged( true ), - m_childSelectedChanged( true ), - m_parentSelectedChanged( true ){ - ASSERT_MESSAGE( ( parent == 0 ) == ( path.size() == 1 ), "instance has invalid parent" ); -} -virtual ~Instance(){ -} - -const scene::Path& path() const { - return m_path; -} - -void* cast( TypeId typeId ) const { - return m_casts.cast( typeId, m_instance ); -} - -const Matrix4& localToWorld() const { - evaluateTransform(); - return m_local2world; -} -void transformChangedLocal(){ - ASSERT_NOTNULL( m_parent ); - m_transformChanged = true; - m_boundsChanged = true; - m_childBoundsChanged = true; - m_transformChangedCallback(); -} -void transformChanged(){ - GlobalSceneGraph().traverse_subgraph( TransformChangedWalker(), m_path ); - boundsChanged(); -} -void setTransformChangedCallback( const Callback& callback ){ - m_transformChangedCallback = callback; -} - - -const AABB& worldAABB() const { - evaluateBounds(); - return m_bounds; -} -const AABB& childBounds() const { - evaluateChildBounds(); - return m_childBounds; -} -void boundsChanged(){ - m_boundsChanged = true; - m_childBoundsChanged = true; - if ( m_parent != 0 ) { - m_parent->boundsChanged(); - } - GlobalSceneGraph().boundsChanged(); -} - -void childSelectedChanged(){ - m_childSelectedChanged = true; - m_childSelectedChangedCallback(); - if ( m_parent != 0 ) { - m_parent->childSelectedChanged(); - } -} -bool childSelected() const { - if ( m_childSelectedChanged ) { - m_childSelectedChanged = false; - GlobalSceneGraph().traverse_subgraph( ChildSelectedWalker( m_childSelected ), m_path ); - } - return m_childSelected; -} - -void setChildSelectedChangedCallback( const Callback& callback ){ - m_childSelectedChangedCallback = callback; -} -void selectedChanged(){ - m_isSelectedChanged = true; - if ( m_parent != 0 ) { - m_parent->childSelectedChanged(); - } - GlobalSceneGraph().traverse_subgraph( ParentSelectedChangedWalker(), m_path ); -} -bool isSelected() const { - if ( m_isSelectedChanged ) { - m_isSelectedChanged = false; - const Selectable* selectable = Instance_getSelectable( *this ); - m_isSelected = selectable != 0 && selectable->isSelected(); - } - return m_isSelected; -} - -void parentSelectedChanged(){ - m_parentSelectedChanged = true; -} -bool parentSelected() const { - if ( m_parentSelectedChanged ) { - m_parentSelectedChanged = false; - m_parentSelected = m_parent != 0 && ( m_parent->isSelected() || m_parent->parentSelected() ); - } - return m_parentSelected; -} -}; -} - -template -class InstanceTypeCast -{ -public: -static Type* cast( scene::Instance& instance ){ - return static_cast( instance.cast( StaticInstanceType::getTypeId() ) ); -} -static const Type* cast( const scene::Instance& instance ){ - return static_cast( instance.cast( StaticInstanceType::getTypeId() ) ); -} -}; - -template -class InstanceWalker : public scene::Graph::Walker -{ -const Functor& m_functor; -public: -InstanceWalker( const Functor& functor ) : m_functor( functor ){ -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - m_functor( instance ); - return true; -} -}; - -template -class ChildInstanceWalker : public scene::Graph::Walker -{ -const Functor& m_functor; -mutable std::size_t m_depth; -public: -ChildInstanceWalker( const Functor& functor ) : m_functor( functor ), m_depth( 0 ){ -} -bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( m_depth == 1 ) { - m_functor( instance ); - } - return ++m_depth != 2; -} -void post( const scene::Path& path, scene::Instance& instance ) const { - --m_depth; -} -}; - -template -class InstanceApply : public Functor -{ -public: -InstanceApply( const Functor& functor ) : Functor( functor ){ -} -void operator()( scene::Instance& instance ) const { - Type* result = InstanceTypeCast::cast( instance ); - if ( result != 0 ) { - Functor::operator()( *result ); - } -} -}; - -inline Selectable* Instance_getSelectable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} -inline const Selectable* Instance_getSelectable( const scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - -template -inline void Scene_forEachChildSelectable( const Functor& functor, const scene::Path& path ){ - GlobalSceneGraph().traverse_subgraph( ChildInstanceWalker< InstanceApply >( functor ), path ); -} - -class SelectableSetSelected -{ -bool m_selected; -public: -SelectableSetSelected( bool selected ) : m_selected( selected ){ -} -void operator()( Selectable& selectable ) const { - selectable.setSelected( m_selected ); -} -}; - -inline Bounded* Instance_getBounded( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} -inline const Bounded* Instance_getBounded( const scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - -inline Transformable* Instance_getTransformable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} -inline const Transformable* Instance_getTransformable( const scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - - -inline ComponentSelectionTestable* Instance_getComponentSelectionTestable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - -inline ComponentEditable* Instance_getComponentEditable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - -inline ComponentSnappable* Instance_getComponentSnappable( scene::Instance& instance ){ - return InstanceTypeCast::cast( instance ); -} - - -inline void Instance_setSelected( scene::Instance& instance, bool selected ){ - Selectable* selectable = Instance_getSelectable( instance ); - if ( selectable != 0 ) { - selectable->setSelected( selected ); - } -} - -inline bool Instance_isSelected( scene::Instance& instance ){ - Selectable* selectable = Instance_getSelectable( instance ); - if ( selectable != 0 ) { - return selectable->isSelected(); - } - return false; -} - -inline scene::Instance& findInstance( const scene::Path& path ){ - scene::Instance* instance = GlobalSceneGraph().find( path ); - ASSERT_MESSAGE( instance != 0, "findInstance: path not found in scene-graph" ); - return *instance; -} - -inline void selectPath( const scene::Path& path, bool selected ){ - Instance_setSelected( findInstance( path ), selected ); -} - -class SelectChildren : public scene::Traversable::Walker -{ -mutable scene::Path m_path; -public: -SelectChildren( const scene::Path& root ) - : m_path( root ){ -} -bool pre( scene::Node& node ) const { - m_path.push( makeReference( node ) ); - selectPath( m_path, true ); - return false; -} -void post( scene::Node& node ) const { - m_path.pop(); -} -}; - -inline void Entity_setSelected( scene::Instance& entity, bool selected ){ - scene::Node& node = entity.path().top(); - if ( node_is_group( node ) ) { - Node_getTraversable( node )->traverse( SelectChildren( entity.path() ) ); - } - else - { - Instance_setSelected( entity, selected ); - } -} - -inline bool Entity_isSelected( scene::Instance& entity ){ - if ( node_is_group( entity.path().top() ) ) { - return entity.childSelected(); - } - return Instance_isSelected( entity ); -} - - - -class InstanceCounter -{ -public: -unsigned int m_count; -InstanceCounter() : m_count( 0 ){ -} -}; - - -class Counter -{ -public: -virtual void increment() = 0; -virtual void decrement() = 0; -}; - -#include "generic/callback.h" - -class SimpleCounter : public Counter -{ -Callback m_countChanged; -std::size_t m_count; -public: -void setCountChangedCallback( const Callback& countChanged ){ - m_countChanged = countChanged; -} -void increment(){ - ++m_count; - m_countChanged(); -} -void decrement(){ - --m_count; - m_countChanged(); -} -std::size_t get() const { - return m_count; -} -}; - - -template -class ConstReference; -typedef ConstReference PathConstReference; - -#include "generic/referencecounted.h" -typedef SmartReference > NodeSmartReference; - - -#endif diff --git a/libs/script/Makefile b/libs/script/Makefile deleted file mode 100644 index 24449cc..0000000 --- a/libs/script/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ -_.o - -# binary target -../libscript.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -_.o: _.cpp scripttokeniser.h scripttokenwriter.h - -clean: - -rm -f *.o ../libscript.a diff --git a/libs/script/_.cpp b/libs/script/_.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/libs/script/scripttokeniser.h b/libs/script/scripttokeniser.h deleted file mode 100644 index 8744aec..0000000 --- a/libs/script/scripttokeniser.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SCRIPT_SCRIPTTOKENISER_H ) -#define INCLUDED_SCRIPT_SCRIPTTOKENISER_H - -#include "iscriplib.h" - -class ScriptTokeniser : public Tokeniser -{ -enum CharType -{ - eWhitespace, - eCharToken, - eNewline, - eCharQuote, - eCharSolidus, - eCharStar, - eCharSpecial, -}; - -typedef bool ( ScriptTokeniser::*Tokenise )( char c ); - -Tokenise m_stack[3]; -Tokenise* m_state; -SingleCharacterInputStream m_istream; -std::size_t m_scriptline; -std::size_t m_scriptcolumn; - -char m_token[MAXTOKEN]; -char* m_write; - -char m_current; -bool m_eof; -bool m_crossline; -bool m_unget; -bool m_emit; - -bool m_special; - -CharType charType( const char c ){ - switch ( c ) - { - case '\n': return eNewline; - case '"': return eCharQuote; - case '/': return eCharSolidus; - case '*': return eCharStar; - case '{': case '(': case '}': case ')': case '[': case ']': case ',': case ':': return ( m_special ) ? eCharSpecial : eCharToken; - } - - if ( c > 32 ) { - return eCharToken; - } - return eWhitespace; -} - -Tokenise state(){ - return *m_state; -} -void push( Tokenise state ){ - ASSERT_MESSAGE( m_state != m_stack + 2, "token parser: illegal stack push" ); - *( ++m_state ) = state; -} -void pop(){ - ASSERT_MESSAGE( m_state != m_stack, "token parser: illegal stack pop" ); - --m_state; -} -void add( const char c ){ - if ( m_write < m_token + MAXTOKEN - 1 ) { - *m_write++ = c; - } -} -void remove(){ - ASSERT_MESSAGE( m_write > m_token, "no char to remove" ); - --m_write; -} - -bool tokeniseDefault( char c ){ - switch ( charType( c ) ) - { - case eNewline: - if ( !m_crossline ) { - globalErrorStream() << Unsigned( getLine() ) << ":" << Unsigned( getColumn() ) << ": unexpected end-of-line before token\n"; - return false; - } - break; - case eCharToken: - case eCharStar: - push( Tokenise( &ScriptTokeniser::tokeniseToken ) ); - add( c ); - break; - case eCharSpecial: - push( Tokenise( &ScriptTokeniser::tokeniseSpecial ) ); - add( c ); - break; - case eCharQuote: - push( Tokenise( &ScriptTokeniser::tokeniseQuotedToken ) ); - break; - case eCharSolidus: - push( Tokenise( &ScriptTokeniser::tokeniseSolidus ) ); - break; - default: - break; - } - return true; -} -bool tokeniseToken( char c ){ - switch ( charType( c ) ) - { - case eNewline: - case eWhitespace: - case eCharQuote: - case eCharSpecial: - pop(); - m_emit = true; // emit token - break; - case eCharSolidus: -#if 0 //SPoG: ignore comments in the middle of tokens. - push( Tokenise( &ScriptTokeniser::tokeniseSolidus ) ); - break; -#endif - case eCharToken: - case eCharStar: - add( c ); - break; - default: - break; - } - return true; -} -bool tokeniseQuotedToken( char c ){ - switch ( charType( c ) ) - { - case eNewline: - if ( m_crossline ) { - globalErrorStream() << Unsigned( getLine() ) << ":" << Unsigned( getColumn() ) << ": unexpected end-of-line in quoted token\n"; - return false; - } - break; - case eWhitespace: - case eCharToken: - case eCharSolidus: - case eCharStar: - case eCharSpecial: - add( c ); - break; - case eCharQuote: - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseEndQuote ) ); - break; - default: - break; - } - return true; -} -bool tokeniseSolidus( char c ){ - switch ( charType( c ) ) - { - case eNewline: - case eWhitespace: - case eCharQuote: - case eCharSpecial: - pop(); - add( '/' ); - m_emit = true; // emit single slash - break; - case eCharToken: - pop(); - add( '/' ); - add( c ); - break; - case eCharSolidus: - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseComment ) ); - break; // dont emit single slash - case eCharStar: - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseBlockComment ) ); - break; // dont emit single slash - default: - break; - } - return true; -} -bool tokeniseComment( char c ){ - if ( c == '\n' ) { - pop(); - if ( state() == Tokenise( &ScriptTokeniser::tokeniseToken ) ) { - pop(); - m_emit = true; // emit token immediatly preceding comment - } - } - return true; -} -bool tokeniseBlockComment( char c ){ - if ( c == '*' ) { - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseEndBlockComment ) ); - } - return true; -} -bool tokeniseEndBlockComment( char c ){ - switch ( c ) - { - case '/': - pop(); - if ( state() == Tokenise( &ScriptTokeniser::tokeniseToken ) ) { - pop(); - m_emit = true; // emit token immediatly preceding comment - } - break; // dont emit comment - case '*': - break; // no state change - default: - pop(); - push( Tokenise( &ScriptTokeniser::tokeniseBlockComment ) ); - break; - } - return true; -} -bool tokeniseEndQuote( char c ){ - pop(); - m_emit = true; // emit quoted token - return true; -} -bool tokeniseSpecial( char c ){ - pop(); - m_emit = true; // emit single-character token - return true; -} - -/// Returns true if a token was successfully parsed. -bool tokenise(){ - m_write = m_token; - while ( !eof() ) - { - char c = m_current; - - if ( !( ( *this ).*state() )( c ) ) { - // parse error - m_eof = true; - return false; - } - if ( m_emit ) { - m_emit = false; - return true; - } - - if ( c == '\n' ) { - ++m_scriptline; - m_scriptcolumn = 1; - } - else - { - ++m_scriptcolumn; - } - - m_eof = !m_istream.readChar( m_current ); - } - return m_write != m_token; -} - -const char* fillToken(){ - if ( !tokenise() ) { - return 0; - } - - add( '\0' ); - return m_token; -} - -bool eof(){ - return m_eof; -} - -public: -ScriptTokeniser( TextInputStream& istream, bool special ) - : m_state( m_stack ), - m_istream( istream ), - m_scriptline( 1 ), - m_scriptcolumn( 1 ), - m_crossline( false ), - m_unget( false ), - m_emit( false ), - m_special( special ){ - m_stack[0] = Tokenise( &ScriptTokeniser::tokeniseDefault ); - m_eof = !m_istream.readChar( m_current ); - m_token[MAXTOKEN - 1] = '\0'; -} -void release(){ - delete this; -} -void nextLine(){ - m_crossline = true; -} -const char* getToken(){ - if ( m_unget ) { - m_unget = false; - return m_token; - } - - return fillToken(); -} -void ungetToken(){ - ASSERT_MESSAGE( !m_unget, "can't unget more than one token" ); - m_unget = true; -} -std::size_t getLine() const { - return m_scriptline; -} -std::size_t getColumn() const { - return m_scriptcolumn; -} -}; - - -inline Tokeniser& NewScriptTokeniser( TextInputStream& istream ){ - return *( new ScriptTokeniser( istream, true ) ); -} - -inline Tokeniser& NewSimpleTokeniser( TextInputStream& istream ){ - return *( new ScriptTokeniser( istream, false ) ); -} - -#endif diff --git a/libs/script/scripttokenwriter.h b/libs/script/scripttokenwriter.h deleted file mode 100644 index 49ee57a..0000000 --- a/libs/script/scripttokenwriter.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SCRIPT_SCRIPTTOKENWRITER_H ) -#define INCLUDED_SCRIPT_SCRIPTTOKENWRITER_H - -#include "iscriplib.h" - -class SimpleTokenWriter : public TokenWriter -{ -public: -SimpleTokenWriter( TextOutputStream& ostream ) - : m_ostream( ostream ), m_separator( '\n' ){ -} -~SimpleTokenWriter(){ - writeSeparator(); -} -void release(){ - delete this; -} -void nextLine(){ - m_separator = '\n'; -} -void writeToken( const char* token ){ - ASSERT_MESSAGE( strchr( token, ' ' ) == 0, "token contains whitespace: " ); - writeSeparator(); - m_ostream << token; -} -void writeString( const char* string ){ - writeSeparator(); - m_ostream << '"' << string << '"'; -} -void writeInteger( int i ){ - writeSeparator(); - m_ostream << i; -} -void writeUnsigned( std::size_t i ){ - writeSeparator(); - m_ostream << Unsigned( i ); -} -void writeFloat( double f ){ - writeSeparator(); - m_ostream << Decimal( f ); -} - -private: -void writeSeparator(){ - m_ostream << m_separator; - m_separator = ' '; -} -TextOutputStream& m_ostream; -char m_separator; -}; - -inline TokenWriter& NewSimpleTokenWriter( TextOutputStream& ostream ){ - return *( new SimpleTokenWriter( ostream ) ); -} - -#endif diff --git a/libs/selectionlib.h b/libs/selectionlib.h deleted file mode 100644 index 6789046..0000000 --- a/libs/selectionlib.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_SELECTIONLIB_H ) -#define INCLUDED_SELECTIONLIB_H - -#include "iselection.h" -#include "generic/callback.h" -#include "scenelib.h" -#include - -class SelectableBool : public Selectable -{ -bool m_selected; -public: -SelectableBool() - : m_selected( false ) -{ -} - -void setSelected( bool select = true ){ - m_selected = select; -} -bool isSelected() const { - return m_selected; -} -}; - -class ObservedSelectable : public Selectable -{ -SelectionChangeCallback m_onchanged; -bool m_selected; -public: -ObservedSelectable( const SelectionChangeCallback& onchanged ) : m_onchanged( onchanged ), m_selected( false ){ -} -ObservedSelectable( const ObservedSelectable& other ) : Selectable( other ), m_onchanged( other.m_onchanged ), m_selected( false ){ - setSelected( other.isSelected() ); -} -ObservedSelectable& operator=( const ObservedSelectable& other ){ - setSelected( other.isSelected() ); - return *this; -} -~ObservedSelectable(){ - setSelected( false ); -} - -void setSelected( bool select ){ - if ( select ^ m_selected ) { - m_selected = select; - - m_onchanged( *this ); - } -} -bool isSelected() const { - return m_selected; -} -}; - -class SelectableInstance : public scene::Instance -{ -class TypeCasts -{ -InstanceTypeCastTable m_casts; -public: -TypeCasts(){ - InstanceContainedCast::install( m_casts ); -} -InstanceTypeCastTable& get(){ - return m_casts; -} -}; - -ObservedSelectable m_selectable; -public: - -typedef LazyStatic StaticTypeCasts; - -SelectableInstance( const scene::Path& path, scene::Instance* parent, void* instance = 0, InstanceTypeCastTable& casts = StaticTypeCasts::instance().get() ) : - Instance( path, parent, instance != 0 ? instance : this, casts ), - m_selectable( SelectedChangedCaller( *this ) ){ -} - -Selectable& get( NullType){ - return m_selectable; -} - -Selectable& getSelectable(){ - return m_selectable; -} -const Selectable& getSelectable() const { - return m_selectable; -} - -void selectedChanged( const Selectable& selectable ){ - GlobalSelectionSystem().getObserver ( SelectionSystem::ePrimitive )( selectable ); - GlobalSelectionSystem().onSelectedChanged( *this, selectable ); - - Instance::selectedChanged(); -} -typedef MemberCaller SelectedChangedCaller; -}; - - -template -inline bool range_check( Iterator start, Iterator finish, Iterator iter ){ - for (; start != finish; ++start ) - { - if ( start == iter ) { - return true; - } - } - return false; -} - -#include - -template -class SelectionList -{ -typedef std::list List; -List m_selection; -public: -typedef typename List::iterator iterator; -typedef typename List::const_iterator const_iterator; - -iterator begin(){ - return m_selection.begin(); -} -const_iterator begin() const { - return m_selection.begin(); -} -iterator end(){ - return m_selection.end(); -} -const_iterator end() const { - return m_selection.end(); -} -bool empty() const { - return m_selection.empty(); -} -std::size_t size() const { - return m_selection.size(); -} -Selected& back(){ - return *m_selection.back(); -} -Selected& back() const { - return *m_selection.back(); -} -void append( Selected& selected ){ - m_selection.push_back( &selected ); -} -void erase( Selected& selected ){ - typename List::reverse_iterator i = std::find( m_selection.rbegin(), m_selection.rend(), &selected ); - ASSERT_MESSAGE( i != m_selection.rend(), "selection-tracking error" ); - ASSERT_MESSAGE( range_check( m_selection.begin(), m_selection.end(), --i.base() ), "selection-tracking error" ); - m_selection.erase( --i.base() ); -} -}; - - -#endif diff --git a/libs/shaderlib.h b/libs/shaderlib.h deleted file mode 100644 index bcd540e..0000000 --- a/libs/shaderlib.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_SHADERLIB_H ) -#define INCLUDED_SHADERLIB_H - -#include "string/string.h" -#include "character.h" -#include "ishaders.h" - -inline bool shader_equal( const char* shader, const char* other ){ - return string_equal_nocase( shader, other ); -} - -inline bool shader_equal_n( const char* shader, const char* other, std::size_t n ){ - return string_equal_nocase_n( shader, other, n ); -} - -inline bool shader_less( const char* shader, const char* other ){ - return string_less_nocase( shader, other ); -} - -inline bool shader_equal_prefix( const char* string, const char* prefix ){ - return shader_equal_n( string, prefix, string_length( prefix ) ); -} - -class shader_less_t -{ -public: -bool operator()( const CopiedString& shader, const CopiedString& other ) const { - return shader_less( shader.c_str(), other.c_str() ); -} -}; - -inline bool shader_valid( const char* shader ){ - return string_is_ascii( shader ) - && strchr( shader, ' ' ) == 0 - && strchr( shader, '\n' ) == 0 - && strchr( shader, '\r' ) == 0 - && strchr( shader, '\t' ) == 0 - && strchr( shader, '\v' ) == 0 - && strchr( shader, '\\' ) == 0; -} - -inline const char* GlobalTexturePrefix_get(){ - return GlobalShaderSystem().getTexturePrefix(); -} - -inline bool shader_is_texture( const char* name ){ - return shader_equal_prefix( name, GlobalTexturePrefix_get() ); -} - -inline const char* shader_get_textureName( const char* name ){ - return name + string_length( GlobalTexturePrefix_get() ); -} - -inline bool texdef_name_valid( const char* name ){ - return shader_valid( name ) && shader_is_texture( name ); -} - -inline const char* texdef_name_default(){ - return GlobalTexturePrefix_get(); -} - - -#endif diff --git a/libs/signal/Makefile b/libs/signal/Makefile deleted file mode 100644 index bfd9233..0000000 --- a/libs/signal/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - signal.o - -# binary target -../libsignal.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -signal.o: signal.cpp isignal.h signal.h signalfwd.h - -clean: - -rm -f *.o ../libsignal.a diff --git a/libs/signal/isignal.h b/libs/signal/isignal.h deleted file mode 100644 index 66075be..0000000 --- a/libs/signal/isignal.h +++ /dev/null @@ -1,166 +0,0 @@ - -#if !defined( INCLUDED_ISIGNAL_H ) -#define INCLUDED_ISIGNAL_H - -#include "generic/callback.h" -#include "signal/signalfwd.h" - -class SignalHandlerResult -{ -bool value; -public: -explicit SignalHandlerResult( bool value ) : value( value ){ -} -bool operator==( SignalHandlerResult other ) const { - return value == other.value; -} -bool operator!=( SignalHandlerResult other ) const { - return !operator==( other ); -} -}; - -const SignalHandlerResult SIGNAL_CONTINUE_EMISSION = SignalHandlerResult( false ); -const SignalHandlerResult SIGNAL_STOP_EMISSION = SignalHandlerResult( true ); - -template -class SignalHandlerCallerN; - -template -class SignalHandlerCallerN { -public: -using func = SignalHandlerResult(Ts ...); - -static SignalHandlerResult call(Ts... args) { - Caller::call(args ...); - return SIGNAL_CONTINUE_EMISSION; -} -}; - -template -using SignalHandlerCaller = SignalHandlerCallerN >; - -template -using SignalHandlerCaller1 = SignalHandlerCaller; - -template -using SignalHandlerCaller2 = SignalHandlerCaller; - -template -using SignalHandlerCaller3 = SignalHandlerCaller; - -template -using SignalHandlerCaller4 = SignalHandlerCaller; - -template -class TypeEqual { -public: -using type = False; -}; - -template -class TypeEqual { -public: -using type = True; -}; - -template class Wrapper> -class SignalHandlerN : public CB { -public: -template -SignalHandlerN(const BindFirstOpaque &caller) - : CB(BindFirstOpaque, - get_result_type - >::type>(caller.getBound())) { -} -}; - -class SignalHandler : public SignalHandlerN, SignalHandlerCaller1> { -using SignalHandlerN, SignalHandlerCaller1>::SignalHandlerN; -}; - -template -inline SignalHandler makeSignalHandler( const BindFirstOpaque& caller ){ - return SignalHandler( caller ); -} -template -inline SignalHandler makeSignalHandler(const Caller &caller, get_argument callee) { - return SignalHandler( BindFirstOpaque( callee ) ); -} - -template -class SignalHandler1 : public SignalHandlerN, SignalHandlerCaller2> { -using SignalHandlerN, SignalHandlerCaller2>::SignalHandlerN; -}; - -template -inline SignalHandler1 > makeSignalHandler1(const BindFirstOpaque &caller) { - return SignalHandler1 >(caller); -} -template -inline SignalHandler1 > -makeSignalHandler1(const Caller &caller, get_argument callee) { - return SignalHandler1 >(BindFirstOpaque(callee)); -} - -template -class SignalHandler2 - : public SignalHandlerN, SignalHandlerCaller3> { -using SignalHandlerN, SignalHandlerCaller3>::SignalHandlerN; -}; - -template -inline SignalHandler2< - get_argument, - get_argument - > makeSignalHandler2(const BindFirstOpaque &caller) { - return SignalHandler2< - get_argument, - get_argument - >( caller ); -} -template -inline SignalHandler2< - get_argument, - get_argument - > makeSignalHandler2(const Caller &caller, get_argument callee) { - return SignalHandler2< - get_argument, - get_argument - >(BindFirstOpaque(callee)); -} - -template -class SignalHandler3 - : public SignalHandlerN, SignalHandlerCaller4> { -using SignalHandlerN, SignalHandlerCaller4>::SignalHandlerN; -}; - -template -inline SignalHandler3< - get_argument, - get_argument, - get_argument - > makeSignalHandler3(const BindFirstOpaque &caller) { - return SignalHandler3< - get_argument, - get_argument, - get_argument - >( caller ); -} -template -inline SignalHandler3< - get_argument, - get_argument, - get_argument - > makeSignalHandler3(const Caller &caller, get_argument callee) { - return SignalHandler3< - get_argument, - get_argument, - get_argument - >(BindFirstOpaque(callee)); -} - -#endif diff --git a/libs/signal/signal.cpp b/libs/signal/signal.cpp deleted file mode 100644 index 703901d..0000000 --- a/libs/signal/signal.cpp +++ /dev/null @@ -1,96 +0,0 @@ - -#include "signal.h" - - - -namespace -{ -class Test -{ -}; -class A1 -{ -}; -class A2 -{ -}; -class A3 -{ -}; - -SignalHandlerResult handler0( Test& ){ - return SIGNAL_CONTINUE_EMISSION; -} -typedef Function TestHandler0; - -int function0( Test& ){ - return 7; -} -typedef Function TestFunction0; - -SignalHandlerResult handler1( Test&, A1 ){ - return SIGNAL_CONTINUE_EMISSION; -} -typedef Function TestHandler1; - -void function1( Test&, A1 ){ -} -typedef ReferenceCaller TestFunction1; - -SignalHandlerResult handler2( Test&, A1, A2 ){ - return SIGNAL_CONTINUE_EMISSION; -} -typedef Function TestHandler2; - -void function2( Test&, A1, A2 ){ -} -typedef Function TestFunction2; - -SignalHandlerResult handler3( Test&, A1, A2, A3 ){ - return SIGNAL_CONTINUE_EMISSION; -} -typedef Function TestHandler3; - -void function3( Test&, A1, A2, A3 ){ -} -typedef Function TestFunction3; - -void testSignals(){ - Test test; - { - Signal0 e0; - Signal0::handler_id_type a = e0.connectLast( makeSignalHandler( TestHandler0(), test ) ); // signal handler from direct caller returning result - Signal0::handler_id_type b = e0.connectFirst( makeSignalHandler( TestFunction0(), test ) ); // signal handler from direct caller returning int - e0(); - e0.disconnect( a ); - e0.disconnect( b ); - } - { - typedef Signal1 Signal1Test; - Signal1Test e1; - Signal1Test::handler_id_type a = e1.connectLast( makeSignalHandler1( TestHandler1(), test ) ); // signal handler from direct caller with one argument, returning result - Signal1Test::handler_id_type b = e1.connectFirst( makeSignalHandler1( TestFunction1( test ) ) ); // signal handler from opaque caller with one argument, returning void - e1( A1() ); - e1.disconnect( a ); - e1.disconnect( b ); - } - { - typedef Signal2 Signal2Test; - Signal2Test e2; - Signal2Test::handler_id_type a = e2.connectLast( makeSignalHandler2( TestHandler2(), test ) ); // signal handler from direct caller with two arguments, returning result - Signal2Test::handler_id_type b = e2.connectLast( makeSignalHandler2( TestFunction2(), test ) ); // signal handler from direct caller with two arguments, returning void - e2( A1(), A2() ); - e2.disconnect( a ); - e2.disconnect( b ); - } - { - typedef Signal3 Signal3Test; - Signal3Test e3; - Signal3Test::handler_id_type a = e3.connectLast( makeSignalHandler3( TestHandler3(), test ) ); // signal handler from direct caller with three arguments, returning result - Signal3Test::handler_id_type b = e3.connectLast( makeSignalHandler3( TestFunction3(), test ) ); // signal handler from direct caller with three arguments, returning void - e3( A1(), A2(), A3() ); - e3.disconnect( a ); - e3.disconnect( b ); - } -} -} diff --git a/libs/signal/signal.h b/libs/signal/signal.h deleted file mode 100644 index f10d8bb..0000000 --- a/libs/signal/signal.h +++ /dev/null @@ -1,342 +0,0 @@ - -#if !defined( INCLUDED_SIGNAL_H ) -#define INCLUDED_SIGNAL_H - -#include "isignal.h" -#include "memory/allocator.h" -#include "debugging/debugging.h" -#include - -namespace ListDetail -{ -struct ListNodeBase -{ - ListNodeBase* next; - ListNodeBase* prev; -}; - -inline void list_initialise( ListNodeBase& self ){ - self.next = self.prev = &self; -} - -inline void list_swap( ListNodeBase& self, ListNodeBase& other ){ - ListNodeBase tmp( self ); - if ( other.next == &other ) { - list_initialise( self ); - } - else - { - self = other; - self.next->prev = self.prev->next = &self; - } - if ( tmp.next == &self ) { - list_initialise( other ); - } - else - { - other = tmp; - other.next->prev = other.prev->next = &other; - } -} - -inline void node_link( ListNodeBase* node, ListNodeBase* next ){ - node->next = next; - node->prev = next->prev; - next->prev = node; - node->prev->next = node; -} -inline void node_unlink( ListNodeBase* node ){ - node->prev->next = node->next; - node->next->prev = node->prev; -} - -template -struct ListNode : public ListNodeBase -{ - Value value; - - ListNode( const Value& value ) : value( value ){ - } - ListNode* getNext() const { - return static_cast( next ); - } - ListNode* getPrev() const { - return static_cast( prev ); - } -}; - -template -class NonConstTraits -{ -public: -typedef Type value_type; -typedef value_type* pointer; -typedef value_type& reference; - -template -struct rebind -{ - typedef NonConstTraits other; -}; -}; - -template -class ConstTraits -{ -public: -typedef Type value_type; -typedef const value_type* pointer; -typedef const value_type& reference; - -template -struct rebind -{ - typedef ConstTraits other; -}; -}; - -template -class ListIterator -{ -public: -typedef std::bidirectional_iterator_tag iterator_category; -typedef std::ptrdiff_t difference_type; -typedef difference_type distance_type; -typedef typename Traits::value_type value_type; -typedef typename Traits::pointer pointer; -typedef typename Traits::reference reference; - -private: -typedef ListNode Node; -typedef typename Traits::template rebind::other NodeTraits; -typedef typename NodeTraits::pointer NodePointer; -typedef typename Traits::template rebind< Opaque >::other OpaqueTraits; -typedef typename OpaqueTraits::pointer OpaquePointer; -NodePointer m_node; - -void increment(){ - m_node = m_node->getNext(); -} -void decrement(){ - m_node = m_node->getPrev(); -} - - -public: -explicit ListIterator( NodePointer node ) : m_node( node ){ -} -explicit ListIterator( OpaquePointer p ) : m_node( reinterpret_cast( p ) ){ -} - -NodePointer node(){ - return m_node; -} -OpaquePointer opaque() const { - return reinterpret_cast( m_node ); -} - -bool operator==( const ListIterator& other ) const { - return m_node == other.m_node; -} -bool operator!=( const ListIterator& other ) const { - return !operator==( other ); -} -ListIterator& operator++(){ - increment(); - return *this; -} -ListIterator operator++( int ){ - ListIterator tmp = *this; - increment(); - return tmp; -} -ListIterator& operator--(){ - decrement(); - return *this; -} -ListIterator operator--( int ){ - ListIterator tmp = *this; - decrement(); - return tmp; -} -reference operator*() const { - return m_node->value; -} -pointer operator->() const { - return &( operator*() ); -} -}; -} - -template > -class List : private Allocator -{ -typedef ListDetail::ListNode Node; -ListDetail::ListNodeBase list; -typedef typename Allocator::template rebind::other NodeAllocator; - -Node* newNode( const Value& value ){ - return new ( NodeAllocator( *this ).allocate( 1 ) )Node( value ); -} -void deleteNode( Node* node ){ - node->~Node(); - NodeAllocator( *this ).deallocate( node, 1 ); -} -public: -typedef Value value_type; -typedef ListDetail::ListIterator< ListDetail::NonConstTraits > iterator; -typedef ListDetail::ListIterator< ListDetail::ConstTraits > const_iterator; - -List(){ - list_initialise( list ); -} -explicit List( const Allocator& allocator ) : Allocator( allocator ){ - list_initialise( list ); -} -~List(){ - for (; list.next != &list; ) - { - Node* node = static_cast( list.next ); - list.next = list.next->next; - deleteNode( node ); - } -} -iterator begin(){ - return iterator( static_cast( list.next ) ); -} -iterator end(){ - return iterator( static_cast( &list ) ); -} -const_iterator begin() const { - return const_iterator( static_cast( list.next ) ); -} -const_iterator end() const { - return const_iterator( static_cast( &list ) ); -} -void push_back( const Value& value ){ - insert( end(), value ); -} -void pop_back( const Value& value ){ - erase( --end(), value ); -} -void push_front( const Value& value ){ - insert( begin(), value ); -} -void pop_front( const Value& value ){ - erase( begin(), value ); -} -iterator insert( iterator pos, const Value& value ){ - Node* node = newNode( value ); - node_link( node, pos.node() ); - return iterator( node ); -} -iterator erase( iterator pos ){ - Node* node = pos.node(); - Node* next = node->getNext(); - node_unlink( node ); - deleteNode( node ); - return iterator( next ); -} -}; - -template -class SignalBase -{ -typedef List SignalList; -SignalList events; - -public: - -typedef Functor handler_type; -typedef Handle< Opaque > handler_id_type; -typedef typename SignalList::iterator iterator; -typedef typename SignalList::const_iterator const_iterator; -iterator begin(){ - return events.begin(); -} -iterator end(){ - return events.end(); -} -const_iterator begin() const { - return events.begin(); -} -const_iterator end() const { - return events.end(); -} -handler_id_type connectFirst( const Functor& event ){ - events.push_front( event ); - return handler_id_type( begin().opaque() ); -} -handler_id_type connectLast( const Functor& event ){ - events.push_back( event ); - return handler_id_type( ( --end() ).opaque() ); -} -bool isConnected( handler_id_type id ){ - for ( iterator i = begin(); i != end(); ++i ) - { - if ( id.get() == i.opaque() ) { - return true; - } - } - return false; -} -handler_id_type connectBefore( handler_id_type id, const Functor& event ){ - ASSERT_MESSAGE( isConnected( id ), "SignalBase::connectBefore: invalid id" ); - return events.insert( iterator( id.get() ), event ).opaque(); -} -handler_id_type connectAfter( handler_id_type id, const Functor& event ){ - ASSERT_MESSAGE( isConnected( id ), "SignalBase::connectAfter: invalid id" ); - return events.insert( ++iterator( id.get() ), event ).opaque(); -} -void disconnect( handler_id_type id ){ - ASSERT_MESSAGE( isConnected( id ), "SignalBase::disconnect: invalid id" ); - events.erase( iterator( id.get() ) ); -} -}; - -///\brief -// It is safe to disconnect the signal handler currently being invoked. -template -inline void invokeSignalHandlers( InputIterator first, InputIterator last, SignalHandlerInvoke invoke ){ - while ( first != last && invoke( *first++ ) != SIGNAL_STOP_EMISSION ); -} - -class Signal0 : public SignalBase -{ -public: -void operator()() const { - invokeSignalHandlers( begin(), end(), FunctorInvoke() ); -} -}; - -template -class Signal1 : public SignalBase< SignalHandler1 > -{ -typedef SignalBase< SignalHandler1 > Base; -public: -void operator()( FirstArgument a1 ) const { - invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke( a1 ) ); -} -}; - -template -class Signal2 : public SignalBase< SignalHandler2 > -{ -typedef SignalBase< SignalHandler2 > Base; -public: -void operator()( FirstArgument a1, SecondArgument a2 ) const { - invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke( a1, a2 ) ); -} -}; - -template -class Signal3 : public SignalBase< SignalHandler3 > -{ -typedef SignalBase< SignalHandler3 > Base; -public: -void operator()( FirstArgument a1, SecondArgument a2, ThirdArgument a3 ) const { - invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke( a1, a2, a3 ) ); -} -}; - -#endif diff --git a/libs/signal/signalfwd.h b/libs/signal/signalfwd.h deleted file mode 100644 index 507c0e7..0000000 --- a/libs/signal/signalfwd.h +++ /dev/null @@ -1,44 +0,0 @@ - -#if !defined( INCLUDED_SIGNALFWD_H ) -#define INCLUDED_SIGNALFWD_H - -class SignalHandler; -template -class SignalHandler1; -template -class SignalHandler2; -template -class SignalHandler3; - -template -class Opaque; - -///\brief A pointer that always has a well-defined value. -/// If no value is specified, the appropriate null value is used. -template -class Handle -{ -Type* p; -public: -Handle() : p( 0 ){ -} -explicit Handle( Type* p ) : p( p ){ -} -Type* get() const { - return p; -} -bool isNull() const { - return p == 0; -} -}; - -template -class SignalFwd -{ -public: -typedef Handle< Opaque > handler_id_type; -}; - -typedef SignalFwd::handler_id_type SignalHandlerId; - -#endif diff --git a/libs/splines/Makefile b/libs/splines/Makefile deleted file mode 100644 index d348302..0000000 --- a/libs/splines/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - math_angles.o \ - math_matrix.o \ - math_quaternion.o \ - math_vector.o \ - q_parse.o \ - q_shared.o \ - splines.o \ - util_str.o - -# binary target -../libsplines.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -math_angles.o: math_angles.cpp math_angles.h -math_matrix.o: math_matrix.cpp math_matrix.h -math_quaternion.o: math_quaternion.cpp math_quaternion.h -math_vector.o: math_vector.cpp math_vector.h -q_parse.o: q_parse.cpp -q_shared.o: q_shared.cpp q_shared.h -splines.o: splines.cpp splines.h -util_str.o: util_str.cpp util_str.h util_list.h - -clean: - -rm -f *.o ../libsplines.a diff --git a/libs/splines/math_angles.cpp b/libs/splines/math_angles.cpp deleted file mode 100644 index 81b7f21..0000000 --- a/libs/splines/math_angles.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q_shared.h" -#include - -angles_t ang_zero( 0.0f, 0.0f, 0.0f ); - -void toAngles( mat3_t &src, angles_t &dst ) { - double theta; - double cp; - double sp; - - sp = src[ 0 ][ 2 ]; - - // cap off our sin value so that we don't get any NANs - if ( sp > 1.0 ) { - sp = 1.0; - } - else if ( sp < -1.0 ) { - sp = -1.0; - } - - theta = -asin( sp ); - cp = cos( theta ); - - if ( cp > 8192 * FLT_EPSILON ) { - dst.pitch = theta * 180 / M_PI; - dst.yaw = atan2( src[ 0 ][ 1 ], src[ 0 ][ 0 ] ) * 180 / M_PI; - dst.roll = atan2( src[ 1 ][ 2 ], src[ 2 ][ 2 ] ) * 180 / M_PI; - } - else { - dst.pitch = theta * 180 / M_PI; - dst.yaw = -atan2( src[ 1 ][ 0 ], src[ 1 ][ 1 ] ) * 180 / M_PI; - dst.roll = 0; - } -} - -void toAngles( quat_t &src, angles_t &dst ) { - mat3_t temp; - - toMatrix( src, temp ); - toAngles( temp, dst ); -} - -void toAngles( idVec3 &src, angles_t &dst ) { - dst.pitch = src[ 0 ]; - dst.yaw = src[ 1 ]; - dst.roll = src[ 2 ]; -} - -void angles_t::toVectors( idVec3 *forward, idVec3 *right, idVec3 *up ) { - float angle; - static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs - - angle = yaw * ( M_PI * 2 / 360 ); - sy = sin( angle ); - cy = cos( angle ); - - angle = pitch * ( M_PI * 2 / 360 ); - sp = sin( angle ); - cp = cos( angle ); - - angle = roll * ( M_PI * 2 / 360 ); - sr = sin( angle ); - cr = cos( angle ); - - if ( forward ) { - forward->set( cp * cy, cp * sy, -sp ); - } - - if ( right ) { - right->set( -sr * sp * cy + cr * sy, -sr * sp * sy + -cr * cy, -sr * cp ); - } - - if ( up ) { - up->set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); - } -} - -idVec3 angles_t::toForward( void ) { - float angle; - static float sp, sy, cp, cy; // static to help MS compiler fp bugs - - angle = yaw * ( M_PI * 2 / 360 ); - sy = sin( angle ); - cy = cos( angle ); - - angle = pitch * ( M_PI * 2 / 360 ); - sp = sin( angle ); - cp = cos( angle ); - - return idVec3( cp * cy, cp * sy, -sp ); -} - -/* - ================= - Normalize360 - - returns angles normalized to the range [0 <= angle < 360] - ================= - */ -angles_t& angles_t::Normalize360( void ) { - pitch = ( 360.0 / 65536 ) * ( ( int )( pitch * ( 65536 / 360.0 ) ) & 65535 ); - yaw = ( 360.0 / 65536 ) * ( ( int )( yaw * ( 65536 / 360.0 ) ) & 65535 ); - roll = ( 360.0 / 65536 ) * ( ( int )( roll * ( 65536 / 360.0 ) ) & 65535 ); - - return *this; -} - - -/* - ================= - Normalize180 - - returns angles normalized to the range [-180 < angle <= 180] - ================= - */ -angles_t& angles_t::Normalize180( void ) { - Normalize360(); - - if ( pitch > 180.0 ) { - pitch -= 360.0; - } - - if ( yaw > 180.0 ) { - yaw -= 360.0; - } - - if ( roll > 180.0 ) { - roll -= 360.0; - } - return *this; -} diff --git a/libs/splines/math_angles.h b/libs/splines/math_angles.h deleted file mode 100644 index 3c4dae0..0000000 --- a/libs/splines/math_angles.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __MATH_ANGLES_H__ -#define __MATH_ANGLES_H__ - -#include -#include - -#include "math_vector.h" - -class mat3_t; -class quat_t; -class idVec3; -typedef idVec3 &vec3_p; - -class angles_t { -public: -float pitch; -float yaw; -float roll; - -angles_t(); -angles_t( float pitch, float yaw, float roll ); -angles_t( const idVec3 &vec ); - -friend void toAngles( idVec3 &src, angles_t &dst ); -friend void toAngles( quat_t &src, angles_t &dst ); -friend void toAngles( mat3_t &src, angles_t &dst ); - -operator vec3_p(); - -float operator[]( int index ) const; -float& operator[]( int index ); - -void set( float pitch, float yaw, float roll ); - -void operator=( angles_t const &a ); -void operator=( idVec3 const &a ); - -friend angles_t operator+( const angles_t &a, const angles_t &b ); -angles_t &operator+=( angles_t const &a ); -angles_t &operator+=( idVec3 const &a ); - -friend angles_t operator-( angles_t &a, angles_t &b ); -angles_t &operator-=( angles_t &a ); - -friend angles_t operator*( const angles_t &a, float b ); -friend angles_t operator*( float a, const angles_t &b ); -angles_t &operator*=( float a ); - -friend int operator==( angles_t &a, angles_t &b ); - -friend int operator!=( angles_t &a, angles_t &b ); - -void toVectors( idVec3 *forward, idVec3 *right = NULL, idVec3 *up = NULL ); -idVec3 toForward( void ); - -angles_t &Zero( void ); - -angles_t &Normalize360( void ); -angles_t &Normalize180( void ); -}; - -extern angles_t ang_zero; - -inline angles_t::angles_t() { -} - -inline angles_t::angles_t( float pitch, float yaw, float roll ) { - this->pitch = pitch; - this->yaw = yaw; - this->roll = roll; -} - -inline angles_t::angles_t( const idVec3 &vec ) { - this->pitch = vec.x; - this->yaw = vec.y; - this->roll = vec.z; -} - -inline float angles_t::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &pitch )[ index ]; -} - -inline float& angles_t::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &pitch )[ index ]; -} - -inline angles_t::operator vec3_p( void ) { - return *( idVec3 * )&pitch; -} - -inline void angles_t::set( float pitch, float yaw, float roll ) { - this->pitch = pitch; - this->yaw = yaw; - this->roll = roll; -} - -inline void angles_t::operator=( angles_t const &a ) { - pitch = a.pitch; - yaw = a.yaw; - roll = a.roll; -} - -inline void angles_t::operator=( idVec3 const &a ) { - pitch = a[ 0 ]; - yaw = a[ 1 ]; - roll = a[ 2 ]; -} - -inline angles_t operator+( const angles_t &a, const angles_t &b ) { - return angles_t( a.pitch + b.pitch, a.yaw + b.yaw, a.roll + b.roll ); -} - -inline angles_t& angles_t::operator+=( angles_t const &a ) { - pitch += a.pitch; - yaw += a.yaw; - roll += a.roll; - - return *this; -} - -inline angles_t& angles_t::operator+=( idVec3 const &a ) { - pitch += a.x; - yaw += a.y; - roll += a.z; - - return *this; -} - -inline angles_t operator-( angles_t &a, angles_t &b ) { - return angles_t( a.pitch - b.pitch, a.yaw - b.yaw, a.roll - b.roll ); -} - -inline angles_t& angles_t::operator-=( angles_t &a ) { - pitch -= a.pitch; - yaw -= a.yaw; - roll -= a.roll; - - return *this; -} - -inline angles_t operator*( const angles_t &a, float b ) { - return angles_t( a.pitch * b, a.yaw * b, a.roll * b ); -} - -inline angles_t operator*( float a, const angles_t &b ) { - return angles_t( a * b.pitch, a * b.yaw, a * b.roll ); -} - -inline angles_t& angles_t::operator*=( float a ) { - pitch *= a; - yaw *= a; - roll *= a; - - return *this; -} - -inline int operator==( angles_t &a, angles_t &b ) { - return ( ( a.pitch == b.pitch ) && ( a.yaw == b.yaw ) && ( a.roll == b.roll ) ); -} - -inline int operator!=( angles_t &a, angles_t &b ) { - return ( ( a.pitch != b.pitch ) || ( a.yaw != b.yaw ) || ( a.roll != b.roll ) ); -} - -inline angles_t& angles_t::Zero( void ) { - pitch = 0.0f; - yaw = 0.0f; - roll = 0.0f; - - return *this; -} - -#endif /* !__MATH_ANGLES_H__ */ diff --git a/libs/splines/math_matrix.cpp b/libs/splines/math_matrix.cpp deleted file mode 100644 index 0f6f7c4..0000000 --- a/libs/splines/math_matrix.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q_shared.h" - -mat3_t mat3_default( idVec3( 1, 0, 0 ), idVec3( 0, 1, 0 ), idVec3( 0, 0, 1 ) ); - -void toMatrix( quat_t const &src, mat3_t &dst ) { - float wx, wy, wz; - float xx, yy, yz; - float xy, xz, zz; - float x2, y2, z2; - - x2 = src.x + src.x; - y2 = src.y + src.y; - z2 = src.z + src.z; - - xx = src.x * x2; - xy = src.x * y2; - xz = src.x * z2; - - yy = src.y * y2; - yz = src.y * z2; - zz = src.z * z2; - - wx = src.w * x2; - wy = src.w * y2; - wz = src.w * z2; - - dst[ 0 ][ 0 ] = 1.0f - ( yy + zz ); - dst[ 0 ][ 1 ] = xy - wz; - dst[ 0 ][ 2 ] = xz + wy; - - dst[ 1 ][ 0 ] = xy + wz; - dst[ 1 ][ 1 ] = 1.0f - ( xx + zz ); - dst[ 1 ][ 2 ] = yz - wx; - - dst[ 2 ][ 0 ] = xz - wy; - dst[ 2 ][ 1 ] = yz + wx; - dst[ 2 ][ 2 ] = 1.0f - ( xx + yy ); -} - -void toMatrix( angles_t const &src, mat3_t &dst ) { - float angle; - static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs - - angle = src.yaw * ( M_PI * 2.0f / 360.0f ); - sy = sin( angle ); - cy = cos( angle ); - - angle = src.pitch * ( M_PI * 2.0f / 360.0f ); - sp = sin( angle ); - cp = cos( angle ); - - angle = src.roll * ( M_PI * 2.0f / 360.0f ); - sr = sin( angle ); - cr = cos( angle ); - - dst[ 0 ].set( cp * cy, cp * sy, -sp ); - dst[ 1 ].set( sr * sp * cy + cr * -sy, sr * sp * sy + cr * cy, sr * cp ); - dst[ 2 ].set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); -} - -void toMatrix( idVec3 const &src, mat3_t &dst ) { - angles_t sup = src; - toMatrix( sup, dst ); -} - -void mat3_t::ProjectVector( const idVec3 &src, idVec3 &dst ) const { - dst.x = src * mat[ 0 ]; - dst.y = src * mat[ 1 ]; - dst.z = src * mat[ 2 ]; -} - -void mat3_t::UnprojectVector( const idVec3 &src, idVec3 &dst ) const { - dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z; -} - -void mat3_t::Transpose( mat3_t &matrix ) { - int i; - int j; - - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - matrix[ i ][ j ] = mat[ j ][ i ]; - } - } -} - -void mat3_t::Transpose( void ) { - float temp; - int i; - int j; - - for ( i = 0; i < 3; i++ ) { - for ( j = i + 1; j < 3; j++ ) { - temp = mat[ i ][ j ]; - mat[ i ][ j ] = mat[ j ][ i ]; - mat[ j ][ i ] = temp; - } - } -} - -mat3_t mat3_t::Inverse( void ) const { - mat3_t inv( *this ); - - inv.Transpose(); - - return inv; -} - -void mat3_t::Clear( void ) { - mat[0].set( 1, 0, 0 ); - mat[1].set( 0, 1, 0 ); - mat[2].set( 0, 0, 1 ); -} diff --git a/libs/splines/math_matrix.h b/libs/splines/math_matrix.h deleted file mode 100644 index 741d4bb..0000000 --- a/libs/splines/math_matrix.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __MATH_MATRIX_H__ -#define __MATH_MATRIX_H__ - -#include -#include "math_vector.h" - -class quat_t; -class angles_t; - -class mat3_t { -public: -idVec3 mat[ 3 ]; - -mat3_t(); -mat3_t( float src[ 3 ][ 3 ] ); -mat3_t( idVec3 const &x, idVec3 const &y, idVec3 const &z ); -mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ); - -friend void toMatrix( quat_t const &src, mat3_t &dst ); -friend void toMatrix( angles_t const &src, mat3_t &dst ); -friend void toMatrix( idVec3 const &src, mat3_t &dst ); - -idVec3 operator[]( int index ) const; -idVec3 &operator[]( int index ); - -idVec3 operator*( const idVec3 &vec ) const; -mat3_t operator*( const mat3_t &a ) const; -mat3_t operator*( float a ) const; -mat3_t operator+( mat3_t const &a ) const; -mat3_t operator-( mat3_t const &a ) const; - -friend idVec3 operator*( const idVec3 &vec, const mat3_t &mat ); -friend mat3_t operator*( float a, mat3_t const &b ); - -mat3_t &operator*=( float a ); -mat3_t &operator+=( mat3_t const &a ); -mat3_t &operator-=( mat3_t const &a ); - -void Clear( void ); - -void ProjectVector( const idVec3 &src, idVec3 &dst ) const; -void UnprojectVector( const idVec3 &src, idVec3 &dst ) const; - -void OrthoNormalize( void ); -void Transpose( mat3_t &matrix ); -void Transpose( void ); -mat3_t Inverse( void ) const; -void Identity( void ); - -friend void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst ); -friend mat3_t SkewSymmetric( idVec3 const &src ); -}; - -ID_INLINE mat3_t::mat3_t() { -} - -ID_INLINE mat3_t::mat3_t(float src[3][3]) { - memcpy(mat, src, sizeof(float) * 3 * 3); -} - -ID_INLINE mat3_t::mat3_t( idVec3 const &x, idVec3 const &y, idVec3 const &z ) { - mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; mat[ 0 ].z = x.z; - mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; mat[ 1 ].z = y.z; - mat[ 2 ].x = z.x; mat[ 2 ].y = z.y; mat[ 2 ].z = z.z; -} - -ID_INLINE mat3_t::mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ) { - mat[ 0 ].x = xx; mat[ 0 ].y = xy; mat[ 0 ].z = xz; - mat[ 1 ].x = yx; mat[ 1 ].y = yy; mat[ 1 ].z = yz; - mat[ 2 ].x = zx; mat[ 2 ].y = zy; mat[ 2 ].z = zz; -} - -ID_INLINE idVec3 mat3_t::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 3 ) ); - return mat[ index ]; -} - -ID_INLINE idVec3& mat3_t::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 3 ) ); - return mat[ index ]; -} - -ID_INLINE idVec3 mat3_t::operator*( const idVec3 &vec ) const { - return idVec3( - mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z, - mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z, - mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z ); -} - -ID_INLINE mat3_t mat3_t::operator*( const mat3_t &a ) const { - return mat3_t( - mat[0].x * a[0].x + mat[0].y * a[1].x + mat[0].z * a[2].x, - mat[0].x * a[0].y + mat[0].y * a[1].y + mat[0].z * a[2].y, - mat[0].x * a[0].z + mat[0].y * a[1].z + mat[0].z * a[2].z, - mat[1].x * a[0].x + mat[1].y * a[1].x + mat[1].z * a[2].x, - mat[1].x * a[0].y + mat[1].y * a[1].y + mat[1].z * a[2].y, - mat[1].x * a[0].z + mat[1].y * a[1].z + mat[1].z * a[2].z, - mat[2].x * a[0].x + mat[2].y * a[1].x + mat[2].z * a[2].x, - mat[2].x * a[0].y + mat[2].y * a[1].y + mat[2].z * a[2].y, - mat[2].x * a[0].z + mat[2].y * a[1].z + mat[2].z * a[2].z ); -} - -ID_INLINE mat3_t mat3_t::operator*( float a ) const { - return mat3_t( - mat[0].x * a, mat[0].y * a, mat[0].z * a, - mat[1].x * a, mat[1].y * a, mat[1].z * a, - mat[2].x * a, mat[2].y * a, mat[2].z * a ); -} - -ID_INLINE mat3_t mat3_t::operator+( mat3_t const &a ) const { - return mat3_t( - mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z, - mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z, - mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z ); -} - -ID_INLINE mat3_t mat3_t::operator-( mat3_t const &a ) const { - return mat3_t( - mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z, - mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z, - mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z ); -} - -ID_INLINE idVec3 operator*( const idVec3 &vec, const mat3_t &mat ) { - return idVec3( - mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z, - mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z, - mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z ); -} - -ID_INLINE mat3_t operator*( float a, mat3_t const &b ) { - return mat3_t( - b[0].x * a, b[0].y * a, b[0].z * a, - b[1].x * a, b[1].y * a, b[1].z * a, - b[2].x * a, b[2].y * a, b[2].z * a ); -} - -ID_INLINE mat3_t &mat3_t::operator*=( float a ) { - mat[0].x *= a; mat[0].y *= a; mat[0].z *= a; - mat[1].x *= a; mat[1].y *= a; mat[1].z *= a; - mat[2].x *= a; mat[2].y *= a; mat[2].z *= a; - - return *this; -} - -ID_INLINE mat3_t &mat3_t::operator+=( mat3_t const &a ) { - mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z; - mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z; - mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z; - - return *this; -} - -ID_INLINE mat3_t &mat3_t::operator-=( mat3_t const &a ) { - mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z; - mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z; - mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z; - - return *this; -} - -ID_INLINE void mat3_t::OrthoNormalize( void ) { - mat[ 0 ].Normalize(); - mat[ 2 ].Cross( mat[ 0 ], mat[ 1 ] ); - mat[ 2 ].Normalize(); - mat[ 1 ].Cross( mat[ 2 ], mat[ 0 ] ); - mat[ 1 ].Normalize(); -} - -ID_INLINE void mat3_t::Identity( void ) { - mat[ 0 ].x = 1.f; mat[ 0 ].y = 0.f; mat[ 0 ].z = 0.f; - mat[ 1 ].x = 0.f; mat[ 1 ].y = 1.f; mat[ 1 ].z = 0.f; - mat[ 2 ].x = 0.f; mat[ 2 ].y = 0.f; mat[ 2 ].z = 1.f; -} - -ID_INLINE void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst ) { - dst[0].x = inv[0].x * b[0].x + inv[1].x * b[1].x + inv[2].x * b[2].x; - dst[0].y = inv[0].x * b[0].y + inv[1].x * b[1].y + inv[2].x * b[2].y; - dst[0].z = inv[0].x * b[0].z + inv[1].x * b[1].z + inv[2].x * b[2].z; - dst[1].x = inv[0].y * b[0].x + inv[1].y * b[1].x + inv[2].y * b[2].x; - dst[1].y = inv[0].y * b[0].y + inv[1].y * b[1].y + inv[2].y * b[2].y; - dst[1].z = inv[0].y * b[0].z + inv[1].y * b[1].z + inv[2].y * b[2].z; - dst[2].x = inv[0].z * b[0].x + inv[1].z * b[1].x + inv[2].z * b[2].x; - dst[2].y = inv[0].z * b[0].y + inv[1].z * b[1].y + inv[2].z * b[2].y; - dst[2].z = inv[0].z * b[0].z + inv[1].z * b[1].z + inv[2].z * b[2].z; -} - -ID_INLINE mat3_t SkewSymmetric( idVec3 const &src ) { - return mat3_t( 0.0f, -src.z, src.y, src.z, 0.0f, -src.x, -src.y, src.x, 0.0f ); -} - -extern mat3_t mat3_default; - -#endif /* !__MATH_MATRIX_H__ */ diff --git a/libs/splines/math_quaternion.cpp b/libs/splines/math_quaternion.cpp deleted file mode 100644 index f37f879..0000000 --- a/libs/splines/math_quaternion.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "math_quaternion.h" -#include "math_matrix.h" - -void toQuat( idVec3 &src, quat_t &dst ) { - dst.x = src.x; - dst.y = src.y; - dst.z = src.z; - dst.w = 0.0f; -} - -void toQuat( angles_t &src, quat_t &dst ) { - mat3_t temp; - - toMatrix( src, temp ); - toQuat( temp, dst ); -} - -void toQuat( mat3_t &src, quat_t &dst ) { - float trace; - float s; - int i; - int j; - int k; - - static int next[ 3 ] = { 1, 2, 0 }; - - trace = src[ 0 ][ 0 ] + src[ 1 ][ 1 ] + src[ 2 ][ 2 ]; - if ( trace > 0.0f ) { - s = ( float )sqrt( trace + 1.0f ); - dst.w = s * 0.5f; - s = 0.5f / s; - - dst.x = ( src[ 2 ][ 1 ] - src[ 1 ][ 2 ] ) * s; - dst.y = ( src[ 0 ][ 2 ] - src[ 2 ][ 0 ] ) * s; - dst.z = ( src[ 1 ][ 0 ] - src[ 0 ][ 1 ] ) * s; - } - else { - i = 0; - if ( src[ 1 ][ 1 ] > src[ 0 ][ 0 ] ) { - i = 1; - } - if ( src[ 2 ][ 2 ] > src[ i ][ i ] ) { - i = 2; - } - - j = next[ i ]; - k = next[ j ]; - - s = ( float )sqrt( ( src[ i ][ i ] - ( src[ j ][ j ] + src[ k ][ k ] ) ) + 1.0f ); - dst[ i ] = s * 0.5f; - - s = 0.5f / s; - - dst.w = ( src[ k ][ j ] - src[ j ][ k ] ) * s; - dst[ j ] = ( src[ j ][ i ] + src[ i ][ j ] ) * s; - dst[ k ] = ( src[ k ][ i ] + src[ i ][ k ] ) * s; - } -} diff --git a/libs/splines/math_quaternion.h b/libs/splines/math_quaternion.h deleted file mode 100644 index b33f442..0000000 --- a/libs/splines/math_quaternion.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __MATH_QUATERNION_H__ -#define __MATH_QUATERNION_H__ - -#include -#include - -class idVec3_t; -class angles_t; -class mat3_t; - -class quat_t { -public: -float x; -float y; -float z; -float w; - -quat_t(); -quat_t( float x, float y, float z, float w ); - -friend void toQuat( idVec3_t &src, quat_t &dst ); -friend void toQuat( angles_t &src, quat_t &dst ); -friend void toQuat( mat3_t &src, quat_t &dst ); - -float *vec4( void ); - -float operator[]( int index ) const; -float &operator[]( int index ); - -void set( float x, float y, float z, float w ); - -void operator=( quat_t a ); - -friend quat_t operator+( quat_t a, quat_t b ); -quat_t &operator+=( quat_t a ); - -friend quat_t operator-( quat_t a, quat_t b ); -quat_t &operator-=( quat_t a ); - -friend quat_t operator*( quat_t a, float b ); -friend quat_t operator*( float a, quat_t b ); -quat_t &operator*=( float a ); - -friend int operator==( quat_t a, quat_t b ); -friend int operator!=( quat_t a, quat_t b ); - -float Length( void ); -quat_t &Normalize( void ); - -quat_t operator-(); -}; - -inline quat_t::quat_t() { -} - -inline quat_t::quat_t( float x, float y, float z, float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -inline float *quat_t::vec4( void ) { - return &x; -} - -inline float quat_t::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 4 ) ); - return ( &x )[ index ]; -} - -inline float& quat_t::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 4 ) ); - return ( &x )[ index ]; -} - -inline void quat_t::set( float x, float y, float z, float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -inline void quat_t::operator=( quat_t a ) { - x = a.x; - y = a.y; - z = a.z; - w = a.w; -} - -inline quat_t operator+( quat_t a, quat_t b ) { - return quat_t( a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w ); -} - -inline quat_t& quat_t::operator+=( quat_t a ) { - x += a.x; - y += a.y; - z += a.z; - w += a.w; - - return *this; -} - -inline quat_t operator-( quat_t a, quat_t b ) { - return quat_t( a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w ); -} - -inline quat_t& quat_t::operator-=( quat_t a ) { - x -= a.x; - y -= a.y; - z -= a.z; - w -= a.w; - - return *this; -} - -inline quat_t operator*( quat_t a, float b ) { - return quat_t( a.x * b, a.y * b, a.z * b, a.w * b ); -} - -inline quat_t operator*( float a, quat_t b ) { - return b * a; -} - -inline quat_t& quat_t::operator*=( float a ) { - x *= a; - y *= a; - z *= a; - w *= a; - - return *this; -} - -inline int operator==( quat_t a, quat_t b ) { - return ( ( a.x == b.x ) && ( a.y == b.y ) && ( a.z == b.z ) && ( a.w == b.w ) ); -} - -inline int operator!=( quat_t a, quat_t b ) { - return ( ( a.x != b.x ) || ( a.y != b.y ) || (( a.z != b.z ) && ( a.w != b.w )) ); -} - -inline float quat_t::Length( void ) { - float length; - - length = x * x + y * y + z * z + w * w; - return ( float )sqrt( length ); -} - -inline quat_t& quat_t::Normalize( void ) { - float length; - float ilength; - - length = this->Length(); - if ( length ) { - ilength = 1 / length; - x *= ilength; - y *= ilength; - z *= ilength; - w *= ilength; - } - - return *this; -} - -inline quat_t quat_t::operator-() { - return quat_t( -x, -y, -z, -w ); -} - -#endif /* !__MATH_QUATERNION_H__ */ diff --git a/libs/splines/math_vector.cpp b/libs/splines/math_vector.cpp deleted file mode 100644 index 572f903..0000000 --- a/libs/splines/math_vector.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "math_vector.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h - -#define LERP_DELTA 1e-6 - -idVec3 vec_zero( 0.0f, 0.0f, 0.0f ); - -Bounds boundsZero; - -float idVec3::toYaw( void ) { - float yaw; - - if ( ( y == 0 ) && ( x == 0 ) ) { - yaw = 0; - } - else { - yaw = atan2( y, x ) * 180 / M_PI; - if ( yaw < 0 ) { - yaw += 360; - } - } - - return yaw; -} - -float idVec3::toPitch( void ) { - float forward; - float pitch; - - if ( ( x == 0 ) && ( y == 0 ) ) { - if ( z > 0 ) { - pitch = 90; - } - else { - pitch = 270; - } - } - else { - forward = ( float )idSqrt( x * x + y * y ); - pitch = atan2( z, forward ) * 180 / M_PI; - if ( pitch < 0 ) { - pitch += 360; - } - } - - return pitch; -} - -/* - angles_t idVec3::toAngles( void ) { - float forward; - float yaw; - float pitch; - - if ( ( x == 0 ) && ( y == 0 ) ) { - yaw = 0; - if ( z > 0 ) { - pitch = 90; - } else { - pitch = 270; - } - } else { - yaw = atan2( y, x ) * 180 / M_PI; - if ( yaw < 0 ) { - yaw += 360; - } - - forward = ( float )idSqrt( x * x + y * y ); - pitch = atan2( z, forward ) * 180 / M_PI; - if ( pitch < 0 ) { - pitch += 360; - } - } - - return angles_t( -pitch, yaw, 0 ); - } - */ - -idVec3 LerpVector( idVec3 &w1, idVec3 &w2, const float t ) { - float omega, cosom, sinom, scale0, scale1; - - cosom = w1 * w2; - if ( ( 1.0 - cosom ) > LERP_DELTA ) { - omega = acos( cosom ); - sinom = sin( omega ); - scale0 = sin( ( 1.0 - t ) * omega ) / sinom; - scale1 = sin( t * omega ) / sinom; - } - else { - scale0 = 1.0 - t; - scale1 = t; - } - - return ( w1 * scale0 + w2 * scale1 ); -} - -/* - ============= - idVec3::string - - This is just a convenience function - for printing vectors - ============= - */ -char *idVec3::string( void ) { - static int index = 0; - static char str[ 8 ][ 36 ]; - char *s; - - // use an array so that multiple toString's won't collide - s = str[ index ]; - index = ( index + 1 ) & 7; - - sprintf( s, "%.2f %.2f %.2f", x, y, z ); - - return s; -} diff --git a/libs/splines/math_vector.h b/libs/splines/math_vector.h deleted file mode 100644 index 616116b..0000000 --- a/libs/splines/math_vector.h +++ /dev/null @@ -1,581 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __MATH_VECTOR_H__ -#define __MATH_VECTOR_H__ - -#include "globaldefs.h" - -#if GDEF_COMPILER_MSVC -#pragma warning(disable : 4244) -#endif - -#include -#include - -//#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2]) -//#define VectorSubtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2]) -//#define VectorAdd(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2]) -//#define VectorCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2]) -//#define VectorCopy(a,b) ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z]) - -//#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s)) -#define __VectorMA( v, s, b, o ) ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ) ) -//#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0]) - -#define DotProduct4( x,y ) ( ( x )[0] * ( y )[0] + ( x )[1] * ( y )[1] + ( x )[2] * ( y )[2] + ( x )[3] * ( y )[3] ) -#define VectorSubtract4( a,b,c ) ( ( c )[0] = ( a )[0] - ( b )[0],( c )[1] = ( a )[1] - ( b )[1],( c )[2] = ( a )[2] - ( b )[2],( c )[3] = ( a )[3] - ( b )[3] ) -#define VectorAdd4( a,b,c ) ( ( c )[0] = ( a )[0] + ( b )[0],( c )[1] = ( a )[1] + ( b )[1],( c )[2] = ( a )[2] + ( b )[2],( c )[3] = ( a )[3] + ( b )[3] ) -#define VectorCopy4( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] ) -#define VectorScale4( v, s, o ) ( ( o )[0] = ( v )[0] * ( s ),( o )[1] = ( v )[1] * ( s ),( o )[2] = ( v )[2] * ( s ),( o )[3] = ( v )[3] * ( s ) ) -#define VectorMA4( v, s, b, o ) ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ),( o )[3] = ( v )[3] + ( b )[3] * ( s ) ) - - -//#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0) -#define VectorNegate( a,b ) ( ( b )[0] = -( a )[0],( b )[1] = -( a )[1],( b )[2] = -( a )[2] ) -//#define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z)) -#define Vector4Copy( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] ) - -#define SnapVector( v ) {v[0] = (int)v[0]; v[1] = (int)v[1]; v[2] = (int)v[2]; } - - -//#include "util_heap.h" - -#ifndef EQUAL_EPSILON -#define EQUAL_EPSILON 0.001 -#endif - -float Q_fabs( float f ); - -#ifndef ID_INLINE -#define ID_INLINE GDEF_ATTRIBUTE_INLINE -#endif - -// if this is defined, vec3 will take four elements, which may allow -// easier SIMD optimizations -//#define FAT_VEC3 -//#ifdef __ppc__ -//#pragma align(16) -//#endif - -class angles_t; -#ifdef __ppc__ -// Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction, -// runs *much* faster than calling sqrt(). We'll use two Newton-Raphson -// refinement steps to get bunch more precision in the 1/sqrt() value for very little cost. -// We'll then multiply 1/sqrt times the original value to get the sqrt. -// This is about 12.4 times faster than sqrt() and according to my testing (not exhaustive) -// it returns fairly accurate results (error below 1.0e-5 up to 100000.0 in 0.1 increments). - -static inline float idSqrt( float x ) { - const float half = 0.5; - const float one = 1.0; - float B, y0, y1; - - // This'll NaN if it hits frsqrte. Handle both +0.0 and -0.0 - if ( fabs( x ) == 0.0 ) { - return x; - } - B = x; - -#if GDEF_COMPILER_GNU - asm ( "frsqrte %0,%1" : "=f" ( y0 ) : "f" ( B ) ); -#else - y0 = __frsqrte( B ); -#endif - /* First refinement step */ - - y1 = y0 + half * y0 * ( one - B * y0 * y0 ); - - /* Second refinement step -- copy the output of the last step to the input of this step */ - - y0 = y1; - y1 = y0 + half * y0 * ( one - B * y0 * y0 ); - - /* Get sqrt(x) from x * 1/sqrt(x) */ - return x * y1; -} -#else -static inline double idSqrt( double x ) { - return sqrt( x ); -} -#endif - - -//class idVec3 : public idHeap { -class idVec3 { -public: -#ifndef FAT_VEC3 -float x,y,z; -#else -float x,y,z,dist; -#endif - -#ifndef FAT_VEC3 -idVec3() { -}; -#else -idVec3() { - dist = 0.0f; -}; -#endif -idVec3( const float x, const float y, const float z ); - -operator float *(); - -float operator[]( const int index ) const; -float &operator[]( const int index ); - -void set( const float x, const float y, const float z ); - -idVec3 operator-() const; - -idVec3 &operator=( const idVec3 &a ); - -float operator*( const idVec3 &a ) const; -idVec3 operator*( const float a ) const; -friend idVec3 operator*( float a, idVec3 b ); - -idVec3 operator+( const idVec3 &a ) const; -idVec3 operator-( const idVec3 &a ) const; - -idVec3 &operator+=( const idVec3 &a ); -idVec3 &operator-=( const idVec3 &a ); -idVec3 &operator*=( const float a ); - -int operator==( const idVec3 &a ) const; -int operator!=( const idVec3 &a ) const; - -idVec3 Cross( const idVec3 &a ) const; -idVec3 &Cross( const idVec3 &a, const idVec3 &b ); - -float Length( void ) const; -float Normalize( void ); - -void Zero( void ); -void Snap( void ); -void SnapTowards( const idVec3 &to ); - -float toYaw( void ); -float toPitch( void ); -angles_t toAngles( void ); -friend idVec3 LerpVector( const idVec3 &w1, const idVec3 &w2, const float t ); - -char *string( void ); -}; - -extern idVec3 vec_zero; - -ID_INLINE idVec3::idVec3( const float x, const float y, const float z ) { - this->x = x; - this->y = y; - this->z = z; -#ifdef FAT_VEC3 - this->dist = 0.0f; -#endif -} - -ID_INLINE float idVec3::operator[]( const int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float &idVec3::operator[]( const int index ) { - return ( &x )[ index ]; -} - -ID_INLINE idVec3::operator float *( void ) { - return &x; -} - -ID_INLINE idVec3 idVec3::operator-() const { - return idVec3( -x, -y, -z ); -} - -ID_INLINE idVec3 &idVec3::operator=( const idVec3 &a ) { - x = a.x; - y = a.y; - z = a.z; - - return *this; -} - -ID_INLINE void idVec3::set( const float x, const float y, const float z ) { - this->x = x; - this->y = y; - this->z = z; -} - -ID_INLINE idVec3 idVec3::operator-( const idVec3 &a ) const { - return idVec3( x - a.x, y - a.y, z - a.z ); -} - -ID_INLINE float idVec3::operator*( const idVec3 &a ) const { - return x * a.x + y * a.y + z * a.z; -} - -ID_INLINE idVec3 idVec3::operator*( const float a ) const { - return idVec3( x * a, y * a, z * a ); -} - -ID_INLINE idVec3 operator*( const float a, const idVec3 b ) { - return idVec3( b.x * a, b.y * a, b.z * a ); -} - -ID_INLINE idVec3 idVec3::operator+( const idVec3 &a ) const { - return idVec3( x + a.x, y + a.y, z + a.z ); -} - -ID_INLINE idVec3 &idVec3::operator+=( const idVec3 &a ) { - x += a.x; - y += a.y; - z += a.z; - - return *this; -} - -ID_INLINE idVec3 &idVec3::operator-=( const idVec3 &a ) { - x -= a.x; - y -= a.y; - z -= a.z; - - return *this; -} - -ID_INLINE idVec3 &idVec3::operator*=( const float a ) { - x *= a; - y *= a; - z *= a; - - return *this; -} - -ID_INLINE int idVec3::operator==( const idVec3 &a ) const { - if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) { - return false; - } - - if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) { - return false; - } - - if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) { - return false; - } - - return true; -} - -ID_INLINE int idVec3::operator!=( const idVec3 &a ) const { - if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) { - return true; - } - - if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) { - return true; - } - - if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) { - return true; - } - - return false; -} - -ID_INLINE idVec3 idVec3::Cross( const idVec3 &a ) const { - return idVec3( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x ); -} - -ID_INLINE idVec3 &idVec3::Cross( const idVec3 &a, const idVec3 &b ) { - x = a.y * b.z - a.z * b.y; - y = a.z * b.x - a.x * b.z; - z = a.x * b.y - a.y * b.x; - - return *this; -} - -ID_INLINE float idVec3::Length( void ) const { - float length; - - length = x * x + y * y + z * z; - return ( float )idSqrt( length ); -} - -ID_INLINE float idVec3::Normalize( void ) { - float length; - float ilength; - - length = this->Length(); - if ( length ) { - ilength = 1.0f / length; - x *= ilength; - y *= ilength; - z *= ilength; - } - - return length; -} - -ID_INLINE void idVec3::Zero( void ) { - x = 0.0f; - y = 0.0f; - z = 0.0f; -} - -ID_INLINE void idVec3::Snap( void ) { - x = float( int( x ) ); - y = float( int( y ) ); - z = float( int( z ) ); -} - -/* - ====================== - SnapTowards - - Round a vector to integers for more efficient network - transmission, but make sure that it rounds towards a given point - rather than blindly truncating. This prevents it from truncating - into a wall. - ====================== - */ -ID_INLINE void idVec3::SnapTowards( const idVec3 &to ) { - if ( to.x <= x ) { - x = float( int( x ) ); - } - else { - x = float( int( x ) + 1 ); - } - - if ( to.y <= y ) { - y = float( int( y ) ); - } - else { - y = float( int( y ) + 1 ); - } - - if ( to.z <= z ) { - z = float( int( z ) ); - } - else { - z = float( int( z ) + 1 ); - } -} - -//=============================================================== - -class Bounds { -public: -idVec3 b[2]; - -Bounds(); -Bounds( const idVec3 &mins, const idVec3 &maxs ); - -void Clear(); -void Zero(); -float Radius(); // radius from origin, not from center -idVec3 Center(); -void AddPoint( const idVec3 &v ); -void AddBounds( const Bounds &bb ); -bool IsCleared(); -bool ContainsPoint( const idVec3 &p ); -bool IntersectsBounds( const Bounds &b2 ); // touching is NOT intersecting -}; - -extern Bounds boundsZero; - -ID_INLINE Bounds::Bounds(){ -} - -ID_INLINE bool Bounds::IsCleared() { - return b[0][0] > b[1][0]; -} - -ID_INLINE bool Bounds::ContainsPoint( const idVec3 &p ) { - if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2] - || p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) { - return false; - } - return true; -} - -ID_INLINE bool Bounds::IntersectsBounds( const Bounds &b2 ) { - if ( b2.b[1][0] < b[0][0] || b2.b[1][1] < b[0][1] || b2.b[1][2] < b[0][2] - || b2.b[0][0] > b[1][0] || b2.b[0][1] > b[1][1] || b2.b[0][2] > b[1][2] ) { - return false; - } - return true; -} - -ID_INLINE Bounds::Bounds( const idVec3 &mins, const idVec3 &maxs ) { - b[0] = mins; - b[1] = maxs; -} - -ID_INLINE idVec3 Bounds::Center() { - return idVec3( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f ); -} - -ID_INLINE void Bounds::Clear() { - b[0][0] = b[0][1] = b[0][2] = 99999; - b[1][0] = b[1][1] = b[1][2] = -99999; -} - -ID_INLINE void Bounds::Zero() { - b[0][0] = b[0][1] = b[0][2] = - b[1][0] = b[1][1] = b[1][2] = 0; -} - -ID_INLINE void Bounds::AddPoint( const idVec3 &v ) { - if ( v[0] < b[0][0] ) { - b[0][0] = v[0]; - } - if ( v[0] > b[1][0] ) { - b[1][0] = v[0]; - } - if ( v[1] < b[0][1] ) { - b[0][1] = v[1]; - } - if ( v[1] > b[1][1] ) { - b[1][1] = v[1]; - } - if ( v[2] < b[0][2] ) { - b[0][2] = v[2]; - } - if ( v[2] > b[1][2] ) { - b[1][2] = v[2]; - } -} - - -ID_INLINE void Bounds::AddBounds( const Bounds &bb ) { - if ( bb.b[0][0] < b[0][0] ) { - b[0][0] = bb.b[0][0]; - } - if ( bb.b[0][1] < b[0][1] ) { - b[0][1] = bb.b[0][1]; - } - if ( bb.b[0][2] < b[0][2] ) { - b[0][2] = bb.b[0][2]; - } - - if ( bb.b[1][0] > b[1][0] ) { - b[1][0] = bb.b[1][0]; - } - if ( bb.b[1][1] > b[1][1] ) { - b[1][1] = bb.b[1][1]; - } - if ( bb.b[1][2] > b[1][2] ) { - b[1][2] = bb.b[1][2]; - } -} - -ID_INLINE float Bounds::Radius() { - int i; - float total; - float a, aa; - - total = 0; - for ( i = 0; i < 3; i++ ) { - a = (float)fabs( b[0][i] ); - aa = (float)fabs( b[1][i] ); - if ( aa > a ) { - a = aa; - } - total += a * a; - } - - return (float)idSqrt( total ); -} - -//=============================================================== - - -class idVec2 { -public: -float x; -float y; - -operator float *(); -float operator[]( int index ) const; -float &operator[]( int index ); -}; - -ID_INLINE float idVec2::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec2::operator[]( int index ) { - return ( &x )[ index ]; -} - -ID_INLINE idVec2::operator float *( void ) { - return &x; -} - -class idVec4 : public idVec3 { -public: -#ifndef FAT_VEC3 -float dist; -#endif -idVec4(); -~idVec4() { -}; - -idVec4( float x, float y, float z, float dist ); -float operator[]( int index ) const; -float &operator[]( int index ); -}; - -ID_INLINE idVec4::idVec4() { -} -ID_INLINE idVec4::idVec4( float x, float y, float z, float dist ) { - this->x = x; - this->y = y; - this->z = z; - this->dist = dist; -} - -ID_INLINE float idVec4::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec4::operator[]( int index ) { - return ( &x )[ index ]; -} - - -class idVec5_t : public idVec3 { -public: -float s; -float t; -float operator[]( int index ) const; -float &operator[]( int index ); -}; - - -ID_INLINE float idVec5_t::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec5_t::operator[]( int index ) { - return ( &x )[ index ]; -} - -#endif /* !__MATH_VECTOR_H__ */ diff --git a/libs/splines/q_parse.cpp b/libs/splines/q_parse.cpp deleted file mode 100644 index b7954ed..0000000 --- a/libs/splines/q_parse.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// q_parse.c -- support for parsing text files - -#include "q_shared.h" - -/* - ============================================================================ - - PARSING - - ============================================================================ - */ - -// multiple character punctuation tokens -static const char *punctuation[] = { - "+=", "-=", "*=", "/=", "&=", "|=", "++", "--", - "&&", "||", "<=", ">=", "==", "!=", - NULL -}; - -typedef struct { - char token[MAX_TOKEN_CHARS]; - int lines; - qboolean ungetToken; - char parseFile[MAX_QPATH]; -} parseInfo_t; - -const int MAX_PARSE_INFO = 16; -static parseInfo_t parseInfo[MAX_PARSE_INFO]; -static int parseInfoNum; -static parseInfo_t *pi = &parseInfo[0]; - -/* - =================== - Com_BeginParseSession - =================== - */ -void Com_BeginParseSession( const char *filename ) { - if ( parseInfoNum == MAX_PARSE_INFO - 1 ) { - Com_Error( ERR_FATAL, "Com_BeginParseSession: session overflow" ); - } - parseInfoNum++; - pi = &parseInfo[parseInfoNum]; - - pi->lines = 1; - Q_strncpyz( pi->parseFile, filename, sizeof( pi->parseFile ) ); -} - -/* - =================== - Com_EndParseSession - =================== - */ -void Com_EndParseSession( void ) { - if ( parseInfoNum == 0 ) { - Com_Error( ERR_FATAL, "Com_EndParseSession: session underflow" ); - } - parseInfoNum--; - pi = &parseInfo[parseInfoNum]; -} - -/* - =================== - Com_GetCurrentParseLine - =================== - */ -int Com_GetCurrentParseLine( void ) { - return pi->lines; -} - -/* - =================== - Com_ScriptError - - Prints the script name and line number in the message - =================== - */ -void Com_ScriptError( const char *msg, ... ) { - va_list argptr; - char string[32000]; - - va_start( argptr, msg ); - vsprintf( string, msg,argptr ); - va_end( argptr ); - - Com_Error( ERR_DROP, "File %s, line %i: %s", pi->parseFile, pi->lines, string ); -} - -void Com_ScriptWarning( const char *msg, ... ) { - va_list argptr; - char string[32000]; - - va_start( argptr, msg ); - vsprintf( string, msg,argptr ); - va_end( argptr ); - - Com_Printf( "File %s, line %i: %s", pi->parseFile, pi->lines, string ); -} - - -/* - =================== - Com_UngetToken - - Calling this will make the next Com_Parse return - the current token instead of advancing the pointer - =================== - */ -void Com_UngetToken( void ) { - if ( pi->ungetToken ) { - Com_ScriptError( "UngetToken called twice" ); - } - pi->ungetToken = qtrue; -} - - -static const char *SkipWhitespace( const char (*data), qboolean *hasNewLines ) { - int c; - - while ( ( c = *data ) <= ' ' ) { - if ( !c ) { - return NULL; - } - if ( c == '\n' ) { - pi->lines++; - *hasNewLines = qtrue; - } - data++; - } - - return data; -} - -/* - ============== - Com_ParseExt - - Parse a token out of a string - Will never return NULL, just empty strings. - An empty string will only be returned at end of file. - - If "allowLineBreaks" is qtrue then an empty - string will be returned if the next token is - a newline. - ============== - */ -static char *Com_ParseExt( const char *( *data_p ), qboolean allowLineBreaks ) { - int c = 0, len; - qboolean hasNewLines = qfalse; - const char *data; - const char **punc; - - if ( !data_p ) { - Com_Error( ERR_FATAL, "Com_ParseExt: NULL data_p" ); - } - - data = *data_p; - len = 0; - pi->token[0] = 0; - - // make sure incoming data is valid - if ( !data ) { - *data_p = NULL; - return pi->token; - } - - // skip any leading whitespace - while ( 1 ) { - // skip whitespace - data = SkipWhitespace( data, &hasNewLines ); - if ( !data ) { - *data_p = NULL; - return pi->token; - } - if ( hasNewLines && !allowLineBreaks ) { - *data_p = data; - return pi->token; - } - - c = *data; - - // skip double slash comments - if ( c == '/' && data[1] == '/' ) { - while ( *data && *data != '\n' ) { - data++; - } - continue; - } - - // skip /* */ comments - if ( c == '/' && data[1] == '*' ) { - while ( *data && ( *data != '*' || data[1] != '/' ) ) { - if ( *data == '\n' ) { - pi->lines++; - } - data++; - } - if ( *data ) { - data += 2; - } - continue; - } - - // a real token to parse - break; - } - - // handle quoted strings - if ( c == '\"' ) { - data++; - while ( 1 ) { - c = *data++; - if ( ( c == '\\' ) && ( *data == '\"' ) ) { - // allow quoted strings to use \" to indicate the " character - data++; - } - else if ( c == '\"' || !c ) { - pi->token[len] = 0; - *data_p = ( char * ) data; - return pi->token; - } - else if ( *data == '\n' ) { - pi->lines++; - } - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - } - } - - // check for a number - // is this parsing of negative numbers going to cause expression problems - if ( ( c >= '0' && c <= '9' ) || ( c == '-' && data[ 1 ] >= '0' && data[ 1 ] <= '9' ) || - ( c == '.' && data[ 1 ] >= '0' && data[ 1 ] <= '9' ) ) { - do { - - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - - c = *data; - } while ( ( c >= '0' && c <= '9' ) || c == '.' ); - - // parse the exponent - if ( c == 'e' || c == 'E' ) { - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - c = *data; - - if ( c == '-' || c == '+' ) { - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - c = *data; - } - - do { - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - - c = *data; - } while ( c >= '0' && c <= '9' ); - } - - if ( len == MAX_TOKEN_CHARS ) { - len = 0; - } - pi->token[len] = 0; - - *data_p = ( char * ) data; - return pi->token; - } - - // check for a regular word - // we still allow forward and back slashes in name tokens for pathnames - // and also colons for drive letters - if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_' || c == '/' || c == '\\' ) { - do { - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - data++; - - c = *data; - } while ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_' - || ( c >= '0' && c <= '9' ) || c == '/' || c == '\\' || c == ':' || c == '.' ); - - if ( len == MAX_TOKEN_CHARS ) { - len = 0; - } - pi->token[len] = 0; - - *data_p = ( char * ) data; - return pi->token; - } - - // check for multi-character punctuation token - for ( punc = punctuation; *punc; punc++ ) { - int l; - int j; - - l = strlen( *punc ); - for ( j = 0; j < l; j++ ) { - if ( data[j] != ( *punc )[j] ) { - break; - } - } - if ( j == l ) { - // a valid multi-character punctuation - memcpy( pi->token, *punc, l ); - pi->token[l] = 0; - data += l; - *data_p = (char *)data; - return pi->token; - } - } - - // single character punctuation - pi->token[0] = *data; - pi->token[1] = 0; - data++; - *data_p = (char *)data; - - return pi->token; -} - -/* - =================== - Com_Parse - =================== - */ -const char *Com_Parse( const char *( *data_p ) ) { - if ( pi->ungetToken ) { - pi->ungetToken = qfalse; - return pi->token; - } - return Com_ParseExt( data_p, qtrue ); -} - -/* - =================== - Com_ParseOnLine - =================== - */ -const char *Com_ParseOnLine( const char *( *data_p ) ) { - if ( pi->ungetToken ) { - pi->ungetToken = qfalse; - return pi->token; - } - return Com_ParseExt( data_p, qfalse ); -} - - - -/* - ================== - Com_MatchToken - ================== - */ -void Com_MatchToken( const char *( *buf_p ), const char *match, qboolean warning ) { - const char *token; - - token = Com_Parse( buf_p ); - if ( strcmp( token, match ) ) { - if ( warning ) { - Com_ScriptWarning( "MatchToken: %s != %s", token, match ); - } - else { - Com_ScriptError( "MatchToken: %s != %s", token, match ); - } - } -} - - -/* - ================= - Com_SkipBracedSection - - The next token should be an open brace. - Skips until a matching close brace is found. - Internal brace depths are properly skipped. - ================= - */ -void Com_SkipBracedSection( const char *( *program ) ) { - const char *token; - int depth; - - depth = 0; - do { - token = Com_Parse( program ); - if ( token[1] == 0 ) { - if ( token[0] == '{' ) { - depth++; - } - else if ( token[0] == '}' ) { - depth--; - } - } - } while ( depth && *program ); -} - -/* - ================= - Com_SkipRestOfLine - ================= - */ -void Com_SkipRestOfLine( const char *( *data ) ) { - const char *p; - int c; - - p = *data; - while ( ( c = *p++ ) != 0 ) { - if ( c == '\n' ) { - pi->lines++; - break; - } - } - - *data = p; -} - -/* - ==================== - Com_ParseRestOfLine - ==================== - */ -const char *Com_ParseRestOfLine( const char *( *data_p ) ) { - static char line[MAX_TOKEN_CHARS]; - const char *token; - - line[0] = 0; - while ( 1 ) { - token = Com_ParseOnLine( data_p ); - if ( !token[0] ) { - break; - } - if ( line[0] ) { - Q_strcat( line, sizeof( line ), " " ); - } - Q_strcat( line, sizeof( line ), token ); - } - - return line; -} - - -float Com_ParseFloat( const char *( *buf_p ) ) { - const char *token; - - token = Com_Parse( buf_p ); - if ( !token[0] ) { - return 0; - } - return atof( token ); -} - -int Com_ParseInt( const char *( *buf_p ) ) { - const char *token; - - token = Com_Parse( buf_p ); - if ( !token[0] ) { - return 0; - } - return (int)atof( token ); -} - - - -void Com_Parse1DMatrix( const char *( *buf_p ), int x, float *m ) { - const char *token; - int i; - - Com_MatchToken( buf_p, "(" ); - - for ( i = 0; i < x; i++ ) { - token = Com_Parse( buf_p ); - m[i] = atof( token ); - } - - Com_MatchToken( buf_p, ")" ); -} - -void Com_Parse2DMatrix( const char *( *buf_p ), int y, int x, float *m ) { - int i; - - Com_MatchToken( buf_p, "(" ); - - for ( i = 0; i < y; i++ ) { - Com_Parse1DMatrix( buf_p, x, m + i * x ); - } - - Com_MatchToken( buf_p, ")" ); -} - -void Com_Parse3DMatrix( const char *( *buf_p ), int z, int y, int x, float *m ) { - int i; - - Com_MatchToken( buf_p, "(" ); - - for ( i = 0; i < z; i++ ) { - Com_Parse2DMatrix( buf_p, y, x, m + i * x * y ); - } - - Com_MatchToken( buf_p, ")" ); -} diff --git a/libs/splines/q_shared.cpp b/libs/splines/q_shared.cpp deleted file mode 100644 index 8cec7bf..0000000 --- a/libs/splines/q_shared.cpp +++ /dev/null @@ -1,1011 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// q_shared.c -- stateless support routines that are included in each code dll -#include "q_shared.h" - -/* - ============================================================================ - - GROWLISTS - - ============================================================================ - */ - -// malloc / free all in one place for debugging -extern "C" void *Com_Allocate( int bytes ); -extern "C" void Com_Dealloc( void *ptr ); - -void Com_InitGrowList( growList_t *list, int maxElements ) { - list->maxElements = maxElements; - list->currentElements = 0; - list->elements = (void **)Com_Allocate( list->maxElements * sizeof( void * ) ); -} - -int Com_AddToGrowList( growList_t *list, void *data ) { - void **old; - - if ( list->currentElements != list->maxElements ) { - list->elements[list->currentElements] = data; - return list->currentElements++; - } - - // grow, reallocate and move - old = list->elements; - - if ( list->maxElements < 0 ) { - Com_Error( ERR_FATAL, "Com_AddToGrowList: maxElements = %i", list->maxElements ); - } - - if ( list->maxElements == 0 ) { - // initialize the list to hold 100 elements - Com_InitGrowList( list, 100 ); - return Com_AddToGrowList( list, data ); - } - - list->maxElements *= 2; - - Com_DPrintf( "Resizing growlist to %i maxElements\n", list->maxElements ); - - list->elements = (void **)Com_Allocate( list->maxElements * sizeof( void * ) ); - - if ( !list->elements ) { - Com_Error( ERR_DROP, "Growlist alloc failed" ); - } - - memcpy( list->elements, old, list->currentElements * sizeof( void * ) ); - - Com_Dealloc( old ); - - return Com_AddToGrowList( list, data ); -} - -void *Com_GrowListElement( const growList_t *list, int index ) { - if ( index < 0 || index >= list->currentElements ) { - Com_Error( ERR_DROP, "Com_GrowListElement: %i out of range of %i", - index, list->currentElements ); - } - return list->elements[index]; -} - -int Com_IndexForGrowListElement( const growList_t *list, const void *element ) { - int i; - - for ( i = 0; i < list->currentElements; i++ ) { - if ( list->elements[i] == element ) { - return i; - } - } - return -1; -} - -//============================================================================ - - -float Com_Clamp( float min, float max, float value ) { - if ( value < min ) { - return min; - } - if ( value > max ) { - return max; - } - return value; -} - -/* - ============ - Com_StringContains - ============ - */ -const char *Com_StringContains( const char *str1, const char *str2, int casesensitive ) { - int len, i, j; - - len = strlen( str1 ) - strlen( str2 ); - for ( i = 0; i <= len; i++, str1++ ) { - for ( j = 0; str2[j]; j++ ) { - if ( casesensitive ) { - if ( str1[j] != str2[j] ) { - break; - } - } - else { - if ( toupper( str1[j] ) != toupper( str2[j] ) ) { - break; - } - } - } - if ( !str2[j] ) { - return str1; - } - } - return NULL; -} - -/* - ============ - Com_Filter - ============ - */ -int Com_Filter( const char *filter, const char *name, int casesensitive ){ - char buf[MAX_TOKEN_CHARS]; - const char *ptr; - int i, found; - - while ( *filter ) { - if ( *filter == '*' ) { - filter++; - for ( i = 0; *filter; i++ ) { - if ( *filter == '*' || *filter == '?' ) { - break; - } - buf[i] = *filter; - filter++; - } - buf[i] = '\0'; - if ( strlen( buf ) ) { - ptr = Com_StringContains( name, buf, casesensitive ); - if ( !ptr ) { - return qfalse; - } - name = ptr + strlen( buf ); - } - } - else if ( *filter == '?' ) { - filter++; - name++; - } - else if ( *filter == '[' && *( filter + 1 ) == '[' ) { - filter++; - } - else if ( *filter == '[' ) { - filter++; - found = qfalse; - while ( *filter && !found ) { - if ( *filter == ']' && *( filter + 1 ) != ']' ) { - break; - } - if ( *( filter + 1 ) == '-' && *( filter + 2 ) && ( *( filter + 2 ) != ']' || *( filter + 3 ) == ']' ) ) { - if ( casesensitive ) { - if ( *name >= *filter && *name <= *( filter + 2 ) ) { - found = qtrue; - } - } - else { - if ( toupper( *name ) >= toupper( *filter ) && - toupper( *name ) <= toupper( *( filter + 2 ) ) ) { - found = qtrue; - } - } - filter += 3; - } - else { - if ( casesensitive ) { - if ( *filter == *name ) { - found = qtrue; - } - } - else { - if ( toupper( *filter ) == toupper( *name ) ) { - found = qtrue; - } - } - filter++; - } - } - if ( !found ) { - return qfalse; - } - while ( *filter ) { - if ( *filter == ']' && *( filter + 1 ) != ']' ) { - break; - } - filter++; - } - filter++; - name++; - } - else { - if ( casesensitive ) { - if ( *filter != *name ) { - return qfalse; - } - } - else { - if ( toupper( *filter ) != toupper( *name ) ) { - return qfalse; - } - } - filter++; - name++; - } - } - return qtrue; -} - - -/* - ================ - Com_HashString - - ================ - */ -int Com_HashString( const char *fname ) { - int i; - long hash; - char letter; - - hash = 0; - i = 0; - while ( fname[i] != '\0' ) { - letter = tolower( fname[i] ); - if ( letter == '.' ) { - break; // don't include extension - } - if ( letter == '\\' ) { - letter = '/'; // damn path names - } - hash += (long)( letter ) * ( i + 119 ); - i++; - } - hash &= ( FILE_HASH_SIZE - 1 ); - return hash; -} - - -/* - ============ - Com_SkipPath - ============ - */ -char *Com_SkipPath( char *pathname ){ - char *last; - - last = pathname; - while ( *pathname ) - { - if ( *pathname == '/' ) { - last = pathname + 1; - } - pathname++; - } - return last; -} - -/* - ============ - Com_StripExtension - ============ - */ -void Com_StripExtension( const char *in, char *out ) { - while ( *in && *in != '.' ) { - *out++ = *in++; - } - *out = 0; -} - - -/* - ================== - Com_DefaultExtension - ================== - */ -void Com_DefaultExtension( char *path, int maxSize, const char *extension ) { - char oldPath[MAX_QPATH]; - char *src; - -// -// if path doesn't have a .EXT, append extension -// (extension should include the .) -// - src = path + strlen( path ) - 1; - - while ( *src != '/' && src != path ) { - if ( *src == '.' ) { - return; // it has an extension - } - src--; - } - - Q_strncpyz( oldPath, path, sizeof( oldPath ) ); - Com_sprintf( path, maxSize, "%s%s", oldPath, extension ); -} - -/* - ============================================================================ - - BYTE ORDER FUNCTIONS - - ============================================================================ - */ - -// can't just use function pointers, or dll linkage can -// mess up when qcommon is included in multiple places -static short ( *_BigShort )( short l ); -static short ( *_LittleShort )( short l ); -static int ( *_BigLong )( int l ); -static int ( *_LittleLong )( int l ); -static float ( *_BigFloat )( float l ); -static float ( *_LittleFloat )( float l ); - -short BigShort( short l ){ - return _BigShort( l ); -} -short LittleShort( short l ) { - return _LittleShort( l ); -} -int BigLong( int l ) { - return _BigLong( l ); -} -int LittleLong( int l ) { - return _LittleLong( l ); -} -float BigFloat( float l ) { - return _BigFloat( l ); -} -float LittleFloat( float l ) { - return _LittleFloat( l ); -} - -short ShortSwap( short l ){ - byte b1,b2; - - b1 = l & 255; - b2 = ( l >> 8 ) & 255; - - return ( b1 << 8 ) + b2; -} - -short ShortNoSwap( short l ){ - return l; -} - -int LongSwap( int l ){ - byte b1,b2,b3,b4; - - b1 = l & 255; - b2 = ( l >> 8 ) & 255; - b3 = ( l >> 16 ) & 255; - b4 = ( l >> 24 ) & 255; - - return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; -} - -int LongNoSwap( int l ){ - return l; -} - -float FloatSwap( float f ){ - union - { - float f; - byte b[4]; - } dat1, dat2; - - - dat1.f = f; - dat2.b[0] = dat1.b[3]; - dat2.b[1] = dat1.b[2]; - dat2.b[2] = dat1.b[1]; - dat2.b[3] = dat1.b[0]; - return dat2.f; -} - -float FloatNoSwap( float f ){ - return f; -} - -/* - ================ - Swap_Init - ================ - */ -void Swap_Init( void ){ - byte swaptest[2] = {1,0}; - -// set the byte swapping variables in a portable manner - if ( *(short *)swaptest == 1 ) { - _BigShort = ShortSwap; - _LittleShort = ShortNoSwap; - _BigLong = LongSwap; - _LittleLong = LongNoSwap; - _BigFloat = FloatSwap; - _LittleFloat = FloatNoSwap; - } - else - { - _BigShort = ShortNoSwap; - _LittleShort = ShortSwap; - _BigLong = LongNoSwap; - _LittleLong = LongSwap; - _BigFloat = FloatNoSwap; - _LittleFloat = FloatSwap; - } - -} - -/* - =============== - Com_ParseInfos - =============== - */ -int Com_ParseInfos( const char *buf, int max, char infos[][MAX_INFO_STRING] ) { - const char *token; - int count; - char key[MAX_TOKEN_CHARS]; - - count = 0; - - while ( 1 ) { - token = Com_Parse( &buf ); - if ( !token[0] ) { - break; - } - if ( strcmp( token, "{" ) ) { - Com_Printf( "Missing { in info file\n" ); - break; - } - - if ( count == max ) { - Com_Printf( "Max infos exceeded\n" ); - break; - } - - infos[count][0] = 0; - while ( 1 ) { - token = Com_Parse( &buf ); - if ( !token[0] ) { - Com_Printf( "Unexpected end of info file\n" ); - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - Q_strncpyz( key, token, sizeof( key ) ); - - token = Com_ParseOnLine( &buf ); - if ( !token[0] ) { - token = ""; - } - Info_SetValueForKey( infos[count], key, token ); - } - count++; - } - - return count; -} - - - -/* - ============================================================================ - - LIBRARY REPLACEMENT FUNCTIONS - - ============================================================================ - */ - -int Q_isprint( int c ){ - if ( c >= 0x20 && c <= 0x7E ) { - return ( 1 ); - } - return ( 0 ); -} - -int Q_islower( int c ){ - if ( c >= 'a' && c <= 'z' ) { - return ( 1 ); - } - return ( 0 ); -} - -int Q_isupper( int c ){ - if ( c >= 'A' && c <= 'Z' ) { - return ( 1 ); - } - return ( 0 ); -} - -int Q_isalpha( int c ){ - if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ) { - return ( 1 ); - } - return ( 0 ); -} - -char* Q_strrchr( const char* string, int c ){ - char cc = c; - char *s; - char *sp = (char *)0; - - s = (char*)string; - - while ( *s ) - { - if ( *s == cc ) { - sp = s; - } - s++; - } - if ( cc == 0 ) { - sp = s; - } - - return sp; -} - -/* - ============= - Q_strncpyz - - Safe strncpy that ensures a trailing zero - ============= - */ -void Q_strncpyz( char *dest, const char *src, std::size_t destsize ) { - if ( !src ) { - Com_Error( ERR_FATAL, "Q_strncpyz: NULL src" ); - } - if ( destsize < 1 ) { - Com_Error( ERR_FATAL,"Q_strncpyz: destsize < 1" ); - } - - strncpy( dest, src, destsize - 1 ); - dest[destsize - 1] = 0; -} - -int Q_stricmpn( const char *s1, const char *s2, int n ) { - int c1, c2; - - do { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - return 0; // strings are equal until end point - } - - if ( c1 != c2 ) { - if ( c1 >= 'a' && c1 <= 'z' ) { - c1 -= ( 'a' - 'A' ); - } - if ( c2 >= 'a' && c2 <= 'z' ) { - c2 -= ( 'a' - 'A' ); - } - if ( c1 != c2 ) { - return c1 < c2 ? -1 : 1; - } - } - } while ( c1 ); - - return 0; // strings are equal -} - -int Q_strncmp( const char *s1, const char *s2, int n ) { - int c1, c2; - - do { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - return 0; // strings are equal until end point - } - - if ( c1 != c2 ) { - return c1 < c2 ? -1 : 1; - } - } while ( c1 ); - - return 0; // strings are equal -} - -int Q_stricmp( const char *s1, const char *s2 ) { - return Q_stricmpn( s1, s2, 99999 ); -} - - -char *Q_strlwr( char *s1 ) { - char *s; - - s = s1; - while ( *s ) { - *s = tolower( *s ); - s++; - } - return s1; -} - -char *Q_strupr( char *s1 ) { - char *s; - - s = s1; - while ( *s ) { - *s = toupper( *s ); - s++; - } - return s1; -} - - -// never goes past bounds or leaves without a terminating 0 -void Q_strcat( char *dest, std::size_t size, const char *src ) { - auto l1 = strlen( dest ); - if ( l1 >= size ) { - Com_Error( ERR_FATAL, "Q_strcat: already overflowed" ); - } - Q_strncpyz( dest + l1, src, size - l1 ); -} - - -int Q_PrintStrlen( const char *string ) { - int len; - const char *p; - - if ( !string ) { - return 0; - } - - len = 0; - p = string; - while ( *p ) { - if ( Q_IsColorString( p ) ) { - p += 2; - continue; - } - p++; - len++; - } - - return len; -} - - -char *Q_CleanStr( char *string ) { - char* d; - char* s; - int c; - - s = string; - d = string; - while ( ( c = *s ) != 0 ) { - if ( Q_IsColorString( s ) ) { - s++; - } - else if ( c >= 0x20 && c <= 0x7E ) { - *d++ = c; - } - s++; - } - *d = '\0'; - - return string; -} - - -void QDECL Com_sprintf( char *dest, std::size_t size, const char *fmt, ... ) { - va_list argptr; - char bigbuffer[32000]; // big, but small enough to fit in PPC stack - - va_start( argptr,fmt ); - int ret = vsprintf( bigbuffer,fmt,argptr ); - va_end( argptr ); - if ( ret < 0 ) { - Com_Error(ERR_FATAL, "Com_sprintf: vsprintf failed"); - } - auto len = static_cast(ret); - if ( len >= sizeof( bigbuffer ) ) { - Com_Error( ERR_FATAL, "Com_sprintf: overflowed bigbuffer" ); - } - if ( len >= size ) { - Com_Printf( "Com_sprintf: overflow of %i in %i\n", len, size ); - } - Q_strncpyz( dest, bigbuffer, size ); -} - - -/* - ============ - va - - does a varargs printf into a temp buffer, so I don't need to have - varargs versions of all text functions. - FIXME: make this buffer size safe someday - ============ - */ -char *QDECL va( const char *format, ... ) { - va_list argptr; - static char string[2][32000]; // in case va is called by nested functions - static int index = 0; - char *buf; - - buf = string[index & 1]; - index++; - - va_start( argptr, format ); - vsprintf( buf, format,argptr ); - va_end( argptr ); - - return buf; -} - - -/* - ===================================================================== - - INFO STRINGS - - ===================================================================== - */ - -/* - =============== - Info_ValueForKey - - Searches the string for the given - key and returns the associated value, or an empty string. - FIXME: overflow check? - =============== - */ -const char *Info_ValueForKey( const char *s, const char *key ) { - char pkey[MAX_INFO_KEY]; - static char value[2][MAX_INFO_VALUE]; // use two buffers so compares - // work without stomping on each other - static int valueindex = 0; - char *o; - - if ( !s || !key ) { - return ""; - } - - if ( strlen( s ) >= MAX_INFO_STRING ) { - Com_Error( ERR_DROP, "Info_ValueForKey: oversize infostring" ); - } - - valueindex ^= 1; - if ( *s == '\\' ) { - s++; - } - while ( 1 ) - { - o = pkey; - while ( *s != '\\' ) - { - if ( !*s ) { - return ""; - } - *o++ = *s++; - } - *o = 0; - s++; - - o = value[valueindex]; - - while ( *s != '\\' && *s ) - { - *o++ = *s++; - } - *o = 0; - - if ( !Q_stricmp( key, pkey ) ) { - return value[valueindex]; - } - - if ( !*s ) { - break; - } - s++; - } - - return ""; -} - - -/* - =================== - Info_NextPair - - Used to itterate through all the key/value pairs in an info string - =================== - */ -void Info_NextPair( const char *( *head ), char key[MAX_INFO_KEY], char value[MAX_INFO_VALUE] ) { - char *o; - const char *s; - - s = *head; - - if ( *s == '\\' ) { - s++; - } - key[0] = 0; - value[0] = 0; - - o = key; - while ( *s != '\\' ) { - if ( !*s ) { - *o = 0; - *head = s; - return; - } - *o++ = *s++; - } - *o = 0; - s++; - - o = value; - while ( *s != '\\' && *s ) { - *o++ = *s++; - } - *o = 0; - - *head = s; -} - - -/* - =================== - Info_RemoveKey - =================== - */ -void Info_RemoveKey( char *s, const char *key ) { - char *start; - char pkey[MAX_INFO_KEY]; - char value[MAX_INFO_VALUE]; - char *o; - - if ( strlen( s ) >= MAX_INFO_STRING ) { - Com_Error( ERR_DROP, "Info_RemoveKey: oversize infostring" ); - } - - if ( strchr( key, '\\' ) ) { - return; - } - - while ( 1 ) - { - start = s; - if ( *s == '\\' ) { - s++; - } - o = pkey; - while ( *s != '\\' ) - { - if ( !*s ) { - return; - } - *o++ = *s++; - } - *o = 0; - s++; - - o = value; - while ( *s != '\\' && *s ) - { - if ( !*s ) { - return; - } - *o++ = *s++; - } - *o = 0; - - if ( !strcmp( key, pkey ) ) { - strcpy( start, s ); // remove this part - return; - } - - if ( !*s ) { - return; - } - } - -} - - -/* - ================== - Info_Validate - - Some characters are illegal in info strings because they - can mess up the server's parsing - ================== - */ -qboolean Info_Validate( const char *s ) { - if ( strchr( s, '\"' ) ) { - return qfalse; - } - if ( strchr( s, ';' ) ) { - return qfalse; - } - return qtrue; -} - -/* - ================== - Info_SetValueForKey - - Changes or adds a key/value pair - ================== - */ -void Info_SetValueForKey( char *s, const char *key, const char *value ) { - char newi[MAX_INFO_STRING]; - - if ( strlen( s ) >= MAX_INFO_STRING ) { - Com_Error( ERR_DROP, "Info_SetValueForKey: oversize infostring" ); - } - - if ( strchr( key, '\\' ) || strchr( value, '\\' ) ) { - Com_Printf( "Can't use keys or values with a \\\n" ); - return; - } - - if ( strchr( key, ';' ) || strchr( value, ';' ) ) { - Com_Printf( "Can't use keys or values with a semicolon\n" ); - return; - } - - if ( strchr( key, '\"' ) || strchr( value, '\"' ) ) { - Com_Printf( "Can't use keys or values with a \"\n" ); - return; - } - - Info_RemoveKey( s, key ); - if ( !value || !strlen( value ) ) { - return; - } - - Com_sprintf( newi, sizeof( newi ), "\\%s\\%s", key, value ); - - if ( strlen( newi ) + strlen( s ) > MAX_INFO_STRING ) { - Com_Printf( "Info string length exceeded\n" ); - return; - } - - strcat( s, newi ); -} - -//==================================================================== - - -/* - =============== - ParseHex - =============== - */ -int ParseHex( const char *text ) { - int value; - int c; - - value = 0; - while ( ( c = *text++ ) != 0 ) { - if ( c >= '0' && c <= '9' ) { - value = value * 16 + c - '0'; - continue; - } - if ( c >= 'a' && c <= 'f' ) { - value = value * 16 + 10 + c - 'a'; - continue; - } - if ( c >= 'A' && c <= 'F' ) { - value = value * 16 + 10 + c - 'A'; - continue; - } - } - - return value; -} diff --git a/libs/splines/q_shared.h b/libs/splines/q_shared.h deleted file mode 100644 index 10a7562..0000000 --- a/libs/splines/q_shared.h +++ /dev/null @@ -1,803 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __Q_SHARED_H -#define __Q_SHARED_H - -#include "globaldefs.h" - -// q_shared.h -- included first by ALL program modules. -// these are the definitions that have no dependance on -// central system services, and can be used by any part -// of the program without any state issues. - -// A user mod should never modify this file - -#define Q3_VERSION "DOOM 0.01" - -// alignment macros for SIMD -#define ALIGN_ON -#define ALIGN_OFF - -#if GDEF_COMPILER_MSVC - -#pragma warning(disable : 4018) // signed/unsigned mismatch -#pragma warning(disable : 4032) -#pragma warning(disable : 4051) -#pragma warning(disable : 4057) // slightly different base types -#pragma warning(disable : 4100) // unreferenced formal parameter -#pragma warning(disable : 4115) -#pragma warning(disable : 4125) // decimal digit terminates octal escape sequence -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4136) -#pragma warning(disable : 4201) -#pragma warning(disable : 4214) -#pragma warning(disable : 4244) -#pragma warning(disable : 4305) // truncation from const double to float -#pragma warning(disable : 4310) // cast truncates constant value -#pragma warning(disable : 4514) -#pragma warning(disable : 4711) // selected for automatic inline expansion -#pragma warning(disable : 4220) // varargs matches remaining parameters - -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if GDEF_OS_WINDOWS // mac doesn't have malloc.h -#include // for _alloca() -#endif -#if GDEF_COMPILER_MSVC - -//#pragma intrinsic( memset, memcpy ) - -#endif - - -// this is the define for determining if we have an asm version of a C function -#if GDEF_ARCH_BITS_32 && !defined __sun__ && !defined __LCC__ -#define id386 1 -#else -#define id386 0 -#endif - -// for windows fastcall option - -#define QDECL - -//======================= WIN32 DEFINES ================================= - -#if GDEF_OS_WINDOWS - -#define MAC_STATIC - -#undef QDECL -#define QDECL __cdecl - -// buildstring will be incorporated into the version string -#ifdef NDEBUG -#if GDEF_ARCH_BITS_32 -#define CPUSTRING "win-x86" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP" -#endif -#else -#if GDEF_ARCH_BITS_32 -#define CPUSTRING "win-x86-debug" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP-debug" -#endif -#endif - - -#define PATH_SEP '\\' - -#endif - -//======================= MAC OS X SERVER DEFINES ===================== - -#if GDEF_OS_MACOS && defined( __MACH__ ) - -#define MAC_STATIC - -#ifdef __ppc__ -#define CPUSTRING "MacOSXS-ppc" -#elif GDEF_ARCH_BITS_32 -#define CPUSTRING "MacOSXS-i386" -#else -#define CPUSTRING "MacOSXS-other" -#endif - -#define PATH_SEP '/' - -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define _alloca alloca - -#undef ALIGN_ON -#undef ALIGN_OFF -#define ALIGN_ON #pragma align( 16 ) -#define ALIGN_OFF #pragma align() - -#ifdef __cplusplus -extern "C" { -#endif - -void *osxAllocateMemory( long size ); -void osxFreeMemory( void *pointer ); - -#ifdef __cplusplus -} -#endif - -#endif - -//======================= MAC DEFINES ================================= - -#ifdef __MACOS__ - -#define MAC_STATIC static - -#define CPUSTRING "MacOS-PPC" - -#define PATH_SEP ':' - -void Sys_PumpEvents( void ); - -#endif - -#ifdef __MRC__ - -#define MAC_STATIC - -#define CPUSTRING "MacOS-PPC" - -#define PATH_SEP ':' - -void Sys_PumpEvents( void ); - -#undef QDECL -#define QDECL __cdecl - -#define _alloca alloca -#endif - -//======================= LINUX DEFINES ================================= - -// the mac compiler can't handle >32k of locals, so we -// just waste space and make big arrays static... -#if GDEF_OS_LINUX - -#define MAC_STATIC - -#if GDEF_ARCH_BITS_32 -#define CPUSTRING "linux-i386" -#elif defined __axp__ -#define CPUSTRING "linux-alpha" -#else -#define CPUSTRING "linux-other" -#endif - -#define PATH_SEP '/' - -#endif - -//============================================================= - -typedef enum {qfalse, qtrue} qboolean; - -typedef unsigned char byte; - -#define EQUAL_EPSILON 0.001 - -typedef int qhandle_t; -typedef int sfxHandle_t; -typedef int fileHandle_t; -typedef int clipHandle_t; - -typedef enum { - INVALID_JOINT = -1 -} jointHandle_t; - -#ifndef NULL -#define NULL ( (void *)0 ) -#endif - -#define MAX_QINT 0x7fffffff -#define MIN_QINT ( -MAX_QINT - 1 ) - -#if !defined(__cplusplus) && !defined(max) -#define max( x, y ) ( ( ( x ) > ( y ) ) ? ( x ) : ( y ) ) -#define min( x, y ) ( ( ( x ) < ( y ) ) ? ( x ) : ( y ) ) -#endif - -#ifndef sign -#define sign( f ) ( ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ) ) -#endif - -// angle indexes -#define PITCH 0 // up / down -#define YAW 1 // left / right -#define ROLL 2 // fall over - -// the game guarantees that no string from the network will ever -// exceed MAX_STRING_CHARS -#define MAX_STRING_CHARS 1024 // max length of a string passed to Cmd_TokenizeString -#define MAX_STRING_TOKENS 256 // max tokens resulting from Cmd_TokenizeString -#define MAX_TOKEN_CHARS 1024 // max length of an individual token - -#define MAX_INFO_STRING 1024 -#define MAX_INFO_KEY 1024 -#define MAX_INFO_VALUE 1024 - - -#define MAX_QPATH 64 // max length of a quake game pathname -#ifdef PATH_MAX -#define MAX_OSPATH PATH_MAX // max length of a filesystem pathname -#else -#define MAX_OSPATH 128 // max length of a filesystem pathname -#endif - -#define MAX_NAME_LENGTH 32 // max length of a client name - -// paramters for command buffer stuffing -typedef enum { - EXEC_NOW, // don't return until completed, a VM should NEVER use this, - // because some commands might cause the VM to be unloaded... - EXEC_INSERT, // insert at current position, but don't run yet - EXEC_APPEND // add to end of the command buffer (normal case) -} cbufExec_t; - - -// -// these aren't needed by any of the VMs. put in another header? -// -#define MAX_MAP_AREA_BYTES 32 // bit vector of area visibility - -#undef ERR_FATAL // malloc.h on unix - -// parameters to the main Error routine -typedef enum { - ERR_NONE, - ERR_FATAL, // exit the entire game with a popup window - ERR_DROP, // print to console and disconnect from game - ERR_DISCONNECT, // don't kill server - ERR_NEED_CD // pop up the need-cd dialog -} errorParm_t; - - -// font rendering values used by ui and cgame - -#define PROP_GAP_WIDTH 3 -#define PROP_SPACE_WIDTH 8 -#define PROP_HEIGHT 27 -#define PROP_SMALL_SIZE_SCALE 0.75 - -#define BLINK_DIVISOR 200 -#define PULSE_DIVISOR 75 - -#define UI_LEFT 0x00000000 // default -#define UI_CENTER 0x00000001 -#define UI_RIGHT 0x00000002 -#define UI_FORMATMASK 0x00000007 -#define UI_SMALLFONT 0x00000010 -#define UI_BIGFONT 0x00000020 // default -#define UI_GIANTFONT 0x00000040 -#define UI_DROPSHADOW 0x00000800 -#define UI_BLINK 0x00001000 -#define UI_INVERSE 0x00002000 -#define UI_PULSE 0x00004000 - - -/* - ============================================================== - - MATHLIB - - ============================================================== - */ -#ifdef __cplusplus // so we can include this in C code -#define SIDE_FRONT 0 -#define SIDE_BACK 1 -#define SIDE_ON 2 -#define SIDE_CROSS 3 - -#define Q_PI 3.14159265358979323846 -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -#include "math_vector.h" -#include "math_angles.h" -#include "math_matrix.h" -#include "math_quaternion.h" - -class idVec3; // for defining vectors -typedef idVec3 &vec3_p; // for passing vectors as function arguments -typedef const idVec3 &vec3_c; // for passing vectors as const function arguments - -class angles_t; // for defining angle vectors -typedef angles_t &angles_p; // for passing angles as function arguments -typedef const angles_t &angles_c; // for passing angles as const function arguments - -class mat3_t; // for defining matrices -typedef mat3_t &mat3_p; // for passing matrices as function arguments -typedef const mat3_t &mat3_c; // for passing matrices as const function arguments - - - -#define NUMVERTEXNORMALS 162 -extern idVec3 bytedirs[NUMVERTEXNORMALS]; - -// all drawing is done to a 640*480 virtual screen size -// and will be automatically scaled to the real resolution -#define SCREEN_WIDTH 640 -#define SCREEN_HEIGHT 480 - -#define TINYCHAR_WIDTH ( SMALLCHAR_WIDTH ) -#define TINYCHAR_HEIGHT ( SMALLCHAR_HEIGHT / 2 ) - -#define SMALLCHAR_WIDTH 8 -#define SMALLCHAR_HEIGHT 16 - -#define BIGCHAR_WIDTH 16 -#define BIGCHAR_HEIGHT 16 - -#define GIANTCHAR_WIDTH 32 -#define GIANTCHAR_HEIGHT 48 - -extern idVec4 colorBlack; -extern idVec4 colorRed; -extern idVec4 colorGreen; -extern idVec4 colorBlue; -extern idVec4 colorYellow; -extern idVec4 colorMagenta; -extern idVec4 colorCyan; -extern idVec4 colorWhite; -extern idVec4 colorLtGrey; -extern idVec4 colorMdGrey; -extern idVec4 colorDkGrey; - -#define Q_COLOR_ESCAPE '^' -#define Q_IsColorString( p ) ( p && *( p ) == Q_COLOR_ESCAPE && *( ( p ) + 1 ) && *( ( p ) + 1 ) != Q_COLOR_ESCAPE ) - -#define COLOR_BLACK '0' -#define COLOR_RED '1' -#define COLOR_GREEN '2' -#define COLOR_YELLOW '3' -#define COLOR_BLUE '4' -#define COLOR_CYAN '5' -#define COLOR_MAGENTA '6' -#define COLOR_WHITE '7' -#define ColorIndex( c ) ( ( ( c ) - '0' ) & 7 ) - -#define S_COLOR_BLACK "^0" -#define S_COLOR_RED "^1" -#define S_COLOR_GREEN "^2" -#define S_COLOR_YELLOW "^3" -#define S_COLOR_BLUE "^4" -#define S_COLOR_CYAN "^5" -#define S_COLOR_MAGENTA "^6" -#define S_COLOR_WHITE "^7" - -extern idVec4 g_color_table[8]; - -#define MAKERGB( v, r, g, b ) v[0] = r; v[1] = g; v[2] = b -#define MAKERGBA( v, r, g, b, a ) v[0] = r; v[1] = g; v[2] = b; v[3] = a - -#define DEG2RAD( a ) ( ( ( a ) * M_PI ) / 180.0F ) -#define RAD2DEG( a ) ( ( ( a ) * 180.0f ) / M_PI ) - -struct cplane_s; - -extern idVec3 vec3_origin; -extern idVec4 vec4_origin; -extern mat3_t axisDefault; - -#define nanmask ( 255 << 23 ) - -#define IS_NAN( x ) ( ( ( *(int *)&x ) & nanmask ) == nanmask ) - -float Q_fabs( float f ); -float Q_rsqrt( float f ); // reciprocal square root - -#define SQRTFAST( x ) ( 1.0f / Q_rsqrt( x ) ) - -signed char ClampChar( int i ); -signed short ClampShort( int i ); - -// this isn't a real cheap function to call! -int DirToByte( const idVec3 &dir ); -void ByteToDir( int b, vec3_p dir ); - -#define DotProduct( a,b ) ( ( a )[0] * ( b )[0] + ( a )[1] * ( b )[1] + ( a )[2] * ( b )[2] ) -#define VectorSubtract( a,b,c ) ( ( c )[0] = ( a )[0] - ( b )[0],( c )[1] = ( a )[1] - ( b )[1],( c )[2] = ( a )[2] - ( b )[2] ) -#define VectorAdd( a,b,c ) ( ( c )[0] = ( a )[0] + ( b )[0],( c )[1] = ( a )[1] + ( b )[1],( c )[2] = ( a )[2] + ( b )[2] ) -#define VectorCopy( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2] ) -//#define VectorCopy(a,b) ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z]) - -#define VectorScale( v, s, o ) ( ( o )[0] = ( v )[0] * ( s ),( o )[1] = ( v )[1] * ( s ),( o )[2] = ( v )[2] * ( s ) ) -#define VectorMA( v, s, b, o ) ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ) ) -#define CrossProduct( a,b,c ) ( ( c )[0] = ( a )[1] * ( b )[2] - ( a )[2] * ( b )[1],( c )[1] = ( a )[2] * ( b )[0] - ( a )[0] * ( b )[2],( c )[2] = ( a )[0] * ( b )[1] - ( a )[1] * ( b )[0] ) - -#define DotProduct4( x,y ) ( ( x )[0] * ( y )[0] + ( x )[1] * ( y )[1] + ( x )[2] * ( y )[2] + ( x )[3] * ( y )[3] ) -#define VectorSubtract4( a,b,c ) ( ( c )[0] = ( a )[0] - ( b )[0],( c )[1] = ( a )[1] - ( b )[1],( c )[2] = ( a )[2] - ( b )[2],( c )[3] = ( a )[3] - ( b )[3] ) -#define VectorAdd4( a,b,c ) ( ( c )[0] = ( a )[0] + ( b )[0],( c )[1] = ( a )[1] + ( b )[1],( c )[2] = ( a )[2] + ( b )[2],( c )[3] = ( a )[3] + ( b )[3] ) -#define VectorCopy4( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] ) -#define VectorScale4( v, s, o ) ( ( o )[0] = ( v )[0] * ( s ),( o )[1] = ( v )[1] * ( s ),( o )[2] = ( v )[2] * ( s ),( o )[3] = ( v )[3] * ( s ) ) -#define VectorMA4( v, s, b, o ) ( ( o )[0] = ( v )[0] + ( b )[0] * ( s ),( o )[1] = ( v )[1] + ( b )[1] * ( s ),( o )[2] = ( v )[2] + ( b )[2] * ( s ),( o )[3] = ( v )[3] + ( b )[3] * ( s ) ) - - -#define VectorClear( a ) ( ( a )[0] = ( a )[1] = ( a )[2] = 0 ) -#define VectorNegate( a,b ) ( ( b )[0] = -( a )[0],( b )[1] = -( a )[1],( b )[2] = -( a )[2] ) -#define VectorSet( v, x, y, z ) ( ( v )[0] = ( x ), ( v )[1] = ( y ), ( v )[2] = ( z ) ) -#define Vector4Copy( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2],( b )[3] = ( a )[3] ) - -#define SnapVector( v ) {v[0] = (int)v[0]; v[1] = (int)v[1]; v[2] = (int)v[2]; } - -float NormalizeColor( vec3_c in, vec3_p out ); - -int VectorCompare( vec3_c v1, vec3_c v2 ); -float VectorLength( vec3_c v ); -float Distance( vec3_c p1, vec3_c p2 ); -float DistanceSquared( vec3_c p1, vec3_c p2 ); -float VectorNormalize( vec3_p v ); // returns vector length -void VectorNormalizeFast( vec3_p v ); // does NOT return vector length, uses rsqrt approximation -float VectorNormalize2( vec3_c v, vec3_p out ); -void VectorInverse( vec3_p v ); -void VectorRotate( vec3_c in, mat3_c matrix, vec3_p out ); -void VectorPolar( vec3_p v, float radius, float theta, float phi ); -void VectorSnap( vec3_p v ); -void Vector53Copy( const idVec5_t &in, vec3_p out ); -void Vector5Scale( const idVec5_t &v, float scale, idVec5_t &out ); -void Vector5Add( const idVec5_t &va, const idVec5_t &vb, idVec5_t &out ); -void VectorRotate3( vec3_c vIn, vec3_c vRotation, vec3_p out ); -void VectorRotate3Origin( vec3_c vIn, vec3_c vRotation, vec3_c vOrigin, vec3_p out ); - - -int Q_log2( int val ); - -int Q_rand( int *seed ); -float Q_random( int *seed ); -float Q_crandom( int *seed ); - -#define random() ( ( rand() & 0x7fff ) / ( (float)0x7fff ) ) -#define crandom() ( 2.0 * ( random() - 0.5 ) ) - -float Q_rint( float in ); - -void vectoangles( vec3_c value1, angles_p angles ); -void AnglesToAxis( angles_c angles, mat3_p axis ); - -void AxisCopy( mat3_c in, mat3_p out ); -qboolean AxisRotated( mat3_c in ); // assumes a non-degenerate axis - -int SignbitsForNormal( vec3_c normal ); -int BoxOnPlaneSide( const Bounds &b, struct cplane_s *p ); - -float AngleMod( float a ); -float LerpAngle( float from, float to, float frac ); -float AngleSubtract( float a1, float a2 ); -void AnglesSubtract( angles_c v1, angles_c v2, angles_p v3 ); - -float AngleNormalize360( float angle ); -float AngleNormalize180( float angle ); -float AngleDelta( float angle1, float angle2 ); - -qboolean PlaneFromPoints( idVec4 &plane, vec3_c a, vec3_c b, vec3_c c ); -void ProjectPointOnPlane( vec3_p dst, vec3_c p, vec3_c normal ); -void RotatePointAroundVector( vec3_p dst, vec3_c dir, vec3_c point, float degrees ); -void RotateAroundDirection( mat3_p axis, float yaw ); -void MakeNormalVectors( vec3_c forward, vec3_p right, vec3_p up ); -// perpendicular vector could be replaced by this - -int PlaneTypeForNormal( vec3_c normal ); - -void MatrixMultiply( mat3_c in1, mat3_c in2, mat3_p out ); -void MatrixInverseMultiply( mat3_c in1, mat3_c in2, mat3_p out ); // in2 is transposed during multiply -void MatrixTransformVector( vec3_c in, mat3_c matrix, vec3_p out ); -void MatrixProjectVector( vec3_c in, mat3_c matrix, vec3_p out ); // Places the vector into a new coordinate system. -void AngleVectors( angles_c angles, vec3_p forward, vec3_p right, vec3_p up ); -void PerpendicularVector( vec3_p dst, vec3_c src ); - -float TriangleArea( vec3_c a, vec3_c b, vec3_c c ); -#endif // __cplusplus - -//============================================= - -float Com_Clamp( float min, float max, float value ); - -#define FILE_HASH_SIZE 1024 -int Com_HashString( const char *fname ); - -char *Com_SkipPath( char *pathname ); - -// it is ok for out == in -void Com_StripExtension( const char *in, char *out ); - -// "extension" should include the dot: ".map" -void Com_DefaultExtension( char *path, int maxSize, const char *extension ); - -int Com_ParseInfos( const char *buf, int max, char infos[][MAX_INFO_STRING] ); - -/* - ===================================================================================== - - SCRIPT PARSING - - ===================================================================================== - */ - -// this just controls the comment printing, it doesn't actually load a file -void Com_BeginParseSession( const char *filename ); -void Com_EndParseSession( void ); - -int Com_GetCurrentParseLine( void ); - -// Will never return NULL, just empty strings. -// An empty string will only be returned at end of file. -// ParseOnLine will return empty if there isn't another token on this line - -// this funny typedef just means a moving pointer into a const char * buffer -const char *Com_Parse( const char *( *data_p ) ); -const char *Com_ParseOnLine( const char *( *data_p ) ); -const char *Com_ParseRestOfLine( const char *( *data_p ) ); - -void Com_UngetToken( void ); - -#ifdef __cplusplus -void Com_MatchToken( const char *( *buf_p ), const char *match, qboolean warning = qfalse ); -#else -void Com_MatchToken( const char *( *buf_p ), const char *match, qboolean warning ); -#endif - -void Com_ScriptError( const char *msg, ... ); -void Com_ScriptWarning( const char *msg, ... ); - -void Com_SkipBracedSection( const char *( *program ) ); -void Com_SkipRestOfLine( const char *( *data ) ); - -float Com_ParseFloat( const char *( *buf_p ) ); -int Com_ParseInt( const char *( *buf_p ) ); - -void Com_Parse1DMatrix( const char *( *buf_p ), int x, float *m ); -void Com_Parse2DMatrix( const char *( *buf_p ), int y, int x, float *m ); -void Com_Parse3DMatrix( const char *( *buf_p ), int z, int y, int x, float *m ); - -//===================================================================================== -#ifdef __cplusplus -extern "C" { -#endif - -void QDECL Com_sprintf( char *dest, std::size_t size, const char *fmt, ... ); - - -// mode parm for FS_FOpenFile -typedef enum { - FS_READ, - FS_WRITE, - FS_APPEND, - FS_APPEND_SYNC -} fsMode_t; - -typedef enum { - FS_SEEK_CUR, - FS_SEEK_END, - FS_SEEK_SET -} fsOrigin_t; - -//============================================= - -int Q_isprint( int c ); -int Q_islower( int c ); -int Q_isupper( int c ); -int Q_isalpha( int c ); - -// portable case insensitive compare -int Q_stricmp( const char *s1, const char *s2 ); -int Q_strncmp( const char *s1, const char *s2, int n ); -int Q_stricmpn( const char *s1, const char *s2, int n ); -char *Q_strlwr( char *s1 ); -char *Q_strupr( char *s1 ); -char *Q_strrchr( const char* string, int c ); - -// buffer size safe library replacements -void Q_strncpyz( char *dest, const char *src, std::size_t destsize ); -void Q_strcat( char *dest, std::size_t size, const char *src ); - -// strlen that discounts Quake color sequences -int Q_PrintStrlen( const char *string ); -// removes color sequences from string -char *Q_CleanStr( char *string ); - -int Com_Filter( const char *filter, const char *name, int casesensitive ); -const char *Com_StringContains( const char *str1, const char *str2, int casesensitive ); - - -//============================================= - -short BigShort( short l ); -short LittleShort( short l ); -int BigLong( int l ); -int LittleLong( int l ); -float BigFloat( float l ); -float LittleFloat( float l ); - -void Swap_Init( void ); -char *QDECL va( const char *format, ... ); - -#ifdef __cplusplus -} -#endif - - -//============================================= -#ifdef __cplusplus -// -// mapfile parsing -// -typedef struct ePair_s { - char *key; - char *value; -} ePair_t; - -typedef struct mapSide_s { - char material[MAX_QPATH]; - idVec4 plane; - idVec4 textureVectors[2]; -} mapSide_t; - -typedef struct { - int numSides; - mapSide_t **sides; -} mapBrush_t; - -typedef struct { - idVec3 xyz; - float st[2]; -} patchVertex_t; - -typedef struct { - char material[MAX_QPATH]; - int width, height; - patchVertex_t *patchVerts; -} mapPatch_t; - -typedef struct { - char modelName[MAX_QPATH]; - float matrix[16]; -} mapModel_t; - -typedef struct mapPrimitive_s { - int numEpairs; - ePair_t **ePairs; - - // only one of these will be non-NULL - mapBrush_t *brush; - mapPatch_t *patch; - mapModel_t *model; -} mapPrimitive_t; - -typedef struct mapEntity_s { - int numPrimitives; - mapPrimitive_t **primitives; - - int numEpairs; - ePair_t **ePairs; -} mapEntity_t; - -typedef struct { - int numEntities; - mapEntity_t **entities; -} mapFile_t; - - -// the order of entities, brushes, and sides will be maintained, the -// lists won't be swapped on each load or save -mapFile_t *ParseMapFile( const char *text ); -void FreeMapFile( mapFile_t *mapFile ); -void WriteMapFile( const mapFile_t *mapFile, FILE *f ); - -// key names are case-insensitive -const char *ValueForMapEntityKey( const mapEntity_t *ent, const char *key ); -float FloatForMapEntityKey( const mapEntity_t *ent, const char *key ); -qboolean GetVectorForMapEntityKey( const mapEntity_t *ent, const char *key, idVec3 &vec ); - -typedef struct { - idVec3 xyz; - idVec2 st; - idVec3 normal; - idVec3 tangents[2]; - byte smoothing[4]; // colors for silhouette smoothing -} drawVert_t; - -typedef struct { - int width, height; - drawVert_t *verts; -} drawVertMesh_t; - -// Tesselate a map patch into smoothed, drawable vertexes -// MaxError of around 4 is reasonable -drawVertMesh_t *SubdivideMapPatch( const mapPatch_t *patch, float maxError ); -#endif // __cplusplus - -//========================================= - -#ifdef __cplusplus -extern "C" { -#endif - -void QDECL Com_Error( int level, const char *error, ... ); -void QDECL Com_Printf( const char *msg, ... ); -void QDECL Com_DPrintf( const char *msg, ... ); - -#ifdef __cplusplus -} -#endif - - -typedef struct { - qboolean frameMemory; - int currentElements; - int maxElements; // will reallocate and move when exceeded - void **elements; -} growList_t; - -// you don't need to init the growlist if you don't mind it growing and moving -// the list as it expands -void Com_InitGrowList( growList_t *list, int maxElements ); -int Com_AddToGrowList( growList_t *list, void *data ); -void *Com_GrowListElement( const growList_t *list, int index ); -int Com_IndexForGrowListElement( const growList_t *list, const void *element ); - - -// -// key / value info strings -// -const char *Info_ValueForKey( const char *s, const char *key ); -void Info_RemoveKey( char *s, const char *key ); -void Info_SetValueForKey( char *s, const char *key, const char *value ); -qboolean Info_Validate( const char *s ); -void Info_NextPair( const char *( *s ), char key[MAX_INFO_KEY], char value[MAX_INFO_VALUE] ); - -// get cvar defs, collision defs, etc -//#include "../shared/interface.h" - -// get key code numbers for events -//#include "../shared/keycodes.h" - -#ifdef __cplusplus -// get the polygon winding functions -//#include "../shared/windings.h" - -// get the flags class -//#include "../shared/idflags.h" -#endif // __cplusplus - -#endif // __Q_SHARED_H diff --git a/libs/splines/splines.cpp b/libs/splines/splines.cpp deleted file mode 100644 index e35d82b..0000000 --- a/libs/splines/splines.cpp +++ /dev/null @@ -1,1449 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q_shared.h" -#include "splines.h" - -extern "C" { -int FS_Write( const void *buffer, int len, fileHandle_t h ); -int FS_ReadFile( const char *qpath, void **buffer ); -void FS_FreeFile( void *buffer ); -fileHandle_t FS_FOpenFileWrite( const char *filename ); -void FS_FCloseFile( fileHandle_t f ); -void Cbuf_AddText( const char *text ); -void Cbuf_Execute( void ); -} - -float Q_fabs( float f ) { - int tmp = *( int * ) &f; - tmp &= 0x7FFFFFFF; - return *( float * ) &tmp; -} - -// (SA) making a list of cameras so I can use -// the splines as targets for other things. -// Certainly better ways to do this, but this lets -// me get underway quickly with ents that need spline -// targets. -const int MAX_CAMERAS = 64; - -idCameraDef camera[MAX_CAMERAS]; - -extern "C" { -qboolean loadCamera( int camNum, const char *name ) { - if ( camNum < 0 || camNum >= MAX_CAMERAS ) { - return qfalse; - } - camera[camNum].clear(); - return (qboolean)camera[camNum].load( name ); -} - -qboolean getCameraInfo( int camNum, int time, float *origin, float *angles, float *fov ) { - idVec3 dir, org; - if ( camNum < 0 || camNum >= MAX_CAMERAS ) { - return qfalse; - } - org[0] = origin[0]; - org[1] = origin[1]; - org[2] = origin[2]; - if ( camera[camNum].getCameraInfo( time, org, dir, fov ) ) { - origin[0] = org[0]; - origin[1] = org[1]; - origin[2] = org[2]; - angles[1] = atan2( dir[1], dir[0] ) * 180 / 3.14159; - angles[0] = asin( dir[2] ) * 180 / 3.14159; - return qtrue; - } - return qfalse; -} - -void startCamera( int camNum, int time ) { - if ( camNum < 0 || camNum >= MAX_CAMERAS ) { - return; - } - camera[camNum].startCamera( time ); -} - -} - - -//#include "../shared/windings.h" -//#include "../qcommon/qcommon.h" -//#include "../sys/sys_public.h" -//#include "../game/game_entity.h" - -idCameraDef splineList; -idCameraDef *g_splineList = &splineList; - -idVec3 idSplineList::zero( 0,0,0 ); - -void glLabeledPoint( idVec3 &color, idVec3 &point, float size, const char *label ) { - glColor3fv( color ); - glPointSize( size ); - glBegin( GL_POINTS ); - glVertex3fv( point ); - glEnd(); - idVec3 v = point; - v.x += 1; - v.y += 1; - v.z += 1; - glRasterPos3fv( v ); - glCallLists( strlen( label ), GL_UNSIGNED_BYTE, label ); -} - - -void glBox( idVec3 &color, idVec3 &point, float size ) { - idVec3 mins( point ); - idVec3 maxs( point ); - mins[0] -= size; - mins[1] += size; - mins[2] -= size; - maxs[0] += size; - maxs[1] -= size; - maxs[2] += size; - glColor3fv( color ); - glBegin( GL_LINE_LOOP ); - glVertex3f( mins[0],mins[1],mins[2] ); - glVertex3f( maxs[0],mins[1],mins[2] ); - glVertex3f( maxs[0],maxs[1],mins[2] ); - glVertex3f( mins[0],maxs[1],mins[2] ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex3f( mins[0],mins[1],maxs[2] ); - glVertex3f( maxs[0],mins[1],maxs[2] ); - glVertex3f( maxs[0],maxs[1],maxs[2] ); - glVertex3f( mins[0],maxs[1],maxs[2] ); - glEnd(); - - glBegin( GL_LINES ); - glVertex3f( mins[0],mins[1],mins[2] ); - glVertex3f( mins[0],mins[1],maxs[2] ); - glVertex3f( mins[0],maxs[1],maxs[2] ); - glVertex3f( mins[0],maxs[1],mins[2] ); - glVertex3f( maxs[0],mins[1],mins[2] ); - glVertex3f( maxs[0],mins[1],maxs[2] ); - glVertex3f( maxs[0],maxs[1],maxs[2] ); - glVertex3f( maxs[0],maxs[1],mins[2] ); - glEnd(); - -} - -void splineTest() { - //g_splineList->load("p:/doom/base/maps/test_base1.camera"); -} - -void splineDraw() { - //g_splineList->addToRenderer(); -} - - -//extern void D_DebugLine( const idVec3 &color, const idVec3 &start, const idVec3 &end ); - -void debugLine( idVec3 &color, float x, float y, float z, float x2, float y2, float z2 ) { - idVec3 from( x, y, z ); - idVec3 to( x2, y2, z2 ); - //D_DebugLine(color, from, to); -} - -void idSplineList::addToRenderer() { - - if ( controlPoints.Num() == 0 ) { - return; - } - - idVec3 mins, maxs; - idVec3 yellow( 1.0, 1.0, 0 ); - idVec3 white( 1.0, 1.0, 1.0 ); - int i; - - for ( i = 0; i < controlPoints.Num(); i++ ) { - VectorCopy( *controlPoints[i], mins ); - VectorCopy( mins, maxs ); - mins[0] -= 8; - mins[1] += 8; - mins[2] -= 8; - maxs[0] += 8; - maxs[1] -= 8; - maxs[2] += 8; - debugLine( yellow, mins[0], mins[1], mins[2], maxs[0], mins[1], mins[2] ); - debugLine( yellow, maxs[0], mins[1], mins[2], maxs[0], maxs[1], mins[2] ); - debugLine( yellow, maxs[0], maxs[1], mins[2], mins[0], maxs[1], mins[2] ); - debugLine( yellow, mins[0], maxs[1], mins[2], mins[0], mins[1], mins[2] ); - - debugLine( yellow, mins[0], mins[1], maxs[2], maxs[0], mins[1], maxs[2] ); - debugLine( yellow, maxs[0], mins[1], maxs[2], maxs[0], maxs[1], maxs[2] ); - debugLine( yellow, maxs[0], maxs[1], maxs[2], mins[0], maxs[1], maxs[2] ); - debugLine( yellow, mins[0], maxs[1], maxs[2], mins[0], mins[1], maxs[2] ); - - } - - int step = 0; - idVec3 step1; - for ( i = 3; i < controlPoints.Num(); i++ ) { - for ( float tension = 0.0f; tension < 1.001f; tension += 0.1f ) { - float x = 0; - float y = 0; - float z = 0; - for ( int j = 0; j < 4; j++ ) { - x += controlPoints[i - ( 3 - j )]->x * calcSpline( j, tension ); - y += controlPoints[i - ( 3 - j )]->y * calcSpline( j, tension ); - z += controlPoints[i - ( 3 - j )]->z * calcSpline( j, tension ); - } - if ( step == 0 ) { - step1[0] = x; - step1[1] = y; - step1[2] = z; - step = 1; - } - else { - debugLine( white, step1[0], step1[1], step1[2], x, y, z ); - step = 0; - } - - } - } -} - -void idSplineList::buildSpline() { - //int start = Sys_Milliseconds(); - clearSpline(); - for ( int i = 3; i < controlPoints.Num(); i++ ) { - for ( float tension = 0.0f; tension < 1.001f; tension += granularity ) { - float x = 0; - float y = 0; - float z = 0; - for ( int j = 0; j < 4; j++ ) { - x += controlPoints[i - ( 3 - j )]->x * calcSpline( j, tension ); - y += controlPoints[i - ( 3 - j )]->y * calcSpline( j, tension ); - z += controlPoints[i - ( 3 - j )]->z * calcSpline( j, tension ); - } - splinePoints.Append( new idVec3( x, y, z ) ); - } - } - dirty = false; - //Com_Printf("Spline build took %f seconds\n", (float)(Sys_Milliseconds() - start) / 1000); -} - - -void idSplineList::draw( bool editMode ) { - int i; - idVec4 yellow( 1, 1, 0, 1 ); - - if ( controlPoints.Num() == 0 ) { - return; - } - - if ( dirty ) { - buildSpline(); - } - - - glColor3fv( controlColor ); - glPointSize( 5 ); - - glBegin( GL_POINTS ); - for ( i = 0; i < controlPoints.Num(); i++ ) { - glVertex3fv( *controlPoints[i] ); - } - glEnd(); - - if ( editMode ) { - for ( i = 0; i < controlPoints.Num(); i++ ) { - glBox( activeColor, *controlPoints[i], 4 ); - } - } - - //Draw the curve - glColor3fv( pathColor ); - glBegin( GL_LINE_STRIP ); - int count = splinePoints.Num(); - for ( i = 0; i < count; i++ ) { - glVertex3fv( *splinePoints[i] ); - } - glEnd(); - - if ( editMode ) { - glColor3fv( segmentColor ); - glPointSize( 3 ); - glBegin( GL_POINTS ); - for ( i = 0; i < count; i++ ) { - glVertex3fv( *splinePoints[i] ); - } - glEnd(); - } - if ( count > 0 ) { - //assert(activeSegment >=0 && activeSegment < count); - if ( activeSegment >= 0 && activeSegment < count ) { - glBox( activeColor, *splinePoints[activeSegment], 6 ); - glBox( yellow, *splinePoints[activeSegment], 8 ); - } - } - -} - -float idSplineList::totalDistance() { - - // FIXME: save dist and return - // - if ( controlPoints.Num() == 0 ) { - return 0.0; - } - - if ( dirty ) { - buildSpline(); - } - - float dist = 0.0; - idVec3 temp; - int count = splinePoints.Num(); - for ( int i = 1; i < count; i++ ) { - temp = *splinePoints[i - 1]; - temp -= *splinePoints[i]; - dist += temp.Length(); - } - return dist; -} - -void idSplineList::initPosition( long bt, long totalTime ) { - - if ( dirty ) { - buildSpline(); - } - - if ( splinePoints.Num() == 0 ) { - return; - } - - baseTime = bt; - time = totalTime; - - // calc distance to travel ( this will soon be broken into time segments ) - splineTime.Clear(); - splineTime.Append( bt ); - double dist = totalDistance(); - double distSoFar = 0.0; - idVec3 temp; - int count = splinePoints.Num(); - //for(int i = 2; i < count - 1; i++) { - for ( int i = 1; i < count; i++ ) { - temp = *splinePoints[i - 1]; - temp -= *splinePoints[i]; - distSoFar += temp.Length(); - double percent = distSoFar / dist; - percent *= totalTime; - splineTime.Append( percent + bt ); - } - assert( splineTime.Num() == splinePoints.Num() ); - activeSegment = 0; -} - - - -float idSplineList::calcSpline( int step, float tension ) { - switch ( step ) { - case 0: return ( pow( 1 - tension, 3 ) ) / 6; - case 1: return ( 3 * pow( tension, 3 ) - 6 * pow( tension, 2 ) + 4 ) / 6; - case 2: return ( -3 * pow( tension, 3 ) + 3 * pow( tension, 2 ) + 3 * tension + 1 ) / 6; - case 3: return pow( tension, 3 ) / 6; - } - return 0.0; -} - - - -void idSplineList::updateSelection( const idVec3 &move ) { - if ( selected ) { - dirty = true; - VectorAdd( *selected, move, *selected ); - } -} - - -void idSplineList::setSelectedPoint( idVec3 *p ) { - if ( p ) { - p->Snap(); - for ( int i = 0; i < controlPoints.Num(); i++ ) { - if ( *p == *controlPoints[i] ) { - selected = controlPoints[i]; - } - } - } - else { - selected = NULL; - } -} - -const idVec3 *idSplineList::getPosition( long t ) { - static idVec3 interpolatedPos; - - int count = splineTime.Num(); - if ( count == 0 ) { - return &zero; - } - -// Com_Printf("Time: %d\n", t); - assert( splineTime.Num() == splinePoints.Num() ); - - while ( activeSegment < count ) { - if ( splineTime[activeSegment] >= t ) { - if ( activeSegment > 0 && activeSegment < count - 1 ) { - double timeHi = splineTime[activeSegment + 1]; - double timeLo = splineTime[activeSegment - 1]; - double percent = ( timeHi - t ) / ( timeHi - timeLo ); - // pick two bounding points - idVec3 v1 = *splinePoints[activeSegment - 1]; - idVec3 v2 = *splinePoints[activeSegment + 1]; - v2 *= ( 1.0 - percent ); - v1 *= percent; - v2 += v1; - interpolatedPos = v2; - return &interpolatedPos; - } - return splinePoints[activeSegment]; - } - else { - activeSegment++; - } - } - return splinePoints[count - 1]; -} - -void idSplineList::parse( const char *( *text ) ) { - const char *token; - //Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !Q_stricmp( token, "}" ) ) { - break; - } - - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !Q_stricmp( token, "(" ) || !Q_stricmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - const char *token = Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "granularity" ) == 0 ) { - granularity = atof( token ); - } - else if ( Q_stricmp( key.c_str(), "name" ) == 0 ) { - name = token; - } - token = Com_Parse( text ); - - } while ( 1 ); - - if ( !Q_stricmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - // read the control point - idVec3 point; - Com_Parse1DMatrix( text, 3, point ); - addPoint( point.x, point.y, point.z ); - } while ( 1 ); - - //Com_UngetToken(); - //Com_MatchToken( text, "}" ); - dirty = true; -} - -void idSplineList::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - //s = va("\t\tname %s\n", name.c_str()); - //FS_Write(s.c_str(), s.length(), file); - s = va( "\t\t\tgranularity %f\n", granularity ); - FS_Write( s.c_str(), s.length(), file ); - int count = controlPoints.Num(); - for ( int i = 0; i < count; i++ ) { - s = va( "\t\t\t( %f %f %f )\n", controlPoints[i]->x, controlPoints[i]->y, controlPoints[i]->z ); - FS_Write( s.c_str(), s.length(), file ); - } - s = "\t\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - - -void idCameraDef::getActiveSegmentInfo( int segment, idVec3 &origin, idVec3 &direction, float *fov ) { -#if 0 - if ( !cameraSpline.validTime() ) { - buildCamera(); - } - double d = (double)segment / numSegments(); - getCameraInfo( d * totalTime * 1000, origin, direction, fov ); -#endif -/* - if (!cameraSpline.validTime()) { - buildCamera(); - } - origin = *cameraSpline.getSegmentPoint(segment); - - - idVec3 temp; - - int numTargets = getTargetSpline()->controlPoints.Num(); - int count = cameraSpline.splineTime.Num(); - if (numTargets == 0) { - // follow the path - if (cameraSpline.getActiveSegment() < count - 1) { - temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1]; - } - } else if (numTargets == 1) { - temp = *getTargetSpline()->controlPoints[0]; - } else { - temp = *getTargetSpline()->getSegmentPoint(segment); - } - - temp -= origin; - temp.Normalize(); - direction = temp; - */ -} - -bool idCameraDef::getCameraInfo( long time, idVec3 &origin, idVec3 &direction, float *fv ) { - - char buff[1024]; - - if ( ( time - startTime ) / 1000 > totalTime ) { - return false; - } - - - for ( int i = 0; i < events.Num(); i++ ) { - if ( time >= startTime + events[i]->getTime() && !events[i]->getTriggered() ) { - events[i]->setTriggered( true ); - if ( events[i]->getType() == idCameraEvent::EVENT_TARGET ) { - setActiveTargetByName( events[i]->getParam() ); - getActiveTarget()->start( startTime + events[i]->getTime() ); - //Com_Printf("Triggered event switch to target: %s\n",events[i]->getParam()); - } - else if ( events[i]->getType() == idCameraEvent::EVENT_TRIGGER ) { - //idEntity *ent = NULL; - //ent = level.FindTarget( ent, events[i]->getParam()); - //if (ent) { - // ent->signal( SIG_TRIGGER ); - // ent->ProcessEvent( &EV_Activate, world ); - //} - } - else if ( events[i]->getType() == idCameraEvent::EVENT_FOV ) { - memset( buff, 0, sizeof( buff ) ); - strcpy( buff, events[i]->getParam() ); - const char *param1 = strtok( buff, " \t,\0" ); - const char *param2 = strtok( NULL, " \t,\0" ); - float len = ( param2 ) ? atof( param2 ) : 0; - float newfov = ( param1 ) ? atof( param1 ) : 90; - fov.reset( fov.getFOV( time ), newfov, time, len ); - //*fv = fov = atof(events[i]->getParam()); - } - else if ( events[i]->getType() == idCameraEvent::EVENT_FADEIN ) { - float time = atof( events[i]->getParam() ); - Cbuf_AddText( va( "fade 0 0 0 0 %f", time ) ); - Cbuf_Execute(); - } - else if ( events[i]->getType() == idCameraEvent::EVENT_FADEOUT ) { - float time = atof( events[i]->getParam() ); - Cbuf_AddText( va( "fade 0 0 0 255 %f", time ) ); - Cbuf_Execute(); - } - else if ( events[i]->getType() == idCameraEvent::EVENT_CAMERA ) { - memset( buff, 0, sizeof( buff ) ); - strcpy( buff, events[i]->getParam() ); - const char *param1 = strtok( buff, " \t,\0" ); - const char *param2 = strtok( NULL, " \t,\0" ); - - if ( param2 ) { - loadCamera( atoi( param1 ), va( "cameras/%s.camera", param2 ) ); - startCamera( time ); - } - else { - loadCamera( 0, va( "cameras/%s.camera", events[i]->getParam() ) ); - startCamera( time ); - } - return true; - } - else if ( events[i]->getType() == idCameraEvent::EVENT_STOP ) { - return false; - } - } - } - - origin = *cameraPosition->getPosition( time ); - - *fv = fov.getFOV( time ); - - idVec3 temp = origin; - - int numTargets = targetPositions.Num(); - if ( numTargets == 0 ) { -/* - // follow the path - if (cameraSpline.getActiveSegment() < count - 1) { - temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1]; - if (temp == origin) { - int index = cameraSpline.getActiveSegment() + 2; - while (temp == origin && index < count - 1) { - temp = *cameraSpline.splinePoints[index++]; - } - } - } - */ - } - else { - if ( getActiveTarget()->numPoints() > 0 ) { - temp = *getActiveTarget()->getPosition( time ); - } - } - - temp -= origin; - temp.Normalize(); - direction = temp; - - return true; -} - -bool idCameraDef::waitEvent( int index ) { - //for (int i = 0; i < events.Num(); i++) { - // if (events[i]->getSegment() == index && events[i]->getType() == idCameraEvent::EVENT_WAIT) { - // return true; - // } - //} - return false; -} - - -const int NUM_CCELERATION_SEGS = 10; -const int CELL_AMT = 5; - -void idCameraDef::buildCamera() { - int i; - idList waits; - idList targets; - - totalTime = baseTime; - cameraPosition->setTime( (long)totalTime * 1000 ); - // we have a base time layout for the path and the target path - // now we need to layer on any wait or speed changes - for ( i = 0; i < events.Num(); i++ ) { - events[i]->setTriggered( false ); - switch ( events[i]->getType() ) { - default: break; - case idCameraEvent::EVENT_TARGET: { - targets.Append( i ); - break; - } - case idCameraEvent::EVENT_FEATHER: { - long startTime = 0; - float speed = 0; - long loopTime = 10; - float stepGoal = cameraPosition->getBaseVelocity() / ( 1000 / loopTime ); - while ( startTime <= 1000 ) { - cameraPosition->addVelocity( startTime, loopTime, speed ); - speed += stepGoal; - if ( speed > cameraPosition->getBaseVelocity() ) { - speed = cameraPosition->getBaseVelocity(); - } - startTime += loopTime; - } - - startTime = (long)( totalTime * 1000 - 1000 ); - long endTime = startTime + 1000; - speed = cameraPosition->getBaseVelocity(); - while ( startTime < endTime ) { - speed -= stepGoal; - if ( speed < 0 ) { - speed = 0; - } - cameraPosition->addVelocity( startTime, loopTime, speed ); - startTime += loopTime; - } - break; - - } - case idCameraEvent::EVENT_WAIT: { - waits.Append( atof( events[i]->getParam() ) ); - - //FIXME: this is quite hacky for Wolf E3, accel and decel needs - // do be parameter based etc.. - long startTime = events[i]->getTime() - 1000; - if ( startTime < 0 ) { - startTime = 0; - } - float speed = cameraPosition->getBaseVelocity(); - long loopTime = 10; - float steps = speed / ( ( events[i]->getTime() - startTime ) / loopTime ); - while ( startTime <= events[i]->getTime() - loopTime ) { - cameraPosition->addVelocity( startTime, loopTime, speed ); - speed -= steps; - startTime += loopTime; - } - cameraPosition->addVelocity( events[i]->getTime(), (long)atof( events[i]->getParam() ) * 1000, 0 ); - - startTime = (long)( events[i]->getTime() + atof( events[i]->getParam() ) * 1000 ); - long endTime = startTime + 1000; - speed = 0; - while ( startTime <= endTime ) { - cameraPosition->addVelocity( startTime, loopTime, speed ); - speed += steps; - startTime += loopTime; - } - break; - } - case idCameraEvent::EVENT_TARGETWAIT: { - //targetWaits.Append(i); - break; - } - case idCameraEvent::EVENT_SPEED: { -/* - // take the average delay between up to the next five segments - float adjust = atof(events[i]->getParam()); - int index = events[i]->getSegment(); - total = 0; - count = 0; - - // get total amount of time over the remainder of the segment - for (j = index; j < cameraSpline.numSegments() - 1; j++) { - total += cameraSpline.getSegmentTime(j + 1) - cameraSpline.getSegmentTime(j); - count++; - } - - // multiply that by the adjustment - double newTotal = total * adjust; - // what is the difference.. - newTotal -= total; - totalTime += newTotal / 1000; - - // per segment difference - newTotal /= count; - int additive = newTotal; - - // now propogate that difference out to each segment - for (j = index; j < cameraSpline.numSegments(); j++) { - cameraSpline.addSegmentTime(j, additive); - additive += newTotal; - } - break; - */ - } - } - } - - - for ( i = 0; i < waits.Num(); i++ ) { - totalTime += waits[i]; - } - - // on a new target switch, we need to take time to this point ( since last target switch ) - // and allocate it across the active target, then reset time to this point - long timeSoFar = 0; - long total = (long)( totalTime * 1000 ); - for ( i = 0; i < targets.Num(); i++ ) { - long t; - if ( i < targets.Num() - 1 ) { - t = events[targets[i + 1]]->getTime(); - } - else { - t = total - timeSoFar; - } - // t is how much time to use for this target - setActiveTargetByName( events[targets[i]]->getParam() ); - getActiveTarget()->setTime( t ); - timeSoFar += t; - } - - -} - -void idCameraDef::startCamera( long t ) { - cameraPosition->clearVelocities(); - cameraPosition->start( t ); - buildCamera(); - fov.reset( 90, 90, t, 0 ); - //for (int i = 0; i < targetPositions.Num(); i++) { - // targetPositions[i]-> - //} - startTime = t; - cameraRunning = true; -} - - -void idCameraDef::parse( const char *( *text ) ) { - - const char *token; - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !Q_stricmp( token, "}" ) ) { - break; - } - - if ( Q_stricmp( token, "time" ) == 0 ) { - baseTime = Com_ParseFloat( text ); - } - else if ( Q_stricmp( token, "camera_fixed" ) == 0 ) { - cameraPosition = new idFixedPosition(); - cameraPosition->parse( text ); - } - else if ( Q_stricmp( token, "camera_interpolated" ) == 0 ) { - cameraPosition = new idInterpolatedPosition(); - cameraPosition->parse( text ); - } - else if ( Q_stricmp( token, "camera_spline" ) == 0 ) { - cameraPosition = new idSplinePosition(); - cameraPosition->parse( text ); - } - else if ( Q_stricmp( token, "target_fixed" ) == 0 ) { - idFixedPosition *pos = new idFixedPosition(); - pos->parse( text ); - targetPositions.Append( pos ); - } - else if ( Q_stricmp( token, "target_interpolated" ) == 0 ) { - idInterpolatedPosition *pos = new idInterpolatedPosition(); - pos->parse( text ); - targetPositions.Append( pos ); - } - else if ( Q_stricmp( token, "target_spline" ) == 0 ) { - idSplinePosition *pos = new idSplinePosition(); - pos->parse( text ); - targetPositions.Append( pos ); - } - else if ( Q_stricmp( token, "fov" ) == 0 ) { - fov.parse( text ); - } - else if ( Q_stricmp( token, "event" ) == 0 ) { - idCameraEvent *event = new idCameraEvent(); - event->parse( text ); - addEvent( event ); - } - - - } while ( 1 ); - - if ( !cameraPosition ) { - Com_Printf( "no camera position specified\n" ); - // prevent a crash later on - cameraPosition = new idFixedPosition(); - } - - Com_UngetToken(); - Com_MatchToken( text, "}" ); - -} - -bool idCameraDef::load( const char *filename ) { - char *buf; - const char *buf_p; - - FS_ReadFile( filename, (void **)&buf ); - if ( !buf ) { - return false; - } - - clear(); - Com_BeginParseSession( filename ); - buf_p = buf; - parse( &buf_p ); - Com_EndParseSession(); - FS_FreeFile( buf ); - - return true; -} - -void idCameraDef::save( const char *filename ) { - fileHandle_t file = FS_FOpenFileWrite( filename ); - if ( file ) { - int i; - idStr s = "cameraPathDef { \n"; - FS_Write( s.c_str(), s.length(), file ); - s = va( "\ttime %f\n", baseTime ); - FS_Write( s.c_str(), s.length(), file ); - - cameraPosition->write( file, va( "camera_%s",cameraPosition->typeStr() ) ); - - for ( i = 0; i < numTargets(); i++ ) { - targetPositions[i]->write( file, va( "target_%s", targetPositions[i]->typeStr() ) ); - } - - for ( i = 0; i < events.Num(); i++ ) { - events[i]->write( file, "event" ); - } - - fov.write( file, "fov" ); - - s = "}\n"; - FS_Write( s.c_str(), s.length(), file ); - } - FS_FCloseFile( file ); -} - -int idCameraDef::sortEvents( const void *p1, const void *p2 ) { - idCameraEvent *ev1 = (idCameraEvent*)( p1 ); - idCameraEvent *ev2 = (idCameraEvent*)( p2 ); - - if ( ev1->getTime() > ev2->getTime() ) { - return -1; - } - if ( ev1->getTime() < ev2->getTime() ) { - return 1; - } - return 0; -} - -void idCameraDef::addEvent( idCameraEvent *event ) { - events.Append( event ); - //events.Sort(&sortEvents); - -} -void idCameraDef::addEvent( idCameraEvent::eventType t, const char *param, long time ) { - addEvent( new idCameraEvent( t, param, time ) ); - buildCamera(); -} - -void idCameraDef::removeEvent( int index ) { - events.RemoveIndex( index ); - buildCamera(); -} - - -const char *idCameraEvent::eventStr[] = { - "NA", - "WAIT", - "TARGETWAIT", - "SPEED", - "TARGET", - "SNAPTARGET", - "FOV", - "CMD", - "TRIGGER", - "STOP", - "CAMERA", - "FADEOUT", - "FADEIN", - "FEATHER" -}; - -void idCameraEvent::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - const char *token = Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "type" ) == 0 ) { - type = static_cast( atoi( token ) ); - } - else if ( Q_stricmp( key.c_str(), "param" ) == 0 ) { - paramStr = token; - } - else if ( Q_stricmp( key.c_str(), "time" ) == 0 ) { - time = atoi( token ); - } - token = Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - -void idCameraEvent::write( fileHandle_t file, const char *name ) { - idStr s = va( "\t%s {\n", name ); - FS_Write( s.c_str(), s.length(), file ); - s = va( "\t\ttype %d\n", static_cast( type ) ); - FS_Write( s.c_str(), s.length(), file ); - s = va( "\t\tparam \"%s\"\n", paramStr.c_str() ); - FS_Write( s.c_str(), s.length(), file ); - s = va( "\t\ttime %d\n", time ); - FS_Write( s.c_str(), s.length(), file ); - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - - -const char *idCameraPosition::positionStr[] = { - "Fixed", - "Interpolated", - "Spline", -}; - - - -const idVec3 *idInterpolatedPosition::getPosition( long t ) { - static idVec3 interpolatedPos; - - float velocity = getVelocity( t ); - float timePassed = t - lastTime; - lastTime = t; - - // convert to seconds - timePassed /= 1000; - - float distToTravel = timePassed * velocity; - - idVec3 temp = startPos; - temp -= endPos; - float distance = temp.Length(); - - distSoFar += distToTravel; - float percent = (float)( distSoFar ) / distance; - - if ( percent > 1.0 ) { - percent = 1.0; - } - else if ( percent < 0.0 ) { - percent = 0.0; - } - - // the following line does a straigt calc on percentage of time - // float percent = (float)(startTime + time - t) / time; - - idVec3 v1 = startPos; - idVec3 v2 = endPos; - v1 *= ( 1.0 - percent ); - v2 *= percent; - v1 += v2; - interpolatedPos = v1; - return &interpolatedPos; -} - - -void idCameraFOV::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - const char *token = Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "fov" ) == 0 ) { - fov = atof( token ); - } - else if ( Q_stricmp( key.c_str(), "startFOV" ) == 0 ) { - startFOV = atof( token ); - } - else if ( Q_stricmp( key.c_str(), "endFOV" ) == 0 ) { - endFOV = atof( token ); - } - else if ( Q_stricmp( key.c_str(), "time" ) == 0 ) { - time = atoi( token ); - } - token = Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - -bool idCameraPosition::parseToken( const char *key, const char *( *text ) ) { - const char *token = Com_Parse( text ); - if ( Q_stricmp( key, "time" ) == 0 ) { - time = atol( token ); - return true; - } - else if ( Q_stricmp( key, "type" ) == 0 ) { - type = static_cast( atoi( token ) ); - return true; - } - else if ( Q_stricmp( key, "velocity" ) == 0 ) { - long t = atol( token ); - token = Com_Parse( text ); - long d = atol( token ); - token = Com_Parse( text ); - float s = atof( token ); - addVelocity( t, d, s ); - return true; - } - else if ( Q_stricmp( key, "baseVelocity" ) == 0 ) { - baseVelocity = atof( token ); - return true; - } - else if ( Q_stricmp( key, "name" ) == 0 ) { - name = token; - return true; - } - else if ( Q_stricmp( key, "time" ) == 0 ) { - time = atoi( token ); - return true; - } - Com_UngetToken(); - return false; -} - - - -void idFixedPosition::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - - Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "pos" ) == 0 ) { - Com_UngetToken(); - Com_Parse1DMatrix( text, 3, pos ); - } - else { - Com_UngetToken(); - idCameraPosition::parseToken( key.c_str(), text ); - } - Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - -void idInterpolatedPosition::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - - Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "startPos" ) == 0 ) { - Com_UngetToken(); - Com_Parse1DMatrix( text, 3, startPos ); - } - else if ( Q_stricmp( key.c_str(), "endPos" ) == 0 ) { - Com_UngetToken(); - Com_Parse1DMatrix( text, 3, endPos ); - } - else { - Com_UngetToken(); - idCameraPosition::parseToken( key.c_str(), text ); - } - Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - - -void idSplinePosition::parse( const char *( *text ) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp( token, "(" ) || !strcmp( token, "}" ) ) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine( text ); - - Com_Parse( text ); - if ( Q_stricmp( key.c_str(), "target" ) == 0 ) { - target.parse( text ); - } - else { - Com_UngetToken(); - idCameraPosition::parseToken( key.c_str(), text ); - } - Com_Parse( text ); - - } while ( 1 ); - - if ( !strcmp( token, "}" ) ) { - break; - } - - } while ( 1 ); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - - - -void idCameraFOV::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tfov %f\n", fov ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tstartFOV %f\n", startFOV ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tendFOV %f\n", endFOV ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\ttime %i\n", time ); - FS_Write( s.c_str(), s.length(), file ); - - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - - -void idCameraPosition::write( fileHandle_t file, const char *p ) { - - idStr s = va( "\t\ttime %i\n", time ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\ttype %i\n", static_cast( type ) ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tname %s\n", name.c_str() ); - FS_Write( s.c_str(), s.length(), file ); - - s = va( "\t\tbaseVelocity %f\n", baseVelocity ); - FS_Write( s.c_str(), s.length(), file ); - - for ( int i = 0; i < velocities.Num(); i++ ) { - s = va( "\t\tvelocity %i %i %f\n", velocities[i]->startTime, velocities[i]->time, velocities[i]->speed ); - FS_Write( s.c_str(), s.length(), file ); - } - -} - -void idFixedPosition::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - idCameraPosition::write( file, p ); - s = va( "\t\tpos ( %f %f %f )\n", pos.x, pos.y, pos.z ); - FS_Write( s.c_str(), s.length(), file ); - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - -void idInterpolatedPosition::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - idCameraPosition::write( file, p ); - s = va( "\t\tstartPos ( %f %f %f )\n", startPos.x, startPos.y, startPos.z ); - FS_Write( s.c_str(), s.length(), file ); - s = va( "\t\tendPos ( %f %f %f )\n", endPos.x, endPos.y, endPos.z ); - FS_Write( s.c_str(), s.length(), file ); - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - -void idSplinePosition::write( fileHandle_t file, const char *p ) { - idStr s = va( "\t%s {\n", p ); - FS_Write( s.c_str(), s.length(), file ); - idCameraPosition::write( file, p ); - target.write( file, "target" ); - s = "\t}\n"; - FS_Write( s.c_str(), s.length(), file ); -} - -void idCameraDef::addTarget( const char *name, idCameraPosition::positionType type ) { - idCameraPosition *pos = newFromType( type ); - if ( pos ) { - pos->setName( name ); - targetPositions.Append( pos ); - activeTarget = numTargets() - 1; - if ( activeTarget == 0 ) { - // first one - addEvent( idCameraEvent::EVENT_TARGET, name, 0 ); - } - } -} - -const idVec3 *idSplinePosition::getPosition( long t ) { - static idVec3 interpolatedPos; - - float velocity = getVelocity( t ); - float timePassed = t - lastTime; - lastTime = t; - - // convert to seconds - timePassed /= 1000; - - float distToTravel = timePassed * velocity; - - distSoFar += distToTravel; - double tempDistance = target.totalDistance(); - - double percent = (double)( distSoFar ) / tempDistance; - - double targetDistance = percent * tempDistance; - tempDistance = 0; - - double lastDistance1,lastDistance2; - lastDistance1 = lastDistance2 = 0; - idVec3 temp; - int count = target.numSegments(); - int i; - for ( i = 1; i < count; i++ ) { - temp = *target.getSegmentPoint( i - 1 ); - temp -= *target.getSegmentPoint( i ); - tempDistance += temp.Length(); - if ( i & 1 ) { - lastDistance1 = tempDistance; - } - else { - lastDistance2 = tempDistance; - } - if ( tempDistance >= targetDistance ) { - break; - } - } - - if ( i >= count - 1 ) { - interpolatedPos = *target.getSegmentPoint( i - 1 ); - } - else { -#if 0 - double timeHi = target.getSegmentTime( i + 1 ); - double timeLo = target.getSegmentTime( i - 1 ); - double percent = ( timeHi - t ) / ( timeHi - timeLo ); - idVec3 v1 = *target.getSegmentPoint( i - 1 ); - idVec3 v2 = *target.getSegmentPoint( i + 1 ); - v2 *= ( 1.0 - percent ); - v1 *= percent; - v2 += v1; - interpolatedPos = v2; -#else - if ( lastDistance1 > lastDistance2 ) { - double d = lastDistance2; - lastDistance2 = lastDistance1; - lastDistance1 = d; - } - - idVec3 v1 = *target.getSegmentPoint( i - 1 ); - idVec3 v2 = *target.getSegmentPoint( i ); - double percent = ( lastDistance2 - targetDistance ) / ( lastDistance2 - lastDistance1 ); - v2 *= ( 1.0 - percent ); - v1 *= percent; - v2 += v1; - interpolatedPos = v2; -#endif - } - return &interpolatedPos; - -} diff --git a/libs/splines/splines.h b/libs/splines/splines.h deleted file mode 100644 index 051f76b..0000000 --- a/libs/splines/splines.h +++ /dev/null @@ -1,1140 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __SPLINES_H -#define __SPLINES_H - -#define GTKRADIANT - -#ifdef GTKRADIANT -#include "igl.h" -#endif - -#include "util_list.h" -#include "util_str.h" -#include "math_vector.h" - -typedef int fileHandle_t; - -extern void glBox( idVec3 &color, idVec3 &point, float size ); -extern void glLabeledPoint( idVec3 &color, idVec3 &point, float size, const char *label ); - -static idVec4 blue( 0, 0, 1, 1 ); -static idVec4 red( 1, 0, 0, 1 ); - -class idPointListInterface { -public: -idPointListInterface() { - selectedPoints.Clear(); -}; -virtual ~idPointListInterface() { -}; - -virtual int numPoints() { - return 0; -} - -virtual void addPoint( const float x, const float y, const float z ) { -} -virtual void addPoint( const idVec3 &v ) { -} -virtual void removePoint( int index ) { -} -virtual idVec3 *getPoint( int index ) { - return NULL; -} - -int selectPointByRay( float ox, float oy, float oz, float dx, float dy, float dz, bool single ) { - idVec3 origin( ox, oy, oz ); - idVec3 dir( dx, dy, dz ); - return selectPointByRay( origin, dir, single ); -} - -int selectPointByRay( const idVec3 origin, const idVec3 direction, bool single ) { - int i, besti, count; - float d, bestd; - idVec3 temp, temp2; - - // find the point closest to the ray - besti = -1; - bestd = 8; - count = numPoints(); - - for ( i = 0; i < count; i++ ) { - temp = *getPoint( i ); - temp2 = temp; - temp -= origin; - d = DotProduct( temp, direction ); - __VectorMA( origin, d, direction, temp ); - temp2 -= temp; - d = temp2.Length(); - if ( d <= bestd ) { - bestd = d; - besti = i; - } - } - - if ( besti >= 0 ) { - selectPoint( besti, single ); - } - - return besti; -} - -int isPointSelected( int index ) { - int count = selectedPoints.Num(); - for ( int i = 0; i < count; i++ ) { - if ( selectedPoints[i] == index ) { - return i; - } - } - return -1; -} - -int selectPoint( int index, bool single ) { - if ( index >= 0 && index < numPoints() ) { - if ( single ) { - deselectAll(); - } - else { - if ( isPointSelected( index ) >= 0 ) { - selectedPoints.Remove( index ); - } - } - return selectedPoints.Append( index ); - } - return -1; -} - -void selectAll() { - selectedPoints.Clear(); - for ( int i = 0; i < numPoints(); i++ ) { - selectedPoints.Append( i ); - } -} - -void deselectAll() { - selectedPoints.Clear(); -} - -int numSelectedPoints(); - -idVec3 *getSelectedPoint( int index ) { - assert( index >= 0 && index < numSelectedPoints() ); - return getPoint( selectedPoints[index] ); -} - -virtual void updateSelection( float x, float y, float z ) { - idVec3 move( x, y, z ); - updateSelection( move ); -} - -virtual void updateSelection( const idVec3 &move ) { - int count = selectedPoints.Num(); - for ( int i = 0; i < count; i++ ) { - *getPoint( selectedPoints[i] ) += move; - } -} - -void drawSelection() { - int count = selectedPoints.Num(); - for ( int i = 0; i < count; i++ ) { - glBox( red, *getPoint( selectedPoints[i] ), 4 ); - } -} - -protected: -idList selectedPoints; - -}; - - -class idSplineList { - -public: - -idSplineList() { - clear(); -} - -idSplineList( const char *p ) { - clear(); - name = p; -}; - -~idSplineList() { - clear(); -}; - -void clearControl() { - for ( int i = 0; i < controlPoints.Num(); i++ ) { - delete controlPoints[i]; - } - controlPoints.Clear(); -} - -void clearSpline() { - for ( int i = 0; i < splinePoints.Num(); i++ ) { - delete splinePoints[i]; - } - splinePoints.Clear(); -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -void clear() { - clearControl(); - clearSpline(); - splineTime.Clear(); - selected = NULL; - dirty = true; - activeSegment = 0; - granularity = 0.025f; - pathColor.set( 1.0f, 0.5f, 0.0f ); - controlColor.set( 0.7f, 0.0f, 1.0f ); - segmentColor.set( 0.0f, 0.0f, 1.0f ); - activeColor.set( 1.0f, 0.0f, 0.0f ); -} - -void initPosition( long startTime, long totalTime ); -const idVec3 *getPosition( long time ); - - -void draw( bool editMode ); -void addToRenderer(); - -void setSelectedPoint( idVec3 *p ); -idVec3 *getSelectedPoint() { - return selected; -} - -void addPoint( const idVec3 &v ) { - controlPoints.Append( new idVec3( v ) ); - dirty = true; -} - -void addPoint( float x, float y, float z ) { - controlPoints.Append( new idVec3( x, y, z ) ); - dirty = true; -} - -void updateSelection( const idVec3 &move ); - -void startEdit() { - editMode = true; -} - -void stopEdit() { - editMode = false; -} - -void buildSpline(); - -void setGranularity( float f ) { - granularity = f; -} - -float getGranularity() { - return granularity; -} - -int numPoints() { - return controlPoints.Num(); -} - -idVec3 *getPoint( int index ) { - assert( index >= 0 && index < controlPoints.Num() ); - return controlPoints[index]; -} - -idVec3 *getSegmentPoint( int index ) { - assert( index >= 0 && index < splinePoints.Num() ); - return splinePoints[index]; -} - - -void setSegmentTime( int index, int time ) { - assert( index >= 0 && index < splinePoints.Num() ); - splineTime[index] = time; -} - -int getSegmentTime( int index ) { - assert( index >= 0 && index < splinePoints.Num() ); - return (int)splineTime[index]; -} -void addSegmentTime( int index, int time ) { - assert( index >= 0 && index < splinePoints.Num() ); - splineTime[index] += time; -} - -float totalDistance(); - -static idVec3 zero; - -int getActiveSegment() { - return activeSegment; -} - -void setActiveSegment( int i ) { - //assert(i >= 0 && (splinePoints.Num() > 0 && i < splinePoints.Num())); - activeSegment = i; -} - -int numSegments() { - return splinePoints.Num(); -} - -void setColors( idVec3 &path, idVec3 &segment, idVec3 &control, idVec3 &active ) { - pathColor = path; - segmentColor = segment; - controlColor = control; - activeColor = active; -} - -const char *getName() { - return name.c_str(); -} - -void setName( const char *p ) { - name = p; -} - -bool validTime() { - if ( dirty ) { - buildSpline(); - } - // gcc doesn't allow static casting away from bools - // why? I've no idea... - return (bool)( splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num() ); -} - -void setTime( long t ) { - time = t; -} - -void setBaseTime( long t ) { - baseTime = t; -} - -protected: -idStr name; -float calcSpline( int step, float tension ); -idList controlPoints; -idList splinePoints; -idList splineTime; -idVec3 *selected; -idVec3 pathColor, segmentColor, controlColor, activeColor; -float granularity; -bool editMode; -bool dirty; -int activeSegment; -long baseTime; -long time; -friend class idCamera; -}; - -// time in milliseconds -// velocity where 1.0 equal rough walking speed -struct idVelocity { - idVelocity( long start, long duration, float s ) { - startTime = start; - time = duration; - speed = s; - } - long startTime; - long time; - float speed; -}; - -// can either be a look at or origin position for a camera -// -class idCameraPosition : public idPointListInterface { -public: - -virtual void clearVelocities() { - for ( int i = 0; i < velocities.Num(); i++ ) { - delete velocities[i]; - velocities[i] = NULL; - } - velocities.Clear(); -} - -virtual void clear() { - editMode = false; - clearVelocities(); -} - -idCameraPosition( const char *p ) { - name = p; -} - -idCameraPosition() { - time = 0; - name = "position"; -} - -idCameraPosition( long t ) { - time = t; -} - -virtual ~idCameraPosition() { - clear(); -} - - -// this can be done with RTTI syntax but i like the derived classes setting a type -// makes serialization a bit easier to see -// -enum positionType { - FIXED = 0x00, - INTERPOLATED, - SPLINE, - POSITION_COUNT -}; - - -virtual void start( long t ) { - startTime = t; -} - -long getTime() { - return time; -} - -virtual void setTime( long t ) { - time = t; -} - -float getBaseVelocity() { - return baseVelocity; -} - -float getVelocity( long t ) { - long check = t - startTime; - for ( int i = 0; i < velocities.Num(); i++ ) { - if ( check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time ) { - return velocities[i]->speed; - } - } - return baseVelocity; -} - -void addVelocity( long start, long duration, float speed ) { - velocities.Append( new idVelocity( start, duration, speed ) ); -} - -virtual const idVec3 *getPosition( long t ) { - assert( true ); - return NULL; -} - -virtual void draw( bool editMode ) { -}; - -virtual void parse( const char *( *text ) ) { -}; -virtual void write( fileHandle_t file, const char *name ); -virtual bool parseToken( const char *key, const char *( *text ) ); - -const char *getName() { - return name.c_str(); -} - -void setName( const char *p ) { - name = p; -} - -virtual void startEdit() { - editMode = true; -} - -virtual void stopEdit() { - editMode = false; -} - -virtual void draw() { -}; - -const char *typeStr() { - return positionStr[static_cast( type )]; -} - -void calcVelocity( float distance ) { - float secs = (float)time / 1000; - baseVelocity = distance / secs; -} - -protected: -static const char* positionStr[POSITION_COUNT]; -long startTime; -long time; -idCameraPosition::positionType type; -idStr name; -bool editMode; -idList velocities; -float baseVelocity; -}; - -class idFixedPosition : public idCameraPosition { -public: - -void init() { - pos.Zero(); - type = idCameraPosition::FIXED; -} - -idFixedPosition() : idCameraPosition() { - init(); -} - -idFixedPosition( idVec3 p ) : idCameraPosition() { - init(); - pos = p; -} - -virtual void addPoint( const idVec3 &v ) { - pos = v; -} - -virtual void addPoint( const float x, const float y, const float z ) { - pos.set( x, y, z ); -} - - -~idFixedPosition() { -} - -virtual const idVec3 *getPosition( long t ) { - return &pos; -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -virtual int numPoints() { - return 1; -} - -virtual idVec3 *getPoint( int index ) { - if ( index != 0 ) { - assert( true ); - } - ; - return &pos; -} - -virtual void draw( bool editMode ) { - glLabeledPoint( blue, pos, ( editMode ) ? 5 : 3, "Fixed point" ); -} - -protected: -idVec3 pos; -}; - -class idInterpolatedPosition : public idCameraPosition { -public: - -void init() { - type = idCameraPosition::INTERPOLATED; - first = true; - startPos.Zero(); - endPos.Zero(); -} - -idInterpolatedPosition() : idCameraPosition() { - init(); -} - -idInterpolatedPosition( idVec3 start, idVec3 end, long time ) : idCameraPosition( time ) { - init(); - startPos = start; - endPos = end; -} - -~idInterpolatedPosition() { -} - -virtual const idVec3 *getPosition( long t ); - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -virtual int numPoints() { - return 2; -} - -virtual idVec3 *getPoint( int index ) { - assert( index >= 0 && index < 2 ); - if ( index == 0 ) { - return &startPos; - } - return &endPos; -} - -virtual void addPoint( const float x, const float y, const float z ) { - if ( first ) { - startPos.set( x, y, z ); - first = false; - } - else { - endPos.set( x, y, z ); - first = true; - } -} - -virtual void addPoint( const idVec3 &v ) { - if ( first ) { - startPos = v; - first = false; - } - else { - endPos = v; - first = true; - } -} - -virtual void draw( bool editMode ) { - glLabeledPoint( blue, startPos, ( editMode ) ? 5 : 3, "Start interpolated" ); - glLabeledPoint( blue, endPos, ( editMode ) ? 5 : 3, "End interpolated" ); - glBegin( GL_LINES ); - glVertex3fv( startPos ); - glVertex3fv( endPos ); - glEnd(); -} - -virtual void start( long t ) { - idCameraPosition::start( t ); - lastTime = startTime; - distSoFar = 0.0; - idVec3 temp = startPos; - temp -= endPos; - calcVelocity( temp.Length() ); -} - -protected: -bool first; -idVec3 startPos; -idVec3 endPos; -long lastTime; -float distSoFar; -}; - -class idSplinePosition : public idCameraPosition { -public: - -void init() { - type = idCameraPosition::SPLINE; -} - -idSplinePosition() : idCameraPosition() { - init(); -} - -idSplinePosition( long time ) : idCameraPosition( time ) { - init(); -} - -~idSplinePosition() { -} - -virtual void start( long t ) { - idCameraPosition::start( t ); - target.initPosition( t, time ); - lastTime = startTime; - distSoFar = 0.0; - calcVelocity( target.totalDistance() ); -} - -//virtual const idVec3 *getPosition(long t) { -// return target.getPosition(t); -//} -virtual const idVec3 *getPosition( long t ); - - -//virtual const idVec3 *getPosition(long t) const { - -void addControlPoint( idVec3 &v ) { - target.addPoint( v ); -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -virtual int numPoints() { - return target.numPoints(); -} - -virtual idVec3 *getPoint( int index ) { - return target.getPoint( index ); -} - -virtual void addPoint( const idVec3 &v ) { - target.addPoint( v ); -} - -virtual void addPoint( const float x, const float y, const float z ) { - target.addPoint( x, y, z ); -} - -virtual void draw( bool editMode ) { - target.draw( editMode ); -} - -virtual void updateSelection( const idVec3 &move ) { - idCameraPosition::updateSelection( move ); - target.buildSpline(); -} - -protected: -idSplineList target; -long lastTime; -float distSoFar; -}; - -class idCameraFOV { -public: - -idCameraFOV() { - time = 0; - length = 0; - fov = 90; -} - -idCameraFOV( int v ) { - time = 0; - length = 0; - fov = v; -} - -idCameraFOV( int s, int e, long t ) { - startFOV = s; - endFOV = e; - length = t; -} - - -~idCameraFOV(){ -} - -void setFOV( float f ) { - fov = f; -} - -float getFOV( long t ) { - if ( length ) { - float percent = ( t - startTime ) / length; - if ( percent < 0.0 ) { - percent = 0.0; - } - else if ( percent > 1.0 ) { - percent = 1.0; - } - float temp = endFOV - startFOV; - temp *= percent; - fov = startFOV + temp; - - if ( percent == 1.0 ) { - length = 0.0; - } - } - return fov; -} - -void start( long t ) { - startTime = t; -} - -void reset( float startfov, float endfov, int start, float len ) { - startFOV = startfov; - endFOV = endfov; - startTime = start; - length = len * 1000; -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -protected: -float fov; -float startFOV; -float endFOV; -int startTime; -int time; -float length; -}; - - - - -class idCameraEvent { -public: // parameters -enum eventType { - EVENT_NA = 0x00, - EVENT_WAIT, // - EVENT_TARGETWAIT, // - EVENT_SPEED, // - EVENT_TARGET, // char(name) - EVENT_SNAPTARGET, // - EVENT_FOV, // int(time), int(targetfov) - EVENT_CMD, // - EVENT_TRIGGER, // - EVENT_STOP, // - EVENT_CAMERA, // - EVENT_FADEOUT, // int(time) - EVENT_FADEIN, // int(time) - EVENT_FEATHER, // - EVENT_COUNT -}; - -static const char* eventStr[EVENT_COUNT]; - -idCameraEvent() { - paramStr = ""; - type = EVENT_NA; - time = 0; -} - -idCameraEvent( eventType t, const char *param, long n ) { - type = t; - paramStr = param; - time = n; -} - -~idCameraEvent() { -}; - -eventType getType() { - return type; -} - -const char *typeStr() { - return eventStr[static_cast( type )]; -} - -const char *getParam() { - return paramStr.c_str(); -} - -long getTime() { - return time; -} - -void setTime( long n ) { - time = n; -} - -void parse( const char *( *text ) ); -void write( fileHandle_t file, const char *name ); - -void setTriggered( bool b ) { - triggered = b; -} - -bool getTriggered() { - return triggered; -} - -protected: -eventType type; -idStr paramStr; -long time; -bool triggered; - -}; - -class idCameraDef { -public: - -void clear() { - currentCameraPosition = 0; - cameraRunning = false; - lastDirection.Zero(); - baseTime = 30; - activeTarget = 0; - name = "camera01"; - fov.setFOV( 90 ); - int i; - for ( i = 0; i < targetPositions.Num(); i++ ) { - delete targetPositions[i]; - } - for ( i = 0; i < events.Num(); i++ ) { - delete events[i]; - } - delete cameraPosition; - cameraPosition = NULL; - events.Clear(); - targetPositions.Clear(); -} - -idCameraPosition *startNewCamera( idCameraPosition::positionType type ) { - clear(); - if ( type == idCameraPosition::SPLINE ) { - cameraPosition = new idSplinePosition(); - } - else if ( type == idCameraPosition::INTERPOLATED ) { - cameraPosition = new idInterpolatedPosition(); - } - else { - cameraPosition = new idFixedPosition(); - } - return cameraPosition; -} - -idCameraDef() { - cameraPosition = NULL; - clear(); -} - -~idCameraDef() { - clear(); -} - -void addEvent( idCameraEvent::eventType t, const char *param, long time ); - -void addEvent( idCameraEvent *event ); - -void removeEvent( int index ); - -static int sortEvents( const void *p1, const void *p2 ); - -int numEvents() { - return events.Num(); -} - -idCameraEvent *getEvent( int index ) { - assert( index >= 0 && index < events.Num() ); - return events[index]; -} - -void parse( const char *( *text ) ); -bool load( const char *filename ); -void save( const char *filename ); - -void buildCamera(); - -//idSplineList *getcameraPosition() { -// return &cameraPosition; -//} - -static idCameraPosition *newFromType( idCameraPosition::positionType t ) { - switch ( t ) { - case idCameraPosition::FIXED: return new idFixedPosition(); - case idCameraPosition::INTERPOLATED: return new idInterpolatedPosition(); - case idCameraPosition::SPLINE: return new idSplinePosition(); - default: - break; - }; - return NULL; -} - -void addTarget( const char *name, idCameraPosition::positionType type ); - -idCameraPosition *getActiveTarget() { - if ( targetPositions.Num() == 0 ) { - addTarget( NULL, idCameraPosition::FIXED ); - } - return targetPositions[activeTarget]; -} - -idCameraPosition *getActiveTarget( int index ) { - if ( targetPositions.Num() == 0 ) { - addTarget( NULL, idCameraPosition::FIXED ); - return targetPositions[0]; - } - return targetPositions[index]; -} - -int numTargets() { - return targetPositions.Num(); -} - - -void setActiveTargetByName( const char *name ) { - for ( int i = 0; i < targetPositions.Num(); i++ ) { - if ( Q_stricmp( name, targetPositions[i]->getName() ) == 0 ) { - setActiveTarget( i ); - return; - } - } -} - -void setActiveTarget( int index ) { - assert( index >= 0 && index < targetPositions.Num() ); - activeTarget = index; -} - -void setRunning( bool b ) { - cameraRunning = b; -} - -void setBaseTime( float f ) { - baseTime = f; -} - -float getBaseTime() { - return baseTime; -} - -float getTotalTime() { - return totalTime; -} - -void startCamera( long t ); -void stopCamera() { - cameraRunning = true; -} -void getActiveSegmentInfo( int segment, idVec3 &origin, idVec3 &direction, float *fv ); - -bool getCameraInfo( long time, idVec3 &origin, idVec3 &direction, float *fv ); -bool getCameraInfo( long time, float *origin, float *direction, float *fv ) { - idVec3 org, dir; - org[0] = origin[0]; - org[1] = origin[1]; - org[2] = origin[2]; - dir[0] = direction[0]; - dir[1] = direction[1]; - dir[2] = direction[2]; - bool b = getCameraInfo( time, org, dir, fv ); - origin[0] = org[0]; - origin[1] = org[1]; - origin[2] = org[2]; - direction[0] = dir[0]; - direction[1] = dir[1]; - direction[2] = dir[2]; - return b; -} - -void draw( bool editMode ) { - // gcc doesn't allow casting away from bools - // why? I've no idea... - if ( cameraPosition ) { - cameraPosition->draw( (bool)( ( editMode || cameraRunning ) && cameraEdit ) ); - int count = targetPositions.Num(); - for ( int i = 0; i < count; i++ ) { - targetPositions[i]->draw( (bool)( ( editMode || cameraRunning ) && i == activeTarget && !cameraEdit ) ); - } - } -} - -/* - int numSegments() { - if (cameraEdit) { - return cameraPosition.numSegments(); - } - return getTargetSpline()->numSegments(); - } - - int getActiveSegment() { - if (cameraEdit) { - return cameraPosition.getActiveSegment(); - } - return getTargetSpline()->getActiveSegment(); - } - - void setActiveSegment(int i) { - if (cameraEdit) { - cameraPosition.setActiveSegment(i); - } else { - getTargetSpline()->setActiveSegment(i); - } - } - */ -int numPoints() { - if ( cameraEdit ) { - return cameraPosition->numPoints(); - } - return getActiveTarget()->numPoints(); -} - -const idVec3 *getPoint( int index ) { - if ( cameraEdit ) { - return cameraPosition->getPoint( index ); - } - return getActiveTarget()->getPoint( index ); -} - -void stopEdit() { - editMode = false; - if ( cameraEdit ) { - cameraPosition->stopEdit(); - } - else { - getActiveTarget()->stopEdit(); - } -} - -void startEdit( bool camera ) { - cameraEdit = camera; - if ( camera ) { - cameraPosition->startEdit(); - for ( int i = 0; i < targetPositions.Num(); i++ ) { - targetPositions[i]->stopEdit(); - } - } - else { - getActiveTarget()->startEdit(); - cameraPosition->stopEdit(); - } - editMode = true; -} - -bool waitEvent( int index ); - -const char *getName() { - return name.c_str(); -} - -void setName( const char *p ) { - name = p; -} - -idCameraPosition *getPositionObj() { - if ( cameraPosition == NULL ) { - cameraPosition = new idFixedPosition(); - } - return cameraPosition; -} - -protected: -idStr name; -int currentCameraPosition; -idVec3 lastDirection; -bool cameraRunning; -idCameraPosition *cameraPosition; -idList targetPositions; -idList events; -idCameraFOV fov; -int activeTarget; -float totalTime; -float baseTime; -long startTime; - -bool cameraEdit; -bool editMode; -}; - -extern bool g_splineMode; - -extern idCameraDef *g_splineList; - - -#endif diff --git a/libs/splines/util_list.h b/libs/splines/util_list.h deleted file mode 100644 index dfa92fb..0000000 --- a/libs/splines/util_list.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __UTIL_LIST_H__ -#define __UTIL_LIST_H__ - -#include -#include - -template< class type > -class idList { -private: -int m_num; -int m_size; -int m_granularity; -type *m_list; - -public: -idList( int granularity = 16 ); -~idList(); -void Clear( void ); -int Num( void ); -void SetNum( int num ); -void SetGranularity( int granularity ); -void Condense( void ); -int Size( void ); -void Resize( int size ); -type operator[]( int index ) const; -type &operator[]( int index ); -int Append( type const & obj ); -int AddUnique( type const & obj ); -type *Find( type const & obj, int *index = NULL ); -bool RemoveIndex( int index ); -bool Remove( type const & obj ); -typedef int cmp_t ( const void *, const void * ); -void Sort( cmp_t *compare ); -}; - -/* - ================ - idList::idList( int ) - ================ - */ -template< class type > -inline idList::idList( int granularity ) { - assert( granularity > 0 ); - - m_list = NULL; - m_granularity = granularity; - Clear(); -} - -/* - ================ - idList::~idList - ================ - */ -template< class type > -inline idList::~idList() { - Clear(); -} - -/* - ================ - idList::Clear - ================ - */ -template< class type > -inline void idList::Clear( void ) { - if ( m_list ) { - delete[] m_list; - } - - m_list = NULL; - m_num = 0; - m_size = 0; -} - -/* - ================ - idList::Num - ================ - */ -template< class type > -inline int idList::Num( void ) { - return m_num; -} - -/* - ================ - idList::SetNum - ================ - */ -template< class type > -inline void idList::SetNum( int num ) { - assert( num >= 0 ); - if ( num > m_size ) { - // resize it up to the closest level of granularity - Resize( ( ( num + m_granularity - 1 ) / m_granularity ) * m_granularity ); - } - m_num = num; -} - -/* - ================ - idList::SetGranularity - ================ - */ -template< class type > -inline void idList::SetGranularity( int granularity ) { - int newsize; - - assert( granularity > 0 ); - m_granularity = granularity; - - if ( m_list ) { - // resize it to the closest level of granularity - newsize = ( ( m_num + m_granularity - 1 ) / m_granularity ) * m_granularity; - if ( newsize != m_size ) { - Resize( newsize ); - } - } -} - -/* - ================ - idList::Condense - - Resizes the array to exactly the number of elements it contains - ================ - */ -template< class type > -inline void idList::Condense( void ) { - if ( m_list ) { - if ( m_num ) { - Resize( m_num ); - } - else { - Clear(); - } - } -} - -/* - ================ - idList::Size - ================ - */ -template< class type > -inline int idList::Size( void ) { - return m_size; -} - -/* - ================ - idList::Resize - ================ - */ -template< class type > -inline void idList::Resize( int size ) { - type *temp; - int i; - - assert( size > 0 ); - - if ( size <= 0 ) { - Clear(); - return; - } - - temp = m_list; - m_size = size; - if ( m_size < m_num ) { - m_num = m_size; - } - - m_list = new type[ m_size ]; - for ( i = 0; i < m_num; i++ ) { - m_list[ i ] = temp[ i ]; - } - - if ( temp ) { - delete[] temp; - } -} - -/* - ================ - idList::operator[] const - ================ - */ -template< class type > -inline type idList::operator[]( int index ) const { - assert( index >= 0 ); - assert( index < m_num ); - - return m_list[ index ]; -} - -/* - ================ - idList::operator[] - ================ - */ -template< class type > -inline type &idList::operator[]( int index ) { - assert( index >= 0 ); - assert( index < m_num ); - - return m_list[ index ]; -} - -/* - ================ - idList::Append - ================ - */ -template< class type > -inline int idList::Append( type const & obj ) { - if ( !m_list ) { - Resize( m_granularity ); - } - - if ( m_num == m_size ) { - Resize( m_size + m_granularity ); - } - - m_list[ m_num ] = obj; - m_num++; - - return m_num - 1; -} - -/* - ================ - idList::AddUnique - ================ - */ -template< class type > -inline int idList::AddUnique( type const & obj ) { - int index; - - if ( !Find( obj, &index ) ) { - index = Append( obj ); - } - - return index; -} - -/* - ================ - idList::Find - ================ - */ -template< class type > -inline type *idList::Find( type const & obj, int *index ) { - int i; - - for ( i = 0; i < m_num; i++ ) { - if ( m_list[ i ] == obj ) { - if ( index ) { - *index = i; - } - return &m_list[ i ]; - } - } - - return NULL; -} - -/* - ================ - idList::RemoveIndex - ================ - */ -template< class type > -inline bool idList::RemoveIndex( int index ) { - int i; - - if ( !m_list || !m_num ) { - return false; - } - - assert( index >= 0 ); - assert( index < m_num ); - - if ( ( index < 0 ) || ( index >= m_num ) ) { - return false; - } - - m_num--; - for ( i = index; i < m_num; i++ ) { - m_list[ i ] = m_list[ i + 1 ]; - } - - return true; -} - -/* - ================ - idList::Remove - ================ - */ -template< class type > -inline bool idList::Remove( type const & obj ) { - int index; - - if ( Find( obj, &index ) ) { - return RemoveIndex( index ); - } - - return false; -} - -/* - ================ - idList::Sort - ================ - */ -template< class type > -inline void idList::Sort( cmp_t *compare ) { - if ( !m_list ) { - return; - } - - qsort( ( void * )m_list, ( size_t )m_num, sizeof( type ), compare ); -} - -#endif /* !__UTIL_LIST_H__ */ diff --git a/libs/splines/util_str.cpp b/libs/splines/util_str.cpp deleted file mode 100644 index c64ca73..0000000 --- a/libs/splines/util_str.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//need to rewrite this - -#include "util_str.h" -#include -#include -#include -#include - -#if GDEF_COMPILER_MSVC -#pragma warning(disable : 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data -#pragma warning(disable : 4710) // function 'blah' not inlined -#endif - -static const int STR_ALLOC_GRAN = 20; - -// screwy but intentional -#ifdef __APPLE_BUG__ -char *idStr::__tolower -#else -char *idStr::tolower -#endif -( - char *s1 -){ - char *s; - - s = s1; - while ( *s ) - { - *s = ::tolower( *s ); - s++; - } - - return s1; -} - -// screwy but intentional -#ifdef __APPLE_BUG__ -char *idStr::__toupper -#else -char *idStr::toupper -#endif -( - char *s1 -){ - char *s; - - s = s1; - while ( *s ) - { - *s = ::toupper( *s ); - s++; - } - - return s1; -} - -int idStr::icmpn -( - const char *s1, - const char *s2, - int n -){ - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - // idStrings are equal until end point - return 0; - } - - if ( c1 != c2 ) { - if ( c1 >= 'a' && c1 <= 'z' ) { - c1 -= ( 'a' - 'A' ); - } - - if ( c2 >= 'a' && c2 <= 'z' ) { - c2 -= ( 'a' - 'A' ); - } - - if ( c1 < c2 ) { - // strings less than - return -1; - } - else if ( c1 > c2 ) { - // strings greater than - return 1; - } - } - } - while ( c1 ); - - // strings are equal - return 0; -} - -int idStr::icmp -( - const char *s1, - const char *s2 -){ - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( c1 != c2 ) { - if ( c1 >= 'a' && c1 <= 'z' ) { - c1 -= ( 'a' - 'A' ); - } - - if ( c2 >= 'a' && c2 <= 'z' ) { - c2 -= ( 'a' - 'A' ); - } - - if ( c1 < c2 ) { - // strings less than - return -1; - } - else if ( c1 > c2 ) { - // strings greater than - return 1; - } - } - } - while ( c1 ); - - // strings are equal - return 0; -} - -int idStr::cmpn -( - const char *s1, - const char *s2, - int n -){ - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) { - // strings are equal until end point - return 0; - } - - if ( c1 < c2 ) { - // strings less than - return -1; - } - else if ( c1 > c2 ) { - // strings greater than - return 1; - } - } - while ( c1 ); - - // strings are equal - return 0; -} - -int idStr::cmp -( - const char *s1, - const char *s2 -){ - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( c1 < c2 ) { - // strings less than - return -1; - } - else if ( c1 > c2 ) { - // strings greater than - return 1; - } - } - while ( c1 ); - - // strings are equal - return 0; -} - -/* - ============ - IsNumeric - - Checks a string to see if it contains only numerical values. - ============ - */ -bool idStr::isNumeric -( - const char *str -){ - int len; - int i; - bool dot; - - if ( *str == '-' ) { - str++; - } - - dot = false; - len = strlen( str ); - for ( i = 0; i < len; i++ ) - { - if ( !isdigit( str[ i ] ) ) { - if ( ( str[ i ] == '.' ) && !dot ) { - dot = true; - continue; - } - return false; - } - } - - return true; -} - -idStr operator+ -( - const idStr& a, - const float b -){ - char text[ 20 ]; - - idStr result( a ); - - sprintf( text, "%f", b ); - result.append( text ); - - return result; -} - -idStr operator+ -( - const idStr& a, - const int b -){ - char text[ 20 ]; - - idStr result( a ); - - sprintf( text, "%d", b ); - result.append( text ); - - return result; -} - -idStr operator+ -( - const idStr& a, - const unsigned b -){ - char text[ 20 ]; - - idStr result( a ); - - sprintf( text, "%u", b ); - result.append( text ); - - return result; -} - -idStr& idStr::operator+= -( - const float a -){ - char text[ 20 ]; - - sprintf( text, "%f", a ); - append( text ); - - return *this; -} - -idStr& idStr::operator+= -( - const int a -){ - char text[ 20 ]; - - sprintf( text, "%d", a ); - append( text ); - - return *this; -} - -idStr& idStr::operator+= -( - const unsigned a -){ - char text[ 20 ]; - - sprintf( text, "%u", a ); - append( text ); - - return *this; -} - -void idStr::CapLength -( - int newlen -){ - assert( m_data ); - - if ( length() <= newlen ) { - return; - } - - EnsureDataWritable(); - - m_data->data[newlen] = 0; - m_data->len = newlen; -} - -void idStr::EnsureDataWritable -( - void -){ - assert( m_data ); - strdata *olddata; - int len; - - if ( !m_data->refcount ) { - return; - } - - olddata = m_data; - len = length(); - - m_data = new strdata; - - EnsureAlloced( len + 1, false ); - strncpy( m_data->data, olddata->data, len + 1 ); - m_data->len = len; - - olddata->DelRef(); -} - -void idStr::EnsureAlloced( int amount, bool keepold ) { - - if ( !m_data ) { - m_data = new strdata(); - } - - // Now, let's make sure it's writable - EnsureDataWritable(); - - char *newbuffer; - bool wasalloced = ( m_data->alloced != 0 ); - - if ( amount < m_data->alloced ) { - return; - } - - assert( amount ); - if ( amount == 1 ) { - m_data->alloced = 1; - } - else { - int newsize, mod; - mod = amount % STR_ALLOC_GRAN; - if ( !mod ) { - newsize = amount; - } - else { - newsize = amount + STR_ALLOC_GRAN - mod; - } - m_data->alloced = newsize; - } - - newbuffer = new char[m_data->alloced]; - if ( wasalloced && keepold ) { - strcpy( newbuffer, m_data->data ); - } - - if ( m_data->data ) { - delete [] m_data->data; - } - m_data->data = newbuffer; -} - -void idStr::BackSlashesToSlashes -( - void -){ - int i; - - EnsureDataWritable(); - - for ( i = 0; i < m_data->len; i++ ) - { - if ( m_data->data[i] == '\\' ) { - m_data->data[i] = '/'; - } - } -} - -void idStr::snprintf -( - char *dst, - int size, - const char *fmt, - ... -){ - char buffer[0x10000]; - int len; - va_list argptr; - - va_start( argptr,fmt ); - len = vsprintf( buffer,fmt,argptr ); - va_end( argptr ); - - assert( len < size ); - - strncpy( dst, buffer, size - 1 ); -} - -#if GDEF_COMPILER_MSVC -#pragma warning(disable : 4189) // local variable is initialized but not referenced -#endif - -/* - ================= - TestStringClass - - This is a fairly rigorous test of the idStr class's functionality. - Because of the fairly global and subtle ramifications of a bug occuring - in this class, it should be run after any changes to the class. - Add more tests as functionality is changed. Tests should include - any possible bounds violation and NULL data tests. - ================= - */ -void TestStringClass -( - void -){ - char ch; // ch == ? - (void) ch; - idStr *t; // t == ? - idStr a; // a.len == 0, a.data == "\0" - idStr b; // b.len == 0, b.data == "\0" - idStr c( "test" ); // c.len == 4, c.data == "test\0" - idStr d( c ); // d.len == 4, d.data == "test\0" - idStr e( static_cast( NULL ) ); - // e.len == 0, e.data == "\0" ASSERT! - int i; // i == ? - (void) i; - - i = a.length(); // i == 0 - i = c.length(); // i == 4 - - t = new idStr(); // t->len == 0, t->data == "\0" - delete t; // t == ? - - b = "test"; // b.len == 4, b.data == "test\0" - t = new idStr( "test" ); // t->len == 4, t->data == "test\0" - delete t; // t == ? - - a = c; // a.len == 4, a.data == "test\0" -// a = ""; - a = NULL; // a.len == 0, a.data == "\0" ASSERT! - a = c + d; // a.len == 8, a.data == "testtest\0" - a = c + "wow"; // a.len == 7, a.data == "testwow\0" - a = c + static_cast( NULL ); - // a.len == 4, a.data == "test\0" ASSERT! - a = "this" + d; // a.len == 8, a.data == "thistest\0" - a = static_cast( NULL ) + d; - // a.len == 4, a.data == "test\0" ASSERT! - a += c; // a.len == 8, a.data == "testtest\0" - a += "wow"; // a.len == 11, a.data == "testtestwow\0" - a += static_cast( NULL ); - // a.len == 11, a.data == "testtestwow\0" ASSERT! - - a = "test"; // a.len == 4, a.data == "test\0" - ch = a[ 0 ]; // ch == 't' - ch = a[ -1 ]; // ch == 0 ASSERT! - ch = a[ 1000 ]; // ch == 0 ASSERT! - ch = a[ 0 ]; // ch == 't' - ch = a[ 1 ]; // ch == 'e' - ch = a[ 2 ]; // ch == 's' - ch = a[ 3 ]; // ch == 't' - ch = a[ 4 ]; // ch == '\0' ASSERT! - ch = a[ 5 ]; // ch == '\0' ASSERT! - - a[ 1 ] = 'b'; // a.len == 4, a.data == "tbst\0" - a[ -1 ] = 'b'; // a.len == 4, a.data == "tbst\0" ASSERT! - a[ 0 ] = '0'; // a.len == 4, a.data == "0bst\0" - a[ 1 ] = '1'; // a.len == 4, a.data == "01st\0" - a[ 2 ] = '2'; // a.len == 4, a.data == "012t\0" - a[ 3 ] = '3'; // a.len == 4, a.data == "0123\0" - a[ 4 ] = '4'; // a.len == 4, a.data == "0123\0" ASSERT! - a[ 5 ] = '5'; // a.len == 4, a.data == "0123\0" ASSERT! - a[ 7 ] = '7'; // a.len == 4, a.data == "0123\0" ASSERT! - - a = "test"; // a.len == 4, a.data == "test\0" - b = "no"; // b.len == 2, b.data == "no\0" - - i = ( a == b ); // i == 0 - i = ( a == c ); // i == 1 - - i = ( a == "blow" ); // i == 0 - i = ( a == "test" ); // i == 1 - i = ( a == NULL ); // i == 0 ASSERT! - - i = ( "test" == b ); // i == 0 - i = ( "test" == a ); // i == 1 - i = ( NULL == a ); // i == 0 ASSERT! - - i = ( a != b ); // i == 1 - i = ( a != c ); // i == 0 - - i = ( a != "blow" ); // i == 1 - i = ( a != "test" ); // i == 0 - i = ( a != NULL ); // i == 1 ASSERT! - - i = ( "test" != b ); // i == 1 - i = ( "test" != a ); // i == 0 - i = ( NULL != a ); // i == 1 ASSERT! - - a = "test"; // a.data == "test" - b = a; // b.data == "test" - - a = "not"; // a.data == "not", b.data == "test" - - a = b; // a.data == b.data == "test" - - a += b; // a.data == "testtest", b.data = "test" - - a = b; - - a[1] = '1'; // a.data = "t1st", b.data = "test" -} - -#if GDEF_COMPILER_MSVC -#pragma warning(default : 4189) // local variable is initialized but not referenced -#pragma warning(disable : 4514) // unreferenced inline function has been removed -#endif diff --git a/libs/splines/util_str.h b/libs/splines/util_str.h deleted file mode 100644 index b7cb976..0000000 --- a/libs/splines/util_str.h +++ /dev/null @@ -1,724 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//need to rewrite this - -#ifndef __UTIL_STR_H__ -#define __UTIL_STR_H__ - -#include -#include -#include - -#if GDEF_COMPILER_MSVC -#pragma warning(disable : 4710) // function 'blah' not inlined -#endif - -void TestStringClass(); - -class strdata -{ -public: -strdata () : len( 0 ), refcount( 0 ), data( NULL ), alloced( 0 ) { -} -~strdata (){ - if ( data ) { - delete [] data; - } -} - -void AddRef() { - refcount++; -} -bool DelRef(){ // True if killed - refcount--; - if ( refcount < 0 ) { - delete this; - return true; - } - - return false; -} - -int len; -int refcount; -char *data; -int alloced; -}; - -class idStr { -protected: -strdata *m_data; -void EnsureAlloced( int, bool keepold = true ); -void EnsureDataWritable(); - -public: -~idStr(); -idStr(); -idStr( const char *text ); -idStr( const idStr& string ); -idStr( const idStr string, int start, int end ); -idStr( const char ch ); -idStr( const int num ); -idStr( const float num ); -idStr( const unsigned num ); -int length( void ) const; -int allocated( void ) const; -const char * c_str( void ) const; - -void append( const char *text ); -void append( const idStr& text ); -char operator[]( int index ) const; -char& operator[]( int index ); - -void operator=( const idStr& text ); -void operator=( const char *text ); - -friend idStr operator+( const idStr& a, const idStr& b ); -friend idStr operator+( const idStr& a, const char *b ); -friend idStr operator+( const char *a, const idStr& b ); - -friend idStr operator+( const idStr& a, const float b ); -friend idStr operator+( const idStr& a, const int b ); -friend idStr operator+( const idStr& a, const unsigned b ); -friend idStr operator+( const idStr& a, const bool b ); -friend idStr operator+( const idStr& a, const char b ); - -idStr& operator+=( const idStr& a ); -idStr& operator+=( const char *a ); -idStr& operator+=( const float a ); -idStr& operator+=( const char a ); -idStr& operator+=( const int a ); -idStr& operator+=( const unsigned a ); -idStr& operator+=( const bool a ); - -friend bool operator==( const idStr& a, const idStr& b ); -friend bool operator==( const idStr& a, const char *b ); -friend bool operator==( const char *a, const idStr& b ); - -friend bool operator!=( const idStr& a, const idStr& b ); -friend bool operator!=( const idStr& a, const char *b ); -friend bool operator!=( const char *a, const idStr& b ); - -operator const char *() const; -operator const char *(); - -int icmpn( const char *text, int n ) const; -int icmpn( const idStr& text, int n ) const; -int icmp( const char *text ) const; -int icmp( const idStr& text ) const; -int cmpn( const char *text, int n ) const; -int cmpn( const idStr& text, int n ) const; -int cmp( const char *text ) const; -int cmp( const idStr& text ) const; - -void tolower( void ); -void toupper( void ); - -static char *tolower( char *s1 ); -static char *toupper( char *s1 ); - -static int icmpn( const char *s1, const char *s2, int n ); -static int icmp( const char *s1, const char *s2 ); -static int cmpn( const char *s1, const char *s2, int n ); -static int cmp( const char *s1, const char *s2 ); - -static void snprintf( char *dst, int size, const char *fmt, ... ); - -static bool isNumeric( const char *str ); -bool isNumeric( void ) const; - -void CapLength( int ); - -void BackSlashesToSlashes(); - -}; - -inline idStr::~idStr(){ - if ( m_data ) { - m_data->DelRef(); - m_data = NULL; - } -} - -inline idStr::idStr() : m_data( NULL ){ - EnsureAlloced( 1 ); - m_data->data[ 0 ] = 0; -} - -inline idStr::idStr -( - const char *text -) : m_data( NULL ){ - int len; - - assert( text ); - - if ( text ) { - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; - } - else - { - EnsureAlloced( 1 ); - m_data->data[ 0 ] = 0; - m_data->len = 0; - } -} - -inline idStr::idStr -( - const idStr& text -) : m_data( NULL ){ - m_data = text.m_data; - m_data->AddRef(); -} - -inline idStr::idStr -( - const idStr text, - int start, - int end -) : m_data( NULL ){ - int i; - int len; - - if ( end > text.length() ) { - end = text.length(); - } - - if ( start > text.length() ) { - start = text.length(); - } - - len = end - start; - if ( len < 0 ) { - len = 0; - } - - EnsureAlloced( len + 1 ); - - for ( i = 0; i < len; i++ ) - { - m_data->data[ i ] = text[ start + i ]; - } - - m_data->data[ len ] = 0; - m_data->len = len; -} - -inline idStr::idStr -( - const char ch -) : m_data( NULL ){ - EnsureAlloced( 2 ); - - m_data->data[ 0 ] = ch; - m_data->data[ 1 ] = 0; - m_data->len = 1; -} - -inline idStr::idStr -( - const float num -) : m_data( NULL ){ - char text[ 32 ]; - int len; - - sprintf( text, "%.3f", num ); - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; -} - -inline idStr::idStr -( - const int num -) : m_data( NULL ){ - char text[ 32 ]; - int len; - - sprintf( text, "%d", num ); - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; -} - -inline idStr::idStr -( - const unsigned num -) : m_data( NULL ){ - char text[ 32 ]; - int len; - - sprintf( text, "%u", num ); - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; -} - -inline int idStr::length( void ) const { - return ( m_data != NULL ) ? m_data->len : 0; -} - -inline int idStr::allocated( void ) const { - return ( m_data != NULL ) ? m_data->alloced + sizeof( *m_data ) : 0; -} - -inline const char *idStr::c_str( void ) const { - assert( m_data ); - - return m_data->data; -} - -inline void idStr::append -( - const char *text -){ - int len; - - assert( text ); - - if ( text ) { - len = length() + strlen( text ); - EnsureAlloced( len + 1 ); - - strcat( m_data->data, text ); - m_data->len = len; - } -} - -inline void idStr::append -( - const idStr& text -){ - int len; - - len = length() + text.length(); - EnsureAlloced( len + 1 ); - - strcat( m_data->data, text.c_str() ); - m_data->len = len; -} - -inline char idStr::operator[]( int index ) const { - assert( m_data ); - - if ( !m_data ) { - return 0; - } - - // don't include the '/0' in the test, because technically, it's out of bounds - assert( ( index >= 0 ) && ( index < m_data->len ) ); - - // In release mode, give them a null character - // don't include the '/0' in the test, because technically, it's out of bounds - if ( ( index < 0 ) || ( index >= m_data->len ) ) { - return 0; - } - - return m_data->data[ index ]; -} - -inline char& idStr::operator[] -( - int index -){ - // Used for result for invalid indices - static char dummy = 0; - assert( m_data ); - - // We don't know if they'll write to it or not - // if it's not a const object - EnsureDataWritable(); - - if ( !m_data ) { - return dummy; - } - - // don't include the '/0' in the test, because technically, it's out of bounds - assert( ( index >= 0 ) && ( index < m_data->len ) ); - - // In release mode, let them change a safe variable - // don't include the '/0' in the test, because technically, it's out of bounds - if ( ( index < 0 ) || ( index >= m_data->len ) ) { - return dummy; - } - - return m_data->data[ index ]; -} - -inline void idStr::operator= -( - const idStr& text -){ - // adding the reference before deleting our current reference prevents - // us from deleting our string if we are copying from ourself - text.m_data->AddRef(); - m_data->DelRef(); - m_data = text.m_data; -} - -inline void idStr::operator= -( - const char *text -){ - int len; - - assert( text ); - - if ( !text ) { - // safe behaviour if NULL - EnsureAlloced( 1, false ); - m_data->data[0] = 0; - m_data->len = 0; - return; - } - - if ( !m_data ) { - len = strlen( text ); - EnsureAlloced( len + 1, false ); - strcpy( m_data->data, text ); - m_data->len = len; - return; - } - - if ( text == m_data->data ) { - return; // Copying same thing. Punt. - - } - // If we alias and I don't do this, I could corrupt other strings... This - // will get called with EnsureAlloced anyway - EnsureDataWritable(); - - // Now we need to check if we're aliasing.. - if ( text >= m_data->data && text <= m_data->data + m_data->len ) { - // Great, we're aliasing. We're copying from inside ourselves. - // This means that I don't have to ensure that anything is alloced, - // though I'll assert just in case. - int diff = text - m_data->data; - int i; - - assert( strlen( text ) < (unsigned) m_data->len ); - - for ( i = 0; text[i]; i++ ) - { - m_data->data[i] = text[i]; - } - - m_data->data[i] = 0; - - m_data->len -= diff; - - return; - } - - len = strlen( text ); - EnsureAlloced( len + 1, false ); - strcpy( m_data->data, text ); - m_data->len = len; -} - -inline idStr operator+ -( - const idStr& a, - const idStr& b -){ - idStr result( a ); - - result.append( b ); - - return result; -} - -inline idStr operator+ -( - const idStr& a, - const char *b -){ - idStr result( a ); - - result.append( b ); - - return result; -} - -inline idStr operator+ -( - const char *a, - const idStr& b -){ - idStr result( a ); - - result.append( b ); - - return result; -} - -inline idStr operator+ -( - const idStr& a, - const bool b -){ - idStr result( a ); - - result.append( b ? "true" : "false" ); - - return result; -} - -inline idStr operator+ -( - const idStr& a, - const char b -){ - char text[ 2 ]; - - text[ 0 ] = b; - text[ 1 ] = 0; - - return a + text; -} - -inline idStr& idStr::operator+= -( - const idStr& a -){ - append( a ); - return *this; -} - -inline idStr& idStr::operator+= -( - const char *a -){ - append( a ); - return *this; -} - -inline idStr& idStr::operator+= -( - const char a -){ - char text[ 2 ]; - - text[ 0 ] = a; - text[ 1 ] = 0; - append( text ); - - return *this; -} - -inline idStr& idStr::operator+= -( - const bool a -){ - append( a ? "true" : "false" ); - return *this; -} - -inline bool operator== -( - const idStr& a, - const idStr& b -){ - return ( !strcmp( a.c_str(), b.c_str() ) ); -} - -inline bool operator== -( - const idStr& a, - const char *b -){ - assert( b ); - if ( !b ) { - return false; - } - return ( !strcmp( a.c_str(), b ) ); -} - -inline bool operator== -( - const char *a, - const idStr& b -){ - assert( a ); - if ( !a ) { - return false; - } - return ( !strcmp( a, b.c_str() ) ); -} - -inline bool operator!= -( - const idStr& a, - const idStr& b -){ - return !( a == b ); -} - -inline bool operator!= -( - const idStr& a, - const char *b -){ - return !( a == b ); -} - -inline bool operator!= -( - const char *a, - const idStr& b -){ - return !( a == b ); -} - -inline int idStr::icmpn -( - const char *text, - int n -) const { - assert( m_data ); - assert( text ); - - return idStr::icmpn( m_data->data, text, n ); -} - -inline int idStr::icmpn -( - const idStr& text, - int n -) const { - assert( m_data ); - assert( text.m_data ); - - return idStr::icmpn( m_data->data, text.m_data->data, n ); -} - -inline int idStr::icmp -( - const char *text -) const { - assert( m_data ); - assert( text ); - - return idStr::icmp( m_data->data, text ); -} - -inline int idStr::icmp -( - const idStr& text -) const { - assert( c_str() ); - assert( text.c_str() ); - - return idStr::icmp( c_str(), text.c_str() ); -} - -inline int idStr::cmp -( - const char *text -) const { - assert( m_data ); - assert( text ); - - return idStr::cmp( m_data->data, text ); -} - -inline int idStr::cmp -( - const idStr& text -) const { - assert( c_str() ); - assert( text.c_str() ); - - return idStr::cmp( c_str(), text.c_str() ); -} - -inline int idStr::cmpn -( - const char *text, - int n -) const { - assert( c_str() ); - assert( text ); - - return idStr::cmpn( c_str(), text, n ); -} - -inline int idStr::cmpn -( - const idStr& text, - int n -) const { - assert( c_str() ); - assert( text.c_str() ); - - return idStr::cmpn( c_str(), text.c_str(), n ); -} - -inline void idStr::tolower -( - void -){ - assert( m_data ); - - EnsureDataWritable(); - - idStr::tolower( m_data->data ); -} - -inline void idStr::toupper -( - void -){ - assert( m_data ); - - EnsureDataWritable(); - - idStr::toupper( m_data->data ); -} - -inline bool idStr::isNumeric -( - void -) const { - assert( m_data ); - return idStr::isNumeric( m_data->data ); -} - -inline idStr::operator const char *() { - return c_str(); -} - -inline idStr::operator const char * -( - void -) const { - return c_str(); -} - -#endif diff --git a/libs/str.h b/libs/str.h deleted file mode 100644 index fb2b269..0000000 --- a/libs/str.h +++ /dev/null @@ -1,502 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __STR__ -#define __STR__ - -#include "globaldefs.h" - -// -// class Str -// loose replacement for CString from MFC -// - -#include -#include - -#include -#include - -#include - -#if GDEF_COMPILER_MSVC -#define strcasecmp strcmpi -#if _MSC_VER < 1400 -#define vsnprintf std::vsnprintf -#endif -#else -#include -#endif - -// NOTE TTimo __StrDup was initially implemented in pakstuff.cpp -// causing a bunch of issues for broader targets that use Str.h (such as plugins and modules) -// Q_StrDup should be used now, using a #define __StrDup for easy transition - -#define __StrDup Q_StrDup - -inline char* Q_StrDup( const char* pStr ){ - if ( pStr == 0 ) { - pStr = ""; - } - - return strcpy( new char[strlen( pStr ) + 1], pStr ); -} - -#if !GDEF_OS_WINDOWS -#define strcmpi strcasecmp -#define stricmp strcasecmp -#define strnicmp strncasecmp - -inline char* strlwr( char* string ){ - char *cp; - for ( cp = string; *cp; ++cp ) - { - if ( 'A' <= *cp && *cp <= 'Z' ) { - *cp += 'a' - 'A'; - } - } - - return string; -} - -inline char* strupr( char* string ){ - char *cp; - for ( cp = string; *cp; ++cp ) - { - if ( 'a' <= *cp && *cp <= 'z' ) { - *cp += 'A' - 'a'; - } - } - - return string; -} -#endif - -static char *g_pStrWork = 0; - -class Str -{ -protected: -bool m_bIgnoreCase; -char *m_pStr; - -public: -Str(){ - m_bIgnoreCase = true; - m_pStr = new char[1]; - m_pStr[0] = '\0'; -} - -Str( char *p ){ - m_bIgnoreCase = true; - m_pStr = __StrDup( p ); -} - -Str( const char *p ){ - m_bIgnoreCase = true; - m_pStr = __StrDup( p ); -} - -Str( const unsigned char *p ){ - m_bIgnoreCase = true; - m_pStr = __StrDup( reinterpret_cast( p ) ); -} - -Str( const char c ){ - m_bIgnoreCase = true; - m_pStr = new char[2]; - m_pStr[0] = c; - m_pStr[1] = '\0'; -} - -const char* GetBuffer() const { - return m_pStr; -} - -char* GetBuffer(){ - return m_pStr; -} - -Str( const Str &s ){ - m_bIgnoreCase = true; - m_pStr = __StrDup( s.GetBuffer() ); -} - -void Deallocate(){ - delete []m_pStr; - m_pStr = 0; -} - -void Allocate( std::size_t n ){ - Deallocate(); - m_pStr = new char[n]; -} - -void MakeEmpty(){ - Deallocate(); - m_pStr = __StrDup( "" ); -} - -~Str(){ - Deallocate(); - // NOTE TTimo: someone explain this g_pStrWork to me? - if ( g_pStrWork ) { - delete []g_pStrWork; - } - g_pStrWork = 0; -} - -void MakeLower(){ - if ( m_pStr ) { - strlwr( m_pStr ); - } -} - -void MakeUpper(){ - if ( m_pStr ) { - strupr( m_pStr ); - } -} - -void TrimRight(){ - char* lpsz = m_pStr; - char* lpszLast = 0; - while ( *lpsz != '\0' ) - { - if ( isspace( *lpsz ) ) { - if ( lpszLast == 0 ) { - lpszLast = lpsz; - } - } - else{ - lpszLast = 0; - } - lpsz++; - } - - if ( lpszLast != 0 ) { - // truncate at trailing space start - *lpszLast = '\0'; - } -} - -void TrimLeft(){ - // find first non-space character - char* lpsz = m_pStr; - while ( isspace( *lpsz ) ) - lpsz++; - - // fix up data and length - std::size_t nDataLength = GetLength() - ( lpsz - m_pStr ); - memmove( m_pStr, lpsz, ( nDataLength + 1 ) ); -} - -char* Find( const char *p ){ - return strstr( m_pStr, p ); -} - -// search starting at a given offset -char* Find( const char *p, std::size_t offset ){ - return strstr( m_pStr + offset, p ); -} - -char* Find( const char ch ){ - return strchr( m_pStr, ch ); -} - -char* ReverseFind( const char ch ){ - return strrchr( m_pStr, ch ); -} - -int Compare( const char* str ) const { - return strcmp( m_pStr, str ); -} - -int CompareNoCase( const char* str ) const { - return strcasecmp( m_pStr, str ); -} - -std::size_t GetLength(){ - return ( m_pStr ) ? strlen( m_pStr ) : 0; -} - -const char* Left( std::size_t n ){ - delete []g_pStrWork; - if ( n > 0 ) { - g_pStrWork = new char[n + 1]; - strncpy( g_pStrWork, m_pStr, n ); - g_pStrWork[n] = '\0'; - } - else - { - g_pStrWork = new char[1]; - g_pStrWork[0] = '\0'; - } - return g_pStrWork; -} - -const char* Right( std::size_t n ){ - delete []g_pStrWork; - if ( n > 0 ) { - g_pStrWork = new char[n + 1]; - std::size_t nStart = GetLength() - n; - strncpy( g_pStrWork, &m_pStr[nStart], n ); - g_pStrWork[n] = '\0'; - } - else - { - g_pStrWork = new char[1]; - g_pStrWork[0] = '\0'; - } - return g_pStrWork; -} - -const char* Mid( std::size_t nFirst ) const { - return Mid( nFirst, strlen( m_pStr ) - nFirst ); -} - -const char* Mid( std::size_t first, std::size_t n ) const { - delete []g_pStrWork; - if ( n > 0 ) { - g_pStrWork = new char[n + 1]; - strncpy( g_pStrWork, m_pStr + first, n ); - g_pStrWork[n] = '\0'; - } - else - { - g_pStrWork = new char[1]; - g_pStrWork[0] = '\0'; - } - return g_pStrWork; -} - -#if 0 // defined(__G_LIB_H__) -void Format( const char* fmt, ... ){ - va_list args; - char *buffer; - - va_start( args, fmt ); - buffer = g_strdup_vprintf( fmt, args ); - va_end( args ); - - delete[] m_pStr; - m_pStr = __StrDup( buffer ); - g_free( buffer ); -} -#else -void Format( const char* fmt, ... ){ - char buffer[1024]; - - { - va_list args; - va_start( args, fmt ); - vsnprintf( buffer, 1023, fmt, args ); - va_end( args ); - } - - delete[] m_pStr; - m_pStr = __StrDup( buffer ); -} -#endif - -void SetAt( std::size_t n, char ch ){ - if ( n < GetLength() ) { - m_pStr[n] = ch; - } -} - -// NOTE: unlike CString, this looses the pointer -void ReleaseBuffer( std::size_t n ){ - char* tmp = m_pStr; - tmp[n] = '\0'; - m_pStr = __StrDup( tmp ); - delete []tmp; -} -void ReleaseBuffer(){ - ReleaseBuffer( GetLength() ); -} - -char* GetBufferSetLength( std::size_t n ){ - char *p = new char[n + 1]; - strncpy( p, m_pStr, n ); - p[n] = '\0'; - delete []m_pStr; - m_pStr = p; - return m_pStr; -} - -// char& operator *() { return *m_pStr; } -// char& operator *() const { return *const_cast(this)->m_pStr; } -operator void*() { - return m_pStr; -} -operator char*() { - return m_pStr; -} -operator const char*() const { return reinterpret_cast( m_pStr ); } -operator unsigned char*() { - return reinterpret_cast( m_pStr ); -} -operator const unsigned char*() const { return reinterpret_cast( m_pStr ); } -Str& operator =( const Str& rhs ){ - if ( &rhs != this ) { - delete[] m_pStr; - m_pStr = __StrDup( rhs.m_pStr ); - } - return *this; -} - -Str& operator =( const char* pStr ){ - if ( m_pStr != pStr ) { - delete[] m_pStr; - m_pStr = __StrDup( pStr ); - } - return *this; -} - -Str& operator +=( const char ch ){ - std::size_t len = GetLength(); - char *p = new char[len + 1 + 1]; - - if ( m_pStr ) { - strcpy( p, m_pStr ); - delete[] m_pStr; - } - - m_pStr = p; - m_pStr[len] = ch; - m_pStr[len + 1] = '\0'; - - return *this; -} - -Str& operator +=( const char *pStr ){ - if ( pStr ) { - if ( m_pStr ) { - char *p = new char[strlen( m_pStr ) + strlen( pStr ) + 1]; - strcpy( p, m_pStr ); - strcat( p, pStr ); - delete[] m_pStr; - m_pStr = p; - } - else - { - m_pStr = __StrDup( pStr ); - } - } - return *this; -} - - -bool operator ==( const Str& rhs ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, rhs.m_pStr ) == 0 : strcmp( m_pStr, rhs.m_pStr ) == 0; -} -bool operator ==( char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) == 0 : strcmp( m_pStr, pStr ) == 0; -} -bool operator ==( const char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) == 0 : strcmp( m_pStr, pStr ) == 0; -} -bool operator !=( Str& rhs ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, rhs.m_pStr ) != 0 : strcmp( m_pStr, rhs.m_pStr ) != 0; -} -bool operator !=( char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) != 0 : strcmp( m_pStr, pStr ) != 0; -} -bool operator !=( const char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) != 0 : strcmp( m_pStr, pStr ) != 0; -} -bool operator <( const Str& rhs ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, rhs.m_pStr ) < 0 : strcmp( m_pStr, rhs.m_pStr ) < 0; -} -bool operator <( char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) < 0 : strcmp( m_pStr, pStr ) < 0; -} -bool operator <( const char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) < 0 : strcmp( m_pStr, pStr ) < 0; -} -bool operator >( const Str& rhs ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, rhs.m_pStr ) > 0 : strcmp( m_pStr, rhs.m_pStr ) > 0; -} -bool operator >( char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) > 0 : strcmp( m_pStr, pStr ) > 0; -} -bool operator >( const char* pStr ) const { - return ( m_bIgnoreCase ) ? stricmp( m_pStr, pStr ) > 0 : strcmp( m_pStr, pStr ) > 0; -} -char& operator []( std::size_t nIndex ) { - return m_pStr[nIndex]; -} -const char& operator []( std::size_t nIndex ) const { - return m_pStr[nIndex]; -} -char GetAt( std::size_t nIndex ) { - return m_pStr[nIndex]; -} -}; - - -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Str& str ){ - return ostream << str.GetBuffer(); -} - - -inline void AddSlash( Str& strPath ){ - if ( strPath.GetLength() > 0 ) { - if ( ( strPath.GetAt( strPath.GetLength() - 1 ) != '/' ) && - ( strPath.GetAt( strPath.GetLength() - 1 ) != '\\' ) ) { - strPath += '/'; - } - } -} - -inline bool ExtractPath_and_Filename( const char* pPath, Str& strPath, Str& strFilename ){ - Str strPathName; - strPathName = pPath; - const char* substr = strPathName.ReverseFind( '\\' ); - if ( substr == 0 ) { - // TTimo: try forward slash, some are using forward - substr = strPathName.ReverseFind( '/' ); - } - if ( substr != 0 ) { - std::size_t nSlash = substr - strPathName.GetBuffer(); - strPath = strPathName.Left( nSlash + 1 ); - strFilename = strPathName.Right( strPathName.GetLength() - nSlash - 1 ); - } - else{ - strFilename = pPath; - } - return true; -} - - - -#endif diff --git a/libs/stream/Makefile b/libs/stream/Makefile deleted file mode 100644 index 1d701b7..0000000 --- a/libs/stream/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - _.o - -# binary target -../libstream.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -_.o: _.cpp filestream.h memstream.h stringstream.h textfilestream.h textstream.h - -clean: - -rm -f *.o ../libstream.a diff --git a/libs/stream/_.cpp b/libs/stream/_.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/libs/stream/filestream.h b/libs/stream/filestream.h deleted file mode 100644 index 826f6b5..0000000 --- a/libs/stream/filestream.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_FILESTREAM_H ) -#define INCLUDED_STREAM_FILESTREAM_H - -#include "idatastream.h" -#include -#include - -namespace FileStreamDetail -{ -inline int whence_for_seekdir( SeekableStream::seekdir direction ){ - switch ( direction ) - { - case SeekableStream::cur: - return SEEK_CUR; - case SeekableStream::end: - return SEEK_END; - default: - break; - } - return SEEK_SET; -} -} - - -/// \brief A wrapper around a file input stream opened for reading in binary mode. Similar to std::ifstream. -/// -/// - Maintains a valid file handle associated with a name passed to the constructor. -/// - Implements SeekableInputStream. -class FileInputStream : public SeekableInputStream -{ -std::FILE* m_file; -public: -FileInputStream( const char* name ){ - m_file = name[0] == '\0' ? 0 : fopen( name, "rb" ); -} -~FileInputStream(){ - if ( !failed() ) { - fclose( m_file ); - } -} - -bool failed() const { - return m_file == 0; -} - -size_type read( byte_type* buffer, size_type length ){ - return fread( buffer, 1, length, m_file ); -} - -size_type seek( size_type position ){ - return fseek( m_file, static_cast( position ), SEEK_SET ); -} -size_type seek( offset_type offset, seekdir direction ){ - return fseek( m_file, offset, FileStreamDetail::whence_for_seekdir( direction ) ); -} -size_type tell() const { - return ftell( m_file ); -} - -std::FILE* file(){ - return m_file; -} -}; - -/// \brief A wrapper around a FileInputStream limiting access. -/// -/// - Maintains an input stream. -/// - Provides input starting at an offset in the file for a limited range. -class SubFileInputStream : public InputStream -{ -FileInputStream& m_istream; -size_type m_remaining; -public: -typedef FileInputStream::position_type position_type; - -SubFileInputStream( FileInputStream& istream, position_type offset, size_type size ) - : m_istream( istream ), m_remaining( size ){ - m_istream.seek( offset ); -} - -size_type read( byte_type* buffer, size_type length ){ - size_type result = m_istream.read( buffer, std::min( length, m_remaining ) ); - m_remaining -= result; - return result; -} -}; - - -/// \brief A wrapper around a stdc file stream opened for writing in binary mode. Similar to std::ofstream.. -/// -/// - Maintains a valid file handle associated with a name passed to the constructor. -/// - Implements SeekableInputStream. -class FileOutputStream : public SeekableOutputStream -{ -std::FILE* m_file; -public: -FileOutputStream( const char* name ){ - m_file = name[0] == '\0' ? 0 : fopen( name, "wb" ); -} -~FileOutputStream(){ - if ( !failed() ) { - fclose( m_file ); - } -} - -bool failed() const { - return m_file == 0; -} - -size_type write( const byte_type* buffer, size_type length ){ - return fwrite( buffer, 1, length, m_file ); -} - -size_type seek( size_type position ){ - return fseek( m_file, static_cast( position ), SEEK_SET ); -} -size_type seek( offset_type offset, seekdir direction ){ - return fseek( m_file, offset, FileStreamDetail::whence_for_seekdir( direction ) ); -} -size_type tell() const { - return ftell( m_file ); -} -}; - -inline bool file_copy( const char* source, const char* target ){ - const std::size_t buffer_size = 1024; - unsigned char buffer[buffer_size]; - - FileInputStream sourceFile( source ); - if ( sourceFile.failed() ) { - return false; - } - FileOutputStream targetFile( target ); - if ( targetFile.failed() ) { - return false; - } - - for (;; ) - { - std::size_t size = sourceFile.read( buffer, buffer_size ); - if ( size == 0 ) { - break; - } - if ( targetFile.write( buffer, size ) != size ) { - return false; - } - } - return true; -} - - -#endif diff --git a/libs/stream/memstream.h b/libs/stream/memstream.h deleted file mode 100644 index 75bd23a..0000000 --- a/libs/stream/memstream.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_MEMSTREAM_H ) -#define INCLUDED_STREAM_MEMSTREAM_H - -#include "itextstream.h" -#include -#include - -class BufferOutputStream : public TextOutputStream -{ -std::vector m_buffer; -public: -std::size_t write( const char* buffer, std::size_t length ){ - m_buffer.insert( m_buffer.end(), buffer, buffer + length ); - return length; -} -const char* data() const { - return &( *m_buffer.begin() ); -} -std::size_t size() const { - return m_buffer.size(); -} -void clear(){ - std::vector empty; - std::swap( empty, m_buffer ); -} -}; - -template -inline BufferOutputStream& operator<<( BufferOutputStream& ostream, const T& t ){ - return ostream_write( ostream, t ); -} - - -class BufferInputStream : public TextInputStream -{ -const char* m_read; -const char* m_end; -public: -BufferInputStream( const char* buffer, std::size_t length ) - : m_read( buffer ), m_end( buffer + length ){ -} -std::size_t read( char* buffer, std::size_t length ){ - std::size_t count = std::min( std::size_t( m_end - m_read ), length ); - const char* end = m_read + count; - while ( m_read != end ) - { - *buffer++ = *m_read++; - } - return count; -} -}; - -#endif diff --git a/libs/stream/stringstream.h b/libs/stream/stringstream.h deleted file mode 100644 index 8511bd4..0000000 --- a/libs/stream/stringstream.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_STRINGSTREAM_H ) -#define INCLUDED_STREAM_STRINGSTREAM_H - -#include "itextstream.h" -#include "string/string.h" -#include - - -/// \brief A wrapper around a STL vector of char. -/// Maintains a null-terminated array of char. -/// Provides a limited STL-style interface to push and pop characters at the end of the string. -class StringBuffer -{ -std::vector m_string; -public: -StringBuffer(){ - m_string.push_back( '\0' ); -} -explicit StringBuffer( std::size_t capacity ){ - m_string.reserve( capacity ); - m_string.push_back( '\0' ); -} -explicit StringBuffer( const char* string ) : m_string( string, string + string_length( string ) + 1 ){ -} - -typedef std::vector::iterator iterator; -typedef std::vector::const_iterator const_iterator; - -iterator begin(){ - return m_string.begin(); -} -const_iterator begin() const { - return m_string.begin(); -} -iterator end(){ - return m_string.end() - 1; -} -const_iterator end() const { - return m_string.end() - 1; -} - -void push_back( char c ){ - m_string.insert( end(), c ); -} -void pop_back(){ - m_string.erase( end() - 1 ); -} -void push_range( const char* first, const char* last ){ - m_string.insert( end(), first, last ); -} -void push_string( const char* string ){ - push_range( string, string + string_length( string ) ); -} -char* c_str(){ - return &( *m_string.begin() ); -} -const char* c_str() const { - return &( *m_string.begin() ); -} - -char& back(){ - return *( end() - 1 ); -} -const char& back() const { - return *( end() - 1 ); -} -bool empty() const { - return m_string.size() == 1; -} -void clear(){ - m_string.clear(); - m_string.push_back( '\0' ); -} -}; - -/// \brief A TextOutputStream which writes to a StringBuffer. -/// Similar to std::stringstream. -class StringOutputStream : public TextOutputStream -{ -StringBuffer m_string; -public: -typedef StringBuffer::iterator iterator; -typedef StringBuffer::const_iterator const_iterator; - -StringOutputStream(){ -} -explicit StringOutputStream( std::size_t capacity ) : m_string( capacity ){ -} -std::size_t write( const char* buffer, std::size_t length ){ - m_string.push_range( buffer, buffer + length ); - return length; -} - -iterator begin(){ - return m_string.begin(); -} -const_iterator begin() const { - return m_string.begin(); -} -iterator end(){ - return m_string.end(); -} -const_iterator end() const { - return m_string.end(); -} - -bool empty() const { - return m_string.empty(); -} -char* c_str(){ - return m_string.c_str(); -} -const char* c_str() const { - return m_string.c_str(); -} -void clear(){ - m_string.clear(); -} -}; - -template -inline StringOutputStream& operator<<( StringOutputStream& ostream, const T& t ){ - return ostream_write( ostream, t ); -} - - -#endif diff --git a/libs/stream/textfilestream.h b/libs/stream/textfilestream.h deleted file mode 100644 index 41dc938..0000000 --- a/libs/stream/textfilestream.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_TEXTFILESTREAM_H ) -#define INCLUDED_STREAM_TEXTFILESTREAM_H - -#include "itextstream.h" -#include - -/// \brief A wrapper around a file input stream opened for reading in text mode. Similar to std::ifstream. -class TextFileInputStream : public TextInputStream -{ -FILE* m_file; -public: -TextFileInputStream( const char* name ){ - m_file = name[0] == '\0' ? 0 : fopen( name, "rt" ); -} -~TextFileInputStream(){ - if ( !failed() ) { - fclose( m_file ); - } -} - -bool failed() const { - return m_file == 0; -} - -std::size_t read( char* buffer, std::size_t length ){ - return fread( buffer, 1, length, m_file ); -} -}; - -/// \brief A wrapper around a file input stream opened for writing in text mode. Similar to std::ofstream. -class TextFileOutputStream : public TextOutputStream -{ -FILE* m_file; -public: -TextFileOutputStream( const char* name ){ - m_file = name[0] == '\0' ? 0 : fopen( name, "wt" ); -} -~TextFileOutputStream(){ - if ( !failed() ) { - fclose( m_file ); - } -} - -bool failed() const { - return m_file == 0; -} - -std::size_t write( const char* buffer, std::size_t length ){ - return fwrite( buffer, 1, length, m_file ); -} -}; - -template -inline TextFileOutputStream& operator<<( TextFileOutputStream& ostream, const T& t ){ - return ostream_write( ostream, t ); -} - - -#endif diff --git a/libs/stream/textstream.h b/libs/stream/textstream.h deleted file mode 100644 index ad1a0be..0000000 --- a/libs/stream/textstream.h +++ /dev/null @@ -1,475 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STREAM_TEXTSTREAM_H ) -#define INCLUDED_STREAM_TEXTSTREAM_H - -#include "globaldefs.h" - -/// \file -/// \brief Text-output-formatting. - -#include "itextstream.h" -#include "string/string.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "generic/arrayrange.h" - -namespace TextOutputDetail -{ -inline char* write_unsigned_nonzero_decimal_backward( char* ptr, unsigned int decimal ){ - for (; decimal != 0; decimal /= 10 ) - { - *--ptr = char('0' + int(decimal % 10) ); - } - return ptr; -} - - #if GDEF_ARCH_BITS_64 -inline char* write_size_t_nonzero_decimal_backward( char* ptr, size_t decimal ){ - for (; decimal != 0; decimal /= 10 ) - { - *--ptr = char('0' + (size_t)( decimal % 10 ) ); - } - return ptr; -} - #endif - -inline char* write_signed_nonzero_decimal_backward( char* ptr, int decimal, bool show_positive ){ - const bool negative = decimal < 0; - ptr = write_unsigned_nonzero_decimal_backward( ptr, negative ? -decimal : decimal ); - if ( negative ) { - *--ptr = '-'; - } - else if ( show_positive ) { - *--ptr = '+'; - } - return ptr; -} - -inline char* write_unsigned_nonzero_decimal_backward( char* ptr, unsigned int decimal, bool show_positive ){ - ptr = write_unsigned_nonzero_decimal_backward( ptr, decimal ); - if ( show_positive ) { - *--ptr = '+'; - } - return ptr; -} - - #if GDEF_ARCH_BITS_64 -inline char* write_size_t_nonzero_decimal_backward( char* ptr, size_t decimal, bool show_positive ){ - ptr = write_size_t_nonzero_decimal_backward( ptr, decimal ); - if ( show_positive ) { - *--ptr = '+'; - } - return ptr; -} - #endif - -inline char* write_signed_decimal_backward( char* ptr, int decimal, bool show_positive ){ - if ( decimal == 0 ) { - *--ptr = '0'; - } - else - { - ptr = write_signed_nonzero_decimal_backward( ptr, decimal, show_positive ); - } - return ptr; -} - -inline char* write_unsigned_decimal_backward( char* ptr, unsigned int decimal, bool show_positive ){ - if ( decimal == 0 ) { - *--ptr = '0'; - } - else - { - ptr = write_unsigned_nonzero_decimal_backward( ptr, decimal, show_positive ); - } - return ptr; -} - - #if GDEF_ARCH_BITS_64 -inline char* write_size_t_decimal_backward( char* ptr, size_t decimal, bool show_positive ){ - if ( decimal == 0 ) { - *--ptr = '0'; - } - else - { - ptr = write_size_t_nonzero_decimal_backward( ptr, decimal, show_positive ); - } - return ptr; -} - #endif -} - - -#if GDEF_OS_WINDOWS -#define snprintf _snprintf -#endif - -/// \brief Writes a single character \p c to \p ostream. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, char c ){ - ostream.write( &c, 1 ); - return ostream; -} - -/// \brief Writes a double-precision floating point value \p d to \p ostream. -/// The value will be formatted either as decimal with trailing zeros removed, or with scientific 'e' notation, whichever is shorter. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const double d ){ - const std::size_t bufferSize = 16; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%g", d ) ); - return ostream; -} - -/// \brief Writes a single-precision floating point value \p f to \p ostream. -/// The value will be formatted either as decimal with trailing zeros removed, or with scientific 'e' notation, whichever is shorter. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const float f ){ - return ostream_write( ostream, static_cast( f ) ); -} - -/// \brief Writes a signed integer \p i to \p ostream in decimal form. -/// A '-' sign will be added if the value is negative. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const int i ){ - const std::size_t bufferSize = 16; -#if 1 - char buf[bufferSize]; - char* begin = TextOutputDetail::write_signed_decimal_backward( buf + bufferSize, i, false ); - ostream.write( begin, ( buf + bufferSize ) - begin ); -#else - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%i", i ) ); -#endif - return ostream; -} - -typedef unsigned int Unsigned; - -/// \brief Writes an unsigned integer \p i to \p ostream in decimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Unsigned i ){ - const std::size_t bufferSize = 16; -#if 1 - char buf[bufferSize]; - char* begin = TextOutputDetail::write_unsigned_decimal_backward( buf + bufferSize, i, false ); - ostream.write( begin, ( buf + bufferSize ) - begin ); -#else - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%u", i ) ); -#endif - return ostream; -} - -#if GDEF_ARCH_BITS_64 - -/// \brief Writes a size_t \p i to \p ostream in decimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const size_t i ){ - // max is 18446744073709551615, buffer of 32 chars should always be enough - const std::size_t bufferSize = 32; -#if 1 - char buf[bufferSize]; - char* begin = TextOutputDetail::write_size_t_decimal_backward( buf + bufferSize, i, false ); - ostream.write( begin, ( buf + bufferSize ) - begin ); -#else - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%u", i ) ); -#endif - return ostream; -} - -#endif - -/// \brief Writes a null-terminated \p string to \p ostream. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const char* string ){ - ostream.write( string, strlen( string ) ); - return ostream; -} - -class HexChar -{ -public: -char m_value; -HexChar( char value ) : m_value( value ){ -} -}; - -/// \brief Writes a single character \p c to \p ostream in hexadecimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const HexChar& c ){ - const std::size_t bufferSize = 16; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%X", c.m_value & 0xFF ) ); - return ostream; -} - -class FloatFormat -{ -public: -double m_f; -int m_width; -int m_precision; -FloatFormat( double f, int width, int precision ) - : m_f( f ), m_width( width ), m_precision( precision ){ -} -}; - -/// \brief Writes a floating point value to \p ostream with a specific width and precision. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const FloatFormat& formatted ){ - const std::size_t bufferSize = 32; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%*.*lf", formatted.m_width, formatted.m_precision, formatted.m_f ) ); - return ostream; -} - -// never displays exponent, prints up to 10 decimal places -class Decimal -{ -public: -double m_f; -Decimal( double f ) : m_f( f ){ -} -}; - -/// \brief Writes a floating point value to \p ostream in decimal form with trailing zeros removed. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Decimal& decimal ){ - const int bufferSize = 22; - char buf[bufferSize]; - std::size_t length = snprintf( buf, bufferSize, "%10.10lf", decimal.m_f ); - const char* first = buf; - for (; *first == ' '; ++first ) - { - } - const char* last = buf + length - 1; - for (; *last == '0'; --last ) - { - } - if ( *last == '.' ) { - --last; - } - ostream.write( first, last - first + 1 ); - return ostream; -} - - -/// \brief Writes a \p range of characters to \p ostream. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const StringRange& range ){ - ostream.write( range.first, range.last - range.first ); - return ostream; -} - -template -class Quoted -{ -public: -const Type& m_type; -Quoted( const Type& type ) - : m_type( type ){ -} -}; - -template -inline Quoted makeQuoted( const Type& type ){ - return Quoted( type ); -} - -/// \brief Writes any type to \p ostream with a quotation mark character before and after it. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Quoted& quoted ){ - return ostream << '"' << quoted.m_type << '"'; -} - - -class LowerCase -{ -public: -const char* m_string; -LowerCase( const char* string ) : m_string( string ){ -} -}; - -/// \brief Writes a string to \p ostream converted to lower-case. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const LowerCase& lower ){ - for ( const char* p = lower.m_string; *p != '\0'; ++p ) - { - ostream << static_cast( std::tolower( *p ) ); - } - return ostream; -} - - -/// \brief A wrapper for a TextInputStream optimised for reading a single character at a time. -template -class SingleCharacterInputStream -{ -TextInputStreamType& m_inputStream; -char m_buffer[SIZE]; -char* m_cur; -char* m_end; - -bool fillBuffer(){ - m_end = m_buffer + m_inputStream.read( m_buffer, SIZE ); - m_cur = m_buffer; - return m_cur != m_end; -} -public: - -SingleCharacterInputStream( TextInputStreamType& inputStream ) : m_inputStream( inputStream ), m_cur( m_buffer ), m_end( m_buffer ){ -} -bool readChar( char& c ){ - if ( m_cur == m_end && !fillBuffer() ) { - return false; - } - - c = *m_cur++; - return true; -} -}; - -/// \brief A wrapper for a TextOutputStream, optimised for writing a single character at a time. -class SingleCharacterOutputStream : public TextOutputStream -{ -enum unnamed0 { m_bufsize = 1024 }; -TextOutputStream& m_ostream; -char m_buffer[m_bufsize]; -char* m_pos; -const char* m_end; - -const char* end() const { - return m_end; -} -void reset(){ - m_pos = m_buffer; -} -void flush(){ - m_ostream.write( m_buffer, m_pos - m_buffer ); - reset(); -} -public: -SingleCharacterOutputStream( TextOutputStream& ostream ) : m_ostream( ostream ), m_pos( m_buffer ), m_end( m_buffer + m_bufsize ){ -} -~SingleCharacterOutputStream(){ - flush(); -} -void write( const char c ){ - if ( m_pos == end() ) { - flush(); - } - *m_pos++ = c; -} -std::size_t write( const char* buffer, std::size_t length ){ - const char*const end = buffer + length; - for ( const char* p = buffer; p != end; ++p ) - { - write( *p ); - } - return length; -} -}; - - -/// \brief A wrapper for a TextInputStream used for reading one text line at a time. -template -class TextLinesInputStream -{ -TextInputStreamType& m_inputStream; -char m_buffer[SIZE + 1]; -char* m_cur; -char* m_end; - -int fillBuffer(){ - m_end = m_buffer + m_inputStream.read( m_buffer, SIZE ); - m_cur = m_buffer; - m_buffer[SIZE] = '\0'; - *m_end = '\0'; - return m_end - m_cur; -} -public: - -TextLinesInputStream( TextInputStreamType& inputStream ) : m_inputStream( inputStream ), m_cur( m_buffer ), m_end( m_buffer ){ - m_buffer[0] = '\0'; -} - -CopiedString readLine(){ - std::string s; - char* m_fin; - - while ( (m_fin = strchr( m_cur, '\n' )) == 0 ) - { - s.append( m_cur, m_end - m_cur ); - if ( fillBuffer() <= 0 ) break; - } - if ( m_fin != 0 ) { - s.append( m_cur, m_fin - m_cur + 1 ); - m_cur = m_fin + 1; - } - - return CopiedString( s.c_str() ); -} -}; - - -/// \brief A wrapper for a TextOutputStream, optimised for writing a few characters at a time. -template -class BufferedTextOutputStream : public TextOutputStream -{ -TextOutputStreamType outputStream; -char m_buffer[SIZE]; -char* m_cur; - -public: -BufferedTextOutputStream( TextOutputStreamType& outputStream ) : outputStream( outputStream ), m_cur( m_buffer ){ -} -~BufferedTextOutputStream(){ - outputStream.write( m_buffer, m_cur - m_buffer ); -} -std::size_t write( const char* buffer, std::size_t length ){ - std::size_t remaining = length; - for (;; ) - { - std::size_t n = std::min( remaining, std::size_t( ( m_buffer + SIZE ) - m_cur ) ); - m_cur = std::copy( buffer, buffer + n, m_cur ); - remaining -= n; - if ( remaining == 0 ) { - return 0; - } - outputStream.write( m_buffer, SIZE ); - m_cur = m_buffer; - } -} -}; - -#endif diff --git a/libs/string/Makefile b/libs/string/Makefile deleted file mode 100644 index 02cdcae..0000000 --- a/libs/string/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# WorldSpawn Makefile - -LIB_CFLAGS=$(CFLAGS) -I../../include -I../../libs -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - pooledstring.o - -# binary target -../libstring.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -pooledstring.o: pooledstring.cpp pooledstring.h string.h stringfwd.h - -clean: - -rm -f *.o ../libstring.a diff --git a/libs/string/pooledstring.cpp b/libs/string/pooledstring.cpp deleted file mode 100644 index d438633..0000000 --- a/libs/string/pooledstring.cpp +++ /dev/null @@ -1,25 +0,0 @@ - -#include "pooledstring.h" -#include "globaldefs.h" -#include "generic/static.h" - -#if GDEF_DEBUG - -namespace ExamplePooledString -{ -void testStuff(){ - PooledString< LazyStatic > a, b; - a = "monkey"; - b = "monkey"; - a = ""; -} - -struct Always -{ - Always(){ - testStuff(); - } -} always; -} - -#endif diff --git a/libs/string/pooledstring.h b/libs/string/pooledstring.h deleted file mode 100644 index a388acf..0000000 --- a/libs/string/pooledstring.h +++ /dev/null @@ -1,93 +0,0 @@ - -#if !defined( INCLUDED_POOLEDSTRING_H ) -#define INCLUDED_POOLEDSTRING_H - -#include -#include "generic/static.h" -#include "string/string.h" -#include "container/hashtable.h" -#include "container/hashfunc.h" - -/// \brief The string pool class. -class StringPool : public HashTable -{ -}; - -inline void StringPool_analyse( StringPool& pool ){ - typedef std::multimap Ordered; - Ordered ordered; - std::size_t total = 0; - std::size_t pooled = 0; - for ( StringPool::iterator i = pool.begin(); i != pool.end(); ++i ) - { - std::size_t size = string_length( ( *i ).key ) + 1; - total += size * ( *i ).value; - pooled += size + 20; - ordered.insert( Ordered::value_type( ( *i ).value, ( *i ).key ) ); - } - globalOutputStream() << "total: " << Unsigned( total ) << " pooled:" << Unsigned( pooled ) << "\n"; - for ( Ordered::iterator i = ordered.begin(); i != ordered.end(); ++i ) - { - globalOutputStream() << ( *i ).second << " " << Unsigned( ( *i ).first ) << "\n"; - } -} - - -/// \brief A string which can be copied with zero memory cost and minimal runtime cost. -/// -/// \param PoolContext The string pool context to use. -template -class PooledString -{ -StringPool::iterator m_i; -static StringPool::iterator increment( StringPool::iterator i ){ - ++( *i ).value; - return i; -} -static StringPool::iterator insert( const char* string ){ - StringPool::iterator i = PoolContext::instance().find( const_cast( string ) ); - if ( i == PoolContext::instance().end() ) { - return PoolContext::instance().insert( string_clone( string ), 1 ); - } - return increment( i ); -} -static void erase( StringPool::iterator i ){ - if ( --( *i ).value == 0 ) { - char* string = ( *i ).key; - PoolContext::instance().erase( i ); - string_release( string, string_length( string ) ); - } -} -public: -PooledString() : m_i( insert( "" ) ){ -} -PooledString( const PooledString& other ) : m_i( increment( other.m_i ) ){ -} -PooledString( const char* string ) : m_i( insert( string ) ){ -} -~PooledString(){ - erase( m_i ); -} -PooledString& operator=( const PooledString& other ){ - PooledString tmp( other ); - tmp.swap( *this ); - return *this; -} -PooledString& operator=( const char* string ){ - PooledString tmp( string ); - tmp.swap( *this ); - return *this; -} -void swap( PooledString& other ){ - std::swap( m_i, other.m_i ); -} -bool operator==( const PooledString& other ) const { - return m_i == other.m_i; -} -const char* c_str() const { - return ( *m_i ).key; -} -}; - - -#endif diff --git a/libs/string/string.h b/libs/string/string.h deleted file mode 100644 index 8c76a91..0000000 --- a/libs/string/string.h +++ /dev/null @@ -1,548 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STRING_STRING_H ) -#define INCLUDED_STRING_STRING_H - -#include "globaldefs.h" - -/// \file -/// C-style null-terminated-character-array string library. - -#include -#include -#include - -#include "memory/allocator.h" -#include "generic/arrayrange.h" - -/// \brief Returns true if \p string length is zero. -/// O(1) -inline bool string_empty( const char* string ){ - return *string == '\0'; -} - -/// \brief Returns true if \p string length is not zero. -/// O(1) -inline bool string_not_empty( const char* string ){ - return !string_empty( string ); -} - -/// \brief Returns <0 if \p string is lexicographically less than \p other. -/// Returns >0 if \p string is lexicographically greater than \p other. -/// Returns 0 if \p string is lexicographically equal to \p other. -/// O(n) -inline int string_compare( const char* string, const char* other ){ - return std::strcmp( string, other ); -} - -/// \brief Returns true if \p string is lexicographically equal to \p other. -/// O(n) -inline bool string_equal( const char* string, const char* other ){ - return string_compare( string, other ) == 0; -} - -/// \brief Returns true if [\p string, \p string + \p n) is lexicographically equal to [\p other, \p other + \p n). -/// O(n) -inline bool string_equal_n( const char* string, const char* other, std::size_t n ){ - return std::strncmp( string, other, n ) == 0; -} - -/// \brief Returns true if \p string is lexicographically less than \p other. -/// O(n) -inline bool string_less( const char* string, const char* other ){ - return string_compare( string, other ) < 0; -} - -/// \brief Returns true if \p string is lexicographically greater than \p other. -/// O(n) -inline bool string_greater( const char* string, const char* other ){ - return string_compare( string, other ) > 0; -} - -/// \brief Returns <0 if \p string is lexicographically less than \p other after converting both to lower-case. -/// Returns >0 if \p string is lexicographically greater than \p other after converting both to lower-case. -/// Returns 0 if \p string is lexicographically equal to \p other after converting both to lower-case. -/// O(n) -inline int string_compare_nocase( const char* string, const char* other ){ -#if GDEF_OS_WINDOWS - return _stricmp( string, other ); -#else - return strcasecmp( string, other ); -#endif -} - -/// \brief Returns <0 if [\p string, \p string + \p n) is lexicographically less than [\p other, \p other + \p n). -/// Returns >0 if [\p string, \p string + \p n) is lexicographically greater than [\p other, \p other + \p n). -/// Returns 0 if [\p string, \p string + \p n) is lexicographically equal to [\p other, \p other + \p n). -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline int string_compare_nocase_n( const char* string, const char* other, std::size_t n ){ -#if GDEF_OS_WINDOWS - return _strnicmp( string, other, n ); -#else - return strncasecmp( string, other, n ); -#endif -} - -/// \brief Returns true if \p string is lexicographically equal to \p other. -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline bool string_equal_nocase( const char* string, const char* other ){ - return string_compare_nocase( string, other ) == 0; -} - -/// \brief Returns true if [\p string, \p string + \p n) is lexicographically equal to [\p other, \p other + \p n). -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline bool string_equal_nocase_n( const char* string, const char* other, std::size_t n ){ - return string_compare_nocase_n( string, other, n ) == 0; -} - -/// \brief Returns true if \p string is lexicographically less than \p other. -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline bool string_less_nocase( const char* string, const char* other ){ - return string_compare_nocase( string, other ) < 0; -} - -/// \brief Returns true if \p string is lexicographically greater than \p other. -/// Treats all ascii characters as lower-case during comparisons. -/// O(n) -inline bool string_greater_nocase( const char* string, const char* other ){ - return string_compare_nocase( string, other ) > 0; -} - -/// \brief Returns the number of non-null characters in \p string. -/// O(n) -inline std::size_t string_length( const char* string ){ - return std::strlen( string ); -} - -/// \brief Returns true if the beginning of \p string is equal to \p prefix. -/// O(n) -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) -inline char* string_copy( char* string, const char* other ){ - return std::strcpy( string, other ); -} - -/// \brief Allocates a string buffer large enough to hold \p length characters, using \p allocator. -/// The returned buffer must be released with \c string_release using a matching \p allocator. -template -inline char* string_new( std::size_t length, Allocator& allocator ){ - return allocator.allocate( length + 1 ); -} - -/// \brief Deallocates the \p buffer large enough to hold \p length characters, using \p allocator. -template -inline void string_release( char* buffer, std::size_t length, Allocator& allocator ){ - allocator.deallocate( buffer, length + 1 ); -} - -/// \brief Returns a newly-allocated string which is a clone of \p other, using \p allocator. -/// The returned buffer must be released with \c string_release using a matching \p allocator. -template -inline char* string_clone( const char* other, Allocator& allocator ){ - char* copied = string_new( string_length( other ), allocator ); - std::strcpy( copied, other ); - return copied; -} - -/// \brief Returns a newly-allocated string which is a clone of [\p first, \p last), using \p allocator. -/// The returned buffer must be released with \c string_release using a matching \p allocator. -template -inline char* string_clone_range( StringRange range, Allocator& allocator ){ - std::size_t length = range.last - range.first; - char* copied = strncpy( string_new( length, allocator ), range.first, length ); - copied[length] = '\0'; - return copied; -} - -/// \brief Allocates a string buffer large enough to hold \p length characters. -/// The returned buffer must be released with \c string_release. -inline char* string_new( std::size_t length ){ - DefaultAllocator allocator; - return string_new( length, allocator ); -} - -/// \brief Allocates a new buffer large enough to hold two concatenated strings and fills it with strings. -inline char* string_new_concat( const char* a, const char* b ){ - char* str = string_new( string_length( a ) + string_length( b ) ); - strcpy( str, a ); - strcat( str, b ); - return str; -} - -/// \brief Deallocates the \p buffer large enough to hold \p length characters. -inline void string_release( char* string, std::size_t length ){ - DefaultAllocator allocator; - string_release( string, length, allocator ); -} - -/// \brief Returns a newly-allocated string which is a clone of \p other. -/// The returned buffer must be released with \c string_release. -inline char* string_clone( const char* other ){ - DefaultAllocator allocator; - return string_clone( other, allocator ); -} - -/// \brief Returns a newly-allocated string which is a clone of [\p first, \p last). -/// The returned buffer must be released with \c string_release. -inline char* string_clone_range( StringRange range ){ - DefaultAllocator allocator; - return string_clone_range( range, allocator ); -} - -typedef char* char_pointer; -/// \brief Swaps the values of \p string and \p other. -inline void string_swap( char_pointer& string, char_pointer& other ){ - std::swap( string, other ); -} - -typedef const char* char_const_pointer; -/// \brief Swaps the values of \p string and \p other. -inline void string_swap( char_const_pointer& string, char_const_pointer& other ){ - std::swap( string, other ); -} - -/// \brief Converts each character of \p string to lower-case and returns \p string. -/// O(n) -inline char* string_to_lowercase( char* string ){ - for ( char* p = string; *p != '\0'; ++p ) - { - *p = (char)std::tolower( *p ); - } - return string; -} - -/// \brief Converts each character of \p string to upper-case and returns \p string. -/// O(n) -inline char* string_to_uppercase( char* string ){ - for ( char* p = string; *p != '\0'; ++p ) - { - *p = (char)std::toupper( *p ); - } - return string; -} - -/// \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; - } - else if ( !intoken ) { - return token; - } - ++m_pos; - } - return token; -} -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(){ - 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. -/// -/// \param Buffer The string storage implementation. Must be DefaultConstructible, CopyConstructible and Assignable. Must implement: -/// \li Buffer(const char* string) - constructor which copies a c-style \p string. -/// \li Buffer(const char* first, const char*) - constructor which copies a c-style string range [\p first, \p last). -/// \li void swap(Buffer& other) - swaps contents with \p other. -/// \li const char* c_str() - returns the stored non-mutable c-style string. -template -class String : public Buffer -{ -public: - -String() - : Buffer(){ -} -String( const char* string ) - : Buffer( string ){ -} -String( StringRange range ) - : Buffer( range ){ -} - -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 ); -} - -bool empty() const { - return string_empty( Buffer::c_str() ); -} -}; - -template -inline bool operator<( const String& self, const String& other ){ - return string_less( self.c_str(), other.c_str() ); -} - -template -inline bool operator>( const String& self, const String& other ){ - return string_greater( self.c_str(), other.c_str() ); -} - -template -inline bool operator==( const String& self, const String& other ){ - return string_equal( self.c_str(), other.c_str() ); -} - -template -inline bool operator!=( const String& self, const String& other ){ - return !string_equal( self.c_str(), other.c_str() ); -} - -template -inline bool operator==( const String& self, const char* other ){ - return string_equal( self.c_str(), other ); -} - -template -inline bool operator!=( const String& self, const char* other ){ - return !string_equal( self.c_str(), other ); -} - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -template -inline void swap( String& self, String& other ){ - self.swap( other ); -} -} - - -/// \brief A non-mutable string buffer which manages memory allocation. -template -class CopiedBuffer : private Allocator -{ -char* m_string; - -char* copy_range( StringRange range ){ - return string_clone_range( range, static_cast( *this ) ); -} -char* copy( const char* other ){ - return string_clone( other, static_cast( *this ) ); -} -void destroy( char* string ){ - string_release( string, string_length( string ), static_cast( *this ) ); -} - -protected: -~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 ); -} -}; - -/// \brief A non-mutable string which uses copy-by-value for assignment. -typedef String< CopiedBuffer< DefaultAllocator > > CopiedString; - - -/// \brief A non-mutable string buffer which uses reference-counting to avoid unnecessary allocations. -template -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( 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( 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( buffer ) ); -} -void decref( char* buffer ){ - if ( --( *reinterpret_cast( buffer ) ) == 0 ) { - destroy( buffer ); - } -} - -protected: -~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 ); -} -}; - -/// \brief A non-mutable string which uses copy-by-reference for assignment of SmartString. -typedef String< SmartBuffer< DefaultAllocator > > SmartString; - -class StringEqualNoCase -{ -public: -bool operator()( const CopiedString& key, const CopiedString& other ) const { - return string_equal_nocase( key.c_str(), other.c_str() ); -} -}; - -struct StringLessNoCase -{ - bool operator()( const CopiedString& x, const CopiedString& y ) const { - return string_less_nocase( x.c_str(), y.c_str() ); - } -}; - -struct RawStringEqual -{ - bool operator()( const char* x, const char* y ) const { - return string_equal( x, y ); - } -}; - -struct RawStringLess -{ - bool operator()( const char* x, const char* y ) const { - return string_less( x, y ); - } -}; - -struct RawStringLessNoCase -{ - bool operator()( const char* x, const char* y ) const { - return string_less_nocase( x, y ); - } -}; - -#endif diff --git a/libs/string/stringfwd.h b/libs/string/stringfwd.h deleted file mode 100644 index d3d634e..0000000 --- a/libs/string/stringfwd.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STRING_STRINGFWD_H ) -#define INCLUDED_STRING_STRINGFWD_H - -// forward-declaration of CopiedString - -template -class DefaultAllocator; -template -class CopiedBuffer; -template -class String; -typedef String< CopiedBuffer< DefaultAllocator > > CopiedString; - -#endif diff --git a/libs/stringio.h b/libs/stringio.h deleted file mode 100644 index 962adf3..0000000 --- a/libs/stringio.h +++ /dev/null @@ -1,374 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_STRINGIO_H ) -#define INCLUDED_STRINGIO_H - -#include -#include - -#include "generic/vector.h" -#include "iscriplib.h" -#include "string/string.h" -#include "generic/callback.h" -#include "property.h" - -inline float string_read_float( const char* string ){ - return static_cast( atof( string ) ); -} - -inline int string_read_int( const char* string ){ - return atoi( string ); -} - -inline bool char_is_whitespace( char c ){ - return c == ' ' || c == '\t'; -} - -inline const char* string_remove_whitespace( const char* string ){ - for (;; ) - { - if ( !char_is_whitespace( *string ) ) { - break; - } - ++string; - } - return string; -} - -inline const char* string_remove_zeros( const char* string ){ - for (;; ) - { - char c = *string; - if ( c != '0' ) { - break; - } - ++string; - } - return string; -} - -inline const char* string_remove_sign( const char* string ){ - if ( *string == '-' || *string == '+' ) { // signed zero - acceptable - return ++string; - } - return string; -} - -inline bool string_is_unsigned_zero( const char* string ){ - for (; *string != '\0'; ++string ) - { - if ( *string != '0' ) { - return false; - } - } - return true; -} - -inline bool string_is_signed_zero( const char* string ){ - return string_is_unsigned_zero( string_remove_sign( string ) ); -} - -//[whitespaces][+|-][nnnnn][.nnnnn][e|E[+|-]nnnn] -//(where whitespaces are any tab or space character and nnnnn may be any number of digits) -inline bool string_is_float_zero( const char* string ){ - string = string_remove_whitespace( string ); - if ( string_empty( string ) ) { - return false; - } - - string = string_remove_sign( string ); - if ( string_empty( string ) ) { - // no whole number or fraction part - return false; - } - - // whole-number part - string = string_remove_zeros( string ); - if ( string_empty( string ) ) { - // no fraction or exponent - return true; - } - if ( *string == '.' ) { - // fraction part - if ( *string++ != '0' ) { - // invalid fraction - return false; - } - string = string_remove_zeros( ++string ); - if ( string_empty( string ) ) { - // no exponent - return true; - } - } - if ( *string == 'e' || *string == 'E' ) { - // exponent part - string = string_remove_sign( ++string ); - if ( *string++ != '0' ) { - // invalid exponent - return false; - } - string = string_remove_zeros( ++string ); - if ( string_empty( string ) ) { - // no trailing whitespace - return true; - } - } - string = string_remove_whitespace( string ); - return string_empty( string ); -} - -inline double buffer_parse_floating_literal( const char*& buffer ){ - return strtod( buffer, const_cast( &buffer ) ); -} - -inline int buffer_parse_signed_decimal_integer_literal( const char*& buffer ){ - return strtol( buffer, const_cast( &buffer ), 10 ); -} - -inline int buffer_parse_unsigned_decimal_integer_literal( const char*& buffer ){ - return strtoul( buffer, const_cast( &buffer ), 10 ); -} - -// [+|-][nnnnn][.nnnnn][e|E[+|-]nnnnn] -inline bool string_parse_float( const char* string, float& f ){ - if ( string_empty( string ) ) { - return false; - } - f = float(buffer_parse_floating_literal( string ) ); - return string_empty( string ); -} - -// format same as float -inline bool string_parse_double( const char* string, double& f ){ - if ( string_empty( string ) ) { - return false; - } - f = buffer_parse_floating_literal( string ); - return string_empty( string ); -} - -// -template -inline bool string_parse_vector3( const char* string, BasicVector3& v ){ - if ( string_empty( string ) || *string == ' ' ) { - return false; - } - v[0] = float(buffer_parse_floating_literal( string ) ); - if ( *string++ != ' ' ) { - return false; - } - v[1] = float(buffer_parse_floating_literal( string ) ); - if ( *string++ != ' ' ) { - return false; - } - v[2] = float(buffer_parse_floating_literal( string ) ); - return string_empty( string ); -} - -template -inline bool string_parse_vector( const char* string, Float* first, Float* last ){ - if ( first != last && ( string_empty( string ) || *string == ' ' ) ) { - return false; - } - for (;; ) - { - *first = float(buffer_parse_floating_literal( string ) ); - if ( ++first == last ) { - return string_empty( string ); - } - if ( *string++ != ' ' ) { - return false; - } - } -} - -// decimal signed integer -inline bool string_parse_int( const char* string, int& i ){ - if ( string_empty( string ) ) { - return false; - } - i = buffer_parse_signed_decimal_integer_literal( string ); - return string_empty( string ); -} - -// decimal unsigned integer -inline bool string_parse_size( const char* string, std::size_t& i ){ - if ( string_empty( string ) ) { - return false; - } - i = buffer_parse_unsigned_decimal_integer_literal( string ); - return string_empty( string ); -} - - -#define RETURN_FALSE_IF_FAIL(expression) do { if (!(expression)) return false; } while (0) - -inline void Tokeniser_unexpectedError( Tokeniser& tokeniser, const char* token, const char* expected ){ - globalErrorStream() << Unsigned( tokeniser.getLine() ) << ":" << Unsigned( tokeniser.getColumn() ) << ": parse error at '" << ( token != 0 ? token : "#EOF" ) << "': expected '" << expected << "'\n"; -} - - -inline bool Tokeniser_getFloat( Tokeniser& tokeniser, float& f ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_parse_float( token, f ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, "#number" ); - return false; -} - -inline bool Tokeniser_getDouble( Tokeniser& tokeniser, double& f ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_parse_double( token, f ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, "#number" ); - return false; -} - -inline bool Tokeniser_getInteger( Tokeniser& tokeniser, int& i ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_parse_int( token, i ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, "#integer" ); - return false; -} - -inline bool Tokeniser_getSize( Tokeniser& tokeniser, std::size_t& i ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_parse_size( token, i ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, "#unsigned-integer" ); - return false; -} - -inline bool Tokeniser_nextTokenMatches( Tokeniser& tokeniser, const char* expected ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_equal( token, expected ) ) { - return true; - } - tokeniser.ungetToken(); - return false; -} - -inline bool Tokeniser_parseToken( Tokeniser& tokeniser, const char* expected ){ - const char* token = tokeniser.getToken(); - if ( token != 0 && string_equal( token, expected ) ) { - return true; - } - Tokeniser_unexpectedError( tokeniser, token, expected ); - return false; -} - -inline bool Tokeniser_nextTokenIsDigit( Tokeniser& tokeniser ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - return false; - } - char c = *token; - tokeniser.ungetToken(); - return std::isdigit( c ) != 0; -} - -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& outputStream, const Vector3& v ){ - return outputStream << '(' << v.x() << ' ' << v.y() << ' ' << v.z() << ')'; -} - - -template<> -struct PropertyImpl { - static void Export(const bool &self, const Callback &returnz) { - returnz(self ? "true" : "false"); - } - - static void Import(bool &self, const char *value) { - self = string_equal(value, "true"); - } -}; - -template<> -struct PropertyImpl { - static void Export(const int &self, const Callback &returnz) { - char buffer[16]; - sprintf(buffer, "%d", self); - returnz(buffer); - } - - static void Import(int &self, const char *value) { - if (!string_parse_int(value, self)) { - self = 0; - } - } -}; - -template<> -struct PropertyImpl { - static void Export(const std::size_t &self, const Callback &returnz) { - char buffer[16]; - sprintf(buffer, "%u", Unsigned(self)); - returnz(buffer); - } - - static void Import(std::size_t &self, const char *value) { - int i; - if (string_parse_int(value, i) && i >= 0) { - self = i; - } else { - self = 0; - } - } -}; - -template<> -struct PropertyImpl { - static void Export(const float &self, const Callback &returnz) { - char buffer[16]; - sprintf(buffer, "%g", self); - returnz(buffer); - } - - static void Import(float &self, const char *value) { - if (!string_parse_float(value, self)) { - self = 0; - } - } -}; - -template<> -struct PropertyImpl { - static void Export(const Vector3 &self, const Callback &returnz) { - char buffer[64]; - sprintf(buffer, "%g %g %g", self[0], self[1], self[2]); - returnz(buffer); - } - - static void Import(Vector3 &self, const char *value) { - if (!string_parse_vector3(value, self)) { - self = Vector3(0, 0, 0); - } - } -}; - -#endif diff --git a/libs/texturelib.h b/libs/texturelib.h deleted file mode 100644 index d9da1e8..0000000 --- a/libs/texturelib.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TEXTURELIB_H ) -#define INCLUDED_TEXTURELIB_H - -#include "generic/vector.h" -typedef Vector3 Colour3; -typedef unsigned int GLuint; -class LoadImageCallback; - -// describes a GL texture -struct qtexture_t -{ - qtexture_t( const LoadImageCallback& load, const char* name ) : load( load ), name( name ){ - } - const LoadImageCallback& load; - const char* name; - std::size_t width, height; - GLuint texture_number; // gl bind number - Colour3 color; // for flat shade mode - int surfaceFlags, contentFlags, value; -}; - -#endif diff --git a/libs/transformlib.h b/libs/transformlib.h deleted file mode 100644 index 10dc14f..0000000 --- a/libs/transformlib.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TRANSFORMLIB_H ) -#define INCLUDED_TRANSFORMLIB_H - -#include "generic/constant.h" -#include "math/matrix.h" -#include "math/quaternion.h" - - -/// \brief A transform node. -class TransformNode -{ -public: -STRING_CONSTANT( Name, "TransformNode" ); -/// \brief Returns the transform which maps the node's local-space into the local-space of its parent node. -virtual const Matrix4& localToParent() const = 0; -}; - -/// \brief A transform node which has no effect. -class IdentityTransform : public TransformNode -{ -public: -/// \brief Returns the identity matrix. -const Matrix4& localToParent() const { - return g_matrix4_identity; -} -}; - -/// \brief A transform node which stores a generic transformation matrix. -class MatrixTransform : public TransformNode -{ -Matrix4 m_localToParent; -public: -MatrixTransform() : m_localToParent( g_matrix4_identity ){ -} - -Matrix4& localToParent(){ - return m_localToParent; -} -/// \brief Returns the stored local->parent transform. -const Matrix4& localToParent() const { - return m_localToParent; -} -}; - - -#include "generic/callback.h" - -typedef Vector3 Translation; -typedef Quaternion Rotation; -typedef Vector3 Scale; - -inline Matrix4 matrix4_transform_for_components( const Translation& translation, const Rotation& rotation, const Scale& scale ){ - Matrix4 result( matrix4_rotation_for_quaternion_quantised( rotation ) ); - vector4_to_vector3( result.x() ) *= scale.x(); - vector4_to_vector3( result.y() ) *= scale.y(); - vector4_to_vector3( result.z() ) *= scale.z(); - result.tx() = translation.x(); - result.ty() = translation.y(); - result.tz() = translation.z(); - return result; -} - -typedef bool TransformModifierType; -const TransformModifierType TRANSFORM_PRIMITIVE = false; -const TransformModifierType TRANSFORM_COMPONENT = true; - -/// \brief A transformable scene-graph instance. -/// -/// A transformable instance may be translated, rotated or scaled. -/// The state of the instanced node's geometrical representation -/// will be the product of its geometry and the transforms of each -/// of its instances, applied in the order they appear in a graph -/// traversal. -/// Freezing the transform on an instance will cause its transform -/// to be permanently applied to the geometry of the node. -class Transformable -{ -public: -STRING_CONSTANT( Name, "Transformable" ); - -virtual void setType( TransformModifierType type ) = 0; -virtual void setTranslation( const Translation& value ) = 0; -virtual void setRotation( const Rotation& value ) = 0; -virtual void setScale( const Scale& value ) = 0; -virtual void freezeTransform() = 0; -}; - -const Translation c_translation_identity = Translation( 0, 0, 0 ); -const Rotation c_rotation_identity = c_quaternion_identity; -const Scale c_scale_identity = Scale( 1, 1, 1 ); - - -class TransformModifier : public Transformable -{ -Translation m_translation; -Rotation m_rotation; -Scale m_scale; -Callback m_changed; -Callback m_apply; -TransformModifierType m_type; -public: - -TransformModifier( const Callback& changed, const Callback& apply ) : - m_translation( c_translation_identity ), - m_rotation( c_quaternion_identity ), - m_scale( c_scale_identity ), - m_changed( changed ), - m_apply( apply ), - m_type( TRANSFORM_PRIMITIVE ){ -} -void setType( TransformModifierType type ){ - m_type = type; -} -TransformModifierType getType() const { - return m_type; -} -void setTranslation( const Translation& value ){ - m_translation = value; - m_changed(); -} -void setRotation( const Rotation& value ){ - m_rotation = value; - m_changed(); -} -void setScale( const Scale& value ){ - m_scale = value; - m_changed(); -} -void freezeTransform(){ - if ( m_translation != c_translation_identity - || m_rotation != c_rotation_identity - || m_scale != c_scale_identity ) { - m_apply(); - m_translation = c_translation_identity; - m_rotation = c_rotation_identity; - m_scale = c_scale_identity; - m_changed(); - } -} -const Translation& getTranslation() const { - return m_translation; -} -const Rotation& getRotation() const { - return m_rotation; -} -const Scale& getScale() const { - return m_scale; -} -Matrix4 calculateTransform() const { - return matrix4_transform_for_components( getTranslation(), getRotation(), getScale() ); -} -}; - - -#endif diff --git a/libs/traverselib.h b/libs/traverselib.h deleted file mode 100644 index d19ca9b..0000000 --- a/libs/traverselib.h +++ /dev/null @@ -1,362 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TRAVERSELIB_H ) -#define INCLUDED_TRAVERSELIB_H - -#include "debugging/debugging.h" - -#include "scenelib.h" -#include "undolib.h" -#include "container/container.h" - -#include -#include -#include - -class TraversableObserverInsertOutputIterator -{ -protected: -scene::Traversable::Observer* m_observer; -public: -typedef std::output_iterator_tag iterator_category; -typedef void difference_type; -typedef void value_type; -typedef void pointer; -typedef void reference; - -TraversableObserverInsertOutputIterator( scene::Traversable::Observer* observer ) - : m_observer( observer ){ -} -TraversableObserverInsertOutputIterator& operator=( const NodeReference& node ){ - m_observer->insert( node ); - return *this; -} -TraversableObserverInsertOutputIterator& operator=( const NodeSmartReference& node ){ - m_observer->insert( node ); - return *this; -} -TraversableObserverInsertOutputIterator& operator*() { - return *this; -} -TraversableObserverInsertOutputIterator& operator++() { - return *this; -} -TraversableObserverInsertOutputIterator& operator++( int ) { - return *this; -} -}; - -class TraversableObserverEraseOutputIterator -{ -protected: -scene::Traversable::Observer* m_observer; -public: -typedef std::output_iterator_tag iterator_category; -typedef void difference_type; -typedef void value_type; -typedef void pointer; -typedef void reference; - -TraversableObserverEraseOutputIterator( scene::Traversable::Observer* observer ) - : m_observer( observer ){ -} -TraversableObserverEraseOutputIterator& operator=( const NodeReference& node ){ - m_observer->erase( node ); - return *this; -} -TraversableObserverEraseOutputIterator& operator=( const NodeSmartReference& node ){ - m_observer->erase( node ); - return *this; -} -TraversableObserverEraseOutputIterator& operator*() { - return *this; -} -TraversableObserverEraseOutputIterator& operator++() { - return *this; -} -TraversableObserverEraseOutputIterator& operator++( int ) { - return *this; -} -}; -typedef UnsortedSet UnsortedNodeSet; - -/// \brief Calls \p observer->\c insert for each node that exists only in \p other and \p observer->\c erase for each node that exists only in \p self -inline void nodeset_diff( const UnsortedNodeSet& self, const UnsortedNodeSet& other, scene::Traversable::Observer* observer ){ - std::vector sorted( self.begin(), self.end() ); - std::vector other_sorted( other.begin(), other.end() ); - - std::sort( sorted.begin(), sorted.end() ); - std::sort( other_sorted.begin(), other_sorted.end() ); - - std::set_difference( sorted.begin(), sorted.end(), other_sorted.begin(), other_sorted.end(), TraversableObserverEraseOutputIterator( observer ) ); - std::set_difference( other_sorted.begin(), other_sorted.end(), sorted.begin(), sorted.end(), TraversableObserverInsertOutputIterator( observer ) ); -} - -/// \brief A sequence of node references which notifies an observer of inserts and deletions, and uses the global undo system to provide undo for modifications. -class TraversableNodeSet : public scene::Traversable -{ -UnsortedNodeSet m_children; -UndoableObject m_undo; -Observer* m_observer; - -void copy( const TraversableNodeSet& other ){ - m_children = other.m_children; -} -void notifyInsertAll(){ - if ( m_observer ) { - for ( UnsortedNodeSet::iterator i = m_children.begin(); i != m_children.end(); ++i ) - { - m_observer->insert( *i ); - } - } -} -void notifyEraseAll(){ - if ( m_observer ) { - for ( UnsortedNodeSet::iterator i = m_children.begin(); i != m_children.end(); ++i ) - { - m_observer->erase( *i ); - } - } -} -public: -TraversableNodeSet() - : m_undo( *this ), m_observer( 0 ){ -} -TraversableNodeSet( const TraversableNodeSet& other ) - : scene::Traversable( other ), m_undo( *this ), m_observer( 0 ){ - copy( other ); - notifyInsertAll(); -} -~TraversableNodeSet(){ - notifyEraseAll(); -} -TraversableNodeSet& operator=( const TraversableNodeSet& other ){ -#if 1 // optimised change-tracking using diff algorithm - if ( m_observer ) { - nodeset_diff( m_children, other.m_children, m_observer ); - } - copy( other ); -#else - TraversableNodeSet tmp( other ); - tmp.swap( *this ); -#endif - return *this; -} -void swap( TraversableNodeSet& other ){ - std::swap( m_children, other.m_children ); - std::swap( m_observer, other.m_observer ); -} - -void attach( Observer* observer ){ - ASSERT_MESSAGE( m_observer == 0, "TraversableNodeSet::attach: observer cannot be attached" ); - m_observer = observer; - notifyInsertAll(); -} -void detach( Observer* observer ){ - ASSERT_MESSAGE( m_observer == observer, "TraversableNodeSet::detach: observer cannot be detached" ); - notifyEraseAll(); - m_observer = 0; -} -/// \brief \copydoc scene::Traversable::insert() -void insert( scene::Node& node ){ - m_undo.save(); - - ASSERT_MESSAGE( m_children.find( NodeSmartReference( node ) ) == m_children.end(), "TraversableNodeSet::insert - element already exists" ); - - m_children.insert( NodeSmartReference( node ) ); - - if ( m_observer ) { - m_observer->insert( node ); - } -} -/// \brief \copydoc scene::Traversable::erase() -void erase( scene::Node& node ){ - m_undo.save(); - - ASSERT_MESSAGE( m_children.find( NodeSmartReference( node ) ) != m_children.end(), "TraversableNodeSet::erase - failed to find element" ); - - if ( m_observer ) { - m_observer->erase( node ); - } - - m_children.erase( NodeSmartReference( node ) ); -} -/// \brief \copydoc scene::Traversable::traverse() -void traverse( const Walker& walker ){ - UnsortedNodeSet::iterator i = m_children.begin(); - while ( i != m_children.end() ) - { - // post-increment the iterator - Node_traverseSubgraph( *i++, walker ); - // the Walker can safely remove the current node from - // this container without invalidating the iterator - } -} -/// \brief \copydoc scene::Traversable::empty() -bool empty() const { - return m_children.empty(); -} - -void instanceAttach( MapFile* map ){ - m_undo.instanceAttach( map ); -} -void instanceDetach( MapFile* map ){ - m_undo.instanceDetach( map ); -} -}; - -namespace std -{ -/// \brief Swaps the values of \p self and \p other. -/// Overloads std::swap. -inline void swap( TraversableNodeSet& self, TraversableNodeSet& other ){ - self.swap( other ); -} -} - - -class TraversableNode : public scene::Traversable -{ -public: -TraversableNode() : m_node( 0 ), m_observer( 0 ){ -} - -// traverse -void attach( Observer* observer ){ - ASSERT_MESSAGE( m_observer == 0, "TraversableNode::attach - cannot attach observer" ); - m_observer = observer; - if ( m_node != 0 ) { - m_observer->insert( *m_node ); - } -} -void detach( Observer* observer ){ - ASSERT_MESSAGE( m_observer == observer, "TraversableNode::detach - cannot detach observer" ); - if ( m_node != 0 ) { - m_observer->erase( *m_node ); - } - m_observer = 0; -} -void insert( scene::Node& node ){ - ASSERT_MESSAGE( m_node == 0, "TraversableNode::insert - element already exists" ); - - m_node = &node; - node.IncRef(); - - if ( m_observer != 0 ) { - m_observer->insert( node ); - } -} -void erase( scene::Node& node ){ - ASSERT_MESSAGE( m_node == &node, "TraversableNode::erase - failed to find element" ); - - if ( m_observer != 0 ) { - m_observer->erase( node ); - } - - m_node = 0; - node.DecRef(); -} -void traverse( const scene::Traversable::Walker& walker ){ - if ( m_node != 0 ) { - Node_traverseSubgraph( *m_node, walker ); - } -} -bool empty() const { - return m_node != 0; -} - -scene::Node& get(){ - return *m_node; -} - -private: -scene::Node* m_node; -Observer* m_observer; -}; - -class TraversableObserverInsert -{ -scene::Node& node; -public: -TraversableObserverInsert( scene::Node& node ) : node( node ){ -} -void operator()( scene::Traversable::Observer& observer ) const { - observer.insert( node ); -} -}; - -class TraversableObserverErase -{ -scene::Node& node; -public: -TraversableObserverErase( scene::Node& node ) : node( node ){ -} -void operator()( scene::Traversable::Observer& observer ) const { - observer.erase( node ); -} -}; - -class TraversableObserverPairRelay : public ReferencePair, public scene::Traversable::Observer -{ -public: -void insert( scene::Node& node ){ - forEach( TraversableObserverInsert( node ) ); -} -void erase( scene::Node& node ){ - forEach( TraversableObserverErase( node ) ); -} -}; - -template -class ReferenceSet -{ -typedef UniqueSet Values; -Values m_values; -public: -void attach( Type& t ){ - m_values.insert( &t ); -} -void detach( Type& t ){ - m_values.erase( &t ); -} -template -void forEach( const Functor& functor ){ - for ( typename Values::iterator i = m_values.begin(); i != m_values.end(); ++i ) - { - functor( *( *i ) ); - } -} -}; - -class TraversableObserverRelay : public ReferenceSet, public scene::Traversable::Observer -{ -public: -void insert( scene::Node& node ){ - forEach( TraversableObserverInsert( node ) ); -} -void erase( scene::Node& node ){ - forEach( TraversableObserverErase( node ) ); -} -}; - - -#endif diff --git a/libs/typesystem.h b/libs/typesystem.h deleted file mode 100644 index 5dc6778..0000000 --- a/libs/typesystem.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TYPESYSTEM_H ) -#define INCLUDED_TYPESYSTEM_H - - -#include -#include -#include "generic/callback.h" -#include "generic/static.h" - -class InitialiserList -{ -typedef std::list > Initialisers; -Initialisers m_initialisers; -mutable bool m_initialised; -public: -InitialiserList() : m_initialised( false ){ -} -void addInitialiser( const Callback& callback ){ - m_initialisers.push_back( callback ); -} -void initialise() const { - if ( !m_initialised ) { - m_initialised = true; - - for ( Initialisers::const_iterator i = m_initialisers.begin(); i != m_initialisers.end(); ++i ) - { - ( *i )( ); - } - } -} -}; - -//--Type System------------------- - -class TypeSystemInitialiser : public InitialiserList -{ -}; - -typedef SmartStatic StaticTypeSystemInitialiser; - -class TypeSystemRef : public StaticTypeSystemInitialiser -{ -public: -TypeSystemRef(){ - StaticTypeSystemInitialiser::instance().initialise(); -} -}; - - - -typedef std::size_t TypeId; -typedef void*( *TypeCast )( void* ); - -template -class TypeCastTable -{ -TypeCast m_casts[SIZE]; -public: -TypeCastTable(){ - std::uninitialized_fill( m_casts, m_casts + SIZE, TypeCast( 0 ) ); -} -void install( TypeId typeId, TypeCast typeCast ){ - m_casts[typeId] = typeCast; -} -void* cast( TypeId typeId, void* p ){ - TypeCast typeCast = m_casts[typeId]; - if ( typeCast != 0 ) { - return typeCast( p ); - } - return 0; -} -}; - -template -class CastInstaller -{ -public: -static void install( TypeCastTable& table ){ - table.install( Type::getTypeId(), Cast::cast ); -} -}; - -template -class IdentityCast -{ -public: -static void* cast( void* p ){ - return p; -} -}; - -template -class StaticCast -{ -public: -static void* cast( void* p ){ - return static_cast( reinterpret_cast( p ) ); -} -}; - -template -class NullType -{ -}; - -template -class ContainedCast -{ -public: -static void* cast( void* p ){ - return &reinterpret_cast( p )->get( NullType() ); -} -}; - - -#endif diff --git a/libs/uilib/Makefile b/libs/uilib/Makefile deleted file mode 100644 index 62d24dc..0000000 --- a/libs/uilib/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# WorldSpawn Makefile - -GTK_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -GLIB_CFLAGS=$(shell pkg-config --cflags glib-2.0) -LIB_CFLAGS=$(CFLAGS) $(GTK_CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -DGTK_TARGET=2 -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - uilib.o - -# binary target -../libuilib.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -uilib.o: uilib.cpp uilib.h - -clean: - -rm -f *.o ../libuilib.a diff --git a/libs/uilib/uilib.cpp b/libs/uilib/uilib.cpp deleted file mode 100644 index 46d3332..0000000 --- a/libs/uilib/uilib.cpp +++ /dev/null @@ -1,506 +0,0 @@ -#include "uilib.h" - -#include - -#include - -#include "gtkutil/dialog.h" -#include "gtkutil/filechooser.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/window.h" - -namespace ui { - -bool init(int *argc, char **argv[], char const *parameter_string, char const **error) -{ - gtk_disable_setlocale(); - static GOptionEntry entries[] = {{}}; - char const *translation_domain = NULL; - GError *gerror = NULL; - bool ret = gtk_init_with_args(argc, argv, parameter_string, entries, translation_domain, &gerror) != 0; - if (!ret) { - *error = gerror->message; - } - return ret; -} - -void main() -{ - gtk_main(); -} - -void process() -{ - while (gtk_events_pending()) { - gtk_main_iteration(); - } -} - -#define IMPL(T, F) template<> _IMPL(T, F) -#define _IMPL(T, F) struct verify { using self = T; static self test(self it) { return self::from(F(it)); } } - -template -struct verify; - -template _IMPL(T,); - -template -using pointer_remove_const = std::add_pointer< - typename std::remove_const< - typename std::remove_pointer::type - >::type - >; - -#define this (verify::test(*static_cast(const_cast::type>(this)))) - -IMPL(Editable, GTK_EDITABLE); - -void IEditable::editable(bool value) -{ - gtk_editable_set_editable(this, value); -} - -IMPL(TreeModel, GTK_TREE_MODEL); - -IMPL(Widget, GTK_WIDGET); - -Widget::Widget(ui::New_t) : Widget(nullptr) -{ -} - -Window IWidget::window() -{ - return Window::from(gtk_widget_get_toplevel(this)); -} - -const char * -IWidget::file_dialog(bool open, const char *title, const char *path, const char *pattern, bool want_load, - bool want_import, bool want_save) -{ - return ::file_dialog(this.window(), open, title, path, pattern, want_load, want_import, want_save); -} - -bool IWidget::visible() -{ - return gtk_widget_get_visible(this) != 0; -} - -void IWidget::visible(bool shown) -{ - if (shown) { - this.show(); - } else { - this.hide(); - } -} - -void IWidget::show() -{ - gtk_widget_show(this); -} - -void IWidget::hide() -{ - gtk_widget_hide(this); -} - -Dimensions IWidget::dimensions() -{ - GtkAllocation allocation; - gtk_widget_get_allocation(this, &allocation); - return Dimensions{allocation.width, allocation.height}; -} - -void IWidget::dimensions(int width, int height) -{ - gtk_widget_set_size_request(this, width, height); -} - -void IWidget::destroy() -{ - gtk_widget_destroy(this); -} - -IMPL(Container, GTK_CONTAINER); - -void IContainer::add(Widget widget) -{ - gtk_container_add(this, widget); -} - -void IContainer::remove(Widget widget) -{ - gtk_container_remove(this, widget); -} - -IMPL(Bin, GTK_BIN); - -IMPL(Window, GTK_WINDOW); - -Window::Window(window_type type) : Window(GTK_WINDOW(gtk_window_new( - type == window_type::TOP ? GTK_WINDOW_TOPLEVEL : - type == window_type::POPUP ? GTK_WINDOW_POPUP : - GTK_WINDOW_TOPLEVEL - ))) -{ -} - -Window IWindow::create_dialog_window(const char *title, void func(), void *data, int default_w, int default_h) -{ - return Window(::create_dialog_window(this, title, func, data, default_w, default_h)); -} - -Window IWindow::create_modal_dialog_window(const char *title, ModalDialog &dialog, int default_w, int default_h) -{ - return Window(::create_modal_dialog_window(this, title, dialog, default_w, default_h)); -} - -Window IWindow::create_floating_window(const char *title) -{ - return Window(::create_floating_window(title, this)); -} - -std::uint64_t IWindow::on_key_press(bool (*f)(Widget widget, _GdkEventKey *event, void *extra), void *extra) -{ - using f_t = decltype(f); - struct user_data { - f_t f; - void *extra; - } *pass = new user_data{f, extra}; - auto dtor = [](user_data *data, GClosure *) { - delete data; - }; - auto func = [](_GtkWidget *widget, GdkEventKey *event, user_data *args) -> bool { - return args->f(Widget::from(widget), event, args->extra); - }; - auto clos = g_cclosure_new(G_CALLBACK(+func), pass, reinterpret_cast(+dtor)); - return g_signal_connect_closure(G_OBJECT(this), "key-press-event", clos, false); -} - -void IWindow::add_accel_group(AccelGroup group) -{ - gtk_window_add_accel_group(this, group); -} - -IMPL(Alignment, GTK_ALIGNMENT); - -Alignment::Alignment(float xalign, float yalign, float xscale, float yscale) - : Alignment(GTK_ALIGNMENT(gtk_alignment_new(xalign, yalign, xscale, yscale))) -{ -} - -IMPL(Frame, GTK_FRAME); - -Frame::Frame(const char *label) : Frame(GTK_FRAME(gtk_frame_new(label))) -{ -} - -IMPL(Button, GTK_BUTTON); - -Button::Button(ui::New_t) : Button(GTK_BUTTON(gtk_button_new())) -{ -} - -Button::Button(const char *label) : Button(GTK_BUTTON(gtk_button_new_with_label(label))) -{ -} - -IMPL(ToggleButton, GTK_TOGGLE_BUTTON); - -bool IToggleButton::active() const -{ - return gtk_toggle_button_get_active(this) != 0; -} - -void IToggleButton::active(bool value) -{ - gtk_toggle_button_set_active(this, value); -} - -IMPL(CheckButton, GTK_CHECK_BUTTON); - -CheckButton::CheckButton(ui::New_t) : CheckButton(GTK_CHECK_BUTTON(gtk_check_button_new())) -{ -} - -CheckButton::CheckButton(const char *label) : CheckButton(GTK_CHECK_BUTTON(gtk_check_button_new_with_label(label))) -{ -} - -IMPL(MenuItem, GTK_MENU_ITEM); - -MenuItem::MenuItem(ui::New_t) : MenuItem(GTK_MENU_ITEM(gtk_menu_item_new())) -{ -} - -MenuItem::MenuItem(const char *label, bool mnemonic) : MenuItem( - GTK_MENU_ITEM((mnemonic ? gtk_menu_item_new_with_mnemonic : gtk_menu_item_new_with_label)(label))) -{ -} - -IMPL(TearoffMenuItem, GTK_TEAROFF_MENU_ITEM); - -TearoffMenuItem::TearoffMenuItem(ui::New_t) : TearoffMenuItem(GTK_TEAROFF_MENU_ITEM(gtk_tearoff_menu_item_new())) -{ -} - -IMPL(ComboBoxText, GTK_COMBO_BOX_TEXT); - -ComboBoxText::ComboBoxText(ui::New_t) : ComboBoxText(GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new_with_entry())) -{ -} - -IMPL(ScrolledWindow, GTK_SCROLLED_WINDOW); - -ScrolledWindow::ScrolledWindow(ui::New_t) : ScrolledWindow(GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(nullptr, nullptr))) -{ -} - -void IScrolledWindow::overflow(Policy x, Policy y) -{ - gtk_scrolled_window_set_policy(this, static_cast(x), static_cast(y)); -} - -IMPL(Box, GTK_BOX); - -void IBox::pack_start(ui::Widget child, bool expand, bool fill, unsigned int padding) -{ - gtk_box_pack_start(this, child, expand, fill, padding); -} - -void IBox::pack_end(ui::Widget child, bool expand, bool fill, unsigned int padding) -{ - gtk_box_pack_end(this, child, expand, fill, padding); -} - -IMPL(VBox, GTK_VBOX); - -VBox::VBox(bool homogenous, int spacing) : VBox(GTK_VBOX(gtk_vbox_new(homogenous, spacing))) -{ -} - -IMPL(HBox, GTK_HBOX); - -HBox::HBox(bool homogenous, int spacing) : HBox(GTK_HBOX(gtk_hbox_new(homogenous, spacing))) -{ -} - -IMPL(HPaned, GTK_HPANED); - -HPaned::HPaned(ui::New_t) : HPaned(GTK_HPANED(gtk_hpaned_new())) -{ -} - -IMPL(VPaned, GTK_VPANED); - -VPaned::VPaned(ui::New_t) : VPaned(GTK_VPANED(gtk_vpaned_new())) -{ -} - -IMPL(Menu, GTK_MENU); - -Menu::Menu(ui::New_t) : Menu(GTK_MENU(gtk_menu_new())) -{ -} - -IMPL(Table, GTK_TABLE); - -Table::Table(std::size_t rows, std::size_t columns, bool homogenous) : Table( - GTK_TABLE(gtk_table_new(rows, columns, homogenous)) - ) -{ -} - -void ITable::attach(Widget child, TableAttach attach, TableAttachOptions options, TablePadding padding) { - gtk_table_attach(this, child, - attach.left, attach.right, attach.top, attach.bottom, - static_cast(options.x), static_cast(options.y), - padding.x, padding.y - ); -} - -IMPL(TextView, GTK_TEXT_VIEW); - -TextView::TextView(ui::New_t) : TextView(GTK_TEXT_VIEW(gtk_text_view_new())) -{ -} - -void ITextView::text(char const *str) -{ - GtkTextBuffer *buffer = gtk_text_view_get_buffer(this); - gtk_text_buffer_set_text(buffer, str, -1); -} - -TreeView::TreeView(ui::New_t) : TreeView(GTK_TREE_VIEW(gtk_tree_view_new())) -{ -} - -TreeView::TreeView(TreeModel model) : TreeView(GTK_TREE_VIEW(gtk_tree_view_new_with_model(model))) -{ -} - -IMPL(Label, GTK_LABEL); - -Label::Label(const char *label) : Label(GTK_LABEL(gtk_label_new(label))) -{ -} - -void ILabel::text(char const *str) -{ - gtk_label_set_text(this, str); -} - -IMPL(Image, GTK_IMAGE); - -Image::Image(ui::New_t) : Image(GTK_IMAGE(gtk_image_new())) -{ -} - -IMPL(Entry, GTK_ENTRY); - -Entry::Entry(ui::New_t) : Entry(GTK_ENTRY(gtk_entry_new())) -{ -} - -Entry::Entry(std::size_t max_length) : Entry(ui::New) -{ - gtk_entry_set_max_length(this, static_cast(max_length)); -} - -char const *IEntry::text() -{ - return gtk_entry_get_text(this); -} - -void IEntry::text(char const *str) -{ - return gtk_entry_set_text(this, str); -} - -IMPL(SpinButton, GTK_SPIN_BUTTON); - -SpinButton::SpinButton(Adjustment adjustment, double climb_rate, std::size_t digits) : SpinButton( - GTK_SPIN_BUTTON(gtk_spin_button_new(adjustment, climb_rate, digits))) -{ -} - -IMPL(HScale, GTK_HSCALE); - -HScale::HScale(Adjustment adjustment) : HScale(GTK_HSCALE(gtk_hscale_new(adjustment))) -{ -} - -HScale::HScale(double min, double max, double step) : HScale(GTK_HSCALE(gtk_hscale_new_with_range(min, max, step))) -{ -} - -IMPL(Adjustment, GTK_ADJUSTMENT); - -Adjustment::Adjustment(double value, - double lower, double upper, - double step_increment, double page_increment, - double page_size) - : Adjustment( - GTK_ADJUSTMENT(gtk_adjustment_new(value, lower, upper, step_increment, page_increment, page_size))) -{ -} - -IMPL(CellRendererText, GTK_CELL_RENDERER_TEXT); - -CellRendererText::CellRendererText(ui::New_t) : CellRendererText(GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new())) -{ -} - -IMPL(TreeViewColumn, GTK_TREE_VIEW_COLUMN); - -TreeViewColumn::TreeViewColumn(const char *title, CellRenderer renderer, - std::initializer_list attributes) - : TreeViewColumn(gtk_tree_view_column_new_with_attributes(title, renderer, nullptr)) -{ - for (auto &it : attributes) { - gtk_tree_view_column_add_attribute(this, renderer, it.attribute, it.column); - } -} - -IMPL(AccelGroup, GTK_ACCEL_GROUP); - -AccelGroup::AccelGroup(ui::New_t) : AccelGroup(GTK_ACCEL_GROUP(gtk_accel_group_new())) -{ -} - -IMPL(ListStore, GTK_LIST_STORE); - -void IListStore::clear() -{ - gtk_list_store_clear(this); -} - -void IListStore::append() -{ - gtk_list_store_append(this, nullptr); -} - -IMPL(TreeStore, GTK_TREE_STORE); - -// IMPL(TreePath, GTK_TREE_PATH); - -TreePath::TreePath(ui::New_t) : TreePath(gtk_tree_path_new()) -{ -} - -TreePath::TreePath(const char *path) : TreePath(gtk_tree_path_new_from_string(path)) -{ -} - -// Custom - -#if GTK_TARGET == 3 - -IMPL(GLArea, (void *)); - -#elif GTK_TARGET == 2 - -IMPL(GLArea, GTK_DRAWING_AREA); - -#endif - -guint IGLArea::on_render(GCallback pFunction, void *data) -{ -#if GTK_TARGET == 3 - return this.connect("render", pFunction, data); -#endif -#if GTK_TARGET == 2 - return this.connect("expose_event", pFunction, data); -#endif -} - -// global - -Window root{ui::null}; - -alert_response alert(Window parent, std::string text, std::string title, alert_type type, alert_icon icon) -{ - auto ret = gtk_MessageBox(parent, text.c_str(), - title.c_str(), - type == alert_type::OK ? eMB_OK : - type == alert_type::OKCANCEL ? eMB_OKCANCEL : - type == alert_type::YESNO ? eMB_YESNO : - type == alert_type::YESNOCANCEL ? eMB_YESNOCANCEL : - type == alert_type::NOYES ? eMB_NOYES : - eMB_OK, - icon == alert_icon::Default ? eMB_ICONDEFAULT : - icon == alert_icon::Error ? eMB_ICONERROR : - icon == alert_icon::Warning ? eMB_ICONWARNING : - icon == alert_icon::Question ? eMB_ICONQUESTION : - icon == alert_icon::Asterisk ? eMB_ICONASTERISK : - eMB_ICONDEFAULT - ); - return - ret == eIDOK ? alert_response::OK : - ret == eIDCANCEL ? alert_response::CANCEL : - ret == eIDYES ? alert_response::YES : - ret == eIDNO ? alert_response::NO : - alert_response::OK; -} - -} diff --git a/libs/uilib/uilib.h b/libs/uilib/uilib.h deleted file mode 100644 index ebe6ef9..0000000 --- a/libs/uilib/uilib.h +++ /dev/null @@ -1,649 +0,0 @@ -#ifndef INCLUDED_UILIB_H -#define INCLUDED_UILIB_H - -#include -#include - -struct _GdkEventKey; -struct _GtkAccelGroup; -struct _GtkAdjustment; -struct _GtkAlignment; -struct _GtkBin; -struct _GtkBox; -struct _GtkButton; -struct _GtkCellEditable; -struct _GtkCellRenderer; -struct _GtkCellRendererText; -struct _GtkCheckButton; -struct _GtkCheckMenuItem; -struct _GtkComboBox; -struct _GtkComboBoxText; -struct _GtkContainer; -struct _GtkDialog; -struct _GtkEditable; -struct _GtkEntry; -struct _GtkEntryCompletion; -struct _GtkFrame; -struct _GtkHBox; -struct _GtkHPaned; -struct _GtkHScale; -struct _GtkImage; -struct _GtkItem; -struct _GtkLabel; -struct _GtkListStore; -struct _GtkTreeIter; -struct _GtkMenu; -struct _GtkMenuBar; -struct _GtkMenuItem; -struct _GtkMenuShell; -struct _GtkMisc; -struct _GtkObject; -struct _GtkPaned; -struct _GtkRadioButton; -struct _GtkRadioMenuItem; -struct _GtkRadioToolButton; -struct _GtkRange; -struct _GtkScale; -struct _GtkScrolledWindow; -struct _GtkSpinButton; -struct _GtkTable; -struct _GtkTearoffMenuItem; -struct _GtkTextView; -struct _GtkToggleButton; -struct _GtkToggleToolButton; -struct _GtkToolbar; -struct _GtkToolButton; -struct _GtkToolItem; -struct _GtkTreeModel; -struct _GtkTreePath; -struct _GtkTreeSelection; -struct _GtkTreeStore; -struct _GtkTreeView; -struct _GtkTreeViewColumn; -struct _GtkVBox; -struct _GtkVPaned; -struct _GtkWidget; -struct _GtkWindow; -struct _GTypeInstance; - -#if GTK_TARGET == 3 -struct _GtkGLArea; -#endif - -#if GTK_TARGET == 2 -using _GtkGLArea = struct _GtkDrawingArea; -#endif - -struct ModalDialog; - -namespace ui { - -bool init(int *argc, char **argv[], char const *parameter_string, char const **error); - -void main(); - -void process(); - -enum class window_type { - TOP, - POPUP -}; - -enum class Shadow { - NONE, - IN, - OUT, - ETCHED_IN, - ETCHED_OUT -}; - -enum class Policy { - ALWAYS, - AUTOMATIC, - NEVER -}; - -namespace details { - -enum class Convert { - Implicit, Explicit -}; - -template -struct Convertible; - -template -struct Convertible { - operator T() const - { return reinterpret_cast(static_cast(this)->_handle); } -}; - -template -struct Convertible { - explicit operator T() const - { return reinterpret_cast(static_cast(this)->_handle); } -}; - -template -struct All : T ... { - All() - { - }; -}; - -template -struct Mixin; -template -struct Mixin { - using type = All; -}; -template -struct Mixin { - using type = All; -}; -} - -const struct Null {} null = {}; -const struct New_t {} New = {}; - -class Object : - public details::Convertible, - public details::Convertible { -public: -using self = Object *; -using native = _GtkObject *; -native _handle; - -explicit Object(native h) : _handle(h) -{ -} - -explicit operator bool() const -{ return _handle != nullptr; } - -explicit operator void *() const -{ return _handle; } - -void unref() -{ - g_object_unref(_handle); -} - -void ref() -{ - g_object_ref(_handle); -} - -template -gulong connect(char const *detailed_signal, Lambda &&c_handler, void *data); - -template -gulong connect(char const *detailed_signal, Lambda &&c_handler, Object data); -}; -static_assert(sizeof(Object) == sizeof(Object::native), "object slicing"); - -#define WRAP(name, super, T, interfaces, ctors, methods) \ - class name; \ - class I ## name : public details::Convertible { \ -public: \ - using self = name *; \ - methods \ - }; \ - class name : public super, public I ## name, public details::Mixin::type { \ -public: \ - using self = name *; \ - using native = T *; \ -protected: \ - explicit name(native h) noexcept : super(reinterpret_cast(h)) {} \ -public: \ - explicit name(Null n) noexcept : name((native) nullptr) {} \ - explicit name(New_t); \ - static name from(native h) { return name(h); } \ - static name from(void *ptr) { return name((native) ptr); } \ - ctors \ - }; \ - inline bool operator<(name self, name other) { return self._handle < other._handle; } \ - static_assert(sizeof(name) == sizeof(super), "object slicing") - -// https://developer.gnome.org/gtk2/stable/ch01.html - -// GInterface - -WRAP(CellEditable, Object, _GtkCellEditable, (), - , - ); - -WRAP(Editable, Object, _GtkEditable, (), - , - void editable(bool value); - ); - -WRAP(TreeModel, Object, _GtkTreeModel, (), - , - ); - -// GObject - -struct Dimensions { - int width; - int height; -}; - -class Window; -WRAP(Widget, Object, _GtkWidget, (), - , - Window window(); - const char *file_dialog( - bool open, - const char *title, - const char *path = nullptr, - const char *pattern = nullptr, - bool want_load = false, - bool want_import = false, - bool want_save = false - ); - bool visible(); - void visible(bool shown); - void show(); - void hide(); - Dimensions dimensions(); - void dimensions(int width, int height); - void destroy(); - ); - -WRAP(Container, Widget, _GtkContainer, (), - , - void add(Widget widget); - - void remove(Widget widget); - - template - void foreach(Lambda &&lambda); - ); - -WRAP(Bin, Container, _GtkBin, (), - , - ); - -class AccelGroup; -WRAP(Window, Bin, _GtkWindow, (), - explicit Window(window_type type); - , - Window create_dialog_window( - const char *title, - void func(), - void *data, - int default_w = -1, - int default_h = -1 - ); - - Window create_modal_dialog_window( - const char *title, - ModalDialog &dialog, - int default_w = -1, - int default_h = -1 - ); - - Window create_floating_window(const char *title); - - std::uint64_t on_key_press( - bool (*f)(Widget widget, _GdkEventKey *event, void *extra), - void *extra = nullptr - ); - - void add_accel_group(AccelGroup group); - ); - -WRAP(Dialog, Window, _GtkDialog, (), - , - ); - -WRAP(Alignment, Bin, _GtkAlignment, (), - Alignment(float xalign, float yalign, float xscale, float yscale); - , - ); - -WRAP(Frame, Bin, _GtkFrame, (), - explicit Frame(const char *label = nullptr); - , - ); - -WRAP(Button, Bin, _GtkButton, (), - explicit Button(const char *label); - , - ); - -WRAP(ToggleButton, Button, _GtkToggleButton, (), - , - bool active() const; - void active(bool value); - ); - -WRAP(CheckButton, ToggleButton, _GtkCheckButton, (), - explicit CheckButton(const char *label); - , - ); - -WRAP(RadioButton, CheckButton, _GtkRadioButton, (), - , - ); - -WRAP(Item, Bin, _GtkItem, (), - , - ); - -WRAP(MenuItem, Item, _GtkMenuItem, (), - explicit MenuItem(const char *label, bool mnemonic = false); - , - ); - -WRAP(CheckMenuItem, MenuItem, _GtkCheckMenuItem, (), - , - ); - -WRAP(RadioMenuItem, CheckMenuItem, _GtkRadioMenuItem, (), - , - ); - -WRAP(TearoffMenuItem, MenuItem, _GtkTearoffMenuItem, (), - , - ); - -WRAP(ComboBox, Bin, _GtkComboBox, (), - , - ); - -WRAP(ComboBoxText, ComboBox, _GtkComboBoxText, (), - , - ); - -WRAP(ToolItem, Bin, _GtkToolItem, (), - , - ); - -WRAP(ToolButton, ToolItem, _GtkToolButton, (), - , - ); - -WRAP(ToggleToolButton, ToolButton, _GtkToggleToolButton, (), - , - ); - -WRAP(RadioToolButton, ToggleToolButton, _GtkRadioToolButton, (), - , - ); - -WRAP(ScrolledWindow, Bin, _GtkScrolledWindow, (), - , - void overflow(Policy x, Policy y); - ); - -WRAP(Box, Container, _GtkBox, (), - , - void pack_start(ui::Widget child, bool expand, bool fill, unsigned int padding); - void pack_end(ui::Widget child, bool expand, bool fill, unsigned int padding); - ); - -WRAP(VBox, Box, _GtkVBox, (), - VBox(bool homogenous, int spacing); - , - ); - -WRAP(HBox, Box, _GtkHBox, (), - HBox(bool homogenous, int spacing); - , - ); - -WRAP(Paned, Container, _GtkPaned, (), - , - ); - -WRAP(HPaned, Paned, _GtkHPaned, (), - , - ); - -WRAP(VPaned, Paned, _GtkVPaned, (), - , - ); - -WRAP(MenuShell, Container, _GtkMenuShell, (), - , - ); - -WRAP(MenuBar, MenuShell, _GtkMenuBar, (), - , - ); - -WRAP(Menu, MenuShell, _GtkMenu, (), - , - ); - -struct TableAttach { - unsigned int left, right, top, bottom; -}; - -struct TableAttachOptions { - // todo: type safety - unsigned int x, y; -}; - -struct TablePadding { - unsigned int x, y; -}; - -WRAP(Table, Container, _GtkTable, (), - Table(std::size_t rows, std::size_t columns, bool homogenous); - , - // 5 = expand | fill - void attach(Widget child, TableAttach attach, TableAttachOptions options = {5, 5}, TablePadding padding = {0, 0}); - ); - -WRAP(TextView, Container, _GtkTextView, (), - , - void text(char const *str); - ); - -WRAP(Toolbar, Container, _GtkToolbar, (), - , - ); - -class TreeModel; -WRAP(TreeView, Widget, _GtkTreeView, (), - TreeView(TreeModel model); - , - ); - -WRAP(Misc, Widget, _GtkMisc, (), - , - ); - -WRAP(Label, Widget, _GtkLabel, (), - explicit Label(const char *label); - , - void text(char const *str); - ); - -WRAP(Image, Widget, _GtkImage, (), - , - ); - -WRAP(Entry, Widget, _GtkEntry, (IEditable, ICellEditable), - explicit Entry(std::size_t max_length); - , - char const *text(); - void text(char const *str); - ); - -class Adjustment; -WRAP(SpinButton, Entry, _GtkSpinButton, (), - SpinButton(Adjustment adjustment, double climb_rate, std::size_t digits); - , - ); - -WRAP(Range, Widget, _GtkRange, (), - , - ); - -WRAP(Scale, Range, _GtkScale, (), - , - ); - -WRAP(HScale, Scale, _GtkHScale, (), - explicit HScale(Adjustment adjustment); - HScale(double min, double max, double step); - , - ); - -WRAP(Adjustment, Object, _GtkAdjustment, (), - Adjustment(double value, - double lower, double upper, - double step_increment, double page_increment, - double page_size); - , - ); - -WRAP(CellRenderer, Object, _GtkCellRenderer, (), - , - ); - -WRAP(CellRendererText, CellRenderer, _GtkCellRendererText, (), - , - ); - -struct TreeViewColumnAttribute { - const char *attribute; - int column; -}; -WRAP(TreeViewColumn, Object, _GtkTreeViewColumn, (), - TreeViewColumn(const char *title, CellRenderer renderer, std::initializer_list attributes); - , - ); - -WRAP(AccelGroup, Object, _GtkAccelGroup, (), - , - ); - -WRAP(EntryCompletion, Object, _GtkEntryCompletion, (), - , - ); - -WRAP(ListStore, Object, _GtkListStore, (ITreeModel), - , - void clear(); - - template - void append(T ... args); - - void append(); - ); - -WRAP(TreeStore, Object, _GtkTreeStore, (ITreeModel), - , - ); - -WRAP(TreeSelection, Object, _GtkTreeSelection, (), - , - ); - -// GBoxed - -WRAP(TreePath, Object, _GtkTreePath, (), - explicit TreePath(const char *path); - , - ); - -// Custom - -WRAP(GLArea, Widget, _GtkGLArea, (), - , - guint on_render(GCallback pFunction, void *data); - ); - -#undef WRAP - -// global - -enum class alert_response { - OK, - CANCEL, - YES, - NO, -}; - -enum class alert_type { - OK, - OKCANCEL, - YESNO, - YESNOCANCEL, - NOYES, -}; - -enum class alert_icon { - Default, - Error, - Warning, - Question, - Asterisk, -}; - -extern class Window root; - -alert_response alert( - Window parent, - std::string text, - std::string title = "WorldSpawn", - alert_type type = alert_type::OK, - alert_icon icon = alert_icon::Default - ); - -// callbacks - -namespace { -using GtkCallback = void (*)(_GtkWidget *, void *); -extern "C" { -void gtk_container_foreach(_GtkContainer *, GtkCallback, void *); -} -} - -#define this (*static_cast(this)) - -template -gulong Object::connect(char const *detailed_signal, Lambda &&c_handler, void *data) -{ - return g_signal_connect(G_OBJECT(this), detailed_signal, c_handler, data); -} - -template -gulong Object::connect(char const *detailed_signal, Lambda &&c_handler, Object data) -{ - return g_signal_connect(G_OBJECT(this), detailed_signal, c_handler, (_GtkObject *) data); -} - -template -void IContainer::foreach(Lambda &&lambda) -{ - GtkCallback cb = [](_GtkWidget *widget, void *data) -> void { - using Function = typename std::decay::type; - Function *f = static_cast(data); - (*f)(Widget::from(widget)); - }; - gtk_container_foreach(this, cb, &lambda); -} - -namespace { -extern "C" { -void gtk_list_store_insert_with_values(_GtkListStore *, _GtkTreeIter *, gint position, ...); -} -} - -template -void IListStore::append(T... args) { - static_assert(sizeof...(args) % 2 == 0, "received an odd number of arguments"); - gtk_list_store_insert_with_values(this, NULL, -1, args ..., -1); -} - -#undef this - -} - -#endif diff --git a/libs/undolib.h b/libs/undolib.h deleted file mode 100644 index 957971f..0000000 --- a/libs/undolib.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_UNDOLIB_H ) -#define INCLUDED_UNDOLIB_H - -#include "iundo.h" -#include "mapfile.h" -#include "warnings.h" -#include "generic/callback.h" - -template -class BasicUndoMemento : public UndoMemento -{ -Copyable m_data; -public: -BasicUndoMemento( const Copyable& data ) - : m_data( data ){ -} - -void release(){ - delete this; -} - -const Copyable& get() const { - return m_data; -} -}; - - -template -class ObservedUndoableObject : public Undoable -{ -typedef Callback ImportCallback; - -Copyable& m_object; -ImportCallback m_importCallback; -UndoObserver* m_undoQueue; -MapFile* m_map; -public: - -ObservedUndoableObject( Copyable & object, const ImportCallback &importCallback ) - : m_object( object ), m_importCallback( importCallback ), m_undoQueue( 0 ), m_map( 0 ) -{ -} -~ObservedUndoableObject(){ -} - -MapFile* map(){ - return m_map; -} - -void instanceAttach( MapFile* map ){ - m_map = map; - m_undoQueue = GlobalUndoSystem().observer( this ); -} -void instanceDetach( MapFile* map ){ - m_map = 0; - m_undoQueue = 0; - GlobalUndoSystem().release( this ); -} - -void save(){ - if ( m_map != 0 ) { - m_map->changed(); - } - if ( m_undoQueue != 0 ) { - m_undoQueue->save( this ); - } -} - -UndoMemento* exportState() const { - return new BasicUndoMemento( m_object ); -} -void importState( const UndoMemento* state ){ - save(); - m_importCallback( ( static_cast*>( state ) )->get() ); -} -}; - -template -class UndoableObject : public Undoable -{ -Copyable& m_object; -UndoObserver* m_undoQueue; -MapFile* m_map; - -public: -UndoableObject( Copyable& object ) - : m_object( object ), m_undoQueue( 0 ), m_map( 0 ) -{ -} -~UndoableObject(){ -} - -void instanceAttach( MapFile* map ){ - m_map = map; - m_undoQueue = GlobalUndoSystem().observer( this ); -} -void instanceDetach( MapFile* map ){ - m_map = 0; - m_undoQueue = 0; - GlobalUndoSystem().release( this ); -} - -void save(){ - if ( m_map != 0 ) { - m_map->changed(); - } - if ( m_undoQueue != 0 ) { - m_undoQueue->save( this ); - } -} - -UndoMemento* exportState() const { - return new BasicUndoMemento( m_object ); -} -void importState( const UndoMemento* state ){ - save(); - m_object = ( static_cast*>( state ) )->get(); -} -}; - -#endif diff --git a/libs/uniquenames.h b/libs/uniquenames.h deleted file mode 100644 index 09ebde9..0000000 --- a/libs/uniquenames.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_UNIQUENAMES_H ) -#define INCLUDED_UNIQUENAMES_H - -#include "debugging/debugging.h" -#include -#include "string/string.h" -#include "generic/static.h" - -#if 1 -class Postfix -{ -unsigned int m_value; -public: -Postfix( const char* postfix ) : m_value( atoi( postfix ) ){ -} -unsigned int number() const { - return m_value; -} -void write( char* buffer ) const { - sprintf( buffer, "%u", m_value ); -} -Postfix& operator++(){ - ++m_value; - return *this; -} -bool operator<( const Postfix& other ) const { - return m_value < other.m_value; -} -bool operator==( const Postfix& other ) const { - return m_value == other.m_value; -} -bool operator!=( const Postfix& other ) const { - return !operator==( other ); -} -}; - -#else -class Postfix -{ -std::pair m_value; -public: -Postfix( unsigned int number, unsigned int leading_zeros ) - : m_value( leading_zeros, number ){ -} -Postfix( const char* postfix ) - : m_value( number_count_leading_zeros( postfix ), atoi( postfix ) ){ -} -unsigned int number() const { - return m_value.second; -} -unsigned int leading_zeros() const { - return m_value.first; -} -void write( char* buffer ){ - for ( unsigned int count = 0; count < m_value.first; ++count, ++buffer ) - *buffer = '0'; - sprintf( buffer, "%u", m_value.second ); -} -Postfix& operator++(){ - ++m_value.second; - if ( m_value.first != 0 && m_value.second % 10 == 0 ) { - --m_value.first; - } - return *this; -} -bool operator<( const Postfix& other ) const { - return m_value < other.m_value; -} -bool operator==( const Postfix& other ) const { - return m_value == other.m_value; -} -bool operator!=( const Postfix& other ) const { - return !operator==( other ); -} -}; - -#endif - -typedef std::pair name_t; - -inline void name_write( char* buffer, name_t name ){ - strcpy( buffer, name.first.c_str() ); - name.second.write( buffer + strlen( name.first.c_str() ) ); -} - -inline name_t name_read( const char* name ){ - const char* end = name + strlen( name ); - for ( const char* p = end; end != name; --p ) - { - if ( strrchr( "1234567890", *p ) == NULL ) { - break; - } - end = p; - } - - return name_t( CopiedString( StringRange( name, end ) ), Postfix( end ) ); -} - - -class PostFixes -{ -public: -typedef std::map postfixes_t; -postfixes_t m_postfixes; - -private: -Postfix find_first_empty() const { - Postfix postfix( "1" ); - for ( postfixes_t::const_iterator i = m_postfixes.find( postfix ); i != m_postfixes.end(); ++i, ++postfix ) - { - if ( ( *i ).first != postfix ) { - break; - } - } - return postfix; -} - -public: -Postfix make_unique( Postfix postfix ) const { - postfixes_t::const_iterator i = m_postfixes.find( postfix ); - if ( i == m_postfixes.end() ) { - return postfix; - } - else - { - return find_first_empty(); - } -} - -void insert( Postfix postfix ){ - postfixes_t::iterator i = m_postfixes.find( postfix ); - if ( i == m_postfixes.end() ) { - m_postfixes.insert( postfixes_t::value_type( postfix, 1 ) ); - } - else - { - ++( *i ).second; - } -} - -void erase( Postfix postfix ){ - postfixes_t::iterator i = m_postfixes.find( postfix ); - if ( i == m_postfixes.end() ) { - // error - } - else - { - if ( --( *i ).second == 0 ) { - m_postfixes.erase( i ); - } - } -} - -bool empty() const { - return m_postfixes.empty(); -} -}; - - -class UniqueNames -{ -typedef std::map names_t; -names_t m_names; -public: -name_t make_unique( const name_t& name ) const { - char buf[80]; - name_t r( "","" ); - name_write( buf, name ); - globalErrorStream() << "find unique name for " << buf << "\n"; - globalErrorStream() << "> currently registered names:\n"; - for ( names_t::const_iterator i = m_names.begin(); i != m_names.end(); ++i ) - { - globalErrorStream() << ">> " << i->first.c_str() << ": "; - for ( PostFixes::postfixes_t::const_iterator j = i->second.m_postfixes.begin(); j != i->second.m_postfixes.end(); ++j ) - { - j->first.write( buf ); - globalErrorStream() << " '" << buf << "'"; - } - globalErrorStream() << "\n"; - } - names_t::const_iterator i = m_names.find( name.first ); - if ( i == m_names.end() ) { - r = name; - } - else - { - r = name_t( name.first, ( *i ).second.make_unique( name.second ) ); - } - name_write( buf, r ); - globalErrorStream() << "> unique name is " << buf << "\n"; - return r; -} - -void insert( const name_t& name ){ - m_names[name.first].insert( name.second ); -} - -void erase( const name_t& name ){ - names_t::iterator i = m_names.find( name.first ); - if ( i == m_names.end() ) { - ASSERT_MESSAGE( true, "erase: name not found" ); - } - else - { - ( *i ).second.erase( name.second ); - if ( ( *i ).second.empty() ) { - m_names.erase( i ); - } - } -} - -bool empty() const { - return m_names.empty(); -} -}; - - - -#if 0 - -#undef ERROR_MESSAGE -#define ERROR_MESSAGE( message ) - -class TestUniqueName -{ -void name_check_equal( const name_t& name, const char* string, unsigned int postfix ){ - ASSERT_MESSAGE( strcmp( name.first.c_str(), string ) == 0 - && name.second.number() == postfix, - "test failed!" ); -} -void test_refcount(){ - Names names; - - names.insert( name_t( "func_bleh_", "100" ) ); - names.insert( name_t( "func_bleh_", "100" ) ); - names.insert( name_t( "func_bleh_", "100" ) ); - - - names.erase( name_t( "func_bleh_", "100" ) ); - names.erase( name_t( "func_bleh_", "100" ) ); - names.erase( name_t( "func_bleh_", "100" ) ); - - ASSERT_MESSAGE( names.empty(), "test failed!" ); -} - -void test_make_unique(){ - Names names; - - { - name_t name( names.make_unique( name_t( "func_bleh_", "01" ) ) ); - name_check_equal( name, "func_bleh_", 1 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "04" ) ) ); - name_check_equal( name, "func_bleh_", 4 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "04" ) ) ); - name_check_equal( name, "func_bleh_", 2 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "1" ) ) ); - name_check_equal( name, "func_bleh_", 3 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "2" ) ) ); - name_check_equal( name, "func_bleh_", 5 ); - names.insert( name ); - } - { - name_t name( names.make_unique( name_t( "func_bleh_", "3" ) ) ); - name_check_equal( name, "func_bleh_", 6 ); - names.insert( name ); - } - - names.erase( name_t( "func_bleh_", "1" ) ); - names.erase( name_t( "func_bleh_", "2" ) ); - names.erase( name_t( "func_bleh_", "3" ) ); - names.erase( name_t( "func_bleh_", "4" ) ); - names.erase( name_t( "func_bleh_", "5" ) ); - names.erase( name_t( "func_bleh_", "6" ) ); - - ASSERT_MESSAGE( names.empty(), "test failed!" ); -} -public: -TestUniqueName(){ - test_refcount(); - test_make_unique(); -} -}; - -const TestUniqueName g_testuniquename; - -#endif - - -#endif diff --git a/libs/versionlib.h b/libs/versionlib.h deleted file mode 100644 index 80d98cd..0000000 --- a/libs/versionlib.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_VERSIONLIB_H ) -#define INCLUDED_VERSIONLIB_H - -#include -#include -#include - -class Version -{ -public: -int major; -int minor; -}; - -inline bool operator<( const Version& version, const Version& other ){ - return version.major < other.major || ( !( other.major < version.major ) && version.minor < other.minor ); -} - -template -TextOutputStreamType& ostream_write( TextOutputStreamType& outputStream, const Version& version ){ - return outputStream << version.major << '.' << version.minor; -} - -/// \brief Returns true if \p version (code) is compatible with \p other (data). -inline bool version_compatible( const Version& version, const Version& other ){ - return version.major == other.major // different major-versions are always incompatible - && !( version.minor < other.minor ); // data minor-version is incompatible if greater than code minor-version -} - -inline int string_range_parse_unsigned_decimal_integer( const char* first, const char* last ){ - int result = 0; - for (; first != last; ++first ) - { - result *= 10; - result += *first - '0'; - } - return result; -} - -inline Version version_parse( const char* versionString ){ - Version version; - const char* endVersion = versionString + strlen( versionString ); - - const char* endMajor = strchr( versionString, '.' ); - if ( endMajor == 0 ) { - endMajor = endVersion; - - version.minor = 0; - } - else - { - const char* endMinor = strchr( endMajor + 1, '.' ); - if ( endMinor == 0 ) { - endMinor = endVersion; - } - version.minor = string_range_parse_unsigned_decimal_integer( endMajor + 1, endMinor ); - } - version.major = string_range_parse_unsigned_decimal_integer( versionString, endMajor ); - - return version; -} - -#endif diff --git a/libs/xml/Makefile b/libs/xml/Makefile deleted file mode 100644 index 9275cbd..0000000 --- a/libs/xml/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# WorldSpawn Makefile - -GTK_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -XML_CFLAGS=$(shell pkg-config --cflags libxml-2.0) - -LIB_CFLAGS=$(CFLAGS) $(GTK_CFLAGS) $(XML_CFLAGS) -I../../include -I../../libs -DGTK_TARGET=2 -DO_CXX=$(CXX) -static -fPIC $(LIB_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - xmltextags.o - -# binary target -../libxmllib.a: $(WS_OBJS) - ar rcs $@ $(WS_OBJS) - -# object files -xmltextags.o: ixml.h xmlelement.h xmlparser.h xmltextags.cpp xmltextags.h xmlwriter.h - -clean: - -rm -f *.o ../libxmllib.a diff --git a/libs/xml/ixml.h b/libs/xml/ixml.h deleted file mode 100644 index 7b86020..0000000 --- a/libs/xml/ixml.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XML_IXML_H ) -#define INCLUDED_XML_IXML_H - -#include "itextstream.h" -#include "generic/constant.h" - -class XMLAttrVisitor -{ -public: -virtual void visit( const char* name, const char* value ) = 0; -}; - -class XMLElement -{ -public: -virtual const char* name() const = 0; -virtual const char* attribute( const char* name ) const = 0; -virtual void forEachAttribute( XMLAttrVisitor& visitor ) const = 0; -}; - -class XMLImporter : public TextOutputStream -{ -public: -STRING_CONSTANT( Name, "XMLImporter" ); - -virtual void pushElement( const XMLElement& element ) = 0; -virtual void popElement( const char* name ) = 0; -}; - -class XMLExporter -{ -public: -STRING_CONSTANT( Name, "XMLExporter" ); - -virtual void exportXML( XMLImporter& importer ) = 0; -}; - - -#endif diff --git a/libs/xml/xmlelement.h b/libs/xml/xmlelement.h deleted file mode 100644 index 5bedf55..0000000 --- a/libs/xml/xmlelement.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XML_XMLELEMENT_H ) -#define INCLUDED_XML_XMLELEMENT_H - -#include "xml/ixml.h" -#include "string/string.h" - -#include - -///\brief All string pointers passed to an instance of this class are not -/// copied and must stay valid for the lifetime of the instance. -class StaticElement : public XMLElement -{ -typedef std::map attrs_t; -public: -StaticElement( const char* name ) - : m_name( name ){ -} -void insertAttribute( const char* name, const char* value ){ - m_attrs.insert( attrs_t::value_type( name, value ) ); -} -const char* name() const { - return m_name; -} -const char* attribute( const char* name ) const { - attrs_t::const_iterator i = m_attrs.find( name ); - if ( i != m_attrs.end() ) { - return i->second; - } - else{ - return ""; - } -} -void forEachAttribute( XMLAttrVisitor& visitor ) const { - for ( attrs_t::const_iterator i = m_attrs.begin(); i != m_attrs.end(); ++i ) - { - visitor.visit( i->first, i->second ); - } -} -private: -const char* m_name; -attrs_t m_attrs; -}; - -///\brief All string pointers passed to an instance of this class are copied. -class DynamicElement : public XMLElement -{ -typedef std::map attrs_t; -public: -DynamicElement( const char* name ) - : m_name( name ){ -} -void insertAttribute( const char* name, const char* value ){ - m_attrs.insert( attrs_t::value_type( name, value ) ); -} -const char* name() const { - return m_name.c_str(); -} -const char* attribute( const char* name ) const { - attrs_t::const_iterator i = m_attrs.find( name ); - if ( i != m_attrs.end() ) { - return i->second.c_str(); - } - else{ - return ""; - } -} -void forEachAttribute( XMLAttrVisitor& visitor ) const { - for ( attrs_t::const_iterator i = m_attrs.begin(); i != m_attrs.end(); ++i ) - { - visitor.visit( i->first.c_str(), i->second.c_str() ); - } -} -private: -CopiedString m_name; -attrs_t m_attrs; -}; - -#endif diff --git a/libs/xml/xmlparser.h b/libs/xml/xmlparser.h deleted file mode 100644 index 17bcc68..0000000 --- a/libs/xml/xmlparser.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XML_XMLPARSER_H ) -#define INCLUDED_XML_XMLPARSER_H - -#include -#include -#include "ixml.h" -#include "libxml/parser.h" -#include "convert.h" - -class TextInputStream; - -class SAXElement : public XMLElement -{ -public: -SAXElement( const char* name, const char** atts ) - : m_name( name ), m_atts( atts ){ -} -const char* name() const { - return m_name; -} -const char* attribute( const char* name ) const { - if ( m_atts != 0 ) { - for ( const char** att = m_atts; *att != 0; att += 2 ) - { - if ( strcmp( *att, name ) == 0 ) { - return *( ++att ); - } - } - } - return ""; -} -void forEachAttribute( XMLAttrVisitor& visitor ) const { - if ( m_atts != 0 ) { - for ( const char** att = m_atts; *att != 0; att += 2 ) - { - visitor.visit( *att, *( att + 1 ) ); - } - } -} -private: -const char* m_name; -const char** m_atts; -}; - -#include - -class FormattedVA -{ -public: -const char* m_format; -va_list& m_arguments; -FormattedVA( const char* format, va_list& m_arguments ) - : m_format( format ), m_arguments( m_arguments ){ -} -}; - -class Formatted -{ -public: -const char* m_format; -mutable va_list m_arguments; -Formatted( const char* format, ... ) - : m_format( format ){ - va_start( m_arguments, format ); -} -~Formatted(){ - va_end( m_arguments ); -} -}; - -#ifdef _MSC_VER -#if _MSC_VER < 1400 -#define vsnprintf std::vsnprintf -#endif -#endif - -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const FormattedVA& formatted ){ - char buffer[1024]; - ostream.write( buffer, vsnprintf( buffer, 1023, formatted.m_format, formatted.m_arguments ) ); - return ostream; -} - -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Formatted& formatted ){ - char buffer[1024]; - ostream.write( buffer, vsnprintf( buffer, 1023, formatted.m_format, formatted.m_arguments ) ); - return ostream; -} - -class XMLSAXImporter -{ -XMLImporter& m_importer; -xmlSAXHandler m_sax; - -static void startElement( void *user_data, const xmlChar *name, const xmlChar **atts ){ - SAXElement element( reinterpret_cast( name ), reinterpret_cast( atts ) ); - reinterpret_cast( user_data )->m_importer.pushElement( element ); -} -static void endElement( void *user_data, const xmlChar *name ){ - reinterpret_cast( user_data )->m_importer.popElement( reinterpret_cast( name ) ); -} -static void characters( void *user_data, const xmlChar *ch, int len ){ - reinterpret_cast( user_data )->m_importer - << StringRange( reinterpret_cast( ch ), reinterpret_cast( ch + len ) ); -} - -static void warning( void *user_data, const char *msg, ... ){ - va_list args; - va_start( args, msg ); - globalErrorStream() << "XML WARNING: " << FormattedVA( msg, args ); - va_end( args ); -} -static void error( void *user_data, const char *msg, ... ){ - va_list args; - va_start( args, msg ); - globalErrorStream() << "XML ERROR: " << FormattedVA( msg, args ); - va_end( args ); -} - -public: -XMLSAXImporter( XMLImporter& importer ) : m_importer( importer ){ - m_sax.internalSubset = 0; - m_sax.isStandalone = 0; - m_sax.hasInternalSubset = 0; - m_sax.hasExternalSubset = 0; - m_sax.resolveEntity = 0; - m_sax.getEntity = 0; - m_sax.entityDecl = 0; - m_sax.notationDecl = 0; - m_sax.attributeDecl = 0; - m_sax.elementDecl = 0; - m_sax.unparsedEntityDecl = 0; - m_sax.setDocumentLocator = 0; - m_sax.startDocument = 0; - m_sax.endDocument = 0; - m_sax.startElement = startElement; - m_sax.endElement = endElement; - m_sax.reference = 0; - m_sax.characters = characters; - m_sax.ignorableWhitespace = 0; - m_sax.processingInstruction = 0; - m_sax.comment = 0; - m_sax.warning = warning; - m_sax.error = error; - m_sax.fatalError = 0; - m_sax.getParameterEntity = 0; - m_sax.cdataBlock = 0; - m_sax.externalSubset = 0; - m_sax.initialized = 1; -} - -xmlSAXHandler* callbacks(){ - return &m_sax; -} -void* context(){ - return this; -} -}; - -class XMLStreamParser : public XMLExporter -{ -enum unnamed0 { BUFSIZE = 1024 }; -public: -XMLStreamParser( TextInputStream& istream ) - : m_istream( istream ){ -} -virtual void exportXML( XMLImporter& importer ){ - bool wellFormed = false; - - char chars[BUFSIZE]; - std::size_t res = m_istream.read( chars, 4 ); - if ( res > 0 ) { - XMLSAXImporter sax( importer ); - - xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt( sax.callbacks(), sax.context(), chars, static_cast( res ), 0 ); - ctxt->replaceEntities = 1; - - while ( ( res = m_istream.read( chars, BUFSIZE ) ) > 0 ) - { - xmlParseChunk( ctxt, chars, static_cast( res ), 0 ); - } - xmlParseChunk( ctxt, chars, 0, 1 ); - - wellFormed = ( ctxt->wellFormed == 1 ); - - xmlFreeParserCtxt( ctxt ); - } - - (void) wellFormed; - //return wellFormed; -} -private: -TextInputStream& m_istream; -}; - - - -#endif diff --git a/libs/xml/xmltextags.cpp b/libs/xml/xmltextags.cpp deleted file mode 100644 index 00f57a0..0000000 --- a/libs/xml/xmltextags.cpp +++ /dev/null @@ -1,592 +0,0 @@ -/* - Copyright (C) 2006, Stefan Greven. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "xmltextags.h" - -#include - -#include "qerplugin.h" -#include "stream/stringstream.h" - -XmlTagBuilder::XmlTagBuilder(){ -} - -XmlTagBuilder::~XmlTagBuilder(){ - // clean up - xmlFreeDoc( doc ); - xmlXPathFreeContext( context ); -} - -bool XmlTagBuilder::CreateXmlDocument(){ - /* Creates an XML file - - returns TRUE if the file was created successfully or FALSE when failed - */ - - xmlTextWriterPtr writer; - - writer = xmlNewTextWriterDoc( &doc, 0 ); - - // begin a new UTF-8 formatted xml document - xmlTextWriterStartDocument( writer, NULL, "UTF-8", NULL ); - - // create the root node with stock and custom elements - xmlTextWriterStartElement( writer, (xmlChar*)"root" ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n " ); - xmlTextWriterStartElement( writer, (xmlChar*)"stock" ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n " ); - xmlTextWriterEndElement( writer ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n " ); - xmlTextWriterStartElement( writer, (xmlChar*)"custom" ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n " ); - xmlTextWriterEndElement( writer ); - xmlTextWriterWriteString( writer, (xmlChar*)"\n" ); - xmlTextWriterEndElement( writer ); - - // end of the xml document - xmlTextWriterEndDocument( writer ); - xmlFreeTextWriter( writer ); - - if ( !doc ) { - return false; - } - else { - context = xmlXPathNewContext( doc ); - return true; - } -} - -bool XmlTagBuilder::OpenXmlDoc( const char* file, const char* savefile ){ - /* Reads a XML document from a file - - returns TRUE if the document was read successfully or FALSE when failed - */ - - if ( savefile ) { - m_savefilename = savefile; - } - else{ - m_savefilename = file; - } - - doc = xmlParseFile( file ); // TODO error checking! - - if ( !doc ) { - return false; - } - else { - context = xmlXPathNewContext( doc ); - return true; - } -} - -bool XmlTagBuilder::SaveXmlDoc( void ){ - return SaveXmlDoc( m_savefilename.c_str() ); -} - -bool XmlTagBuilder::SaveXmlDoc( const char* file ){ - /* Writes the XML document - - returns TRUE if the document was saved successfully or FALSE when saving failed - */ - - xmlSaveNoEmptyTags = 1; - - if ( xmlSaveFile( file, doc ) != -1 ) { - return true; - } - return false; -} - -bool XmlTagBuilder::AddShaderNode( const char* shader, TextureType textureType, NodeShaderType nodeShaderType ){ - /* Adds a shader node - - char* shader - the name of the shader or texture (without trailing .tga or something) - - returns TRUE if the node was added successfully or FALSE when failed - */ - - xmlNodeSetPtr nodePtr = NULL; - xmlXPathObjectPtr xpathPtr = NULL; - - switch ( textureType ) - { - case STOCK: - xpathPtr = XpathEval( "/root/stock" ); - break; - case CUSTOM: - xpathPtr = XpathEval( "/root/custom" ); - }; - - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlNodePtr newnode, newtext; - xmlNodePtr nodeParent = nodePtr->nodeTab[0]; - - // create a new node and set the node attribute (shader path) - switch ( nodeShaderType ) - { - case SHADER: - newnode = xmlNewNode( NULL, (xmlChar*)"shader" ); - break; - case TEXTURE: - newnode = xmlNewNode( NULL, (xmlChar*)"texture" ); - }; - - newnode = xmlDocCopyNode( newnode, doc, 1 ); - xmlSetProp( newnode, (xmlChar*)"path", (xmlChar*)shader ); - xmlNodeSetContent( newnode, (xmlChar*)"\n " ); - - if ( nodePtr->nodeTab[0]->children->next == NULL ) { // there are no shaders yet - // add spaces - newtext = xmlNewText( (xmlChar*)" " ); - xmlAddChild( nodeParent->children, newtext ); - - // add the new node - xmlAddNextSibling( nodeParent->children, newnode ); - - // append a new line - newtext = xmlNewText( (xmlChar*)"\n " ); - xmlAddNextSibling( nodeParent->children->next, newtext ); - } - else { - // add the node - xmlAddNextSibling( nodeParent->children, newnode ); - - // append a new line and spaces - newtext = xmlNewText( (xmlChar*)"\n " ); - xmlAddNextSibling( nodeParent->children->next, newtext ); - } - - xmlXPathFreeObject( xpathPtr ); - return true; - } - else { - xmlXPathFreeObject( xpathPtr ); - return false; - } -} - -bool XmlTagBuilder::DeleteShaderNode( const char* shader ){ - /* Deletes a shader node - - char* shader - the name of the shader or texture (without trailing .tga or something) - - returns TRUE if the node was deleted successfully or FALSE when failed - */ - - char buffer[256]; - char* expression = GetTagsXpathExpression( buffer, shader, EMPTY ); - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlNodePtr ptrContent = nodePtr->nodeTab[0]; - xmlNodePtr ptrWhitespace = nodePtr->nodeTab[0]->prev; - - // delete the node - xmlUnlinkNode( ptrContent ); - xmlFreeNode( ptrContent ); - - // delete leading whitespace node - xmlUnlinkNode( ptrWhitespace ); - xmlFreeNode( ptrWhitespace ); - xmlXPathFreeObject( xpathPtr ); - return true; - } - xmlXPathFreeObject( xpathPtr ); - return false; -} - -bool XmlTagBuilder::CheckShaderTag( const char* shader ){ - /* Checks whether there exists an entry for a shader/texture with at least one tag - - char* shader - the name of the shader or texture (without trailing .tga or something) - - returns TRUE if the shader is already stored in the XML tag file and has at least one tag - */ - - // build the XPath expression to search for - char buffer[256]; - strcpy( buffer, "/root/*/*[@path='" ); - strcat( buffer, shader ); - strcat( buffer, "']" ); - - char* expression = buffer; - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlXPathFreeObject( xpathPtr ); - return true; - } - else { - xmlXPathFreeObject( xpathPtr ); - return false; - } -} - -bool XmlTagBuilder::CheckShaderTag( const char* shader, const char* content ){ - /* Checks whether a tag with content already exists - - char* shader - the name of the shader or texture (without trailing .tga or something) - char* content - the node content (a tag name) - - returns TRUE if the tag with content already exists or FALSE if not - */ - - // build the XPath expression to search for - // example expression: "/stock/*[@path='textures/alpha/barb_wire'][child::tag='Alpha']"; - - char buffer[256]; - strcpy( buffer, "/root/*/*[@path='" ); - strcat( buffer, shader ); - strcat( buffer, "'][child::tag='" ); - strcat( buffer, content ); - strcat( buffer, "']" ); - - char* expression = buffer; - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlXPathFreeObject( xpathPtr ); - return true; - } - else { - xmlXPathFreeObject( xpathPtr ); - return false; - } -} - -bool XmlTagBuilder::AddShaderTag( const char* shader, const char* content, NodeTagType nodeTagType ){ - /* Adds a tag node to an existing shader/texture node if there's no tag with the same content yet - - char* shader - the name of the shader or texture (without trailing .tga or something) - char* content - the node content (a tag name) - - returns TRUE if the node was added successfully or FALSE when failed - */ - - // build the XPath expression - char buffer[256]; - char* expression = GetTagsXpathExpression( buffer, shader, EMPTY ); - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { // node was found - xmlNodePtr newnode = xmlNewNode( NULL, (xmlChar*)"tag" ); - xmlNodePtr nodeParent = nodePtr->nodeTab[0]; - newnode = xmlDocCopyNode( newnode, doc, 1 ); - xmlNodeSetContent( newnode, (xmlChar*)content ); - - if ( nodePtr->nodeTab[0]->children->next == NULL ) { // shader node has NO children - // add spaces - xmlNodePtr newtext = xmlNewText( (xmlChar*)" " ); - xmlAddChild( nodeParent->children, newtext ); - - // add new node - xmlAddNextSibling( nodeParent->children, newnode ); - - // append a new line + spaces - newtext = xmlNewText( (xmlChar*)"\n " ); - xmlAddNextSibling( nodeParent->children->next, newtext ); - } - else { // shader node has children already - the new node will be the first sibling - xmlAddNextSibling( nodeParent->children, newnode ); - xmlNodePtr newtext = xmlNewText( (xmlChar*)"\n " ); - xmlAddNextSibling( nodeParent->children->next, newtext ); - } - xmlXPathFreeObject( xpathPtr ); - return true; - } - else { - xmlXPathFreeObject( xpathPtr ); - return false; - } -} - -//int XmlTagBuilder::RenameShaderTag(const char* oldtag, const char* newtag) -int XmlTagBuilder::RenameShaderTag( const char* oldtag, CopiedString newtag ){ - /* Replaces tag node contents - - char* oldtag - the node content that sould be changed - char* newtag - the new node content - - returns the number of renamed shaders - */ - - int num = 0; - - // build the XPath expression - char expression[256]; - strcpy( expression, "/root/*/*[child::tag='" ); - strcat( expression, oldtag ); - strcat( expression, "']/*" ); - - xmlXPathObjectPtr result = xmlXPathEvalExpression( (xmlChar*)expression, context ); - if ( !result ) { - return 0; - } - xmlNodeSetPtr nodePtr = result->nodesetval; - - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - xmlNodePtr ptrContent = nodePtr->nodeTab[i]; - char* content = (char*)xmlNodeGetContent( ptrContent ); - - if ( strcmp( content, oldtag ) == 0 ) { // found a node with old content? - xmlNodeSetContent( ptrContent, (xmlChar*)newtag.c_str() ); - num++; - } - } - - SaveXmlDoc(); - xmlXPathFreeObject( result ); // CHANGED - return num; -} - -bool XmlTagBuilder::DeleteShaderTag( const char* shader, const char* tag ){ - /* Deletes a child node of a shader - - char* shader - the name of the shader or texture (without trailing .tga or something) - char* tag - the tag being deleted - - returns TRUE if the node was deleted successfully or FALSE when failed - */ - - char buffer[256]; - char* expression = GetTagsXpathExpression( buffer, shader, TAG ); - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return false; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - xmlNodePtr ptrContent = nodePtr->nodeTab[i]; - char* content = (char*)(xmlChar*)xmlNodeGetContent( ptrContent ); - - if ( strcmp( content, tag ) == 0 ) { // find the node - xmlNodePtr ptrWhitespace = nodePtr->nodeTab[i]->prev; - // delete the node - xmlUnlinkNode( ptrContent ); - xmlFreeNode( ptrContent ); - - // delete leading whitespace node - xmlUnlinkNode( ptrWhitespace ); - xmlFreeNode( ptrWhitespace ); - xmlXPathFreeObject( xpathPtr ); - return true; - } - } - } - xmlXPathFreeObject( xpathPtr ); - return false; -} - -bool XmlTagBuilder::DeleteTag( const char* tag ){ - /* Deletes a tag from all shaders - - char* tag - the tag being deleted from all shaders - - returns TRUE if the tag was deleted successfully or FALSE when failed - */ - - char expression[256]; - strcpy( expression, "/root/*/*[child::tag='" ); - strcat( expression, tag ); - strcat( expression, "']" ); - - std::set dellist; - TagSearch( expression, dellist ); - std::set::iterator iter; - - for ( iter = dellist.begin(); iter != dellist.end(); iter++ ) - { - DeleteShaderTag( iter->c_str(), tag ); - } - SaveXmlDoc(); - - return true; -} - -void XmlTagBuilder::GetShaderTags( const char* shader, std::vector& tags ){ - /* Gets the tags from a shader - - char* shader - the name of the shader - - returns a vector containing the tags - */ - - char const *expression; - - if ( shader == NULL ) { // get all tags from all shaders - expression = "/root/*/*/tag"; - } - else { - char buffer[256]; - expression = GetTagsXpathExpression( buffer, shader, TAG ); - } - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - tags.push_back( (CopiedString)(char*)xmlNodeGetContent( nodePtr->nodeTab[i] ) ); - } - } - xmlXPathFreeObject( xpathPtr ); -} - -void XmlTagBuilder::GetUntagged( std::set& shaders ){ - /* Gets all textures and shaders listed in the xml file that don't have any tag - - returns a set containing the shaders (with path) - */ - - char const *expression = "/root/*/*[not(child::tag)]"; - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlNodePtr ptr; - - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - ptr = nodePtr->nodeTab[i]; - shaders.insert( (char*)xmlGetProp( ptr, (xmlChar*)"path" ) ); - } - } - - xmlXPathFreeObject( xpathPtr ); -} - -void XmlTagBuilder::GetAllTags( std::set& tags ){ - /* Gets a list of all tags that are used (assigned to any shader) - - returns a set containing all used tags - */ - - char const *expression = "/root/*/*/tag"; - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - tags.insert( (CopiedString)(char*)xmlNodeGetContent( nodePtr->nodeTab[i] ) ); - } - } - - xmlXPathFreeObject( xpathPtr ); -} - -void XmlTagBuilder::TagSearch( const char* expression, std::set& paths ){ - /* Searches shaders by tags - - char* expression - the XPath expression to search - - returns a set containing the found shaders - */ - - xmlXPathObjectPtr xpathPtr = XpathEval( expression ); - xmlNodeSetPtr nodePtr; - if ( xpathPtr ) { - nodePtr = xpathPtr->nodesetval; - } - else{ - return; - } - - if ( !xmlXPathNodeSetIsEmpty( nodePtr ) ) { - xmlNodePtr ptr; - xmlChar* xmlattrib; - for ( int i = 0; i < nodePtr->nodeNr; i++ ) - { - ptr = nodePtr->nodeTab[i]; - xmlattrib = xmlGetProp( ptr, (xmlChar*)"path" ); - paths.insert( (CopiedString)(char*)xmlattrib ); - } - } - xmlXPathFreeObject( xpathPtr ); -} diff --git a/libs/xml/xmltextags.h b/libs/xml/xmltextags.h deleted file mode 100644 index 7a1bae6..0000000 --- a/libs/xml/xmltextags.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright (C) 2006, Stefan Greven. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XMLTEXTAGS_H ) -#define INCLUDED_XMLTEXTAGS_H - -#include -#include -#include - -#include "iscriplib.h" - -#include -#include - -enum NodeTagType -{ - TAG, - EMPTY -}; - -enum NodeShaderType -{ - SHADER, - TEXTURE -}; - -enum TextureType -{ - STOCK, - CUSTOM -}; - -class XmlTagBuilder -{ -private: -CopiedString m_savefilename; -xmlDocPtr doc; -xmlXPathContextPtr context; -xmlNodeSetPtr nodePtr; - -xmlXPathObjectPtr XpathEval( const char* queryString ){ - xmlChar* expression = (xmlChar*)queryString; - xmlXPathObjectPtr result = xmlXPathEvalExpression( expression, context ); - return result; -}; - -char* GetTagsXpathExpression( char* buffer, const char* shader, NodeTagType nodeTagType ){ - strcpy( buffer, "/root/*/*[@path='" ); - strcat( buffer, shader ); - - switch ( nodeTagType ) - { - case TAG: - strcat( buffer, "']/tag" ); - break; - case EMPTY: - strcat( buffer, "']" ); - }; - - return buffer; -} - -public: -XmlTagBuilder(); -~XmlTagBuilder(); - -bool CreateXmlDocument(); -bool OpenXmlDoc( const char* file, const char* savefile = 0 ); -bool SaveXmlDoc( const char* file ); -bool SaveXmlDoc( void ); -bool AddShaderNode( const char* shader, TextureType textureType, NodeShaderType nodeShaderType ); -bool DeleteShaderNode( const char* shader ); -bool CheckShaderTag( const char* shader ); -bool CheckShaderTag( const char* shader, const char* content ); -bool AddShaderTag( const char* shader, const char* content, NodeTagType nodeTagType ); -bool DeleteTag( const char* tag ); -int RenameShaderTag( const char* oldtag, CopiedString newtag ); -bool DeleteShaderTag( const char* shader, const char* tag ); -void GetShaderTags( const char* shader, std::vector& tags ); -void GetUntagged( std::set& shaders ); -void GetAllTags( std::set& tags ); -void TagSearch( const char* expression, std::set& paths ); -}; - -#endif diff --git a/libs/xml/xmlwriter.h b/libs/xml/xmlwriter.h deleted file mode 100644 index c144646..0000000 --- a/libs/xml/xmlwriter.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XML_XMLWRITER_H ) -#define INCLUDED_XML_XMLWRITER_H - -#include "convert.h" -#include -#include "xml/ixml.h" - -class XMLEntityOutputStream -{ -SingleCharacterOutputStream m_ostream; -public: -XMLEntityOutputStream( TextOutputStream& ostream ) - : m_ostream( ostream ){ -} -void write( const char c ){ - m_ostream.write( c ); -} -void writeEscaped( const char c ){ - switch ( c ) - { - case '<': - write( '&' ); - write( 'l' ); - write( 't' ); - write( ';' ); - break; - case '>': - write( '&' ); - write( 'g' ); - write( 't' ); - write( ';' ); - break; - case '"': - write( '&' ); - write( 'q' ); - write( 'u' ); - write( 'o' ); - write( 't' ); - write( ';' ); - break; - case '&': - write( '&' ); - write( 'a' ); - write( 'm' ); - write( 'p' ); - write( ';' ); - break; - default: - write( c ); - break; - } -} -std::size_t write( const char* buffer, std::size_t length ){ - const char*const end = buffer + length; - for ( const char* p = buffer; p != end; ++p ) - { - writeEscaped( *p ); - } - return length; -} -}; - -template -inline XMLEntityOutputStream& operator<<( XMLEntityOutputStream& ostream, const T& t ){ - return ostream_write( ostream, t ); -} - - -class XMLStreamWriter : public XMLImporter, public XMLAttrVisitor -{ -class state_t -{ -public: -enum EState -{ - eStartElement, - eContent, -}; -state_t() - : m_state( eStartElement ) -{ -} -EState m_state; -}; - -XMLEntityOutputStream m_ostream; -std::vector m_elements; - -void write_cdata( const char* buffer, std::size_t length ){ - m_ostream << StringRange( buffer, buffer + length ); -} -void write_string( const char* string ){ - m_ostream << string; -} -void write_quoted_string( const char* string ){ - m_ostream.write( '"' ); - m_ostream << string; - m_ostream.write( '"' ); -} -public: -XMLStreamWriter( TextOutputStream& ostream ) - : m_ostream( ostream ){ - m_elements.push_back( state_t() ); - m_elements.back().m_state = state_t::eContent; - m_ostream.write( '<' ); - m_ostream.write( '?' ); - write_string( "xml" ); - visit( "version", "1.0" ); - m_ostream.write( '?' ); - m_ostream.write( '>' ); -} - -void pushElement( const XMLElement& element ){ - if ( m_elements.back().m_state == state_t::eStartElement ) { - m_elements.back().m_state = state_t::eContent; - m_ostream.write( '>' ); - } - - m_elements.push_back( state_t() ); - - m_ostream.write( '<' ); - write_string( element.name() ); - element.forEachAttribute( *this ); -} -void popElement( const char* name ){ - if ( m_elements.back().m_state == state_t::eStartElement ) { - m_ostream.write( '/' ); - m_ostream.write( '>' ); - m_elements.pop_back(); - } - else - { - m_ostream.write( '<' ); - m_ostream.write( '/' ); - write_string( name ); - m_ostream.write( '>' ); - m_elements.pop_back(); - } -} -std::size_t write( const char* data, std::size_t length ){ - if ( m_elements.back().m_state == state_t::eStartElement ) { - m_elements.back().m_state = state_t::eContent; - m_ostream.write( '>' ); - } - write_cdata( data, length ); - return length; -} - -void visit( const char* name, const char* value ){ - m_ostream.write( ' ' ); - write_string( name ); - m_ostream.write( '=' ); - write_quoted_string( value ); -} -}; - - -#endif diff --git a/plugins/Makefile b/plugins/Makefile deleted file mode 100644 index 87e9306..0000000 --- a/plugins/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -all: - mkdir -p ../build/plugins - cd archivezip && $(MAKE) - cd archivewad && $(MAKE) - cd archivepak && $(MAKE) - cd entity && $(MAKE) - cd image && $(MAKE) - cd imagehl && $(MAKE) - cd iqmmodel && $(MAKE) - cd mapq3 && $(MAKE) - cd model && $(MAKE) - cd matsys && $(MAKE) - cd shaders && $(MAKE) - cd vfspk3 && $(MAKE) - cd brushexport && $(MAKE) - cd prtview && $(MAKE) -clean: - -rm -rf ../build/plugins - cd archivezip && $(MAKE) clean - cd archivewad && $(MAKE) clean - cd archivepak && $(MAKE) clean - cd entity && $(MAKE) clean - cd image && $(MAKE) clean - cd imagehl && $(MAKE) clean - cd iqmmodel && $(MAKE) clean - cd mapq3 && $(MAKE) clean - cd model && $(MAKE) clean - cd shaders && $(MAKE) clean - cd matsys && $(MAKE) clean - cd vfspk3 && $(MAKE) clean - cd brushexport && $(MAKE) clean - cd prtview && $(MAKE) clean diff --git a/plugins/archivepak/Makefile b/plugins/archivepak/Makefile deleted file mode 100644 index 6d91d7e..0000000 --- a/plugins/archivepak/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# WorldSpawn Plugin Makefile - -LIB_EXT=so -PLUGIN_CFLAGS=$(CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) -shared - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - archive.o plugin.o - -# binary target -../../build/plugins/libarchivepak.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -archive.o: archive.cpp archive.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libarchivepak.$(LIB_EXT) diff --git a/plugins/archivepak/archive.cpp b/plugins/archivepak/archive.cpp deleted file mode 100644 index ee19333..0000000 --- a/plugins/archivepak/archive.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "archive.h" - -#include "idatastream.h" -#include "cmdlib.h" -#include "bytestreamutils.h" -#include -#include "stream/filestream.h" - -#include "iarchive.h" - -#include "archivelib.h" - - -#include -#include "string/string.h" -#include "fs_filesystem.h" - -inline void buffer_findreplace( char* buffer, char find, char replace ){ - while ( *buffer != '\0' ) - { - if ( *buffer == find ) { - *buffer = replace; - } - ++buffer; - } -} - -#include "pak.h" - -class PakArchive : public Archive -{ -class PakRecord -{ -public: -PakRecord( unsigned int position, unsigned int stream_size ) - : m_position( position ), m_stream_size( stream_size ){ -} -unsigned int m_position; -unsigned int m_stream_size; -}; -typedef GenericFileSystem PakFileSystem; -PakFileSystem m_filesystem; -FileInputStream m_pakfile; -CopiedString m_name; - -public: - -PakArchive( const char* name ) - : m_pakfile( name ), m_name( name ){ - if ( !m_pakfile.failed() ) { - pakheader_t header; - - m_pakfile.read( reinterpret_cast( header.magic ), 4 ); - header.diroffset = istream_read_uint32_le( m_pakfile ); - header.dirsize = istream_read_uint32_le( m_pakfile ); - - if ( strncmp( header.magic, "PACK", 4 ) == 0 ) { - m_pakfile.seek( header.diroffset ); - - for ( unsigned int i = 0; i < header.dirsize; i += sizeof( pakentry_t ) ) - { - pakentry_t entry; - - m_pakfile.read( reinterpret_cast( entry.filename ), 0x38 ); - entry.offset = istream_read_uint32_le( m_pakfile ); - entry.size = istream_read_uint32_le( m_pakfile ); - - buffer_findreplace( entry.filename, '\\', '/' ); - - PakFileSystem::entry_type& file = m_filesystem[entry.filename]; - if ( !file.is_directory() ) { - globalOutputStream() << "Warning: pak archive " << makeQuoted( m_name.c_str() ) << " contains duplicated file: " << makeQuoted( entry.filename ) << "\n"; - } - else - { - file = new PakRecord( entry.offset, entry.size ); - } - } - } - } -} - -~PakArchive(){ - for ( PakFileSystem::iterator i = m_filesystem.begin(); i != m_filesystem.end(); ++i ) - delete i->second.file(); -} - -void release(){ - delete this; -} -ArchiveFile* openFile( const char* name ){ - PakFileSystem::iterator i = m_filesystem.find( name ); - if ( i != m_filesystem.end() && !i->second.is_directory() ) { - PakRecord* file = i->second.file(); - return StoredArchiveFile::create( name, m_name.c_str(), file->m_position, file->m_stream_size, file->m_stream_size ); - } - return 0; -} -virtual ArchiveTextFile* openTextFile( const char* name ){ - PakFileSystem::iterator i = m_filesystem.find( name ); - if ( i != m_filesystem.end() && !i->second.is_directory() ) { - PakRecord* file = i->second.file(); - return StoredArchiveTextFile::create( name, m_name.c_str(), file->m_position, file->m_stream_size ); - } - return 0; -} -bool containsFile( const char* name ){ - PakFileSystem::iterator i = m_filesystem.find( name ); - return i != m_filesystem.end() && !i->second.is_directory(); -} -void forEachFile( VisitorFunc visitor, const char* root ){ - m_filesystem.traverse( visitor, root ); -} -}; - - -Archive* OpenArchive( const char* name ){ - return new PakArchive( name ); -} - -#if 0 - -class TestArchive -{ -public: -TestArchive(){ - Archive* archive = OpenArchive( "c:/quake3/baseq3/pak0.pak" ); - ArchiveFile* file = archive->openFile( "gfx/palette.lmp" ); - if ( file != 0 ) { - char buffer[1024]; - file->getInputStream().read( (InputStream::byte_type*)buffer, 1024 ); - file->release(); - } - archive->release(); -} -}; - -TestArchive g_test; - -#endif - -#if 0 - -class TestArchive -{ -class TestVisitor : public Archive::IVisitor -{ -public: -void visit( const char* name ){ - int bleh = 0; -} -}; -public: -TestArchive(){ - { - Archive* archive = OpenArchive( "" ); - archive->release(); - } - { - Archive* archive = OpenArchive( "NONEXISTANTFILE" ); - archive->release(); - } - { - Archive* archive = OpenArchive( "c:/quake/id1/pak0.pak" ); - ArchiveFile* file = archive->openFile( "gfx/palette.lmp" ); - if ( file != 0 ) { - char buffer[1024]; - file->getInputStream().read( (InputStream::byte_type*)buffer, 1024 ); - file->release(); - } - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 0 ), "progs/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 0 ), "maps/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 1 ), "sound/ambience/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "sound/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eDirectories, 1 ), "sound/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 2 ), "sound/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 2 ), "" ); - archive->release(); - } -} -}; - -TestArchive g_test; - -#endif diff --git a/plugins/archivepak/archive.h b/plugins/archivepak/archive.h deleted file mode 100644 index 309cef5..0000000 --- a/plugins/archivepak/archive.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -class Archive; -Archive* OpenArchive( const char* name ); diff --git a/plugins/archivepak/pak.h b/plugins/archivepak/pak.h deleted file mode 100644 index 2205156..0000000 --- a/plugins/archivepak/pak.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PAK_H ) -#define INCLUDED_PAK_H - -struct pakheader_t -{ - char magic[4]; // Name of the new WAD format ("PACK") - unsigned int diroffset; // Position of WAD directory from start of file - unsigned int dirsize; // Number of entries * 0x40 (64 char) -}; - -struct pakentry_t -{ - char filename[0x38]; // Name of the file, Unix style, with extension, 50 chars, padded with '\0'. - unsigned int offset; // Position of the entry in PACK file - unsigned int size; // Size of the entry in PACK file -}; - -#endif diff --git a/plugins/archivepak/plugin.cpp b/plugins/archivepak/plugin.cpp deleted file mode 100644 index 489af0b..0000000 --- a/plugins/archivepak/plugin.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iarchive.h" - -#include "debugging/debugging.h" -#include "modulesystem/singletonmodule.h" - -#include "archive.h" - -class ArchivePakAPI -{ -_QERArchiveTable m_archivepak; -public: -typedef _QERArchiveTable Type; -STRING_CONSTANT( Name, "pak" ); - -ArchivePakAPI(){ - m_archivepak.m_pfnOpenArchive = &OpenArchive; -} -_QERArchiveTable* getTable(){ - return &m_archivepak; -} -}; - -typedef SingletonModule ArchivePakModule; - -ArchivePakModule g_ArchivePakModule; - - -extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){ - initialiseModule( server ); - - g_ArchivePakModule.selfRegister(); -} diff --git a/plugins/archivewad/Makefile b/plugins/archivewad/Makefile deleted file mode 100644 index ab561ba..0000000 --- a/plugins/archivewad/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# WorldSpawn Plugin Makefile - -PLUGIN_CFLAGS=$(CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - archive.o plugin.o - -# binary target -../../build/plugins/libarchivewad.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -archive.o: archive.cpp archive.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libarchivewad.$(LIB_EXT) diff --git a/plugins/archivewad/archive.cpp b/plugins/archivewad/archive.cpp deleted file mode 100644 index 357f9cd..0000000 --- a/plugins/archivewad/archive.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "archive.h" - -#include "idatastream.h" -#include "bytestreamutils.h" -#include -#include "stream/filestream.h" - -#include "iarchive.h" - -#include "archivelib.h" - - -#include -#include "string/string.h" - -#include "wad.h" - -class WadArchive final : public Archive -{ - class wad_record_t - { - public: - wad_record_t( unsigned int position, unsigned int stream_size, unsigned int file_size ) - : m_position( position ), m_stream_size( stream_size ), m_file_size( file_size ) - {} - unsigned int m_position; - unsigned int m_stream_size; - unsigned int m_file_size; - }; - - enum EWadVersion - { - eNotValid, - eWAD2, - eWAD3, - }; - - typedef std::map files_t; - files_t m_files; - CopiedString m_name; - FileInputStream m_wadfile; - - EWadVersion wad_version( const char* identification ){ - if ( strncmp( identification, "WAD2", 4 ) == 0 ) { - return eWAD2; - } - if ( strncmp( identification, "WAD3", 4 ) == 0 ) { - return eWAD3; - } - return eNotValid; - } - - const char* type_for_version( EWadVersion version ){ - switch ( version ) - { - case eWAD2: - return ".mip"; - case eWAD3: - return ".hlw"; - default: - break; - } - return ""; - } - - int miptex_type_for_version( EWadVersion version ){ - switch ( version ) - { - case eWAD2: - return TYP_MIPTEX; - case eWAD3: - return 67; - default: - break; - } - return -1; - } - -public: - WadArchive( const char* name ) - : m_name( name ), m_wadfile( name ){ - if ( !m_wadfile.failed() ) { - wadinfo_t wadinfo; - istream_read_wadinfo( m_wadfile, wadinfo ); - - EWadVersion version = wad_version( wadinfo.identification ); - int miptexType = miptex_type_for_version( version ); - - if ( version != eNotValid ) { - m_wadfile.seek( wadinfo.infotableofs ); - - for ( int i = 0; i < wadinfo.numlumps; ++i ) - { - char buffer[32]; - lumpinfo_t lumpinfo; - istream_read_lumpinfo( m_wadfile, lumpinfo ); - if ( lumpinfo.type == miptexType ) { - strcpy( buffer, "textures/" ); - strcat( buffer, lumpinfo.name ); - strcat( buffer, type_for_version( version ) ); - m_files.insert( files_t::value_type( buffer, wad_record_t( lumpinfo.filepos, lumpinfo.disksize, lumpinfo.size ) ) ); - } - } - } - } - } - - void release(){ - delete this; - } - ArchiveFile* openFile( const char* name ){ - files_t::iterator i = m_files.find( name ); - if ( i != m_files.end() ) { - return StoredArchiveFile::create( name, m_name.c_str(), i->second.m_position, i->second.m_stream_size, i->second.m_file_size ); - } - return 0; - } - virtual ArchiveTextFile* openTextFile( const char* name ){ - files_t::iterator i = m_files.find( name ); - if ( i != m_files.end() ) { - return StoredArchiveTextFile::create( name, m_name.c_str(), i->second.m_position, i->second.m_stream_size ); - } - return 0; - } - bool containsFile( const char* name ){ - return m_files.find( name ) != m_files.end(); - } - void forEachFile( VisitorFunc visitor, const char* root ){ - if ( root[0] == '\0' ) { - if ( visitor.directory( "textures/", 1 ) ) { - return; - } - } - else if ( strcmp( root, "textures/" ) != 0 ) { - return; - } - - for ( files_t::iterator i = m_files.begin(); i != m_files.end(); ++i ) - visitor.file( i->first.c_str() ); - } -}; - - -Archive* OpenArchive( const char* name ){ - return new WadArchive( name ); -} - -#if 0 - -class TestArchive -{ - class TestVisitor : public Archive::IVisitor - { - public: - void visit( const char* name ){ - int bleh = 0; - } - }; -public: - TestArchive(){ - { - Archive* archive = OpenArchive( "" ); - archive->release(); - } - { - Archive* archive = OpenArchive( "NONEXISTANTFILE" ); - archive->release(); - } - { - Archive* archive = OpenArchive( "c:/quake/id1/quake101.wad" ); - ArchiveFile* file = archive->openFile( "textures/sky1.mip" ); - if ( file != 0 ) { - unsigned char* buffer = new unsigned char[file->size()]; - file->getInputStream().read( (InputStream::byte_type*)buffer, file->size() ); - delete[] buffer; - file->release(); - } - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "textures/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "textures/" ); - archive->release(); - } - } -}; - -TestArchive g_test; - -#endif diff --git a/plugins/archivewad/archive.h b/plugins/archivewad/archive.h deleted file mode 100644 index 309cef5..0000000 --- a/plugins/archivewad/archive.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -class Archive; -Archive* OpenArchive( const char* name ); diff --git a/plugins/archivewad/plugin.cpp b/plugins/archivewad/plugin.cpp deleted file mode 100644 index 66d0fed..0000000 --- a/plugins/archivewad/plugin.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iarchive.h" - -#include "debugging/debugging.h" -#include "modulesystem/singletonmodule.h" - -#include "archive.h" - -class ArchiveWadAPI -{ - _QERArchiveTable m_archivewad; -public: - typedef _QERArchiveTable Type; - STRING_CONSTANT( Name, "wad" ); - - ArchiveWadAPI(){ - m_archivewad.m_pfnOpenArchive = &OpenArchive; - } - _QERArchiveTable* getTable(){ - return &m_archivewad; - } -}; - -typedef SingletonModule ArchiveWadModule; - -ArchiveWadModule g_ArchiveWadModule; - - -extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){ - initialiseModule( server ); - - g_ArchiveWadModule.selfRegister(); -} diff --git a/plugins/archivewad/wad.h b/plugins/archivewad/wad.h deleted file mode 100644 index 617900c..0000000 --- a/plugins/archivewad/wad.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_WAD_H ) -#define INCLUDED_WAD_H - -#include "bytestreamutils.h" -#include "idatastream.h" - -#define CMP_NONE 0 -#define CMP_LZSS 1 - -#define TYP_NONE 0 -#define TYP_LABEL 1 - -#define TYP_LUMPY 64 // 64 + grab command number -#define TYP_PALETTE 64 -#define TYP_QTEX 65 -#define TYP_QPIC 66 -#define TYP_SOUND 67 -#define TYP_MIPTEX 68 - -typedef struct -{ - char identification[4]; // should be WAD2 or 2DAW - int numlumps; - int infotableofs; -} wadinfo_t; - -typedef struct -{ - int filepos; - int disksize; - int size; // uncompressed - char type; - char compression; - char pad1, pad2; - char name[16]; // must be null terminated -} lumpinfo_t; - -inline void istream_read_wadinfo( InputStream& istream, wadinfo_t& wadinfo ){ - istream.read( reinterpret_cast( wadinfo.identification ), 4 ); - wadinfo.numlumps = istream_read_int32_le( istream ); - wadinfo.infotableofs = istream_read_int32_le( istream ); -} - -inline void istream_read_lumpinfo( InputStream& istream, lumpinfo_t& lumpinfo ){ - lumpinfo.filepos = istream_read_int32_le( istream ); - lumpinfo.disksize = istream_read_int32_le( istream ); - lumpinfo.size = istream_read_int32_le( istream ); - lumpinfo.type = istream_read_byte( istream ); - lumpinfo.compression = istream_read_byte( istream ); - lumpinfo.pad1 = istream_read_byte( istream ); - lumpinfo.pad2 = istream_read_byte( istream ); - istream.read( reinterpret_cast( lumpinfo.name ), 16 ); -} - -#endif diff --git a/plugins/archivezip/Makefile b/plugins/archivezip/Makefile deleted file mode 100644 index 430807c..0000000 --- a/plugins/archivezip/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# WorldSpawn Plugin Makefile - -ZLIB_LDFLAGS=$(shell pkg-config --libs zlib) - -PLUGIN_CFLAGS=$(CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) -shared $(ZLIB_LDFLAGS) -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - archive.o plugin.o - -# binary target -../../build/plugins/libarchivezip.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -archive.o: archive.cpp archive.h -plugin.o: plugin.cpp zlibstream.h - -clean: - -rm -f *.o ../../build/plugins/libarchivezip.$(LIB_EXT) diff --git a/plugins/archivezip/archive.cpp b/plugins/archivezip/archive.cpp deleted file mode 100644 index d7be70d..0000000 --- a/plugins/archivezip/archive.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "idatastream.h" -#include "cmdlib.h" -#include "bytestreamutils.h" - -#include "modulesystem.h" -#include "iarchive.h" - -#include -#include "stream/filestream.h" -#include "container/array.h" -#include "archivelib.h" -#include "zlibstream.h" - -class DeflatedArchiveFile : public ArchiveFile { -CopiedString m_name; -FileInputStream m_istream; -SubFileInputStream m_substream; -DeflatedInputStream m_zipstream; -FileInputStream::size_type m_size; -public: -typedef FileInputStream::size_type size_type; -typedef FileInputStream::position_type position_type; - -DeflatedArchiveFile(const char *name, const char *archiveName, position_type position, size_type stream_size, - size_type file_size) - : m_name(name), m_istream(archiveName), m_substream(m_istream, position, stream_size), - m_zipstream(m_substream), m_size(file_size) -{ -} - -void release() -{ - delete this; -} - -size_type size() const -{ - return m_size; -} - -const char *getName() const -{ - return m_name.c_str(); -} - -InputStream &getInputStream() -{ - return m_zipstream; -} -}; - -class DeflatedArchiveTextFile : public ArchiveTextFile { -CopiedString m_name; -FileInputStream m_istream; -SubFileInputStream m_substream; -DeflatedInputStream m_zipstream; -BinaryToTextInputStream m_textStream; -public: -typedef FileInputStream::size_type size_type; -typedef FileInputStream::position_type position_type; - -DeflatedArchiveTextFile(const char *name, const char *archiveName, position_type position, size_type stream_size) - : m_name(name), m_istream(archiveName), m_substream(m_istream, position, stream_size), - m_zipstream(m_substream), m_textStream(m_zipstream) -{ -} - -void release() -{ - delete this; -} - -TextInputStream &getInputStream() -{ - return m_textStream; -} -}; - -#include "pkzip.h" - -#include -#include "string/string.h" -#include "fs_filesystem.h" - - -class ZipArchive : public Archive { -class ZipRecord { -public: -enum ECompressionMode { - eStored, - eDeflated, -}; - -ZipRecord(unsigned int position, unsigned int compressed_size, unsigned int uncompressed_size, - ECompressionMode mode) - : m_position(position), m_stream_size(compressed_size), m_file_size(uncompressed_size), m_mode(mode) -{ -} - -unsigned int m_position; -unsigned int m_stream_size; -unsigned int m_file_size; -ECompressionMode m_mode; -}; - -typedef GenericFileSystem ZipFileSystem; -ZipFileSystem m_filesystem; -CopiedString m_name; -FileInputStream m_istream; - -bool read_record() -{ - zip_magic magic; - istream_read_zip_magic(m_istream, magic); - if (!(magic == zip_root_dirent_magic)) { - return false; - } - zip_version version_encoder; - istream_read_zip_version(m_istream, version_encoder); - zip_version version_extract; - istream_read_zip_version(m_istream, version_extract); - //unsigned short flags = - istream_read_int16_le(m_istream); - unsigned short compression_mode = istream_read_int16_le(m_istream); - if (compression_mode != Z_DEFLATED && compression_mode != 0) { - return false; - } - zip_dostime dostime; - istream_read_zip_dostime(m_istream, dostime); - //unsigned int crc32 = - istream_read_int32_le(m_istream); - unsigned int compressed_size = istream_read_uint32_le(m_istream); - unsigned int uncompressed_size = istream_read_uint32_le(m_istream); - unsigned int namelength = istream_read_uint16_le(m_istream); - unsigned short extras = istream_read_uint16_le(m_istream); - unsigned short comment = istream_read_uint16_le(m_istream); - //unsigned short diskstart = - istream_read_int16_le(m_istream); - //unsigned short filetype = - istream_read_int16_le(m_istream); - //unsigned int filemode = - istream_read_int32_le(m_istream); - unsigned int position = istream_read_int32_le(m_istream); - - Array filename(namelength + 1); - m_istream.read(reinterpret_cast( filename.data()), namelength); - filename[namelength] = '\0'; - - m_istream.seek(extras + comment, FileInputStream::cur); - - if (path_is_directory(filename.data())) { - m_filesystem[filename.data()] = 0; - } else { - ZipFileSystem::entry_type &file = m_filesystem[filename.data()]; - if (!file.is_directory()) { - globalOutputStream() << "Warning: zip archive " << makeQuoted(m_name.c_str()) - << " contains duplicated file: " << makeQuoted(filename.data()) << "\n"; - } else { - file = new ZipRecord(position, compressed_size, uncompressed_size, - (compression_mode == Z_DEFLATED) ? ZipRecord::eDeflated : ZipRecord::eStored); - } - } - - return true; -} - -bool read_pkzip() -{ - SeekableStream::position_type pos = pkzip_find_disk_trailer(m_istream); - if (pos != 0) { - zip_disk_trailer disk_trailer; - m_istream.seek(pos); - istream_read_zip_disk_trailer(m_istream, disk_trailer); - if (!(disk_trailer.z_magic == zip_disk_trailer_magic)) { - return false; - } - - m_istream.seek(disk_trailer.z_rootseek); - for (unsigned int i = 0; i < disk_trailer.z_entries; ++i) { - if (!read_record()) { - return false; - } - } - return true; - } - return false; -} - -public: -ZipArchive(const char *name) - : m_name(name), m_istream(name) -{ - if (!m_istream.failed()) { - if (!read_pkzip()) { - globalErrorStream() << "ERROR: invalid zip-file " << makeQuoted(name) << '\n'; - } - } -} - -~ZipArchive() -{ - for (ZipFileSystem::iterator i = m_filesystem.begin(); i != m_filesystem.end(); ++i) { - delete i->second.file(); - } -} - -bool failed() -{ - return m_istream.failed(); -} - -void release() -{ - delete this; -} - -ArchiveFile *openFile(const char *name) -{ - ZipFileSystem::iterator i = m_filesystem.find(name); - if (i != m_filesystem.end() && !i->second.is_directory()) { - ZipRecord *file = i->second.file(); - - m_istream.seek(file->m_position); - zip_file_header file_header; - istream_read_zip_file_header(m_istream, file_header); - if (file_header.z_magic != zip_file_header_magic) { - globalErrorStream() << "error reading zip file " << makeQuoted(m_name.c_str()); - return 0; - } - - switch (file->m_mode) { - case ZipRecord::eStored: - return StoredArchiveFile::create(name, m_name.c_str(), m_istream.tell(), file->m_stream_size, - file->m_file_size); - case ZipRecord::eDeflated: - return new DeflatedArchiveFile(name, m_name.c_str(), m_istream.tell(), file->m_stream_size, - file->m_file_size); - } - } - return 0; -} - -ArchiveTextFile *openTextFile(const char *name) -{ - ZipFileSystem::iterator i = m_filesystem.find(name); - if (i != m_filesystem.end() && !i->second.is_directory()) { - ZipRecord *file = i->second.file(); - - m_istream.seek(file->m_position); - zip_file_header file_header; - istream_read_zip_file_header(m_istream, file_header); - if (file_header.z_magic != zip_file_header_magic) { - globalErrorStream() << "error reading zip file " << makeQuoted(m_name.c_str()); - return 0; - } - - switch (file->m_mode) { - case ZipRecord::eStored: - return StoredArchiveTextFile::create(name, m_name.c_str(), m_istream.tell(), file->m_stream_size); - case ZipRecord::eDeflated: - return new DeflatedArchiveTextFile(name, m_name.c_str(), m_istream.tell(), file->m_stream_size); - } - } - return 0; -} - -bool containsFile(const char *name) -{ - ZipFileSystem::iterator i = m_filesystem.find(name); - return i != m_filesystem.end() && !i->second.is_directory(); -} - -void forEachFile(VisitorFunc visitor, const char *root) -{ - m_filesystem.traverse(visitor, root); -} -}; - -Archive *OpenArchive(const char *name) -{ - return new ZipArchive(name); -} - -#if 0 - -class TestZip -{ -class TestVisitor : public Archive::IVisitor -{ -public: -void visit( const char* name ){ - int bleh = 0; -} -}; -public: -TestZip(){ - testzip( "c:/quake3/baseq3/mapmedia.pk3", "textures/radiant/notex.tga" ); -} - -void testzip( const char* name, const char* filename ){ - Archive* archive = OpenArchive( name ); - ArchiveFile* file = archive->openFile( filename ); - if ( file != 0 ) { - unsigned char buffer[4096]; - std::size_t count = file->getInputStream().read( (InputStream::byte_type*)buffer, 4096 ); - file->release(); - } - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 1 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eDirectories, 1 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "textures" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "textures/" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 2 ), "" ); - archive->release(); -} -}; - -TestZip g_TestZip; - -#endif diff --git a/plugins/archivezip/archive.h b/plugins/archivezip/archive.h deleted file mode 100644 index 95f64d9..0000000 --- a/plugins/archivezip/archive.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -Archive *OpenArchive(const char *name); diff --git a/plugins/archivezip/pkzip.h b/plugins/archivezip/pkzip.h deleted file mode 100644 index 296d15f..0000000 --- a/plugins/archivezip/pkzip.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PKZIP_H ) -#define INCLUDED_PKZIP_H - -#include "bytestreamutils.h" -#include "idatastream.h" -#include - -class zip_magic { -public: -bool operator==(const zip_magic &other) const -{ - return m_value[0] == other.m_value[0] - && m_value[1] == other.m_value[1] - && m_value[2] == other.m_value[2] - && m_value[3] == other.m_value[3]; -} - -bool operator!=(const zip_magic &other) const -{ - return !(*this == other); -} - -char m_value[4]; -}; - -inline void istream_read_zip_magic(InputStream &istream, zip_magic &magic) -{ - istream.read(reinterpret_cast( magic.m_value ), 4); -} - -struct zip_version { - char version; - char ostype; -}; - -inline void istream_read_zip_version(InputStream &istream, zip_version &version) -{ - version.version = istream_read_byte(istream); - version.ostype = istream_read_byte(istream); -} - -struct zip_dostime { - unsigned short time; - unsigned short date; -}; - -inline void istream_read_zip_dostime(InputStream &istream, zip_dostime &dostime) -{ - dostime.time = istream_read_int16_le(istream); - dostime.date = istream_read_int16_le(istream); -} - -const zip_magic zip_file_header_magic = {{'P', 'K', 0x03, 0x04}}; - -/* A. Local file header */ -struct zip_file_header { - zip_magic z_magic; /* local file header signature (0x04034b50) */ - zip_version z_extract; /* version needed to extract */ - unsigned short z_flags; /* general purpose bit flag */ - unsigned short z_compr; /* compression method */ - zip_dostime z_dostime; /* last mod file time (dos format) */ - unsigned int z_crc32; /* crc-32 */ - unsigned int z_csize; /* compressed size */ - unsigned int z_usize; /* uncompressed size */ - unsigned short z_namlen; /* filename length (null if stdin) */ - unsigned short z_extras; /* extra field length */ - /* followed by filename (of variable size) */ - /* followed by extra field (of variable size) */ -}; - -inline void istream_read_zip_file_header(SeekableInputStream &istream, zip_file_header &file_header) -{ - istream_read_zip_magic(istream, file_header.z_magic); - istream_read_zip_version(istream, file_header.z_extract); - file_header.z_flags = istream_read_uint16_le(istream); - file_header.z_compr = istream_read_uint16_le(istream); - istream_read_zip_dostime(istream, file_header.z_dostime); - file_header.z_crc32 = istream_read_uint32_le(istream); - file_header.z_csize = istream_read_uint32_le(istream); - file_header.z_usize = istream_read_uint32_le(istream); - file_header.z_namlen = istream_read_uint16_le(istream); - file_header.z_extras = istream_read_uint16_le(istream); - istream.seek(file_header.z_namlen + file_header.z_extras, SeekableInputStream::cur); -} - -/* B. data descriptor - * the data descriptor exists only if bit 3 of z_flags is set. It is byte aligned - * and immediately follows the last byte of compressed data. It is only used if - * the output media of the compressor was not seekable, eg. standard output. - */ -const zip_magic zip_file_trailer_magic = {{'P', 'K', 0x07, 0x08}}; - -struct zip_file_trailer { - zip_magic z_magic; - unsigned int z_crc32; /* crc-32 */ - unsigned int z_csize; /* compressed size */ - unsigned int z_usize; /* uncompressed size */ -}; - -inline void istream_read_zip_file_trailer(InputStream &istream, zip_file_trailer &file_trailer) -{ - istream_read_zip_magic(istream, file_trailer.z_magic); - file_trailer.z_crc32 = istream_read_uint32_le(istream); - file_trailer.z_csize = istream_read_uint32_le(istream); - file_trailer.z_usize = istream_read_uint32_le(istream); -} - - -/* C. central directory structure: - [file header] . . . end of central dir record - */ - -/* directory file header - * - a single entry including filename, extras and comment may not exceed 64k. - */ - -const zip_magic zip_root_dirent_magic = {{'P', 'K', 0x01, 0x02}}; - -struct zip_root_dirent { - zip_magic z_magic; - zip_version z_encoder; /* version made by */ - zip_version z_extract; /* version need to extract */ - unsigned short z_flags; /* general purpose bit flag */ - unsigned short z_compr; /* compression method */ - zip_dostime z_dostime; /* last mod file time&date (dos format) */ - unsigned int z_crc32; /* crc-32 */ - unsigned int z_csize; /* compressed size */ - unsigned int z_usize; /* uncompressed size */ - unsigned short z_namlen; /* filename length (null if stdin) */ - unsigned short z_extras; /* extra field length */ - unsigned short z_comment; /* file comment length */ - unsigned short z_diskstart; /* disk number of start (if spanning zip over multiple disks) */ - unsigned short z_filetype; /* internal file attributes, bit0 = ascii */ - unsigned int z_filemode; /* extrnal file attributes, eg. msdos attrib byte */ - unsigned int z_off; /* relative offset of local file header, seekval if singledisk */ - /* followed by filename (of variable size) */ - /* followed by extra field (of variable size) */ - /* followed by file comment (of variable size) */ -}; - -inline void istream_read_zip_root_dirent(SeekableInputStream &istream, zip_root_dirent &root_dirent) -{ - istream_read_zip_magic(istream, root_dirent.z_magic); - istream_read_zip_version(istream, root_dirent.z_encoder); - istream_read_zip_version(istream, root_dirent.z_extract); - root_dirent.z_flags = istream_read_uint16_le(istream); - root_dirent.z_compr = istream_read_uint16_le(istream); - istream_read_zip_dostime(istream, root_dirent.z_dostime); - root_dirent.z_crc32 = istream_read_uint32_le(istream); - root_dirent.z_csize = istream_read_uint32_le(istream); - root_dirent.z_usize = istream_read_uint32_le(istream); - root_dirent.z_namlen = istream_read_uint16_le(istream); - root_dirent.z_extras = istream_read_uint16_le(istream); - root_dirent.z_comment = istream_read_uint16_le(istream); - root_dirent.z_diskstart = istream_read_uint16_le(istream); - root_dirent.z_filetype = istream_read_uint16_le(istream); - root_dirent.z_filemode = istream_read_uint32_le(istream); - root_dirent.z_off = istream_read_uint32_le(istream); - istream.seek(root_dirent.z_namlen + root_dirent.z_extras + root_dirent.z_comment, SeekableInputStream::cur); -} - -/* end of central dir record */ -const zip_magic zip_disk_trailer_magic = {{'P', 'K', 0x05, 0x06}}; -const unsigned int disk_trailer_length = 22; -struct zip_disk_trailer { - zip_magic z_magic; - unsigned short z_disk; /* number of this disk */ - unsigned short z_finaldisk; /* number of the disk with the start of the central dir */ - unsigned short z_entries; /* total number of entries in the central dir on this disk */ - unsigned short z_finalentries; /* total number of entries in the central dir */ - unsigned int z_rootsize; /* size of the central directory */ - unsigned int z_rootseek; /* offset of start of central directory with respect to * - * the starting disk number */ - unsigned short z_comment; /* zipfile comment length */ - /* followed by zipfile comment (of variable size) */ -}; - -inline void istream_read_zip_disk_trailer(SeekableInputStream &istream, zip_disk_trailer &disk_trailer) -{ - istream_read_zip_magic(istream, disk_trailer.z_magic); - disk_trailer.z_disk = istream_read_uint16_le(istream); - disk_trailer.z_finaldisk = istream_read_uint16_le(istream); - disk_trailer.z_entries = istream_read_uint16_le(istream); - disk_trailer.z_finalentries = istream_read_uint16_le(istream); - disk_trailer.z_rootsize = istream_read_uint32_le(istream); - disk_trailer.z_rootseek = istream_read_uint32_le(istream); - disk_trailer.z_comment = istream_read_uint16_le(istream); - istream.seek(disk_trailer.z_comment, SeekableInputStream::cur); -} - -inline SeekableStream::position_type pkzip_find_disk_trailer(SeekableInputStream &istream) -{ - istream.seek(0, SeekableInputStream::end); - SeekableStream::position_type start_position = istream.tell(); - if (start_position < disk_trailer_length) { - return 0; - } - start_position -= disk_trailer_length; - - zip_magic magic; - istream.seek(start_position); - istream_read_zip_magic(istream, magic); - - if (magic == zip_disk_trailer_magic) { - return start_position; - } else { - const SeekableStream::position_type max_comment = 0x10000; - const SeekableStream::position_type bufshift = 6; - const SeekableStream::position_type bufsize = max_comment >> bufshift; - unsigned char buffer[bufsize]; - - SeekableStream::position_type search_end = (max_comment < start_position) ? start_position - max_comment : 0; - SeekableStream::position_type position = start_position; - while (position != search_end) { - StreamBase::size_type to_read = std::min(bufsize, position - search_end); - position -= to_read; - - istream.seek(position); - StreamBase::size_type size = istream.read(buffer, to_read); - - unsigned char *p = buffer + size; - while (p != buffer) { - --p; - magic.m_value[3] = magic.m_value[2]; - magic.m_value[2] = magic.m_value[1]; - magic.m_value[1] = magic.m_value[0]; - magic.m_value[0] = *p; - if (magic == zip_disk_trailer_magic) { - return position + (p - buffer); - } - } - } - return 0; - } -} - -#endif diff --git a/plugins/archivezip/plugin.cpp b/plugins/archivezip/plugin.cpp deleted file mode 100644 index 8e619d9..0000000 --- a/plugins/archivezip/plugin.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iarchive.h" - -#include "debugging/debugging.h" -#include "modulesystem/singletonmodule.h" - -#include "archive.h" - - -class ArchiveZipAPI { -_QERArchiveTable m_archivezip; -public: -typedef _QERArchiveTable Type; - -STRING_CONSTANT(Name, "pk3"); - -ArchiveZipAPI() -{ - m_archivezip.m_pfnOpenArchive = &OpenArchive; -} - -_QERArchiveTable *getTable() -{ - return &m_archivezip; -} -}; - -typedef SingletonModule ArchiveZipModule; - -ArchiveZipModule g_ArchiveZipModule; - - -class ArchivePK4API { -_QERArchiveTable m_archivepk4; -public: -typedef _QERArchiveTable Type; - -STRING_CONSTANT(Name, "pk4"); - -ArchivePK4API() -{ - m_archivepk4.m_pfnOpenArchive = &OpenArchive; -} - -_QERArchiveTable *getTable() -{ - return &m_archivepk4; -} -}; - -typedef SingletonModule ArchivePK4Module; - -ArchivePK4Module g_ArchivePK4Module; - - -class ArchiveDPKAPI { -_QERArchiveTable m_archivedpk; -public: -typedef _QERArchiveTable Type; - -STRING_CONSTANT(Name, "dpk"); - -ArchiveDPKAPI() -{ - m_archivedpk.m_pfnOpenArchive = &OpenArchive; -} - -_QERArchiveTable *getTable() -{ - return &m_archivedpk; -} -}; - -typedef SingletonModule ArchiveDPKModule; - -ArchiveDPKModule g_ArchiveDPKModule; - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_ArchiveZipModule.selfRegister(); - g_ArchivePK4Module.selfRegister(); - g_ArchiveDPKModule.selfRegister(); -} diff --git a/plugins/archivezip/zlibstream.h b/plugins/archivezip/zlibstream.h deleted file mode 100644 index 3761462..0000000 --- a/plugins/archivezip/zlibstream.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ZLIBSTREAM_H ) -#define INCLUDED_ZLIBSTREAM_H - -#include "zlib.h" -#include "idatastream.h" - -/// \brief A wrapper around an InputStream of data compressed with the zlib deflate algorithm. -/// -/// - Uses z_stream to decompress the data stream on the fly. -/// - Uses a buffer to reduce the number of times the wrapped stream must be read. -class DeflatedInputStream : public InputStream { -InputStream &m_istream; -z_stream m_zipstream; -enum unnamed0 { m_bufsize = 1024 }; -unsigned char m_buffer[m_bufsize]; - -public: -DeflatedInputStream(InputStream &istream) - : m_istream(istream) -{ - m_zipstream.zalloc = 0; - m_zipstream.zfree = 0; - m_zipstream.opaque = 0; - m_zipstream.avail_in = 0; - inflateInit2(&m_zipstream, -MAX_WBITS); -} - -~DeflatedInputStream() -{ - inflateEnd(&m_zipstream); -} - -size_type read(byte_type *buffer, size_type length) -{ - m_zipstream.next_out = buffer; - m_zipstream.avail_out = static_cast( length ); - while (m_zipstream.avail_out != 0) { - if (m_zipstream.avail_in == 0) { - m_zipstream.next_in = m_buffer; - m_zipstream.avail_in = static_cast( m_istream.read(m_buffer, m_bufsize)); - } - if (inflate(&m_zipstream, Z_SYNC_FLUSH) != Z_OK) { - break; - } - } - return length - m_zipstream.avail_out; -} -}; - -#endif diff --git a/plugins/brushexport/Makefile b/plugins/brushexport/Makefile deleted file mode 100644 index 115dbcb..0000000 --- a/plugins/brushexport/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# WorldSpawn Plugin Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - callbacks.o export.o interface.o plugin.o support.o - -# binary target -../../build/plugins/libbrushexport.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libuilib.a ../../libs/libgtkutil.a $(PLUGIN_LDFLAGS) - -# object files -callbacks.o: callbacks.cpp callbacks.h -export.o: export.cpp export.h -interface.o: interface.cpp -plugin.o: plugin.cpp plugin.h -support.o: support.cpp support.h - -clean: - -rm -f *.o ../../build/plugins/libbrushexport.$(LIB_EXT) diff --git a/plugins/brushexport/callbacks.cpp b/plugins/brushexport/callbacks.cpp deleted file mode 100644 index d21ec5a..0000000 --- a/plugins/brushexport/callbacks.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include -#include -#include - -#include "qerplugin.h" -#include "debugging/debugging.h" -#include "support.h" -#include "export.h" - -// stuff from interface.cpp -void DestroyWindow(); - - -namespace callbacks { - -void OnDestroy(ui::Widget w, gpointer data) -{ - DestroyWindow(); -} - -void OnExportClicked(ui::Button button, gpointer user_data) -{ - auto window = ui::Window::from(lookup_widget(button, "w_plugplug2")); - ASSERT_TRUE(window); - const char *cpath = GlobalRadiant().m_pfnFileDialog(window, false, "Save as Obj", 0, 0, false, false, true); - if (!cpath) { - return; - } - - std::string path(cpath); - - // get ignore list from ui - std::set ignore; - - auto view = ui::TreeView::from(lookup_widget(button, "t_materialist")); - ui::ListStore list = ui::ListStore::from(gtk_tree_view_get_model(view)); - - GtkTreeIter iter; - gboolean valid = gtk_tree_model_get_iter_first(list, &iter); - while (valid) { - gchar *data; - gtk_tree_model_get(list, &iter, 0, &data, -1); - globalOutputStream() << data << "\n"; - ignore.insert(std::string(data)); - g_free(data); - valid = gtk_tree_model_iter_next(list, &iter); - } - - for (std::set::iterator it(ignore.begin()); it != ignore.end(); ++it) { - globalOutputStream() << it->c_str() << "\n"; - } - - // collapse mode - collapsemode mode = COLLAPSE_NONE; - - auto radio = lookup_widget(button, "r_collapse"); - ASSERT_TRUE(radio); - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) { - mode = COLLAPSE_ALL; - } else { - radio = lookup_widget(button, "r_collapsebymaterial"); - ASSERT_TRUE(radio); - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) { - mode = COLLAPSE_BY_MATERIAL; - } else { - radio = lookup_widget(button, "r_nocollapse"); - ASSERT_TRUE(radio); - ASSERT_TRUE(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))); - mode = COLLAPSE_NONE; - } - } - - // export materials? - auto toggle = lookup_widget(button, "t_exportmaterials"); - ASSERT_TRUE(toggle); - - bool exportmat = FALSE; - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle))) { - exportmat = TRUE; - } - - // limit material names? - toggle = lookup_widget(button, "t_limitmatnames"); - ASSERT_TRUE(toggle); - - bool limitMatNames = FALSE; - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)) && exportmat) { - limitMatNames = TRUE; - } - - // create objects instead of groups? - toggle = lookup_widget(button, "t_objects"); - ASSERT_TRUE(toggle); - - bool objects = FALSE; - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)) && exportmat) { - objects = TRUE; - } - - // export - ExportSelection(ignore, mode, exportmat, path, limitMatNames, objects); -} - -void OnAddMaterial(ui::Button button, gpointer user_data) -{ - auto edit = ui::Entry::from(lookup_widget(button, "ed_materialname")); - ASSERT_TRUE(edit); - - const gchar *name = gtk_entry_get_text(edit); - if (g_utf8_strlen(name, -1) > 0) { - ui::ListStore list = ui::ListStore::from( - gtk_tree_view_get_model(ui::TreeView::from(lookup_widget(button, "t_materialist")))); - list.append(0, name); - gtk_entry_set_text(edit, ""); - } -} - -void OnRemoveMaterial(ui::Button button, gpointer user_data) -{ - ui::TreeView view = ui::TreeView::from(lookup_widget(button, "t_materialist")); - ui::ListStore list = ui::ListStore::from(gtk_tree_view_get_model(view)); - auto sel = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(sel, 0, &iter)) { - gtk_list_store_remove(list, &iter); - } -} - -void OnExportMatClicked(ui::Button button, gpointer user_data) -{ - ui::Widget toggleLimit = lookup_widget(button, "t_limitmatnames"); - ui::Widget toggleObject = lookup_widget(button, "t_objects"); - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) { - gtk_widget_set_sensitive(toggleLimit, TRUE); - gtk_widget_set_sensitive(toggleObject, TRUE); - } else { - gtk_widget_set_sensitive(toggleLimit, FALSE); - gtk_widget_set_sensitive(toggleObject, FALSE); - } -} - -} // callbacks diff --git a/plugins/brushexport/callbacks.h b/plugins/brushexport/callbacks.h deleted file mode 100644 index c10ef3d..0000000 --- a/plugins/brushexport/callbacks.h +++ /dev/null @@ -1,16 +0,0 @@ - -#include - -namespace callbacks { - -void OnDestroy(ui::Widget, gpointer); - -void OnExportClicked(ui::Button, gpointer); - -void OnAddMaterial(ui::Button, gpointer); - -void OnRemoveMaterial(ui::Button, gpointer); - -void OnExportMatClicked(ui::Button button, gpointer); - -} // callbacks diff --git a/plugins/brushexport/export.cpp b/plugins/brushexport/export.cpp deleted file mode 100644 index f07dc61..0000000 --- a/plugins/brushexport/export.cpp +++ /dev/null @@ -1,367 +0,0 @@ -#include "export.h" -#include "globaldefs.h" -#include "debugging/debugging.h" -#include "ibrush.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" - -#include - -// this is very evil, but right now there is no better way -#include "../../src/brush.h" - -// for limNames -const int MAX_MATERIAL_NAME = 20; - -/* - Abstract baseclass for modelexporters - the class collects all the data which then gets - exported through the WriteToFile method. - */ -class ExportData { -public: -ExportData(const std::set &ignorelist, collapsemode mode, bool limNames, bool objs); - -virtual ~ExportData(void); - -virtual void BeginBrush(Brush &b); - -virtual void AddBrushFace(Face &f); - -virtual void EndBrush(void); - -virtual bool WriteToFile(const std::string &path, collapsemode mode) const = 0; - -protected: - -// a group of faces -class group { -public: -std::string name; -std::list faces; -}; - -std::list groups; - -private: - -// "textures/common/caulk" -> "caulk" -void GetShaderNameFromShaderPath(const char *path, std::string &name); - -group *current; -collapsemode mode; -const std::set &ignorelist; -}; - -ExportData::ExportData(const std::set &_ignorelist, collapsemode _mode, bool _limNames, bool _objs) - : mode(_mode), - ignorelist(_ignorelist) -{ - current = 0; - - // in this mode, we need just one group - if (mode == COLLAPSE_ALL) { - groups.push_back(group()); - current = &groups.back(); - current->name = "all"; - } -} - -ExportData::~ExportData(void) -{ - -} - -void ExportData::BeginBrush(Brush &b) -{ - // create a new group for each brush - if (mode == COLLAPSE_NONE) { - groups.push_back(group()); - current = &groups.back(); - - StringOutputStream str(256); - str << "Brush" << (const unsigned int) groups.size(); - current->name = str.c_str(); - } -} - -void ExportData::EndBrush(void) -{ - // all faces of this brush were on the ignorelist, discard the emptygroup - if (mode == COLLAPSE_NONE) { - ASSERT_NOTNULL(current); - if (current->faces.empty()) { - groups.pop_back(); - current = 0; - } - } -} - -void ExportData::AddBrushFace(Face &f) -{ - std::string shadername; - GetShaderNameFromShaderPath(f.GetShader(), shadername); - - // ignore faces from ignore list - if (ignorelist.find(shadername) != ignorelist.end()) { - return; - } - - if (mode == COLLAPSE_BY_MATERIAL) { - // find a group for this material - current = 0; - const std::list::iterator end(groups.end()); - for (std::list::iterator it(groups.begin()); it != end; ++it) { - if (it->name == shadername) { - current = &(*it); - } - } - - // no group found, create one - if (!current) { - groups.push_back(group()); - current = &groups.back(); - current->name = shadername; - } - } - - ASSERT_NOTNULL(current); - - // add face to current group - current->faces.push_back(&f); - -#if GDEF_DEBUG - globalOutputStream() << "Added Face to group " << current->name.c_str() << "\n"; -#endif -} - -void ExportData::GetShaderNameFromShaderPath(const char *path, std::string &name) -{ - std::string tmp(path); - - size_t last_slash = tmp.find_last_of("/"); - - if (last_slash != std::string::npos && last_slash == (tmp.length() - 1)) { - name = path; - } else { - name = tmp.substr(last_slash + 1, tmp.length() - last_slash); - } - -#if GDEF_DEBUG - globalOutputStream() << "Last: " << (const unsigned int) last_slash << " " << "length: " - << (const unsigned int) tmp.length() << "Name: " << name.c_str() << "\n"; -#endif -} - -/* - Exporter writing facedata as wavefront object - */ -class ExportDataAsWavefront : public ExportData { -private: -bool expmat; -bool limNames; -bool objs; - -public: -ExportDataAsWavefront(const std::set &_ignorelist, collapsemode _mode, bool _expmat, bool _limNames, - bool _objs) - : ExportData(_ignorelist, _mode, _limNames, _objs) -{ - expmat = _expmat; - limNames = _limNames; - objs = _objs; -} - -bool WriteToFile(const std::string &path, collapsemode mode) const; -}; - -bool ExportDataAsWavefront::WriteToFile(const std::string &path, collapsemode mode) const -{ - std::string objFile = path; - - if (path.compare(path.length() - 4, 4, ".obj") != 0) { - objFile += ".obj"; - } - - std::string mtlFile = objFile.substr(0, objFile.length() - 4) + ".mtl"; - - std::set materials; - - TextFileOutputStream out(objFile.c_str()); - - if (out.failed()) { - globalErrorStream() << "Unable to open file\n"; - return false; - } - - out - << "# Wavefront Objectfile exported with radiants brushexport plugin 3.0 by Thomas 'namespace' Nitschke, spam@codecreator.net\n\n"; - - if (expmat) { - size_t last = mtlFile.find_last_of("//"); - std::string mtllib = mtlFile.substr(last + 1, mtlFile.size() - last).c_str(); - out << "mtllib " << mtllib.c_str() << "\n"; - } - - unsigned int vertex_count = 0; - - const std::list::const_iterator gend(groups.end()); - for (std::list::const_iterator git(groups.begin()); git != gend; ++git) { - typedef std::multimap bm; - bm brushMaterials; - typedef std::pair String_Pair; - - const std::list::const_iterator end(git->faces.end()); - - // submesh starts here - if (objs) { - out << "\no "; - } else { - out << "\ng "; - } - out << git->name.c_str() << "\n"; - - // material - if (expmat && mode == COLLAPSE_ALL) { - out << "usemtl material" << "\n\n"; - materials.insert("material"); - } - - for (std::list::const_iterator it(git->faces.begin()); it != end; ++it) { - const Winding &w((*it)->getWinding()); - - // vertices - for (size_t i = 0; i < w.numpoints; ++i) { - out << "v " << FloatFormat(w[i].vertex.x(), 1, 6) << " " << FloatFormat(w[i].vertex.z(), 1, 6) << " " - << FloatFormat(w[i].vertex.y(), 1, 6) << "\n"; - } - } - out << "\n"; - - for (std::list::const_iterator it(git->faces.begin()); it != end; ++it) { - const Winding &w((*it)->getWinding()); - - // texcoords - for (size_t i = 0; i < w.numpoints; ++i) { - out << "vt " << FloatFormat(w[i].texcoord.x(), 1, 6) << " " << FloatFormat(w[i].texcoord.y(), 1, 6) - << "\n"; - } - } - - for (std::list::const_iterator it(git->faces.begin()); it != end; ++it) { - const Winding &w((*it)->getWinding()); - - // faces - StringOutputStream faceLine(256); - faceLine << "\nf"; - for (size_t i = 0; i < w.numpoints; ++i, ++vertex_count) { - faceLine << " " << vertex_count + 1 << "/" << vertex_count + 1; - } - - if (mode != COLLAPSE_ALL) { - materials.insert((*it)->getShader().getShader()); - brushMaterials.insert(String_Pair((*it)->getShader().getShader(), faceLine.c_str())); - } else { - out << faceLine.c_str(); - } - } - - if (mode != COLLAPSE_ALL) { - std::string lastMat; - std::string mat; - std::string faces; - - for (bm::iterator iter = brushMaterials.begin(); iter != brushMaterials.end(); iter++) { - mat = (*iter).first.c_str(); - faces = (*iter).second.c_str(); - - if (mat != lastMat) { - if (limNames && mat.size() > MAX_MATERIAL_NAME) { - out << "\nusemtl " << mat.substr(mat.size() - MAX_MATERIAL_NAME, mat.size()).c_str(); - } else { - out << "\nusemtl " << mat.c_str(); - } - } - - out << faces.c_str(); - lastMat = mat; - } - } - - out << "\n"; - } - - if (expmat) { - TextFileOutputStream outMtl(mtlFile.c_str()); - if (outMtl.failed()) { - globalErrorStream() << "Unable to open material file\n"; - return false; - } - - outMtl << "# Wavefront material file exported with NetRadiants brushexport plugin.\n"; - outMtl << "# Material Count: " << (const Unsigned) materials.size() << "\n\n"; - for (std::set::const_iterator it(materials.begin()); it != materials.end(); ++it) { - if (limNames && it->size() > MAX_MATERIAL_NAME) { - outMtl << "newmtl " << it->substr(it->size() - MAX_MATERIAL_NAME, it->size()).c_str() << "\n"; - } else { - outMtl << "newmtl " << it->c_str() << "\n"; - } - } - } - - return true; -} - - -class ForEachFace : public BrushVisitor { -public: -ForEachFace(ExportData &_exporter) - : exporter(_exporter) -{ -} - -void visit(Face &face) const -{ - exporter.AddBrushFace(face); -} - -private: -ExportData &exporter; -}; - -class ForEachSelected : public SelectionSystem::Visitor { -public: -ForEachSelected(ExportData &_exporter) - : exporter(_exporter) -{ -} - -void visit(scene::Instance &instance) const -{ - BrushInstance *bptr = InstanceTypeCast::cast(instance); - if (bptr) { - Brush &brush(bptr->getBrush()); - - exporter.BeginBrush(brush); - ForEachFace face_vis(exporter); - brush.forEachFace(face_vis); - exporter.EndBrush(); - } -} - -private: -ExportData &exporter; -}; - -bool ExportSelection(const std::set &ignorelist, collapsemode m, bool exmat, const std::string &path, - bool limNames, bool objs) -{ - ExportDataAsWavefront exporter(ignorelist, m, exmat, limNames, objs); - - ForEachSelected vis(exporter); - GlobalSelectionSystem().foreachSelected(vis); - - return exporter.WriteToFile(path, m); -} diff --git a/plugins/brushexport/export.h b/plugins/brushexport/export.h deleted file mode 100644 index 68b3c3f..0000000 --- a/plugins/brushexport/export.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef EXPORT_H -#define EXPORT_H - -#include -#include - -enum collapsemode { - COLLAPSE_ALL, - COLLAPSE_BY_MATERIAL, - COLLAPSE_NONE -}; - -bool ExportSelection(const std::set &ignorelist, collapsemode m, bool exmat, const std::string &path, - bool limitMatNames, bool objects); - -#endif diff --git a/plugins/brushexport/interface.cpp b/plugins/brushexport/interface.cpp deleted file mode 100644 index 3988d48..0000000 --- a/plugins/brushexport/interface.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#include -#include - -#include "debugging/debugging.h" -#include "callbacks.h" -#include "support.h" - -#define GLADE_HOOKUP_OBJECT(component, widget, name) \ - g_object_set_data_full( G_OBJECT( component ), name, \ - g_object_ref( (void *) widget ), (GDestroyNotify) g_object_unref ) - -#define GLADE_HOOKUP_OBJECT_NO_REF(component, widget, name) \ - g_object_set_data( G_OBJECT( component ), name, (void *) widget ) - -// created by glade -ui::Widget create_w_plugplug2(void) -{ - GSList *r_collapse_group = NULL; - - auto w_plugplug2 = ui::Window(ui::window_type::TOP); - gtk_widget_set_name(w_plugplug2, "w_plugplug2"); - gtk_window_set_title(w_plugplug2, "BrushExport-Plugin 3.0 by namespace"); - gtk_window_set_position(w_plugplug2, GTK_WIN_POS_CENTER); - gtk_window_set_destroy_with_parent(w_plugplug2, TRUE); - - auto vbox1 = ui::VBox(FALSE, 0); - gtk_widget_set_name(vbox1, "vbox1"); - vbox1.show(); - w_plugplug2.add(vbox1); - gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5); - - auto hbox2 = ui::HBox(TRUE, 5); - gtk_widget_set_name(hbox2, "hbox2"); - hbox2.show(); - vbox1.pack_start(hbox2, FALSE, FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(hbox2), 5); - - auto vbox4 = ui::VBox(TRUE, 0); - gtk_widget_set_name(vbox4, "vbox4"); - vbox4.show(); - hbox2.pack_start(vbox4, TRUE, FALSE, 0); - - auto r_collapse = ui::Widget::from(gtk_radio_button_new_with_mnemonic(NULL, "Collapse mesh")); - gtk_widget_set_name(r_collapse, "r_collapse"); - gtk_widget_set_tooltip_text(r_collapse, "Collapse all brushes into a single group"); - r_collapse.show(); - vbox4.pack_start(r_collapse, FALSE, FALSE, 0); - gtk_radio_button_set_group(GTK_RADIO_BUTTON(r_collapse), r_collapse_group); - r_collapse_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(r_collapse)); - - auto r_collapsebymaterial = ui::Widget::from(gtk_radio_button_new_with_mnemonic(NULL, "Collapse by material")); - gtk_widget_set_name(r_collapsebymaterial, "r_collapsebymaterial"); - gtk_widget_set_tooltip_text(r_collapsebymaterial, "Collapse into groups by material"); - r_collapsebymaterial.show(); - vbox4.pack_start(r_collapsebymaterial, FALSE, FALSE, 0); - gtk_radio_button_set_group(GTK_RADIO_BUTTON(r_collapsebymaterial), r_collapse_group); - r_collapse_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(r_collapsebymaterial)); - - auto r_nocollapse = ui::Widget::from(gtk_radio_button_new_with_mnemonic(NULL, "Don't collapse")); - gtk_widget_set_name(r_nocollapse, "r_nocollapse"); - gtk_widget_set_tooltip_text(r_nocollapse, "Every brush is stored in its own group"); - r_nocollapse.show(); - vbox4.pack_start(r_nocollapse, FALSE, FALSE, 0); - gtk_radio_button_set_group(GTK_RADIO_BUTTON(r_nocollapse), r_collapse_group); - r_collapse_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(r_nocollapse)); - - auto vbox3 = ui::VBox(FALSE, 0); - gtk_widget_set_name(vbox3, "vbox3"); - vbox3.show(); - hbox2.pack_start(vbox3, FALSE, FALSE, 0); - - auto b_export = ui::Button::from(gtk_button_new_from_stock("gtk-save")); - gtk_widget_set_name(b_export, "b_export"); - b_export.show(); - vbox3.pack_start(b_export, TRUE, FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(b_export), 5); - - auto b_close = ui::Button::from(gtk_button_new_from_stock("gtk-cancel")); - gtk_widget_set_name(b_close, "b_close"); - b_close.show(); - vbox3.pack_start(b_close, TRUE, FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(b_close), 5); - - auto vbox2 = ui::VBox(FALSE, 5); - gtk_widget_set_name(vbox2, "vbox2"); - vbox2.show(); - vbox1.pack_start(vbox2, TRUE, TRUE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 2); - - auto label1 = ui::Label("Ignored materials:"); - gtk_widget_set_name(label1, "label1"); - label1.show(); - vbox2.pack_start(label1, FALSE, FALSE, 0); - - auto scrolledwindow1 = ui::ScrolledWindow(ui::New); - gtk_widget_set_name(scrolledwindow1, "scrolledwindow1"); - scrolledwindow1.show(); - vbox2.pack_start(scrolledwindow1, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow1), GTK_SHADOW_IN); - - auto t_materialist = ui::TreeView(ui::New); - gtk_widget_set_name(t_materialist, "t_materialist"); - t_materialist.show(); - scrolledwindow1.add(t_materialist); - gtk_tree_view_set_headers_visible(t_materialist, FALSE); - gtk_tree_view_set_enable_search(t_materialist, FALSE); - - auto ed_materialname = ui::Entry(ui::New); - gtk_widget_set_name(ed_materialname, "ed_materialname"); - ed_materialname.show(); - vbox2.pack_start(ed_materialname, FALSE, FALSE, 0); - - auto hbox1 = ui::HBox(TRUE, 0); - gtk_widget_set_name(hbox1, "hbox1"); - hbox1.show(); - vbox2.pack_start(hbox1, FALSE, FALSE, 0); - - auto b_addmaterial = ui::Button::from(gtk_button_new_from_stock("gtk-add")); - gtk_widget_set_name(b_addmaterial, "b_addmaterial"); - b_addmaterial.show(); - hbox1.pack_start(b_addmaterial, FALSE, FALSE, 0); - - auto b_removematerial = ui::Button::from(gtk_button_new_from_stock("gtk-remove")); - gtk_widget_set_name(b_removematerial, "b_removematerial"); - b_removematerial.show(); - hbox1.pack_start(b_removematerial, FALSE, FALSE, 0); - - auto t_limitmatnames = ui::Widget::from( - gtk_check_button_new_with_mnemonic("Use short material names (max. 20 chars)")); - gtk_widget_set_name(t_limitmatnames, "t_limitmatnames"); - t_limitmatnames.show(); - vbox2.pack_end(t_limitmatnames, FALSE, FALSE, 0); - - auto t_objects = ui::Widget::from(gtk_check_button_new_with_mnemonic("Create (o)bjects instead of (g)roups")); - gtk_widget_set_name(t_objects, "t_objects"); - t_objects.show(); - vbox2.pack_end(t_objects, FALSE, FALSE, 0); - - auto t_exportmaterials = ui::CheckButton::from( - gtk_check_button_new_with_mnemonic("Create material information (.mtl file)")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t_exportmaterials), true); - gtk_widget_set_name(t_exportmaterials, "t_exportmaterials"); - t_exportmaterials.show(); - vbox2.pack_end(t_exportmaterials, FALSE, FALSE, 10); - - using namespace callbacks; - w_plugplug2.connect("destroy", G_CALLBACK(OnDestroy), NULL); - g_signal_connect_swapped(G_OBJECT(b_close), "clicked", G_CALLBACK(OnDestroy), NULL); - - b_export.connect("clicked", G_CALLBACK(OnExportClicked), NULL); - b_addmaterial.connect("clicked", G_CALLBACK(OnAddMaterial), NULL); - b_removematerial.connect("clicked", G_CALLBACK(OnRemoveMaterial), NULL); - t_exportmaterials.connect("clicked", G_CALLBACK(OnExportMatClicked), NULL); - - /* Store pointers to all widgets, for use by lookup_widget(). */ - GLADE_HOOKUP_OBJECT_NO_REF(w_plugplug2, w_plugplug2, "w_plugplug2"); - GLADE_HOOKUP_OBJECT(w_plugplug2, vbox1, "vbox1"); - GLADE_HOOKUP_OBJECT(w_plugplug2, hbox2, "hbox2"); - GLADE_HOOKUP_OBJECT(w_plugplug2, vbox4, "vbox4"); - GLADE_HOOKUP_OBJECT(w_plugplug2, r_collapse, "r_collapse"); - GLADE_HOOKUP_OBJECT(w_plugplug2, r_collapsebymaterial, "r_collapsebymaterial"); - GLADE_HOOKUP_OBJECT(w_plugplug2, r_nocollapse, "r_nocollapse"); - GLADE_HOOKUP_OBJECT(w_plugplug2, vbox3, "vbox3"); - GLADE_HOOKUP_OBJECT(w_plugplug2, b_export, "b_export"); - GLADE_HOOKUP_OBJECT(w_plugplug2, b_close, "b_close"); - GLADE_HOOKUP_OBJECT(w_plugplug2, vbox2, "vbox2"); - GLADE_HOOKUP_OBJECT(w_plugplug2, label1, "label1"); - GLADE_HOOKUP_OBJECT(w_plugplug2, scrolledwindow1, "scrolledwindow1"); - GLADE_HOOKUP_OBJECT(w_plugplug2, t_materialist, "t_materialist"); - GLADE_HOOKUP_OBJECT(w_plugplug2, ed_materialname, "ed_materialname"); - GLADE_HOOKUP_OBJECT(w_plugplug2, hbox1, "hbox1"); - GLADE_HOOKUP_OBJECT(w_plugplug2, b_addmaterial, "b_addmaterial"); - GLADE_HOOKUP_OBJECT(w_plugplug2, b_removematerial, "b_removematerial"); - GLADE_HOOKUP_OBJECT(w_plugplug2, t_exportmaterials, "t_exportmaterials"); - GLADE_HOOKUP_OBJECT(w_plugplug2, t_limitmatnames, "t_limitmatnames"); - GLADE_HOOKUP_OBJECT(w_plugplug2, t_objects, "t_objects"); - - return w_plugplug2; -} - -// global main window, is 0 when not created -ui::Widget g_brushexp_window{ui::null}; - -// spawn plugin window (and make sure it got destroyed first or never created) -void CreateWindow(void) -{ - ASSERT_TRUE(!g_brushexp_window); - - ui::Widget wnd = create_w_plugplug2(); - - // column & renderer - auto col = ui::TreeViewColumn::from(gtk_tree_view_column_new()); - gtk_tree_view_column_set_title(col, "materials"); - auto view = ui::TreeView::from(lookup_widget(wnd, "t_materialist")); - gtk_tree_view_append_column(view, col); - auto renderer = ui::CellRendererText(ui::New); - gtk_tree_view_insert_column_with_attributes(view, -1, "", renderer, "text", 0, NULL); - - // list store - auto ignorelist = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - gtk_tree_view_set_model(view, ignorelist); - ignorelist.unref(); - - gtk_widget_show_all(wnd); - g_brushexp_window = wnd; -} - -void DestroyWindow() -{ - ASSERT_TRUE(g_brushexp_window); - ui::Widget(g_brushexp_window).destroy(); - g_brushexp_window = ui::Widget(ui::null); -} - -bool IsWindowOpen() -{ - return g_brushexp_window; -} diff --git a/plugins/brushexport/plugin.cpp b/plugins/brushexport/plugin.cpp deleted file mode 100644 index 950c19e..0000000 --- a/plugins/brushexport/plugin.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright (C) 2006, Thomas Nitschke. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "plugin.h" - -#include "iplugin.h" -#include "qerplugin.h" - -#include - -#include "debugging/debugging.h" -#include "string/string.h" -#include "modulesystem/singletonmodule.h" -#include "stream/textfilestream.h" -#include "stream/stringstream.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/filechooser.h" - -#include "ibrush.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "ifilesystem.h" -#include "ifiletypes.h" - -#include "support.h" - -#include "typesystem.h" - -void CreateWindow(void); - -void DestroyWindow(void); - -bool IsWindowOpen(void); - -namespace BrushExport { -ui::Window g_mainwnd{ui::null}; - -const char *init(void *hApp, void *pMainWidget) -{ - g_mainwnd = ui::Window::from(pMainWidget); - ASSERT_TRUE(g_mainwnd); - return ""; -} - -const char *getName() -{ - return "Brush export Plugin"; -} - -const char *getCommandList() -{ - return "About;Export selected as Wavefront OBJ"; -} - -const char *getCommandTitleList() -{ - return ""; -} - -void dispatch(const char *command, float *vMin, float *vMax, bool bSingleBrush) -{ - if (string_equal(command, "About")) { - GlobalRadiant().m_pfnMessageBox(g_mainwnd, "Brushexport plugin v 2.0 by namespace (www.codecreator.net)\n" - "Enjoy!\n\nSend feedback to spam@codecreator.net", "About me...", - eMB_OK, - eMB_ICONDEFAULT); - } else if (string_equal(command, "Export selected as Wavefront OBJ")) { - if (IsWindowOpen()) { - DestroyWindow(); - } - CreateWindow(); - } -} -} - -class BrushExportDependencies : - public GlobalRadiantModuleRef, - public GlobalFiletypesModuleRef, - public GlobalBrushModuleRef, - public GlobalFileSystemModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalSelectionModuleRef { -public: -BrushExportDependencies(void) - : GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")) -{ -} -}; - -class BrushExportModule : public TypeSystemRef { -_QERPluginTable m_plugin; -public: -typedef _QERPluginTable Type; - -STRING_CONSTANT(Name, "Export Brushes"); - -BrushExportModule() -{ - m_plugin.m_pfnQERPlug_Init = &BrushExport::init; - m_plugin.m_pfnQERPlug_GetName = &BrushExport::getName; - m_plugin.m_pfnQERPlug_GetCommandList = &BrushExport::getCommandList; - m_plugin.m_pfnQERPlug_GetCommandTitleList = &BrushExport::getCommandTitleList; - m_plugin.m_pfnQERPlug_Dispatch = &BrushExport::dispatch; -} - -_QERPluginTable *getTable() -{ - return &m_plugin; -} -}; - -typedef SingletonModule SingletonBrushExportModule; -SingletonBrushExportModule g_BrushExportModule; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - g_BrushExportModule.selfRegister(); -} diff --git a/plugins/brushexport/plugin.h b/plugins/brushexport/plugin.h deleted file mode 100644 index d924f64..0000000 --- a/plugins/brushexport/plugin.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2006, Thomas Nitschke. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSH_EXPORT_H ) -#define INCLUDED_BRUSH_EXPORT_H - -#endif diff --git a/plugins/brushexport/support.cpp b/plugins/brushexport/support.cpp deleted file mode 100644 index c10e5b0..0000000 --- a/plugins/brushexport/support.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -#include "support.h" - -ui::Widget -lookup_widget(ui::Widget widget, - const gchar *widget_name) -{ - ui::Widget parent{ui::null}; - - for (;;) { - if (GTK_IS_MENU(widget)) { - parent = ui::Widget::from(gtk_menu_get_attach_widget(GTK_MENU(widget))); - } else { - parent = ui::Widget::from(gtk_widget_get_parent(widget)); - } - if (!parent) { - parent = ui::Widget::from(g_object_get_data(G_OBJECT(widget), "GladeParentKey")); - } - if (parent == NULL) { - break; - } - widget = parent; - } - - auto found_widget = ui::Widget::from(g_object_get_data(G_OBJECT(widget), widget_name)); - if (!found_widget) { - g_warning("Widget not found: %s", widget_name); - } - return found_widget; -} diff --git a/plugins/brushexport/support.h b/plugins/brushexport/support.h deleted file mode 100644 index 374ba75..0000000 --- a/plugins/brushexport/support.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * DO NOT EDIT THIS FILE - it is generated by Glade. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -/* - * Public Functions. - */ - -/* - * This function returns a widget in a component created by Glade. - * Call it with the toplevel widget in the component (i.e. a window/dialog), - * or alternatively any widget in the component, and the name of the widget - * you want returned. - */ -ui::Widget lookup_widget(ui::Widget widget, - const gchar *widget_name); diff --git a/plugins/entity/Makefile b/plugins/entity/Makefile deleted file mode 100644 index d6005ec..0000000 --- a/plugins/entity/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - eclassmodel.o \ - entity.o \ - filters.o \ - generic.o \ - group.o \ - light.o \ - miscmodel.o \ - prop_dynamic.o \ - plugin.o \ - skincache.o \ - targetable.o - -# binary target -../../build/plugins/libentity.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -eclassmodel.o: eclassmodel.cpp eclassmodel.h -entity.o: entity.cpp entity.h -filters.o: filters.cpp filters.h -generic.o: generic.cpp generic.h -group.o: group.cpp group.h -light.o: light.cpp light.h -miscmodel.o: miscmodel.cpp miscmodel.h -prop_dynamic.o: prop_dynamic.cpp prop_dynamic.h -plugin.o: plugin.cpp -skincache.o: skincache.cpp skincache.h -targetable.o: targetable.cpp targetable.h - -clean: - -rm -f *.o ../../build/plugins/libentity.$(LIB_EXT) diff --git a/plugins/entity/angle.h b/plugins/entity/angle.h deleted file mode 100644 index 2c9c8c2..0000000 --- a/plugins/entity/angle.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ANGLE_H ) -#define INCLUDED_ANGLE_H - -#include "ientity.h" - -#include "math/quaternion.h" -#include "generic/callback.h" -#include "stringio.h" - -const float ANGLEKEY_IDENTITY = 0; - -inline void default_angle(float &angle) -{ - angle = ANGLEKEY_IDENTITY; -} - -inline void normalise_angle(float &angle) -{ - angle = static_cast( float_mod(angle, 360.0)); -} - -inline void read_angle(float &angle, const char *value) -{ - if (!string_parse_float(value, angle)) { - angle = 0; - } else { - normalise_angle(angle); - } -} - -inline void write_angle(float angle, Entity *entity) -{ - if (angle == 0) { - entity->setKeyValue("angle", ""); - } else { - char value[64]; - sprintf(value, "%f", angle); - entity->setKeyValue("angle", value); - } -} - -class AngleKey { -Callback m_angleChanged; -public: -float m_angle; - - -AngleKey(const Callback &angleChanged) - : m_angleChanged(angleChanged), m_angle(ANGLEKEY_IDENTITY) -{ -} - -void angleChanged(const char *value) -{ - read_angle(m_angle, value); - m_angleChanged(); -} - -typedef MemberCaller AngleChangedCaller; - -void write(Entity *entity) const -{ - write_angle(m_angle, entity); -} -}; - -inline float angle_rotated(float angle, const Quaternion &rotation) -{ - return matrix4_get_rotation_euler_xyz_degrees( - matrix4_multiplied_by_matrix4( - matrix4_rotation_for_z_degrees(angle), - matrix4_rotation_for_quaternion_quantised(rotation) - ) - ).z(); -} - -#endif diff --git a/plugins/entity/angles.h b/plugins/entity/angles.h deleted file mode 100644 index dca01c2..0000000 --- a/plugins/entity/angles.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ANGLES_H ) -#define INCLUDED_ANGLES_H - -#include "ientity.h" - -#include "math/quaternion.h" -#include "generic/callback.h" -#include "stringio.h" - -#include "angle.h" - -const Vector3 ANGLESKEY_IDENTITY = Vector3(0, 0, 0); - -inline void default_angles(Vector3 &angles) -{ - angles = ANGLESKEY_IDENTITY; -} - -inline void normalise_angles(Vector3 &angles) -{ - angles[0] = static_cast( float_mod(angles[0], 360)); - angles[1] = static_cast( float_mod(angles[1], 360)); - angles[2] = static_cast( float_mod(angles[2], 360)); -} - -inline void read_angle(Vector3 &angles, const char *value) -{ - if (!string_parse_float(value, angles[2])) { - default_angles(angles); - } else { - angles[0] = 0; - angles[1] = 0; - normalise_angles(angles); - } -} - -inline void read_angles(Vector3 &angles, const char *value) -{ - if (!string_parse_vector3(value, angles)) { - default_angles(angles); - printf("Failed to read angles!\n"); - } else { - angles = Vector3(angles[2], angles[0], angles[1]); - normalise_angles(angles); - } -} - -inline void write_angles(const Vector3 &angles, Entity *entity) -{ - if (angles[0] == 0 - && angles[1] == 0 - && angles[2] == 0) { - entity->setKeyValue("angles", ""); - } else { - char value[64]; - sprintf(value, "%f %f %f", angles[1], angles[2], angles[0]); - entity->setKeyValue("angles", value); - } -} - -inline Vector3 angles_rotated(const Vector3 &angles, const Quaternion &rotation) -{ - return matrix4_get_rotation_euler_xyz_degrees( - matrix4_multiplied_by_matrix4( - matrix4_rotation_for_euler_xyz_degrees(angles), - matrix4_rotation_for_quaternion_quantised(rotation) - ) - ); -} - -class AnglesKey { -Callback m_anglesChanged; -public: -Vector3 m_angles; - - -AnglesKey(const Callback &anglesChanged) - : m_anglesChanged(anglesChanged), m_angles(ANGLESKEY_IDENTITY) -{ -} - -void angleChanged(const char *value) -{ - read_angle(m_angles, value); - m_anglesChanged(); -} - -typedef MemberCaller AngleChangedCaller; - -void anglesChanged(const char *value) -{ - read_angles(m_angles, value); - m_anglesChanged(); -} - -typedef MemberCaller AnglesChangedCaller; - -void write(Entity *entity) const -{ - write_angles(m_angles, entity); -} -}; - - -#endif diff --git a/plugins/entity/colour.h b/plugins/entity/colour.h deleted file mode 100644 index e1e9237..0000000 --- a/plugins/entity/colour.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_COLOUR_H ) -#define INCLUDED_COLOUR_H - -#include "ientity.h" -#include "irender.h" - -#include "math/vector.h" -#include "eclasslib.h" -#include "generic/callback.h" -#include "stringio.h" - -inline void default_colour(Vector3 &colour) -{ - colour = Vector3(1, 1, 1); -} - -inline void read_colour(Vector3 &colour, const char *value) -{ - if (!string_parse_vector3(value, colour)) { - default_colour(colour); - } -} - -inline void read_colour255(Vector3 &colour, const char *value) -{ - if (!string_parse_vector3(value, colour)) { - default_colour(colour); - } else { - colour[0] /= 255; - colour[1] /= 255; - colour[2] /= 255; - } -} - -inline void write_colour(const Vector3 &colour, Entity *entity) -{ - char value[64]; - - sprintf(value, "%f %f %f", colour[0], colour[1], colour[2]); - entity->setKeyValue("_color", value); -} - -class Colour { -Callback m_colourChanged; -Shader *m_state; - -void capture_state() -{ - m_state = colour_capture_state_fill(m_colour); -} - -void release_state() -{ - colour_release_state_fill(m_colour); -} - -public: -Vector3 m_colour; - -Colour(const Callback &colourChanged) - : m_colourChanged(colourChanged) -{ - default_colour(m_colour); - capture_state(); -} - -~Colour() -{ - release_state(); -} - -void colourChanged(const char *value) -{ - release_state(); - read_colour(m_colour, value); - capture_state(); - - m_colourChanged(); -} - -void colour255Changed(const char *value) -{ - release_state(); - read_colour255(m_colour, value); - capture_state(); - - m_colourChanged(); -} - -typedef MemberCaller ColourChangedCaller; -typedef MemberCaller Colour255ChangedCaller; - - -void write(Entity *entity) const -{ - write_colour(m_colour, entity); -} - -Shader *state() const -{ - return m_state; -} -}; - -#endif diff --git a/plugins/entity/curve.h b/plugins/entity/curve.h deleted file mode 100644 index 038771a..0000000 --- a/plugins/entity/curve.h +++ /dev/null @@ -1,452 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CURVE_H ) -#define INCLUDED_CURVE_H - -#include "ientity.h" -#include "selectable.h" -#include "renderable.h" - -#include - -#include "math/curve.h" -#include "stream/stringstream.h" -#include "signal/signal.h" -#include "selectionlib.h" -#include "render.h" -#include "stringio.h" - -class RenderableCurve : public OpenGLRenderable { -public: -std::vector m_vertices; - -void render(RenderStateFlags state) const -{ - pointvertex_gl_array(&m_vertices.front()); - glDrawArrays(GL_LINE_STRIP, 0, GLsizei(m_vertices.size())); -} -}; - -inline void plotBasisFunction(std::size_t numSegments, int point, int degree) -{ - Knots knots; - KnotVector_openUniform(knots, 4, degree); - - globalOutputStream() << "plotBasisFunction point " << point << " of 4, knot vector:"; - for (Knots::iterator i = knots.begin(); i != knots.end(); ++i) { - globalOutputStream() << " " << *i; - } - globalOutputStream() << "\n"; - globalOutputStream() << "t=0 basis=" << BSpline_basis(knots, point, degree, 0.0) << "\n"; - for (std::size_t i = 1; i < numSegments; ++i) { - double t = (1.0 / double(numSegments)) * double(i); - globalOutputStream() << "t=" << t << " basis=" << BSpline_basis(knots, point, degree, t) << "\n"; - } - globalOutputStream() << "t=1 basis=" << BSpline_basis(knots, point, degree, 1.0) << "\n"; -} - -inline bool ControlPoints_parse(ControlPoints &controlPoints, const char *value) -{ - StringTokeniser tokeniser(value, " "); - - std::size_t size; - if (!string_parse_size(tokeniser.getToken(), size)) { - return false; - } - - if (size < 3) { - return false; - } - controlPoints.resize(size); - - if (!string_equal(tokeniser.getToken(), "(")) { - return false; - } - for (ControlPoints::iterator i = controlPoints.begin(); i != controlPoints.end(); ++i) { - if (!string_parse_float(tokeniser.getToken(), (*i).x()) - || !string_parse_float(tokeniser.getToken(), (*i).y()) - || !string_parse_float(tokeniser.getToken(), (*i).z())) { - return false; - } - } - if (!string_equal(tokeniser.getToken(), ")")) { - return false; - } - return true; -} - -inline void ControlPoints_write(const ControlPoints &controlPoints, StringOutputStream &value) -{ - value << Unsigned(controlPoints.size()) << " ("; - for (ControlPoints::const_iterator i = controlPoints.begin(); i != controlPoints.end(); ++i) { - value << " " << (*i).x() << " " << (*i).y() << " " << (*i).z() << " "; - } - value << ")"; -} - -inline void -ControlPoint_testSelect(const Vector3 &point, ObservedSelectable &selectable, Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - test.TestPoint(point, best); - if (best.valid()) { - Selector_add(selector, selectable, best); - } -} - -class CurveEditType { -public: -Shader *m_controlsShader; -Shader *m_selectedShader; -}; - -inline void ControlPoints_write(ControlPoints &controlPoints, const char *key, Entity &entity) -{ - StringOutputStream value(256); - if (!controlPoints.empty()) { - ControlPoints_write(controlPoints, value); - } - entity.setKeyValue(key, value.c_str()); -} - -class CurveEdit { -SelectionChangeCallback m_selectionChanged; -ControlPoints &m_controlPoints; -typedef Array Selectables; -Selectables m_selectables; - -RenderablePointVector m_controlsRender; -mutable RenderablePointVector m_selectedRender; - -public: -typedef Static Type; - -CurveEdit(ControlPoints &controlPoints, const SelectionChangeCallback &selectionChanged) : - m_selectionChanged(selectionChanged), - m_controlPoints(controlPoints), - m_controlsRender(GL_POINTS), - m_selectedRender(GL_POINTS) -{ -} - -template -const Functor &forEachSelected(const Functor &functor) -{ - ASSERT_MESSAGE(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch"); - ControlPoints::iterator p = m_controlPoints.begin(); - for (Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p) { - if ((*i).isSelected()) { - functor(*p); - } - } - return functor; -} - -template -const Functor &forEachSelected(const Functor &functor) const -{ - ASSERT_MESSAGE(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch"); - ControlPoints::const_iterator p = m_controlPoints.begin(); - for (Selectables::const_iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p) { - if ((*i).isSelected()) { - functor(*p); - } - } - return functor; -} - -template -const Functor &forEach(const Functor &functor) const -{ - for (ControlPoints::const_iterator i = m_controlPoints.begin(); i != m_controlPoints.end(); ++i) { - functor(*i); - } - return functor; -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - ASSERT_MESSAGE(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch"); - ControlPoints::const_iterator p = m_controlPoints.begin(); - for (Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p) { - ControlPoint_testSelect(*p, *i, selector, test); - } -} - -bool isSelected() const -{ - for (Selectables::const_iterator i = m_selectables.begin(); i != m_selectables.end(); ++i) { - if ((*i).isSelected()) { - return true; - } - } - return false; -} - -void setSelected(bool selected) -{ - for (Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i) { - (*i).setSelected(selected); - } -} - -void write(const char *key, Entity &entity) -{ - ControlPoints_write(m_controlPoints, key, entity); -} - -void transform(const Matrix4 &matrix) -{ - forEachSelected([&](Vector3 &point) { - matrix4_transform_point(matrix, point); - }); -} - -void snapto(float snap) -{ - forEachSelected([&](Vector3 &point) { - vector3_snap(point, snap); - }); -} - -void updateSelected() const -{ - m_selectedRender.clear(); - forEachSelected([&](const Vector3 &point) { - m_selectedRender.push_back(PointVertex(vertex3f_for_vector3(point), colour_selected)); - }); -} - -void renderComponents(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(Type::instance().m_controlsShader, Renderer::eWireframeOnly); - renderer.SetState(Type::instance().m_controlsShader, Renderer::eFullMaterials); - renderer.addRenderable(m_controlsRender, localToWorld); -} - -void renderComponentsSelected(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - updateSelected(); - if (!m_selectedRender.empty()) { - renderer.Highlight(Renderer::ePrimitive, false); - renderer.SetState(Type::instance().m_selectedShader, Renderer::eWireframeOnly); - renderer.SetState(Type::instance().m_selectedShader, Renderer::eFullMaterials); - renderer.addRenderable(m_selectedRender, localToWorld); - } -} - -void curveChanged() -{ - m_selectables.resize(m_controlPoints.size(), m_selectionChanged); - - m_controlsRender.clear(); - m_controlsRender.reserve(m_controlPoints.size()); - forEach([&](const Vector3 &point) { - m_controlsRender.push_back(PointVertex(vertex3f_for_vector3(point), colour_vertex)); - }); - - m_selectedRender.reserve(m_controlPoints.size()); -} - -typedef MemberCaller CurveChangedCaller; -}; - - -const int NURBS_degree = 3; - -class NURBSCurve { -Signal0 m_curveChanged; -Callback m_boundsChanged; -public: -ControlPoints m_controlPoints; -ControlPoints m_controlPointsTransformed; -NURBSWeights m_weights; -Knots m_knots; -RenderableCurve m_renderCurve; -AABB m_bounds; - -NURBSCurve(const Callback &boundsChanged) : m_boundsChanged(boundsChanged) -{ -} - -SignalHandlerId connect(const SignalHandler &curveChanged) -{ - curveChanged(); - return m_curveChanged.connectLast(curveChanged); -} - -void disconnect(SignalHandlerId id) -{ - m_curveChanged.disconnect(id); -} - -void notify() -{ - m_curveChanged(); -} - -void tesselate() -{ - if (!m_controlPointsTransformed.empty()) { - const std::size_t numSegments = (m_controlPointsTransformed.size() - 1) * 16; - m_renderCurve.m_vertices.resize(numSegments + 1); - m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3(m_controlPointsTransformed[0]); - for (std::size_t i = 1; i < numSegments; ++i) { - m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3( - NURBS_evaluate(m_controlPointsTransformed, m_weights, m_knots, NURBS_degree, - (1.0 / double(numSegments)) * double(i))); - } - m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3( - m_controlPointsTransformed[m_controlPointsTransformed.size() - 1]); - } else { - m_renderCurve.m_vertices.clear(); - } -} - -void curveChanged() -{ - tesselate(); - - m_bounds = AABB(); - for (ControlPoints::iterator i = m_controlPointsTransformed.begin(); - i != m_controlPointsTransformed.end(); ++i) { - aabb_extend_by_point_safe(m_bounds, (*i)); - } - - m_boundsChanged(); - notify(); -} - -bool parseCurve(const char *value) -{ - if (!ControlPoints_parse(m_controlPoints, value)) { - return false; - } - - m_weights.resize(m_controlPoints.size()); - for (NURBSWeights::iterator i = m_weights.begin(); i != m_weights.end(); ++i) { - (*i) = 1; - } - - KnotVector_openUniform(m_knots, m_controlPoints.size(), NURBS_degree); - - //plotBasisFunction(8, 0, NURBS_degree); - - return true; -} - -void curveChanged(const char *value) -{ - if (string_empty(value) || !parseCurve(value)) { - m_controlPoints.resize(0); - m_knots.resize(0); - m_weights.resize(0); - } - m_controlPointsTransformed = m_controlPoints; - curveChanged(); -} - -typedef MemberCaller CurveChangedCaller; -}; - -class CatmullRomSpline { -Signal0 m_curveChanged; -Callback m_boundsChanged; -public: -ControlPoints m_controlPoints; -ControlPoints m_controlPointsTransformed; -RenderableCurve m_renderCurve; -AABB m_bounds; - -CatmullRomSpline(const Callback &boundsChanged) : m_boundsChanged(boundsChanged) -{ -} - -SignalHandlerId connect(const SignalHandler &curveChanged) -{ - curveChanged(); - return m_curveChanged.connectLast(curveChanged); -} - -void disconnect(SignalHandlerId id) -{ - m_curveChanged.disconnect(id); -} - -void notify() -{ - m_curveChanged(); -} - -void tesselate() -{ - if (!m_controlPointsTransformed.empty()) { - const std::size_t numSegments = (m_controlPointsTransformed.size() - 1) * 16; - m_renderCurve.m_vertices.resize(numSegments + 1); - m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3(m_controlPointsTransformed[0]); - for (std::size_t i = 1; i < numSegments; ++i) { - m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3( - CatmullRom_evaluate(m_controlPointsTransformed, (1.0 / double(numSegments)) * double(i))); - } - m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3( - m_controlPointsTransformed[m_controlPointsTransformed.size() - 1]); - } else { - m_renderCurve.m_vertices.clear(); - } -} - -bool parseCurve(const char *value) -{ - return ControlPoints_parse(m_controlPoints, value); -} - -void curveChanged() -{ - tesselate(); - - m_bounds = AABB(); - for (ControlPoints::iterator i = m_controlPointsTransformed.begin(); - i != m_controlPointsTransformed.end(); ++i) { - aabb_extend_by_point_safe(m_bounds, (*i)); - } - - m_boundsChanged(); - notify(); -} - -void curveChanged(const char *value) -{ - if (string_empty(value) || !parseCurve(value)) { - m_controlPoints.resize(0); - } - m_controlPointsTransformed = m_controlPoints; - curveChanged(); -} - -typedef MemberCaller CurveChangedCaller; -}; - -const char *const curve_Nurbs = "curve_Nurbs"; -const char *const curve_CatmullRomSpline = "curve_CatmullRomSpline"; - - -#endif diff --git a/plugins/entity/doom3group.cpp b/plugins/entity/doom3group.cpp deleted file mode 100644 index a5d8912..0000000 --- a/plugins/entity/doom3group.cpp +++ /dev/null @@ -1,854 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any Doom3 entity which does not have a fixed size specified in its entity-definition (e.g. func_static). -/// -/// This entity behaves as a group only when the "model" key is empty or is the same as the "name" key. Otherwise it behaves as a model. -/// When behaving as a group, the "origin" key is the translation to be applied to all brushes (not patches) grouped under this entity. -/// When behaving as a model, the "origin", "angle" and "rotation" keys directly control the entity's local-to-parent transform. -/// When either the "curve_Nurbs" or "curve_CatmullRomSpline" keys define a curve, the curve is rendered and can be edited. - -#include "doom3group.h" - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" -#include "modelskin.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" -#include "stream/stringstream.h" -#include "pivot.h" - -#include "targetable.h" -#include "origin.h" -#include "angle.h" -#include "rotation.h" -#include "model.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" -#include "curve.h" -#include "modelskinkey.h" - -#include "entity.h" - -inline void -PointVertexArray_testSelect(PointVertex *first, std::size_t count, SelectionTest &test, SelectionIntersection &best) -{ - test.TestLineStrip( - VertexPointer( - reinterpret_cast( &first->vertex ), - sizeof(PointVertex) - ), - IndexPointer::index_type(count), - best - ); -} - -class Doom3Group : - public Bounded, - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -TraversableNodeSet m_traverse; -MatrixTransform m_transform; - -SingletonModel m_model; -OriginKey m_originKey; -Vector3 m_origin; - -RotationKey m_rotationKey; -Float9 m_rotation; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -TraversableObserverPairRelay m_traverseObservers; -Doom3GroupOrigin m_funcStaticOrigin; -RenderablePivot m_renderOrigin; -RenderableNamedEntity m_renderName; -mutable Vector3 m_name_origin; -ModelSkinKey m_skin; - -public: -NURBSCurve m_curveNURBS; -SignalHandlerId m_curveNURBSChanged; -CatmullRomSpline m_curveCatmullRom; -SignalHandlerId m_curveCatmullRomChanged; -private: -mutable AABB m_curveBounds; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -CopiedString m_name; -CopiedString m_modelKey; -bool m_isModel; - -scene::Traversable *m_traversable; - -void construct() -{ - default_rotation(m_rotation); - - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("model", Doom3Group::ModelChangedCaller(*this)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("angle", RotationKey::AngleChangedCaller(m_rotationKey)); - m_keyObservers.insert("rotation", RotationKey::RotationChangedCaller(m_rotationKey)); - m_keyObservers.insert("name", NameChangedCaller(*this)); - m_keyObservers.insert(curve_Nurbs, NURBSCurve::CurveChangedCaller(m_curveNURBS)); - m_keyObservers.insert(curve_CatmullRomSpline, CatmullRomSpline::CurveChangedCaller(m_curveCatmullRom)); - m_keyObservers.insert("skin", ModelSkinKey::SkinChangedCaller(m_skin)); - - m_traverseObservers.attach(m_funcStaticOrigin); - m_isModel = false; - m_nameKeys.setKeyIsName(keyIsNameDoom3Doom3Group); - attachTraverse(); - - m_entity.attach(m_keyObservers); -} - -void destroy() -{ - m_entity.detach(m_keyObservers); - - if (isModel()) { - detachModel(); - } else { - detachTraverse(); - } - - m_traverseObservers.detach(m_funcStaticOrigin); -} - -void attachModel() -{ - m_traversable = &m_model.getTraversable(); - m_model.attach(&m_traverseObservers); -} - -void detachModel() -{ - m_traversable = 0; - m_model.detach(&m_traverseObservers); -} - -void attachTraverse() -{ - m_traversable = &m_traverse; - m_traverse.attach(&m_traverseObservers); -} - -void detachTraverse() -{ - m_traversable = 0; - m_traverse.detach(&m_traverseObservers); -} - -bool isModel() const -{ - return m_isModel; -} - -void setIsModel(bool newValue) -{ - if (newValue && !m_isModel) { - detachTraverse(); - attachModel(); - - m_nameKeys.setKeyIsName(Static::instance().m_keyIsName); - m_model.modelChanged(m_modelKey.c_str()); - } else if (!newValue && m_isModel) { - detachModel(); - attachTraverse(); - - m_nameKeys.setKeyIsName(keyIsNameDoom3Doom3Group); - } - m_isModel = newValue; - updateTransform(); -} - -void updateIsModel() -{ - setIsModel(!string_equal(m_modelKey.c_str(), m_name.c_str())); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void nameChanged(const char *value) -{ - m_name = value; - updateIsModel(); -} - -typedef MemberCaller NameChangedCaller; - -void modelChanged(const char *value) -{ - m_modelKey = value; - updateIsModel(); - if (isModel()) { - m_model.modelChanged(value); - } else { - m_model.modelChanged(""); - } -} - -typedef MemberCaller ModelChangedCaller; - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - if (isModel()) { - matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); - matrix4_multiply_by_matrix4(m_transform.localToParent(), rotation_toMatrix(m_rotation)); - } - m_transformChanged(); - if (!isModel()) { - m_funcStaticOrigin.originChanged(); - } -} - -typedef MemberCaller UpdateTransformCaller; - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void rotationChanged() -{ - rotation_assign(m_rotation, m_rotationKey.m_rotation); - updateTransform(); -} - -typedef MemberCaller RotationChangedCaller; - -void skinChanged() -{ - if (isModel()) { - scene::Node *node = m_model.getNode(); - if (node != 0) { - Node_modelSkinChanged(*node); - } - } -} - -typedef MemberCaller SkinChangedCaller; - -public: -Doom3Group(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &boundsChanged, const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_funcStaticOrigin(m_traverse, m_origin), - m_renderName(m_named, m_name_origin), - m_name_origin(g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_curveNURBS(boundsChanged), - m_curveCatmullRom(boundsChanged), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform), - m_traversable(0) -{ - construct(); -} - -Doom3Group(const Doom3Group &other, scene::Node &node, const Callback &transformChanged, - const Callback &boundsChanged, const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_funcStaticOrigin(m_traverse, m_origin), - m_renderName(m_named, g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_curveNURBS(boundsChanged), - m_curveCatmullRom(boundsChanged), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform), - m_traversable(0) -{ - construct(); -} - -~Doom3Group() -{ - destroy(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_traverse.instanceAttach(path_find_mapfile(path.begin(), path.end())); - - m_funcStaticOrigin.enable(); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_funcStaticOrigin.disable(); - - m_traverse.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return *m_traversable; -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -ModelSkin &getModelSkin() -{ - return m_skin.get(); -} - -void attach(scene::Traversable::Observer *observer) -{ - m_traverseObservers.attach(*observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_traverseObservers.detach(*observer); -} - -const AABB &localAABB() const -{ - m_curveBounds = m_curveNURBS.m_bounds; - aabb_extend_by_aabb_safe(m_curveBounds, m_curveCatmullRom.m_bounds); - return m_curveBounds; -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - if (isModel() && selected) { - m_renderOrigin.render(renderer, volume, localToWorld); - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials); - - if (!m_curveNURBS.m_renderCurve.m_vertices.empty()) { - renderer.addRenderable(m_curveNURBS.m_renderCurve, localToWorld); - } - if (!m_curveCatmullRom.m_renderCurve.m_vertices.empty()) { - renderer.addRenderable(m_curveCatmullRom.m_renderCurve, localToWorld); - } -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected, - const AABB &childBounds) const -{ - renderSolid(renderer, volume, localToWorld, selected); - - if (g_showNames) { - // draw models as usual - if (!isModel()) { - // don't draw the name for worldspawn - if (!strcmp(m_entity.getEntityClass().name(), "worldspawn")) { - return; - } - - // place name in the middle of the "children cloud" - m_name_origin = childBounds.origin; - } - - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void testSelect(Selector &selector, SelectionTest &test, SelectionIntersection &best) -{ - PointVertexArray_testSelect(&m_curveNURBS.m_renderCurve.m_vertices[0], - m_curveNURBS.m_renderCurve.m_vertices.size(), test, best); - PointVertexArray_testSelect(&m_curveCatmullRom.m_renderCurve.m_vertices[0], - m_curveCatmullRom.m_renderCurve.m_vertices.size(), test, best); -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - rotation_rotate(m_rotation, rotation); -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - rotation_assign(m_rotation, m_rotationKey.m_rotation); - m_curveNURBS.m_controlPointsTransformed = m_curveNURBS.m_controlPoints; - m_curveCatmullRom.m_controlPointsTransformed = m_curveCatmullRom.m_controlPoints; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - rotation_assign(m_rotationKey.m_rotation, m_rotation); - m_rotationKey.write(&m_entity); - m_curveNURBS.m_controlPoints = m_curveNURBS.m_controlPointsTransformed; - ControlPoints_write(m_curveNURBS.m_controlPoints, curve_Nurbs, m_entity); - m_curveCatmullRom.m_controlPoints = m_curveCatmullRom.m_controlPointsTransformed; - ControlPoints_write(m_curveCatmullRom.m_controlPoints, curve_CatmullRomSpline, m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); - m_curveNURBS.curveChanged(); - m_curveCatmullRom.curveChanged(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class Doom3GroupInstance : - public TargetableInstance, - public TransformModifier, - public Renderable, - public SelectionTestable, - public ComponentSelectionTestable, - public ComponentEditable, - public ComponentSnappable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -Doom3Group &m_contained; -CurveEdit m_curveNURBS; -CurveEdit m_curveCatmullRom; -mutable AABB m_aabb_component; -public: - -typedef LazyStatic StaticTypeCasts; - - -Bounded &get(NullType) -{ - return m_contained; -} - -STRING_CONSTANT(Name, "Doom3GroupInstance"); - -Doom3GroupInstance(const scene::Path &path, scene::Instance *parent, Doom3Group &contained) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), - TransformModifier(Doom3Group::TransformChangedCaller(contained), ApplyTransformCaller(*this)), - m_contained(contained), - m_curveNURBS(m_contained.m_curveNURBS.m_controlPointsTransformed, SelectionChangedComponentCaller(*this)), - m_curveCatmullRom(m_contained.m_curveCatmullRom.m_controlPointsTransformed, - SelectionChangedComponentCaller(*this)) -{ - m_contained.instanceAttach(Instance::path()); - m_contained.m_curveNURBSChanged = m_contained.m_curveNURBS.connect(CurveEdit::CurveChangedCaller(m_curveNURBS)); - m_contained.m_curveCatmullRomChanged = m_contained.m_curveCatmullRom.connect( - CurveEdit::CurveChangedCaller(m_curveCatmullRom)); - - StaticRenderableConnectionLines::instance().attach(*this); -} - -~Doom3GroupInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - - m_contained.m_curveCatmullRom.disconnect(m_contained.m_curveCatmullRomChanged); - m_contained.m_curveNURBS.disconnect(m_contained.m_curveNURBSChanged); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); - - m_curveNURBS.renderComponentsSelected(renderer, volume, localToWorld()); - m_curveCatmullRom.renderComponentsSelected(renderer, volume, localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected(), - Instance::childBounds()); - - m_curveNURBS.renderComponentsSelected(renderer, volume, localToWorld()); - m_curveCatmullRom.renderComponentsSelected(renderer, volume, localToWorld()); -} - -void renderComponents(Renderer &renderer, const VolumeTest &volume) const -{ - if (GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex) { - m_curveNURBS.renderComponents(renderer, volume, localToWorld()); - m_curveCatmullRom.renderComponents(renderer, volume, localToWorld()); - } -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - test.BeginMesh(localToWorld()); - SelectionIntersection best; - - m_contained.testSelect(selector, test, best); - - if (best.valid()) { - Selector_add(selector, getSelectable(), best); - } -} - -bool isSelectedComponents() const -{ - return m_curveNURBS.isSelected() || m_curveCatmullRom.isSelected(); -} - -void setSelectedComponents(bool selected, SelectionSystem::EComponentMode mode) -{ - if (mode == SelectionSystem::eVertex) { - m_curveNURBS.setSelected(selected); - m_curveCatmullRom.setSelected(selected); - } -} - -void testSelectComponents(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) -{ - if (mode == SelectionSystem::eVertex) { - test.BeginMesh(localToWorld()); - m_curveNURBS.testSelect(selector, test); - m_curveCatmullRom.testSelect(selector, test); - } -} - -void transformComponents(const Matrix4 &matrix) -{ - if (m_curveNURBS.isSelected()) { - m_curveNURBS.transform(matrix); - } - if (m_curveCatmullRom.isSelected()) { - m_curveCatmullRom.transform(matrix); - } -} - -const AABB &getSelectedComponentsBounds() const -{ - m_aabb_component = AABB(); - m_curveNURBS.forEachSelected([&](const Vector3 &point) { - aabb_extend_by_point_safe(m_aabb_component, point); - }); - m_curveCatmullRom.forEachSelected([&](const Vector3 &point) { - aabb_extend_by_point_safe(m_aabb_component, point); - }); - return m_aabb_component; -} - -void snapComponents(float snap) -{ - if (m_curveNURBS.isSelected()) { - m_curveNURBS.snapto(snap); - m_curveNURBS.write(curve_Nurbs, m_contained.getEntity()); - } - if (m_curveCatmullRom.isSelected()) { - m_curveCatmullRom.snapto(snap); - m_curveCatmullRom.write(curve_CatmullRomSpline, m_contained.getEntity()); - } -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - } else { - transformComponents(calculateTransform()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; - -void selectionChangedComponent(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); - GlobalSelectionSystem().onComponentSelection(*this, selectable); -} - -typedef MemberCaller SelectionChangedComponentCaller; -}; - -class Doom3GroupNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Doom3Group m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: - -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -ModelSkin &get(NullType) -{ - return m_contained.getModelSkin(); -} - -Doom3GroupNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -Doom3GroupNode(const Doom3GroupNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~Doom3GroupNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new Doom3GroupNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new Doom3GroupInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -void Doom3Group_construct() -{ - CurveEdit::Type::instance().m_controlsShader = GlobalShaderCache().capture("$POINT"); - CurveEdit::Type::instance().m_selectedShader = GlobalShaderCache().capture("$SELPOINT"); -} - -void Doom3Group_destroy() -{ - GlobalShaderCache().release("$SELPOINT"); - GlobalShaderCache().release("$POINT"); -} - -scene::Node &New_Doom3Group(EntityClass *eclass) -{ - return (new Doom3GroupNode(eclass))->node(); -} diff --git a/plugins/entity/doom3group.h b/plugins/entity/doom3group.h deleted file mode 100644 index a5e0cd2..0000000 --- a/plugins/entity/doom3group.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STATIC_H ) -#define INCLUDED_STATIC_H - -namespace scene { -class Node; -} -class EntityClass; - -void Doom3Group_construct(); - -void Doom3Group_destroy(); - -scene::Node &New_Doom3Group(EntityClass *eclass); - -#endif diff --git a/plugins/entity/eclassmodel.cpp b/plugins/entity/eclassmodel.cpp deleted file mode 100644 index 0e40ae1..0000000 --- a/plugins/entity/eclassmodel.cpp +++ /dev/null @@ -1,543 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any entity which has a fixed size specified in its entity-definition and displays a model (e.g. ammo_bfg). -/// -/// This entity displays the model specified in its entity-definition. -/// The "origin" and "angle" keys directly control the entity's local-to-parent transform. -/// The "rotation" key directly controls the entity's local-to-parent transform for Doom3 only. - -#include "eclassmodel.h" - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" -#include "pivot.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "rotation.h" -#include "model.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" -#include "modelskinkey.h" - -#include "entity.h" - -class EclassModel : - public Snappable { -MatrixTransform m_transform; -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; - -OriginKey m_originKey; -Vector3 m_origin; -AnglesKey m_anglesKey; -Vector3 m_angles; -RotationKey m_rotationKey; -Float9 m_rotation; -SingletonModel m_model; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -RenderablePivot m_renderOrigin; -RenderableNamedEntity m_renderName; -ModelSkinKey m_skin; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - default_rotation(m_rotation); - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey)); - m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("model", SingletonModel::ModelChangedCaller(m_model)); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); - matrix4_multiply_by_matrix4(m_transform.localToParent(), matrix4_rotation_for_euler_xyz_degrees(m_angles)); - m_transformChanged(); -} - -typedef MemberCaller UpdateTransformCaller; - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void anglesChanged() -{ - m_angles = m_anglesKey.m_angles; - updateTransform(); -} - -typedef MemberCaller AnglesChangedCaller; - -void rotationChanged() -{ - rotation_assign(m_rotation, m_rotationKey.m_rotation); - updateTransform(); -} - -typedef MemberCaller RotationChangedCaller; - -void skinChanged() -{ - scene::Node *node = m_model.getNode(); - if (node != 0) { - Node_modelSkinChanged(*node); - } -} - -typedef MemberCaller SkinChangedCaller; - -public: - -EclassModel(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -EclassModel(const EclassModel &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - m_model.modelChanged(m_entity.getEntityClass().modelpath()); - m_skin.skinChanged(m_entity.getEntityClass().skin()); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_skin.skinChanged(""); - m_model.modelChanged(""); - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_model.getTraversable(); -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -ModelSkin &getModelSkin() -{ - return m_skin.get(); -} - -void attach(scene::Traversable::Observer *observer) -{ - m_model.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_model.detach(observer); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - if (selected) { - m_renderOrigin.render(renderer, volume, localToWorld); - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderSolid(renderer, volume, localToWorld, selected); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - if (g_gameType == eGameTypeDoom3) { - rotation_rotate(m_rotation, rotation); - } else { - m_angles = angles_rotated(m_angles, rotation); - } -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - if (g_gameType == eGameTypeDoom3) { - rotation_assign(m_rotation, m_rotationKey.m_rotation); - } else { - m_angles = m_anglesKey.m_angles; - } -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - if (g_gameType == eGameTypeDoom3) { - rotation_assign(m_rotationKey.m_rotation, m_rotation); - m_rotationKey.write(&m_entity); - } else { - m_anglesKey.m_angles = m_angles; - m_anglesKey.write(&m_entity); - } -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class EclassModelInstance : public TargetableInstance, public TransformModifier, public Renderable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -EclassModel &m_contained; -public: -typedef LazyStatic StaticTypeCasts; - -STRING_CONSTANT(Name, "EclassModelInstance"); - -EclassModelInstance(const scene::Path &path, scene::Instance *parent, EclassModel &contained) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), - TransformModifier(EclassModel::TransformChangedCaller(contained), ApplyTransformCaller(*this)), - m_contained(contained) -{ - m_contained.instanceAttach(Instance::path()); - - StaticRenderableConnectionLines::instance().attach(*this); -} - -~EclassModelInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class EclassModelNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -EclassModel m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -ModelSkin &get(NullType) -{ - return m_contained.getModelSkin(); -} - -EclassModelNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -EclassModelNode(const EclassModelNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~EclassModelNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Node &clone() const -{ - return (new EclassModelNode(*this))->node(); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new EclassModelInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_EclassModel(EntityClass *eclass) -{ - return (new EclassModelNode(eclass))->node(); -} diff --git a/plugins/entity/eclassmodel.h b/plugins/entity/eclassmodel.h deleted file mode 100644 index ebf9da2..0000000 --- a/plugins/entity/eclassmodel.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASSMODEL_H ) -#define INCLUDED_ECLASSMODEL_H - -namespace scene { -class Node; -} -class EntityClass; - -scene::Node &New_EclassModel(EntityClass *eclass); - -#include "entity.h" - -#endif diff --git a/plugins/entity/entity.cpp b/plugins/entity/entity.cpp deleted file mode 100644 index 8d2a035..0000000 --- a/plugins/entity/entity.cpp +++ /dev/null @@ -1,400 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "entity.h" - -#include "ifilter.h" -#include "selectable.h" -#include "namespace.h" - -#include "scenelib.h" -#include "entitylib.h" -#include "eclasslib.h" -#include "pivot.h" - -#include "targetable.h" -#include "uniquenames.h" -#include "namekeys.h" -#include "stream/stringstream.h" -#include "filters.h" - - -#include "miscmodel.h" -#include "prop_dynamic.h" -#include "light.h" -#include "group.h" -#include "eclassmodel.h" -#include "generic.h" -#include "doom3group.h" - - -EGameType g_gameType; - -inline scene::Node &entity_for_eclass(EntityClass *eclass) -{ - if ( classname_equal(eclass->name(), "prop_dynamic" ) ) { - return New_PropDynamic(eclass); - } else if ( classname_equal(eclass->name(), "prop_static" ) ) { - return New_PropStatic(eclass); - } else if ( classname_equal(eclass->name(), "prop_physics" ) ) { - return New_PropStatic(eclass); - } else if (classname_equal(eclass->name(), "light") - || classname_equal(eclass->name(), "lightJunior")) { - return New_Light(eclass); - } else if (classname_equal(eclass->name(), "env_sound") - || classname_equal(eclass->name(), "lightJunior")) { - return New_Light(eclass); - } - - if (!eclass->fixedsize) { - /*if (g_gameType == eGameTypeDoom3) { - return New_Doom3Group(eclass); - } else {*/ - return New_Group(eclass); - /*}*/ - } else if (!string_empty(eclass->modelpath())) { - return New_EclassModel(eclass); - } else { - return New_GenericEntity(eclass); - } -} - -void Entity_setName(Entity &entity, const char *name) -{ - entity.setKeyValue("name", name); -} - -typedef ReferenceCaller EntitySetNameCaller; - -inline Namespaced *Node_getNamespaced(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -inline scene::Node &node_for_eclass(EntityClass *eclass) -{ - scene::Node &node = entity_for_eclass(eclass); - Node_getEntity(node)->setKeyValue("classname", eclass->name()); - - /*if (string_not_empty(eclass->name()) - && !string_equal(eclass->name(), "worldspawn") - && !string_equal(eclass->name(), "UNKNOWN_CLASS")) { - char buffer[1024]; - strcpy(buffer, eclass->name()); - strcat(buffer, "_1"); - GlobalNamespace().makeUnique(buffer, EntitySetNameCaller(*Node_getEntity(node))); - }*/ - - Namespaced *namespaced = Node_getNamespaced(node); - if (namespaced != 0) { - namespaced->setNamespace(GlobalNamespace()); - } - - return node; -} - -EntityCreator::KeyValueChangedFunc EntityKeyValues::m_entityKeyValueChanged = 0; -EntityCreator::KeyValueChangedFunc KeyValue::m_entityKeyValueChanged = 0; -Counter *EntityKeyValues::m_counter = 0; - -bool g_showNames = false; -bool g_showAngles = false; -bool g_newLightDraw = true; -bool g_lightRadii = true; - -class ConnectEntities { -public: -Entity *m_e1; -Entity *m_e2; -int m_index; - -ConnectEntities(Entity *e1, Entity *e2, int index) : m_e1(e1), m_e2(e2), m_index(index) -{ -} - -const char *keyname() -{ - StringOutputStream key(16); - if (m_index <= 0) { - return "target"; - } - if (m_index == 1) { - return "killtarget"; - } - key << "target" << m_index; - return key.c_str(); -} - -void connect(const char *name) -{ - m_e1->setKeyValue(keyname(), name); - m_e2->setKeyValue("targetname", name); -} - -typedef MemberCaller ConnectCaller; -}; - -inline Entity *ScenePath_getEntity(const scene::Path &path) -{ - Entity *entity = Node_getEntity(path.top()); - if (entity == 0) { - entity = Node_getEntity(path.parent()); - } - return entity; -} - -class Quake3EntityCreator : public EntityCreator { -public: -scene::Node &createEntity(EntityClass *eclass) -{ - return node_for_eclass(eclass); -} - -void setKeyValueChangedFunc(KeyValueChangedFunc func) -{ - EntityKeyValues::setKeyValueChangedFunc(func); -} - -void setCounter(Counter *counter) -{ - EntityKeyValues::setCounter(counter); -} - -void connectEntities(const scene::Path &path, const scene::Path &targetPath, int index) -{ - Entity *e1 = ScenePath_getEntity(path); - Entity *e2 = ScenePath_getEntity(targetPath); - - if (e1 == 0 || e2 == 0) { - globalErrorStream() << "entityConnectSelected: both of the selected instances must be an entity\n"; - return; - } - - if (e1 == e2) { - globalErrorStream() - << "entityConnectSelected: the selected instances must not both be from the same entity\n"; - return; - } - - - UndoableCommand undo("entityConnectSelected"); - - if (g_gameType == eGameTypeDoom3) { - StringOutputStream key(16); - if (index >= 0) { - key << "target"; - if (index != 0) { - key << index; - } - e1->setKeyValue(key.c_str(), e2->getKeyValue("name")); - key.clear(); - } else { - for (unsigned int i = 0;; ++i) { - key << "target"; - if (i != 0) { - key << i; - } - const char *value = e1->getKeyValue(key.c_str()); - if (string_empty(value)) { - e1->setKeyValue(key.c_str(), e2->getKeyValue("name")); - break; - } - key.clear(); - } - } - } else { - ConnectEntities connector(e1, e2, index); - const char *value = e2->getKeyValue("targetname"); - if (!string_empty(value)) { - connector.connect(value); - } else { - const char *type = e2->getKeyValue("classname"); - if (string_empty(type)) { - type = "t"; - } - StringOutputStream key(64); - key << type << "1"; - GlobalNamespace().makeUnique(key.c_str(), ConnectEntities::ConnectCaller(connector)); - } - } - - SceneChangeNotify(); -} - -void setLightRadii(bool lightRadii) -{ - g_lightRadii = lightRadii; -} - -bool getLightRadii() const -{ - return g_lightRadii; -} - -void setShowNames(bool showNames) -{ - g_showNames = showNames; -} - -bool getShowNames() -{ - return g_showNames; -} - -void setShowAngles(bool showAngles) -{ - g_showAngles = showAngles; -} - -bool getShowAngles() -{ - return g_showAngles; -} - -void printStatistics() const -{ - StringPool_analyse(EntityKeyValues::getPool()); -} -}; - -Quake3EntityCreator g_Quake3EntityCreator; - -EntityCreator &GetEntityCreator() -{ - return g_Quake3EntityCreator; -} - - -class filter_entity_classname : public EntityFilter { -const char *m_classname; -public: -filter_entity_classname(const char *classname) : m_classname(classname) -{ -} - -bool filter(const Entity &entity) const -{ - return string_equal(entity.getKeyValue("classname"), m_classname); -} -}; - -class filter_entity_classgroup : public EntityFilter { -const char *m_classgroup; -std::size_t m_length; -public: -filter_entity_classgroup(const char *classgroup) : m_classgroup(classgroup), m_length(string_length(m_classgroup)) -{ -} - -bool filter(const Entity &entity) const -{ - return string_equal_n(entity.getKeyValue("classname"), m_classgroup, m_length); -} -}; - -/* this is such a bad hack because radiant sucks and I ran out of time */ -class filter_entity_classtwo : public EntityFilter { -const char *m_classname1; -const char *m_classname2; -public: -filter_entity_classtwo(const char *classname1, const char *classname2) : m_classname1(classname1), m_classname2(classname2) -{ -} - -bool filter(const Entity &entity) const -{ - return string_equal(entity.getKeyValue("classname"), m_classname1) || string_equal(entity.getKeyValue("classname"), m_classname2); -} -}; - -filter_entity_classtwo g_filter_entity_world("worldspawn", "func_group"); -filter_entity_classname g_filter_entity_func_group("func_group"); -filter_entity_classtwo g_filter_entity_details("func_detail", "func_detail_illusionary"); -filter_entity_classname g_filter_entity_light("light"); -filter_entity_classname g_filter_entity_prop_static("prop_static"); -filter_entity_classname g_filter_entity_prop_dynamic("prop_dynamic"); -filter_entity_classgroup g_filter_entity_trigger("trigger_"); -filter_entity_classgroup g_filter_entity_path("path_"); - -class filter_entity_doom3model : public EntityFilter { -public: -bool filter(const Entity &entity) const -{ - return string_equal(entity.getKeyValue("classname"), "func_static") - && !string_equal(entity.getKeyValue("model"), entity.getKeyValue("name")); -} -}; - -filter_entity_doom3model g_filter_entity_doom3model; - - -void Entity_InitFilters() -{ - add_entity_filter(g_filter_entity_world, EXCLUDE_WORLD); - add_entity_filter(g_filter_entity_func_group, EXCLUDE_GROUP); - add_entity_filter(g_filter_entity_details, EXCLUDE_DETAILS); - add_entity_filter(g_filter_entity_trigger, EXCLUDE_TRIGGERS); - add_entity_filter(g_filter_entity_prop_static, EXCLUDE_MODELS); - add_entity_filter(g_filter_entity_prop_dynamic, EXCLUDE_MODELS); - add_entity_filter(g_filter_entity_doom3model, EXCLUDE_MODELS); - add_entity_filter(g_filter_entity_light, EXCLUDE_LIGHTS); - add_entity_filter(g_filter_entity_path, EXCLUDE_PATHS); - add_entity_filter(g_filter_entity_world, EXCLUDE_ENT, true); -} - - -#include "preferencesystem.h" - -void Entity_Construct(EGameType gameType) -{ - g_gameType = gameType; - - Static::instance().m_keyIsName = keyIsNameQuake3; - Static::instance().m_nameKey = "targetname"; - - - GlobalPreferenceSystem().registerPreference("SI_ShowNames", make_property_string(g_showNames)); - GlobalPreferenceSystem().registerPreference("SI_ShowAngles", make_property_string(g_showAngles)); - GlobalPreferenceSystem().registerPreference("NewLightStyle", make_property_string(g_newLightDraw)); - GlobalPreferenceSystem().registerPreference("LightRadiuses", make_property_string(g_lightRadii)); - - Entity_InitFilters(); - Light_Construct(); - PropStatic_construct(); - PropDynamic_construct(); - /* Doom3Group_construct();*/ - - RenderablePivot::StaticShader::instance() = GlobalShaderCache().capture("$PIVOT"); - - GlobalShaderCache().attachRenderable(StaticRenderableConnectionLines::instance()); -} - -void Entity_Destroy() -{ - GlobalShaderCache().detachRenderable(StaticRenderableConnectionLines::instance()); - - GlobalShaderCache().release("$PIVOT"); - - /*Doom3Group_destroy();*/ - PropStatic_destroy(); - PropDynamic_destroy(); - Light_Destroy(); -} diff --git a/plugins/entity/entity.h b/plugins/entity/entity.h deleted file mode 100644 index a1fe3eb..0000000 --- a/plugins/entity/entity.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ENTITY_H ) -#define INCLUDED_ENTITY_H - -class EntityCreator; - -EntityCreator &GetEntityCreator(); - -enum EGameType { - eGameTypeQuake3, - eGameTypeRTCW, - eGameTypeDoom3, -}; - -extern EGameType g_gameType; - -class FilterSystem; - -void Entity_Construct(EGameType gameType = eGameTypeQuake3); - -void Entity_Destroy(); - -extern bool g_showNames; -extern bool g_showAngles; -extern bool g_newLightDraw; -extern bool g_lightRadii; - -#endif diff --git a/plugins/entity/filters.cpp b/plugins/entity/filters.cpp deleted file mode 100644 index 3453fe5..0000000 --- a/plugins/entity/filters.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "filters.h" - -#include "ifilter.h" - -#include - -class EntityFilterWrapper : public Filter { -bool m_active; -bool m_invert; -EntityFilter &m_filter; -public: -EntityFilterWrapper(EntityFilter &filter, bool invert) : m_invert(invert), m_filter(filter) -{ -} - -void setActive(bool active) -{ - m_active = active; -} - -bool active() -{ - return m_active; -} - -bool filter(const Entity &entity) -{ - return m_invert ^ m_filter.filter(entity); -} -}; - - -typedef std::list EntityFilters; -EntityFilters g_entityFilters; - -void add_entity_filter(EntityFilter &filter, int mask, bool invert) -{ - g_entityFilters.push_back(EntityFilterWrapper(filter, invert)); - GlobalFilterSystem().addFilter(g_entityFilters.back(), mask); -} - -bool entity_filtered(Entity &entity) -{ - for (EntityFilters::iterator i = g_entityFilters.begin(); i != g_entityFilters.end(); ++i) { - if ((*i).active() && (*i).filter(entity)) { - return true; - } - } - return false; -} diff --git a/plugins/entity/filters.h b/plugins/entity/filters.h deleted file mode 100644 index 7be17b2..0000000 --- a/plugins/entity/filters.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_FILTERS_H ) -#define INCLUDED_FILTERS_H - -#include "ifilter.h" - -#include "generic/callback.h" -#include "scenelib.h" - -class Entity; - -class EntityFilter { -public: -virtual bool filter(const Entity &entity) const = 0; -}; - -bool entity_filtered(Entity &entity); - -void add_entity_filter(EntityFilter &filter, int mask, bool invert = false); - -class ClassnameFilter : public Filterable { -scene::Node &m_node; -public: -Entity &m_entity; - -ClassnameFilter(Entity &entity, scene::Node &node) : m_node(node), m_entity(entity) -{ -} - -~ClassnameFilter() -{ -} - -void instanceAttach() -{ - GlobalFilterSystem().registerFilterable(*this); -} - -void instanceDetach() -{ - GlobalFilterSystem().unregisterFilterable(*this); -} - -void updateFiltered() -{ - if (entity_filtered(m_entity)) { - m_node.enable(scene::Node::eFiltered); - } else { - m_node.disable(scene::Node::eFiltered); - } -} - -void classnameChanged(const char *value) -{ - updateFiltered(); -} - -typedef MemberCaller ClassnameChangedCaller; -}; - -#endif diff --git a/plugins/entity/generic.cpp b/plugins/entity/generic.cpp deleted file mode 100644 index a7fd902..0000000 --- a/plugins/entity/generic.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any entity which has a fixed size specified in its entity-definition and does not display a model (e.g. info_player_start). -/// -/// This entity displays an axis-aligned bounding box of the size and colour specified in its entity-definition. -/// The "origin" key directly controls the entity's local-to-parent transform. -/// An arrow is drawn to visualise the "angle" key. - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "math/frustum.h" -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" -#include "math/line.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" -#include "rotation.h" - -#include "entity.h" - - -class RenderableArrow : public OpenGLRenderable { -const Vector3 &m_origin; -const Vector3 &m_angles; - -public: -RenderableArrow(const Vector3 &origin, const Vector3 &angles) - : m_origin(origin), m_angles(angles) -{ -} - -void render(RenderStateFlags state) const -{ - Matrix4 mat = matrix4_rotation_for_euler_xyz_degrees(m_angles); - arrow_draw(m_origin, matrix4_transformed_direction(mat, Vector3(1, 0, 0)), - matrix4_transformed_direction(mat, Vector3(0, 1, 0)), - matrix4_transformed_direction(mat, Vector3(0, 0, 1))); -} -}; - -inline void read_aabb(AABB &aabb, const EntityClass &eclass) -{ - aabb = aabb_for_minmax(eclass.mins, eclass.maxs); -} - - -class GenericEntity : - public Cullable, - public Bounded, - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -MatrixTransform m_transform; - -OriginKey m_originKey; -Vector3 m_origin; -AnglesKey m_anglesKey; -Vector3 m_angles; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; - -AABB m_aabb_local; - -RenderableArrow m_arrow; -RenderableSolidAABB m_aabb_solid; -RenderableWireframeAABB m_aabb_wire; -RenderableNamedEntity m_renderName; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - read_aabb(m_aabb_local, m_entity.getEntityClass()); - - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey)); - m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); - m_transformChanged(); -} - -typedef MemberCaller UpdateTransformCaller; - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void anglesChanged() -{ - m_angles = m_anglesKey.m_angles; - updateTransform(); -} - -typedef MemberCaller AnglesChangedCaller; -public: - -GenericEntity(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_arrow(m_aabb_local.origin, m_angles), - m_aabb_solid(m_aabb_local), - m_aabb_wire(m_aabb_local), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -GenericEntity(const GenericEntity &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_arrow(m_aabb_local.origin, m_angles), - m_aabb_solid(m_aabb_local), - m_aabb_wire(m_aabb_local), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return volume.TestAABB(localAABB(), localToWorld); -} - -void renderArrow(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - if (g_showAngles) { - renderer.addRenderable(m_arrow, localToWorld); - } -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_entity.getEntityClass().m_state_fill, Renderer::eFullMaterials); - renderer.addRenderable(m_aabb_solid, localToWorld); - renderArrow(renderer, volume, localToWorld); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - if (string_equal(m_entity.getKeyValue("classname"), "worldspawn")) { - /* todo: handle colors differently for worldspawn brushes */ - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - } else { - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - } - - renderer.addRenderable(m_aabb_wire, localToWorld); - renderArrow(renderer, volume, localToWorld); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - aabb_testselect(m_aabb_local, test, best); - if (best.valid()) { - selector.addIntersection(best); - } -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - m_angles = angles_rotated(m_angles, rotation); -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - m_angles = m_anglesKey.m_angles; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - m_anglesKey.m_angles = m_angles; - m_anglesKey.write(&m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class GenericEntityInstance : - public TargetableInstance, - public TransformModifier, - public Renderable, - public SelectionTestable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -GenericEntity &m_contained; -mutable AABB m_bounds; -public: - -typedef LazyStatic StaticTypeCasts; - -Bounded &get(NullType) -{ - return m_contained; -} - -Cullable &get(NullType) -{ - return m_contained; -} - -STRING_CONSTANT(Name, "GenericEntityInstance"); - -GenericEntityInstance(const scene::Path &path, scene::Instance *parent, GenericEntity &contained) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), - TransformModifier(GenericEntity::TransformChangedCaller(contained), ApplyTransformCaller(*this)), - m_contained(contained) -{ - m_contained.instanceAttach(Instance::path()); - - StaticRenderableConnectionLines::instance().attach(*this); -} - -~GenericEntityInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld()); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_contained.testSelect(selector, test, Instance::localToWorld()); -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class GenericEntityNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -InstanceSet m_instances; - -scene::Node m_node; -GenericEntity m_contained; - -public: -typedef LazyStatic StaticTypeCasts; - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -GenericEntityNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ -} - -GenericEntityNode(const GenericEntityNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new GenericEntityNode(*this))->node(); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new GenericEntityInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_GenericEntity(EntityClass *eclass) -{ - return (new GenericEntityNode(eclass))->node(); -} diff --git a/plugins/entity/generic.h b/plugins/entity/generic.h deleted file mode 100644 index 1a04b95..0000000 --- a/plugins/entity/generic.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GENERIC_H ) -#define INCLUDED_GENERIC_H - -scene::Node &New_GenericEntity(EntityClass *eclass); - -#endif diff --git a/plugins/entity/group.cpp b/plugins/entity/group.cpp deleted file mode 100644 index 8760cca..0000000 --- a/plugins/entity/group.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any entity which does not have a fixed size specified in its entity-definition (except misc_model). -/// -/// This entity behaves as a group, i.e. it contains brushes. - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "scale.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" - -#include "entity.h" - -/// The "origin" key directly controls the entity's local-to-parent transform. - -class Group { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -MatrixTransform m_transform; -TraversableNodeSet m_traverse; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; - -OriginKey m_originKey; -Vector3 m_origin; - -RenderableNamedEntity m_renderName; -mutable Vector3 m_name_origin; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); -} - -public: -Group(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_renderName(m_named, m_name_origin), - m_name_origin(g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -Group(const Group &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_traverse.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_traverse.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_traverse; -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -void attach(scene::Traversable::Observer *observer) -{ - m_traverse.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_traverse.detach(observer); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, - const AABB &childBounds) const -{ - renderSolid(renderer, volume, localToWorld); - - if (g_showNames) { - // don't draw the name for worldspawn - if (!strcmp(m_entity.getEntityClass().name(), "worldspawn")) { - return; - } - - // place name in the middle of the "children cloud" - m_name_origin = childBounds.origin; - - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); - m_transformChanged(); -} - -typedef MemberCaller UpdateTransformCaller; - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -#if 0 -class TransformableSetTranslation -{ -Translation m_value; -public: -TransformableSetTranslation( const Translation& value ) : m_value( value ){ -} -void operator()( Transformable& transformable ) const { - transformable.setTranslation( m_value ); -} -}; - -class TransformableSetRotation -{ -Rotation m_value; -public: -TransformableSetRotation( const Rotation& value ) : m_value( value ){ -} -void operator()( Transformable& transformable ) const { - transformable.setRotation( m_value ); -} -}; - -class TransformableSetScale -{ -Scale m_value; -public: -TransformableSetScale( const Scale& value ) : m_value( value ){ -} -void operator()( Transformable& transformable ) const { - transformable.setScale( m_value ); -} -}; - -class TransformableSetType -{ -TransformModifierType m_value; -public: -TransformableSetType( const TransformModifierType& value ) : m_value( value ){ -} -void operator()( Transformable& transformable ) const { - transformable.setType( m_value ); -} -}; - -class TransformableFreezeTransform -{ -TransformModifierType m_value; -public: -void operator()( Transformable& transformable ) const { - transformable.freezeTransform(); -} -}; - -template -inline void Scene_forEachChildTransformable( const Functor& functor, const scene::Path& path ){ - GlobalSceneGraph().traverse_subgraph( ChildInstanceWalker< InstanceApply >( functor ), path ); -} -#endif - -class GroupInstance : - public TargetableInstance, - public TransformModifier, -#if 0 - public Transformable, -#endif - public Renderable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceStaticCast::install(m_casts); -#if 0 - InstanceStaticCast::install( m_casts ); -#endif -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -Group &m_contained; -public: -typedef LazyStatic StaticTypeCasts; - -GroupInstance(const scene::Path &path, scene::Instance *parent, Group &group) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), group.getEntity(), *this), - TransformModifier(Group::TransformChangedCaller(group), ApplyTransformCaller(*this)), - m_contained(group) -{ - m_contained.instanceAttach(Instance::path()); - StaticRenderableConnectionLines::instance().attach(*this); -} - -~GroupInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), Instance::childBounds()); -} - -STRING_CONSTANT(Name, "GroupInstance"); - -#if 0 -void setType( TransformModifierType type ){ - Scene_forEachChildTransformable( TransformableSetType( type ), Instance::path() ); -} -void setTranslation( const Translation& value ){ - Scene_forEachChildTransformable( TransformableSetTranslation( value ), Instance::path() ); -} -void setRotation( const Rotation& value ){ - Scene_forEachChildTransformable( TransformableSetRotation( value ), Instance::path() ); -} -void setScale( const Scale& value ){ - Scene_forEachChildTransformable( TransformableSetScale( value ), Instance::path() ); -} -void freezeTransform(){ - Scene_forEachChildTransformable( TransformableFreezeTransform(), Instance::path() ); -} - -void evaluateTransform(){ -} -#endif - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class GroupNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Group m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: - -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -GroupNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -GroupNode(const GroupNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~GroupNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new GroupNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new GroupInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_Group(EntityClass *eclass) -{ - return (new GroupNode(eclass))->node(); -} diff --git a/plugins/entity/group.h b/plugins/entity/group.h deleted file mode 100644 index c8c8353..0000000 --- a/plugins/entity/group.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GROUP_H ) -#define INCLUDED_GROUP_H - -scene::Node &New_Group(EntityClass *eclass); - -#endif diff --git a/plugins/entity/keyobservers.h b/plugins/entity/keyobservers.h deleted file mode 100644 index 5767674..0000000 --- a/plugins/entity/keyobservers.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_KEYOBSERVERS_H ) -#define INCLUDED_KEYOBSERVERS_H - -#include "entitylib.h" -#include - -class KeyObserverMap : public Entity::Observer { -typedef std::multimap KeyObservers; -KeyObservers m_keyObservers; -public: -void insert(const char *key, const KeyObserver &observer) -{ - m_keyObservers.insert(KeyObservers::value_type(key, observer)); -} - -void insert(const char *key, EntityKeyValue &value) -{ - for (KeyObservers::const_iterator i = m_keyObservers.find(key); - i != m_keyObservers.end() && string_equal((*i).first, key); ++i) { - value.attach((*i).second); - } -} - -void erase(const char *key, EntityKeyValue &value) -{ - for (KeyObservers::const_iterator i = m_keyObservers.find(key); - i != m_keyObservers.end() && string_equal((*i).first, key); ++i) { - value.detach((*i).second); - } -} -}; - -#endif diff --git a/plugins/entity/light.cpp b/plugins/entity/light.cpp deleted file mode 100644 index f177d5b..0000000 --- a/plugins/entity/light.cpp +++ /dev/null @@ -1,1680 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents any light entity (e.g. light). -/// -/// This entity dislays a special 'light' model. -/// The "origin" key directly controls the position of the light model in local space. -/// The "_color" key controls the colour of the light model. -/// The "light" key is visualised with a sphere representing the approximate coverage of the light (except Doom3). -/// Doom3 special behaviour: -/// The entity behaves as a group. -/// The "origin" key is the translation to be applied to all brushes (not patches) grouped under this entity. -/// The "light_center" and "light_radius" keys are visualised with a point and a box when the light is selected. -/// The "rotation" key directly controls the orientation of the light bounding box in local space. -/// The "light_origin" key controls the position of the light independently of the "origin" key if it is specified. -/// The "light_rotation" key duplicates the behaviour of the "rotation" key if it is specified. This appears to be an unfinished feature in Doom3. - -#include "light.h" - -#include - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "math/frustum.h" -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "entitylib.h" -#include "render.h" -#include "eclasslib.h" -#include "render.h" -#include "stringio.h" -#include "traverselib.h" -#include "dragplanes.h" - -#include "targetable.h" -#include "origin.h" -#include "colour.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" -#include "rotation.h" - -#include "entity.h" - -extern bool g_newLightDraw; - - -void sphere_draw_fill(const Vector3 &origin, float radius, int sides) -{ - if (radius <= 0) { - return; - } - - const double dt = c_2pi / static_cast( sides ); - const double dp = c_pi / static_cast( sides ); - - glBegin(GL_TRIANGLES); - for (int i = 0; i <= sides - 1; ++i) { - for (int j = 0; j <= sides - 2; ++j) { - const double t = i * dt; - const double p = (j * dp) - (c_pi / 2.0); - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - } - } - - { - const double p = (sides - 1) * dp - (c_pi / 2.0); - for (int i = 0; i <= sides - 1; ++i) { - const double t = i * dt; - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - } - } - glEnd(); -} - -void sphere_draw_wire(const Vector3 &origin, float radius, int sides) -{ - { - glBegin(GL_LINE_LOOP); - - for (int i = 0; i <= sides; i++) { - double ds = sin((i * 2 * c_pi) / sides); - double dc = cos((i * 2 * c_pi) / sides); - - glVertex3f( - static_cast( origin[0] + radius * dc ), - static_cast( origin[1] + radius * ds ), - origin[2] - ); - } - - glEnd(); - } - - { - glBegin(GL_LINE_LOOP); - - for (int i = 0; i <= sides; i++) { - double ds = sin((i * 2 * c_pi) / sides); - double dc = cos((i * 2 * c_pi) / sides); - - glVertex3f( - static_cast( origin[0] + radius * dc ), - origin[1], - static_cast( origin[2] + radius * ds ) - ); - } - - glEnd(); - } - - { - glBegin(GL_LINE_LOOP); - - for (int i = 0; i <= sides; i++) { - double ds = sin((i * 2 * c_pi) / sides); - double dc = cos((i * 2 * c_pi) / sides); - - glVertex3f( - origin[0], - static_cast( origin[1] + radius * dc ), - static_cast( origin[2] + radius * ds ) - ); - } - - glEnd(); - } -} - -void light_draw_box_lines(const Vector3 &origin, const Vector3 points[8]) -{ - //draw lines from the center of the bbox to the corners - glBegin(GL_LINES); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[1])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[5])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[2])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[6])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[0])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[4])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[3])); - - glVertex3fv(vector3_to_array(origin)); - glVertex3fv(vector3_to_array(points[7])); - - glEnd(); -} - -void light_draw_radius_wire(const Vector3 &origin, const float envelope[3]) -{ - if (envelope[0] > 0) { - sphere_draw_wire(origin, envelope[0], 24); - } - if (envelope[1] > 0) { - sphere_draw_wire(origin, envelope[1], 24); - } - if (envelope[2] > 0) { - sphere_draw_wire(origin, envelope[2], 24); - } -} - -void light_draw_radius_fill(const Vector3 &origin, const float envelope[3]) -{ - if (envelope[0] > 0) { - sphere_draw_fill(origin, envelope[0], 16); - } - if (envelope[1] > 0) { - sphere_draw_fill(origin, envelope[1], 16); - } - if (envelope[2] > 0) { - sphere_draw_fill(origin, envelope[2], 16); - } -} - -void light_vertices(const AABB &aabb_light, Vector3 points[6]) -{ - Vector3 max(vector3_added(aabb_light.origin, aabb_light.extents)); - Vector3 min(vector3_subtracted(aabb_light.origin, aabb_light.extents)); - Vector3 mid(aabb_light.origin); - - // top, bottom, middle-up, middle-right, middle-down, middle-left - points[0] = Vector3(mid[0], mid[1], max[2]); - points[1] = Vector3(mid[0], mid[1], min[2]); - points[2] = Vector3(mid[0], max[1], mid[2]); - points[3] = Vector3(max[0], mid[1], mid[2]); - points[4] = Vector3(mid[0], min[1], mid[2]); - points[5] = Vector3(min[0], mid[1], mid[2]); -} - -void light_draw(const AABB &aabb_light, RenderStateFlags state) -{ - Vector3 points[6]; - light_vertices(aabb_light, points); - - typedef unsigned int index_t; - const index_t indices[24] = { - 0, 2, 3, - 0, 3, 4, - 0, 4, 5, - 0, 5, 2, - 1, 2, 5, - 1, 5, 4, - 1, 4, 3, - 1, 3, 2 - }; - - glVertexPointer(3, GL_FLOAT, 0, points); - glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(index_t), RenderIndexTypeID, indices); -} - -// These variables are tweakable on the q3map2 console, setting to q3map2 -// default here as there is no way to find out what the user actually uses -// right now. Maybe move them to worldspawn? -float fPointScale = 7500.f; -float fLinearScale = 1.f / 8000.f; - -float light_radius_linear(float fIntensity, float fFalloffTolerance) -{ - return ((fIntensity * fPointScale * fLinearScale) - fFalloffTolerance); -} - -float light_radius(float fIntensity, float fFalloffTolerance) -{ - return sqrt(fIntensity * fPointScale / fFalloffTolerance); -} - -bool spawnflags_linear(int flags) -{ - return (flags & 1); -} - -class LightRadii { -public: -float m_radii[3]; - -private: -float m_primaryIntensity; -float m_secondaryIntensity; -int m_flags; -float m_fade; -float m_scale; - -void calculateRadii() -{ - float intensity = 300.0f; - - if (m_primaryIntensity != 0.0f) { - intensity = m_primaryIntensity; - } else if (m_secondaryIntensity != 0.0f) { - intensity = m_secondaryIntensity; - } - - if (m_scale) { - intensity = m_scale * 0.5f; - m_radii[0] = light_radius(intensity, 1.0f); - m_radii[1] = light_radius(intensity, 48.0f); - m_radii[2] = light_radius(intensity, 255.0f); - } else { - if (spawnflags_linear(m_flags)) { - m_radii[0] = light_radius_linear(intensity, 1.0f) / m_fade; - m_radii[1] = light_radius_linear(intensity, 48.0f) / m_fade; - m_radii[2] = light_radius_linear(intensity, 255.0f) / m_fade; - } else { - m_radii[0] = light_radius(intensity, 1.0f); - m_radii[1] = light_radius(intensity, 48.0f); - m_radii[2] = light_radius(intensity, 255.0f); - } - } -} - -public: -LightRadii() : m_primaryIntensity(0), m_secondaryIntensity(0), m_flags(0), m_fade(1), m_scale(1) -{ -} - - -void primaryIntensityChanged(const char *value) -{ - m_primaryIntensity = string_read_float(value); - calculateRadii(); -} - -typedef MemberCaller PrimaryIntensityChangedCaller; - -void secondaryIntensityChanged(const char *value) -{ - m_secondaryIntensity = string_read_float(value); - calculateRadii(); -} - -typedef MemberCaller SecondaryIntensityChangedCaller; - -void scaleChanged(const char *value) -{ - m_scale = string_read_float(value); - calculateRadii(); -} - -typedef MemberCaller ScaleChangedCaller; - -void fadeChanged(const char *value) -{ - m_fade = string_read_float(value); - if (m_fade <= 0.0f) { - m_fade = 1.0f; - } - calculateRadii(); -} - -typedef MemberCaller FadeChangedCaller; - -void flagsChanged(const char *value) -{ - m_flags = string_read_int(value); - calculateRadii(); -} - -typedef MemberCaller FlagsChangedCaller; -}; - -class LightRadius { -public: -Vector3 m_defaultRadius; -Vector3 m_radius; -Vector3 m_radiusTransformed; -Vector3 m_center; -Callback m_changed; -bool m_useCenterKey; - -LightRadius(const char *defaultRadius) : m_defaultRadius(300, 300, 300), m_center(0, 0, 0), - m_useCenterKey(false) -{ - if (!string_parse_vector3(defaultRadius, m_defaultRadius)) { - globalErrorStream() << "LightRadius: failed to parse default light radius\n"; - } - m_radius = m_defaultRadius; -} - -void lightRadiusChanged(const char *value) -{ - if (!string_parse_vector3(value, m_radius)) { - m_radius = m_defaultRadius; - } - m_radiusTransformed = m_radius; - m_changed(); - SceneChangeNotify(); -} - -typedef MemberCaller LightRadiusChangedCaller; - -void lightCenterChanged(const char *value) -{ - m_useCenterKey = string_parse_vector3(value, m_center); - if (!m_useCenterKey) { - m_center = Vector3(0, 0, 0); - } - SceneChangeNotify(); -} - -typedef MemberCaller LightCenterChangedCaller; -}; - -class RenderLightRadiiWire : public OpenGLRenderable { -LightRadii &m_radii; -const Vector3 &m_origin; -public: -RenderLightRadiiWire(LightRadii &radii, const Vector3 &origin) : m_radii(radii), m_origin(origin) -{ -} - -void render(RenderStateFlags state) const -{ - light_draw_radius_wire(m_origin, m_radii.m_radii); -} -}; - -class RenderLightRadiiFill : public OpenGLRenderable { -LightRadii &m_radii; -const Vector3 &m_origin; -public: -static Shader *m_state; - -RenderLightRadiiFill(LightRadii &radii, const Vector3 &origin) : m_radii(radii), m_origin(origin) -{ -} - -void render(RenderStateFlags state) const -{ - light_draw_radius_fill(m_origin, m_radii.m_radii); -} -}; - -class RenderLightRadiiBox : public OpenGLRenderable { -const Vector3 &m_origin; -public: -mutable Vector3 m_points[8]; -static Shader *m_state; - -RenderLightRadiiBox(const Vector3 &origin) : m_origin(origin) -{ -} - -void render(RenderStateFlags state) const -{ - //draw the bounding box of light based on light_radius key - if ((state & RENDER_FILL) != 0) { - aabb_draw_flatshade(m_points); - } else { - aabb_draw_wire(m_points); - } - -#if 1 //disable if you dont want lines going from the center of the light bbox to the corners - light_draw_box_lines(m_origin, m_points); -#endif -} -}; - -Shader *RenderLightRadiiFill::m_state = 0; - -class RenderLightCenter : public OpenGLRenderable { -const Vector3 &m_center; -EntityClass &m_eclass; -public: -static Shader *m_state; - -RenderLightCenter(const Vector3 ¢er, EntityClass &eclass) : m_center(center), m_eclass(eclass) -{ -} - -void render(RenderStateFlags state) const -{ - glBegin(GL_POINTS); - glColor3fv(vector3_to_array(m_eclass.color)); - glVertex3fv(vector3_to_array(m_center)); - glEnd(); -} -}; - -Shader *RenderLightCenter::m_state = 0; - -class RenderLightProjection : public OpenGLRenderable { -const Matrix4 &m_projection; -public: - -RenderLightProjection(const Matrix4 &projection) : m_projection(projection) -{ -} - -void render(RenderStateFlags state) const -{ - Matrix4 unproject(matrix4_full_inverse(m_projection)); - Vector3 points[8]; - aabb_corners(AABB(Vector3(0.5f, 0.5f, 0.5f), Vector3(0.5f, 0.5f, 0.5f)), points); - points[0] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[0], 1))); - points[1] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[1], 1))); - points[2] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[2], 1))); - points[3] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[3], 1))); - points[4] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[4], 1))); - points[5] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[5], 1))); - points[6] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[6], 1))); - points[7] = vector4_projected(matrix4_transformed_vector4(unproject, Vector4(points[7], 1))); -// Vector4 test1 = matrix4_transformed_vector4( unproject, Vector4( 0.5f, 0.5f, 0.5f, 1 ) ); -// Vector3 test2 = vector4_projected( test1 ); - aabb_draw_wire(points); -} -}; - -inline void default_extents(Vector3 &extents) -{ - extents = Vector3(8, 8, 8); -} - -class ShaderRef { -CopiedString m_name; -Shader *m_shader; - -void capture() -{ - m_shader = GlobalShaderCache().capture(m_name.c_str()); -} - -void release() -{ - GlobalShaderCache().release(m_name.c_str()); -} - -public: -ShaderRef() -{ - capture(); -} - -~ShaderRef() -{ - release(); -} - -void setName(const char *name) -{ - release(); - m_name = name; - capture(); -} - -Shader *get() const -{ - return m_shader; -} -}; - -class LightShader { -ShaderRef m_shader; - -void setDefault() -{ - m_shader.setName(m_defaultShader); -} - -public: -static const char *m_defaultShader; - -LightShader() -{ - setDefault(); -} - -void valueChanged(const char *value) -{ - if (string_empty(value)) { - setDefault(); - } else { - m_shader.setName(value); - } - SceneChangeNotify(); -} - -typedef MemberCaller ValueChangedCaller; - -Shader *get() const -{ - return m_shader.get(); -} -}; - -const char *LightShader::m_defaultShader = ""; - -inline const BasicVector4 &plane3_to_vector4(const Plane3 &self) -{ - return reinterpret_cast &>( self ); -} - -inline BasicVector4 &plane3_to_vector4(Plane3 &self) -{ - return reinterpret_cast &>( self ); -} - -inline Matrix4 matrix4_from_planes(const Plane3 &left, const Plane3 &right, const Plane3 &bottom, const Plane3 &top, - const Plane3 &front, const Plane3 &back) -{ - return Matrix4( - (right.a - left.a) / 2, - (top.a - bottom.a) / 2, - (back.a - front.a) / 2, - right.a - (right.a - left.a) / 2, - (right.b - left.b) / 2, - (top.b - bottom.b) / 2, - (back.b - front.b) / 2, - right.b - (right.b - left.b) / 2, - (right.c - left.c) / 2, - (top.c - bottom.c) / 2, - (back.c - front.c) / 2, - right.c - (right.c - left.c) / 2, - (right.d - left.d) / 2, - (top.d - bottom.d) / 2, - (back.d - front.d) / 2, - right.d - (right.d - left.d) / 2 - ); -} - -class Light : - public OpenGLRenderable, - public Cullable, - public Bounded, - public Editable, - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -TraversableNodeSet m_traverse; -IdentityTransform m_transform; - -OriginKey m_originKey; -RotationKey m_rotationKey; -Float9 m_rotation; -Colour m_colour; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -TraversableObserverPairRelay m_traverseObservers; - -LightRadii m_radii; -LightRadius m_radius; - -RenderLightRadiiWire m_radii_wire; -RenderLightRadiiFill m_radii_fill; -RenderLightRadiiBox m_radii_box; -RenderLightCenter m_render_center; -RenderableNamedEntity m_renderName; - -Vector3 m_lightOrigin; -bool m_useLightOrigin; -Float9 m_lightRotation; -bool m_useLightRotation; - -Vector3 m_lightTarget; -bool m_useLightTarget; -Vector3 m_lightUp; -bool m_useLightUp; -Vector3 m_lightRight; -bool m_useLightRight; -Vector3 m_lightStart; -bool m_useLightStart; -Vector3 m_lightEnd; -bool m_useLightEnd; - -mutable AABB m_doom3AABB; -mutable Matrix4 m_doom3Rotation; -mutable Matrix4 m_doom3Projection; -mutable Frustum m_doom3Frustum; -mutable bool m_doom3ProjectionChanged; - -RenderLightProjection m_renderProjection; - -LightShader m_shader; - -AABB m_aabb_light; - -Callback m_transformChanged; -Callback m_boundsChanged; -Callback m_evaluateTransform; - -void construct() -{ - default_rotation(m_rotation); - m_aabb_light.origin = Vector3(0, 0, 0); - default_extents(m_aabb_light.extents); - - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("_color", Colour::ColourChangedCaller(m_colour)); - m_keyObservers.insert("_color255", Colour::Colour255ChangedCaller(m_colour)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("_light", LightRadii::PrimaryIntensityChangedCaller(m_radii)); - m_keyObservers.insert("light", LightRadii::SecondaryIntensityChangedCaller(m_radii)); - m_keyObservers.insert("fade", LightRadii::FadeChangedCaller(m_radii)); - m_keyObservers.insert("radius", LightRadii::ScaleChangedCaller(m_radii)); - m_keyObservers.insert("scale", LightRadii::ScaleChangedCaller(m_radii)); - m_keyObservers.insert("spawnflags", LightRadii::FlagsChangedCaller(m_radii)); - -} - -void destroy() -{ - -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void updateOrigin() -{ - m_boundsChanged(); - m_radius.m_changed(); - GlobalSelectionSystem().pivotChanged(); -} - -void originChanged() -{ - m_aabb_light.origin = m_useLightOrigin ? m_lightOrigin : m_originKey.m_origin; - updateOrigin(); -} - -typedef MemberCaller OriginChangedCaller; - -void lightOriginChanged(const char *value) -{ - m_useLightOrigin = !string_empty(value); - if (m_useLightOrigin) { - read_origin(m_lightOrigin, value); - } - originChanged(); -} - -typedef MemberCaller LightOriginChangedCaller; - -void lightTargetChanged(const char *value) -{ - m_useLightTarget = !string_empty(value); - if (m_useLightTarget) { - read_origin(m_lightTarget, value); - } - projectionChanged(); -} - -typedef MemberCaller LightTargetChangedCaller; - -void lightUpChanged(const char *value) -{ - m_useLightUp = !string_empty(value); - if (m_useLightUp) { - read_origin(m_lightUp, value); - } - projectionChanged(); -} - -typedef MemberCaller LightUpChangedCaller; - -void lightRightChanged(const char *value) -{ - m_useLightRight = !string_empty(value); - if (m_useLightRight) { - read_origin(m_lightRight, value); - } - projectionChanged(); -} - -typedef MemberCaller LightRightChangedCaller; - -void lightStartChanged(const char *value) -{ - m_useLightStart = !string_empty(value); - if (m_useLightStart) { - read_origin(m_lightStart, value); - } - projectionChanged(); -} - -typedef MemberCaller LightStartChangedCaller; - -void lightEndChanged(const char *value) -{ - m_useLightEnd = !string_empty(value); - if (m_useLightEnd) { - read_origin(m_lightEnd, value); - } - projectionChanged(); -} - -typedef MemberCaller LightEndChangedCaller; - -void writeLightOrigin() -{ - write_origin(m_lightOrigin, &m_entity, "light_origin"); -} - -void updateLightRadiiBox() const -{ - const Matrix4 &rotation = rotation_toMatrix(m_rotation); - aabb_corners(AABB(Vector3(0, 0, 0), m_radius.m_radiusTransformed), m_radii_box.m_points); - matrix4_transform_point(rotation, m_radii_box.m_points[0]); - vector3_add(m_radii_box.m_points[0], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[1]); - vector3_add(m_radii_box.m_points[1], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[2]); - vector3_add(m_radii_box.m_points[2], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[3]); - vector3_add(m_radii_box.m_points[3], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[4]); - vector3_add(m_radii_box.m_points[4], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[5]); - vector3_add(m_radii_box.m_points[5], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[6]); - vector3_add(m_radii_box.m_points[6], m_aabb_light.origin); - matrix4_transform_point(rotation, m_radii_box.m_points[7]); - vector3_add(m_radii_box.m_points[7], m_aabb_light.origin); -} - -void rotationChanged() -{ - rotation_assign(m_rotation, m_useLightRotation ? m_lightRotation : m_rotationKey.m_rotation); - GlobalSelectionSystem().pivotChanged(); -} - -typedef MemberCaller RotationChangedCaller; - -void lightRotationChanged(const char *value) -{ - m_useLightRotation = !string_empty(value); - if (m_useLightRotation) { - read_rotation(m_lightRotation, value); - } - rotationChanged(); -} - -typedef MemberCaller LightRotationChangedCaller; - -public: - -Light(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &boundsChanged, const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_rotationKey(RotationChangedCaller(*this)), - m_colour(Callback()), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_radius(EntityClass_valueForKey(m_entity.getEntityClass(), "light_radius")), - m_radii_wire(m_radii, m_aabb_light.origin), - m_radii_fill(m_radii, m_aabb_light.origin), - m_radii_box(m_aabb_light.origin), - m_render_center(m_radius.m_center, m_entity.getEntityClass()), - m_renderName(m_named, m_aabb_light.origin), - m_useLightOrigin(false), - m_useLightRotation(false), - m_renderProjection(m_doom3Projection), - m_transformChanged(transformChanged), - m_boundsChanged(boundsChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -Light(const Light &other, scene::Node &node, const Callback &transformChanged, - const Callback &boundsChanged, const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_rotationKey(RotationChangedCaller(*this)), - m_colour(Callback()), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_radius(EntityClass_valueForKey(m_entity.getEntityClass(), "light_radius")), - m_radii_wire(m_radii, m_aabb_light.origin), - m_radii_fill(m_radii, m_aabb_light.origin), - m_radii_box(m_aabb_light.origin), - m_render_center(m_radius.m_center, m_entity.getEntityClass()), - m_renderName(m_named, m_aabb_light.origin), - m_useLightOrigin(false), - m_useLightRotation(false), - m_renderProjection(m_doom3Projection), - m_transformChanged(transformChanged), - m_boundsChanged(boundsChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -~Light() -{ - destroy(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_traverse; -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -void attach(scene::Traversable::Observer *observer) -{ - m_traverseObservers.attach(*observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_traverseObservers.detach(*observer); -} - -void render(RenderStateFlags state) const -{ - if (!g_newLightDraw) { - aabb_draw(m_aabb_light, state); - } else { - light_draw(m_aabb_light, state); - } -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return volume.TestAABB(m_aabb_light, localToWorld); -} - -// cache -const AABB &localAABB() const -{ - return m_aabb_light; -} - - -mutable Matrix4 m_projectionOrientation; - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - renderer.SetState(m_colour.state(), Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); - - if (selected && g_lightRadii && string_empty(m_entity.getKeyValue("target"))) { - if (renderer.getStyle() == Renderer::eFullMaterials) { - renderer.SetState(RenderLightRadiiFill::m_state, Renderer::eFullMaterials); - renderer.Highlight(Renderer::ePrimitive, false); - renderer.addRenderable(m_radii_fill, localToWorld); - } else { - renderer.addRenderable(m_radii_wire, localToWorld); - } - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderSolid(renderer, volume, localToWorld, selected); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - aabb_testselect(m_aabb_light, test, best); - if (best.valid()) { - selector.addIntersection(best); - } -} - -void translate(const Vector3 &translation) -{ - m_aabb_light.origin = origin_translated(m_aabb_light.origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - rotation_rotate(m_rotation, rotation); -} - -void snapto(float snap) -{ - if (m_useLightOrigin) { - m_lightOrigin = origin_snapped(m_lightOrigin, snap); - writeLightOrigin(); - } else { - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); - } -} - -void setLightRadius(const AABB &aabb) -{ - m_aabb_light.origin = aabb.origin; - m_radius.m_radiusTransformed = aabb.extents; -} - -void transformLightRadius(const Matrix4 &transform) -{ - matrix4_transform_point(transform, m_aabb_light.origin); -} - -void revertTransform() -{ - m_aabb_light.origin = m_useLightOrigin ? m_lightOrigin : m_originKey.m_origin; - rotation_assign(m_rotation, m_useLightRotation ? m_lightRotation : m_rotationKey.m_rotation); - m_radius.m_radiusTransformed = m_radius.m_radius; -} - -void freezeTransform() -{ - if (m_useLightOrigin) { - m_lightOrigin = m_aabb_light.origin; - writeLightOrigin(); - } else { - m_originKey.m_origin = m_aabb_light.origin; - m_originKey.write(&m_entity); - } -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateOrigin(); -} - -typedef MemberCaller TransformChangedCaller; - -mutable Matrix4 m_localPivot; - -const Matrix4 &getLocalPivot() const -{ - m_localPivot = rotation_toMatrix(m_rotation); - vector4_to_vector3(m_localPivot.t()) = m_aabb_light.origin; - return m_localPivot; -} - -void setLightChangedCallback(const Callback &callback) -{ - m_radius.m_changed = callback; -} - -const AABB &aabb() const -{ - m_doom3AABB = AABB(m_aabb_light.origin, m_radius.m_radiusTransformed); - return m_doom3AABB; -} - -bool testAABB(const AABB &other) const -{ - if (isProjected()) { - Matrix4 transform = rotation(); - vector4_to_vector3(transform.t()) = localAABB().origin; - projection(); - Frustum frustum(frustum_transformed(m_doom3Frustum, transform)); - return frustum_test_aabb(frustum, other) != c_volumeOutside; - } - // test against an AABB which contains the rotated bounds of this light. - const AABB &bounds = aabb(); - return aabb_intersects_aabb(other, AABB( - bounds.origin, - Vector3( - static_cast( fabs(m_rotation[0] * bounds.extents[0]) - + fabs(m_rotation[3] * bounds.extents[1]) - + fabs(m_rotation[6] * bounds.extents[2])), - static_cast( fabs(m_rotation[1] * bounds.extents[0]) - + fabs(m_rotation[4] * bounds.extents[1]) - + fabs(m_rotation[7] * bounds.extents[2])), - static_cast( fabs(m_rotation[2] * bounds.extents[0]) - + fabs(m_rotation[5] * bounds.extents[1]) - + fabs(m_rotation[8] * bounds.extents[2])) - ) - )); -} - -const Matrix4 &rotation() const -{ - m_doom3Rotation = rotation_toMatrix(m_rotation); - return m_doom3Rotation; -} - -const Vector3 &offset() const -{ - return m_radius.m_center; -} - -const Vector3 &colour() const -{ - return m_colour.m_colour; -} - -bool isProjected() const -{ - return m_useLightTarget && m_useLightUp && m_useLightRight; -} - -void projectionChanged() -{ - m_doom3ProjectionChanged = true; - m_radius.m_changed(); - SceneChangeNotify(); -} - -const Matrix4 &projection() const -{ - if (!m_doom3ProjectionChanged) { - return m_doom3Projection; - } - m_doom3ProjectionChanged = false; - m_doom3Projection = g_matrix4_identity; - matrix4_translate_by_vec3(m_doom3Projection, Vector3(0.5f, 0.5f, 0)); - matrix4_scale_by_vec3(m_doom3Projection, Vector3(0.5f, 0.5f, 1)); - -#if 0 - Vector3 right = vector3_cross( m_lightUp, vector3_normalised( m_lightTarget ) ); - Vector3 up = vector3_cross( vector3_normalised( m_lightTarget ), m_lightRight ); - Vector3 target = m_lightTarget; - Matrix4 test( - -right.x(), -right.y(), -right.z(), 0, - -up.x(), -up.y(), -up.z(), 0, - -target.x(), -target.y(), -target.z(), 0, - 0, 0, 0, 1 - ); - Matrix4 frustum = matrix4_frustum( -0.01, 0.01, -0.01, 0.01, 0.01, 1.0 ); - test = matrix4_full_inverse( test ); - matrix4_premultiply_by_matrix4( test, frustum ); - matrix4_multiply_by_matrix4( m_doom3Projection, test ); -#elif 0 - const float nearFar = 1 / 49.5f; - Vector3 right = vector3_cross( m_lightUp, vector3_normalised( m_lightTarget + m_lightRight ) ); - Vector3 up = vector3_cross( vector3_normalised( m_lightTarget + m_lightUp ), m_lightRight ); - Vector3 target = vector3_negated( m_lightTarget * ( 1 + nearFar ) ); - float scale = -1 / vector3_length( m_lightTarget ); - Matrix4 test( - -inverse( right.x() ), -inverse( up.x() ), -inverse( target.x() ), 0, - -inverse( right.y() ), -inverse( up.y() ), -inverse( target.y() ), 0, - -inverse( right.z() ), -inverse( up.z() ), -inverse( target.z() ), scale, - 0, 0, -nearFar, 0 - ); - matrix4_multiply_by_matrix4( m_doom3Projection, test ); -#elif 0 - Vector3 leftA( m_lightTarget - m_lightRight ); - Vector3 leftB( m_lightRight + m_lightUp ); - Plane3 left( vector3_normalised( vector3_cross( leftA, leftB ) ) * ( 1.0 / 128 ), 0 ); - Vector3 rightA( m_lightTarget + m_lightRight ); - Vector3 rightB( vector3_cross( rightA, m_lightTarget ) ); - Plane3 right( vector3_normalised( vector3_cross( rightA, rightB ) ) * ( 1.0 / 128 ), 0 ); - Vector3 bottomA( m_lightTarget - m_lightUp ); - Vector3 bottomB( vector3_cross( bottomA, m_lightTarget ) ); - Plane3 bottom( vector3_normalised( vector3_cross( bottomA, bottomB ) ) * ( 1.0 / 128 ), 0 ); - Vector3 topA( m_lightTarget + m_lightUp ); - Vector3 topB( vector3_cross( topA, m_lightTarget ) ); - Plane3 top( vector3_normalised( vector3_cross( topA, topB ) ) * ( 1.0 / 128 ), 0 ); - Plane3 front( vector3_normalised( m_lightTarget ) * ( 1.0 / 128 ), 1 ); - Plane3 back( vector3_normalised( vector3_negated( m_lightTarget ) ) * ( 1.0 / 128 ), 0 ); - Matrix4 test( matrix4_from_planes( plane3_flipped( left ), plane3_flipped( right ), plane3_flipped( bottom ), plane3_flipped( top ), plane3_flipped( front ), plane3_flipped( back ) ) ); - matrix4_multiply_by_matrix4( m_doom3Projection, test ); -#else - - Plane3 lightProject[4]; - - Vector3 start = m_useLightStart && m_useLightEnd ? m_lightStart : vector3_normalised(m_lightTarget); - Vector3 stop = m_useLightStart && m_useLightEnd ? m_lightEnd : m_lightTarget; - - float rLen = vector3_length(m_lightRight); - Vector3 right = vector3_divided(m_lightRight, rLen); - float uLen = vector3_length(m_lightUp); - Vector3 up = vector3_divided(m_lightUp, uLen); - Vector3 normal = vector3_normalised(vector3_cross(up, right)); - - float dist = vector3_dot(m_lightTarget, normal); - if (dist < 0) { - dist = -dist; - normal = vector3_negated(normal); - } - - right *= (0.5f * dist) / rLen; - up *= -(0.5f * dist) / uLen; - - lightProject[2] = Plane3(normal, 0); - lightProject[0] = Plane3(right, 0); - lightProject[1] = Plane3(up, 0); - - // now offset to center - Vector4 targetGlobal(m_lightTarget, 1); - { - float a = vector4_dot(targetGlobal, plane3_to_vector4(lightProject[0])); - float b = vector4_dot(targetGlobal, plane3_to_vector4(lightProject[2])); - float ofs = 0.5f - a / b; - plane3_to_vector4(lightProject[0]) += plane3_to_vector4(lightProject[2]) * ofs; - } - { - float a = vector4_dot(targetGlobal, plane3_to_vector4(lightProject[1])); - float b = vector4_dot(targetGlobal, plane3_to_vector4(lightProject[2])); - float ofs = 0.5f - a / b; - plane3_to_vector4(lightProject[1]) += plane3_to_vector4(lightProject[2]) * ofs; - } - - // set the falloff vector - Vector3 falloff = stop - start; - float length = vector3_length(falloff); - falloff = vector3_divided(falloff, length); - if (length <= 0) { - length = 1; - } - falloff *= (1.0f / length); - lightProject[3] = Plane3(falloff, -vector3_dot(start, falloff)); - - // we want the planes of s=0, s=q, t=0, and t=q - m_doom3Frustum.left = lightProject[0]; - m_doom3Frustum.bottom = lightProject[1]; - m_doom3Frustum.right = Plane3(lightProject[2].normal() - lightProject[0].normal(), - lightProject[2].dist() - lightProject[0].dist()); - m_doom3Frustum.top = Plane3(lightProject[2].normal() - lightProject[1].normal(), - lightProject[2].dist() - lightProject[1].dist()); - - // we want the planes of s=0 and s=1 for front and rear clipping planes - m_doom3Frustum.front = lightProject[3]; - - m_doom3Frustum.back = lightProject[3]; - m_doom3Frustum.back.dist() -= 1.0f; - m_doom3Frustum.back = plane3_flipped(m_doom3Frustum.back); - - Matrix4 test(matrix4_from_planes(m_doom3Frustum.left, m_doom3Frustum.right, m_doom3Frustum.bottom, - m_doom3Frustum.top, m_doom3Frustum.front, m_doom3Frustum.back)); - matrix4_multiply_by_matrix4(m_doom3Projection, test); - - m_doom3Frustum.left = plane3_normalised(m_doom3Frustum.left); - m_doom3Frustum.right = plane3_normalised(m_doom3Frustum.right); - m_doom3Frustum.bottom = plane3_normalised(m_doom3Frustum.bottom); - m_doom3Frustum.top = plane3_normalised(m_doom3Frustum.top); - m_doom3Frustum.back = plane3_normalised(m_doom3Frustum.back); - m_doom3Frustum.front = plane3_normalised(m_doom3Frustum.front); -#endif - //matrix4_scale_by_vec3(m_doom3Projection, Vector3(1.0 / 128, 1.0 / 128, 1.0 / 128)); - return m_doom3Projection; -} - -Shader *getShader() const -{ - return m_shader.get(); -} -}; - -class LightInstance : - public TargetableInstance, - public TransformModifier, - public Renderable, - public SelectionTestable, - public RendererLight, - public PlaneSelectable, - public ComponentSelectionTestable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceContainedCast::install(m_casts); - //InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -Light &m_contained; -DragPlanes m_dragPlanes; // dragplanes for lightresizing using mousedrag -public: -typedef LazyStatic StaticTypeCasts; - -Bounded &get(NullType) -{ - return m_contained; -} - -STRING_CONSTANT(Name, "LightInstance"); - -LightInstance(const scene::Path &path, scene::Instance *parent, Light &contained) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), - TransformModifier(Light::TransformChangedCaller(contained), ApplyTransformCaller(*this)), - m_contained(contained), - m_dragPlanes(SelectedChangedComponentCaller(*this)) -{ - m_contained.instanceAttach(Instance::path()); - StaticRenderableConnectionLines::instance().attach(*this); -} - -~LightInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_contained.testSelect(selector, test, Instance::localToWorld()); -} - -void selectPlanes(Selector &selector, SelectionTest &test, const PlaneCallback &selectedPlaneCallback) -{ - test.BeginMesh(localToWorld()); - m_dragPlanes.selectPlanes(m_contained.aabb(), selector, test, selectedPlaneCallback, rotation()); -} - -void selectReversedPlanes(Selector &selector, const SelectedPlanes &selectedPlanes) -{ - m_dragPlanes.selectReversedPlanes(m_contained.aabb(), selector, selectedPlanes, rotation()); -} - -bool isSelectedComponents() const -{ - return m_dragPlanes.isSelected(); -} - -void setSelectedComponents(bool select, SelectionSystem::EComponentMode mode) -{ - if (mode == SelectionSystem::eFace) { - m_dragPlanes.setSelected(false); - } -} - -void testSelectComponents(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) -{ -} - -void selectedChangedComponent(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); - GlobalSelectionSystem().onComponentSelection(*this, selectable); -} - -typedef MemberCaller SelectedChangedComponentCaller; - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - } else { - //globalOutputStream() << getTranslation() << "\n"; - - m_dragPlanes.m_bounds = m_contained.aabb(); - m_contained.setLightRadius(m_dragPlanes.evaluateResize(getTranslation(), rotation())); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; - -void lightChanged() -{ - GlobalShaderCache().changed(*this); -} - -typedef MemberCaller LightChangedCaller; - -Shader *getShader() const -{ - return m_contained.getShader(); -} - -const AABB &aabb() const -{ - return m_contained.aabb(); -} - -bool testAABB(const AABB &other) const -{ - return m_contained.testAABB(other); -} - -const Matrix4 &rotation() const -{ - return m_contained.rotation(); -} - -const Vector3 &offset() const -{ - return m_contained.offset(); -} - -const Vector3 &colour() const -{ - return m_contained.colour(); -} - -bool isProjected() const -{ - return m_contained.isProjected(); -} - -const Matrix4 &projection() const -{ - return m_contained.projection(); -} -}; - -class LightNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Light m_contained; - -void construct() -{ -} - -void destroy() -{ - -} - -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Editable &get(NullType) -{ - return m_contained; -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -LightNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -LightNode(const LightNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~LightNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new LightNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new LightInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -void Light_Construct() -{ - RenderLightRadiiFill::m_state = GlobalShaderCache().capture("$Q3MAP2_LIGHT_SPHERE"); - RenderLightCenter::m_state = GlobalShaderCache().capture("$BIGPOINT"); -} - -void Light_Destroy() -{ - GlobalShaderCache().release("$Q3MAP2_LIGHT_SPHERE"); - GlobalShaderCache().release("$BIGPOINT"); -} - -scene::Node &New_Light(EntityClass *eclass) -{ - return (new LightNode(eclass))->node(); -} diff --git a/plugins/entity/light.h b/plugins/entity/light.h deleted file mode 100644 index 81d9ff6..0000000 --- a/plugins/entity/light.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_LIGHT_H ) -#define INCLUDED_LIGHT_H - -namespace scene { -class Node; -} -class EntityClass; - -scene::Node &New_Light(EntityClass *eclass); - -void Light_Construct(); - -void Light_Destroy(); - -#endif diff --git a/plugins/entity/miscmodel.cpp b/plugins/entity/miscmodel.cpp deleted file mode 100644 index 7d69bad..0000000 --- a/plugins/entity/miscmodel.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief Represents the Quake3 misc_model entity. -/// -/// This entity displays the model specified in its "model" key. -/// The "origin", "angles" and "modelscale*" keys directly control the entity's local-to-parent transform. - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "eclasslib.h" -#include "render.h" -#include "pivot.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "scale.h" -#include "model.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" - -#include "entity.h" - -class PropStatic : - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -MatrixTransform m_transform; - -OriginKey m_originKey; -Vector3 m_origin; -AnglesKey m_anglesKey; -Vector3 m_angles; -ScaleKey m_scaleKey; -Vector3 m_scale; - -SingletonModel m_model; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -RenderablePivot m_renderOrigin; -RenderableNamedEntity m_renderName; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("model", SingletonModel::ModelChangedCaller(m_model)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey)); - m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey)); - m_keyObservers.insert("modelscale", ScaleKey::UniformScaleChangedCaller(m_scaleKey)); - m_keyObservers.insert("modelscale_vec", ScaleKey::ScaleChangedCaller(m_scaleKey)); -} - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_transform_by_euler_xyz_degrees(m_transform.localToParent(), m_origin, m_angles, m_scale); - m_transformChanged(); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void anglesChanged() -{ - m_angles = m_anglesKey.m_angles; - updateTransform(); -} - -typedef MemberCaller AnglesChangedCaller; - -void scaleChanged() -{ - m_scale = m_scaleKey.m_scale; - updateTransform(); -} - -typedef MemberCaller ScaleChangedCaller; -public: - -PropStatic(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_scaleKey(ScaleChangedCaller(*this)), - m_scale(SCALEKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -PropStatic(const PropStatic &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_scaleKey(ScaleChangedCaller(*this)), - m_scale(SCALEKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_model.getTraversable(); -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -void attach(scene::Traversable::Observer *observer) -{ - m_model.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_model.detach(observer); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - if (selected) { - m_renderOrigin.render(renderer, volume, localToWorld); - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderSolid(renderer, volume, localToWorld, selected); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - m_angles = angles_rotated(m_angles, rotation); -} - -void scale(const Vector3 &scaling) -{ - m_scale = scale_scaled(m_scale, scaling); -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - m_angles = m_anglesKey.m_angles; - m_scale = m_scaleKey.m_scale; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - m_anglesKey.m_angles = m_angles; - m_anglesKey.write(&m_entity); - m_scaleKey.m_scale = m_scale; - m_scaleKey.write(&m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class PropStaticInstance : public TargetableInstance, public TransformModifier, public Renderable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -PropStatic &m_contained; -public: -typedef LazyStatic StaticTypeCasts; - -STRING_CONSTANT(Name, "PropStaticInstance"); - -PropStaticInstance(const scene::Path &path, scene::Instance *parent, PropStatic &miscmodel) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), miscmodel.getEntity(), *this), - TransformModifier(PropStatic::TransformChangedCaller(miscmodel), ApplyTransformCaller(*this)), - m_contained(miscmodel) -{ - m_contained.instanceAttach(Instance::path()); - StaticRenderableConnectionLines::instance().attach(*this); -} - -~PropStaticInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - m_contained.scale(getScale()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class PropStaticNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -PropStatic m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -PropStaticNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -PropStaticNode(const PropStaticNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~PropStaticNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new PropStaticNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new PropStaticInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_PropStatic(EntityClass *eclass) -{ - return (new PropStaticNode(eclass))->node(); -} - -void PropStatic_construct() -{ -} - -void PropStatic_destroy() -{ -} diff --git a/plugins/entity/miscmodel.h b/plugins/entity/miscmodel.h deleted file mode 100644 index 7b0befe..0000000 --- a/plugins/entity/miscmodel.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MISCMODEL_H ) -#define INCLUDED_MISCMODEL_H - -scene::Node &New_PropStatic(EntityClass *eclass); - -void PropStatic_construct(); - -void PropStatic_destroy(); - -#endif diff --git a/plugins/entity/model.h b/plugins/entity/model.h deleted file mode 100644 index 114cad9..0000000 --- a/plugins/entity/model.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODEL_H ) -#define INCLUDED_MODEL_H - -#include "entitylib.h" -#include "traverselib.h" -#include "generic/callback.h" -#include "stream/stringstream.h" -#include "os/path.h" -#include "moduleobserver.h" - -class EModel : public ModuleObserver { -ResourceReference m_resource; -scene::Traversable &m_traverse; -scene::Node *m_node; -Callback m_modelChanged; - -public: -EModel(scene::Traversable &traversable, const Callback &modelChanged) - : m_resource(""), m_traverse(traversable), m_node(0), m_modelChanged(modelChanged) -{ - m_resource.attach(*this); -} - -~EModel() -{ - m_resource.detach(*this); -} - -void realise() -{ - m_resource.get()->load(); - m_node = m_resource.get()->getNode(); - if (m_node != 0) { - m_traverse.insert(*m_node); - } -} - -void unrealise() -{ - if (m_node != 0) { - m_traverse.erase(*m_node); - } -} - -void modelChanged(const char *value) -{ - StringOutputStream cleaned(string_length(value)); - cleaned << PathCleaned(value); - m_resource.detach(*this); - m_resource.setName(cleaned.c_str()); - m_resource.attach(*this); - m_modelChanged(); -} - -typedef MemberCaller ModelChangedCaller; - -const char *getName() const -{ - return m_resource.getName(); -} - -scene::Node *getNode() const -{ - return m_node; -} -}; - -class SingletonModel { -TraversableNode m_traverse; -EModel m_model; -public: -SingletonModel() - : m_model(m_traverse, Callback()) -{ -} - -void attach(scene::Traversable::Observer *observer) -{ - m_traverse.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_traverse.detach(observer); -} - -scene::Traversable &getTraversable() -{ - return m_traverse; -} - -void modelChanged(const char *value) -{ - m_model.modelChanged(value); -} - -typedef MemberCaller ModelChangedCaller; - -scene::Node *getNode() const -{ - return m_model.getNode(); -} -}; - -#endif diff --git a/plugins/entity/modelskinkey.h b/plugins/entity/modelskinkey.h deleted file mode 100644 index c995ac4..0000000 --- a/plugins/entity/modelskinkey.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODELSKINKEY_H ) -#define INCLUDED_MODELSKINKEY_H - -#include "modelskin.h" - -#include "os/path.h" -#include "stream/stringstream.h" -#include "moduleobserver.h" -#include "entitylib.h" -#include "traverselib.h" - -inline void parseTextureName(CopiedString &name, const char *token) -{ - StringOutputStream cleaned(256); - cleaned << PathCleaned(token); - name = StringRange(cleaned.c_str(), path_get_filename_base_end(cleaned.c_str())); // remove extension -} - -class ModelSkinKey : public ModuleObserver { -CopiedString m_name; -ModelSkin *m_skin; -Callback m_skinChangedCallback; - -ModelSkinKey(const ModelSkinKey &); - -ModelSkinKey operator=(const ModelSkinKey &); - -void construct() -{ - m_skin = &GlobalModelSkinCache().capture(m_name.c_str()); - m_skin->attach(*this); -} - -void destroy() -{ - m_skin->detach(*this); - GlobalModelSkinCache().release(m_name.c_str()); -} - -public: -ModelSkinKey(const Callback &skinChangedCallback) : m_skinChangedCallback(skinChangedCallback) -{ - construct(); -} - -~ModelSkinKey() -{ - destroy(); -} - -ModelSkin &get() const -{ - return *m_skin; -} - -void skinChanged(const char *value) -{ - destroy(); - parseTextureName(m_name, value); - construct(); -} - -typedef MemberCaller SkinChangedCaller; - -void realise() -{ - m_skinChangedCallback(); -} - -void unrealise() -{ -} -}; - -class InstanceSkinChanged : public scene::Instantiable::Visitor { -public: -void visit(scene::Instance &instance) const -{ - //\todo don't do this for instances that are not children of the entity setting the skin - SkinnedModel *skinned = InstanceTypeCast::cast(instance); - if (skinned != 0) { - skinned->skinChanged(); - } -} -}; - -inline void Node_modelSkinChanged(scene::Node &node) -{ - scene::Instantiable *instantiable = Node_getInstantiable(node); - ASSERT_NOTNULL(instantiable); - instantiable->forEachInstance(InstanceSkinChanged()); -} - -#endif diff --git a/plugins/entity/namedentity.h b/plugins/entity/namedentity.h deleted file mode 100644 index d3f6c0d..0000000 --- a/plugins/entity/namedentity.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_NAMEDENTITY_H ) -#define INCLUDED_NAMEDENTITY_H - -#include "entitylib.h" -#include "eclasslib.h" -#include "generic/callback.h" -#include "nameable.h" - -#include - -class NameCallbackSet { -typedef std::set NameCallbacks; -NameCallbacks m_callbacks; -public: -void insert(const NameCallback &callback) -{ - m_callbacks.insert(callback); -} - -void erase(const NameCallback &callback) -{ - m_callbacks.erase(callback); -} - -void changed(const char *name) const -{ - for (NameCallbacks::const_iterator i = m_callbacks.begin(); i != m_callbacks.end(); ++i) { - (*i)(name); - } -} -}; - -class NamedEntity : public Nameable { -EntityKeyValues &m_entity; -NameCallbackSet m_changed; -CopiedString m_name; -public: -NamedEntity(EntityKeyValues &entity) : m_entity(entity) -{ -} - -const char *name() const -{ - if (string_empty(m_name.c_str())) { - return m_entity.getEntityClass().name(); - } - return m_name.c_str(); -} - -void attach(const NameCallback &callback) -{ - m_changed.insert(callback); -} - -void detach(const NameCallback &callback) -{ - m_changed.erase(callback); -} - -void identifierChanged(const char *value) -{ - if (string_empty(value)) { - m_changed.changed(m_entity.getEntityClass().name()); - } else { - m_changed.changed(value); - } - m_name = value; -} - -typedef MemberCaller IdentifierChangedCaller; -}; - -class RenderableNamedEntity : public OpenGLRenderable { -const NamedEntity &m_named; -const Vector3 &m_position; -public: -RenderableNamedEntity(const NamedEntity &named, const Vector3 &position) - : m_named(named), m_position(position) -{ -} - -void render(RenderStateFlags state) const -{ - glRasterPos3fv(vector3_to_array(m_position)); - GlobalOpenGL().drawString(m_named.name()); -} -}; - - -#endif diff --git a/plugins/entity/namekeys.h b/plugins/entity/namekeys.h deleted file mode 100644 index f113338..0000000 --- a/plugins/entity/namekeys.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_NAMEKEYS_H ) -#define INCLUDED_NAMEKEYS_H - -#include -#include -#include "generic/static.h" -#include "entitylib.h" -#include "namespace.h" - -inline bool string_is_integer(const char *string) -{ - strtol(string, const_cast( &string ), 10); - return *string == '\0'; -} - -typedef bool ( *KeyIsNameFunc )(const char *key); - -class KeyIsName { -public: -KeyIsNameFunc m_keyIsName; -const char *m_nameKey; - -KeyIsName() -{ -} -}; - - -typedef MemberCaller KeyValueAssignCaller; -typedef MemberCaller KeyValueAttachCaller; -typedef MemberCaller KeyValueDetachCaller; - -class NameKeys : public Entity::Observer, public Namespaced { -Namespace *m_namespace; -EntityKeyValues &m_entity; -KeyIsNameFunc m_keyIsName; - -NameKeys(const NameKeys &other); - -NameKeys &operator=(const NameKeys &other); - -typedef std::map KeyValues; -KeyValues m_keyValues; - -void insertName(const char *key, EntityKeyValue &value) -{ - if (m_namespace != 0 && m_keyIsName(key)) { - //globalOutputStream() << "insert " << key << "\n"; - m_namespace->attach(KeyValueAssignCaller(value), KeyValueAttachCaller(value)); - } -} - -void eraseName(const char *key, EntityKeyValue &value) -{ - if (m_namespace != 0 && m_keyIsName(key)) { - //globalOutputStream() << "erase " << key << "\n"; - m_namespace->detach(KeyValueAssignCaller(value), KeyValueDetachCaller(value)); - } -} - -void insertAll() -{ - for (KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) { - insertName((*i).first.c_str(), *(*i).second); - } -} - -void eraseAll() -{ - for (KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) { - eraseName((*i).first.c_str(), *(*i).second); - } -} - -public: -NameKeys(EntityKeyValues &entity) : m_namespace(0), m_entity(entity), - m_keyIsName(Static::instance().m_keyIsName) -{ - m_entity.attach(*this); -} - -~NameKeys() -{ - m_entity.detach(*this); -} - -void setNamespace(Namespace &space) -{ - eraseAll(); - m_namespace = &space; - insertAll(); -} - -void setKeyIsName(KeyIsNameFunc keyIsName) -{ - eraseAll(); - m_keyIsName = keyIsName; - insertAll(); -} - -void insert(const char *key, EntityKeyValue &value) -{ - m_keyValues.insert(KeyValues::value_type(key, &value)); - insertName(key, value); -} - -void erase(const char *key, EntityKeyValue &value) -{ - eraseName(key, value); - m_keyValues.erase(key); -} -}; - -inline bool keyIsNameDoom3(const char *key) -{ - return string_equal(key, "target") - || (string_equal_n(key, "target", 6) && string_is_integer(key + 6)) - || string_equal(key, "name"); -} - -inline bool keyIsNameDoom3Doom3Group(const char *key) -{ - return keyIsNameDoom3(key) - || string_equal(key, "model"); -} - -inline bool keyIsNameQuake3(const char *key) -{ - return string_equal(key, "target") - || string_equal(key, "targetname") - || string_equal(key, "killtarget") - || (string_equal_n(key, "target", 6) && string_is_integer(key + 6)); // Nexuiz -} - -#endif diff --git a/plugins/entity/origin.h b/plugins/entity/origin.h deleted file mode 100644 index 2ac5522..0000000 --- a/plugins/entity/origin.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ORIGIN_H ) -#define INCLUDED_ORIGIN_H - -#include "ientity.h" - -#include "math/matrix.h" -#include "generic/callback.h" -#include "stringio.h" - -const Vector3 ORIGINKEY_IDENTITY = Vector3(0, 0, 0); - -inline void default_origin(Vector3 &origin) -{ - origin = ORIGINKEY_IDENTITY; -} - -inline void read_origin(Vector3 &origin, const char *value) -{ - if (!string_parse_vector3(value, origin)) { - default_origin(origin); - } -} - -inline void write_origin(const Vector3 &origin, Entity *entity, const char *key) -{ - char value[64]; - sprintf(value, "%f %f %f", origin[0], origin[1], origin[2]); - entity->setKeyValue(key, value); -} - -inline Vector3 origin_translated(const Vector3 &origin, const Vector3 &translation) -{ - return matrix4_get_translation_vec3( - matrix4_multiplied_by_matrix4( - matrix4_translation_for_vec3(origin), - matrix4_translation_for_vec3(translation) - ) - ); -} - -inline Vector3 origin_snapped(const Vector3 &origin, float snap) -{ - return vector3_snapped(origin, snap); -} - -class OriginKey { -Callback m_originChanged; -public: -Vector3 m_origin; - - -OriginKey(const Callback &originChanged) - : m_originChanged(originChanged), m_origin(ORIGINKEY_IDENTITY) -{ -} - -void originChanged(const char *value) -{ - read_origin(m_origin, value); - m_originChanged(); -} - -typedef MemberCaller OriginChangedCaller; - - -void write(Entity *entity) const -{ - write_origin(m_origin, entity, "origin"); -} -}; - - -#include "scenelib.h" - -inline BrushDoom3 *Node_getBrushDoom3(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -inline void BrushDoom3_setDoom3GroupOrigin(scene::Node &node, const Vector3 &origin) -{ - BrushDoom3 *brush = Node_getBrushDoom3(node); - if (brush != 0) { - brush->setDoom3GroupOrigin(origin); - } -} - -class SetDoom3GroupOriginWalker : public scene::Traversable::Walker { -const Vector3 &m_origin; -public: -SetDoom3GroupOriginWalker(const Vector3 &origin) : m_origin(origin) -{ -} - -bool pre(scene::Node &node) const -{ - BrushDoom3_setDoom3GroupOrigin(node, m_origin); - return true; -} -}; - -class Doom3GroupOrigin : public scene::Traversable::Observer { -scene::Traversable &m_set; -const Vector3 &m_origin; -bool m_enabled; - -public: -Doom3GroupOrigin(scene::Traversable &set, const Vector3 &origin) : m_set(set), m_origin(origin), m_enabled(false) -{ -} - -void enable() -{ - m_enabled = true; - originChanged(); -} - -void disable() -{ - m_enabled = false; -} - -void originChanged() -{ - if (m_enabled) { - m_set.traverse(SetDoom3GroupOriginWalker(m_origin)); - } -} - -void insert(scene::Node &node) -{ - if (m_enabled) { - BrushDoom3_setDoom3GroupOrigin(node, m_origin); - } -} - -void erase(scene::Node &node) -{ - if (m_enabled) { - BrushDoom3_setDoom3GroupOrigin(node, Vector3(0, 0, 0)); - } -} -}; - - -#endif diff --git a/plugins/entity/plugin.cpp b/plugins/entity/plugin.cpp deleted file mode 100644 index 3da9088..0000000 --- a/plugins/entity/plugin.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "debugging/debugging.h" - -#include "iscenegraph.h" -#include "irender.h" -#include "iselection.h" -#include "ientity.h" -#include "iundo.h" -#include "ieclass.h" -#include "igl.h" -#include "ireference.h" -#include "ifilter.h" -#include "preferencesystem.h" -#include "qerplugin.h" -#include "namespace.h" -#include "modelskin.h" - -#include "typesystem.h" - -#include "entity.h" -#include "skincache.h" - -#include "modulesystem/singletonmodule.h" - -class EntityDependencies : - public GlobalRadiantModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalReferenceModuleRef, - public GlobalFilterModuleRef, - public GlobalPreferenceSystemModuleRef, - public GlobalNamespaceModuleRef, - public GlobalModelSkinCacheModuleRef { -}; - -class EntityQ3API : public TypeSystemRef { -EntityCreator *m_entityq3; -public: -typedef EntityCreator Type; - -STRING_CONSTANT(Name, "quake3"); - -EntityQ3API() -{ - Entity_Construct(); - - m_entityq3 = &GetEntityCreator(); - - GlobalReferenceCache().setEntityCreator(*m_entityq3); -} - -~EntityQ3API() -{ - Entity_Destroy(); -} - -EntityCreator *getTable() -{ - return m_entityq3; -} -}; - -typedef SingletonModule EntityQ3Module; - -EntityQ3Module g_EntityQ3Module; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_EntityQ3Module.selfRegister(); - Doom3ModelSkinCacheModule_selfRegister(server); -} diff --git a/plugins/entity/prop_dynamic.cpp b/plugins/entity/prop_dynamic.cpp deleted file mode 100644 index 3bcde39..0000000 --- a/plugins/entity/prop_dynamic.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "cullable.h" -#include "renderable.h" -#include "editable.h" - -#include "selectionlib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "entitylib.h" -#include "eclasslib.h" -#include "render.h" -#include "pivot.h" - -#include "targetable.h" -#include "origin.h" -#include "angles.h" -#include "scale.h" -#include "model.h" -#include "filters.h" -#include "namedentity.h" -#include "keyobservers.h" -#include "namekeys.h" - -#include "entity.h" - -class PropDynamic : - public Snappable { -EntityKeyValues m_entity; -KeyObserverMap m_keyObservers; -MatrixTransform m_transform; - -OriginKey m_originKey; -Vector3 m_origin; -AnglesKey m_anglesKey; -Vector3 m_angles; -ScaleKey m_scaleKey; -Vector3 m_scale; - -SingletonModel m_model; - -ClassnameFilter m_filter; -NamedEntity m_named; -NameKeys m_nameKeys; -RenderablePivot m_renderOrigin; -RenderableNamedEntity m_renderName; - -Callback m_transformChanged; -Callback m_evaluateTransform; - -void construct() -{ - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("model", SingletonModel::ModelChangedCaller(m_model)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey)); - m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey)); - m_keyObservers.insert("modelscale", ScaleKey::UniformScaleChangedCaller(m_scaleKey)); - m_keyObservers.insert("modelscale_vec", ScaleKey::ScaleChangedCaller(m_scaleKey)); -} - -void updateTransform() -{ - m_transform.localToParent() = g_matrix4_identity; - matrix4_transform_by_euler_xyz_degrees(m_transform.localToParent(), m_origin, m_angles, m_scale); - m_transformChanged(); -} - -// vc 2k5 compiler fix -#if _MSC_VER >= 1400 -public: -#endif - -void originChanged() -{ - m_origin = m_originKey.m_origin; - updateTransform(); -} - -typedef MemberCaller OriginChangedCaller; - -void anglesChanged() -{ - m_angles = m_anglesKey.m_angles; - updateTransform(); -} - -typedef MemberCaller AnglesChangedCaller; - -void scaleChanged() -{ - m_scale = m_scaleKey.m_scale; - updateTransform(); -} - -typedef MemberCaller ScaleChangedCaller; -public: - -PropDynamic(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_scaleKey(ScaleChangedCaller(*this)), - m_scale(SCALEKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -PropDynamic(const PropDynamic &other, scene::Node &node, const Callback &transformChanged, - const Callback &evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_anglesKey(AnglesChangedCaller(*this)), - m_angles(ANGLESKEY_IDENTITY), - m_scaleKey(ScaleChangedCaller(*this)), - m_scale(SCALEKEY_IDENTITY), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_renderName(m_named, g_vector3_identity), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform) -{ - construct(); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_entity.attach(m_keyObservers); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_entity.detach(m_keyObservers); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } -} - -EntityKeyValues &getEntity() -{ - return m_entity; -} - -const EntityKeyValues &getEntity() const -{ - return m_entity; -} - -scene::Traversable &getTraversable() -{ - return m_model.getTraversable(); -} - -Namespaced &getNamespaced() -{ - return m_nameKeys; -} - -Nameable &getNameable() -{ - return m_named; -} - -TransformNode &getTransformNode() -{ - return m_transform; -} - -void attach(scene::Traversable::Observer *observer) -{ - m_model.attach(observer); -} - -void detach(scene::Traversable::Observer *observer) -{ - m_model.detach(observer); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - if (selected) { - m_renderOrigin.render(renderer, volume, localToWorld); - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const -{ - renderSolid(renderer, volume, localToWorld, selected); - if (g_showNames) { - renderer.addRenderable(m_renderName, localToWorld); - } -} - -void translate(const Vector3 &translation) -{ - m_origin = origin_translated(m_origin, translation); -} - -void rotate(const Quaternion &rotation) -{ - m_angles = angles_rotated(m_angles, rotation); -} - -void scale(const Vector3 &scaling) -{ - m_scale = scale_scaled(m_scale, scaling); -} - -void snapto(float snap) -{ - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); -} - -void revertTransform() -{ - m_origin = m_originKey.m_origin; - m_angles = m_anglesKey.m_angles; - m_scale = m_scaleKey.m_scale; -} - -void freezeTransform() -{ - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - m_anglesKey.m_angles = m_angles; - m_anglesKey.write(&m_entity); - m_scaleKey.m_scale = m_scale; - m_scaleKey.write(&m_entity); -} - -void transformChanged() -{ - revertTransform(); - m_evaluateTransform(); - updateTransform(); -} - -typedef MemberCaller TransformChangedCaller; -}; - -class PropDynamicInstance : public TargetableInstance, public TransformModifier, public Renderable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -PropDynamic &m_contained; -public: -typedef LazyStatic StaticTypeCasts; - -STRING_CONSTANT(Name, "PropDynamicInstance"); - -PropDynamicInstance(const scene::Path &path, scene::Instance *parent, PropDynamic &miscmodel) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), miscmodel.getEntity(), *this), - TransformModifier(PropDynamic::TransformChangedCaller(miscmodel), ApplyTransformCaller(*this)), - m_contained(miscmodel) -{ - m_contained.instanceAttach(Instance::path()); - StaticRenderableConnectionLines::instance().attach(*this); -} - -~PropDynamicInstance() -{ - StaticRenderableConnectionLines::instance().detach(*this); - m_contained.instanceDetach(Instance::path()); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); -} - -void evaluateTransform() -{ - if (getType() == TRANSFORM_PRIMITIVE) { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); - m_contained.scale(getScale()); - } -} - -void applyTransform() -{ - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; -}; - -class PropDynamicNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -PropDynamic m_contained; - -void construct() -{ - m_contained.attach(this); -} - -void destroy() -{ - m_contained.detach(this); -} - -public: -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_contained.getTraversable(); -} - -Snappable &get(NullType) -{ - return m_contained; -} - -TransformNode &get(NullType) -{ - return m_contained.getTransformNode(); -} - -Entity &get(NullType) -{ - return m_contained.getEntity(); -} - -Nameable &get(NullType) -{ - return m_contained.getNameable(); -} - -Namespaced &get(NullType) -{ - return m_contained.getNamespaced(); -} - -PropDynamicNode(EntityClass *eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -PropDynamicNode(const PropDynamicNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), - InstanceSetEvaluateTransform::Caller(m_instances)) -{ - construct(); -} - -~PropDynamicNode() -{ - destroy(); -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new PropDynamicNode(*this))->node(); -} - -void insert(scene::Node &child) -{ - m_instances.insert(child); -} - -void erase(scene::Node &child) -{ - m_instances.erase(child); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new PropDynamicInstance(path, parent, m_contained); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -scene::Node &New_PropDynamic(EntityClass *eclass) -{ - return (new PropDynamicNode(eclass))->node(); -} - -void PropDynamic_construct() -{ -} - -void PropDynamic_destroy() -{ -} diff --git a/plugins/entity/prop_dynamic.h b/plugins/entity/prop_dynamic.h deleted file mode 100644 index 56d30f5..0000000 --- a/plugins/entity/prop_dynamic.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PROPDYNAMIC_H ) -#define INCLUDED_PROPDYNAMIC_H - -scene::Node &New_PropDynamic(EntityClass *eclass); - -void PropDynamic_construct(); - -void PropDynamic_destroy(); - -#endif diff --git a/plugins/entity/rotation.h b/plugins/entity/rotation.h deleted file mode 100644 index 50aa953..0000000 --- a/plugins/entity/rotation.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ROTATION_H ) -#define INCLUDED_ROTATION_H - -#include "ientity.h" - -#include "stream/stringstream.h" -#include "math/quaternion.h" -#include "generic/callback.h" -#include "stringio.h" - -#include "angle.h" - -typedef float Float9[9]; - -inline void default_rotation(Float9 rotation) -{ - rotation[0] = 1; - rotation[1] = 0; - rotation[2] = 0; - rotation[3] = 0; - rotation[4] = 1; - rotation[5] = 0; - rotation[6] = 0; - rotation[7] = 0; - rotation[8] = 1; -} - -inline void write_rotation(const Float9 rotation, Entity *entity, const char *key = "rotation") -{ - if (rotation[0] == 1 - && rotation[1] == 0 - && rotation[2] == 0 - && rotation[3] == 0 - && rotation[4] == 1 - && rotation[5] == 0 - && rotation[6] == 0 - && rotation[7] == 0 - && rotation[8] == 1) { - entity->setKeyValue(key, ""); - } else { - StringOutputStream value(256); - value << rotation[0] << ' ' - << rotation[1] << ' ' - << rotation[2] << ' ' - << rotation[3] << ' ' - << rotation[4] << ' ' - << rotation[5] << ' ' - << rotation[6] << ' ' - << rotation[7] << ' ' - << rotation[8]; - entity->setKeyValue(key, value.c_str()); - } -} - -inline void read_rotation(Float9 rotation, const char *value) -{ - if (!string_parse_vector(value, rotation, rotation + 9)) { - default_rotation(rotation); - } -} - -inline Matrix4 rotation_toMatrix(const Float9 rotation) -{ - return Matrix4( - rotation[0], - rotation[1], - rotation[2], - 0, - rotation[3], - rotation[4], - rotation[5], - 0, - rotation[6], - rotation[7], - rotation[8], - 0, - 0, - 0, - 0, - 1 - ); -} - -inline void rotation_fromMatrix(Float9 rotation, const Matrix4 &matrix) -{ - rotation[0] = matrix.xx(); - rotation[1] = matrix.xy(); - rotation[2] = matrix.xz(); - rotation[3] = matrix.yx(); - rotation[4] = matrix.yy(); - rotation[5] = matrix.yz(); - rotation[6] = matrix.zx(); - rotation[7] = matrix.zy(); - rotation[8] = matrix.zz(); -} - -inline void rotation_assign(Float9 rotation, const Float9 other) -{ - rotation[0] = other[0]; - rotation[1] = other[1]; - rotation[2] = other[2]; - rotation[3] = other[3]; - rotation[4] = other[4]; - rotation[5] = other[5]; - rotation[6] = other[6]; - rotation[7] = other[7]; - rotation[8] = other[8]; -} - -inline void rotation_rotate(Float9 rotation, const Quaternion &rotate) -{ - rotation_fromMatrix(rotation, - matrix4_multiplied_by_matrix4( - rotation_toMatrix(rotation), - matrix4_rotation_for_quaternion_quantised(rotate) - ) - ); -} - -inline void read_angle(Float9 rotation, const char *value) -{ - float angle; - if (!string_parse_float(value, angle)) { - default_rotation(rotation); - } else { - rotation_fromMatrix(rotation, matrix4_rotation_for_z_degrees(angle)); - } -} - -class RotationKey { -Callback m_rotationChanged; -public: -Float9 m_rotation; - - -RotationKey(const Callback &rotationChanged) - : m_rotationChanged(rotationChanged) -{ - default_rotation(m_rotation); -} - -void angleChanged(const char *value) -{ - read_angle(m_rotation, value); - m_rotationChanged(); -} - -typedef MemberCaller AngleChangedCaller; - -void rotationChanged(const char *value) -{ - read_rotation(m_rotation, value); - m_rotationChanged(); -} - -typedef MemberCaller RotationChangedCaller; - -void write(Entity *entity) const -{ - Vector3 euler = matrix4_get_rotation_euler_xyz_degrees(rotation_toMatrix(m_rotation)); - if (euler[0] == 0 && euler[1] == 0) { - entity->setKeyValue("rotation", ""); - write_angle(euler[2], entity); - } else { - entity->setKeyValue("angle", ""); - write_rotation(m_rotation, entity); - } -} -}; - -#endif diff --git a/plugins/entity/scale.h b/plugins/entity/scale.h deleted file mode 100644 index 6f79b47..0000000 --- a/plugins/entity/scale.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SCALE_H ) -#define INCLUDED_SCALE_H - -#include "ientity.h" - -#include "math/matrix.h" -#include "generic/callback.h" -#include "stringio.h" - -const Vector3 SCALEKEY_IDENTITY = Vector3(1, 1, 1); - -inline void default_scale(Vector3 &scale) -{ - scale = SCALEKEY_IDENTITY; -} - -inline void read_scale(Vector3 &scalevec, const char *value) -{ - float scale; - if (!string_parse_float(value, scale) - || scale == 0) { - default_scale(scalevec); - } else { - scalevec = Vector3(scale, scale, scale); - } -} - -inline void read_scalevec(Vector3 &scale, const char *value) -{ - if (!string_parse_vector3(value, scale) - || scale[0] == 0 - || scale[1] == 0 - || scale[2] == 0) { - default_scale(scale); - } -} - -inline void write_scale(const Vector3 &scale, Entity *entity) -{ - if (scale[0] == 1 && scale[1] == 1 && scale[2] == 1) { - entity->setKeyValue("modelscale", ""); - entity->setKeyValue("modelscale_vec", ""); - } else { - char value[64]; - - if (scale[0] == scale[1] && scale[0] == scale[2]) { - sprintf(value, "%f", scale[0]); - entity->setKeyValue("modelscale_vec", ""); - entity->setKeyValue("modelscale", value); - } else { - sprintf(value, "%f %f %f", scale[0], scale[1], scale[2]); - entity->setKeyValue("modelscale", ""); - entity->setKeyValue("modelscale_vec", value); - } - } -} - -inline Vector3 scale_scaled(const Vector3 &scale, const Vector3 &scaling) -{ - return matrix4_get_scale_vec3( - matrix4_multiplied_by_matrix4( - matrix4_scale_for_vec3(scale), - matrix4_scale_for_vec3(scaling) - ) - ); -} - - -class ScaleKey { -Callback m_scaleChanged; -public: -Vector3 m_scale; - - -ScaleKey(const Callback &scaleChanged) - : m_scaleChanged(scaleChanged), m_scale(SCALEKEY_IDENTITY) -{ -} - -void uniformScaleChanged(const char *value) -{ - read_scale(m_scale, value); - m_scaleChanged(); -} - -typedef MemberCaller UniformScaleChangedCaller; - -void scaleChanged(const char *value) -{ - read_scalevec(m_scale, value); - m_scaleChanged(); -} - -typedef MemberCaller ScaleChangedCaller; - -void write(Entity *entity) const -{ - write_scale(m_scale, entity); -} -}; - - -#endif diff --git a/plugins/entity/skincache.cpp b/plugins/entity/skincache.cpp deleted file mode 100644 index 5ee747f..0000000 --- a/plugins/entity/skincache.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "skincache.h" - -#include "ifilesystem.h" -#include "iscriplib.h" -#include "iarchive.h" -#include "modelskin.h" - -#include - -#include "stream/stringstream.h" -#include "generic/callback.h" -#include "container/cache.h" -#include "container/hashfunc.h" -#include "os/path.h" -#include "moduleobservers.h" -#include "modulesystem/singletonmodule.h" -#include "stringio.h" - -void parseShaderName(CopiedString &name, const char *token) -{ - StringOutputStream cleaned(256); - cleaned << PathCleaned(token); - name = cleaned.c_str(); -} - -class Doom3ModelSkin { -typedef std::map Remaps; -Remaps m_remaps; -public: -bool parseTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "{")); - tokeniser.nextLine(); - for (;;) { - const char *token = tokeniser.getToken(); - if (token == 0) { - return false; - } - if (string_equal(token, "}")) { - tokeniser.nextLine(); - return true; - } else if (string_equal(token, "model")) { - //const char* model = - tokeniser.getToken(); - } else { - CopiedString from, to; - parseShaderName(from, token); - - tokeniser.nextLine(); // hack to handle badly formed skins - - parseShaderName(to, tokeniser.getToken()); - - if (!string_equal(from.c_str(), to.c_str())) { - m_remaps.insert(Remaps::value_type(from, to)); - } - } - tokeniser.nextLine(); - } -} - -const char *getRemap(const char *name) const -{ - Remaps::const_iterator i = m_remaps.find(name); - if (i != m_remaps.end()) { - return (*i).second.c_str(); - } - return ""; -} - -void forEachRemap(const SkinRemapCallback &callback) const -{ - for (Remaps::const_iterator i = m_remaps.begin(); i != m_remaps.end(); ++i) { - callback(SkinRemap((*i).first.c_str(), (*i).second.c_str())); - } -} -}; - -class GlobalSkins { -public: -typedef std::map SkinMap; -SkinMap m_skins; -Doom3ModelSkin g_nullSkin; - -Doom3ModelSkin &getSkin(const char *name) -{ - SkinMap::iterator i = m_skins.find(name); - if (i != m_skins.end()) { - return (*i).second; - } - - return g_nullSkin; -} - -bool parseTokens(Tokeniser &tokeniser) -{ - tokeniser.nextLine(); - for (;;) { - const char *token = tokeniser.getToken(); - if (token == 0) { - // end of token stream - return true; - } - if (!string_equal(token, "skin")) { - Tokeniser_unexpectedError(tokeniser, token, "skin"); - return false; - } - const char *other = tokeniser.getToken(); - if (other == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#string"); - return false; - } - CopiedString name; - parseShaderName(name, other); - Doom3ModelSkin &skin = m_skins[name]; - RETURN_FALSE_IF_FAIL(skin.parseTokens(tokeniser)); - } -} - -void parseFile(const char *name) -{ - StringOutputStream relativeName(64); - relativeName << "skins/" << name; - ArchiveTextFile *file = GlobalFileSystem().openTextFile(relativeName.c_str()); - if (file != 0) { - globalOutputStream() << "parsing skins from " << makeQuoted(name) << "\n"; - { - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(file->getInputStream()); - parseTokens(tokeniser); - tokeniser.release(); - } - file->release(); - } else { - globalErrorStream() << "failed to open " << makeQuoted(name) << "\n"; - } -} - -typedef MemberCaller ParseFileCaller; - -void construct() -{ - GlobalFileSystem().forEachFile("skins/", "skin", ParseFileCaller(*this)); -} - -void destroy() -{ - m_skins.clear(); -} - -void realise() -{ - construct(); -} - -void unrealise() -{ - destroy(); -} -}; - -GlobalSkins g_skins; - - -class Doom3ModelSkinCacheElement : public ModelSkin { -ModuleObservers m_observers; -Doom3ModelSkin *m_skin; -public: -Doom3ModelSkinCacheElement() : m_skin(0) -{ -} - -void attach(ModuleObserver &observer) -{ - m_observers.attach(observer); - if (realised()) { - observer.realise(); - } -} - -void detach(ModuleObserver &observer) -{ - if (realised()) { - observer.unrealise(); - } - m_observers.detach(observer); -} - -bool realised() const -{ - return m_skin != 0; -} - -void realise(const char *name) -{ - ASSERT_MESSAGE(!realised(), "Doom3ModelSkinCacheElement::realise: already realised"); - m_skin = &g_skins.getSkin(name); - m_observers.realise(); -} - -void unrealise() -{ - ASSERT_MESSAGE(realised(), "Doom3ModelSkinCacheElement::unrealise: not realised"); - m_observers.unrealise(); - m_skin = 0; -} - -const char *getRemap(const char *name) const -{ - ASSERT_MESSAGE(realised(), "Doom3ModelSkinCacheElement::getRemap: not realised"); - return m_skin->getRemap(name); -} - -void forEachRemap(const SkinRemapCallback &callback) const -{ - ASSERT_MESSAGE(realised(), "Doom3ModelSkinCacheElement::forEachRemap: not realised"); - m_skin->forEachRemap(callback); -} -}; - -class Doom3ModelSkinCache : public ModelSkinCache, public ModuleObserver { -class CreateDoom3ModelSkin { -Doom3ModelSkinCache &m_cache; -public: -explicit CreateDoom3ModelSkin(Doom3ModelSkinCache &cache) - : m_cache(cache) -{ -} - -Doom3ModelSkinCacheElement *construct(const CopiedString &name) -{ - Doom3ModelSkinCacheElement *skin = new Doom3ModelSkinCacheElement; - if (m_cache.realised()) { - skin->realise(name.c_str()); - } - return skin; -} - -void destroy(Doom3ModelSkinCacheElement *skin) -{ - if (m_cache.realised()) { - skin->unrealise(); - } - delete skin; -} -}; - -typedef HashedCache, CreateDoom3ModelSkin> Cache; -Cache m_cache; -bool m_realised; - -public: -typedef ModelSkinCache Type; - -STRING_CONSTANT(Name, "*"); - -ModelSkinCache *getTable() -{ - return this; -} - -Doom3ModelSkinCache() : m_cache(CreateDoom3ModelSkin(*this)), m_realised(false) -{ - GlobalFileSystem().attach(*this); -} - -~Doom3ModelSkinCache() -{ - GlobalFileSystem().detach(*this); -} - -ModelSkin &capture(const char *name) -{ - return *m_cache.capture(name); -} - -void release(const char *name) -{ - m_cache.release(name); -} - -bool realised() const -{ - return m_realised; -} - -void realise() -{ - g_skins.realise(); - m_realised = true; - for (Cache::iterator i = m_cache.begin(); i != m_cache.end(); ++i) { - (*i).value->realise((*i).key.c_str()); - } -} - -void unrealise() -{ - m_realised = false; - for (Cache::iterator i = m_cache.begin(); i != m_cache.end(); ++i) { - (*i).value->unrealise(); - } - g_skins.unrealise(); -} -}; - -class Doom3ModelSkinCacheDependencies : public GlobalFileSystemModuleRef, public GlobalScripLibModuleRef { -}; - -typedef SingletonModule Doom3ModelSkinCacheModule; - -Doom3ModelSkinCacheModule g_Doom3ModelSkinCacheModule; - -void Doom3ModelSkinCacheModule_selfRegister(ModuleServer &server) -{ - g_Doom3ModelSkinCacheModule.selfRegister(); -} diff --git a/plugins/entity/skincache.h b/plugins/entity/skincache.h deleted file mode 100644 index 7970843..0000000 --- a/plugins/entity/skincache.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SKINCACHE_H ) -#define INCLUDED_SKINCACHE_H - -class ModuleServer; - -void Doom3ModelSkinCacheModule_selfRegister(ModuleServer &server); - -#endif diff --git a/plugins/entity/targetable.cpp b/plugins/entity/targetable.cpp deleted file mode 100644 index 16d2bcd..0000000 --- a/plugins/entity/targetable.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "targetable.h" - -typedef std::map targetnames_t; - -const char *g_targetable_nameKey = "targetname"; - -targetnames_t g_targetnames; - -targetables_t *getTargetables(const char *targetname) -{ - if (targetname[0] == '\0') { - return 0; - } - return &g_targetnames[targetname]; -} - -Shader *RenderableTargetingEntity::m_state; diff --git a/plugins/entity/targetable.h b/plugins/entity/targetable.h deleted file mode 100644 index d6df314..0000000 --- a/plugins/entity/targetable.h +++ /dev/null @@ -1,451 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TARGETABLE_H ) -#define INCLUDED_TARGETABLE_H - -#include -#include - -#include "cullable.h" -#include "renderable.h" - -#include "math/line.h" -#include "render.h" -#include "generic/callback.h" -#include "selectionlib.h" -#include "entitylib.h" -#include "eclasslib.h" -#include "stringio.h" - -class Targetable { -public: -virtual const Vector3 &world_position() const = 0; -}; - -typedef std::set targetables_t; - -extern const char *g_targetable_nameKey; - -targetables_t *getTargetables(const char *targetname); - -class EntityConnectionLine : public OpenGLRenderable { -public: -Vector3 start; -Vector3 end; - -void render(RenderStateFlags state) const -{ - float s1[2], s2[2]; - Vector3 dir(vector3_subtracted(end, start)); - double len = vector3_length(dir); - vector3_scale(dir, 8.0 * (1.0 / len)); - s1[0] = dir[0] - dir[1]; - s1[1] = dir[0] + dir[1]; - s2[0] = dir[0] + dir[1]; - s2[1] = -dir[0] + dir[1]; - - glBegin(GL_LINES); - - glVertex3fv(vector3_to_array(start)); - glVertex3fv(vector3_to_array(end)); - - len *= 0.0625; // half / 8 - - Vector3 arrow(start); - for (unsigned int i = 0, count = (len < 32) ? 1 : static_cast( len * 0.0625 ); i < count; i++) { - vector3_add(arrow, vector3_scaled(dir, (len < 32) ? len : 32)); - glVertex3fv(vector3_to_array(arrow)); - glVertex3f(arrow[0] + s1[0], arrow[1] + s1[1], arrow[2] + dir[2]); - glVertex3fv(vector3_to_array(arrow)); - glVertex3f(arrow[0] + s2[0], arrow[1] + s2[1], arrow[2] + dir[2]); - } - - glEnd(); -} -}; - -class TargetedEntity { -Targetable &m_targetable; -targetables_t *m_targets; - -void construct() -{ - if (m_targets != 0) { - m_targets->insert(&m_targetable); - } -} - -void destroy() -{ - if (m_targets != 0) { - m_targets->erase(&m_targetable); - } -} - -public: -TargetedEntity(Targetable &targetable) - : m_targetable(targetable), m_targets(getTargetables("")) -{ - construct(); -} - -~TargetedEntity() -{ - destroy(); -} - -void targetnameChanged(const char *name) -{ - destroy(); - m_targets = getTargetables(name); - construct(); -} - -typedef MemberCaller TargetnameChangedCaller; -}; - - -class TargetingEntity { -targetables_t *m_targets; -public: -TargetingEntity() : - m_targets(getTargetables("")) -{ -} - -void targetChanged(const char *target) -{ - m_targets = getTargetables(target); -} - -typedef MemberCaller TargetChangedCaller; - -typedef targetables_t::iterator iterator; - -iterator begin() const -{ - if (m_targets == 0) { - return iterator(); - } - return m_targets->begin(); -} - -iterator end() const -{ - if (m_targets == 0) { - return iterator(); - } - return m_targets->end(); -} - -size_t size() const -{ - if (m_targets == 0) { - return 0; - } - return m_targets->size(); -} - -bool empty() const -{ - return m_targets == 0 || m_targets->empty(); -} -}; - - -template -void TargetingEntity_forEach(const TargetingEntity &targets, const Functor &functor) -{ - for (TargetingEntity::iterator i = targets.begin(); i != targets.end(); ++i) { - functor((*i)->world_position()); - } -} - -typedef std::map TargetingEntities; - -template -void TargetingEntities_forEach(const TargetingEntities &targetingEntities, const Functor &functor) -{ - for (TargetingEntities::const_iterator i = targetingEntities.begin(); i != targetingEntities.end(); ++i) { - TargetingEntity_forEach((*i).second, functor); - } -} - -class TargetLinesPushBack { -RenderablePointVector &m_targetLines; -const Vector3 &m_worldPosition; -const VolumeTest &m_volume; -public: -TargetLinesPushBack(RenderablePointVector &targetLines, const Vector3 &worldPosition, const VolumeTest &volume) : - m_targetLines(targetLines), m_worldPosition(worldPosition), m_volume(volume) -{ -} - -void operator()(const Vector3 &worldPosition) const -{ - if (m_volume.TestLine(segment_for_startend(m_worldPosition, worldPosition))) { - m_targetLines.push_back(PointVertex(reinterpret_cast( m_worldPosition ))); - m_targetLines.push_back(PointVertex(reinterpret_cast( worldPosition ))); - } -} -}; - -class TargetKeys : public Entity::Observer { -TargetingEntities m_targetingEntities; -Callback m_targetsChanged; - -bool readTargetKey(const char *key, std::size_t &index) -{ - if (string_equal_n(key, "target", 6)) { - index = 0; - if (string_empty(key + 6) || string_parse_size(key + 6, index)) { - return true; - } - } - if (string_equal(key, "killtarget")) { - index = -1; - return true; - } - return false; -} - -public: -void setTargetsChanged(const Callback &targetsChanged) -{ - m_targetsChanged = targetsChanged; -} - -void targetsChanged() -{ - m_targetsChanged(); -} - -void insert(const char *key, EntityKeyValue &value) -{ - std::size_t index; - if (readTargetKey(key, index)) { - TargetingEntities::iterator i = m_targetingEntities.insert( - TargetingEntities::value_type(index, TargetingEntity())).first; - value.attach(TargetingEntity::TargetChangedCaller((*i).second)); - targetsChanged(); - } -} - -void erase(const char *key, EntityKeyValue &value) -{ - std::size_t index; - if (readTargetKey(key, index)) { - TargetingEntities::iterator i = m_targetingEntities.find(index); - value.detach(TargetingEntity::TargetChangedCaller((*i).second)); - m_targetingEntities.erase(i); - targetsChanged(); - } -} - -const TargetingEntities &get() const -{ - return m_targetingEntities; -} -}; - - -class RenderableTargetingEntity { -TargetingEntity &m_targets; -mutable RenderablePointVector m_target_lines; -public: -static Shader *m_state; - -RenderableTargetingEntity(TargetingEntity &targets) - : m_targets(targets), m_target_lines(GL_LINES) -{ -} - -void compile(const VolumeTest &volume, const Vector3 &world_position) const -{ - m_target_lines.clear(); - m_target_lines.reserve(m_targets.size() * 2); - TargetingEntity_forEach(m_targets, TargetLinesPushBack(m_target_lines, world_position, volume)); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Vector3 &world_position) const -{ - if (!m_targets.empty()) { - compile(volume, world_position); - if (!m_target_lines.empty()) { - renderer.addRenderable(m_target_lines, g_matrix4_identity); - } - } -} -}; - -class RenderableTargetingEntities { -const TargetingEntities &m_targets; -mutable RenderablePointVector m_target_lines; -public: -static Shader *m_state; - -RenderableTargetingEntities(const TargetingEntities &targets) - : m_targets(targets), m_target_lines(GL_LINES) -{ -} - -void compile(const VolumeTest &volume, const Vector3 &world_position) const -{ - m_target_lines.clear(); - TargetingEntities_forEach(m_targets, TargetLinesPushBack(m_target_lines, world_position, volume)); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Vector3 &world_position) const -{ - if (!m_targets.empty()) { - compile(volume, world_position); - if (!m_target_lines.empty()) { - renderer.addRenderable(m_target_lines, g_matrix4_identity); - } - } -} -}; - - -class TargetableInstance : - public SelectableInstance, - public Targetable, - public Entity::Observer { -mutable Vertex3f m_position; -EntityKeyValues &m_entity; -TargetKeys m_targeting; -TargetedEntity m_targeted; -RenderableTargetingEntities m_renderable; -public: - -TargetableInstance( - const scene::Path &path, - scene::Instance *parent, - void *instance, - InstanceTypeCastTable &casts, - EntityKeyValues &entity, - Targetable &targetable - ) : - SelectableInstance(path, parent, instance, casts), - m_entity(entity), - m_targeted(targetable), - m_renderable(m_targeting.get()) -{ - m_entity.attach(*this); - m_entity.attach(m_targeting); -} - -~TargetableInstance() -{ - m_entity.detach(m_targeting); - m_entity.detach(*this); -} - -void setTargetsChanged(const Callback &targetsChanged) -{ - m_targeting.setTargetsChanged(targetsChanged); -} - -void targetsChanged() -{ - m_targeting.targetsChanged(); -} - -void insert(const char *key, EntityKeyValue &value) -{ - if (string_equal(key, g_targetable_nameKey)) { - value.attach(TargetedEntity::TargetnameChangedCaller(m_targeted)); - } -} - -void erase(const char *key, EntityKeyValue &value) -{ - if (string_equal(key, g_targetable_nameKey)) { - value.detach(TargetedEntity::TargetnameChangedCaller(m_targeted)); - } -} - -const Vector3 &world_position() const -{ -#if 1 - const AABB &bounds = Instance::worldAABB(); - if (aabb_valid(bounds)) { - return bounds.origin; - } -#else - const AABB& childBounds = Instance::childBounds(); - if ( aabb_valid( childBounds ) ) { - return childBounds.origin; - } -#endif - return vector4_to_vector3(localToWorld().t()); -} - -void render(Renderer &renderer, const VolumeTest &volume) const -{ - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials); - m_renderable.render(renderer, volume, world_position()); -} - -const TargetingEntities &getTargeting() const -{ - return m_targeting.get(); -} -}; - - -class RenderableConnectionLines : public Renderable { -typedef std::set TargetableInstances; -TargetableInstances m_instances; -public: -void attach(TargetableInstance &instance) -{ - ASSERT_MESSAGE(m_instances.find(&instance) == m_instances.end(), "cannot attach instance"); - m_instances.insert(&instance); -} - -void detach(TargetableInstance &instance) -{ - ASSERT_MESSAGE(m_instances.find(&instance) != m_instances.end(), "cannot detach instance"); - m_instances.erase(&instance); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - for (TargetableInstances::const_iterator i = m_instances.begin(); i != m_instances.end(); ++i) { - if ((*i)->path().top().get().visible()) { - (*i)->render(renderer, volume); - } - } -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} -}; - -typedef Static StaticRenderableConnectionLines; - -#endif diff --git a/plugins/image/Makefile b/plugins/image/Makefile deleted file mode 100644 index 7b8c863..0000000 --- a/plugins/image/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -JPEG_CFLAGS=$(shell pkg-config --cflags libjpeg) -JPEG_LDFLAGS=$(shell pkg-config --libs libjpeg) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) $(JPEG_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) $(JPEG_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - bmp.o dds.o image.o jpeg.o ktx.o pcx.o tga.o - -# binary target -../../build/plugins/libimage.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libddslib.a ../../libs/libetclib.a $(PLUGIN_LDFLAGS) - -# object files -bmp.o: bmp.cpp bmp.h -dds.o: dds.cpp dds.h -image.o: image.cpp -jpeg.o: jpeg.cpp jpeg.h -ktx.o: ktx.cpp ktx.h -pcx.o: pcx.cpp pcx.h -tga.o: tga.cpp tga.h - -clean: - -rm -f *.o ../../build/plugins/libimage.$(LIB_EXT) diff --git a/plugins/image/bmp.cpp b/plugins/image/bmp.cpp deleted file mode 100644 index a89bb63..0000000 --- a/plugins/image/bmp.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "bmp.h" - -#include "ifilesystem.h" - -typedef unsigned char byte; - -#include "imagelib.h" -#include "bytestreamutils.h" - - -typedef unsigned char PaletteEntry[4]; -typedef struct { - char id[2]; - unsigned long fileSize; - unsigned long reserved0; - unsigned long bitmapDataOffset; - unsigned long bitmapHeaderSize; - unsigned long width; - unsigned long height; - unsigned short planes; - unsigned short bitsPerPixel; - unsigned long compression; - unsigned long bitmapDataSize; - unsigned long hRes; - unsigned long vRes; - unsigned long colors; - unsigned long importantColors; - PaletteEntry palette[256]; -} BMPHeader_t; - -class ReadPixel8 { -PaletteEntry *m_palette; -public: -ReadPixel8(PaletteEntry *palette) : m_palette(palette) -{ -} - -void operator()(PointerInputStream &inputStream, byte *&pixbuf) const -{ - byte palIndex; - inputStream.read(&palIndex, 1); - *pixbuf++ = m_palette[palIndex][2]; - *pixbuf++ = m_palette[palIndex][1]; - *pixbuf++ = m_palette[palIndex][0]; - *pixbuf++ = 0xff; -} -}; - -class ReadPixel16 { -public: -void operator()(PointerInputStream &inputStream, byte *&pixbuf) const -{ - unsigned short shortPixel; - inputStream.read(reinterpret_cast( &shortPixel ), sizeof(unsigned short)); //!\todo Is this endian safe? - *pixbuf++ = static_cast( shortPixel & (31 << 10)) >> 7; - *pixbuf++ = static_cast( shortPixel & (31 << 5)) >> 2; - *pixbuf++ = static_cast( shortPixel & (31)) << 3; - *pixbuf++ = 0xff; -} -}; - -class ReadPixel24 { -public: -void operator()(PointerInputStream &inputStream, byte *&pixbuf) const -{ - byte bgr[3]; - inputStream.read(bgr, 3); - *pixbuf++ = bgr[2]; - *pixbuf++ = bgr[1]; - *pixbuf++ = bgr[0]; - *pixbuf++ = 255; -} -}; - -class ReadPixel32 { -public: -void operator()(PointerInputStream &inputStream, byte *&pixbuf) const -{ - byte bgra[4]; - inputStream.read(bgra, 4); - *pixbuf++ = bgra[2]; - *pixbuf++ = bgra[1]; - *pixbuf++ = bgra[0]; - *pixbuf++ = bgra[3]; -} -}; - -template -void ReadBMP(PointerInputStream &inputStream, byte *bmpRGBA, int rows, int columns, ReadPixel readPixel) -{ - for (int row = rows - 1; row >= 0; row--) { - byte *pixbuf = bmpRGBA + row * columns * 4; - - for (int column = 0; column < columns; column++) { - readPixel(inputStream, pixbuf); - } - } -} - -Image *LoadBMPBuff(PointerInputStream &inputStream, std::size_t length) -{ - BMPHeader_t bmpHeader; - inputStream.read(reinterpret_cast( bmpHeader.id ), 2); - bmpHeader.fileSize = istream_read_uint32_le(inputStream); - bmpHeader.reserved0 = istream_read_uint32_le(inputStream); - bmpHeader.bitmapDataOffset = istream_read_uint32_le(inputStream); - bmpHeader.bitmapHeaderSize = istream_read_uint32_le(inputStream); - bmpHeader.width = istream_read_uint32_le(inputStream); - bmpHeader.height = istream_read_uint32_le(inputStream); - bmpHeader.planes = istream_read_uint16_le(inputStream); - bmpHeader.bitsPerPixel = istream_read_uint16_le(inputStream); - bmpHeader.compression = istream_read_uint32_le(inputStream); - bmpHeader.bitmapDataSize = istream_read_uint32_le(inputStream); - bmpHeader.hRes = istream_read_uint32_le(inputStream); - bmpHeader.vRes = istream_read_uint32_le(inputStream); - bmpHeader.colors = istream_read_uint32_le(inputStream); - bmpHeader.importantColors = istream_read_uint32_le(inputStream); - - if (bmpHeader.bitsPerPixel == 8) { - int paletteSize = bmpHeader.colors * 4; - inputStream.read(reinterpret_cast( bmpHeader.palette ), paletteSize); - } - - if (bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M') { - globalErrorStream() << "LoadBMP: only Windows-style BMP files supported\n"; - return 0; - } - if (bmpHeader.fileSize != length) { - globalErrorStream() << "LoadBMP: header size does not match file size (" << Unsigned(bmpHeader.fileSize) - << " vs. " << Unsigned(length) << ")\n"; - return 0; - } - if (bmpHeader.compression != 0) { - globalErrorStream() << "LoadBMP: only uncompressed BMP files supported\n"; - return 0; - } - if (bmpHeader.bitsPerPixel < 8) { - globalErrorStream() << "LoadBMP: monochrome and 4-bit BMP files not supported\n"; - return 0; - } - - int columns = bmpHeader.width; - int rows = bmpHeader.height; - if (rows < 0) { - rows = -rows; - } - - RGBAImage *image = new RGBAImage(columns, rows); - - switch (bmpHeader.bitsPerPixel) { - case 8: - ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel8(bmpHeader.palette)); - break; - case 16: - ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel16()); - break; - case 24: - ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel24()); - break; - case 32: - ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel32()); - break; - default: - globalErrorStream() << "LoadBMP: illegal pixel_size '" << bmpHeader.bitsPerPixel << "'\n"; - image->release(); - return 0; - } - return image; -} - -Image *LoadBMP(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - PointerInputStream inputStream(buffer.buffer); - return LoadBMPBuff(inputStream, buffer.length); -} diff --git a/plugins/image/bmp.h b/plugins/image/bmp.h deleted file mode 100644 index 043c289..0000000 --- a/plugins/image/bmp.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_BMP_H ) -#define INCLUDED_BMP_H - -class Image; - -class ArchiveFile; - -Image *LoadBMP(ArchiveFile &file); - -#endif diff --git a/plugins/image/dds.cpp b/plugins/image/dds.cpp deleted file mode 100644 index 09d3649..0000000 --- a/plugins/image/dds.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dds.h" - -#include - -#include "ifilesystem.h" -#include "iarchive.h" -#include "idatastream.h" - -#include "ddslib.h" -#include "imagelib.h" - -Image *LoadDDSBuff(const byte *buffer) -{ - int width, height; - ddsPF_t pixelFormat; - if (DDSGetInfo(reinterpret_cast( const_cast( buffer )), &width, &height, &pixelFormat) == - -1) { - return 0; - } - - RGBAImage *image = new RGBAImage(width, height); - - if (DDSDecompress(reinterpret_cast( const_cast( buffer )), image->getRGBAPixels()) == -1) { - image->release(); - return 0; - } - return image; -} - -Image *LoadDDS(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - return LoadDDSBuff(buffer.buffer); -} diff --git a/plugins/image/dds.h b/plugins/image/dds.h deleted file mode 100644 index 5e65831..0000000 --- a/plugins/image/dds.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_DDS_H ) -#define INCLUDED_DDS_H - -class Image; - -class ArchiveFile; - -Image *LoadDDS(ArchiveFile &file); - -#endif diff --git a/plugins/image/image.cpp b/plugins/image/image.cpp deleted file mode 100644 index 9458c5b..0000000 --- a/plugins/image/image.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ifilesystem.h" -#include "iimage.h" - -#include "jpeg.h" -#include "tga.h" -#include "bmp.h" -#include "pcx.h" -#include "dds.h" -#include "ktx.h" - - -#include "modulesystem/singletonmodule.h" - -class ImageDependencies : public GlobalFileSystemModuleRef { -}; - -class ImageTGAAPI { -_QERPlugImageTable m_imagetga; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "tga"); - -ImageTGAAPI() -{ - m_imagetga.loadImage = LoadTGA; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagetga; -} -}; - -typedef SingletonModule ImageTGAModule; - -ImageTGAModule g_ImageTGAModule; - - -class ImageJPGAPI { -_QERPlugImageTable m_imagejpg; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "jpg"); - -ImageJPGAPI() -{ - m_imagejpg.loadImage = LoadJPG; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagejpg; -} -}; - -typedef SingletonModule ImageJPGModule; - -ImageJPGModule g_ImageJPGModule; - - -class ImageBMPAPI { -_QERPlugImageTable m_imagebmp; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "bmp"); - -ImageBMPAPI() -{ - m_imagebmp.loadImage = LoadBMP; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagebmp; -} -}; - -typedef SingletonModule ImageBMPModule; - -ImageBMPModule g_ImageBMPModule; - - -class ImagePCXAPI { -_QERPlugImageTable m_imagepcx; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "pcx"); - -ImagePCXAPI() -{ - m_imagepcx.loadImage = LoadPCX32; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagepcx; -} -}; - -typedef SingletonModule ImagePCXModule; - -ImagePCXModule g_ImagePCXModule; - - -class ImageDDSAPI { -_QERPlugImageTable m_imagedds; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "dds"); - -ImageDDSAPI() -{ - m_imagedds.loadImage = LoadDDS; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagedds; -} -}; - -typedef SingletonModule ImageDDSModule; - -ImageDDSModule g_ImageDDSModule; - - -class ImageKTXAPI { -_QERPlugImageTable m_imagektx; -public: -typedef _QERPlugImageTable Type; - -STRING_CONSTANT(Name, "ktx"); - -ImageKTXAPI() -{ - m_imagektx.loadImage = LoadKTX; -} - -_QERPlugImageTable *getTable() -{ - return &m_imagektx; -} -}; - -typedef SingletonModule ImageKTXModule; - -ImageKTXModule g_ImageKTXModule; - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_ImageTGAModule.selfRegister(); - g_ImageJPGModule.selfRegister(); - g_ImageBMPModule.selfRegister(); - g_ImagePCXModule.selfRegister(); - g_ImageDDSModule.selfRegister(); - g_ImageKTXModule.selfRegister(); -} diff --git a/plugins/image/jpeg.cpp b/plugins/image/jpeg.cpp deleted file mode 100644 index a91fa5e..0000000 --- a/plugins/image/jpeg.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Functions to load JPEG files from a buffer, based on jdatasrc.c -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "jpeg.h" - -#include -#include -#include -#include - -extern "C" { -#include -#include -} - -#include "ifilesystem.h" - -#include "imagelib.h" - -typedef unsigned char byte; - -/* Expanded data source object for stdio input */ - -typedef struct { - struct jpeg_source_mgr pub; /* public fields */ - - int src_size; - JOCTET *src_buffer; - - JOCTET *buffer; /* start of buffer */ - boolean start_of_file; /* have we gotten any data yet? */ -} my_source_mgr; - -typedef my_source_mgr *my_src_ptr; - -const int INPUT_BUF_SIZE = 4096; /* choose an efficiently fread'able size */ - - -/* - * Initialize source --- called by jpeg_read_header - * before any data is actually read. - */ - -static void my_init_source(j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* We reset the empty-input-file flag for each image, - * but we don't clear the input buffer. - * This is correct behavior for reading a series of images from one source. - */ - src->start_of_file = TRUE; -} - - -/* - * Fill the input buffer --- called whenever buffer is emptied. - * - * In typical applications, this should read fresh data into the buffer - * (ignoring the current state of next_input_byte & bytes_in_buffer), - * reset the pointer & count to the start of the buffer, and return TRUE - * indicating that the buffer has been reloaded. It is not necessary to - * fill the buffer entirely, only to obtain at least one more byte. - * - * There is no such thing as an EOF return. If the end of the file has been - * reached, the routine has a choice of ERREXIT() or inserting fake data into - * the buffer. In most cases, generating a warning message and inserting a - * fake EOI marker is the best course of action --- this will allow the - * decompressor to output however much of the image is there. However, - * the resulting error message is misleading if the real problem is an empty - * input file, so we handle that case specially. - * - * In applications that need to be able to suspend compression due to input - * not being available yet, a FALSE return indicates that no more data can be - * obtained right now, but more may be forthcoming later. In this situation, - * the decompressor will return to its caller (with an indication of the - * number of scanlines it has read, if any). The application should resume - * decompression after it has loaded more data into the input buffer. Note - * that there are substantial restrictions on the use of suspension --- see - * the documentation. - * - * When suspending, the decompressor will back up to a convenient restart point - * (typically the start of the current MCU). next_input_byte & bytes_in_buffer - * indicate where the restart point will be if the current call returns FALSE. - * Data beyond this point must be rescanned after resumption, so move it to - * the front of the buffer rather than discarding it. - */ - -static boolean my_fill_input_buffer(j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - size_t nbytes; - - if (src->src_size > INPUT_BUF_SIZE) { - nbytes = INPUT_BUF_SIZE; - } else { - nbytes = src->src_size; - } - - memcpy(src->buffer, src->src_buffer, nbytes); - src->src_buffer += nbytes; - src->src_size -= nbytes; - - if (nbytes <= 0) { - if (src->start_of_file) { /* Treat empty input file as fatal error */ - ERREXIT(cinfo, JERR_INPUT_EMPTY); - } - WARNMS(cinfo, JWRN_JPEG_EOF); - /* Insert a fake EOI marker */ - src->buffer[0] = (JOCTET) 0xFF; - src->buffer[1] = (JOCTET) JPEG_EOI; - nbytes = 2; - } - - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = nbytes; - src->start_of_file = FALSE; - - return TRUE; -} - - -/* - * Skip data --- used to skip over a potentially large amount of - * uninteresting data (such as an APPn marker). - * - * Writers of suspendable-input applications must note that skip_input_data - * is not granted the right to give a suspension return. If the skip extends - * beyond the data currently in the buffer, the buffer can be marked empty so - * that the next read will cause a fill_input_buffer call that can suspend. - * Arranging for additional bytes to be discarded before reloading the input - * buffer is the application writer's problem. - */ - -static void my_skip_input_data(j_decompress_ptr cinfo, long num_bytes) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* Just a dumb implementation for now. Could use fseek() except - * it doesn't work on pipes. Not clear that being smart is worth - * any trouble anyway --- large skips are infrequent. - */ - if (num_bytes > 0) { - while (num_bytes > (long) src->pub.bytes_in_buffer) { - num_bytes -= (long) src->pub.bytes_in_buffer; - (void) my_fill_input_buffer(cinfo); - /* note we assume that fill_input_buffer will never return FALSE, - * so suspension need not be handled. - */ - } - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; - } -} - - -/* - * An additional method that can be provided by data source modules is the - * resync_to_restart method for error recovery in the presence of RST markers. - * For the moment, this source module just uses the default resync method - * provided by the JPEG library. That method assumes that no backtracking - * is possible. - */ - - -/* - * Terminate source --- called by jpeg_finish_decompress - * after all data has been read. Often a no-op. - * - * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding - * application must deal with any cleanup that should happen even - * for error exit. - */ - -static void my_term_source(j_decompress_ptr cinfo) -{ - /* no work necessary here */ -} - - -/* - * Prepare for input from a stdio stream. - * The caller must have already opened the stream, and is responsible - * for closing it after finishing decompression. - */ - -static void jpeg_buffer_src(j_decompress_ptr cinfo, void *buffer, int bufsize) -{ - my_src_ptr src; - - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling jpeg_stdio_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) - * This makes it unsafe to use this manager and a different source - * manager serially with the same JPEG object. Caveat programmer. - */ - if (cinfo->src == NULL) { /* first time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT, - sizeof(my_source_mgr)); - src = (my_src_ptr) cinfo->src; - src->buffer = (JOCTET *) - (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT, - INPUT_BUF_SIZE * sizeof(JOCTET)); - } - - src = (my_src_ptr) cinfo->src; - src->pub.init_source = my_init_source; - src->pub.fill_input_buffer = my_fill_input_buffer; - src->pub.skip_input_data = my_skip_input_data; - src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->pub.term_source = my_term_source; - src->src_buffer = (JOCTET *) buffer; - src->src_size = bufsize; - src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - src->pub.next_input_byte = NULL; /* until buffer loaded */ -} - -// ============================================================================= - -static char errormsg[JMSG_LENGTH_MAX]; - -typedef struct my_jpeg_error_mgr { - struct jpeg_error_mgr pub; // "public" fields - jmp_buf setjmp_buffer; // for return to caller -} bt_jpeg_error_mgr; - -static void my_jpeg_error_exit(j_common_ptr cinfo) -{ - my_jpeg_error_mgr *myerr = (bt_jpeg_error_mgr *) cinfo->err; - - (*cinfo->err->format_message)(cinfo, errormsg); - - longjmp(myerr->setjmp_buffer, 1); -} - -// stash a scanline -static void j_putRGBScanline(unsigned char *jpegline, int widthPix, unsigned char *outBuf, int row) -{ - int offset = row * widthPix * 4; - int count; - - for (count = 0; count < widthPix; count++) { - unsigned char iRed, iBlu, iGrn; - unsigned char *oRed, *oBlu, *oGrn, *oAlp; - - iRed = *(jpegline + count * 3 + 0); - iGrn = *(jpegline + count * 3 + 1); - iBlu = *(jpegline + count * 3 + 2); - - oRed = outBuf + offset + count * 4 + 0; - oGrn = outBuf + offset + count * 4 + 1; - oBlu = outBuf + offset + count * 4 + 2; - oAlp = outBuf + offset + count * 4 + 3; - - *oRed = iRed; - *oGrn = iGrn; - *oBlu = iBlu; - *oAlp = 255; - } -} - -// stash a scanline -static void j_putRGBAScanline(unsigned char *jpegline, int widthPix, unsigned char *outBuf, int row) -{ - int offset = row * widthPix * 4; - int count; - - for (count = 0; count < widthPix; count++) { - unsigned char iRed, iBlu, iGrn, iAlp; - unsigned char *oRed, *oBlu, *oGrn, *oAlp; - - iRed = *(jpegline + count * 4 + 0); - iGrn = *(jpegline + count * 4 + 1); - iBlu = *(jpegline + count * 4 + 2); - iAlp = *(jpegline + count * 4 + 3); - - oRed = outBuf + offset + count * 4 + 0; - oGrn = outBuf + offset + count * 4 + 1; - oBlu = outBuf + offset + count * 4 + 2; - oAlp = outBuf + offset + count * 4 + 3; - - *oRed = iRed; - *oGrn = iGrn; - *oBlu = iBlu; - - //!\todo fix jpeglib, it leaves alpha channel uninitialised -#if 1 - (void) iAlp; - *oAlp = 255; -#else - *oAlp = iAlp; -#endif - } -} - -// stash a gray scanline -static void j_putGrayScanlineToRGB(unsigned char *jpegline, int widthPix, unsigned char *outBuf, int row) -{ - int offset = row * widthPix * 4; - int count; - - for (count = 0; count < widthPix; count++) { - unsigned char iGray; - unsigned char *oRed, *oBlu, *oGrn, *oAlp; - - // get our grayscale value - iGray = *(jpegline + count); - - oRed = outBuf + offset + count * 4; - oGrn = outBuf + offset + count * 4 + 1; - oBlu = outBuf + offset + count * 4 + 2; - oAlp = outBuf + offset + count * 4 + 3; - - *oRed = iGray; - *oGrn = iGray; - *oBlu = iGray; - *oAlp = 255; - } -} - -static Image *LoadJPGBuff_(const void *src_buffer, int src_size) -{ - struct jpeg_decompress_struct cinfo; - struct my_jpeg_error_mgr jerr; - - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = my_jpeg_error_exit; - - if (setjmp(jerr.setjmp_buffer)) { //< TODO: use c++ exceptions instead of setjmp/longjmp to handle errors - globalErrorStream() << "WARNING: JPEG library error: " << errormsg << "\n"; - jpeg_destroy_decompress(&cinfo); - return 0; - } - - jpeg_create_decompress(&cinfo); - jpeg_buffer_src(&cinfo, const_cast( src_buffer ), src_size); - jpeg_read_header(&cinfo, TRUE); - jpeg_start_decompress(&cinfo); - - int row_stride = cinfo.output_width * cinfo.output_components; - - RGBAImage *image = new RGBAImage(cinfo.output_width, cinfo.output_height); - - JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - - while (cinfo.output_scanline < cinfo.output_height) { - jpeg_read_scanlines(&cinfo, buffer, 1); - - if (cinfo.out_color_components == 4) { - j_putRGBAScanline(buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1); - } else if (cinfo.out_color_components == 3) { - j_putRGBScanline(buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1); - } else if (cinfo.out_color_components == 1) { - j_putGrayScanlineToRGB(buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1); - } - } - - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - - return image; -} - -Image *LoadJPG(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - return LoadJPGBuff_(buffer.buffer, static_cast( buffer.length )); -} diff --git a/plugins/image/jpeg.h b/plugins/image/jpeg.h deleted file mode 100644 index 2295297..0000000 --- a/plugins/image/jpeg.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined ( INCLUDED_JPEG_H ) -#define INCLUDED_JPEG_H - -class Image; - -class ArchiveFile; - -Image *LoadJPG(ArchiveFile &file); - -#endif diff --git a/plugins/image/ktx.cpp b/plugins/image/ktx.cpp deleted file mode 100644 index 0692bc8..0000000 --- a/plugins/image/ktx.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* - Copyright (C) 2015, SiPlus, Chasseur de bots. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ktx.h" - -#include - -#include "bytestreamutils.h" -#include "etclib.h" -#include "ifilesystem.h" -#include "imagelib.h" - - -const int KTX_TYPE_UNSIGNED_BYTE = 0x1401; -const int KTX_TYPE_UNSIGNED_SHORT_4_4_4_4 = 0x8033; -const int KTX_TYPE_UNSIGNED_SHORT_5_5_5_1 = 0x8034; -const int KTX_TYPE_UNSIGNED_SHORT_5_6_5 = 0x8363; - -const int KTX_FORMAT_ALPHA = 0x1906; -const int KTX_FORMAT_RGB = 0x1907; -const int KTX_FORMAT_RGBA = 0x1908; -const int KTX_FORMAT_LUMINANCE = 0x1909; -const int KTX_FORMAT_LUMINANCE_ALPHA = 0x190A; -const int KTX_FORMAT_BGR = 0x80E0; -const int KTX_FORMAT_BGRA = 0x80E1; - -const int KTX_FORMAT_ETC1_RGB8 = 0x8D64; - -class KTX_Decoder { -public: -virtual ~KTX_Decoder() = default; - -virtual void Decode(PointerInputStream &istream, byte *out) = 0; - -virtual unsigned int GetPixelSize() = 0; -}; - -class KTX_Decoder_A8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - out[0] = out[1] = out[2] = 0; - out[3] = istream_read_byte(istream); -} - -virtual unsigned int GetPixelSize() -{ - return 1; -} -}; - -class KTX_Decoder_RGB8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - istream.read(out, 3); - out[3] = 255; -} - -virtual unsigned int GetPixelSize() -{ - return 3; -} -}; - -class KTX_Decoder_RGBA8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - istream.read(out, 4); -} - -virtual unsigned int GetPixelSize() -{ - return 4; -} -}; - -class KTX_Decoder_L8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - byte l = istream_read_byte(istream); - out[0] = out[1] = out[2] = l; - out[3] = 255; -} - -virtual unsigned int GetPixelSize() -{ - return 1; -} -}; - -class KTX_Decoder_LA8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - byte la[2]; - istream.read(la, 2); - out[0] = out[1] = out[2] = la[0]; - out[3] = la[1]; -} - -virtual unsigned int GetPixelSize() -{ - return 2; -} -}; - -class KTX_Decoder_BGR8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - byte bgr[3]; - istream.read(bgr, 3); - out[0] = bgr[2]; - out[1] = bgr[1]; - out[2] = bgr[0]; - out[3] = 255; -} - -virtual unsigned int GetPixelSize() -{ - return 3; -} -}; - -class KTX_Decoder_BGRA8 : public KTX_Decoder { -public: -virtual void Decode(PointerInputStream &istream, byte *out) -{ - byte bgra[4]; - istream.read(bgra, 4); - out[0] = bgra[2]; - out[1] = bgra[1]; - out[2] = bgra[0]; - out[3] = bgra[3]; -} - -virtual unsigned int GetPixelSize() -{ - return 4; -} -}; - -class KTX_Decoder_RGBA4 : public KTX_Decoder { -protected: -bool m_bigEndian; -public: -KTX_Decoder_RGBA4(bool bigEndian) : m_bigEndian(bigEndian) -{ -} - -virtual void Decode(PointerInputStream &istream, byte *out) -{ - uint16_t rgba; - if (m_bigEndian) { - rgba = istream_read_uint16_be(istream); - } else { - rgba = istream_read_uint16_le(istream); - } - int r = (rgba >> 12) & 0xf; - int g = (rgba >> 8) & 0xf; - int b = (rgba >> 4) & 0xf; - int a = rgba & 0xf; - out[0] = (r << 4) | r; - out[1] = (g << 4) | g; - out[2] = (b << 4) | b; - out[3] = (a << 4) | a; -} - -virtual unsigned int GetPixelSize() -{ - return 2; -} -}; - -class KTX_Decoder_RGBA5 : public KTX_Decoder { -protected: -bool m_bigEndian; -public: -KTX_Decoder_RGBA5(bool bigEndian) : m_bigEndian(bigEndian) -{ -} - -virtual void Decode(PointerInputStream &istream, byte *out) -{ - uint16_t rgba; - if (m_bigEndian) { - rgba = istream_read_uint16_be(istream); - } else { - rgba = istream_read_uint16_le(istream); - } - int r = (rgba >> 11) & 0x1f; - int g = (rgba >> 6) & 0x1f; - int b = (rgba >> 1) & 0x1f; - out[0] = (r << 3) | (r >> 2); - out[1] = (g << 3) | (g >> 2); - out[2] = (b << 3) | (b >> 2); - out[3] = (rgba & 1) * 255; -} - -virtual unsigned int GetPixelSize() -{ - return 2; -} -}; - -class KTX_Decoder_RGB5 : public KTX_Decoder { -protected: -bool m_bigEndian; -public: -KTX_Decoder_RGB5(bool bigEndian) : m_bigEndian(bigEndian) -{ -} - -virtual void Decode(PointerInputStream &istream, byte *out) -{ - uint16_t rgb; - if (m_bigEndian) { - rgb = istream_read_uint16_be(istream); - } else { - rgb = istream_read_uint16_le(istream); - } - int r = (rgb >> 11) & 0x1f; - int g = (rgb >> 5) & 0x3f; - int b = rgb & 0x1f; - out[0] = (r << 3) | (r >> 2); - out[1] = (g << 2) | (g >> 4); - out[2] = (b << 3) | (b >> 2); - out[3] = 255; -} - -virtual unsigned int GetPixelSize() -{ - return 2; -} -}; - -static void KTX_DecodeETC1(PointerInputStream &istream, Image &image) -{ - unsigned int width = image.getWidth(), height = image.getHeight(); - unsigned int stride = width * 4; - byte *pixbuf = image.getRGBAPixels(); - byte etc[8], rgba[64]; - - for (unsigned int y = 0; y < height; y += 4, pixbuf += stride * 4) { - unsigned int blockrows = height - y; - if (blockrows > 4) { - blockrows = 4; - } - - byte *p = pixbuf; - for (unsigned int x = 0; x < width; x += 4, p += 16) { - istream.read(etc, 8); - ETC_DecodeETC1Block(etc, rgba, qtrue); - - unsigned int blockrowsize = width - x; - if (blockrowsize > 4) { - blockrowsize = 4; - } - blockrowsize *= 4; - for (unsigned int blockrow = 0; blockrow < blockrows; blockrow++) { - memcpy(p + blockrow * stride, rgba + blockrow * 16, blockrowsize); - } - } - } -} - -Image *LoadKTXBuff(PointerInputStream &istream) -{ - byte identifier[12]; - istream.read(identifier, 12); - if (memcmp(identifier, "\xABKTX 11\xBB\r\n\x1A\n", 12)) { - globalErrorStream() << "LoadKTX: Image has the wrong identifier\n"; - return 0; - } - - bool bigEndian = (istream_read_uint32_le(istream) == 0x01020304); - - unsigned int type; - if (bigEndian) { - type = istream_read_uint32_be(istream); - } else { - type = istream_read_uint32_le(istream); - } - - // For compressed textures, the format is in glInternalFormat. - // For uncompressed textures, it's in glBaseInternalFormat. - istream.seek((type ? 3 : 2) * sizeof(uint32_t)); - unsigned int format; - if (bigEndian) { - format = istream_read_uint32_be(istream); - } else { - format = istream_read_uint32_le(istream); - } - if (!type) { - istream.seek(sizeof(uint32_t)); - } - - unsigned int width, height; - if (bigEndian) { - width = istream_read_uint32_be(istream); - height = istream_read_uint32_be(istream); - } else { - width = istream_read_uint32_le(istream); - height = istream_read_uint32_le(istream); - } - if (!width) { - globalErrorStream() << "LoadKTX: Image has zero width\n"; - return 0; - } - if (!height) { - height = 1; - } - - // Skip the key/values and load the first 2D image in the texture. - // Since KTXorientation is only a hint and has no effect on the texture data and coordinates, it must be ignored. - istream.seek(4 * sizeof(uint32_t)); - unsigned int bytesOfKeyValueData; - if (bigEndian) { - bytesOfKeyValueData = istream_read_uint32_be(istream); - } else { - bytesOfKeyValueData = istream_read_uint32_le(istream); - } - istream.seek(bytesOfKeyValueData + sizeof(uint32_t)); - - RGBAImage *image = new RGBAImage(width, height); - - if (type) { - KTX_Decoder *decoder = NULL; - switch (type) { - case KTX_TYPE_UNSIGNED_BYTE: - switch (format) { - case KTX_FORMAT_ALPHA: - decoder = new KTX_Decoder_A8(); - break; - case KTX_FORMAT_RGB: - decoder = new KTX_Decoder_RGB8(); - break; - case KTX_FORMAT_RGBA: - decoder = new KTX_Decoder_RGBA8(); - break; - case KTX_FORMAT_LUMINANCE: - decoder = new KTX_Decoder_L8(); - break; - case KTX_FORMAT_LUMINANCE_ALPHA: - decoder = new KTX_Decoder_LA8(); - break; - case KTX_FORMAT_BGR: - decoder = new KTX_Decoder_BGR8(); - break; - case KTX_FORMAT_BGRA: - decoder = new KTX_Decoder_BGRA8(); - break; - } - break; - case KTX_TYPE_UNSIGNED_SHORT_4_4_4_4: - if (format == KTX_FORMAT_RGBA) { - decoder = new KTX_Decoder_RGBA4(bigEndian); - } - break; - case KTX_TYPE_UNSIGNED_SHORT_5_5_5_1: - if (format == KTX_FORMAT_RGBA) { - decoder = new KTX_Decoder_RGBA5(bigEndian); - } - break; - case KTX_TYPE_UNSIGNED_SHORT_5_6_5: - if (format == KTX_FORMAT_RGB) { - decoder = new KTX_Decoder_RGB5(bigEndian); - } - break; - } - - if (!decoder) { - globalErrorStream() << "LoadKTX: Image has an unsupported pixel type " << type << " or format " << format - << "\n"; - image->release(); - return 0; - } - - unsigned int inRowLength = width * decoder->GetPixelSize(); - unsigned int inPadding = ((inRowLength + 3) & ~3) - inRowLength; - byte *out = image->getRGBAPixels(); - for (unsigned int y = 0; y < height; y++) { - for (unsigned int x = 0; x < width; x++, out += 4) { - decoder->Decode(istream, out); - } - - if (inPadding) { - istream.seek(inPadding); - } - } - - delete decoder; - } else { - switch (format) { - case KTX_FORMAT_ETC1_RGB8: - KTX_DecodeETC1(istream, *image); - break; - default: - globalErrorStream() << "LoadKTX: Image has an unsupported compressed format " << format << "\n"; - image->release(); - return 0; - } - } - - return image; -} - -Image *LoadKTX(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - PointerInputStream istream(buffer.buffer); - return LoadKTXBuff(istream); -} diff --git a/plugins/image/ktx.h b/plugins/image/ktx.h deleted file mode 100644 index f9b0553..0000000 --- a/plugins/image/ktx.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2015, SiPlus, Chasseur de bots. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_KTX_H ) -#define INCLUDED_KTX_H - -class Image; - -class ArchiveFile; - -Image *LoadKTX(ArchiveFile &file); - -#endif diff --git a/plugins/image/pcx.cpp b/plugins/image/pcx.cpp deleted file mode 100644 index 99646f3..0000000 --- a/plugins/image/pcx.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "pcx.h" - -#include "ifilesystem.h" - -typedef unsigned char byte; - -#include - -#include "imagelib.h" -#include "bytestreamutils.h" - -/* - ================================================================= - - PCX LOADING - - ================================================================= - */ - -typedef struct { - unsigned char manufacturer; - unsigned char version; - unsigned char encoding; - unsigned char bits_per_pixel; - unsigned short xmin, ymin, xmax, ymax; - unsigned short hres, vres; - unsigned char palette[48]; - unsigned char reserved; - unsigned char color_planes; - unsigned short bytes_per_line; - unsigned short palette_type; - unsigned char filler[58]; - unsigned char data; // unbounded -} pcx_t; - -/* - ============== - LoadPCX - ============== - */ - -struct PCXRLEPacket { - byte data; - int length; -}; - -inline void ByteStream_readPCXRLEPacket(PointerInputStream &inputStream, PCXRLEPacket &packet) -{ - byte d; - inputStream.read(&d, 1); - if ((d & 0xC0) == 0xC0) { - packet.length = d & 0x3F; - inputStream.read(&packet.data, 1); - } else { - packet.length = 1; - packet.data = d; - } -} - -void LoadPCXBuff(byte *buffer, std::size_t len, byte **pic, byte **palette, int *width, int *height) -{ - *pic = 0; - - pcx_t pcx; - int x, y, lsize; - byte *out, *pix; - - /* parse the PCX file */ - - PointerInputStream inputStream(buffer); - - pcx.manufacturer = istream_read_byte(inputStream); - pcx.version = istream_read_byte(inputStream); - pcx.encoding = istream_read_byte(inputStream); - pcx.bits_per_pixel = istream_read_byte(inputStream); - pcx.xmin = istream_read_int16_le(inputStream); - pcx.ymin = istream_read_int16_le(inputStream); - pcx.xmax = istream_read_int16_le(inputStream); - pcx.ymax = istream_read_int16_le(inputStream); - pcx.hres = istream_read_int16_le(inputStream); - pcx.vres = istream_read_int16_le(inputStream); - inputStream.read(pcx.palette, 48); - pcx.reserved = istream_read_byte(inputStream); - pcx.color_planes = istream_read_byte(inputStream); - pcx.bytes_per_line = istream_read_int16_le(inputStream); - pcx.palette_type = istream_read_int16_le(inputStream); - inputStream.read(pcx.filler, 58); - - - if (pcx.manufacturer != 0x0a - || pcx.version != 5 - || pcx.encoding != 1 - || pcx.bits_per_pixel != 8) { - return; - } - - if (width) { - *width = pcx.xmax + 1; - } - if (height) { - *height = pcx.ymax + 1; - } - - if (!pic) { - return; - } - - out = (byte *) malloc((pcx.ymax + 1) * (pcx.xmax + 1)); - - *pic = out; - pix = out; - - /* RR2DO2: pcx fix */ - lsize = pcx.color_planes * pcx.bytes_per_line; - - /* go scanline by scanline */ - for (y = 0; y <= pcx.ymax; y++, pix += pcx.xmax + 1) { - /* do a scanline */ - for (x = 0; x <= pcx.xmax;) { - /* RR2DO2 */ - PCXRLEPacket packet; - ByteStream_readPCXRLEPacket(inputStream, packet); - - while (packet.length-- > 0) { - pix[x++] = packet.data; - } - } - - /* RR2DO2: discard any other data */ - PCXRLEPacket packet; - while (x < lsize) { - ByteStream_readPCXRLEPacket(inputStream, packet); - x++; - } - while (packet.length-- > 0) { - x++; - } - } - - /* validity check */ - if (std::size_t(inputStream.get() - buffer) > len) { - *pic = 0; - } - - if (palette) { - *palette = (byte *) malloc(768); - memcpy(*palette, buffer + len - 768, 768); - } -} - -/* - ============== - LoadPCX32 - ============== - */ -Image *LoadPCX32Buff(byte *buffer, std::size_t length) -{ - byte *palette; - byte *pic8; - int i, c, p, width, height; - byte *pic32; - - LoadPCXBuff(buffer, length, &pic8, &palette, &width, &height); - if (!pic8) { - return 0; - } - - RGBAImage *image = new RGBAImage(width, height); - c = (width) * (height); - pic32 = image->getRGBAPixels(); - for (i = 0; i < c; i++) { - p = pic8[i]; - pic32[0] = palette[p * 3]; - pic32[1] = palette[p * 3 + 1]; - pic32[2] = palette[p * 3 + 2]; - pic32[3] = 255; - pic32 += 4; - } - - free(pic8); - free(palette); - - return image; -} - -Image *LoadPCX32(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - return LoadPCX32Buff(buffer.buffer, buffer.length); -} diff --git a/plugins/image/pcx.h b/plugins/image/pcx.h deleted file mode 100644 index 81f10e4..0000000 --- a/plugins/image/pcx.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_PCX_H ) -#define INCLUDED_PCX_H - -class Image; - -class ArchiveFile; - -Image *LoadPCX32(ArchiveFile &file); - -#endif diff --git a/plugins/image/tga.cpp b/plugins/image/tga.cpp deleted file mode 100644 index 7aa85bd..0000000 --- a/plugins/image/tga.cpp +++ /dev/null @@ -1,433 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "tga.h" - -#include "ifilesystem.h" -#include "iarchive.h" -#include "idatastream.h" - -typedef unsigned char byte; - -#include - -#include "generic/bitfield.h" -#include "imagelib.h" -#include "bytestreamutils.h" - -// represents x,y origin of tga image being decoded -class Flip00 {}; // no flip -class Flip01 {}; // vertical flip only -class Flip10 {}; // horizontal flip only -class Flip11 {}; // both - -template -void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip00 &) -{ - RGBAPixel *end = image.pixels + (image.height * image.width); - for (RGBAPixel *row = end; row != image.pixels; row -= image.width) { - for (RGBAPixel *pixel = row - image.width; pixel != row; ++pixel) { - decode(istream, *pixel); - } - } -} - -template -void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip01 &) -{ - RGBAPixel *end = image.pixels + (image.height * image.width); - for (RGBAPixel *row = image.pixels; row != end; row += image.width) { - for (RGBAPixel *pixel = row; pixel != row + image.width; ++pixel) { - decode(istream, *pixel); - } - } -} - -template -void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip10 &) -{ - RGBAPixel *end = image.pixels + (image.height * image.width); - for (RGBAPixel *row = end; row != image.pixels; row -= image.width) { - for (RGBAPixel *pixel = row; pixel != row - image.width;) { - decode(istream, *--pixel); - } - } -} - -template -void image_decode(PointerInputStream &istream, PixelDecoder &decode, RGBAImage &image, const Flip11 &) -{ - RGBAPixel *end = image.pixels + (image.height * image.width); - for (RGBAPixel *row = image.pixels; row != end; row += image.width) { - for (RGBAPixel *pixel = row + image.width; pixel != row;) { - decode(istream, *--pixel); - } - } -} - -inline void istream_read_gray(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream.read(&pixel.blue, 1); - pixel.red = pixel.green = pixel.blue; - pixel.alpha = 0xff; -} - -inline void istream_read_rgb(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream.read(&pixel.blue, 1); - istream.read(&pixel.green, 1); - istream.read(&pixel.red, 1); - pixel.alpha = 0xff; -} - -inline void istream_read_rgba(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream.read(&pixel.blue, 1); - istream.read(&pixel.green, 1); - istream.read(&pixel.red, 1); - istream.read(&pixel.alpha, 1); -} - -class TargaDecodeGrayPixel { -public: -void operator()(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream_read_gray(istream, pixel); -} -}; - -template -void targa_decode_grayscale(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeGrayPixel decode; - image_decode(istream, decode, image, flip); -} - -class TargaDecodeRGBPixel { -public: -void operator()(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream_read_rgb(istream, pixel); -} -}; - -template -void targa_decode_rgb(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeRGBPixel decode; - image_decode(istream, decode, image, flip); -} - -class TargaDecodeRGBAPixel { -public: -void operator()(PointerInputStream &istream, RGBAPixel &pixel) -{ - istream_read_rgba(istream, pixel); -} -}; - -template -void targa_decode_rgba(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeRGBAPixel decode; - image_decode(istream, decode, image, flip); -} - -typedef byte TargaPacket; -typedef byte TargaPacketSize; - -inline void targa_packet_read_istream(TargaPacket &packet, PointerInputStream &istream) -{ - istream.read(&packet, 1); -} - -inline bool targa_packet_is_rle(const TargaPacket &packet) -{ - return (packet & 0x80) != 0; -} - -inline TargaPacketSize targa_packet_size(const TargaPacket &packet) -{ - return 1 + (packet & 0x7f); -} - - -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; -RGBAPixel m_pixel; -TargaPacket m_packet; -public: -TargaDecodeRGBPixelRLE() : 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_rgb(istream, m_pixel); - } - } - - if (targa_packet_is_rle(m_packet)) { - pixel = m_pixel; - } else { - istream_read_rgb(istream, pixel); - } - - --m_packetSize; -} -}; - -template -void targa_decode_rle_rgb(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeRGBPixelRLE decode; - image_decode(istream, decode, image, flip); -} - -class TargaDecodeRGBAPixelRLE { -TargaPacketSize m_packetSize; -RGBAPixel m_pixel; -TargaPacket m_packet; -public: -TargaDecodeRGBAPixelRLE() : 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_rgba(istream, m_pixel); - } - } - - if (targa_packet_is_rle(m_packet)) { - pixel = m_pixel; - } else { - istream_read_rgba(istream, pixel); - } - - --m_packetSize; -} -}; - -template -void targa_decode_rle_rgba(PointerInputStream &istream, RGBAImage &image, const Flip &flip) -{ - TargaDecodeRGBAPixelRLE decode; - image_decode(istream, decode, image, flip); -} - -struct TargaHeader { - unsigned char id_length, colormap_type, image_type; - unsigned short colormap_index, colormap_length; - unsigned char colormap_size; - unsigned short x_origin, y_origin, width, height; - unsigned char pixel_size, attributes; -}; - -inline void targa_header_read_istream(TargaHeader &targa_header, PointerInputStream &istream) -{ - targa_header.id_length = istream_read_byte(istream); - targa_header.colormap_type = istream_read_byte(istream); - targa_header.image_type = istream_read_byte(istream); - - targa_header.colormap_index = istream_read_int16_le(istream); - targa_header.colormap_length = istream_read_int16_le(istream); - targa_header.colormap_size = istream_read_byte(istream); - targa_header.x_origin = istream_read_int16_le(istream); - targa_header.y_origin = istream_read_int16_le(istream); - targa_header.width = istream_read_int16_le(istream); - targa_header.height = istream_read_int16_le(istream); - targa_header.pixel_size = istream_read_byte(istream); - targa_header.attributes = istream_read_byte(istream); - - if (targa_header.id_length != 0) { - istream.seek(targa_header.id_length); // skip TARGA image comment - } -} - -template -class ScopeDelete { -Type *m_value; - -ScopeDelete(const ScopeDelete &); - -ScopeDelete &operator=(const ScopeDelete &); - -public: -ScopeDelete(Type *value) : m_value(value) -{ -} - -~ScopeDelete() -{ - delete m_value; -} - -Type *get_pointer() const -{ - return m_value; -} -}; - -template -Image *Targa_decodeImageData(const TargaHeader &targa_header, PointerInputStream &istream, const Flip &flip) -{ - RGBAImage *image = new RGBAImage(targa_header.width, targa_header.height); - - if (targa_header.image_type == 2 || targa_header.image_type == 3) { - switch (targa_header.pixel_size) { - case 8: - targa_decode_grayscale(istream, *image, flip); - break; - case 24: - targa_decode_rgb(istream, *image, flip); - break; - case 32: - targa_decode_rgba(istream, *image, flip); - break; - default: - globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n"; - image->release(); - return 0; - } - } 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; - case 32: - targa_decode_rle_rgba(istream, *image, flip); - break; - default: - globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n"; - image->release(); - return 0; - } - } - - return image; -} - -const unsigned int TGA_FLIP_HORIZONTAL = 0x10; -const unsigned int TGA_FLIP_VERTICAL = 0x20; - -Image *LoadTGABuff(const byte *buffer) -{ - PointerInputStream istream(buffer); - TargaHeader targa_header; - - targa_header_read_istream(targa_header, istream); - - 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), 10 (RGB), and 11 (gray) TGA images supported\n"; - return 0; - } - - if (targa_header.colormap_type != 0) { - globalErrorStream() << "LoadTGA: colormaps not supported\n"; - return 0; - } - - 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; - } - - if (!bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL) - && !bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) { - return Targa_decodeImageData(targa_header, istream, Flip00()); - } - if (!bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL) - && bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) { - return Targa_decodeImageData(targa_header, istream, Flip01()); - } - if (bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL) - && !bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) { - return Targa_decodeImageData(targa_header, istream, Flip10()); - } - if (bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL) - && bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL)) { - return Targa_decodeImageData(targa_header, istream, Flip11()); - } - - // unreachable - return 0; -} - -Image *LoadTGA(ArchiveFile &file) -{ - ScopedArchiveBuffer buffer(file); - return LoadTGABuff(buffer.buffer); -} diff --git a/plugins/image/tga.h b/plugins/image/tga.h deleted file mode 100644 index 226a997..0000000 --- a/plugins/image/tga.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TGA_H ) -#define INCLUDED_TGA_H - -class Image; - -class ArchiveFile; - -Image *LoadTGA(ArchiveFile &file); - -#endif diff --git a/plugins/imagehl/Makefile b/plugins/imagehl/Makefile deleted file mode 100644 index a8738fb..0000000 --- a/plugins/imagehl/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# WorldSpawn Plugin Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - hlw.o imagehl.o mip.o sprite.o - -# binary target -../../build/plugins/libimagehl.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libuilib.a ../../libs/libgtkutil.a $(PLUGIN_LDFLAGS) - -# object files -hlw.o: hlw.cpp hlw.h -imagehl.o: imagehl.cpp -mip.o: mip.cpp mip.h -sprite.o: sprite.cpp sprite.h - -clean: - -rm -f *.o ../../build/plugins/libimagehl.$(LIB_EXT) diff --git a/plugins/imagehl/hlw.cpp b/plugins/imagehl/hlw.cpp deleted file mode 100644 index 7327554..0000000 --- a/plugins/imagehl/hlw.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// by Hydra - hydra@hydras-world.com -// -// HLW = Half-Life-WAD, I don't know if the actual in data in the WAD files -// has it's own name, so I'm just calling the individal textures .HLW files :) -// -// Thanks to the guys that made Wally for releasing an example WAD loader. -// without it this would not have been possible. - -#include "hlw.h" - -#include -#include -#include - -typedef unsigned char byte; - -#include "ifilesystem.h" - -#include "imagelib.h" - - -/* - ============================================================================ - - HLW IMAGE - - HalfLife WAD files contain files that look like this: - - Mip section - First mip - Mip header - First mip (width * height) - Second mip (width * height / 4) - Third mip (width * height / 16) - Fourth mip (width * height / 64) - Palette size (WORD) - Palette (Palette size * 3) - Padding (WORD) - - ============================================================================ - */ - -#define GET_MIP_DATA_SIZE( WIDTH, HEIGHT ) ( sizeof( WAD3_MIP ) + ( WIDTH * HEIGHT ) + ( WIDTH * HEIGHT / 4 ) + ( WIDTH * HEIGHT / 16 ) + ( WIDTH * HEIGHT / 64 ) ) - -typedef struct -{ - char name[16]; - unsigned int width, height; - unsigned int offsets[4]; // four mip maps stored -} WAD3_MIP, *LPWAD3_MIP; - -/* - ========================================================= - - HLW LOADING - - Hydra: this code isn't bullet proof and probably won't - like corrupt WAD files, but it works for now. - - TODO: make it more robust. - ========================================================= - */ - -/* - ============= - LoadHLW - ============= - */ - -Image* LoadHLWBuff( byte* buffer ){ - byte *buf_p; - unsigned long mipdatasize; - int columns, rows; - byte *pixbuf; - int row, column; - byte *palette; - LPWAD3_MIP lpMip; - unsigned char red, green, blue, alphabyte; - - lpMip = (LPWAD3_MIP)buffer; //!\todo Make endian-safe. - - mipdatasize = GET_MIP_DATA_SIZE( lpMip->width,lpMip->height ); - - palette = buffer + mipdatasize + 2; - - buf_p = buffer + lpMip->offsets[0]; - - columns = lpMip->width; - rows = lpMip->height; - - RGBAImage* image = new RGBAImage( columns, rows ); - - for ( row = 0; row < rows; row++ ) - { - pixbuf = image->getRGBAPixels() + row * columns * 4; - - for ( column = 0; column < columns; column++ ) - { - int palIndex; - - palIndex = *buf_p++; - - red = *( palette + ( palIndex * 3 ) ); - green = *( palette + ( palIndex * 3 ) + 1 ); - blue = *( palette + ( palIndex * 3 ) + 2 ); - - // HalfLife engine makes pixels that are BLUE transparent. - // So show them that way in the editor. - if ( blue == 0xff && red == 0x00 && green == 0x00 ) { - alphabyte = 0x00; - blue = 0x00; // don't set the resulting pixel to blue - } - else - { - alphabyte = 0xff; - } - - *pixbuf++ = red; - *pixbuf++ = green; - *pixbuf++ = blue; - - *pixbuf++ = alphabyte; - } - } - - return image; -} - -Image* LoadHLW( ArchiveFile& file ){ - ScopedArchiveBuffer buffer( file ); - return LoadHLWBuff( buffer.buffer ); -} diff --git a/plugins/imagehl/hlw.h b/plugins/imagehl/hlw.h deleted file mode 100644 index 3313823..0000000 --- a/plugins/imagehl/hlw.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_HLW_H ) -#define INCLUDED_HLW_H - -class Image; -class ArchiveFile; - -Image* LoadHLW( ArchiveFile& file ); - -#endif diff --git a/plugins/imagehl/imagehl.cpp b/plugins/imagehl/imagehl.cpp deleted file mode 100644 index dfdf98b..0000000 --- a/plugins/imagehl/imagehl.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "debugging/debugging.h" -#include "ifilesystem.h" -#include "iimage.h" - -#include "hlw.h" -#include "mip.h" -#include "sprite.h" - -#include "modulesystem/singletonmodule.h" - - -class ImageDependencies : public GlobalFileSystemModuleRef -{ -}; - -class ImageHLWAPI -{ -_QERPlugImageTable m_imagehlw; -public: -typedef _QERPlugImageTable Type; -STRING_CONSTANT( Name, "hlw" ); - -ImageHLWAPI(){ - m_imagehlw.loadImage = LoadHLW; -} -_QERPlugImageTable* getTable(){ - return &m_imagehlw; -} -}; - -typedef SingletonModule ImageHLWModule; - -ImageHLWModule g_ImageHLWModule; - - -class ImageMipAPI -{ -_QERPlugImageTable m_imagemip; -public: -typedef _QERPlugImageTable Type; -STRING_CONSTANT( Name, "mip" ); - -ImageMipAPI(){ - m_imagemip.loadImage = LoadMIP; -} -_QERPlugImageTable* getTable(){ - return &m_imagemip; -} -}; - -typedef SingletonModule ImageMipModule; - -ImageMipModule g_ImageMipModule; - - -class ImageSpriteAPI -{ -_QERPlugImageTable m_imagesprite; -public: -typedef _QERPlugImageTable Type; -STRING_CONSTANT( Name, "spr" ); - -ImageSpriteAPI(){ - m_imagesprite.loadImage = LoadIDSP; -} -_QERPlugImageTable* getTable(){ - return &m_imagesprite; -} -}; - -typedef SingletonModule ImageSpriteModule; - -ImageSpriteModule g_ImageSpriteModule; - - - -extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){ - initialiseModule( server ); - - g_ImageHLWModule.selfRegister(); - g_ImageMipModule.selfRegister(); - g_ImageSpriteModule.selfRegister(); -} diff --git a/plugins/imagehl/imagehl.txt b/plugins/imagehl/imagehl.txt deleted file mode 100644 index e442e64..0000000 --- a/plugins/imagehl/imagehl.txt +++ /dev/null @@ -1,30 +0,0 @@ -ImageHL -======= - -Coding by Dominic Clifton - Hydra - hydra@hydras-world.com - -What is it ? ------------- - -This GTKRadiant 1.2+ plugin handles the loading of textures from .WAD files. -I'll refer to these textures as .HLW files, even though they don't have any -extension when they're stored in the .WAD file itself. - -You need a VFS plugin to go with this plugin that can open and read .WAD files -My VFSWAD plugin does just this. - -Developer Notes ---------------- - -The project file will copy the compiled DLL file and this .TXT file to -"$(HLRADIANTDIR)modules" so make sure you have that environment variable -defined. - -For my GTKRadiant 1.2 HalfLife game pack files I use the directory: -"E:\games\HalfLife\Tools\GTKR12N". Under which there are the directories -"modules" and "plugins" - -Credits -------- -Thanks to the guys that made Wally for releasing an example WAD loader. -without it this would not have been possible. diff --git a/plugins/imagehl/mip.cpp b/plugins/imagehl/mip.cpp deleted file mode 100644 index a9d5a71..0000000 --- a/plugins/imagehl/mip.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mip.h" - -#include -#include -#include - -typedef unsigned char byte; - -#include "ifilesystem.h" - -#include "imagelib.h" -#include "bytestreamutils.h" - -/* - ============================================================================ - - MIP IMAGE - - Quake WAD files contain miptex files that look like this: - - Mip section - First mip - Mip header - First mip (width * height) - Second mip (width * height / 4) - Third mip (width * height / 16) - Fourth mip (width * height / 64) - - ============================================================================ - */ - -#define GET_MIP_DATA_SIZE( WIDTH, HEIGHT ) ( sizeof( WAD3_MIP ) + ( WIDTH * HEIGHT ) + ( WIDTH * HEIGHT / 4 ) + ( WIDTH * HEIGHT / 16 ) + ( WIDTH * HEIGHT / 64 ) ) - -const int MIP_NAME_LENGTH = 16; -const int MIP_MIPMAP_COUNT = 4; -typedef struct -{ - char name[MIP_NAME_LENGTH]; - unsigned int width, height; - unsigned int offsets[MIP_MIPMAP_COUNT]; // four mip maps stored -} WAD3_MIP, *LPWAD3_MIP; - -static const byte quakepalette[768] = -{ - 0x00,0x00,0x00, 0x0f,0x0f,0x0f, 0x1f,0x1f,0x1f, 0x2f,0x2f,0x2f, - 0x3f,0x3f,0x3f, 0x4b,0x4b,0x4b, 0x5b,0x5b,0x5b, 0x6b,0x6b,0x6b, - 0x7b,0x7b,0x7b, 0x8b,0x8b,0x8b, 0x9b,0x9b,0x9b, 0xab,0xab,0xab, - 0xbb,0xbb,0xbb, 0xcb,0xcb,0xcb, 0xdb,0xdb,0xdb, 0xeb,0xeb,0xeb, - 0x0f,0x0b,0x07, 0x17,0x0f,0x0b, 0x1f,0x17,0x0b, 0x27,0x1b,0x0f, - 0x2f,0x23,0x13, 0x37,0x2b,0x17, 0x3f,0x2f,0x17, 0x4b,0x37,0x1b, - 0x53,0x3b,0x1b, 0x5b,0x43,0x1f, 0x63,0x4b,0x1f, 0x6b,0x53,0x1f, - 0x73,0x57,0x1f, 0x7b,0x5f,0x23, 0x83,0x67,0x23, 0x8f,0x6f,0x23, - 0x0b,0x0b,0x0f, 0x13,0x13,0x1b, 0x1b,0x1b,0x27, 0x27,0x27,0x33, - 0x2f,0x2f,0x3f, 0x37,0x37,0x4b, 0x3f,0x3f,0x57, 0x47,0x47,0x67, - 0x4f,0x4f,0x73, 0x5b,0x5b,0x7f, 0x63,0x63,0x8b, 0x6b,0x6b,0x97, - 0x73,0x73,0xa3, 0x7b,0x7b,0xaf, 0x83,0x83,0xbb, 0x8b,0x8b,0xcb, - 0x00,0x00,0x00, 0x07,0x07,0x00, 0x0b,0x0b,0x00, 0x13,0x13,0x00, - 0x1b,0x1b,0x00, 0x23,0x23,0x00, 0x2b,0x2b,0x07, 0x2f,0x2f,0x07, - 0x37,0x37,0x07, 0x3f,0x3f,0x07, 0x47,0x47,0x07, 0x4b,0x4b,0x0b, - 0x53,0x53,0x0b, 0x5b,0x5b,0x0b, 0x63,0x63,0x0b, 0x6b,0x6b,0x0f, - 0x07,0x00,0x00, 0x0f,0x00,0x00, 0x17,0x00,0x00, 0x1f,0x00,0x00, - 0x27,0x00,0x00, 0x2f,0x00,0x00, 0x37,0x00,0x00, 0x3f,0x00,0x00, - 0x47,0x00,0x00, 0x4f,0x00,0x00, 0x57,0x00,0x00, 0x5f,0x00,0x00, - 0x67,0x00,0x00, 0x6f,0x00,0x00, 0x77,0x00,0x00, 0x7f,0x00,0x00, - 0x13,0x13,0x00, 0x1b,0x1b,0x00, 0x23,0x23,0x00, 0x2f,0x2b,0x00, - 0x37,0x2f,0x00, 0x43,0x37,0x00, 0x4b,0x3b,0x07, 0x57,0x43,0x07, - 0x5f,0x47,0x07, 0x6b,0x4b,0x0b, 0x77,0x53,0x0f, 0x83,0x57,0x13, - 0x8b,0x5b,0x13, 0x97,0x5f,0x1b, 0xa3,0x63,0x1f, 0xaf,0x67,0x23, - 0x23,0x13,0x07, 0x2f,0x17,0x0b, 0x3b,0x1f,0x0f, 0x4b,0x23,0x13, - 0x57,0x2b,0x17, 0x63,0x2f,0x1f, 0x73,0x37,0x23, 0x7f,0x3b,0x2b, - 0x8f,0x43,0x33, 0x9f,0x4f,0x33, 0xaf,0x63,0x2f, 0xbf,0x77,0x2f, - 0xcf,0x8f,0x2b, 0xdf,0xab,0x27, 0xef,0xcb,0x1f, 0xff,0xf3,0x1b, - 0x0b,0x07,0x00, 0x1b,0x13,0x00, 0x2b,0x23,0x0f, 0x37,0x2b,0x13, - 0x47,0x33,0x1b, 0x53,0x37,0x23, 0x63,0x3f,0x2b, 0x6f,0x47,0x33, - 0x7f,0x53,0x3f, 0x8b,0x5f,0x47, 0x9b,0x6b,0x53, 0xa7,0x7b,0x5f, - 0xb7,0x87,0x6b, 0xc3,0x93,0x7b, 0xd3,0xa3,0x8b, 0xe3,0xb3,0x97, - 0xab,0x8b,0xa3, 0x9f,0x7f,0x97, 0x93,0x73,0x87, 0x8b,0x67,0x7b, - 0x7f,0x5b,0x6f, 0x77,0x53,0x63, 0x6b,0x4b,0x57, 0x5f,0x3f,0x4b, - 0x57,0x37,0x43, 0x4b,0x2f,0x37, 0x43,0x27,0x2f, 0x37,0x1f,0x23, - 0x2b,0x17,0x1b, 0x23,0x13,0x13, 0x17,0x0b,0x0b, 0x0f,0x07,0x07, - 0xbb,0x73,0x9f, 0xaf,0x6b,0x8f, 0xa3,0x5f,0x83, 0x97,0x57,0x77, - 0x8b,0x4f,0x6b, 0x7f,0x4b,0x5f, 0x73,0x43,0x53, 0x6b,0x3b,0x4b, - 0x5f,0x33,0x3f, 0x53,0x2b,0x37, 0x47,0x23,0x2b, 0x3b,0x1f,0x23, - 0x2f,0x17,0x1b, 0x23,0x13,0x13, 0x17,0x0b,0x0b, 0x0f,0x07,0x07, - 0xdb,0xc3,0xbb, 0xcb,0xb3,0xa7, 0xbf,0xa3,0x9b, 0xaf,0x97,0x8b, - 0xa3,0x87,0x7b, 0x97,0x7b,0x6f, 0x87,0x6f,0x5f, 0x7b,0x63,0x53, - 0x6b,0x57,0x47, 0x5f,0x4b,0x3b, 0x53,0x3f,0x33, 0x43,0x33,0x27, - 0x37,0x2b,0x1f, 0x27,0x1f,0x17, 0x1b,0x13,0x0f, 0x0f,0x0b,0x07, - 0x6f,0x83,0x7b, 0x67,0x7b,0x6f, 0x5f,0x73,0x67, 0x57,0x6b,0x5f, - 0x4f,0x63,0x57, 0x47,0x5b,0x4f, 0x3f,0x53,0x47, 0x37,0x4b,0x3f, - 0x2f,0x43,0x37, 0x2b,0x3b,0x2f, 0x23,0x33,0x27, 0x1f,0x2b,0x1f, - 0x17,0x23,0x17, 0x0f,0x1b,0x13, 0x0b,0x13,0x0b, 0x07,0x0b,0x07, - 0xff,0xf3,0x1b, 0xef,0xdf,0x17, 0xdb,0xcb,0x13, 0xcb,0xb7,0x0f, - 0xbb,0xa7,0x0f, 0xab,0x97,0x0b, 0x9b,0x83,0x07, 0x8b,0x73,0x07, - 0x7b,0x63,0x07, 0x6b,0x53,0x00, 0x5b,0x47,0x00, 0x4b,0x37,0x00, - 0x3b,0x2b,0x00, 0x2b,0x1f,0x00, 0x1b,0x0f,0x00, 0x0b,0x07,0x00, - 0x00,0x00,0xff, 0x0b,0x0b,0xef, 0x13,0x13,0xdf, 0x1b,0x1b,0xcf, - 0x23,0x23,0xbf, 0x2b,0x2b,0xaf, 0x2f,0x2f,0x9f, 0x2f,0x2f,0x8f, - 0x2f,0x2f,0x7f, 0x2f,0x2f,0x6f, 0x2f,0x2f,0x5f, 0x2b,0x2b,0x4f, - 0x23,0x23,0x3f, 0x1b,0x1b,0x2f, 0x13,0x13,0x1f, 0x0b,0x0b,0x0f, - 0x2b,0x00,0x00, 0x3b,0x00,0x00, 0x4b,0x07,0x00, 0x5f,0x07,0x00, - 0x6f,0x0f,0x00, 0x7f,0x17,0x07, 0x93,0x1f,0x07, 0xa3,0x27,0x0b, - 0xb7,0x33,0x0f, 0xc3,0x4b,0x1b, 0xcf,0x63,0x2b, 0xdb,0x7f,0x3b, - 0xe3,0x97,0x4f, 0xe7,0xab,0x5f, 0xef,0xbf,0x77, 0xf7,0xd3,0x8b, - 0xa7,0x7b,0x3b, 0xb7,0x9b,0x37, 0xc7,0xc3,0x37, 0xe7,0xe3,0x57, - 0x7f,0xbf,0xff, 0xab,0xe7,0xff, 0xd7,0xff,0xff, 0x67,0x00,0x00, - 0x8b,0x00,0x00, 0xb3,0x00,0x00, 0xd7,0x00,0x00, 0xff,0x00,0x00, - 0xff,0xf3,0x93, 0xff,0xf7,0xc7, 0xff,0xff,0xff, 0x9f,0x5b,0x53 -}; - -/* - ============= - LoadMIP - ============= - */ - -Image* LoadMIPBuff( byte* buffer ){ - byte *buf_p; - int palettelength; - int columns, rows, numPixels; - byte *pixbuf; - int i; - byte *loadedpalette; - const byte *palette; - - loadedpalette = 0; - - PointerInputStream inputStream( buffer ); - - inputStream.seek( MIP_NAME_LENGTH ); - columns = istream_read_int32_le( inputStream ); - rows = istream_read_int32_le( inputStream ); - int offset = istream_read_int32_le( inputStream ); - - if ( std::size_t( columns ) > 65536 && std::size_t( rows ) > 65536 ) { - return 0; - } - -// unsigned long mipdatasize = GET_MIP_DATA_SIZE( columns, rows ); - - palettelength = vfsLoadFile( "gfx/palette.lmp", (void **) &loadedpalette ); - if ( palettelength == 768 ) { - palette = loadedpalette; - } - else - { - loadedpalette = 0; - palette = quakepalette; - } - - buf_p = buffer + offset; - - numPixels = columns * rows; - - RGBAImage* image = new RGBAImage( columns, rows ); - - //Sys_Printf("lpMip->width = %i, lpMip->height = %i, lpMip->offsets[0] = %i, lpMip->offsets[1] = %i, lpMip->offsets[2] = %i, lpMip->offsets[3] = %i, numPixels = %i\n", lpMip->width, lpMip->height, lpMip->offsets[0], lpMip->offsets[1], lpMip->offsets[2], lpMip->offsets[3], numPixels); - //for (i = 0; i < sizeof(*lpMip); i++) - // Sys_Printf("%02x", (int) ((unsigned char *)lpMip)[i]); - - pixbuf = image->getRGBAPixels(); - - for ( i = 0; i < numPixels; i++ ) - { - int palIndex = *buf_p++; - *pixbuf++ = palette[palIndex * 3]; - *pixbuf++ = palette[palIndex * 3 + 1]; - *pixbuf++ = palette[palIndex * 3 + 2]; - *pixbuf++ = 0xff; - } - - if ( loadedpalette != 0 ) { - vfsFreeFile( loadedpalette ); - } - - return image; -} - -Image* LoadMIP( ArchiveFile& file ){ - ScopedArchiveBuffer buffer( file ); - return LoadMIPBuff( buffer.buffer ); -} diff --git a/plugins/imagehl/mip.h b/plugins/imagehl/mip.h deleted file mode 100644 index ea11d8f..0000000 --- a/plugins/imagehl/mip.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_MIP_H ) -#define INCLUDED_MIP_H - -class Image; -class ArchiveFile; - -Image* LoadMIP( ArchiveFile& file ); - -#endif diff --git a/plugins/imagehl/sprite.cpp b/plugins/imagehl/sprite.cpp deleted file mode 100644 index 195d952..0000000 --- a/plugins/imagehl/sprite.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// by Hydra - hydra@hydras-world.com - -#include "sprite.h" - -#include -#include -#include - -typedef unsigned char byte; - -#include "ifilesystem.h" - -#include "imagelib.h" - -/* - ============================================================================ - - IDSP IMAGE (.spr files) - - Some code copied straight from the Q1 source, also used the HalfLife SDK as - a reference. - - ============================================================================ - */ - -typedef enum {ST_SYNC = 0, ST_RAND } synctype_t; -typedef enum { SPR_SINGLE = 0, SPR_GROUP } spriteframetype_t; - -typedef struct dspriteheader_s { - int ident; - int version; -} dspriteheader_t; - -// Quake1 -typedef struct { - int type; - float boundingradius; - int width; - int height; - int numframes; - float beamlength; - synctype_t synctype; -} dspritev1_t; - -// Halflife -typedef struct { - int type; - int texFormat; - float boundingradius; - int width; - int height; - int numframes; - float beamlength; - synctype_t synctype; -} dspritev2_t; - -typedef struct { - int origin[2]; - int width; - int height; -} dspriteframe_t; - -typedef struct { - short type; -} dspriteframetype_t; - -/* - typedef struct { - byte rgb[256][3]; - } dpalette_t; - */ - -const int IDSPRITEHEADER = ( ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'D' << 8 ) + 'I' ); -// little-endian "IDSP" - -/* - ============= - LoadIDSP - ============= - */ - -Image* LoadIDSPBuff( byte *buffer ){ - byte *buf_p; - int columns, rows; - byte *pixbuf; - - int row, column; - byte *palette; - unsigned char red, green, blue, alphabyte; - - dspriteheader_t *header; - dspritev1_t *pinv1; - dspritev2_t *pinv2; - dspriteframetype_t *pframetype; - int version; - int numframes; - dspriteframe_t *spriteframe; - - header = (dspriteheader_t *)buffer; - - if ( header->ident != IDSPRITEHEADER ) { - globalErrorStream() << "WARNING: IDSP file has wrong header\n"; - return 0; - } - - version = header->version; - if ( version != 1 && version != 2 ) { - globalErrorStream() << "WARNING: IDSP file has wrong version number " - "(" << version << " should be 1 or 2)\n"; - return 0; - } - - // initialise variables depending on the sprite version. - switch ( version ) - { - case 1: - pinv1 = (dspritev1_t *)( header + 1 ); - numframes = pinv1->numframes; - columns = pinv1->width; - rows = pinv1->height; - pframetype = (dspriteframetype_t *)( pinv1 + 1 ); - break; - case 2: - pinv2 = (dspritev2_t *)( header + 1 ); - numframes = pinv2->numframes; - columns = pinv2->width; - rows = pinv2->height; - pframetype = (dspriteframetype_t *)( pinv2 + 1 ); - break; - default: - globalErrorStream() << "WARNING: IDSP file has unsupported version\n"; - return 0; - } - if ( numframes > 1 ) { - globalErrorStream() << "WARNING: IDSP file has multiple frames, only the first frame will be used.\n"; - } - - // palette = buffer+mipdatasize+2; - // buf_p = buffer+lpMip->offsets[0]; - - RGBAImage* image = new RGBAImage( columns, rows ); - -#ifdef DEBUG - frametype = spriteframetype_t( pframetype->type ); - if ( frametype == SPR_SINGLE ) { - globalOutputStream() << "Single Frame\n"; - } - else if ( frametype == SPR_GROUP ) { - globalOutputStream() << "Group of Frames\n"; - } - else - { - globalOutputStream() << "Bleh!\n"; // <-- we always get this, wtf! - } -#endif - - palette = (byte *)( pframetype + 1 ); - spriteframe = (dspriteframe_t *)( palette + ( 256 * 3 ) + 4 ); // what are those 4 extra bytes ? what's missing ? - buf_p = (byte *)( spriteframe + 1 ); - - for ( row = 0; row < rows; row++ ) - { - pixbuf = image->getRGBAPixels() + row * columns * 4; - - for ( column = 0; column < columns; column++ ) - { - int palIndex; - - palIndex = *buf_p++; - - red = *( palette + ( palIndex * 3 ) ); - green = *( palette + ( palIndex * 3 ) + 1 ); - blue = *( palette + ( palIndex * 3 ) + 2 ); - - // HalfLife engine makes pixels that are BLUE transparent. (RGB = 0x0000FF) - // So show them that way in the editor. - if ( blue == 0xff && red == 0x00 && green == 0x00 ) { - alphabyte = 0xff; //FIXME: backwards? (so sprite models to render correctly) - blue = 0x00; // don't set the resulting pixel to blue - } - else - { - alphabyte = 0x00; //FIXME: backwards? (so sprite models to render correctly) - } - - *pixbuf++ = red; - *pixbuf++ = green; - *pixbuf++ = blue; - - *pixbuf++ = alphabyte; - } - } - - return image; -} - -Image* LoadIDSP( ArchiveFile& file ){ - ScopedArchiveBuffer buffer( file ); - return LoadIDSPBuff( buffer.buffer ); -} diff --git a/plugins/imagehl/sprite.h b/plugins/imagehl/sprite.h deleted file mode 100644 index d6635d9..0000000 --- a/plugins/imagehl/sprite.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_SPRITE_H ) -#define INCLUDED_SPRITE_H - -class Image; -class ArchiveFile; - -Image* LoadIDSP( ArchiveFile& file ); - -#endif diff --git a/plugins/iqmmodel/Makefile b/plugins/iqmmodel/Makefile deleted file mode 100644 index 3a0d957..0000000 --- a/plugins/iqmmodel/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - iqm.o plugin.o - -# binary target -../../build/plugins/libiqmmodel.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -iqm.o: iqm.cpp iqm.h -plugin.o: plugin.cpp plugin.h - -clean: - -rm -f *.o ../../build/plugins/libiqmmodel.$(LIB_EXT) diff --git a/plugins/iqmmodel/iqm.cpp b/plugins/iqmmodel/iqm.cpp deleted file mode 100644 index 79ec6ac..0000000 --- a/plugins/iqmmodel/iqm.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - Copyright (C) 2010-2014 COR Entertainment, LLC. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iqm.h" - -#include "ifilesystem.h" -#include "imodel.h" - -#include "imagelib.h" -#include "bytestreamutils.h" - -#include "../md3model/model.h" - -typedef unsigned char byte; - -/* - ======================================================================== - - .IQM triangle model file format - - ======================================================================== - */ - -typedef struct { - float s; - float t; -} iqmSt_t; - -void istream_read_iqmSt( PointerInputStream &inputStream, iqmSt_t &st ){ - st.s = istream_read_float32_le( inputStream ); - st.t = istream_read_float32_le( inputStream ); -} - -typedef struct { - unsigned int indices[3]; -} iqmTriangle_t; - -void istream_read_iqmTriangle( PointerInputStream &inputStream, iqmTriangle_t &triangle ){ - triangle.indices[0] = istream_read_int32_le( inputStream ); - triangle.indices[1] = istream_read_int32_le( inputStream ); - triangle.indices[2] = istream_read_int32_le( inputStream ); -} - -typedef struct { - float v[3]; -} iqmPos_t; - -void istream_read_iqmPos( PointerInputStream &inputStream, iqmPos_t &iqmPos ){ - iqmPos.v[0] = istream_read_float32_le( inputStream ); - iqmPos.v[1] = istream_read_float32_le( inputStream ); - iqmPos.v[2] = istream_read_float32_le( inputStream ); -} - -const int IQM_POSITION = 0; -const int IQM_TEXCOORD = 1; -const int IQM_NORMAL = 2; -const int IQM_TANGENT = 3; -const int IQM_BLENDINDEXES = 4; -const int IQM_BLENDWEIGHTS = 5; -const int IQM_COLOR = 6; -const int IQM_CUSTOM = 0x10; - -const int IQM_BYTE = 0; -const int IQM_UBYTE = 1; -const int IQM_SHORT = 2; -const int IQM_USHORT = 3; -const int IQM_INT = 4; -const int IQM_UINT = 5; -const int IQM_HALF = 6; -const int IQM_FLOAT = 7; -const int IQM_DOUBLE = 8; - -// animflags -const int IQM_LOOP = 1; - -typedef struct iqmHeader_s { - byte id[16]; - unsigned int version; - unsigned int filesize; - unsigned int flags; - unsigned int num_text, ofs_text; - unsigned int num_meshes, ofs_meshes; - unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays; - unsigned int num_triangles, ofs_triangles, ofs_neighbors; - unsigned int num_joints, ofs_joints; - unsigned int num_poses, ofs_poses; - unsigned int num_anims, ofs_anims; - unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds; - unsigned int num_comment, ofs_comment; - unsigned int num_extensions, ofs_extensions; -} iqmHeader_t; - -void istream_read_iqmHeader( PointerInputStream &inputStream, iqmHeader_t &header ){ - inputStream.read( header.id, 16 ); -#define READINT( x ) header.x = istream_read_int32_le( inputStream ); - READINT( version ) - READINT( filesize ) - READINT( flags ) - READINT( num_text ) - READINT( ofs_text ) - READINT( num_meshes ) - READINT( ofs_meshes ) - READINT( num_vertexarrays ) - READINT( num_vertexes ) - READINT( ofs_vertexarrays ) - READINT( num_triangles ) - READINT( ofs_triangles ) - READINT( ofs_neighbors ) - READINT( num_joints ) - READINT( ofs_joints ) - READINT( num_frames ) - READINT( num_framechannels ) - READINT( ofs_frames ) - READINT( ofs_bounds ) - READINT( num_comment ) - READINT( ofs_comment ) - READINT( num_extensions ) - READINT( ofs_extensions ) -#undef READINT -} - -typedef struct iqmmesh_s { - unsigned int name; - unsigned int material; - unsigned int first_vertex; - unsigned int num_vertexes; - unsigned int first_triangle; - unsigned int num_triangles; -} iqmmesh_t; - -void istream_read_iqmMesh( PointerInputStream &inputStream, iqmmesh_t &iqmmesh ){ -#define READUINT( x ) iqmmesh.x = istream_read_uint32_le( inputStream ); - READUINT( name ) - READUINT( material ) - READUINT( first_vertex ) - READUINT( num_vertexes ) - READUINT( first_triangle ) - READUINT( num_triangles ) -#undef READUINT -} - -typedef struct iqmvertexarray_s { - unsigned int type; - unsigned int flags; - unsigned int format; - unsigned int size; - unsigned int offset; -} iqmvertexarray_t; - -void istream_read_iqmVertexarray( PointerInputStream &inputStream, iqmvertexarray_t &vertexarray ){ -#define READINT( x ) vertexarray.x = istream_read_int32_le( inputStream ); - READINT( type ) - READINT( flags ) - READINT( format ) - READINT( size ) - READINT( offset ) -#undef READINT -} - -ArbitraryMeshVertex IQMVertex_construct( const iqmPos_t *pos, const iqmPos_t *norm, const iqmSt_t *st ){ - return ArbitraryMeshVertex( - Vertex3f( pos->v[0], pos->v[1], pos->v[2] ), - Normal3f( norm->v[0], norm->v[1], norm->v[2] ), - TexCoord2f( st->s, st->t ) - ); -} - -void IQMSurface_read( Model &model, const byte *buffer, ArchiveFile &file ){ - iqmHeader_t header; - { - PointerInputStream inputStream( buffer ); - istream_read_iqmHeader( inputStream, header ); - } - - int ofs_position = -1, ofs_st = -1, ofs_normal = -1; - PointerInputStream vaStream( buffer + header.ofs_vertexarrays ); - for ( unsigned int i = 0; i < header.num_vertexarrays; i++ ) { - iqmvertexarray_t va; - istream_read_iqmVertexarray( vaStream, va ); - - switch ( va.type ) { - case IQM_POSITION: - if ( va.format == IQM_FLOAT && va.size == 3 ) { - ofs_position = va.offset; - } - break; - case IQM_TEXCOORD: - if ( va.format == IQM_FLOAT && va.size == 2 ) { - ofs_st = va.offset; - } - break; - case IQM_NORMAL: - if ( va.format == IQM_FLOAT && va.size == 3 ) { - ofs_normal = va.offset; - } - break; - } - } - - PointerInputStream posStream( buffer + ofs_position ); - Array iqmPos( header.num_vertexes ); - for ( Array::iterator i = iqmPos.begin(); i != iqmPos.end(); ++i ) { - istream_read_iqmPos( posStream, *i ); - } - - PointerInputStream normStream( buffer + ofs_normal ); - Array iqmNorm( header.num_vertexes ); - for ( Array::iterator i = iqmNorm.begin(); i != iqmNorm.end(); ++i ) { - istream_read_iqmPos( normStream, *i ); - } - - Array iqmSt( header.num_vertexes ); - PointerInputStream stStream( buffer + ofs_st ); - for ( Array::iterator i = iqmSt.begin(); i != iqmSt.end(); ++i ) { - istream_read_iqmSt( stStream, *i ); - } - - PointerInputStream iqmMesh( buffer + header.ofs_meshes ); - for ( unsigned int m = 0; m < header.num_meshes; m++ ) { - Surface &surface = model.newSurface(); - - iqmmesh_t iqmmesh; - istream_read_iqmMesh( iqmMesh, iqmmesh ); - - bool material_found = false; - // if not malformed data neither missing string - if ( iqmmesh.material <= header.num_text && iqmmesh.material > 0 ) { - char *material; - material = (char*) buffer + header.ofs_text + iqmmesh.material; - - if ( material[0] != '\0' ) { - surface.setShader( material ); - material_found = true; - } - } - - if ( !material_found ) { - // empty string will trigger "textures/shader/notex" on display - surface.setShader( "" ); - } - - UniqueVertexBuffer inserter( surface.vertices() ); - inserter.reserve( iqmmesh.num_vertexes ); - - surface.indices().reserve( iqmmesh.num_vertexes ); - - unsigned int triangle_offset = header.ofs_triangles + iqmmesh.first_triangle * sizeof( iqmTriangle_t ); - PointerInputStream triangleStream( buffer + triangle_offset ); - for ( unsigned int i = 0; i < iqmmesh.num_triangles; ++i ) { - iqmTriangle_t triangle; - istream_read_iqmTriangle( triangleStream, triangle ); - for ( int j = 0; j < 3; j++ ) { - surface.indices().insert( inserter.insert( IQMVertex_construct( - &iqmPos[triangle.indices[j]], - &iqmNorm[triangle.indices[j]], - &iqmSt[triangle.indices[j]] ) ) ); - } - } - - surface.updateAABB(); - } -} - -void IQMModel_read( Model &model, const byte *buffer, ArchiveFile &file ){ - IQMSurface_read( model, buffer, file ); - model.updateAABB(); -} - -scene::Node &IQMModel_new( const byte *buffer, ArchiveFile &file ){ - ModelNode *modelNode = new ModelNode(); - IQMModel_read( modelNode->model(), buffer, file ); - return modelNode->node(); -} - -scene::Node &IQMModel_default(){ - ModelNode *modelNode = new ModelNode(); - Model_constructNull( modelNode->model() ); - return modelNode->node(); -} - -scene::Node &IQMModel_fromBuffer( unsigned char *buffer, ArchiveFile &file ){ - if ( memcmp( buffer, "INTERQUAKEMODEL", 16 ) ) { - globalErrorStream() << "IQM read error: incorrect ident\n"; - return IQMModel_default(); - } - else { - return IQMModel_new( buffer, file ); - } -} - -scene::Node &loadIQMModel( ArchiveFile &file ){ - ScopedArchiveBuffer buffer( file ); - return IQMModel_fromBuffer( buffer.buffer, file ); -} diff --git a/plugins/iqmmodel/iqm.h b/plugins/iqmmodel/iqm.h deleted file mode 100644 index 8f48f3b..0000000 --- a/plugins/iqmmodel/iqm.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_IQM_H ) -#define INCLUDED_IQM_H - -namespace scene { class Node; } -class ArchiveFile; - -scene::Node &loadIQMModel( ArchiveFile &file ); - - -#endif diff --git a/plugins/iqmmodel/plugin.cpp b/plugins/iqmmodel/plugin.cpp deleted file mode 100644 index 79f2288..0000000 --- a/plugins/iqmmodel/plugin.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "plugin.h" - -#include "iscenegraph.h" -#include "irender.h" -#include "iselection.h" -#include "iimage.h" -#include "imodel.h" -#include "igl.h" -#include "ifilesystem.h" -#include "iundo.h" -#include "ifiletypes.h" -#include "iscriplib.h" - -#include "modulesystem/singletonmodule.h" -#include "typesystem.h" - -#include "iqm.h" - - -class IQMModelLoader : public ModelLoader { -public: -scene::Node &loadModel( ArchiveFile &file ){ - return loadIQMModel( file ); -} -}; - -/* InterQuake Model Format */ -class ModelDependencies : - public GlobalFileSystemModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalFiletypesModuleRef { -}; - -class ModelIQMAPI : public TypeSystemRef { -IQMModelLoader m_modeliqm; -public: -typedef ModelLoader Type; - -STRING_CONSTANT( Name, "iqm" ); - -ModelIQMAPI(){ - GlobalFiletypesModule::getTable().addType( Type::Name(), Name(), filetype_t( "InterQuake Models", "*.iqm" ) ); -} - -ModelLoader *getTable(){ - return &m_modeliqm; -} -}; -typedef SingletonModule ModelIQMModule; -ModelIQMModule g_ModelIQMModule; - -/* Vera Visions Model Format */ -class ModelVVMAPI : public TypeSystemRef { -IQMModelLoader m_modeliqm; -public: -typedef ModelLoader Type; - -STRING_CONSTANT( Name, "vvm" ); - -ModelVVMAPI(){ - GlobalFiletypesModule::getTable().addType( Type::Name(), Name(), filetype_t( "Vera Visions Model", "*.vvm" ) ); -} - -ModelLoader *getTable(){ - return &m_modeliqm; -} -}; -typedef SingletonModule ModelVVMModule; -ModelVVMModule g_ModelVVMModule; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules( ModuleServer &server ){ - initialiseModule( server ); - - g_ModelIQMModule.selfRegister(); - g_ModelVVMModule.selfRegister(); -} diff --git a/plugins/iqmmodel/plugin.h b/plugins/iqmmodel/plugin.h deleted file mode 100644 index c6bfe6c..0000000 --- a/plugins/iqmmodel/plugin.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SAMPLE_H ) -#define INCLUDED_SAMPLE_H - -#endif diff --git a/plugins/mapq3/Makefile b/plugins/mapq3/Makefile deleted file mode 100644 index 6c41a79..0000000 --- a/plugins/mapq3/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - parse.o plugin.o write.o - -# binary target -../../build/plugins/libmapq3.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -parse.o: parse.cpp parse.h -plugin.o: plugin.cpp -write.o: write.cpp write.h - -clean: - -rm -f *.o ../../build/plugins/libmapq3.$(LIB_EXT) diff --git a/plugins/mapq3/parse.cpp b/plugins/mapq3/parse.cpp deleted file mode 100644 index e40951e..0000000 --- a/plugins/mapq3/parse.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parse.h" - -#include - -#include "ientity.h" -#include "ibrush.h" -#include "ipatch.h" -#include "ieclass.h" -#include "iscriplib.h" -#include "scenelib.h" -#include "string/string.h" -#include "stringio.h" -#include "eclasslib.h" - -inline MapImporter *Node_getMapImporter(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - - -typedef std::list > KeyValues; - -NodeSmartReference g_nullNode(NewNullNode()); - - -NodeSmartReference Entity_create(EntityCreator &entityTable, EntityClass *entityClass, const KeyValues &keyValues) -{ - scene::Node &entity(entityTable.createEntity(entityClass)); - for (KeyValues::const_iterator i = keyValues.begin(); i != keyValues.end(); ++i) { - Node_getEntity(entity)->setKeyValue((*i).first.c_str(), (*i).second.c_str()); - } - return NodeSmartReference(entity); -} - -NodeSmartReference -Entity_parseTokens(Tokeniser &tokeniser, EntityCreator &entityTable, const PrimitiveParser &parser, int index) -{ - NodeSmartReference entity(g_nullNode); - KeyValues keyValues; - const char *classname = ""; - - int count_primitives = 0; - while (1) { - tokeniser.nextLine(); - const char *token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#entity-token"); - return g_nullNode; - } - if (!strcmp(token, "}")) { // end entity - if (entity == g_nullNode) { - // entity does not have brushes - entity = Entity_create(entityTable, GlobalEntityClassManager().findOrInsert(classname, false), - keyValues); - } - return entity; - } else if (!strcmp(token, "{")) { // begin primitive - if (entity == g_nullNode) { - // entity has brushes - entity = Entity_create(entityTable, GlobalEntityClassManager().findOrInsert(classname, true), - keyValues); - } - - tokeniser.nextLine(); - - NodeSmartReference primitive(parser.parsePrimitive(tokeniser)); - if (primitive == g_nullNode || !Node_getMapImporter(primitive)->importTokens(tokeniser)) { - globalErrorStream() << "brush " << count_primitives << ": parse error\n"; - return g_nullNode; - } - - scene::Traversable *traversable = Node_getTraversable(entity); - if (Node_getEntity(entity)->isContainer() && traversable != 0) { - traversable->insert(primitive); - } else { - globalErrorStream() << "entity " << index << ": type " << classname << ": discarding brush " - << count_primitives << "\n"; - } - ++count_primitives; - } else // epair - { - CopiedString key(token); - token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#epair-value"); - return g_nullNode; - } - keyValues.push_back(KeyValues::value_type(key, token)); - if (string_equal(key.c_str(), "classname")) { - classname = keyValues.back().second.c_str(); - } - } - } - // unreachable code - return g_nullNode; -} - -void Map_Read(scene::Node &root, Tokeniser &tokeniser, EntityCreator &entityTable, const PrimitiveParser &parser) -{ - int count_entities = 0; - for (;;) { - tokeniser.nextLine(); - if (!tokeniser.getToken()) { // { or 0 - break; - } - - NodeSmartReference entity(Entity_parseTokens(tokeniser, entityTable, parser, count_entities)); - - if (entity == g_nullNode) { - globalErrorStream() << "entity " << count_entities << ": parse error\n"; - return; - } - - Node_getTraversable(root)->insert(entity); - - ++count_entities; - } -} diff --git a/plugins/mapq3/parse.h b/plugins/mapq3/parse.h deleted file mode 100644 index 81b6357..0000000 --- a/plugins/mapq3/parse.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PARSE_H ) -#define INCLUDED_PARSE_H - -#include "imap.h" - -class BrushCreator; - -class PatchCreator; - -class PrimitiveParser { -public: -virtual scene::Node &parsePrimitive(Tokeniser &tokeniser) const = 0; -}; - -void Map_Read(scene::Node &root, Tokeniser &tokeniser, EntityCreator &entityTable, const PrimitiveParser &parser); - -namespace scene { -class Node; -} - -#include "generic/referencecounted.h" - -typedef SmartReference > NodeSmartReference; - -extern NodeSmartReference g_nullNode; - -#endif diff --git a/plugins/mapq3/plugin.cpp b/plugins/mapq3/plugin.cpp deleted file mode 100644 index ce1e71b..0000000 --- a/plugins/mapq3/plugin.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "iscriplib.h" -#include "ibrush.h" -#include "ipatch.h" -#include "ifiletypes.h" -#include "ieclass.h" -#include "qerplugin.h" - -#include "scenelib.h" -#include "string/string.h" -#include "stringio.h" -#include "generic/constant.h" - -#include "modulesystem/singletonmodule.h" - -#include "parse.h" -#include "write.h" - -class MapDependencies : - public GlobalRadiantModuleRef, - public GlobalBrushModuleRef, - public GlobalPatchModuleRef, - public GlobalFiletypesModuleRef, - public GlobalScripLibModuleRef, - public GlobalEntityClassManagerModuleRef, - public GlobalSceneGraphModuleRef { -public: -MapDependencies() : - GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")), - GlobalPatchModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("patchtypes")), - GlobalEntityClassManagerModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entityclass")) -{ -} -}; - -class MapQ3API : public TypeSystemRef, public MapFormat, public PrimitiveParser { -mutable bool detectedFormat; -public: -typedef MapFormat Type; - -STRING_CONSTANT(Name, "worldspawn"); - -MapQ3API() -{ - GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), - filetype_t("WorldSpawn maps", "*.map", true, true, true)); - GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), - filetype_t("WorldSpawn region", "*.reg", true, true, true)); - GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), - filetype_t("WorldSpawn compiled maps", "*.bsp", false, true, false)); -} - -MapFormat *getTable() -{ - return this; -} - -scene::Node &parsePrimitive(Tokeniser &tokeniser) const -{ - const char *primitive = tokeniser.getToken(); - if (primitive != 0) { - if (string_equal(primitive, "patchDef2") || string_equal(primitive, "patchDef2WS")) { - return GlobalPatchModule::getTable().createPatch(false, false); - } if (string_equal(primitive, "patchDef3") || string_equal(primitive, "patchDef3WS")) { - return GlobalPatchModule::getTable().createPatch(true, false); - } if (string_equal(primitive, "patchDefWS")) { - return GlobalPatchModule::getTable().createPatch(false, true); - } - - if (!detectedFormat) - { - EBrushType fmt; - if (string_equal(primitive, "brushDef")) - fmt = eBrushTypeQuake3BP; - else if (string_equal(primitive, "(")) - { - if (1) //tokeniser.getLine - fmt = eBrushTypeQuake3Valve; - else - fmt = eBrushTypeQuake3; - } - if (fmt != GlobalBrushModule::getTable().getBrushType()) - GlobalBrushModule::getTable().setBrushType(fmt); - } - - switch(GlobalBrushModule::getTable().getBrushType()) - { - default: - tokeniser.ungetToken(); // ( - case eBrushTypeQuake3BP: - return GlobalBrushModule::getTable().createBrush(); - } - } - - Tokeniser_unexpectedError(tokeniser, primitive, "#quake3-primitive"); - return g_nullNode; -} - -void readGraph(scene::Node &root, TextInputStream &inputStream, EntityCreator &entityTable) const -{ - detectedFormat = false; - wrongFormat = false; - Tokeniser &tokeniser = GlobalScripLibModule::getTable().m_pfnNewSimpleTokeniser(inputStream); - Map_Read(root, tokeniser, entityTable, *this); - tokeniser.release(); -} - -void writeGraph(scene::Node &root, GraphTraversalFunc traverse, TextOutputStream &outputStream) const -{ - TokenWriter &writer = GlobalScripLibModule::getTable().m_pfnNewSimpleTokenWriter(outputStream); - Map_Write(root, traverse, writer, false); - writer.release(); -} -}; - -typedef SingletonModule MapQ3Module; - -MapQ3Module g_MapQ3Module; - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_MapQ3Module.selfRegister(); -} diff --git a/plugins/mapq3/write.cpp b/plugins/mapq3/write.cpp deleted file mode 100644 index aa94776..0000000 --- a/plugins/mapq3/write.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "write.h" - -#include "ientity.h" -#include "iscriplib.h" -#include "scenelib.h" - -inline MapExporter *Node_getMapExporter(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - - -static std::size_t g_count_entities; -static std::size_t g_count_brushes; - - -void Entity_ExportTokens(const Entity &entity, TokenWriter &writer) -{ - g_count_brushes = 0; - - class WriteKeyValue : public Entity::Visitor { - TokenWriter &m_writer; -public: - WriteKeyValue(TokenWriter &writer) - : m_writer(writer) - { - } - - void visit(const char *key, const char *value) - { - /* cut anything after # including the symbol itself */ - if (!strncmp(key, "On", 2)) { - StringTokeniser st(key, "#"); - m_writer.writeString(st.getToken()); - } else { - m_writer.writeString(key); - } - - m_writer.writeString(value); - m_writer.nextLine(); - } - - } visitor(writer); - - entity.forEachKeyValue(visitor); -} - -class WriteTokensWalker : public scene::Traversable::Walker { -mutable Stack m_stack; -TokenWriter &m_writer; -bool m_ignorePatches; -public: -WriteTokensWalker(TokenWriter &writer, bool ignorePatches) - : m_writer(writer), m_ignorePatches(ignorePatches) -{ -} - -bool pre(scene::Node &node) const -{ - m_stack.push(false); - - Entity *entity = Node_getEntity(node); - if (entity != 0) { - m_writer.writeToken("//"); - m_writer.writeToken("entity"); - m_writer.writeUnsigned(g_count_entities++); - m_writer.nextLine(); - - m_writer.writeToken("{"); - m_writer.nextLine(); - m_stack.top() = true; - - Entity_ExportTokens(*entity, m_writer); - } else { - MapExporter *exporter = Node_getMapExporter(node); - if (exporter != 0 - && !(m_ignorePatches && Node_isPatch(node))) { - m_writer.writeToken("//"); - m_writer.writeToken("brush"); - m_writer.writeUnsigned(g_count_brushes++); - m_writer.nextLine(); - - exporter->exportTokens(m_writer); - } - } - - return true; -} - -void post(scene::Node &node) const -{ - if (m_stack.top()) { - m_writer.writeToken("}"); - m_writer.nextLine(); - } - m_stack.pop(); -} -}; - -void Map_Write(scene::Node &root, GraphTraversalFunc traverse, TokenWriter &writer, bool ignorePatches) -{ - g_count_entities = 0; - traverse(root, WriteTokensWalker(writer, ignorePatches)); -} diff --git a/plugins/mapq3/write.h b/plugins/mapq3/write.h deleted file mode 100644 index 0fbfce0..0000000 --- a/plugins/mapq3/write.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_WRITE_H ) -#define INCLUDED_WRITE_H - -#include "imap.h" - -void Map_Write(scene::Node &root, GraphTraversalFunc traverse, TokenWriter &writer, bool ignorePatches); - -#endif diff --git a/plugins/matsys/Makefile b/plugins/matsys/Makefile deleted file mode 100644 index 9fd0fd8..0000000 --- a/plugins/matsys/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - shaders.o plugin.o - -# binary target -../../build/plugins/libmatsys.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -shaders.o: shaders.cpp shaders.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libmatsys.$(LIB_EXT) diff --git a/plugins/matsys/plugin.cpp b/plugins/matsys/plugin.cpp deleted file mode 100644 index 12fedab..0000000 --- a/plugins/matsys/plugin.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ishaders.h" -#include "ifilesystem.h" -#include "itextures.h" -#include "iscriplib.h" -#include "qerplugin.h" - -#include "string/string.h" -#include "modulesystem/singletonmodule.h" -#include "shaders.h" - -class ShadersDependencies : - public GlobalFileSystemModuleRef, - public GlobalTexturesModuleRef, - public GlobalScripLibModuleRef, - public GlobalRadiantModuleRef { -ImageModuleRef m_bitmapModule; -public: -ShadersDependencies() : - m_bitmapModule("tga") -{ -} - -ImageModuleRef &getBitmapModule() -{ - return m_bitmapModule; -} -}; - -class MaterialAPI { -ShaderSystem *m_shadersq3; -public: -typedef ShaderSystem Type; - -STRING_CONSTANT(Name, "mat"); - -MaterialAPI(ShadersDependencies &dependencies) -{ - g_shadersExtension = "mat"; - g_shadersDirectory = "textures/"; - g_enableDefaultShaders = false; - g_useShaderList = false; - g_bitmapModule = dependencies.getBitmapModule().getTable(); - Shaders_Construct(); - m_shadersq3 = &GetShaderSystem(); -} - -~MaterialAPI() -{ - Shaders_Destroy(); -} - -ShaderSystem *getTable() -{ - return m_shadersq3; -} -}; - -typedef SingletonModule > MaterialModule; -MaterialModule g_MaterialModule; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - g_MaterialModule.selfRegister(); -} diff --git a/plugins/matsys/shaders.cpp b/plugins/matsys/shaders.cpp deleted file mode 100644 index 5b9d65c..0000000 --- a/plugins/matsys/shaders.cpp +++ /dev/null @@ -1,1578 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Shaders Manager Plugin -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "shaders.h" -#include "globaldefs.h" - -#include -#include -#include -#include - -#include "ifilesystem.h" -#include "ishaders.h" -#include "iscriplib.h" -#include "itextures.h" -#include "qerplugin.h" -#include "irender.h" - -#include - -#include "debugging/debugging.h" -#include "string/pooledstring.h" -#include "math/vector.h" -#include "generic/callback.h" -#include "generic/referencecounted.h" -#include "stream/memstream.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" -#include "os/path.h" -#include "os/dir.h" -#include "os/file.h" -#include "stringio.h" -#include "shaderlib.h" -#include "texturelib.h" -#include "cmdlib.h" -#include "moduleobservers.h" -#include "archivelib.h" -#include "imagelib.h" - -const char *g_shadersExtension = ""; -const char *g_shadersDirectory = ""; -bool g_enableDefaultShaders = true; -bool g_useShaderList = true; -_QERPlugImageTable *g_bitmapModule = 0; -const char *g_texturePrefix = "textures/"; - -void ActiveShaders_IteratorBegin(); -bool ActiveShaders_IteratorAtEnd(); -IShader *ActiveShaders_IteratorCurrent(); -void ActiveShaders_IteratorIncrement(); -Callback g_ActiveShadersChangedNotify; -void FreeShaders(); -void LoadShaderFile(const char *filename); -qtexture_t *Texture_ForName(const char *filename); - -/*! - NOTE TTimo: there is an important distinction between SHADER_NOT_FOUND and SHADER_NOTEX: - SHADER_NOT_FOUND means we didn't find the raw texture or the shader for this - SHADER_NOTEX means we recognize this as a shader script, but we are missing the texture to represent it - this was in the initial design of the shader code since early GtkRadiant alpha, and got sort of foxed in 1.2 and put back in - */ -Image *loadBitmap(void *environment, const char *name) -{ - DirectoryArchiveFile file(name, name); - if (!file.failed()) { - return g_bitmapModule->loadImage(file); - } - return 0; -} - -inline byte *getPixel(byte *pixels, int width, int height, int x, int y) -{ - return pixels + (((((y + height) % height) * width) + ((x + width) % width)) * 4); -} - -class KernelElement { -public: -int x, y; -float w; -}; - -Image &convertHeightmapToNormalmap(Image &heightmap, float scale) -{ - int w = heightmap.getWidth(); - int h = heightmap.getHeight(); - - Image &normalmap = *(new RGBAImage(heightmap.getWidth(), heightmap.getHeight())); - - byte *in = heightmap.getRGBAPixels(); - byte *out = normalmap.getRGBAPixels(); - - #if 1 - // no filtering - const int kernelSize = 2; - KernelElement kernel_du[kernelSize] = { - {-1, 0, -0.5f}, - {1, 0, 0.5f} - }; - KernelElement kernel_dv[kernelSize] = { - {0, 1, 0.5f}, - {0, -1, -0.5f} - }; - #else - // 3x3 Prewitt - const int kernelSize = 6; - KernelElement kernel_du[kernelSize] = { - {-1, 1,-1.0f }, - {-1, 0,-1.0f }, - {-1,-1,-1.0f }, - { 1, 1, 1.0f }, - { 1, 0, 1.0f }, - { 1,-1, 1.0f } - }; - KernelElement kernel_dv[kernelSize] = { - {-1, 1, 1.0f }, - { 0, 1, 1.0f }, - { 1, 1, 1.0f }, - {-1,-1,-1.0f }, - { 0,-1,-1.0f }, - { 1,-1,-1.0f } - }; - #endif - - int x, y = 0; - while (y < h) { - x = 0; - while (x < w) { - float du = 0; - for (KernelElement *i = kernel_du; i != kernel_du + kernelSize; ++i) { - du += (getPixel(in, w, h, x + (*i).x, y + (*i).y)[0] / 255.0) * (*i).w; - } - float dv = 0; - for (KernelElement *i = kernel_dv; i != kernel_dv + kernelSize; ++i) { - dv += (getPixel(in, w, h, x + (*i).x, y + (*i).y)[0] / 255.0) * (*i).w; - } - - float nx = -du * scale; - float ny = -dv * scale; - float nz = 1.0; - - // Normalize - float norm = 1.0 / sqrt(nx * nx + ny * ny + nz * nz); - out[0] = float_to_integer(((nx * norm) + 1) * 127.5); - out[1] = float_to_integer(((ny * norm) + 1) * 127.5); - out[2] = float_to_integer(((nz * norm) + 1) * 127.5); - out[3] = 255; - - x++; - out += 4; - } - - y++; - } - - return normalmap; -} - -Image *loadHeightmap(void *environment, const char *name) -{ - Image *heightmap = GlobalTexturesCache().loadImage(name); - if (heightmap != 0) { - Image &normalmap = convertHeightmapToNormalmap(*heightmap, *reinterpret_cast( environment )); - heightmap->release(); - return &normalmap; - } - return 0; -} - -Image *loadSpecial(void *environment, const char *name) -{ - if (*name == '_') { // special image - StringOutputStream bitmapName(256); - bitmapName << GlobalRadiant().getAppPath() << "bitmaps/" << name + 1 << ".tga"; - Image *image = loadBitmap(environment, bitmapName.c_str()); - if (image != 0) { - return image; - } - } - return GlobalTexturesCache().loadImage(name); -} - -class ShaderPoolContext { -}; - -typedef Static ShaderPool; -typedef PooledString ShaderString; -typedef ShaderString ShaderVariable; -typedef ShaderString ShaderValue; -typedef CopiedString TextureExpression; - -// clean a texture name to the qtexture_t name format we use internally -// NOTE: case sensitivity: the engine is case sensitive. we store the shader name with case information and save with case -// information as well. but we assume there won't be any case conflict and so when doing lookups based on shader name, -// we compare as case insensitive. That is Radiant is case insensitive, but knows that the engine is case sensitive. -//++timo FIXME: we need to put code somewhere to detect when two shaders that are case insensitive equal are present -template -void parseTextureName(StringType &name, const char *token) -{ - StringOutputStream cleaned(256); - cleaned << PathCleaned(token); - name = CopiedString( - StringRange(cleaned.c_str(), path_get_filename_base_end(cleaned.c_str()))).c_str(); // remove extension -} - -bool Tokeniser_parseTextureName(Tokeniser &tokeniser, TextureExpression &name) -{ - const char *token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#texture-name"); - return false; - } - parseTextureName(name, token); - return true; -} - -bool Tokeniser_parseShaderName(Tokeniser &tokeniser, CopiedString &name) -{ - const char *token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#shader-name"); - return false; - } - parseTextureName(name, token); - return true; -} - -bool Tokeniser_parseString(Tokeniser &tokeniser, ShaderString &string) -{ - const char *token = tokeniser.getToken(); - if (token == 0) { - Tokeniser_unexpectedError(tokeniser, token, "#string"); - return false; - } - string = token; - return true; -} - -typedef std::list ShaderParameters; -typedef std::list ShaderArguments; -typedef std::pair BlendFuncExpression; - -class ShaderTemplate { -std::size_t m_refcount; -CopiedString m_Name; -CopiedString m_WadName; -public: - -ShaderParameters m_params; -TextureExpression m_textureName; -TextureExpression m_diffuse; -TextureExpression m_bump; -ShaderValue m_heightmapScale; -TextureExpression m_specular; -TextureExpression m_lightFalloffImage; - -int m_nFlags; -float m_fTrans; -int m_iPolygonOffset; - -// alphafunc stuff -IShader::EAlphaFunc m_AlphaFunc; -float m_AlphaRef; -// cull stuff -IShader::ECull m_Cull; - -ShaderTemplate() : - m_refcount(0) -{ - m_nFlags = 0; - m_fTrans = 1.0f; -} - -void IncRef() -{ - ++m_refcount; -} - -void DecRef() -{ - ASSERT_MESSAGE(m_refcount != 0, "shader reference-count going below zero"); - if (--m_refcount == 0) { - delete this; - } -} - -std::size_t refcount() -{ - return m_refcount; -} - -const char *getName() const -{ - return m_Name.c_str(); -} - -void setName(const char *name) -{ - m_Name = name; -} -// ----------------------------------------- - -bool parseMaterial(Tokeniser &tokeniser); -bool parseTemplate(Tokeniser &tokeniser); - - -void CreateDefault(const char *name) -{ - /*if (g_enableDefaultShaders) { - m_textureName = name; - } else { - m_textureName = ""; - }*/ - setName(name); -} - -class MapLayerTemplate { -TextureExpression m_texture; -BlendFuncExpression m_blendFunc; -bool m_clampToBorder; -ShaderValue m_alphaTest; -public: -MapLayerTemplate(const TextureExpression &texture, const BlendFuncExpression &blendFunc, bool clampToBorder, - const ShaderValue &alphaTest) : - m_texture(texture), - m_blendFunc(blendFunc), - m_clampToBorder(false), - m_alphaTest(alphaTest) -{ -} - -const TextureExpression &texture() const -{ - return m_texture; -} - -const BlendFuncExpression &blendFunc() const -{ - return m_blendFunc; -} - -bool clampToBorder() const -{ - return m_clampToBorder; -} - -const ShaderValue &alphaTest() const -{ - return m_alphaTest; -} -}; - -typedef std::vector MapLayers; -MapLayers m_layers; -}; - -enum LayerTypeId { - LAYER_NONE, - LAYER_BLEND, - LAYER_DIFFUSEMAP, - LAYER_BUMPMAP, - LAYER_SPECULARMAP -}; - -class LayerTemplate { -public: -LayerTypeId m_type; -TextureExpression m_texture; -BlendFuncExpression m_blendFunc; -bool m_clampToBorder; -ShaderValue m_alphaTest; -ShaderValue m_heightmapScale; - -LayerTemplate() : m_type(LAYER_NONE), m_blendFunc("GL_ONE", "GL_ZERO"), m_clampToBorder(false), m_alphaTest("-1"), - m_heightmapScale("0") -{ -} -}; - -bool parseShaderParameters(Tokeniser &tokeniser, ShaderParameters ¶ms) -{ - Tokeniser_parseToken(tokeniser, "("); - for (;;) { - const char *param = tokeniser.getToken(); - if (string_equal(param, ")")) { - break; - } - params.push_back(param); - const char *comma = tokeniser.getToken(); - if (string_equal(comma, ")")) { - break; - } - if (!string_equal(comma, ",")) { - Tokeniser_unexpectedError(tokeniser, comma, ","); - return false; - } - } - return true; -} - -bool ShaderTemplate::parseTemplate(Tokeniser &tokeniser) -{ - m_Name = tokeniser.getToken(); - if (!parseShaderParameters(tokeniser, m_params)) { - globalErrorStream() << "shader template: " << makeQuoted(m_Name.c_str()) << ": parameter parse failed\n"; - return false; - } - - return parseMaterial(tokeniser); -} - -typedef SmartPointer ShaderTemplatePointer; -typedef std::map ShaderTemplateMap; - -ShaderTemplateMap g_shaders; -ShaderTemplateMap g_shaderTemplates; - -ShaderTemplate *findTemplate(const char *name) -{ - ShaderTemplateMap::iterator i = g_shaderTemplates.find(name); - if (i != g_shaderTemplates.end()) { - return (*i).second.get(); - } - return 0; -} - -class ShaderDefinition { -public: -ShaderDefinition(ShaderTemplate *shaderTemplate, const ShaderArguments &args, const char *filename) - : shaderTemplate(shaderTemplate), args(args), filename(filename) -{ -} - -ShaderTemplate *shaderTemplate; -ShaderArguments args; -const char *filename; -}; - -typedef std::map ShaderDefinitionMap; -ShaderDefinitionMap g_shaderDefinitions; - -bool parseTemplateInstance(Tokeniser &tokeniser, const char *filename) -{ - CopiedString name; - RETURN_FALSE_IF_FAIL(Tokeniser_parseShaderName(tokeniser, name)); - const char *templateName = tokeniser.getToken(); - ShaderTemplate *shaderTemplate = findTemplate(templateName); - if (shaderTemplate == 0) { - globalErrorStream() << "shader instance: " << makeQuoted(name.c_str()) << ": shader template not found: " - << makeQuoted(templateName) << "\n"; - } - - ShaderArguments args; - if (!parseShaderParameters(tokeniser, args)) { - globalErrorStream() << "shader instance: " << makeQuoted(name.c_str()) << ": argument parse failed\n"; - return false; - } - - if (shaderTemplate != 0) { - if (!g_shaderDefinitions.insert( - ShaderDefinitionMap::value_type(name, ShaderDefinition(shaderTemplate, args, filename))).second) { - globalErrorStream() << "shader instance: " << makeQuoted(name.c_str()) - << ": already exists, second definition ignored\n"; - } - } - return true; -} - -const char *evaluateShaderValue(const char *value, const ShaderParameters ¶ms, const ShaderArguments &args) -{ - ShaderArguments::const_iterator j = args.begin(); - for (ShaderParameters::const_iterator i = params.begin(); i != params.end(); ++i, ++j) { - const char *other = (*i).c_str(); - if (string_equal(value, other)) { - return (*j).c_str(); - } - } - return value; -} - -///\todo BlendFunc parsing -BlendFunc -evaluateBlendFunc(const BlendFuncExpression &blendFunc, const ShaderParameters ¶ms, const ShaderArguments &args) -{ - return BlendFunc(BLEND_ONE, BLEND_ZERO); -} - -qtexture_t* evaluateTexture( const TextureExpression& texture, const ShaderParameters& params, const ShaderArguments& args, const LoadImageCallback& loader = GlobalTexturesCache().defaultLoader() ){ - StringOutputStream result( 64 ); - const char* expression = texture.c_str(); - const char* end = expression + string_length( expression ); - if ( !string_empty( expression ) ) { - for (;; ) - { - const char* best = end; - const char* bestParam = 0; - const char* bestArg = 0; - ShaderArguments::const_iterator j = args.begin(); - for ( ShaderParameters::const_iterator i = params.begin(); i != params.end(); ++i, ++j ) - { - const char* found = strstr( expression, ( *i ).c_str() ); - if ( found != 0 && found < best ) { - best = found; - bestParam = ( *i ).c_str(); - bestArg = ( *j ).c_str(); - } - } - if ( best != end ) { - result << StringRange( expression, best ); - result << PathCleaned( bestArg ); - expression = best + string_length( bestParam ); - } - else - { - break; - } - } - result << expression; - } - return GlobalTexturesCache().capture( loader, result.c_str() ); -} - -float evaluateFloat(const ShaderValue &value, const ShaderParameters ¶ms, const ShaderArguments &args) -{ - const char *result = evaluateShaderValue(value.c_str(), params, args); - float f = 0.0f; - if (!string_parse_float(result, f)) { - globalErrorStream() << "parsing float value failed: " << makeQuoted(result) << "\n"; - } - return f; -} - -BlendFactor evaluateBlendFactor(const ShaderValue &value, const ShaderParameters ¶ms, const ShaderArguments &args) -{ - const char *result = evaluateShaderValue(value.c_str(), params, args); - - if (string_equal_nocase(result, "gl_zero")) { - return BLEND_ZERO; - } - if (string_equal_nocase(result, "gl_one")) { - return BLEND_ONE; - } - if (string_equal_nocase(result, "gl_src_color")) { - return BLEND_SRC_COLOUR; - } - if (string_equal_nocase(result, "gl_one_minus_src_color")) { - return BLEND_ONE_MINUS_SRC_COLOUR; - } - if (string_equal_nocase(result, "gl_src_alpha")) { - return BLEND_SRC_ALPHA; - } - if (string_equal_nocase(result, "gl_one_minus_src_alpha")) { - return BLEND_ONE_MINUS_SRC_ALPHA; - } - if (string_equal_nocase(result, "gl_dst_color")) { - return BLEND_DST_COLOUR; - } - if (string_equal_nocase(result, "gl_one_minus_dst_color")) { - return BLEND_ONE_MINUS_DST_COLOUR; - } - if (string_equal_nocase(result, "gl_dst_alpha")) { - return BLEND_DST_ALPHA; - } - if (string_equal_nocase(result, "gl_one_minus_dst_alpha")) { - return BLEND_ONE_MINUS_DST_ALPHA; - } - if (string_equal_nocase(result, "gl_src_alpha_saturate")) { - return BLEND_SRC_ALPHA_SATURATE; - } - - globalErrorStream() << "parsing blend-factor value failed: " << makeQuoted(result) << "\n"; - return BLEND_ZERO; -} - -class CShader : public IShader { -std::size_t m_refcount; -const ShaderTemplate &m_template; -const ShaderArguments &m_args; -const char *m_filename; -// name is shader-name, otherwise texture-name (if not a real shader) -CopiedString m_Name; -CopiedString m_WadName; -qtexture_t *m_pTexture; -qtexture_t *m_notfound; -qtexture_t *m_pDiffuse; -float m_heightmapScale; -qtexture_t *m_pBump; -qtexture_t *m_pSpecular; -qtexture_t *m_pLightFalloffImage; -BlendFunc m_blendFunc; -bool m_bInUse; - -public: -CShader(const ShaderDefinition &definition) : - m_refcount(0), - m_template(*definition.shaderTemplate), - m_args(definition.args), - m_filename(definition.filename), - m_blendFunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA), - m_bInUse(false) -{ - m_pTexture = 0; - m_pDiffuse = 0; - m_pBump = 0; - m_pSpecular = 0; - m_notfound = 0; - realise(); -} - -virtual ~CShader() -{ - unrealise(); - - ASSERT_MESSAGE(m_refcount == 0, "deleting active shader"); -} - -// IShaders implementation ----------------- -void IncRef() -{ - ++m_refcount; -} - -void DecRef() -{ - ASSERT_MESSAGE(m_refcount != 0, "shader reference-count going below zero"); - if (--m_refcount == 0) { - delete this; - } -} - -std::size_t refcount() -{ - return m_refcount; -} - -// get/set the qtexture_t* Radiant uses to represent this shader object -qtexture_t *getTexture() const -{ - return m_pTexture; -} - -qtexture_t *getDiffuse() const -{ - return m_pDiffuse; -} - -qtexture_t *getBump() const -{ - return m_pBump; -} - -qtexture_t *getSpecular() const -{ - return m_pSpecular; -} - -// get shader name -const char *getName() const -{ - return m_Name.c_str(); -} - -const char* getWadName() const -{ - return m_WadName.c_str(); -} - - -bool IsInUse() const -{ - return m_bInUse; -} - -void SetInUse(bool bInUse) -{ - m_bInUse = bInUse; - g_ActiveShadersChangedNotify(); -} - -// get the shader flags -int getFlags() const -{ - return m_template.m_nFlags; -} - -// get the transparency value -float getTrans() const -{ - return m_template.m_fTrans; -} - -int getPolygonOffset() const -{ - return m_template.m_iPolygonOffset; -} - -// test if it's a true shader, or a default shader created to wrap around a texture -bool IsDefault() const -{ - return string_empty(m_filename); -} - -// get the alphaFunc -void getAlphaFunc(EAlphaFunc *func, float *ref) -{ - *func = m_template.m_AlphaFunc; - *ref = m_template.m_AlphaRef; -}; - -BlendFunc getBlendFunc() const -{ - return m_blendFunc; -} - -// get the cull type -ECull getCull() -{ - return m_template.m_Cull; -}; - -// get shader file name (ie the file where this one is defined) -const char *getShaderFileName() const -{ - return m_filename; -} -// ----------------------------------------- - -void realise() -{ - m_pTexture = evaluateTexture(m_template.m_textureName, m_template.m_params, m_args); - - if (m_pTexture->texture_number == 0) { - m_notfound = m_pTexture; - { - StringOutputStream name(256); - name << GlobalRadiant().getAppPath() << "bitmaps/" << (IsDefault() ? "notex.tga" : "shadernotex.tga"); - m_pTexture = GlobalTexturesCache().capture(LoadImageCallback(0, loadBitmap), name.c_str()); - } - } -} - -void unrealise() -{ - GlobalTexturesCache().release(m_pTexture); - - if (m_notfound != 0) { - GlobalTexturesCache().release(m_notfound); - } -} - -// set shader name -void setName(const char *name) -{ - m_Name = name; -} - -void setWadName( const char* name ) -{ - m_WadName = name; -} - -class MapLayer : public ShaderLayer { -qtexture_t *m_texture; -BlendFunc m_blendFunc; -bool m_clampToBorder; -float m_alphaTest; -public: -MapLayer(qtexture_t *texture, BlendFunc blendFunc, bool clampToBorder, float alphaTest) : - m_texture(texture), - m_blendFunc(blendFunc), - m_clampToBorder(false), - m_alphaTest(alphaTest) -{ -} - -qtexture_t *texture() const -{ - return m_texture; -} - -BlendFunc blendFunc() const -{ - return m_blendFunc; -} - -bool clampToBorder() const -{ - return m_clampToBorder; -} - -float alphaTest() const -{ - return m_alphaTest; -} -}; - -static MapLayer evaluateLayer(const ShaderTemplate::MapLayerTemplate &layerTemplate, const ShaderParameters ¶ms, - const ShaderArguments &args) -{ - return MapLayer( - evaluateTexture(layerTemplate.texture(), params, args), - evaluateBlendFunc(layerTemplate.blendFunc(), params, args), - layerTemplate.clampToBorder(), - evaluateFloat(layerTemplate.alphaTest(), params, args) - ); -} - -typedef std::vector MapLayers; -MapLayers m_layers; - -const ShaderLayer *firstLayer() const -{ - if (m_layers.empty()) { - return 0; - } - return &m_layers.front(); -} - -void forEachLayer(const ShaderLayerCallback &callback) const -{ - for (MapLayers::const_iterator i = m_layers.begin(); i != m_layers.end(); ++i) { - callback(*i); - } -} - -qtexture_t *lightFalloffImage() const -{ - if (!string_empty(m_template.m_lightFalloffImage.c_str())) { - return m_pLightFalloffImage; - } - return 0; -} -}; - -typedef SmartPointer ShaderPointer; -typedef std::map shaders_t; -shaders_t g_ActiveShaders; -static shaders_t::iterator g_ActiveShadersIterator; - -void ActiveShaders_IteratorBegin() -{ - g_ActiveShadersIterator = g_ActiveShaders.begin(); -} - -bool ActiveShaders_IteratorAtEnd() -{ - return g_ActiveShadersIterator == g_ActiveShaders.end(); -} - -IShader *ActiveShaders_IteratorCurrent() -{ - return static_cast( g_ActiveShadersIterator->second ); -} - -void ActiveShaders_IteratorIncrement() -{ - ++g_ActiveShadersIterator; -} - -void debug_check_shaders(shaders_t &shaders) -{ - for (shaders_t::iterator i = shaders.begin(); i != shaders.end(); ++i) { - ASSERT_MESSAGE(i->second->refcount() == 1, "orphan shader still referenced"); - } -} - -// will free all GL binded qtextures and shaders -// NOTE: doesn't make much sense out of Radiant exit or called during a reload -void FreeShaders() -{ - // reload shaders - // empty the actives shaders list - debug_check_shaders(g_ActiveShaders); - g_ActiveShaders.clear(); - g_shaders.clear(); - g_shaderTemplates.clear(); - g_shaderDefinitions.clear(); - g_ActiveShadersChangedNotify(); -} - -bool ShaderTemplate::parseMaterial(Tokeniser &tokeniser) -{ - tokeniser.nextLine(); - - // we need to read until we hit a balanced } - int depth = 0; - for (;;) { - tokeniser.nextLine(); - const char *token = tokeniser.getToken(); - - if (token == 0) { - return false; - } - - if (string_equal(token, "{")) { - ++depth; - continue; - } else if (string_equal(token, "}")) { - --depth; - if (depth < 0) { // underflow - return false; - } - if (depth == 0) { // end of shader - break; - } - - continue; - } - - if (depth == 1) { - if (string_equal_nocase(token, "qer_nocarve")) { - m_nFlags |= QER_NOCARVE; - } else if (string_equal_nocase(token, "polygonoffset")) { - if (Tokeniser_getInteger(tokeniser, m_iPolygonOffset) == false) { - m_iPolygonOffset = 1; - } - m_nFlags |= QER_POLYOFS; - } else if (string_equal_nocase(token, "qer_trans")) { - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, m_fTrans)); - m_nFlags |= QER_TRANS; - } else if (string_equal_nocase(token, "qer_editorimage") || string_equal_nocase(token, "diffusemap")) { - RETURN_FALSE_IF_FAIL(Tokeniser_parseTextureName(tokeniser, m_textureName)); - } else if (string_equal_nocase(token, "qer_alphafunc")) { - const char *alphafunc = tokeniser.getToken(); - - if (alphafunc == 0) { - Tokeniser_unexpectedError(tokeniser, alphafunc, "#alphafunc"); - return false; - } - - if (string_equal_nocase(alphafunc, "equal")) { - m_AlphaFunc = IShader::eEqual; - } else if (string_equal_nocase(alphafunc, "greater")) { - m_AlphaFunc = IShader::eGreater; - } else if (string_equal_nocase(alphafunc, "less")) { - m_AlphaFunc = IShader::eLess; - } else if (string_equal_nocase(alphafunc, "gequal")) { - m_AlphaFunc = IShader::eGEqual; - } else if (string_equal_nocase(alphafunc, "lequal")) { - m_AlphaFunc = IShader::eLEqual; - } else { - m_AlphaFunc = IShader::eAlways; - } - - m_nFlags |= QER_ALPHATEST; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, m_AlphaRef)); - } else if (string_equal_nocase(token, "cull")) { - const char *cull = tokeniser.getToken(); - - if (cull == 0) { - Tokeniser_unexpectedError(tokeniser, cull, "#cull"); - return false; - } - - if (string_equal_nocase(cull, "none") - || string_equal_nocase(cull, "twosided") - || string_equal_nocase(cull, "disable")) { - m_Cull = IShader::eCullNone; - } else if (string_equal_nocase(cull, "back") - || string_equal_nocase(cull, "backside") - || string_equal_nocase(cull, "backsided")) { - m_Cull = IShader::eCullBack; - } else { - m_Cull = IShader::eCullBack; - } - - m_nFlags |= QER_CULL; - } else if (string_equal_nocase(token, "surfaceparm")) { - const char *surfaceparm = tokeniser.getToken(); - - if (surfaceparm == 0) { - Tokeniser_unexpectedError(tokeniser, surfaceparm, "#surfaceparm"); - return false; - } - - if (string_equal_nocase(surfaceparm, "fog")) { - m_nFlags |= QER_FOG; - if (m_fTrans == 1.0f) { // has not been explicitly set by qer_trans - m_fTrans = 0.35f; - } - } else if (string_equal_nocase(surfaceparm, "nodraw")) { - m_nFlags |= QER_NODRAW; - } else if (string_equal_nocase(surfaceparm, "nonsolid")) { - m_nFlags |= QER_NONSOLID; - } else if (string_equal_nocase(surfaceparm, "water")) { - m_nFlags |= QER_WATER; - } else if (string_equal_nocase(surfaceparm, "lava")) { - m_nFlags |= QER_LAVA; - } else if (string_equal_nocase(surfaceparm, "areaportal")) { - m_nFlags |= QER_AREAPORTAL; - } else if (string_equal_nocase(surfaceparm, "playerclip")) { - m_nFlags |= QER_CLIP; - } else if (string_equal_nocase(surfaceparm, "botclip")) { - m_nFlags |= QER_BOTCLIP; - } - } - } - } - - return true; -} - -class Layer { -public: -LayerTypeId m_type; -TextureExpression m_texture; -BlendFunc m_blendFunc; -bool m_clampToBorder; -float m_alphaTest; -float m_heightmapScale; - -Layer() : m_type(LAYER_NONE), m_blendFunc(BLEND_ONE, BLEND_ZERO), m_clampToBorder(false), m_alphaTest(-1), - m_heightmapScale(0) -{ -} -}; - -std::list g_shaderFilenames; - -#if defined(WIN64) || defined(WIN32) -char * -strndup (const char *s, size_t n) -{ - char *result; - size_t len = strlen (s); - - if (n < len) - len = n; - - result = (char *) malloc (len + 1); - - if (!result) - return 0; - - result[len] = '\0'; - return (char *) memcpy (result, s, len); -} -#endif - -char* m_substring(const char* str, size_t begin, size_t len) -{ - if (str == 0 || strlen(str) == 0 || strlen(str) < begin || strlen(str) < (begin+len)) { - return 0; - } - - return strndup(str + begin, len); -} - -void ParseShaderFile(Tokeniser &tokeniser, const char *filename) -{ - g_shaderFilenames.push_back(filename); - filename = g_shaderFilenames.back().c_str(); - tokeniser.nextLine(); - for (;;) { - const char *token = tokeniser.getToken(); - - if (token == 0) { - break; - } - - if (string_equal(token, "table")) { - if (tokeniser.getToken() == 0) { - Tokeniser_unexpectedError(tokeniser, 0, "#table-name"); - return; - } - if (!Tokeniser_parseToken(tokeniser, "{")) { - return; - } - for (;;) { - const char *option = tokeniser.getToken(); - if (string_equal(option, "{")) { - for (;;) { - const char *value = tokeniser.getToken(); - if (string_equal(value, "}")) { - break; - } - } - - if (!Tokeniser_parseToken(tokeniser, "}")) { - return; - } - break; - } - } - } else { - if (string_equal(token, "guide")) { - parseTemplateInstance(tokeniser, filename); - } else { - if (!string_equal(token, "material") - && !string_equal(token, "particle") - && !string_equal(token, "skin")) { - tokeniser.ungetToken(); - } - // first token should be the path + name.. (from base) - ShaderTemplatePointer shaderTemplate(new ShaderTemplate()); - shaderTemplate->setName( m_substring( filename, 0, strlen( filename) - 4 ) ); // EUKARA - - g_shaders.insert(ShaderTemplateMap::value_type(shaderTemplate->getName(), shaderTemplate)); - - bool result = shaderTemplate->parseMaterial(tokeniser); - if (result) { - // do we already have this shader? - if (!g_shaderDefinitions.insert(ShaderDefinitionMap::value_type(shaderTemplate->getName(), - ShaderDefinition( - shaderTemplate.get(), - ShaderArguments(), - filename))).second) { - #if GDEF_DEBUG - globalOutputStream() << "WARNING: shader " << shaderTemplate->getName() - << " is already in memory, definition in " << filename << " ignored.\n"; - #endif - } - } else { - globalErrorStream() << "Error parsing material " << shaderTemplate->getName() << "\n"; - return; - } - } - } - } -} - -void parseGuideFile(Tokeniser &tokeniser, const char *filename) -{ - tokeniser.nextLine(); - for (;;) { - const char *token = tokeniser.getToken(); - - if (token == 0) { - break; - } - - if (string_equal(token, "guide")) { - // first token should be the path + name.. (from base) - ShaderTemplatePointer shaderTemplate(new ShaderTemplate); - shaderTemplate->parseTemplate(tokeniser); - if (!g_shaderTemplates.insert( - ShaderTemplateMap::value_type(shaderTemplate->getName(), shaderTemplate)).second) { - globalErrorStream() << "guide " << makeQuoted(shaderTemplate->getName()) - << ": already defined, second definition ignored\n"; - } - } else if (string_equal(token, "inlineGuide")) { - // skip entire inlineGuide definition - std::size_t depth = 0; - for (;;) { - tokeniser.nextLine(); - token = tokeniser.getToken(); - if (string_equal(token, "{")) { - ++depth; - } else if (string_equal(token, "}")) { - if (--depth == 0) { - break; - } - } - } - } - } -} - -void LoadShaderFile(const char *filename) -{ - ArchiveTextFile *file = GlobalFileSystem().openTextFile(filename); - - if (file != 0) { - // we probably only want to output when errors happen - //globalOutputStream() << "Parsing material " << filename << "\n"; - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser(file->getInputStream()); - ParseShaderFile(tokeniser, filename); - tokeniser.release(); - file->release(); - } else { - globalOutputStream() << "Unable to read material " << filename << "\n"; - } -} - -void loadGuideFile(const char *filename) -{ - StringOutputStream fullname(256); - fullname << "guides/" << filename; - ArchiveTextFile *file = GlobalFileSystem().openTextFile(fullname.c_str()); - - if (file != 0) { - globalOutputStream() << "Parsing guide file " << fullname.c_str() << "\n"; - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser(file->getInputStream()); - parseGuideFile(tokeniser, fullname.c_str()); - tokeniser.release(); - file->release(); - } else { - globalOutputStream() << "Unable to read guide file " << fullname.c_str() << "\n"; - } -} - -CShader* Try_Shader_ForName( const char* name ){ - { - shaders_t::iterator i = g_ActiveShaders.find( name ); - if ( i != g_ActiveShaders.end() ) { - return ( *i ).second; - } - } - // active shader was not found - - // find matching shader definition - ShaderDefinitionMap::iterator i = g_shaderDefinitions.find( name ); - if ( i == g_shaderDefinitions.end() ) { - // shader definition was not found - - // create new shader definition from default shader template - ShaderTemplatePointer shaderTemplate( new ShaderTemplate() ); - shaderTemplate->CreateDefault( name ); - g_shaderTemplates.insert( ShaderTemplateMap::value_type( shaderTemplate->getName(), shaderTemplate ) ); - - i = g_shaderDefinitions.insert( ShaderDefinitionMap::value_type( name, ShaderDefinition( shaderTemplate.get(), ShaderArguments(), "" ) ) ).first; - } - - // create shader from existing definition - ShaderPointer pShader( new CShader( ( *i ).second ) ); - pShader->setName( name ); - g_ActiveShaders.insert( shaders_t::value_type( name, pShader ) ); - g_ActiveShadersChangedNotify(); - return pShader; -} - -IShader *Shader_ForName(const char *name) -{ - ASSERT_NOTNULL(name); - - IShader *pShader = Try_Shader_ForName(name); - pShader->IncRef(); - return pShader; -} - - -// the list of scripts/*.shader files we need to work with -// those are listed in shaderlist file -GSList *l_shaderfiles = 0; - -GSList *Shaders_getShaderFileList() -{ - return l_shaderfiles; -} - -/* - ================== - DumpUnreferencedShaders - usefull function: dumps the list of .shader files that are not referenced to the console - ================== - */ -void IfFound_dumpUnreferencedShader(bool &bFound, const char *filename) -{ - bool listed = false; - - for (GSList *sh = l_shaderfiles; sh != 0; sh = g_slist_next(sh)) { - if (!strcmp((char *) sh->data, filename)) { - listed = true; - break; - } - } - - if (!listed) { - if (!bFound) { - bFound = true; - globalOutputStream() << "Following shader files are not referenced in any shaderlist.txt:\n"; - } - globalOutputStream() << "\t" << filename << "\n"; - } -} - -typedef ReferenceCaller IfFoundDumpUnreferencedShaderCaller; - -void DumpUnreferencedShaders() -{ - bool bFound = false; - GlobalFileSystem().forEachFile(g_shadersDirectory, g_shadersExtension, IfFoundDumpUnreferencedShaderCaller(bFound)); -} - -void ShaderList_addShaderFile(const char *dirstring) -{ - bool found = false; - - for (GSList *tmp = l_shaderfiles; tmp != 0; tmp = tmp->next) { - if (string_equal_nocase(dirstring, (char *) tmp->data)) { - found = true; - globalOutputStream() << "duplicate entry \"" << (char *) tmp->data << "\" in shaderlist.txt\n"; - break; - } - } - - if (!found) { - l_shaderfiles = g_slist_append(l_shaderfiles, strdup(dirstring)); - } -} - -/* - ================== - BuildShaderList - build a CStringList of shader names - ================== - */ -void BuildShaderList(TextInputStream &shaderlist) -{ - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(shaderlist); - tokeniser.nextLine(); - const char *token = tokeniser.getToken(); - StringOutputStream shaderFile(64); - while (token != 0) { - // each token should be a shader filename - shaderFile << token << "." << g_shadersExtension; - ShaderList_addShaderFile(shaderFile.c_str()); - tokeniser.nextLine(); - token = tokeniser.getToken(); - shaderFile.clear(); - } - tokeniser.release(); -} - -void FreeShaderList() -{ - while (l_shaderfiles != 0) { - free(l_shaderfiles->data); - l_shaderfiles = g_slist_remove(l_shaderfiles, l_shaderfiles->data); - } -} - -void ShaderList_addFromArchive(const char *archivename) -{ - const char *shaderpath = GlobalRadiant().getGameDescriptionKeyValue("shaderpath"); - if (string_empty(shaderpath)) { - return; - } - - StringOutputStream shaderlist(256); - shaderlist << DirectoryCleaned(shaderpath) << "shaderlist.txt"; - - Archive *archive = GlobalFileSystem().getArchive(archivename, false); - if (archive) { - ArchiveTextFile *file = archive->openTextFile(shaderlist.c_str()); - if (file) { - globalOutputStream() << "Found shaderlist.txt in " << archivename << "\n"; - BuildShaderList(file->getInputStream()); - file->release(); - } - } -} - -#include "stream/filestream.h" - -bool -shaderlist_findOrInstall(const char *enginePath, const char *toolsPath, const char *shaderPath, const char *gamename) -{ - StringOutputStream absShaderList(256); - absShaderList << enginePath << gamename << '/' << shaderPath << "shaderlist.txt"; - if (file_exists(absShaderList.c_str())) { - return true; - } - { - StringOutputStream directory(256); - directory << enginePath << gamename << '/' << shaderPath; - if (!file_exists(directory.c_str()) && !Q_mkdir(directory.c_str())) { - return false; - } - } - { - StringOutputStream defaultShaderList(256); - defaultShaderList << toolsPath << gamename << '/' << "default_shaderlist.txt"; - if (file_exists(defaultShaderList.c_str())) { - return file_copy(defaultShaderList.c_str(), absShaderList.c_str()); - } - } - return false; -} - -void Shaders_Load() -{ - /*if (QUAKE4) { - GlobalFileSystem().forEachFile("guides/", "guide", makeCallbackF(loadGuideFile), 0); - }*/ - - const char *shaderPath = GlobalRadiant().getGameDescriptionKeyValue("shaderpath"); - if (!string_empty(shaderPath)) { - StringOutputStream path(256); - path << DirectoryCleaned(shaderPath); - - if (g_useShaderList) { - // preload shader files that have been listed in shaderlist.txt - const char *basegame = GlobalRadiant().getRequiredGameDescriptionKeyValue("basegame"); - const char *gamename = GlobalRadiant().getGameName(); - const char *enginePath = GlobalRadiant().getEnginePath(); - const char *toolsPath = GlobalRadiant().getGameToolsPath(); - bool isMod = !string_equal(basegame, gamename); - - if (!isMod || !shaderlist_findOrInstall(enginePath, toolsPath, path.c_str(), gamename)) { - gamename = basegame; - shaderlist_findOrInstall(enginePath, toolsPath, path.c_str(), gamename); - } - - GlobalFileSystem().forEachArchive(makeCallbackF(ShaderList_addFromArchive), false, true); - DumpUnreferencedShaders(); - } else { - GlobalFileSystem().forEachFile(path.c_str(), g_shadersExtension, makeCallbackF(ShaderList_addShaderFile), 0); - } - - GSList *lst = l_shaderfiles; - StringOutputStream shadername(256); - while (lst) { - shadername << path.c_str() << reinterpret_cast( lst->data ); - LoadShaderFile(shadername.c_str()); - shadername.clear(); - lst = lst->next; - } - } - - //StringPool_analyse(ShaderPool::instance()); -} - -void Shaders_Free() -{ - FreeShaders(); - FreeShaderList(); - g_shaderFilenames.clear(); -} - -ModuleObservers g_observers; - -// wait until filesystem and is realised before loading anything -std::size_t g_shaders_unrealised = 1; -bool Shaders_realised() -{ - return g_shaders_unrealised == 0; -} - -void Shaders_Realise() -{ - if (--g_shaders_unrealised == 0) { - Shaders_Load(); - g_observers.realise(); - } -} - -void Shaders_Unrealise() -{ - if (++g_shaders_unrealised == 1) { - g_observers.unrealise(); - Shaders_Free(); - } -} - -void Shaders_Refresh() -{ - Shaders_Unrealise(); - Shaders_Realise(); -} - -class MaterialSystem : public ShaderSystem, public ModuleObserver { -public: -void realise() -{ - Shaders_Realise(); -} - -void unrealise() -{ - Shaders_Unrealise(); -} - -void refresh() -{ - Shaders_Refresh(); -} - -IShader *getShaderForName(const char *name) -{ - return Shader_ForName(name); -} - -void foreachShaderName(const ShaderNameCallback &callback) -{ - for (ShaderDefinitionMap::const_iterator i = g_shaderDefinitions.begin(); i != g_shaderDefinitions.end(); ++i) { - callback((*i).first.c_str()); - } -} - -void beginActiveShadersIterator() -{ - ActiveShaders_IteratorBegin(); -} - -bool endActiveShadersIterator() -{ - return ActiveShaders_IteratorAtEnd(); -} - -IShader *dereferenceActiveShadersIterator() -{ - return ActiveShaders_IteratorCurrent(); -} - -void incrementActiveShadersIterator() -{ - ActiveShaders_IteratorIncrement(); -} - -void setActiveShadersChangedNotify(const Callback ¬ify) -{ - g_ActiveShadersChangedNotify = notify; -} - -void attach(ModuleObserver &observer) -{ - g_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - g_observers.detach(observer); -} - -void setLightingEnabled(bool enabled) -{ - -} - -const char *getTexturePrefix() const -{ - return g_texturePrefix; -} -}; - -MaterialSystem g_MaterialSystem; - -ShaderSystem &GetShaderSystem() -{ - return g_MaterialSystem; -} - -void Shaders_Construct() -{ - GlobalFileSystem().attach(g_MaterialSystem); -} - -void Shaders_Destroy() -{ - GlobalFileSystem().detach(g_MaterialSystem); - - if (Shaders_realised()) { - Shaders_Free(); - } -} diff --git a/plugins/matsys/shaders.h b/plugins/matsys/shaders.h deleted file mode 100644 index 4c9859a..0000000 --- a/plugins/matsys/shaders.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_SHADERS_H ) -#define INCLUDED_SHADERS_H -void Shaders_Construct(); -void Shaders_Destroy(); -class ShaderSystem; -ShaderSystem &GetShaderSystem(); -extern const char *g_shadersExtension; -extern const char *g_shadersDirectory; -extern bool g_enableDefaultShaders; -extern bool g_useShaderList; -struct _QERPlugImageTable; -extern _QERPlugImageTable *g_bitmapModule; -#endif diff --git a/plugins/md3model/model.h b/plugins/md3model/model.h deleted file mode 100644 index 14c7de1..0000000 --- a/plugins/md3model/model.h +++ /dev/null @@ -1,634 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODEL_H ) -#define INCLUDED_MODEL_H - -#include "globaldefs.h" -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" -#include "modelskin.h" - -#include "math/frustum.h" -#include "string/string.h" -#include "generic/static.h" -#include "stream/stringstream.h" -#include "os/path.h" -#include "scenelib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "render.h" - -class VectorLightList : public LightList { -typedef std::vector Lights; -Lights m_lights; -public: -void addLight(const RendererLight &light) -{ - m_lights.push_back(&light); -} - -void clear() -{ - m_lights.clear(); -} - -void evaluateLights() const -{ -} - -void lightsChanged() const -{ -} - -void forEachLight(const RendererLightCallback &callback) const -{ - for (Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i) { - callback(*(*i)); - } -} -}; - -inline VertexPointer vertexpointer_arbitrarymeshvertex(const ArbitraryMeshVertex *array) -{ - return VertexPointer(VertexPointer::pointer(&array->vertex), sizeof(ArbitraryMeshVertex)); -} - -inline void parseTextureName(CopiedString &name, const char *token) -{ - StringOutputStream cleaned(256); - cleaned << PathCleaned(token); - name = StringRange(cleaned.c_str(), path_get_filename_base_end(cleaned.c_str())); // remove extension -} - -// generic renderable triangle surface -class Surface : - public OpenGLRenderable { -public: -typedef VertexBuffer vertices_t; -typedef IndexBuffer indices_t; -private: - -AABB m_aabb_local; -CopiedString m_shader; -Shader *m_state; - -vertices_t m_vertices; -indices_t m_indices; - -void CaptureShader() -{ - m_state = GlobalShaderCache().capture(m_shader.c_str()); -} - -void ReleaseShader() -{ - GlobalShaderCache().release(m_shader.c_str()); -} - -public: - -Surface() - : m_shader(""), m_state(0) -{ - CaptureShader(); -} - -~Surface() -{ - ReleaseShader(); -} - -vertices_t &vertices() -{ - return m_vertices; -} - -indices_t &indices() -{ - return m_indices; -} - -void setShader(const char *name) -{ - ReleaseShader(); - parseTextureName(m_shader, name); - CaptureShader(); -} - -const char *getShader() const -{ - return m_shader.c_str(); -} - -Shader *getState() const -{ - return m_state; -} - -void updateAABB() -{ - m_aabb_local = AABB(); - for (vertices_t::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - aabb_extend_by_point_safe(m_aabb_local, reinterpret_cast((*i).vertex )); - } - - - for (Surface::indices_t::iterator i = m_indices.begin(); i != m_indices.end(); i += 3) { - ArbitraryMeshVertex &a = m_vertices[*(i + 0)]; - ArbitraryMeshVertex &b = m_vertices[*(i + 1)]; - ArbitraryMeshVertex &c = m_vertices[*(i + 2)]; - - ArbitraryMeshTriangle_sumTangents(a, b, c); - } - - for (Surface::vertices_t::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - vector3_normalise(reinterpret_cast((*i).tangent )); - vector3_normalise(reinterpret_cast((*i).bitangent )); - } -} - -void render(RenderStateFlags state) const -{ - if ((state & RENDER_BUMP) != 0) { - if (GlobalShaderCache().useShaderLanguage()) { - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glVertexAttribPointerARB(c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->texcoord); - glVertexAttribPointerARB(c_attr_Tangent, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->tangent); - glVertexAttribPointerARB(c_attr_Binormal, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->bitangent); - } else { - glVertexAttribPointerARB(11, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glVertexAttribPointerARB(8, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord); - glVertexAttribPointerARB(9, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->tangent); - glVertexAttribPointerARB(10, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->bitangent); - } - } else { - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glTexCoordPointer(2, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord); - } - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->vertex); - glDrawElements(GL_TRIANGLES, GLsizei(m_indices.size()), RenderIndexTypeID, m_indices.data()); - -#if 0 - glBegin(GL_LINES); - - for (VertexBuffer::const_iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - Vector3 normal = vector3_added(vertex3f_to_vector3((*i).vertex), - vector3_scaled(normal3f_to_vector3((*i).normal), 8)); - glVertex3fv(vertex3f_to_array((*i).vertex)); - glVertex3fv(vector3_to_array(normal)); - } - glEnd(); -#endif -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -void render(Renderer &renderer, const Matrix4 &localToWorld, Shader *state) const -{ - renderer.SetState(state, Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); -} - -void render(Renderer &renderer, const Matrix4 &localToWorld) const -{ - render(renderer, localToWorld, m_state); -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - test.TestTriangles( - vertexpointer_arbitrarymeshvertex(m_vertices.data()), - IndexPointer(m_indices.data(), IndexPointer::index_type(m_indices.size())), - best - ); - if (best.valid()) { - selector.addIntersection(best); - } -} -}; - -// generic model node -class Model : - public Cullable, - public Bounded { -typedef std::vector surfaces_t; -surfaces_t m_surfaces; - -AABB m_aabb_local; -public: -Callback m_lightsChanged; - -~Model() -{ - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - delete *i; - } -} - -typedef surfaces_t::const_iterator const_iterator; - -const_iterator begin() const -{ - return m_surfaces.begin(); -} - -const_iterator end() const -{ - return m_surfaces.end(); -} - -std::size_t size() const -{ - return m_surfaces.size(); -} - -Surface &newSurface() -{ - m_surfaces.push_back(new Surface); - return *m_surfaces.back(); -} - -void updateAABB() -{ - m_aabb_local = AABB(); - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - aabb_extend_by_aabb_safe(m_aabb_local, (*i)->localAABB()); - } -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -virtual const AABB &localAABB() const -{ - return m_aabb_local; -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - if ((*i)->intersectVolume(test.getVolume(), localToWorld) != c_volumeOutside) { - (*i)->testSelect(selector, test, localToWorld); - } - } -} -}; - -inline void Surface_addLight(const Surface &surface, VectorLightList &lights, const Matrix4 &localToWorld, - const RendererLight &light) -{ - if (light.testAABB(aabb_for_oriented_aabb(surface.localAABB(), localToWorld))) { - lights.addLight(light); - } -} - -class ModelInstance : - public scene::Instance, - public Renderable, - public SelectionTestable, - public LightCullable, - public SkinnedModel { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -Model &m_model; - -const LightList *m_lightList; -typedef Array SurfaceLightLists; -SurfaceLightLists m_surfaceLightLists; - -class Remap { -public: -CopiedString first; -Shader *second; - -Remap() : second(0) -{ -} -}; - -typedef Array SurfaceRemaps; -SurfaceRemaps m_skins; -public: - -typedef LazyStatic StaticTypeCasts; - -Bounded &get(NullType) -{ - return m_model; -} - -Cullable &get(NullType) -{ - return m_model; -} - -void lightsChanged() -{ - m_lightList->lightsChanged(); -} - -typedef MemberCaller LightsChangedCaller; - -void constructRemaps() -{ - ModelSkin *skin = NodeTypeCast::cast(path().parent()); - if (skin != 0 && skin->realised()) { - SurfaceRemaps::iterator j = m_skins.begin(); - for (Model::const_iterator i = m_model.begin(); i != m_model.end(); ++i, ++j) { - const char *remap = skin->getRemap((*i)->getShader()); - if (!string_empty(remap)) { - (*j).first = remap; - (*j).second = GlobalShaderCache().capture(remap); - } else { - (*j).second = 0; - } - } - SceneChangeNotify(); - } -} - -void destroyRemaps() -{ - for (SurfaceRemaps::iterator i = m_skins.begin(); i != m_skins.end(); ++i) { - if ((*i).second != 0) { - GlobalShaderCache().release((*i).first.c_str()); - (*i).second = 0; - } - } -} - -void skinChanged() -{ - ASSERT_MESSAGE(m_skins.size() == m_model.size(), "ERROR"); - destroyRemaps(); - constructRemaps(); -} - -ModelInstance(const scene::Path &path, scene::Instance *parent, Model &model) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_model(model), - m_surfaceLightLists(m_model.size()), - m_skins(m_model.size()) -{ - m_lightList = &GlobalShaderCache().attach(*this); - m_model.m_lightsChanged = LightsChangedCaller(*this); - - Instance::setTransformChangedCallback(LightsChangedCaller(*this)); - - constructRemaps(); -} - -~ModelInstance() -{ - destroyRemaps(); - - Instance::setTransformChangedCallback(Callback()); - - m_model.m_lightsChanged = Callback(); - GlobalShaderCache().detach(*this); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - SurfaceLightLists::const_iterator j = m_surfaceLightLists.begin(); - SurfaceRemaps::const_iterator k = m_skins.begin(); - for (Model::const_iterator i = m_model.begin(); i != m_model.end(); ++i, ++j, ++k) { - if ((*i)->intersectVolume(volume, localToWorld) != c_volumeOutside) { - renderer.setLights(*j); - (*i)->render(renderer, localToWorld, (*k).second != 0 ? (*k).second : (*i)->getState()); - } - } -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_lightList->evaluateLights(); - - render(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_model.testSelect(selector, test, Instance::localToWorld()); -} - -bool testLight(const RendererLight &light) const -{ - return light.testAABB(worldAABB()); -} - -void insertLight(const RendererLight &light) -{ - const Matrix4 &localToWorld = Instance::localToWorld(); - SurfaceLightLists::iterator j = m_surfaceLightLists.begin(); - for (Model::const_iterator i = m_model.begin(); i != m_model.end(); ++i) { - Surface_addLight(*(*i), *j++, localToWorld, light); - } -} - -void clearLights() -{ - for (SurfaceLightLists::iterator i = m_surfaceLightLists.begin(); i != m_surfaceLightLists.end(); ++i) { - (*i).clear(); - } -} -}; - -class ModelNode : public scene::Node::Symbiot, public scene::Instantiable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Model m_model; -public: - -typedef LazyStatic StaticTypeCasts; - -ModelNode() : m_node(this, this, StaticTypeCasts::instance().get()) -{ -} - -Model &model() -{ - return m_model; -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new ModelInstance(path, parent, m_model); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - - -inline void -Surface_constructQuad(Surface &surface, const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &d, - const Vector3 &normal) -{ - surface.vertices().push_back( - ArbitraryMeshVertex( - vertex3f_for_vector3(a), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_topleft) - ) - ); - surface.vertices().push_back( - ArbitraryMeshVertex( - vertex3f_for_vector3(b), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_topright) - ) - ); - surface.vertices().push_back( - ArbitraryMeshVertex( - vertex3f_for_vector3(c), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_botright) - ) - ); - surface.vertices().push_back( - ArbitraryMeshVertex( - vertex3f_for_vector3(d), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_botleft) - ) - ); -} - -inline void Model_constructNull(Model &model) -{ - Surface &surface = model.newSurface(); - - AABB aabb(Vector3(0, 0, 0), Vector3(8, 8, 8)); - - Vector3 points[8]; - aabb_corners(aabb, points); - - surface.vertices().reserve(24); - - Surface_constructQuad(surface, points[2], points[1], points[5], points[6], aabb_normals[0]); - Surface_constructQuad(surface, points[1], points[0], points[4], points[5], aabb_normals[1]); - Surface_constructQuad(surface, points[0], points[1], points[2], points[3], aabb_normals[2]); - Surface_constructQuad(surface, points[0], points[3], points[7], points[4], aabb_normals[3]); - Surface_constructQuad(surface, points[3], points[2], points[6], points[7], aabb_normals[4]); - Surface_constructQuad(surface, points[7], points[6], points[5], points[4], aabb_normals[5]); - - surface.indices().reserve(36); - - RenderIndex indices[36] = { - 0, 1, 2, 0, 2, 3, - 4, 5, 6, 4, 6, 7, - 8, 9, 10, 8, 10, 11, - 12, 13, 14, 12, 14, 15, - 16, 17, 18, 16, 18, 19, - 20, 21, 22, 10, 22, 23, - }; - - for (RenderIndex *i = indices; i != indices + (sizeof(indices) / sizeof(RenderIndex)); ++i) { - surface.indices().insert(*i); - } - - surface.setShader(""); - - surface.updateAABB(); - - model.updateAABB(); -} - -#endif diff --git a/plugins/model/Makefile b/plugins/model/Makefile deleted file mode 100644 index bae6d1b..0000000 --- a/plugins/model/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - model.o plugin.o - -# binary target -../../build/plugins/libmodel.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libpicomodel.a $(PLUGIN_LDFLAGS) - -# object files -model.o: model.cpp model.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libmodel.$(LIB_EXT) \ No newline at end of file diff --git a/plugins/model/bitmaps/model_reload_entity.bmp b/plugins/model/bitmaps/model_reload_entity.bmp deleted file mode 100644 index 800a0df..0000000 Binary files a/plugins/model/bitmaps/model_reload_entity.bmp and /dev/null differ diff --git a/plugins/model/bitmaps/picomodel.bmp b/plugins/model/bitmaps/picomodel.bmp deleted file mode 100644 index 0d9c88e..0000000 Binary files a/plugins/model/bitmaps/picomodel.bmp and /dev/null differ diff --git a/plugins/model/model.cpp b/plugins/model/model.cpp deleted file mode 100644 index 036c508..0000000 --- a/plugins/model/model.cpp +++ /dev/null @@ -1,1025 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "model.h" -#include "globaldefs.h" - -#include "picomodel.h" - -#include "iarchive.h" -#include "idatastream.h" -#include "imodel.h" -#include "modelskin.h" - -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" - -#include "math/frustum.h" -#include "string/string.h" -#include "generic/static.h" -#include "shaderlib.h" -#include "scenelib.h" -#include "instancelib.h" -#include "transformlib.h" -#include "traverselib.h" -#include "render.h" - -class VectorLightList : public LightList { -typedef std::vector Lights; -Lights m_lights; -public: -void addLight(const RendererLight &light) -{ - m_lights.push_back(&light); -} - -void clear() -{ - m_lights.clear(); -} - -void evaluateLights() const -{ -} - -void lightsChanged() const -{ -} - -void forEachLight(const RendererLightCallback &callback) const -{ - for (Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i) { - callback(*(*i)); - } -} -}; - -class PicoSurface : - public OpenGLRenderable { -AABB m_aabb_local; -CopiedString m_shader; -Shader *m_state; - -Array m_vertices; -Array m_indices; - -public: - -PicoSurface() -{ - constructNull(); - CaptureShader(); -} - -PicoSurface(picoSurface_t *surface) -{ - CopyPicoSurface(surface); - CaptureShader(); -} - -~PicoSurface() -{ - ReleaseShader(); -} - -void render(RenderStateFlags state) const -{ - if ((state & RENDER_BUMP) != 0) { - if (GlobalShaderCache().useShaderLanguage()) { - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glVertexAttribPointerARB(c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->texcoord); - glVertexAttribPointerARB(c_attr_Tangent, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->tangent); - glVertexAttribPointerARB(c_attr_Binormal, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->bitangent); - } else { - glVertexAttribPointerARB(11, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glVertexAttribPointerARB(8, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord); - glVertexAttribPointerARB(9, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->tangent); - glVertexAttribPointerARB(10, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), - &m_vertices.data()->bitangent); - } - } else { - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal); - glTexCoordPointer(2, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord); - } - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->vertex); - glDrawElements(GL_TRIANGLES, GLsizei(m_indices.size()), RenderIndexTypeID, m_indices.data()); - -#if 0 - GLfloat modelview[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, modelview); // I know this is slow as hell, but hey - we're in _DEBUG - Matrix4 modelview_inv( - modelview[0], modelview[1], modelview[2], modelview[3], - modelview[4], modelview[5], modelview[6], modelview[7], - modelview[8], modelview[9], modelview[10], modelview[11], - modelview[12], modelview[13], modelview[14], modelview[15]); - matrix4_full_invert(modelview_inv); - Matrix4 modelview_inv_transposed = matrix4_transposed(modelview_inv); - - glBegin(GL_LINES); - - for (Array::const_iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - Vector3 normal = normal3f_to_vector3((*i).normal); - normal = matrix4_transformed_direction(modelview_inv, vector3_normalised( - matrix4_transformed_direction(modelview_inv_transposed, normal))); // do some magic - Vector3 normalTransformed = vector3_added(vertex3f_to_vector3((*i).vertex), vector3_scaled(normal, 8)); - glVertex3fv(vertex3f_to_array((*i).vertex)); - glVertex3fv(vector3_to_array(normalTransformed)); - } - glEnd(); -#endif -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -void render(Renderer &renderer, const Matrix4 &localToWorld, Shader *state) const -{ - renderer.SetState(state, Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); -} - -void render(Renderer &renderer, const Matrix4 &localToWorld) const -{ - render(renderer, localToWorld, m_state); -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - testSelect(test, best); - if (best.valid()) { - selector.addIntersection(best); - } -} - -const char *getShader() const -{ - return m_shader.c_str(); -} - -Shader *getState() const -{ - return m_state; -} - -private: - -void CaptureShader() -{ - m_state = GlobalShaderCache().capture(m_shader.c_str()); -} - -void ReleaseShader() -{ - GlobalShaderCache().release(m_shader.c_str()); -} - -void UpdateAABB() -{ - m_aabb_local = AABB(); - for (std::size_t i = 0; i < m_vertices.size(); ++i) { - aabb_extend_by_point_safe(m_aabb_local, reinterpret_cast( m_vertices[i].vertex )); - } - - - for (Array::iterator i = m_indices.begin(); i != m_indices.end(); i += 3) { - ArbitraryMeshVertex &a = m_vertices[*(i + 0)]; - ArbitraryMeshVertex &b = m_vertices[*(i + 1)]; - ArbitraryMeshVertex &c = m_vertices[*(i + 2)]; - - ArbitraryMeshTriangle_sumTangents(a, b, c); - } - - for (Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - vector3_normalise(reinterpret_cast((*i).tangent )); - vector3_normalise(reinterpret_cast((*i).bitangent )); - } -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - test.TestTriangles( - VertexPointer(VertexPointer::pointer(&m_vertices.data()->vertex), sizeof(ArbitraryMeshVertex)), - IndexPointer(m_indices.data(), IndexPointer::index_type(m_indices.size())), - best - ); -} - -void CopyPicoSurface(picoSurface_t *surface) -{ - picoShader_t *shader = PicoGetSurfaceShader(surface); - if (shader == 0) { - m_shader = ""; - } else { - m_shader = PicoGetShaderName(shader); - } - - m_vertices.resize(PicoGetSurfaceNumVertexes(surface)); - m_indices.resize(PicoGetSurfaceNumIndexes(surface)); - - for (std::size_t i = 0; i < m_vertices.size(); ++i) { - picoVec_t *xyz = PicoGetSurfaceXYZ(surface, int(i)); - m_vertices[i].vertex = vertex3f_from_array(xyz); - - picoVec_t *normal = PicoGetSurfaceNormal(surface, int(i)); - m_vertices[i].normal = normal3f_from_array(normal); - - picoVec_t *st = PicoGetSurfaceST(surface, 0, int(i)); - m_vertices[i].texcoord = TexCoord2f(st[0], st[1]); - -#if 0 - picoVec_t* color = PicoGetSurfaceColor( surface, 0, int(i) ); - m_vertices[i].colour = Colour4b( color[0], color[1], color[2], color[3] ); -#endif - } - - picoIndex_t *indexes = PicoGetSurfaceIndexes(surface, 0); - for (std::size_t j = 0; j < m_indices.size(); ++j) { - m_indices[j] = indexes[j]; - } - - UpdateAABB(); -} - -void constructQuad(std::size_t index, const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &d, - const Vector3 &normal) -{ - m_vertices[index * 4 + 0] = ArbitraryMeshVertex( - vertex3f_for_vector3(a), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_topleft) - ); - m_vertices[index * 4 + 1] = ArbitraryMeshVertex( - vertex3f_for_vector3(b), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_topright) - ); - m_vertices[index * 4 + 2] = ArbitraryMeshVertex( - vertex3f_for_vector3(c), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_botright) - ); - m_vertices[index * 4 + 3] = ArbitraryMeshVertex( - vertex3f_for_vector3(d), - normal3f_for_vector3(normal), - texcoord2f_from_array(aabb_texcoord_botleft) - ); -} - -void constructNull() -{ - AABB aabb(Vector3(0, 0, 0), Vector3(8, 8, 8)); - - Vector3 points[8]; - aabb_corners(aabb, points); - - m_vertices.resize(24); - - constructQuad(0, points[2], points[1], points[5], points[6], aabb_normals[0]); - constructQuad(1, points[1], points[0], points[4], points[5], aabb_normals[1]); - constructQuad(2, points[0], points[1], points[2], points[3], aabb_normals[2]); - constructQuad(3, points[0], points[3], points[7], points[4], aabb_normals[3]); - constructQuad(4, points[3], points[2], points[6], points[7], aabb_normals[4]); - constructQuad(5, points[7], points[6], points[5], points[4], aabb_normals[5]); - - m_indices.resize(36); - - RenderIndex indices[36] = { - 0, 1, 2, 0, 2, 3, - 4, 5, 6, 4, 6, 7, - 8, 9, 10, 8, 10, 11, - 12, 13, 14, 12, 14, 15, - 16, 17, 18, 16, 18, 19, - 20, 21, 22, 10, 22, 23, - }; - - - Array::iterator j = m_indices.begin(); - for (RenderIndex *i = indices; i != indices + (sizeof(indices) / sizeof(RenderIndex)); ++i) { - *j++ = *i; - } - - m_shader = ""; - - UpdateAABB(); -} -}; - - -typedef std::pair PicoModelKey; - - -class PicoModel : - public Cullable, - public Bounded { -typedef std::vector surfaces_t; -surfaces_t m_surfaces; - -AABB m_aabb_local; -public: -Callback m_lightsChanged; - -PicoModel() -{ - constructNull(); -} - -PicoModel(picoModel_t *model) -{ - CopyPicoModel(model); -} - -~PicoModel() -{ - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - delete *i; - } -} - -typedef surfaces_t::const_iterator const_iterator; - -const_iterator begin() const -{ - return m_surfaces.begin(); -} - -const_iterator end() const -{ - return m_surfaces.end(); -} - -std::size_t size() const -{ - return m_surfaces.size(); -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -virtual const AABB &localAABB() const -{ - return m_aabb_local; -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, - std::vector states) const -{ - for (surfaces_t::const_iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - if ((*i)->intersectVolume(volume, localToWorld) != c_volumeOutside) { - (*i)->render(renderer, localToWorld, states[i - m_surfaces.begin()]); - } - } -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - for (surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i) { - if ((*i)->intersectVolume(test.getVolume(), localToWorld) != c_volumeOutside) { - (*i)->testSelect(selector, test, localToWorld); - } - } -} - -private: -void CopyPicoModel(picoModel_t *model) -{ - m_aabb_local = AABB(); - - /* each surface on the model will become a new map drawsurface */ - int numSurfaces = PicoGetModelNumSurfaces(model); - //% SYs_FPrintf( SYS_VRB, "Model %s has %d surfaces\n", name, numSurfaces ); - for (int s = 0; s < numSurfaces; ++s) { - /* get surface */ - picoSurface_t *surface = PicoGetModelSurface(model, s); - if (surface == 0) { - continue; - } - - /* only handle triangle surfaces initially (fixme: support patches) */ - if (PicoGetSurfaceType(surface) != PICO_TRIANGLES) { - continue; - } - - /* fix the surface's normals */ - PicoFixSurfaceNormals(surface); - - PicoSurface *picosurface = new PicoSurface(surface); - aabb_extend_by_aabb_safe(m_aabb_local, picosurface->localAABB()); - m_surfaces.push_back(picosurface); - } -} - -void constructNull() -{ - PicoSurface *picosurface = new PicoSurface(); - m_aabb_local = picosurface->localAABB(); - m_surfaces.push_back(picosurface); -} -}; - -inline void -Surface_addLight(PicoSurface &surface, VectorLightList &lights, const Matrix4 &localToWorld, const RendererLight &light) -{ - if (light.testAABB(aabb_for_oriented_aabb(surface.localAABB(), localToWorld))) { - lights.addLight(light); - } -} - -class PicoModelInstance : - public scene::Instance, - public Renderable, - public SelectionTestable, - public LightCullable, - public SkinnedModel { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -PicoModel &m_picomodel; - -const LightList *m_lightList; -typedef Array SurfaceLightLists; -SurfaceLightLists m_surfaceLightLists; - -class Remap { -public: -CopiedString first; -Shader *second; - -Remap() : second(0) -{ -} -}; - -typedef Array SurfaceRemaps; -SurfaceRemaps m_skins; - -PicoModelInstance(const PicoModelInstance &); - -PicoModelInstance operator=(const PicoModelInstance &); - -public: -typedef LazyStatic StaticTypeCasts; - -void *m_test; - -Bounded &get(NullType) -{ - return m_picomodel; -} - -Cullable &get(NullType) -{ - return m_picomodel; -} - -void lightsChanged() -{ - m_lightList->lightsChanged(); -} - -typedef MemberCaller LightsChangedCaller; - -void constructRemaps() -{ - ASSERT_MESSAGE(m_skins.size() == m_picomodel.size(), "ERROR"); - ModelSkin *skin = NodeTypeCast::cast(path().parent()); - if (skin != 0 && skin->realised()) { - SurfaceRemaps::iterator j = m_skins.begin(); - for (PicoModel::const_iterator i = m_picomodel.begin(); i != m_picomodel.end(); ++i, ++j) { - const char *remap = skin->getRemap((*i)->getShader()); - if (!string_empty(remap)) { - (*j).first = remap; - (*j).second = GlobalShaderCache().capture(remap); - } else { - (*j).second = 0; - } - } - SceneChangeNotify(); - } -} - -void destroyRemaps() -{ - ASSERT_MESSAGE(m_skins.size() == m_picomodel.size(), "ERROR"); - for (SurfaceRemaps::iterator i = m_skins.begin(); i != m_skins.end(); ++i) { - if ((*i).second != 0) { - GlobalShaderCache().release((*i).first.c_str()); - (*i).second = 0; - } - } -} - -void skinChanged() -{ - destroyRemaps(); - constructRemaps(); -} - -PicoModelInstance(const scene::Path &path, scene::Instance *parent, PicoModel &picomodel) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_picomodel(picomodel), - m_surfaceLightLists(m_picomodel.size()), - m_skins(m_picomodel.size()) -{ - m_lightList = &GlobalShaderCache().attach(*this); - m_picomodel.m_lightsChanged = LightsChangedCaller(*this); - - Instance::setTransformChangedCallback(LightsChangedCaller(*this)); - - constructRemaps(); -} - -~PicoModelInstance() -{ - destroyRemaps(); - - Instance::setTransformChangedCallback(Callback()); - - m_picomodel.m_lightsChanged = Callback(); - GlobalShaderCache().detach(*this); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - SurfaceLightLists::const_iterator j = m_surfaceLightLists.begin(); - SurfaceRemaps::const_iterator k = m_skins.begin(); - for (PicoModel::const_iterator i = m_picomodel.begin(); i != m_picomodel.end(); ++i, ++j, ++k) { - if ((*i)->intersectVolume(volume, localToWorld) != c_volumeOutside) { - renderer.setLights(*j); - (*i)->render(renderer, localToWorld, (*k).second != 0 ? (*k).second : (*i)->getState()); - } - } -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_lightList->evaluateLights(); - - render(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_picomodel.testSelect(selector, test, Instance::localToWorld()); -} - -bool testLight(const RendererLight &light) const -{ - return light.testAABB(worldAABB()); -} - -void insertLight(const RendererLight &light) -{ - const Matrix4 &localToWorld = Instance::localToWorld(); - SurfaceLightLists::iterator j = m_surfaceLightLists.begin(); - for (PicoModel::const_iterator i = m_picomodel.begin(); i != m_picomodel.end(); ++i) { - Surface_addLight(*(*i), *j++, localToWorld, light); - } -} - -void clearLights() -{ - for (SurfaceLightLists::iterator i = m_surfaceLightLists.begin(); i != m_surfaceLightLists.end(); ++i) { - (*i).clear(); - } -} -}; - -class PicoModelNode : public scene::Node::Symbiot, public scene::Instantiable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -PicoModel m_picomodel; - -public: -typedef LazyStatic StaticTypeCasts; - -PicoModelNode() : m_node(this, this, StaticTypeCasts::instance().get()) -{ -} - -PicoModelNode(picoModel_t *model) : m_node(this, this, StaticTypeCasts::instance().get()), m_picomodel(model) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new PicoModelInstance(path, parent, m_picomodel); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - - -#if 0 - -template -class create_new -{ -public: -static Type* construct( const Key& key ){ - return new Type( key ); -} -static void destroy( Type* value ){ - delete value; -} -}; - -template > -class cache_element : public creation_policy -{ -public: -inline cache_element() : m_count( 0 ), m_value( 0 ) { -} -inline ~cache_element(){ - ASSERT_MESSAGE( m_count == 0, "destroyed a reference before it was released\n" ); - if ( m_count > 0 ) { - destroy(); - } -} -inline Type* capture( const Key& key ){ - if ( ++m_count == 1 ) { - construct( key ); - } - return m_value; -} -inline void release(){ - ASSERT_MESSAGE( !empty(), "failed to release reference - not found in cache\n" ); - if ( --m_count == 0 ) { - destroy(); - } -} -inline bool empty(){ - return m_count == 0; -} -inline void refresh( const Key& key ){ - m_value->refresh( key ); -} -private: -inline void construct( const Key& key ){ - m_value = creation_policy::construct( key ); -} -inline void destroy(){ - creation_policy::destroy( m_value ); -} - -std::size_t m_count; -Type* m_value; -}; - -class create_picomodel -{ -typedef PicoModelKey key_type; -typedef PicoModel value_type; -public: -static value_type* construct( const key_type& key ){ - picoModel_t* picomodel = PicoLoadModel( const_cast( key.first.c_str() ), key.second ); - value_type* value = new value_type( picomodel ); - PicoFreeModel( picomodel ); - return value; -} -static void destroy( value_type* value ){ - delete value; -} -}; - -#include - -class ModelCache -{ -typedef PicoModel value_type; - -public: -typedef PicoModelKey key_type; -typedef cache_element elem_type; -typedef std::map cache_type; - -value_type* capture( const key_type& key ){ - return m_cache[key].capture( key ); -} -void release( const key_type& key ){ - m_cache[key].release(); -} - -private: -cache_type m_cache; -}; - -ModelCache g_model_cache; - - - -typedef struct remap_s { - char m_remapbuff[64 + 1024]; - char *original; - char *remap; -} remap_t; - -class RemapWrapper : - public Cullable, - public Bounded -{ -public: -RemapWrapper( const char* name ){ - parse_namestr( name ); - - m_model = g_model_cache.capture( ModelCache::key_type( m_name, m_frame ) ); - - construct_shaders(); -} -virtual ~RemapWrapper(){ - g_model_cache.release( ModelCache::key_type( m_name, m_frame ) ); - - for ( shaders_t::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i ) - { - GlobalShaderCache().release( ( *i ).c_str() ); - } - - for ( remaps_t::iterator j = m_remaps.begin(); j != m_remaps.end(); ++j ) - { - delete ( *j ); - } -} - -VolumeIntersectionValue intersectVolume( const VolumeTest& test, const Matrix4& localToWorld ) const { - return m_model->intersectVolume( test, localToWorld ); -} - -virtual const AABB& localAABB() const { - return m_model->localAABB(); -} - -void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const { - m_model->render( renderer, volume, localToWorld, m_states ); -} - -void testSelect( Selector& selector, SelectionTest& test, const Matrix4& localToWorld ){ - m_model->testSelect( selector, test, localToWorld ); -} - -private: -void add_remap( const char *remap ){ - const char *ch; - remap_t *pRemap; - - ch = remap; - - while ( *ch && *ch != ';' ) - ch++; - - if ( *ch == '\0' ) { - // bad remap - globalErrorStream() << "WARNING: Shader _remap key found in a model entity without a ; character\n"; - } - else { - pRemap = new remap_t; - - strncpy( pRemap->m_remapbuff, remap, sizeof( pRemap->m_remapbuff ) ); - - pRemap->m_remapbuff[ch - remap] = '\0'; - - pRemap->original = pRemap->m_remapbuff; - pRemap->remap = pRemap->m_remapbuff + ( ch - remap ) + 1; - - m_remaps.push_back( pRemap ); - } -} - -void parse_namestr( const char *name ){ - const char *ptr, *s; - bool hasName, hasFrame; - - hasName = hasFrame = false; - - m_frame = 0; - - for ( s = ptr = name; ; ++ptr ) - { - if ( !hasName && ( *ptr == ':' || *ptr == '\0' ) ) { - // model name - hasName = true; - m_name = CopiedString( s, ptr ); - s = ptr + 1; - } - else if ( *ptr == '?' || *ptr == '\0' ) { - // model frame - hasFrame = true; - m_frame = atoi( CopiedString( s, ptr ).c_str() ); - s = ptr + 1; - } - else if ( *ptr == '&' || *ptr == '\0' ) { - // a remap - add_remap( CopiedString( s, ptr ).c_str() ); - s = ptr + 1; - } - - if ( *ptr == '\0' ) { - break; - } - } -} - -void construct_shaders(){ - const char* global_shader = shader_for_remap( "*" ); - - m_shaders.reserve( m_model->size() ); - m_states.reserve( m_model->size() ); - for ( PicoModel::iterator i = m_model->begin(); i != m_model->end(); ++i ) - { - const char* shader = shader_for_remap( ( *i )->getShader() ); - m_shaders.push_back( - ( shader[0] != '\0' ) - ? shader - : ( global_shader[0] != '\0' ) - ? global_shader - : ( *i )->getShader() ); - m_states.push_back( GlobalShaderCache().capture( m_shaders.back().c_str() ) ); - } -} - -inline const char* shader_for_remap( const char* remap ){ - for ( remaps_t::iterator i = m_remaps.begin(); i != m_remaps.end(); ++i ) - { - if ( shader_equal( remap, ( *i )->original ) ) { - return ( *i )->remap; - } - } - return ""; -} - -CopiedString m_name; -int m_frame; -PicoModel* m_model; - -typedef std::vector remaps_t; -remaps_t m_remaps; -typedef std::vector shaders_t; -shaders_t m_shaders; -typedef std::vector states_t; -states_t m_states; -}; - -class RemapWrapperInstance : public scene::Instance, public Renderable, public SelectionTestable -{ -RemapWrapper& m_remapwrapper; -public: -RemapWrapperInstance( const scene::Path& path, scene::Instance* parent, RemapWrapper& remapwrapper ) : Instance( path, parent ), m_remapwrapper( remapwrapper ){ - scene::Instance::m_cullable = &m_remapwrapper; - scene::Instance::m_render = this; - scene::Instance::m_select = this; -} - -void renderSolid( Renderer& renderer, const VolumeTest& volume ) const { - m_remapwrapper.render( renderer, volume, Instance::localToWorld() ); -} -void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const { - renderSolid( renderer, volume ); -} - -void testSelect( Selector& selector, SelectionTest& test ){ - m_remapwrapper.testSelect( selector, test, Instance::localToWorld() ); -} -}; - -class RemapWrapperNode : public scene::Node::Symbiot, public scene::Instantiable -{ -scene::Node m_node; -typedef RemapWrapperInstance instance_type; -InstanceSet m_instances; -RemapWrapper m_remapwrapper; -public: -RemapWrapperNode( const char* name ) : m_node( this ), m_remapwrapper( name ){ - m_node.m_instance = this; -} - -void release(){ - delete this; -} -scene::Node& node(){ - return m_node; -} - -scene::Instance* create( const scene::Path& path, scene::Instance* parent ){ - return new instance_type( path, parent, m_remapwrapper ); -} -void forEachInstance( const scene::Instantiable::Visitor& visitor ){ - m_instances.forEachInstance( visitor ); -} -void insert( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance ){ - m_instances.insert( observer, path, instance ); -} -scene::Instance* erase( scene::Instantiable::Observer* observer, const scene::Path& path ){ - return m_instances.erase( observer, path ); -} -}; - -scene::Node& LoadRemapModel( const char* name ){ - return ( new RemapWrapperNode( name ) )->node(); -} - -#endif - - -size_t picoInputStreamReam(void *inputStream, unsigned char *buffer, size_t length) -{ - return reinterpret_cast( inputStream )->read(buffer, length); -} - -scene::Node &loadPicoModel(const picoModule_t *module, ArchiveFile &file) -{ - picoModel_t *model = PicoModuleLoadModelStream(module, &file.getInputStream(), picoInputStreamReam, file.size(), 0, - file.getName()); - PicoModelNode *modelNode = new PicoModelNode(model); - PicoFreeModel(model); - return modelNode->node(); -} diff --git a/plugins/model/model.h b/plugins/model/model.h deleted file mode 100644 index b0145f5..0000000 --- a/plugins/model/model.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MODEL_H ) -#define INCLUDED_MODEL_H - -namespace scene { class Node; } -class ArchiveFile; - -typedef struct picoModule_s picoModule_t; - -scene::Node &loadPicoModel(const picoModule_t *module, ArchiveFile &file); - -#endif diff --git a/plugins/model/plugin.cpp b/plugins/model/plugin.cpp deleted file mode 100644 index df619d0..0000000 --- a/plugins/model/plugin.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "picomodel.h" - -typedef unsigned char byte; - -#include -#include -#include - -#include "iscenegraph.h" -#include "irender.h" -#include "iselection.h" -#include "iimage.h" -#include "imodel.h" -#include "igl.h" -#include "ifilesystem.h" -#include "iundo.h" -#include "ifiletypes.h" - -#include "modulesystem/singletonmodule.h" -#include "stream/textstream.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "typesystem.h" - -#include "model.h" - -void PicoPrintFunc(int level, const char *str) -{ - if (str == 0) { - return; - } - switch (level) { - case PICO_NORMAL: - globalOutputStream() << str << "\n"; - break; - - case PICO_VERBOSE: - //globalOutputStream() << "PICO_VERBOSE: " << str << "\n"; - break; - - case PICO_WARNING: - globalErrorStream() << "PICO_WARNING: " << str << "\n"; - break; - - case PICO_ERROR: - globalErrorStream() << "PICO_ERROR: " << str << "\n"; - break; - - case PICO_FATAL: - globalErrorStream() << "PICO_FATAL: " << str << "\n"; - break; - } -} - -void PicoLoadFileFunc(const char *name, byte **buffer, int *bufSize) -{ - *bufSize = vfsLoadFile(name, (void **) buffer); -} - -void PicoFreeFileFunc(void *file) -{ - vfsFreeFile(file); -} - -void pico_initialise() -{ - PicoInit(); - PicoSetMallocFunc(malloc); - PicoSetFreeFunc(free); - PicoSetPrintFunc(PicoPrintFunc); - PicoSetLoadFileFunc(PicoLoadFileFunc); - PicoSetFreeFileFunc(PicoFreeFileFunc); -} - - -class PicoModelLoader : public ModelLoader { -const picoModule_t *m_module; -public: -PicoModelLoader(const picoModule_t *module) : m_module(module) -{ -} - -scene::Node &loadModel(ArchiveFile &file) -{ - return loadPicoModel(m_module, file); -} -}; - -class ModelPicoDependencies : - public GlobalFileSystemModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalFiletypesModuleRef { -}; - -class ModelPicoAPI : public TypeSystemRef { -PicoModelLoader m_modelLoader; -public: -typedef ModelLoader Type; - -ModelPicoAPI(const char *extension, const picoModule_t *module) : - m_modelLoader(module) -{ - StringOutputStream filter(128); - filter << "*." << extension; - GlobalFiletypesModule::getTable().addType(Type::Name(), extension, - filetype_t(module->displayName, filter.c_str())); -} - -ModelLoader *getTable() -{ - return &m_modelLoader; -} -}; - -class PicoModelAPIConstructor { -CopiedString m_extension; -const picoModule_t *m_module; -public: -PicoModelAPIConstructor(const char *extension, const picoModule_t *module) : - m_extension(extension), m_module(module) -{ -} - -const char *getName() -{ - return m_extension.c_str(); -} - -ModelPicoAPI *constructAPI(ModelPicoDependencies &dependencies) -{ - return new ModelPicoAPI(m_extension.c_str(), m_module); -} - -void destroyAPI(ModelPicoAPI *api) -{ - delete api; -} -}; - - -typedef SingletonModule PicoModelModule; -typedef std::list PicoModelModules; -PicoModelModules g_PicoModelModules; - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - pico_initialise(); - - const picoModule_t **modules = PicoModuleList(0); - while (*modules != 0) { - const picoModule_t *module = *modules++; - if (module->canload && module->load) { - for (char *const *ext = module->defaultExts; *ext != 0; ++ext) { - g_PicoModelModules.push_back(PicoModelModule(PicoModelAPIConstructor(*ext, module))); - g_PicoModelModules.back().selfRegister(); - } - } - } -} diff --git a/plugins/prtview/AboutDialog.cpp b/plugins/prtview/AboutDialog.cpp deleted file mode 100644 index ef37d98..0000000 --- a/plugins/prtview/AboutDialog.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "AboutDialog.h" -#include -#include -#include -#include "gtkutil/pointer.h" - -#include "prtview.h" -#include "ConfigDialog.h" - -static void dialog_button_callback(ui::Widget widget, gpointer data) -{ - int *loop, *ret; - - auto parent = widget.window(); - loop = (int *) g_object_get_data(G_OBJECT(parent), "loop"); - ret = (int *) g_object_get_data(G_OBJECT(parent), "ret"); - - *loop = 0; - *ret = gpointer_to_int(data); -} - -static gint dialog_delete_callback(ui::Widget widget, GdkEvent *event, gpointer data) -{ - widget.hide(); - int *loop = (int *) g_object_get_data(G_OBJECT(widget), "loop"); - *loop = 0; - return TRUE; -} - -void DoAboutDlg() -{ - int loop = 1, ret = IDCANCEL; - - auto dlg = ui::Window(ui::window_type::TOP); - gtk_window_set_title(dlg, "About Portal Viewer"); - dlg.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL); - dlg.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL); - g_object_set_data(G_OBJECT(dlg), "loop", &loop); - g_object_set_data(G_OBJECT(dlg), "ret", &ret); - - auto hbox = ui::HBox(FALSE, 10); - hbox.show(); - dlg.add(hbox); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 10); - - char const *label_text = "Version 1.000\n\n" - "Gtk port by Leonardo Zide\nleo@lokigames.com\n\n" - "Written by Geoffrey DeWan\ngdewan@prairienet.org\n\n" - "Built against WorldSpawn\n" - __DATE__; - auto label = ui::Label(label_text); - label.show(); - hbox.pack_start(label, TRUE, TRUE, 0); - gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); - - auto vbox = ui::VBox(FALSE, 0); - vbox.show(); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - auto button = ui::Button("OK"); - button.show(); - vbox.pack_start(button, FALSE, FALSE, 0); - button.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDOK)); - button.dimensions(60, -1); - - gtk_grab_add(dlg); - dlg.show(); - - while (loop) { - gtk_main_iteration(); - } - - gtk_grab_remove(dlg); - dlg.destroy(); -} - - -///////////////////////////////////////////////////////////////////////////// -// CAboutDialog message handlers diff --git a/plugins/prtview/AboutDialog.h b/plugins/prtview/AboutDialog.h deleted file mode 100644 index b46fa93..0000000 --- a/plugins/prtview/AboutDialog.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined( INCLUDED_ABOUTDIALOG_H ) -#define INCLUDED_ABOUTDIALOG_H - -void DoAboutDlg(); - -#endif diff --git a/plugins/prtview/ConfigDialog.cpp b/plugins/prtview/ConfigDialog.cpp deleted file mode 100644 index 73b2ce8..0000000 --- a/plugins/prtview/ConfigDialog.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "ConfigDialog.h" -#include -#include -#include -#include "gtkutil/pointer.h" - -#include "iscenegraph.h" - -#include "prtview.h" -#include "portals.h" - -static void dialog_button_callback(ui::Widget widget, gpointer data) -{ - int *loop, *ret; - - auto parent = widget.window(); - loop = (int *) g_object_get_data(G_OBJECT(parent), "loop"); - ret = (int *) g_object_get_data(G_OBJECT(parent), "ret"); - - *loop = 0; - *ret = gpointer_to_int(data); -} - -static gint dialog_delete_callback(ui::Widget widget, GdkEvent *event, gpointer data) -{ - widget.hide(); - int *loop = (int *) g_object_get_data(G_OBJECT(widget), "loop"); - *loop = 0; - return TRUE; -} - -// ============================================================================= -// Color selection dialog - -static int DoColor(PackedColour *c) -{ - GdkColor clr; - int loop = 1, ret = IDCANCEL; - - clr.red = (guint16) (GetRValue(*c) * (65535 / 255)); - clr.blue = (guint16) (GetGValue(*c) * (65535 / 255)); - clr.green = (guint16) (GetBValue(*c) * (65535 / 255)); - - auto dlg = ui::Widget::from(gtk_color_selection_dialog_new("Choose Color")); - gtk_color_selection_set_current_color( - GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg))), &clr); - dlg.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL); - dlg.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL); - - GtkWidget *ok_button, *cancel_button; - g_object_get(dlg, "ok-button", &ok_button, "cancel-button", &cancel_button, nullptr); - - ui::Widget::from(ok_button).connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDOK)); - ui::Widget::from(cancel_button).connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDCANCEL)); - g_object_set_data(G_OBJECT(dlg), "loop", &loop); - g_object_set_data(G_OBJECT(dlg), "ret", &ret); - - dlg.show(); - gtk_grab_add(dlg); - - while (loop) { - gtk_main_iteration(); - } - - gtk_color_selection_get_current_color( - GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg))), &clr); - - gtk_grab_remove(dlg); - dlg.destroy(); - - if (ret == IDOK) { - *c = RGB(clr.red / (65535 / 255), clr.green / (65535 / 255), clr.blue / (65535 / 255)); - } - - return ret; -} - -static void Set2DText(ui::Widget label) -{ - char s[40]; - - sprintf(s, "Line Width = %6.3f", portals.width_2d * 0.5f); - - gtk_label_set_text(GTK_LABEL(label), s); -} - -static void Set3DText(ui::Widget label) -{ - char s[40]; - - sprintf(s, "Line Width = %6.3f", portals.width_3d * 0.5f); - - gtk_label_set_text(GTK_LABEL(label), s); -} - -static void Set3DTransText(ui::Widget label) -{ - char s[40]; - - sprintf(s, "Polygon transparency = %d%%", (int) portals.trans_3d); - - gtk_label_set_text(GTK_LABEL(label), s); -} - -static void SetClipText(ui::Widget label) -{ - char s[40]; - - sprintf(s, "Cubic clip range = %d", (int) portals.clip_range * 64); - - gtk_label_set_text(GTK_LABEL(label), s); -} - -static void OnScroll2d(ui::Adjustment adj, gpointer data) -{ - portals.width_2d = static_cast( gtk_adjustment_get_value(adj)); - Set2DText(ui::Widget::from(data)); - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnScroll3d(ui::Adjustment adj, gpointer data) -{ - portals.width_3d = static_cast( gtk_adjustment_get_value(adj)); - Set3DText(ui::Widget::from(data)); - - SceneChangeNotify(); -} - -static void OnScrollTrans(ui::Adjustment adj, gpointer data) -{ - portals.trans_3d = static_cast( gtk_adjustment_get_value(adj)); - Set3DTransText(ui::Widget::from(data)); - - SceneChangeNotify(); -} - -static void OnScrollClip(ui::Adjustment adj, gpointer data) -{ - portals.clip_range = static_cast( gtk_adjustment_get_value(adj)); - SetClipText(ui::Widget::from(data)); - - SceneChangeNotify(); -} - -static void OnAntiAlias2d(ui::Widget widget, gpointer data) -{ - portals.aa_2d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - Portals_shadersChanged(); - - SceneChangeNotify(); -} - -static void OnConfig2d(ui::Widget widget, gpointer data) -{ - portals.show_2d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - SceneChangeNotify(); -} - -static void OnColor2d(ui::Widget widget, gpointer data) -{ - if (DoColor(&portals.color_2d) == IDOK) { - Portals_shadersChanged(); - - SceneChangeNotify(); - } -} - -static void OnConfig3d(ui::Widget widget, gpointer data) -{ - portals.show_3d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - SceneChangeNotify(); -} - - -static void OnAntiAlias3d(ui::Widget widget, gpointer data) -{ - portals.aa_3d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnColor3d(ui::Widget widget, gpointer data) -{ - if (DoColor(&portals.color_3d) == IDOK) { - Portals_shadersChanged(); - - SceneChangeNotify(); - } -} - -static void OnColorFog(ui::Widget widget, gpointer data) -{ - if (DoColor(&portals.color_fog) == IDOK) { - Portals_shadersChanged(); - - SceneChangeNotify(); - } -} - -static void OnFog(ui::Widget widget, gpointer data) -{ - portals.fog = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnSelchangeZbuffer(ui::Widget widget, gpointer data) -{ - portals.zbuffer = gpointer_to_int(data); - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnPoly(ui::Widget widget, gpointer data) -{ - portals.polygons = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); - - SceneChangeNotify(); -} - -static void OnLines(ui::Widget widget, gpointer data) -{ - portals.lines = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); - - SceneChangeNotify(); -} - -static void OnClip(ui::Widget widget, gpointer data) -{ - portals.clip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? true : false; - - SceneChangeNotify(); -} - -void DoConfigDialog() -{ - int loop = 1, ret = IDCANCEL; - - auto dlg = ui::Window(ui::window_type::TOP); - gtk_window_set_title(dlg, "Portal Viewer Configuration"); - dlg.connect("delete_event", - G_CALLBACK(dialog_delete_callback), NULL); - dlg.connect("destroy", - G_CALLBACK(gtk_widget_destroy), NULL); - g_object_set_data(G_OBJECT(dlg), "loop", &loop); - g_object_set_data(G_OBJECT(dlg), "ret", &ret); - - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - dlg.add(vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - - auto frame = ui::Frame("3D View"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - - auto vbox2 = ui::VBox(FALSE, 5); - vbox2.show(); - frame.add(vbox2); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); - - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, TRUE, 0); - - auto adj = ui::Adjustment(portals.width_3d, 2, 40, 1, 1, 0); - auto lw3slider = ui::HScale(adj); - lw3slider.show(); - hbox.pack_start(lw3slider, TRUE, TRUE, 0); - gtk_scale_set_draw_value(GTK_SCALE(lw3slider), FALSE); - - auto lw3label = ui::Label(""); - lw3label.show(); - hbox.pack_start(lw3label, FALSE, TRUE, 0); - adj.connect("value_changed", G_CALLBACK(OnScroll3d), lw3label); - - auto table = ui::Table(2, 4, FALSE); - table.show(); - vbox2.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - auto button = ui::Button("Color"); - button.show(); - table.attach(button, {0, 1, 0, 1}, {GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnColor3d), NULL); - - button = ui::Button("Depth Color"); - button.show(); - table.attach(button, {0, 1, 1, 2}, {GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnColorFog), NULL); - - auto aa3check = ui::CheckButton("Anti-Alias (May not work on some video cards)"); - aa3check.show(); - table.attach(aa3check, {1, 4, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - aa3check.connect("toggled", G_CALLBACK(OnAntiAlias3d), NULL); - - auto depthcheck = ui::CheckButton("Depth Cue"); - depthcheck.show(); - table.attach(depthcheck, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - depthcheck.connect("toggled", G_CALLBACK(OnFog), NULL); - - auto linescheck = ui::CheckButton("Lines"); - linescheck.show(); - table.attach(linescheck, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - linescheck.connect("toggled", G_CALLBACK(OnLines), NULL); - - auto polyscheck = ui::CheckButton("Polygons"); - polyscheck.show(); - table.attach(polyscheck, {3, 4, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - polyscheck.connect("toggled", G_CALLBACK(OnPoly), NULL); - - auto zlist = ui::ComboBoxText(ui::New); - zlist.show(); - vbox2.pack_start(zlist, TRUE, FALSE, 0); - - gtk_combo_box_text_append_text(zlist, "Z-Buffer Test and Write (recommended for solid or no polygons)"); - gtk_combo_box_text_append_text(zlist, "Z-Buffer Test Only (recommended for transparent polygons)"); - gtk_combo_box_text_append_text(zlist, "Z-Buffer Off"); - - zlist.connect("changed", G_CALLBACK(+[] (ui::ComboBox self, void *) { - OnSelchangeZbuffer(self, GINT_TO_POINTER(gtk_combo_box_get_active(self))); - }), nullptr); - - table = ui::Table(2, 2, FALSE); - table.show(); - vbox2.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - adj = ui::Adjustment(portals.trans_3d, 0, 100, 1, 1, 0); - auto transslider = ui::HScale(adj); - transslider.show(); - table.attach(transslider, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_scale_set_draw_value(GTK_SCALE(transslider), FALSE); - - auto translabel = ui::Label(""); - translabel.show(); - table.attach(translabel, {1, 2, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(translabel), 0.0, 0.0); - adj.connect("value_changed", G_CALLBACK(OnScrollTrans), translabel); - - adj = ui::Adjustment(portals.clip_range, 1, 128, 1, 1, 0); - auto clipslider = ui::HScale(adj); - clipslider.show(); - table.attach(clipslider, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_scale_set_draw_value(GTK_SCALE(clipslider), FALSE); - - auto cliplabel = ui::Label(""); - cliplabel.show(); - table.attach(cliplabel, {1, 2, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(cliplabel), 0.0, 0.0); - adj.connect("value_changed", G_CALLBACK(OnScrollClip), cliplabel); - - hbox = ui::HBox(TRUE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, FALSE, 0); - - auto show3check = ui::CheckButton("Show"); - show3check.show(); - hbox.pack_start(show3check, TRUE, TRUE, 0); - show3check.connect("toggled", G_CALLBACK(OnConfig3d), NULL); - - auto portalcheck = ui::CheckButton("Portal cubic clipper"); - portalcheck.show(); - hbox.pack_start(portalcheck, TRUE, TRUE, 0); - portalcheck.connect("toggled", G_CALLBACK(OnClip), NULL); - - frame = ui::Frame("2D View"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - - vbox2 = ui::VBox(FALSE, 5); - vbox2.show(); - frame.add(vbox2); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, FALSE, 0); - - adj = ui::Adjustment(portals.width_2d, 2, 40, 1, 1, 0); - auto lw2slider = ui::HScale(adj); - lw2slider.show(); - hbox.pack_start(lw2slider, TRUE, TRUE, 0); - gtk_scale_set_draw_value(GTK_SCALE(lw2slider), FALSE); - - auto lw2label = ui::Label(""); - lw2label.show(); - hbox.pack_start(lw2label, FALSE, TRUE, 0); - adj.connect("value_changed", G_CALLBACK(OnScroll2d), lw2label); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, FALSE, 0); - - button = ui::Button("Color"); - button.show(); - hbox.pack_start(button, FALSE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnColor2d), NULL); - button.dimensions(60, -1); - - auto aa2check = ui::CheckButton("Anti-Alias (May not work on some video cards)"); - aa2check.show(); - hbox.pack_start(aa2check, TRUE, TRUE, 0); - aa2check.connect("toggled", G_CALLBACK(OnAntiAlias2d), NULL); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox2.pack_start(hbox, TRUE, FALSE, 0); - - auto show2check = ui::CheckButton("Show"); - show2check.show(); - hbox.pack_start(show2check, FALSE, FALSE, 0); - show2check.connect("toggled", G_CALLBACK(OnConfig2d), NULL); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, FALSE, FALSE, 0); - - button = ui::Button("OK"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDOK)); - button.dimensions(60, -1); - - // initialize dialog - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show2check), portals.show_2d); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(aa2check), portals.aa_2d); - Set2DText(lw2label); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show3check), portals.show_3d); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(depthcheck), portals.fog); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(polyscheck), portals.polygons); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linescheck), portals.lines); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(aa3check), portals.aa_3d); - gtk_combo_box_set_active(zlist, portals.zbuffer); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(portalcheck), portals.clip); - - Set3DText(lw3label); - Set3DTransText(translabel); - SetClipText(cliplabel); - - gtk_grab_add(dlg); - dlg.show(); - - while (loop) { - gtk_main_iteration(); - } - - gtk_grab_remove(dlg); - dlg.destroy(); -} diff --git a/plugins/prtview/ConfigDialog.h b/plugins/prtview/ConfigDialog.h deleted file mode 100644 index a972584..0000000 --- a/plugins/prtview/ConfigDialog.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined( INCLUDED_CONFIGDIALOG_H ) -#define INCLUDED_CONFIGDIALOG_H - -void DoConfigDialog(); - -#endif diff --git a/plugins/prtview/LICENSE b/plugins/prtview/LICENSE deleted file mode 100644 index 8d1c8b6..0000000 --- a/plugins/prtview/LICENSE +++ /dev/null @@ -1 +0,0 @@ - diff --git a/plugins/prtview/LoadPortalFileDialog.cpp b/plugins/prtview/LoadPortalFileDialog.cpp deleted file mode 100644 index 29709bd..0000000 --- a/plugins/prtview/LoadPortalFileDialog.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// LoadPortalFileDialog.cpp : implementation file -// - -#include "LoadPortalFileDialog.h" - -#include -#include -#include "stream/stringstream.h" -#include "convert.h" -#include "gtkutil/pointer.h" - -#include "qerplugin.h" - -#include "prtview.h" -#include "portals.h" - -static void dialog_button_callback(ui::Widget widget, gpointer data) -{ - int *loop, *ret; - - auto parent = widget.window(); - loop = (int *) g_object_get_data(G_OBJECT(parent), "loop"); - ret = (int *) g_object_get_data(G_OBJECT(parent), "ret"); - - *loop = 0; - *ret = gpointer_to_int(data); -} - -static gint dialog_delete_callback(ui::Widget widget, GdkEvent *event, gpointer data) -{ - widget.hide(); - int *loop = (int *) g_object_get_data(G_OBJECT(widget), "loop"); - *loop = 0; - return TRUE; -} - -static void change_clicked(ui::Widget widget, gpointer data) -{ - char *filename = NULL; - - auto file_sel = ui::Widget::from( - gtk_file_chooser_dialog_new("Locate portal (.prt) file", nullptr, GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - nullptr)); - - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_sel), portals.fn); - - if (gtk_dialog_run(GTK_DIALOG (file_sel)) == GTK_RESPONSE_ACCEPT) { - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (file_sel)); - } - ui::Widget(file_sel).destroy(); - - if (filename != NULL) { - strcpy(portals.fn, filename); - gtk_entry_set_text(GTK_ENTRY(data), filename); - g_free(filename); - } -} - -int DoLoadPortalFileDialog() -{ - int loop = 1, ret = IDCANCEL; - - auto dlg = ui::Window(ui::window_type::TOP); - gtk_window_set_title(dlg, "Load .prt"); - dlg.connect("delete_event", - G_CALLBACK(dialog_delete_callback), NULL); - dlg.connect("destroy", - G_CALLBACK(gtk_widget_destroy), NULL); - g_object_set_data(G_OBJECT(dlg), "loop", &loop); - g_object_set_data(G_OBJECT(dlg), "ret", &ret); - - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - dlg.add(vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - - auto entry = ui::Entry(ui::New); - entry.show(); - gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); - vbox.pack_start(entry, FALSE, FALSE, 0); - - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, FALSE, FALSE, 0); - - auto check3d = ui::CheckButton("Show 3D"); - check3d.show(); - hbox.pack_start(check3d, FALSE, FALSE, 0); - - auto check2d = ui::CheckButton("Show 2D"); - check2d.show(); - hbox.pack_start(check2d, FALSE, FALSE, 0); - - auto button = ui::Button("Change"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", G_CALLBACK(change_clicked), entry); - button.dimensions(60, -1); - - hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, FALSE, FALSE, 0); - - button = ui::Button("Cancel"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDCANCEL)); - button.dimensions(60, -1); - - button = ui::Button("OK"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(IDOK)); - button.dimensions(60, -1); - - strcpy(portals.fn, GlobalRadiant().getMapName()); - char *fn = strrchr(portals.fn, '.'); - if (fn != NULL) { - strcpy(fn, ".prt"); - } - - StringOutputStream value(256); - value << portals.fn; - gtk_entry_set_text(GTK_ENTRY(entry), value.c_str()); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check2d), portals.show_2d); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check3d), portals.show_3d); - - gtk_grab_add(dlg); - dlg.show(); - - while (loop) { - gtk_main_iteration(); - } - - if (ret == IDOK) { - portals.Purge(); - - portals.show_3d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check3d)) ? true : false; - portals.show_2d = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check2d)) ? true : false; - } - - gtk_grab_remove(dlg); - dlg.destroy(); - - return ret; -} diff --git a/plugins/prtview/LoadPortalFileDialog.h b/plugins/prtview/LoadPortalFileDialog.h deleted file mode 100644 index 62dfc3d..0000000 --- a/plugins/prtview/LoadPortalFileDialog.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined( INCLUDED_LOADPORTALFILEDIALOG_H ) -#define INCLUDED_LOADPORTALFILEDIALOG_H - -int DoLoadPortalFileDialog(); - -#endif diff --git a/plugins/prtview/Makefile b/plugins/prtview/Makefile deleted file mode 100644 index 0cc18dd..0000000 --- a/plugins/prtview/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# WorldSpawn Plugin Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - AboutDialog.o ConfigDialog.o LoadPortalFileDialog.o portals.o prtview.o - -# binary target -../../build/plugins/libprtview.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libuilib.a ../../libs/libgtkutil.a ../../libs/libprofile.a $(PLUGIN_LDFLAGS) - -# object files -AboutDialog.o: AboutDialog.cpp AboutDialog.h -ConfigDialog.o: ConfigDialog.cpp ConfigDialog.h -LoadPortalFileDialog.o: LoadPortalFileDialog.cpp LoadPortalFileDialog.h -portals.o: portals.cpp portals.h -prtview.o: prtview.cpp prtview.h - -clean: - -rm -f *.o ../../build/plugins/libprtview.$(LIB_EXT) diff --git a/plugins/prtview/PrtView.txt b/plugins/prtview/PrtView.txt deleted file mode 100644 index 50228e0..0000000 --- a/plugins/prtview/PrtView.txt +++ /dev/null @@ -1,12 +0,0 @@ -Put PrtView.dll in the Q3Radiant plugins directory. - -This program is pretty self explanitary, but point needs to -be mentioned. In the configuration menu for 3D view options, -the lines and polygons flags are tri-state. In the third state, -the lines or polygons will only be drawn if the have the -hint flag set. Older version of q3map will not set this flag -and the hint shader may have to be modified to set it. As of -this writing, I do not know all the details. - -Geoffrey DeWan -gdewan@prairienet.org \ No newline at end of file diff --git a/plugins/prtview/portals.cpp b/plugins/prtview/portals.cpp deleted file mode 100644 index 52ee03c..0000000 --- a/plugins/prtview/portals.cpp +++ /dev/null @@ -1,639 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "portals.h" -#include "globaldefs.h" -#include -#include - -#if !GDEF_OS_MACOS - -#include - -#endif - -#include - -#include "iglrender.h" -#include "cullable.h" - -#include "prtview.h" - -const int LINE_BUF = 1000; - -CPortals portals; -CPortalsRender render; - -int compare(const void *arg1, const void *arg2) -{ - - if (portals.portal[*((int *) arg1)].dist > portals.portal[*((int *) arg2)].dist) { - return -1; - } else if (portals.portal[*((int *) arg1)].dist < portals.portal[*((int *) arg2)].dist) { - return 1; - } - - return 0; -} - - -CBspPortal::CBspPortal() -{ - memset(this, 0, sizeof(CBspPortal)); -} - -CBspPortal::~CBspPortal() -{ - delete[] point; - delete[] inner_point; -} - -bool CBspPortal::Build(char *def) -{ - char *c = def; - unsigned int n; - int dummy1, dummy2; - int res_cnt, i; - - if (portals.hint_flags) { - res_cnt = sscanf(def, "%u %d %d %d", &point_count, &dummy1, &dummy2, (int *) &hint); - } else { - sscanf(def, "%u", &point_count); - hint = false; - } - - if (point_count < 3 || (portals.hint_flags && res_cnt < 4)) { - return false; - } - - point = new CBspPoint[point_count]; - inner_point = new CBspPoint[point_count]; - - for (n = 0; n < point_count; n++) { - for (; *c != 0 && *c != '('; c++) {} - - if (*c == 0) { - return false; - } - - c++; - - sscanf(c, "%f %f %f", point[n].p, point[n].p + 1, point[n].p + 2); - - center.p[0] += point[n].p[0]; - center.p[1] += point[n].p[1]; - center.p[2] += point[n].p[2]; - - if (n == 0) { - for (i = 0; i < 3; i++) { - min[i] = point[n].p[i]; - max[i] = point[n].p[i]; - } - } else { - for (i = 0; i < 3; i++) { - if (min[i] > point[n].p[i]) { - min[i] = point[n].p[i]; - } - if (max[i] < point[n].p[i]) { - max[i] = point[n].p[i]; - } - } - } - } - - center.p[0] /= (float) point_count; - center.p[1] /= (float) point_count; - center.p[2] /= (float) point_count; - - for (n = 0; n < point_count; n++) { - inner_point[n].p[0] = (0.01f * center.p[0]) + (0.99f * point[n].p[0]); - inner_point[n].p[1] = (0.01f * center.p[1]) + (0.99f * point[n].p[1]); - inner_point[n].p[2] = (0.01f * center.p[2]) + (0.99f * point[n].p[2]); - } - - fp_color_random[0] = (float) (rand() & 0xff) / 255.0f; - fp_color_random[1] = (float) (rand() & 0xff) / 255.0f; - fp_color_random[2] = (float) (rand() & 0xff) / 255.0f; - fp_color_random[3] = 1.0f; - - return true; -} - -CPortals::CPortals() -{ - memset(this, 0, sizeof(CPortals)); -} - -CPortals::~CPortals() -{ - Purge(); -} - -void CPortals::Purge() -{ - delete[] portal; - delete[] portal_sort; - portal = NULL; - portal_sort = NULL; - portal_count = 0; - - /* - delete[] node; - node = NULL; - node_count = 0; - */ -} - -void CPortals::Load() -{ - char buf[LINE_BUF + 1]; - - memset(buf, 0, LINE_BUF + 1); - - Purge(); - - globalOutputStream() << MSG_PREFIX "Loading portal file " << fn << ".\n"; - - FILE *in; - - in = fopen(fn, "rt"); - - if (in == NULL) { - globalOutputStream() << " ERROR - could not open file.\n"; - - return; - } - - if (!fgets(buf, LINE_BUF, in)) { - fclose(in); - - globalOutputStream() << " ERROR - File ended prematurely.\n"; - - return; - } - - if (strncmp("PRT1", buf, 4) != 0) { - fclose(in); - - globalOutputStream() << " ERROR - File header indicates wrong file type (should be \"PRT1\").\n"; - - return; - } - - if (!fgets(buf, LINE_BUF, in)) { - fclose(in); - - globalOutputStream() << " ERROR - File ended prematurely.\n"; - - return; - } - - sscanf(buf, "%u", &node_count); -/* - if(node_count > 0xFFFF) - { - fclose(in); - - node_count = 0; - - globalOutputStream() << " ERROR - Extreme number of nodes, aborting.\n"; - - return; - } - */ - - if (!fgets(buf, LINE_BUF, in)) { - fclose(in); - - node_count = 0; - - globalOutputStream() << " ERROR - File ended prematurely.\n"; - - return; - } - - sscanf(buf, "%u", &portal_count); - - if (portal_count > 0xFFFF) { - fclose(in); - - portal_count = 0; - node_count = 0; - - globalOutputStream() << " ERROR - Extreme number of portals, aborting.\n"; - - return; - } - - if (portal_count == 0) { - fclose(in); - - portal_count = 0; - node_count = 0; - - globalOutputStream() << " ERROR - number of portals equals 0, aborting.\n"; - - return; - } - -// node = new CBspNode[node_count]; - portal = new CBspPortal[portal_count]; - portal_sort = new int[portal_count]; - - unsigned int n; - bool first = true; - unsigned test_vals_1, test_vals_2; - - hint_flags = false; - - for (n = 0; n < portal_count;) { - if (!fgets(buf, LINE_BUF, in)) { - fclose(in); - - Purge(); - - globalOutputStream() << " ERROR - Could not find information for portal number " << n + 1 << " of " - << portal_count << ".\n"; - - return; - } - - if (!portal[n].Build(buf)) { - if (first && sscanf(buf, "%d %d", (int *) &test_vals_1, (int *) &test_vals_2) == - 1) { // skip additional counts of later data, not needed - // We can count on hint flags being in the file - hint_flags = true; - continue; - } - - first = false; - - fclose(in); - - Purge(); - - globalOutputStream() << " ERROR - Information for portal number " << n + 1 << " of " << portal_count - << " is not formatted correctly.\n"; - - return; - } - - n++; - } - - fclose(in); - - globalOutputStream() << " " << node_count << " portals read in.\n"; -} - -#include "math/matrix.h" - -const char *g_state_solid = "$plugins/prtview/solid"; -const char *g_state_solid_outline = "$plugins/prtview/solid_outline"; -const char *g_state_wireframe = "$plugins/prtview/wireframe"; -Shader *g_shader_solid = 0; -Shader *g_shader_solid_outline = 0; -Shader *g_shader_wireframe = 0; - -void Portals_constructShaders() -{ - OpenGLState state; - GlobalOpenGLStateLibrary().getDefaultState(state); - state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortOverlayFirst; - state.m_linewidth = portals.width_2d * 0.5f; - state.m_colour[0] = portals.fp_color_2d[0]; - state.m_colour[1] = portals.fp_color_2d[1]; - state.m_colour[2] = portals.fp_color_2d[2]; - state.m_colour[3] = portals.fp_color_2d[3]; - if (portals.aa_2d) { - state.m_state |= RENDER_BLEND | RENDER_LINESMOOTH; - } - GlobalOpenGLStateLibrary().insert(g_state_wireframe, state); - - GlobalOpenGLStateLibrary().getDefaultState(state); - state.m_state = RENDER_FILL | RENDER_BLEND | RENDER_COLOURWRITE | RENDER_COLOURCHANGE | RENDER_SMOOTH; - - if (portals.aa_3d) { - state.m_state |= RENDER_POLYGONSMOOTH; - } - - switch (portals.zbuffer) { - case 1: - state.m_state |= RENDER_DEPTHTEST; - break; - case 2: - break; - default: - state.m_state |= RENDER_DEPTHTEST; - state.m_state |= RENDER_DEPTHWRITE; - } - - if (portals.fog) { - state.m_state |= RENDER_FOG; - - state.m_fog.mode = GL_EXP; - state.m_fog.density = 0.001f; - state.m_fog.start = 10.0f; - state.m_fog.end = 10000.0f; - state.m_fog.index = 0; - state.m_fog.colour[0] = portals.fp_color_fog[0]; - state.m_fog.colour[1] = portals.fp_color_fog[1]; - state.m_fog.colour[2] = portals.fp_color_fog[2]; - state.m_fog.colour[3] = portals.fp_color_fog[3]; - } - - GlobalOpenGLStateLibrary().insert(g_state_solid, state); - - GlobalOpenGLStateLibrary().getDefaultState(state); - state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortOverlayFirst; - state.m_linewidth = portals.width_3d * 0.5f; - state.m_colour[0] = portals.fp_color_3d[0]; - state.m_colour[1] = portals.fp_color_3d[1]; - state.m_colour[2] = portals.fp_color_3d[2]; - state.m_colour[3] = portals.fp_color_3d[3]; - - if (portals.aa_3d) { - state.m_state |= RENDER_LINESMOOTH; - } - - switch (portals.zbuffer) { - case 1: - state.m_state |= RENDER_DEPTHTEST; - break; - case 2: - break; - default: - state.m_state |= RENDER_DEPTHTEST; - state.m_state |= RENDER_DEPTHWRITE; - } - - if (portals.fog) { - state.m_state |= RENDER_FOG; - - state.m_fog.mode = GL_EXP; - state.m_fog.density = 0.001f; - state.m_fog.start = 10.0f; - state.m_fog.end = 10000.0f; - state.m_fog.index = 0; - state.m_fog.colour[0] = portals.fp_color_fog[0]; - state.m_fog.colour[1] = portals.fp_color_fog[1]; - state.m_fog.colour[2] = portals.fp_color_fog[2]; - state.m_fog.colour[3] = portals.fp_color_fog[3]; - } - - GlobalOpenGLStateLibrary().insert(g_state_solid_outline, state); - - g_shader_solid = GlobalShaderCache().capture(g_state_solid); - g_shader_solid_outline = GlobalShaderCache().capture(g_state_solid_outline); - g_shader_wireframe = GlobalShaderCache().capture(g_state_wireframe); -} - -void Portals_destroyShaders() -{ - GlobalShaderCache().release(g_state_solid); - GlobalShaderCache().release(g_state_solid_outline); - GlobalShaderCache().release(g_state_wireframe); - GlobalOpenGLStateLibrary().erase(g_state_solid); - GlobalOpenGLStateLibrary().erase(g_state_solid_outline); - GlobalOpenGLStateLibrary().erase(g_state_wireframe); -} - -void Portals_shadersChanged() -{ - Portals_destroyShaders(); - portals.FixColors(); - Portals_constructShaders(); -} - -void CPortals::FixColors() -{ - fp_color_2d[0] = (float) GetRValue(color_2d) / 255.0f; - fp_color_2d[1] = (float) GetGValue(color_2d) / 255.0f; - fp_color_2d[2] = (float) GetBValue(color_2d) / 255.0f; - fp_color_2d[3] = 1.0f; - - fp_color_3d[0] = (float) GetRValue(color_3d) / 255.0f; - fp_color_3d[1] = (float) GetGValue(color_3d) / 255.0f; - fp_color_3d[2] = (float) GetBValue(color_3d) / 255.0f; - fp_color_3d[3] = 1.0f; - - fp_color_fog[0] = 0.0f; //(float)GetRValue(color_fog) / 255.0f; - fp_color_fog[1] = 0.0f; //(float)GetGValue(color_fog) / 255.0f; - fp_color_fog[2] = 0.0f; //(float)GetBValue(color_fog) / 255.0f; - fp_color_fog[3] = 1.0f; -} - -void CPortalsRender::renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - if (!portals.show_2d || portals.portal_count < 1) { - return; - } - - renderer.SetState(g_shader_wireframe, Renderer::eWireframeOnly); - - renderer.addRenderable(m_drawWireframe, g_matrix4_identity); -} - -void CPortalsDrawWireframe::render(RenderStateFlags state) const -{ - unsigned int n, p; - - for (n = 0; n < portals.portal_count; n++) { - glBegin(GL_LINE_LOOP); - - for (p = 0; p < portals.portal[n].point_count; p++) - glVertex3fv(portals.portal[n].point[p].p); - - glEnd(); - } -} - -CubicClipVolume calculateCubicClipVolume(const Matrix4 &viewproj) -{ - CubicClipVolume clip; - clip.cam = vector4_projected( - matrix4_transformed_vector4( - matrix4_full_inverse(viewproj), - Vector4(0, 0, -1, 1) - ) - ); - clip.min[0] = clip.cam[0] + (portals.clip_range * 64.0f); - clip.min[1] = clip.cam[1] + (portals.clip_range * 64.0f); - clip.min[2] = clip.cam[2] + (portals.clip_range * 64.0f); - clip.max[0] = clip.cam[0] - (portals.clip_range * 64.0f); - clip.max[1] = clip.cam[1] - (portals.clip_range * 64.0f); - clip.max[2] = clip.cam[2] - (portals.clip_range * 64.0f); - return clip; -} - -void CPortalsRender::renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - if (!portals.show_3d || portals.portal_count < 1) { - return; - } - - CubicClipVolume clip = calculateCubicClipVolume( - matrix4_multiplied_by_matrix4(volume.GetProjection(), volume.GetModelview())); - - if (portals.polygons) { - renderer.SetState(g_shader_solid, Renderer::eWireframeOnly); - renderer.SetState(g_shader_solid, Renderer::eFullMaterials); - - m_drawSolid.clip = clip; - renderer.addRenderable(m_drawSolid, g_matrix4_identity); - } - - if (portals.lines) { - renderer.SetState(g_shader_solid_outline, Renderer::eWireframeOnly); - renderer.SetState(g_shader_solid_outline, Renderer::eFullMaterials); - - m_drawSolidOutline.clip = clip; - renderer.addRenderable(m_drawSolidOutline, g_matrix4_identity); - } -} - -void CPortalsDrawSolid::render(RenderStateFlags state) const -{ - float trans = (100.0f - portals.trans_3d) / 100.0f; - - unsigned int n, p; - - if (portals.zbuffer != 0) { - float d; - - for (n = 0; n < portals.portal_count; n++) { - d = (float) clip.cam[0] - portals.portal[n].center.p[0]; - portals.portal[n].dist = d * d; - - d = (float) clip.cam[1] - portals.portal[n].center.p[1]; - portals.portal[n].dist += d * d; - - d = (float) clip.cam[2] - portals.portal[n].center.p[2]; - portals.portal[n].dist += d * d; - - portals.portal_sort[n] = n; - } - - qsort(portals.portal_sort, portals.portal_count, 4, compare); - - for (n = 0; n < portals.portal_count; n++) { - if (portals.polygons == 2 && !portals.portal[portals.portal_sort[n]].hint) { - continue; - } - - if (portals.clip) { - if (clip.min[0] < portals.portal[portals.portal_sort[n]].min[0]) { - continue; - } else if (clip.min[1] < portals.portal[portals.portal_sort[n]].min[1]) { - continue; - } else if (clip.min[2] < portals.portal[portals.portal_sort[n]].min[2]) { - continue; - } else if (clip.max[0] > portals.portal[portals.portal_sort[n]].max[0]) { - continue; - } else if (clip.max[1] > portals.portal[portals.portal_sort[n]].max[1]) { - continue; - } else if (clip.max[2] > portals.portal[portals.portal_sort[n]].max[2]) { - continue; - } - } - - glColor4f(portals.portal[portals.portal_sort[n]].fp_color_random[0], - portals.portal[portals.portal_sort[n]].fp_color_random[1], - portals.portal[portals.portal_sort[n]].fp_color_random[2], trans); - - glBegin(GL_POLYGON); - - for (p = 0; p < portals.portal[portals.portal_sort[n]].point_count; p++) - glVertex3fv(portals.portal[portals.portal_sort[n]].point[p].p); - - glEnd(); - } - } else { - for (n = 0; n < portals.portal_count; n++) { - if (portals.polygons == 2 && !portals.portal[n].hint) { - continue; - } - - if (portals.clip) { - if (clip.min[0] < portals.portal[n].min[0]) { - continue; - } else if (clip.min[1] < portals.portal[n].min[1]) { - continue; - } else if (clip.min[2] < portals.portal[n].min[2]) { - continue; - } else if (clip.max[0] > portals.portal[n].max[0]) { - continue; - } else if (clip.max[1] > portals.portal[n].max[1]) { - continue; - } else if (clip.max[2] > portals.portal[n].max[2]) { - continue; - } - } - - glColor4f(portals.portal[n].fp_color_random[0], portals.portal[n].fp_color_random[1], - portals.portal[n].fp_color_random[2], trans); - - glBegin(GL_POLYGON); - - for (p = 0; p < portals.portal[n].point_count; p++) - glVertex3fv(portals.portal[n].point[p].p); - - glEnd(); - } - } -} - -void CPortalsDrawSolidOutline::render(RenderStateFlags state) const -{ - for (unsigned int n = 0; n < portals.portal_count; n++) { - if (portals.lines == 2 && !portals.portal[n].hint) { - continue; - } - - if (portals.clip) { - if (clip.min[0] < portals.portal[n].min[0]) { - continue; - } - if (clip.min[1] < portals.portal[n].min[1]) { - continue; - } - if (clip.min[2] < portals.portal[n].min[2]) { - continue; - } - if (clip.max[0] > portals.portal[n].max[0]) { - continue; - } - if (clip.max[1] > portals.portal[n].max[1]) { - continue; - } - if (clip.max[2] > portals.portal[n].max[2]) { - continue; - } - } - - glBegin(GL_LINE_LOOP); - - for (unsigned int p = 0; p < portals.portal[n].point_count; p++) - glVertex3fv(portals.portal[n].inner_point[p].p); - - glEnd(); - } -} diff --git a/plugins/prtview/portals.h b/plugins/prtview/portals.h deleted file mode 100644 index 28c77dc..0000000 --- a/plugins/prtview/portals.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _PORTALS_H_ -#define _PORTALS_H_ - -#include -#include "irender.h" -#include "renderable.h" -#include "math/vector.h" - - -class CBspPoint { -public: -float p[3]; -}; - -class CBspPortal { -public: -CBspPortal(); - -~CBspPortal(); - -protected: - -public: -CBspPoint center; -unsigned point_count; -CBspPoint *point; -CBspPoint *inner_point; -float fp_color_random[4]; -float min[3]; -float max[3]; -float dist; -bool hint; - -bool Build(char *def); -}; - -#ifdef PATH_MAX -const int PRTVIEW_PATH_MAX = PATH_MAX; -#else -const int PRTVIEW_PATH_MAX = 260; -#endif -typedef guint32 PackedColour; -#define RGB(r, g, b) ( (guint32)( ( (guint8) ( r ) | ( (guint16) ( g ) << 8 ) ) | ( ( (guint32) (guint8) ( b ) ) << 16 ) ) ) -#define GetRValue(rgb) ( (guint8)( rgb ) ) -#define GetGValue(rgb) ( (guint8)( ( (guint16)( rgb ) ) >> 8 ) ) -#define GetBValue(rgb) ( (guint8)( ( rgb ) >> 16 ) ) - - -class CPortals { -public: - -CPortals(); - -~CPortals(); - -protected: - - -public: - -void Load(); // use filename in fn -void Purge(); - -void FixColors(); - -char fn[PRTVIEW_PATH_MAX]; - -int zbuffer; -int polygons; -int lines; -bool show_3d; -bool aa_3d; -bool fog; -PackedColour color_3d; -float width_3d; // in 8'ths -float fp_color_3d[4]; -PackedColour color_fog; -float fp_color_fog[4]; -float trans_3d; -float clip_range; -bool clip; - -bool show_2d; -bool aa_2d; -PackedColour color_2d; -float width_2d; // in 8'ths -float fp_color_2d[4]; - -CBspPortal *portal; -int *portal_sort; -bool hint_flags; -// CBspNode *node; - -unsigned int node_count; -unsigned int portal_count; -}; - -class CubicClipVolume { -public: -Vector3 cam, min, max; -}; - -class CPortalsDrawSolid : public OpenGLRenderable { -public: -mutable CubicClipVolume clip; - -void render(RenderStateFlags state) const; -}; - -class CPortalsDrawSolidOutline : public OpenGLRenderable { -public: -mutable CubicClipVolume clip; - -void render(RenderStateFlags state) const; -}; - -class CPortalsDrawWireframe : public OpenGLRenderable { -public: -void render(RenderStateFlags state) const; -}; - -class CPortalsRender : public Renderable { -public: -CPortalsDrawSolid m_drawSolid; -CPortalsDrawSolidOutline m_drawSolidOutline; -CPortalsDrawWireframe m_drawWireframe; - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const; - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const; -}; - -extern CPortals portals; -extern CPortalsRender render; - -void Portals_constructShaders(); - -void Portals_destroyShaders(); - -void Portals_shadersChanged(); - - -#endif // _PORTALS_H_ diff --git a/plugins/prtview/prtview.cpp b/plugins/prtview/prtview.cpp deleted file mode 100644 index a6a93c6..0000000 --- a/plugins/prtview/prtview.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "prtview.h" -#include -#include - -#include "profile/profile.h" - -#include "qerplugin.h" -#include "iscenegraph.h" -#include "iglrender.h" -#include "iplugin.h" -#include "stream/stringstream.h" - -#include "portals.h" -#include "AboutDialog.h" -#include "ConfigDialog.h" -#include "LoadPortalFileDialog.h" - -#define Q3R_CMD_SPLITTER "-" -#define Q3R_CMD_ABOUT "About Portal Viewer" -#define Q3R_CMD_LOAD "Load .prt file" -#define Q3R_CMD_RELEASE "Unload .prt file" -#define Q3R_CMD_SHOW_3D "Toggle portals (3D)" -#define Q3R_CMD_SHOW_2D "Toggle portals (2D)" -#define Q3R_CMD_OPTIONS "Configure Portal Viewer" - -CopiedString INIfn; - -///////////////////////////////////////////////////////////////////////////// -// CPrtViewApp construction - -const char *RENDER_2D = "Render2D"; -const char *WIDTH_2D = "Width2D"; -const char *AA_2D = "AntiAlias2D"; -const char *COLOR_2D = "Color2D"; - -const char *RENDER_3D = "Render3D"; -const char *WIDTH_3D = "Width3D"; -const char *AA_3D = "AntiAlias3D"; -const char *COLOR_3D = "Color3D"; -const char *COLOR_FOG = "ColorFog"; -const char *FOG = "Fog"; -const char *ZBUFFER = "ZBuffer"; -const char *POLYGON = "Polygons"; -const char *LINE = "Lines"; -const char *TRANS_3D = "Transparency"; -const char *CLIP_RANGE = "ClipRange"; -const char *CLIP = "Clip"; - - -void PrtView_construct() -{ - StringOutputStream tmp(64); - tmp << GlobalRadiant().getSettingsPath() << "prtview.ini"; - INIfn = tmp.c_str(); - - portals.show_2d = INIGetInt(RENDER_2D, FALSE) ? true : false; - portals.aa_2d = INIGetInt(AA_2D, FALSE) ? true : false; - portals.width_2d = (float) INIGetInt(WIDTH_2D, 10); - portals.color_2d = (PackedColour) INIGetInt(COLOR_2D, RGB(0, 0, 255)) & 0xFFFFFF; - - if (portals.width_2d > 40.0f) { - portals.width_2d = 40.0f; - } else if (portals.width_2d < 2.0f) { - portals.width_2d = 2.0f; - } - - portals.show_3d = INIGetInt(RENDER_3D, TRUE) ? true : false; - - portals.zbuffer = INIGetInt(ZBUFFER, 1); - portals.fog = INIGetInt(FOG, FALSE) ? true : false; - portals.polygons = INIGetInt(POLYGON, TRUE); - portals.lines = INIGetInt(LINE, TRUE); - portals.aa_3d = INIGetInt(AA_3D, FALSE) ? true : false; - portals.width_3d = (float) INIGetInt(WIDTH_3D, 4); - portals.color_3d = (PackedColour) INIGetInt(COLOR_3D, RGB(255, 255, 0)) & 0xFFFFFF; - portals.color_fog = (PackedColour) INIGetInt(COLOR_FOG, RGB(127, 127, 127)) & 0xFFFFFF; - portals.trans_3d = (float) INIGetInt(TRANS_3D, 50); - portals.clip = INIGetInt(CLIP, FALSE) ? true : false; - portals.clip_range = (float) INIGetInt(CLIP_RANGE, 16); - - if (portals.clip_range < 1) { - portals.clip_range = 1; - } else if (portals.clip_range > 128) { - portals.clip_range = 128; - } - - if (portals.zbuffer < 0) { - portals.zbuffer = 0; - } else if (portals.zbuffer > 2) { - portals.zbuffer = 0; - } - - if (portals.width_3d > 40.0f) { - portals.width_3d = 40.0f; - } else if (portals.width_3d < 2.0f) { - portals.width_3d = 2.0f; - } - - if (portals.trans_3d > 100.0f) { - portals.trans_3d = 100.0f; - } else if (portals.trans_3d < 0.0f) { - portals.trans_3d = 0.0f; - } - - SaveConfig(); - - portals.FixColors(); - - Portals_constructShaders(); - GlobalShaderCache().attachRenderable(render); -} - -void PrtView_destroy() -{ - GlobalShaderCache().detachRenderable(render); - Portals_destroyShaders(); -} - -void SaveConfig() -{ - INISetInt(RENDER_2D, portals.show_2d, "Draw in 2D windows"); - INISetInt(WIDTH_2D, (int) portals.width_2d, "Width of lines in 2D windows (in units of 1/2)"); - INISetInt(COLOR_2D, (int) portals.color_2d, "Color of lines in 2D windows"); - INISetInt(AA_2D, portals.aa_2d, "Draw lines in 2D window anti-aliased"); - - INISetInt(ZBUFFER, portals.zbuffer, "ZBuffer level in 3D window"); - INISetInt(FOG, portals.fog, "Use depth cueing in 3D window"); - INISetInt(POLYGON, portals.polygons, "Render using polygons polygons in 3D window"); - INISetInt(LINE, portals.polygons, "Render using lines in 3D window"); - INISetInt(RENDER_3D, portals.show_3d, "Draw in 3D windows"); - INISetInt(WIDTH_3D, (int) portals.width_3d, "Width of lines in 3D window (in units of 1/2)"); - INISetInt(COLOR_3D, (int) portals.color_3d, "Color of lines/polygons in 3D window"); - INISetInt(COLOR_FOG, (int) portals.color_fog, "Color of distant lines/polygons in 3D window"); - INISetInt(AA_3D, portals.aa_3d, "Draw lines in 3D window anti-aliased"); - INISetInt(TRANS_3D, (int) portals.trans_3d, "Transparency in 3d view (0 = solid, 100 = invisible)"); - INISetInt(CLIP, portals.clip, "Cubic clipper active for portal viewer"); - INISetInt(CLIP_RANGE, (int) portals.clip_range, "Portal viewer cubic clip distance (in units of 64)"); -} - - -const char *CONFIG_SECTION = "Configuration"; - -int INIGetInt(const char *key, int def) -{ - char value[1024]; - - if (read_var(INIfn.c_str(), CONFIG_SECTION, key, value)) { - return atoi(value); - } else { - return def; - } -} - -void INISetInt(const char *key, int val, const char *comment /* = NULL */ ) -{ - char s[1000]; - - if (comment) { - sprintf(s, "%d ; %s", val, comment); - } else { - sprintf(s, "%d", val); - } - save_var(INIfn.c_str(), CONFIG_SECTION, key, s); -} - - -// plugin name -static const char *PLUGIN_NAME = "Portal Viewer"; -// commands in the menu -static const char *PLUGIN_COMMANDS = - Q3R_CMD_ABOUT ";" - Q3R_CMD_SPLITTER ";" - Q3R_CMD_OPTIONS ";" - Q3R_CMD_SPLITTER ";" - Q3R_CMD_SHOW_2D ";" - Q3R_CMD_SHOW_3D ";" - Q3R_CMD_SPLITTER ";" - Q3R_CMD_RELEASE ";" - Q3R_CMD_LOAD; - - -const char *QERPlug_Init(void *hApp, void *pMainWidget) -{ - return "Portal Viewer for WorldSpawn"; -} - -const char *QERPlug_GetName() -{ - return PLUGIN_NAME; -} - -const char *QERPlug_GetCommandList() -{ - return PLUGIN_COMMANDS; -} - - -const char *QERPlug_GetCommandTitleList() -{ - return ""; -} - - -void QERPlug_Dispatch(const char *p, float *vMin, float *vMax, bool bSingleBrush) -{ - globalOutputStream() << MSG_PREFIX "Command \"" << p << "\"\n"; - - if (!strcmp(p, Q3R_CMD_ABOUT)) { - DoAboutDlg(); - } else if (!strcmp(p, Q3R_CMD_LOAD)) { - if (DoLoadPortalFileDialog() == IDOK) { - portals.Load(); - SceneChangeNotify(); - } else { - globalOutputStream() << MSG_PREFIX "Portal file load aborted.\n"; - } - } else if (!strcmp(p, Q3R_CMD_RELEASE)) { - portals.Purge(); - - SceneChangeNotify(); - - globalOutputStream() << MSG_PREFIX "Portals unloaded.\n"; - } else if (!strcmp(p, Q3R_CMD_SHOW_2D)) { - portals.show_2d = !portals.show_2d; - - SceneChangeNotify(); - SaveConfig(); - - if (portals.show_2d) { - globalOutputStream() << MSG_PREFIX "Portals will be rendered in 2D view.\n"; - } else { - globalOutputStream() << MSG_PREFIX "Portals will NOT be rendered in 2D view.\n"; - } - } else if (!strcmp(p, Q3R_CMD_SHOW_3D)) { - portals.show_3d = !portals.show_3d; - SaveConfig(); - - SceneChangeNotify(); - - if (portals.show_3d) { - globalOutputStream() << MSG_PREFIX "Portals will be rendered in 3D view.\n"; - } else { - globalOutputStream() << MSG_PREFIX "Portals will NOT be rendered in 3D view.\n"; - } - } else if (!strcmp(p, Q3R_CMD_OPTIONS)) { - DoConfigDialog(); - SaveConfig(); - - SceneChangeNotify(); - } -} - - -#include "modulesystem/singletonmodule.h" - -class PrtViewPluginDependencies : - public GlobalSceneGraphModuleRef, - public GlobalRadiantModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalOpenGLModuleRef, - public GlobalOpenGLStateLibraryModuleRef { -}; - -class PrtViewPluginModule { -_QERPluginTable m_plugin; -public: -typedef _QERPluginTable Type; - -STRING_CONSTANT(Name, "PRT Viewer"); - -PrtViewPluginModule() -{ - m_plugin.m_pfnQERPlug_Init = QERPlug_Init; - m_plugin.m_pfnQERPlug_GetName = QERPlug_GetName; - m_plugin.m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList; - m_plugin.m_pfnQERPlug_GetCommandTitleList = QERPlug_GetCommandTitleList; - m_plugin.m_pfnQERPlug_Dispatch = QERPlug_Dispatch; - - PrtView_construct(); -} - -~PrtViewPluginModule() -{ - PrtView_destroy(); -} - -_QERPluginTable *getTable() -{ - return &m_plugin; -} -}; - -typedef SingletonModule SingletonPrtViewPluginModule; - -SingletonPrtViewPluginModule g_PrtViewPluginModule; - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_PrtViewPluginModule.selfRegister(); -} diff --git a/plugins/prtview/prtview.h b/plugins/prtview/prtview.h deleted file mode 100644 index 2253474..0000000 --- a/plugins/prtview/prtview.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - PrtView plugin for GtkRadiant - Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined( INCLUDED_PRTVIEW_H ) -#define INCLUDED_PRTVIEW_H - -#define MSG_PREFIX "Portal Viewer plugin: " - -void InitInstance(); - -void SaveConfig(); - -int INIGetInt(const char *key, int def); - -void INISetInt(const char *key, int val, const char *comment = 0); - -const int IDOK = 1; -const int IDCANCEL = 2; - - -#endif diff --git a/plugins/shaders/Makefile b/plugins/shaders/Makefile deleted file mode 100644 index 0ce814b..0000000 --- a/plugins/shaders/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - shaders.o plugin.o - -# binary target -../../build/plugins/libshaders.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(PLUGIN_LDFLAGS) - -# object files -shaders.o: shaders.cpp shaders.h -plugin.o: plugin.cpp - -clean: - -rm -f *.o ../../build/plugins/libshaders.$(LIB_EXT) diff --git a/plugins/shaders/plugin.cpp b/plugins/shaders/plugin.cpp deleted file mode 100644 index 8e5a453..0000000 --- a/plugins/shaders/plugin.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ishaders.h" -#include "ifilesystem.h" -#include "itextures.h" -#include "iscriplib.h" -#include "qerplugin.h" - -#include "string/string.h" -#include "modulesystem/singletonmodule.h" - -#include "shaders.h" - -class ShadersDependencies : - public GlobalFileSystemModuleRef, - public GlobalTexturesModuleRef, - public GlobalScripLibModuleRef, - public GlobalRadiantModuleRef -{ -ImageModuleRef m_bitmapModule; -public: -ShadersDependencies() : - m_bitmapModule( "tga" ){ -} -ImageModuleRef& getBitmapModule(){ - return m_bitmapModule; -} -}; - -class ShadersQ3API -{ -ShaderSystem* m_shadersq3; -public: -typedef ShaderSystem Type; -STRING_CONSTANT( Name, "quake3" ); - -ShadersQ3API( ShadersDependencies& dependencies ){ - g_shadersExtension = "shader"; - g_shadersDirectory = "scripts/"; - g_bitmapModule = dependencies.getBitmapModule().getTable(); - Shaders_Construct(); - m_shadersq3 = &GetShaderSystem(); -} -~ShadersQ3API(){ - Shaders_Destroy(); -} -ShaderSystem* getTable(){ - return m_shadersq3; -} -}; - -typedef SingletonModule > ShadersQ3Module; - -ShadersQ3Module g_ShadersQ3Module; - - -class ShadersDoom3API -{ -ShaderSystem* m_shadersdoom3; -public: -typedef ShaderSystem Type; -STRING_CONSTANT( Name, "doom3" ); - -ShadersDoom3API( ShadersDependencies& dependencies ){ - g_shadersExtension = "mtr"; - g_shadersDirectory = "materials/"; - g_enableDefaultShaders = false; - g_shaderLanguage = SHADERLANGUAGE_DOOM3; - g_useShaderList = false; - g_bitmapModule = dependencies.getBitmapModule().getTable(); - Shaders_Construct(); - m_shadersdoom3 = &GetShaderSystem(); -} -~ShadersDoom3API(){ - Shaders_Destroy(); -} -ShaderSystem* getTable(){ - return m_shadersdoom3; -} -}; - -typedef SingletonModule > ShadersDoom3Module; - -ShadersDoom3Module g_ShadersDoom3Module; - - -class ShadersQuake4API -{ -ShaderSystem* m_shadersquake4; -public: -typedef ShaderSystem Type; -STRING_CONSTANT( Name, "quake4" ); - -ShadersQuake4API( ShadersDependencies& dependencies ){ - g_shadersExtension = "mtr"; - g_shadersDirectory = "materials/"; - g_enableDefaultShaders = false; - g_shaderLanguage = SHADERLANGUAGE_QUAKE4; - g_useShaderList = false; - g_bitmapModule = dependencies.getBitmapModule().getTable(); - Shaders_Construct(); - m_shadersquake4 = &GetShaderSystem(); -} -~ShadersQuake4API(){ - Shaders_Destroy(); -} -ShaderSystem* getTable(){ - return m_shadersquake4; -} -}; - -typedef SingletonModule > ShadersQuake4Module; - -ShadersQuake4Module g_ShadersQuake4Module; - - - -extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){ - initialiseModule( server ); - - g_ShadersQ3Module.selfRegister(); - g_ShadersDoom3Module.selfRegister(); - g_ShadersQuake4Module.selfRegister(); -} diff --git a/plugins/shaders/shaders.cpp b/plugins/shaders/shaders.cpp deleted file mode 100644 index 3846942..0000000 --- a/plugins/shaders/shaders.cpp +++ /dev/null @@ -1,1842 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Shaders Manager Plugin -// -// Leonardo Zide ( leo@lokigames.com ) -// - -#include "defaults.h" -#include "shaders.h" -#include "globaldefs.h" - -#include -#include -#include -#include - -#include "ifilesystem.h" -#include "ishaders.h" -#include "iscriplib.h" -#include "itextures.h" -#include "qerplugin.h" -#include "irender.h" - -#include - -#include "debugging/debugging.h" -#include "string/pooledstring.h" -#include "math/vector.h" -#include "generic/callback.h" -#include "generic/referencecounted.h" -#include "stream/memstream.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" -#include "os/path.h" -#include "os/dir.h" -#include "os/file.h" -#include "stringio.h" -#include "shaderlib.h" -#include "texturelib.h" -#include "cmdlib.h" -#include "moduleobservers.h" -#include "archivelib.h" -#include "imagelib.h" - -const char* g_shadersExtension = ""; -const char* g_shadersDirectory = ""; -bool g_enableDefaultShaders = true; -ShaderLanguage g_shaderLanguage = SHADERLANGUAGE_QUAKE3; -bool g_useShaderList = true; -_QERPlugImageTable* g_bitmapModule = 0; -const char* g_texturePrefix = DEFAULT_TEXTURE_DIRNAME; - -void ActiveShaders_IteratorBegin(); - -bool ActiveShaders_IteratorAtEnd(); - -IShader *ActiveShaders_IteratorCurrent(); - -void ActiveShaders_IteratorIncrement(); - -Callback g_ActiveShadersChangedNotify; - -void FreeShaders(); - -void LoadShaderFile( const char *filename ); - -/*! - NOTE TTimo: there is an important distinction between SHADER_NOT_FOUND and SHADER_NOTEX: - SHADER_NOT_FOUND means we didn't find the raw texture or the shader for this - SHADER_NOTEX means we recognize this as a shader script, but we are missing the texture to represent it - this was in the initial design of the shader code since early GtkRadiant alpha, and got sort of foxed in 1.2 and put back in - */ - -Image* loadBitmap( void* environment, const char* name ){ - DirectoryArchiveFile file( name, name ); - if ( !file.failed() ) { - return g_bitmapModule->loadImage( file ); - } - return 0; -} - -inline byte* getPixel( byte* pixels, int width, int height, int x, int y ){ - return pixels + ( ( ( ( ( y + height ) % height ) * width ) + ( ( x + width ) % width ) ) * 4 ); -} - -class KernelElement -{ -public: -int x, y; -float w; -}; - -Image& convertHeightmapToNormalmap( Image& heightmap, float scale ){ - int w = heightmap.getWidth(); - int h = heightmap.getHeight(); - - Image& normalmap = *( new RGBAImage( heightmap.getWidth(), heightmap.getHeight() ) ); - - byte* in = heightmap.getRGBAPixels(); - byte* out = normalmap.getRGBAPixels(); - -#if 1 - // no filtering - const int kernelSize = 2; - KernelElement kernel_du[kernelSize] = { - {-1, 0,-0.5f }, - { 1, 0, 0.5f } - }; - KernelElement kernel_dv[kernelSize] = { - { 0, 1, 0.5f }, - { 0,-1,-0.5f } - }; -#else - // 3x3 Prewitt - const int kernelSize = 6; - KernelElement kernel_du[kernelSize] = { - {-1, 1,-1.0f }, - {-1, 0,-1.0f }, - {-1,-1,-1.0f }, - { 1, 1, 1.0f }, - { 1, 0, 1.0f }, - { 1,-1, 1.0f } - }; - KernelElement kernel_dv[kernelSize] = { - {-1, 1, 1.0f }, - { 0, 1, 1.0f }, - { 1, 1, 1.0f }, - {-1,-1,-1.0f }, - { 0,-1,-1.0f }, - { 1,-1,-1.0f } - }; -#endif - - int x, y = 0; - while ( y < h ) - { - x = 0; - while ( x < w ) - { - float du = 0; - for ( KernelElement* i = kernel_du; i != kernel_du + kernelSize; ++i ) - { - du += ( getPixel( in, w, h, x + ( *i ).x, y + ( *i ).y )[0] / 255.0 ) * ( *i ).w; - } - float dv = 0; - for ( KernelElement* i = kernel_dv; i != kernel_dv + kernelSize; ++i ) - { - dv += ( getPixel( in, w, h, x + ( *i ).x, y + ( *i ).y )[0] / 255.0 ) * ( *i ).w; - } - - float nx = -du * scale; - float ny = -dv * scale; - float nz = 1.0; - - // Normalize - float norm = 1.0 / sqrt( nx * nx + ny * ny + nz * nz ); - out[0] = float_to_integer( ( ( nx * norm ) + 1 ) * 127.5 ); - out[1] = float_to_integer( ( ( ny * norm ) + 1 ) * 127.5 ); - out[2] = float_to_integer( ( ( nz * norm ) + 1 ) * 127.5 ); - out[3] = 255; - - x++; - out += 4; - } - - y++; - } - - return normalmap; -} - -Image* loadHeightmap( void* environment, const char* name ){ - Image* heightmap = GlobalTexturesCache().loadImage( name ); - if ( heightmap != 0 ) { - Image& normalmap = convertHeightmapToNormalmap( *heightmap, *reinterpret_cast( environment ) ); - heightmap->release(); - return &normalmap; - } - return 0; -} - -class ShaderPoolContext -{ -}; - -typedef Static ShaderPool; -typedef PooledString ShaderString; -typedef ShaderString ShaderVariable; -typedef ShaderString ShaderValue; -typedef CopiedString TextureExpression; - -// clean a texture name to the qtexture_t name format we use internally -// NOTE: case sensitivity: the engine is case sensitive. we store the shader name with case information and save with case -// information as well. but we assume there won't be any case conflict and so when doing lookups based on shader name, -// we compare as case insensitive. That is Radiant is case insensitive, but knows that the engine is case sensitive. -//++timo FIXME: we need to put code somewhere to detect when two shaders that are case insensitive equal are present -template -void parseTextureName( StringType& name, const char* token ){ - StringOutputStream cleaned( 256 ); - cleaned << PathCleaned( token ); - name = CopiedString( StringRange( cleaned.c_str(), path_get_filename_base_end( cleaned.c_str() ) ) ).c_str(); // remove extension -} - -bool Tokeniser_parseTextureName( Tokeniser& tokeniser, TextureExpression& name ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - Tokeniser_unexpectedError( tokeniser, token, "#texture-name" ); - return false; - } - parseTextureName( name, token ); - return true; -} - -bool Tokeniser_parseShaderName( Tokeniser& tokeniser, CopiedString& name ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - Tokeniser_unexpectedError( tokeniser, token, "#shader-name" ); - return false; - } - parseTextureName( name, token ); - return true; -} - -bool Tokeniser_parseString( Tokeniser& tokeniser, ShaderString& string ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - Tokeniser_unexpectedError( tokeniser, token, "#string" ); - return false; - } - string = token; - return true; -} - - -typedef std::list ShaderParameters; -typedef std::list ShaderArguments; - -typedef std::pair BlendFuncExpression; - -class ShaderTemplate -{ -std::size_t m_refcount; -CopiedString m_Name; -CopiedString m_WadName; -public: - -ShaderParameters m_params; - -TextureExpression m_textureName; -TextureExpression m_diffuse; -TextureExpression m_bump; -ShaderValue m_heightmapScale; -TextureExpression m_specular; -TextureExpression m_lightFalloffImage; - -int m_nFlags; -float m_fTrans; - -// alphafunc stuff -IShader::EAlphaFunc m_AlphaFunc; -float m_AlphaRef; -// cull stuff -IShader::ECull m_Cull; - -ShaderTemplate() : - m_refcount( 0 ){ - m_nFlags = 0; - m_fTrans = 1.0f; -} - -void IncRef(){ - ++m_refcount; -} - -void DecRef(){ - ASSERT_MESSAGE( m_refcount != 0, "shader reference-count going below zero" ); - if ( --m_refcount == 0 ) { - delete this; - } -} - -std::size_t refcount(){ - return m_refcount; -} - -const char* getName() const { - return m_Name.c_str(); -} - -void setName( const char* name ){ - m_Name = name; -} - -// ----------------------------------------- - -bool parseDoom3( Tokeniser& tokeniser ); - -bool parseQuake3( Tokeniser& tokeniser ); - -bool parseTemplate( Tokeniser& tokeniser ); - - -void CreateDefault( const char *name ){ - if ( g_enableDefaultShaders ) { - m_textureName = name; - } - else - { - m_textureName = ""; - } - setName( name ); -} - - -class MapLayerTemplate -{ -TextureExpression m_texture; -BlendFuncExpression m_blendFunc; -bool m_clampToBorder; -ShaderValue m_alphaTest; -public: -MapLayerTemplate( const TextureExpression& texture, const BlendFuncExpression& blendFunc, bool clampToBorder, const ShaderValue& alphaTest ) : - m_texture( texture ), - m_blendFunc( blendFunc ), - m_clampToBorder( false ), - m_alphaTest( alphaTest ){ -} - -const TextureExpression& texture() const { - return m_texture; -} - -const BlendFuncExpression& blendFunc() const { - return m_blendFunc; -} - -bool clampToBorder() const { - return m_clampToBorder; -} - -const ShaderValue& alphaTest() const { - return m_alphaTest; -} -}; - -typedef std::vector MapLayers; -MapLayers m_layers; -}; - - -bool Doom3Shader_parseHeightmap( Tokeniser& tokeniser, TextureExpression& bump, ShaderValue& heightmapScale ){ - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, bump ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "," ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseString( tokeniser, heightmapScale ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) ); - return true; -} - -bool Doom3Shader_parseAddnormals( Tokeniser& tokeniser, TextureExpression& bump ){ - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, bump ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "," ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "heightmap" ) ); - TextureExpression heightmapName; - ShaderValue heightmapScale; - RETURN_FALSE_IF_FAIL( Doom3Shader_parseHeightmap( tokeniser, heightmapName, heightmapScale ) ); - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) ); - return true; -} - -bool Doom3Shader_parseBumpmap( Tokeniser& tokeniser, TextureExpression& bump, ShaderValue& heightmapScale ){ - const char* token = tokeniser.getToken(); - if ( token == 0 ) { - Tokeniser_unexpectedError( tokeniser, token, "#bumpmap" ); - return false; - } - if ( string_equal( token, "heightmap" ) ) { - RETURN_FALSE_IF_FAIL( Doom3Shader_parseHeightmap( tokeniser, bump, heightmapScale ) ); - } - else if ( string_equal( token, "addnormals" ) ) { - RETURN_FALSE_IF_FAIL( Doom3Shader_parseAddnormals( tokeniser, bump ) ); - } - else - { - parseTextureName( bump, token ); - } - return true; -} - -enum LayerTypeId -{ - LAYER_NONE, - LAYER_BLEND, - LAYER_DIFFUSEMAP, - LAYER_BUMPMAP, - LAYER_SPECULARMAP -}; - -class LayerTemplate -{ -public: -LayerTypeId m_type; -TextureExpression m_texture; -BlendFuncExpression m_blendFunc; -bool m_clampToBorder; -ShaderValue m_alphaTest; -ShaderValue m_heightmapScale; - -LayerTemplate() : m_type( LAYER_NONE ), m_blendFunc( "GL_ONE", "GL_ZERO" ), m_clampToBorder( false ), m_alphaTest( "-1" ), m_heightmapScale( "0" ){ -} -}; - -bool parseShaderParameters( Tokeniser& tokeniser, ShaderParameters& params ){ - Tokeniser_parseToken( tokeniser, "(" ); - for (;; ) - { - const char* param = tokeniser.getToken(); - if ( string_equal( param, ")" ) ) { - break; - } - params.push_back( param ); - const char* comma = tokeniser.getToken(); - if ( string_equal( comma, ")" ) ) { - break; - } - if ( !string_equal( comma, "," ) ) { - Tokeniser_unexpectedError( tokeniser, comma, "," ); - return false; - } - } - return true; -} - -bool ShaderTemplate::parseTemplate( Tokeniser& tokeniser ){ - m_Name = tokeniser.getToken(); - if ( !parseShaderParameters( tokeniser, m_params ) ) { - globalErrorStream() << "shader template: " << makeQuoted( m_Name.c_str() ) << ": parameter parse failed\n"; - return false; - } - - return parseDoom3( tokeniser ); -} - -bool ShaderTemplate::parseDoom3( Tokeniser& tokeniser ){ - LayerTemplate currentLayer; - bool isFog = false; - - // we need to read until we hit a balanced } - int depth = 0; - for (;; ) - { - tokeniser.nextLine(); - const char* token = tokeniser.getToken(); - - if ( token == 0 ) { - return false; - } - - if ( string_equal( token, "{" ) ) { - ++depth; - continue; - } - else if ( string_equal( token, "}" ) ) { - --depth; - if ( depth < 0 ) { // error - return false; - } - if ( depth == 0 ) { // end of shader - break; - } - if ( depth == 1 ) { // end of layer - if ( currentLayer.m_type == LAYER_DIFFUSEMAP ) { - m_diffuse = currentLayer.m_texture; - } - else if ( currentLayer.m_type == LAYER_BUMPMAP ) { - m_bump = currentLayer.m_texture; - } - else if ( currentLayer.m_type == LAYER_SPECULARMAP ) { - m_specular = currentLayer.m_texture; - } - else if ( !string_empty( currentLayer.m_texture.c_str() ) ) { - m_layers.push_back( MapLayerTemplate( - currentLayer.m_texture.c_str(), - currentLayer.m_blendFunc, - currentLayer.m_clampToBorder, - currentLayer.m_alphaTest - ) ); - } - currentLayer.m_type = LAYER_NONE; - currentLayer.m_texture = ""; - } - continue; - } - - if ( depth == 2 ) { // in layer - if ( string_equal_nocase( token, "blend" ) ) { - const char* blend = tokeniser.getToken(); - - if ( blend == 0 ) { - Tokeniser_unexpectedError( tokeniser, blend, "#blend" ); - return false; - } - - if ( string_equal_nocase( blend, "diffusemap" ) ) { - currentLayer.m_type = LAYER_DIFFUSEMAP; - } - else if ( string_equal_nocase( blend, "bumpmap" ) ) { - currentLayer.m_type = LAYER_BUMPMAP; - } - else if ( string_equal_nocase( blend, "specularmap" ) ) { - currentLayer.m_type = LAYER_SPECULARMAP; - } - else - { - currentLayer.m_blendFunc.first = blend; - - const char* comma = tokeniser.getToken(); - - if ( comma == 0 ) { - Tokeniser_unexpectedError( tokeniser, comma, "#comma" ); - return false; - } - - if ( string_equal( comma, "," ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseString( tokeniser, currentLayer.m_blendFunc.second ) ); - } - else - { - currentLayer.m_blendFunc.second = ""; - tokeniser.ungetToken(); - } - } - } - else if ( string_equal_nocase( token, "map" ) ) { - if ( currentLayer.m_type == LAYER_BUMPMAP ) { - RETURN_FALSE_IF_FAIL( Doom3Shader_parseBumpmap( tokeniser, currentLayer.m_texture, currentLayer.m_heightmapScale ) ); - } - else - { - const char* map = tokeniser.getToken(); - - if ( map == 0 ) { - Tokeniser_unexpectedError( tokeniser, map, "#map" ); - return false; - } - - if ( string_equal( map, "makealpha" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) ); - const char* texture = tokeniser.getToken(); - if ( texture == 0 ) { - Tokeniser_unexpectedError( tokeniser, texture, "#texture" ); - return false; - } - currentLayer.m_texture = texture; - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) ); - } - else - { - parseTextureName( currentLayer.m_texture, map ); - } - } - } - else if ( string_equal_nocase( token, "zeroclamp" ) ) { - currentLayer.m_clampToBorder = true; - } -#if 0 - else if ( string_equal_nocase( token, "alphaTest" ) ) { - Tokeniser_getFloat( tokeniser, currentLayer.m_alphaTest ); - } -#endif - } - else if ( depth == 1 ) { - if ( string_equal_nocase( token, "qer_editorimage" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, m_textureName ) ); - } - else if ( string_equal_nocase( token, "qer_trans" ) ) { - m_fTrans = string_read_float( tokeniser.getToken() ); - m_nFlags |= QER_TRANS; - } - else if ( string_equal_nocase( token, "translucent" ) ) { - m_fTrans = 1; - m_nFlags |= QER_TRANS; - } - else if ( string_equal( token, "DECAL_MACRO" ) ) { - m_fTrans = 1; - m_nFlags |= QER_TRANS; - } - else if ( string_equal_nocase( token, "bumpmap" ) ) { - RETURN_FALSE_IF_FAIL( Doom3Shader_parseBumpmap( tokeniser, m_bump, m_heightmapScale ) ); - } - else if ( string_equal_nocase( token, "diffusemap" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, m_diffuse ) ); - } - else if ( string_equal_nocase( token, "specularmap" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, m_specular ) ); - } - else if ( string_equal_nocase( token, "twosided" ) ) { - m_Cull = IShader::eCullNone; - m_nFlags |= QER_CULL; - } - else if ( string_equal_nocase( token, "nodraw" ) ) { - m_nFlags |= QER_NODRAW; - } - else if ( string_equal_nocase( token, "nonsolid" ) ) { - m_nFlags |= QER_NONSOLID; - } - else if ( string_equal_nocase( token, "liquid" ) ) { - m_nFlags |= QER_WATER; - } - else if ( string_equal_nocase( token, "areaportal" ) ) { - m_nFlags |= QER_AREAPORTAL; - } - else if ( string_equal_nocase( token, "playerclip" ) - || string_equal_nocase( token, "monsterclip" ) - || string_equal_nocase( token, "ikclip" ) - || string_equal_nocase( token, "moveableclip" ) ) { - m_nFlags |= QER_CLIP; - } - if ( string_equal_nocase( token, "fogLight" ) ) { - isFog = true; - } - else if ( !isFog && string_equal_nocase( token, "lightFalloffImage" ) ) { - const char* lightFalloffImage = tokeniser.getToken(); - if ( lightFalloffImage == 0 ) { - Tokeniser_unexpectedError( tokeniser, lightFalloffImage, "#lightFalloffImage" ); - return false; - } - if ( string_equal_nocase( lightFalloffImage, "makeintensity" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) ); - TextureExpression name; - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, name ) ); - m_lightFalloffImage = name; - RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) ); - } - else - { - m_lightFalloffImage = lightFalloffImage; - } - } - } - } - - if ( string_empty( m_textureName.c_str() ) ) { - m_textureName = m_diffuse; - } - - return true; -} - -typedef SmartPointer ShaderTemplatePointer; -typedef std::map ShaderTemplateMap; - -ShaderTemplateMap g_shaders; -ShaderTemplateMap g_shaderTemplates; - -ShaderTemplate* findTemplate( const char* name ){ - ShaderTemplateMap::iterator i = g_shaderTemplates.find( name ); - if ( i != g_shaderTemplates.end() ) { - return ( *i ).second.get(); - } - return 0; -} - -class ShaderDefinition -{ -public: -ShaderDefinition( ShaderTemplate* shaderTemplate, const ShaderArguments& args, const char* filename ) - : shaderTemplate( shaderTemplate ), args( args ), filename( filename ){ -} - -ShaderTemplate* shaderTemplate; -ShaderArguments args; -const char* filename; -}; - -typedef std::map ShaderDefinitionMap; - -ShaderDefinitionMap g_shaderDefinitions; - -bool parseTemplateInstance( Tokeniser& tokeniser, const char* filename ){ - CopiedString name; - RETURN_FALSE_IF_FAIL( Tokeniser_parseShaderName( tokeniser, name ) ); - const char* templateName = tokeniser.getToken(); - ShaderTemplate* shaderTemplate = findTemplate( templateName ); - if ( shaderTemplate == 0 ) { - globalErrorStream() << "shader instance: " << makeQuoted( name.c_str() ) << ": shader template not found: " << makeQuoted( templateName ) << "\n"; - } - - ShaderArguments args; - if ( !parseShaderParameters( tokeniser, args ) ) { - globalErrorStream() << "shader instance: " << makeQuoted( name.c_str() ) << ": argument parse failed\n"; - return false; - } - - if ( shaderTemplate != 0 ) { - if ( !g_shaderDefinitions.insert( ShaderDefinitionMap::value_type( name, ShaderDefinition( shaderTemplate, args, filename ) ) ).second ) { - globalErrorStream() << "shader instance: " << makeQuoted( name.c_str() ) << ": already exists, second definition ignored\n"; - } - } - return true; -} - - -const char* evaluateShaderValue( const char* value, const ShaderParameters& params, const ShaderArguments& args ){ - ShaderArguments::const_iterator j = args.begin(); - for ( ShaderParameters::const_iterator i = params.begin(); i != params.end(); ++i, ++j ) - { - const char* other = ( *i ).c_str(); - if ( string_equal( value, other ) ) { - return ( *j ).c_str(); - } - } - return value; -} - -///\todo BlendFunc parsing -BlendFunc evaluateBlendFunc( const BlendFuncExpression& blendFunc, const ShaderParameters& params, const ShaderArguments& args ){ - return BlendFunc( BLEND_ONE, BLEND_ZERO ); -} - -qtexture_t* evaluateTexture( const TextureExpression& texture, const ShaderParameters& params, const ShaderArguments& args, const LoadImageCallback& loader = GlobalTexturesCache().defaultLoader() ){ - StringOutputStream result( 64 ); - const char* expression = texture.c_str(); - const char* end = expression + string_length( expression ); - if ( !string_empty( expression ) ) { - for (;; ) - { - const char* best = end; - const char* bestParam = 0; - const char* bestArg = 0; - ShaderArguments::const_iterator j = args.begin(); - for ( ShaderParameters::const_iterator i = params.begin(); i != params.end(); ++i, ++j ) - { - const char* found = strstr( expression, ( *i ).c_str() ); - if ( found != 0 && found < best ) { - best = found; - bestParam = ( *i ).c_str(); - bestArg = ( *j ).c_str(); - } - } - if ( best != end ) { - result << StringRange( expression, best ); - result << PathCleaned( bestArg ); - expression = best + string_length( bestParam ); - } - else - { - break; - } - } - result << expression; - } - return GlobalTexturesCache().capture( loader, result.c_str() ); -} - -float evaluateFloat( const ShaderValue& value, const ShaderParameters& params, const ShaderArguments& args ){ - const char* result = evaluateShaderValue( value.c_str(), params, args ); - float f; - if ( !string_parse_float( result, f ) ) { - globalErrorStream() << "parsing float value failed: " << makeQuoted( result ) << "\n"; - } - return f; -} - -BlendFactor evaluateBlendFactor( const ShaderValue& value, const ShaderParameters& params, const ShaderArguments& args ){ - const char* result = evaluateShaderValue( value.c_str(), params, args ); - - if ( string_equal_nocase( result, "gl_zero" ) ) { - return BLEND_ZERO; - } - if ( string_equal_nocase( result, "gl_one" ) ) { - return BLEND_ONE; - } - if ( string_equal_nocase( result, "gl_src_color" ) ) { - return BLEND_SRC_COLOUR; - } - if ( string_equal_nocase( result, "gl_one_minus_src_color" ) ) { - return BLEND_ONE_MINUS_SRC_COLOUR; - } - if ( string_equal_nocase( result, "gl_src_alpha" ) ) { - return BLEND_SRC_ALPHA; - } - if ( string_equal_nocase( result, "gl_one_minus_src_alpha" ) ) { - return BLEND_ONE_MINUS_SRC_ALPHA; - } - if ( string_equal_nocase( result, "gl_dst_color" ) ) { - return BLEND_DST_COLOUR; - } - if ( string_equal_nocase( result, "gl_one_minus_dst_color" ) ) { - return BLEND_ONE_MINUS_DST_COLOUR; - } - if ( string_equal_nocase( result, "gl_dst_alpha" ) ) { - return BLEND_DST_ALPHA; - } - if ( string_equal_nocase( result, "gl_one_minus_dst_alpha" ) ) { - return BLEND_ONE_MINUS_DST_ALPHA; - } - if ( string_equal_nocase( result, "gl_src_alpha_saturate" ) ) { - return BLEND_SRC_ALPHA_SATURATE; - } - - globalErrorStream() << "parsing blend-factor value failed: " << makeQuoted( result ) << "\n"; - return BLEND_ZERO; -} - -class CShader : public IShader -{ -std::size_t m_refcount; - -const ShaderTemplate& m_template; -const ShaderArguments& m_args; -const char* m_filename; -// name is shader-name, otherwise texture-name ( if not a real shader ) -CopiedString m_Name; -CopiedString m_WadName; - -qtexture_t* m_pTexture; -qtexture_t* m_notfound; -qtexture_t* m_pDiffuse; -float m_heightmapScale; -qtexture_t* m_pBump; -qtexture_t* m_pSpecular; -qtexture_t* m_pLightFalloffImage; -BlendFunc m_blendFunc; - -bool m_bInUse; - - -public: -static bool m_lightingEnabled; - -CShader( const ShaderDefinition& definition ) : - m_refcount( 0 ), - m_template( *definition.shaderTemplate ), - m_args( definition.args ), - m_filename( definition.filename ), - m_blendFunc( BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA ), - m_bInUse( false ){ - m_pTexture = 0; - m_pDiffuse = 0; - m_pBump = 0; - m_pSpecular = 0; - - m_notfound = 0; - - realise(); -} - -virtual ~CShader(){ - unrealise(); - - ASSERT_MESSAGE( m_refcount == 0, "deleting active shader" ); -} - -// IShaders implementation ----------------- -void IncRef(){ - ++m_refcount; -} - -void DecRef(){ - ASSERT_MESSAGE( m_refcount != 0, "shader reference-count going below zero" ); - if ( --m_refcount == 0 ) { - delete this; - } -} - -std::size_t refcount(){ - return m_refcount; -} - -// get/set the qtexture_t* Radiant uses to represent this shader object -qtexture_t* getTexture() const { - return m_pTexture; -} - -qtexture_t* getDiffuse() const { - return m_pDiffuse; -} - -qtexture_t* getBump() const { - return m_pBump; -} - -qtexture_t* getSpecular() const { - return m_pSpecular; -} - -// get shader name -const char* getName() const { - return m_Name.c_str(); -} - -const char* getWadName() const { - return m_WadName.c_str(); -} - -bool IsInUse() const { - return m_bInUse; -} - -void SetInUse( bool bInUse ){ - m_bInUse = bInUse; - g_ActiveShadersChangedNotify(); -} - -// get the shader flags -int getFlags() const { - return m_template.m_nFlags; -} - -// get the transparency value -float getTrans() const { - return m_template.m_fTrans; -} - -int getPolygonOffset() const -{ - return 0; -} - -// test if it's a true shader, or a default shader created to wrap around a texture -bool IsDefault() const { - return string_empty( m_filename ); -} - -// get the alphaFunc -void getAlphaFunc( EAlphaFunc *func, float *ref ) { *func = m_template.m_AlphaFunc; *ref = m_template.m_AlphaRef; }; -BlendFunc getBlendFunc() const { - return m_blendFunc; -} - -// get the cull type -ECull getCull(){ - return m_template.m_Cull; -}; - -// get shader file name ( ie the file where this one is defined ) -const char* getShaderFileName() const { - return m_filename; -} -// ----------------------------------------- - -void realise() -{ - m_pTexture = evaluateTexture(m_template.m_textureName, m_template.m_params, m_args); - - if (m_pTexture->texture_number == 0) { - m_notfound = m_pTexture; - { - StringOutputStream name(256); - name << GlobalRadiant().getAppPath() << "bitmaps/" << (IsDefault() ? "notex.tga" : "shadernotex.tga"); - m_pTexture = GlobalTexturesCache().capture(LoadImageCallback(0, loadBitmap), name.c_str()); - } - } -} - -void unrealise(){ - GlobalTexturesCache().release( m_pTexture ); - - if ( m_notfound != 0 ) { - GlobalTexturesCache().release( m_notfound ); - } - - unrealiseLighting(); -} - -void realiseLighting(){ - if ( m_lightingEnabled ) { - LoadImageCallback loader = GlobalTexturesCache().defaultLoader(); - if ( !string_empty( m_template.m_heightmapScale.c_str() ) ) { - m_heightmapScale = evaluateFloat( m_template.m_heightmapScale, m_template.m_params, m_args ); - loader = LoadImageCallback( &m_heightmapScale, loadHeightmap ); - } - m_pDiffuse = evaluateTexture( m_template.m_diffuse, m_template.m_params, m_args ); - m_pBump = evaluateTexture( m_template.m_bump, m_template.m_params, m_args, loader ); - m_pSpecular = evaluateTexture( m_template.m_specular, m_template.m_params, m_args ); - m_pLightFalloffImage = evaluateTexture( m_template.m_lightFalloffImage, m_template.m_params, m_args ); - - for ( ShaderTemplate::MapLayers::const_iterator i = m_template.m_layers.begin(); i != m_template.m_layers.end(); ++i ) - { - m_layers.push_back( evaluateLayer( *i, m_template.m_params, m_args ) ); - } - - if ( m_layers.size() == 1 ) { - const BlendFuncExpression& blendFunc = m_template.m_layers.front().blendFunc(); - if ( !string_empty( blendFunc.second.c_str() ) ) { - m_blendFunc = BlendFunc( - evaluateBlendFactor( blendFunc.first.c_str(), m_template.m_params, m_args ), - evaluateBlendFactor( blendFunc.second.c_str(), m_template.m_params, m_args ) - ); - } - else - { - const char* blend = evaluateShaderValue( blendFunc.first.c_str(), m_template.m_params, m_args ); - - if ( string_equal_nocase( blend, "add" ) ) { - m_blendFunc = BlendFunc( BLEND_ONE, BLEND_ONE ); - } - else if ( string_equal_nocase( blend, "filter" ) ) { - m_blendFunc = BlendFunc( BLEND_DST_COLOUR, BLEND_ZERO ); - } - else if ( string_equal_nocase( blend, "blend" ) ) { - m_blendFunc = BlendFunc( BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA ); - } - else - { - globalErrorStream() << "parsing blend value failed: " << makeQuoted( blend ) << "\n"; - } - } - } - } -} - -void unrealiseLighting(){ - if ( m_lightingEnabled ) { - GlobalTexturesCache().release( m_pDiffuse ); - GlobalTexturesCache().release( m_pBump ); - GlobalTexturesCache().release( m_pSpecular ); - - GlobalTexturesCache().release( m_pLightFalloffImage ); - - for ( MapLayers::iterator i = m_layers.begin(); i != m_layers.end(); ++i ) - { - GlobalTexturesCache().release( ( *i ).texture() ); - } - m_layers.clear(); - - m_blendFunc = BlendFunc( BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA ); - } -} - -// set shader name -void setName( const char* name ){ - m_Name = name; -} - -void setWadName( const char* name ){ - m_WadName = name; -} - -class MapLayer : public ShaderLayer -{ -qtexture_t* m_texture; -BlendFunc m_blendFunc; -bool m_clampToBorder; -float m_alphaTest; -public: -MapLayer( qtexture_t* texture, BlendFunc blendFunc, bool clampToBorder, float alphaTest ) : - m_texture( texture ), - m_blendFunc( blendFunc ), - m_clampToBorder( false ), - m_alphaTest( alphaTest ){ -} - -qtexture_t* texture() const { - return m_texture; -} - -BlendFunc blendFunc() const { - return m_blendFunc; -} - -bool clampToBorder() const { - return m_clampToBorder; -} - -float alphaTest() const { - return m_alphaTest; -} -}; - -static MapLayer evaluateLayer( const ShaderTemplate::MapLayerTemplate& layerTemplate, const ShaderParameters& params, const ShaderArguments& args ){ - return MapLayer( - evaluateTexture( layerTemplate.texture(), params, args ), - evaluateBlendFunc( layerTemplate.blendFunc(), params, args ), - layerTemplate.clampToBorder(), - evaluateFloat( layerTemplate.alphaTest(), params, args ) - ); -} - -typedef std::vector MapLayers; -MapLayers m_layers; - -const ShaderLayer* firstLayer() const { - if ( m_layers.empty() ) { - return 0; - } - return &m_layers.front(); -} - -void forEachLayer(const ShaderLayerCallback &callback) const -{ - for (MapLayers::const_iterator i = m_layers.begin(); i != m_layers.end(); ++i) { - callback(*i); - } -} - -qtexture_t* lightFalloffImage() const { - if ( !string_empty( m_template.m_lightFalloffImage.c_str() ) ) { - return m_pLightFalloffImage; - } - return 0; -} -}; - -bool CShader::m_lightingEnabled = false; - -typedef SmartPointer ShaderPointer; -typedef std::map shaders_t; - -shaders_t g_ActiveShaders; - -static shaders_t::iterator g_ActiveShadersIterator; - -void ActiveShaders_IteratorBegin(){ - g_ActiveShadersIterator = g_ActiveShaders.begin(); -} - -bool ActiveShaders_IteratorAtEnd(){ - return g_ActiveShadersIterator == g_ActiveShaders.end(); -} - -IShader *ActiveShaders_IteratorCurrent(){ - return static_cast( g_ActiveShadersIterator->second ); -} - -void ActiveShaders_IteratorIncrement(){ - ++g_ActiveShadersIterator; -} - -void debug_check_shaders( shaders_t& shaders ){ - for ( shaders_t::iterator i = shaders.begin(); i != shaders.end(); ++i ) - { - ASSERT_MESSAGE( i->second->refcount() == 1, "orphan shader still referenced" ); - } -} - -// will free all GL binded qtextures and shaders -// NOTE: doesn't make much sense out of Radiant exit or called during a reload -void FreeShaders(){ - // reload shaders - // empty the actives shaders list - debug_check_shaders( g_ActiveShaders ); - g_ActiveShaders.clear(); - g_shaders.clear(); - g_shaderTemplates.clear(); - g_shaderDefinitions.clear(); - g_ActiveShadersChangedNotify(); -} - -bool ShaderTemplate::parseQuake3( Tokeniser& tokeniser ){ - // name of the qtexture_t we'll use to represent this shader ( this one has the "textures\" before ) - m_textureName = m_Name.c_str(); - - tokeniser.nextLine(); - - // we need to read until we hit a balanced } - int depth = 0; - for (;; ) - { - tokeniser.nextLine(); - const char* token = tokeniser.getToken(); - - if ( token == 0 ) { - return false; - } - - if ( string_equal( token, "{" ) ) { - ++depth; - continue; - } - else if ( string_equal( token, "}" ) ) { - --depth; - if ( depth < 0 ) { // underflow - return false; - } - if ( depth == 0 ) { // end of shader - break; - } - - continue; - } - - if ( depth == 1 ) { - if ( string_equal_nocase( token, "qer_nocarve" ) ) { - m_nFlags |= QER_NOCARVE; - } - else if ( string_equal_nocase( token, "qer_trans" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, m_fTrans ) ); - m_nFlags |= QER_TRANS; - } - else if ( string_equal_nocase( token, "qer_editorimage" ) ) { - RETURN_FALSE_IF_FAIL( Tokeniser_parseTextureName( tokeniser, m_textureName ) ); - } - else if ( string_equal_nocase( token, "qer_alphafunc" ) ) { - const char* alphafunc = tokeniser.getToken(); - - if ( alphafunc == 0 ) { - Tokeniser_unexpectedError( tokeniser, alphafunc, "#alphafunc" ); - return false; - } - - if ( string_equal_nocase( alphafunc, "equal" ) ) { - m_AlphaFunc = IShader::eEqual; - } - else if ( string_equal_nocase( alphafunc, "greater" ) ) { - m_AlphaFunc = IShader::eGreater; - } - else if ( string_equal_nocase( alphafunc, "less" ) ) { - m_AlphaFunc = IShader::eLess; - } - else if ( string_equal_nocase( alphafunc, "gequal" ) ) { - m_AlphaFunc = IShader::eGEqual; - } - else if ( string_equal_nocase( alphafunc, "lequal" ) ) { - m_AlphaFunc = IShader::eLEqual; - } - else - { - m_AlphaFunc = IShader::eAlways; - } - - m_nFlags |= QER_ALPHATEST; - - RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, m_AlphaRef ) ); - } - else if ( string_equal_nocase( token, "cull" ) ) { - const char* cull = tokeniser.getToken(); - - if ( cull == 0 ) { - Tokeniser_unexpectedError( tokeniser, cull, "#cull" ); - return false; - } - - if ( string_equal_nocase( cull, "none" ) - || string_equal_nocase( cull, "twosided" ) - || string_equal_nocase( cull, "disable" ) ) { - m_Cull = IShader::eCullNone; - } - else if ( string_equal_nocase( cull, "back" ) - || string_equal_nocase( cull, "backside" ) - || string_equal_nocase( cull, "backsided" ) ) { - m_Cull = IShader::eCullBack; - } - else - { - m_Cull = IShader::eCullBack; - } - - m_nFlags |= QER_CULL; - } - else if ( string_equal_nocase( token, "surfaceparm" ) ) { - const char* surfaceparm = tokeniser.getToken(); - - if ( surfaceparm == 0 ) { - Tokeniser_unexpectedError( tokeniser, surfaceparm, "#surfaceparm" ); - return false; - } - - if ( string_equal_nocase( surfaceparm, "fog" ) ) { - m_nFlags |= QER_FOG; - if ( m_fTrans == 1.0f ) { // has not been explicitly set by qer_trans - m_fTrans = 0.35f; - } - } - else if ( string_equal_nocase( surfaceparm, "nodraw" ) ) { - m_nFlags |= QER_NODRAW; - } - else if ( string_equal_nocase( surfaceparm, "nonsolid" ) ) { - m_nFlags |= QER_NONSOLID; - } - else if ( string_equal_nocase( surfaceparm, "water" ) ) { - m_nFlags |= QER_WATER; - } - else if ( string_equal_nocase( surfaceparm, "lava" ) ) { - m_nFlags |= QER_LAVA; - } - else if ( string_equal_nocase( surfaceparm, "areaportal" ) ) { - m_nFlags |= QER_AREAPORTAL; - } - else if ( string_equal_nocase( surfaceparm, "playerclip" ) ) { - m_nFlags |= QER_CLIP; - } - else if ( string_equal_nocase( surfaceparm, "botclip" ) ) { - m_nFlags |= QER_BOTCLIP; - } - } - } - } - - return true; -} - -class Layer -{ -public: -LayerTypeId m_type; -TextureExpression m_texture; -BlendFunc m_blendFunc; -bool m_clampToBorder; -float m_alphaTest; -float m_heightmapScale; - -Layer() : m_type( LAYER_NONE ), m_blendFunc( BLEND_ONE, BLEND_ZERO ), m_clampToBorder( false ), m_alphaTest( -1 ), m_heightmapScale( 0 ){ -} -}; - -std::list g_shaderFilenames; - -void ParseShaderFile( Tokeniser& tokeniser, const char* filename ){ - g_shaderFilenames.push_back( filename ); - filename = g_shaderFilenames.back().c_str(); - tokeniser.nextLine(); - for (;; ) - { - const char* token = tokeniser.getToken(); - - if ( token == 0 ) { - break; - } - - if ( string_equal( token, "table" ) ) { - if ( tokeniser.getToken() == 0 ) { - Tokeniser_unexpectedError( tokeniser, 0, "#table-name" ); - return; - } - if ( !Tokeniser_parseToken( tokeniser, "{" ) ) { - return; - } - for (;; ) - { - const char* option = tokeniser.getToken(); - if ( string_equal( option, "{" ) ) { - for (;; ) - { - const char* value = tokeniser.getToken(); - if ( string_equal( value, "}" ) ) { - break; - } - } - - if ( !Tokeniser_parseToken( tokeniser, "}" ) ) { - return; - } - break; - } - } - } - else - { - if ( string_equal( token, "guide" ) ) { - parseTemplateInstance( tokeniser, filename ); - } - else - { - if ( !string_equal( token, "material" ) - && !string_equal( token, "particle" ) - && !string_equal( token, "skin" ) ) { - tokeniser.ungetToken(); - } - // first token should be the path + name.. ( from base ) - CopiedString name; - if ( !Tokeniser_parseShaderName( tokeniser, name ) ) { - } - ShaderTemplatePointer shaderTemplate( new ShaderTemplate() ); - shaderTemplate->setName( name.c_str() ); - - g_shaders.insert( ShaderTemplateMap::value_type( shaderTemplate->getName(), shaderTemplate ) ); - - bool result = ( g_shaderLanguage == SHADERLANGUAGE_QUAKE3 ) - ? shaderTemplate->parseQuake3( tokeniser ) - : shaderTemplate->parseDoom3( tokeniser ); - if ( result ) { - // do we already have this shader? - if ( !g_shaderDefinitions.insert( ShaderDefinitionMap::value_type( shaderTemplate->getName(), ShaderDefinition( shaderTemplate.get(), ShaderArguments(), filename ) ) ).second ) { -#if GDEF_DEBUG - globalOutputStream() << "WARNING: shader " << shaderTemplate->getName() << " is already in memory, definition in " << filename << " ignored.\n"; -#endif - } - } - else - { - globalErrorStream() << "Error parsing shader " << shaderTemplate->getName() << "\n"; - return; - } - } - } - } -} - -void parseGuideFile( Tokeniser& tokeniser, const char* filename ){ - tokeniser.nextLine(); - for (;; ) - { - const char* token = tokeniser.getToken(); - - if ( token == 0 ) { - break; - } - - if ( string_equal( token, "guide" ) ) { - // first token should be the path + name.. ( from base ) - ShaderTemplatePointer shaderTemplate( new ShaderTemplate ); - shaderTemplate->parseTemplate( tokeniser ); - if ( !g_shaderTemplates.insert( ShaderTemplateMap::value_type( shaderTemplate->getName(), shaderTemplate ) ).second ) { - globalErrorStream() << "guide " << makeQuoted( shaderTemplate->getName() ) << ": already defined, second definition ignored\n"; - } - } - else if ( string_equal( token, "inlineGuide" ) ) { - // skip entire inlineGuide definition - std::size_t depth = 0; - for (;; ) - { - tokeniser.nextLine(); - token = tokeniser.getToken(); - if ( string_equal( token, "{" ) ) { - ++depth; - } - else if ( string_equal( token, "}" ) ) { - if ( --depth == 0 ) { - break; - } - } - } - } - } -} - -void LoadShaderFile( const char* filename ){ - ArchiveTextFile* file = GlobalFileSystem().openTextFile( filename ); - - if ( file != 0 ) { - globalOutputStream() << "Parsing shaderfile " << filename << "\n"; - - Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser( file->getInputStream() ); - - ParseShaderFile( tokeniser, filename ); - - tokeniser.release(); - file->release(); - } - else - { - globalOutputStream() << "Unable to read shaderfile " << filename << "\n"; - } -} - -void loadGuideFile( const char* filename ){ - StringOutputStream fullname( 256 ); - fullname << "guides/" << filename; - ArchiveTextFile* file = GlobalFileSystem().openTextFile( fullname.c_str() ); - - if ( file != 0 ) { - globalOutputStream() << "Parsing guide file " << fullname.c_str() << "\n"; - - Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser( file->getInputStream() ); - - parseGuideFile( tokeniser, fullname.c_str() ); - - tokeniser.release(); - file->release(); - } - else - { - globalOutputStream() << "Unable to read guide file " << fullname.c_str() << "\n"; - } -} - -CShader* Try_Shader_ForName( const char* name ){ - { - shaders_t::iterator i = g_ActiveShaders.find( name ); - if ( i != g_ActiveShaders.end() ) { - return ( *i ).second; - } - } - // active shader was not found - - // find matching shader definition - ShaderDefinitionMap::iterator i = g_shaderDefinitions.find( name ); - if ( i == g_shaderDefinitions.end() ) { - // shader definition was not found - - // create new shader definition from default shader template - ShaderTemplatePointer shaderTemplate( new ShaderTemplate() ); - shaderTemplate->CreateDefault( name ); - g_shaderTemplates.insert( ShaderTemplateMap::value_type( shaderTemplate->getName(), shaderTemplate ) ); - - i = g_shaderDefinitions.insert( ShaderDefinitionMap::value_type( name, ShaderDefinition( shaderTemplate.get(), ShaderArguments(), "" ) ) ).first; - } - - // create shader from existing definition - ShaderPointer pShader( new CShader( ( *i ).second ) ); - pShader->setName( name ); - g_ActiveShaders.insert( shaders_t::value_type( name, pShader ) ); - g_ActiveShadersChangedNotify(); - return pShader; -} - -IShader *Shader_ForName( const char *name ){ - ASSERT_NOTNULL( name ); - - IShader *pShader = Try_Shader_ForName( name ); - pShader->IncRef(); - return pShader; -} - - -// the list of scripts/*.shader files we need to work with -// those are listed in shaderlist file -GSList *l_shaderfiles = 0; - -GSList* Shaders_getShaderFileList(){ - return l_shaderfiles; -} - -/* - ================== - DumpUnreferencedShaders - usefull function: dumps the list of .shader files that are not referenced to the console - ================== - */ -void IfFound_dumpUnreferencedShader( bool& bFound, const char* filename ){ - bool listed = false; - - for ( GSList* sh = l_shaderfiles; sh != 0; sh = g_slist_next( sh ) ) - { - if ( !strcmp( (char*)sh->data, filename ) ) { - listed = true; - break; - } - } - - if ( !listed ) { - if ( !bFound ) { - bFound = true; - globalOutputStream() << "Following shader files are not referenced in any shaderlist.txt:\n"; - } - globalOutputStream() << "\t" << filename << "\n"; - } -} - -typedef ReferenceCaller IfFoundDumpUnreferencedShaderCaller; - -void DumpUnreferencedShaders(){ - bool bFound = false; - GlobalFileSystem().forEachFile( g_shadersDirectory, g_shadersExtension, IfFoundDumpUnreferencedShaderCaller( bFound ) ); -} - -void ShaderList_addShaderFile( const char* dirstring ){ - bool found = false; - - for ( GSList* tmp = l_shaderfiles; tmp != 0; tmp = tmp->next ) - { - if ( string_equal_nocase( dirstring, (char*)tmp->data ) ) { - found = true; - globalOutputStream() << "duplicate entry \"" << (char*)tmp->data << "\" in shaderlist.txt\n"; - break; - } - } - - if ( !found ) { - l_shaderfiles = g_slist_append( l_shaderfiles, strdup( dirstring ) ); - } -} - -/* - ================== - BuildShaderList - build a CStringList of shader names - ================== - */ -void BuildShaderList( TextInputStream& shaderlist ){ - Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser( shaderlist ); - tokeniser.nextLine(); - const char* token = tokeniser.getToken(); - StringOutputStream shaderFile( 64 ); - while ( token != 0 ) - { - // each token should be a shader filename - shaderFile << token << "." << g_shadersExtension; - - ShaderList_addShaderFile( shaderFile.c_str() ); - - tokeniser.nextLine(); - token = tokeniser.getToken(); - - shaderFile.clear(); - } - tokeniser.release(); -} - -void FreeShaderList(){ - while ( l_shaderfiles != 0 ) - { - free( l_shaderfiles->data ); - l_shaderfiles = g_slist_remove( l_shaderfiles, l_shaderfiles->data ); - } -} - -void ShaderList_addFromArchive( const char *archivename ){ - const char *shaderpath = GlobalRadiant().getGameDescriptionKeyValue( "shaderpath" ); - if ( string_empty( shaderpath ) ) { - return; - } - - StringOutputStream shaderlist( 256 ); - shaderlist << DirectoryCleaned( shaderpath ) << "shaderlist.txt"; - - Archive *archive = GlobalFileSystem().getArchive( archivename, false ); - if ( archive ) { - ArchiveTextFile *file = archive->openTextFile( shaderlist.c_str() ); - if ( file ) { - globalOutputStream() << "Found shaderlist.txt in " << archivename << "\n"; - BuildShaderList( file->getInputStream() ); - file->release(); - } - } -} - -#include "stream/filestream.h" - -bool shaderlist_findOrInstall( const char* enginePath, const char* toolsPath, const char* shaderPath, const char* gamename ){ - StringOutputStream absShaderList( 256 ); - absShaderList << enginePath << gamename << '/' << shaderPath << "shaderlist.txt"; - if ( file_exists( absShaderList.c_str() ) ) { - return true; - } - { - StringOutputStream directory( 256 ); - directory << enginePath << gamename << '/' << shaderPath; - if ( !file_exists( directory.c_str() ) && !Q_mkdir( directory.c_str() ) ) { - return false; - } - } - { - StringOutputStream defaultShaderList( 256 ); - defaultShaderList << toolsPath << gamename << '/' << "default_shaderlist.txt"; - if ( file_exists( defaultShaderList.c_str() ) ) { - return file_copy( defaultShaderList.c_str(), absShaderList.c_str() ); - } - } - return false; -} - -void Shaders_Load(){ - if ( g_shaderLanguage == SHADERLANGUAGE_QUAKE4 ) { - GlobalFileSystem().forEachFile("guides/", "guide", makeCallbackF(loadGuideFile), 0); - } - - const char* shaderPath = GlobalRadiant().getGameDescriptionKeyValue( "shaderpath" ); - if ( !string_empty( shaderPath ) ) { - StringOutputStream path( 256 ); - path << DirectoryCleaned( shaderPath ); - - if ( g_useShaderList ) { - // preload shader files that have been listed in shaderlist.txt - const char* basegame = GlobalRadiant().getRequiredGameDescriptionKeyValue( "basegame" ); - const char* gamename = GlobalRadiant().getGameName(); - const char* enginePath = GlobalRadiant().getEnginePath(); - const char* toolsPath = GlobalRadiant().getGameToolsPath(); - - bool isMod = !string_equal( basegame, gamename ); - - if ( !isMod || !shaderlist_findOrInstall( enginePath, toolsPath, path.c_str(), gamename ) ) { - gamename = basegame; - shaderlist_findOrInstall( enginePath, toolsPath, path.c_str(), gamename ); - } - - GlobalFileSystem().forEachArchive(makeCallbackF(ShaderList_addFromArchive), false, true); - DumpUnreferencedShaders(); - } - else - { - GlobalFileSystem().forEachFile(path.c_str(), g_shadersExtension, makeCallbackF(ShaderList_addShaderFile), 0); - } - - GSList *lst = l_shaderfiles; - StringOutputStream shadername( 256 ); - while ( lst ) - { - shadername << path.c_str() << reinterpret_cast( lst->data ); - LoadShaderFile( shadername.c_str() ); - shadername.clear(); - lst = lst->next; - } - } - - //StringPool_analyse( ShaderPool::instance() ); -} - -void Shaders_Free(){ - FreeShaders(); - FreeShaderList(); - g_shaderFilenames.clear(); -} - -ModuleObservers g_observers; - -std::size_t g_shaders_unrealised = 1; // wait until filesystem and is realised before loading anything -bool Shaders_realised(){ - return g_shaders_unrealised == 0; -} - -void Shaders_Realise(){ - if ( --g_shaders_unrealised == 0 ) { - Shaders_Load(); - g_observers.realise(); - } -} - -void Shaders_Unrealise(){ - if ( ++g_shaders_unrealised == 1 ) { - g_observers.unrealise(); - Shaders_Free(); - } -} - -void Shaders_Refresh(){ - Shaders_Unrealise(); - Shaders_Realise(); -} - -class Quake3ShaderSystem : public ShaderSystem, public ModuleObserver -{ -public: -void realise(){ - Shaders_Realise(); -} - -void unrealise(){ - Shaders_Unrealise(); -} - -void refresh(){ - Shaders_Refresh(); -} - -IShader* getShaderForName( const char* name ){ - return Shader_ForName( name ); -} - -void foreachShaderName( const ShaderNameCallback& callback ){ - for ( ShaderDefinitionMap::const_iterator i = g_shaderDefinitions.begin(); i != g_shaderDefinitions.end(); ++i ) - { - callback( ( *i ).first.c_str() ); - } -} - -void beginActiveShadersIterator(){ - ActiveShaders_IteratorBegin(); -} - -bool endActiveShadersIterator(){ - return ActiveShaders_IteratorAtEnd(); -} - -IShader* dereferenceActiveShadersIterator(){ - return ActiveShaders_IteratorCurrent(); -} - -void incrementActiveShadersIterator(){ - ActiveShaders_IteratorIncrement(); -} - -void setActiveShadersChangedNotify( const Callback& notify ){ - g_ActiveShadersChangedNotify = notify; -} - -void attach( ModuleObserver& observer ){ - g_observers.attach( observer ); -} - -void detach( ModuleObserver& observer ){ - g_observers.detach( observer ); -} - -void setLightingEnabled( bool enabled ){ - if ( CShader::m_lightingEnabled != enabled ) { - for ( shaders_t::const_iterator i = g_ActiveShaders.begin(); i != g_ActiveShaders.end(); ++i ) - { - ( *i ).second->unrealiseLighting(); - } - CShader::m_lightingEnabled = enabled; - for ( shaders_t::const_iterator i = g_ActiveShaders.begin(); i != g_ActiveShaders.end(); ++i ) - { - ( *i ).second->realiseLighting(); - } - } -} - -const char* getTexturePrefix() const { - return g_texturePrefix; -} -}; - -Quake3ShaderSystem g_Quake3ShaderSystem; - -ShaderSystem& GetShaderSystem(){ - return g_Quake3ShaderSystem; -} - -void Shaders_Construct(){ - GlobalFileSystem().attach( g_Quake3ShaderSystem ); -} - -void Shaders_Destroy(){ - GlobalFileSystem().detach( g_Quake3ShaderSystem ); - - if ( Shaders_realised() ) { - Shaders_Free(); - } -} diff --git a/plugins/shaders/shaders.h b/plugins/shaders/shaders.h deleted file mode 100644 index 88f193f..0000000 --- a/plugins/shaders/shaders.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_SHADERS_H ) -#define INCLUDED_SHADERS_H - -void Shaders_Construct(); -void Shaders_Destroy(); -class ShaderSystem; -ShaderSystem& GetShaderSystem(); - -enum ShaderLanguage -{ - SHADERLANGUAGE_QUAKE3, - SHADERLANGUAGE_DOOM3, - SHADERLANGUAGE_QUAKE4 -}; - -extern const char* g_shadersExtension; -extern const char* g_shadersDirectory; -extern ShaderLanguage g_shaderLanguage; -extern bool g_enableDefaultShaders; -extern bool g_useShaderList; -struct _QERPlugImageTable; -extern _QERPlugImageTable* g_bitmapModule; - - -#endif diff --git a/plugins/vfspk3/Makefile b/plugins/vfspk3/Makefile deleted file mode 100644 index eb28767..0000000 --- a/plugins/vfspk3/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# WorldSpawn Makefile - -GLIB_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -DGTK_TARGET=2 -GLIB_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) - -PLUGIN_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) -I../../include -I../../libs -fPIC -fvisibility=hidden -PLUGIN_LDFLAGS=$(LDFLAGS) $(GLIB_LDFLAGS) -shared -LIB_EXT=so - -DO_CXX=$(CXX) $(PLUGIN_CFLAGS) -o $@ -c $< - -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - archive.o vfs.o vfspk3.o - -# binary target -../../build/plugins/libvfspk3.$(LIB_EXT): $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) ../../libs/libfilematch.a $(PLUGIN_LDFLAGS) - -# object files -archive.o: archive.cpp archive.h -vfs.o: vfs.cpp vfs.h -vfspk3.o: vfspk3.cpp - -clean: - -rm -f *.o ../../build/plugins/libvfspk3.$(LIB_EXT) diff --git a/plugins/vfspk3/archive.cpp b/plugins/vfspk3/archive.cpp deleted file mode 100644 index 49fc1c7..0000000 --- a/plugins/vfspk3/archive.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "archive.h" - -#include "idatastream.h" -#include "iarchive.h" - -#include -#include -#include - -#include "stream/filestream.h" -#include "stream/textfilestream.h" -#include "string/string.h" -#include "os/path.h" -#include "os/file.h" -#include "os/dir.h" -#include "archivelib.h" -#include "fs_path.h" - - -class DirectoryArchive : public Archive { -CopiedString m_root; -public: -DirectoryArchive(const char *root) : m_root(root) -{ -} - -void release() -{ - delete this; -} - -virtual ArchiveFile *openFile(const char *name) -{ - UnixPath path(m_root.c_str()); - path.push_filename(name); - DirectoryArchiveFile *file = new DirectoryArchiveFile(name, path.c_str()); - if (!file->failed()) { - return file; - } - file->release(); - return 0; -} - -virtual ArchiveTextFile *openTextFile(const char *name) -{ - UnixPath path(m_root.c_str()); - path.push_filename(name); - DirectoryArchiveTextFile *file = new DirectoryArchiveTextFile(name, path.c_str()); - if (!file->failed()) { - return file; - } - file->release(); - return 0; -} - -virtual bool containsFile(const char *name) -{ - UnixPath path(m_root.c_str()); - path.push_filename(name); - return file_readable(path.c_str()); -} - -virtual void forEachFile(VisitorFunc visitor, const char *root) -{ - std::vector dirs; - UnixPath path(m_root.c_str()); - path.push(root); - dirs.push_back(directory_open(path.c_str())); - - while (!dirs.empty() && directory_good(dirs.back())) { - const char *name = directory_read_and_increment(dirs.back()); - - if (name == 0) { - directory_close(dirs.back()); - dirs.pop_back(); - path.pop(); - } else if (!string_equal(name, ".") && !string_equal(name, "..")) { - path.push_filename(name); - - bool is_directory = file_is_directory(path.c_str()); - - if (!is_directory) { - visitor.file(path_make_relative(path.c_str(), m_root.c_str())); - } - - path.pop(); - - if (is_directory) { - path.push(name); - - if (!visitor.directory(path_make_relative(path.c_str(), m_root.c_str()), dirs.size())) { - dirs.push_back(directory_open(path.c_str())); - } else { - path.pop(); - } - } - } - } -} -}; - -Archive *OpenArchive(const char *name) -{ - return new DirectoryArchive(name); -} - -#if 0 - -class TestArchive -{ -class TestVisitor : public Archive::IVisitor -{ -public: -virtual void visit( const char* name ){ - int bleh = 0; -} -}; -public: -void test1(){ - Archive* archive = OpenArchive( "d:/quake/id1/" ); - ArchiveFile* file = archive->openFile( "quake101.wad" ); - if ( file != 0 ) { - char buffer[1024]; - file->getInputStream().read( buffer, 1024 ); - file->release(); - } - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "" ); - archive->release(); -} -void test2(){ - Archive* archive = OpenArchive( "d:/gtkradiant_root/baseq3/" ); - TestVisitor visitor; - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 2 ), "" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 1 ), "textures" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eDirectories, 1 ), "textures" ); - archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "textures" ); - archive->release(); -} -TestArchive(){ - test1(); - test2(); -} -}; - -TestArchive g_test; - -#endif diff --git a/plugins/vfspk3/archive.h b/plugins/vfspk3/archive.h deleted file mode 100644 index 2704d25..0000000 --- a/plugins/vfspk3/archive.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ARCHIVE_H ) -#define INCLUDED_ARCHIVE_H - -#include "iarchive.h" - -const _QERArchiveTable *GetArchiveTable(ArchiveModules &archiveModules, const char *type); - -#endif diff --git a/plugins/vfspk3/vfs.cpp b/plugins/vfspk3/vfs.cpp deleted file mode 100644 index df7673b..0000000 --- a/plugins/vfspk3/vfs.cpp +++ /dev/null @@ -1,971 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Rules: -// -// - Directories should be searched in the following order: ~/.q3a/baseq3, -// install dir (/usr/local/games/quake3/baseq3) and cd_path (/mnt/cdrom/baseq3). -// -// - Pak files are searched first inside the directories. -// - Case insensitive. -// - Unix-style slashes (/) (windows is backwards .. everyone knows that) -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "vfs.h" -#include "globaldefs.h" - -#include -#include -#include - -#include "qerplugin.h" -#include "idatastream.h" -#include "iarchive.h" - -ArchiveModules &FileSystemQ3API_getArchiveModules(); - -#include "ifilesystem.h" - -#include "generic/callback.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "os/path.h" -#include "moduleobservers.h" -#include "filematch.h" -#include "dpkdeps.h" - - -const int VFS_MAXDIRS = 64; - -#if GDEF_OS_WINDOWS -#define PATH_MAX 260 -#endif - -#define gamemode_get GlobalRadiant().getGameMode - - - -// ============================================================================= -// Global variables - -Archive *OpenArchive(const char *name); - -struct archive_entry_t { - CopiedString name; - Archive *archive; - bool is_pakfile; -}; - -#include -#include - -typedef std::list archives_t; - -static archives_t g_archives; -static char g_strDirs[VFS_MAXDIRS][PATH_MAX + 1]; -static int g_numDirs; -static char g_strForbiddenDirs[VFS_MAXDIRS][PATH_MAX + 1]; -static int g_numForbiddenDirs = 0; -static bool g_bUsePak = true; - -ModuleObservers g_observers; - -// ============================================================================= -// Static functions - -static void AddSlash(char *str) -{ - std::size_t n = strlen(str); - if (n > 0) { - if (str[n - 1] != '\\' && str[n - 1] != '/') { - globalErrorStream() << "WARNING: directory path does not end with separator: " << str << "\n"; - strcat(str, "/"); - } - } -} - -static void FixDOSName(char *src) -{ - if (src == 0 || strchr(src, '\\') == 0) { - return; - } - - globalErrorStream() << "WARNING: invalid path separator '\\': " << src << "\n"; - - while (*src) { - if (*src == '\\') { - *src = '/'; - } - src++; - } -} - -const _QERArchiveTable *GetArchiveTable(ArchiveModules &archiveModules, const char *ext) -{ - StringOutputStream tmp(16); - tmp << LowerCase(ext); - return archiveModules.findModule(tmp.c_str()); -} - -static Archive *InitPakFile(ArchiveModules &archiveModules, const char *filename) -{ - const _QERArchiveTable *table = GetArchiveTable(archiveModules, path_get_extension(filename)); - - if (table != 0) { - archive_entry_t entry; - entry.name = filename; - - entry.archive = table->m_pfnOpenArchive(filename); - entry.is_pakfile = true; - g_archives.push_back(entry); - globalOutputStream() << " " << path_get_extension(filename) << " file: " << filename << "\n"; - - return entry.archive; - } - - return 0; -} - -static Archive *InitWadFile(ArchiveModules &archiveModules, const char *filename) -{ - const _QERArchiveTable *table = GetArchiveTable(archiveModules, path_get_extension(filename)); - - if (table != 0) { - archive_entry_t entry; - entry.name = filename; - - entry.archive = table->m_pfnOpenArchive(filename); - entry.is_pakfile = false; - g_archives.push_back(entry); - globalOutputStream() << " wad file: " << filename << "\n"; - - return entry.archive; - } - - return 0; -} - -inline void pathlist_prepend_unique(GSList *&pathlist, char *path) -{ - if (g_slist_find_custom(pathlist, path, (GCompareFunc) path_compare) == 0) { - pathlist = g_slist_prepend(pathlist, path); - } else { - g_free(path); - } -} - -class DirectoryListVisitor : public Archive::Visitor { -GSList *&m_matches; -const char *m_directory; -public: -DirectoryListVisitor(GSList *&matches, const char *directory) - : m_matches(matches), m_directory(directory) -{ -} - -void visit(const char *name) -{ - const char *subname = path_make_relative(name, m_directory); - if (subname != name) { - if (subname[0] == '/') { - ++subname; - } - char *dir = g_strdup(subname); - char *last_char = dir + strlen(dir); - if (last_char != dir && *(--last_char) == '/') { - *last_char = '\0'; - } - pathlist_prepend_unique(m_matches, dir); - } -} -}; - -class FileListVisitor : public Archive::Visitor { -GSList *&m_matches; -const char *m_directory; -const char *m_extension; -public: -FileListVisitor(GSList *&matches, const char *directory, const char *extension) - : m_matches(matches), m_directory(directory), m_extension(extension) -{ -} - -void visit(const char *name) -{ - const char *subname = path_make_relative(name, m_directory); - if (subname != name) { - if (subname[0] == '/') { - ++subname; - } - if (m_extension[0] == '*' || extension_equal(path_get_extension(subname), m_extension)) { - pathlist_prepend_unique(m_matches, g_strdup(subname)); - } - } -} -}; - -static GSList *GetListInternal(const char *refdir, const char *ext, bool directories, std::size_t depth) -{ - GSList *files = 0; - - ASSERT_MESSAGE(refdir[strlen(refdir) - 1] == '/', "search path does not end in '/'"); - - if (directories) { - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - DirectoryListVisitor visitor(files, refdir); - (*i).archive->forEachFile(Archive::VisitorFunc(visitor, Archive::eDirectories, depth), refdir); - } - } else { - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - FileListVisitor visitor(files, refdir, ext); - (*i).archive->forEachFile(Archive::VisitorFunc(visitor, Archive::eFiles, depth), refdir); - } - } - - files = g_slist_reverse(files); - - return files; -} - -inline int ascii_to_upper(int c) -{ - if (c >= 'a' && c <= 'z') { - return c - ('a' - 'A'); - } - return c; -} - -/*! - This behaves identically to stricmp(a,b), except that ASCII chars - [\]^`_ come AFTER alphabet chars instead of before. This is because - it converts all alphabet chars to uppercase before comparison, - while stricmp converts them to lowercase. - */ -static int string_compare_nocase_upper(const char *a, const char *b) -{ - for (;;) { - int c1 = ascii_to_upper(*a++); - int c2 = ascii_to_upper(*b++); - - if (c1 < c2) { - return -1; // a < b - } - if (c1 > c2) { - return 1; // a > b - } - if (c1 == 0) { - return 0; // a == b - } - } -} - -// Arnout: note - sort pakfiles in reverse order. This ensures that -// later pakfiles override earlier ones. This because the vfs module -// returns a filehandle to the first file it can find (while it should -// return the filehandle to the file in the most overriding pakfile, the -// last one in the list that is). - -//!\todo Analyse the code in rtcw/q3 to see which order it sorts pak files. -class PakLess { -public: -bool operator()(const CopiedString &self, const CopiedString &other) const -{ - return string_compare_nocase_upper(self.c_str(), other.c_str()) > 0; -} -}; - -typedef std::set Archives; - -Archive *AddPk3Dir(const char *fullpath) -{ - if (g_numDirs == VFS_MAXDIRS) { return 0; } - - strncpy(g_strDirs[g_numDirs], fullpath, PATH_MAX); - g_strDirs[g_numDirs][PATH_MAX] = '\0'; - g_numDirs++; - - { - archive_entry_t entry; - entry.name = fullpath; - entry.archive = OpenArchive(fullpath); - entry.is_pakfile = false; - g_archives.push_back(entry); - - return entry.archive; - } -} - -// for Daemon DPK vfs - -Archive *AddDpkDir(const char *fullpath) -{ - return AddPk3Dir(fullpath); -} - -struct pakfile_path_t { - CopiedString fullpath; // full pak dir or pk3dir name - bool is_pakfile; // defines is it .pk3dir or .pk3 file -}; - -typedef std::pair PakfilePathsKV; -typedef std::map PakfilePaths; // key must have no extension, only name - -static PakfilePaths g_pakfile_paths; - -void AddDpkPak(const char *name, const char *fullpath, bool is_pakfile) -{ - pakfile_path_t pakfile_path; - pakfile_path.fullpath = fullpath; - pakfile_path.is_pakfile = is_pakfile; - g_pakfile_paths.insert(PakfilePathsKV(name, pakfile_path)); -} - -// takes name without ext, returns without ext -static const char *GetLatestDpkPakVersion(const char *name) -{ - const char *maxversion = 0; - const char *result = 0; - const char *pakname; - const char *pakversion; - int namelen = string_length(name); - - for (PakfilePaths::iterator i = g_pakfile_paths.begin(); i != g_pakfile_paths.end(); ++i) { - pakname = i->first.c_str(); - if (strncmp(pakname, name, namelen) != 0 || pakname[namelen] != '_') { continue; } - pakversion = pakname + (namelen + 1); - if (maxversion == 0 || DpkPakVersionCmp(pakversion, maxversion) > 0) { - maxversion = pakversion; - result = pakname; - } - } - return result; -} - -// release string after using -static char *GetCurrentMapDpkPakName() -{ - char *mapdir; - char *mapname; - int mapnamelen; - char *result = 0; - - mapname = string_clone(GlobalRadiant().getMapName()); - mapnamelen = string_length(mapname); - - mapdir = strrchr(mapname, '/'); - if (mapdir) { - mapdir -= 12; - if (strncmp(mapdir, ".dpkdir/maps/", 13) == 0) { - *mapdir = '\0'; - mapdir = strrchr(mapname, '/'); - if (mapdir) { mapdir++; } - else { mapdir = mapname; } - result = string_clone(mapdir); - } - } - - string_release(mapname, mapnamelen); - return result; - -} - -// prevent loading duplicates or circular references -static Archives g_loaded_dpk_paks; - -// actual pak adding on initialise, deferred from InitDirectory -// Daemon DPK filesystem doesn't need load all paks it finds -static void LoadDpkPakWithDeps(const char *pakname) -{ - Archive *arc; - ArchiveTextFile *depsFile; - - if (pakname == NULL) { - // load DEPS from game pack - StringOutputStream baseDirectory(256); - const char *basegame = GlobalRadiant().getRequiredGameDescriptionKeyValue("basegame"); - baseDirectory << GlobalRadiant().getGameToolsPath() << basegame << '/'; - arc = AddDpkDir(baseDirectory.c_str()); - depsFile = arc->openTextFile("DEPS"); - } else { - const char *und = strrchr(pakname, '_'); - if (!und) { - pakname = GetLatestDpkPakVersion(pakname); - } - if (!pakname || g_loaded_dpk_paks.find(pakname) != g_loaded_dpk_paks.end()) { - return; - } - - PakfilePaths::iterator i = g_pakfile_paths.find(pakname); - if (i == g_pakfile_paths.end()) { - return; - } - - if (i->second.is_pakfile) { - arc = InitPakFile(FileSystemQ3API_getArchiveModules(), i->second.fullpath.c_str()); - } else { - arc = AddDpkDir(i->second.fullpath.c_str()); - } - g_loaded_dpk_paks.insert(pakname); - - depsFile = arc->openTextFile("DEPS"); - } - - if (!depsFile) { - return; - } - - { - TextLinesInputStream istream = depsFile->getInputStream(); - - CopiedString line; - char *p_name; - char *p_version; - while (line = istream.readLine(), string_length(line.c_str())) { - if (!DpkReadDepsLine(line.c_str(), &p_name, &p_version)) { continue; } - if (!p_version) { - const char *p_latest = GetLatestDpkPakVersion(p_name); - if (p_latest) { LoadDpkPakWithDeps(p_latest); } - } else { - int len = string_length(p_name) + string_length(p_version) + 1; - char *p_pakname = string_new(len); - sprintf(p_pakname, "%s_%s", p_name, p_version); - LoadDpkPakWithDeps(p_pakname); - string_release(p_pakname, len); - } - string_release(p_name, string_length(p_name)); - if (p_version) { string_release(p_version, string_length(p_version)); } - } - } - - depsFile->release(); -} - -// end for Daemon DPK vfs - -// ============================================================================= -// Global functions - -// reads all pak files from a dir -void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ - int j; - - g_numForbiddenDirs = 0; - StringTokeniser st( GlobalRadiant().getGameDescriptionKeyValue( "forbidden_paths" ), " " ); - for ( j = 0; j < VFS_MAXDIRS; ++j ) - { - const char *t = st.getToken(); - if ( string_empty( t ) ) { - break; - } - strncpy( g_strForbiddenDirs[g_numForbiddenDirs], t, PATH_MAX ); - g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = '\0'; - ++g_numForbiddenDirs; - } - - for ( j = 0; j < g_numForbiddenDirs; ++j ) - { - char* dbuf = g_strdup( directory ); - if ( *dbuf && dbuf[strlen( dbuf ) - 1] == '/' ) { - dbuf[strlen( dbuf ) - 1] = 0; - } - const char *p = strrchr( dbuf, '/' ); - p = ( p ? ( p + 1 ) : dbuf ); - if ( matchpattern( p, g_strForbiddenDirs[j], TRUE ) ) { - g_free( dbuf ); - break; - } - g_free( dbuf ); - } - if ( j < g_numForbiddenDirs ) { - printf( "Directory %s matched by forbidden dirs, removed\n", directory ); - return; - } - - if ( g_numDirs == VFS_MAXDIRS ) { - return; - } - - strncpy( g_strDirs[g_numDirs], directory, PATH_MAX ); - g_strDirs[g_numDirs][PATH_MAX] = '\0'; - FixDOSName( g_strDirs[g_numDirs] ); - AddSlash( g_strDirs[g_numDirs] ); - - const char* path = g_strDirs[g_numDirs]; - - g_numDirs++; - - { - g_archives.push_back( archive_entry_t{ path, OpenArchive( path ), false } ); - } - - if ( g_bUsePak ) { - GDir* dir = g_dir_open( path, 0, 0 ); - - if ( dir != 0 ) { - globalOutputStream() << "vfs directory: " << path << "\n"; - - const char* ignore_prefix = ""; - const char* override_prefix = ""; - - { - // See if we are in "sp" or "mp" mapping mode - const char* gamemode = gamemode_get(); - - if ( strcmp( gamemode, "sp" ) == 0 ) { - ignore_prefix = "mp_"; - override_prefix = "sp_"; - } - else if ( strcmp( gamemode, "mp" ) == 0 ) { - ignore_prefix = "sp_"; - override_prefix = "mp_"; - } - } - - Archives archives; - Archives archivesOverride; - for (;; ) - { - const char* name = g_dir_read_name( dir ); - if ( name == 0 ) { - break; - } - - for ( j = 0; j < g_numForbiddenDirs; ++j ) - { - const char *p = strrchr( name, '/' ); - p = ( p ? ( p + 1 ) : name ); - if ( matchpattern( p, g_strForbiddenDirs[j], TRUE ) ) { - break; - } - } - if ( j < g_numForbiddenDirs ) { - continue; - } - - const char *ext = strrchr( name, '.' ); - - if ( ext && !string_compare_nocase_upper( ext, ".pk3dir" ) ) { - if ( g_numDirs == VFS_MAXDIRS ) { - continue; - } - snprintf( g_strDirs[g_numDirs], PATH_MAX, "%s%s/", path, name ); - g_strDirs[g_numDirs][PATH_MAX] = '\0'; - FixDOSName( g_strDirs[g_numDirs] ); - AddSlash( g_strDirs[g_numDirs] ); - g_numDirs++; - - { - g_archives.push_back( archive_entry_t{ g_strDirs[g_numDirs - 1], OpenArchive( g_strDirs[g_numDirs - 1] ), false } ); - } - } - - if ( ( ext == 0 ) || *( ++ext ) == '\0' || GetArchiveTable( archiveModules, ext ) == 0 ) { - continue; - } - - // using the same kludge as in engine to ensure consistency - if ( !string_empty( ignore_prefix ) && strncmp( name, ignore_prefix, strlen( ignore_prefix ) ) == 0 ) { - continue; - } - if ( !string_empty( override_prefix ) && strncmp( name, override_prefix, strlen( override_prefix ) ) == 0 ) { - archivesOverride.insert( name ); - continue; - } - - archives.insert( name ); - } - - g_dir_close( dir ); - - // add the entries to the vfs - for ( Archives::iterator i = archivesOverride.begin(); i != archivesOverride.end(); ++i ) - { - char filename[PATH_MAX]; - strcpy( filename, path ); - strcat( filename, ( *i ).c_str() ); - InitPakFile( archiveModules, filename ); - } - for ( Archives::iterator i = archives.begin(); i != archives.end(); ++i ) - { - char filename[PATH_MAX]; - strcpy( filename, path ); - strcat( filename, ( *i ).c_str() ); - InitPakFile( archiveModules, filename ); - } - } - else - { - globalErrorStream() << "vfs directory not found: " << path << "\n"; - } - } -} - -// frees all memory that we allocated -// FIXME TTimo this should be improved so that we can shutdown and restart the VFS without exiting Radiant? -// (for instance when modifying the project settings) -void Shutdown() -{ - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - (*i).archive->release(); - } - g_archives.clear(); - - g_numDirs = 0; - g_numForbiddenDirs = 0; - - g_pakfile_paths.clear(); - g_loaded_dpk_paks.clear(); -} - -const int VFS_SEARCH_PAK = 0x1; -const int VFS_SEARCH_DIR = 0x2; - -int GetFileCount(const char *filename, int flag) -{ - int count = 0; - char fixed[PATH_MAX + 1]; - - strncpy(fixed, filename, PATH_MAX); - fixed[PATH_MAX] = '\0'; - FixDOSName(fixed); - - if (!flag) { - flag = VFS_SEARCH_PAK | VFS_SEARCH_DIR; - } - - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if (((*i).is_pakfile && (flag & VFS_SEARCH_PAK) != 0) - || (!(*i).is_pakfile && (flag & VFS_SEARCH_DIR) != 0)) { - if ((*i).archive->containsFile(fixed)) { - ++count; - } - } - } - - return count; -} - -ArchiveFile *OpenFile(const char *filename) -{ - ASSERT_MESSAGE(strchr(filename, '\\') == 0, "path contains invalid separator '\\': \"" << filename << "\""); - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - ArchiveFile *file = (*i).archive->openFile(filename); - if (file != 0) { - return file; - } - } - - return 0; -} - -ArchiveTextFile *OpenTextFile(const char *filename) -{ - ASSERT_MESSAGE(strchr(filename, '\\') == 0, "path contains invalid separator '\\': \"" << filename << "\""); - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - ArchiveTextFile *file = (*i).archive->openTextFile(filename); - if (file != 0) { - return file; - } - } - - return 0; -} - -// NOTE: when loading a file, you have to allocate one extra byte and set it to \0 -std::size_t LoadFile(const char *filename, void **bufferptr, int index) -{ - char fixed[PATH_MAX + 1]; - - strncpy(fixed, filename, PATH_MAX); - fixed[PATH_MAX] = '\0'; - FixDOSName(fixed); - - ArchiveFile *file = OpenFile(fixed); - - if (file != 0) { - *bufferptr = malloc(file->size() + 1); - // we need to end the buffer with a 0 - ((char *) (*bufferptr))[file->size()] = 0; - - std::size_t length = file->getInputStream().read((InputStream::byte_type *) *bufferptr, file->size()); - file->release(); - return length; - } - - *bufferptr = 0; - return 0; -} - -void FreeFile(void *p) -{ - free(p); -} - -GSList *GetFileList(const char *dir, const char *ext, std::size_t depth) -{ - return GetListInternal(dir, ext, false, depth); -} - -GSList *GetDirList(const char *dir, std::size_t depth) -{ - return GetListInternal(dir, 0, true, depth); -} - -void ClearFileDirList(GSList **lst) -{ - while (*lst) { - g_free((*lst)->data); - *lst = g_slist_remove(*lst, (*lst)->data); - } -} - -const char *FindFile(const char *relative) -{ - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if ((*i).archive->containsFile(relative)) { - return (*i).name.c_str(); - } - } - - return ""; -} - -const char *FindPath(const char *absolute) -{ - const char *best = ""; - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if (string_length((*i).name.c_str()) > string_length(best)) { - if (path_equal_n(absolute, (*i).name.c_str(), string_length((*i).name.c_str()))) { - best = (*i).name.c_str(); - } - } - } - - return best; -} - - -class Quake3FileSystem : public VirtualFileSystem { -public: -void initDirectory(const char *path) -{ - InitDirectory(path, FileSystemQ3API_getArchiveModules()); -} - -void initialise() -{ - load(); - globalOutputStream() << "filesystem initialised\n"; - g_observers.realise(); -} - -void load() -{ - ArchiveModules &archiveModules = FileSystemQ3API_getArchiveModules(); - bool is_dpk_vfs = 1; - - if (is_dpk_vfs) { - const char *pakname; - g_loaded_dpk_paks.clear(); - - // Load DEPS from game pack - LoadDpkPakWithDeps(NULL); - - // prevent VFS double start, for MapName="" and MapName="unnamed.map" - if (string_length(GlobalRadiant().getMapName())) { - // load map's paks from DEPS - char *mappakname = GetCurrentMapDpkPakName(); - if (mappakname != NULL) { - LoadDpkPakWithDeps(mappakname); - string_release(mappakname, string_length(mappakname)); - } - } - - g_pakfile_paths.clear(); - g_loaded_dpk_paks.clear(); - } -} - -void clear() -{ - // like shutdown() but does not unrealise (keep map etc.) - Shutdown(); -} - -void refresh() -{ - // like initialise() but does not realise (keep map etc.) - load(); - globalOutputStream() << "filesystem refreshed\n"; -} - -void shutdown() -{ - g_observers.unrealise(); - globalOutputStream() << "filesystem shutdown\n"; - Shutdown(); -} - -int getFileCount(const char *filename, int flags) -{ - return GetFileCount(filename, flags); -} - -ArchiveFile *openFile(const char *filename) -{ - return OpenFile(filename); -} - -ArchiveTextFile *openTextFile(const char *filename) -{ - return OpenTextFile(filename); -} - -std::size_t loadFile(const char *filename, void **buffer) -{ - return LoadFile(filename, buffer, 0); -} - -void freeFile(void *p) -{ - FreeFile(p); -} - -void forEachDirectory(const char *basedir, const FileNameCallback &callback, std::size_t depth) -{ - GSList *list = GetDirList(basedir, depth); - - for (GSList *i = list; i != 0; i = g_slist_next(i)) { - callback(reinterpret_cast((*i).data )); - } - - ClearFileDirList(&list); -} - -void forEachFile(const char *basedir, const char *extension, const FileNameCallback &callback, std::size_t depth) -{ - GSList *list = GetFileList(basedir, extension, depth); - - for (GSList *i = list; i != 0; i = g_slist_next(i)) { - const char *name = reinterpret_cast((*i).data ); - if (extension_equal(path_get_extension(name), extension)) { - callback(name); - } - } - - ClearFileDirList(&list); -} - -GSList *getDirList(const char *basedir) -{ - return GetDirList(basedir, 1); -} - -GSList *getFileList(const char *basedir, const char *extension) -{ - return GetFileList(basedir, extension, 1); -} - -void clearFileDirList(GSList **lst) -{ - ClearFileDirList(lst); -} - -const char *findFile(const char *name) -{ - return FindFile(name); -} - -const char *findRoot(const char *name) -{ - return FindPath(name); -} - -void attach(ModuleObserver &observer) -{ - g_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - g_observers.detach(observer); -} - -Archive *getArchive(const char *archiveName, bool pakonly) -{ - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if (pakonly && !(*i).is_pakfile) { - continue; - } - if (path_equal((*i).name.c_str(), archiveName)) { - return (*i).archive; - } - } - return 0; -} - -void forEachArchive(const ArchiveNameCallback &callback, bool pakonly, bool reverse) -{ - if (reverse) { - g_archives.reverse(); - } - - for (archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i) { - if (pakonly && !(*i).is_pakfile) { - continue; - } - - callback((*i).name.c_str()); - } - - if (reverse) { - g_archives.reverse(); - } -} -}; - - -Quake3FileSystem g_Quake3FileSystem; - -VirtualFileSystem &GetFileSystem() -{ - return g_Quake3FileSystem; -} - -void FileSystem_Init() -{ -} - -void FileSystem_Shutdown() -{ -} diff --git a/plugins/vfspk3/vfs.h b/plugins/vfspk3/vfs.h deleted file mode 100644 index 277c7b3..0000000 --- a/plugins/vfspk3/vfs.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_VFS_H ) -#define INCLUDED_VFS_H - -void FileSystem_Init(); - -void FileSystem_Shutdown(); - -class VirtualFileSystem; - -VirtualFileSystem &GetFileSystem(); - -#endif diff --git a/plugins/vfspk3/vfspk3.cpp b/plugins/vfspk3/vfspk3.cpp deleted file mode 100644 index 3ff2a12..0000000 --- a/plugins/vfspk3/vfspk3.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "qerplugin.h" -#include "iarchive.h" -#include "ifilesystem.h" - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/modulesmap.h" - -#include "vfs.h" - -class FileSystemDependencies : public GlobalRadiantModuleRef { -ArchiveModulesRef m_archive_modules; -public: -FileSystemDependencies() : - m_archive_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("archivetypes")) -{ -} - -ArchiveModules &getArchiveModules() -{ - return m_archive_modules.get(); -} -}; - -class FileSystemQ3API { -VirtualFileSystem *m_filesystemq3; -public: -typedef VirtualFileSystem Type; - -STRING_CONSTANT(Name, "*"); - -FileSystemQ3API() -{ - FileSystem_Init(); - m_filesystemq3 = &GetFileSystem(); -} - -~FileSystemQ3API() -{ - FileSystem_Shutdown(); -} - -VirtualFileSystem *getTable() -{ - return m_filesystemq3; -} -}; - -typedef SingletonModule FileSystemQ3Module; - -FileSystemQ3Module g_FileSystemQ3Module; - -ArchiveModules &FileSystemQ3API_getArchiveModules() -{ - return g_FileSystemQ3Module.getDependencies().getArchiveModules(); -} - - -extern "C" void -#ifdef _WIN32 -__declspec(dllexport) -#else -__attribute__((visibility("default"))) -#endif -Radiant_RegisterModules(ModuleServer &server) -{ - initialiseModule(server); - - g_FileSystemQ3Module.selfRegister(); -} diff --git a/resources/Makefile b/resources/Makefile deleted file mode 100644 index 3a0821e..0000000 --- a/resources/Makefile +++ /dev/null @@ -1,119 +0,0 @@ -all: - mkdir -p ../build/bitmaps - mkdir -p ../build/games - mkdir -p ../build/gl - mkdir -p ../build/platform.game - mkdir -p ../build/goldsrc.game - cp -vf ./defaultkeys.ini ../build/defaultkeys.ini - cp -vf ./platform.game/default_build_menu.xml ../build/platform.game/default_build_menu.xml - cp -vf ./goldsrc.game/default_build_menu.xml ../build/goldsrc.game/default_build_menu.xml - cp -vf ./games/platform.game ../build/games/platform.game - cp -vf ./games/goldsrc.game ../build/games/goldsrc.game - cp -vf ./gl/lighting_DBS_omni_fp.glp ../build/gl/lighting_DBS_omni_fp.glp - cp -vf ./gl/lighting_DBS_omni_fp.glsl ../build/gl/lighting_DBS_omni_fp.glsl - cp -vf ./gl/lighting_DBS_omni_vp.glp ../build/gl/lighting_DBS_omni_vp.glp - cp -vf ./gl/lighting_DBS_omni_vp.glsl ../build/gl/lighting_DBS_omni_vp.glsl - cp -vf ./gl/lighting_DBS_XY_Z_arbfp1.cg ../build/gl/lighting_DBS_XY_Z_arbfp1.cg - cp -vf ./gl/lighting_DBS_XY_Z_arbvp1.cg ../build/gl/lighting_DBS_XY_Z_arbvp1.cg - cp -vf ./gl/utils.cg ../build/gl/utils.cg - cp -vf ./gl/zfill_arbfp1.cg ../build/gl/zfill_arbfp1.cg - cp -vf ./gl/zfill_arbvp1.cg ../build/gl/zfill_arbvp1.cg - cp -vf ./gl/zfill_fp.glp ../build/gl/zfill_fp.glp - cp -vf ./gl/zfill_fp.glsl ../build/gl/zfill_fp.glsl - cp -vf ./gl/zfill_vp.glp ../build/gl/zfill_vp.glp - cp -vf ./gl/zfill_vp.glsl ../build/gl/zfill_vp.glsl - cp -vf ./bitmaps/black.xpm ../build/bitmaps/black.xpm - cp -vf ./bitmaps/brush_flipx.xpm ../build/bitmaps/brush_flipx.xpm - cp -vf ./bitmaps/brush_flipy.xpm ../build/bitmaps/brush_flipy.xpm - cp -vf ./bitmaps/brush_flipz.xpm ../build/bitmaps/brush_flipz.xpm - cp -vf ./bitmaps/brush_rotatex.xpm ../build/bitmaps/brush_rotatex.xpm - cp -vf ./bitmaps/brush_rotatey.xpm ../build/bitmaps/brush_rotatey.xpm - cp -vf ./bitmaps/brush_rotatez.xpm ../build/bitmaps/brush_rotatez.xpm - cp -vf ./bitmaps/cap_bevel.xpm ../build/bitmaps/cap_bevel.xpm - cp -vf ./bitmaps/cap_curve.xpm ../build/bitmaps/cap_curve.xpm - cp -vf ./bitmaps/cap_cylinder.xpm ../build/bitmaps/cap_cylinder.xpm - cp -vf ./bitmaps/cap_endcap.xpm ../build/bitmaps/cap_endcap.xpm - cp -vf ./bitmaps/cap_ibevel.xpm ../build/bitmaps/cap_ibevel.xpm - cp -vf ./bitmaps/cap_iendcap.xpm ../build/bitmaps/cap_iendcap.xpm - cp -vf ./bitmaps/console.xpm ../build/bitmaps/console.xpm - cp -vf ./bitmaps/copy.xpm ../build/bitmaps/copy.xpm - cp -vf ./bitmaps/cut.xpm ../build/bitmaps/cut.xpm - cp -vf ./bitmaps/dontselectcurve.xpm ../build/bitmaps/dontselectcurve.xpm - cp -vf ./bitmaps/dontselectmodel.xpm ../build/bitmaps/dontselectmodel.xpm - cp -vf ./bitmaps/ellipsis.xpm ../build/bitmaps/ellipsis.xpm - cp -vf ./bitmaps/entities.xpm ../build/bitmaps/entities.xpm - cp -vf ./bitmaps/file_new.xpm ../build/bitmaps/file_new.xpm - cp -vf ./bitmaps/file_open.xpm ../build/bitmaps/file_open.xpm - cp -vf ./bitmaps/file_save.xpm ../build/bitmaps/file_save.xpm - cp -vf ./bitmaps/icon.xpm ../build/bitmaps/icon.xpm - cp -vf ./bitmaps/lightinspector.xpm ../build/bitmaps/lightinspector.xpm - cp -vf ./bitmaps/logo.xpm ../build/bitmaps/logo.xpm - cp -vf ./bitmaps/modify_edges.xpm ../build/bitmaps/modify_edges.xpm - cp -vf ./bitmaps/modify_faces.xpm ../build/bitmaps/modify_faces.xpm - cp -vf ./bitmaps/modify_vertices.xpm ../build/bitmaps/modify_vertices.xpm - cp -vf ./bitmaps/noFalloff.xpm ../build/bitmaps/noFalloff.xpm - cp -vf ./bitmaps/notex.tga ../build/bitmaps/notex.tga - cp -vf ./bitmaps/paste.xpm ../build/bitmaps/paste.xpm - cp -vf ./bitmaps/patch_bend.xpm ../build/bitmaps/patch_bend.xpm - cp -vf ./bitmaps/patch_drilldown.xpm ../build/bitmaps/patch_drilldown.xpm - cp -vf ./bitmaps/patch_insdel.xpm ../build/bitmaps/patch_insdel.xpm - cp -vf ./bitmaps/patch_showboundingbox.xpm ../build/bitmaps/patch_showboundingbox.xpm - cp -vf ./bitmaps/patch_weld.xpm ../build/bitmaps/patch_weld.xpm - cp -vf ./bitmaps/patch_wireframe.xpm ../build/bitmaps/patch_wireframe.xpm - cp -vf ./bitmaps/popup_selection.xpm ../build/bitmaps/popup_selection.xpm - cp -vf ./bitmaps/redo.xpm ../build/bitmaps/redo.xpm - cp -vf ./bitmaps/refresh_models.xpm ../build/bitmaps/refresh_models.xpm - cp -vf ./bitmaps/scalelockx.xpm ../build/bitmaps/scalelockx.xpm - cp -vf ./bitmaps/scalelocky.xpm ../build/bitmaps/scalelocky.xpm - cp -vf ./bitmaps/scalelockz.xpm ../build/bitmaps/scalelockz.xpm - cp -vf ./bitmaps/select_additive.xpm ../build/bitmaps/select_additive.xpm - cp -vf ./bitmaps/select_autoexpand.xpm ../build/bitmaps/select_autoexpand.xpm - cp -vf ./bitmaps/selection_csgmerge.xpm ../build/bitmaps/selection_csgmerge.xpm - cp -vf ./bitmaps/selection_csgsubtract.xpm ../build/bitmaps/selection_csgsubtract.xpm - cp -vf ./bitmaps/selection_makehollow.xpm ../build/bitmaps/selection_makehollow.xpm - cp -vf ./bitmaps/selection_makeroom.xpm ../build/bitmaps/selection_makeroom.xpm - cp -vf ./bitmaps/selection_selectcompletetall.xpm ../build/bitmaps/selection_selectcompletetall.xpm - cp -vf ./bitmaps/selection_selectinside.xpm ../build/bitmaps/selection_selectinside.xpm - cp -vf ./bitmaps/selection_selectpartialtall.xpm ../build/bitmaps/selection_selectpartialtall.xpm - cp -vf ./bitmaps/selection_selecttouching.xpm ../build/bitmaps/selection_selecttouching.xpm - cp -vf ./bitmaps/select_mouseresize.xpm ../build/bitmaps/select_mouseresize.xpm - cp -vf ./bitmaps/select_mouserotate.xpm ../build/bitmaps/select_mouserotate.xpm - cp -vf ./bitmaps/select_mousescale.xpm ../build/bitmaps/select_mousescale.xpm - cp -vf ./bitmaps/select_mousetranslate.xpm ../build/bitmaps/select_mousetranslate.xpm - cp -vf ./bitmaps/shadernotex.tga ../build/bitmaps/shadernotex.tga - cp -vf ./bitmaps/show_entities.xpm ../build/bitmaps/show_entities.xpm - cp -vf ./bitmaps/side_brush.png ../build/bitmaps/side_brush.png - cp -vf ./bitmaps/side_cut.png ../build/bitmaps/side_cut.png - cp -vf ./bitmaps/side_edges.xpm ../build/bitmaps/side_edges.xpm - cp -vf ./bitmaps/side_entities.png ../build/bitmaps/side_entities.png - cp -vf ./bitmaps/side_entspec.png ../build/bitmaps/side_entspec.png - cp -vf ./bitmaps/side_faces.xpm ../build/bitmaps/side_faces.xpm - cp -vf ./bitmaps/side_move.png ../build/bitmaps/side_move.png - cp -vf ./bitmaps/side_patch.png ../build/bitmaps/side_patch.png - cp -vf ./bitmaps/side_patchspec.png ../build/bitmaps/side_patchspec.png - cp -vf ./bitmaps/side_rotate.png ../build/bitmaps/side_rotate.png - cp -vf ./bitmaps/side_scale.png ../build/bitmaps/side_scale.png - cp -vf ./bitmaps/side_select.png ../build/bitmaps/side_select.png - cp -vf ./bitmaps/side_surfspec.png ../build/bitmaps/side_surfspec.png - cp -vf ./bitmaps/side_tex.png ../build/bitmaps/side_tex.png - cp -vf ./bitmaps/side_vertices.xpm ../build/bitmaps/side_vertices.xpm - cp -vf ./bitmaps/side_selectface.png ../build/bitmaps/side_selectface.png - cp -vf ./bitmaps/side_selectwhole.png ../build/bitmaps/side_selectwhole.png - cp -vf ./bitmaps/side_resize.png ../build/bitmaps/side_resize.png - cp -vf ./bitmaps/splash.xcf ../build/bitmaps/splash.xcf - cp -vf ./bitmaps/splash.xpm ../build/bitmaps/splash.xpm - cp -vf ./bitmaps/texture_browser.xpm ../build/bitmaps/texture_browser.xpm - cp -vf ./bitmaps/texture_lock.xpm ../build/bitmaps/texture_lock.xpm - cp -vf ./bitmaps/textures_popup.xpm ../build/bitmaps/textures_popup.xpm - cp -vf ./bitmaps/undo.xpm ../build/bitmaps/undo.xpm - cp -vf ./bitmaps/view_cameratoggle.xpm ../build/bitmaps/view_cameratoggle.xpm - cp -vf ./bitmaps/view_cameraupdate.xpm ../build/bitmaps/view_cameraupdate.xpm - cp -vf ./bitmaps/view_change.xpm ../build/bitmaps/view_change.xpm - cp -vf ./bitmaps/view_clipper.xpm ../build/bitmaps/view_clipper.xpm - cp -vf ./bitmaps/view_cubicclipping.xpm ../build/bitmaps/view_cubicclipping.xpm - cp -vf ./bitmaps/view_entity.xpm ../build/bitmaps/view_entity.xpm - cp -vf ./bitmaps/white.xpm ../build/bitmaps/white.xpm - cp -vf ./bitmaps/window1.xpm ../build/bitmaps/window1.xpm - cp -vf ./bitmaps/window2.xpm ../build/bitmaps/window2.xpm - cp -vf ./bitmaps/window3.xpm ../build/bitmaps/window3.xpm - cp -vf ./bitmaps/window4.xpm ../build/bitmaps/window4.xpm \ No newline at end of file diff --git a/resources/bitmaps/black.xpm b/resources/bitmaps/black.xpm deleted file mode 100644 index add2bbc..0000000 --- a/resources/bitmaps/black.xpm +++ /dev/null @@ -1,16 +0,0 @@ -/* XPM */ -static char *black[] = { -/* columns rows colors chars-per-pixel */ -"8 8 2 1 ", -" c black", -". c white", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/brush_flipx.xpm b/resources/bitmaps/brush_flipx.xpm deleted file mode 100644 index 859c5c2..0000000 --- a/resources/bitmaps/brush_flipx.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * brush_flipx_xpm[] = { -"16 16 26 1", -" c None", -". c #C9E5F9", -"+ c #CAE3FB", -"@ c #CAE2FF", -"# c #47E0FF", -"$ c #CAE1FF", -"% c #45DEFF", -"& c #46DEFF", -"* c #C9DEFF", -"= c #44DCFF", -"- c #C9DBFF", -"; c #43DBFF", -"> c #43DAFF", -", c #C9D9FF", -"' c #42D9FF", -") c #41D6FF", -"! c #40D7FF", -"~ c #C8D6FF", -"{ c #41D7FF", -"] c #3FD4FF", -"^ c #C8D4FF", -"/ c #3ED5FF", -"( c #3FD5FF", -"_ c #C7D1FF", -": c #C7D0FF", -"< c #C7CDFF", -" ", -" ", -" . ", -" + ", -" @ ", -" # # $ # # ", -" % & * % % ", -" = - ; ", -" > , ' ", -" ) ! ~ { ! ", -" ] ] ^ / ( ", -" _ ", -" : ", -" < ", -" ", -" "}; diff --git a/resources/bitmaps/brush_flipy.xpm b/resources/bitmaps/brush_flipy.xpm deleted file mode 100644 index 4554a8e..0000000 --- a/resources/bitmaps/brush_flipy.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char * brush_flipy_xpm[] = { -"16 16 29 1", -" c None", -". c #44FFF9", -"+ c #46FFFB", -"@ c #48FFFF", -"# c #47E0FF", -"$ c #47FFFF", -"% c #45DEFF", -"& c #46DEFF", -"* c #45FFFF", -"= c #46DDFF", -"- c #43DBFF", -"; c #43FFFF", -"> c #44DBFF", -", c #42D9FF", -"' c #42FFFF", -") c #43D9FF", -"! c #42DAFF", -"~ c #40D7FF", -"{ c #40FFFF", -"] c #41D7FF", -"^ c #3FD4FF", -"/ c #3EFFFF", -"( c #3DD2FF", -"_ c #3DFFFF", -": c #3BCFFF", -"< c #3CFFFF", -"[ c #3BD0FF", -"} c #39CDFF", -"| c #39FFFF", -" ", -" ", -" . ", -" + ", -" @ ", -" # # $ # # ", -" % & * % = ", -" - - ; > > ", -" , , ' ) ! ", -" ~ { ] ", -" ^ / ^ ", -" ( _ ( ", -" : < [ ", -" } | } ", -" ", -" "}; diff --git a/resources/bitmaps/brush_flipz.xpm b/resources/bitmaps/brush_flipz.xpm deleted file mode 100644 index 5e1c704..0000000 --- a/resources/bitmaps/brush_flipz.xpm +++ /dev/null @@ -1,42 +0,0 @@ -/* XPM */ -static char * brush_flipz_xpm[] = { -"16 16 23 1", -" c None", -". c #44E5FF", -"+ c #46E3FF", -"@ c #48E2FF", -"# c #47E0FF", -"$ c #47E1FF", -"% c #46DEFF", -"& c #45DEFF", -"* c #43DBFF", -"= c #44DBFF", -"- c #43DAFF", -"; c #42D9FF", -"> c #41D6FF", -", c #40D6FF", -"' c #40D7FF", -") c #3FD4FF", -"! c #3ED4FF", -"~ c #3FD5FF", -"{ c #3DD2FF", -"] c #3CD2FF", -"^ c #3DD1FF", -"/ c #3CD0FF", -"( c #39CDFF", -" ", -" ", -" . ", -" + ", -" @ ", -" #$### $ #$### ", -" % & & ", -" * * = ", -" - ; ; ", -" > , ' ", -" ) ! ~ ", -" {{{]{ ^ {{{^{ ", -" / ", -" ( ", -" ", -" "}; diff --git a/resources/bitmaps/brush_rotatex.xpm b/resources/bitmaps/brush_rotatex.xpm deleted file mode 100644 index f7b078a..0000000 --- a/resources/bitmaps/brush_rotatex.xpm +++ /dev/null @@ -1,49 +0,0 @@ -/* XPM */ -static char * brush_rotatex_xpm[] = { -"16 16 30 1", -" c None", -". c #C8E5F6", -"+ c #C9E5F5", -"@ c #C9E5F6", -"# c #C9E4F8", -"$ c #C9E5F9", -"% c #C9E4F9", -"& c #C9E3FC", -"* c #CAE3FF", -"= c #CAE0FF", -"- c #46DEFF", -"; c #45DEFF", -"> c #C9DEFF", -", c #43DBFF", -"' c #44DBFF", -") c #C9DBFF", -"! c #42D9FF", -"~ c #C9DAFF", -"{ c #40D6FF", -"] c #C8D7FF", -"^ c #3FD4FF", -"/ c #3ED5FF", -"( c #C8D5FF", -"_ c #3DD2FF", -": c #3DD1FF", -"< c #C7D2FF", -"[ c #C7D0FF", -"} c #C7CFFF", -"| c #C7CDFF", -"1 c #C6CAFF", -" ", -" ...+@ ", -" #$% ", -" & ", -" * ", -" = ", -" - ; > ", -" , ' ) ", -" ! ~ ", -" { ] ", -" ^ / ( ", -" _ : < ", -" [[}}}", -" ||| ", -" 1 ", -" "}; diff --git a/resources/bitmaps/brush_rotatey.xpm b/resources/bitmaps/brush_rotatey.xpm deleted file mode 100644 index 90eee14..0000000 --- a/resources/bitmaps/brush_rotatey.xpm +++ /dev/null @@ -1,51 +0,0 @@ -/* XPM */ -static char * brush_rotatey_xpm[] = { -"16 16 32 1", -" c None", -". c #41FFF6", -"+ c #42FFF5", -"@ c #42FFF6", -"# c #43FFF8", -"$ c #44FFF9", -"% c #43FFF9", -"& c #45FFFC", -"* c #48FFFF", -"= c #47FFFF", -"- c #46DEFF", -"; c #45DEFF", -"> c #45FFFF", -", c #44DCFF", -"' c #43DBFF", -") c #44FFFF", -"! c #42D9FF", -"~ c #42FFFF", -"{ c #40D7FF", -"] c #40FFFF", -"^ c #3FD4FF", -"/ c #3FFFFF", -"( c #3DD2FF", -"_ c #3DFFFF", -": c #3BCFFF", -"< c #3BFFFF", -"[ c #3CFFFF", -"} c #3ACDFF", -"| c #3AFFFF", -"1 c #39FFFF", -"2 c #38CAFF", -"3 c #38FFFF", -" ", -" ...+@ ", -" #$% ", -" & ", -" * ", -" = ", -" - ; > ", -" , ' ) ", -" ! ! ~ ", -" { { ] ", -" ^ / ", -" ( _ ", -" : <[<[<", -" } |1| ", -" 2 3 ", -" "}; diff --git a/resources/bitmaps/brush_rotatez.xpm b/resources/bitmaps/brush_rotatez.xpm deleted file mode 100644 index b33c7df..0000000 --- a/resources/bitmaps/brush_rotatez.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * brush_rotatez_xpm[] = { -"16 16 26 1", -" c None", -". c #41E5FF", -"+ c #42E5FF", -"@ c #43E4FF", -"# c #44E5FF", -"$ c #45E3FF", -"% c #48E3FF", -"& c #47E0FF", -"* c #46DEFF", -"= c #45DEFF", -"- c #43DBFF", -"; c #44DBFF", -"> c #42D9FF", -", c #42DAFF", -"' c #40D6FF", -") c #40D7FF", -"! c #3FD4FF", -"~ c #3FD5FF", -"{ c #3DD2FF", -"] c #3BCFFF", -"^ c #3CD0FF", -"/ c #3BD0FF", -"( c #3CCFFF", -"_ c #3ACDFF", -": c #39CDFF", -"< c #38CAFF", -" ", -" ...++ ", -" @#@ ", -" $ ", -" % ", -" & ", -" ***== = ", -" - ; ", -" > , ", -" ' ) ", -" ! ~ ", -" { { ", -" ]]]]^ /^](]", -" _:_ ", -" < ", -" "}; diff --git a/resources/bitmaps/cap_bevel.xpm b/resources/bitmaps/cap_bevel.xpm deleted file mode 100644 index ec79202..0000000 --- a/resources/bitmaps/cap_bevel.xpm +++ /dev/null @@ -1,95 +0,0 @@ -/* XPM */ -static char * cap_bevel_xpm[] = { -"24 24 68 1", -" c None", -". c #3FE6F3", -"+ c #40E6F4", -"@ c #3FE5F3", -"# c #41E5F6", -"$ c #42E5F6", -"% c #BEE480", -"& c #BDE480", -"* c #43E4F8", -"= c #44E5F9", -"- c #BCE380", -"; c #BBE380", -"> c #46E3FC", -", c #B9E380", -"' c #B9E280", -") c #BAE280", -"! c #48E2FE", -"~ c #B7E280", -"{ c #B7E180", -"] c #47E0FF", -"^ c #B8DF80", -"/ c #B8E080", -"( c #45DEFF", -"_ c #B9DD80", -": c #BADD80", -"< c #B9DC80", -"[ c #BADC80", -"} c #43DBFF", -"| c #BBDB80", -"1 c #BCDA80", -"2 c #BBDA80", -"3 c #BCDB80", -"4 c #42D9FF", -"5 c #BDD880", -"6 c #BCD980", -"7 c #BDD980", -"8 c #BCD880", -"9 c #41D6FF", -"0 c #BED580", -"a c #BFD680", -"b c #BFD580", -"c c #BED680", -"d c #3FD4FF", -"e c #C0D380", -"f c #C1D480", -"g c #C1D380", -"h c #C0D480", -"i c #3DD2FF", -"j c #C2D180", -"k c #C3D180", -"l c #C2D080", -"m c #3CCFFF", -"n c #C4CE80", -"o c #C3CF80", -"p c #C4CF80", -"q c #C3CE80", -"r c #3ACDFF", -"s c #C6CC80", -"t c #C5CC80", -"u c #37CBFF", -"v c #C8C980", -"w c #C7C980", -"x c #C7CA80", -"y c #36C8FF", -"z c #CAC780", -"A c #CAC680", -"B c #C9C780", -"C c #C9C680", -" ", -" ", -" ", -" ", -" .+..@ ", -" #$#%%&%% ", -" *=---;;-;- ", -" >,''),,'''' ", -" !~{{{~~~~{{{ ", -" ]^^^/^^/^^^^^ ", -" (___::_::::<[[ ", -" }|112122212213 ", -" 456555557857576 ", -" 90aababacccaaaa ", -" deeeefgffheehgg ", -" ijjjkjjlljjjljlj ", -" mnnnnnnopppponqn ", -" rsssstssstsststt ", -" uvwvvwwvwxwwvwwx ", -" yzABBBCBBzBBBzCC ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/cap_curve.xpm b/resources/bitmaps/cap_curve.xpm deleted file mode 100644 index 1e298a8..0000000 --- a/resources/bitmaps/cap_curve.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char * cap_curve_xpm[] = { -"16 16 25 1", -" c None", -". c #48E2FE", -"+ c #48E2FF", -"@ c #48E3FE", -"# c #47E0FF", -"$ c #B8DF80", -"% c #B8E080", -"& c #47E1FF", -"* c #46DEFF", -"= c #B9DD80", -"- c #BADD80", -"; c #45DEFF", -"> c #43DBFF", -", c #BCDA80", -"' c #BBDA80", -") c #44DBFF", -"! c #42D9FF", -"~ c #42DAFF", -"{ c #40D7FF", -"] c #41D7FF", -"^ c #3FD4FF", -"/ c #3FD5FF", -"( c #3ED5FF", -"_ c #3DD2FF", -": c #3DD1FF", -" ", -" .++..@ ", -" ##$%%$$$#& ", -" #$$$%%$$$$%& ", -" *==----==----; ", -" *==----==----; ", -" >>,'',,''''')> ", -" > >)',,''')) > ", -" ! !!!!!~ ! ", -" ! ! ", -" { ] ", -" { ] ", -" ^ / ", -" ^( (/ ", -" _::::_ ", -" "}; diff --git a/resources/bitmaps/cap_cylinder.xpm b/resources/bitmaps/cap_cylinder.xpm deleted file mode 100644 index 0f41c73..0000000 --- a/resources/bitmaps/cap_cylinder.xpm +++ /dev/null @@ -1,102 +0,0 @@ -/* XPM */ -static char * cap_cylinder_xpm[] = { -"24 24 75 1", -" c None", -". c #3FE6F3", -"+ c #40E6F3", -"@ c #41E5F6", -"# c #42E5F5", -"$ c #BDE480", -"% c #BEE480", -"& c #43E4F9", -"* c #BCE380", -"= c #BBE380", -"- c #BBE480", -"; c #43E4F8", -"> c #45E4FB", -", c #B9E280", -"' c #BAE280", -") c #B9E380", -"! c #46E3FB", -"~ c #48E2FE", -"{ c #B7E180", -"] c #B8E180", -"^ c #B7E280", -"/ c #48E2FF", -"( c #47E1FF", -"_ c #B8DF80", -": c #B8E080", -"< c #47E0FF", -"[ c #45DEFF", -"} c #BADD80", -"| c #B9DD80", -"1 c #B9DC80", -"2 c #BADC80", -"3 c #45DDFF", -"4 c #44DBFF", -"5 c #BCDA80", -"6 c #BBDB80", -"7 c #BBDA80", -"8 c #43DCFF", -"9 c #42D9FF", -"0 c #BDD880", -"a c #BCD980", -"b c #BDD980", -"c c #BCD880", -"d c #43DAFF", -"e c #40D7FF", -"f c #BED580", -"g c #BFD680", -"h c #BFD580", -"i c #BED680", -"j c #3FD4FF", -"k c #C0D380", -"l c #C1D480", -"m c #C1D380", -"n c #C0D480", -"o c #3ED4FF", -"p c #3DD2FF", -"q c #C2D180", -"r c #C3D180", -"s c #C2D080", -"t c #3DD1FF", -"u c #3BCFFF", -"v c #C4CE80", -"w c #C3CF80", -"x c #C4CF80", -"y c #3CCFFF", -"z c #39CDFF", -"A c #C6CC80", -"B c #C5CC80", -"C c #37CAFF", -"D c #C7C980", -"E c #C8C980", -"F c #C7CA80", -"G c #38CAFF", -"H c #36C8FF", -"I c #36C7FF", -"J c #35C8FF", -" ", -" ", -" ", -" ", -" ..++.+ ", -" @#$%%%$%@@ ", -" &*==*-***==; ", -" >,,',),,')),,! ", -" ~{]{^{{{^^^^{/ ", -" (_:____:__:____< ", -" [}}|||}}|}}}}123 ", -" 4556557577757758 ", -" 900a00000bc0b0bd ", -" effgghghgiiiggge ", -" jkkkkklmllnkknmo ", -" pqqrqqssqqqsqt ", -" uvvvvvwxxxxwvy ", -" zAABAAABAABz ", -" CCDDEDFDGC ", -" HIHHJH ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/cap_endcap.xpm b/resources/bitmaps/cap_endcap.xpm deleted file mode 100644 index 992d5ce..0000000 --- a/resources/bitmaps/cap_endcap.xpm +++ /dev/null @@ -1,105 +0,0 @@ -/* XPM */ -static char * cap_endcap_xpm[] = { -"24 24 78 1", -" c None", -". c #3FE6F3", -"+ c #40E6F3", -"@ c #41E5F6", -"# c #42E5F5", -"$ c #BDE480", -"% c #BEE480", -"& c #43E4F9", -"* c #BCE380", -"= c #BBE380", -"- c #BBE480", -"; c #43E4F8", -"> c #45E4FB", -", c #B9E280", -"' c #BAE280", -") c #B9E380", -"! c #46E3FB", -"~ c #48E2FE", -"{ c #B7E180", -"] c #B8E180", -"^ c #B7E280", -"/ c #48E2FF", -"( c #47E1FF", -"_ c #B8DF80", -": c #B8E080", -"< c #47E0FF", -"[ c #45DEFF", -"} c #BADD80", -"| c #B9DD80", -"1 c #B9DC80", -"2 c #BADC80", -"3 c #45DDFF", -"4 c #44DBFF", -"5 c #BCDA80", -"6 c #BBDB80", -"7 c #BBDA80", -"8 c #43DCFF", -"9 c #42D9FF", -"0 c #BDD880", -"a c #BCD980", -"b c #BDD980", -"c c #BCD880", -"d c #43DAFF", -"e c #40D7FF", -"f c #BED580", -"g c #BFD680", -"h c #BFD580", -"i c #BED680", -"j c #3FD4FF", -"k c #C0D380", -"l c #C1D480", -"m c #C1D380", -"n c #C0D480", -"o c #3ED4FF", -"p c #3DD2FF", -"q c #C2D180", -"r c #C3D180", -"s c #C2D080", -"t c #3CCFFF", -"u c #C4CE80", -"v c #C3CF80", -"w c #C4CF80", -"x c #C3CE80", -"y c #3BCFFF", -"z c #3ACDFF", -"A c #C6CC80", -"B c #C5CC80", -"C c #37CBFF", -"D c #C8C980", -"E c #C7C980", -"F c #C7CA80", -"G c #38CBFF", -"H c #36C8FF", -"I c #CAC780", -"J c #CAC680", -"K c #C9C780", -"L c #C9C680", -"M c #36C7FF", -" ", -" ", -" ", -" ", -" ..++.+ ", -" @#$%%%$%@@ ", -" &*==*-***==; ", -" >,,',),,')),,! ", -" ~{]{^{{{^^^^{/ ", -" (_:____:__:____< ", -" [}}|||}}|}}}}123 ", -" 4556557577757758 ", -" 900a00000bc0b0bd ", -" effgghghgiiiggge ", -" jkkkkklmllnkknmo ", -" pqqqrqqssqqqsqsp ", -" tuuuuuuvwwwwvuxy ", -" zAAAABAAABAABABz ", -" CDEDDEEDEFEEDEEG ", -" HIJKKKLKKIKKKILM ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/cap_ibevel.xpm b/resources/bitmaps/cap_ibevel.xpm deleted file mode 100644 index 444d7b5..0000000 --- a/resources/bitmaps/cap_ibevel.xpm +++ /dev/null @@ -1,93 +0,0 @@ -/* XPM */ -static char * cap_ibevel_xpm[] = { -"24 24 66 1", -" c None", -". c #C4E780", -"+ c #C5E780", -"@ c #C4E680", -"# c #C1E580", -"$ c #C2E580", -"% c #C2E680", -"& c #BFE580", -"* c #C0E480", -"= c #C0E580", -"- c #BEE480", -"; c #BDE480", -"> c #41E5F6", -", c #42E5F6", -"' c #BBE380", -") c #BCE380", -"! c #BBE480", -"~ c #43E4F9", -"{ c #44E4F9", -"] c #B9E280", -"^ c #BAE280", -"/ c #B9E380", -"( c #BAE380", -"_ c #46E3FB", -": c #B7E180", -"< c #B8E180", -"[ c #B7E280", -"} c #48E2FE", -"| c #B8E080", -"1 c #B8DF80", -"2 c #47E0FF", -"3 c #B9DC80", -"4 c #B9DD80", -"5 c #BADD80", -"6 c #46DEFF", -"7 c #BCDA80", -"8 c #BBDA80", -"9 c #44DCFF", -"0 c #BDD880", -"a c #43DAFF", -"b c #BFD680", -"c c #BED580", -"d c #41D6FF", -"e c #C0D380", -"f c #C0D480", -"g c #3FD4FF", -"h c #C2D180", -"i c #3DD2FF", -"j c #C4CF80", -"k c #C4CE80", -"l c #C3CE80", -"m c #3BCFFF", -"n c #C6CC80", -"o c #C5CC80", -"p c #39CDFF", -"q c #C7C980", -"r c #C8CA80", -"s c #37CAFF", -"t c #C9C780", -"u c #CAC780", -"v c #35C8FF", -"w c #CBC480", -"x c #CBC580", -"y c #34C5FF", -"z c #CDC280", -"A c #32C3FF", -" ", -" ", -" .+.@@@@@@@.....@@... ", -" #$%%%$%$$%%#%#$%#%## ", -" &*&&==*==&&=&=&==*=& ", -" ------;;---;-->,>>>> ", -" '')'))'')!)~~{ ", -" ]^/(]]^]/__ ", -" :::::<:[} ", -" |1|1|112 ", -" 3455546 ", -" 788779 ", -" 00000a ", -" bbbcd ", -" efeeg ", -" hhhhi ", -" jklm ", -" noop ", -" qqrs ", -" tutv ", -" wxwy ", -" zzzA ", -" ", -" "}; diff --git a/resources/bitmaps/cap_iendcap.xpm b/resources/bitmaps/cap_iendcap.xpm deleted file mode 100644 index 2545898..0000000 --- a/resources/bitmaps/cap_iendcap.xpm +++ /dev/null @@ -1,103 +0,0 @@ -/* XPM */ -static char * cap_iendcap_xpm[] = { -"24 24 76 1", -" c None", -". c #C4E780", -"+ c #C5E780", -"@ c #C4E680", -"# c #C1E580", -"$ c #C2E580", -"% c #C2E680", -"& c #BFE580", -"* c #C0E480", -"= c #C0E580", -"- c #BEE480", -"; c #BDE480", -"> c #BBE380", -", c #BCE380", -"' c #44E4F9", -") c #43E4F8", -"! c #44E5F9", -"~ c #43E4F9", -"{ c #B9E280", -"] c #BAE280", -"^ c #B9E380", -"/ c #BAE380", -"( c #46E3FB", -"_ c #45E3FC", -": c #46E4FC", -"< c #46E3FC", -"[ c #B7E180", -"} c #48E2FE", -"| c #B8E280", -"1 c #B8E080", -"2 c #B8DF80", -"3 c #47E0FF", -"4 c #B9DC80", -"5 c #B9DD80", -"6 c #BADD80", -"7 c #45DEFF", -"8 c #45DDFF", -"9 c #BADC80", -"0 c #BCDA80", -"a c #BBDA80", -"b c #44DBFF", -"c c #43DCFF", -"d c #BDD880", -"e c #42D9FF", -"f c #43DAFF", -"g c #BFD680", -"h c #40D7FF", -"i c #C0D380", -"j c #C0D480", -"k c #3FD4FF", -"l c #3ED4FF", -"m c #C1D380", -"n c #C2D180", -"o c #3DD2FF", -"p c #C4CF80", -"q c #C4CE80", -"r c #3CCFFF", -"s c #3BCFFF", -"t c #C3CF80", -"u c #C6CC80", -"v c #C5CC80", -"w c #3ACDFF", -"x c #C7C980", -"y c #37CBFF", -"z c #38CBFF", -"A c #C8C980", -"B c #C9C780", -"C c #CAC780", -"D c #36C8FF", -"E c #36C7FF", -"F c #CBC480", -"G c #CBC580", -"H c #34C5FF", -"I c #CDC280", -"J c #32C3FF", -"K c #CDC180", -" ", -" ", -" .+.@@@@@@@.....@@... ", -" #$%%%$%$$%%#%#$%#%## ", -" &*&&==*==&&=&=&==*=& ", -" ------;;---;---;---- ", -" >>,>,,>')!~~~>>,>,>> ", -" {]^/{(_ :<{{{{{ ", -" [[[[} }[[[| ", -" 1213 3212 ", -" 4567 8966 ", -" 0ab ca0 ", -" dde fdd ", -" ggh hgg ", -" ijk lmm ", -" nno onn ", -" pqr sqt ", -" uvw wuu ", -" xxy zAx ", -" BCD EBB ", -" FGH HFF ", -" IIJ JKI ", -" ", -" "}; diff --git a/resources/bitmaps/console.xpm b/resources/bitmaps/console.xpm deleted file mode 100644 index 0ecdd01..0000000 --- a/resources/bitmaps/console.xpm +++ /dev/null @@ -1,61 +0,0 @@ -/* XPM */ -static char * console_xpm[] = { -"16 16 42 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #86FFFF", -"$ c #88FFFF", -"% c #00C9F7", -"& c #8CFFFF", -"* c #00C7F7", -"= c #00C7F9", -"- c #8AFFFF", -"; c #00C5FD", -"> c #90FFFF", -", c #8EFFFF", -"' c #00C5FF", -") c #00C1FF", -"! c #00C3FF", -"~ c #00BDFF", -"{ c #00BBFF", -"] c #00B7FF", -"^ c #00B9FF", -"/ c #00B3FF", -"( c #84FFFF", -"_ c #00B5FF", -": c #00ADFF", -"< c #82FFFF", -"[ c #00AFFF", -"} c #80FFFF", -"| c #00A9FF", -"1 c #7EFFFF", -"2 c #7CFFFF", -"3 c #00A5FF", -"4 c #7AFFFF", -"5 c #00A3FF", -"6 c #009FFF", -"7 c #76FFFF", -"8 c #78FFFF", -"9 c #009BFF", -"0 c #72FFFF", -"a c #74FFFF", -"b c #0095FF", -"c c #0097FF", -" ", -" ...+.......... ", -" @##$$#$###$$#@ ", -" %&*==%&&-&&&&* ", -" ;>,>>>>>>>>>>' ", -" ),))))!))!,,,) ", -" ~-&&&--&----&{ ", -" ]#^]]]]]]]]]$] ", -" /(#((((((#(((_ ", -" :<[[:}}}<<<}}[ ", -" |111122221111| ", -" 34333355334445 ", -" 67777787777876 ", -" 9000a000a00a09 ", -" bbbbbbbbcbbbbb ", -" "}; diff --git a/resources/bitmaps/copy.xpm b/resources/bitmaps/copy.xpm deleted file mode 100644 index e312da2..0000000 --- a/resources/bitmaps/copy.xpm +++ /dev/null @@ -1,64 +0,0 @@ -/* XPM */ -static char * copy_xpm[] = { -"20 19 42 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #86FFFF", -"$ c #88FFFF", -"% c #00C9F1", -"& c #00CBF3", -"* c #00C9F7", -"= c #8CFFFF", -"- c #8AFFFF", -"; c #00C7F7", -"> c #00C5FD", -", c #90FFFF", -"' c #00C5FF", -") c #00C7FF", -"! c #00C1FF", -"~ c #8EFFFF", -"{ c #00C3FF", -"] c #00BDFF", -"^ c #00BBFF", -"/ c #00B7FF", -"( c #00B9FF", -"_ c #00B3FF", -": c #84FFFF", -"< c #00B5FF", -"[ c #00ADFF", -"} c #82FFFF", -"| c #80FFFF", -"1 c #00AFFF", -"2 c #00A9FF", -"3 c #00ABFF", -"4 c #7CFFFF", -"5 c #7EFFFF", -"6 c #00A3FF", -"7 c #7AFFFF", -"8 c #00A5FF", -"9 c #00A1FF", -"0 c #76FFFF", -"a c #78FFFF", -"b c #009FFF", -"c c #009BFF", -" ", -" ", -" ", -" ...+.. ", -" @##$$%& ", -" *==-=*=; ", -" >,'>,>'')))) ", -" !~~~~~{~~~~!! ", -" ]-]]]]]=---]=^ ", -" /#$##$/$//#///( ", -" _:<____::#::::< ", -" [}||||[|11111|1 ", -" 222223244555542 ", -" 678886878 ", -" 90000a0ab ", -" ccccccccc ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/cut.xpm b/resources/bitmaps/cut.xpm deleted file mode 100644 index a5dba89..0000000 --- a/resources/bitmaps/cut.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char * cut_xpm[] = { -"20 19 26 1", -" c None", -". c #00CBED", -"+ c #00C9F1", -"@ c #00C9F3", -"# c #00C9F7", -"$ c #00C9F9", -"% c #00C5FD", -"& c #00C5FF", -"* c #00C7FD", -"= c #00C7FF", -"- c #00C3FF", -"; c #00C1FF", -"> c #00BDFF", -", c #00B7FF", -"' c #00B3FF", -") c #00B5FF", -"! c #00ADFF", -"~ c #00AFFF", -"{ c #00A9FF", -"] c #00ABFF", -"^ c #00A5FF", -"/ c #00A3FF", -"( c #009FFF", -"_ c #00A1FF", -": c #009BFF", -"< c #0095FF", -" ", -" ", -" ", -" . . ", -" + @ ", -" # $ ", -" %& *= ", -" - ; ", -" >>> ", -" , ", -" '') ", -" ! ~~~ ", -" {]{ ] { ", -" ^ / ^ / ", -" ( _ _ _ ", -" : : :: ", -" << ", -" ", -" "}; diff --git a/resources/bitmaps/dontselectcurve.xpm b/resources/bitmaps/dontselectcurve.xpm deleted file mode 100644 index 0e80113..0000000 --- a/resources/bitmaps/dontselectcurve.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char * dontselectcurve_xpm[] = { -"16 15 26 1", -" c None", -". c #00A5D9", -"+ c #00A4E2", -"@ c #00A5E0", -"# c #00A4E6", -"$ c #00A4E8", -"% c #00A4EA", -"& c #00A4F0", -"* c #00A4F2", -"= c #00A4EE", -"- c #003469", -"; c #00346B", -"> c #00A4F6", -", c #00A4F4", -"' c #00346D", -") c #00A3FA", -"! c #00346F", -"~ c #003471", -"{ c #00A3FF", -"] c #003473", -"^ c #003472", -"/ c #003476", -"( c #003377", -"_ c #00A2FF", -": c #00A1FF", -"< c #00A0FF", -" ", -" .. . ", -" ++@ @ ", -" #$$% $ ", -" &*&= & ", -"-;->>>>-;>,; ;;;", -"' '))))) ' ! ", -"~ ~ {{{~ ~ ~~ ", -"] ] {{{^ ] ] ", -"/(( /___ _ ////", -" ___ _ ", -" ::: : ", -" ::: : ", -" <<< < ", -"<<< < "}; diff --git a/resources/bitmaps/dontselectmodel.xpm b/resources/bitmaps/dontselectmodel.xpm deleted file mode 100644 index 4adcbed..0000000 --- a/resources/bitmaps/dontselectmodel.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char * dontselectmodel_xpm[] = { -"16 15 26 1", -" c None", -". c #00A5D9", -"+ c #00A4E2", -"@ c #00A5E0", -"# c #00A4E6", -"$ c #00A4E8", -"% c #00A4EA", -"& c #00A4F0", -"* c #00A4F2", -"= c #00A4EE", -"- c #003469", -"; c #00A4F6", -"> c #00A4F4", -", c #00346B", -"' c #00346D", -") c #00A3FA", -"! c #00346E", -"~ c #003471", -"{ c #00A3FF", -"] c #003473", -"^ c #003472", -"/ c #003476", -"( c #003377", -"_ c #00A2FF", -": c #00A1FF", -"< c #00A0FF", -" ", -" .. . ", -" ++@ @ ", -" #$$% $ ", -" &*&= & ", -"- -;;;; ;>,, , ", -"''' ' )))) ' ! ", -"~ ~ ~ {{{~ ~~ ~ ", -"] ] ] {{{^ ] ^ ", -"/ ( ___/_ // //", -" ___ _ ", -" ::: : ", -" ::: : ", -" <<< < ", -"<<< < "}; diff --git a/resources/bitmaps/ellipsis.xpm b/resources/bitmaps/ellipsis.xpm deleted file mode 100644 index e825433..0000000 --- a/resources/bitmaps/ellipsis.xpm +++ /dev/null @@ -1,11 +0,0 @@ -/* XPM */ -static char * ellipsis_xpm[] = { -"12 4 4 1", -" c None", -". c #00B7FF", -"+ c #00B3FF", -"@ c #00B5FF", -" ", -" .. .. ..", -" ++ +@ @+", -" "}; diff --git a/resources/bitmaps/entities.xpm b/resources/bitmaps/entities.xpm deleted file mode 100644 index f2b014a..0000000 --- a/resources/bitmaps/entities.xpm +++ /dev/null @@ -1,61 +0,0 @@ -/* XPM */ -static char * entities_xpm[] = { -"16 16 42 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #86FFFF", -"$ c #88FFFF", -"% c #00C9F7", -"& c #8CFFFF", -"* c #00C7F7", -"= c #00C7F9", -"- c #00C9F9", -"; c #00C5FD", -"> c #90FFFF", -", c #8EFFFF", -"' c #00C5FF", -") c #00C1FF", -"! c #00BDFF", -"~ c #8AFFFF", -"{ c #00BBFF", -"] c #00B7FF", -"^ c #00B9FF", -"/ c #00B3FF", -"( c #84FFFF", -"_ c #00B5FF", -": c #00ADFF", -"< c #82FFFF", -"[ c #00AFFF", -"} c #80FFFF", -"| c #00A9FF", -"1 c #7EFFFF", -"2 c #7CFFFF", -"3 c #00A5FF", -"4 c #7AFFFF", -"5 c #00A3FF", -"6 c #009FFF", -"7 c #76FFFF", -"8 c #78FFFF", -"9 c #009BFF", -"0 c #72FFFF", -"a c #74FFFF", -"b c #0095FF", -"c c #0097FF", -" ", -" ...+.......... ", -" @##$$#$###$$#@ ", -" %&*==&&*=--=&* ", -" ;>,>>>>>>>>>>' ", -" ),))),,)),,,,) ", -" !~&&&~~&~~~~&{ ", -" ]#^]]$#]]]#$$] ", -" /(#((((((#(((_ ", -" :<[[:}}[[[[[}[ ", -" |111122221111| ", -" 34333445344445 ", -" 67777787777876 ", -" 9000a000a00a09 ", -" bbbbbbbbcbbbbb ", -" "}; diff --git a/resources/bitmaps/file_new.xpm b/resources/bitmaps/file_new.xpm deleted file mode 100644 index 353b529..0000000 --- a/resources/bitmaps/file_new.xpm +++ /dev/null @@ -1,46 +0,0 @@ -/* XPM */ -static char * file_new_xpm[] = { -"16 16 27 1", -" c None", -". c #39E8EB", -"+ c #39E8EA", -"@ c #38E8EB", -"# c #39E9EB", -"$ c #3DE7F1", -"% c #FFFFFF", -"& c #3EE6F0", -"* c #3DE7F0", -"= c #41E5F6", -"- c #46E3FC", -"; c #46E4FC", -"> c #47E0FF", -", c #44DBFF", -"' c #43DBFF", -") c #41D7FF", -"! c #40D7FF", -"~ c #3CD2FF", -"{ c #3DD2FF", -"] c #39CDFF", -"^ c #36C7FF", -"/ c #36C8FF", -"( c #32C3FF", -"_ c #2FBEFF", -": c #2CB9FF", -"< c #2BB9FF", -"[ c #2BB8FF", -" ", -" ", -" .+@#..#. ", -" $%%%%%%&* ", -" =%%%%%%=%= ", -" -%%%%%%;--- ", -" >%%%%%%%%%> ", -" ,%%%%%%%%%' ", -" )%%%%%%%%%! ", -" ~%%%%%%%%%{ ", -" ]%%%%%%%%%] ", -" ^%%%%%%%%%/ ", -" (%%%%%%%%%( ", -" _%%%%%%%%%_ ", -" :<<::[<:[<< ", -" "}; diff --git a/resources/bitmaps/file_open.xpm b/resources/bitmaps/file_open.xpm deleted file mode 100644 index 5b83d14..0000000 --- a/resources/bitmaps/file_open.xpm +++ /dev/null @@ -1,59 +0,0 @@ -/* XPM */ -static char * file_open_xpm[] = { -"16 16 40 1", -" c None", -". c #39E8EB", -"+ c #39E9EB", -"@ c #3EE6F0", -"# c #3DE6F0", -"$ c #41E5F6", -"% c #42E5F6", -"& c #46E3FC", -"* c #45E3FC", -"= c #46E4FC", -"- c #47E0FF", -"; c #FAFEFF", -"> c #FFFFFF", -", c #47E1FF", -"' c #43DBFF", -") c #44DBFF", -"! c #41D7FF", -"~ c #40D7FF", -"{ c #3CD1FF", -"] c #3DD2FF", -"^ c #3DD1FF", -"/ c #39CDFF", -"( c #99E5FF", -"_ c #9AE5FF", -": c #36C7FF", -"< c #F9FDFF", -"[ c #35C8FF", -"} c #97E3FF", -"| c #98E3FF", -"1 c #98E2FF", -"2 c #32C3FF", -"3 c #96E0FF", -"4 c #2FBEFF", -"5 c #94DEFF", -"6 c #94DDFF", -"7 c #2EBDFF", -"8 c #2CB8FF", -"9 c #2BB9FF", -"0 c #2CB9FF", -"a c #2BB8FF", -" ", -" ", -" .+. ", -" @ @ # ", -" $% ", -" &&* &&= ", -"-;>;---,--- ", -"'>;>;>;>;>) ", -"!;>;>;>;>;~ ", -"{>;>;]]^]]]]]{]]", -"/;>;/(_(_((_(_/ ", -":><[}|||}|}1|[ ", -"2<23333333332 ", -"445555666557 ", -"8909900a90a ", -" "}; diff --git a/resources/bitmaps/file_save.xpm b/resources/bitmaps/file_save.xpm deleted file mode 100644 index 08cf5f7..0000000 --- a/resources/bitmaps/file_save.xpm +++ /dev/null @@ -1,83 +0,0 @@ -/* XPM */ -static char * file_save_xpm[] = { -"16 16 64 1", -" c None", -". c #00D5CB", -"+ c #00D5CD", -"@ c #00D7CD", -"# c #00D1D7", -"$ c #37E7EA", -"% c #00D1D5", -"& c #5CF7F8", -"* c #5DF7F8", -"= c #00CFE1", -"- c #3BE6F1", -"; c #00CDE1", -"> c #64F6FA", -", c #66F6FA", -"' c #00CBED", -") c #3FE4F6", -"! c #6BF6FC", -"~ c #6CF6FC", -"{ c #00C7F9", -"] c #44E2FC", -"^ c #71F5FE", -"/ c #73F5FE", -"( c #00C9F9", -"_ c #00C1FF", -": c #45DFFF", -"< c #74F4FF", -"[ c #45E0FF", -"} c #00C3FF", -"| c #00B9FF", -"1 c #42DAFF", -"2 c #00B7FF", -"3 c #6EF2FF", -"4 c #6FF2FF", -"5 c #00AFFF", -"6 c #3FD6FF", -"7 c #3ED6FF", -"8 c #00ADFF", -"9 c #00A5FF", -"0 c #3AD1FF", -"a c #3BD1FF", -"b c #3BD0FF", -"c c #3AD0FF", -"d c #009BFF", -"e c #37CCFF", -"f c #38CCFF", -"g c #008FFF", -"h c #35C5FF", -"i c #34C6FF", -"j c #0091FF", -"k c #57EBFF", -"l c #59EBFF", -"m c #0085FF", -"n c #31C1FF", -"o c #0087FF", -"p c #52E9FF", -"q c #31C0FF", -"r c #007DFF", -"s c #2EBCFF", -"t c #2DBCFF", -"u c #007BFF", -"v c #4BE8FF", -"w c #4BE7FF", -"x c #0073FF", -"y c #0071FF", -" ", -" .+...@.+..+..+ ", -" #$%&*******#&# ", -" =-;>>>>,,>>;;; ", -" ')'!!~!~!~!')' ", -" {]{^///^///{]( ", -" _:_<<<<<<<<_[} ", -" |1234334343212 ", -" 56785885555765 ", -" 90aaaabaaaaac9 ", -" defdddddddddfd ", -" ghijjjjjjkljij ", -" mnnoomoooppoqo ", -" rstrruuurvwrsu ", -" xxxxxyxxyxxxy ", -" "}; diff --git a/resources/bitmaps/icon.xpm b/resources/bitmaps/icon.xpm deleted file mode 100644 index 60cd969..0000000 --- a/resources/bitmaps/icon.xpm +++ /dev/null @@ -1,271 +0,0 @@ -/* XPM */ -static char *icon[] = { -/* columns rows colors chars-per-pixel */ -"32 32 233 2 ", -" c None", -". c #1E345F", -"X c #1E3666", -"o c #243D6B", -"O c #253A69", -"+ c #213D78", -"@ c #2D415A", -"# c #354756", -"$ c #2B426B", -"% c #26436C", -"& c #35486A", -"* c #3A526A", -"= c #264172", -"- c #2B4374", -"; c #2D4478", -": c #2D497B", -"> c #264777", -", c #354974", -"< c #384B77", -"1 c #3A517B", -"2 c #395276", -"3 c #43546A", -"4 c #42567A", -"5 c #445A7C", -"6 c #485A7C", -"7 c #415573", -"8 c #525C79", -"9 c #424F7D", -"0 c #52637E", -"q c #636565", -"w c #63667D", -"e c #977C7E", -"r c #AE7E7C", -"t c #3D5386", -"y c #3B5587", -"u c #3D548C", -"i c #425483", -"p c #445A83", -"a c #4B5B82", -"s c #445B8C", -"d c #4C5D8B", -"f c #41578A", -"g c #435B93", -"h c #475E9A", -"j c #515C80", -"k c #496187", -"l c #54638E", -"z c #5C6A8C", -"x c #596587", -"c c #4D6293", -"v c #4C6599", -"b c #546592", -"n c #536997", -"m c #5C6C95", -"M c #546A9A", -"N c #5A6C9D", -"B c #56679B", -"V c #5E729D", -"C c #626885", -"Z c #677286", -"A c #767689", -"S c #627391", -"D c #6B759B", -"F c #6F7C9A", -"G c #687597", -"H c #767A9A", -"J c #696991", -"K c #4963A1", -"L c #5C6DA3", -"P c #566AA6", -"I c #5E71A3", -"U c #5C72A8", -"Y c #556AB8", -"T c #516BB9", -"R c #6D7AA2", -"E c #6777A6", -"W c #737EA2", -"Q c #757CA6", -"! c #606FB2", -"~ c #6C7CB4", -"^ c #6878B4", -"/ c #767CB5", -"( c #626CAB", -") c #6377C5", -"_ c #727BC1", -"` c #89788B", -"' c #937F87", -"] c #A17E8F", -"[ c #857CAD", -"{ c #7681A3", -"} c #7583AB", -"| c #7C86AD", -" . c #7D86A8", -".. c #7C87B3", -"X. c #7B8AB4", -"o. c #7B86BC", -"O. c #7D8CBC", -"+. c #7582B7", -"@. c #6D80A2", -"#. c #7987C3", -"$. c #7E8CC2", -"%. c #7483C7", -"&. c #7B8AD5", -"*. c #7F93D0", -"=. c #7894E7", -"-. c #6D8CE7", -";. c #868499", -":. c #98839B", -">. c #8C8B92", -",. c #A88699", -"<. c #B89899", -"1. c #A88588", -"2. c #838BAB", -"3. c #8589AA", -"4. c #9489AA", -"5. c #8B93AC", -"6. c #8790AC", -"7. c #9393A5", -"8. c #838CB3", -"9. c #848EBC", -"0. c #8B8EB5", -"q. c #918AB3", -"w. c #8C95B4", -"e. c #8592BA", -"r. c #8B92BB", -"t. c #8E99BE", -"y. c #8790B3", -"u. c #9395BC", -"i. c #959BBD", -"p. c #989BB5", -"a. c #A897AB", -"s. c #A79AB5", -"d. c #B799BC", -"f. c #AC8DAD", -"g. c #9DA3BD", -"h. c #A2A2BE", -"j. c #ABADBD", -"k. c #ABA7BA", -"l. c #BCA5BD", -"z. c #C4909F", -"x. c #D19DB1", -"c. c #E19DA2", -"v. c #CBAEBC", -"b. c #838EC2", -"n. c #8C94C3", -"m. c #8B94CC", -"M. c #8796C8", -"N. c #949CC3", -"B. c #949BCB", -"V. c #9799CB", -"C. c #808FD1", -"Z. c #8595DC", -"A. c #8897D7", -"S. c #969BD8", -"D. c #A49AC5", -"F. c #9BA1C2", -"G. c #9AA3CC", -"H. c #9EAAD6", -"J. c #92A1DA", -"K. c #9BA6DB", -"L. c #99A5DA", -"P. c #8FA3DD", -"I. c #A1A3C3", -"U. c #A5ABCB", -"Y. c #A8ACC6", -"T. c #B8AAC6", -"R. c #AFB1C6", -"E. c #B8B8CB", -"W. c #A3ACD4", -"Q. c #A9ACD2", -"!. c #A5A9D8", -"~. c #ACB3D5", -"^. c #AEB5DC", -"/. c #A5B2DC", -"(. c #B4BADD", -"). c #B8BBD6", -"_. c #B9ACDD", -"`. c #859BE3", -"'. c #8A9DE9", -"]. c #8EA3E3", -"[. c #8BA4EB", -"{. c #98A8E8", -"}. c #99ADF1", -"|. c #96B6F8", -" X c #A6ACE4", -".X c #B7AAE5", -"XX c #ACB5E3", -"oX c #ADB9E4", -"OX c #A4B3EC", -"+X c #A8B6E8", -"@X c #B3BBE5", -"#X c #B3BDEB", -"$X c #B6BAE3", -"%X c #A4B6F1", -"&X c #ADBCF3", -"*X c #A7B8F4", -"=X c #B6B8F2", -"-X c #A3AAF5", -";X c #C7A5C9", -":X c #D7ABCA", -">X c #C9A8D3", -",X c #D8BCDF", -"X:XX;Xd.4.A w C w h.{ { q.:.f.a B B g g h b.B.P ", -" =X>Xf.[ H H D D 8.z w.g.s.p.6.C f i d N d s L !.^ M ", -" }.S./ / n.N.B.i.2.@.h.R.g.7.T.l 6 D 0.Q p.w.(.W U P M 8 ", -" =._ 8.b.n.Q...9X9XZ E.rXj.6Xk...i.r...I. .3.iXB.9.U U x ", -" =.S.&.) n.kXqXU.i.6XF.h.7X6X1X5.m 6XY.h.H 1 : ~ Q B.o.m v * ", -" [.S.! P U R ~.Y.w.~.Y.6XE.E.6X1XH.i.J o i 6 N M p b m.n.I 6 ", -" A.%.M.h ^ E p g.R.i.R.jXE.6X .;. .9.Y.d d & : 1 X.R R L.X.k ", -"%X&.U.e.( } Q.L E.R.g.h.jXjXj.} p S A Y.0.| = f < N S 1 N.B.s # ", -"[.Z.*.qXU.t.{ b ,.;.s.k.E.7.Z l V 2 w & W N l < : f 1 k M D I 3 ", -"-.) P.W.| L g #.0.e 1.<.1.q A 0 6 & q . X O f B ; 6 y c y y n 3 ", -"-.) o.b.W.N.~ $X(.a.r z.a.7.0 V 2 & 2 2 , 9 a F a l y u N c y 2 ", -"-.T ~ ~ v u + + i 4.l.<.l.` x W 4 , - O O o ; 6 r.} I > L : c & ", -"=.Y Y ^ M.(.3.I t i a.7X8X5.} F a < p o = $ % X l i.V = t f c * ", -"'.A.S.U P Q.dX9Xi.W @.8XtXzXrXtXrXE.| , 0 @.G F o 2 t.= c : k 2 ", -"}.%.#X^ / U.9.o.h t X.S w.wXxXzXxXzXrXw.d F D 6.x 4 8.m : s N @ ", -" +XdX$.N.X.w.h.8 & r.B.i.S g.lXxXxX2Xe.z 5.W.G.F V E H.> y 1 ", -" {.gXb.G.i.1XrXh.a x y.kXrXjXxXxXqX(.{ 4 y.~.2Xy.F.X.K.I c & ", -" -.oXeXr.O.r.~.tX^.h.eXtXzXgX6Xw.} | S F 5.e.aX(.2XoX{.$.k @ ", -" +XyXXXb.G.N.(.dX~.@XqXfXwX@XW.G.t.H 5.0 8.{ 1 e.+XO.m 3 ", -" ].2X*X$.uXH.qXlXXXXXN.uX0XXXe.F.} 5.t.N.0 7 $ } +.k 6 # ", -" [.C.oX2XpXb.uX3X@X!.qX@X!.@XW.^.W.r.X.E O.J.*.B s 2 ", -" =.*.b.oXB.b.oXdXlXdX/.dXhXpXoX^.e.!.K.{.A.M.+.n ", -" ].%X2XyXyXdXaXaXfXlXdXhXdXgXsX/./.#X XM.#.L ", -" [.5XaXaXdXaXsXdXlXgXgXgXgXdXyX&X*XJ.^ L ", -" `.&.%X4XyXyXdXdXdXfXyXyX3X&XOX{.%.L ", -" `.}.&X*X3X4X5X3X&X%XOXJ.C.^ ", -" `.}.].{.].`.Z.%. " -}; diff --git a/resources/bitmaps/lightinspector.xpm b/resources/bitmaps/lightinspector.xpm deleted file mode 100644 index baef0de..0000000 --- a/resources/bitmaps/lightinspector.xpm +++ /dev/null @@ -1,192 +0,0 @@ -/* XPM */ -static char *lightinspector[] = { -/* columns rows colors chars-per-pixel */ -"16 15 171 2 ", -" c #323232", -". c #343434", -"X c #373737", -"o c #3A3A3B", -"O c #3E3D3E", -"+ c #414142", -"@ c gray27", -"# c gray29", -"$ c #4E4F4F", -"% c #545353", -"& c #585858", -"* c #5D5D5D", -"= c #636263", -"- c #686768", -"; c #6D6D6D", -": c #727272", -"> c #343535", -", c #3A3A3A", -"< c #3E3E3D", -"1 c #424241", -"2 c #454546", -"3 c #494849", -"4 c #4C4C4C", -"5 c #515151", -"6 c #555656", -"7 c #5C5B5C", -"8 c #626262", -"9 c #676767", -"0 c #6D6C6D", -"q c #777777", -"w c #363737", -"e c #3A393A", -"r c gray24", -"t c #414041", -"y c #484849", -"u c #656462", -"i c #D9CFBE", -"p c #605E5A", -"a c #555555", -"s c #5D5D5C", -"d c gray40", -"f c #6D6C6C", -"g c #717271", -"h c #7C7C7C", -"j c #414141", -"k c #444444", -"l c #494848", -"z c #666562", -"x c #EEE7DB", -"c c #FFF3DC", -"v c #CBBFAB", -"b c #5B5A57", -"n c #707170", -"m c #818281", -"M c #3C3D3D", -"N c #444445", -"B c #484848", -"V c #EBE5D9", -"C c #FFF8EA", -"Z c #DBCEB7", -"A c #C8BDA8", -"S c #5E5B59", -"D c gray38", -"F c #7A7B7A", -"G c #818181", -"H c #878786", -"J c gray25", -"K c gray28", -"L c #636260", -"P c #C8BDA9", -"I c #646260", -"U c #6A6A69", -"Y c gray48", -"T c #848484", -"R c #8B8B8B", -"E c #626260", -"W c #696866", -"Q c #737272", -"! c #8E8F8E", -"~ c #4B4B4B", -"^ c #D8D1C4", -"/ c #FFF5E4", -"( c #FFF5E3", -") c #FEEFD4", -"_ c #C4B8A4", -"` c #C2B7A2", -"' c #A19889", -"] c #6A6A6A", -"[ c #828283", -"{ c #929292", -"} c #4C4D4C", -"| c gray31", -" . c #656360", -".. c #EBDEC8", -"X. c #FFF1D7", -"o. c #D9CCB5", -"O. c #A29887", -"+. c #A19886", -"@. c #948C7C", -"#. c #51504E", -"$. c #838382", -"%. c #949595", -"&. c #535453", -"*. c gray32", -"=. c #62605C", -"-. c #EADEC6", -";. c #D8CBB4", -":. c #948B7C", -">. c #444341", -",. c #717171", -"<. c #8A8B8B", -"1. c #9B9A9B", -"2. c #595A59", -"3. c #5A5A5A", -"4. c #555556", -"5. c #64625F", -"6. c #EADEC7", -"7. c #928A7B", -"8. c #434240", -"9. c gray30", -"0. c #69696A", -"q. c #838383", -"w. c #959596", -"e. c #A0A0A0", -"r. c #5F5F5F", -"t. c #636464", -"y. c gray37", -"u. c #6A6864", -"i. c #EBDEC6", -"p. c #D7CAB4", -"a. c #938A7C", -"s. c #4E4D4D", -"d. c DimGray", -"f. c gray51", -"g. c gray58", -"h. c #9E9F9F", -"j. c #A5A4A4", -"k. c #5F5E5F", -"l. c #6C6C6D", -"z. c #6D6E6D", -"x. c #706F6A", -"c. c #B3AA98", -"v. c #504F4D", -"b. c #515252", -"n. c #9E9F9E", -"m. c #A4A4A5", -"M. c gray66", -"N. c #636463", -"B. c #696868", -"V. c gray43", -"C. c gray45", -"Z. c #717071", -"A. c #656565", -"S. c gray44", -"D. c #939494", -"F. c gray62", -"G. c #A4A4A4", -"H. c #ABABAC", -"J. c #686868", -"K. c #797879", -"L. c #7D7D7E", -"P. c #818182", -"I. c #808181", -"U. c #898988", -"Y. c #949594", -"T. c #9E9D9E", -"R. c gray64", -"E. c #A7A7A7", -"W. c gray67", -"Q. c #AEAEAE", -"!. c white", -/* pixels */ -" . X o O + @ # $ % & * = - ; : ", -"> X , < 1 2 3 4 5 6 7 8 9 0 : q ", -"w e r t @ y u i p a s d f g q h ", -"e r j k l z x c v b & d n q h m ", -"M j N B u V C c Z A S D n F G H ", -"J N K L V C C c Z Z P I U Y T R ", -"k K E V C C C c Z Z Z A W Q T ! ", -"B ~ ^ / / / ( ) _ _ _ ` ' ] [ { ", -"} | ...X.X.X.o.O.O.+.@.#.9 $.%.", -"5 &.*.=.-.X.X.;.O.O.:.>.*.,.<.1.", -"a 2.3.4.5.6.X.;.O.7.8.9.0.q.w.e.", -"3.r.8 t.y.u.i.p.a.>.s.d.f.g.h.j.", -"k.t.d.l.z.9 x.c.v.b.d.G g.n.m.M.", -"N.B.V.C.q q Z.- A.S.[ D.F.G.M.H.", -"J.z.C.K.L.G P.I.P.U.Y.T.R.E.W.Q." -}; diff --git a/resources/bitmaps/logo.xpm b/resources/bitmaps/logo.xpm deleted file mode 100644 index 2234735..0000000 --- a/resources/bitmaps/logo.xpm +++ /dev/null @@ -1,4295 +0,0 @@ -/* XPM */ -static char * logo_xpm[] = { -"126 126 4166 2", -" c #FFFFFF", -". c #000000", -"+ c #010001", -"@ c #010101", -"# c #040404", -"$ c #050505", -"% c #020202", -"& c #030303", -"* c #060606", -"= c #0D0D0D", -"- c #101010", -"; c #070707", -"> c #0A0A0A", -", c #111111", -"' c #0F0F0F", -") c #131313", -"! c #141314", -"~ c #080808", -"{ c #111011", -"] c #131213", -"^ c #0F0E0F", -"/ c #0B0B0B", -"( c #121112", -"_ c #121212", -": c #0C0C0C", -"< c #191919", -"[ c #434343", -"} c #545454", -"| c #363636", -"1 c #181818", -"2 c #414141", -"3 c #555455", -"4 c #393939", -"5 c #242424", -"6 c #4D4D4D", -"7 c #5F5F5F", -"8 c #616061", -"9 c #606060", -"0 c #535353", -"a c #2E2E2E", -"b c #090909", -"c c #303030", -"d c #5E5E5E", -"e c #4B4B4B", -"f c #232323", -"g c #3B3B3B", -"h c #5A595A", -"i c #5C5C5C", -"j c #424142", -"k c #151515", -"l c #C1C0C1", -"m c #E9E9EA", -"n c #909090", -"o c #3D3D3D", -"p c #B1B1B1", -"q c #E7E7E7", -"r c #9C9C9C", -"s c #212121", -"t c #6A696A", -"u c #D4D4D4", -"v c #EAEAEA", -"w c #DFDFDF", -"x c #818181", -"y c #2F2F2F", -"z c #313131", -"A c #848484", -"B c #E0DFE0", -"C c #D3D3D3", -"D c #676667", -"E c #202020", -"F c #0E0E0E", -"G c #444444", -"H c #AAA9AA", -"I c #EAE9EA", -"J c #B3B3B3", -"K c #515151", -"L c #141414", -"M c #2C2C2C", -"N c #A2A2A2", -"O c #F2F1F2", -"P c #F0F0F1", -"Q c #C3C3C3", -"R c #EDEBED", -"S c #EEEEEE", -"T c #727272", -"U c #1E1D1E", -"V c #C9C9C9", -"W c #EDEAED", -"X c #E3D9E4", -"Y c #E4DEE5", -"Z c #E5DFE5", -"` c #E3DAE4", -" . c #E9E3E9", -".. c #DEDEDE", -"+. c #585858", -"@. c #5A5A5B", -"#. c #DFDEDF", -"$. c #E8E3E8", -"%. c #E5DEE5", -"&. c #EDEBEE", -"*. c #C8C8C8", -"=. c #3F3F3F", -"-. c #1F1F1F", -";. c #7E7E7E", -">. c #F0F0F0", -",. c #E5DCE5", -"'. c #E4DCE4", -"). c #E4DDE5", -"!. c #E4DAE4", -"~. c #F0EFF0", -"{. c #979697", -"]. c #2A2A2A", -"^. c #090809", -"/. c #353435", -"(. c #B5B5B6", -"_. c #E8E0E9", -":. c #ECE8ED", -"<. c #4C4B4C", -"[. c #C2C2C3", -"}. c #E6DBE6", -"|. c #EEEBEE", -"1. c #838283", -"2. c #D6D6D6", -"3. c #E2D3E3", -"4. c #E8E2E8", -"5. c #E8E8E8", -"6. c #E8E7E8", -"7. c #EAE7EA", -"8. c #E0CBE0", -"9. c #E6E6E6", -"0. c #666667", -"a. c #161516", -"b. c #070607", -"c. c #171617", -"d. c #696869", -"e. c #E0CAE0", -"f. c #EAE9EB", -"g. c #E8E2E9", -"h. c #E3D3E3", -"i. c #D6D5D6", -"j. c #0E0D0E", -"k. c #252525", -"l. c #919091", -"m. c #EEEAEE", -"n. c #E1CFE2", -"o. c #EBEBEB", -"p. c #E7E7E8", -"q. c #E3D4E3", -"r. c #E9E1E9", -"s. c #333233", -"t. c #0A090A", -"u. c #353535", -"v. c #B4B4B5", -"w. c #E5D6E6", -"x. c #E9E1EA", -"y. c #A1A0A1", -"z. c #4B4A4B", -"A. c #E2D1E3", -"B. c #EBE5EC", -"C. c #838184", -"D. c #080809", -"E. c #4E4D4E", -"F. c #D5D4D5", -"G. c #DFC8E0", -"H. c #E5E2E5", -"I. c #8B8A8B", -"J. c #7F7E7F", -"K. c #DAD9DA", -"L. c #DDC3DF", -"M. c #E4E3E4", -"N. c #060607", -"O. c #DEC6DF", -"P. c #D9D9DA", -"Q. c #7C7B7D", -"R. c #8F8D8F", -"S. c #EEECEF", -"T. c #D4D4D5", -"U. c #0D0C0E", -"V. c #050405", -"W. c #262526", -"X. c #918F91", -"Y. c #EBE4EB", -"Z. c #E3D2E4", -"`. c #C6C5C7", -" + c #767576", -".+ c #B2B1B3", -"++ c #E6DBE7", -"@+ c #E5D8E6", -"#+ c #A9A8AA", -"$+ c #333333", -"%+ c #343435", -"&+ c #B3B2B4", -"*+ c #DDCCE3", -"=+ c #E4D9E8", -"-+ c #9F9EA0", -";+ c #4A494B", -">+ c #BFBEC0", -",+ c #D9C5E1", -"'+ c #E7DEEA", -")+ c #817F82", -"!+ c #242324", -"~+ c #080708", -"{+ c #0E0C0E", -"]+ c #4D4C4D", -"^+ c #D3D2D4", -"/+ c #D4B9DD", -"(+ c #E1DDE2", -"_+ c #716F72", -":+ c #5E5D5E", -"<+ c #D4D3D5", -"[+ c #D5B5DC", -"}+ c #E2E1E3", -"|+ c #636263", -"1+ c #141415", -"2+ c #161517", -"3+ c #686769", -"4+ c #E1DFE2", -"5+ c #D6B8DD", -"6+ c #767477", -"7+ c #D3BADD", -"8+ c #D2D2D3", -"9+ c #4A4A4B", -"0+ c #0D0C0D", -"a+ c #040405", -"b+ c #080709", -"c+ c #252426", -"d+ c #8F8D90", -"e+ c #E7DCE9", -"f+ c #DAC9E2", -"g+ c #BDBCBE", -"h+ c #A5A4A6", -"i+ c #E1D3E5", -"j+ c #DECEE4", -"k+ c #A7A6A8", -"l+ c #323233", -"m+ c #09080A", -"n+ c #343334", -"o+ c #B1AFB2", -"p+ c #D4C3E0", -"q+ c #DED1E5", -"r+ c #9D9C9F", -"s+ c #49484A", -"t+ c #CEB9DE", -"u+ c #E2D7E7", -"v+ c #7F7D81", -"w+ c #232223", -"x+ c #D0D0D2", -"y+ c #C6ABDA", -"z+ c #DFD8E0", -"A+ c #6E6C70", -"B+ c #59585A", -"C+ c #D2D1D3", -"D+ c #E5DBE7", -"E+ c #CBCACC", -"F+ c #676568", -"G+ c #DFDAE0", -"H+ c #C7A8D9", -"I+ c #D2D0D3", -"J+ c #585659", -"K+ c #767478", -"L+ c #E9E2EB", -"M+ c #C7ACDA", -"N+ c #D0CFD1", -"O+ c #0C0B0D", -"P+ c #242425", -"Q+ c #8D8B8E", -"R+ c #E1D6E6", -"S+ c #D1BEDF", -"T+ c #BBBABC", -"U+ c #4B4A4C", -"V+ c #A3A1A4", -"W+ c #D9CAE2", -"X+ c #D5C5E1", -"Y+ c #A5A3A7", -"Z+ c #323132", -"`+ c #333234", -" @ c #AFADB0", -".@ c #CAB8DD", -"+@ c #D6C8E2", -"@@ c #9B999D", -"#@ c #484749", -"$@ c #BAB9BD", -"%@ c #C2ADDA", -"&@ c #DCCFE4", -"*@ c #7D7A80", -"=@ c #222123", -"-@ c #070608", -";@ c #020102", -">@ c #4A494C", -",@ c #CECDD0", -"'@ c #B79AD6", -")@ c #DBD2DE", -"!@ c #737176", -"~@ c #535255", -"{@ c #A6A5A7", -"]@ c #626162", -"^@ c #060506", -"/@ c #151416", -"(@ c #656367", -"_@ c #DCD5DE", -":@ c #B796D6", -"<@ c #D0CED2", -"[@ c #6A686C", -"}@ c #9A979E", -"|@ c #DACEE4", -"1@ c #B69BD6", -"2@ c #CECDCF", -"3@ c #484649", -"4@ c #0B0A0D", -"5@ c #242325", -"6@ c #8B888D", -"7@ c #DACDE4", -"8@ c #C5B1DC", -"9@ c #BBB9BD", -"0@ c #575659", -"a@ c #A4A1A6", -"b@ c #D0C0DF", -"c@ c #CCBADE", -"d@ c #A3A1A5", -"e@ c #313032", -"f@ c #030203", -"g@ c #323133", -"h@ c #ACAAAF", -"i@ c #BEACD8", -"j@ c #CEBFDE", -"k@ c #99979B", -"l@ c #464548", -"m@ c #B8B6BB", -"n@ c #B6A0D4", -"o@ c #D3C6E2", -"p@ c #7A767E", -"q@ c #212023", -"r@ c #49474B", -"s@ c #CBCACE", -"t@ c #A688CE", -"u@ c #D0C2DC", -"v@ c #BDBAC1", -"w@ c #B6B4B9", -"x@ c #B9B7BB", -"y@ c #A9A7AB", -"z@ c #59575B", -"A@ c #1D1C1D", -"B@ c #050506", -"C@ c #141315", -"D@ c #636065", -"E@ c #D7CEDB", -"F@ c #997BCB", -"G@ c #D7CFDB", -"H@ c #BEBBC2", -"I@ c #D9D0DF", -"J@ c #9D82C9", -"K@ c #C0ABD8", -"L@ c #C4C3C6", -"M@ c #3E3D3F", -"N@ c #09080B", -"O@ c #030304", -"P@ c #232224", -"Q@ c #88858B", -"R@ c #D2C4E1", -"S@ c #AD94D0", -"T@ c #D2CFD5", -"U@ c #B8B6BC", -"V@ c #CAC7CE", -"W@ c #B9A3D4", -"X@ c #C0AED8", -"Y@ c #A09DA3", -"Z@ c #302F31", -"`@ c #070609", -" # c #020203", -".# c #312F32", -"+# c #A9A7AD", -"@# c #B3A0CE", -"## c #C5B5D8", -"$# c #969499", -"%# c #454347", -"&# c #B5B3B8", -"*# c #A790C8", -"=# c #CBBDDC", -"-# c #77737C", -";# c #201F22", -"># c #060507", -",# c #010102", -"'# c #040304", -")# c #0A080C", -"!# c #474549", -"~# c #C8C5CB", -"{# c #9175BB", -"]# c #8269B2", -"^# c #AA94C7", -"/# c #AE9AC8", -"(# c #CCBDDB", -"_# c #444245", -":# c #121114", -"<# c #605D64", -"[# c #D1C7D9", -"}# c #715BA9", -"|# c #9077BA", -"1# c #A790C6", -"2# c #7F66AF", -"3# c #836AB6", -"4# c #D3CBD8", -"5# c #767379", -"6# c #242426", -"7# c #858289", -"8# c #C9BBDB", -"9# c #6E58A4", -"0# c #9D85C1", -"a# c #AD99C8", -"b# c #A28AC3", -"c# c #705AA6", -"d# c #B5A3CF", -"e# c #9D9AA1", -"f# c #2E2D30", -"g# c #060608", -"h# c #060508", -"i# c #302E31", -"j# c #A6A3AA", -"k# c #A792C4", -"l# c #BAA9D1", -"m# c #939097", -"n# c #444146", -"o# c #B2AFB6", -"p# c #9980BB", -"q# c #C3B3D6", -"r# c #746E7A", -"s# c #1F1E21", -"t# c #050507", -"u# c #464348", -"v# c #C5BEC9", -"w# c #7D64AB", -"x# c #876FB2", -"y# c #BDAAD3", -"z# c #C2B0D6", -"A# c #C1B0D6", -"B# c #C7B4DA", -"C# c #D7D2D9", -"D# c #0F0F10", -"E# c #121013", -"F# c #5E5A62", -"G# c #CBBED6", -"H# c #5F4B94", -"I# c #9D85C2", -"J# c #B9A6D2", -"K# c #866EB1", -"L# c #69549C", -"M# c #D0C2DA", -"N# c #86828A", -"O# c #29272A", -"P# c #837E87", -"Q# c #C0B0D5", -"R# c #614D96", -"S# c #AF98CC", -"T# c #C1AFD6", -"U# c #B6A0CF", -"V# c #6B559D", -"W# c #AA95C5", -"X# c #9A969F", -"Y# c #2D2B2F", -"Z# c #060407", -"`# c #2E2B30", -" $ c #A39BA8", -".$ c #9A83B8", -"+$ c #AF9BC7", -"@$ c #908995", -"#$ c #423D45", -"$$ c #AFA6B3", -"%$ c #8B71AE", -"&$ c #B8A5CE", -"*$ c #706777", -"=$ c #1E1C20", -"-$ c #050406", -";$ c #08070A", -">$ c #443F47", -",$ c #C2B4C6", -"'$ c #6C569C", -")$ c #B9A4CE", -"!$ c #92899A", -"~$ c #86818B", -"{$ c #8E8893", -"]$ c #908A95", -"^$ c #7A777D", -"/$ c #343335", -"($ c #040305", -"_$ c #110F13", -":$ c #5C5560", -"<$ c #C4B1D3", -"[$ c #5D4A95", -"}$ c #C4B0CD", -"|$ c #968D9D", -"1$ c #CBBBD3", -"2$ c #7B64A5", -"3$ c #856CAB", -"4$ c #C1B7C5", -"5$ c #3D383F", -"6$ c #201D21", -"7$ c #7F7785", -"8$ c #B6A2CC", -"9$ c #876DAC", -"0$ c #BBAFC1", -"a$ c #8A8390", -"b$ c #ABA0B2", -"c$ c #9F86BD", -"d$ c #9C86BA", -"e$ c #978E9C", -"f$ c #2C292E", -"g$ c #050407", -"h$ c #2D272F", -"i$ c #A090A5", -"j$ c #8C73AA", -"k$ c #A58CBE", -"l$ c #8D7F92", -"m$ c #403843", -"n$ c #AB9AB0", -"o$ c #7A61A0", -"p$ c #AE96C4", -"q$ c #6C5F74", -"r$ c #1D191F", -"s$ c #030204", -"t$ c #080609", -"u$ c #423A45", -"v$ c #BDA6C3", -"w$ c #58458B", -"x$ c #B59DC9", -"y$ c #625768", -"z$ c #49414C", -"A$ c #A896AC", -"B$ c #BDA7C1", -"C$ c #6B5E70", -"D$ c #272128", -"E$ c #100D12", -"F$ c #594E5E", -"G$ c #BAA2CD", -"H$ c #514087", -"I$ c #BBA4C4", -"J$ c #574E5C", -"K$ c #7A6D82", -"L$ c #B69CCC", -"M$ c #5B478B", -"N$ c #BEA8C3", -"O$ c #070509", -"P$ c #040306", -"Q$ c #1F1A21", -"R$ c #7C6E82", -"S$ c #AB93C2", -"T$ c #846AA5", -"U$ c #473F4A", -"V$ c #918397", -"W$ c #9D84B9", -"X$ c #8F77AD", -"Y$ c #938499", -"Z$ c #2B252D", -"`$ c #050306", -" % c #2B232E", -".% c #9C84A2", -"+% c #7E649F", -"@% c #987DB4", -"#% c #8A7590", -"$% c #3F3443", -"%% c #A88DAD", -"&% c #67528F", -"*% c #A386BC", -"=% c #685770", -"-% c #1C161E", -";% c #403544", -">% c #B698C0", -",% c #453577", -"'% c #AB8EC2", -")% c #5B4C62", -"!% c #4C4051", -"~% c #B395C1", -"{% c #7D64A7", -"]% c #BC9FC6", -"^% c #46394A", -"/% c #0B080D", -"(% c #0F0B11", -"_% c #55475C", -":% c #B193C6", -"<% c #3D2F6F", -"[% c #B496C0", -"}% c #493D4E", -"|% c #605067", -"1% c #B698CC", -"2% c #48387A", -"3% c #B79AC0", -"4% c #3E3342", -"5% c #060408", -"6% c #1E1820", -"7% c #78657F", -"8% c #A184BA", -"9% c #735B99", -"0% c #A68DAC", -"a% c #3D3341", -"b% c #8C7792", -"c% c #9075AE", -"d% c #8268A1", -"e% c #8F7996", -"f% c #29222C", -"g% c #040205", -"h% c #2A212C", -"i% c #997F9E", -"j% c #735E92", -"k% c #856C9F", -"l% c #8D7493", -"m% c #514257", -"n% c #A789B0", -"o% c #4F4074", -"p% c #9B7FB3", -"q% c #65526D", -"r% c #1B151D", -"s% c #3E3242", -"t% c #B192BC", -"u% c #382E5D", -"v% c #A386BA", -"w% c #5A4961", -"x% c #4C3E51", -"y% c #A88BBC", -"z% c #282049", -"A% c #AD8FC0", -"B% c #504156", -"C% c #0D090F", -"D% c #000001", -"E% c #0F0A10", -"F% c #534359", -"G% c #A98CBE", -"H% c #302753", -"I% c #AD8FBD", -"J% c #46394B", -"K% c #5C4B63", -"L% c #AF91C2", -"M% c #3C3162", -"N% c #B293BC", -"O% c #3C3040", -"P% c #1D161F", -"Q% c #75617C", -"R% c #987DB0", -"S% c #675488", -"T% c #A487A8", -"U% c #3B303F", -"V% c #89718F", -"W% c #876EA1", -"X% c #776196", -"Y% c #8C7392", -"Z% c #28202B", -"`% c #271E29", -" & c #987D9B", -".& c #7C6693", -"+& c #392E4E", -"@& c #AC8DBB", -"#& c #977C9F", -"$& c #A487B6", -"%& c #191326", -"&& c #A285B3", -"*& c #624F68", -"=& c #19121A", -"-& c #040204", -";& c #3D3140", -">& c #AF8FBA", -",& c #352B4A", -"'& c #997EAD", -")& c #6F5A78", -"!& c #695671", -"~& c #A184B3", -"{& c #201A2F", -"]& c #AA8BBA", -"^& c #504155", -"/& c #0D090E", -"(& c #0E0A10", -"_& c #524257", -":& c #A789B9", -"<& c #2D2440", -"[& c #AB8DBA", -"}& c #453749", -"|& c #5B4961", -"1& c #AD8EBB", -"2& c #392E50", -"3& c #B091BA", -"4& c #3B2F3F", -"5& c #1C151E", -"6& c #745F79", -"7& c #967BA6", -"8& c #65527D", -"9& c #A285A6", -"0& c #3A2E3D", -"a& c #88708C", -"b& c #846C99", -"c& c #745F8A", -"d& c #8B7290", -"e& c #281F2A", -"f& c #19131B", -"g& c #624F66", -"h& c #B191BD", -"i& c #4C3E60", -"j& c #3A2F4C", -"k& c #6D5985", -"l& c #241D31", -"m& c #6D5982", -"n& c #B090B8", -"o& c #4B3C4E", -"p& c #3C2F3E", -"q& c #B090B9", -"r& c #3A2F4E", -"s& c #58476C", -"t& c #A285B2", -"u& c #A588B5", -"v& c #705C84", -"w& c #14101B", -"x& c #4F3F53", -"y& c #0D080E", -"z& c #0E090F", -"A& c #514155", -"B& c #AA8BB9", -"C& c #2D253D", -"D& c #5B4A61", -"E& c #AD8EBA", -"F& c #3F3354", -"G& c #B292B9", -"H& c #1B141D", -"I& c #745E78", -"J& c #997DA9", -"K& c #64527B", -"L& c #89708C", -"M& c #836C98", -"N& c #79638E", -"O& c #8B718F", -"P& c #070508", -"Q& c #2B222D", -"R& c #69566E", -"S& c #B292C3", -"T& c #645283", -"U& c #473A64", -"V& c #7D669A", -"W& c #55455B", -"X& c #201922", -"Y& c #2E2530", -"Z& c #9D82A1", -"`& c #9C80B6", -" * c #4A3C68", -".* c #473964", -"+* c #473A65", -"@* c #816A9F", -"#* c #B192B8", -"$* c #3F3342", -"%* c #09060A", -"&* c #0A070B", -"** c #413545", -"=* c #B091B9", -"-* c #876FAB", -";* c #B192BD", -">* c #453848", -",* c #5C4B61", -"'* c #BA99CD", -")* c #A083BA", -"!* c #977D9B", -"~* c #2D242F", -"{* c #140F15", -"]* c #59495D", -"^* c #B595C5", -"/* c #8F75B2", -"(* c #8A718E", -"_* c #9E81B9", -":* c #B292C5", -"<* c #6F5B74", -"[* c #1D161E", -"}* c #0A060B", -"|* c #2C222E", -"1* c #65526A", -"2* c #A285A7", -"3* c #A184A8", -"4* c #9E81A2", -"5* c #211923", -"6* c #120D13", -"7* c #453748", -"8* c #947997", -"9* c #A083A8", -"0* c #A183A8", -"a* c #9E81A1", -"b* c #1C151D", -"c* c #1E161F", -"d* c #544458", -"e* c #A083A3", -"f* c #8E7490", -"g* c #342935", -"h* c #483A4A", -"i* c #A487A6", -"j* c #8F7593", -"k* c #433546", -"l* c #110C12", -"m* c #2B212D", -"n* c #6B576F", -"o* c #A587A8", -"p* c #7C657D", -"q* c #2B212C", -"r* c #68556A", -"s* c #7A637E", -"t* c #342936", -"u* c #080508", -"v* c #1F1720", -"w* c #322734", -"x* c #362A38", -"y* c #2F2531", -"z* c #181219", -"A* c #120C13", -"B* c #352A38", -"C* c #362B39", -"D* c #362B38", -"E* c #2E2430", -"F* c #171118", -"G* c #2B222C", -"H* c #0F0B10", -"I* c #302631", -"J* c #2A212B", -"K* c #100B11", -"L* c #070407", -"M* c #201821", -"N* c #322733", -"O* c #251C25", -"P* c #0B070B", -"Q* c #201921", -"R* c #241C25", -"S* c #050305", -"T* c #060406", -"U* c #020103", -"V* c #020204", -"W* c #030305", -"X* c #050307", -"Y* c #09070E", -"Z* c #0E0B15", -"`* c #0B0910", -" = c #0A080D", -".= c #09080C", -"+= c #09070B", -"@= c #09070C", -"#= c #0A080E", -"$= c #0A080F", -"%= c #09070F", -"&= c #07050C", -"*= c #050409", -"== c #040308", -"-= c #050408", -";= c #030205", -">= c #0F0C14", -",= c #13101A", -"'= c #1A1625", -")= c #1D182B", -"!= c #201A2C", -"~= c #201A2A", -"{= c #241D2E", -"]= c #261F30", -"^= c #261F32", -"/= c #2A2338", -"(= c #231D31", -"_= c #1D192B", -":= c #1C182A", -"<= c #1A1527", -"[= c #181425", -"}= c #171324", -"|= c #151121", -"1= c #120F1F", -"2= c #0B0815", -"3= c #030206", -"4= c #0B080E", -"5= c #14101A", -"6= c #241E30", -"7= c #2A233A", -"8= c #2D253E", -"9= c #362D4D", -"0= c #4C3F6D", -"a= c #403457", -"b= c #44375A", -"c= c #4B3D64", -"d= c #554673", -"e= c #5A4A7B", -"f= c #625188", -"g= c #64538D", -"h= c #504271", -"i= c #463A64", -"j= c #433762", -"k= c #433764", -"l= c #392F56", -"m= c #342B4F", -"n= c #332B50", -"o= c #26203C", -"p= c #30284C", -"q= c #2A2343", -"r= c #0F0C1B", -"s= c #010103", -"t= c #1A1622", -"u= c #272032", -"v= c #2F273C", -"w= c #473A60", -"x= c #7A65A3", -"y= c #846DAA", -"z= c #A388BE", -"A= c #BCA4D2", -"B= c #BFA9D1", -"C= c #C9B6D6", -"D= c #D1C1DC", -"E= c #DACCE1", -"F= c #DACAE1", -"G= c #D4C3DE", -"H= c #C8B3D8", -"I= c #B49ACB", -"J= c #A084BE", -"K= c #967CBF", -"L= c #7964A7", -"M= c #5A4B81", -"N= c #4F4276", -"O= c #51447C", -"P= c #453A6B", -"Q= c #2A2341", -"R= c #1E192F", -"S= c #100C1A", -"T= c #090710", -"U= c #060509", -"V= c #100D16", -"W= c #1F1A28", -"X= c #2A2336", -"Y= c #352B45", -"Z= c #554671", -"`= c #9178AC", -" - c #C8B5D7", -".- c #DED1E2", -"+- c #E6DCE7", -"@- c #D9D6D9", -"#- c #C3C3C4", -"$- c #ADACAE", -"%- c #A4A3A4", -"&- c #8D8C8F", -"*- c #8E8D90", -"=- c #A3A3A3", -"-- c #AEACAF", -";- c #BFBFBF", -">- c #D7D5D7", -",- c #DCCEE2", -"'- c #C6AFD8", -")- c #AB8ECC", -"!- c #9F85C8", -"~- c #473B65", -"{- c #2B2440", -"]- c #28213E", -"^- c #1A1629", -"/- c #151223", -"(- c #0C0914", -"_- c #040307", -":- c #0C0A11", -"<- c #1E1826", -"[- c #292235", -"}- c #382E4A", -"|- c #675486", -"1- c #A78DBE", -"2- c #D3C3DD", -"3- c #E3DEE3", -"4- c #C6C5C6", -"5- c #9A9B9B", -"6- c #646465", -"7- c #565656", -"8- c #505050", -"9- c #4C4C4D", -"0- c #484848", -"a- c #444445", -"b- c #404040", -"c- c #3C3C3D", -"d- c #373737", -"e- c #47464B", -"f- c #939294", -"g- c #E3E0E4", -"h- c #E7E0E9", -"i- c #AF96C8", -"j- c #75609C", -"k- c #5C4C85", -"l- c #443967", -"m- c #403664", -"n- c #30284B", -"o- c #0E0B17", -"p- c #07060D", -"q- c #0E0C15", -"r- c #17131E", -"s- c #282133", -"t- c #342B44", -"u- c #685588", -"v- c #AD94C3", -"w- c #DBCEE1", -"x- c #D6D4D6", -"y- c #A5A5A6", -"z- c #666565", -"A- c #636363", -"B- c #616161", -"C- c #605F62", -"D- c #5C5C5E", -"E- c #5C5B62", -"F- c #666277", -"G- c #68627C", -"H- c #605B70", -"I- c #53505D", -"J- c #4B4952", -"K- c #544F66", -"L- c #464451", -"M- c #38383A", -"N- c #35343A", -"O- c #2E2D2E", -"P- c #29292A", -"Q- c #1E1E1E", -"R- c #383738", -"S- c #9B9A9C", -"T- c #D3D1D4", -"U- c #DED1E3", -"V- c #BFA6D2", -"W- c #836CA9", -"X- c #3F345A", -"Y- c #27213A", -"Z- c #1E192C", -"`- c #171323", -" ; c #06050A", -".; c #06050B", -"+; c #08070F", -"@; c #0D0A15", -"#; c #120E1C", -"$; c #181423", -"%; c #221C2E", -"&; c #2B243A", -"*; c #4A3C62", -"=; c #9A81B5", -"-; c #D7C8DF", -";; c #D8D6D8", -">; c #6E6E6E", -",; c #6C6C6C", -"'; c #6A6A6A", -"); c #69696A", -"!; c #6C6B73", -"~; c #78738A", -"{; c #736E83", -"]; c #726D83", -"^; c #8A7FAA", -"/; c #9E8FC3", -"(; c #8378A3", -"_; c #6D6684", -":; c #595567", -"<; c #6C6388", -"[; c #58526B", -"}; c #42404A", -"|; c #484358", -"1; c #464157", -"2; c #353340", -"3; c #33303F", -"4; c #242329", -"5; c #1C1C1D", -"6; c #161616", -"7; c #818182", -"8; c #D8D6D9", -"9; c #9E83BD", -"0; c #50416D", -"a; c #2B243D", -"b; c #2D2643", -"c; c #201A32", -"d; c #0D0A16", -"e; c #07050D", -"f; c #07060E", -"g; c #06040B", -"h; c #110E1C", -"i; c #0C0A14", -"j; c #120F1C", -"k; c #120F1E", -"l; c #1C172C", -"m; c #241E38", -"n; c #2C2542", -"o; c #453963", -"p; c #79639D", -"q; c #BEA7CF", -"r; c #E1DBE2", -"s; c #ADADAD", -"t; c #747474", -"u; c #747475", -"v; c #747377", -"w; c #7A7783", -"x; c #7C7888", -"y; c #7E7A8D", -"z; c #9088AC", -"A; c #87809E", -"B; c #877FA0", -"C; c #9A8DBD", -"D; c #A998CE", -"E; c #9587B4", -"F; c #7B7297", -"G; c #726A8B", -"H; c #9182B5", -"I; c #655D7C", -"J; c #605877", -"K; c #544E68", -"L; c #665B86", -"M; c #4C4562", -"N; c #594E78", -"O; c #3B364E", -"P; c #272531", -"Q; c #201E28", -"R; c #17161D", -"S; c #9F9E9F", -"T; c #E3DCE4", -"U; c #C1ABD2", -"V; c #9C82C2", -"W; c #665599", -"X; c #352C50", -"Y; c #1E192E", -"Z; c #161223", -"`; c #161323", -" > c #1B172B", -".> c #120F1D", -"+> c #06050C", -"@> c #08060F", -"#> c #161222", -"$> c #100D1A", -"%> c #130F1E", -"&> c #1D182E", -"*> c #251F3A", -"=> c #261F3B", -"-> c #2D2647", -";> c #5E4E8F", -">> c #7C67B1", -",> c #A589CB", -"'> c #E0D4E4", -")> c #888889", -"!> c #7A7A7A", -"~> c #7B7B7B", -"{> c #7E7D83", -"]> c #898596", -"^> c #888495", -"/> c #817E8A", -"(> c #8D879F", -"_> c #938BAA", -":> c #9990B5", -"<> c #A296C0", -"[> c #837D97", -"}> c #9C8FB7", -"|> c #B4A3D5", -"1> c #DCCDEE", -"2> c #C4B2E0", -"3> c #C6B1E3", -"4> c #DAC4EF", -"5> c #CBBBE1", -"6> c #AC98D5", -"7> c #9C89C7", -"8> c #8B79B7", -"9> c #786AA1", -"0> c #7969A5", -"a> c #594E79", -"b> c #342F43", -"c> c #40385B", -"d> c #221F2E", -"e> c #15141A", -"f> c #0D0C10", -"g> c #5A595C", -"h> c #D1D0D2", -"i> c #DDCDE2", -"j> c #8871AB", -"k> c #2E2645", -"l> c #201B32", -"m> c #1A1628", -"n> c #231D36", -"o> c #0E0C17", -"p> c #1E1930", -"q> c #231D37", -"r> c #251F39", -"s> c #3C325C", -"t> c #8670B8", -"u> c #CAAEDB", -"v> c #E4DAE6", -"w> c #BFBFC0", -"x> c #7D7D7D", -"y> c #7F7F7F", -"z> c #85848B", -"A> c #948FA4", -"B> c #A39BB7", -"C> c #A69DBA", -"D> c #A59DBE", -"E> c #918CA0", -"F> c #8F899E", -"G> c #ACA1C4", -"H> c #B2A6CB", -"I> c #C1B3D8", -"J> c #C3B6D8", -"K> c #9F93BC", -"L> c #C1B1DC", -"M> c #D3BFE7", -"N> c #E3D5F1", -"O> c #E3D4F1", -"P> c #EDE0F3", -"Q> c #F3EDF6", -"R> c #E2CFF1", -"S> c #E4CDF2", -"T> c #9B87C9", -"U> c #8C7ABA", -"V> c #B8A3DE", -"W> c #7968A1", -"X> c #51476E", -"Y> c #5D5083", -"Z> c #41385D", -"`> c #2A243C", -" , c #1B1829", -"., c #100D19", -"+, c #010104", -"@, c #B7B6B8", -"#, c #E2D7E5", -"$, c #BAA1D4", -"%, c #514374", -"&, c #1F1A2D", -"*, c #292240", -"=, c #191527", -"-, c #040407", -";, c #0C0913", -">, c #231D34", -",, c #423765", -"', c #645390", -"), c #A58AC5", -"!, c #E5DFE6", -"~, c #B4B3B5", -"{, c #808080", -"], c #848386", -"^, c #908D9B", -"/, c #A49EB7", -"(, c #B7ADC8", -"_, c #C6BED4", -":, c #C6BFD4", -"<, c #B9B0CA", -"[, c #B3A9C6", -"}, c #AEA5C1", -"|, c #BCB1CF", -"1, c #D8CFE8", -"2, c #DAD1EB", -"3, c #E3D9EF", -"4, c #C9BDDF", -"5, c #CBBCE0", -"6, c #E0D2EE", -"7, c #E6DBF2", -"8, c #F5F0F6", -"9, c #F2EAF5", -"0, c #DDCBEE", -"a, c #D0B9EC", -"b, c #D3BEEC", -"c, c #AC95D9", -"d, c #AD96DC", -"e, c #EFE3F5", -"f, c #B39ED2", -"g, c #B19CCE", -"h, c #9880C9", -"i, c #5B4D81", -"j, c #2E2942", -"k, c #3A3158", -"l, c #332A50", -"m, c #08060E", -"n, c #A1A1A2", -"o, c #E4DBE6", -"p, c #947BB4", -"q, c #44385F", -"r, c #27213B", -"s, c #0E0B16", -"t, c #040408", -"u, c #13101F", -"v, c #1D182D", -"w, c #231E37", -"x, c #29223B", -"y, c #473B64", -"z, c #A78CC7", -"A, c #E1D8E3", -"B, c #A7A7A8", -"C, c #858585", -"D, c #8E8D95", -"E, c #AAA3BC", -"F, c #BBB3C8", -"G, c #C8C3D6", -"H, c #CEC8DF", -"I, c #D9D1E9", -"J, c #D0C9DF", -"K, c #C3BAD0", -"L, c #CEC7DE", -"M, c #C6BDD7", -"N, c #DCD3EB", -"O, c #DDD4EC", -"P, c #EADFF2", -"Q, c #E7DCF0", -"R, c #DCD0EB", -"S, c #DED2EB", -"T, c #E7DCF2", -"U, c #F2ECF5", -"V, c #E9DFF2", -"W, c #B9A4DB", -"X, c #E2D0F1", -"Y, c #D7C4ED", -"Z, c #BCA6DE", -"`, c #C2ADE4", -" ' c #FDFCFE", -".' c #F3EBF8", -"+' c #F7F1F8", -"@' c #BAA0E1", -"#' c #65568B", -"$' c #4D416D", -"%' c #645392", -"&' c #372E54", -"*' c #100D1B", -"=' c #020104", -"-' c #A0A0A0", -";' c #DFD2E3", -">' c #8F76AF", -",' c #352B49", -"'' c #1F1A30", -")' c #0A0812", -"!' c #1B162A", -"~' c #29223A", -"{' c #443861", -"]' c #977DBF", -"^' c #E0D5E4", -"/' c #B4B2B4", -"(' c #868687", -"_' c #9A97A8", -":' c #A19CAF", -"<' c #A5A0B4", -"[' c #BAB4C7", -"}' c #CAC4D8", -"|' c #E8DEF2", -"1' c #F8F4F9", -"2' c #E8E3EF", -"3' c #D1CAE0", -"4' c #DAD2EA", -"5' c #D8CFE6", -"6' c #E3D9EE", -"7' c #F2EDF6", -"8' c #F1E9F5", -"9' c #ECE3F3", -"0' c #E4DAF0", -"a' c #EBE2F3", -"b' c #E6DAF1", -"c' c #C0ADDD", -"d' c #EADDF2", -"e' c #F7F4F8", -"f' c #EEE3F5", -"g' c #F5EFFA", -"h' c #E3CDF4", -"i' c #A48DCA", -"j' c #AE95D1", -"k' c #1A152A", -"l' c #06040C", -"m' c #9F9F9F", -"n' c #DCCFE2", -"o' c #8770A8", -"p' c #2E2640", -"q' c #07060B", -"r' c #030207", -"s' c #151122", -"t' c #3E3360", -"u' c #352C4B", -"v' c #8971AD", -"w' c #DBCDE2", -"x' c #C0C0C1", -"y' c #868688", -"z' c #918F99", -"A' c #A19DAF", -"B' c #B4AEC1", -"C' c #B3AEBF", -"D' c #B8B4C2", -"E' c #D2CCDF", -"F' c #D3CCE2", -"G' c #D2CBE2", -"H' c #EEE8F4", -"I' c #FEFEFE", -"J' c #F7F4F9", -"K' c #F8F5F9", -"L' c #DCD4EA", -"M' c #F2ECF6", -"N' c #F9F6F9", -"O' c #FBF9FB", -"P' c #FAF9FA", -"Q' c #F6F3F7", -"R' c #F6F2F8", -"S' c #F4EEF7", -"T' c #F5F1F8", -"U' c #C7B5DF", -"V' c #EEE4F5", -"W' c #E7D7F2", -"X' c #FCFBFC", -"Y' c #FAFAFB", -"Z' c #F9F5FA", -"`' c #E6D2F4", -" ) c #B395E0", -".) c #5A4B80", -"+) c #483C6B", -"@) c #372D54", -"#) c #221B39", -"$) c #151025", -"%) c #05030A", -"&) c #BCBBBC", -"*) c #D3C2DC", -"=) c #715D95", -"-) c #292239", -";) c #1C1727", -">) c #08060D", -",) c #030306", -"') c #0E0B18", -")) c #251E38", -"!) c #4B3F72", -"~) c #675591", -"{) c #CCB7D8", -"]) c #7D7E7E", -"^) c #838384", -"/) c #93909D", -"() c #A19CB0", -"_) c #ABA5BA", -":) c #C4BECF", -"<) c #C7C1D3", -"[) c #CEC8DE", -"}) c #DBD2E8", -"|) c #DED7EA", -"1) c #DED7E8", -"2) c #F7F3F8", -"3) c #FBFAFB", -"4) c #F1EAF5", -"5) c #F5F0F8", -"6) c #FCFCFC", -"7) c #FBFBFB", -"8) c #E3D6EF", -"9) c #FBFBFC", -"0) c #D3C0E7", -"a) c #D0BEEB", -"b) c #A58BD2", -"c) c #9179C5", -"d) c #5D4E83", -"e) c #8A7BA9", -"f) c #7A679F", -"g) c #282040", -"h) c #292043", -"i) c #282043", -"j) c #0C0918", -"k) c #151022", -"l) c #D4D2D5", -"m) c #C2AAD4", -"n) c #564778", -"o) c #2B2441", -"p) c #1B172A", -"q) c #110E1B", -"r) c #0B0813", -"s) c #473B6E", -"t) c #5F4F8A", -"u) c #AB8FCD", -"v) c #89898A", -"w) c #89888E", -"x) c #A19CB1", -"y) c #B3ACC1", -"z) c #BCB7C7", -"A) c #C8C2D5", -"B) c #EEE9F3", -"C) c #CDC8DB", -"D) c #E4DDEE", -"E) c #EAE2F3", -"F) c #DAD2E8", -"G) c #E9E0F1", -"H) c #F8F6F9", -"I) c #FDFDFD", -"J) c #F6F0F7", -"K) c #F5F1F7", -"L) c #F7F2F8", -"M) c #FAF8FB", -"N) c #F9F7FA", -"O) c #F8F5FA", -"P) c #B5A2D4", -"Q) c #EEE6F5", -"R) c #FBF8FC", -"S) c #EEE5F6", -"T) c #8A76B3", -"U) c #8772B2", -"V) c #8F78BE", -"W) c #7A66A2", -"X) c #E5DAEF", -"Y) c #A98CD1", -"Z) c #554481", -"`) c #7059A1", -" ! c #483970", -".! c #1A142D", -"+! c #04030A", -"@! c #5F5E60", -"#! c #E5E0E7", -"$! c #A389C3", -"%! c #4E4171", -"&! c #2C2544", -"*! c #0D0B16", -"=! c #28223D", -"-! c #65549A", -";! c #AC90D1", -">! c #DBCCE1", -",! c #AFAEB0", -"'! c #838387", -")! c #9592A2", -"!! c #ADA7BD", -"~! c #CBC4D9", -"{! c #DDD6E7", -"]! c #E4DCED", -"^! c #F8F6FA", -"/! c #E6DFF0", -"(! c #E6DEEF", -"_! c #E7DEF0", -":! c #F6F1F7", -"~ c #E1D0EC", -",~ c #8D73C2", -"'~ c #8169AD", -")~ c #B8A5CD", -"!~ c #A18AC3", -"~~ c #392D59", -"{~ c #281F41", -"]~ c #2E244C", -"^~ c #080612", -"/~ c #979798", -"(~ c #D5C6DE", -"_~ c #705D98", -":~ c #403560", -"<~ c #241E37", -"[~ c #090711", -"}~ c #272036", -"|~ c #42375A", -"1~ c #BDA3D2", -"2~ c #6F6F6E", -"3~ c #757576", -"4~ c #83808B", -"5~ c #9490A3", -"6~ c #BAB3CB", -"7~ c #DAD2E6", -"8~ c #E5DFED", -"9~ c #EEE9F4", -"0~ c #EDE6F4", -"a~ c #EBE5F2", -"b~ c #D2CBDF", -"c~ c #C7C2D2", -"d~ c #D7CFE4", -"e~ c #F1EBF5", -"f~ c #F9F9FA", -"g~ c #F9F8FA", -"h~ c #EBE2F2", -"i~ c #ECE4F2", -"j~ c #F3ECF5", -"k~ c #F7F4F7", -"l~ c #EFE7F4", -"m~ c #EFE6F4", -"n~ c #F4EFF6", -"o~ c #F2E9F5", -"p~ c #E9DEF3", -"q~ c #E1CDF1", -"r~ c #EBDCF3", -"s~ c #F2E6F5", -"t~ c #FAF6FB", -"u~ c #DCCCE8", -"v~ c #D9C7E3", -"w~ c #DCC8E1", -"x~ c #BCA2D2", -"y~ c #8269B0", -"z~ c #45376C", -"A~ c #2B2247", -"B~ c #0D0918", -"C~ c #DAD7DA", -"D~ c #AA90C4", -"E~ c #3A304F", -"F~ c #0F0D19", -"G~ c #06040A", -"H~ c #4C3F74", -"I~ c #7C679F", -"J~ c #DECEE1", -"K~ c #A9A9A9", -"L~ c #6D6D6D", -"M~ c #747476", -"N~ c #82808A", -"O~ c #A69EBA", -"P~ c #D0C8E1", -"Q~ c #D9D1EB", -"R~ c #E4DBEF", -"S~ c #FBFAFC", -"T~ c #FDFCFD", -"U~ c #F6F4F8", -"V~ c #E3DDEA", -"W~ c #D2CADD", -"X~ c #E4DBED", -"Y~ c #F1E8F4", -"Z~ c #F2EBF5", -"`~ c #F2EFF6", -" { c #E0D7EB", -".{ c #EBE6F2", -"+{ c #F2E9F4", -"@{ c #F0E6F3", -"#{ c #EEE6F4", -"${ c #E4D8F0", -"%{ c #E1CFEF", -"&{ c #E3D0F1", -"*{ c #E5D0F1", -"={ c #EDDCF4", -"-{ c #E7D2F3", -";{ c #C8B3DF", -">{ c #E1C9F2", -",{ c #EDE3F6", -"'{ c #ECE1F6", -"){ c #D8C9E5", -"!{ c #F3F0F5", -"~{ c #BAACD0", -"{{ c #5D4A8A", -"]{ c #2E254A", -"^{ c #110D1E", -"/{ c #0D0A19", -"({ c #A3A3A5", -"_{ c #D1C0DC", -":{ c #534471", -"<{ c #221C2F", -"[{ c #16121F", -"}{ c #0D0A14", -"|{ c #302846", -"1{ c #6A589E", -"2{ c #C1A5D9", -"3{ c #E3E0E3", -"4{ c #6C6A6D", -"5{ c #6B6C6B", -"6{ c #868392", -"7{ c #9690A7", -"8{ c #DFD6EC", -"9{ c #DBD3E9", -"0{ c #D8D0E7", -"a{ c #E4DEEE", -"b{ c #F3ECF6", -"c{ c #F4EFF7", -"d{ c #E8E0F1", -"e{ c #F4F1F7", -"f{ c #F7F5F8", -"g{ c #E6DFEF", -"h{ c #DED6EB", -"i{ c #ECE6F1", -"j{ c #E5DBEF", -"k{ c #DDD2EC", -"l{ c #E4D9EE", -"m{ c #E3D7F0", -"n{ c #E1D1EE", -"o{ c #BFACD9", -"p{ c #E2D2EE", -"q{ c #F1E6F5", -"r{ c #EFDFF4", -"s{ c #BFA9D7", -"t{ c #9984C1", -"u{ c #D5BCEC", -"v{ c #B9A0DE", -"w{ c #EBD3F3", -"x{ c #E5D7F0", -"y{ c #EFE6F5", -"z{ c #F4EFF5", -"A{ c #BEABD4", -"B{ c #675395", -"C{ c #1D172F", -"D{ c #1A152C", -"E{ c #1D1631", -"F{ c #0D0A1A", -"G{ c #484549", -"H{ c #E5DEE7", -"I{ c #9379B5", -"J{ c #312844", -"K{ c #1A1623", -"L{ c #0D0B14", -"M{ c #13101D", -"N{ c #2D2645", -"O{ c #816BB2", -"P{ c #DAC5E0", -"Q{ c #C8C8C9", -"R{ c #646464", -"S{ c #6C6C70", -"T{ c #7E7A8A", -"U{ c #8C879D", -"V{ c #9A93AE", -"W{ c #A59DB9", -"X{ c #BFB7CF", -"Y{ c #DBD3E8", -"Z{ c #ECE5F2", -"`{ c #E4DCEE", -" ] c #E9E1F2", -".] c #F6F3F8", -"+] c #EFE7F3", -"@] c #D5CDE3", -"#] c #D8D1E5", -"$] c #E0D8ED", -"%] c #E5DEEE", -"&] c #EBE2F1", -"*] c #CFC7DB", -"=] c #E0D6E9", -"-] c #ECE3F2", -";] c #BEB2CF", -">] c #C0B5D0", -",] c #B3A6C7", -"'] c #BBADD0", -")] c #D6C8E6", -"!] c #DAC7EC", -"~] c #A997C6", -"{] c #EEE3F4", -"]] c #DBCEE9", -"^] c #8C7AB0", -"/] c #CBB5E8", -"(] c #C7B1E1", -"_] c #D9BDEF", -":] c #CBB3E7", -"<] c #C9B0DF", -"[] c #D7CAE6", -"}] c #DBCEE5", -"|] c #6B569B", -"1] c #3B2F5B", -"2] c #1D1730", -"3] c #261E3F", -"4] c #CAC9CB", -"5] c #BBA2D1", -"6] c #41365C", -"7] c #211C2E", -"8] c #100D17", -"9] c #13101B", -"0] c #312842", -"a] c #9279B5", -"b] c #E4DAE7", -"c] c #A0A0A1", -"d] c #626262", -"e] c #6F6D77", -"f] c #7A7685", -"g] c #8B859D", -"h] c #B8ACCE", -"i] c #C7BDD7", -"j] c #CDC3DC", -"k] c #D9D1E5", -"l] c #F1ECF5", -"m] c #F1ECF6", -"n] c #D5CEE3", -"o] c #CCC6D7", -"p] c #D1C9DD", -"q] c #D5CEE2", -"r] c #D5CEE0", -"s] c #DBD2E6", -"t] c #BFB4CD", -"u] c #B1A8C0", -"v] c #7B7784", -"w] c #666568", -"x] c #636166", -"y] c #5E5D62", -"z] c #7B7389", -"A] c #AA9BBE", -"B] c #AC99C8", -"C] c #E0CEEE", -"D] c #F0E5F4", -"E] c #E8DBF2", -"F] c #D0B8E7", -"G] c #DCC7EC", -"H] c #EFDDF4", -"I] c #E7D5F3", -"J] c #DFC1F2", -"K] c #DDC3ED", -"L] c #CCB3E4", -"M] c #FAF7FB", -"N] c #F9F9F9", -"O] c #ECE3EE", -"P] c #DECAE4", -"Q] c #BBA3D4", -"R] c #584784", -"S] c #30264C", -"T] c #231C3A", -"U] c #06040D", -"V] c #9E9EA0", -"W] c #D5C3DE", -"X] c #5E4D82", -"Y] c #221D30", -"Z] c #181426", -"`] c #14111B", -" ^ c #3B3150", -".^ c #B094CB", -"+^ c #EBE8EC", -"@^ c #6D6C6F", -"#^ c #606061", -"$^ c #706D7A", -"%^ c #847E97", -"&^ c #9A90B2", -"*^ c #BEB3D1", -"=^ c #DFD6EB", -"-^ c #CAC0DA", -";^ c #D7CFE2", -">^ c #E4DBEE", -",^ c #ECE6F3", -"'^ c #F4EEF6", -")^ c #EDE4F3", -"!^ c #E4DBEC", -"~^ c #DCD3E8", -"{^ c #D8CFE2", -"]^ c #E4DAEE", -"^^ c #CDC3DA", -"/^ c #888290", -"(^ c #686868", -"_^ c #595959", -":^ c #4F4F4F", -"<^ c #5B5664", -"[^ c #86799C", -"}^ c #B7A2D0", -"|^ c #B69EDC", -"1^ c #CDBBE5", -"2^ c #F7F2F7", -"3^ c #F6EFF9", -"4^ c #CAB4E7", -"5^ c #A58EC6", -"6^ c #B596D8", -"7^ c #F6F2F7", -"8^ c #ECE5F0", -"9^ c #8F74C1", -"0^ c #403362", -"a^ c #151023", -"b^ c #0E0B1A", -"c^ c #05040C", -"d^ c #5B5B5E", -"e^ c #DDD0E2", -"f^ c #6A578D", -"g^ c #28213A", -"h^ c #211C34", -"i^ c #07060C", -"j^ c #15121D", -"k^ c #3B3151", -"l^ c #9E82BB", -"m^ c #DAD6DA", -"n^ c #575757", -"o^ c #5F5E61", -"p^ c #716D7E", -"q^ c #7E798F", -"r^ c #A99EC3", -"s^ c #E6DCF0", -"t^ c #F4EDF6", -"u^ c #F8F4FA", -"v^ c #F9F7FB", -"w^ c #F0E9F5", -"x^ c #EEE7F3", -"y^ c #ECE3F0", -"z^ c #F1E9F4", -"A^ c #CDC4DA", -"B^ c #8B8595", -"C^ c #646564", -"D^ c #5B5B5B", -"E^ c #515152", -"F^ c #4C4C4C", -"G^ c #474747", -"H^ c #424242", -"I^ c #414043", -"J^ c #544E5F", -"K^ c #8575A2", -"L^ c #D9BFEF", -"M^ c #EFE2F5", -"N^ c #DDD0ED", -"O^ c #C1A4E5", -"P^ c #A087CA", -"Q^ c #D4C6E2", -"R^ c #A692C4", -"S^ c #4D3E72", -"T^ c #2E2548", -"U^ c #1B162D", -"V^ c #2E244B", -"W^ c #18122A", -"X^ c #DED7DF", -"Y^ c #997EBE", -"Z^ c #433864", -"`^ c #16121D", -" / c #332A43", -"./ c #C7C6C8", -"+/ c #5F5D65", -"@/ c #6A6775", -"#/ c #787387", -"$/ c #9C90B7", -"%/ c #C0B3D7", -"&/ c #EEE5F4", -"*/ c #EFE9F4", -"=/ c #ECE4F3", -"-/ c #DFD6E9", -";/ c #E1D7EC", -">/ c #E2D8EC", -",/ c #E2D9ED", -"'/ c #E7DDEE", -")/ c #9D96A9", -"!/ c #696969", -"~/ c #656565", -"{/ c #4E4E4E", -"]/ c #4A4949", -"^/ c #454545", -"// c #40403F", -"(/ c #3A3A3A", -"_/ c #534C61", -":/ c #C1A6DC", -"( c #B398D8", -",( c #D1B2E7", -"'( c #D7BCEC", -")( c #DDBEEB", -"!( c #ECDFF0", -"~( c #D0C2E2", -"{( c #9E83C6", -"]( c #BCA5D2", -"^( c #AD93C8", -"/( c #6C579A", -"(( c #AD9BC9", -"_( c #B89BD6", -":( c #AB8BD3", -"<( c #9980BC", -"[( c #7760A7", -"}( c #5A4888", -"|( c #3D3062", -"1( c #A7A6A9", -"2( c #B9A3CB", -"3( c #392F4C", -"4( c #191521", -"5( c #08070B", -"6( c #1F1A29", -"7( c #44385B", -"8( c #CBB8D8", -"9( c #A6A6A6", -"0( c #4B4B4D", -"a( c #656078", -"b( c #887DA9", -"c( c #B1A0D1", -"d( c #D8CBE9", -"e( c #E7DCF1", -"f( c #EEE7F4", -"g( c #EEE5F3", -"h( c #BAAECB", -"i( c #676669", -"j( c #5E5E5F", -"k( c #555554", -"l( c #494949", -"m( c #323232", -"n( c #2D2D2D", -"o( c #282828", -"p( c #34303A", -"q( c #6A5C85", -"r( c #8975B1", -"s( c #AC91D1", -"t( c #BEA0DC", -"u( c #B697D1", -"v( c #967BBD", -"w( c #8169A7", -"x( c #C8B3D9", -"y( c #B69DCD", -"z( c #AA90C5", -"A( c #CAAFDA", -"B( c #C7A4D9", -"C( c #8C72B9", -"D( c #645094", -"E( c #9F82C9", -"F( c #8B70BA", -"G( c #4B3B74", -"H( c #161027", -"I( c #9B9B9C", -"J( c #C1ADD2", -"K( c #3D3251", -"L( c #1C1725", -"M( c #07060A", -"N( c #08060B", -"O( c #221C2C", -"P( c #483B60", -"Q( c #8D8C90", -"R( c #464648", -"S( c #5D596D", -"T( c #766D90", -"U( c #9285B3", -"V( c #B09DD2", -"W( c #B3A1D4", -"X( c #B2A1D2", -"Y( c #C5B7DD", -"Z( c #E7DEF2", -"`( c #EDE8F3", -" _ c #AB9FBD", -"._ c #59595A", -"+_ c #404041", -"@_ c #3C3C3C", -"#_ c #222223", -"$_ c #564B6B", -"%_ c #7D6AA1", -"&_ c #A489C8", -"*_ c #B093D3", -"=_ c #9177B2", -"-_ c #886FB0", -";_ c #8169A5", -">_ c #AD96C5", -",_ c #CBADD9", -"'_ c #BFA0D5", -")_ c #CAA9DA", -"!_ c #AC8BD1", -"~_ c #B697D4", -"{_ c #B198CF", -"]_ c #5D4B8B", -"^_ c #2D244A", -"/_ c #130F24", -"(_ c #9C9C9D", -"__ c #C5B1D4", -":_ c #403455", -"<_ c #1E1927", -"[_ c #0B090F", -"}_ c #231D2D", -"|_ c #483B5F", -"1_ c #CFC0DB", -"2_ c #8E8C90", -"3_ c #504D59", -"4_ c #635D76", -"5_ c #8A7DAD", -"6_ c #877BA6", -"7_ c #9386B4", -"8_ c #B6A6D2", -"9_ c #CAB7E3", -"0_ c #DDCFED", -"a_ c #DDD1EA", -"b_ c #9D90B3", -"c_ c #5B5A5C", -"d_ c #525252", -"e_ c #343434", -"f_ c #272727", -"g_ c #222222", -"h_ c #1F1F20", -"i_ c #504565", -"j_ c #8E77B3", -"k_ c #D4BAE4", -"l_ c #D4BAE3", -"m_ c #9D81C1", -"n_ c #59487B", -"o_ c #7A63A1", -"p_ c #AD90D0", -"q_ c #E0D0E4", -"r_ c #C9AFD9", -"s_ c #A78ACB", -"t_ c #9C7ECD", -"u_ c #987CC5", -"v_ c #715B9D", -"w_ c #4F4079", -"x_ c #403364", -"y_ c #362B57", -"z_ c #1A142E", -"A_ c #423658", -"B_ c #0B0914", -"C_ c #CBB9D8", -"D_ c #A5A5A5", -"E_ c #47454C", -"F_ c #5E5870", -"G_ c #7B709A", -"H_ c #8B7EAE", -"I_ c #B19ED8", -"J_ c #DFCDEF", -"K_ c #DDCCEE", -"L_ c #EEE4F4", -"M_ c #F3EEF6", -"N_ c #AA9DBC", -"O_ c #545455", -"P_ c #4A4A4A", -"Q_ c #383938", -"R_ c #232126", -"S_ c #594C71", -"T_ c #947CB7", -"U_ c #D8CAE2", -"V_ c #EFE9F0", -"W_ c #CAAFDC", -"X_ c #A287C6", -"Y_ c #E5D9E9", -"Z_ c #E1D4E8", -"`_ c #E1D7EA", -" : c #E5DBE9", -".: c #B4A0CD", -"+: c #8C72B6", -"@: c #635092", -"#: c #5D4A89", -"$: c #31274F", -"%: c #1C1630", -"&: c #0A0713", -"*: c #C2AED2", -"=: c #3E3352", -"-: c #1D1825", -";: c #28223F", -">: c #2C2543", -",: c #45385E", -"': c #A4A4A4", -"): c #424148", -"!: c #58536A", -"~: c #696180", -"{: c #7C719A", -"]: c #BDAADD", -"^: c #CEB9E9", -"/: c #EEE4F3", -"(: c #CDBCE0", -"_: c #B4A3CB", -":: c #6E677B", -"<: c #1B1B1B", -"[: c #2D2836", -"}: c #8F78B2", -"|: c #C9ACDC", -"1: c #D5C1E2", -"2: c #DDCAE4", -"3: c #DBCEE3", -"4: c #9176BA", -"5: c #BEA8D1", -"6: c #F1EBF2", -"7: c #F2F1F3", -"8: c #F1EFF2", -"9: c #E7E3ED", -"0: c #947CBA", -"a: c #836AB3", -"b: c #CFB7DC", -"c: c #AD8CD2", -"d: c #5B4988", -"e: c #18132A", -"f: c #A8A7AB", -"g: c #BAA3CC", -"h: c #392F4B", -"i: c #09080D", -"j: c #0F0C19", -"k: c #211B2E", -"l: c #403558", -"m: c #BAA3CE", -"n: c #B6B5B6", -"o: c #3B3A3F", -"p: c #4E495C", -"q: c #6B6287", -"r: c #887AAE", -"s: c #A793D3", -"t: c #DCCAEF", -"u: c #EFE5F4", -"v: c #E2D1EE", -"w: c #DDC9EE", -"x: c #8C7EA2", -"y: c #464546", -"z: c #1C1C1C", -"A: c #19191A", -"B: c #453B58", -"C: c #796596", -"D: c #9178BB", -"E: c #D5C1E4", -"F: c #EAE6EB", -"G: c #E6E2EC", -"H: c #D2BEDE", -"I: c #E0D3E5", -"J: c #DCCDE4", -"K: c #EEEAF0", -"L: c #D4BADE", -"M: c #AD90CE", -"N: c #E0D5E7", -"O: c #AF92CB", -"P: c #52427D", -"Q: c #1E1733", -"R: c #342B45", -"S: c #0A070E", -"T: c #1B1725", -"U: c #3B3152", -"V: c #B59ACC", -"W: c #C6C6C7", -"X: c #38373D", -"Y: c #534C67", -"Z: c #7D6FA4", -"`: c #8A7AB3", -" < c #A390CE", -".< c #E5D3F2", -"+< c #F9F5F9", -"@< c #EADEF3", -"#< c #DBCDEA", -"$< c #D7C2EA", -"%< c #8B7DA2", -"&< c #524E59", -"*< c #25222C", -"=< c #736196", -"-< c #C7ADDC", -";< c #EAE0EC", -">< c #EFEDF0", -",< c #EFEAF0", -"'< c #F7F7F7", -")< c #CAB6DC", -"!< c #C9B0DB", -"~< c #A286C4", -"{< c #8067B4", -"]< c #8E73B5", -"^< c #8B70B4", -"/< c #3C305F", -"(< c #181229", -"_< c #CDC9CF", -":< c #9D82B6", -"<< c #322942", -"[< c #16121E", -"}< c #2E263F", -"|< c #A085BC", -"1< c #DAD7DB", -"2< c #302F32", -"3< c #48435A", -"4< c #595171", -"5< c #8676AF", -"6< c #D8C6EF", -"7< c #EFE3F4", -"8< c #E6D6F2", -"9< c #ECDDF2", -"0< c #F5EDF5", -"a< c #F0E3F4", -"b< c #C3ADE0", -"c< c #CCB8E2", -"d< c #766B8C", -"e< c #4F4A58", -"f< c #1B191D", -"g< c #443A57", -"h< c #8E76B2", -"i< c #D1BBE2", -"j< c #EAE3EB", -"k< c #CFB3DB", -"l< c #D2BCDF", -"m< c #F9F7F9", -"n< c #F3F0F4", -"o< c #F6F4F6", -"p< c #E6DBEC", -"q< c #8E77AD", -"r< c #433565", -"s< c #4D3E74", -"t< c #413464", -"u< c #3E3161", -"v< c #1B1530", -"w< c #DDD4DF", -"x< c #866EAD", -"y< c #181424", -"z< c #0F0C18", -"A< c #120F19", -"B< c #745F99", -"C< c #E3D9E5", -"D< c #2A2A2B", -"E< c #383542", -"F< c #524A6A", -"G< c #907DBE", -"H< c #C1AAE0", -"I< c #F2E5F5", -"J< c #F4EBF5", -"K< c #EDE1F4", -"L< c #ECDFF4", -"M< c #F8F3F9", -"N< c #D1C0E2", -"O< c #C6AEDF", -"P< c #A48FC2", -"Q< c #645A78", -"R< c #3E3A45", -"S< c #292929", -"T< c #282430", -"U< c #3E354F", -"V< c #685788", -"W< c #544670", -"X< c #BDA4D3", -"Y< c #B8A0CF", -"Z< c #D6BEDE", -"`< c #DCD0E3", -" [ c #E6DBE9", -".[ c #FAFAFA", -"+[ c #F6F5F7", -"@[ c #C7B2DB", -"#[ c #A082C0", -"$[ c #7F66A2", -"%[ c #352A54", -"&[ c #020205", -"*[ c #625F65", -"=[ c #604F7F", -"-[ c #312845", -";[ c #110E19", -">[ c #0F0C16", -",[ c #231D33", -"'[ c #53446F", -")[ c #CEBCDA", -"![ c #939394", -"~[ c #343140", -"{[ c #5C527C", -"][ c #6A5D8D", -"^[ c #8F7CBD", -"/[ c #C4ACDF", -"([ c #F3E8F5", -"_[ c #F5EEF7", -":[ c #EBE1F3", -"<[ c #DDC9F0", -"[[ c #E7D1F2", -"}[ c #DEC5EF", -"|[ c #A28BC5", -"1[ c #4E465E", -"2[ c #272628", -"3[ c #222124", -"4[ c #2D2935", -"5[ c #2E2937", -"6[ c #4B4061", -"7[ c #6F5D8E", -"8[ c #7E6A9C", -"9[ c #8B73B1", -"0[ c #C8B2D6", -"a[ c #836DA4", -"b[ c #9D80C2", -"c[ c #8B72B1", -"d[ c #D6CCDF", -"e[ c #EDE9EF", -"f[ c #EFEAF3", -"g[ c #CBB5DD", -"h[ c #6F59A0", -"i[ c #31274E", -"j[ c #1D1732", -"k[ c #A0A0A3", -"l[ c #C6B3D5", -"m[ c #45395C", -"n[ c #2D253F", -"o[ c #09070D", -"p[ c #1C1726", -"q[ c #382E4B", -"r[ c #C5C4C6", -"s[ c #292730", -"t[ c #3E3851", -"u[ c #51486B", -"v[ c #6F6195", -"w[ c #9681C9", -"x[ c #CDB2ED", -"y[ c #E9D8F4", -"z[ c #F5EDF7", -"A[ c #E8DAF3", -"B[ c #C5AEDE", -"C[ c #F3EBF6", -"D[ c #D9BDF1", -"E[ c #8471A2", -"F[ c #62557C", -"G[ c #8F7AAF", -"H[ c #BC9ED5", -"I[ c #816E99", -"J[ c #9B81C5", -"K[ c #8770AE", -"L[ c #BDAAD5", -"M[ c #A890CB", -"N[ c #CAB0D9", -"O[ c #DDD2E3", -"P[ c #8F7BAF", -"Q[ c #A286C6", -"R[ c #BDA1D5", -"S[ c #C7B7D9", -"T[ c #D0C7E0", -"U[ c #EEE9F0", -"V[ c #DFCFE5", -"W[ c #F3F2F4", -"X[ c #F7F7F8", -"Y[ c #E0D5E9", -"Z[ c #BCA8D4", -"`[ c #55447A", -" } c #271F3F", -".} c #171226", -"+} c #110D1F", -"@} c #CCCBCE", -"#} c #CFB8DD", -"$} c #7E69B5", -"%} c #4A3E73", -"&} c #010002", -"*} c #171320", -"=} c #362D4E", -"-} c #9C81BE", -";} c #E4DFE5", -">} c #1D1D1D", -",} c #27252F", -"'} c #353144", -")} c #584D77", -"!} c #8C77BE", -"~} c #B498E5", -"{} c #D9C4F2", -"]} c #EAD9F4", -"^} c #F3EEF8", -"/} c #DDD4EB", -"(} c #CAB5DD", -"_} c #DCC5F1", -":} c #F3EAF6", -"<} c #D1BFEA", -"[} c #CDB0E7", -"}} c #917BB7", -"|} c #BFA0DF", -"1} c #EDD8F1", -"2} c #D4C7E1", -"3} c #7A65A1", -"4} c #B297D4", -"5} c #AD91D2", -"6} c #DDD1E7", -"7} c #B59DCE", -"8} c #B196C8", -"9} c #CBB5D8", -"0} c #B295CF", -"a} c #886FB8", -"b} c #987CC0", -"c} c #7C65A9", -"d} c #9B86B7", -"e} c #B89ED3", -"f} c #E0D6E7", -"g} c #D7C9E3", -"h} c #AE95D0", -"i} c #675398", -"j} c #453767", -"k} c #2A2144", -"l} c #1C162F", -"m} c #49494A", -"n} c #E0D5E3", -"o} c #876FB1", -"p} c #6A59A0", -"q} c #433869", -"r} c #110E18", -"s} c #2E2742", -"t} c #7B66A3", -"u} c #E4D9E6", -"v} c #9D9C9D", -"w} c #171817", -"x} c #1A1A1B", -"y} c #282531", -"z} c #4F446C", -"A} c #8571B7", -"B} c #CAB1E8", -"C} c #ECD3F4", -"D} c #F9F4FA", -"E} c #F4ECF7", -"F} c #F3ECF7", -"G} c #C5AEE2", -"H} c #D0B4EA", -"I} c #EDE6F3", -"J} c #D2BAEB", -"K} c #DDCAED", -"L} c #CFBEE7", -"M} c #EDDDF4", -"N} c #EBD9F3", -"O} c #D1B7E6", -"P} c #DFC0E9", -"Q} c #EADDF0", -"R} c #F4F0F5", -"S} c #9080A5", -"T} c #8878A1", -"U} c #C1AAD7", -"V} c #AE8FCE", -"W} c #C6B8D5", -"X} c #A187C9", -"Y} c #9E85B9", -"Z} c #BC9ED0", -"`} c #BEA9D5", -" | c #B79DCF", -".| c #A58DC1", -"+| c #655290", -"@| c #AA97C7", -"#| c #EAE4EF", -"$| c #D6C5E1", -"%| c #9079B3", -"&| c #6C5798", -"*| c #1B152E", -"=| c #A5A5A7", -"-| c #C6B2D4", -";| c #473A5E", -">| c #322946", -",| c #07050F", -"'| c #7460A1", -")| c #CEB7DC", -"!| c #D7D5D8", -"~| c #242130", -"{| c #554979", -"]| c #8872BE", -"^| c #A68CDB", -"/| c #CDACEE", -"(| c #F0E2F6", -"_| c #E4D3F4", -":| c #A98FCF", -"<| c #7C6AA1", -"[| c #AF96D2", -"}| c #D4C3E6", -"|| c #B29BD1", -"1| c #E7E0EF", -"2| c #EBE0F1", -"3| c #CCB0DE", -"4| c #DCD0E7", -"5| c #E1CFE9", -"6| c #C2A3DA", -"7| c #E3D1E7", -"8| c #EDE8EE", -"9| c #C5B8D3", -"0| c #524371", -"a| c #C7BCD4", -"b| c #DBD0E5", -"c| c #BC9BD3", -"d| c #E4DBEA", -"e| c #C4AFDA", -"f| c #CDB9DD", -"g| c #EDE6EE", -"h| c #EFE9F1", -"i| c #D8D0E3", -"j| c #ECE6F0", -"k| c #F0ECF1", -"l| c #D7C6E2", -"m| c #B195CB", -"n| c #51417A", -"o| c #191429", -"p| c #05040A", -"q| c #010007", -"r| c #DBD7DD", -"s| c #9980B5", -"t| c #302843", -"u| c #1B1627", -"v| c #0A0810", -"w| c #1A1525", -"x| c #2E2642", -"y| c #705C93", -"z| c #D9C9E0", -"A| c #838285", -"B| c #1D1A28", -"C| c #443A63", -"D| c #7461A3", -"E| c #6C5B99", -"F| c #B597E1", -"G| c #DCBFF1", -"H| c #F9F2F9", -"I| c #FEFEFF", -"J| c #F4E8F7", -"K| c #CAB9E2", -"L| c #9F85C3", -"M| c #DEBFEE", -"N| c #FAF6FA", -"O| c #B499D3", -"P| c #DACFE9", -"Q| c #D9C1E4", -"R| c #EADEF0", -"S| c #D9C8E3", -"T| c #D9C8E1", -"U| c #C8ACD6", -"V| c #EAE6EC", -"W| c #E4DAE8", -"X| c #9A7EC0", -"Y| c #C8B4D8", -"Z| c #DFD2E5", -"`| c #C5AED7", -" 1 c #DDD1E5", -".1 c #E8DCEB", -"+1 c #F1EFF3", -"@1 c #F4F1F5", -"#1 c #F4F3F5", -"$1 c #EEEBF1", -"%1 c #9278B6", -"&1 c #765FA6", -"*1 c #51417C", -"=1 c #211A36", -"-1 c #130F22", -";1 c #959597", -">1 c #D2C2DC", -",1 c #615082", -"'1 c #29223C", -")1 c #15121E", -"!1 c #0D0A13", -"~1 c #261F35", -"{1 c #4E416F", -"]1 c #AA8FC3", -"^1 c #D7D4D8", -"/1 c #0E0E12", -"(1 c #252037", -"_1 c #342C4C", -":1 c #6D5B9D", -"<1 c #C1A1E3", -"[1 c #DFC2EE", -"}1 c #F6ECF8", -"|1 c #F6F0F8", -"11 c #EBDEF3", -"21 c #A388CA", -"31 c #A98ED0", -"41 c #AE92D2", -"51 c #E0D2EB", -"61 c #DBCCE9", -"71 c #EFE9F2", -"81 c #EFEBF0", -"91 c #E7DCE8", -"01 c #D6C1DE", -"a1 c #DED4E5", -"b1 c #F5F4F6", -"c1 c #BFADD5", -"d1 c #886FB3", -"e1 c #D5C2E0", -"f1 c #F4F1F6", -"g1 c #DCCAE2", -"h1 c #F5F2F6", -"i1 c #F0EDF1", -"j1 c #BFAED7", -"k1 c #362B54", -"l1 c #201934", -"m1 c #151125", -"n1 c #080610", -"o1 c #312E33", -"p1 c #D9D5DA", -"q1 c #A289BD", -"r1 c #1E1929", -"s1 c #1B1628", -"t1 c #453A67", -"u1 c #7B65A7", -"v1 c #D8C8DF", -"w1 c #0C0B10", -"x1 c #231D35", -"y1 c #463A69", -"z1 c #A689D2", -"A1 c #DDC0E9", -"B1 c #E3D7EF", -"C1 c #E1CAEC", -"D1 c #F6EDF7", -"E1 c #D3BFE6", -"F1 c #B99ADC", -"G1 c #C8ADDE", -"H1 c #B6AACF", -"I1 c #EADDEB", -"J1 c #F8F8F8", -"K1 c #DBD1E3", -"L1 c #B79ACE", -"M1 c #E3D5E6", -"N1 c #E2D5E5", -"O1 c #BFB3D2", -"P1 c #BFA2D7", -"Q1 c #E6DCEC", -"R1 c #E1D3E7", -"S1 c #F1EDF3", -"T1 c #DED3E6", -"U1 c #120E20", -"V1 c #A9A9AB", -"W1 c #D1BEDB", -"X1 c #5D4C7C", -"Y1 c #272035", -"Z1 c #1A1627", -"`1 c #0F0C1A", -" 2 c #4B3E6D", -".2 c #BBA2D2", -"+2 c #E8E6E9", -"@2 c #110E1D", -"#2 c #3D325F", -"$2 c #755FAA", -"%2 c #A98BD3", -"&2 c #BC9EDB", -"*2 c #8D76BF", -"=2 c #C2A8DE", -"-2 c #F0E8F2", -";2 c #D8C0E6", -">2 c #E8DDEE", -",2 c #A58CC9", -"'2 c #BCA0D5", -")2 c #E8E1EE", -"!2 c #F4F4F5", -"~2 c #DECBE3", -"{2 c #F2EEF4", -"]2 c #E8E2EE", -"^2 c #7A639C", -"/2 c #C4B6D6", -"(2 c #E7DEE9", -"_2 c #E4D7E8", -":2 c #E4DBE8", -"<2 c #F1EDF5", -"[2 c #F8F8F9", -"}2 c #CBB2DB", -"|2 c #D9C5E2", -"12 c #E3D7E6", -"22 c #EEEBF2", -"32 c #C7B5DA", -"42 c #7863A3", -"52 c #261E3E", -"62 c #140F24", -"72 c #E0D8E2", -"82 c #8A72AA", -"92 c #342B49", -"02 c #251F38", -"a2 c #2B2443", -"b2 c #2C2545", -"c2 c #0B0812", -"d2 c #1E192D", -"e2 c #4E4177", -"f2 c #A68AD2", -"g2 c #DDCCE2", -"h2 c #493B72", -"i2 c #6C57A1", -"j2 c #675394", -"k2 c #564681", -"l2 c #A086C7", -"m2 c #E0CDE5", -"n2 c #A184C8", -"o2 c #F1EBF4", -"p2 c #D2C5DE", -"q2 c #8C75AE", -"r2 c #B69BCF", -"s2 c #F3EDF4", -"t2 c #DACBE2", -"u2 c #C9AED9", -"v2 c #D8C8DE", -"w2 c #B29BCA", -"x2 c #E4DCE8", -"y2 c #E0D4E5", -"z2 c #ECE7ED", -"A2 c #E9E3EC", -"B2 c #B59FD1", -"C2 c #E7DFEC", -"D2 c #8A70B0", -"E2 c #624F89", -"F2 c #9E85BC", -"G2 c #C8B0D9", -"H2 c #BEACD5", -"I2 c #BEA6D7", -"J2 c #665298", -"K2 c #3F3262", -"L2 c #B9A1CE", -"M2 c #4F416D", -"N2 c #3A3159", -"O2 c #31294C", -"P2 c #141120", -"Q2 c #0D0B15", -"R2 c #050308", -"S2 c #151020", -"T2 c #6C5A9E", -"U2 c #B496D6", -"V2 c #E3DAE6", -"W2 c #B7B7B8", -"X2 c #231B3B", -"Y2 c #332851", -"Z2 c #2F254B", -"`2 c #443668", -" 3 c #BA9ED5", -".3 c #725CA3", -"+3 c #E8DDEC", -"@3 c #B192CE", -"#3 c #685495", -"$3 c #E6DAE8", -"%3 c #F7F6F8", -"&3 c #F0EEF1", -"*3 c #EBE2ED", -"=3 c #B395CF", -"-3 c #BFA2D8", -";3 c #E9E0EC", -">3 c #D1BBDD", -",3 c #E3D6E7", -"'3 c #F5F5F6", -")3 c #EAE4EC", -"!3 c #DAC5E1", -"~3 c #D1C0E0", -"{3 c #B796D2", -"]3 c #614E86", -"^3 c #5C4A88", -"/3 c #6F5996", -"(3 c #5C4A87", -"_3 c #7B63A9", -":3 c #090612", -"<3 c #BCBBBF", -"[3 c #CFBBDA", -"}3 c #6A578E", -"|3 c #2D2642", -"13 c #1A162A", -"23 c #1B1528", -"33 c #322948", -"43 c #7A65A9", -"53 c #C7ABDB", -"63 c #E9E5EB", -"73 c #403365", -"83 c #5F4C8F", -"93 c #765FAA", -"03 c #705A9E", -"a3 c #D9C8E2", -"b3 c #CAB5DB", -"c3 c #EBE7EC", -"d3 c #D5C1E0", -"e3 c #DDCBE2", -"f3 c #A68ACD", -"g3 c #E6D7E8", -"h3 c #F1EEF2", -"i3 c #D9CBE2", -"j3 c #C2B1D5", -"k3 c #F3F1F3", -"l3 c #F1F1F2", -"m3 c #EBE6ED", -"n3 c #F5F3F5", -"o3 c #CEB5DD", -"p3 c #C4A4D9", -"q3 c #B498D5", -"r3 c #C6ACD8", -"s3 c #9177C2", -"t3 c #443769", -"u3 c #271F40", -"v3 c #241C3C", -"w3 c #A3A1A6", -"x3 c #D6C6DE", -"y3 c #745F94", -"z3 c #221C33", -"A3 c #110E1A", -"B3 c #1D182A", -"C3 c #3F3556", -"D3 c #7F69AD", -"E3 c #CEB3DC", -"F3 c #E5DDE7", -"G3 c #9E9D9E", -"H3 c #50407A", -"I3 c #695498", -"J3 c #675397", -"K3 c #7A62AE", -"L3 c #C0A8D6", -"M3 c #D3BCDF", -"N3 c #AF92D3", -"O3 c #BBA5CF", -"P3 c #C1ACD3", -"Q3 c #EDEBEF", -"R3 c #B293D5", -"S3 c #B49BD2", -"T3 c #CCB8DC", -"U3 c #E5DEE8", -"V3 c #EFEDF1", -"W3 c #EBE4EE", -"X3 c #CAB9DC", -"Y3 c #C4B4D4", -"Z3 c #B997D4", -"`3 c #9176C7", -" 4 c #685497", -".4 c #6A5598", -"+4 c #433668", -"@4 c #181329", -"#4 c #0C0916", -"$4 c #DBCDE1", -"%4 c #826BA0", -"&4 c #2E263E", -"*4 c #1F1A2A", -"=4 c #110D19", -"-4 c #0A0811", -";4 c #211B2F", -">4 c #382E55", -",4 c #6D5B9E", -"'4 c #080611", -")4 c #1F1834", -"!4 c #322750", -"~4 c #392D5A", -"{4 c #3B2F5C", -"]4 c #554480", -"^4 c #B49ACF", -"/4 c #C7A6D9", -"(4 c #9679C6", -"_4 c #C4A9D9", -":4 c #B497CA", -"<4 c #8269B5", -"[4 c #D4C1DE", -"}4 c #E2D6E6", -"|4 c #C7B3DC", -"14 c #7E66B5", -"24 c #997EBD", -"34 c #AF8FD3", -"44 c #BFA4D8", -"54 c #AD8DD2", -"64 c #C7ACDB", -"74 c #BE9FD8", -"84 c #8B74B5", -"94 c #46386A", -"04 c #725C9C", -"a4 c #493A70", -"b4 c #30264D", -"c4 c #120E21", -"d4 c #9F9FA2", -"e4 c #DACCE0", -"f4 c #876FA4", -"g4 c #342B46", -"h4 c #1F1A2C", -"i4 c #362D52", -"j4 c #524474", -"k4 c #967DB7", -"l4 c #B4B4B4", -"m4 c #0D0A18", -"n4 c #1A142C", -"o4 c #231B39", -"p4 c #372C57", -"q4 c #292041", -"r4 c #755EAB", -"s4 c #9B7DCA", -"t4 c #BC9DD6", -"u4 c #6F5AA2", -"v4 c #C9AADA", -"w4 c #B899D2", -"x4 c #9075BB", -"y4 c #7C64A5", -"z4 c #584783", -"A4 c #A384CA", -"B4 c #886EC1", -"C4 c #6D58A0", -"D4 c #8B70C0", -"E4 c #876DB7", -"F4 c #6F5A99", -"G4 c #2E2549", -"H4 c #292042", -"I4 c #2F254C", -"J4 c #0C0917", -"K4 c #292731", -"L4 c #BCBBBD", -"M4 c #826BA1", -"N4 c #352C47", -"O4 c #241E2E", -"P4 c #151120", -"Q4 c #1C182B", -"R4 c #272137", -"S4 c #957BBB", -"T4 c #CFCECF", -"U4 c #58585A", -"V4 c #19132B", -"W4 c #140F23", -"X4 c #282042", -"Y4 c #443669", -"Z4 c #9579BF", -"`4 c #735C9F", -" 5 c #423464", -".5 c #594883", -"+5 c #8F74BD", -"@5 c #69559A", -"#5 c #594784", -"$5 c #634F92", -"%5 c #4C3D73", -"&5 c #534379", -"*5 c #705A9B", -"=5 c #4F3F77", -"-5 c #5C4A8A", -";5 c #645196", -">5 c #2F254A", -",5 c #2A2143", -"'5 c #1D1731", -")5 c #0B0814", -"!5 c #5E5E61", -"~5 c #D7C5DF", -"{5 c #8B73AF", -"]5 c #352C48", -"^5 c #251E2F", -"/5 c #0E0B13", -"(5 c #08060C", -"_5 c #08070E", -":5 c #100D18", -"<5 c #2E2646", -"[5 c #483C68", -"}5 c #77629F", -"|5 c #C7B0D8", -"15 c #E4DEE4", -"25 c #0B0816", -"35 c #2E254B", -"45 c #3F3263", -"55 c #3E3160", -"65 c #1A152B", -"75 c #5D4B8C", -"85 c #453769", -"95 c #2B2244", -"05 c #4A3B71", -"a5 c #221B38", -"b5 c #3F3264", -"c5 c #0E0B1B", -"d5 c #06050D", -"e5 c #0E0C14", -"f5 c #A8A8AB", -"g5 c #9077C1", -"h5 c #4E4172", -"i5 c #241E36", -"j5 c #15111E", -"k5 c #382E52", -"l5 c #604F85", -"m5 c #A388BF", -"n5 c #D9CBE0", -"o5 c #D9D7D9", -"p5 c #848384", -"q5 c #110D20", -"r5 c #0E0B19", -"s5 c #161126", -"t5 c #372C58", -"u5 c #352A55", -"v5 c #1D1630", -"w5 c #151024", -"x5 c #100C1D", -"y5 c #07050E", -"z5 c #969698", -"A5 c #DBDADC", -"B5 c #AA8FCD", -"C5 c #7B66B2", -"D5 c #6B59A2", -"E5 c #3A315A", -"F5 c #1C172B", -"G5 c #1E182B", -"H5 c #282136", -"I5 c #362D49", -"J5 c #68568A", -"K5 c #B198C7", -"L5 c #DFD3E4", -"M5 c #D6D4D8", -"N5 c #9A9A9A", -"O5 c #353335", -"P5 c #040309", -"Q5 c #130F23", -"R5 c #0F0C1C", -"S5 c #353538", -"T5 c #9E9DA0", -"U5 c #D9D8DA", -"V5 c #E6E2E8", -"W5 c #C2ABD7", -"X5 c #7B65A5", -"Y5 c #5D4D89", -"Z5 c #64549B", -"`5 c #514480", -" 6 c #231E38", -".6 c #07050B", -"+6 c #1F1928", -"@6 c #2A2337", -"#6 c #705C92", -"$6 c #B298C9", -"%6 c #D9CAE1", -"&6 c #C5C5C6", -"*6 c #919192", -"=6 c #504D54", -"-6 c #949397", -";6 c #E3DDE5", -">6 c #CFBDDC", -",6 c #CAACDA", -"'6 c #BA9DD3", -")6 c #665594", -"!6 c #433866", -"~6 c #332A4E", -"{6 c #241D39", -"]6 c #141021", -"^6 c #08070C", -"/6 c #110D16", -"(6 c #705D99", -"_6 c #9D82BD", -":6 c #BCA6D0", -"<6 c #D1C1DD", -"[6 c #E4DBE7", -"}6 c #DBD7DB", -"|6 c #C3C2C4", -"16 c #B4B3B6", -"26 c #989899", -"36 c #98989A", -"46 c #9E9D9F", -"56 c #C8C7C8", -"66 c #DBD6DC", -"76 c #E1D6E5", -"86 c #D5C2DE", -"96 c #C1AAD4", -"06 c #8E75B2", -"a6 c #7561A6", -"b6 c #7A65AF", -"c6 c #715FA5", -"d6 c #362D53", -"e6 c #120E1F", -"f6 c #17131F", -"g6 c #1E192A", -"h6 c #262036", -"i6 c #332A46", -"j6 c #3C3150", -"k6 c #4D3F66", -"l6 c #6A568A", -"m6 c #8C73A9", -"n6 c #A78DBF", -"o6 c #B79FC9", -"p6 c #C1AED2", -"q6 c #CAB7D7", -"r6 c #CFBEDB", -"s6 c #CEBDDA", -"t6 c #B7A0CA", -"u6 c #A88EBF", -"v6 c #8E75AA", -"w6 c #6B588D", -"x6 c #5F4F84", -"y6 c #463A62", -"z6 c #4A3E70", -"A6 c #423764", -"B6 c #393058", -"C6 c #2F2747", -"D6 c #1F192F", -"E6 c #130F1F", -"F6 c #0A0712", -"G6 c #030307", -"H6 c #0B0911", -"I6 c #0F0C15", -"J6 c #15111C", -"K6 c #1B1724", -"L6 c #2B2338", -"M6 c #443759", -"N6 c #4A3D63", -"O6 c #3E3351", -"P6 c #382E49", -"Q6 c #312840", -"R6 c #2D253A", -"S6 c #282134", -"T6 c #251F32", -"U6 c #241E32", -"V6 c #1A1528", -"W6 c #0C0A0F", -"X6 c #100D15", -"Y6 c #1C1724", -"Z6 c #211B2B", -"`6 c #1C1624", -" 7 c #18141F", -".7 c #0D0A10", -"+7 c #0D0B13", -"@7 c #313031", -"#7 c #3A393A", -"$7 c #414041", -"%7 c #3F3E3F", -"&7 c #222122", -"*7 c #3E3E3E", -"=7 c #BABABA", -"-7 c #BEBEBE", -";7 c #666666", -">7 c #BCBCBC", -",7 c #C5C5C5", -"'7 c #C6C6C6", -")7 c #252526", -"!7 c #262626", -"~7 c #6B6B6B", -"{7 c #BDBDBD", -"]7 c #C4C4C4", -"^7 c #A2A1A2", -"/7 c #BDBCBD", -"(7 c #C4C3C4", -"_7 c #707070", -":7 c #C3C2C2", -"<7 c #D2D2D2", -"[7 c #D9D9D9", -"}7 c #575657", -"|7 c #737373", -"17 c #F6F6F7", -"27 c #F1F1F1", -"37 c #ABABAB", -"47 c #171717", -"57 c #D4D3D4", -"67 c #EAE6EA", -"77 c #EBE7EB", -"87 c #AAAAAA", -"97 c #EFEEEF", -"07 c #EAE8EB", -"a7 c #EAE7EB", -"b7 c #EBE8EB", -"c7 c #363536", -"d7 c #D5D5D5", -"e7 c #EBE9EB", -"f7 c #F2F2F2", -"g7 c #A3A3A4", -"h7 c #D8D8D8", -"i7 c #EBE9EC", -"j7 c #EBEAEC", -"k7 c #ECEAEC", -"l7 c #F3F3F3", -"m7 c #A1A1A1", -"n7 c #1A191A", -"o7 c #DBDADB", -"p7 c #ECEBEC", -"q7 c #D9D8D9", -"r7 c #767676", -"s7 c #E6DDE6", -"t7 c #F1F0F1", -"u7 c #E1CFE1", -"v7 c #E4D9E4", -"w7 c #F2F2F3", -"x7 c #6C6B6C", -"y7 c #E1D3E2", -"z7 c #E5DDE6", -"A7 c #E6DEE7", -"B7 c #636364", -"C7 c #ECECEC", -"D7 c #E1D1E1", -"E7 c #E5DDE5", -"F7 c #EFEFEF", -"G7 c #C2C2C2", -"H7 c #717171", -"I7 c #E2D6E2", -"J7 c #EFEFF0", -"K7 c #E6DFE6", -"L7 c #212021", -"M7 c #747374", -"N7 c #F4F4F4", -"O7 c #E2D7E3", -"P7 c #E5DEE6", -"Q7 c #E9E4E9", -"R7 c #F3F3F4", -"S7 c #E3D8E3", -"T7 c #ECEBED", -"U7 c #EAE5EA", -"V7 c #C3C2C3", -"W7 c #E5E5E5", -"X7 c #D7D7D7", -"Y7 c #595859", -"Z7 c #757476", -"`7 c #8B8B8B", -" 8 c #E3D4E4", -".8 c #ECE8EC", -"+8 c #A7A6A7", -"@8 c #1B1A1B", -"#8 c #6E6D6E", -"$8 c #E5E4E5", -"%8 c #E1CEE1", -"&8 c #DDDCDD", -"*8 c #949394", -"=8 c #A3A2A4", -"-8 c #D1D1D2", -";8 c #484849", -">8 c #3D3C3D", -",8 c #8D8D8D", -"'8 c #D0CFD0", -")8 c #A5A4A5", -"!8 c #838383", -"~8 c #737273", -"{8 c #E2D2E3", -"]8 c #DDDDDD", -"^8 c #939293", -"/8 c #A6A5A6", -"(8 c #E4D6E5", -"_8 c #C4C4C5", -":8 c #DBDBDC", -"<8 c #929293", -"[8 c #EDEAEE", -"}8 c #E5D8E5", -"|8 c #797879", -"18 c #E3D6E4", -"28 c #D3D3D4", -"38 c #929292", -"48 c #A9A8A9", -"58 c #403F40", -"68 c #0C0B0C", -"78 c #686668", -"88 c #E3E2E4", -"98 c #DCC1DE", -"08 c #D5D4D6", -"a8 c #585758", -"b8 c #747375", -"c8 c #EEEBEF", -"d8 c #DBC2DF", -"e8 c #0E0D0F", -"f8 c #E0CEE3", -"g8 c #EBE4EC", -"h8 c #848284", -"i8 c #181819", -"j8 c #6D6C6D", -"k8 c #E2E0E3", -"l8 c #DCC3DF", -"m8 c #D5D5D6", -"n8 c #5C5B5C", -"o8 c #7D7C7E", -"p8 c #DEC7E1", -"q8 c #CFCFD0", -"r8 c #474647", -"s8 c #E1CDE2", -"t8 c #EDE8ED", -"u8 c #807E80", -"v8 c #0C0C0D", -"w8 c #727172", -"x8 c #828082", -"y8 c #EDE9ED", -"z8 c #E0CCE2", -"A8 c #454445", -"B8 c #757475", -"C8 c #EFECEF", -"D8 c #E0CAE1", -"E8 c #848385", -"F8 c #E1CEE2", -"G8 c #C2C1C3", -"H8 c #434243", -"I8 c #787678", -"J8 c #878587", -"K8 c #E3D1E4", -"L8 c #0B0B0C", -"M8 c #666567", -"N8 c #E0DDE1", -"O8 c #D0B1DB", -"P8 c #575658", -"Q8 c #737174", -"R8 c #CFB5DC", -"S8 c #100F10", -"T8 c #3E3D3E", -"U8 c #BEBDBF", -"V8 c #D7C3E0", -"W8 c #7F7D80", -"X8 c #252425", -"Y8 c #181718", -"Z8 c #6B6A6C", -"`8 c #E0DBE1", -" 9 c #D1B5DC", -".9 c #555456", -"+9 c #787779", -"@9 c #E4D9E7", -"#9 c #0B0A0B", -"$9 c #424243", -"%9 c #C0BFC1", -"&9 c #D7C1DF", -"*9 c #7B797C", -"=9 c #1A191B", -"-9 c #716F71", -";9 c #D4BBDE", -">9 c #525152", -",9 c #7D7B7E", -"'9 c #D6BFDF", -")9 c #C1C0C2", -"!9 c #444344", -"~9 c #201F21", -"{9 c #747274", -"]9 c #D6BDDE", -"^9 c #515051", -"/9 c #807E81", -"(9 c #EAE1EB", -"_9 c #D7C2E0", -":9 c #212022", -"<9 c #D7BFDF", -"[9 c #504F51", -"}9 c #E8E0EA", -"|9 c #ADACAD", -"19 c #656366", -"29 c #DED8DF", -"39 c #C0A1D8", -"49 c #D0CFD2", -"59 c #565457", -"69 c #716F73", -"79 c #E8E1EA", -"89 c #CFCED1", -"99 c #0C0B0E", -"09 c #0C0A0C", -"a9 c #3C3B3D", -"b9 c #BCBABD", -"c9 c #CBB6DD", -"d9 c #7D7A7F", -"e9 c #09090A", -"f9 c #171618", -"g9 c #6A686B", -"h9 c #DDD7DF", -"i9 c #C2A5D9", -"j9 c #565558", -"k9 c #E1E1E2", -"l9 c #C9C8CA", -"m9 c #1D1D1E", -"n9 c #403F41", -"o9 c #BEBCBF", -"p9 c #CBB4DC", -"q9 c #E5DCE9", -"r9 c #79767A", -"s9 c #1F1E20", -"t9 c #6F6D70", -"u9 c #E9E2EA", -"v9 c #C7ADDA", -"w9 c #7B787C", -"x9 c #E6DCE9", -"y9 c #CAB3DC", -"z9 c #BFBDC0", -"A9 c #434244", -"B9 c #201E20", -"C9 c #727073", -"D9 c #CAB0DB", -"E9 c #4F4D4F", -"F9 c #7D7B7F", -"G9 c #E5DBE8", -"H9 c #CCB6DD", -"I9 c #BEBDC0", -"J9 c #414042", -"K9 c #747276", -"L9 c #CBB3DC", -"M9 c #C3C2C5", -"N9 c #515052", -"O9 c #706F70", -"P9 c #E2E2E3", -"Q9 c #5B5A5B", -"R9 c #636165", -"S9 c #DBD3DD", -"T9 c #B090D5", -"U9 c #CECCD0", -"V9 c #545256", -"W9 c #6F6C71", -"X9 c #E3DAE8", -"Y9 c #B195D5", -"Z9 c #CDCCCF", -"`9 c #49474A", -" 0 c #0C0A0D", -".0 c #070708", -"+0 c #0A080B", -"@0 c #3B3A3C", -"#0 c #B9B8BC", -"$0 c #C0AADA", -"%0 c #DCD0E4", -"&0 c #202022", -"*0 c #68666A", -"=0 c #D9D0DD", -"-0 c #AF90D4", -";0 c #848089", -">0 c #7E7B82", -",0 c #8B888E", -"'0 c #757377", -")0 c #3A393B", -"!0 c #0A090B", -"~0 c #3F3E40", -"{0 c #BBBABE", -"]0 c #BFA8D9", -"^0 c #E0D5E6", -"/0 c #1E1D1F", -"(0 c #19181A", -"_0 c #6D6B6F", -":0 c #B99DD7", -"<0 c #4E4D50", -"[0 c #78767B", -"}0 c #BEA6D9", -"|0 c #424143", -"10 c #1F1D20", -"20 c #706D72", -"30 c #BBA1D8", -"40 c #CBCACD", -"50 c #4D4C4E", -"60 c #7B787E", -"70 c #DFD4E6", -"80 c #C0A9DA", -"90 c #BCBABE", -"00 c #727074", -"a0 c #BA9FD7", -"b0 c #837F87", -"c0 c #817E84", -"d0 c #8C8A8F", -"e0 c #717073", -"f0 c #353436", -"g0 c #131215", -"h0 c #615F64", -"i0 c #D6CCDB", -"j0 c #9E7FCC", -"k0 c #CBC7CE", -"l0 c #525155", -"m0 c #6C6970", -"n0 c #DDD4E5", -"o0 c #A285CA", -"p0 c #CAC9CD", -"q0 c #474649", -"r0 c #39383B", -"s0 c #B7B5B9", -"t0 c #B49DD2", -"u0 c #D4C7E2", -"v0 c #78747C", -"w0 c #141316", -"x0 c #646166", -"y0 c #D6CCDA", -"z0 c #896EC1", -"A0 c #BFABD6", -"B0 c #D3C7E2", -"C0 c #D4C9E2", -"D0 c #D7CBE3", -"E0 c #D6D2D9", -"F0 c #3E3C3F", -"G0 c #B9B7BC", -"H0 c #B199D3", -"I0 c #747077", -"J0 c #1D1C1E", -"K0 c #181719", -"L0 c #6B686E", -"M0 c #DFD5E5", -"N0 c #A98DD0", -"O0 c #4D4B4F", -"P0 c #76737A", -"Q0 c #AF97D1", -"R0 c #BAB8BC", -"S0 c #413F42", -"T0 c #1E1C1F", -"U0 c #6E6B71", -"V0 c #DFD5E6", -"W0 c #AC91D2", -"X0 c #C9C8CB", -"Y0 c #4C4A4D", -"Z0 c #78757C", -"`0 c #D8CCE3", -" a c #B39CD3", -".a c #3F3D40", -"+a c #1D1C1F", -"@a c #6E6B70", -"#a c #E0D7E6", -"$a c #9074C8", -"%a c #C7B5DB", -"&a c #D7CCE3", -"*a c #D8D5DA", -"=a c #6F6D71", -"-a c #201F20", -";a c #5F5C62", -">a c #D0C5D8", -",a c #896FBD", -"'a c #C8C1CB", -")a c #514E53", -"!a c #6A666E", -"~a c #9074BC", -"{a c #C7C4CA", -"]a c #464448", -"^a c #0A090C", -"/a c #38373A", -"(a c #B4B2B7", -"_a c #A58EC7", -":a c #CBBEDC", -"b c #C6C0C9", -",b c #4A474C", -"'b c #706B75", -")b c #CABBDB", -"!b c #9277B7", -"~b c #B4AFB8", -"{b c #3E3B40", -"]b c #1B1A1E", -"^b c #69646D", -"/b c #8C71B6", -"(b c #C3BFC6", -"_b c #48464B", -":b c #736D78", -"c c #4B3B80", -",c c #B9A0C3", -"'c c #4B414F", -")c c #615467", -"!c c #BFA5D2", -"~c c #554388", -"{c c #BCA4C2", -"]c c #403844", -"^c c #342D37", -"/c c #AA98AF", -"(c c #78609F", -"_c c #B097C6", -":c c #6A5D72", -"d c #604B8A", -",d c #AD90C4", -"'d c #64546C", -")d c #5C4E63", -"!d c #B89ACE", -"~d c #4C3B7F", -"{d c #B99CC1", -"]d c #443949", -"^d c #66556E", -"/d c #AD90C5", -"(d c #5C4888", -"_d c #A88EAF", -":d c #382F3C", -"e c #5E4D65", -",e c #AD8EC2", -"'e c #473973", -")e c #A789B2", -"!e c #58485E", -"~e c #6F5B79", -"{e c #9D80B6", -"]e c #5B4982", -"^e c #A588AB", -"/e c #332936", -"(e c #433646", -"_e c #AE8FB6", -":e c #66537C", -"f c #181320", -",f c #251E31", -"'f c #221B2D", -")f c #16111D", -"!f c #7E6794", -"~f c #A789AA", -"{f c #312733", -"]f c #4E3F51", -"^f c #BA99C5", -"/f c #4B3D62", -"(f c #1A1523", -"_f c #120E18", -":f c #241D30", -"g c #2C232E", -",g c #483B4C", -"'g c #1A141C", -")g c #3E3240", -"!g c #181218", -"~g c #2B232D", -"{g c #493C4C", -"]g c #3D3240", -"^g c #4D3F51", -"/g c #19131A", -"(g c #0C080D", -"_g c #0C070D", -":g c #0C080E", -" , > % . . . . . . . . @ * ' ) ! ! ) - ~ @ . . . . . . . . @ ~ { ) ! ! ] ^ $ @ . . . . . . . . % / ( ! ! ! _ : & . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . @ & < [ } | 1 2 3 4 { % . . . . . . @ $ 5 6 7 8 8 9 0 a b @ . . . . . . @ > c } 9 8 8 d e f $ @ . . . . . . % _ g h 9 8 8 i j 1 & @ . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . @ # k } l m n o p q r 2 = & . . . . @ * s t u v v v v w x y ~ % . . . . % ~ z A B v v v v C D E $ @ . . . . & F G H m v v v I J K L # @ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . % b M N O P N e Q R S T U ; @ . . . # : 2 V W X Y Z ` ...+._ $ @ . . @ $ ) @.#.$.` %.Y X &.*.=.: # . . . @ ; -.;.>.,.'.%.).!.~.{.].^.% . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & > /.(._.:.N <.[.}.|.1.5 ^.% . . . $ F 6 2.3.4.5.6.7.8.9.0.a.b.@ . . @ ; c.d.9.e.f.6.5.g.h.i.e j.$ . . . % ^.k.l.m.n.o.p.v q.r.H s.t.& . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & t.u.v.w.x.y.z.l A.B.C.5 D.% . . . $ j.E.F.G.H.I.J.K.L.M.D a.N.@ . . @ b.c.d.M.O.P.Q.R.S.G.T.e U.V.. . . % ^.W.X.Y.Z.`. +.+++@+#+$+t.& . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & t.%+&+*+=+-+;+>+,+'+)+!+~+% . . . V.{+]+^+/+(+_+:+<+[+}+|+1+* @ . . @ N.2+3+4+5+<+h 6+:.7+8+9+0+a+. . . % b+c+d+e+f+g+E.h+i+j+k+l+m+& . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & m+n+o+p+q+r+s+g+t+u+v+w+~+% . . . a+U.<.x+y+z+A+B+C+D+E+<.^ # . . . @ * a.F+G+H+I+J+K+L+M+N+s+O+# . . . % ~+P+Q+R+S+T+U+V+W+X+Y+Z+^.& . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . & b+`+ @.@+@@@#@$@%@&@*@=@-@;@. . . # O+>@,@'@)@!@~@{@.+]@s $ @ . . . @ ^@/@(@_@:@<@[@}@|@1@2@3@4@# . . . % -@5@6@7@8@9@0@a@b@c@d@e@b+f@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . f@b+g@h@i@j@k@l@m@n@o@p@q@-@;@. . . # 4@r@s@t@u@v@w@x@y@z@A@# @ . . . @ B@C@D@E@F@G@H@I@J@K@L@M@N@O@. . . ;@-@P@Q@R@S@T@U@V@W@X@Y@Z@`@f@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . #-@.#+#@###$#%#&#*#=#-#;#>#,#. . . '#)#!#~#{#]#^#/#/#(#&#_#O+& . . . @ B@:#<#[#}#|#1#2#3#4#5#6#>#% . . . ;@>#q@7#8#9#0#a#b#c#d#e#f#g# #. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . #h#i#j#k#l#m#n#o#p#q#r#s#t#@ . . . '#N@u#v#w#x#y#z#A#B#C#~@D#a+@ . . @ V.E#F#G#H#I#J#K#L#M#N#O#>#% . . . ,#t#;#P#Q#R#S#T#U#V#W#X#Y#>#% . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . % Z#`# $.$+$@$#$$$%$&$*$=$-$@ . . . O@;$>$,$'$)$!$~${$]$^$/$; % . . . @ ($_$:$<$[$}$|$1$2$3$4$5$`@& . . . @ -$6$7$8$9$0$a$b$c$d$e$f$g$% . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . % -$h$i$j$k$l$m$n$o$p$q$r$($@ . . . s$t$u$v$w$x$y$z$A$B$C$D$-$@ . . . + ($E$F$G$H$I$J$K$L$M$N$m$O$f@. . . @ P$Q$R$S$T$n$U$V$W$X$Y$Z$`$% . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ;@P$ %.%+%@%#%$%%%&%*%=%-%($@ . . . f@O$;%>%,%'%)%!%~%{%]%^%/%f@. . . + O@(%_%:%<%[%}%|%1%2%3%4%5%f@. . . @ ($6%7%8%9%0%a%b%c%d%e%f%P$;@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ;@g%h%i%j%k%l%m%n%o%p%q%r%g%@ . . . f@5%s%t%u%v%w%x%y%z%A%B%C%s$D%. . + s$E%F%G%H%I%J%K%L%M%N%O%Z#f@. . . @ g%P%Q%R%S%T%U%V%W%X%Y%Z%g%;@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ;@g%`% &.&+&@&#&$&%&&&*&=&-&@ . . . f@Z#;&>&,&'&)&!&~&{&]&^&/&f@+ . . + s$(&_&:&<&[&}&|&1&2&3&4&Z# #. . . @ s$5&6&7&8&9&0&a&b&c&d&e&-&;@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . @ s$f&g&h&i&j&k&l&m&n&o&E%f@+ . . . f@Z#p&q&r&s&t&u&v&w&@&x&y&s$D%. . + s$z&A&B&C&[&}&D&E&F&G&0&Z# #. . . @ -&H&I&J&K&9&0&L&M&N&O&`%g%;@. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . @ P&Q&R&S&T&U&V&t%W&X&($@ . . . . ;@`$Y&Z&`& *.*.*+*@*#*$*%*f@. . . . f@&***=*-*;*>*,*'*)*!*~*`$;@. . . + s${*]*^*/*T%0&(*_*:*<*[*-&@ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . ;@}*|*1*2*3*4*_&5*Z#@ . . . . . . #6*7*8*3*9*9*0*a*A&b*s$+ . . . . + -&c*d*e*f*g*h*i*j*k*l* #. . . . . @ Z#m*n*o*p*q*r*o*s*t*%*;@. . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . ;@u*v*w*x*y*z*`$@ . . . . . . . . ;@A*q*B*C*C*D*E*F*f@. . . . . . . . s$=&y*G*H*z*I*J*K*;@. . . . . . . + L*M*N*O*P*Q*N*R*}*@ . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . @ -&`$S*`$s$@ . . . . . . . . . . #S*`$`$`$`$`$f@+ . . . . . . . . + s$Z#S*@ ;@T*`$U*. . . . . . . . . @ ($Z#-&+ f@Z#($,#. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . @ ;@U*;@+ . . . . . . . . . . . . ;@U*U*U*U*;@+ . . . . . . . . . . @ #;@. + ;@;@. . . . . . . . . . . @ ;@@ . @ ;@,#. . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%D%. . . . D%D%. . . @ @ . . . D%D%. . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%. . . D%D%,#V*U*U*U*;@ #V* #U*,#U* #,#+ D%@ ,#U*@ . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . D%@ @ @ U*W*X*Y*Z*`* =.=+=@= =#=$=Y*Y*%=&=*===*=-=;=@ . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . D%,# #-$@=>=,='=)=!=~={=]=^=/=(=(=)=_=:=<=[=}=|=1=2=3=D%. . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . D%U*W*h#4=5=6=7=8=9=0=a=b=c=d=e=f=g=h=i=j=k=l=m=n=o=p=q=r=3=s=+ . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . @ ($@=>=t=u=v=w=x=y=z=A=B=C=D=E=E=F=G=H=I=J=K=L=M=N=O=P=Q=R=S=T===V*@ . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . D%D%,#,#@ U*U=V=W=X=Y=Z=`= -.-+-@-#-$-%-&-J.;.*-=---;->-g.,-'-)-!-~-{-]-[=^-/-(-_-U*+ . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . D%,#W*W*P$U=-=:-<-[-}-|-1-2-3-4-5-6-7-0 8-9-0-a-b-c-d-$+a ].e-f-l g-h-i-j-k-l-m-n-}=o-p-;=,#D%. . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . D%+ ,#U*W*p-%=Y*q-r-s-t-u-v-w-x-y-z-A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-f Q-R-S-T-U-V-W-X-Y-Z-`-o- ;V*,#,#D%. . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . ,#;=_-.; ;.;+;@;#;$;%;&;*;=;-;;;r >;,;';);!;~;{;];^;/;(;_;:;<;[;};|;1;2;3;4;5;6;, 7;8;,-9;0;a;b;c;d;e;&=f;==,#. . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . + g;h;i;|=j;k;|=l;m;n;o;p;q;r;s;t;t;u;v;w;x;y;z;A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;F b S;T;U;V;W;X;Y;Z;`; >.>+>,#. . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . ,#@>#>$>%>&>*>=>->;>>>,>'>T.)>!>~>{>]>^>/>(>_>:><>[>}>|>1>2>3>4>5>6>7>8>9>0>a>b>c>d>e>f>$ g>h>i>j>+*k>l>m>n>R=@;_-,#. . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . ,# ;o>p>q>l;r>->s>t>u>v>w>x>y>z>A>B>C>D>E>F>G>H>I>J>K>L>M>N>O>P>Q>R>S>T>U>V>W>X>Y>Z>`> ,.,% +,@,#,$,%,&,Y;*,=,@;*= #D%. . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . @ -,;,Z;m;*>>,,,',),!,~,{,],^,/,(,_,:,<,[,},|,1,2,3,4,5,6,7,8,9,0,a,b,c,d,e,f,g,h,i,j,k,l,m,D%. n,o,p,q,r,Y;|=s,%=P$,#. . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . @ t,u,v,l;w,x,y,z,A,B,x C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,`, '.'+'@'#'$'%'&'*'='. . -';'>','Z-''.,Y*-=V*+ . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . D%V*)'u,!'~'{']'^'/'x ('_':'<'['}'I,|'1'2'3'4'5'6'7'8'9'0'a'9,b'c'd'e'9,f' g'h'i'j'',k>k'*=l',#. m'n'o'p')=.,q' ;P$,#+ . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . D%. . . . ,#r's't'u'v'w'x'{,y'z'A'B'C'D'E'F'G'H'I'J'K'L'M'N'O'P'Q'R'S'T'U'Q>V'W'X' Y'Z'`' ).)+)@)#)$)%)D%. &)*)=)-);)s,>)-,;=,#. . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . ,#_-,),#. D%_-')))!)~){)i.])^)/)()_):)<)[)})M'|)1)2)3)1'4)5)6)7)I'I' X'8)9)0)R, I'a)b)c)d)e)f)g)h)i)j)+ k)l)m)n)o)p)$>&=W*,#+ . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . D%_-$>q)-=@ U*r)^-s)t)u)3-v)y>w)x)y)z)A)B)C)D)E)E)F)G)H)I)J)K)L)7) M)N)O)P)Q) R)S)T)U)V)W)X)Y)Z)`) !.!+!. @!#!$!%!&!''*!_-s$s=D%. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . D%_-(-)'==,#V*@;=!-!;!>!,!~>'!)!!!~!{!]!2)^!/!(!H'_!N)M'6)3):!==+ . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%D%+ X*Q!R!S!T!U!k!V!W!X!Y!J,Z!R'I'I'I'`! ~s!.~+~2) X'P'6)I'@~3)6)#~R'$~N)%~&~*~=~-~%~;~ >~,~'~)~!~~~{~]~^~. /~(~_~:~<~^-[~s=. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . @ #;,}~|~1~P.2~3~4~5~6~7~8~9~0~J'I'I'O)a~b~c~d~e~f~g~h~i~O'j~k~1'l~m~n~o~p~q~r~s~@~H)I)t~X'm~u~v~w~x~y~z~A~B~. . C~D~E~(=[=F~_-+ . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%V*G~Y;H~I~J~K~L~M~N~O~P~Q~R~$~x!S~S~ T~e'U~V~W~X~Y~Z~`~ {.{9,+{j~@{#{${%{&{*{={-{;{>{,{'{X' N'){!{~{{{]{^{/{==. ({_{:{<{[{f!.;U*. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#_-}{|{1{2{3{4{5{v;6{7{_,8{9{0{a{b{c{Z'H)d{U,e{f{g{h{h{Q'i{5'j{k{l{m{n~n{o{p{q{r{s{t{u{v{w{x{y{I'I)z{A{B{C{D{E{F{. G{H{I{J{K{L{ ;;=,#. . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . + V**=M{N{O{P{Q{R{S{T{U{V{W{X{Y{Z{`{ ].]Q>+]@]#]$]%].]&]*]=]-];]>],]'])]j~!]~]{]f~]]^]/](]_]:]<][] x!}]|]1]2]3]/{. . 4]5]6]7]8]T=U= #. . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . + U*X*9]0]a]b]c]d]e]f]g]h]i]j]k]l]2)q!9)M)m]n]o]p]q]r]q!s]t]u]v]w]x]y]z]A]B]C]D]E]F]G]H]I]J]K]L]M]T~N]O]P]Q]R]S]T]U]+ . V]W]X]Y]v,Z])',)@ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#g$`] ^.^+^@^#^$^%^&^*^=^-^;^>^,^P'I):!'^)^!^~^{^=^]^^^/^(^A-d _^} :^9+<^[^}^|^1^2^3^4^5^6^w!I'I'6)6)7^8^9^0^a^b^c^. d^e^f^g^Q=h^o-i^V*. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . @ g$j^k^l^m^n^o^p^q^r^s^t^u^[!I)v^7)N'N'w^x^y^)^l~z^A^B^);C^9 D^7-E^F^G^H^I^J^K^L^M^N^O^P^Q^u!7)6)u! S~R^S^T^U^V^W^,#. X^Y^Z^h^=,)'.;;=. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#g$`^ /1-./} +/@/#/$/%/a'&/T'I'u!-]*/=/-/;/>/,/z^'/)/!/~/B-i +.0 {/]/^///(/u._/:/f/-=@ . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#h#g/j&h/i/K j/k/l/m/n/N)`!e~3) 6)o/p/>^q/r/,/s/t/u/~/B-v/_^} 8-e G^H^o w/$+x/y/z/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/0/P/. Q/R/ /S/f!T/U/m,,#. . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#V/<-W/X/Y/6 Z/`/ (.(+(q!8,@($~ I'#(N'e'(,('()(!(~({(](^(/(((_(:(<([(}(|(W^. 1(2(3(4(@=f/q)+>@ . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#5(6(7(8(9(0(a(b(c(d(e(f(F/+'.]I' I'K)g(3/j{h(i(j(D^+.k(K 6 l(G b-g d-m(n(o(p(q(r(s(t(u(v(w(x(y(z(A(B(C(D(E(F(G(H(. I(J(K(L(M(P$-=V*. . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . ,#N(O(P(D=Q(R(S(T(U(V(W(X(Y(Z(q/:!x! N)`('^+] _@!._n^} 8-F^l(^/+_@_w/$+y ].k.#_$_%_&_*_=_-_;_>_,_'_i+)_!_~_{_]_^_/_. (___:_<_@= #,#@ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . s$[_}_|_1_2_H^3_4_5_6_7_8_9_0_l~X'u! 6)O'a_b_c_k(d_:^e 0-G 2 @_w/e_c -(f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z_s=(___A_W=[_P$s$V*,#. . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . U*B_[=Y]7(C_D_o E_F_G_H_I_J_K_L_X'6)x! I'6)M_8)N_O_:^6 P_G^G b-@_Q_e_c M o(f -.R_S_T_U_V_W_X_Y_Z_`_ :.:+:@:o_#:$:%:&:,#I(*:=:-:#=-=P$s$,#. . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . D%==e!;:>:,:<$':4 ):!:~:{:]:^:E]g~u! I'[!/:(:_:::P_0-^/H^=.g w/e_c M o(5 E <:[:}:|:1:2:3:4:5:6:7:8:9:0:a:b:c:d:e:==. f:g:h:g/i:*= #@ . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . ,)j:}=k:l:m:n:e_o:p:q:r:s:t:t^T~ I'u!7)r/u:v:w:x:y:[ b-o (/d-$+c M o(5 E z:A:B:C:D:E:F:7:G:H:I:J: :K:L:M:N:O:P:Q:c^. Q/v-R:r-N(W*@ . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . ,#P$S:T:U:V:W:y X:Y:Z:`: <.<,);=D%. . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . D%,#h#`^}<|<1<-(2<3<4<5<6[,['[)[![5 ~[{[][^[/[={([M},}'})}!}~}{}M] x!]}^}/}(}m<1'@~_}:}<}[}}}|}1}2}3}4}5}6}7}8}9}0}a}b}c}d}e}f}g}h}i}j}k}l}/{D%m}n}o}p}q}k'==+ . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . ,#,#@ ;=r}s}t}u}v}w}x}y}z}A}B}C}P'I' D}E}F}G}H}I}J}K}L}P'M}N}O}P}Q}R}S}T}U}V}W}X}Y}Z}`} |.|+|@|#|$|%|&|i[*|^{%). =|-|;|>|k',|,#. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . + ,)-=V*;=`*}<'|)|!|_ 1+~|{|]|^|/|(|I) O'_|:|<|[|}|||1|2|3|4|5|6|7|8|9|0|a|b|c|d|e|f|g|e+h|i|j|k|l|m|n|o|[~p|+ q|r|s|t|u|v|V*. . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . D%+ W*-=W*;=i^w|x|y|z|A|' B|C|D|E|F|G|H|I' u! I|J|K|L|M|N|O|M)P|Q|R|S|T|U|V|W|X|Y|.[Z|`| 1.1+1@1X[#1I)$1%1&1*1=1-1U*. ;1>1,1'1)1v|,)D%. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . @ ;@ #-,.;!1~1{1]1^1b /1(1_1:1<1[1}1I'M]|1I) 11213141e'51I'6171o/819101a1b1c1d1e1X'f1R@g1W[I'h1X[P'i1j1k1l1m1n1,#o1p1q10]r1}{>);=D%. . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%,#P$_- ;s1t1u1v1-'* w1x1y1z1A1R'B1C1D1+'Y'E1F1G1H1+[f{D!I1+[J17)P K1L1M1N1O1P1Q1 6)R1S1D!I'I)I)3)T1I!U1@>D%. V1W1X1Y1Z1^-`1_-,#D%. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%D%@ ,#;=f!'1 2.2+2@.% @2#2$2%2&2*2=2-2;2P'>2,2'2)2J1I)!2~2{2I).[X[]2^2/2(2_2M1:2<2[2}2|212f1X'2232425262l'. w]72829202a2b2}=c2-=,#. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . D%D%@ @ U*T=d2e2f2g28+. &[0/h2i2j2k2l2m2n2o2p2q2r2s2N]P2Q2 ;;@. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . D%@ D%,#R2S2o)T2U2V2W2. r'X2Y2Z2`2J[ 3.3+3@3#3$3%3&3*3=3-3u!I);3>3o/O',3n<'3I')3!3~3{3]3^3/3(3_3u<$):3,#. <3[3}3|3e/ >13h;f/p-W*D%. . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . @ D%D%,#g;2333435363n,. c^62A~73839303a3&|&1b3c3d3e3f3g3I'I'h3i3j3k3l3m3f~J1n3o3p3q3r3s3t3=1u3v3/{D%. w3x3y3-[z3A3i;)'-=V* #@ . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . D%. . ,#e;B3C3D3E3F3G3. +!$)*|$:H3n|I3J3K3L3M3N3O3P3i3Q3.[4/R3S3T3l3U3V3W3X3Y3Z3`3 4.4+4@4#4c^&[. (_$4%4&4*4=4 ;P$V*@ . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . D%D%. D%V*-4;4>4,4F!C<-'. D%'4)4!4~4{4{{]4^4/4(4_4:4<4[4}4|414243444546474849404}(a4u3b4c4s=. . d4e4f4g4h48]P$,#+ D%D%. . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . @ ,#,#. . # ;j;n>i4j4k4;'l4. D%r'm4n4o4p4q4.4r4s4t4N/u4v4w4x4y4z4A4B4C4D4E4F4G4S]H4I4e:J4^~. K4L4v1M4N4O4r}i^;=@ D%. . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . @ ,#+ . . + V*%=P4Q4R4i=S4W]T4U4. . 2=V4W4X4K2Y4Z4`4 5.5+5@5#5$5%5&5*5=5-5;5>5,5'5U1)5n1='. !5<+~5{5]5^5/5(5v|_5W*U*@ . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . D%D%+ . . @ P$%=:5m><5[5}5|515-'. . ;=25e:#)354555a^6575859505*1a5S] }H4b5a!$)c5d5,#. e5f5Y G2g5h5i5j5>)i^f/-4-= #+ . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . @ s=,#. + U*W*.;s,[=<~k5l5m5n5o5p5. . ,#K!q5/{r=r5s5t5T]3]H4u5v5#4w5b^U1x5y5+ . . z5A5w'B5C5D5E5F5.,%= ;.;-=V*@ . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . ,#W*V*D%D%D%D%,#;=%=u,G5H5I5J5K5L5M5N5O5. . . U*P5'4+}#4c4Q5c4R5l'D%='@ . . S5T5U5V5W5X5Y5Z5`5 6|=f/q'P$V*,#D%. . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . @ # #,#@ . . . D%,#_-.6V=+6@6R!#6$6%6;}&6*6;+. . . . D%. . . D%. . . =6-6Q{;6>6,6'6)6!6~6n={6]6)'-=V*,#D%. . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . D%@ ,#,#. . . . . D%U*-=^6/66(}~6](6_6:6<6[6}6|616m'S;263646m'@,566676869606a6b6c6d6&!&>e6'43=V*,#D%. . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . D%D%. . . . . . D%;@V*($`*f6g6h6i6j6k6l6m6n6o6p6q6r6s6C=J(t6u6v6w6x6y6z6A6B6C6D6E6F6G6s=@ D%. . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . D%,#-,Y*H6I6J6K6{=u=L6<<3(=:M6c=N6M6O6P6Q6R6S6T6U6r>*>V6j:p|3=U*,#D%. . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . D%U*V* #s$P$h#+=W6X6J6S/Y6+6Z6Z6+6`6 7`]X6.7[_+7j;$>y5&[,#D%D%. . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%@ ,#;@ #W*-$h#h#`@M(M(`@h#g$-$W*s$P$.6p-_-,#D%. . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%+ . . D%+ @ ,#,#,#,#,#,#+ D%D%D%,#V* #+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D%D%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . @ & % . @ & & @ . . . @ & # # # # & @ . . . @ & # # # # f@@ . . . @ & # # # # % @ . . . @ & # # # # % . . . . @ & # # # # % . . . . @ & # # # # % . . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . @ $ > ; % & b b # . . @ $ / : : : : b & . . @ $ / : : : : b & . . @ * / : : : : b & . . @ * / : : : : b & . . @ * / : : : : b & . . @ * / : : : : b & . . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . # >}| z _ <:| z L % @ $ Q-w/2 2 2 =.z L % @ $ -.4 2 2 2 =.@7) % @ $ -.4 2 2 2 =.c _ % @ * E 4 2 2 2 =.y _ % @ * s #7$72 2 %7a , % @ ; &7(/b-2 $7*7O-, % . + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . @ $ g_6-=7':o 0 -7':8-6;b 5 ;7>7,7'7'7,7':{/k b )7(^>7'7'7'7,7=-6 k b !7!/>7'7'7'7,7N e L b o(~7{74-'74-]7^7P_) b S -(_7{7]7]7]7:7U!G^, & @ . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ # - :^<7O [7}7|71727374 47K 57~.676767772787d-47} u 977.07a7b7O Y/c71 *(d7~.b7a7a7e7f7g7$+1 +.h797b7e7e7i7f7N m(< @.[797e7j7j7k7l7m7z n7v/o797k7k7k7p7f7U!a b & . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ b.6;;7q ).q7h r7l7s72.e <:7 5.t7k7u7v797w7u H^>}x7q y7a7>.97z7A7<7G^z:B7C727k7D7E7F7l7G7*7-.H7l7I7j7P J7K74.]7[ L7M7N7O7p727~.P7Q7(72 &7r7R7S7T727~.!,U7V7*7: # . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ ; 6;d.W7u7X7Y7Z7t7n.i.]+! (/H7`7T4 8.8+8p5A-o(@8#8$8%8&8*8=8S.h.-8;8! >8|7,8'8 8|.)8!8#^k.A@~8P {8]8^8/8|.(8_8^/s +l3q.:8<8k+[8}8(7[ g_|8t718283848W }.V75868# . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ b.a.78889808a8b8c8d857<.e8- s G^l f8g8h8m(z:0+i8j8k8l8m8n8o8[8p8q8r8j., g_z.V7s8t8u8@7<:v8@8w8S.G.F.Y7x8y8z8V7A8L7B8C8D88+a8E8:.F8G8H8&7I8S.z856}7J8z2K8l *7L8# . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ * a.M8N8O8^+P8Q8z2R8C+U+U.t.S8T8U8V8(2W8X8= b Y8Z8`8 9^+.9+9:.@9x'g #9^.{ $9%9&9j<*9#_0+b =9-9z2;98+>9,9j<'9)9!9~9{9:.]9N+^9/9(9_9%9j :96+z2<9r[[9x8B.}9|9n+t.& . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ ^@/@192939495969792{89;+99~ 09a9b9c9u+d9=@e9D.f9g9h9i9h>j93+k9l9]@m9$ $ O+n9o9p9q9r9s9e9D.n7t9u9v949[9w9x9y9z9A9B9C9j0,0'0)0: ## !0~0{0]0^05#/0b+~+(0_0x2:0,@<0[0^0}0<3|01020q930405060708090n9s#00:2a0~#b0c0d0e0f0> % @ . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ B@g0h0i0j0k0l0m0n0o0p0q04@.0m+r0s0t0u0v0~9-@.0w0x0y0z0A0B0C0D0E0'0X8^@$ N@F0G0H0|@I0J0.0.0K0L0M0N0s@O0P0|@Q0R0S0T0U0V0W0X0Y0Z0`0 aG0.a+a@a#a$a%aD0&ab|*a=a-aB@% . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + @ -$:#;a>a,a'a)a!a`0~a{a]a^ab.;$/a(a_a:a#`@RaSaTaUaVaT0t#f@$ P@WaXaYaZa`a b.b+b@b;$N.V/#b$b%b8#&b*bh#>#=b-bia;b>b,b'b)b!b~b{b]b^bia/b(b_b:b#P&hbibjbkblbmb-$ #'#nbobpbqbrbsbtbubvbwbt$>#`@xbybzbAbBbCb>#>#DbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb`b c.c+c@c#c$c%c&c*ch#'#. . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + + ($=c-c;c>c,c'c)c!c~c{c]cO$Z#V/^c/c(c_c:c#9c0cacbcccdcecP&Z#fcgchcicjckclcmcncocpcqcy$m)rcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJc5%O@. . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + + s$E%KcLcMcNcOcPcQcRcSc4%P&P&C%TcUcVcWcXcYcZcZ#`c d.d+d@d#d$d%d&d*d=d5%P&C%-d;d>d,d'dP%ZcZ#zc)d!d~d{d]d^d/d(d_d:de,e'e)e!e~e{e]e^e/e`$f@. . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . f@}*(e_e:e-[f,f'f)f!f~f{fA*]f^f/f(f#f_f:ffifjfkf($ #. . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . @ L*lfTe=*mfnfofZef&`$Z#h%pfqfrf,e,esftfd*uf%*Q&vfwfxfxfxfyfzfAf=&%*cfBfCfAeDfAeEfFfGfz*%*E*HfCfIfAeIfJfKfLfF*}*y*MfNfOfPfQfRfSfTfUf}*VfMfWfXfXfXfYfZf=f{*f@@ . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . @ L*M*`f g.g+g`e($@ @ @gh%#g$g%g$g gCe[*-&;@%*h%&g*g=g=g g-gb*s$;@%*Q&Qd*g*g*g;gKdr%f@;@&*>g,g*g*g*g;gqd'gf@;@&*~*vd)g!g~g{g]gf&f@;@ZcE*Ze}f*g*g^god/gf@+ + . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . + . . . . @ -&%*(g_gP&f@+ . . @ `$Zc:g(g:g:g%*-&. . @ `$&*:g:g:g(gV/s$. . @ T*Zc:g(g(g(g%*s$. . @ -$Zc(g:g:g(gt$f@. . @ T*/% c #00BBFF", -", c #00B7FF", -"' c #00B3FF", -") c #00B5FF", -"! c #00ADFF", -"~ c #00AFFF", -"{ c #00A9FF", -"] c #00A5FF", -"^ c #00A3FF", -"/ c #009FFF", -"( c #00A1FF", -"_ c #009BFF", -": c #0095FF", -"< c #0097FF", -" ", -" .++++++++++ ", -" @ @# ", -" $ % $ ", -" &&*&&&*&&*& = ", -" *********** - ", -" ; ; > ", -" , , , ", -" ' ' ) ", -" ! ~ ~ ", -" { { { ", -" ] ] ^ ", -" / ( / ", -" _ __ ", -" ::::::::<:: ", -" "}; diff --git a/resources/bitmaps/modify_faces.xpm b/resources/bitmaps/modify_faces.xpm deleted file mode 100644 index 1860c82..0000000 --- a/resources/bitmaps/modify_faces.xpm +++ /dev/null @@ -1,47 +0,0 @@ -/* XPM */ -static char * modify_faces_xpm[] = { -"16 16 28 1", -" c None", -". c #00CBEB", -"+ c #00CBED", -"@ c #00C9F1", -"# c #00C9F3", -"$ c #00C7F7", -"% c #00C7F9", -"& c #00C5FD", -"* c #00C5FF", -"= c #00C7FD", -"- c #00C7FF", -"; c #00C1FF", -"> c #00FFFF", -", c #00BDFF", -"' c #00BBFF", -") c #00B7FF", -"! c #00B3FF", -"~ c #00B5FF", -"{ c #00ADFF", -"] c #00AFFF", -"^ c #00A9FF", -"/ c #00A5FF", -"( c #00A3FF", -"_ c #009FFF", -": c #00A1FF", -"< c #009BFF", -"[ c #0095FF", -"} c #0097FF", -" ", -" .++++++++++ ", -" @ @# ", -" $ % $ ", -" &&*&=&*&=-= * ", -" ;>>>>>>>>>; ; ", -" ,>>>>>>>>>, ' ", -" )>>>>>>>>>) ) ", -" !>>>>>>>>>! ~ ", -" {>>>>>>>>>] ] ", -" ^>>>>>>>>>^ ^ ", -" />>>>>>>>>/ ( ", -" _>>>>>>>>>: _ ", -" <>>>>>>>>><< ", -" [[[[[[[[}[[ ", -" "}; diff --git a/resources/bitmaps/modify_vertices.xpm b/resources/bitmaps/modify_vertices.xpm deleted file mode 100644 index 11715eb..0000000 --- a/resources/bitmaps/modify_vertices.xpm +++ /dev/null @@ -1,47 +0,0 @@ -/* XPM */ -static char * modify_vertices_xpm[] = { -"16 16 28 1", -" c None", -". c #00CBEB", -"+ c #00CBED", -"@ c #00C9F1", -"# c #00C9F3", -"$ c #00C7F7", -"% c #00FFF9", -"& c #00C5FD", -"* c #00C5FF", -"= c #00C7FD", -"- c #00FFFF", -"; c #00FFFD", -"> c #00C1FF", -", c #00BDFF", -"' c #00BBFF", -") c #00B7FF", -"! c #00B3FF", -"~ c #00B5FF", -"{ c #00ADFF", -"] c #00AFFF", -"^ c #00A9FF", -"/ c #00A5FF", -"( c #00A3FF", -"_ c #009FFF", -": c #00A1FF", -"< c #009BFF", -"[ c #0095FF", -"} c #0097FF", -" ", -" .++++++++++ ", -" @ @# ", -" $ %%% $ ", -" &&*&=&*&=-;- * ", -" > --- > ", -" , , ' ", -" ) ) ) ", -" ! ! ~ ", -" { ] ] ", -" ^ ^ ^ ", -" / / ( ", -" _ : _ ", -" < << ", -" [[[[[[[[}[[ ", -" "}; diff --git a/resources/bitmaps/noFalloff.xpm b/resources/bitmaps/noFalloff.xpm deleted file mode 100644 index 7225685..0000000 --- a/resources/bitmaps/noFalloff.xpm +++ /dev/null @@ -1,15 +0,0 @@ -/* XPM */ -static char *noFalloff[] = { -/* columns rows colors chars-per-pixel */ -"64 8 1 1 ", -" c white", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/notex.tga b/resources/bitmaps/notex.tga deleted file mode 100644 index 594a463..0000000 Binary files a/resources/bitmaps/notex.tga and /dev/null differ diff --git a/resources/bitmaps/paste.xpm b/resources/bitmaps/paste.xpm deleted file mode 100644 index 3e048d7..0000000 --- a/resources/bitmaps/paste.xpm +++ /dev/null @@ -1,77 +0,0 @@ -/* XPM */ -static char * paste_xpm[] = { -"20 19 55 1", -" c None", -". c #00CBED", -"+ c #00C9F3", -"@ c #00C9F1", -"# c #86FFF1", -"$ c #88FFF3", -"% c #00C9F7", -"& c #0BFFF7", -"* c #0DFFFF", -"= c #0DFFF7", -"- c #00C7F9", -"; c #8CFFF9", -"> c #00C7F7", -", c #8CFFF7", -"' c #0DFFF9", -") c #00C5FD", -"! c #11FFFF", -"~ c #00C5FF", -"{ c #68FFFF", -"] c #00C7FF", -"^ c #00C3FF", -"/ c #0FFFFF", -"( c #8EFFFF", -"_ c #00C1FF", -": c #00BDFF", -"< c #0BFFFF", -"[ c #00BBFF", -"} c #00B7FF", -"| c #07FFFF", -"1 c #09FFFF", -"2 c #00B3FF", -"3 c #05FFFF", -"4 c #84FFFF", -"5 c #86FFFF", -"6 c #00B5FF", -"7 c #00AFFF", -"8 c #03FFFF", -"9 c #01FFFF", -"0 c #80FFFF", -"a c #82FFFF", -"b c #00A9FF", -"c c #00FFFF", -"d c #00ABFF", -"e c #7CFFFF", -"f c #7EFFFF", -"g c #00A5FF", -"h c #7AFFFF", -"i c #009FFF", -"j c #78FFFF", -"k c #00A1FF", -"l c #009BFF", -"m c #72FFFF", -"n c #74FFFF", -"o c #0095FF", -"p c #0097FF", -" ", -" ", -" ", -" .... ", -" ++@++#$++++@ ", -" %&*=-;%>,-*'*- ", -" )!!~{{{{{{]!!) ", -" ^/(____^__^//_ ", -" :<<***<<*<<<<[ ", -" }||1||}}}}}}}} ", -" 233|3324445462 ", -" 788999700aaa707 ", -" bcccccdedddfbdbb ", -" gcccccghhhhhhhhg ", -" icccccijkkkkkiji ", -" llllllmmnmmnmnl ", -" ooopooooop ", -" ", -" "}; diff --git a/resources/bitmaps/patch_bend.xpm b/resources/bitmaps/patch_bend.xpm deleted file mode 100644 index abcf6f5..0000000 --- a/resources/bitmaps/patch_bend.xpm +++ /dev/null @@ -1,56 +0,0 @@ -/* XPM */ -static char * patch_bend_xpm[] = { -"16 15 38 1", -" c None", -". c #00CBE7", -"+ c #00CDE7", -"@ c #00CBED", -"# c #51FFFF", -"$ c #4FFFFF", -"% c #00C9F3", -"& c #53FFFF", -"* c #55FFFF", -"= c #00C9F1", -"- c #00CBF3", -"; c #00C7F7", -"> c #00C7F9", -", c #59FFFF", -"' c #57FFFF", -") c #00C9F9", -"! c #00C7FD", -"~ c #00C5FD", -"{ c #5DFFFF", -"] c #00C3FF", -"^ c #00C1FF", -"/ c #5BFFFF", -"( c #00BDFF", -"_ c #00BBFF", -": c #00B7FF", -"< c #00B9FF", -"[ c #00B5FF", -"} c #00B3FF", -"| c #00AFFF", -"1 c #4DFFFF", -"2 c #00A9FF", -"3 c #00ABFF", -"4 c #4BFFFF", -"5 c #00A5FF", -"6 c #00A3FF", -"7 c #47FFFF", -"8 c #009FFF", -"9 c #00A1FF", -" .++++ ", -" @##$$@@@ ", -" %&**=-&&&% ", -" ;;>>,,,'))> ", -" !~{{!{{{~ ", -" ]^////^ ", -" ( ('''(__ ", -" :<: :*:**: ", -" [ [}###[ ", -" | |$11| ", -" 2 2 34442 ", -" 5555566 5775 ", -" 88 9 999 ", -" ", -" "}; diff --git a/resources/bitmaps/patch_drilldown.xpm b/resources/bitmaps/patch_drilldown.xpm deleted file mode 100644 index 0148477..0000000 --- a/resources/bitmaps/patch_drilldown.xpm +++ /dev/null @@ -1,36 +0,0 @@ -/* XPM */ -static char * patch_drilldown_xpm[] = { -"16 15 18 1", -" c None", -". c #00CBFF", -"+ c #00C9FF", -"@ c #00C7FF", -"# c #19C7FD", -"$ c #17C1FF", -"% c #00BDFF", -"& c #00B7FF", -"* c #00B3FF", -"= c #00B5FF", -"- c #0BAFFF", -"; c #00A9FF", -"> c #00ABFF", -", c #00A5FF", -"' c #00A3FF", -") c #00A1FF", -"! c #009FFF", -"~ c #009BFF", -" ", -" ... ", -" +++ ", -" @@@ ", -" # ", -" $ ", -" %%% ", -" &&& ", -" **= ", -" - ", -" ;;> ", -" ,', ", -" ))! ", -" ~ ", -" "}; diff --git a/resources/bitmaps/patch_insdel.xpm b/resources/bitmaps/patch_insdel.xpm deleted file mode 100644 index 18ac12c..0000000 --- a/resources/bitmaps/patch_insdel.xpm +++ /dev/null @@ -1,51 +0,0 @@ -/* XPM */ -static char * patch_insdel_xpm[] = { -"16 15 33 1", -" c None", -". c #46E373", -"+ c #45E374", -"@ c #46E374", -"# c #46E473", -"$ c #48E376", -"% c #47E077", -"& c #45DE77", -"* c #46DE77", -"= c #44DB77", -"- c #43DA77", -"; c #42D977", -"> c #42DA77", -", c #47D6FF", -"' c #40D777", -") c #40D677", -"! c #48D7FF", -"~ c #48D6FF", -"{ c #47D7FF", -"] c #3FD477", -"^ c #3FD577", -"/ c #3ED477", -"( c #3DD277", -"_ c #3BCFFF", -": c #3CD0FF", -"< c #3BD077", -"[ c #3BCF77", -"} c #39CDFF", -"| c #39CD77", -"1 c #3ACD77", -"2 c #38CAFF", -"3 c #37CAFF", -"4 c #38CA77", -" ", -" ", -" ", -" ..+@#..+ ", -" $ ", -" % ", -" &*&&& ", -" === ", -" -;; > >;> ", -" ,'')!~!{{{'''!", -" ]]] ]^/ ", -" ( ", -" _ : < [ ", -" } ||1| ", -" 2 3 4 "}; diff --git a/resources/bitmaps/patch_showboundingbox.xpm b/resources/bitmaps/patch_showboundingbox.xpm deleted file mode 100644 index 0c8e9ed..0000000 --- a/resources/bitmaps/patch_showboundingbox.xpm +++ /dev/null @@ -1,67 +0,0 @@ -/* XPM */ -static char * patch_showboundingbox_xpm[] = { -"16 15 49 1", -" c None", -". c #067682", -"+ c #077681", -"@ c #047584", -"# c #08DCF7", -"$ c #9DF1FB", -"% c #08DBF7", -"& c #9CF1FC", -"* c #09DCF6", -"= c #037585", -"- c #9BF0FD", -"; c #04D9FB", -"> c #037485", -", c #017387", -"' c #01D7FE", -") c #99EFFF", -"! c #9AEFFE", -"~ c #007388", -"{ c #007288", -"] c #007188", -"^ c #99EEFF", -"/ c #00D4FF", -"( c #007088", -"_ c #00D2FF", -": c #99EDFF", -"< c #99ECFF", -"[ c #006F88", -"} c #006E88", -"| c #99EBFF", -"1 c #00CEFF", -"2 c #006D88", -"3 c #00CCFF", -"4 c #99EAFF", -"5 c #006B88", -"6 c #99E9FF", -"7 c #00CAFF", -"8 c #006C88", -"9 c #006A88", -"0 c #00C6FF", -"a c #99E8FF", -"b c #006888", -"c c #99E7FF", -"d c #00C4FF", -"e c #006788", -"f c #00C1FF", -"g c #99E6FF", -"h c #00C2FF", -"i c #006688", -"j c #006588", -" ", -" ...+.......... ", -" @#$%&*&#&#&*$@ ", -" =-----------;> ", -" ,')!!!)!,~!)!{ ", -" ]^^^^^{]^^^^/] ", -" (_:::(::::::<[ ", -" }|<|}|||||||1} ", -" 23|42444|44|42 ", -" 56445464444478 ", -" 90aaa99666aa69 ", -" bccccccbbcccdb ", -" efgfgfghchchge ", -" iiiijiiijiijij ", -" "}; diff --git a/resources/bitmaps/patch_weld.xpm b/resources/bitmaps/patch_weld.xpm deleted file mode 100644 index fba2eeb..0000000 --- a/resources/bitmaps/patch_weld.xpm +++ /dev/null @@ -1,57 +0,0 @@ -/* XPM */ -static char * patch_weld_xpm[] = { -"16 15 39 1", -" c None", -". c #84E6F3", -"+ c #84E5F6", -"@ c #83E4F9", -"# c #83E3FC", -"$ c #46E304", -"% c #46E403", -"& c #83E2FF", -"* c #83E2FE", -"= c #48E277", -"- c #83E0FF", -"; c #83E1FF", -"> c #47E177", -", c #47E077", -"' c #83DEFF", -") c #46DE00", -"! c #45DE77", -"~ c #46DE77", -"{ c #45DE00", -"] c #83DCFF", -"^ c #84DBFF", -"/ c #44DB77", -"( c #84D9FF", -"_ c #43D9FF", -": c #42D9FF", -"< c #42DAFF", -"[ c #84D6FF", -"} c #40D600", -"| c #41D7FF", -"1 c #40D7FF", -"2 c #84D4FF", -"3 c #3FD5FF", -"4 c #3FD4FF", -"5 c #84D2FF", -"6 c #3DD2FF", -"7 c #84CFFF", -"8 c #3BD0FF", -"9 c #3CCFFF", -"0 c #84CDFF", -" . ", -" + ", -" @ ", -" ## $ % ", -" & * = ", -" -; >,, ", -" ' ) !~! { ", -" ] ^/ ", -" ( ( _:<:< ", -" [ } ||11 ", -" 2 344 ", -" 5 5 66 6 ", -" 7 8 9 ", -" 0 ", -" "}; diff --git a/resources/bitmaps/patch_wireframe.xpm b/resources/bitmaps/patch_wireframe.xpm deleted file mode 100644 index 90e1168..0000000 --- a/resources/bitmaps/patch_wireframe.xpm +++ /dev/null @@ -1,46 +0,0 @@ -/* XPM */ -static char * patch_wireframe_xpm[] = { -"16 15 28 1", -" c None", -". c #027486", -"+ c #017387", -"@ c #9AEFFE", -"# c #007388", -"$ c #007288", -"% c #99EEFF", -"& c #007188", -"* c #007088", -"= c #99EDFF", -"- c #006F88", -"; c #006E88", -"> c #99EBFF", -", c #006D88", -"' c #99EAFF", -") c #006B88", -"! c #99E9FF", -"~ c #006C88", -"{ c #006A88", -"] c #99E8FF", -"^ c #006888", -"/ c #99E7FF", -"( c #006788", -"_ c #99E6FF", -": c #006588", -"< c #99E5FF", -"[ c #006688", -"} c #006488", -" ", -" ", -" ", -" . ", -" +@# ", -" $%%$& ", -" **=*==* ", -" -;;>>;>>;>; ", -" ,>',',',,'>', ", -" )!'~)~!')')'~ ", -" {{]]!{{!!]{ ", -" ^//^^^//^ ", -" ((__((( ", -" :<[ ", -" } "}; diff --git a/resources/bitmaps/popup_selection.xpm b/resources/bitmaps/popup_selection.xpm deleted file mode 100644 index 1b987e1..0000000 --- a/resources/bitmaps/popup_selection.xpm +++ /dev/null @@ -1,41 +0,0 @@ -/* XPM */ -static char * popup_selection_xpm[] = { -"16 15 23 1", -" c None", -". c #0CDEF3", -"+ c #09DCF6", -"@ c #FFFFFF", -"# c #01D7FE", -"$ c #00D8FF", -"% c #00D7FF", -"& c #00D4FF", -"* c #00D2FF", -"= c #007088", -"- c #006E88", -"; c #00CCFF", -"> c #006D88", -", c #00CDFF", -"' c #00C8FF", -") c #006C88", -"! c #00CAFF", -"~ c #00C1FF", -"{ c #00C2FF", -"] c #000000", -"^ c #11C3FF", -"/ c #11C0FF", -"( c #11C1FF", -" ", -" .. .. .. .. ", -" + ", -" @ ", -" # @ $ % ", -" & @ & ", -" * * ==== ", -" @ --- ", -" ; >> , ", -" ' @) ! ", -" ", -" ", -" ~~ ~~ {{ ]]]", -" ]^^", -" ]/("}; diff --git a/resources/bitmaps/redo.xpm b/resources/bitmaps/redo.xpm deleted file mode 100644 index 435a652..0000000 --- a/resources/bitmaps/redo.xpm +++ /dev/null @@ -1,36 +0,0 @@ -/* XPM */ -static char * redo_xpm[] = { -"16 16 17 1", -" c None", -". c #47E0FF", -"+ c #47E1FF", -"@ c #46DEFF", -"# c #45DEFF", -"$ c #46DDFF", -"% c #43DBFF", -"& c #44DBFF", -"* c #42D9FF", -"= c #42DAFF", -"- c #41D6FF", -"; c #41D7FF", -"> c #40D7FF", -", c #3FD4FF", -"' c #3ED5FF", -") c #3FD5FF", -"! c #3DD2FF", -" ", -" ", -" ", -" ", -" ", -" ...+ ", -" @ @# $ ", -" % & && ", -" * *=* ", -" - ;;>> ", -" , '),,) ", -" ! ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/refresh_models.xpm b/resources/bitmaps/refresh_models.xpm deleted file mode 100644 index 330f96b..0000000 --- a/resources/bitmaps/refresh_models.xpm +++ /dev/null @@ -1,91 +0,0 @@ -/* XPM */ -static char * refresh_models_xpm[] = { -"16 16 72 1", -" c None", -". c #3FCBE7", -"+ c #3FCDE7", -"@ c #41CDE7", -"# c #43CBED", -"$ c #84FFEB", -"% c #84FFED", -"& c #82FFED", -"* c #49C9F3", -"= c #86FFF3", -"- c #86FFF1", -"; c #88FFF3", -"> c #49C9F1", -", c #47C9F1", -"' c #47C9F3", -") c #4BC9F7", -"! c #8CFFF7", -"~ c #4DC7F7", -"{ c #4BC7F9", -"] c #4DC7F9", -"^ c #4DC9F7", -"/ c #8AFFF9", -"( c #8CFFF9", -"_ c #51C5FD", -": c #90FFFD", -"< c #51C7FD", -"[ c #90FFFF", -"} c #4FC3FF", -"| c #4FC1FF", -"1 c #8EFFFF", -"2 c #4BBDFF", -"3 c #8AFFFF", -"4 c #8CFFFF", -"5 c #4BBBFF", -"6 c #49B7FF", -"7 c #47B7FF", -"8 c #49B9FF", -"9 c #88FFFF", -"0 c #86FFFF", -"a c #47B9FF", -"b c #45B3FF", -"c c #84FFFF", -"d c #45B5FF", -"e c #47B3FF", -"f c #47B5FF", -"g c #41AFFF", -"h c #82FFFF", -"i c #80FFFF", -"j c #41ADFF", -"k c #3FA9FF", -"l c #7EFFFF", -"m c #3DA9FF", -"n c #3BA5FF", -"o c #7AFFFF", -"p c #78FFFF", -"q c #3BA3FF", -"r c #399FFF", -"s c #76FFFF", -"t c #37A1FF", -"u c #39A1FF", -"v c #359BFF", -"w c #72FFFF", -"x c #339BFF", -"y c #74FFFF", -"z c #2F97FF", -"A c #2F95FF", -"B c #3195FF", -"C c #70FFFF", -"D c #6EFFFF", -"E c #2D91FF", -"F c #2D8FFF", -"G c #2B91FF", -" .++@@+ .", -" ##$%&&&%## ##", -" *=-;;-;===;>,;'", -" )!~{]^~!/((((!]", -"_:_ _<[:[:[_", -"}| }1111|", -"2 233435", -"67787767 690990a", -"bcc0ccb bdebdbdf", -"ghhiij g", -"kllllk mm", -"noooponq non", -"rsssssspttttusr ", -"vwxxwywwwywwywv ", -"zA ABCDCCCCAB ", -"E FEEGEE "}; diff --git a/resources/bitmaps/scalelockx.xpm b/resources/bitmaps/scalelockx.xpm deleted file mode 100644 index 9a64cfb..0000000 --- a/resources/bitmaps/scalelockx.xpm +++ /dev/null @@ -1,25 +0,0 @@ -/* XPM */ -static char *scalelockx[] = { -/* columns rows colors chars-per-pixel */ -"16 15 4 1 ", -" c None", -". c black", -"X c blue", -"o c white", -/* pixels */ -" ", -" .............. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .oooXXooXXooo. ", -" .oooXXooXXooo. ", -" .ooooXXXXoooo. ", -" .oooooXXooooo. ", -" .ooooXXXXoooo. ", -" .oooXXooXXooo. ", -" .oooXXooXXooo. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .............. ", -" " -}; diff --git a/resources/bitmaps/scalelocky.xpm b/resources/bitmaps/scalelocky.xpm deleted file mode 100644 index a8e72ad..0000000 --- a/resources/bitmaps/scalelocky.xpm +++ /dev/null @@ -1,25 +0,0 @@ -/* XPM */ -static char *scalelocky[] = { -/* columns rows colors chars-per-pixel */ -"16 15 4 1 ", -" c None", -". c black", -"X c blue", -"o c white", -/* pixels */ -" ", -" .............. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .ooXXooooXXoo. ", -" .ooXXooooXXoo. ", -" .oooXXooXXooo. ", -" .ooooXXXXoooo. ", -" .oooooXXooooo. ", -" .oooooXXooooo. ", -" .oooooXXooooo. ", -" .oooooXXooooo. ", -" .oooooooooooo. ", -" .............. ", -" " -}; diff --git a/resources/bitmaps/scalelockz.xpm b/resources/bitmaps/scalelockz.xpm deleted file mode 100644 index bb4f5c2..0000000 --- a/resources/bitmaps/scalelockz.xpm +++ /dev/null @@ -1,25 +0,0 @@ -/* XPM */ -static char *scalelockz[] = { -/* columns rows colors chars-per-pixel */ -"16 15 4 1 ", -" c None", -". c black", -"X c blue", -"o c white", -/* pixels */ -" ", -" .............. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .oooXXXXXoooo. ", -" .ooooooXXoooo. ", -" .oooooXXooooo. ", -" .ooooXXoooooo. ", -" .ooooXXoooooo. ", -" .oooXXooooooo. ", -" .oooXXXXXoooo. ", -" .oooooooooooo. ", -" .oooooooooooo. ", -" .............. ", -" " -}; diff --git a/resources/bitmaps/select_additive.xpm b/resources/bitmaps/select_additive.xpm deleted file mode 100644 index 565faac..0000000 --- a/resources/bitmaps/select_additive.xpm +++ /dev/null @@ -1,22 +0,0 @@ -/* XPM */ -static char * select_additive_xpm[] = { -"16 16 3 1", -" c None", -". c #46E3FB", -"+ c #23727E", -" ", -" .............. ", -" . . ", -" . . ", -" . . . ", -" . .+ . ", -" . .+ . ", -" . ....... . ", -" . ++.++++ . ", -" . .+ . ", -" . .+ . ", -" . + . ", -" . . ", -" . . ", -" .............. ", -" "}; diff --git a/resources/bitmaps/select_autoexpand.xpm b/resources/bitmaps/select_autoexpand.xpm deleted file mode 100644 index 4ff8b7a..0000000 --- a/resources/bitmaps/select_autoexpand.xpm +++ /dev/null @@ -1,22 +0,0 @@ -/* XPM */ -static char * select_autoexpand_xpm[] = { -"16 16 3 1", -" c None", -". c #46E3FB", -"+ c #2C909F", -" ", -" .............. ", -" . . ", -" . .. . ", -" . .. +.. . ", -" . ..+ ..+ . ", -" . ..+ ..+ . ", -" . ......+ . ", -" . ..++..+ . ", -" . ..+ ..+ . ", -" . ..+ ..+ . ", -" . ..+ ..+ . ", -" . ++ ++ . ", -" . . ", -" .............. ", -" "}; diff --git a/resources/bitmaps/select_mouseresize.xpm b/resources/bitmaps/select_mouseresize.xpm deleted file mode 100644 index 03fd817..0000000 --- a/resources/bitmaps/select_mouseresize.xpm +++ /dev/null @@ -1,40 +0,0 @@ -/* XPM */ -static char * select_mouseresize_xpm[] = { -"16 16 21 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #00C9F7", -"$ c #00C7F7", -"% c #00C5FD", -"& c #00C5FF", -"* c #00C1FF", -"= c #00BBFF", -"- c #00B7FF", -"; c #00B3FF", -"> c #00B5FF", -", c #00ADFF", -"' c #00A9FF", -") c #00A5FF", -"! c #00A3FF", -"~ c #009FFF", -"{ c #009BFF", -"] c #0095FF", -"^ c #0097FF", -" ", -" ..+ ... ... ", -" @ ", -" # $ ", -" % & ", -" * ", -" = ", -" - - ", -" ; > ", -" , ", -" ' ", -" ) ! ", -" ~ ~ ", -" { ", -" ]]] ]]^ ]]] ", -" "}; diff --git a/resources/bitmaps/select_mouserotate.xpm b/resources/bitmaps/select_mouserotate.xpm deleted file mode 100644 index fa75182..0000000 --- a/resources/bitmaps/select_mouserotate.xpm +++ /dev/null @@ -1,42 +0,0 @@ -/* XPM */ -static char * select_mouserotate_xpm[] = { -"16 16 23 1", -" c None", -". c #00CBFF", -"+ c #00C9FF", -"@ c #00C7FF", -"# c #00C5FF", -"$ c #00C5FD", -"% c #00C7FD", -"& c #00C1FF", -"* c #00C3FF", -"= c #00BDFF", -"- c #00BBFF", -"; c #00B7FF", -"> c #00B9FF", -", c #00B3FF", -"' c #00B5FF", -") c #00AFFF", -"! c #00A9FF", -"~ c #00ABFF", -"{ c #00A5FF", -"] c #00A3FF", -"^ c #009FFF", -"/ c #009BFF", -"( c #0095FF", -" ", -" .... ", -" ++ ++ ", -" @ + ", -" # #$%$#$%@ @ ", -" & & * & ", -"= = = - ", -"; > ;;;;;>", -", ' , ',' ", -") ) ) ) ", -" ! ! ~ ", -" { {{{{]]{{ ", -" ^ ", -" // ", -" (( ", -" "}; diff --git a/resources/bitmaps/select_mousescale.xpm b/resources/bitmaps/select_mousescale.xpm deleted file mode 100644 index 3bc4f2b..0000000 --- a/resources/bitmaps/select_mousescale.xpm +++ /dev/null @@ -1,41 +0,0 @@ -/* XPM */ -static char * select_mousescale_xpm[] = { -"16 16 22 1", -" c None", -". c #00CBFF", -"+ c #00C9FF", -"@ c #00C7FF", -"# c #00C5FF", -"$ c #00C1FF", -"% c #00C3FF", -"& c #00BDFF", -"* c #00B7FF", -"= c #00B9FF", -"- c #00B3FF", -"; c #00B5FF", -"> c #00ADFF", -", c #00AFFF", -"' c #00A9FF", -") c #00ABFF", -"! c #00A5FF", -"~ c #00A3FF", -"{ c #009FFF", -"] c #00A1FF", -"^ c #009BFF", -"/ c #0095FF", -" ", -" ... ... ... ", -" ", -" + @@++@ @ ", -" # @@@@ # ", -" $ %$$ $ ", -" & && ", -" **=***** * * ", -" - - ; ", -" > , , ", -" ' ) ", -" ! ~ ~ ", -" { ] { ", -" ^ ^ ^ ", -" //////// /// ", -" "}; diff --git a/resources/bitmaps/select_mousetranslate.xpm b/resources/bitmaps/select_mousetranslate.xpm deleted file mode 100644 index f2b007e..0000000 --- a/resources/bitmaps/select_mousetranslate.xpm +++ /dev/null @@ -1,31 +0,0 @@ -/* XPM */ -static char * select_mousetranslate_xpm[] = { -"16 16 12 1", -" c None", -". c #000000", -"+ c #01D8FE", -"@ c #00D4FF", -"# c #00D2FF", -"$ c #00D0FF", -"% c #00CEFF", -"& c #00CCFF", -"* c #00CDFF", -"= c #00C9FF", -"- c #00CAFF", -"; c #00C6FF", -" ", -" ....... ", -" . . ", -" . . ", -" . . + ", -" . . @@ ", -" . . ##$ ", -" . .%%%%%%% ", -" . . &*& ", -" . . =- ", -" . . ; ", -" . . ", -" . . ", -" . . ", -" ....... ", -" "}; diff --git a/resources/bitmaps/selection_csgmerge.xpm b/resources/bitmaps/selection_csgmerge.xpm deleted file mode 100644 index 3c4e514..0000000 --- a/resources/bitmaps/selection_csgmerge.xpm +++ /dev/null @@ -1,63 +0,0 @@ -/* XPM */ -static char * selection_csgmerge_xpm[] = { -"16 16 44 1", -" c None", -". c #41E5F6", -"+ c #42E5F5", -"@ c #41FFFF", -"# c #42FFFF", -"$ c #43E4F8", -"% c #44E4F9", -"& c #44FFFF", -"* c #43FFFF", -"= c #46E4FB", -"- c #45E3FC", -"; c #46FFFF", -"> c #48E2FE", -", c #48FFFF", -"' c #47E1FF", -") c #47E0FF", -"! c #47FFFF", -"~ c #45DEFF", -"{ c #46DEFF", -"] c #45FFFF", -"^ c #44DBFF", -"/ c #43DBFF", -"( c #44DCFF", -"_ c #42D9FF", -": c #40D7FF", -"< c #40FFFF", -"[ c #3FD4FF", -"} c #3EFFFF", -"| c #3FFFFF", -"1 c #3DD2FF", -"2 c #3CD2FF", -"3 c #3DFFFF", -"4 c #3CCFFF", -"5 c #3BCFFF", -"6 c #3BFFFF", -"7 c #3ACDFF", -"8 c #39CDFF", -"9 c #39FFFF", -"0 c #3AFFFF", -"a c #37CBFF", -"b c #37CAFF", -"c c #38CAFF", -"d c #38FFFF", -"e c #37FFFF", -" ", -"....+ @@#@@", -"$ % & *", -"= - ; ;", -"> > , , ,", -"' ) !! ! !", -"~ { ]]; ] ]", -"^//(/ &*&& * *", -"_ _ ### # *", -": : << @ <", -"[ [ } | }", -"1 2 3 3", -"4 5 6 6", -"7 8 9 0", -"abcbb deddd", -" "}; diff --git a/resources/bitmaps/selection_csgsubtract.xpm b/resources/bitmaps/selection_csgsubtract.xpm deleted file mode 100644 index 638918f..0000000 --- a/resources/bitmaps/selection_csgsubtract.xpm +++ /dev/null @@ -1,63 +0,0 @@ -/* XPM */ -static char * selection_csgsubtract_xpm[] = { -"16 16 44 1", -" c None", -". c #41E5F6", -"+ c #42E5F5", -"@ c #42E5F6", -"# c #44E4F9", -"$ c #45E4FB", -"% c #46E4FC", -"& c #46E3FB", -"* c #48E2FE", -"= c #47E2FF", -"- c #48E3FE", -"; c #48E2FF", -"> c #48E3FF", -", c #47E0FF", -"' c #47FFFF", -") c #45DEFF", -"! c #46DEFF", -"~ c #46FFFF", -"{ c #45FFFF", -"] c #45DDFF", -"^ c #43DBFF", -"/ c #44FFFF", -"( c #42D9FF", -"_ c #42FFFF", -": c #42DAFF", -"< c #41D6FF", -"[ c #40D7FF", -"} c #40FFFF", -"| c #41FFFF", -"1 c #41D7FF", -"2 c #3FD4FF", -"3 c #3FFFFF", -"4 c #3EFFFF", -"5 c #3ED4FF", -"6 c #3DD2FF", -"7 c #3CD2FF", -"8 c #3DD1FF", -"9 c #3BCFFF", -"0 c #3CCFFF", -"a c #39CDFF", -"b c #3ACDFF", -"c c #37CAFF", -"d c #38CAFF", -"e c #38CBFF", -" ", -" ...+@...@...@. ", -" # # # ", -" $ % & ", -" **=*-*;*->- ; ", -" , , ' ' ', , ", -" ) !~ { { ) ] ", -" ^ ^ / / /^ ^ ", -" ( (_ _ _ ( : ", -" < [ } } |1 [ ", -" 2 23 4 4 2 5 ", -" 6 76688666868 ", -" 9 9 0 ", -" a a b ", -" cdccddcdeddcdd ", -" "}; diff --git a/resources/bitmaps/selection_makehollow.xpm b/resources/bitmaps/selection_makehollow.xpm deleted file mode 100644 index b640ded..0000000 --- a/resources/bitmaps/selection_makehollow.xpm +++ /dev/null @@ -1,58 +0,0 @@ -/* XPM */ -static char * selection_makehollow_xpm[] = { -"16 16 39 1", -" c None", -". c #41E5F6", -"+ c #42E5F5", -"@ c #42E5F6", -"# c #44E4F9", -"$ c #45E4FB", -"% c #46FFFF", -"& c #45FFFF", -"* c #46E3FB", -"= c #48E2FE", -"- c #48FFFF", -"; c #48E2FF", -"> c #47E0FF", -", c #47FFFF", -"' c #45DEFF", -") c #45DDFF", -"! c #43DBFF", -"~ c #44FFFF", -"{ c #42D9FF", -"] c #43FFFF", -"^ c #42DAFF", -"/ c #41D6FF", -"( c #40FFFF", -"_ c #40D7FF", -": c #3FD4FF", -"< c #3FFFFF", -"[ c #3ED4FF", -"} c #3DD2FF", -"| c #3DFFFF", -"1 c #3DD1FF", -"2 c #3BCFFF", -"3 c #3BFFFF", -"4 c #3CFFFF", -"5 c #3CCFFF", -"6 c #39CDFF", -"7 c #3ACDFF", -"8 c #37CAFF", -"9 c #38CAFF", -"0 c #38CBFF", -" ", -" ...+@...@...@. ", -" # # ", -" $ %& %% &% % * ", -" = - ; ", -" > , > ", -" ' % & ) ", -" ! ~ ! ", -" { ] ^ ", -" / ( ( _ ", -" : < [ ", -" } | 1 ", -" 2 3 33 33 34 5 ", -" 6 7 ", -" 89889989099899 ", -" "}; diff --git a/resources/bitmaps/selection_makeroom.xpm b/resources/bitmaps/selection_makeroom.xpm deleted file mode 100644 index dad129e..0000000 --- a/resources/bitmaps/selection_makeroom.xpm +++ /dev/null @@ -1,57 +0,0 @@ -/* XPM */ -static char * selection_makeroom_xpm[] = { -"16 16 38 1", -" c None", -". c #41FFFF", -"+ c #42FFFF", -"@ c #44FFFF", -"# c #45FFFF", -"$ c #46E3FB", -"% c #45E3FC", -"& c #46E3FC", -"* c #46E4FB", -"= c #46E4FC", -"- c #47E2FF", -"; c #48E3FF", -"> c #48FFFF", -", c #47FFFF", -"' c #47E0FF", -") c #46DEFF", -"! c #45DEFF", -"~ c #43FFFF", -"{ c #44DCFF", -"] c #44DBFF", -"^ c #43DAFF", -"/ c #42DAFF", -"( c #40D7FF", -"_ c #40FFFF", -": c #3FFFFF", -"< c #3FD4FF", -"[ c #3EFFFF", -"} c #3DFFFF", -"| c #3DD2FF", -"1 c #3DD1FF", -"2 c #3BCFFF", -"3 c #3CD0FF", -"4 c #3BD0FF", -"5 c #3CFFFF", -"6 c #39FFFF", -"7 c #3AFFFF", -"8 c #37FFFF", -"9 c #38FFFF", -" ", -" ... +.. +.. +. ", -" @ @ ", -" # $%&*$$%==& ", -" - ; > ", -" , ' ' , ", -" # ) ! # ", -" ~ { ] ", -" ^ / + ", -" . ( ( _ ", -" : < < [ ", -" } | 1 ", -" 2222344443 5 ", -" 6 7 ", -" 89 899 999 899 ", -" "}; diff --git a/resources/bitmaps/selection_selectcompletetall.xpm b/resources/bitmaps/selection_selectcompletetall.xpm deleted file mode 100644 index 841c164..0000000 --- a/resources/bitmaps/selection_selectcompletetall.xpm +++ /dev/null @@ -1,46 +0,0 @@ -/* XPM */ -static char * selection_selectcompletetall_xpm[] = { -"16 16 27 1", -" c None", -". c #09A7B7", -"+ c #0AA7B6", -"@ c #06A5BA", -"# c #04A5BC", -"$ c #04A4BC", -"% c #01A2BF", -"& c #00A2C0", -"* c #00A0C0", -"= c #00A1C0", -"- c #009EC0", -"; c #009DC0", -"> c #009BC0", -", c #0099C0", -"' c #009AC0", -") c #0097C0", -"! c #0098C0", -"~ c #0095C0", -"{ c #0096C0", -"] c #0093C0", -"^ c #0094C0", -"/ c #0092C0", -"( c #0091C0", -"_ c #0090C0", -": c #008FC0", -"< c #008DC0", -"[ c #008EC0", -" ", -" ...+.......... ", -" @ @ ", -" # $ ", -" % & ", -" *=****=**=**** ", -" - - - ; ", -" > > >>>> > > ", -" , , , ' , ' ", -" ) ! ! ! ! ! ", -" ~ ~ { { ~ ~ ", -" ] ^ ] ] ] / ", -" ( ( ( / / ( ", -" _ _ _ : _ : ", -" <<<< <<<[ <<<< ", -" "}; diff --git a/resources/bitmaps/selection_selectinside.xpm b/resources/bitmaps/selection_selectinside.xpm deleted file mode 100644 index 2efef7f..0000000 --- a/resources/bitmaps/selection_selectinside.xpm +++ /dev/null @@ -1,73 +0,0 @@ -/* XPM */ -static char * selection_selectinside_xpm[] = { -"16 16 54 1", -" c None", -". c #C8E5F6", -"+ c #C9E5F5", -"@ c #C9E5F6", -"# c #41E5F6", -"$ c #42E5F6", -"% c #C9E4F9", -"& c #44E4F9", -"* c #C9E4FB", -"= c #CAE3FB", -"- c #C9E3FC", -"; c #CAE3FC", -"> c #CAE4FB", -", c #46E4FC", -"' c #46E3FB", -") c #CAE2FE", -"! c #CAE2FF", -"~ c #48E3FE", -"{ c #48E2FF", -"] c #CAE0FF", -"^ c #CAE1FF", -"/ c #47E0FF", -"( c #C9DEFF", -"_ c #CADEFF", -": c #45DEFF", -"< c #45DDFF", -"[ c #C9DBFF", -"} c #C9DCFF", -"| c #43DBFF", -"1 c #C9DAFF", -"2 c #42D9FF", -"3 c #42DAFF", -"4 c #C8D6FF", -"5 c #C8D7FF", -"6 c #41D7FF", -"7 c #40D7FF", -"8 c #C8D4FF", -"9 c #C8D5FF", -"0 c #3FD4FF", -"a c #3ED4FF", -"b c #C7D2FF", -"c c #3DD2FF", -"d c #3DD1FF", -"e c #C7CFFF", -"f c #C7D0FF", -"g c #3BD0FF", -"h c #3CCFFF", -"i c #C7CDFF", -"j c #39CDFF", -"k c #3ACDFF", -"l c #C6CAFF", -"m c #C6CBFF", -"n c #38CAFF", -"o c #37CAFF", -" ", -" .. +@ .. ##$# ", -" % & & ", -" * =-;>= - , ' ", -" ) ! ! ~ { ", -" ] ^ ] / / ", -" ( _ ( ( : < ", -" [ }[[[[ | | ", -" 1 2 3 ", -" 4 5545 5 6 7 ", -" 8 8 9 0 a ", -" b b b c d ", -" e eeee f g h ", -" i j k ", -" ll ll lm nonn ", -" "}; diff --git a/resources/bitmaps/selection_selectpartialtall.xpm b/resources/bitmaps/selection_selectpartialtall.xpm deleted file mode 100644 index 47067ff..0000000 --- a/resources/bitmaps/selection_selectpartialtall.xpm +++ /dev/null @@ -1,32 +0,0 @@ -/* XPM */ -static char * selection_selectpartialtall_xpm[] = { -"16 16 13 1", -" c None", -". c #000000", -"+ c #01A2BF", -"@ c #00A0C0", -"# c #009EC0", -"$ c #009BC0", -"% c #0099C0", -"& c #0097C0", -"* c #0098C0", -"= c #0095C0", -"- c #0096C0", -"; c #0093C0", -"> c #0092C0", -" ", -" ...... ....... ", -" . . . . ", -" . . . . ", -" + + + . ", -" @ @ @ . ", -" # # # . ", -" $ $ $$$$$.. ", -" % % ", -" & * *****.. ", -" = - - . ", -" ; ; > . ", -" . . . . ", -" . . . . ", -" ...... ....... ", -" "}; diff --git a/resources/bitmaps/selection_selecttouching.xpm b/resources/bitmaps/selection_selecttouching.xpm deleted file mode 100644 index d32bf3a..0000000 --- a/resources/bitmaps/selection_selecttouching.xpm +++ /dev/null @@ -1,65 +0,0 @@ -/* XPM */ -static char * selection_selecttouching_xpm[] = { -"16 16 46 1", -" c None", -". c #C8E5F6", -"+ c #C9E5F5", -"@ c #C9E5F6", -"# c #C9E4F9", -"$ c #C9E4FB", -"% c #CAE3FB", -"& c #CAE2FE", -"* c #CAE2FF", -"= c #CAE3FE", -"- c #CAE3FF", -"; c #CAE0FF", -"> c #45DEFF", -", c #46DEFF", -"' c #C9DEFF", -") c #46DDFF", -"! c #45DDFF", -"~ c #43DBFF", -"{ c #C9DBFF", -"] c #42D9FF", -"^ c #C9D9FF", -"/ c #C9DAFF", -"( c #42DAFF", -"_ c #41D6FF", -": c #40D7FF", -"< c #C8D7FF", -"[ c #41D7FF", -"} c #3FD4FF", -"| c #C8D5FF", -"1 c #3ED4FF", -"2 c #3DD2FF", -"3 c #3CD2FF", -"4 c #C7D2FF", -"5 c #3DD1FF", -"6 c #3BCFFF", -"7 c #C7CFFF", -"8 c #C7D0FF", -"9 c #3BD0FF", -"0 c #3CCFFF", -"a c #39CDFF", -"b c #C7CDFF", -"c c #3ACDFF", -"d c #37CAFF", -"e c #38CAFF", -"f c #C6CAFF", -"g c #C6CBFF", -" ", -" ...+@...@...@. ", -" # # ", -" $ % ", -" &&*&=&*&=-=-&* ", -" ; ; ", -" >>,, ' ' >>)! ", -" ~ ~ { { ~ ~ ", -" ] ] ^ / ] ( ", -" _ : < < [ : ", -" } } | | } 1 ", -" 2 3 4 4 2 5 ", -" 6 6 7 8 9 0 ", -" a a b b a c ", -" dedd fffg edee ", -" "}; diff --git a/resources/bitmaps/shadernotex.tga b/resources/bitmaps/shadernotex.tga deleted file mode 100644 index a666c7b..0000000 Binary files a/resources/bitmaps/shadernotex.tga and /dev/null differ diff --git a/resources/bitmaps/show_entities.xpm b/resources/bitmaps/show_entities.xpm deleted file mode 100644 index 1d5e342..0000000 --- a/resources/bitmaps/show_entities.xpm +++ /dev/null @@ -1,24 +0,0 @@ -/* XPM */ -static char * show_entities_xpm[] = { -"16 15 6 1", -" c None", -". c #FFFFFF", -"+ c #FF0000", -"@ c #FF00FF", -"# c #0000FF", -"$ c #00FFFF", -" ", -" ........ ", -" .++++++.. ", -" .++++++.+. ", -" .+@+++@.+@. ", -" .@@@@@@.@@. ", -" .@@@@@@.@@. ", -" .@@@@@@.@@. ", -" .@@@@@@.@@. ", -" ........@@. ", -" .@@@@@@.@. ", -" .@@@@@@.. ", -" ........ ###", -" #$$", -" #$$"}; diff --git a/resources/bitmaps/side_brush.png b/resources/bitmaps/side_brush.png deleted file mode 100644 index 933c2bb..0000000 Binary files a/resources/bitmaps/side_brush.png and /dev/null differ diff --git a/resources/bitmaps/side_clipper.xpm b/resources/bitmaps/side_clipper.xpm deleted file mode 100644 index bcb87e1..0000000 --- a/resources/bitmaps/side_clipper.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char *side_clipper[] = { -/* columns rows colors chars-per-pixel */ -"40 32 7 1 ", -" c None", -". c black", -"X c #800000", -"o c red", -"O c #008000", -"+ c green", -"@ c #808080", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" +++++X ", -" ++++++XoXX ", -" +++++++oXoXXXX ", -" ++++++XoXoXoXXXX ", -" OOOOO@oXoXoXoXXXX ", -" OOOOOO@oXoXoXXXXXX ", -" OOOOOOO@oXoXoXXXXXX ", -" OOOOOOOO@oXoXXXXXX@ ", -" OOOOOOOOO@oXoXXXX@@ ", -" OOOOOOOOO@oXoXX@@@ ", -" OOOOOOOOOO@oXX@@@. ", -" OOOOOOOOOOO@o@@@@ ", -" OOOOOOOOOOOO@@@@@ ", -" OOOOOOOOOOOO@@@@ ", -" OOOOOOOOOOO@@@ ", -" OOOOOOOOOO@@@ ", -" OOOOOOO@@ ", -" OOOO@ ", -" OO ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/side_cut.png b/resources/bitmaps/side_cut.png deleted file mode 100644 index c04d87f..0000000 Binary files a/resources/bitmaps/side_cut.png and /dev/null differ diff --git a/resources/bitmaps/side_edges.xpm b/resources/bitmaps/side_edges.xpm deleted file mode 100644 index 12ed1df..0000000 --- a/resources/bitmaps/side_edges.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * side_edges_xpm[] = { -"19 16 26 1", -" c None", -". c #FFFFFF", -"+ c #C0C0C0", -"@ c #000000", -"# c #808080", -"$ c #00D8FF", -"% c #006A80", -"& c #006B80", -"* c #00CEFF", -"= c #006780", -"- c #00CBFF", -"; c #00CCFF", -"> c #006480", -", c #00C6FF", -"' c #00C7FF", -") c #006380", -"! c #006280", -"~ c #00C4FF", -"{ c #00C3FF", -"] c #006080", -"^ c #00BEFF", -"/ c #005E80", -"( c #005B80", -"_ c #00B6FF", -": c #005980", -"< c #005880", -" . . ", -" .....+...@@ ", -"#........@@@ ", -"######..+@@@ ", -" #####.#@$@@ ", -" ####.##@%&@ ", -" #######@@**=@ ", -" ##.####@@-;;=@ ", -" #######@@>,',)@ ", -" #######@@ !~{@ ", -" #######@@ ]^]@ ", -" ####@ /// ", -" # (_(@ ", -" :::@", -" <@@", -" @ "}; diff --git a/resources/bitmaps/side_entities.png b/resources/bitmaps/side_entities.png deleted file mode 100644 index 644dae5..0000000 Binary files a/resources/bitmaps/side_entities.png and /dev/null differ diff --git a/resources/bitmaps/side_entities.xpm b/resources/bitmaps/side_entities.xpm deleted file mode 100644 index adf3bea..0000000 --- a/resources/bitmaps/side_entities.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char *side_entities[] = { -/* columns rows colors chars-per-pixel */ -"40 32 7 1 ", -" c None", -". c black", -"X c #0C0C0C", -"o c #808080", -"O c #C0C0C0", -"+ c #F3F3F3", -"@ c white", -/* pixels */ -" ", -" ", -" ", -" ", -" @ ", -" @ @ ", -" @ @O@O@ooo ", -" @@O@O@Oo.oo ", -" @@@@@OOoo.oo ", -" @@@@OOOOo..o ", -" O@@@OOOOo..o ", -" @@@@OOOOo..o ", -" @@OOO@OOOo..o ", -" @OOOOO@Oo...o ", -" @ OOOOOO@O..oo ", -" @ OOOooo@o.o ", -" @ Oooo.oOo ", -" ooo..o o ", -" Oo...o o ", -" Ooo..o ", -" OOoooo ", -" OOOo.. ", -" @@@OOO.. ", -" OOoo.. ", -" O@@Ooo.. ", -" OOoo.o ", -" @ o ", -" X X X ", -" + + + ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/side_entspec.png b/resources/bitmaps/side_entspec.png deleted file mode 100644 index 98fcf20..0000000 Binary files a/resources/bitmaps/side_entspec.png and /dev/null differ diff --git a/resources/bitmaps/side_faces.xpm b/resources/bitmaps/side_faces.xpm deleted file mode 100644 index f27f59d..0000000 --- a/resources/bitmaps/side_faces.xpm +++ /dev/null @@ -1,58 +0,0 @@ -/* XPM */ -static char * side_faces_xpm[] = { -"17 16 39 1", -" c None", -". c #00FCFF", -"+ c #00FBFF", -"@ c #00F1FF", -"# c #00F2FF", -"$ c #00EFFF", -"% c #808080", -"& c #007680", -"* c #007780", -"= c #00EDFF", -"- c #00ECFF", -"; c #007180", -"> c #007280", -", c #006C80", -"' c #006D80", -") c #00D8FF", -"! c #000000", -"~ c #006A80", -"{ c #006B80", -"] c #006780", -"^ c #006880", -"/ c #00CEFF", -"( c #006680", -"_ c #00CBFF", -": c #00CCFF", -"< c #006480", -"[ c #006380", -"} c #00C6FF", -"| c #00C7FF", -"1 c #006280", -"2 c #00C4FF", -"3 c #00C3FF", -"4 c #006080", -"5 c #00BEFF", -"6 c #005E80", -"7 c #005B80", -"8 c #00B6FF", -"9 c #005980", -"0 c #005880", -" .++..+.+ ", -"@@@#$@@@@@%% ", -"&&*&===--%%% ", -";;>;>;>;%%%% ", -",,,,,',)!%%% ", -"~~{{~~~~{!%% ", -" ]]]^]]]//]! ", -" (((](((_::]! ", -" <[[[[<<<}|}[! ", -" 11111111123! ", -" 444444%454! ", -" 6666 666 ", -" 787! ", -" 999!", -" 0!!", -" ! "}; diff --git a/resources/bitmaps/side_find.xpm b/resources/bitmaps/side_find.xpm deleted file mode 100644 index 2e5ef63..0000000 --- a/resources/bitmaps/side_find.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char *side_find[] = { -/* columns rows colors chars-per-pixel */ -"40 32 6 1 ", -" c None", -". c black", -"X c #800000", -"o c red", -"O c #808000", -"+ c #808080", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" oooX+ ", -" ooXXooX+ ", -" oXXooXXoX+ ", -" XoooooXXoX ", -" oXoooooXXoX+ ", -" o.ooooXXXoo. ", -" oXoooXXX.Xo+ ", -" +XooXoXX+Xo. ", -" .XXoXXX.OXX ", -" XXoXXX..oX+ ", -" o.XXX+.+oX ", -" X.X+.+oX+ ", -" oooooXX.+ ", -" oXXoX.+ ", -" XoX.+ ", -" XoX. ", -" ooX.+ ", -" XoX.. ", -" XoX+ ", -" oX+ ", -" ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/side_move.png b/resources/bitmaps/side_move.png deleted file mode 100644 index 8a5a7a2..0000000 Binary files a/resources/bitmaps/side_move.png and /dev/null differ diff --git a/resources/bitmaps/side_patch.png b/resources/bitmaps/side_patch.png deleted file mode 100644 index 51ca2f2..0000000 Binary files a/resources/bitmaps/side_patch.png and /dev/null differ diff --git a/resources/bitmaps/side_patch.xpm b/resources/bitmaps/side_patch.xpm deleted file mode 100644 index 1645017..0000000 --- a/resources/bitmaps/side_patch.xpm +++ /dev/null @@ -1,157 +0,0 @@ -/* XPM */ -static char *side_patch[] = { -/* columns rows colors chars-per-pixel */ -"40 32 119 2 ", -" c None", -". c #0C0C0C", -"X c #0C0E23", -"o c #0C0E24", -"O c #0D0F27", -"+ c #0D1028", -"@ c #0F122D", -"# c #101330", -"$ c #111433", -"% c #131638", -"& c #13173A", -"* c #450000", -"= c #4F0000", -"- c #520000", -"; c #5C0000", -": c #5D0000", -"> c #670000", -", c #690000", -"< c #740000", -"1 c #7F0000", -"2 c #7F0100", -"3 c #7F0001", -"4 c #7F0101", -"5 c #171B42", -"6 c #1E235A", -"7 c #1E245B", -"8 c #232968", -"9 c #232969", -"0 c #242A6B", -"q c #242A6C", -"w c #262D72", -"e c #272D74", -"r c #2E3477", -"t c #29307B", -"y c #29317C", -"u c #800100", -"i c #800001", -"p c #800101", -"a c #820202", -"s c #8C0C0C", -"d c #8D0E0C", -"f c #8D0C0E", -"g c #8D0E0E", -"h c #981919", -"j c #991919", -"k c #981A19", -"l c #991A19", -"z c #98191A", -"x c #99191A", -"c c #981A1A", -"v c #991A1A", -"b c #9F2420", -"n c #9F2421", -"m c #A12420", -"M c #A12421", -"N c #A42424", -"B c #AC302D", -"V c #AD312E", -"C c #B03131", -"Z c #B13131", -"A c #B33331", -"S c #B33133", -"D c #B13333", -"F c #B33333", -"G c #B73C38", -"H c #B93D3A", -"J c #C44846", -"K c #D05452", -"L c #DC5F5C", -"P c #DD5F5C", -"I c #DC5F5D", -"U c #DC615C", -"Y c #DD615C", -"T c #DE625E", -"R c #E76B69", -"E c #EA6D6A", -"W c #F47876", -"Q c #F47976", -"! c #F47877", -"~ c #F67876", -"^ c #2C3485", -"/ c #2D3586", -"( c #2E3689", -") c #2E368B", -"_ c #323983", -"` c #30388F", -"' c #313A93", -"] c #323A95", -"[ c #323B96", -"{ c #383F91", -"} c #333D9A", -"| c #343D9C", -" . c #3E4492", -".. c #4C52A5", -"X. c #565CB1", -"o. c #6B70B7", -"O. c #7B7FBA", -"+. c #4550C1", -"@. c #4651C1", -"#. c #4E58C4", -"$. c #4F59C4", -"%. c #535DC6", -"&. c #606ACA", -"*. c #7980CB", -"=. c #7F86D4", -"-. c #FF8482", -";. c #FF8582", -":. c #FF8584", -">. c #878DD0", -",. c #8189D5", -"<. c #838BD6", -"1. c #868DD7", -"2. c #8990D8", -"3. c #8A91D8", -"4. c #8B92D8", -"5. c #9198DA", -"6. c #9399DB", -"7. c #989EDD", -"8. c #F3F3F3", -/* pixels */ -" ", -" ", -" D * ", -" D :.N W B - m * ", -" D -.N W k E g T a K < J , H ; B = b * ", -" r D -.N W j E g T a K < J , H ; C = m * ", -" .O D :.N W j E g T a K < J , H : B = b * ", -" O & _ S -.N W j E f T a K < J , H ; C = m * ", -" ..X 7 q Z -.N W k E g T 1 K < J , H : B = m * ", -" @ + e y { Z -.N ! k E f T 1 K < J , H : B = b * ", -" X.X 6 9 ' } D -.N ~ k E f T a K < J , H ; B = b * ", -" $ O ^ w ) $.*. Z -.N W x E g T 1 K < J , H : B = b * ", -" o.O & 9 ] | %.2. D -.N W k E g T 1 K < J , H ; B = b * ", -" 5 X ^ w ` +.=.=.1. D -.N W k E g T 1 K < J , H ; B = m * ", -" O.O & 9 t ) #.=.2.6. C -.N W k E g L 1 K < J , H ; B = m * ", -" # X 6 9 ` X.&.5.2.7. C -.N W k E g L a K < J , H ; C = b * ", -" + + e y ^ $.,.2.6.7. D -.N W k E g L a K < J , H ; B = b * ", -" q ] | &.6.2. C -.N W x E f L 1 K < J , H ; B = b * ", -" C -.N W k E s P a K < J , H ; B = m * ", -" C -.N W k E s P 1 K < J , G ; B = b * ", -" C -.N W k E s L 1 K < J , G ; B = m * ", -" C -.N W k E s T 1 K < J , G ; B = m * ", -" D -.N W h R s L 1 K < J , G ; B = m * ", -" C -.N W h R s U 1 K < J , G : B = b * ", -" -.N W k R s L 1 K < J > G : B = m ", -" k R s L a K < J > G : ", -" ", -" . . . ", -" 8. 8. 8. ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/side_patchspec.png b/resources/bitmaps/side_patchspec.png deleted file mode 100644 index ef83a3a..0000000 Binary files a/resources/bitmaps/side_patchspec.png and /dev/null differ diff --git a/resources/bitmaps/side_resize.png b/resources/bitmaps/side_resize.png deleted file mode 100644 index 0501c33..0000000 Binary files a/resources/bitmaps/side_resize.png and /dev/null differ diff --git a/resources/bitmaps/side_resize.xpm b/resources/bitmaps/side_resize.xpm deleted file mode 100644 index 354f6f5..0000000 --- a/resources/bitmaps/side_resize.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char *side_resize[] = { -/* columns rows colors chars-per-pixel */ -"40 32 5 1 ", -" c None", -". c black", -"X c #3E3E3E", -"o c gray43", -"O c #F8F8F8", -/* pixels */ -" ", -" ", -" ... ... ... ", -" . ", -" . . ", -" . . ", -" . ", -" . ", -" . . ", -" . . ", -" . ", -" . OOOOOOO ", -" . . OOOOOOOOOOOOOOOo ", -" . . XOOOOOOOOOOOOOOOOoo ", -" . XXXXXXOOOOOOOOOoooo ", -" ... ... ... XXXXXXXXXXOOOOooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXoooo ", -" XXXXXXXXXXooo ", -" XXXXXXXoo ", -" XXXXo ", -" X ", -" ", -" " -}; diff --git a/resources/bitmaps/side_rotate.png b/resources/bitmaps/side_rotate.png deleted file mode 100644 index b273e18..0000000 Binary files a/resources/bitmaps/side_rotate.png and /dev/null differ diff --git a/resources/bitmaps/side_rotate.xpm b/resources/bitmaps/side_rotate.xpm deleted file mode 100644 index ab8d223..0000000 --- a/resources/bitmaps/side_rotate.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char *side_rotate[] = { -/* columns rows colors chars-per-pixel */ -"40 32 6 1 ", -" c None", -". c black", -"X c #3E3E3E", -"o c gray43", -"O c blue", -"+ c #F8F8F8", -/* pixels */ -" ", -" ", -" ", -" OOOO ", -" OO OO ", -" O O ", -" O ........ O ", -" O . . O ", -" O . . O ", -" O . .OOOOO ", -" O . . OOO ", -" O . . O +++++++ ", -" O . . +++++++++++++++o ", -" O ........ X++++++++++++++++oo ", -" O XXXXXX+++++++++oooo ", -" OO XXXXXXXXXX++++ooooo ", -" OO XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXoooo ", -" XXXXXXXXXXooo ", -" XXXXXXXoo ", -" XXXXo ", -" X ", -" ", -" " -}; diff --git a/resources/bitmaps/side_scale.png b/resources/bitmaps/side_scale.png deleted file mode 100644 index b51c500..0000000 Binary files a/resources/bitmaps/side_scale.png and /dev/null differ diff --git a/resources/bitmaps/side_scale.xpm b/resources/bitmaps/side_scale.xpm deleted file mode 100644 index 0362663..0000000 --- a/resources/bitmaps/side_scale.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char *side_scale[] = { -/* columns rows colors chars-per-pixel */ -"40 32 6 1 ", -" c None", -". c black", -"X c #3E3E3E", -"o c gray43", -"O c blue", -"+ c #F8F8F8", -/* pixels */ -" ", -" ", -" ", -" OOO OOO OOO ", -" ", -" O OOOOO O ", -" O OOOO O ", -" O OOO O ", -" O OO ", -" ........ O O ", -" . . O ", -" . . O +++++++ ", -" . . +++++++++++++++o ", -" . . O++++++++++++++++oo ", -" . . OXXXXX+++++++++oooo ", -" . . OXXXXXXXXX++++ooooo ", -" ........ OOO XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXoooo ", -" XXXXXXXXXXooo ", -" XXXXXXXoo ", -" XXXXo ", -" X ", -" ", -" " -}; diff --git a/resources/bitmaps/side_select.png b/resources/bitmaps/side_select.png deleted file mode 100644 index b8f30aa..0000000 Binary files a/resources/bitmaps/side_select.png and /dev/null differ diff --git a/resources/bitmaps/side_selectface.png b/resources/bitmaps/side_selectface.png deleted file mode 100644 index 946ab14..0000000 Binary files a/resources/bitmaps/side_selectface.png and /dev/null differ diff --git a/resources/bitmaps/side_selectwhole.png b/resources/bitmaps/side_selectwhole.png deleted file mode 100644 index 51fcff8..0000000 Binary files a/resources/bitmaps/side_selectwhole.png and /dev/null differ diff --git a/resources/bitmaps/side_surface.xpm b/resources/bitmaps/side_surface.xpm deleted file mode 100644 index c5849fa..0000000 --- a/resources/bitmaps/side_surface.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char *side_surface[] = { -/* columns rows colors chars-per-pixel */ -"40 32 10 1 ", -" c None", -". c #0C0C0C", -"X c #800000", -"o c red", -"O c #FF0100", -"+ c #FF0001", -"@ c #008000", -"# c yellow", -"$ c #C3C3C3", -"% c #F3F3F3", -/* pixels */ -" ", -" ", -" $$$$ ", -" $oooo$$$ ", -" $o$$$$ooo$ ", -" $o$ $$o$ ", -" $oo$ $o$ ", -" $oo$ $o$ ", -" $oo$ $o$ ", -" $oo$$$$ $ ", -" $oooooo$$ ", -" $ooooooo$ ####### ", -" $$$ooooo$ ###############@ ", -" $$$ooo$ X################@@ ", -" $ $oo$ XXXXXX#########@@@@ ", -" $o$ $oo$ XXXXXXXXXX####@@@@@ ", -" $o$ $oo$ XXXXXXXXXXXXX@@@@@ ", -" $oo$ $oo$ XXXXXXXXXXXXX@@@@@ ", -" $oo$$ $$o$ XXXXXXXXXXXXX@@@@@ ", -" $o$oo$$$oo$ XXXXXXXXXXXX@@@@@ ", -" $ $$ooo$$ XXXXXXXXXXXX@@@@@ ", -" $$$ XXXXXXXXXXXX@@@@@ ", -" XXXXXXXXXXXX@@@@@ ", -" XXXXXXXXXXXX@@@@@ ", -" XXXXXXXXXXXX@@@@@ ", -" XXXXXXXXXXX@@@@ ", -" XXXXXXXXXX@@@ ", -" . . . XXXXXXX@@ ", -" % % % XXXX@ ", -" X ", -" ", -" " -}; diff --git a/resources/bitmaps/side_surfspec.png b/resources/bitmaps/side_surfspec.png deleted file mode 100644 index eeb0f89..0000000 Binary files a/resources/bitmaps/side_surfspec.png and /dev/null differ diff --git a/resources/bitmaps/side_tex.png b/resources/bitmaps/side_tex.png deleted file mode 100644 index 308e528..0000000 Binary files a/resources/bitmaps/side_tex.png and /dev/null differ diff --git a/resources/bitmaps/side_textures.xpm b/resources/bitmaps/side_textures.xpm deleted file mode 100644 index 25c2197..0000000 --- a/resources/bitmaps/side_textures.xpm +++ /dev/null @@ -1,148 +0,0 @@ -/* XPM */ -static char *side_textures[] = { -/* columns rows colors chars-per-pixel */ -"40 32 110 2 ", -" c None", -". c #0C0C0C", -"X c #240C04", -"o c #291207", -"O c #3C1D09", -"+ c #381D14", -"@ c #372116", -"# c #3E271F", -"$ c #452B21", -"% c #4E372F", -"& c #533C33", -"* c #5A3F34", -"= c #5B402B", -"- c #62463A", -"; c #63483D", -": c #6F543F", -"> c #634B44", -", c #694F42", -"< c #6A5248", -"1 c #725647", -"2 c #72574B", -"3 c #775D50", -"4 c #7C6251", -"5 c #FF0000", -"6 c #9E5113", -"7 c #AC4F0C", -"8 c #A5540F", -"9 c #B2530F", -"0 c #A05116", -"q c #AD5514", -"w c #AC5B1D", -"e c #B45514", -"r c #B35A15", -"t c #B95914", -"y c #B45C1B", -"u c #BB5E1B", -"i c #B36317", -"p c #B6641F", -"a c #BB631C", -"s c #BB6B1C", -"d c #AD5F22", -"f c #B55F20", -"g c #B85D22", -"h c #B46425", -"j c #BB6621", -"k c #BB6A22", -"l c #B76729", -"z c #B46C2B", -"x c #BC6E2B", -"c c #BF702B", -"v c #BC6932", -"b c #BE7130", -"n c #C16A1E", -"m c #C26724", -"M c #C26C25", -"N c #C36C29", -"B c #C96D28", -"V c #C77326", -"C c #C4732B", -"Z c #C9732C", -"A c #CA792E", -"S c #C37432", -"D c #CB7431", -"F c #C77C33", -"G c #C97A33", -"H c #C27738", -"J c #CC7D3B", -"K c #D27737", -"L c #D17A3E", -"P c #856856", -"I c #8E7362", -"U c #927565", -"Y c #CC7E42", -"T c #CE823B", -"R c #D1853E", -"E c #A28975", -"W c #A3877B", -"Q c #AE917F", -"! c #CE8342", -"~ c #D78941", -"^ c #D18E4D", -"/ c #DD9555", -"( c #637BB5", -") c #6681B5", -"_ c #6A82B7", -"` c #6781B9", -"' c #6C85BB", -"] c #6F88BD", -"[ c #728CBD", -"{ c #728CC1", -"} c #788EC0", -"| c #7791C4", -" . c #7B94C3", -".. c #7F9AC5", -"X. c #7C95C9", -"o. c #7F9AC8", -"O. c #B29681", -"+. c #B29583", -"@. c #B59888", -"#. c #B99C8A", -"$. c #BAA393", -"%. c #C8AD98", -"&. c #839ECE", -"*. c #84A0C9", -"=. c #88A4C8", -"-. c #87A2D1", -";. c #8FA9D6", -":. c #9CB5DD", -">. c #C3C3C3", -",. c #F3F3F3", -/* pixels */ -" ", -" ", -" ", -" >.>.>.>.>.>.>.>.>.>.>.>.>.>. ", -" >.5 5 5 5 5 5 5 5 5 5 5 5 5 5 >. ", -" >.5 >.>.>.>.>.5 5 >.>.>.>.>.5 >. ", -" >.5 >. >.5 5 >. >.5 >. ", -" >.5 >. >.5 5 >. >.5 >. ", -" >.5 >. >.5 5 >. >.5 >. ", -" >. >.5 5 >. >. ", -" >.5 5 >. ", -" >.5 5 >. O +.1 W - + $ ", -" >.5 5 >. E : O.#.@.U < * > X & X 3 4 * ' ", -" >.5 5 >. k o $.I %.Q I U - > $ * # % o ; I ' [ ", -" >.5 5 >. C F x x k v P 1 2 - < > % X @ ' _ ) ' ", -" >.5 5 >. C F F k h S 6 x J q & & * X { ] ] | [ ", -" >.5 5 >. h G F j r S w w Y e u p N { } X.| . ", -" >.5 5 >. 8 T C D a S c d S q N N j [ [ X.&.&. ", -" >.>.>.5 5 >.>.>. p R S Z N G c b z q j j k { { ' ' ' ", -" >.5 5 5 5 5 5 5 5 >. R R j B J z / ! S N M x | [ ( ( ( ", -" >.>.>.>.>.>.>.>. G C C a x z ^ / g N D G &.;.&.[ ' ", -" ! x j d l h J L w n m V _ [ .:.' ", -" R m m N Y d x S g t s C ( ( X. .( ", -" F N 7 C v 6 Y D e u B M ( ( ` ( ( ", -" F M 9 m h f K B r u B V ( ( ( ( ( ", -" n a r u e r a s B k C ' ( ( _ ", -" a i s n 9 n s A A s | ' [ ", -" . . . n s s s s A V ..-. ", -" ,. ,. ,. V s G C =. ", -" C ", -" ", -" " -}; diff --git a/resources/bitmaps/side_transform.xpm b/resources/bitmaps/side_transform.xpm deleted file mode 100644 index b7e6f85..0000000 --- a/resources/bitmaps/side_transform.xpm +++ /dev/null @@ -1,44 +0,0 @@ -/* XPM */ -static char *side_transform[] = { -/* columns rows colors chars-per-pixel */ -"40 32 6 1 ", -" c None", -". c black", -"X c #3E3E3E", -"o c gray43", -"O c blue", -"+ c #F8F8F8", -/* pixels */ -" ", -" ", -" ", -" ....... ", -" . . ", -" . . ", -" . . O ", -" . . OO ", -" . . OOO ", -" . .OOOOOOO ", -" . . OOO ", -" . . OO +++++++ ", -" . . O +++++++++++++++o ", -" . . X++++++++++++++++oo ", -" . . XXXXXX+++++++++oooo ", -" . . XXXXXXXXXX++++ooooo ", -" ....... XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXXooooo ", -" XXXXXXXXXXXoooo ", -" XXXXXXXXXXooo ", -" XXXXXXXoo ", -" XXXXo ", -" X ", -" ", -" " -}; diff --git a/resources/bitmaps/side_vertices.xpm b/resources/bitmaps/side_vertices.xpm deleted file mode 100644 index 85ef028..0000000 --- a/resources/bitmaps/side_vertices.xpm +++ /dev/null @@ -1,52 +0,0 @@ -/* XPM */ -static char * side_vertices_xpm[] = { -"19 16 33 1", -" c None", -". c #00FBFF", -"+ c #808080", -"@ c #00F1FF", -"# c #00EFFF", -"$ c #00EDFF", -"% c #00EAFF", -"& c #000000", -"* c #00EBFF", -"= c #00E1FF", -"- c #007280", -"; c #00D8FF", -"> c #006D80", -", c #006A80", -"' c #00D4FF", -") c #006780", -"! c #00CEFF", -"~ c #00CCFF", -"{ c #00CDFF", -"] c #00C6FF", -"^ c #00C4FF", -"/ c #00C3FF", -"( c #006280", -"_ c #006080", -": c #00BEFF", -"< c #00BBFF", -"[ c #005E80", -"} c #00BCFF", -"| c #00B7FF", -"1 c #00B6FF", -"2 c #005B80", -"3 c #005980", -"4 c #005880", -" .. ", -" +@@ +@# ", -"$%& +&$* ", -"== +&-+ + ", -" + +;>+ ", -" & &,'& ", -" & & )!!& ", -" ++ + )~{)) ", -" ]] + ]]]]& ", -" ^/ & (//( ", -" &&+ &+& _:_& ", -" +&&+<& [[}[ ", -" | 12& ", -" 333&", -" 4&&", -" & "}; diff --git a/resources/bitmaps/splash.xcf b/resources/bitmaps/splash.xcf deleted file mode 100644 index 2884cb2..0000000 Binary files a/resources/bitmaps/splash.xcf and /dev/null differ diff --git a/resources/bitmaps/splash.xpm b/resources/bitmaps/splash.xpm deleted file mode 100644 index 14c3fdc..0000000 --- a/resources/bitmaps/splash.xpm +++ /dev/null @@ -1,15768 +0,0 @@ -/* XPM */ -static char * splash_xpm[] = { -"340 188 15577 3", -" c #000000", -". c #FFFFFF", -"+ c #07000E", -"@ c #070E03", -"# c #160B1A", -"$ c #03161D", -"% c #342C38", -"& c #000E1A", -"* c #47565D", -"= c #0E1D25", -"- c #4E4756", -"; c #21474B", -"> c #071A21", -", c #0E0312", -"' c #213038", -") c #1A1221", -"! c #A59D96", -"~ c #C7B4B0", -"{ c #615A65", -"] c #292530", -"^ c #3C4B52", -"/ c #291A16", -"( c #69787F", -"_ c #C7D6E1", -": c #1A2930", -"< c #1D0B07", -"[ c #032138", -"} c #61524E", -"| c #7F706C", -"1 c #70615D", -"2 c #303F47", -"3 c #30211D", -"4 c #1A344B", -"5 c #43473F", -"6 c #56656C", -"7 c #E9DAD6", -"8 c #2C5D70", -"9 c #3F302C", -"0 c #2C475D", -"a c #96BFC3", -"b c #252921", -"c c #564743", -"d c #38303C", -"e c #523C29", -"f c #9D6C4E", -"g c #3C2912", -"h c #29383F", -"i c #968783", -"j c #653F30", -"k c #433C47", -"l c #695A43", -"m c #010101", -"n c #000101", -"o c #52787B", -"p c #000001", -"q c #020101", -"r c #454443", -"s c #676564", -"t c #ACA7A3", -"u c #B6B0AC", -"v c #B2AFAA", -"w c #BEBBB6", -"x c #CCC8C6", -"y c #CBC7C5", -"z c #C5C2BC", -"A c #BDBAB8", -"B c #BCB9B3", -"C c #C3C0BA", -"D c #CAC6C4", -"E c #C8C7C7", -"F c #878686", -"G c #5F5F5E", -"H c #070707", -"I c #010000", -"J c #020202", -"K c #B08374", -"L c #232121", -"M c #42403F", -"N c #878584", -"O c #999493", -"P c #ACA8A7", -"Q c #A6A1A0", -"R c #A29E9C", -"S c #A4A09F", -"T c #94908E", -"U c #9C9897", -"V c #9A9594", -"W c #A09B9A", -"X c #B6B2AE", -"Y c #BBB8B3", -"Z c #C7C3C2", -"` c #CFCECC", -" . c #D2D1CF", -".. c #D9D8D5", -"+. c #D5D4D2", -"@. c #8A8789", -"#. c #4B4A4A", -"$. c #789DA1", -"%. c #4B3C38", -"&. c #0B0A0A", -"*. c #464545", -"=. c #72716E", -"-. c #646260", -";. c #62605F", -">. c #7F7A79", -",. c #807977", -"'. c #7A7674", -"). c #6C6867", -"!. c #706B6A", -"~. c #656461", -"{. c #6E6D6B", -"]. c #7E7978", -"^. c #777271", -"/. c #898483", -"(. c #989392", -"_. c #8C8786", -":. c #AEA9A8", -"<. c #B3B0AF", -"[. c #C3C0BE", -"}. c #DCD9D8", -"|. c #E3DFDF", -"1. c #DBD9D8", -"2. c #BEBCBB", -"3. c #706E6E", -"4. c #1E1E1E", -"5. c #050505", -"6. c #0A0A0A", -"7. c #494846", -"8. c #5E5C5B", -"9. c #53534E", -"0. c #555451", -"a. c #5C5B59", -"b. c #4F4A49", -"c. c #494844", -"d. c #51504D", -"e. c #666561", -"f. c #847F7E", -"g. c #777672", -"h. c #868582", -"i. c #84837F", -"j. c #908B8A", -"k. c #938E8D", -"l. c #7D7877", -"m. c #787372", -"n. c #686462", -"o. c #6D6867", -"p. c #6C6766", -"q. c #767170", -"r. c #908986", -"s. c #9E9794", -"t. c #B3AFAE", -"u. c #BBB7B6", -"v. c #B2ACAC", -"w. c #AEA8A4", -"x. c #AFABAB", -"y. c #737271", -"z. c #292826", -"A. c #050504", -"B. c #3A3939", -"C. c #53514F", -"D. c #42403E", -"E. c #464543", -"F. c #494845", -"G. c #605F5C", -"H. c #666564", -"I. c #8D8A89", -"J. c #959190", -"K. c #918C8B", -"L. c #9F9A99", -"M. c #878483", -"N. c #85807F", -"O. c #7D7978", -"P. c #868280", -"Q. c #797473", -"R. c #676662", -"S. c #5C5B58", -"T. c #706E6B", -"U. c #868382", -"V. c #9B9795", -"W. c #A8A3A2", -"X. c #6D6D6D", -"Y. c #151515", -"Z. c #211A29", -"`. c #928B96", -" + c #0E293F", -".+ c #292926", -"++ c #666664", -"@+ c #4A4946", -"#+ c #403F3D", -"$+ c #454442", -"%+ c #444340", -"&+ c #4B4A48", -"*+ c #706E6C", -"=+ c #5F5E5B", -"-+ c #656460", -";+ c #625E5C", -">+ c #83827F", -",+ c #6D6C6A", -"'+ c #6C6B68", -")+ c #65605F", -"!+ c #878382", -"~+ c #837E7D", -"{+ c #736E6D", -"]+ c #807D7C", -"^+ c #A2A19F", -"/+ c #5A5856", -"(+ c #7B8B92", -"_+ c #0B3C4E", -":+ c #83969D", -"<+ c #FBE5E1", -"[+ c #5E5C5A", -"}+ c #4E4D4A", -"|+ c #3F3E3D", -"1+ c #3F3D3E", -"2+ c #403F3F", -"3+ c #444242", -"4+ c #423F3E", -"5+ c #484644", -"6+ c #6D6C68", -"7+ c #4E4D49", -"8+ c #4B4A46", -"9+ c #585654", -"0+ c #504D4E", -"a+ c #4F4E4B", -"b+ c #6B6A67", -"c+ c #928D8C", -"d+ c #9E9998", -"e+ c #726D6C", -"f+ c #706C6B", -"g+ c #7C7776", -"h+ c #8D8987", -"i+ c #AEAAA9", -"j+ c #B8B4B3", -"k+ c #033447", -"l+ c #1F1F1E", -"m+ c #5B5A5A", -"n+ c #3F3E3B", -"o+ c #3D3B3B", -"p+ c #454344", -"q+ c #403E3F", -"r+ c #423F40", -"s+ c #62615F", -"t+ c #6A6865", -"u+ c #5C5856", -"v+ c #43423F", -"w+ c #403F3E", -"x+ c #51504E", -"y+ c #605C5B", -"z+ c #918C8C", -"A+ c #AFAAA9", -"B+ c #807C7A", -"C+ c #716C6B", -"D+ c #6B6665", -"E+ c #73706D", -"F+ c #6E6B68", -"G+ c #A19C9B", -"H+ c #B9B4B3", -"I+ c #D2D1D1", -"J+ c #504F4F", -"K+ c #020204", -"L+ c #33334D", -"M+ c #49487E", -"N+ c #565C94", -"O+ c #747AAE", -"P+ c #8D97CE", -"Q+ c #9CA3E2", -"R+ c #9AA8EC", -"S+ c #A3B2F4", -"T+ c #A8B1F5", -"U+ c #A7AEF1", -"V+ c #A3AEEF", -"W+ c #A2ACEE", -"X+ c #A8ABF3", -"Y+ c #9CABF2", -"Z+ c #9EA7F4", -"`+ c #A0AAF7", -" @ c #A0A9F6", -".@ c #9AA4F1", -"+@ c #9BA4F3", -"@@ c #929AEE", -"#@ c #909AED", -"$@ c #949FEE", -"%@ c #929BEF", -"&@ c #9098ED", -"*@ c #8B94E0", -"=@ c #878AD1", -"-@ c #6C6EB1", -";@ c #545197", -">@ c #42407F", -",@ c #302F51", -"'@ c #292929", -")@ c #555453", -"!@ c #3B3A38", -"~@ c #3E3B3D", -"{@ c #434042", -"]@ c #494646", -"^@ c #5A5956", -"/@ c #666562", -"(@ c #595855", -"_@ c #403E3E", -":@ c #43403F", -"<@ c #4D4B49", -"[@ c #615E5C", -"}@ c #928D8D", -"|@ c #8B8685", -"1@ c #6A6866", -"2@ c #797673", -"3@ c #94918C", -"4@ c #BEBAB9", -"5@ c #565554", -"6@ c #282A49", -"7@ c #555884", -"8@ c #747DAA", -"9@ c #97A1DD", -"0@ c #A0A7F4", -"a@ c #A0A9F5", -"b@ c #A3AAF7", -"c@ c #AAB7FF", -"d@ c #B1BCFF", -"e@ c #B0C2FF", -"f@ c #B2C3FF", -"g@ c #B1C1FF", -"h@ c #B0BEFF", -"i@ c #AEB8FF", -"j@ c #AFBAFF", -"k@ c #B1B9FF", -"l@ c #A7B0FF", -"m@ c #A6AFFB", -"n@ c #9BA2F4", -"o@ c #9598EE", -"p@ c #9FA3FA", -"q@ c #A6ACF9", -"r@ c #A9AEFA", -"s@ c #A4A9FA", -"t@ c #ABACFD", -"u@ c #A9ACFE", -"v@ c #A9AEFE", -"w@ c #A7AAFE", -"x@ c #A1AAF9", -"y@ c #9FA7F9", -"z@ c #9FA6FC", -"A@ c #9AA2FD", -"B@ c #9BA3F3", -"C@ c #979EF8", -"D@ c #949FF4", -"E@ c #949CF9", -"F@ c #959FF9", -"G@ c #939AF5", -"H@ c #9299E1", -"I@ c #8B8EE9", -"J@ c #7E82C4", -"K@ c #5B5BA6", -"L@ c #46457E", -"M@ c #29254A", -"N@ c #323232", -"O@ c #3B393A", -"P@ c #3F3E3E", -"Q@ c #3D3A3B", -"R@ c #464445", -"S@ c #454342", -"T@ c #504F4D", -"U@ c #74706E", -"V@ c #C1BCBB", -"W@ c #C2BDBC", -"X@ c #292A4F", -"Y@ c #596190", -"Z@ c #959ED5", -"`@ c #ACB6F6", -" # c #AAB9FB", -".# c #AFC2FF", -"+# c #BCC6FF", -"@# c #BAC0FE", -"## c #A9AFFF", -"$# c #A6B2FF", -"%# c #B6BBFF", -"&# c #B7B9FF", -"*# c #B0B6FF", -"=# c #ACB0FF", -"-# c #A9AEFF", -";# c #A0A7FA", -"># c #99A0F5", -",# c #8E94F1", -"'# c #989AF1", -")# c #8E91F2", -"!# c #8482E9", -"~# c #7D80E4", -"{# c #7E7AEA", -"]# c #8586E6", -"^# c #8D86E4", -"/# c #948CE0", -"(# c #9F99E4", -"_# c #9C95E5", -":# c #9F97E5", -"<# c #9490E5", -"[# c #9A95ED", -"}# c #A29EF2", -"|# c #A3A0EE", -"1# c #A4A2EE", -"2# c #A4A3EF", -"3# c #A09FF1", -"4# c #B0ACFD", -"5# c #A7A9FC", -"6# c #A8ACFD", -"7# c #A0A7FD", -"8# c #A0A9F4", -"9# c #999EF1", -"0# c #9C97F3", -"a# c #9998E3", -"b# c #9898E6", -"c# c #9797F0", -"d# c #989BF0", -"e# c #979EF5", -"f# c #949BF8", -"g# c #8C93EF", -"h# c #8E95EC", -"i# c #878ADC", -"j# c #515590", -"k# c #2D2A5B", -"l# c #302F2F", -"m# c #4D4D4B", -"n# c #424040", -"o# c #393638", -"p# c #3A3936", -"q# c #434040", -"r# c #4B4A49", -"s# c #545350", -"t# c #5E5B5A", -"u# c #676261", -"v# c #8E8B89", -"w# c #8E8A89", -"x# c #827D7C", -"y# c #797674", -"z# c #73706E", -"A# c #6A6664", -"B# c #666160", -"C# c #B8B3B2", -"D# c #5B5B5A", -"E# c #020402", -"F# c #363961", -"G# c #666EAB", -"H# c #9CA6EB", -"I# c #9EA9F6", -"J# c #9BA9FD", -"K# c #A7B1FF", -"L# c #B3BBFF", -"M# c #B7C0FF", -"N# c #BDC6FF", -"O# c #BBC0FF", -"P# c #B6B4FF", -"Q# c #B3B2F7", -"R# c #A9ABF9", -"S# c #AEB1FD", -"T# c #A4A8FB", -"U# c #9E9EF0", -"V# c #9892E6", -"W# c #8E8BE2", -"X# c #958CE0", -"Y# c #8B84DD", -"Z# c #867EDD", -"`# c #8982DF", -" $ c #9087E4", -".$ c #8C89E2", -"+$ c #938CE1", -"@$ c #9A92E4", -"#$ c #A19AE9", -"$$ c #A49FF2", -"%$ c #BBB7F9", -"&$ c #C2B8FA", -"*$ c #BDB8F9", -"=$ c #B0AAF7", -"-$ c #AFABF6", -";$ c #A7A1F0", -">$ c #A299E9", -",$ c #A7A0E6", -"'$ c #AEA8EE", -")$ c #B1B1FA", -"!$ c #9C99E7", -"~$ c #9F99EC", -"{$ c #9895E9", -"]$ c #9C99E9", -"^$ c #A4A6F5", -"/$ c #B1AFFF", -"($ c #B0B0FC", -"_$ c #9E99ED", -":$ c #9090E7", -"<$ c #9794EA", -"[$ c #9B9AE5", -"}$ c #A09EF0", -"|$ c #9B9BF0", -"1$ c #A3A3F7", -"2$ c #A0A4F4", -"3$ c #99A2F5", -"4$ c #959EF4", -"5$ c #9B9FF4", -"6$ c #9BA1F4", -"7$ c #999CEF", -"8$ c #6667AF", -"9$ c #423D6C", -"0$ c #2E2D2D", -"a$ c #494948", -"b$ c #504F4E", -"c$ c #3A3838", -"d$ c #444243", -"e$ c #5B5A58", -"f$ c #6B6666", -"g$ c #989493", -"h$ c #ABA7A6", -"i$ c #979291", -"j$ c #A7A2A1", -"k$ c #4D4B4A", -"l$ c #242548", -"m$ c #5A5F9A", -"n$ c #9BA4E7", -"o$ c #A6B7F9", -"p$ c #ABBDFF", -"q$ c #B3C1FF", -"r$ c #B0B8FF", -"s$ c #B4B8FF", -"t$ c #BAC1FF", -"u$ c #BEC2FF", -"v$ c #BABDF7", -"w$ c #B2B2FC", -"x$ c #B2AEF5", -"y$ c #A19EE6", -"z$ c #A09ADF", -"A$ c #A39BE1", -"B$ c #9A91DE", -"C$ c #9B91D9", -"D$ c #9F94DC", -"E$ c #A093D8", -"F$ c #9E93D5", -"G$ c #A295D8", -"H$ c #A393CE", -"I$ c #A993DA", -"J$ c #A898D2", -"K$ c #B09AD3", -"L$ c #AE9CD3", -"M$ c #A999DB", -"N$ c #AF9FDE", -"O$ c #A89ADE", -"P$ c #A9A0DF", -"Q$ c #B6AADE", -"R$ c #B6A8E1", -"S$ c #ACA3DF", -"T$ c #A79ED8", -"U$ c #A8A0D7", -"V$ c #BDB3EE", -"W$ c #BAB0EF", -"X$ c #ABA3DF", -"Y$ c #998ED3", -"Z$ c #A99FDE", -"`$ c #B3AAEB", -" % c #AEA9EA", -".% c #AEA9ED", -"+% c #B3B1F5", -"@% c #B8B6F5", -"#% c #A9A2F3", -"$% c #B0AEF3", -"%% c #A4A7EC", -"&% c #9C9BEF", -"*% c #A1A1F5", -"=% c #8E8DE4", -"-% c #8685D9", -";% c #958EDF", -">% c #9390DD", -",% c #9B94DE", -"'% c #9C95DF", -")% c #9593E0", -"!% c #9992DC", -"~% c #9B93D9", -"{% c #9892DE", -"]% c #9A92E1", -"^% c #9B97E9", -"/% c #9599F5", -"(% c #9299EF", -"_% c #9397E6", -":% c #5E5C9C", -"<% c #28264F", -"[% c #2B2B2B", -"}% c #494946", -"|% c #3A3839", -"1% c #50504E", -"2% c #4A4948", -"3% c #676664", -"4% c #8C8984", -"5% c #938D8A", -"6% c #B0ABAA", -"7% c #B2AEAC", -"8% c #3A3B6D", -"9% c #7E8AC2", -"0% c #A8B7F8", -"a% c #A9B7FD", -"b% c #A3B2FD", -"c% c #B3BEFF", -"d% c #BEC4FF", -"e% c #BEC1FF", -"f% c #C1C1FF", -"g% c #C2C2FF", -"h% c #BEBBFF", -"i% c #AFA9F6", -"j% c #A39AE5", -"k% c #8B89D7", -"l% c #9891DE", -"m% c #8D89D2", -"n% c #9890D4", -"o% c #9C92DF", -"p% c #A99FE2", -"q% c #B4A4E0", -"r% c #AFA6E1", -"s% c #B1A4E4", -"t% c #B09ED8", -"u% c #AA99CF", -"v% c #A092CD", -"w% c #9487CB", -"x% c #9887CB", -"y% c #9E8DC8", -"z% c #AB95CC", -"A% c #B99ED3", -"B% c #B49BD2", -"C% c #B39ACD", -"D% c #B19CD2", -"E% c #AE9AD0", -"F% c #B79CD3", -"G% c #B79FDC", -"H% c #B9A4D9", -"I% c #BAAADB", -"J% c #B6A4D7", -"K% c #B0A1D4", -"L% c #A498D2", -"M% c #B3A2D9", -"N% c #C0B4E7", -"O% c #C3B9F1", -"P% c #C2BBEF", -"Q% c #C3BCF3", -"R% c #CDC5FF", -"S% c #C1BEFF", -"T% c #C1C0FF", -"U% c #C4C0FF", -"V% c #BCBBFF", -"W% c #BCBCFC", -"X% c #B9B8F5", -"Y% c #BDB9FB", -"Z% c #B7B6FF", -"`% c #ABB1F9", -" & c #A8A9F6", -".& c #A9ACFA", -"+& c #ACA8FA", -"@& c #A7A3EF", -"#& c #A8A4EA", -"$& c #A29EE5", -"%& c #AAA0E0", -"&& c #9F97DE", -"*& c #9C93D5", -"=& c #9990D4", -"-& c #938CD0", -";& c #978ED3", -">& c #958DDB", -",& c #9C92E1", -"'& c #9590DF", -")& c #9590EA", -"!& c #9390E6", -"~& c #807CC1", -"{& c #3F3A70", -"]& c #1B1B1B", -"^& c #61605E", -"/& c #3F3D3B", -"(& c #434240", -"_& c #565553", -":& c #444342", -"<& c #494645", -"[& c #686765", -"}& c #747371", -"|& c #7E7C7A", -"1& c #6E6D6A", -"2& c #2D2D2D", -"3& c #3D3A67", -"4& c #9093DC", -"5& c #A4B1FA", -"6& c #B1C5FF", -"7& c #AFBBFF", -"8& c #A8B1FD", -"9& c #A8AEFC", -"0& c #AFB4FF", -"a& c #BBBEFF", -"b& c #B6B2F8", -"c& c #AAA4F0", -"d& c #9E9BEB", -"e& c #AAA2F3", -"f& c #A4A3F1", -"g& c #B4ACF2", -"h& c #B7AFF0", -"i& c #B2ACF0", -"j& c #BDB4F4", -"k& c #BBB2F5", -"l& c #C2B8F8", -"m& c #B9B1F0", -"n& c #ACA6EC", -"o& c #B6B1F4", -"p& c #BCB3F2", -"q& c #BCB1F2", -"r& c #B9AEEE", -"s& c #AFA4E3", -"t& c #A99FE5", -"u& c #9992DF", -"v& c #8D86D8", -"w& c #B098D2", -"x& c #BA9FD1", -"y& c #C4A4D3", -"z& c #C2A6D1", -"A& c #C3A6D1", -"B& c #BCA3D3", -"C& c #B9A3CF", -"D& c #B8A0D1", -"E& c #BBA4D7", -"F& c #C0A4DA", -"G& c #BDA6D7", -"H& c #BEA8D3", -"I& c #B9A0D0", -"J& c #B49CD7", -"K& c #AF97CC", -"L& c #AC99CF", -"M& c #AAA1CD", -"N& c #ACA2D4", -"O& c #CCC2EF", -"P& c #D0CAFF", -"Q& c #D4D0FF", -"R& c #D3D0FF", -"S& c #CBC7FF", -"T& c #CDC6FF", -"U& c #C8BEF6", -"V& c #C0B7EB", -"W& c #CABEE9", -"X& c #CAC2F0", -"Y& c #CCC3FA", -"Z& c #C3BEFF", -"`& c #CABDFF", -" * c #C1B9F7", -".* c #B6ACF4", -"+* c #B2ABF1", -"@* c #B4ABEE", -"#* c #B6ACEF", -"$* c #B3AFF8", -"%* c #B1ABF2", -"&* c #B1A9EB", -"** c #A79CE9", -"=* c #9F97D3", -"-* c #9E90D0", -";* c #988DD2", -">* c #978CD1", -",* c #978BD4", -"'* c #958AD8", -")* c #908AE2", -"!* c #8C8AE4", -"~* c #9590DD", -"{* c #443E72", -"]* c #6E6E6D", -"^* c #3D3B39", -"/* c #3A3938", -"(* c #353432", -"_* c #353434", -":* c #393636", -"<* c #40403E", -"[* c #64645E", -"}* c #797974", -"|* c #8A8985", -"1* c #6C6B67", -"2* c #85827F", -"3* c #898383", -"4* c #837F7E", -"5* c #8B8783", -"6* c #7F7976", -"7* c #8A8685", -"8* c #999595", -"9* c #2E2D54", -"0* c #666AB3", -"a* c #909EF3", -"b* c #91A2F8", -"c* c #9AAAFC", -"d* c #9CA1F7", -"e* c #9392EE", -"f* c #AEAFFF", -"g* c #C1C5FF", -"h* c #C2C5FF", -"i* c #B7B4FE", -"j* c #AEA8F6", -"k* c #C1B9FF", -"l* c #C3BCF9", -"m* c #D3CBFF", -"n* c #E7DAFF", -"o* c #EADCFF", -"p* c #EED7FF", -"q* c #CCC5FF", -"r* c #CDC4FF", -"s* c #CBC3F9", -"t* c #CDC3FC", -"u* c #ACA8E9", -"v* c #948CDF", -"w* c #9086DC", -"x* c #948CD7", -"y* c #8E84C6", -"z* c #9084D2", -"A* c #8E85D7", -"B* c #9087DB", -"C* c #7E7ACD", -"D* c #938DD7", -"E* c #B2A1D2", -"F* c #BDA1C7", -"G* c #CAAAD2", -"H* c #CEAFD5", -"I* c #CDABD7", -"J* c #C7ACD9", -"K* c #C8A4D3", -"L* c #CCA9D0", -"M* c #C7A3C8", -"N* c #C5A6CA", -"O* c #C8A4CC", -"P* c #C6A8C8", -"Q* c #C6A9D0", -"R* c #B39FC6", -"S* c #AF9BD0", -"T* c #AA9CD7", -"U* c #AA9ED8", -"V* c #A998CF", -"W* c #AF97CB", -"X* c #AB9AC4", -"Y* c #B19FCE", -"Z* c #B9ABDB", -"`* c #C5BBEA", -" = c #D8CBF8", -".= c #D4CEFF", -"+= c #D7D0FF", -"@= c #D4CCFF", -"#= c #C2BDFF", -"$= c #C4C0F3", -"%= c #B2AEEC", -"&= c #BEB7EF", -"*= c #B4B0EE", -"== c #AEA7E2", -"-= c #A79ED7", -";= c #9E93CB", -">= c #9A93D0", -",= c #9F93D5", -"'= c #A99CE3", -")= c #ACA8EA", -"!= c #AEA9F1", -"~= c #A9A8F3", -"{= c #AFA7ED", -"]= c #ABA4E6", -"^= c #AFA4E7", -"/= c #9F95D7", -"(= c #9F95DD", -"_= c #A098E3", -":= c #A09AE5", -"<= c #9C94DE", -"[= c #958CD5", -"}= c #938AD8", -"|= c #978EE3", -"1= c #9792E6", -"2= c #6D6AB1", -"3= c #35325A", -"4= c #51504F", -"5= c #71706D", -"6= c #3E3D3A", -"7= c #343330", -"8= c #383536", -"9= c #4B4949", -"0= c #706D6A", -"a= c #716E6B", -"b= c #71706C", -"c= c #8A8584", -"d= c #686764", -"e= c #827E7D", -"f= c #7D7773", -"g= c #84807A", -"h= c #6A6766", -"i= c #060606", -"j= c #13041B", -"k= c #341F3F", -"l= c #372342", -"m= c #18081D", -"n= c #0F1D25", -"o= c #08010E", -"p= c #0B0A1E", -"q= c #545B9E", -"r= c #99A0F2", -"s= c #97A3FA", -"t= c #93A3F9", -"u= c #8C94F2", -"v= c #8C92EF", -"w= c #8B91F1", -"x= c #8B8BEB", -"y= c #9F99F0", -"z= c #AFA9F3", -"A= c #BDBDFF", -"B= c #CEC8FF", -"C= c #D3CCFF", -"D= c #DFD2FF", -"E= c #DAD0FF", -"F= c #E4D8FF", -"G= c #DED2FF", -"H= c #DBD2F1", -"I= c #DBD4F9", -"J= c #D7CFF8", -"K= c #FFF1FF", -"L= c #BDB8EA", -"M= c #BAB0EC", -"N= c #B2AAEA", -"O= c #9F9AE5", -"P= c #9A94E4", -"Q= c #8D89D9", -"R= c #867ECF", -"S= c #7E73CB", -"T= c #7E74CB", -"U= c #8C84DB", -"V= c #8E8AD7", -"W= c #9A95DB", -"X= c #AAA0DA", -"Y= c #BCA7D5", -"Z= c #BEA4CD", -"`= c #BAA2CE", -" - c #C4A9CD", -".- c #C3A3D2", -"+- c #BC9FC6", -"@- c #BD9BBE", -"#- c #CAA0CA", -"$- c #C7A1C5", -"%- c #C2A2BA", -"&- c #CAA3C8", -"*- c #C1A1BD", -"=- c #C6A1C8", -"-- c #CAA8CA", -";- c #BEA1D0", -">- c #BBA0D0", -",- c #9F91C4", -"'- c #A694CC", -")- c #9F92C7", -"!- c #998CC4", -"~- c #AB97CE", -"{- c #A497D1", -"]- c #A293C3", -"^- c #A394CB", -"/- c #AB9ED0", -"(- c #CDC3EA", -"_- c #E1D5F8", -":- c #E3D7FF", -"<- c #C8BEE9", -"[- c #C0B6EB", -"}- c #CAC1FD", -"|- c #CCC2FE", -"1- c #C1B9FA", -"2- c #C0B7F8", -"3- c #AFAAEB", -"4- c #AFA8E3", -"5- c #ABA1DE", -"6- c #A99FDF", -"7- c #AA9FE0", -"8- c #B7ABEE", -"9- c #B3ACF1", -"0- c #C3B8F8", -"a- c #B8B1EC", -"b- c #B1ACF4", -"c- c #B3ACF2", -"d- c #ACA8ED", -"e- c #B2AAF5", -"f- c #AEAAF2", -"g- c #A4A4EC", -"h- c #A7A1ED", -"i- c #A9A0E6", -"j- c #A097E2", -"k- c #988EDB", -"l- c #9990DD", -"m- c #9991E3", -"n- c #625B94", -"o- c #0B0B1B", -"p- c #341E3F", -"q- c #362142", -"r- c #372242", -"s- c #362441", -"t- c #34203F", -"u- c #13051B", -"v- c #2D2B2A", -"w- c #73736E", -"x- c #3D3A3A", -"y- c #4B3F50", -"z- c #493D4F", -"A- c #493C4E", -"B- c #4D4154", -"C- c #4D4153", -"D- c #4C4152", -"E- c #4F4355", -"F- c #4F4455", -"G- c #524758", -"H- c #584E5B", -"I- c #524F50", -"J- c #535350", -"K- c #574D5B", -"L- c #574D5A", -"M- c #5A515E", -"N- c #554B59", -"O- c #5E5460", -"P- c #665E68", -"Q- c #5B535F", -"R- c #6C656D", -"S- c #716C6C", -"T- c #6D6A69", -"U- c #63615F", -"V- c #77736D", -"W- c #76726D", -"X- c #767472", -"Y- c #737270", -"Z- c #646461", -"`- c #777673", -" ; c #6C6A68", -".; c #979292", -"+; c #A19E9C", -"@; c #484848", -"#; c #835234", -"$; c #562C21", -"%; c #100317", -"&; c #6D8B83", -"*; c #CBD1C3", -"=; c #EDE7DF", -"-; c #B18BC2", -";; c #A67BBC", -">; c #B08AC1", -",; c #EAE3D8", -"'; c #E0DBBB", -"); c #8D8567", -"!; c #110618", -"~; c #07000D", -"{; c #121B1D", -"]; c #D2EFDD", -"^; c #D2CE93", -"/; c #30345B", -"(; c #9899E3", -"_; c #A1A9FC", -":; c #A8B3FE", -"<; c #9AA6FD", -"[; c #949AF8", -"}; c #8C93F5", -"|; c #8C92F0", -"1; c #8383EA", -"2; c #7A7DEA", -"3; c #9291EE", -"4; c #8E8ADF", -"5; c #B3B1F2", -"6; c #CFCBFF", -"7; c #D1CFFF", -"8; c #DDD3FF", -"9; c #D1CAFF", -"0; c #D3C8FF", -"a; c #9F9CE3", -"b; c #8E87D8", -"c; c #8E87D5", -"d; c #8B80D2", -"e; c #AAA1E3", -"f; c #9A95DE", -"g; c #948BD9", -"h; c #8C86D4", -"i; c #918AD2", -"j; c #8279CF", -"k; c #736CC3", -"l; c #6C68B9", -"m; c #6E68C0", -"n; c #6C67BD", -"o; c #7972C8", -"p; c #736EBA", -"q; c #8279C0", -"r; c #A795C8", -"s; c #B19CCA", -"t; c #B9A1C5", -"u; c #B09AC6", -"v; c #B198C7", -"w; c #B197C4", -"x; c #B99CC8", -"y; c #B897BD", -"z; c #B495BA", -"A; c #B89CB1", -"B; c #C1A1B3", -"C; c #CDA6BA", -"D; c #D1AACC", -"E; c #CAA7C8", -"F; c #C7A3C5", -"G; c #C8A4C8", -"H; c #CAA6C5", -"I; c #CDA6CD", -"J; c #C1A3C8", -"K; c #B9A0CC", -"L; c #AF9CCC", -"M; c #9B8EBE", -"N; c #988AC4", -"O; c #9486C7", -"P; c #A091CE", -"Q; c #9C92CD", -"R; c #B0A9E1", -"S; c #A9A3D0", -"T; c #C6BDE3", -"U; c #C3B6DB", -"V; c #B9A8CF", -"W; c #B1A2C7", -"X; c #B8ACD2", -"Y; c #CBBDEC", -"Z; c #C1B8F0", -"`; c #C2B6F1", -" > c #B6ACE5", -".> c #C6BCF9", -"+> c #BAB3EC", -"@> c #C3B3EF", -"#> c #B9ACED", -"$> c #B7B0F1", -"%> c #BEB6F6", -"&> c #CFC2FB", -"*> c #C6BDFD", -"=> c #BCB1F3", -"-> c #B7ACF0", -";> c #B0AAF0", -">> c #B2ACF2", -",> c #ACA7EE", -"'> c #A89EDD", -")> c #A29AE0", -"!> c #A399DB", -"~> c #9E94DD", -"{> c #9A91D9", -"]> c #948AD8", -"^> c #9189D5", -"/> c #988DDB", -"(> c #3A345A", -"_> c #9FCABC", -":> c #B28BC4", -"<> c #A97CBE", -"[> c #AE82C1", -"}> c #A87CBD", -"|> c #A47BB9", -"1> c #A37BB8", -"2> c #A67BBB", -"3> c #A67ABC", -"4> c #A87BBD", -"5> c #B791C7", -"6> c #BEB78B", -"7> c #07010D", -"8> c #7C7B79", -"9> c #656560", -"0> c #AFD6C7", -"a> c #AB7EBF", -"b> c #A77BBC", -"c> c #B28BC3", -"d> c #F3EEE4", -"e> c #AAA774", -"f> c #403F3C", -"g> c #444341", -"h> c #53524F", -"i> c #5E5D5A", -"j> c #C4E1D4", -"k> c #B48DC5", -"l> c #A77BBD", -"m> c #DBD4AA", -"n> c #6F6E6C", -"o> c #696866", -"p> c #5C5A58", -"q> c #82817E", -"r> c #949190", -"s> c #8C8683", -"t> c #9E9894", -"u> c #0F0E0E", -"v> c #659382", -"w> c #DBE0DA", -"x> c #D1B8DE", -"y> c #C7A5D8", -"z> c #F0E7E5", -"A> c #B98AC9", -"B> c #AF76C6", -"C> c #B684C9", -"D> c #E3D5E0", -"E> c #E8DDEC", -"F> c #D9C4E3", -"G> c #F5F0D9", -"H> c #908D5C", -"I> c #090F05", -"J> c #100B13", -"K> c #90C4AF", -"L> c #ECE9ED", -"M> c #E5E2B0", -"N> c #06000C", -"O> c #06000D", -"P> c #515389", -"Q> c #9CA7F7", -"R> c #98A0F7", -"S> c #9295EE", -"T> c #8586EC", -"U> c #8585E5", -"V> c #8484E4", -"W> c #7F7FE9", -"X> c #8483E3", -"Y> c #938EEE", -"Z> c #8E8AE2", -"`> c #A19BEB", -" , c #9493E6", -"., c #B0AAF5", -"+, c #BEB9FE", -"@, c #BAB8F8", -"#, c #C4C0ED", -"$, c #9E95DA", -"%, c #ACA4EA", -"&, c #B7B0EF", -"*, c #8C89D7", -"=, c #8078CD", -"-, c #938CDC", -";, c #8279CC", -">, c #7A74C3", -",, c #7971C7", -"', c #837ACC", -"), c #7F77CA", -"!, c #7972BE", -"~, c #7870C6", -"{, c #7C74BE", -"], c #948BCF", -"^, c #9993D9", -"/, c #A69BD9", -"(, c #B1A2D4", -"_, c #BAA8D7", -":, c #C0AAD9", -"<, c #C1A8CE", -"[, c #BDA2CB", -"}, c #A995BB", -"|, c #B094C2", -"1, c #B69AC0", -"2, c #B399B9", -"3, c #B99BBE", -"4, c #BA9BBD", -"5, c #BD9EB6", -"6, c #CAA6B8", -"7, c #D2ACBE", -"8, c #D0ACC3", -"9, c #CDACBA", -"0, c #CAAAC1", -"a, c #CBA9C3", -"b, c #CCABC3", -"c, c #C7A8B9", -"d, c #CBA8C5", -"e, c #C4A6C6", -"f, c #C3A8C3", -"g, c #C2A7CE", -"h, c #BCAAD1", -"i, c #B0A0C1", -"j, c #AE9BC7", -"k, c #A194C5", -"l, c #9E91CC", -"m, c #B7AEEC", -"n, c #C6BCF6", -"o, c #ABA2DF", -"p, c #A89AC7", -"q, c #B4A6CB", -"r, c #B3A0CA", -"s, c #C3B2D7", -"t, c #A99BC3", -"u, c #B3A2C6", -"v, c #B9AFE1", -"w, c #CFC1F1", -"x, c #CBBEF6", -"y, c #C8BDF4", -"z, c #D2C5FF", -"A, c #D2C3F7", -"B, c #B8B0EB", -"C, c #AAA2D8", -"D, c #B6AEE6", -"E, c #C3BAF8", -"F, c #CDC0FF", -"G, c #CFC0FA", -"H, c #BAB2F0", -"I, c #AFA8EA", -"J, c #B2A8E9", -"K, c #B2ABED", -"L, c #B7AEF0", -"M, c #ABA4E0", -"N, c #A99FE0", -"O, c #A49ADC", -"P, c #9E94D4", -"Q, c #9C91D7", -"R, c #9A8ED8", -"S, c #988CD4", -"T, c #978BD9", -"U, c #928ED8", -"V, c #4D487D", -"W, c #9BC8B9", -"X, c #BE8FD1", -"Y, c #B985CF", -"Z, c #D2B8DF", -"`, c #B783CF", -" ' c #A36DBF", -".' c #9E6FBA", -"+' c #9E70B9", -"@' c #A16FBD", -"#' c #B179CC", -"$' c #B57BCF", -"%' c #B883CF", -"&' c #D2B7D8", -"*' c #BBB485", -"=' c #05000B", -"-' c #323230", -";' c #706F6C", -">' c #4E4D4B", -",' c #413F3D", -"'' c #ACD4C5", -")' c #B780CE", -"!' c #C49DD7", -"~' c #B47ECE", -"{' c #B37BCD", -"]' c #BC8DD2", -"^' c #BF91D2", -"/' c #F5F1E4", -"(' c #A4A16F", -"_' c #4F4E4C", -":' c #C4E2D4", -"<' c #C69FD6", -"[' c #B57ECF", -"}' c #B279CC", -"|' c #A36CC0", -"1' c #B47BCE", -"2' c #BE90D1", -"3' c #D9D2A8", -"4' c #666563", -"5' c #52514E", -"6' c #5C5A57", -"7' c #949391", -"8' c #7F7E7C", -"9' c #999591", -"0' c #8D8787", -"a' c #646161", -"b' c #040404", -"c' c #98C7B1", -"d' c #F8F6F6", -"e' c #D5BCE3", -"f' c #EDE6D4", -"g' c #92896C", -"h' c #1B0823", -"i' c #371843", -"j' c #3A1B47", -"k' c #381A44", -"l' c #250E2D", -"m' c #3D4F53", -"n' c #B3CFBE", -"o' c #FCFDF6", -"p' c #FFFEF8", -"q' c #CAC590", -"r' c #556166", -"s' c #D8D6DC", -"t' c #BB99CD", -"u' c #E0DAB2", -"v' c #07020C", -"w' c #05000A", -"x' c #010105", -"y' c #575E90", -"z' c #A8B3F5", -"A' c #A2ACFC", -"B' c #8C94F5", -"C' c #848CF2", -"D' c #848CEB", -"E' c #878CEC", -"F' c #8D94ED", -"G' c #837FE4", -"H' c #8482EB", -"I' c #8A8AEE", -"J' c #807AE1", -"K' c #9C94E7", -"L' c #B8B7F8", -"M' c #A2A2EE", -"N' c #A4A2E7", -"O' c #B3B0F2", -"P' c #AFAAF4", -"Q' c #9C98E0", -"R' c #A199E9", -"S' c #C1BAF4", -"T' c #9991DE", -"U' c #B9B0E5", -"V' c #A399D7", -"W' c #7E74CA", -"X' c #8479D0", -"Y' c #7771BC", -"Z' c #7A72C4", -"`' c #7C72C2", -" ) c #897EC8", -".) c #9086CA", -"+) c #9C93D3", -"@) c #A49ED8", -"#) c #B4A7DA", -"$) c #BDAED7", -"%) c #D7B6DB", -"&) c #D3B6DA", -"*) c #D1B8D5", -"=) c #CFB4DB", -"-) c #C2AAD7", -";) c #C3A6CA", -">) c #B69ABD", -",) c #BC9BBD", -"') c #AE95A8", -")) c #AF90AB", -"!) c #AF8EAC", -"~) c #B28EAB", -"{) c #BA98B2", -"]) c #BE9BAB", -"^) c #B99AA9", -"/) c #C69FA9", -"() c #CE9BA2", -"_) c #CB9B9F", -":) c #CC99A8", -"<) c #C89BA9", -"[) c #C5A0AE", -"}) c #C6A2B7", -"|) c #C5A6B8", -"1) c #C2A6BA", -"2) c #C5A6C5", -"3) c #C6A9CB", -"4) c #C0A8C3", -"5) c #BEA9C2", -"6) c #C0A9CB", -"7) c #BCA3CD", -"8) c #A395CA", -"9) c #807CC3", -"0) c #9494DA", -"a) c #8E8DD5", -"b) c #8B84C0", -"c) c #9991CC", -"d) c #A393C3", -"e) c #B1A1C6", -"f) c #B3A3CA", -"g) c #AF99C0", -"h) c #A795B6", -"i) c #B3A1CD", -"j) c #B0A2CA", -"k) c #B9AED4", -"l) c #C2B4EA", -"m) c #CAC3FC", -"n) c #D1CAFD", -"o) c #C1B9F1", -"p) c #B8B0E3", -"q) c #B1A8DE", -"r) c #B4ABE0", -"s) c #C7BBF6", -"t) c #BCB3EC", -"u) c #B6AFED", -"v) c #B9B2EE", -"w) c #B6B1EC", -"x) c #B4AFE7", -"y) c #ABA9ED", -"z) c #AAA6E7", -"A) c #B0A7E5", -"B) c #A49CE1", -"C) c #A49ADB", -"D) c #9992D3", -"E) c #998ECF", -"F) c #988CD0", -"G) c #988AD8", -"H) c #988CD7", -"I) c #60548C", -"J) c #020206", -"K) c #14041C", -"L) c #391946", -"M) c #3C1B49", -"N) c #3C444F", -"O) c #D2E2E0", -"P) c #C18FD8", -"Q) c #A973C5", -"R) c #A673C1", -"S) c #B07FC9", -"T) c #E7DCCD", -"U) c #605055", -"V) c #3B1C48", -"W) c #30173A", -"X) c #22151A", -"Y) c #030007", -"Z) c #525050", -"`) c #61615D", -" ! c #535250", -".! c #3A3638", -"+! c #4B3852", -"@! c #4A3552", -"#! c #525D65", -"$! c #DEE6E7", -"%! c #AA73C5", -"&! c #A973C4", -"*! c #BF8FD6", -"=! c #E4D9C2", -"-! c #564554", -";! c #483550", -">! c #433F42", -",! c #2F2D2C", -"'! c #32302F", -")! c #3E3D3B", -"!! c #545351", -"~! c #787775", -"{! c #6A6966", -"]! c #646360", -"^! c #504D4D", -"/! c #5A4D5E", -"(! c #748B8A", -"_! c #D9E1E0", -":! c #C492DC", -"~ c #CDA9B3", -",~ c #D3AAB9", -"'~ c #D2A3B6", -")~ c #D1A0A8", -"!~ c #C6A0AB", -"~~ c #C5A1B1", -"{~ c #BE9CA6", -"]~ c #BA99A7", -"^~ c #BA97A8", -"/~ c #B999A4", -"(~ c #BB9BA9", -"_~ c #C3A0C3", -":~ c #C6A4C8", -"<~ c #C2A2C2", -"[~ c #C4A4C7", -"}~ c #BEA4C4", -"|~ c #C0A6C8", -"1~ c #BAA3CB", -"2~ c #A998C1", -"3~ c #9E93D3", -"4~ c #B0AFEF", -"5~ c #B8B0F4", -"6~ c #AFAAEC", -"7~ c #9A97D4", -"8~ c #A495BE", -"9~ c #A894BA", -"0~ c #A894B8", -"a~ c #A999B2", -"b~ c #A695B1", -"c~ c #B099BE", -"d~ c #A793B0", -"e~ c #B09EC5", -"f~ c #AB9ABB", -"g~ c #B4A4C8", -"h~ c #C5B7E4", -"i~ c #CEC2ED", -"j~ c #D1C3F5", -"k~ c #B4AADD", -"l~ c #A99BD2", -"m~ c #B9AFE7", -"n~ c #C2B8F0", -"o~ c #BDB3F6", -"p~ c #B7B3EC", -"q~ c #B0A9E9", -"r~ c #C2B9F0", -"s~ c #D1C8FF", -"t~ c #C7BEF1", -"u~ c #B6AFF1", -"v~ c #B9B1EF", -"w~ c #AEA8E9", -"x~ c #A8A1DE", -"y~ c #A69BE0", -"z~ c #9E95D5", -"A~ c #A094D5", -"B~ c #9B8DD4", -"C~ c #9485D0", -"D~ c #9285CC", -"E~ c #5C538C", -"F~ c #090616", -"G~ c #5D8C7C", -"H~ c #EEE8F2", -"I~ c #B689CC", -"J~ c #AD7DC5", -"K~ c #B78BCC", -"L~ c #D6CFA6", -"M~ c #080808", -"N~ c #010002", -"O~ c #1C1C1C", -"P~ c #5E5E59", -"Q~ c #565651", -"R~ c #474643", -"S~ c #343331", -"T~ c #32312F", -"U~ c #31302D", -"V~ c #80B7A2", -"W~ c #EFE8F3", -"X~ c #B78ACC", -"Y~ c #B388C9", -"Z~ c #DED3E3", -"`~ c #C2BE89", -" { c #181817", -".{ c #1B1B1A", -"+{ c #212120", -"@{ c #232321", -"#{ c #2E2D2C", -"${ c #333230", -"%{ c #4C4C47", -"&{ c #6F6F69", -"*{ c #6C6C66", -"={ c #5E5D5C", -"-{ c #504E4C", -";{ c #505453", -">{ c #E7F2ED", -",{ c #F9F5FB", -"'{ c #DCD9A3", -"){ c #232221", -"!{ c #171715", -"~{ c #1A1918", -"{{ c #201F1E", -"]{ c #504D4C", -"^{ c #75736F", -"/{ c #928E8B", -"({ c #7C7873", -"_{ c #888483", -":{ c #989490", -"<{ c #6C6866", -"[{ c #598676", -"}{ c #E5E1E7", -"|{ c #D4B7E3", -"1{ c #F1EBCA", -"2{ c #06010A", -"3{ c #020005", -"4{ c #121B1F", -"5{ c #131D21", -"6{ c #040C11", -"7{ c #182A24", -"8{ c #D3EBE0", -"9{ c #C89DDD", -"0{ c #B37ECB", -"a{ c #B88CCD", -"b{ c #E2DCB8", -"c{ c #62678B", -"d{ c #565D85", -"e{ c #5C6299", -"f{ c #676EBE", -"g{ c #7E84DA", -"h{ c #8C91ED", -"i{ c #A5A3F2", -"j{ c #9498ED", -"k{ c #9292EA", -"l{ c #9E9AE9", -"m{ c #7E78DB", -"n{ c #9090EA", -"o{ c #B6B0FD", -"p{ c #ACAEF2", -"q{ c #C3BBFD", -"r{ c #C8C1FA", -"s{ c #D8CFF5", -"t{ c #E7D1F6", -"u{ c #E3C4EE", -"v{ c #DDB7E4", -"w{ c #CFB1DA", -"x{ c #C7A8CB", -"y{ c #D1AED7", -"z{ c #D5B1D7", -"A{ c #D3B0D7", -"B{ c #D9B7CB", -"C{ c #EBC0D4", -"D{ c #D9B9CE", -"E{ c #D0B4D3", -"F{ c #CBB3D5", -"G{ c #D5BAE2", -"H{ c #CBB4D5", -"I{ c #C7ACCE", -"J{ c #D2B3D5", -"K{ c #B9A8D1", -"L{ c #C8B6E1", -"M{ c #CFBAE2", -"N{ c #C8B2DA", -"O{ c #B7A7D5", -"P{ c #B2A4D4", -"Q{ c #AF9BC5", -"R{ c #AA95BC", -"S{ c #988CBC", -"T{ c #AC9AD0", -"U{ c #AC9ABC", -"V{ c #A993B2", -"W{ c #9C8AA9", -"X{ c #9F8CAE", -"Y{ c #AC98B9", -"Z{ c #C2A6BD", -"`{ c #CCAEC6", -" ] c #D5B3C3", -".] c #D1ABBE", -"+] c #CAA7B6", -"@] c #C2A2B2", -"#] c #B99AA7", -"$] c #AA91A8", -"%] c #B294B4", -"&] c #B094B0", -"*] c #B79EB2", -"=] c #B69FAB", -"-] c #B99CAF", -";] c #BB99A4", -">] c #C197A0", -",] c #B794A6", -"'] c #B79AAE", -")] c #BCA1B8", -"!] c #BEA3BE", -"~] c #CEACCE", -"{] c #C5ABCA", -"]] c #C6AECF", -"^] c #B8A2C8", -"/] c #A799CA", -"(] c #C5C0F4", -"_] c #B8B2F1", -":] c #9A97D7", -"<] c #8D85B3", -"[] c #978CB4", -"}] c #A897B9", -"|] c #AC99BA", -"1] c #B19ABB", -"2] c #AF99B6", -"3] c #A290AF", -"4] c #A190B2", -"5] c #A699C1", -"6] c #C4B7E9", -"7] c #A79FCC", -"8] c #A89BCC", -"9] c #D0C4F3", -"0] c #C4BAF2", -"a] c #BCB4E9", -"b] c #B6AEEA", -"c] c #C0B7F2", -"d] c #B9B4EF", -"e] c #D0C3FD", -"f] c #C7BDF7", -"g] c #B3AEED", -"h] c #BEB6ED", -"i] c #BDB6ED", -"j] c #B2ABE3", -"k] c #B2A3E7", -"l] c #A89FE0", -"m] c #A398D4", -"n] c #9C92D8", -"o] c #948BD2", -"p] c #8D83CB", -"q] c #8D80C6", -"r] c #5B518A", -"s] c #0B0919", -"t] c #111C1A", -"u] c #DCECE6", -"v] c #BB90D1", -"w] c #B88FCD", -"x] c #EFE9D5", -"y] c #25241C", -"z] c #030303", -"A] c #010001", -"B] c #413F3E", -"C] c #585756", -"D] c #585854", -"E] c #51514B", -"F] c #3D3C3B", -"G] c #373533", -"H] c #3C3C37", -"I] c #373732", -"J] c #2B2A29", -"K] c #2D3D37", -"L] c #EAF0EE", -"M] c #BB8FD1", -"N] c #B081C8", -"O] c #BE99D1", -"P] c #ECE6C6", -"Q] c #0F100F", -"R] c #10100F", -"S] c #21201F", -"T] c #565652", -"U] c #716E67", -"V] c #75726D", -"W] c #6D6C69", -"X] c #868583", -"Y] c #7A7876", -"Z] c #726C69", -"`] c #5A5A55", -" ^ c #51514D", -".^ c #D6F5E4", -"+^ c #FEFDE9", -"@^ c #3C3A27", -"#^ c #100F0F", -"$^ c #0D0D0C", -"%^ c #181717", -"&^ c #2C2C2A", -"*^ c #393836", -"=^ c #4B4A47", -"-^ c #625F5E", -";^ c #666460", -">^ c #4F4F4A", -",^ c #423F3F", -"'^ c #6E6B6A", -")^ c #A6A09C", -"!^ c #AFA9A6", -"~^ c #908D8C", -"{^ c #0B0B0B", -"]^ c #CCE5DB", -"^^ c #C7A7D8", -"/^ c #F1EAF1", -"(^ c #848056", -"_^ c #010003", -":^ c #444E53", -"<^ c #695E5B", -"[^ c #0D0510", -"}^ c #0F0914", -"|^ c #030006", -"1^ c #3A5850", -"2^ c #E9EBEE", -"3^ c #C89EDD", -"4^ c #BD91D2", -"5^ c #E4DCB9", -"6^ c #353A59", -"7^ c #30335A", -"8^ c #404278", -"9^ c #7979B8", -"0^ c #888AD6", -"a^ c #A4A3F2", -"b^ c #AFAEF8", -"c^ c #8280E2", -"d^ c #827EDC", -"e^ c #8983DC", -"f^ c #B8B2F7", -"g^ c #CCC7FF", -"h^ c #CAC2FF", -"i^ c #C2BAED", -"j^ c #D7BEF0", -"k^ c #DFC6FD", -"l^ c #E1C2EA", -"m^ c #D8B9DE", -"n^ c #CFB0D5", -"o^ c #D9B8D5", -"p^ c #D9B7D7", -"q^ c #D8B6D7", -"r^ c #D2B2D3", -"s^ c #DFBDD4", -"t^ c #E0BDDF", -"u^ c #DFBADF", -"v^ c #D5BDCF", -"w^ c #CFB6D5", -"x^ c #CFB1D7", -"y^ c #D0B0D1", -"z^ c #CAB3D4", -"A^ c #D2B6E3", -"B^ c #CAB6E5", -"C^ c #DAC1EE", -"D^ c #D8BDE3", -"E^ c #C4B1D5", -"F^ c #C0ACD9", -"G^ c #BDAAD9", -"H^ c #AEA4D5", -"I^ c #9890CD", -"J^ c #958DD1", -"K^ c #9187C8", -"L^ c #9187C6", -"M^ c #A89CC6", -"N^ c #B1A0D1", -"O^ c #B8A3D2", -"P^ c #A897BC", -"Q^ c #B798BE", -"R^ c #BDA0C8", -"S^ c #BC9FC1", -"T^ c #BCA1C1", -"U^ c #A793B6", -"V^ c #A48DB2", -"W^ c #AB99B1", -"X^ c #B79CC1", -"Y^ c #BDA3CB", -"Z^ c #BAA2C3", -"`^ c #B89CC0", -" / c #BBA2BB", -"./ c #B9A2B3", -"+/ c #BB9CA8", -"@/ c #B994A1", -"#/ c #B498AB", -"$/ c #B398A8", -"%/ c #BA98A7", -"&/ c #BA98A3", -"*/ c #C49EA8", -"=/ c #C4A3B7", -"-/ c #D0AFBE", -";/ c #CEB2C3", -">/ c #C8ACC1", -",/ c #C5AECE", -"'/ c #AC9FC6", -")/ c #A6A1DA", -"!/ c #9B9AD7", -"~/ c #8985C0", -"{/ c #77739F", -"]/ c #9387B4", -"^/ c #A795BD", -"// c #B39EC3", -"(/ c #BAA2C6", -"_/ c #BDA0C7", -":/ c #B6A3BE", -"( c #F3EDDA", -",( c #1F1D14", -"'( c #020003", -")( c #021016", -"!( c #000A15", -"~( c #0B181F", -"{( c #040009", -"]( c #373D66", -"^( c #9BD0C9", -"/( c #F1EAF4", -"(( c #C7A4D7", -"_( c #E3DCB7", -":( c #222439", -"<( c #1F203F", -"[( c #504F74", -"}( c #8586B4", -"|( c #9595E0", -"1( c #A4A6F0", -"2( c #9291EA", -"3( c #8483E1", -"4( c #8C85D9", -"5( c #9E9BE7", -"6( c #A8A6F4", -"7( c #CCC5F8", -"8( c #ABA7EB", -"9( c #A49BE3", -"0( c #DAC2F2", -"a( c #E9CEFD", -"b( c #E3C5ED", -"c( c #DBBADF", -"d( c #DBB9DC", -"e( c #DFBEE6", -"f( c #E1BDDD", -"g( c #E1BED9", -"h( c #DDBDC6", -"i( c #E1BECE", -"j( c #DEBBD1", -"k( c #DCBCCA", -"l( c #DFBCD2", -"m( c #D5B8CE", -"n( c #D1B3CE", -"o( c #D3B3D2", -"p( c #CEB7C7", -"q( c #CFB4CD", -"r( c #E2BEE4", -"s( c #DFC1E6", -"t( c #DBC4EE", -"u( c #D0B8E6", -"v( c #D8BDE1", -"w( c #D2C1F3", -"x( c #D2C0ED", -"y( c #C2AFD5", -"z( c #AFA0C5", -"A( c #9990BC", -"B( c #938CCB", -"C( c #7C77B2", -"D( c #8078BD", -"E( c #8E87C8", -"F( c #9E94C8", -"G( c #B8A8DA", -"H( c #AC9CC2", -"I( c #A99AC4", -"J( c #A394B8", -"K( c #9A8DB2", -"L( c #9E93BB", -"M( c #A193BD", -"N( c #AB9FC6", -"O( c #BEABD2", -"P( c #BCA9CD", -"Q( c #BDA6CD", -"R( c #BDA6CA", -"S( c #C1ABC6", -"T( c #C7ABD1", -"U( c #C2A9C2", -"V( c #BBA0B7", -"W( c #BC9AA7", -"X( c #BB9CA9", -"Y( c #C19FAB", -"Z( c #C49EA9", -"`( c #C09CA3", -" _ c #C099A3", -"._ c #C49EA0", -"+_ c #CCA8B6", -"@_ c #D2B1BD", -"#_ c #CCB0C7", -"$_ c #C7AACC", -"%_ c #A292BC", -"&_ c #A99FD4", -"*_ c #D3C5E9", -"=_ c #B0AAEB", -"-_ c #A8A4E6", -";_ c #B0ABD7", -">_ c #8E8BC3", -",_ c #877FBA", -"'_ c #8A7FBB", -")_ c #8C83B3", -"!_ c #7F7CA9", -"~_ c #7776A3", -"{_ c #6E6C9E", -"]_ c #8B84BC", -"^_ c #9A90C1", -"/_ c #9E90C1", -"(_ c #9F92BB", -"__ c #A690C1", -":_ c #A79AC2", -"<_ c #A39BBD", -"[_ c #A190C0", -"}_ c #A49EC5", -"|_ c #9186B8", -"1_ c #A192C7", -"2_ c #978BB9", -"3_ c #9185B6", -"4_ c #A394C1", -"5_ c #CEC4F2", -"6_ c #D2C2F6", -"7_ c #C0B8E7", -"8_ c #AAA3D2", -"9_ c #B2A8DE", -"0_ c #ACA1DE", -"a_ c #988ACF", -"b_ c #9A90D8", -"c_ c #9B90D4", -"d_ c #9086CE", -"e_ c #9083C5", -"f_ c #897DC1", -"g_ c #463E6A", -"h_ c #000D19", -"i_ c #4B7365", -"j_ c #EFEBF2", -"k_ c #C29ED3", -"l_ c #B992CC", -"m_ c #C6A8D5", -"n_ c #DAD4A9", -"o_ c #080908", -"p_ c #2B2B29", -"q_ c #5D5D58", -"r_ c #6B6B65", -"s_ c #64645F", -"t_ c #363533", -"u_ c #33322F", -"v_ c #363432", -"w_ c #343133", -"x_ c #312E30", -"y_ c #8AC0AC", -"z_ c #E1D8E5", -"A_ c #BD9ACE", -"B_ c #BE9CCF", -"C_ c #E5DFE7", -"D_ c #C4C089", -"E_ c #121110", -"F_ c #222121", -"G_ c #383635", -"H_ c #484745", -"I_ c #555550", -"J_ c #74746E", -"K_ c #7C7C76", -"L_ c #8E8B86", -"M_ c #B4B1AC", -"N_ c #6D6D68", -"O_ c #93C9B2", -"P_ c #FFFFFB", -"Q_ c #999669", -"R_ c #191817", -"S_ c #141313", -"T_ c #282825", -"U_ c #3B3B37", -"V_ c #5B5A57", -"W_ c #575654", -"X_ c #454542", -"Y_ c #4A4949", -"Z_ c #6D6A67", -"`_ c #938F8D", -" : c #9F9E9E", -".: c #9DCCBD", -"+: c #CAB0D8", -"@: c #C3A1D3", -"#: c #EDE7C9", -"$: c #08060A", -"%: c #363964", -"&: c #9293E2", -"*: c #838BD6", -"=: c #7180BB", -"-: c #E9F1ED", -";: c #CDADDC", -">: c #E4DDB8", -",: c #1C1A2C", -"': c #1D1B36", -"): c #4B4A6E", -"!: c #948FB2", -"~: c #AAA7D9", -"{: c #948DD8", -"]: c #A7A1EC", -"^: c #CCC2F6", -"/: c #E9DFFF", -"(: c #DED7FF", -"_: c #C6BCF4", -":: c #A79FE0", -"<: c #B6A9EA", -"[: c #D8C6F4", -"}: c #E1C6F0", -"|: c #E1C0E6", -"1: c #E3C1E7", -"2: c #E7C4E6", -"3: c #E2C0DC", -"4: c #DEBDD7", -"5: c #DFBCCE", -"6: c #D7B4C4", -"7: c #D7B7CB", -"8: c #DCBACC", -"9: c #DAB8CB", -"0: c #DAB8CD", -"a: c #D5B6CA", -"b: c #D4B4CE", -"c: c #D4B6D0", -"d: c #DCBBD4", -"e: c #DDBEDA", -"f: c #E3C2E9", -"g: c #E7CBEE", -"h: c #EED0F5", -"i: c #EED0F2", -"j: c #EECCF0", -"k: c #E0BEE0", -"l: c #C8AECF", -"m: c #C3AAC6", -"n: c #B69FC0", -"o: c #A995BE", -"p: c #B29EC5", -"q: c #9A8DBE", -"r: c #8B85C7", -"s: c #9A97CD", -"t: c #8079B9", -"u: c #6B689A", -"v: c #837CA9", -"w: c #A899BC", -"x: c #9E8CB0", -"y: c #A695BA", -"z: c #A897BD", -"A: c #A797C6", -"B: c #A092BA", -"C: c #B4A2CA", -"D: c #B8A3CA", -"E: c #BEA4CB", -"F: c #B29FC2", -"G: c #B3A0BB", -"H: c #B99EBC", -"I: c #C0A7CA", -"J: c #B69CBB", -"K: c #BAA3BB", -"L: c #BCA3BB", -"M: c #B69AB4", -"N: c #B8A0B2", -"O: c #C1A1AC", -"P: c #C4A1AA", -"Q: c #C5A4B1", -"R: c #C7A4B8", -"S: c #C1A0AE", -"T: c #C49A9C", -"U: c #D5B1BB", -"V: c #D7B6C8", -"W: c #C4ABB9", -"X: c #C6A8C2", -"Y: c #BCA2CB", -"Z: c #C3B0CF", -"`: c #8A82B7", -" < c #7E7CBE", -".< c #9F9BD5", -"+< c #BBB4F2", -"@< c #CAC3F7", -"#< c #B2A9E7", -"$< c #8C86C8", -"%< c #8C84C6", -"&< c #B3AAE0", -"*< c #AAA3D3", -"=< c #6E6DA3", -"-< c #928AC0", -";< c #948DB1", -">< c #978DB2", -",< c #988EB6", -"'< c #9C8BBB", -")< c #948AB3", -"!< c #9F90BC", -"~< c #9A8BB8", -"{< c #9086AF", -"]< c #9F92C0", -"^< c #A79ACB", -"/< c #9A92C6", -"(< c #A9A2D1", -"_< c #B4A9E2", -":< c #CBBCEE", -"<< c #C7BADF", -"[< c #D0C0F2", -"}< c #CCC2F3", -"|< c #B4A6DA", -"1< c #9C8EC3", -"2< c #9A90C7", -"3< c #958BCF", -"4< c #8C82C8", -"5< c #8A7FC6", -"6< c #8C85CB", -"7< c #998ED1", -"8< c #9489C6", -"9< c #897EBA", -"0< c #8A7DC0", -"a< c #2F2A4F", -"b< c #DCEEE6", -"c< c #BE9ACF", -"d< c #C4A5D3", -"e< c #F1ECD9", -"f< c #26251D", -"g< c #383834", -"h< c #575752", -"i< c #666661", -"j< c #74746F", -"k< c #373536", -"l< c #B9DFD0", -"m< c #CAAFD8", -"n< c #BF9BD0", -"o< c #BE9ACE", -"p< c #C9AED7", -"q< c #EFEACC", -"r< c #171716", -"s< c #363534", -"t< c #4C4B49", -"u< c #545352", -"v< c #514F4D", -"w< c #75756F", -"x< c #84807C", -"y< c #ACAAA7", -"z< c #A7A7A2", -"A< c #73736D", -"B< c #696963", -"C< c #D2F4E2", -"D< c #FCFBE0", -"E< c #505048", -"F< c #33332F", -"G< c #252423", -"H< c #1E1E1C", -"I< c #252422", -"J< c #3B3A39", -"K< c #52514F", -"L< c #484744", -"M< c #514F4E", -"N< c #697473", -"O< c #9FA399", -"P< c #C0BCAF", -"Q< c #CAC4B2", -"R< c #B8B29E", -"S< c #98927D", -"T< c #676565", -"U< c #888784", -"V< c #ABA9A7", -"W< c #A9A6A4", -"X< c #B0ACA8", -"Y< c #A19E9B", -"Z< c #1A1A19", -"`< c #190F1F", -" [ c #43364A", -".[ c #4A3C53", -"+[ c #46384D", -"@[ c #46384C", -"#[ c #45384C", -"$[ c #45384D", -"%[ c #332739", -"&[ c #0F0615", -"*[ c #08010F", -"=[ c #43354A", -"-[ c #46384E", -";[ c #47394E", -">[ c #44364A", -",[ c #19101F", -"'[ c #26161B", -")[ c #3D3044", -"![ c #140B1A", -"~[ c #BFE1D4", -"{[ c #C6A7D4", -"][ c #C5A5D4", -"^[ c #EFEACE", -"/[ c #090709", -"([ c #21203A", -"_[ c #9CA5E2", -":[ c #9DA6F9", -"<[ c #9098F1", -"[[ c #9099EF", -"}[ c #757ECA", -"|[ c #BFE4DC", -"1[ c #DDC3EA", -"2[ c #E7E1BA", -"3[ c #1F1D32", -"4[ c #2E2C3F", -"5[ c #595671", -"6[ c #9990B2", -"7[ c #C3B4E1", -"8[ c #E7D3F7", -"9[ c #F1DAFD", -"0[ c #F4D8FC", -"a[ c #F2D4FB", -"b[ c #EBCFF6", -"c[ c #F4D4F1", -"d[ c #EAC8F6", -"e[ c #E7C7EB", -"f[ c #E7C7E8", -"g[ c #D6B5DD", -"h[ c #D5B5DB", -"i[ c #CDAEDA", -"j[ c #D9B6D8", -"k[ c #DBBACF", -"l[ c #D7B3C6", -"m[ c #CCADC9", -"n[ c #C5AABE", -"o[ c #CAAFC2", -"p[ c #DEB9CA", -"q[ c #E0BACB", -"r[ c #DDB6BF", -"s[ c #DBB9CB", -"t[ c #DCBED2", -"u[ c #D1B6CB", -"v[ c #E4C7ED", -"w[ c #F6CFFC", -"x[ c #EECCFB", -"y[ c #E6C5EA", -"z[ c #DCBDD3", -"A[ c #DDBDCB", -"B[ c #D3B3C2", -"C[ c #CFACBC", -"D[ c #C8B1C0", -"E[ c #C6ABCC", -"F[ c #C0ABD4", -"G[ c #BAA3CF", -"H[ c #BCB1D2", -"I[ c #D8EADC", -"J[ c #CEC4BC", -"K[ c #8881B6", -"L[ c #7571A8", -"M[ c #7B72AE", -"N[ c #827EC1", -"O[ c #8981B6", -"P[ c #A093C3", -"Q[ c #AC9BC8", -"R[ c #A999C0", -"S[ c #9E94B7", -"T[ c #978EB6", -"U[ c #A091BA", -"V[ c #A895BD", -"W[ c #AB94B7", -"X[ c #B09CBF", -"Y[ c #B8A2C3", -"Z[ c #B8A2B9", -"`[ c #B7A1C3", -" } c #B59FBB", -".} c #B199BA", -"+} c #B99FBB", -"@} c #AE98B8", -"#} c #B098B5", -"$} c #BCA1BB", -"%} c #BEA2AF", -"&} c #C5A6B2", -"*} c #C7A4B3", -"=} c #C6A7B8", -"-} c #C19BA9", -";} c #CEA9B7", -">} c #D1B1C5", -",} c #C3A9C1", -"'} c #C7ACC3", -")} c #C7A9C5", -"!} c #C6AACA", -"~} c #B5A1BC", -"{} c #A192BC", -"]} c #BDADDE", -"^} c #C5B8E6", -"/} c #AEA4D0", -"(} c #C3B9EE", -"_} c #BAB1DC", -":} c #DDC3F2", -"<} c #DDC7EC", -"[} c #D6C2EC", -"}} c #8F84B9", -"|} c #7F77A9", -"1} c #8780C2", -"2} c #847ABA", -"3} c #857EB5", -"4} c #988DC2", -"5} c #9790C1", -"6} c #9B91BA", -"7} c #A292C3", -"8} c #A699CA", -"9} c #A599CA", -"0} c #B0A2CB", -"a} c #B1ABDA", -"b} c #DACAF0", -"c} c #C5BBF0", -"d} c #D4C6F3", -"e} c #BDB3DB", -"f} c #CCBCF4", -"g} c #BBB1EC", -"h} c #A79FD4", -"i} c #9289BA", -"j} c #998EC4", -"k} c #9186CD", -"l} c #7E78BC", -"m} c #8B7DC3", -"n} c #9183C7", -"o} c #9286C6", -"p} c #998CCE", -"q} c #9A89C2", -"r} c #8E7FBC", -"s} c #867AB0", -"t} c #251D32", -"u} c #9FD2BF", -"v} c #E3D1EC", -"w} c #C5A6D5", -"x} c #C5A9D3", -"y} c #E6E1E6", -"z} c #8B895E", -"A} c #3A3A38", -"B} c #555551", -"C} c #666660", -"D} c #3E4640", -"E} c #E8F1ED", -"F} c #CCAFD9", -"G} c #CFAFDE", -"H} c #C3A3D3", -"I} c #C7ABD6", -"J} c #F4F0EC", -"K} c #575536", -"L} c #0F0F0E", -"M} c #2D2C2C", -"N} c #434140", -"O} c #62625D", -"P} c #6D6D67", -"Q} c #70706A", -"R} c #706D66", -"S} c #676762", -"T} c #6D7B73", -"U} c #F8FEF8", -"V} c #E6E4AD", -"W} c #373735", -"X} c #272725", -"Y} c #272625", -"Z} c #2A2927", -"`} c #333130", -" | c #4E4C4A", -".| c #627069", -"+| c #C2D4C4", -"@| c #F5F3EA", -"#| c #E7D7EF", -"$| c #DCC3E9", -"%| c #DBC1E8", -"&| c #DBC1E7", -"*| c #E0C9EB", -"=| c #F9F5F1", -"-| c #EBE6CF", -";| c #BFB997", -">| c #8A8787", -",| c #9C9998", -"'| c #9C9796", -")| c #96908C", -"!| c #9C9793", -"~| c #97918D", -"{| c #192927", -"]| c #D9EADD", -"^| c #D1B8DA", -"/| c #D4B9DF", -"(| c #CCB0D8", -"_| c #C5AAD2", -":| c #C5AAD1", -"<| c #CAAED7", -"[| c #D4B9DE", -"}| c #CBAFD7", -"|| c #C8ACD5", -"1| c #CAAFD5", -"2| c #DACBD3", -"3| c #D2CBB6", -"4| c #A69F82", -"5| c #1B1320", -"6| c #0C0511", -"7| c #243C35", -"8| c #E1EDE1", -"9| c #D1B7DA", -"0| c #D4B8DE", -"a| c #C9ADD5", -"b| c #C4A8D0", -"c| c #D5BADE", -"d| c #CFB3DA", -"e| c #D2B8DA", -"f| c #B9B389", -"g| c #C8ABD5", -"h| c #CBB0D7", -"i| c #D9C7D9", -"j| c #DFD8C9", -"k| c #C4BE9D", -"l| c #484433", -"m| c #C9E7DB", -"n| c #CAACD8", -"o| c #C8ABD6", -"p| c #F3EFE5", -"q| c #393826", -"r| c #030304", -"s| c #5F659C", -"t| c #A4AEF8", -"u| c #979EF9", -"v| c #8B97F5", -"w| c #8C8BEB", -"x| c #928BDA", -"y| c #9A91D5", -"z| c #A4C6CC", -"A| c #FBF9FC", -"B| c #ECE7B8", -"C| c #413E4D", -"D| c #46404B", -"E| c #6E6476", -"F| c #A394B2", -"G| c #D9BDE1", -"H| c #E7CEF6", -"I| c #E2F0E7", -"J| c #D2B8DB", -"K| c #D5BBE0", -"L| c #D5BADF", -"M| c #CBAED7", -"N| c #D8BFDD", -"O| c #E2D9CB", -"P| c #DDCBB8", -"Q| c #D9B5C0", -"R| c #DDB3C3", -"S| c #D9AFB9", -"T| c #DBB6CB", -"U| c #EDCAE9", -"V| c #F4D1F0", -"W| c #E7C7E6", -"X| c #E4C0DF", -"Y| c #CFABBC", -"Z| c #D1AEBD", -"`| c #DAB6C4", -" 1 c #E7BAC5", -".1 c #DCB9D2", -"+1 c #D2B6D5", -"@1 c #C1A8CC", -"#1 c #C2A7C6", -"$1 c #B6DCD2", -"%1 c #EEECEF", -"&1 c #F7F5DE", -"*1 c #928BB6", -"=1 c #595A88", -"-1 c #57568A", -";1 c #505382", -">1 c #4E5485", -",1 c #55588D", -"'1 c #646598", -")1 c #8E85B6", -"!1 c #9B8DB2", -"~1 c #908BA2", -"{1 c #DEEDE1", -"]1 c #D6BDDE", -"^1 c #CAAED6", -"/1 c #C5A9D1", -"(1 c #D7BCE0", -"_1 c #DBC2E2", -":1 c #E6DCBC", -"<1 c #AF9CB6", -"[1 c #A491AD", -"}1 c #B59EAD", -"|1 c #BCA4B9", -"11 c #C3DFD7", -"21 c #D5BADD", -"31 c #CAADD6", -"41 c #C7ABD3", -"51 c #D6BBE0", -"61 c #DFC6E5", -"71 c #F6F0D5", -"81 c #BAA7AF", -"91 c #C6ABCB", -"01 c #CAAACB", -"a1 c #C0A5BE", -"b1 c #BAA2B3", -"c1 c #C3A2C7", -"d1 c #BEDBD4", -"e1 c #DCC4E2", -"f1 c #C7ABD4", -"g1 c #C4AAD1", -"h1 c #DAC2E1", -"i1 c #F5F2DC", -"j1 c #86849C", -"k1 c #636396", -"l1 c #69719D", -"m1 c #E2EEE4", -"n1 c #D0B7DA", -"o1 c #C8ADD4", -"p1 c #C9B0D2", -"q1 c #E3DCCE", -"r1 c #D4C6E2", -"s1 c #DBCAF6", -"t1 c #B3A9CE", -"u1 c #C4B7E7", -"v1 c #D5C4F7", -"w1 c #B7B0E0", -"x1 c #ACA8DD", -"y1 c #A39BD4", -"z1 c #938AC2", -"A1 c #8785B8", -"B1 c #E0EFE5", -"C1 c #DBC2E1", -"D1 c #C6AAD3", -"E1 c #D6BBE1", -"F1 c #DDC5E4", -"G1 c #D3CAB7", -"H1 c #4A426F", -"I1 c #44695D", -"J1 c #F2F1F4", -"K1 c #CCB0DA", -"L1 c #C3A5D2", -"M1 c #CDB5D9", -"N1 c #DFD9AF", -"O1 c #484843", -"P1 c #6E6E69", -"Q1 c #393835", -"R1 c #73A691", -"S1 c #F7F5F6", -"T1 c #CAB0D3", -"U1 c #ECE4EF", -"V1 c #C6ABD4", -"W1 c #E6E2E8", -"X1 c #CBC890", -"Y1 c #222120", -"Z1 c #353532", -"`1 c #474645", -" 2 c #5D5D57", -".2 c #72726D", -"+2 c #62625C", -"@2 c #62625E", -"#2 c #96CCB6", -"$2 c #FFFFFA", -"%2 c #97946D", -"&2 c #292827", -"*2 c #302F2D", -"=2 c #42423E", -"-2 c #494944", -";2 c #7A7877", -">2 c #AAC7B8", -",2 c #ECE9E9", -"'2 c #E3CFEC", -")2 c #FBF8F3", -"!2 c #E8E3C3", -"~2 c #A39B81", -"{2 c #5C5060", -"]2 c #5C5061", -"^2 c #60636C", -"/2 c #AFC3B5", -"(2 c #ECF2E6", -"_2 c #E9DAF0", -":2 c #E6D7EE", -"<2 c #E9E3D0", -"[2 c #B2AF92", -"}2 c #757270", -"|2 c #7C7A79", -"12 c #9A9695", -"22 c #8F8B85", -"32 c #9A9494", -"42 c #CEE3D4", -"52 c #DEC6E4", -"62 c #F1E8EA", -"72 c #DCC5E7", -"82 c #C6A7D5", -"92 c #C5A6D4", -"02 c #D8BEE5", -"a2 c #F1E8E8", -"b2 c #DABEE3", -"c2 c #D6B8E3", -"d2 c #D8B9E4", -"e2 c #D9BCE5", -"f2 c #E5D3E9", -"g2 c #DEC6EA", -"h2 c #E1CBEC", -"i2 c #F8F5EF", -"j2 c #DFD9B9", -"k2 c #5C583E", -"l2 c #0A0410", -"m2 c #1F342F", -"n2 c #D8E8D9", -"o2 c #F2E9EC", -"p2 c #C5A7D4", -"q2 c #F4EDF5", -"r2 c #E5D3E5", -"s2 c #D9BCE3", -"t2 c #DFC9E0", -"u2 c #ADA77D", -"v2 c #DABFE3", -"w2 c #D6B7E3", -"x2 c #D9BDE4", -"y2 c #EBDEEA", -"z2 c #E6D5EE", -"A2 c #E2CDED", -"B2 c #F8F5F5", -"C2 c #E9E4CB", -"D2 c #807D56", -"E2 c #0E0913", -"F2 c #08020E", -"G2 c #BFE4D6", -"H2 c #D3B8E0", -"I2 c #C8AED6", -"J2 c #E6E1E8", -"K2 c #C2BF8A", -"L2 c #19191A", -"M2 c #1D2019", -"N2 c #31355A", -"O2 c #A4AFF9", -"P2 c #9BA1F6", -"Q2 c #929CF9", -"R2 c #8B8EEE", -"S2 c #9B92EB", -"T2 c #B4A4EA", -"U2 c #C9AFEB", -"V2 c #CAADE5", -"W2 c #C0ABCF", -"X2 c #FBFEFB", -"Y2 c #F0EBBC", -"Z2 c #615766", -"`2 c #564E5C", -" 3 c #75687E", -".3 c #A595B4", -"+3 c #CEC0E1", -"@3 c #F0DAF6", -"#3 c #E2F1E8", -"$3 c #E0C8E6", -"%3 c #F3EAEC", -"&3 c #F2E9E9", -"*3 c #DBC0E4", -"=3 c #D7B9E4", -"-3 c #D7B8E4", -";3 c #DBC0E5", -">3 c #F2E8EE", -",3 c #DEC8E9", -"'3 c #EAE5E4", -")3 c #E5DABE", -"!3 c #DBB8D2", -"~3 c #E0BED5", -"{3 c #E3BBC8", -"]3 c #DBB4BC", -"^3 c #D8B6CA", -"/3 c #D8B3C7", -"(3 c #D4AEBC", -"_3 c #CEA8AF", -":3 c #DAAFBA", -"<3 c #D7B2C5", -"[3 c #D3B2BD", -"}3 c #D3B1C3", -"|3 c #C3A3B6", -"13 c #AA93A9", -"23 c #B89FB8", -"33 c #BEA5C0", -"43 c #DEEEE6", -"53 c #D1BDDC", -"63 c #E7E3E8", -"73 c #D1C6AD", -"83 c #8E7E9D", -"93 c #67667C", -"03 c #494D79", -"a3 c #4D5284", -"b3 c #4E5285", -"c3 c #55588C", -"d3 c #686792", -"e3 c #A493BA", -"f3 c #9389A4", -"g3 c #D9EBDD", -"h3 c #EAD9E7", -"i3 c #F4EDF4", -"j3 c #F5EFF2", -"k3 c #EFE4E4", -"l3 c #DFD5B1", -"m3 c #9C8895", -"n3 c #9B8998", -"o3 c #AF96A0", -"p3 c #B39EAE", -"q3 c #C1D9D1", -"r3 c #DFC7E5", -"s3 c #F2EAEE", -"t3 c #D9BFE6", -"u3 c #C8A9D7", -"v3 c #C2A4D1", -"w3 c #C9ADD7", -"x3 c #F1EBF4", -"y3 c #F8F4E7", -"z3 c #F4EEC9", -"A3 c #AF959D", -"B3 c #B298AA", -"C3 c #B79DAD", -"D3 c #B698A7", -"E3 c #BB98A1", -"F3 c #B8939E", -"G3 c #B7D5C5", -"H3 c #F5EFED", -"I3 c #DCC2E9", -"J3 c #D5B7E4", -"K3 c #CCACDB", -"L3 c #F7F2F4", -"M3 c #FAF7DB", -"N3 c #ACA5B2", -"O3 c #7D78A6", -"P3 c #666E96", -"Q3 c #DBEAE0", -"R3 c #DCC3E5", -"S3 c #E2CDE7", -"T3 c #F1E9F1", -"U3 c #CCB4D8", -"V3 c #ECE5D2", -"W3 c #B4AAC7", -"X3 c #9088B1", -"Y3 c #968EB9", -"Z3 c #A29BCB", -"`3 c #AEA6D6", -" 4 c #A9A5DA", -".4 c #ACA2D8", -"+4 c #998EC6", -"@4 c #948ABE", -"#4 c #DBF1E2", -"$4 c #F6F0EF", -"%4 c #F6F0F3", -"&4 c #F5EFE5", -"*4 c #C9C3A9", -"=4 c #7C6FA1", -"-4 c #7C71A1", -";4 c #26203C", -">4 c #DAF1E6", -",4 c #DAC0E6", -"'4 c #C7AAD5", -")4 c #CBB2D7", -"!4 c #F2EEDD", -"~4 c #323225", -"{4 c #373634", -"]4 c #747472", -"^4 c #BFEBD6", -"/4 c #FAF6E6", -"(4 c #BA9FC7", -"_4 c #E6ECEB", -":4 c #CEB4DB", -"<4 c #CEB8D9", -"[4 c #F0EBCF", -"}4 c #141414", -"|4 c #30302E", -"14 c #60605B", -"24 c #FCFADD", -"34 c #4F4E48", -"44 c #272624", -"54 c #262624", -"64 c #686862", -"74 c #71716B", -"84 c #4A4848", -"94 c #5F6C66", -"04 c #CEDDD5", -"a4 c #D5BFE0", -"b4 c #E6D6EE", -"c4 c #F0EACF", -"d4 c #747362", -"e4 c #3D3B3D", -"f4 c #2E2C2C", -"g4 c #2F2E2C", -"h4 c #2E2D2B", -"i4 c #555553", -"j4 c #90B8A8", -"k4 c #F5F3F3", -"l4 c #E3D0EC", -"m4 c #EEE9E9", -"n4 c #C8C596", -"o4 c #7F7B7B", -"p4 c #787774", -"q4 c #848381", -"r4 c #8D8D88", -"s4 c #979393", -"t4 c #1A111F", -"u4 c #241B2A", -"v4 c #CDE5DD", -"w4 c #CBB1D8", -"x4 c #F4EEF4", -"y4 c #75724F", -"z4 c #483A4E", -"A4 c #4D3E54", -"B4 c #4D3E53", -"C4 c #4B3D52", -"D4 c #403347", -"E4 c #647877", -"F4 c #D3E7D8", -"G4 c #FBF8FA", -"H4 c #E2D0EC", -"I4 c #EBE6E4", -"J4 c #BDBA87", -"K4 c #0D0812", -"L4 c #44364B", -"M4 c #D9E9E4", -"N4 c #CBB2D8", -"O4 c #F4EFF5", -"P4 c #C0BC85", -"Q4 c #3B2F41", -"R4 c #493B50", -"S4 c #413447", -"T4 c #120C17", -"U4 c #050009", -"V4 c #F4EEF3", -"W4 c #787551", -"X4 c #4C4055", -"Y4 c #4C3E54", -"Z4 c #4C3E53", -"`4 c #4A3C51", -" 5 c #332939", -".5 c #556768", -"+5 c #C6DBCB", -"@5 c #F9F7F6", -"#5 c #ECE8EA", -"$5 c #D6D2A7", -"%5 c #1F1C21", -"&5 c #0A0510", -"*5 c #99CDBA", -"=5 c #E8DBEF", -"-5 c #CAAFD7", -";5 c #CBB5D6", -">5 c #E6E1DC", -",5 c #747255", -"'5 c #1A191A", -")5 c #08060B", -"!5 c #08030C", -"~5 c #6B6FA6", -"{5 c #A1A8F3", -"]5 c #9096F0", -"^5 c #9193F0", -"/5 c #A69EE9", -"(5 c #C4B2F0", -"_5 c #CFB8F0", -":5 c #E4C3EB", -"<5 c #E4BBEC", -"[5 c #DCB1E1", -"}5 c #D9BFE8", -"|5 c #ECFDF1", -"15 c #EEEABA", -"25 c #7D6F81", -"35 c #695F70", -"45 c #7F7387", -"55 c #B49DB9", -"65 c #C4B7D4", -"75 c #E0C2EF", -"85 c #DCBEEC", -"95 c #D4C3EE", -"05 c #BEAFDA", -"a5 c #D2E8E2", -"b5 c #AB9C90", -"c5 c #998092", -"d5 c #9C8195", -"e5 c #A48796", -"f5 c #9D8193", -"g5 c #987D90", -"h5 c #987A8B", -"i5 c #A2ACAF", -"j5 c #E6EDE9", -"k5 c #DFC9E9", -"l5 c #D2BBDD", -"m5 c #E7E2DA", -"n5 c #CCB29F", -"o5 c #C2A1AC", -"p5 c #D1ABB8", -"q5 c #D7ADB7", -"r5 c #D8A9B1", -"s5 c #D6AAB1", -"t5 c #C8A0A8", -"u5 c #D5A9AC", -"v5 c #CDA9AF", -"w5 c #CAA3AA", -"x5 c #AE94A3", -"y5 c #B094A9", -"z5 c #C19AA4", -"A5 c #C2A3B3", -"B5 c #AEBFC3", -"C5 c #CFB8DA", -"D5 c #EEE9C9", -"E5 c #736576", -"F5 c #706279", -"G5 c #67647C", -"H5 c #494B7B", -"I5 c #474D7F", -"J5 c #494F7F", -"K5 c #4D5180", -"L5 c #A18EB3", -"M5 c #B19BBD", -"N5 c #9A8BA8", -"O5 c #A78FA9", -"P5 c #A7C0B9", -"Q5 c #F3EFF5", -"R5 c #CEB3DB", -"S5 c #F3EDEE", -"T5 c #9C9084", -"U5 c #76667B", -"V5 c #746675", -"W5 c #8A7387", -"X5 c #978090", -"Y5 c #A88CA8", -"Z5 c #B49BB5", -"`5 c #CCACC8", -" 6 c #CAABB8", -".6 c #BAA1B3", -"+6 c #DEEEE9", -"@6 c #E5DDB6", -"#6 c #867074", -"$6 c #847072", -"%6 c #877279", -"&6 c #947D86", -"*6 c #A68C99", -"=6 c #AF919A", -"-6 c #B68F9D", -";6 c #B28E98", -">6 c #B892A0", -",6 c #AE8A98", -"'6 c #C0E0D3", -")6 c #F7F2F9", -"!6 c #E2CBED", -"~6 c #F4EEDE", -"{6 c #928881", -"]6 c #685E75", -"^6 c #776B86", -"/6 c #918AA8", -"(6 c #AAA0C3", -"_6 c #938CAE", -":6 c #9C91C6", -"<6 c #A298C9", -"[6 c #C9EBE2", -"}6 c #DDC4E9", -"|6 c #D3B8E2", -"16 c #CCB0D9", -"26 c #DCD1E2", -"36 c #DED9AF", -"46 c #4B4A76", -"56 c #625F8B", -"66 c #918BBC", -"76 c #ACA8D4", -"86 c #A09BCC", -"96 c #9D90C0", -"06 c #948AB7", -"a6 c #998CBA", -"b6 c #9A89B7", -"c6 c #B3D5CF", -"d6 c #F7F2F8", -"e6 c #F5EEE0", -"f6 c #7B7487", -"g6 c #564F7E", -"h6 c #5E5683", -"i6 c #69618E", -"j6 c #70688F", -"k6 c #776B9A", -"l6 c #4A4565", -"m6 c #96CEB8", -"n6 c #F3EDF6", -"o6 c #CBB6D7", -"p6 c #E7E3E7", -"q6 c #969365", -"r6 c #181816", -"s6 c #333330", -"t6 c #666663", -"u6 c #575653", -"v6 c #49534C", -"w6 c #F1FDF3", -"x6 c #E9E6B3", -"y6 c #504554", -"z6 c #B9E1D2", -"A6 c #DEC8E8", -"B6 c #CAB2D7", -"C6 c #CCB7D8", -"D6 c #EEEBEA", -"E6 c #696745", -"F6 c #2C2B2A", -"G6 c #5A5957", -"H6 c #7E7E79", -"I6 c #7A7A74", -"J6 c #5B5B56", -"K6 c #5F7469", -"L6 c #FAFEF9", -"M6 c #DFDCA3", -"N6 c #464542", -"O6 c #272526", -"P6 c #20201E", -"Q6 c #494847", -"R6 c #777771", -"S6 c #7B7873", -"T6 c #87847F", -"U6 c #6A6A64", -"V6 c #576E63", -"W6 c #D9E1DD", -"X6 c #D5C2DF", -"Y6 c #E2CFEB", -"Z6 c #EAE4C2", -"`6 c #595656", -" 7 c #383735", -".7 c #2F2D2F", -"+7 c #201F20", -"@7 c #2A2929", -"#7 c #212020", -"$7 c #242323", -"%7 c #272525", -"&7 c #2D2C2B", -"*7 c #383835", -"=7 c #5D8575", -"-7 c #F1F3F3", -";7 c #E4D5ED", -">7 c #EBE8EB", -",7 c #D7D4A2", -"'7 c #7C7978", -")7 c #6C6B69", -"!7 c #6D6B69", -"~7 c #827E7C", -"{7 c #A3A09F", -"]7 c #08020D", -"^7 c #B3DDCD", -"/7 c #CFB9DB", -"(7 c #F7F4F1", -"_7 c #4B492C", -":7 c #020401", -"<7 c #09040C", -"[7 c #AADAC4", -"}7 c #F5F0F7", -"|7 c #D5C5DE", -"17 c #E7E4E8", -"27 c #CDCA94", -"37 c #0F0B12", -"47 c #06010B", -"57 c #08030D", -"67 c #C5E6D8", -"77 c #CFB9DA", -"87 c #F7F5F5", -"97 c #565433", -"07 c #040007", -"a7 c #476D60", -"b7 c #E5EFE9", -"c7 c #E3D2EC", -"d7 c #E2D7E7", -"e7 c #DDD9BA", -"f7 c #2F2C2B", -"g7 c #3D6155", -"h7 c #F3F3F4", -"i7 c #D1BBDC", -"j7 c #C8B0D4", -"k7 c #CFBCD8", -"l7 c #E6E1DA", -"m7 c #9A976C", -"n7 c #383945", -"o7 c #8A91C4", -"p7 c #9195E0", -"q7 c #8C8FE9", -"r7 c #9A93EB", -"s7 c #BCABEC", -"t7 c #DBB9EC", -"u7 c #E5BEEF", -"v7 c #EBBEEE", -"w7 c #E0BBDE", -"x7 c #DEAFDF", -"y7 c #E9C6ED", -"z7 c #F2DEF8", -"A7 c #E0D9E5", -"B7 c #C7B3C4", -"C7 c #8E839A", -"D7 c #7E7283", -"E7 c #88778C", -"F7 c #A695A4", -"G7 c #C8A9C2", -"H7 c #D4B3D9", -"I7 c #BEA5CA", -"J7 c #C0A9D1", -"K7 c #D6BADD", -"L7 c #C1E4DA", -"M7 c #75665B", -"N7 c #5B494E", -"O7 c #655157", -"P7 c #735C62", -"Q7 c #7A6268", -"R7 c #80656A", -"S7 c #886F7D", -"T7 c #8A7386", -"U7 c #92798C", -"V7 c #8E7D83", -"W7 c #E0EEE8", -"X7 c #DEC9E8", -"Y7 c #D1BFDC", -"Z7 c #E8E3DE", -"`7 c #B5A18D", -" 8 c #B58E97", -".8 c #CB9EA2", -"+8 c #D6A7AD", -"@8 c #CCA4A0", -"#8 c #D2A2A6", -"$8 c #DBA8AB", -"%8 c #CEA4AB", -"&8 c #CCA4AE", -"*8 c #D1A9A8", -"=8 c #D4A1A7", -"-8 c #CCA2A7", -";8 c #B89CA9", -">8 c #C7E8DC", -",8 c #D6BEE2", -"'8 c #CFBADA", -")8 c #EDE9E7", -"!8 c #787163", -"~8 c #514956", -"{8 c #6C6077", -"]8 c #4F4F72", -"^8 c #464A78", -"/8 c #525484", -"(8 c #4B4E7F", -"_8 c #5C5B83", -":8 c #A592B3", -"<8 c #AB98B8", -"[8 c #9384A4", -"}8 c #84798E", -"|8 c #D9F1E5", -"18 c #F0EDEC", -"28 c #78725C", -"38 c #4B4148", -"48 c #52464E", -"58 c #6A5A68", -"68 c #9C869B", -"78 c #A790AE", -"88 c #BDA4C1", -"98 c #D7BAD7", -"08 c #C7ABB7", -"a8 c #AC929A", -"b8 c #A3C7BB", -"c8 c #F4EFF6", -"d8 c #CEB9DA", -"e8 c #E0DAB0", -"f8 c #534545", -"g8 c #56474D", -"h8 c #635356", -"i8 c #77666B", -"j8 c #8E7C80", -"k8 c #A98C94", -"l8 c #B898A7", -"m8 c #B58F9B", -"n8 c #B291A6", -"o8 c #AD93A4", -"p8 c #A293A3", -"q8 c #FAFEFA", -"r8 c #FCF9F0", -"s8 c #8C8379", -"t8 c #4F4658", -"u8 c #4F465A", -"v8 c #5D566B", -"w8 c #71667E", -"x8 c #837692", -"y8 c #AB9BBE", -"z8 c #8E89AC", -"A8 c #7671A6", -"B8 c #C5EFDD", -"C8 c #F8F5F0", -"D8 c #E7E2E2", -"E8 c #DBC5E6", -"F8 c #D3BEDD", -"G8 c #E8E4E6", -"H8 c #A9A77F", -"I8 c #3A3C62", -"J8 c #646192", -"K8 c #837CB7", -"L8 c #8D87BA", -"M8 c #998FB8", -"N8 c #9C8CBE", -"O8 c #8B81AF", -"P8 c #9587B4", -"Q8 c #9286B0", -"R8 c #85769E", -"S8 c #E1F8EA", -"T8 c #FCFAFC", -"U8 c #AFA984", -"V8 c #413858", -"W8 c #393454", -"X8 c #3B375E", -"Y8 c #444064", -"Z8 c #5F5780", -"`8 c #796E98", -" 9 c #8677AA", -".9 c #8B7FB0", -"+9 c #282535", -"@9 c #395C50", -"#9 c #F4F5F5", -"$9 c #D4C1DF", -"%9 c #CCB6D7", -"&9 c #D5C4DD", -"*9 c #E4DFB5", -"=9 c #141413", -"-9 c #272724", -";9 c #6F6F6B", -">9 c #7DB29D", -",9 c #9D9B69", -"'9 c #2C2C2B", -")9 c #669683", -"!9 c #F4F1F6", -"~9 c #D2BEDC", -"{9 c #CDB9D7", -"]9 c #E0D6E4", -"^9 c #D2CE9C", -"/9 c #111110", -"(9 c #1F1F1D", -"_9 c #42423F", -":9 c #595856", -"<9 c #696964", -"[9 c #797876", -"}9 c #98D0B9", -"|9 c #FFFEF9", -"19 c #898665", -"29 c #3D3C3A", -"39 c #736F6A", -"49 c #7F7C77", -"59 c #77736E", -"69 c #827E78", -"79 c #696D67", -"89 c #D5E5DE", -"99 c #D6C5DF", -"09 c #E1CEEA", -"a9 c #F4EFD8", -"b9 c #63625D", -"c9 c #424140", -"d9 c #1B1A1A", -"e9 c #1E1D1D", -"f9 c #292728", -"g9 c #272627", -"h9 c #343432", -"i9 c #78AC97", -"j9 c #F5F2F5", -"k9 c #DBCCE3", -"l9 c #E9E6E8", -"m9 c #C1BE8D", -"n9 c #474644", -"o9 c #4C4A48", -"p9 c #7B7876", -"q9 c #908C8B", -"r9 c #AFDACB", -"s9 c #D2BFDC", -"t9 c #D3BFDC", -"u9 c #4B4A2C", -"v9 c #1F342D", -"w9 c #EBF4EE", -"x9 c #D3C0DC", -"y9 c #D1C0DA", -"z9 c #E9E5E6", -"A9 c #999667", -"B9 c #06030A", -"C9 c #C1E4D6", -"D9 c #F8F5F4", -"E9 c #504F30", -"F9 c #F7F5F0", -"G9 c #010200", -"H9 c #334C44", -"I9 c #E6F1EC", -"J9 c #E2D0EB", -"K9 c #D8C7E1", -"L9 c #E7E3BE", -"M9 c #141216", -"N9 c #CDECDE", -"O9 c #D1BBDD", -"P9 c #CCB7D7", -"Q9 c #D1C0D9", -"R9 c #E4E1E4", -"S9 c #E0DECA", -"T9 c #BEBBB0", -"U9 c #8D8AC4", -"V9 c #A697D7", -"W9 c #C9A6E6", -"X9 c #D7B2E2", -"Y9 c #E5BAEC", -"Z9 c #E5B7E5", -"`9 c #DAB3D3", -" 0 c #D8AFCF", -".0 c #EFCEFD", -"+0 c #F0E3FE", -"@0 c #FBE5FB", -"#0 c #EFCFEF", -"$0 c #CCB1D0", -"%0 c #A68FAD", -"&0 c #89748A", -"*0 c #887286", -"=0 c #AB8C9A", -"-0 c #CEA4B3", -";0 c #D1B1C8", -">0 c #D0AED3", -",0 c #D6BCE8", -"'0 c #CFB3D7", -")0 c #BFE3D8", -"!0 c #58523B", -"~0 c #322527", -"{0 c #3F3235", -"]0 c #5A474D", -"^0 c #785E66", -"/0 c #8B717C", -"(0 c #8C7484", -"_0 c #91747D", -":0 c #8F6D70", -"<0 c #7F6369", -"[0 c #90B5A4", -"}0 c #F5F1F6", -"|0 c #D4C3DD", -"10 c #F0EBCE", -"20 c #8E706E", -"30 c #AD8483", -"40 c #C19494", -"50 c #D1A0A0", -"60 c #D0A5AC", -"70 c #CEA7B0", -"80 c #BCA3B2", -"90 c #CBA9B8", -"00 c #D5A9B0", -"a0 c #D9AAB6", -"b0 c #C4A3AA", -"c0 c #BBA8B3", -"d0 c #EFF5F1", -"e0 c #D8C7DF", -"f0 c #EDE6F0", -"g0 c #D3C0DD", -"h0 c #DDD2E3", -"i0 c #D6D2A2", -"j0 c #332E36", -"k0 c #554A5D", -"l0 c #514E67", -"m0 c #7D7BA9", -"n0 c #65658E", -"o0 c #7E7DB5", -"p0 c #5C5C89", -"q0 c #4A4E7C", -"r0 c #52537C", -"s0 c #716C87", -"t0 c #8B7D99", -"u0 c #9FD1C1", -"v0 c #F5F1F7", -"w0 c #D5C3DE", -"x0 c #E2DBE6", -"y0 c #D2CE9A", -"z0 c #262027", -"A0 c #2F282D", -"B0 c #564958", -"C0 c #847580", -"D0 c #AC92AC", -"E0 c #C3ACBC", -"F0 c #E5C6E2", -"G0 c #DAB9D9", -"H0 c #B398A0", -"I0 c #9E898B", -"J0 c #EDF4F0", -"K0 c #D2BEDB", -"L0 c #F3EFDC", -"M0 c #3A3330", -"N0 c #32282B", -"O0 c #4B3C40", -"P0 c #69575D", -"Q0 c #8A7377", -"R0 c #A68790", -"S0 c #B2919A", -"T0 c #B58F98", -"U0 c #B696AA", -"V0 c #B49AAC", -"W0 c #A69EA4", -"X0 c #FCFEFB", -"Y0 c #EAE6B3", -"Z0 c #4D424A", -"`0 c #3B323B", -" a c #352D38", -".a c #4A414F", -"+a c #645A6D", -"@a c #897896", -"#a c #A191B0", -"$a c #716E94", -"%a c #464A73", -"&a c #C2EDDA", -"*a c #FCF9EF", -"=a c #C7B4CD", -"-a c #F2EFF4", -";a c #E1CDEA", -">a c #D5C4DE", -",a c #E8E4DA", -"'a c #63605A", -")a c #36375A", -"!a c #464875", -"~a c #505481", -"{a c #736EA0", -"]a c #847BAE", -"^a c #8981AA", -"/a c #8B80AF", -"(a c #8E84AB", -"_a c #81769A", -":a c #C2EEDB", -"b c #09070A", -",b c #C2E6D6", -"'b c #F8F6F4", -")b c #504F2F", -"!b c #100A15", -"~b c #021015", -"{b c #04141A", -"]b c #619280", -"^b c #F4F3F5", -"/b c #DDCFE4", -"(b c #E9E6EA", -"_b c #C5C28C", -":b c #121014", -"c c #A18CA1", -",c c #C9B2C6", -"'c c #D3B7CF", -")c c #C7ADB8", -"!c c #D0B2C4", -"~c c #CBB3C1", -"{c c #BCA9B8", -"]c c #E5F4EB", -"^c c #969265", -"/c c #241C1D", -"(c c #423337", -"_c c #6C575D", -":c c #8D7276", -"d c #F5F3F5", -",d c #E8E4BE", -"'d c #393837", -")d c #9F9F9D", -"!d c #07010E", -"~d c #B0DBCB", -"{d c #010301", -"]d c #B0DCCB", -"^d c #F6F3E0", -"/d c #1F1E13", -"(d c #0C050F", -"_d c #C2E5D6", -":d c #050208", -"e c #DBBCD9", -",e c #DAB6C8", -"'e c #D8B5C7", -")e c #D9BBCF", -"!e c #D3CFDB", -"~e c #FAFAFA", -"{e c #DACDE0", -"]e c #E5E1B6", -"^e c #1E181B", -"/e c #3D3135", -"(e c #6D5A61", -"_e c #947B88", -":e c #A88E9A", -"f c #3C3A3C", -",f c #3B383A", -"'f c #545653", -")f c #E1F3E9", -"!f c #D7CADD", -"~f c #EAE7E5", -"{f c #797754", -"]f c #222220", -"^f c #696864", -"/f c #8F8E8C", -"(f c #B1DCCB", -"_f c #B2DECD", -":f c #D9CDE0", -"g c #DDD8AB", -",g c #1E1B1F", -"'g c #413A45", -")g c #968498", -"!g c #DDBEDC", -"~g c #E5D2E1", -"{g c #CEACAD", -"]g c #D2B0B9", -"^g c #E0BEC6", -"/g c #C6EEDB", -"(g c #FEFDF4", -"_g c #F5F3EF", -":g c #F5F2E3", -"h c #DED4E2", -",h c #F9F7F3", -"'h c #6D6B51", -")h c #151414", -"!h c #3E3C3A", -"~h c #464344", -"{h c #3E3D3C", -"]h c #BDE6D4", -"^h c #ECE2F1", -"/h c #DFD7E3", -"(h c #DDD9AB", -"_h c #5B5857", -":h c #73716F", -"i c #C1B7D8", -",i c #7C799B", -"'i c #9490C2", -")i c #8282B8", -"!i c #51577D", -"~i c #464770", -"{i c #636A8C", -"]i c #EFF7F1", -"^i c #F4F1DB", -"/i c #2E2C28", -"(i c #322D32", -"_i c #665967", -":i c #A693AA", -"j c #605F5E", -",j c #5A5958", -"'j c #595654", -")j c #888582", -"!j c #72706B", -"~j c #7E7B76", -"{j c #817D78", -"]j c #A2C4B4", -"^j c #F8F6E5", -"/j c #414035", -"(j c #151413", -"_j c #1A1A1A", -":j c #403D3E", -"k c #F7F1C3", -",k c #9A7D83", -"'k c #7B6974", -")k c #62545F", -"!k c #AFDDCA", -"~k c #EFE9F3", -"{k c #E1D9E5", -"]k c #CAC68E", -"^k c #2F292D", -"/k c #4E454D", -"(k c #71676D", -"_k c #91879A", -":k c #E6D1F0", -"l c #5E8576", -",l c #F7F7F7", -"'l c #E3DCE5", -")l c #DDD6E0", -"!l c #DFDCAE", -"~l c #31302E", -"{l c #464644", -"]l c #676761", -"^l c #ACE0C9", -"/l c #6B694E", -"(l c #50504C", -"_l c #4D4B46", -":l c #585653", -"m c #F0B7B2", -",m c #D8F1E1", -"'m c #EAE4EC", -")m c #F2EBF4", -"!m c #FCFAF6", -"~m c #A29D6C", -"{m c #16100E", -"]m c #160F0F", -"^m c #382A27", -"/m c #73584F", -"(m c #9E7873", -"_m c #B98E86", -":m c #BF928E", -"n c #7D789F", -",n c #74729B", -"'n c #6A6A9C", -")n c #D0F0E0", -"!n c #DDD4E3", -"~n c #F6F4E6", -"{n c #3A3928", -"]n c #50504B", -"^n c #D1F4E1", -"/n c #FCFADE", -"(n c #525248", -"_n c #3F3F3B", -":n c #424541", -"o c #A49095", -",o c #AD90A9", -"'o c #C4E5D5", -")o c #F2F0EB", -"!o c #756E6C", -"~o c #6C696B", -"{o c #766C6E", -"]o c #8F7A7C", -"^o c #B49196", -"/o c #D8AEA4", -"(o c #EABBAF", -"_o c #F6C0B5", -":o c #EBC7B2", -"p c #343C66", -",p c #3D4777", -"'p c #434D84", -")p c #B8E9D7", -"!p c #57596B", -"~p c #2D3154", -"{p c #2E3153", -"]p c #40416B", -"^p c #565685", -"/p c #6E6C91", -"(p c #787299", -"_p c #7D779C", -":p c #7F79A2", -"

Q c #494D81", -",Q c #5C5F8C", -"'Q c #65668B", -")Q c #7774A9", -"!Q c #78A493", -"~Q c #F8F5F9", -"{Q c #F9F5FA", -"]Q c #CAC68C", -"^Q c #040403", -"/Q c #5F5F5A", -"(Q c #65655F", -"_Q c #70706C", -":Q c #9CCDB8", -"R c #7EAD98", -",R c #ECF1E8", -"'R c #C7A2DA", -")R c #C198D7", -"!R c #D9C4DE", -"~R c #E1D7D5", -"{R c #B087C0", -"]R c #B693C2", -"^R c #E4DBD9", -"/R c #F5F1F3", -"(R c #CEB0DF", -"_R c #F8F4F2", -":R c #DFD8B5", -"S c #D3CD9F", -",S c #31324E", -"'S c #43446D", -")S c #525481", -"!S c #5C5C87", -"~S c #535684", -"{S c #555A87", -"]S c #686799", -"^S c #656591", -"/S c #4D4E7C", -"(S c #40456E", -"_S c #343B5E", -":S c #CCF0DD", -"T c #6F70A7", -",T c #7B76C6", -"'T c #8A82BD", -")T c #9386B5", -"!T c #8E7CA3", -"~T c #796688", -"{T c #68526E", -"]T c #59445D", -"^T c #554056", -"/T c #62505D", -"(T c #80657A", -"_T c #987C97", -":T c #B392B1", -"U c #83829F", -",U c #9C95B3", -"'U c #9B8D9D", -")U c #B8A1B6", -"!U c #C9ADC7", -"~U c #B6A4B9", -"{U c #AB97AD", -"]U c #C8E5D2", -"^U c #C8C592", -"/U c #2C282E", -"(U c #1A161E", -"_U c #1D1A20", -":U c #363038", -"V c #C8C5C0", -",V c #C0BDB7", -"'V c #B7B4AE", -")V c #B1AEA9", -"!V c #A8A4A2", -"~V c #A09C97", -"{V c #989492", -"]V c #9E9A98", -"^V c #ABA9A6", -"/V c #969592", -"(V c #8B8B88", -"_V c #312D2F", -":V c #4B3F4F", -"W c #626477", -",W c #6A677D", -"'W c #6E6A7F", -")W c #6B6A79", -"!W c #6D6C7E", -"~W c #616373", -"{W c #595D6C", -"]W c #605F72", -"^W c #6A6881", -"/W c #807994", -"(W c #6B6573", -"_W c #44424D", -":W c #2E2A33", -"X c #1F2036", -",X c #333454", -"'X c #565581", -")X c #636399", -"!X c #505781", -"~X c #6B6898", -"{X c #646593", -"]X c #4E4E4B", -"^X c #393936", -"/X c #333331", -"(X c #3C3A39", -"_X c #5F5F59", -":X c #5D5955", -"Y c #706C81", -",Y c #626272", -"'Y c #5A5A6B", -")Y c #4E4C59", -"!Y c #3D3E4B", -"~Y c #36353F", -"{Y c #27272F", -"]Y c #1F1F27", -"^Y c #1B1B22", -"/Y c #1F2027", -"(Y c #282831", -"_Y c #333540", -":Y c #40414E", -"Z c #47496F", -",Z c #5B5A84", -"'Z c #595986", -")Z c #4A4E7A", -"!Z c #585B84", -"~Z c #706D9C", -"{Z c #5B5E8F", -"]Z c #51547B", -"^Z c #676492", -"/Z c #5A5883", -"(Z c #3C3C5B", -"_Z c #232643", -":Z c #2A2B4E", -"` c #584C5F", -",` c #514854", -"'` c #504753", -")` c #4C4553", -"!` c #45414D", -"~` c #4B4550", -"{` c #4E4955", -"]` c #534B5A", -"^` c #5C5367", -"/` c #5C596A", -"(` c #625E73", -"_` c #716C80", -":` c #6A687E", -"<` c #6C6A88", -"[` c #706D83", -"}` c #6D6B83", -"|` c #63627B", -"1` c #5B5B71", -"2` c #505062", -"3` c #454656", -"4` c #3D3F4A", -"5` c #323640", -"6` c #323342", -"7` c #2F323D", -"8` c #333442", -"9` c #3B3D4A", -"0` c #414250", -"a` c #474856", -"b` c #515162", -"c` c #5F5E6D", -"d` c #616370", -"e` c #616472", -"f` c #646479", -"g` c #67677D", -"h` c #66667E", -"i` c #626478", -"j` c #64647C", -"k` c #616278", -"l` c #5B5F70", -"m` c #5E616F", -"n` c #5E5F73", -"o` c #515464", -"p` c #484B5B", -"q` c #464656", -"r` c #3F4052", -"s` c #534E66", -"t` c #736B8A", -"u` c #746C87", -"v` c #71698A", -"w` c #726F8D", -"x` c #757488", -"y` c #707388", -"z` c #9E9ABD", -"A` c #ACA9C8", -"B` c #9893B6", -"C` c #8A89A8", -"D` c #9B9AB4", -"E` c #807F94", -"F` c #777285", -"G` c #6A657D", -"H` c #5F5D6E", -"I` c #535060", -"J` c #4E4C5D", -"K` c #494A56", -"L` c #766F86", -"M` c #7A748B", -"N` c #9791A0", -"O` c #A49DB6", -"P` c #9A91AF", -"Q` c #9B92A9", -"R` c #888288", -"S` c #A998AC", -"T` c #BAA3C4", -"U` c #A693A5", -"V` c #AE979E", -"W` c #9E8B9A", -"X` c #948195", -"Y` c #817188", -"Z` c #827388", -"`` c #756E79", -" . c #96819E", -". . c #B49BB8", -"+ . c #C0A2C6", -"@ . c #C2ABCD", -"# . c #C1ACCC", -"$ . c #B4A2B8", -"% . c #918998", -"& . c #46486A", -"* . c #3B3D62", -"= . c #272D4C", -"- . c #212542", -"; . c #202240", -"> . c #242944", -", . c #3A3A61", -"' . c #3C4163", -") . c #444871", -"! . c #5C5E87", -"~ . c #60618B", -"{ . c #5A5A86", -"] . c #5B5E85", -"^ . c #55597D", -"/ . c #54557B", -"( . c #5E5B7D", -"_ . c #565472", -": . c #504E72", -"< . c #373754", -"[ . c #2C2D47", -"} . c #2D2F47", -"| . c #4C4B6C", -"1 . c #47486E", -"2 . c #54547B", -"3 . c #686694", -"4 . c #616288", -"5 . c #4F527D", -"6 . c #494974", -"7 . c #505280", -"8 . c #4F527B", -"9 . c #605F8A", -"0 . c #53577F", -"a . c #5F5F91", -"b . c #51517F", -"c . c #41456D", -"d . c #36385E", -"e . c #303359", -"f . c #474774", -"g . c #464972", -"h . c #51557E", -"i . c #686697", -"j . c #585C8B", -"k . c #565886", -"l . c #5D5D8E", -"m . c #F4F4F4", -"n . c #FCFCFC", -"o . c #232220", -"p . c #4D4D48", -"q . c #989893", -"r . c #8E8B85", -"s . c #97938E", -"t . c #96928D", -"u . c #A8A8A2", -"v . c #8D8B86", -"w . c #C4C3C1", -"x . c #C0BCBA", -"y . c #BCBAB9", -"z . c #CECBC6", -"A . c #C1BDB8", -"B . c #9D9897", -"C . c #A09C9B", -"D . c #817D7C", -"E . c #6F6A67", -"F . c #777674", -"G . c #767672", -"H . c #676463", -"I . c #71716C", -"J . c #6C6C68", -"K . c #403E3D", -"L . c #050B02", -"M . c #040802", -"N . c #000A14", -"O . c #1F2B31", -"P . c #070716", -"Q . c #8191D1", -"R . c #8182CF", -"S . c #AC9ED3", -"T . c #B49FCF", -"U . c #B69DC4", -"V . c #B996B7", -"W . c #BB95B5", -"X . c #C8A1BF", -"Y . c #D0AAC5", -"Z . c #D4B0C4", -"` . c #D3B0CA", -" .. c #D1ABBF", -"... c #D6AEC8", -"+.. c #D2B1CB", -"@.. c #C5A7CC", -"#.. c #BEA0BB", -"$.. c #CAA7C0", -"%.. c #C5A6BC", -"&.. c #C4A4C0", -"*.. c #C2A7C2", -"=.. c #BC9DB9", -"-.. c #A28AA4", -";.. c #A088A5", -">.. c #907E9A", -",.. c #96839F", -"'.. c #9E89A5", -").. c #A08CA3", -"!.. c #96889E", -"~.. c #887E91", -"{.. c #7F728C", -"].. c #76677D", -"^.. c #6B6170", -"/.. c #625869", -"(.. c #5D5466", -"_.. c #5F546C", -":.. c #5A5263", -"<.. c #59525E", -"[.. c #665B71", -"}.. c #655E6E", -"|.. c #6C6578", -"1.. c #6A667C", -"2.. c #6E6A7D", -"3.. c #63647C", -"4.. c #696981", -"5.. c #646584", -"6.. c #67677E", -"7.. c #646581", -"8.. c #5C5E7B", -"9.. c #5D5D75", -"0.. c #56576B", -"a.. c #4E5261", -"b.. c #474C55", -"c.. c #454959", -"d.. c #484960", -"e.. c #47495C", -"f.. c #474A5B", -"g.. c #4E5060", -"h.. c #525266", -"i.. c #535767", -"j.. c #5C5E6C", -"k.. c #606372", -"l.. c #606371", -"m.. c #5F6076", -"n.. c #5C6173", -"o.. c #64647E", -"p.. c #626277", -"q.. c #646478", -"r.. c #5E6074", -"s.. c #5E6072", -"t.. c #5C5C74", -"u.. c #59596D", -"v.. c #57576D", -"w.. c #5D5B70", -"x.. c #686476", -"y.. c #857D9C", -"z.. c #877E9F", -"A.. c #7C758F", -"B.. c #6F6E84", -"C.. c #737085", -"D.. c #8886A2", -"E.. c #B0A8D1", -"F.. c #AEA6CC", -"G.. c #9C94AE", -"H.. c #9892A6", -"I.. c #C3BDCE", -"J.. c #898793", -"K.. c #928A9F", -"L.. c #958DAF", -"M.. c #9893AF", -"N.. c #938F9E", -"O.. c #868198", -"P.. c #8F8AA5", -"Q.. c #9E95B0", -"R.. c #9E9AB5", -"S.. c #B9ADCA", -"T.. c #C1B8D3", -"U.. c #9E9EB8", -"V.. c #91889B", -"W.. c #9A8A99", -"X.. c #BBA2C3", -"Y.. c #B2A3C0", -"Z.. c #AF98B0", -"`.. c #AD9BB6", -" +. c #9386A5", -".+. c #9587A4", -"++. c #9A87A1", -"@+. c #A191A8", -"#+. c #AA9FBD", -"$+. c #A594B2", -"%+. c #AC9BB9", -"&+. c #B19DBD", -"*+. c #AF9FB8", -"=+. c #C1A9CC", -"-+. c #9B8B9A", -";+. c #43435C", -">+. c #4A4A76", -",+. c #4C4D73", -"'+. c #43466B", -")+. c #3B3F5E", -"!+. c #383A5B", -"~+. c #47496D", -"{+. c #454970", -"]+. c #46476B", -"^+. c #44496A", -"/+. c #45486F", -"(+. c #46496F", -"_+. c #494B71", -":+. c #3E446F", -"<+. c #41446B", -"[+. c #4F527E", -"}+. c #4B4E76", -"|+. c #4C4F7A", -"1+. c #515478", -"2+. c #6E6899", -"3+. c #5D5A7B", -"4+. c #444763", -"5+. c #434567", -"6+. c #484873", -"7+. c #4D4D71", -"8+. c #44466C", -"9+. c #4E517C", -"0+. c #55577D", -"a+. c #4D5079", -"b+. c #626192", -"c+. c #4B5179", -"d+. c #565885", -"e+. c #525680", -"f+. c #585A88", -"g+. c #6D6C9E", -"h+. c #515277", -"i+. c #3F416A", -"j+. c #373864", -"k+. c #4B4A78", -"l+. c #5E5D89", -"m+. c #6C6998", -"n+. c #65658F", -"o+. c #5A5B8B", -"p+. c #575889", -"q+. c #555984", -"r+. c #EEEEEE", -"s+. c #5C5C57", -"t+. c #7B7B76", -"u+. c #686864", -"v+. c #87847E", -"w+. c #90908A", -"x+. c #7E7A74", -"y+. c #93938D", -"z+. c #A9A9A4", -"A+. c #A9A8A5", -"B+. c #979792", -"C+. c #B8B5B3", -"D+. c #A9A9A3", -"E+. c #A8A8A4", -"F+. c #BDBCB9", -"G+. c #CDCCCA", -"H+. c #C5C5C0", -"I+. c #C3C3BE", -"J+. c #C1C1BC", -"K+. c #B4B2AB", -"L+. c #A7A49E", -"M+. c #CCCAC3", -"N+. c #A09C9A", -"O+. c #ABA8A3", -"P+. c #B7B2B1", -"Q+. c #B9B6B4", -"R+. c #8D8988", -"S+. c #8A8785", -"T+. c #7E7D79", -"U+. c #878683", -"V+. c #8E8D8A", -"W+. c #858382", -"X+. c #848481", -"Y+. c #8A8987", -"Z+. c #73736F", -"`+. c #7A7A75", -" @. c #686664", -".@. c #5E5E5D", -"+@. c #191919", -"@@. c #060D03", -"#@. c #03141B", -"$@. c #241613", -"%@. c #4C261C", -"&@. c #91A2E5", -"*@. c #838CE5", -"=@. c #C0AFEF", -"-@. c #C5B0E2", -";@. c #D4ADE3", -">@. c #D8ADD7", -",@. c #D2A9C9", -"'@. c #D7B1CE", -")@. c #E0B6CA", -"!@. c #E2BAD1", -"~@. c #DAB4CB", -"{@. c #D9B1D1", -"]@. c #D3B0CE", -"^@. c #CDABCA", -"/@. c #CEA9CA", -"(@. c #C7A4C6", -"_@. c #C2A0C1", -":@. c #CBA4CB", -"<@. c #C1A0C2", -"[@. c #C09EC2", -"}@. c #C2A2C5", -"|@. c #C0A3C6", -"1@. c #BA9DC5", -"2@. c #A993B3", -"3@. c #9D8DAD", -"4@. c #9C8AAB", -"5@. c #9B8BA7", -"6@. c #A58DAE", -"7@. c #A890AE", -"8@. c #A28CB1", -"9@. c #93849F", -"0@. c #867B8F", -"a@. c #827487", -"b@. c #7F718D", -"c@. c #7A6B7E", -"d@. c #6D6479", -"e@. c #6D6577", -"f@. c #6F6678", -"g@. c #71697D", -"h@. c #706B7D", -"i@. c #686577", -"j@. c #716C84", -"k@. c #736F82", -"l@. c #67677C", -"m@. c #6B6A83", -"n@. c #64647D", -"o@. c #616483", -"p@. c #6A6889", -"q@. c #64667C", -"r@. c #606378", -"s@. c #5F5F7A", -"t@. c #5E5F74", -"u@. c #5A5B6D", -"v@. c #565977", -"w@. c #4E536B", -"x@. c #4E5367", -"y@. c #54566C", -"z@. c #56576C", -"A@. c #595C75", -"B@. c #5B5D6E", -"C@. c #606077", -"D@. c #5E5F71", -"E@. c #5D5F72", -"F@. c #5F6175", -"G@. c #5C6071", -"H@. c #5A5F6C", -"I@. c #5E6174", -"J@. c #616179", -"K@. c #626279", -"L@. c #5F6071", -"M@. c #5E6173", -"N@. c #5F6078", -"O@. c #5A5E71", -"P@. c #585C6D", -"Q@. c #5C5D6E", -"R@. c #616176", -"S@. c #7B758C", -"T@. c #887FA2", -"U@. c #8E85AD", -"V@. c #827A96", -"W@. c #A9A5C4", -"X@. c #A9A0C7", -"Y@. c #A79FC7", -"Z@. c #A499B4", -"`@. c #A79ABB", -" #. c #8B868E", -".#. c #B0A8C1", -"+#. c #ADA7C5", -"@#. c #B4AACE", -"##. c #9A94AC", -"$#. c #AAA6B9", -"%#. c #C5BBD3", -"&#. c #BAB1CE", -"*#. c #A19BB9", -"=#. c #8C86A7", -"-#. c #BBB5CB", -";#. c #9494AB", -">#. c #ACA5CA", -",#. c #ACA4BA", -"'#. c #AB9DB2", -")#. c #B29CB8", -"!#. c #A997AC", -"~#. c #B09EBD", -"{#. c #B3A2C2", -"]#. c #ADA1BD", -"^#. c #A899BF", -"/#. c #AB9BBF", -"(#. c #A191B1", -"_#. c #A194B5", -":#. c #B0A3C2", -"<#. c #B8ABD0", -"[#. c #A397B6", -"}#. c #A295AE", -"|#. c #D1BFDA", -"1#. c #AB96AB", -"2#. c #484C6B", -"3#. c #494E6B", -"4#. c #4C4A71", -"5#. c #606389", -"6#. c #4F5378", -"7#. c #4B4F6F", -"8#. c #4A4F70", -"9#. c #4A4E71", -"0#. c #51537C", -"a#. c #4D5176", -"b#. c #494D75", -"c#. c #4B4C75", -"d#. c #474B73", -"e#. c #373E5E", -"f#. c #30345E", -"g#. c #2E375E", -"h#. c #343A5D", -"i#. c #40426D", -"j#. c #404169", -"k#. c #53577D", -"l#. c #58597F", -"m#. c #484C6E", -"n#. c #3F4467", -"o#. c #45486D", -"p#. c #505278", -"q#. c #515479", -"r#. c #42466D", -"s#. c #4F517E", -"t#. c #4E5276", -"u#. c #7777AB", -"v#. c #53567A", -"w#. c #656489", -"x#. c #757298", -"y#. c #9593C0", -"z#. c #58587B", -"A#. c #4E4F74", -"B#. c #7570A9", -"C#. c #7873AA", -"D#. c #525377", -"E#. c #383B63", -"F#. c #373B67", -"G#. c #43456E", -"H#. c #515680", -"I#. c #5D5D8C", -"J#. c #5C5C86", -"K#. c #565780", -"L#. c #4B5072", -"M#. c #535683", -"N#. c #E9E9E9", -"O#. c #F2F2F2", -"P#. c #71716D", -"Q#. c #726E68", -"R#. c #89857F", -"S#. c #93938E", -"T#. c #B1B0AE", -"U#. c #B6B5B2", -"V#. c #9E9D9B", -"W#. c #C5C5BF", -"X#. c #C0BEBB", -"Y#. c #A3A39E", -"Z#. c #BBBAB8", -"`#. c #CBCAC7", -" $. c #C7C7C2", -".$. c #B6B6B0", -"+$. c #9E9999", -"@$. c #98928E", -"#$. c #95928D", -"$$. c #A29E9D", -"%$. c #8F8A89", -"&$. c #92918F", -"*$. c #878583", -"=$. c #969593", -"-$. c #9D9C9A", -";$. c #898886", -">$. c #7F7E7B", -",$. c #80807B", -"'$. c #656563", -")$. c #20201F", -"!$. c #281915", -"~$. c #83574B", -"{$. c #1C0A06", -"]$. c #58669C", -"^$. c #8893EE", -"/$. c #B2AAF1", -"($. c #D5B4F2", -"_$. c #E0B7EA", -":$. c #E2B6E3", -"<$. c #E1AFDE", -"[$. c #E0B2D0", -"}$. c #E4BAD7", -"|$. c #EAC0D3", -"1$. c #E3C0DC", -"2$. c #D7B5CD", -"3$. c #D2B0CF", -"4$. c #C7A6C4", -"5$. c #CBA7CA", -"6$. c #CCA7CC", -"7$. c #C4A2C8", -"8$. c #BE9FC0", -"9$. c #BB99BB", -"0$. c #C09EC1", -"a$. c #BCA0C5", -"b$. c #B69EC3", -"c$. c #AB96B6", -"d$. c #A490B7", -"e$. c #A593B6", -"f$. c #9E8EAE", -"g$. c #9E8BAD", -"h$. c #9788A3", -"i$. c #888199", -"j$. c #897E9E", -"k$. c #887F96", -"l$. c #81798B", -"m$. c #8A7D93", -"n$. c #877A90", -"o$. c #80778A", -"p$. c #797288", -"q$. c #737082", -"r$. c #716E83", -"s$. c #716E87", -"t$. c #68687C", -"u$. c #6F6C82", -"v$. c #6C6B83", -"w$. c #656679", -"x$. c #606579", -"y$. c #5F6279", -"z$. c #666680", -"A$. c #656683", -"B$. c #5E607A", -"C$. c #5E5E76", -"D$. c #65657E", -"E$. c #6C6C83", -"F$. c #63647D", -"G$. c #5D5D7E", -"H$. c #535871", -"I$. c #585972", -"J$. c #595E70", -"K$. c #5B6073", -"L$. c #79768F", -"M$. c #646678", -"N$. c #65657D", -"O$. c #716F8C", -"P$. c #6E6E84", -"Q$. c #595C6D", -"R$. c #565970", -"S$. c #5B5F72", -"T$. c #5B5C74", -"U$. c #5F6177", -"V$. c #5F5F77", -"W$. c #5E6076", -"X$. c #5A5F73", -"Y$. c #595F6D", -"Z$. c #666678", -"`$. c #75728B", -" %. c #6D6D84", -".%. c #78768B", -"+%. c #858294", -"@%. c #918FA2", -"#%. c #A89EBD", -"$%. c #AFA7C6", -"%%. c #B9A8CA", -"&%. c #AB9AB6", -"*%. c #928698", -"=%. c #7E7A8A", -"-%. c #A69FBB", -";%. c #A293B0", -">%. c #A297B6", -",%. c #93889A", -"'%. c #837C88", -")%. c #A8A4B9", -"!%. c #C2BAD9", -"~%. c #CCC3E1", -"{%. c #B1AACE", -"]%. c #8C88A0", -"^%. c #B8B2CD", -"/%. c #ADA2BF", -"(%. c #B6A7C9", -"_%. c #B5A7C6", -":%. c #AFA0B9", -"<%. c #B9A1C1", -"[%. c #AD9FBB", -"}%. c #C0B8D0", -"|%. c #9B98B0", -"1%. c #9089AD", -"2%. c #8F88AD", -"3%. c #988FAF", -"4%. c #948DA4", -"5%. c #807C8D", -"6%. c #ACA3C3", -"7%. c #BCB1CF", -"8%. c #978E9C", -"9%. c #4D4D61", -"0%. c #5C5E7E", -"a%. c #66668D", -"b%. c #63648D", -"c%. c #5D5D85", -"d%. c #5D5E85", -"e%. c #51577F", -"f%. c #5D6087", -"g%. c #676797", -"h%. c #55597C", -"i%. c #4F5374", -"j%. c #3B3F62", -"k%. c #3A3B65", -"l%. c #373B60", -"m%. c #30355B", -"n%. c #353760", -"o%. c #3A3E62", -"p%. c #3E4065", -"q%. c #3E3F63", -"r%. c #3E3F67", -"s%. c #363963", -"t%. c #424469", -"u%. c #3A3D68", -"v%. c #3F4468", -"w%. c #3F4268", -"x%. c #51527D", -"y%. c #494C75", -"z%. c #57587E", -"A%. c #6D6C9B", -"B%. c #626285", -"C%. c #464B6C", -"D%. c #7A79A0", -"E%. c #6D6C86", -"F%. c #6D6993", -"G%. c #787CA5", -"H%. c #666688", -"I%. c #6E6C9D", -"J%. c #54557A", -"K%. c #3E4266", -"L%. c #3C3E64", -"M%. c #41436F", -"N%. c #474B6F", -"O%. c #4C4F7D", -"P%. c #575785", -"Q%. c #585986", -"R%. c #4A507A", -"S%. c #4A4F77", -"T%. c #E3E3E3", -"U%. c #ECECEC", -"V%. c #232323", -"W%. c #60605A", -"X%. c #787672", -"Y%. c #807D78", -"Z%. c #7E7A76", -"`%. c #908D86", -" &. c #9B9A99", -".&. c #BBBBB7", -"+&. c #ABABA6", -"@&. c #A6A29E", -"#&. c #BCBAB7", -"$&. c #BCBBB9", -"%&. c #B8B8B3", -"&&. c #BBBBB6", -"*&. c #C3C3BD", -"=&. c #ACACA8", -"-&. c #A1A09E", -";&. c #92918E", -">&. c #8B8A87", -",&. c #908F8C", -"'&. c #B8B7B5", -")&. c #A6A5A2", -"!&. c #898885", -"~&. c #757371", -"{&. c #3F3F3F", -"]&. c #383F64", -"^&. c #8798F6", -"/&. c #A6A1F8", -"(&. c #C8B6F5", -"_&. c #D5B9E9", -":&. c #E3B8EB", -"<&. c #E3B8E5", -"[&. c #E7B9E1", -"}&. c #F1C3DF", -"|&. c #EBC6DA", -"1&. c #E5C1D5", -"2&. c #D8B8DF", -"3&. c #C7AFD4", -"4&. c #CBAAD0", -"5&. c #CBA9CC", -"6&. c #C4A6CA", -"7&. c #C2A2C6", -"8&. c #C19FC6", -"9&. c #B79BBD", -"0&. c #B698BB", -"a&. c #BA9BC2", -"b&. c #BA9CC1", -"c&. c #B198C2", -"d&. c #A692B6", -"e&. c #9E8CB4", -"f&. c #9A8BB2", -"g&. c #9383A9", -"h&. c #9184A6", -"i&. c #9B8BAC", -"j&. c #9283A2", -"k&. c #867E94", -"l&. c #897D9F", -"m&. c #8C809E", -"n&. c #867D93", -"o&. c #867C93", -"p&. c #857D92", -"q&. c #867D92", -"r&. c #827B8F", -"s&. c #75718E", -"t&. c #767286", -"u&. c #757289", -"v&. c #6B6B85", -"w&. c #696983", -"x&. c #69697F", -"y&. c #67687D", -"z&. c #6A6A83", -"A&. c #807A9C", -"B&. c #847DA4", -"C&. c #616479", -"D&. c #5F627C", -"E&. c #706E8E", -"F&. c #6C6C89", -"G&. c #807DA0", -"H&. c #928DBA", -"I&. c #8C84A4", -"J&. c #797991", -"K&. c #60627E", -"L&. c #555B6C", -"M&. c #686883", -"N&. c #787495", -"O&. c #797695", -"P&. c #827D9E", -"Q&. c #7E7C95", -"R&. c #8A84A6", -"S&. c #7F7F9B", -"T&. c #565A71", -"U&. c #585A71", -"V&. c #565B6D", -"W&. c #595E6E", -"X&. c #5E6073", -"Y&. c #606274", -"Z&. c #5F6273", -"`&. c #5C6172", -" *. c #BCB6C4", -".*. c #898A91", -"+*. c #747282", -"@*. c #6C6D7E", -"#*. c #A19AB7", -"$*. c #D0C6E3", -"%*. c #CEC3E3", -"&*. c #C0B8C8", -"**. c #B4ACCF", -"=*. c #BAB3CB", -"-*. c #ABA2BD", -";*. c #A797AC", -">*. c #928994", -",*. c #C6BFD7", -"'*. c #918B98", -")*. c #A897AF", -"!*. c #978A9E", -"~*. c #868290", -"{*. c #9992B2", -"]*. c #9890B3", -"^*. c #AFA9D6", -"/*. c #A8A0C4", -"(*. c #998FAF", -"_*. c #A69FC7", -":*. c #D0C8DC", -"<*. c #ABA5B9", -"[*. c #9890AF", -"}*. c #B4A9D4", -"|*. c #AA9BBC", -"1*. c #B7A8CC", -"2*. c #B7B1D0", -"3*. c #B4ACC6", -"4*. c #8F89A2", -"5*. c #807D9B", -"6*. c #8E89A7", -"7*. c #9D92B2", -"8*. c #9F99BA", -"9*. c #A7A3BB", -"0*. c #B2A7C7", -"a*. c #8A8292", -"b*. c #3F4254", -"c*. c #464A6D", -"d*. c #505174", -"e*. c #4F5173", -"f*. c #535577", -"g*. c #64618B", -"h*. c #5F6187", -"i*. c #5A5B87", -"j*. c #63638C", -"k*. c #5C5E84", -"l*. c #61618A", -"m*. c #525579", -"n*. c #4D4F74", -"o*. c #45476E", -"p*. c #3A3B60", -"q*. c #3F3E62", -"r*. c #393A5D", -"s*. c #353962", -"t*. c #3C3E65", -"u*. c #3F4164", -"v*. c #3A3E63", -"w*. c #393C65", -"x*. c #373A63", -"y*. c #2B3052", -"z*. c #35385C", -"A*. c #41436A", -"B*. c #5D5C8C", -"C*. c #5B5B85", -"D*. c #64618C", -"E*. c #57577F", -"F*. c #55557C", -"G*. c #626289", -"H*. c #636387", -"I*. c #656488", -"J*. c #464A6A", -"K*. c #5C5E81", -"L*. c #5D5E87", -"M*. c #44476F", -"N*. c #494970", -"O*. c #57587B", -"P*. c #8A889D", -"Q*. c #8D8DAD", -"R*. c #69658B", -"S*. c #3C3F62", -"T*. c #303558", -"U*. c #3B3F6B", -"V*. c #4E527D", -"W*. c #44476E", -"X*. c #4C5077", -"Y*. c #484C72", -"Z*. c #DBDBDB", -"`*. c #E7E7E7", -" =. c #3D3D3A", -".=. c #6E6E68", -"+=. c #7A7871", -"@=. c #7A7772", -"#=. c #AAA9A7", -"$=. c #A6A4A2", -"%=. c #BCBCB8", -"&=. c #B6B4B2", -"*=. c #C4C4C0", -"==. c #D0CDC8", -"-=. c #9E9A95", -";=. c #B3AFAF", -">=. c #BAB6B4", -",=. c #A9A4A4", -"'=. c #928E8D", -")=. c #BEBDBB", -"!=. c #C3C2C0", -"~=. c #9C9B99", -"{=. c #8E8D8B", -"]=. c #0C1021", -"^=. c #93A6F5", -"/=. c #9093F5", -"(=. c #C2B4F5", -"_=. c #CEB7EC", -":=. c #DFB9ED", -"<=. c #E2BBDF", -"[=. c #E0BBD7", -"}=. c #F0C6E2", -"|=. c #EEC3DB", -"1=. c #DFBCD4", -"2=. c #D1B3D9", -"3=. c #C0B0D5", -"4=. c #C5ABD1", -"5=. c #CBABD3", -"6=. c #C4A7D5", -"7=. c #C1A7CE", -"8=. c #BB9FCC", -"9=. c #B79CC5", -"0=. c #B399C1", -"a=. c #AF93BA", -"b=. c #A991BD", -"c=. c #A791BB", -"d=. c #A08DB0", -"e=. c #9786AF", -"f=. c #9285AF", -"g=. c #8A7F9F", -"h=. c #897FA4", -"i=. c #897E9B", -"j=. c #867D95", -"k=. c #867E90", -"l=. c #897E93", -"m=. c #90809E", -"n=. c #7E788C", -"o=. c #7F798E", -"p=. c #8C7D9C", -"q=. c #867D90", -"r=. c #827991", -"s=. c #74728E", -"t=. c #6D6C80", -"u=. c #676684", -"v=. c #626577", -"w=. c #67677F", -"x=. c #6E6D86", -"y=. c #67687E", -"z=. c #76738D", -"A=. c #6A6886", -"B=. c #5E5F78", -"C=. c #7C789C", -"D=. c #767494", -"E=. c #847FA6", -"F=. c #958EC2", -"G=. c #A79BC4", -"H=. c #AEA4CC", -"I=. c #A19AC2", -"J=. c #8B86AB", -"K=. c #73728E", -"L=. c #7E7A94", -"M=. c #797892", -"N=. c #928AB3", -"O=. c #857FA8", -"P=. c #A098C2", -"Q=. c #9A94B8", -"R=. c #B7B1D1", -"S=. c #8D8AA9", -"T=. c #82809C", -"U=. c #6E7087", -"V=. c #72718E", -"W=. c #6B6B83", -"X=. c #5B5F7C", -"Y=. c #5E6176", -"Z=. c #606474", -"`=. c #5B6172", -" -. c #767692", -".-. c #A09DBF", -"+-. c #D0C7EA", -"@-. c #9F98AC", -"#-. c #9795B8", -"$-. c #8A86A7", -"%-. c #A4A2BB", -"&-. c #DACDDE", -"*-. c #D2CBDA", -"=-. c #CEC1D7", -"--. c #B7AFCE", -";-. c #B7AFD0", -">-. c #A297AC", -",-. c #AB9BA3", -"'-. c #C3ABC3", -")-. c #958D9C", -"!-. c #B8ADC5", -"~-. c #9D8FAB", -"{-. c #B39EBA", -"]-. c #898187", -"^-. c #85808E", -"/-. c #89829B", -"(-. c #A19ABD", -"_-. c #A5A0BB", -":-. c #A29BB5", -"<-. c #BEB5D9", -"[-. c #C3B9CB", -"}-. c #A9A2BC", -"|-. c #B1A6CB", -"1-. c #A79FC0", -"2-. c #9E97B1", -"3-. c #908CAA", -"4-. c #73717E", -"5-. c #727184", -"6-. c #8883A7", -"7-. c #9D94B3", -"8-. c #928BAB", -"9-. c #AAA1C5", -"0-. c #B0A7B9", -"a-. c #706E7D", -"b-. c #4B4D68", -"c-. c #585779", -"d-. c #4E5171", -"e-. c #54547E", -"f-. c #4A4E70", -"g-. c #424665", -"h-. c #4D4D6F", -"i-. c #4A4C6E", -"j-. c #5F5E84", -"k-. c #5C5C84", -"l-. c #57587C", -"m-. c #52527B", -"n-. c #474D6F", -"o-. c #3C3E61", -"p-. c #3B3B63", -"q-. c #414163", -"r-. c #4A4C70", -"s-. c #42446A", -"t-. c #424566", -"u-. c #3D4061", -"v-. c #3C3D5E", -"w-. c #3C3E5B", -"x-. c #444465", -"y-. c #3A3B5F", -"z-. c #313356", -"A-. c #2E3156", -"B-. c #373863", -"C-. c #404468", -"D-. c #56567D", -"E-. c #67638C", -"F-. c #656285", -"G-. c #545579", -"H-. c #68678B", -"I-. c #696892", -"J-. c #70719A", -"K-. c #595B79", -"L-. c #4B4B6D", -"M-. c #474B71", -"N-. c #393A60", -"O-. c #3E3F68", -"P-. c #555578", -"Q-. c #444766", -"R-. c #424466", -"S-. c #63608A", -"T-. c #64648B", -"U-. c #4A4B72", -"V-. c #404266", -"W-. c #474A6E", -"X-. c #464A6F", -"Y-. c #565683", -"Z-. c #484A74", -"`-. c #414569", -" ;. c #D4D4D4", -".;. c #E0E0E0", -"+;. c #484842", -"@;. c #B6B4B1", -"#;. c #C2C1BE", -"$;. c #BAB9B7", -"%;. c #B2B2AE", -"&;. c #C6C6C2", -"*;. c #BDBCBA", -"=;. c #B3B3AE", -"-;. c #8E8B8A", -";;. c #91908D", -">;. c #94918E", -",;. c #9F9F9C", -"';. c #B8B7B4", -");. c #959492", -"!;. c #0F0E0C", -"~;. c #8095D5", -"{;. c #808DF4", -"];. c #BEB2FB", -"^;. c #CDB8EF", -"/;. c #E1BCF1", -"(;. c #EBC1E7", -"_;. c #E3B9DC", -":;. c #DFBAD7", -"<;. c #DEB6D8", -"[;. c #D8B3D3", -"};. c #D1AED2", -"|;. c #C3ABDC", -"1;. c #B9A9D4", -"2;. c #BDA7D8", -"3;. c #C0AED5", -"4;. c #C4B2DD", -"5;. c #BAA0D0", -"6;. c #AE9CC8", -"7;. c #A895C5", -"8;. c #A493BD", -"9;. c #9989AA", -"0;. c #9989B2", -"a;. c #9586B0", -"b;. c #9789B1", -"c;. c #9386AB", -"d;. c #8B80A3", -"e;. c #877EA1", -"f;. c #867E9F", -"g;. c #877DA0", -"h;. c #827C91", -"i;. c #847A90", -"j;. c #8D7F97", -"k;. c #8B8094", -"l;. c #8A7F98", -"m;. c #777387", -"n;. c #77738D", -"o;. c #716E90", -"p;. c #767289", -"q;. c #6C6C86", -"r;. c #6A6A80", -"s;. c #6D6C83", -"t;. c #928BB4", -"u;. c #918AAE", -"v;. c #837E97", -"w;. c #8982A3", -"x;. c #6D6E8B", -"y;. c #797794", -"z;. c #71718D", -"A;. c #8B83B0", -"B;. c #7D7A9C", -"C;. c #8D86AF", -"D;. c #948CB7", -"E;. c #9B95CD", -"F;. c #A79CCD", -"G;. c #A49CCD", -"H;. c #BCB6DA", -"I;. c #A3A2BA", -"J;. c #7C7A9A", -"K;. c #9C98C4", -"L;. c #9C94C5", -"M;. c #948CBA", -"N;. c #CBBFE9", -"O;. c #9492B7", -"P;. c #968FB6", -"Q;. c #BFB6DB", -"R;. c #A49CBB", -"S;. c #B5AFD5", -"T;. c #C8C0E2", -"U;. c #A19CBE", -"V;. c #9891C7", -"W;. c #8983AD", -"X;. c #6B6B87", -"Y;. c #696A86", -"Z;. c #66687F", -"`;. c #706D8C", -" >. c #9F9ACC", -".>. c #D2C6F4", -"+>. c #9190B4", -"@>. c #9C96BF", -"#>. c #C2BAEB", -"$>. c #A9A1CE", -"%>. c #89829A", -"&>. c #A199B6", -"*>. c #A098B7", -"=>. c #9A95AA", -"->. c #A698B9", -";>. c #B5A5BC", -">>. c #C8B2CD", -",>. c #CABDCF", -"'>. c #8C8593", -")>. c #A69BB2", -"!>. c #BFA8C3", -"~>. c #9992A2", -"{>. c #978FB1", -"]>. c #A196BF", -"^>. c #A79EBF", -"/>. c #B0A1C2", -"(>. c #91889C", -"_>. c #8B8396", -":>. c #A398BE", -"<>. c #9690B2", -"[>. c #807C93", -"}>. c #A69EC0", -"|>. c #A39DBF", -"1>. c #9A93B7", -"2>. c #7F7B96", -"3>. c #6D6D83", -"4>. c #5D606E", -"5>. c #5F6375", -"6>. c #8480A0", -"7>. c #8583A3", -"8>. c #79788A", -"9>. c #4B4C5D", -"0>. c #434563", -"a>. c #454766", -"b>. c #3E415F", -"c>. c #353B58", -"d>. c #3D3D60", -"e>. c #404164", -"f>. c #424568", -"g>. c #484C6F", -"h>. c #414567", -"i>. c #494C6C", -"j>. c #494B6F", -"k>. c #494B70", -"l>. c #46496C", -"m>. c #424266", -"n>. c #3C3D63", -"o>. c #373C5E", -"p>. c #393C5E", -"q>. c #7574A1", -"r>. c #8281AB", -"s>. c #4F516C", -"t>. c #636484", -"u>. c #515273", -"v>. c #6F708D", -"w>. c #A7A0BC", -"x>. c #A7A0C1", -"y>. c #6F6C90", -"z>. c #636385", -"A>. c #4D4C76", -"B>. c #46486F", -"C>. c #48486D", -"D>. c #4F5075", -"E>. c #595A81", -"F>. c #5E5E81", -"G>. c #565A7B", -"H>. c #565579", -"I>. c #555677", -"J>. c #797A97", -"K>. c #696885", -"L>. c #424468", -"M>. c #3B3D60", -"N>. c #34375C", -"O>. c #3B3E5E", -"P>. c #363857", -"Q>. c #625E88", -"R>. c #535374", -"S>. c #56547F", -"T>. c #45456A", -"U>. c #49496A", -"V>. c #48496A", -"W>. c #3E4263", -"X>. c #484A71", -"Y>. c #4D4D77", -"Z>. c #CDCDCD", -"`>. c #DADADA", -" ,. c #96695D", -".,. c #060505", -"+,. c #8A8784", -"@,. c #ABA6A2", -"#,. c #AFAEAB", -"$,. c #BABAB6", -"%,. c #A4A3A1", -"&,. c #B0AFAC", -"*,. c #A4A19B", -"=,. c #8D8C8A", -"-,. c #807D7A", -";,. c #858482", -">,. c #7E7E7C", -",,. c #515C8B", -"',. c #8B98F3", -"),. c #A09EFB", -"!,. c #CEBBF5", -"~,. c #D1B4E2", -"{,. c #E7BCED", -"],. c #E2BCE1", -"^,. c #E7BDDF", -"/,. c #D8B6DA", -"(,. c #C7A8D4", -"_,. c #BAA6D2", -":,. c #ACA0D1", -"<,. c #B8A6D7", -"[,. c #BCA7D2", -"},. c #C2B1DF", -"|,. c #A999C8", -"1,. c #A08EC2", -"2,. c #9386B0", -"3,. c #8C7EAC", -"4,. c #877EA0", -"5,. c #877EA7", -"6,. c #9083A9", -"7,. c #9180B1", -"8,. c #867CA3", -"9,. c #867D9E", -"0,. c #867DA1", -"a,. c #837A9A", -"b,. c #827A93", -"c,. c #867EA1", -"d,. c #9085B0", -"e,. c #7C7790", -"f,. c #827A98", -"g,. c #7C779A", -"h,. c #686A8B", -"i,. c #676780", -"j,. c #65667A", -"k,. c #867E9E", -"l,. c #7D778C", -"m,. c #AB9FCB", -"n,. c #A79ECA", -"o,. c #B4ACD2", -"p,. c #A6A1C6", -"q,. c #9C95C0", -"r,. c #9991C6", -"s,. c #8B84B1", -"t,. c #938BB6", -"u,. c #978FBF", -"v,. c #958CBA", -"w,. c #938ABB", -"x,. c #A198C1", -"y,. c #BDB5DA", -"z,. c #BAB5D2", -"A,. c #938EAE", -"B,. c #8D88B0", -"C,. c #958FB6", -"D,. c #8E87B0", -"E,. c #9D94BC", -"F,. c #B1ABCB", -"G,. c #A9A2CD", -"H,. c #AFA9D4", -"I,. c #A5A3C1", -"J,. c #8884AC", -"K,. c #ADA5CB", -"L,. c #B7B0CF", -"M,. c #A9A4C8", -"N,. c #8A87AF", -"O,. c #8685B4", -"P,. c #8180A4", -"Q,. c #7E7CA0", -"R,. c #75768D", -"S,. c #505766", -"T,. c #5D6273", -"U,. c #9B94BB", -"V,. c #9792BC", -"W,. c #8C89AE", -"X,. c #B1AACD", -"Y,. c #9894B7", -"Z,. c #9896B0", -"`,. c #8B8C9E", -" '. c #9D99AF", -".'. c #D3C3DD", -"+'. c #D4C6E3", -"@'. c #B8B0CE", -"#'. c #B9AFCB", -"$'. c #B6ACC4", -"%'. c #B4A9BE", -"&'. c #BDAEC5", -"*'. c #ACA3B3", -"='. c #968799", -"-'. c #9E90A8", -";'. c #9B92A5", -">'. c #9B8EA3", -",'. c #A492A6", -"''. c #AD94B3", -")'. c #A899B4", -"!'. c #9C93B0", -"~'. c #9990B9", -"{'. c #978CB2", -"]'. c #9087A1", -"^'. c #84839C", -"/'. c #817D9A", -"('. c #7E7D9D", -"_'. c #72728B", -":'. c #767195", -"<'. c #8281AE", -"['. c #646674", -"}'. c #3B3F51", -"|'. c #28314B", -"1'. c #2C3353", -"2'. c #383C5A", -"3'. c #373B5B", -"4'. c #2E3354", -"5'. c #2D3155", -"6'. c #313252", -"7'. c #343559", -"8'. c #3B3B5D", -"9'. c #45456D", -"0'. c #3E425E", -"a'. c #393C5F", -"b'. c #434568", -"c'. c #48496D", -"d'. c #46486C", -"e'. c #505173", -"f'. c #5C5B7E", -"g'. c #69688B", -"h'. c #4A4A69", -"i'. c #5A5977", -"j'. c #5A5A7C", -"k'. c #5A597A", -"l'. c #6D698C", -"m'. c #9794B2", -"n'. c #A7A2CA", -"o'. c #A19BC3", -"p'. c #77739C", -"q'. c #696998", -"r'. c #635F8D", -"s'. c #615E81", -"t'. c #4E4E72", -"u'. c #494A6D", -"v'. c #535275", -"w'. c #484A68", -"x'. c #4D4F70", -"y'. c #505373", -"z'. c #444567", -"A'. c #515176", -"B'. c #6A6A8D", -"C'. c #5F5E81", -"D'. c #414364", -"E'. c #36365B", -"F'. c #393E63", -"G'. c #3F4166", -"H'. c #444565", -"I'. c #5F628B", -"J'. c #6E6994", -"K'. c #5B5A7A", -"L'. c #393C59", -"M'. c #30325A", -"N'. c #313157", -"O'. c #393A5C", -"P'. c #43456B", -"Q'. c #C6C6C6", -"R'. c #D5D5D5", -"S'. c #767670", -"T'. c #84847E", -"U'. c #8C8C87", -"V'. c #7E7874", -"W'. c #A8A7A4", -"X'. c #A9A8A6", -"Y'. c #B3B2B0", -"Z'. c #ACABA9", -"`'. c #C1BEBB", -" ). c #B6B3B0", -".). c #B7B1AE", -"+). c #A29F9E", -"@). c #928C89", -"#). c #91918B", -"$). c #A29F9C", -"%). c #A3A2A0", -"&). c #A7A7A1", -"*). c #979593", -"=). c #7A7978", -"-). c #706E6D", -";). c #232844", -">). c #91A3F7", -",). c #9093F6", -"'). c #C4B8FC", -")). c #CCB3F2", -"!). c #D5B0EB", -"~). c #DBB4E3", -"{). c #E2BBE1", -"]). c #D9B2DE", -"^). c #BEA6D8", -"/). c #BEA3CF", -"(). c #AB9CC8", -"_). c #B6A3D4", -":). c #AF9ECB", -"<). c #B099CB", -"[). c #B3A1D3", -"}). c #A997C8", -"|). c #9A8CBA", -"1). c #9787B9", -"2). c #9080AE", -"3). c #867DA7", -"4). c #8B7FA7", -"5). c #8C80B1", -"6). c #8279A3", -"7). c #7E779E", -"8). c #877DA1", -"9). c #7C789B", -"0). c #80799A", -"a). c #807A9A", -"b). c #8C84AF", -"c). c #8D85AE", -"d). c #8C83B1", -"e). c #6B6C8B", -"f). c #676784", -"g). c #69697E", -"h). c #61637F", -"i). c #606376", -"j). c #767186", -"k). c #9389AD", -"l). c #C5BDDD", -"m). c #DAC9EE", -"n). c #C9BFE8", -"o). c #BEB3DD", -"p). c #BDB3E6", -"q). c #A09CC7", -"r). c #978EC2", -"s). c #AAA0D1", -"t). c #A298C7", -"u). c #9A96BF", -"v). c #8882AF", -"w). c #9A94BB", -"x). c #8785AD", -"y). c #857FA3", -"z). c #8B83B4", -"A). c #9491BB", -"B). c #CDC0E0", -"C). c #D3CDEA", -"D). c #A7A0CF", -"E). c #908ABB", -"F). c #8D8ABA", -"G). c #918ABD", -"H). c #887FAE", -"I). c #817DA5", -"J). c #8C85B1", -"K). c #8A85B0", -"L). c #5F617B", -"M). c #696980", -"N). c #8C8AB4", -"O). c #8784AB", -"P). c #A39DC0", -"Q). c #7C7997", -"R). c #B6ADCD", -"S). c #BAB2D3", -"T). c #B4ADCE", -"U). c #ACA8C5", -"V). c #AAA7C8", -"W). c #9994B3", -"X). c #76747D", -"Y). c #B6AFCA", -"Z). c #9D94A9", -"`). c #A29EB1", -" !. c #B0AAC0", -".!. c #9D94AF", -"+!. c #877F90", -"@!. c #877E8F", -"#!. c #8A839D", -"$!. c #A899BA", -"%!. c #A295B2", -"&!. c #9C8FA8", -"*!. c #9E90AA", -"=!. c #A595B1", -"-!. c #9D8EA7", -";!. c #9F91AE", -">!. c #9893AB", -",!. c #9589AB", -"'!. c #948CA9", -")!. c #888095", -"!!. c #988FB2", -"~!. c #7E7B96", -"{!. c #827B9F", -"]!. c #7F7FA4", -"^!. c #7D7998", -"/!. c #5B5B69", -"(!. c #323652", -"_!. c #2B324E", -":!. c #2B2D4C", -"~. c #A294C5", -",~. c #AC9ACF", -"'~. c #AA97CA", -")~. c #A290C1", -"!~. c #9F8CBD", -"~~. c #9487B4", -"{~. c #9080AB", -"]~. c #897EA2", -"^~. c #827A9B", -"/~. c #857DA4", -"(~. c #887DA6", -"_~. c #867CA1", -":~. c #867CA2", -"<~. c #827B9C", -"[~. c #8882A7", -"}~. c #887DA7", -"|~. c #8980A4", -"1~. c #9084B4", -"2~. c #A89ED2", -"3~. c #968DBE", -"4~. c #696A84", -"5~. c #76758E", -"6~. c #6A6986", -"7~. c #62637F", -"8~. c #636480", -"9~. c #63637C", -"0~. c #75738C", -"a~. c #817C99", -"b~. c #ACA4C9", -"c~. c #ADA5D0", -"d~. c #A39CC2", -"e~. c #B7AFD5", -"f~. c #A19AC4", -"g~. c #B4AADC", -"h~. c #B0AAD0", -"i~. c #9B92B9", -"j~. c #8E87B2", -"k~. c #797693", -"l~. c #9790B5", -"m~. c #8883AE", -"n~. c #8D86B6", -"o~. c #8681A9", -"p~. c #7D779E", -"q~. c #857FAF", -"r~. c #7E7BA5", -"s~. c #7C7BA3", -"t~. c #7B7598", -"u~. c #837EA8", -"v~. c #9F96C8", -"w~. c #ABA3D4", -"x~. c #A09ACB", -"y~. c #8987BA", -"z~. c #8C86B8", -"A~. c #8883B2", -"B~. c #8683AF", -"C~. c #807BA5", -"D~. c #8B86B2", -"E~. c #7D7AA0", -"F~. c #807EA8", -"G~. c #6F6F89", -"H~. c #72718F", -"I~. c #B3ADC3", -"J~. c #A6A3B3", -"K~. c #6A6B85", -"L~. c #918EBB", -"M~. c #A9A2C0", -"N~. c #A7A0CB", -"O~. c #8483A0", -"P~. c #84839B", -"Q~. c #A19EAF", -"R~. c #A29FAF", -"S~. c #C3B7D2", -"T~. c #CAC2DB", -"U~. c #A29BAE", -"V~. c #A5A3A7", -"W~. c #ADA4B9", -"X~. c #C6B8CD", -"Y~. c #A8A3AD", -"Z~. c #7A7481", -"`~. c #807883", -" {. c #938699", -".{. c #867D91", -"+{. c #9991AC", -"@{. c #A298B5", -"#{. c #AB9EBD", -"${. c #A99BB8", -"%{. c #AE9FBF", -"&{. c #8B859E", -"*{. c #8C849F", -"={. c #8B859D", -"-{. c #837D93", -";{. c #7C7591", -">{. c #74718F", -",{. c #7B7AA3", -"'{. c #656577", -"){. c #414554", -"!{. c #32384F", -"~{. c #2F3352", -"{{. c #313253", -"]{. c #2E324D", -"^{. c #222946", -"/{. c #1C2445", -"({. c #212648", -"_{. c #1E2648", -":{. c #1F254D", -"<{. c #21284C", -"[{. c #252A4A", -"}{. c #202745", -"|{. c #2A304B", -"1{. c #202844", -"2{. c #1F2744", -"3{. c #192347", -"4{. c #23294B", -"5{. c #282B4C", -"6{. c #292D4D", -"7{. c #333355", -"8{. c #363955", -"9{. c #2F3351", -"0{. c #313351", -"a{. c #272B4E", -"b{. c #343458", -"c{. c #303350", -"d{. c #383959", -"e{. c #464664", -"f{. c #333552", -"g{. c #3F3D5E", -"h{. c #3B3C5D", -"i{. c #414164", -"j{. c #555476", -"k{. c #4A4A6D", -"l{. c #434364", -"m{. c #3F4260", -"n{. c #424465", -"o{. c #383A58", -"p{. c #39395A", -"q{. c #393A5A", -"r{. c #383957", -"s{. c #535471", -"t{. c #3F425F", -"u{. c #4B4B6A", -"v{. c #5B5977", -"w{. c #4E4D69", -"x{. c #5F5883", -"y{. c #716F9A", -"z{. c #8982AD", -"A{. c #76709C", -"B{. c #857FA7", -"C{. c #615F7F", -"D{. c #4C4B66", -"E{. c #323450", -"F{. c #2B3050", -"G{. c #2D304E", -"H{. c #2A2B4B", -"I{. c #B9B9B9", -"J{. c #8B8B86", -"K{. c #B9B9B4", -"L{. c #A7A6A2", -"M{. c #A4A3A0", -"N{. c #9A9897", -"O{. c #9B9592", -"P{. c #8A8A85", -"Q{. c #585655", -"R{. c #090906", -"S{. c #4F6091", -"T{. c #899BF5", -"U{. c #9B9BF3", -"V{. c #CAB8F7", -"W{. c #D2B7F4", -"X{. c #CDB3E6", -"Y{. c #D1B0E0", -"Z{. c #C8A9DB", -"`{. c #BDA4DA", -" ]. c #B69FD4", -".]. c #AF9BCE", -"+]. c #AF9BD1", -"@]. c #A794C9", -"#]. c #9A8FBB", -"$]. c #9E8EBA", -"%]. c #9E8CBA", -"&]. c #9988B4", -"*]. c #9B8CB8", -"=]. c #9383AC", -"-]. c #8E81AD", -";]. c #877CA3", -">]. c #81779D", -",]. c #7C769B", -"']. c #837A9E", -")]. c #7F769C", -"!]. c #817A9F", -"~]. c #7E75A3", -"{]. c #7C7599", -"]]. c #9789BC", -"^]. c #8884B4", -"/]. c #928CBC", -"(]. c #9E93C3", -"_]. c #A59DC4", -":]. c #8D85B1", -"<]. c #676783", -"[]. c #716E8E", -"}]. c #60617B", -"|]. c #63637B", -"1]. c #74728A", -"2]. c #827E9D", -"3]. c #7B7695", -"4]. c #B2A8D2", -"5]. c #C3B7E6", -"6]. c #A8A1D4", -"7]. c #B1ABD4", -"8]. c #8481A9", -"9]. c #A59FC5", -"0]. c #ABA1C4", -"a]. c #9692C4", -"b]. c #908AB2", -"c]. c #747191", -"d]. c #8881AB", -"e]. c #747496", -"f]. c #8882B2", -"g]. c #777392", -"h]. c #7B779E", -"i]. c #7E78AA", -"j]. c #737193", -"k]. c #837CAC", -"l]. c #9D95C6", -"m]. c #8981B0", -"n]. c #A79FD1", -"o]. c #A9A3D4", -"p]. c #8D87B5", -"q]. c #8F8CBA", -"r]. c #9E9AC1", -"s]. c #AEA8C4", -"t]. c #837CA7", -"u]. c #767496", -"v]. c #8482B1", -"w]. c #8881AF", -"x]. c #7B7AA2", -"y]. c #817DA8", -"z]. c #7B7597", -"A]. c #76738F", -"B]. c #BDB7C7", -"C]. c #B0AAB5", -"D]. c #656473", -"E]. c #767498", -"F]. c #7C7999", -"G]. c #8885AE", -"H]. c #9190AF", -"I]. c #9A99B6", -"J]. c #A49EB2", -"K]. c #9C98AC", -"L]. c #908D9B", -"M]. c #9893AE", -"N]. c #9996A2", -"O]. c #C5BCC8", -"P]. c #6D706C", -"Q]. c #76717D", -"R]. c #A89FB4", -"S]. c #757578", -"T]. c #5E5E61", -"U]. c #68666E", -"V]. c #7C7991", -"W]. c #576061", -"X]. c #747187", -"Y]. c #878097", -"Z]. c #8B8295", -"`]. c #968AA4", -" ^. c #988DA0", -".^. c #897E95", -"+^. c #847D99", -"@^. c #83778E", -"#^. c #7A778B", -"$^. c #676777", -"%^. c #747291", -"&^. c #5B5C67", -"*^. c #404159", -"=^. c #3E405D", -"-^. c #4A4A6F", -";^. c #494C6B", -">^. c #393D5B", -",^. c #2D3050", -"'^. c #222847", -")^. c #222743", -"!^. c #1C2545", -"~^. c #1C2345", -"{^. c #222644", -"]^. c #2F3050", -"^^. c #313551", -"/^. c #2D3150", -"(^. c #323452", -"_^. c #303450", -":^. c #212842", -"<^. c #1E2345", -"[^. c #1E2546", -"}^. c #192245", -"|^. c #1B2548", -"1^. c #1D2342", -"2^. c #23294C", -"3^. c #1E2348", -"4^. c #1C2244", -"5^. c #222648", -"6^. c #292D49", -"7^. c #45455F", -"8^. c #292B4D", -"9^. c #2D2D4C", -"0^. c #232646", -"a^. c #2D2D4E", -"b^. c #282B4B", -"c^. c #30314E", -"d^. c #353653", -"e^. c #2F314E", -"f^. c #333755", -"g^. c #363654", -"h^. c #363957", -"i^. c #3B3C5E", -"j^. c #3D3D5E", -"k^. c #353955", -"l^. c #3D3F59", -"m^. c #404160", -"n^. c #34374F", -"o^. c #3A3B57", -"p^. c #5B5A78", -"q^. c #817E99", -"r^. c #847F9C", -"s^. c #605B7D", -"t^. c #777192", -"u^. c #ADA5B9", -"v^. c #A19AB3", -"w^. c #8F87AC", -"x^. c #716E8C", -"y^. c #4D4F66", -"z^. c #3D3E58", -"A^. c #393A58", -"B^. c #3D3D5C", -"C^. c #393956", -"D^. c #B6B6B6", -"E^. c #C0C0C0", -"F^. c #3A3A39", -"G^. c #7D7C79", -"H^. c #949490", -"I^. c #85857F", -"J^. c #898580", -"K^. c #979491", -"L^. c #898983", -"M^. c #1B253A", -"N^. c #92A7F3", -"O^. c #8490ED", -"P^. c #AFA7F1", -"Q^. c #CCB7F3", -"R^. c #C9B1E9", -"S^. c #C9ADDE", -"T^. c #C2A6DA", -"U^. c #B7A3D4", -"V^. c #AC9CD0", -"W^. c #A897D0", -"X^. c #A998C9", -"Y^. c #9F93C7", -"Z^. c #A291C7", -"`^. c #9488BD", -" /. c #9081B5", -"./. c #9383B2", -"+/. c #8B7FA4", -"@/. c #8E7DAB", -"#/. c #8C81A5", -"$/. c #8B7DA3", -"%/. c #847AA3", -"&/. c #83789C", -"*/. c #7E7598", -"=/. c #797395", -"-/. c #767190", -";/. c #7C7496", -">/. c #84789E", -",/. c #978BBC", -"'/. c #767396", -")/. c #8D82B0", -"!/. c #A298C6", -"~/. c #A097C6", -"{/. c #9D94C4", -"]/. c #9E96C4", -"^/. c #978EB5", -"//. c #6E6C88", -"(/. c #646580", -"_/. c #727092", -":/. c #5E607C", -"(. c #292E4F", -",(. c #252745", -"'(. c #242643", -")(. c #4C4B64", -"!(. c #626688", -"~(. c #5B5E78", -"{(. c #47475E", -"](. c #5B5D79", -"^(. c #353854", -"/(. c #20253E", -"((. c #222543", -"_(. c #202545", -":(. c #262B4B", -"<(. c #1B2146", -"[(. c #1A2142", -"}(. c #1C2343", -"|(. c #232544", -"1(. c #40405E", -"2(. c #5A5A79", -"3(. c #6D6D7A", -"4(. c #3C3B52", -"5(. c #615E76", -"6(. c #585674", -"7(. c #41415D", -"8(. c #363753", -"9(. c #3C3F5A", -"0(. c #2A2C47", -"a(. c #2F2F4C", -"b(. c #30324C", -"c(. c #343552", -"d(. c #30314F", -"e(. c #2F2F4E", -"f(. c #2D2E4C", -"g(. c #333652", -"h(. c #323655", -"i(. c #333752", -"j(. c #3B3B5C", -"k(. c #444464", -"l(. c #373956", -"m(. c #3F3F5C", -"n(. c #35394D", -"o(. c #42435D", -"p(. c #7A749B", -"q(. c #6C6A8B", -"r(. c #706A90", -"s(. c #A095B5", -"t(. c #AA9FB3", -"u(. c #A295B1", -"v(. c #8D88A7", -"w(. c #8881A1", -"x(. c #6F698C", -"y(. c #514F6A", -"z(. c #545172", -"A(. c #383A54", -"B(. c #353855", -"C(. c #B2B2B2", -"D(. c #787873", -"E(. c #989794", -"F(. c #878782", -"G(. c #A8A6A4", -"H(. c #A1A09C", -"I(. c #A9A4A3", -"J(. c #999593", -"K(. c #82827C", -"L(. c #535050", -"M(. c #9CB3EF", -"N(. c #8894EF", -"O(. c #8F90F0", -"P(. c #C5B3EE", -"Q(. c #C4ADE4", -"R(. c #BAA5DC", -"S(. c #BEA2D9", -"T(. c #B5A2D2", -"U(. c #A899CC", -"V(. c #A293CA", -"W(. c #A497D4", -"X(. c #A394C5", -"Y(. c #A493C8", -"Z(. c #8C7FB0", -"`(. c #8D7CAF", -" _. c #857BA1", -"._. c #8A78AC", -"+_. c #8279A1", -"@_. c #887BA3", -"#_. c #83779E", -"$_. c #83789E", -"%_. c #81779C", -"&_. c #7B729B", -"*_. c #777198", -"=_. c #716C94", -"-_. c #766F94", -";_. c #787193", -">_. c #8782AD", -",_. c #8180A5", -"'_. c #8681AB", -")_. c #938BBC", -"!_. c #A397C8", -"~_. c #AAA2C7", -"{_. c #A29AC2", -"]_. c #928CB5", -"^_. c #7C78A1", -"/_. c #78749B", -"(_. c #686880", -"__. c #62627C", -":_. c #76728C", -"<_. c #BFB0D4", -"[_. c #CFBEDF", -"}_. c #C3B3D3", -"|_. c #D2BAE0", -"1_. c #B8B0C5", -"2_. c #8E89B1", -"3_. c #918EB5", -"4_. c #A098C9", -"5_. c #9891BC", -"6_. c #8E89AF", -"7_. c #9891BD", -"8_. c #8E8CB9", -"9_. c #7F77A3", -"0_. c #7C76A0", -"a_. c #807BA3", -"b_. c #807CA9", -"c_. c #7B74A1", -"d_. c #948BBD", -"e_. c #7F79A4", -"f_. c #8B87A8", -"g_. c #797D92", -"h_. c #4F5364", -"i_. c #4C516C", -"j_. c #4B4E63", -"k_. c #595B76", -"l_. c #686889", -"m_. c #616281", -"n_. c #7771A0", -"o_. c #706D91", -"p_. c #5C5E75", -"q_. c #424A59", -"r_. c #565A75", -"s_. c #7D7AA6", -"t_. c #7A79AB", -"u_. c #747397", -"v_. c #747298", -"w_. c #ADA7C1", -"x_. c #ACAABB", -"y_. c #ADA2BD", -"z_. c #C7BDCE", -"A_. c #B8B7B8", -"B_. c #938DA5", -"C_. c #A7A2BA", -"D_. c #9896B2", -"E_. c #9693A4", -"F_. c #9B9B99", -"G_. c #5D6262", -"H_. c #494D54", -"I_. c #444958", -"J_. c #484D5C", -"K_. c #444B52", -"L_. c #4C5153", -"M_. c #4C5151", -"N_. c #787886", -"O_. c #63646A", -"P_. c #998FA9", -"Q_. c #B5AEB6", -"R_. c #878495", -"S_. c #8C8C8E", -"T_. c #4C5157", -"U_. c #878393", -"V_. c #8E899B", -"W_. c #B2B1B1", -"X_. c #877C8A", -"Y_. c #918697", -"Z_. c #9790AA", -"`_. c #8F8DA4", -" :. c #C6BBC6", -".:. c #B7B1BB", -"+:. c #8F8C9A", -"@:. c #494B56", -"#:. c #2E2E4B", -"$:. c #353657", -"%:. c #484765", -"&:. c #5D5B7A", -"*:. c #585971", -"=:. c #4C4C6E", -"-:. c #4F4E6D", -";:. c #565674", -">:. c #4E4B66", -",:. c #3C3C5D", -"':. c #242745", -"):. c #5E5D86", -"!:. c #797499", -"~:. c #807F91", -"{:. c #47485F", -"]:. c #31344B", -"^:. c #1B223F", -"/:. c #1A203C", -"(:. c #1F2640", -"_:. c #2A2D49", -"::. c #272A42", -"<:. c #252744", -"[:. c #302F4B", -"}:. c #2F3048", -"|:. c #75728E", -"1:. c #545364", -"2:. c #555671", -"3:. c #565575", -"4:. c #575379", -"5:. c #737095", -"6:. c #67678A", -"7:. c #363A50", -"8:. c #353651", -"9:. c #313350", -"0:. c #2C2D49", -"a:. c #31324C", -"b:. c #323250", -"c:. c #30314A", -"d:. c #393C58", -"e:. c #2D3147", -"f:. c #343550", -"g:. c #33384F", -"h:. c #555474", -"i:. c #4E4D68", -"j:. c #44455F", -"k:. c #393955", -"l:. c #5A5573", -"m:. c #68648E", -"n:. c #77729A", -"o:. c #998FB2", -"p:. c #B1A3B1", -"q:. c #B1A0B1", -"r:. c #AA9EB0", -"s:. c #9F97B0", -"t:. c #797788", -"u:. c #656288", -"v:. c #535371", -"w:. c #484863", -"x:. c #3E4057", -"y:. c #AFAFAF", -"z:. c #969595", -"A:. c #91918C", -"B:. c #91908C", -"C:. c #84817E", -"D:. c #979692", -"E:. c #9C9A98", -"F:. c #9C9896", -"G:. c #9A9796", -"H:. c #969591", -"I:. c #94908F", -"J:. c #86817D", -"K:. c #92928C", -"L:. c #7B7B75", -"M:. c #3E4D76", -"N:. c #8B9EED", -"O:. c #8589EA", -"P:. c #9D99E4", -"Q:. c #C0ADE2", -"R:. c #B5A5DB", -"S:. c #A898D4", -"T:. c #A595CF", -"U:. c #9F91C7", -"V:. c #9D8FCE", -"W:. c #A49BD0", -"X:. c #998DC0", -"Y:. c #9D90C7", -"Z:. c #9385B8", -"`:. c #8679A7", -" <. c #8674A8", -".<. c #8275A0", -"+<. c #8176A5", -"@<. c #8075A0", -"#<. c #81739E", -"$<. c #7E7498", -"%<. c #7E72A0", -"&<. c #766D9A", -"*<. c #736E90", -"=<. c #777197", -"-<. c #777299", -";<. c #7A769F", -"><. c #827DAF", -",<. c #8982B8", -"'<. c #8B84AD", -")<. c #908CBC", -"!<. c #9891C2", -"~<. c #ADA3C8", -"{<. c #B0A2C5", -"]<. c #A99ECB", -"^<. c #8B83B1", -"/<. c #7F79A1", -"(<. c #7C7697", -"_<. c #6F6C88", -":<. c #756E8F", -"<<. c #958BAC", -"[<. c #C0B0CE", -"}<. c #A09AC1", -"|<. c #B2A3D4", -"1<. c #C5B7D4", -"2<. c #817CA4", -"3<. c #9187B6", -"4<. c #9894C4", -"5<. c #9C94BF", -"6<. c #A8A1CB", -"7<. c #A5A0CB", -"8<. c #908AB5", -"9<. c #837DA2", -"0<. c #78729D", -"a<. c #76709A", -"b<. c #7B76A2", -"c<. c #757297", -"d<. c #78749F", -"e<. c #8281A9", -"f<. c #595C6C", -"g<. c #BEB3C2", -"h<. c #C9C8D4", -"i<. c #6D6E83", -"j<. c #494C61", -"k<. c #42495B", -"l<. c #464C63", -"m<. c #464B62", -"n<. c #555573", -"o<. c #42495A", -"p<. c #494E64", -"q<. c #444B5D", -"r<. c #414759", -"s<. c #384353", -"t<. c #545768", -"u<. c #6B6989", -"v<. c #7B76A6", -"w<. c #75719D", -"x<. c #4E5260", -"y<. c #64627A", -"z<. c #9C96A6", -"A<. c #CEC1C9", -"B<. c #C5B7CD", -"C<. c #BEB2C5", -"D<. c #A5A2BA", -"E<. c #858299", -"F<. c #A9A1BB", -"G<. c #ABA4C2", -"H<. c #B4ACC7", -"I<. c #717195", -"J<. c #505465", -"K<. c #69698A", -"L<. c #595B6D", -"M<. c #6E6E7C", -"N<. c #898896", -"O<. c #9190A6", -"P<. c #948E9F", -"Q<. c #A59FAA", -"R<. c #7F7B83", -"S<. c #8A8796", -"T<. c #484C51", -"U<. c #555763", -"V<. c #69637A", -"W<. c #5E5D6F", -"X<. c #888395", -"Y<. c #B6B3B3", -"Z<. c #867B7B", -"`<. c #8D8796", -" [. c #A19BAA", -".[. c #AFADBE", -"+[. c #AEA7AC", -"@[. c #B6B0B6", -"#[. c #757774", -"$[. c #444361", -"%[. c #464861", -"&[. c #444463", -"*[. c #3D3D5A", -"=[. c #5C5B78", -"-[. c #616080", -";[. c #6C6D86", -">[. c #636284", -",[. c #494966", -"'[. c #3B3B58", -")[. c #2B2D47", -"![. c #2D3049", -"~[. c #272B3E", -"{[. c #585A75", -"][. c #5C5975", -"^[. c #75738B", -"/[. c #8A85A9", -"([. c #3D3F53", -"_[. c #373955", -":[. c #434261", -"<[. c #353752", -"[[. c #5B547E", -"}[. c #5E5B81", -"|[. c #59557B", -"1[. c #41435A", -"2[. c #52506F", -"3[. c #8A8895", -"4[. c #827E9A", -"5[. c #58576F", -"6[. c #4F4F6E", -"7[. c #585676", -"8[. c #5B5A73", -"9[. c #535271", -"0[. c #66638A", -"a[. c #454560", -"b[. c #3E3F5A", -"c[. c #595878", -"d[. c #494968", -"e[. c #3D4059", -"f[. c #5F5C80", -"g[. c #726F8C", -"h[. c #4E4E60", -"i[. c #52506E", -"j[. c #4F4E6C", -"k[. c #4C4860", -"l[. c #35384D", -"m[. c #3E3F58", -"n[. c #64667D", -"o[. c #4F5169", -"p[. c #645E81", -"q[. c #7F7A9D", -"r[. c #A292AD", -"s[. c #A392AD", -"t[. c #A498AD", -"u[. c #A492AD", -"v[. c #A296AD", -"w[. c #8B849F", -"x[. c #7D759D", -"y[. c #817AA1", -"z[. c #6F698E", -"A[. c #565370", -"B[. c #ABABAB", -"C[. c #AAAAAA", -"D[. c #777574", -"E[. c #757472", -"F[. c #81807E", -"G[. c #90908B", -"H[. c #AAA8A6", -"I[. c #938F8E", -"J[. c #908C8A", -"K[. c #817C7B", -"L[. c #817E79", -"M[. c #87837F", -"N[. c #807E76", -"O[. c #52524D", -"P[. c #504E4D", -"Q[. c #242320", -"R[. c #02030A", -"S[. c #90A3E8", -"T[. c #828DE3", -"U[. c #7C83DD", -"V[. c #AC9FDE", -"W[. c #B2A1D9", -"X[. c #A896D3", -"Y[. c #9F91CD", -"Z[. c #8D84C0", -"`[. c #9187C9", -" }. c #958CC4", -".}. c #9F93C9", -"+}. c #958DBE", -"@}. c #887FB4", -"#}. c #8678A8", -"$}. c #8073A5", -"%}. c #8273A4", -"&}. c #8173A3", -"*}. c #7B7299", -"=}. c #7D7499", -"-}. c #7D7498", -";}. c #746E97", -">}. c #746B96", -",}. c #736B94", -"'}. c #7C70A3", -")}. c #8F87B4", -"!}. c #8F86B6", -"~}. c #8581B3", -"{}. c #8B82B9", -"]}. c #8D86BC", -"^}. c #8E86BD", -"/}. c #9691C5", -"(}. c #9D96C2", -"_}. c #A299BD", -":}. c #A39ABD", -"<}. c #A39AC0", -"[}. c #9A92B8", -"}}. c #8D8AB0", -"|}. c #8A83B0", -"1}. c #7C76A1", -"2}. c #807A9F", -"3}. c #8E88B3", -"4}. c #8F88B5", -"5}. c #9A92BD", -"6}. c #A79EC7", -"7}. c #A69DC6", -"8}. c #8F88B6", -"9}. c #9A92C8", -"0}. c #908AAF", -"a}. c #9F97C3", -"b}. c #938EB7", -"c}. c #7874A2", -"d}. c #6E6C89", -"e}. c #6F6990", -"f}. c #6E6892", -"g}. c #716B93", -"h}. c #525463", -"i}. c #444A54", -"j}. c #5D5C74", -"k}. c #7D7C96", -"l}. c #807B92", -"m}. c #B4B0BF", -"n}. c #464D54", -"o}. c #4C5061", -"p}. c #64667F", -"q}. c #575B70", -"r}. c #424759", -"s}. c #3A4251", -"t}. c #3A4252", -"u}. c #36414F", -"v}. c #38404D", -"w}. c #384055", -"x}. c #384150", -"y}. c #41465B", -"z}. c #5E5D77", -"A}. c #62617F", -"B}. c #5C5C78", -"C}. c #676583", -"D}. c #B7B0BE", -"E}. c #C8C1C8", -"F}. c #94939D", -"G}. c #BAB2C1", -"H}. c #C6BEC6", -"I}. c #C0B7C4", -"J}. c #B0A8BF", -"K}. c #B1ADBE", -"L}. c #8884A1", -"M}. c #56596A", -"N}. c #4F4F6C", -"O}. c #4B4D65", -"P}. c #54536E", -"Q}. c #3E4352", -"R}. c #686773", -"S}. c #898798", -"T}. c #7D7D8E", -"U}. c #666575", -"V}. c #5C5B5B", -"W}. c #5B555C", -"X}. c #807987", -"Y}. c #747080", -"Z}. c #686779", -"`}. c #615C6A", -" |. c #555564", -".|. c #535564", -"+|. c #78748D", -"@|. c #928894", -"#|. c #767379", -"$|. c #9E97A5", -"%|. c #B9B3B9", -"&|. c #B2ACAF", -"*|. c #818183", -"=|. c #3F4259", -"-|. c #3F425D", -";|. c #41445D", -">|. c #4F4D6C", -",|. c #575676", -"'|. c #40415C", -")|. c #373A51", -"!|. c #323548", -"~|. c #37374A", -"{|. c #464661", -"]|. c #656381", -"^|. c #636586", -"/|. c #414353", -"(|. c #4D4B64", -"_|. c #837F9A", -":|. c #9D98AC", -"<|. c #82808F", -"[|. c #6E688A", -"}|. c #5D587B", -"||. c #3D3E56", -"1|. c #41405A", -"2|. c #6E6A93", -"3|. c #7D7A9F", -"4|. c #65648E", -"5|. c #4F5065", -"6|. c #6D6A7B", -"7|. c #A096AB", -"8|. c #9690A8", -"9|. c #5A5677", -"0|. c #736F86", -"a|. c #636186", -"b|. c #7C779F", -"c|. c #515067", -"d|. c #5B587C", -"e|. c #3B3C4D", -"f|. c #5C587E", -"g|. c #6C6C88", -"h|. c #857FA6", -"i|. c #A19AAD", -"j|. c #948CA1", -"k|. c #78728D", -"l|. c #676889", -"m|. c #6E6B89", -"n|. c #4B4E5D", -"o|. c #47475B", -"p|. c #494A61", -"q|. c #2E2F3F", -"r|. c #404358", -"s|. c #53536B", -"t|. c #67607D", -"u|. c #7E7897", -"v|. c #9D91A9", -"w|. c #A092A9", -"x|. c #8E88A3", -"y|. c #958AA8", -"z|. c #9A90A8", -"A|. c #8B839F", -"B|. c #8C85A6", -"C|. c #958BA7", -"D|. c #88849D", -"E|. c #A7A7A7", -"F|. c #000100", -"G|. c #A2A2A2", -"H|. c #181818", -"I|. c #323231", -"J|. c #817F7D", -"K|. c #9E9D9A", -"L|. c #A09F9D", -"M|. c #A19D9C", -"N|. c #8C8887", -"O|. c #888382", -"P|. c #7F7D7B", -"Q|. c #888882", -"R|. c #7D7B73", -"S|. c #3B3A37", -"T|. c #1D1D1D", -"U|. c #875A4E", -"V|. c #556595", -"W|. c #7F8DDA", -"X|. c #7A82D7", -"Y|. c #7D7DCA", -"Z|. c #A396CC", -"`|. c #9289C5", -" 1. c #9689C4", -".1. c #948CC6", -"+1. c #968DC5", -"@1. c #8A83BE", -"#1. c #8C86B6", -"$1. c #867EAE", -"%1. c #8A7AB2", -"&1. c #7D73A8", -"*1. c #7C6E9F", -"=1. c #7A6D9B", -"-1. c #786C98", -";1. c #786D9B", -">1. c #796E9D", -",1. c #736A96", -"'1. c #736C90", -")1. c #726A95", -"!1. c #6F678D", -"~1. c #6C6687", -"{1. c #8276A3", -"]1. c #8A82A8", -"^1. c #8D86B4", -"/1. c #938CBD", -"(1. c #958FC2", -"_1. c #8F88BC", -":1. c #9893BE", -"<1. c #9892C1", -"[1. c #8F88AE", -"}1. c #9A91B6", -"|1. c #9892B5", -"11. c #9792B2", -"21. c #A399C0", -"31. c #8C85B0", -"41. c #8982AF", -"51. c #948BBB", -"61. c #8984AF", -"71. c #9F97C0", -"81. c #958CB5", -"91. c #9892B6", -"01. c #958EB7", -"a1. c #8780B3", -"b1. c #817BA8", -"c1. c #A99EC4", -"d1. c #817D9C", -"e1. c #706F9B", -"f1. c #6A6893", -"g1. c #77719A", -"h1. c #938DB1", -"i1. c #AEA8B6", -"j1. c #727478", -"k1. c #797586", -"l1. c #B7B4C4", -"m1. c #6F6D8E", -"n1. c #5D616B", -"o1. c #404750", -"p1. c #73708B", -"q1. c #9A97B5", -"r1. c #757685", -"s1. c #4B4E67", -"t1. c #414658", -"u1. c #444A5C", -"v1. c #323A4F", -"w1. c #353C4C", -"x1. c #373E4C", -"y1. c #363C52", -"z1. c #3B4156", -"A1. c #3F4355", -"B1. c #474B5E", -"C1. c #494B5D", -"D1. c #5D5C77", -"E1. c #827D89", -"F1. c #9893A9", -"G1. c #717183", -"H1. c #BEBEB8", -"I1. c #BCBCBC", -"J1. c #BCAFBD", -"K1. c #B3A7BD", -"L1. c #717389", -"M1. c #3E4351", -"N1. c #2E313F", -"O1. c #2C2F3C", -"P1. c #30343F", -"Q1. c #757478", -"R1. c #8A8891", -"S1. c #60606E", -"T1. c #5E5E69", -"U1. c #929093", -"V1. c #494C4B", -"W1. c #9C91A0", -"X1. c #9C91A5", -"Y1. c #6E6C7E", -"Z1. c #605D69", -"`1. c #5A5A69", -" 2. c #6B6676", -".2. c #7F7485", -"+2. c #A89DAB", -"@2. c #6D6A70", -"#2. c #A29EA4", -"$2. c #97979A", -"%2. c #4F4F53", -"&2. c #36394E", -"*2. c #555572", -"=2. c #57557A", -"-2. c #464761", -";2. c #4E516C", -">2. c #5A5478", -",2. c #474767", -"'2. c #535277", -")2. c #585478", -"!2. c #6C6B91", -"~2. c #55527D", -"{2. c #4C4C68", -"]2. c #605F87", -"^2. c #68668C", -"/2. c #424357", -"(2. c #575674", -"_2. c #716F92", -":2. c #525172", -"<2. c #7F7A96", -"[2. c #9C95A4", -"}2. c #A19AAF", -"|2. c #9892AF", -"12. c #726D93", -"22. c #434555", -"32. c #3A3A55", -"42. c #585875", -"52. c #53526F", -"62. c #524F6B", -"72. c #50506B", -"82. c #625D83", -"92. c #7E7A97", -"02. c #726D84", -"a2. c #6D6A84", -"b2. c #77778D", -"c2. c #78739E", -"d2. c #847FA3", -"e2. c #7D7996", -"f2. c #928EA7", -"g2. c #8D879D", -"h2. c #8983A4", -"i2. c #A8A0AA", -"j2. c #A19CAA", -"k2. c #A69FAA", -"l2. c #A397A9", -"m2. c #A99DA9", -"n2. c #AA99AA", -"o2. c #9D93A9", -"p2. c #948EA9", -"q2. c #A595A8", -"r2. c #96939C", -"s2. c #8F89A0", -"t2. c #96929E", -"u2. c #7B768C", -"v2. c #515061", -"w2. c #343744", -"x2. c #4B4965", -"y2. c #5F5A80", -"z2. c #726C8C", -"A2. c #9487A6", -"B2. c #8E87A1", -"C2. c #867E9A", -"D2. c #8A7F9E", -"E2. c #9288A4", -"F2. c #A08CA4", -"G2. c #9C8AA3", -"H2. c #998EA3", -"I2. c #A3A3A3", -"J2. c #9B9B9B", -"K2. c #2A2A29", -"L2. c #696969", -"M2. c #8A8886", -"N2. c #A09F9C", -"O2. c #8A8885", -"P2. c #888786", -"Q2. c #8B8987", -"R2. c #6A6968", -"S2. c #6C6A69", -"T2. c #777773", -"U2. c #42433D", -"V2. c #3E3E3D", -"W2. c #1A1A18", -"X2. c #1D2237", -"Y2. c #7C8DD2", -"Z2. c #747ECE", -"`2. c #7273C9", -" 3. c #847EC1", -".3. c #8E86BF", -"+3. c #847AB5", -"@3. c #8377B0", -"#3. c #877DB9", -"$3. c #8078AF", -"%3. c #8479AF", -"&3. c #79709F", -"*3. c #786D9C", -"=3. c #706790", -"-3. c #6D658C", -";3. c #706689", -">3. c #6B658A", -",3. c #6F6691", -"'3. c #70678D", -")3. c #6B6487", -"!3. c #6B6291", -"~3. c #615D82", -"{3. c #6A668C", -"]3. c #80779E", -"^3. c #857FB5", -"/3. c #807CB1", -"(3. c #9993B1", -"_3. c #847FA7", -":3. c #787395", -"<3. c #7B7499", -"[3. c #A59BC0", -"}3. c #8C84AB", -"|3. c #837CA5", -"13. c #7D7798", -"23. c #8C89A3", -"33. c #7F799F", -"43. c #857FAD", -"53. c #AB9EC3", -"63. c #8E88AF", -"73. c #918AB1", -"83. c #8C83AE", -"93. c #978FB5", -"03. c #8D87A9", -"a3. c #736F99", -"b3. c #706B94", -"c3. c #686487", -"d3. c #666489", -"e3. c #625F7D", -"f3. c #8D87AC", -"g3. c #8C889B", -"h3. c #BDB4BF", -"i3. c #94939B", -"j3. c #A49CB3", -"k3. c #BAB3BE", -"l3. c #ABAEAF", -"m3. c #8F8FA1", -"n3. c #9290A6", -"o3. c #9991A7", -"p3. c #B0ABB8", -"q3. c #83809B", -"r3. c #656A74", -"s3. c #45475B", -"t3. c #333949", -"u3. c #2E3643", -"v3. c #2E3749", -"w3. c #323748", -"x3. c #343848", -"y3. c #303748", -"z3. c #303649", -"A3. c #2E3646", -"B3. c #363B4A", -"C3. c #373D4A", -"D3. c #38404E", -"E3. c #72707D", -"F3. c #9B96A3", -"G3. c #A9A0B6", -"H3. c #ACA6B2", -"I3. c #A99FB6", -"J3. c #B6ACB5", -"K3. c #ADA4B4", -"L3. c #8C899E", -"M3. c #6A6B84", -"N3. c #3D4150", -"O3. c #36394C", -"P3. c #2B2F36", -"Q3. c #3D3F4D", -"R3. c #605D68", -"S3. c #686670", -"T3. c #555860", -"U3. c #716E79", -"V3. c #9B939D", -"W3. c #565755", -"X3. c #625C65", -"Y3. c #938A9A", -"Z3. c #766E7D", -"`3. c #817389", -" 4. c #908A95", -".4. c #676674", -"+4. c #8C8594", -"@4. c #786A7B", -"#4. c #8A7E8B", -"$4. c #A8A8AA", -"%4. c #5A5B65", -"&4. c #303241", -"*4. c #504E6B", -"=4. c #60607F", -"-4. c #54527D", -";4. c #515476", -">4. c #353750", -",4. c #3B3B55", -"'4. c #50506D", -")4. c #474863", -"!4. c #414057", -"~4. c #514F6B", -"{4. c #4F4F67", -"]4. c #4C4D5D", -"^4. c #6D6A85", -"/4. c #67687F", -"(4. c #4A4866", -"_4. c #706D8E", -":4. c #6D6D78", -"<4. c #5D5C7B", -"[4. c #706D88", -"}4. c #86819C", -"|4. c #7D7BA5", -"14. c #747092", -"24. c #6A6A85", -"34. c #4A4762", -"44. c #474561", -"54. c #454360", -"64. c #595976", -"74. c #595978", -"84. c #555173", -"94. c #555576", -"04. c #726C8E", -"a4. c #87809B", -"b4. c #87859D", -"c4. c #726F94", -"d4. c #716D91", -"e4. c #595879", -"f4. c #6F6C87", -"g4. c #8D869F", -"h4. c #928AA7", -"i4. c #978DA5", -"j4. c #9C96A3", -"k4. c #A39DA7", -"l4. c #A49BA6", -"m4. c #9A90A3", -"n4. c #A699A6", -"o4. c #9F8EA4", -"p4. c #9A8FA4", -"q4. c #A496A4", -"r4. c #A298A4", -"s4. c #A193A3", -"t4. c #A097A3", -"u4. c #9B93A3", -"v4. c #888499", -"w4. c #77738E", -"x4. c #535175", -"y4. c #4A495F", -"z4. c #454558", -"A4. c #615B7B", -"B4. c #8F84A1", -"C4. c #9484A0", -"D4. c #8A81A0", -"E4. c #8F85A0", -"F4. c #978AA0", -"G4. c #978A9F", -"H4. c #88819A", -"I4. c #9F9FA0", -"J4. c #929292", -"K4. c #747370", -"L4. c #6F6F6E", -"M4. c #8C8C89", -"N4. c #706F6E", -"O4. c #757471", -"P4. c #312F2E", -"Q4. c #0C090B", -"R4. c #8393C5", -"S4. c #727FC5", -"T4. c #6D73C2", -"U4. c #6768BA", -"V4. c #837BB8", -"W4. c #7770AA", -"X4. c #7168A6", -"Y4. c #7A73AE", -"Z4. c #726CA3", -"`4. c #696399", -" 5. c #756B9F", -".5. c #716493", -"+5. c #6C648F", -"@5. c #67608C", -"#5. c #675F8E", -"$5. c #6A6182", -"%5. c #6F658F", -"&5. c #7A739E", -"*5. c #676382", -"=5. c #605A85", -"-5. c #665F8E", -";5. c #5E5B79", -">5. c #79739C", -",5. c #ABA1BF", -"'5. c #7E7BAD", -")5. c #79789A", -"!5. c #625D7E", -"~5. c #8C84AA", -"{5. c #9088A7", -"]5. c #AEA4BE", -"^5. c #9D98B8", -"/5. c #857EA3", -"(5. c #625D7D", -"_5. c #70698B", -":5. c #757095", -"<5. c #8980A1", -"[5. c #9991B6", -"}5. c #988DB8", -"|5. c #8B85AC", -"15. c #9D90B0", -"25. c #A79BB5", -"35. c #8D86AA", -"45. c #7F7996", -"55. c #8E87AB", -"65. c #6C6890", -"75. c #605E7C", -"85. c #5F5D86", -"95. c #62608B", -"05. c #5A5872", -"a5. c #605C77", -"b5. c #87839A", -"c5. c #938FAF", -"d5. c #B2A6B5", -"e5. c #B4ADB4", -"f5. c #818090", -"g5. c #AFA8B3", -"h5. c #B1B1B1", -"i5. c #B2A8B2", -"j5. c #B2B2A4", -"k5. c #B2ABB2", -"l5. c #B1AAAD", -"m5. c #B2A3B2", -"n5. c #393F4A", -"o5. c #404255", -"p5. c #393E53", -"q5. c #2D3441", -"r5. c #2B3340", -"s5. c #2C3341", -"t5. c #31374C", -"u5. c #373B50", -"v5. c #323943", -"w5. c #50505B", -"x5. c #6F6F79", -"y5. c #837E8C", -"z5. c #A7A0A8", -"A5. c #777483", -"B5. c #93909C", -"C5. c #A6A0A9", -"D5. c #AFA6AF", -"E5. c #85819D", -"F5. c #75738E", -"G5. c #74758C", -"H5. c #4D5059", -"I5. c #7B7A82", -"J5. c #6D6D79", -"K5. c #686778", -"L5. c #747388", -"M5. c #848488", -"N5. c #7C798B", -"O5. c #79778A", -"P5. c #5B5864", -"Q5. c #716D77", -"R5. c #988D99", -"S5. c #928D95", -"T5. c #89878B", -"U5. c #7E7B8B", -"V5. c #625E6A", -"W5. c #6A6378", -"X5. c #74697A", -"Y5. c #726C7A", -"Z5. c #8A878C", -"`5. c #434549", -" 6. c #524D67", -".6. c #464659", -"+6. c #424455", -"@6. c #464655", -"#6. c #333544", -"$6. c #313144", -"%6. c #313345", -"&6. c #32324C", -"*6. c #404163", -"=6. c #40405D", -"-6. c #2F314A", -";6. c #37374E", -">6. c #3B3B54", -",6. c #514F68", -"'6. c #686286", -")6. c #605E79", -"!6. c #8F8A9F", -"~6. c #827F94", -"{6. c #807CA0", -"]6. c #8886A0", -"^6. c #706D93", -"/6. c #747293", -"(6. c #9088A4", -"_6. c #57566C", -":6. c #20243A", -"<6. c #1D1F38", -"[6. c #23243B", -"}6. c #46445B", -"|6. c #575271", -"16. c #4F4F6A", -"26. c #5A556D", -"36. c #857D9B", -"46. c #978CA3", -"56. c #6C6689", -"66. c #6A6687", -"76. c #79778E", -"86. c #636076", -"96. c #5B5972", -"06. c #7B7784", -"a6. c #81788C", -"b6. c #7B768D", -"c6. c #56545E", -"d6. c #848390", -"e6. c #474751", -"f6. c #746F81", -"g6. c #968B9E", -"h6. c #9D8E9F", -"i6. c #948A9E", -"j6. c #9F929F", -"k6. c #968D9D", -"l6. c #79748D", -"m6. c #9A929F", -"n6. c #878288", -"o6. c #6A667F", -"p6. c #655F84", -"q6. c #68648B", -"r6. c #636278", -"s6. c #4A4760", -"t6. c #787198", -"u6. c #7E7893", -"v6. c #8C809B", -"w6. c #98849B", -"x6. c #9B899B", -"y6. c #91809B", -"z6. c #837D9B", -"A6. c #8A8A8A", -"B6. c #272726", -"C6. c #30302F", -"D6. c #2E2E2B", -"E6. c #1F1E1E", -"F6. c #050506", -"G6. c #2B324B", -"H6. c #707EBA", -"I6. c #6771B7", -"J6. c #6265B1", -"K6. c #6A68A7", -"L6. c #706AA3", -"M6. c #68619C", -"N6. c #6E659F", -"O6. c #706BA0", -"P6. c #635B90", -"Q6. c #615A8C", -"R6. c #615B8A", -"S6. c #635A89", -"T6. c #696093", -"U6. c #605B84", -"V6. c #5F597E", -"W6. c #635B85", -"X6. c #5F587D", -"Y6. c #635B84", -"Z6. c #6B6993", -"`6. c #5D567D", -" 7. c #5A5577", -".7. c #5C577F", -"+7. c #5E597E", -"@7. c #7A7591", -"#7. c #A89EB7", -"$7. c #A4A3B5", -"%7. c #7D77A2", -"&7. c #5B587E", -"*7. c #5B557C", -"=7. c #817C95", -"-7. c #928BA2", -";7. c #B4A6B4", -">7. c #7E7C8F", -",7. c #504E70", -"'7. c #5E5B7E", -")7. c #53506E", -"!7. c #9A8FAE", -"~7. c #9A8EAF", -"{7. c #9C8FAE", -"]7. c #A69AAF", -"^7. c #A297AB", -"/7. c #5E5C78", -"(7. c #736C89", -"_7. c #6D6B8B", -":7. c #6B678A", -"<7. c #4E4D65", -"[7. c #565570", -"}7. c #3D3E4E", -"|7. c #555269", -"17. c #7B778E", -"27. c #9B92AC", -"37. c #6C6D80", -"47. c #746F80", -"57. c #9F98AA", -"67. c #9E99A8", -"77. c #8780A0", -"87. c #86809F", -"97. c #99939F", -"07. c #A9A3A9", -"a7. c #9D99A1", -"b7. c #605B7A", -"c7. c #8C8C9D", -"d7. c #4A4C61", -"e7. c #2E3644", -"f7. c #2D303F", -"g7. c #2C313E", -"h7. c #2B3142", -"i7. c #323646", -"j7. c #3A3D4C", -"k7. c #5A5A67", -"l7. c #85828E", -"m7. c #58566B", -"n7. c #97929D", -"o7. c #888488", -"p7. c #838088", -"q7. c #8C8792", -"r7. c #949197", -"s7. c #A5A5A5", -"t7. c #8E8AA1", -"u7. c #69667E", -"v7. c #A398A7", -"w7. c #97919E", -"x7. c #726F85", -"y7. c #8D889F", -"z7. c #827B90", -"A7. c #86828F", -"B7. c #837F87", -"C7. c #777583", -"D7. c #696572", -"E7. c #87828E", -"F7. c #908E90", -"G7. c #5F5F61", -"H7. c #908793", -"I7. c #7E7C83", -"J7. c #6D6B6E", -"K7. c #747174", -"L7. c #9A9497", -"M7. c #948E98", -"N7. c #666071", -"O7. c #686175", -"P7. c #79758D", -"Q7. c #5A5B68", -"R7. c #4E4F64", -"S7. c #646175", -"T7. c #777680", -"U7. c #797284", -"V7. c #9B939E", -"W7. c #5A5B6E", -"X7. c #282A39", -"Y7. c #272840", -"Z7. c #262640", -"`7. c #262A44", -" 8. c #2C2E41", -".8. c #383950", -"+8. c #40405A", -"@8. c #666679", -"#8. c #56596E", -"$8. c #595774", -"%8. c #46455D", -"&8. c #474860", -"*8. c #33364A", -"=8. c #514F67", -"-8. c #868291", -";8. c #8B869D", -">8. c #898597", -",8. c #787490", -"'8. c #847C9B", -")8. c #716F87", -"!8. c #2A2A3C", -"~8. c #2A2D43", -"{8. c #555571", -"]8. c #1E202F", -"^8. c #282940", -"/8. c #3F4056", -"(8. c #48465F", -"_8. c #6D6888", -":8. c #847E98", -"<8. c #5A5674", -"[8. c #5A586F", -"}8. c #6A6679", -"|8. c #86808E", -"18. c #3D3F49", -"28. c #303040", -"38. c #454256", -"48. c #787481", -"58. c #504D5F", -"68. c #625E7D", -"78. c #5B5A6E", -"88. c #414150", -"98. c #918996", -"08. c #8F8496", -"a8. c #968696", -"b8. c #908596", -"c8. c #68657A", -"d8. c #515164", -"e8. c #393949", -"f8. c #585373", -"g8. c #746E88", -"h8. c #726B85", -"i8. c #76718A", -"j8. c #5C5A79", -"k8. c #6C668A", -"l8. c #77718B", -"m8. c #877D94", -"n8. c #8E7F93", -"o8. c #907E93", -"p8. c #6E6886", -"q8. c #949494", -"r8. c #828282", -"s8. c #7082AF", -"t8. c #656DAF", -"u8. c #5D61A7", -"v8. c #5B5B9F", -"w8. c #6A639A", -"x8. c #655C99", -"y8. c #605993", -"z8. c #625D93", -"A8. c #595189", -"B8. c #585184", -"C8. c #5B5485", -"D8. c #5E5682", -"E8. c #5D5684", -"F8. c #5E5985", -"G8. c #5D547E", -"H8. c #585378", -"I8. c #5C5478", -"J8. c #5C577C", -"K8. c #746F9A", -"L8. c #6B688F", -"M8. c #56507A", -"N8. c #544F6F", -"O8. c #514E6C", -"P8. c #585271", -"Q8. c #6E6894", -"R8. c #918AA2", -"S8. c #8C8A96", -"T8. c #656386", -"U8. c #5E5782", -"V8. c #524F75", -"W8. c #5B5579", -"X8. c #6F6D88", -"Y8. c #827D8C", -"Z8. c #8E8C96", -"`8. c #6A677C", -" 9. c #48475E", -".9. c #4F4C6E", -"+9. c #7E7797", -"@9. c #867EA0", -"#9. c #827E9F", -"$9. c #A292A6", -"%9. c #918D99", -"&9. c #65617D", -"*9. c #5A5878", -"=9. c #535170", -"-9. c #47475C", -";9. c #47495E", -">9. c #333947", -",9. c #373A47", -"'9. c #4C4A5E", -")9. c #69647D", -"!9. c #848197", -"~9. c #847F8B", -"{9. c #9897A2", -"]9. c #7D7791", -"^9. c #87819A", -"/9. c #A398A3", -"(9. c #9996A3", -"_9. c #83819E", -":9. c #736E95", -"<9. c #857FA1", -"[9. c #9C91A1", -"}9. c #998EA2", -"|9. c #998EA1", -"19. c #9E9DA1", -"29. c #66677A", -"39. c #4D4D5F", -"49. c #3E4153", -"59. c #2F3546", -"69. c #29313A", -"79. c #2A3140", -"89. c #383B4B", -"99. c #4B4A5F", -"09. c #444459", -"a9. c #343A45", -"b9. c #474752", -"c9. c #908B8F", -"d9. c #948D97", -"e9. c #857F81", -"f9. c #9E999E", -"g9. c #998F9E", -"h9. c #9B939F", -"i9. c #878492", -"j9. c #898392", -"k9. c #88829A", -"l9. c #656279", -"m9. c #68657C", -"n9. c #89809A", -"o9. c #686576", -"p9. c #4E4B56", -"q9. c #52525C", -"r9. c #4E4E59", -"s9. c #484849", -"t9. c #474646", -"u9. c #58555E", -"v9. c #878091", -"w9. c #666271", -"x9. c #6A6176", -"y9. c #7C7680", -"z9. c #6A6876", -"A9. c #6E6876", -"B9. c #696677", -"C9. c #625C74", -"D9. c #757585", -"E9. c #8D8899", -"F9. c #737183", -"G9. c #8B8892", -"H9. c #969499", -"I9. c #9A9692", -"J9. c #999395", -"K9. c #8A888A", -"L9. c #58556C", -"M9. c #49485F", -"N9. c #20213A", -"O9. c #1B1E35", -"P9. c #45455E", -"Q9. c #474460", -"R9. c #504C6C", -"S9. c #676478", -"T9. c #4C4B62", -"U9. c #575767", -"V9. c #413E55", -"W9. c #35364D", -"X9. c #292A3E", -"Y9. c #39384A", -"Z9. c #656178", -"`9. c #605C79", -" 0. c #908195", -".0. c #8D8696", -"+0. c #73708A", -"@0. c #53526A", -"#0. c #48476B", -"$0. c #2F2F43", -"%0. c #4F4B6A", -"&0. c #383851", -"*0. c #514C6E", -"=0. c #5E5A77", -"-0. c #767188", -";0. c #68637E", -">0. c #514C65", -",0. c #6B6880", -"'0. c #68667E", -")0. c #6B6786", -"!0. c #7C7987", -"~0. c #737277", -"{0. c #62606A", -"]0. c #706D84", -"^0. c #817F88", -"/0. c #5F5D68", -"(0. c #7F7B85", -"_0. c #757481", -":0. c #585765", -"<0. c #484856", -"[0. c #575367", -"}0. c #646170", -"|0. c #645F74", -"10. c #887D8E", -"20. c #686679", -"30. c #5F5B79", -"40. c #6C6782", -"50. c #7D738D", -"60. c #716A82", -"70. c #7F798D", -"80. c #7E748D", -"90. c #7D738C", -"00. c #7F738B", -"a0. c #7C748A", -"b0. c #867D8B", -"c0. c #7C768B", -"d0. c #726B87", -"e0. c #6E6B88", -"f0. c #797979", -"g0. c #9AACB4", -"h0. c #303953", -"i0. c #5F6CA5", -"j0. c #5D63A1", -"k0. c #55569B", -"l0. c #5A578D", -"m0. c #5D588D", -"n0. c #565188", -"o0. c #58548A", -"p0. c #575084", -"q0. c #524B7D", -"r0. c #504A79", -"s0. c #564E7A", -"t0. c #574E7B", -"u0. c #575181", -"v0. c #514B73", -"w0. c #514B6F", -"x0. c #524B75", -"y0. c #58567D", -"z0. c #6E668C", -"A0. c #7C7597", -"B0. c #746F88", -"C0. c #5E597B", -"D0. c #535072", -"E0. c #4C4969", -"F0. c #524C77", -"G0. c #4B4970", -"H0. c #625F82", -"I0. c #605E82", -"J0. c #504C77", -"K0. c #484561", -"L0. c #515077", -"M0. c #565577", -"N0. c #49495E", -"O0. c #5D596F", -"P0. c #555471", -"Q0. c #41415C", -"R0. c #3D3D58", -"S0. c #3A3B58", -"T0. c #48455F", -"U0. c #575376", -"V0. c #807A98", -"W0. c #807B98", -"X0. c #797492", -"Y0. c #656180", -"Z0. c #646180", -"`0. c #53526D", -" a. c #5C5875", -".a. c #424359", -"+a. c #333848", -"@a. c #424257", -"#a. c #3A3C4D", -"$a. c #45445B", -"%a. c #48475D", -"&a. c #4B4A5C", -"*a. c #908893", -"=a. c #8A8A8F", -"-a. c #847D92", -";a. c #807C94", -">a. c #635F7E", -",a. c #77728F", -"'a. c #968A9B", -")a. c #7F7C94", -"!a. c #6D688B", -"~a. c #7C7689", -"{a. c #817C8F", -"]a. c #978999", -"^a. c #988999", -"/a. c #767681", -"(a. c #292F35", -"_a. c #282E37", -":a. c #252A35", -"b. c #6A6577", -",b. c #49475A", -"'b. c #252638", -")b. c #313141", -"!b. c #1D202C", -"~b. c #151929", -"{b. c #202233", -"]b. c #2C2D3F", -"^b. c #303145", -"/b. c #252A36", -"(b. c #363543", -"_b. c #393749", -":b. c #454260", -"c. c #858091", -",c. c #6C6680", -"'c. c #4D4D63", -")c. c #222A2F", -"!c. c #202732", -"~c. c #222635", -"{c. c #222733", -"]c. c #2B2E39", -"^c. c #363748", -"/c. c #3B3D4F", -"(c. c #4C4C59", -"_c. c #373D42", -":c. c #353943", -"d. c #2B2B41", -",d. c #202337", -"'d. c #242539", -")d. c #2E2E42", -"!d. c #3B3952", -"~d. c #5A566D", -"{d. c #676275", -"]d. c #6D637A", -"^d. c #76697D", -"/d. c #74687A", -"(d. c #756A7C", -"_d. c #79697C", -":d. c #796D7C", -"e. c #3F3F50", -",e. c #30333C", -"'e. c #40404E", -")e. c #6F6C73", -"!e. c #756F78", -"~e. c #807981", -"{e. c #827B85", -"]e. c #868686", -"^e. c #7A7584", -"/e. c #615D75", -"(e. c #656077", -"_e. c #5F5B75", -":e. c #575570", -"f. c #706473", -",f. c #716373", -"'f. c #716272", -")f. c #6A6072", -"!f. c #545161", -"~f. c #5E5A69", -"{f. c #717171", -"]f. c #606060", -"^f. c #5D6787", -"/f. c #4B5082", -"(f. c #47497F", -"_f. c #454278", -":f. c #443F76", -"g. c #706B78", -",g. c #51505E", -"'g. c #625D6E", -")g. c #4C4B5F", -"!g. c #44434F", -"~g. c #7C747C", -"{g. c #726F73", -"]g. c #625E6E", -"^g. c #666464", -"/g. c #726C6F", -"(g. c #756C77", -"_g. c #6E6A72", -":g. c #6E6C74", -"h. c #3D3961", -",h. c #3C3861", -"'h. c #3D3861", -")h. c #3C385E", -"!h. c #3C385B", -"~h. c #3C3859", -"{h. c #3C3857", -"]h. c #3B3857", -"^h. c #393857", -"/h. c #433E60", -"(h. c #4C476A", -"_h. c #55516B", -":h. c #685E79", -"i. c #6C6670", -",i. c #524D5D", -"'i. c #635D67", -")i. c #6E6D6F", -"!i. c #67646C", -"~i. c #343540", -"{i. c #3D3D4B", -"]i. c #1F212A", -"^i. c #292B38", -"/i. c #30303A", -"(i. c #3E3D45", -"_i. c #313240", -":i. c #1C1E30", -"j. c #514C69", -",j. c #3E3B59", -"'j. c #32314D", -")j. c #32304C", -"!j. c #32304E", -"~j. c #37355A", -"{j. c #2E2E49", -"]j. c #3E395B", -"^j. c #343251", -"/j. c #353351", -"(j. c #353250", -"_j. c #414256", -":j. c #545066", -"k. c #1F2030", -",k. c #2D2D3E", -"'k. c #2B2B3D", -")k. c #3B3855", -"!k. c #575264", -"~k. c #434056", -"{k. c #323243", -"]k. c #343348", -"^k. c #2E2E3E", -"/k. c #434158", -"(k. c #5E5A65", -"_k. c #5F5C63", -":k. c #565565", -"l. c #353453", -",l. c #302F4C", -"'l. c #3F3E58", -")l. c #62616F", -"!l. c #6F6F6F", -"~l. c #6A706D", -"{l. c #5E6171", -"]l. c #404156", -"^l. c #5A5770", -"/l. c #53546A", -"(l. c #5C5C6E", -"_l. c #4E4D6B", -":l. c #4A4968", -"m. c #4F5058", -",m. c #535358", -"'m. c #454456", -")m. c #424247", -"!m. c #262730", -"~m. c #1D1D29", -"{m. c #39394A", -"]m. c #323143", -"^m. c #252436", -"/m. c #1D1D2D", -"(m. c #141425", -"_m. c #0B0C1B", -":m. c #161626", -"n. c #363744", -",n. c #2E2E3F", -"'n. c #333345", -")n. c #323140", -"!n. c #393946", -"~n. c #3C3B4C", -"{n. c #2D2D36", -"]n. c #4B4952", -"^n. c #4B4859", -"/n. c #373946", -"(n. c #1B1F24", -"_n. c #21242B", -":n. c #212529", -"o. c #060717", -",o. c #050715", -"'o. c #0B0B19", -")o. c #070914", -"!o. c #060817", -"~o. c #060816", -"{o. c #0C0D1A", -"]o. c #0A0C19", -"^o. c #080A17", -"/o. c #050814", -"(o. c #0E101C", -"_o. c #171823", -":o. c #1D1D2A", -"p. c #484854", -",p. c #1E2125", -"'p. c #20222A", -")p. c #3D3B48", -"!p. c #4B4B50", -"~p. c #3F3D4C", -"{p. c #353546", -"]p. c #37354B", -"^p. c #2F2F41", -"/p. c #24262F", -"(p. c #31303D", -"_p. c #413E4E", -":p. c #504C53", -"q. c #191925", -",q. c #1B1B27", -"'q. c #23212F", -")q. c #3D3D3D", -"!q. c #424962", -"~q. c #3A3D61", -"{q. c #33325F", -"]q. c #322E57", -"^q. c #2F2C55", -"/q. c #2F2B52", -"(q. c #2E2950", -"_q. c #2D294C", -":q. c #2B284A", -"r. c #37363C", -",r. c #454449", -"'r. c #4D4A4D", -")r. c #49434D", -"!r. c #32313A", -"~r. c #424044", -"{r. c #4F4A4F", -"]r. c #514F51", -"^r. c #4C484E", -"/r. c #43404D", -"(r. c #48454C", -"_r. c #393941", -":r. c #444148", -"s. c #28253F", -",s. c #252338", -"'s. c #29273E", -")s. c #27253D", -"!s. c #403E55", -"~s. c #2A2943", -"{s. c #2B2743", -"]s. c #2C2941", -"^s. c #413D4C", -"/s. c #4E4C53", -"(s. c #3D3C47", -"_s. c #29273A", -":s. c #1B1C2B", -"t. c #38373C", -",t. c #403E40", -"'t. c #353338", -")t. c #36343B", -"!t. c #413E42", -"~t. c #3A3A3C", -"{t. c #37363B", -"]t. c #26262C", -"^t. c #12121A", -"/t. c #1D1C28", -"(t. c #292735", -"_t. c #35323D", -":t. c #37333D", -"u. c #383542", -",u. c #403D42", -"'u. c #403F43", -")u. c #383642", -"!u. c #3E3B46", -"~u. c #424045", -"{u. c #2F2E30", -"]u. c #48444B", -"^u. c #49484B", -"/u. c #4D484A", -"(u. c #49464B", -"_u. c #444248", -":u. c #3F3E46", -"v. c #272544", -",v. c #2A2548", -"'v. c #272443", -")v. c #262340", -"!v. c #24213D", -"~v. c #292740", -"{v. c #423E4D", -"]v. c #464251", -"^v. c #434250", -"/v. c #282541", -"(v. c #23223A", -"_v. c #222036", -":v. c #25233D", -"w. c #2C2A31", -",w. c #2B2A32", -"'w. c #15161F", -")w. c #1A1A24", -"!w. c #232228", -"~w. c #14131D", -"{w. c #08080D", -"]w. c #08080E", -"^w. c #17161A", -"/w. c #2C2A2E", -"(w. c #222029", -"_w. c #0F0F14", -":w. c #262529", -"x. c #36333B", -",x. c #26272C", -"'x. c #2A2931", -")x. c #2B2936", -"!x. c #24242F", -"~x. c #35313C", -"{x. c #1A1A21", -"]x. c #28272C", -"^x. c #35333A", -"/x. c #25242A", -"(x. c #26262D", -"_x. c #141514", -":x. c #202021", -"y. c #18172A", -",y. c #111222", -"'y. c #171628", -")y. c #121223", -"!y. c #121221", -"~y. c #141422", -"{y. c #131323", -"]y. c #171627", -"^y. c #10111F", -"/y. c #1D1B2E", -"(y. c #181824", -"_y. c #222032", -":y. c #1E1E31", -"z. c #16141D", -",z. c #0B0B12", -"'z. c #050509", -")z. c #030306", -"!z. c #000102", -"~z. c #252842", -"{z. c #20203F", -"]z. c #201E3B", -"^z. c #1E1D39", -"/z. c #201D36", -"(z. c #1E1C37", -"_z. c #29263B", -":z. c #373342", -"A. c #15141B", -",A. c #131317", -"'A. c #111014", -")A. c #1F1D21", -"!A. c #1E1D20", -"~A. c #0E0E16", -"{A. c #0F0E18", -"]A. c #0E0D18", -"^A. c #0B0A11", -"/A. c #040507", -"(A. c #050508", -"_A. c #030407", -":A. c #06050A", -"B. c #1D1B1E", -",B. c #221F22", -"'B. c #1B191F", -")B. c #0F0E16", -"!B. c #09090C", -"~B. c #08080A", -"{B. c #131217", -"]B. c #1A181C", -"^B. c #1B1A1C", -"/B. c #131219", -"(B. c #0D0D14", -"_B. c #111015", -":B. c #090810", -"C. c #060607", -",C. c #0A090B", -"'C. c #0D0B0D", -")C. c #0A090C", -"!C. c #0A090D", -"~C. c #07060B", -"{C. c #191B30", -"]C. c #14152D", -"^C. c #16152C", -"/C. c #15132A", -"(C. c #16142A", -"_C. c #292631", -":C. c #2E2D32", -"D. c #11101C", -",D. c #06060F", -"'D. c #0C0B14", -")D. c #0E0D19", -"!D. c #13121C", -"~D. c #0E0D17", -"{D. c #030408", -"]D. c #030405", -"^D. c #0E0D13", -"/D. c #0A0A11", -"(D. c #09090E", -"_D. c #0F0E13", -":D. c #06060A", -"E. c #4B4B4B", -",E. c #DEDEDE", -"'E. c #FBFBFB", -")E. c #AEAEAF", -"!E. c #525153", -"~E. c #676668", -"{E. c #3F3D40", -"]E. c #060024", -"^E. c #1D1D1C", -"/E. c #001D23", -"(E. c #090000", -"_E. c #DDDDDD", -":E. c #FDFDFD", -"F. c #062B86", -",F. c #BFCFC1", -"'F. c #BDBFC4", -")F. c #D0AD68", -"!F. c #CCBFB7", -"~F. c #C7CFCA", -"{F. c #C19762", -"]F. c #190040", -"^F. c #060D79", -"/F. c #BDDDD6", -"(F. c #B56B12", -"_F. c #0668A6", -":F. c #7F1D0E", -"G. c #838283", -",G. c #B7B7B8", -"'G. c #6C6C6D", -")G. c #1366AE", -"!G. c #DCDEBD", -"~G. c #060529", -"{G. c #1D1717", -"]G. c #1779B6", -"^G. c #EAEAD0", -"/G. c #945542", -"(G. c #4FA6CF", -"_G. c #60A8D1", -":G. c #469BC7", -"H. c #84BBCA", -",H. c #C9A56C", -"'H. c #2F000D", -")H. c #3D85B3", -"!H. c #D1DDD7", -"~H. c #D9CB9F", -"{H. c #672300", -"]H. c #29659D", -"^H. c #B38949", -"/H. c #001761", -"(H. c #9FC9CF", -"_H. c #DFDFCB", -":H. c #BF8947", -"I. c #064588", -",I. c #B1B9BF", -"'I. c #D2DDD9", -")I. c #DACBBB", -"!I. c #B7A171", -"~I. c #250040", -"{I. c #3C5764", -"]I. c #4C2D0F", -"^I. c #C3DDD0", -"/I. c #A7590E", -"(I. c #57A7CD", -"_I. c #DDC17D", -":I. c #1D0000", -"J. c #89430F", -",J. c #894310", -"'J. c #CB9543", -")J. c #013D7F", -"!J. c #2A2A2A", -"~J. c #717172", -"{J. c #B8B8B8", -"]J. c #CACACB", -"^J. c #380000", -"/J. c #003B6F", -"(J. c #AFCBBF", -"_J. c #AF958D", -":J. c #959397", -"K. c #002C7F", -",K. c #727272", -"'K. c #005393", -")K. c #CBD7B3", -"!K. c #3B89AF", -"~K. c #BDA369", -"{K. c #1F0035", -"]K. c #010100", -"^K. c #002373", -"/K. c #B3D5CB", -"(K. c #AD6F1F", -"_K. c #D3A369", -":K. c #7BB19D", -"L. c #CBBDAF", -",L. c #B3AFA1", -"'L. c #A18F5B", -")L. c #170000", -"!L. c #838383", -"~L. c #B0B0B0", -"{L. c #808080", -"]L. c #777777", -"^L. c #5391B5", -"/L. c #CFD1BD", -"(L. c #000153", -"_L. c #002B57", -":L. c #7B8163", -"M. c #D0D0D0", -",M. c #5395B5", -"'M. c #CBBF8F", -")M. c #571700", -"!M. c #A4A4A4", -"~M. c #979797", -"{M. c #3F204D", -"]M. c #89B5B3", -"^M. c #BBBDBD", -"/M. c #D1C79B", -"(M. c #5F2B00", -"_M. c #004387", -":M. c #B7BF99", -" $ + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + , + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + , + + + + + + + + + + + ' + + + + + + + + + + + + ) + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = - ! ~ { ' > + + + + # + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , , @ + + + + + + + + ] ^ + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + , + + + + + + + + + + + ' + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + ) > + + # + + + + + + + + + + ] + + + + + + + + + + + + $ ^ + + + + + , + + + + + + + + + , , + + + + + + + + + + + + + + + + = ( _ _ ! : , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + @ + + + @ + + + + ) + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + + + + + + # + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + & + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + [ } ! ~ | ' $ @ + + + + + + + + + + + + + + + + + + + + + + + # # + + + + + + + + + + + + + + + + + + + + : 1 2 + + + + + + + + + + + = + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + . ", -" . + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + ) + + + + + + + + + + + + + + + + + + + + + + = + + # + + + + + + + + + + + + + + + + / + + + + + $ [ - ^ 4 $ # + + + , + + + + + + + + + + + + ) + + + + + + + / / @ @ + + + + + + , + + + + + + , + + + + 5 | : + + + + + + + + + + + + + + + + + + + + + + ; 6 > + + + + + + + + + = | + + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + , + + + ) + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + $ = = ) + + # + + + + + + + + + + + + + + + + + + + + + + + < / + + + + + + + + ] + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + ! 7 > + + + + + + + , = + + + + + + $ $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + , $ + + + + + + + + + | + + + + + : 8 $ + + + + + + + + + + + + + + 3 9 + + + + + + + + + + ) + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + , + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + $ ) , , + + + + + + + + + + + + 9 , + + + + + + + + + ) + + + + + + + + + + + + # # + + + + + + + + + + + + + + + + + + + + + + + + + + + % + + + + + + ( 0 + + + + + + + + + + + + + / + + + + + + + $ + + + + + + + + + + + + + + + + + + , $ + + + + + + + + + | + + + + + : 8 $ + + + + + + + + + + + + + + 3 9 + + + + + + + + + + ) + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + ) + : , + + + + = a ' + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + , + + + + @ + + + + + + + + + + + + + + + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # # + + b { = + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + & + + + + @ + + + & + + + + + + , , + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + : , + + + + = a ' + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + . ", -" . + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + # + @ + < $ + + + + + + + + + + + + = + ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + + + + + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + # + + + + + + + + + + + + + + + @ + + + + + + + + $ + + , + + + + + + c + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + # + @ + < $ + + + + + + + + + + + + = + ] + + + + + + + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + & + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + ] + + + + + + + + + + + + + + + + + + # + + + 2 + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + @ + @ + + + + + + + + + + + + + + + + & + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + @ + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + + + + + + + + + + + + + + + + + + # + + + 2 + + + + + + + + + + + + + + + + + , + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + , , + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + d : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # { d + + + + + + + + + + + + + + + + + + + + + + + + + + # ) + e ) + + + + + + + + + + + + + + + + + + + + : % + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , , + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + d : + + + + + + + + + . ", -" . + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + > $ ) + + + + $ ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) = $ + + + + + + + + b + + + + + + + + ] + , # + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # ] + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + , f + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ' : + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + # + + + + + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < / + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , f + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + , + + + + + + + + + + + + . ", -" . $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + & + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + @ + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + $ , + + + + + + + + + + + + + + @ < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + , ' + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + < / + + + @ + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + & + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + @ + + + + . ", -" . + + + + + + + + + + + + + + + + + + # + + + + , + + + + + + + + + + + + + , + + + + + + + + + + + $ $ + + + + + + + + , # + + + + + + + + + + + + + + + + + + # = $ + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + < + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + , + + + + + + + + + + + + + , + + + + + + + + + + + $ $ + + + + + + + + , # + + + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + % $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + @ # + + + + + + + + + + + + + + + + $ + + ) + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + g + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + % $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + @ # + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = : + + + + + + + + + + + , + g + + + + + + + + + + c + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + h + + + + + . ", -" . + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + , + + + + + + + + + + + # + + + + + | i | 5 + + + + + + + + + ' g + + ' + + + + + + # + + + + + + + + + + + + + + + + + + + + + + , + + + + + @ + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + $ + + : + + + + + + + + + + ) ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + , + + + + + + + + + + + # + + + + + | i | 5 + + . ", -" . + + + + / + + + + + + < + + $ b = + + + + + + + + + $ + + + + + + + + + + + < : $ + + + + + + + + + + + + + + + + + + + + + + + + + : } - + + + + + + + + + + + + + + + + + + + + j + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + # - + + + + + + + + + + + + + + + + + + + b % + + + + + + , $ , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + / + + + + + + < + + $ b = + + + + + + + + + $ + + + + + + + + + + + < : $ + + + + + + + + + + + + + + + + + + + + + + + + + : } - + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + ~ { + + + + + + + + + + + + + + ) + + + + + + + ^ ^ + + $ $ + + + + + + + + $ + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , k + + + + + + + @ + + + + + + + + + + + $ + + + + + + + + + + + + + + + + b h + + + + + , = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + ^ + < , + + + + + + + + + + + + + > + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + ~ { + + + + + + + + + + + + + + ) + + + + + + + ^ ^ + + $ $ + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > > + + + + + , + + + + + + + + < + + , + + + + , + + + + : + + + + + + + # > + + + + @ + + + + + + + j + + + + + + + + + + + + + + + + + + + + + + + + + + # # + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + , + + l + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > > + + + + + , + + + + + + + + < + + , + + + + , + + + + : + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + @ + + + + , + + + + + + + + + + + + + + + + + $ + m m + m m m m m m m m m m n m + + + + + , o + + + + + + + + + + + + + + + # < + + + + + + + + + + + b + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + # + + + g @ + + + + + + + ] + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + , + + < + + + + + + + + + @ + + + + + # + + + + + + + + + + + c + + + + + + + + + + + + + + + , + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + , + + + + + + + + + + + + + + + + + $ + + + + + + , + + + + + + + + + + + + + + , o + + . ", -" . + = + + + + + + + + + + + + + + + + + + + + + @ ) + + < + + + + + + + + + ) + < + + + p p + q r s t u v w x y z A B C D E F G H I + + + + + # J + + + 2 + + + + + + + + + ] # + + : + + + + + + + ) + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + b + + + + + + + + + + + + + @ + + + + + + + + + , ) + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + @ + + + + + + + + + + + + + + @ + + + + + # + + + + < % + + + + + & + + + + + > + + + + + + + + + + + + + + + + , + + + + + = + + + + + + + + + + + + + + + + + + + + + @ ) + + < + + + + + + + + + ) + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # . ", -" . + + + + + + + + + + + $ + + + + + + + + + K c + + + + + + + + + + # + + + , / 3 + + m L M N O P Q R R R S T U V W Q X Y Z ` . .. +. @. #. J J J J J J J J + + + + + + + @ + + = $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + # # + + + + + + @ + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + K c + + + + + + + + + + # + + + , / 3 + + + + + + + + + + + + + + + + @ + + + + < + + + + + + + + ) . ", -" . + + + + + + + + + + + $. 2 + + + + + + + = %. + + 3 + + + + + + + } $ + + + + + m &. *. =. -. ;. >. ,. '. ). !. s ~. {. '. ]. ]. '. ^. /. (. _. :. <. [. }. |. 1. 2. 3. 4. 5. J J J J J J + + + + + + + + + + + + + + + + + , + + + + ) + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + @ + + + # + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + $. 2 + + + + + + + = %. + + 3 + + + + + + + } $ + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + . ", -" . + + + + + + + + + + $ ) 0 + + + + + + + + + + + + + + + + + + + + + + + m + 6. 7. 8. 9. 0. a. a. b. c. d. e. f. g. h. i. j. k. l. m. n. o. p. q. m. r. s. t. u. v. v. w. x. y. z. J J J J J J J + + + + + + + + + + + + + @ + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + * = + + + + + + + + + + + + + + + + + + + + + + + + $ ) 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + < + + + + + + + + + + + + + + + + + + + + + : + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A. B. C. D. E. F. C. 0. G. H. ^. '. I. J. K. L. f. M. N. O. g. P. ]. !. Q. m. R. S. T. U. V. W. V. S U L. X. Y. J J J J J J + + # # + + + + + + + + + + + + + + + Z. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + { + + + + + + + + + + + + + & `. ( + + + + + o 0 $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . ", -" . , $ + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + m m .+ ++ @+ #+ D. E. F. $+ %+ &+ *+ ]. >. /. Q. =+ -+ ;+ l. >+ ,+ '+ )+ >. k. U. !+ j. ~+ {+ o. _. ]+ ~+ V K. U O ^+ /+ J J J J J J J < + , + + + @ K + + + + + + + + + + , + + + + + + + + + @ + + + + + , + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + # g + + + + # + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + (+ (+ + + + _+ :+ <+ 8 + + + @ + + + , $ + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < . ", -" . + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + m m [+ }+ |+ 1+ 2+ 3+ 4+ $+ $+ 5+ ,+ ,+ 6+ ^. l. 7+ 8+ 9+ &+ 0+ 5+ a+ 9+ }+ >+ b+ {. o. N. c+ d+ e+ f+ {+ l. g+ ~+ h+ c+ V i+ j+ 4. J J J J J J + + + + : + / + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + = $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ' * + + + + k+ + + + + + + + = + + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + $ + + + + $ + + + + + + + + + + + + + + + + + + + + + + h + + + . ", -" . + + + + + + + $ - + + + + + + + + + + + + + + + + + + + + + + m l+ m+ n+ 4+ o+ p+ q+ r+ r+ &+ 5+ G. s+ {. t+ ;+ u+ $+ |+ %+ v+ q+ w+ E. a+ x+ s+ s+ 9+ y+ z+ k. A+ k. B+ C+ D+ D+ E+ F+ Q. V G+ H+ I+ J+ J J J J J J | d + + / + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ! : + + + + $ $ + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + K+ L+ M+ N+ O+ P+ Q+ R+ S+ T+ U+ V+ W+ X+ Y+ Z+ `+ @ .@ +@ @@ #@ $@ %@ &@ *@ =@ -@ ;@ >@ ,@ K+ + + + + + + + + + + + + + + + + + + + + + @ + / + + + + + + + %. + + + + + + + + + + + $ + + + < + + + @ + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ $ '@ )@ !@ $+ ~@ {@ ~@ 1+ q+ ]@ 5+ a+ ^@ /@ (@ (@ %+ @+ %+ _@ ~@ r+ {@ :@ %+ <@ <@ C. x+ a. 9+ [@ }@ k. V |@ !. Q. '+ '+ 1@ -. R. 2@ 3@ 4@ [. 5@ J J J J J + + g / < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + 6@ 7@ 8@ 9@ 0@ a@ b@ c@ d@ e@ f@ g@ h@ i@ j@ k@ l@ m@ n@ o@ p@ q@ r@ s@ t@ u@ v@ w@ x@ y@ z@ A@ B@ C@ D@ E@ F@ G@ H@ I@ J@ K@ L@ M@ + + + + + + + + $ $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + K < + + + + + + + . ", -" . + + + + + + + + + + + = + + + + + + + + + + + + + + + + + m N@ }+ O@ P@ Q@ O@ q+ r+ v+ 5+ 5+ $+ $+ E. 9+ R@ r+ S@ r r+ 1+ 1+ Q@ q+ v+ v+ &+ T@ x+ a+ 0. 0. a. 1@ l. O T m. U@ Q. T j. =. -. a. s+ j. V@ W@ 8. J J J J J + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ # + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + # + + + + + + * ! $ + $ , + + + + + + + + + + + + + + + X@ Y@ Z@ `@ # .# +# @# ## $# %# &# *# =# -# ;# ># ,# '# )# !# ~# {# ]# ^# /# (# _# :# <# [# }# |# 1# 2# 3# 4# 5# 6# 7# 8# 9# 0# a# b# c# d# e# f# g# h# i# j# k# + + + + + + + + + + + + + + + + + + + + + + + + + + + & # + + + + + + + @ + + + + + + + @ . ", -" . + + + + + + + + + + + # + + # + + + + + + + + + + + + + m l# m# }+ n# Q@ o# p# n+ 7. 5+ &+ &+ E. @+ <@ E. q# &+ r# E. p+ p+ {@ ~@ p+ F. 5+ }+ s# a+ }+ s# 0. t# u# I. v# W. w# ~+ x# g+ B+ y# z# A# B# !. O C# A+ D# E# J J J J + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + % # + ^ + + + + + + + + + + + + F# G# H# I# J# K# L# M# N# O# P# Q# R# S# T# U# V# W# X# Y# Z# `# $ .$ +$ @$ #$ $$ %$ &$ *$ =$ -$ ;$ >$ ,$ '$ )$ !$ ~$ {$ ]$ ^$ /$ ($ ^$ _$ :$ <$ [$ }$ |$ 1$ 2$ 3$ 4$ 5$ 6$ c# 7$ 8$ 9$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / j + , + + + + + + + + . ", -" . + + + + + + + + + + + + + + + + , ) + + & + + + + + + m 0$ a$ &+ b$ c$ Q@ O@ w+ %+ 5+ }+ C. }+ @+ $+ &+ F. @+ F. 5+ D. 1+ d$ ~@ {@ q+ r @+ <@ x+ T@ a+ e$ =+ f$ f+ {. x# c+ O g$ J. h$ _. j. N. >. {+ U@ i$ V W. j$ k$ J J J J + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + @ + + + + + @ + + + @ + + + + + + + + + + + $ @ + + @ + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + < # + + + + + l$ m$ n$ o$ p$ g@ q$ r$ s$ t$ u$ v$ w$ x$ y$ z$ A$ B$ C$ D$ E$ F$ G$ H$ I$ J$ K$ L$ M$ N$ O$ P$ Q$ R$ S$ T$ U$ V$ W$ X$ Y$ Z$ `$ % .% +% @% #% $% %% &% *% =% -% ;% >% ,% '% )% !% ~% {% ]% ^% c# /% (% _% :% <% + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + @ + + + + + + . ", -" . + + + + + + + + + + + + + + + + + # + + + + + + + + + [% )@ }% %+ |% o# o# O@ v+ @+ [+ '+ x+ 9+ C. %+ &+ 1% }+ E. $+ 5+ {@ r+ r+ {@ r+ 2% %+ $+ <@ @+ F. ^@ a. 3% 1@ {. U@ l. N. J. U j. |@ j. m. q. !. 4% 5% L. L. 6% 7% ]@ J J J J + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + 8% 9% 0% a% b% c% +# d% e% f% g% h% i% j% k% l% m% n% o% p% q% r% s% t% u% v% w% x% y% z% A% B% C% D% E% F% G% H% I% J% K% L% M% N% O% P% Q% R% S% T% U% V% W% X% Y% Z% `% & .& +& @& #& $& %& && *& =& -& ;& >& ,& '& )& !& ~& {& + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + $ + + . ", -" . + + + + + + + + + + + + + + + + + + + @ + + + + + + ]& ^& T@ n+ D. /& p# p# 1+ (& '+ . 0. x+ _& 5+ 5+ $+ @+ F. {@ S@ &+ @+ :& 2% v+ <& $+ F. <@ &+ @+ E. *+ ^@ -. [& _& }& ]+ W. d+ !+ j. _. x# |& 1& m. _. f. W. V 7% J. V. 2& J J J + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ' * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + $ @ + + + + + + + + + + + + + + + 3& 4& 5& 6& 7& 8& 9& 0& a& b& c& d& e& f& g& h& i& j& k& l& m& n& o& p& q& r& s& t& u& v& E$ w& x& y& z& A& B& C& D& E& F& G& H& I& J& K& L& M& N& O& P& Q& R& S& T& U& V& W& X& Y& Z& `& * .* +* @* #* $* %* &* ** =* ;& -* ;* >* ,* '* )* !* ~* {* + + + + + + + + + + + + 3 + + + + + + + + + + g + + + + + + + . ", -" . + + + + + + + + + + + + + + + + + + + + + + + + m 5. ]* <@ ^* /* n+ (* _* :* ~@ @+ _& (@ 9+ 2% @+ q# 3+ #+ <* 5+ {@ M T@ 5+ @+ r M x+ 5+ @+ @+ F. <@ F. T@ ^@ [* }* G. =+ 2@ V |* 1* 2* 3* f. -. s+ 4* P. 5* 6* j. i+ O 7* 8* 5. J J + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + * : + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9* 0* a* b* c* d* e* f* d% g* h* i* j* k* l* m* n* o* p* q* r* s* t* u* v* w* x* y* z* A* B* C* D* E* F* G* H* I* J* K* L* M* N* O* P* Q* R* S* T* U* V* W* X* Y* Z* `* = .= += @= #= $= %= &= *= == -= ;= >= ,= '= )= != ~= {= ]= ^= /= (= _= := <= [= }= |= 1= 2= 3= + + + + + + + + ^ + + + + + + + + + + + 9 + + + + + 9 + . ", -" . + + + + + + + + + + + + + + + + + + + + @ + + + m 4= 5= 6= p# !@ 7= (* 8= Q@ ~@ %+ r $+ }+ @+ <& R@ d$ %+ $+ C. 9= D. @+ F. }+ :& d$ <@ a+ ^@ a+ F. T@ s [+ [& 0= a= a. ^& b= c= T@ T@ }+ d= e= s -. b+ e+ f= g= B+ k. 6% _. K. h= i= J J + + + + + + + + + + + + + + + + + + + Z. @ + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + : + + < + + + + @ j= k= l= k= m= n= o= + + + + + + + + + + + + + + + + p= q= r= s= t= u= v= w= x= y= z= A= B= C= D= E= F= G= H= I= J= K= @= L= M= N= O= P= Q= R= S= T= U= V= W= X= Y= Z= `= - .- +- @- #- $- %- &- *- =- -- ;- >- ,- '- )- !- ~- {- ]- ^- /- (- _- :- <- [- }- |- 1- 2- 3- 4- 5- 6- 7- 8- 9- 0- a- b- c- d- e- f- g- h- i- j- k- l- m- := n- o- + + + + + ) + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + j= p- q- r- l= l= s- s- s- s- s- s- t- u- + + v- w- a+ x- y- z- A- z- B- C- D- E- F- G- H- I- $+ }+ J- @+ s# [+ x+ %+ I- K- K- L- M- N- O- P- Q- R- S- T- 3% U- V- W- =. [+ X- {. @+ a+ a+ 0. -. Y- Z- ,+ ^. `- ; h+ w# .; /. !+ +; @; J J + + 9 + + + + + + + + + + + + + + + + + , + + + + + #; 9 + + + + + + + + + + + $; 9 + + + + + + + + + + + + + + + + & + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + %; &; *; =; -; ;; >; ,; '; ); !; ~; + + {; ]; ^; + + + + > + + /; (; _; :; <; [; }; |; 1; 2; 3; <# 4; 5; 6; 7; 8; 9; 0; a; b; c; d; e; f; g; h; i; j; k; l; m; n; o; p; q; r; s; t; u; v; w; x; y; z; A; B; C; D; E; F; G; H; I; J; K; L; u% M; N; O; P; Q; R; S; T; U; V; W; X; Y; Z; `; > .> +> @> #> $> %> &> *> => -> ;> != >> ,> '> )> !> ~> {> ]> ^> /> >% (> + + + + + + + + + + + + + + + + + , + + + + + . ", -" . + + + + + + + + _> :> <> [> }> |> 1> 1> |> 2> 3> 4> 5> 6> 7> J 8> 9> v+ 0> :> 4> a> b> |> 1> 1> |> ;; <> c> d> e> f> g> g> h> i> C. 0. j> k> l> ;; |> |> 2> ;; l> :> m> n> o> p> -+ q> [& 3% 0. a+ E. v+ &+ T@ s# 0. (@ a+ e. t+ e$ 6+ K. d+ r> V. s> t> u> J + + + + + + + + + + + + + + + + + + + + + + + + + + # , + + + + + + + + + + + 3 3 + + + + + + + + + + + # + + + + + + + + + + + + < < + + + + + + + + + + + + + + + + + + + + = + + + + + v> w> x> y> z> A> B> C> D> E> F> G> H> I> J> K> L> M> 7> N> O> O> + P> 8# Q> R> S> T> U> V> W> X> Y> Z> `> , ., +, @, #, R; $, %, &, *, =, -, ;, >, ,, ', ), !, ~, {, ], ^, /, (, _, :, <, [, }, |, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, X$ N, O, P, Q, R, S, T, U, V, + + + + + + + + + + + + + + + + + + + + + . ", -" . + + + + + + + + W, X, Y, Z, `, ' .' +' @' #' $' %' &' *' =' -' ;' >' ,' '' X, )' !' ~' ' .' .' ' {' ]' ^' /' (' (* (& &+ _' T@ [+ 0. :' <' [' }' |' |' }' 1' 1' 2' 3' 3% 4' i> 5' 6' 7' 8' C. C. @+ &+ 5+ 5+ &+ T@ C. C. /@ b+ ^@ /@ W |@ j. (. 9' 0' a' b' J + # + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + c' d' e' f' g' h' i' j' k' l' m' n' o' p' q' r' s' t' u' v' w' x' y' z' A' B' C' D' E' F' G' H' I' J' K' L' M' N' O' P' Q' R' S' T' U' V' W' X' Y' Z' `' ) .) +) @) #) $) %) &) *) =) -) ;) >) ,) ') )) !) ~) {) ]) ^) /) () _) :) <) <) [) }) |) 1) 2) 3) 4) 5) 6) 7) 8) 9) 0) a) b) c) d) e) f) g) h) i) j) k) l) m) n) o) p) q) r) V& s) t) u) v) w) x) y) z) %, A) B) C) D) E) F) G) H) I) J) + + + + + + + + + + + + + + + + + + . ", -" . & + + + + + + + K) L) M) N) O) P) Q) R) S) T) U) V) W) X) Y) Z) `) ! g> .! +! @! #! $! P) %! &! *! =! -! ;! >! ,! '! )! !! ~! {! ]! U- ^! /! (! _! :! :! ~ ,~ '~ )~ !~ ~~ {~ ]~ ^~ /~ (~ _~ :~ <~ [~ }~ |~ 1~ 2~ 3~ 4~ 5~ 6~ 7~ 8~ 9~ 0~ a~ b~ c~ d~ e~ f~ g~ h~ i~ j~ k~ l~ m~ n~ o~ p~ q~ r~ s~ t~ u~ v~ 6~ w~ x~ y~ z~ A~ B~ C~ D~ E~ F~ + + + + + + + + + + + + + + = + . ", -" . + + + + + + + + + O> =' d! G~ H~ I~ J~ K~ L~ M~ N~ N~ O~ b$ P~ Q~ R~ S~ T~ U~ .+ V~ W~ X~ Y~ Z~ `~ { .{ +{ @{ #{ ${ %{ &{ *{ C+ h. ={ e$ -{ ;{ >{ ,{ '{ ){ !{ ~{ {{ T~ ]{ ^{ /{ ({ _{ e$ $+ v+ $+ 5+ }+ <@ C. T@ &+ $+ e$ g$ f. V. G+ W. W. :{ R H+ c+ <{ b' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [{ }{ |{ 1{ 2{ Y) 3{ g! g! g! 4{ 5{ 6{ g! g! 7{ 8{ 9{ 0{ a{ b{ c{ d{ e{ f{ g{ h{ i{ j{ k{ l{ m{ n{ o{ p{ q{ r{ s{ t{ u{ v{ w{ x{ y{ z{ A{ B{ C{ D{ E{ F{ G{ H{ I{ J{ K{ L{ M{ N{ O{ P{ Q{ R{ S{ T{ U{ V{ W{ X{ Y{ Z{ `{ ] .] +] @] #] $] %] &] *] =] -] ;] >] ,] '] )] !] ~] {] ]] ^] /] q) (] _] :] <] [] }] |] 1] 2] 2] d~ 3] 4] 5] 6] L= 7] 8] 9] 0] a] m, b] c] d] e] f] g] h] i] j] k] l] m] n] o] p] q] r] s] + + + + + + + + + + + + + + . ", -" . $ + + + + + + + + O> =' d! t] u] v] n! w] x] y] z] A] B] C] D] E] F] G] H] I] J] K] L] M] N] O] P] Q] R] { {{ S] ${ T] U] V] W] X] Y] Z] `] ^ .^ +^ @^ #^ $^ %^ &^ *^ =^ -^ e= Z] ;^ >^ ,^ n# ,^ 5+ F. &+ T@ <@ 5+ $+ 3+ '^ j. V. )^ !^ d+ W. V H+ U ~^ {^ + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + , + + + + + + @ + : , + + + + + + + + + + + + + + + + + + + + + + + + + + # # ]^ ^^ /^ (^ Y) g! _^ _^ g! 3{ :^ <^ [^ }^ |^ |^ 1^ 2^ 3^ 4^ 5^ 6^ 7^ 8^ 9^ 0^ a^ b^ c^ d^ e^ )& f^ g^ h^ i^ j^ k^ l^ m^ I* n^ o^ p^ q^ r^ s^ t^ u^ v^ w^ x^ y^ z^ A^ B^ C^ D^ E^ F^ G^ H^ I^ J^ K^ L^ M^ N^ O^ P^ Q^ R^ S^ T^ U^ V^ W^ X^ Y^ Z^ `^ / ./ +/ @/ #/ $/ %/ &/ */ =/ -/ ;/ >/ ,/ '/ )/ 3- !/ ~/ {/ ]/ ^/ // (/ _/ :/ + + + + . ", -" . + + + + + + l/ $ + ~; N> w' m/ n/ o/ K~ p/ q/ r/ s/ p t/ F. u/ v/ w/ x/ y/ z/ A/ B/ C/ D/ E/ X~ F/ G/ H/ I/ .{ J/ K/ $+ L/ M/ N/ O/ g. h. P/ Q/ R/ S/ T/ U/ V/ W/ X/ Y/ Z/ `/ y+ ( .( +( C. @+ d$ p+ $+ E. (@ }+ &+ @+ F. n# @( c+ 6! #( 6! $( %( S P j$ &( *( J + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + & * + + + + + + + + + # + , , + + + + + + + + + + + > + + + + + + + + = : + + + + @ + + + + + + + + + + + + 2 =( -( ;( >( ,( g! N~ N~ '( e! d! )( !( =' ~( w' {( ]( ^( /( (( _( :( <( [( }( |( 1( 2( 3( 4( 5( 6( 7( 8( 9( 0( a( b( c( d( e( f( g( h( i( j( k( l( m( n( o( p( q( r( s( t( u( v( w( x( y( z( A( B( C( D( E( F( G( H( I( J( K( L( M( N( k) O( P( Q( R( S( T( U( V( W( X( Y( Z( `( _ ._ +_ @_ #_ $_ %_ &_ *_ =_ -_ ;_ >_ ,_ '_ )_ !_ ~_ {_ ]_ ^_ /_ (_ __ :_ <_ [_ }_ |_ 1_ 2_ 3_ 4_ U; 5_ 6_ 7_ 8_ 9_ 0_ 3~ a_ b_ c_ d_ e_ f_ g_ + + + + + + + + + + + . ", -" . + + + + + @ g + + + h_ N> =' i_ j_ k_ l_ m_ n_ o_ p_ q_ 1@ r_ s_ g> t_ u_ v_ w_ x_ y_ z_ A_ B_ C_ D_ E_ F_ &^ G_ H_ I_ J_ K_ L_ M_ Y J_ N_ O_ P_ Q_ J] R_ S_ T_ U_ ^ T@ !! V_ ]! W_ a. T@ }+ v+ $+ }+ s# &+ X_ F. @+ Y_ Z_ `_ H+ W. d+ h$ :. S $( V |@ : b' + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + ) + > + + + + @ + + + + + + + + + + + + + + + + + + + + + + + @ + + + + , + + + + + + + + + + + + + + ) + + + + .: +: @: #: $: N~ N~ _^ 3{ d! =' N> O> O> O> %: &: *: =: -: ;: >: ,: ': ): !: ~: {: ]: ^: /: (: _: :: <: [: }: |: 1: 2: 3: 4: 5: 6: 7: 8: 9: 0: a: b: c: d: e: f: g: h: i: j: k: l: m: n: o: p: q: r: s: t: u: v: w: x: y: z: A: B: C: D: E: F: G: H: I: J: K: L: M: N: O: P: Q: R: S: T: U: V: W: X: Y: Z: `: < .< +< @< #< $< %< &< *< =< -< ;< >< ,< '< )< !< ~< {< ]< ^< /< (< _< :< << [< }< |< 1< 2< 3< 4< 5< 6< 7< 8< 9< 0< a< , + + + + + 9 + @ . ", -" . + + + + + + ' + : [ + ~; O> 7> b< ;: c< d< e< f< z] g< h< i< j< `) !@ (* 7= S~ y/ k< l< m< n< o< p< q< R] r< s< t< u< v< ]! w< x< y< z< A< B< C< D< E< F< G< H< I< J< K< a+ =^ L< @+ s# F. ^@ (@ a+ E. M< N< O< P< Q< R< S< T< U< V< W< Q (. X< $( 6! R ~+ Y< Z< + + `< [ .[ +[ +[ +[ @[ +[ +[ #[ #[ +[ $[ %[ &[ *[ + + + , + + + + + + + + + `< =[ -[ +[ +[ +[ +[ ;[ ;[ +[ >[ ,[ + + + + + + + + + + + + + '[ [ -[ +[ +[ +[ @[ +[ +[ #[ ;[ +[ +[ #[ )[ ![ *[ + + + + + + + + + + + + + + ~[ {[ ][ ^[ /[ A] A] '( Y) =' O> ~; , ([ _[ :[ <[ [[ }[ |[ 1[ 2[ 3[ 4[ 5[ 6[ 7[ 8[ 9[ 0[ a[ b[ c[ d[ e[ f[ g[ h[ i[ j[ k[ l[ m[ n[ o[ p[ q[ r[ s[ t[ u[ v[ w[ x[ y[ z[ A[ B[ C[ D[ E[ F[ G[ H[ I[ J[ K[ L[ M[ N[ O[ P[ Q[ R[ S[ T[ U[ V[ W[ X[ Y[ Z[ `[ } .} +} @} #} $} %} &} *} =} -} ;} >} ,} '} )} !} ~} {} ]} ^} /} (} _} :} <} [} }} |} 1} 2} 3} 4} 5} 6} 7} 8} 9} 0} a} b} c} d} e} f} z, g} h} i} j} k} l} m} n} o} p} q} r} s} t} + + + + # + + . ", -" . + + + + + + + + 2 0 + + + O> u} v} w} x} y} z} 6. A} B} C} N_ F. t_ (* t_ (* !@ D} E} F} G} H} I} J} K} L} M} N} p> O} P} Q} R} S} ~. b+ T} U} V} x+ W} X} Y} Z} `} | >' }+ &+ F. }+ j. b+ s# .| +| @| #| $| %| &| %| *| =| -| ;| >| ,| '| )| O !| ~| S s. 5@ + {| ]| ^| /| (| _| :| <| [| }| || || || 1| 2| 3| 4| 5| 6| o= + + + + + + + + + 7| 8| 9| 0| a| b| b| a| c| d| <| e| f| + ~; + + + + + + + + + + {| ]| ^| /| (| _| :| <| [| }| || g| g| || h| i| j| k| l| 6| o= + $ + + + + + + + # + m| n| o| p| q| r| N~ g! {( N> ~; + s| t| u| v| w| x| y| z| A| B| C| D| E| F| G| H| I| J| K| (| _| :| <| L| }| || g| || || M| N| O| P| Q| R| S| T| U| V| W| X| m( Y| Z| `| 1 .1 +1 @1 #1 !] $1 %1 &1 *1 =1 -1 ;1 >1 ,1 '1 )1 !1 ~1 {1 ]1 c| ^1 /1 /1 ^1 (1 _1 :1 <1 [1 }1 |1 11 J| 21 31 /1 b| 41 51 61 71 81 91 01 a1 b1 c1 d1 e1 }| f1 g1 a| h1 i1 j1 k1 l1 m1 n1 d| L| o1 p1 q1 r1 s1 t1 u1 v1 w1 x1 y1 z1 A1 B1 C1 M| D1 /1 31 E1 F1 G1 H1 ~; + + + + + . ", -" . + + + + + + + + + + , + + ~; I1 J1 K1 L1 M1 N1 L} X} O1 P1 /+ @+ Q1 Q1 (* 7= p# R1 S1 T1 U1 p< V1 W1 X1 V/ Y1 Z1 `1 2 K_ .2 +2 @2 G. 9+ #2 $2 %2 7. K/ &2 *2 =2 -2 D] >^ $+ E. M 5+ ^. ;2 >2 ,2 '2 )2 !2 ~2 {2 ]2 ^2 /2 (2 _2 :2 <2 [2 }2 g+ |2 12 22 j$ 32 |* + {| 42 52 62 72 82 92 02 a2 b2 c2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2 ~; ~; + + + + + + m2 n2 52 o2 02 p2 p2 02 q2 r2 s2 t2 u2 =' N> O> ~; + + # + + + + + {| 42 52 62 72 m_ p2 02 a2 v2 w2 w2 w2 c2 x2 y2 z2 A2 B2 C2 D2 E2 F2 + + + + + + + + + G2 H2 I2 J2 K2 L2 r| 3{ M2 N> N2 O2 P2 Q2 R2 S2 T2 U2 V2 W2 X2 Y2 Z2 `2 3 .3 +3 @3 #3 $3 %3 72 m_ p2 02 &3 *3 =3 -3 -3 =3 ;3 >3 *| ,3 '3 )3 !3 ~3 {3 ]3 ^3 /3 (3 _3 :3 <3 [3 }3 |3 13 23 33 43 53 63 73 83 93 03 a3 b3 c3 d3 e3 f3 g3 h3 i3 02 {[ 92 02 j3 k3 l3 m3 n3 o3 p3 q3 r3 s3 t3 u3 v3 w3 x3 y3 z3 A3 B3 C3 D3 E3 F3 G3 H3 I3 J3 K3 t3 L3 M3 N3 O3 P3 Q3 R3 S3 T3 K1 p2 U3 V3 W3 X3 Y3 Z3 `3 4 .4 +4 @4 #4 $4 I3 J3 K3 t3 %4 &4 *4 =4 -4 ;4 ~; + + = . ", -" . + + + + + + + + + + @ j + + ~; >4 ,4 '4 )4 !4 ~4 J/ {4 ]4 ~! u/ ^* t_ u_ t_ Q1 ^4 /4 (4 _4 :4 x} <4 [4 }4 R_ |4 R~ 14 *{ *+ 5= 3% a. }+ .^ 24 34 ,! 44 54 )! h< 64 74 r_ ^@ 84 O@ D. 94 04 a4 b4 c4 d4 x+ J< e4 f4 g4 h4 i4 j4 k4 l4 m4 n4 o4 ~! p4 q4 r4 d+ s4 J + t4 [ u4 v4 w4 w4 x4 y4 z4 A4 A4 B4 C4 D4 E4 F4 G4 H4 I4 J4 K4 N> O> + + + + + + t4 L4 u4 M4 N4 w4 O4 P4 Q4 R4 S4 T4 d! U4 =' N> ~; + + # + + + + + t4 [ u4 v4 w4 w4 V4 W4 z4 X4 A4 Y4 Z4 `4 5 .5 +5 @5 l4 #5 $5 %5 &5 ~; ~; + + + + + + *5 =5 -5 ;5 >5 ,5 '5 )5 !5 ~5 {5 ]5 ^5 /5 (5 _5 :5 <5 [5 }5 |5 15 25 35 45 55 65 75 85 95 05 a5 N4 N4 V4 b5 c5 d5 e5 e5 f5 g5 h5 i5 j5 k5 l5 m5 n5 o5 p5 q5 r5 s5 t5 u5 v5 w5 x5 y5 z5 A5 B5 63 )4 C5 D5 E5 F5 G5 H5 I5 J5 K5 L5 M5 N5 O5 P5 Q5 R5 w4 S5 T5 U5 V5 W5 X5 Y5 Z5 `5 6 .6 +6 ,4 '4 N4 @6 #6 $6 %6 &6 *6 =6 -6 ;6 >6 ,6 '6 )6 !6 ~6 {6 ]6 ^6 /6 (6 _6 :6 <6 [6 }6 |6 16 26 36 46 56 66 76 86 96 @4 06 a6 b6 c6 d6 !6 e6 f6 g6 h6 i6 j6 k6 l6 ~; + + . ", -" . + + + + + + + + + + + + + + O> m6 n6 <4 o6 p6 q6 r6 s6 *2 t6 u6 (* (* u_ F. v6 w6 x6 y6 z6 A6 B6 C6 D6 E6 R] F6 $+ h> G6 H6 I6 J6 e$ K6 L6 M6 N6 O6 P6 J] Q6 R6 S6 4! T6 U6 Q~ D. V6 W6 X6 Y6 Z6 `6 7 .7 +7 @7 #7 $7 %7 &7 *7 =7 -7 ;7 >7 ,7 O. '7 )7 !7 ~7 {7 C/ + + O> ]7 ^7 /7 /7 (7 _7 N~ N~ '( :7 3{ <7 3{ 3{ [7 }7 |7 17 27 37 47 N> ~; + + + + + N> 57 67 /7 77 87 97 N~ _^ '( g! e! 07 w' N> O> + + + + + + + + + O> ]7 ^7 77 77 (7 _7 N~ N~ '( g! 3{ 3{ 3{ 3{ 3{ a7 b7 c7 d7 e7 f7 ]7 N> O> + + + + + g7 h7 i7 j7 k7 l7 m7 n7 o7 p7 q7 r7 s7 t7 u7 v7 w7 x7 y7 z7 A7 B7 C7 D7 E7 F7 G7 H7 I7 J7 K7 L7 /7 /7 (7 M7 N7 O7 P7 Q7 R7 S7 T7 U7 V7 W7 X7 Y7 Z7 `7 8 .8 +8 @8 #8 $8 %8 &8 *8 =8 -8 ;8 >8 X6 ,8 '8 )8 !8 ~8 {8 ]8 ^8 /8 (8 _8 :8 <8 [8 }8 |8 X7 i7 18 28 38 48 58 68 78 88 98 08 a8 b8 c8 <4 d8 e8 f8 g8 h8 i8 j8 k8 l8 m8 n8 o8 p8 q8 r8 s8 t8 u8 v8 w8 x8 y8 z8 A8 B8 C8 D8 E8 F8 G8 H8 I8 J8 K8 L8 M8 N8 O8 P8 Q8 R8 S8 T8 U8 V8 W8 X8 Y8 Z8 `8 9 .9 +9 + . ", -" . + + + > + + + + + + + + + + ~; @9 #9 $9 %9 &9 *9 =9 -9 P6 ;9 d. 5+ (* (* ^* >9 P_ ,9 '9 )9 !9 ~9 {9 ]9 ^9 /9 (9 _9 N6 :9 <9 r_ [9 -. }9 |9 19 29 0$ ){ W} F. &{ 39 49 59 69 b= 79 89 99 09 a9 b9 c9 +{ d9 d9 e9 L f9 g9 J] h9 *2 i9 j9 k9 l9 m9 H_ n9 o9 p9 q9 :9 + + O> ]7 r9 s9 t9 C8 u9 p p N~ g! 3{ 3{ 3{ 3{ v9 w9 x9 y9 z9 A9 B9 w' N> ~; + + + + N> 57 C9 t9 t9 D9 E9 p p N~ g! e! Y) w' N> O> + + + + + + # + + O> ]7 r9 t9 ~9 F9 u9 p p G9 g! 3{ e! e! 3{ 3{ g! H9 I9 J9 K9 L9 M9 2{ N> O> + + + + ~; N9 09 O9 P9 Q9 R9 S9 T9 U9 V9 W9 X9 Y9 Z9 `9 0 .0 +0 @0 #0 $0 %0 &0 *0 =0 -0 ;0 >0 ,0 '0 )0 t9 s9 F9 !0 ~0 {0 ]0 ^0 /0 (0 _0 :0 <0 [0 }0 ~9 |0 10 20 30 40 50 60 70 80 90 00 a0 b0 c0 d0 e0 f0 g0 h0 i0 j0 k0 l0 m0 n0 o0 p0 q0 r0 s0 t0 u0 v0 w0 x0 y0 z0 A0 B0 C0 D0 E0 F0 G0 H0 I0 J0 s9 K0 L0 M0 N0 O0 P0 Q0 R0 S0 T0 U0 V0 W0 X0 Y0 Z0 `0 a .a +a @a #a $a %a &a *a =a -a ;a >a ,a 'a )a !a ~a {a ]a ^a /a (a _a :a @b #b $b $b %b _7 p N~ 3{ Y) 07 07 Y) &b *b $b =b -b ;b >b |^ w' N> ~; + + + O> @b ,b $b $b 'b )b A] N~ g! !b ~b =' O> ~; + + + + + 3 + + + O> {b #b $b $b %b _7 p N~ 3{ Y) d! d! d! Y) |^ 3{ ]b ^b /b (b _b :b + + + ~; }b |b 1b 2b 3b 4b 5b 5b 6b 7b 8b 9b 0b ab bb cb db eb fb gb hb ib jb kb lb mb nb ob pb qb rb $b $b %b sb tb ub vb wb xb yb zb Ab Bb Cb Db $b Eb Fb Gb Hb Ib Jb Kb Lb Mb Nb Ob Pb Qb Rb @5 Sb Tb oa Ub Vb Wb Xb Yb Zb `b c .c +c @c #c $c %c &c oa *c ra =c -c ;c >c ,c 'c )c !c ~c {c ]c oa Eb l9 ^c /c (c _c :c Bc Cc Dc Eb Ec Fc Z< #{ &+ Gc >' n+ Q1 Hc Ic Jc Ua 44 Y1 Kc aa ba Lc Mc Nc V/ Oc ${ H_ 7. Pc 9> Qc Rc Sc n9 Tc Uc #+ t< Vc Wc Xc Yc Zc `c d .d *c Wa +d @d Y/ #d $d %d $7 &d *d #+ Q@ o+ o# =d -d ;d >d Dc -b ,d F6 #{ 'd q4 )d + + + !d ~d Dc Dc %b _7 p {d Y) w' =' =' w' !5 ]d Dc =b Dc ^d /d _^ (d =' O> + + + + !d _d Dc Dc 'b )b p _^ |^ w' N> O> ~; + + + + + + + + + + + !d ~d Dc Dc %b _7 p _^ Y) w' =' =' =' =' w' d! :d O> + + + N> 2d 3d Wa 4d ba 5d 6d 7d 8d 4b 4b 9d 0d ad bd cd dd ed fd gd hd id jd kd ld md nd od pd qd Dc qa %b rd sd td ud vd wd xd yd zd Ad Bd Cd Dc Dd Ed Fd Gd Hd Id Jd Kd Ld Md Nd Od Pd Qd Rd Sd Td aa Dc Ec Ud Vd Wd Xd Yd Zd `d e .e +e @e #e $e aa Dc %e &e *e =e -e ;e >e ,e 'e )e !e ~e aa |7 {e ]e ^e /e (e _e :e ' P} `e f K. .f +f @f #f $f u_ sa %f &f 44 T~ *f =f -f 1+ ;f >f ,f o# 'f )f Fe !f ~f {f ]f J] ^f /f + + + + (f {e {e %b u9 p g! d! N> O> O> O> 7> _f :f Lc Fe ~; + + + + |f {e {e 1f )b p '( d! N> O> + + + + + + + + + + + + @ + (f {e {e %b u9 2f g! d! N> O> O> O> O> N> 3f w' 4f 5f {e +f 6f >b |^ U4 N> ~; + + O> 7f 8f 9f 0f af ge Dc bf 5b cf df df ef ef ff gf hf if jf kf lf mf nf of pf qf rf sf tf uf {e {e %b vf wf xf yf zf Af Bf Cf Df Ef Ff Cd {e Gf Hf If Jf Kf Lf Mf Nf Of Pf Qf Rf Sf Tf Uf Vf Wf 5f Xf Yf Zf `f g .g +g @g #g $g %g &g *g =g -g ;g {e +f >g ,g 'g )g !g ~g {g ]g ^g /g (g _g Fe @f :g Og Pg Qg ,! G< Rg Sg Tg Ug Vg Se Wg Xg Yg &2 Zg 2 P} C} `g h .h +h _& @h #h $h %h e$ &h *h =h -h ;h Se >h ,h 'h Pe V/ )h @{ ${ !h ;f 1+ {@ r+ q+ q+ ;f ~h {h ]h ^h Yf /h (h r< Rg _h :h ~; + + $ ~; + + |h 1h [h 2h 3h 4h z] A] 5h Y) =' O> + ^ + + 6h [h [h 7h )b p g! {( N> + + + + + + + + + + + + # + + 9h Ee >h 0h ah bh _^ Y) =' O> + ch dh eh fh gh hh G4 ih jh kh 2h 26 Yf Ge lh mh ff nh oh ph qh rh sh th uh vh wh xh yh zh Ah Bh [h [h }h Ch Dh Eh Fh Gh Hh Ih Jh Kh Lh Mh Nh [h Oh Ph Qh Rh Sh Th Uh Vh Wh Xh Yh Zh `h i .i +i @i #i $i [h %i &i *i =i -i ;i >i ,i 'i )i !i ~i {i ]i Oh [h ^i /i (i _i :i Pi Qi Ri Si Ti Ui Vi Wi 3% 14 h> Xi Yi Zi `i F6 j ,! .j +j @j #j $j %j &j #^ ]f *j Ze *{ =j -j ;j 5+ >j ,j 'j )j !j ~j {j ({ s> $( ]j Ti $j Ri ^j /j (j _j e9 Y} {4 1+ :j r+ d$ p+ {@ q+ q+ O> + + + + + + 7j 8j 9j 0j aj bj N~ cj =' O> + = + + 6h Ri Ri dj ej p g! {( N> + + + + ) + < + + + + + + + + + + + + + + ~; hj Tg Ri ij jj kj r| g! {( N> lj mj nj oj pj qj rj sj tj uj vj wj xj xj yj zj Aj Bj Cj Dj Ej Fj Gj Hj Ij Mb Jj Kj Lj H: Mj Nj Oj Ri Ri gj Pj Qj Rj Sj Tj Uj Vj Wj Xj Yj Zj `j k 0j .k +k @k #k $k %k &k *k =k -k ;k w6 >k ,k 'k )k !k ~k {k Ti ]k ^k /k (k _k :k l ,l 'l )l #l !l t/ sa ~l {l ]l ^l di /l (l _l :l , + + + + + @ + + $ + + < + + ul 'l 'l gj u9 A] g! {( N> + + + + + + + !d vl 3l wl Ec xl 5j _^ Y) yl zl Al Bl Cl Dl El Fl Gl Hl Il Jl Kl Ll Ml Nl pl Ol Pl Ql @l Rl Sl Tl Ul Vl Wl Xl Yl Zl `l m .m _d 3l 3l +m @m #m $m %m &m *m =m -m ;m >m ,m 'm )m !m ~m {m ]m ^m /m (m _m :m n ,n 'n . ", -" . + + + + + + + + + + + + + + + + + ~; )n H~ !n #j ~n {n P6 ya ]n U- ^n /n (n $+ _n X_ Q6 6= :n p ,p 'p )p pc !p ~p {p ]p ^p /p (p _p :p

}p #f |p 1p 2p 3p Z< 4p 5p 6p U} 7p q_ 8p {h _n *j @+ H_ 9p 0p '8 1p ap bp /9 Pe cp dp ep fp gp za hp ip jp kp lp mp np J. =h op pp ~9 ;5 |p qp }4 rp sp tp up G. vp wp &+ &+ -. a+ E. $+ x+ xp yp zp s9 ~9 Ap Bp /9 B/ Cp Dp O> + @ Ep ~9 Fp X7 Gp Hp Ip Hp Jp Kp Lp J9 Mp Np Op Pp Qp Rp p p N~ 3{ {( Sp + + + + + C9 ~9 ~9 D9 ej p g! {( N> + + @ + + + + + + + + + + + + Ep ~9 ~9 F9 u9 A] g! {( N> + # + + < < + < Tp |p ;5 ~9 Up 5j Vp Wp Xp Yp Zp `p q .q +q @q #q $q %q &q *q =q -q ;q >q ,q 'q )q !q O9 ~q {q ]q ^q /q (q _q :q r ,r 'r )r !r p0 ~r #f $9 {r ]r ^r /r (r _r :r pc + + Mr Gr Fr Nr Or Pr Qr Pr Rr Sr Tr Ur Vr Wr Xr Yr Zr `r A] N~ }f d! =' O> + + + + + C9 s s 'b ej p g! {( N> + + + , + + , # + + + + + + + Mr s s C8 u9 A] g! {( N> + + + + + + + + .s |0 |q 2b +s @s #s $s %s &s *s =s -s ;s >s ,s 's )s !s ~s {s ]s ^s /s (s _s :s a Dc Qs Rs Ss Ts Us Vs Ws Xs Ys Zs `s t .t +t @t #t $t %t &t *t =t -t ;t >t ,t 't )t !t ~t {t ]t ^t /t (t _t be :t + + Ep ~9 ~9 F9 .u +u @u #u $u |^ Y) %u Hr Wa &u *u =u r| N~ g! 07 =' O> + + + + + + -u K0 K0 D9 ej p g! {( N> + + + + + + + + + + + + , < + Ep K0 K0 F9 u9 A] g! {( N> + + + + + + + + ;u ~9 Ot 09 >u ,u 'u )u !u ~u {u ]u ^u /u (u _u :u v ,v 'v )v !v ~v {v w0 Tu ]v ^v /v (v _v :v *w =w &( -w Ba >+ _& &+ ;w >w ,w 'w )w !w z] Ma Ua {( N> + + ~w .w .w {w u9 N~ g! ]w ^w 3{ /w v0 (w _w :w x ,x 'x )x !x ~x {x ]x ^x /x (x _x Ot Dv Uu :x !7 &y ~j Jt Zv *y *y #( =y -y Re K1 <| ;y >y =9 ,y ,j 'y )y ,+ !y ~y {y ]y ^y H6 -. @+ <@ C9 /y 82 (y _y M~ b' .{ :y {( N> + , + + + + + + + 3y <| <| 4y ej p g! {( N> + + + + + + 5y 6y ~; O> O> ~; + + + + + + + , + + 7y 8y <| 9y 0y ay by cy dy ey fy gy hy iy jy ky ly G; my ny oy py qy ry sy ty uy vy wy xy yy zy 9y Ay By Cy Dy Ey Fy Gy Hy Iy Jy <| <| Ky Ly My Ny Oy Py Qy Ry Sy Ty Uy Vy Wy Xy Yy Zy `y z .z +z @z #z $z %z &z *z =z -z ;z ;z ;z ;z =z *z >z ,z <| 'z )z !z ~z R- {z ]z ^z /z i, (z _z :z A ,A 'A )A !A .2 C} r_ ~A ]y {A ]A ^A }& <@ /A (A _A :A + + 1A _A _A 2A 3A p _^ |^ d! {( d! 4A 5A _A _A 6A 7A '( Y) =' O> ) + + + + + + 8A _A _A 9A )b A] p g! {( N> + + + + + {; 0A #A N> N> N> N> ~; + + 1A _A _A 2A u9 A] g! {( N> + + + + $ + + aA bA cA dA eA fA gA hA iA jA kA lA mA nA oA pA qA rA sA tA uA vA wA xA yA zA AA BA CA DA EA FA GA HA IA JA KA LA MA NA OA PA QA _A _A l! RA SA TA UA VA WA XA YA ZA `A B .B +B @B #B $B %B &B *B =B -B ;B >B ,B 'B )B !B ~B {B ]B ^B /B (B _B :B ;A C Z/ ,C 'C ${ )C *^ !@ 6= 0. Ax !C $C ~C &C ff {C ]C ^C X} #{ z. /C (C _C :C *y + + iC dC dC jC 3A p g! d! =' N> N> kC lC dC %C mC nC z] g! {( N> + + # # + + + oC dC dC pC )b n p g! qC N> + + + + + rC U} sC =' U4 U4 =' O> + + iC dC dC jC 3A A] g! {( N> + @ < + + + + tC uC vC wC xC yC zC AC BC CC DC EC FC GC HC IC JC KC LC MC NC OC PC QC RC SC TC UC VC WC XC YC ZC `C D .D +D @D #D $D %D &D *D dC dC =D -D ;D >D ,D 'D )D !D ~D {D ]D ^D /D (D _D :D E ,E 'E )E !E ~E {E C ]E ^E /E . ", -" . + + + + + + + + + + + + + + + + + + + m (E _E :E + + + + + + oC FE FE JE )b p g! {( 8h + + + + + KE LE ME {( Y) Y) U4 N> ~; ) zE FE FE BE 3A A] g! {( NE + + + + + + OE PE QE RE SE TE UE VE WE XE YE ZE `E F .F +F @F #F $F %F &F *F =F -F ;F >F ,F 'F )F !F ~F {F ]F ^F /F (F _F :F G ,G 'G )G !G ~G :a be {G ]G ^G /G (G _G :G OG + + zE AE AE BE 3A PG IE g! {( N> + + QG RG AE + + + + + + oC FE FE JE ej VG WG XG YG 7> + + + # + ZG `G H 07 e! |^ d! N> ~; + zE FE .H BE +H VG WG @H #H 7> + + + + + $H %H &H *H =H -H ;H >H ,H 'H )H !H ~H {H ~C ]H ^H /H (H _H :H I ,I 'I )I !I ~I {I ]I ^I /I K[ (I _I :I !d o= + `I S) S) J .J +J @J Q] + + + u] #J $J S) %J &J A] g! *J =J -J + + + !d + ;J >J S) ,J 'J )J !J ~J {J ]J !d + + + ^J 4i /J (J |^ g! 3{ d! _J :J !d `I S) S) BE .J J GJ HJ IJ JJ KJ LJ MJ NJ OJ PJ QJ RJ SJ TJ UJ VJ WJ XJ YJ ZJ `J K .K +K @K #K $K %K &K *K =K -K ;K >K ,K 'K )K S) !K ~K {K ]K ^K /K (K _K :K L ,L L 'L )L J &. {{ !@ !L ~L {L f ]L ^L 3@ /L (L _L f j$ U :L M ,M `E 'M )M !M ~M {M ]M ^M /M (M _M :M N ,N 'N +N )N !N ~N {N ]N ^N /N (N _N :N B} *{ *{ Ba S} (@ ~. s# zN AN vN vN BN CN DN (j EN FN GN HN IN JN KN LN *y MN NN ON PN 6% h$ QN RN SN TN UN VN WN XN YN ZN `N O .O +O @O ;y #O $O %O &O Wi &2 R_ r< X} { w' N> + *O =O -O ;O >O ,O 'O )O !O ~O {O B9 N> ~; + + ]O ^O /O (O _O :O P ,P 'P )P !P ~P {P ]P ^P /P (P .. _P :P fO

O aP :P bP cP dP eP fP 83 gP hP iP jP kP lP mP nP oP pP qP rP sP tP uP vP wP xP xP yP zP AP BP wN CP DP EP FP GP HP IP JP KP LP MP NP OP PP QP RP 'O SP eJ TP UP VP WP XP YP ZP `P Q .Q +Q @Q #Q $Q %Q (g jN &Q *Q =Q -Q ;Q >Q ,Q WK 'Q )Q . ", -" . + + + + + + + + + + + + + + @ + + + + + + Jr !Q ~Q {Q ]Q ^Q ^Q R] .+ 2E /Q H_ >+ *L Q} }* (Q p4 ]! _Q :Q {Q Ur R ,R 'R )R !R ~R {R }> ]R ^R /R (R _R :R S ,S 'S )S !S ~S {S ]S ^S /S (S _S :S T ,T 'T )T !T ~T {T ]T ^T /T (T _T :T U ,U 'U )U !U ~U {U ]U ^U /U (U _U :U V ,V 'V )V !V ~V t> w# {V |@ =y ]V ^V /V (V 5@ B] _V :V =' d! e! _^ A] p p N~ g! Y) U4 N> O> ~; N> {( 3{ pL 5V 6V 7V N~ g! e! 8V e! 9V 0V {( aV 3{ _^ A] p N~ g! bV cV e! e! g! g! N~ A] p p N~ 3{ U4 N> N> =' d! cV _^ A] A] N~ g! 3{ dV eV {a fV gV hV iV jV kV lV mV nV oV pV qV rV sV tV uV vV wV xV yV zV AV BV CV DV EV FV GV HV IV JV KV LV MV NV OV PV QV RV SV TV UV VV WV KT XV YV ZV `V W .W +W @W #W $W %W &W *W =W -W ;W >W ,W 'W )W !W ~W {W ]W ^W /W (W _W :W X ,X 'X )X !X yU ,Q ~X {X . ", -" . + + + + + + + + + + + + + + + + + + + + + ^ ~; ya ]X ^X 54 .j /X (X U6 _X :X 69 49 f V w' d! e! nX N~ N~ A] N~ _^ g! |^ {( [b O> oX pX =' d! g! N~ A] N~ N~ g! g! qX |^ d! w' {( Y) 3{ _^ N~ A] A] N~ _^ 3o g! 3{ 3{ g! g! '( _^ N~ N~ N~ g! Y) =' O> N> w' d! 3{ '( N~ A] A] N~ rX sX tX uX vX wX xX yX zX AX BX CX DX EX FX GX HX IX JX KX LX MX NX OX PX QX RX SX TX UX VX WX XX YX ZX `X Y .Y +Y @Y #Y $Y %Y &Y *Y =Y !W -Y ;Y >Y ,Y 'Y )Y !Y ~Y {Y ]Y ^Y /Y (Y _Y :Y Z ,Z 'Z =1 )Z !Z ~Z {Z ]Z ^Z /Z (Z _Z :Z =' {( 07 GZ ^w 3{ 3{ 3{ e! Y) d! w' N> ~; + + O> =' d! |^ g! g! g! 3{ e! Y) d! w' =' =' {( Y) |^ 3{ g! g! g! e! |^ |^ |^ |^ |^ |^ e! 3{ 3{ g! e! Y) w' N> O> O> =' {( Y) |^ 3{ g! g! g! e! HZ IZ JZ KZ LZ MZ NZ OZ PZ QZ RZ SZ TZ UZ VZ WZ XZ YZ ZZ `Z ` .` +` @` #` $` %` &` *` =` -` ;` >` ,` '` )` !` ~` {` ]` ^` /` (` _` :` <` [` }` }Y |` 1` 2` 3` 4` 5` 6` 7` 8` 9` 0` a` b` c` d` e` f` g` h` i` j` k` l` m` n` o` p` q` r` s` t` u` v` w` x` y` z` A` B` C` D` E` F` G` H` I` J` K` L` M` N` O` P` Q` R` S` T` U` V` W` X` Y` Z` `` .. .+ .@ .# .$ .% .& .* .7I = .- .; .> ., .~i ' .) .zB lx ! .~ .{ .] .9I ^ ./ .( ._ .: .< .[ .} .| .1 .2 .3 .4 .5 .6 .7 .8 .9 .0 .a .b .c .d .e .f .g .h .i .j .[G k .l .m . ", -" n .# + + + + + + + + + # + + + + + + + + + ) + + ~; o .Ax D] p ..h 64 (Q U6 J6 L/ A< YU Lt ^y q .r .s .t .z< u .*y v .tE fZ w .6X uS qS rS 0C x .v tS 6% 8! y .6% z .A .eE c+ R W B .C .QN v# D .E .F .G .H .I .S} BZ Ke J .@2 ,j )y o> K .J J J + + + % ~; O> N> L .w' w' U4 U4 U4 w' w' =' N> O> + + + + O> N> w' {( M .07 d! d! w' =' N> O> N> [b =' w' U4 {( {( {( U4 )( N .w' w' w' w' w' U4 {( {( w' =' N> O> + ~; O> N> =' w' U4 {( O .{( P .Q .R .S .T .U .V .W .X .Y .Z .` . .....+..`{ @..#..$..%..&..*..=..-..;..>..,..'..)..!..~..{..]..^../..(.._..:..<..[..}..|..1..2..3..4..;W 5..6..7..8..9..0..a..b..c..d..e..f..g..h..o` i..j..k..l..m..n..6Y o..p..i` q..r..s..t..u..v..w..x..y..z..A..B..C..D..E..F..G..H..I..J..K..L..M..N..O..P..Q..R..S..T..U..V..W..X..Y..Z..`.. +..+.++.@+.#+.$+.%+.&+.*+.=+.-+.;+.>+.1Z ,+.'+.)+.!+.~+.{+.]+.^+./+.(+._+.gx :+.<+.[+.}+.|+.1+.2+.3+.4+.5+.6+.7+.8+.9+.0+.a+.b+.c+.d+.~a e+.lx f+.g+.IK h+.i+.j+.k+.l+.m+.n+.;G o+.p+.q+.r+. ", -" ln + + + + + + + + + + + + + , + + + + + + + + + + m <* h< Ve `] s+.t+.]l /Q u+.64 v+.(L fE w+.x+.y+.z+.^+ A+.B+.C+.D+.E+.F+.G+.H+.H+.I+.J+.K+.L+.M+.6% V@ N+.h$ #( NN O+.P+.Q+.V. i$ i$ R+.S+._{ T+.U+.V+.W+.X+.Y+.M/ Z+.`+.Dr )y @..@.+@.J J J + + # < # + O> O> O> O> O> O> O> O> O> @@.~; + + + + + + ~; #@.N> $@.%@.L .N> N> pn ~; + ~; O> O> O> N> N> N> N> O> O> O> O> O> O> O> O> N> N> N> O> O> ~; + + + + O> O> O> N> N> N> N> &@.*@.=@.-@.;@.>@.,@.'@.)@.!@.~@.{@.]@.^@./@.(@._@.:@.<@.[@.}@.|@.1@.2@.3@.4@.5@.6@.7@.8@.9@.0@.a@.b@.c@.PH d@.e@.f@.g@.h@.i@.j@.k@.l@.m@.n@.o@.p@.q@.r@.s@.t@.u@.v@.w@.x@.y@.z@.A@.B@.C@.D@.E@.F@.G@.H@.s..I@.J@.K@.L@.t@.M@.N@.O@.P@.Q@.R@.S@.T@.U@.V@.GT W@.X@.Y@.Z@.`@. #..#.+#.@#.##.$#.%#.&#.*#.=#.-#.;#.>#.,#.'#.)#.!#.~#.{#.]#.^#./#.(#._#.:#.<#.[#.}#.|#.1#.qB 2#.3#.4#.5#.6#.7#.8#.9#._+.0#.a#.b#.c#.d#.e#.f#.g#.h#.i#.j#.k#.l#.m#.n#.o#.p#.q#.r#.s#.*X t#.u#.v#.w#.x#.y#.z#.A#.B#.C#.D#.E#.F#.G#.H#.I#.^Z J#.K#.L#.M#.N#. ", -" O#.+ + + # + + + + + + + + + + + + + + + + + + ) # + NG >' P#.M/ _X &{ 0Z P~ ga ]l Q#.R#.T6 eS aC S#.QI T#.U#.V#.W#.X#.Y#.Z#.`#. $.rS qS .$..$.^L Da +$.V. U L. w# @$.#$.T #( c+ J. $.EG ,$.]! 4' '$.)$.m J J J + + + + + + + + # + + + + + + + + + + + + + + + + ~; !$.~$.{$.~; ~; & + + + + + + + + + + + + + + + + + + + + + + + + + # < + + + + + + + ]$.^$./$.($._$.:$.<$.[$.}$.|$.1$.2$.3$.KX 4$.5$.6$.7$.8$.9$.0$.a$.b$.c$.d$.e$.f$.f$.g$.h$.i$.j$.k$.l$.m$.n$.o$.p$.q$.r$.s$.t$.u$.v$.w$.x$.y$.z$.A$.k` N@.B$.C$.D$.E$.F$.G$.H$.I$.J$.K$.L$.M$.N$.O$.P$.N@.Q$.R$.C$.S$.T$.U$.V$.W$.J$.X$.Y$.F@.Z$.`$. %..%.+%.@%.#%.$%.%%.&%.*%.=%.-%.;%.>%.,%.'%.)%.!%.~%.{%.]%.z8 ^%./%.(%._%.:%.<%.[%.}%.|%.1%.2%.3%.4%.5%.6%.7%.8%.9%.0%.a%.b%.c%.d%.e%.f%.g%.h%.i%._+.j%.k%.l%.m%.n%.o%.p%.q%.r%.s%.Kk JW t%.u%.v%.w%.a+.x%.y%.z%.A%.B%.C%.D%.E%.NB o#.F%.G%.H%.I%.J%.K%.L%.M%.N%.O%.P%.Q%.R%.S%.T%. ", -" U%.+ + 2 + + + + + + e + + + + + + + + + + + + , 1 + m V%.Pc C} W%.*{ Q} =L `] ]l P} X%.T6 Y%.Z%.`%.[X &..&.+&.u .@&.#&..&.$&.-V %&.&&.aX *&.=&.-&.S T h$ G+ V. I. V K. _L c= c+ Ar O d+ ;&.>&.,&.0C T#.'&.-&.)&.!&.~&.,+ /@ {&.J J J J + + + + + + + + + + + + + # + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + + + + + + + + + ]&.^&./&.(&._&.:&.<&.[&.}&.|&.1&.2&.3&.4&.5&.6&.7&.8&.9&.0&.a&.b&.c&.d&.e&.f&.g&.h&.i&.j&.k&.l&.m&.n&.o&.p&.q&.r&.s&.t&.u&.v&.w&.x&.y&.z&.z$.A&.B&.v&.C&.D&.E&.F&.G&.H&.I&.J&.K&.K&.L&.M&.N&.O&.P&.Q&.R&.S&.l` J$.X$.T&.U&.V&.W&.X&.Y&.Z&.`&. *..*.+*.@*.#*.$*.%*.&*.**.=*.-*.;*.>*.,*.'*.)*.!*.~*.{*.]*.^*./*.(*._*.:*.<*.[*.}*.|*.1*.2*.3*.4*.5*.6*.7*.8*.9*.0*.a*.b*.c*.d*.e*.f*.g*.h*.i*.j*.k*.l*.m*.n*.o*.p*.q*.r*.s*.t*.o%.o%.u*.v*.w*.x*.y*.z*.A*.B*.C*.D*.E*.F*.G*.H*.I*.J*.K*.L*.M*.N*.O*.P*.Q*.R*.d*.S*.T*.U*.V*.W*.8v X*.Y*.Z*. ", -" `*.+ + + + @ # + + + + + + + + + + + + + + + + + + + + + =./Q +2 ]l 74 .=.C} 9+ *L +=.@=.K_ R#.=w 7' #=.$=.%=.&=.X#.oZ .&.$&.$&.*=.*&.0X ==.-=.;=.7% >=.G+ 7% t. Q ,=.vG @$.|@ '=.>&.(. dX >&.&( 7' )=.!=.T#.~=.{=.Ar >+ s# _& b' J J J J + + + + + + + + + + + + + , + + + + + + + + + + + + + + + < + + + + + + + + + < + + + + + + + + + ~ } + + , + + + + + + + + + + + ]=.^=./=.(=._=.:=.<=.[=.}=.|=.1=.2=.3=.4=.5=.6=.7=.8=.9=.0=.a=.b=.c=.d=.e=.f=.g=.h=.j$.i=.j=.k=.l=.m=.n=.o=.p=.q=.r=.s=.t=.u=.u=.v=.w=.x=.y=.E%.z=.A=.B=.O&.C=.D=.E=.F=.G=.H=.I=.J=.K=.v&.L=.M=.N=.O=.P=.Q=.R=.S=.T=.U=.V=.W=.X=.Y=.Z=.`=. -..-.+-.@-.#-.$-.%-.&-.*-.=-.--.;-.>-.,-.'-.)-.!-.~-.{-.]-.^-./-.(-._-.:-.<-.cf [-.}-.|-.1-.2-.3-.4-.5-.6-.7-.8-.9-.0-.a-.b-.c-.d-.e-.f-.g-.h-.i-.j-.k-.l-.m-.n-.'+.o-.p-.q-.r-.s-.t-.u-.v-.w-.x-.y-.z-.A-.B-.C-.e-.D-.E-.F-.G-.H-.I-.J-.K-.L-.M-.N-.O-.P-.Q-.R-.S-.T-.U-.V-.W-.X-.Y-.U-.Z-.`-. ;. ", -" .;.+ + + + + + + + , # + + + + + + + + + + + + + + + + + m +;.s_ *L *{ R6 8C S} (Q a= Zc g= T6 fE @;.Cr 0C #;.$;.%;.6Q &;.-V *;.sZ =;.A .Da an U 7% j$ W. G+ j$ G+ W f V. T -;.;;.(. >;.QI Cr ,;.';.9Q T#.);.zr HG 3% <@ !;.J J J J + + + + , + + + + + + + + < < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + ~;.{;.];.^;./;.(;._;.:;.<;.[;.};.|;.1;.2;.3;.4;.5;.6;.7;.8;.9;.0;.a;.b;.c;.d;.e;.f;.g;.h;.i;.j;.k;.l;.m;.n;.o;.p;.p;.q;.5Y r;.6..s;.t;.u;.v;.w;.x;.y;.z;.A;.B;.C;.D;.E;.F;.G;.H;.I;.J;.K;.L;.M;.N;.O;.P;.Q;.R;.S;.T;.U;.V;.W;.X;.Y;.Z;.`;. >..>.+>.@>.#>.$>.%>.&>.*>.Ub $*.=>.->.;>.>>.,>.'>.)>.!>.~>.{>.]>.^>./>.(>._>.:>.<>.[>.}>.|>.1>.2>.3>.4>.5>.6>.7>.8>.9>.0>.a>.b>.c>.d>.e>.f>.g>.h>.i>.j>.k>.l>.m>.n>.o>.p>.q>.r>.s>.t>.u>.v>.w>.x>.y>.z>.A>.B>.u*.C>.D>.E>.F>.G>.H>.I>.J>.K>.F>.L>.M>.N>.`D O>.P>.Q>.R>.S>.T>.U>.V>.W>.6 .X>.Y>.Z>. ", -" `>.+ + + + + + + + < ,.+ + + + + + + + + + + + + + + + + + .,._& {. 74 Ba +,.Yv Ba Lt Y%.XU L_ @,.d+ ;&.#,.$&.8X =;.+&.$,.%,.#;.w .sZ &,.*,.bX K. k. w# V. 6! O j. |@ |@ V d+ K. =,.69 -,.;,.[C #=.%,.!=.~=.X] >,.-. i4 e9 J J J J J + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + % + + + + + + + + + + + + + + + + + + + & + + + + + + + + # ,,.',.),.!,.~,.{,.],.^,./,.G* (,._,.:,.T .<,.[,.},.E* |,.1,.2,.3,.4,.5,.6,.7,.8,.9,.0,.a,.a,.b,.c,.d,.e,.f,.g,.h,.m@.i,.m@.j,.k,.l,.m,.n,.{x o,.p,.q,.r,.s,.t,.i} u,.v,.w,.x,.y,.z,.A,.B,.C,.D,.E,.F,.G,.H,.I,.J,.K,.L,.M,.N,.O,.P,.Q,.R,.S,.T,.U,.V,.W,.X,.M,.Y,.Z,.`,. '..'.+'.@'.#'.$'.%'.&'.*'.='.-'.;'.Q` >'.,'.''.)'.!'.~'.{'.]'.^'./'.('._'.:'.<'.['.}'.|'.1'.2'.tU 3'.4'.5'.6'.7'.8'.9'.0'.a'.u-.b'.c'.d'.e'.f'.g'.h'.i'.j'.k'.l'.m'.n'.o'.p'.q'.r'.s'.t'.u'.v'.w'.x'.y'.z'.A'.B'.C'.D'.E'.F'.G'.P-.H'.I'.J'.K'.L'.at M'.N'.O'.P'.>+.Q'. ", -" R'.+ + $ + ) + + + + + + + + + + + + + + + + + + + + + + + m )h 9+ ]A S'.T'.U'.np 4% V'.49 s .s .K. Br W'.X'.W'.%,.Y'.Z'.>=.`'. )..).+).:. 6! k. K. j. k. k. s .@).c= J. (. O d+ #).$).w# %).&).*).Ar Ar =).-).,+ 2% ]& J J J J J + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + ;).>).,).').)).!).~).{).]).^)./)..- ().Q[ _).:).<).[).}).|).1).2).e;.3).4).5).6).7).e;.8).9).0).ht a).b).c).d).e).f).g).m@.4..h).i).j).k).l).m).n).o).p).q).r).s).t).u).B,.5} v).w).x).s=.y).xv z).A).B).C).D).E).F).G).H).I).J).K).N$.L).e).M).N).O).P).Q).R).S).T).U).V).W).X).Y).Z).`). !..!.+!.@!.#!.$!.%!.&!.*!.=!.-!.;!.>!.,!.'!.)!.!!.~!.{!.]!.^!./!.(!._!.:!.~.N^ ,~.'~.)~.I( !~.~~.{~.]~.^~./~.(~.3).-n _~.:~.<~.[~.}~.|~.1~.2~.3~.4~.5~.6~.7~.8~.9~.0~.a~.b~.c~.d~.e~.f~.g~.h~.i~.j~.k~.l~.m~.n~.o~.p~.q~.r~.s~.t~.z).u~.v~.w~.x~.y~.z~.A~.B~.C~.D~.E~.z8 F~.G~.6..H~.I~.J~.K~.L~.M~.N~.O~.P~.Q~.R~.S~.T~.U~.V~.W~.X~.Y~.Z~.`~. {..{.+{.@{.#{.${.%{.&{.*{.={.-{.;{.>{.,{.'{.){.!{.~{.{{.]{.^{./{.({._{.:{.<{.[{.}{.[{.|{.1{.2{.3{.4{.5{.6{.7{.8{.9{.0{.a{.b{.c{.d{.e{.f{.g{.h{.i{.e{.j{.k{.r!.l{.m{.n{.o{.p{.q{.r{.s{.t{.u{.v{.w{.x{.y{.z{.A{.B{.C{.D{.d{.E{.F{.G{.H{.I{. p ", -" Q'.+ + + + + + + + + + + + + + + + + + + + + + < $ + + + + + + + YI mS !y 74 J{.~y *A v+.69 Zv c+ 7' sZ [C K{.0C L{.M{.N{.j$ O eE O{.NN @).W!.@$.@$.T V. J. R 6! {7 6! 6% {V =,.P{.I ..=.1@ '+ *+ R6 Q{.lX R{.J J J J J J + + + + + + + + + + # + + + + + + + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + S{.T{.U{.V{.W{.X{.Y{.Z{.`{. ]..].N^ +].@].#].$].%].&].*].=].-].;].>].,].'].)].!].'].~].{].]].^]./].(]._].:].<].7~.[].}].|].1].2].3].4].5].6].7].8].9].0].a].b].c].d].A~.e].f].A~.g].h].i].j].k].l].m].n].o].p].q].r].s].t].u].v].w].x].y].z].A].B].C].D].E].F].G].H].I].J].K].L].M].N].O].P].Q].R].S].T].U].V].W].X].Y].Z].`]. ^..^.+^.@^.#^.$^.%^.&^.*^.=^.-^.;^.>^.,^.'^.)^.!^.~^.{^.]^.^^./^.(^._^.:^.<^.[^.}^.|^.1^.2^.3^.4^.5^.6^.7^.{^.8^.9^.0^.a^.b^.c^.d^.E{.e^.f^.g^.h^.i^.j^.k^.l^.m^.n^.o^.p^.q^.r^.s^.t^.u^.v^.w^.'].x^.y^.z^.A^.B^.C^.D^. p I ", -" E^.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + m F^.5= G^.H^.#).I^.g= J^.T W'.*;.#=.w .Br O T (. V. t. O T K. #( Da U d+ (. O c+ j. (. i$ R K^.L^.8C A< *{ S'.[& ^& (@ 9+ +@.b' J J J J J J + + + + + + + + ) b + ) + + + + + + + + + + + + + + @ + + + @ + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + M^.N^.O^.P^.Q^.R^.S^.T^.U^.V^.W^.X^.Y^.Z^.`^. /../.+/.@/.#/.$/.%/.&/.*/.=/.-/.;/.>/.,/.'/.)/.!/.~/.{/.]/.^/.//.(/._/.:/.(.,(.'(.)(.!(.~(.{(.](.^(./(.((._(.:(.<(.[(.}(.|(.1(.2(.3(.4(.5(.6(.7(.8(.9(.0(.a(.b(.c(.d(.e(.f(.g(.h(.i(.j(.k(.l(.m(.n(.o(.p(.q(.r(.s(.t(.u(.v(.w(.x(.y(.z(.A(.B(.C(. p ", -" I{.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + m X/ O1 D(.E(.F(.F(.*h 1l k. G(.&=.&,.$=.H(.R L. G+ I(.$( ~=.U V J. (. h+ _. W k. d+ J(.&( K(.S'.P} *L b+ s+ ~. s+ L(.Ta {^ J J J J J J + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + b + + + + + + + + + + + + + + + + M(.N(.O(.P(.Q(.R(.S(.T(.U(.V(.W(.X(.Y(.Z(.`(. _.._.+_.@_.#_.$_.%_.&_.*_.=_.-_.;_.>_.,_.'_.)_.!_.~_.{_.]_.^_./_.(_.__.:_.<_.[_.}_.|_.1_.2_.3_.4_.5_.6_.7_.8_.9_.0_.a_.b_.c_.d_.e_.f_.g_.h_.i_.j_.k_.l_.m_.n_.o_.__.p_.q_.r_.s_.$E t_.u_.v_.w_.x_.y_.z_.A_.B_.C_.D_.E_.F_.G_.H_.I_.J_.K_.L_.M_.N_.O_.P_.Q_.R_.S_.T_.U_.M` V_.W_.X_.Y_.Z_.`_. :..:.+:.@:.#:.$:.%:.&:.*:.=:.-:.;:.>:.,:.':.*(.L+ ):.!:.~:.{:.]:.^:./:.(:._:.Dk ::.<:.[:.}:.|:.1:.2:.dY 3:.4:.5:.6:.7:.8:.9:.0:.a:.b:.c:.d:.e:.f:.g:.h:.i:.R>.j:.k:.l:.m:.n:.o:.p:.q:.r:.s:.t:.u:.v:.w:.x:.y:. ", -" C(.+ + + + + + + + + + + + + + + + + + + + & + + + + + + + + + + + + + m m A/ z:.=L A:.B:.G .C:.D:.E:.F:.G:.B .i$ B .H:.kE =y IN i$ =y c+ c= I:.i$ i$ J:.s> AS *L A< K:.L:.gZ 5= /@ s+ )! e9 b' J J J J J J + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , * ] + + + + + + + + + + + + + + + + + + + + + + + + + / @ + + M:.N:.O:.P:.Q:.R:.S:.T:.U:.V:.W:.X:.Y:.Z:.`:. <..<.+<.@<.#<.$<.%<.&<.*<.=<.-<.;<.><.,<.'<.)<.!<.~<.{<.]<.^<./<.(<._<.:<.<<.[<.}<.|<.1<.2<.3<.4<.5<.6<.7<.8<.9<.0<.a<.b<.c<.d<.e<.f<.g<.h<.i<.j<.k<.l<.m<.n<.o<.p<.q<.r<.s<.t<.u<.v<.w<.x<.y<.z<.A<.B<.C<.D<.E<.F<.G<.H<.I<.J<.K<.6r L<.M<.N<.O<.P<.Q<.R<.S<.T<.U<.V<.y&.W<.X<.Y<.Z<.`<. [..[.+[.@[.#[.$[.%[.&[.*[.=[.-[._N ;[.>[.,[.'[.)[.![.~[.{[.][.^[./[.([._[.:[.<[.[[.}[.|[.1[.2[.3[.4[.5[.6[.7[.8[.9[.0[.a[.b[.c[.av j!.d[.e[.f[.g[.h[.i[.j[.k[.l[.m[.n[.o[.p[.q[._6 r[.s[.t[.u[.v[.w[.x[.y[.z[.A[.B[. ", -" C[.+ + + + + + + + + + + + + + + + + + $ + 0 / + + + + + + + + + + + + + + m sa 4V D[.E[.F[.G[.yS yS v# iE _. tZ QN H[.C .I[.3! J[.tZ _. K[.N. R+.~7 L[.M[.N[.&L w- M/ O[.5' P[.-l Q[.i= J J J J J J J + < + + + + , + + + + + + + + + + + + + + + # + + + $ + + + + + + + + + , + + + + + + + + + + + + + + + + + + & + + + + + + + + + + + R[.S[.T[.U[.V[.W[.X[.Y[.Z[.`[. }..}.+}.@}.#}.$}.%}.&}.*}.=}.-}.;}.>}.,}.'}.)}.!}.~}.{}.]}.^}./}.(}._}.:}.<}.[}.}}.|}.w/.1}.2}.3}.4}.5}.6}.7}.8}.9}.0}.a}.b}.c}.d}.e}.f}.g}.h}.i}.j}.k}.l}.m}.n}.o}.p}.q}.r}.s}.t}.u}.v}.w}.x}.y}.qB z}.A}.B}.C}.D}.E}.F}.G}.H}.I}.J}.K}.L}.M}.N}.O}.P}.Q}.R}.S}.T}.U}.V}.W}.X}.Y}.Z}.`}. |..|.+|.@|.Y< #|.$|.%|.&|.*|.=|.-|.;|.>|.,|.'|.)|.!|.~|.{|.z^.j{.]|.h,.^|./|.(|._|.:|.<|.[|.}|.||.1|.2|.3|.4|.5|.6|.7|.8|./!.9|.0|.a|.b|.c|.d|.e|.f|.&S g|.-/.h|.i|.j|.k|.l|.m|.n|.o|.p|.q|.r|.s|.t|.u|.v|.w|.x|.y|.z|.A|.B|.C|.D|.E|. F|. ", -" G|.+ + + + & + + + + + + + + + + + + + d 2 + + + + + + + + + + + + + + + + + { m H|.I|.=+ J|.Y] ;,.);.K|.%).L|.M|.{V Tt $$.I[.N|.R+.~+ O|.`_ P|.Q|.W- R|.R6 S'.^& jX S|.Z1 T|.M~ J J J J J J J + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + U|.+ + + + + + + + + + + V|.W|.X|.Y|.Z|.`|. 1..1.+1.@1.#1.$1.%1.&1.*1.=1.-1.;1.>1.,1.'1.)1.!1.~1.{1.]1.^1./1.(1._1.:1.<1.[1.}1.|1.11.q,.21.w^.31.41.7_.51.61.71.81.91.01.a1.b1.c1.d1.e1.f1.g1.l/.h1.i1.j1.k1.l1.m1.n1.o1.p1.q1.r1.s1.t1.u1.v1.w1.w1.x1.y1.z1.A1.B1.C1.D1.E1.F1.G1.Xd H1.I1.J1.K1.L1.M1.N1.O1.P1.Q1.R1.S1.T1.U1.);.V1.W1.X1.Y1.Z1.`1.Gz 2..2.+2.@2.#2.$2.%2.&2.*2.=2.-2.;2.>2.,2.'2.)2.!2.~2.{2.]2.^2./2.(2._2.:2.<2.[2.}2.|2.12.22.32.{(.42.52.62.72.82.92.02.a2.b2.c2.d2.e2.f2.g2.h2.i2.j2.k2.l2.m2.n2.o2.p2.q2.r2.s2.t2.u2.v2.w2.x2.y2.z2.A2.B2.C2.D2.E2.F2.G2.H2.I2. ", -" J2.+ + + + + + + + + + + + + + + + # + + & + + + + + + + + + + + + + + + + + 2 + + + m K2.V}.L2.E[.M2.yS X'.);.;&.N2.=,.=,.O2.;,.]y P2.Q2.P2.gZ R2.S2.T2.P~ U2.V2.W2.z] J J J J J J J + + + + + + + + + + @ + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + = $ , , + + + + + + + @ 3 + + + + + + + + + + + + + + X2.Y2.Z2.`2. 3..3.+3.@3..3.#3.$3.%3.&3.*3.=3.-3.;3.>3.,3.'3.Uk )3.!3.~3.{3.]3.E,.^3./3.(3.O;._3.:3.<3.[3.}3.|3.13.23.33.43.7_.53.]>.63.73.83.93.03.a3.b3.F%.c3.2|.d3.e3.f3.g3.h3.i3.j3.k3.l3.m3.n3.o3.p3.q3.r3.s3.t3.u3.v3.w3.x3.y3.z3.A3.B3.C3.D3.E3.F3.G3.H3.I3.J3.K3.L3.M3.N3.O3.P3.Q3.R3.S3.T3.U3.V3.W3.X3.Y3.Z3.`3. 4.|Y .4.+4.@4.#4.$4.%4.Q3.&4.4z *4.=4.-4.;4.>4.,4.'4.)4.!4.~4.{4.]4.^4./4.(4._4.:4.<4.[4.}4.|4.14.24.34.44.54.64.74.84.94.04.a4.P_.b4.c4.d4.e4.f4.g4.h4.i4.j4.k4.l4.m4.n4.o4.p4.q4.r4.s4.t4.u4.v4.w4.x4.y4.z4.A4.B4.C4.D4.E4.F4.G4.H4.I4. ", -" J4.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , ) + + m m m 'C 8p K4.:h L4.M4.M4.:h N4.O4.)7 O/ 4' s+ ^& -. r# $+ P4.Q4.z] J + J J J J J J + @ @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + e + + + + + + + + + + + + + + R4.S4.T4.U4.V4.W4.X4.Y4.Z4.`4. 5..5.+5.@5.#5.#5.$5.p[.%5.&5.*5.=5.-5.;5.c3.>5.,5.'5.aG )5.!5.~5.{5.]5.^5./5.(5._5.:5.<5.[5.}5.;< |5.15.25.35.45.55.65.75.85.95.05.a5.b5.c5.d5.e5.f5.g5.C(.h5.i5.j5.k5.l5.m5.$2.n5.o5.p5.q5.r5.s5.t5.u5.v5.w5.x5.b` y5.z5.A5.B5.C5.D5.E5.F5.G5.H5.'Y I5.J5.K5.L5.M5.N5.O5.P5.Q5.R5.YJ S5.T5.U5.V5.W5.X5.Y5.Z5.`5. 6..6.+6.@6.#6.$6.%6.8(.&6.^G *6.=6.-6.;6.>6.,6.//.'6.)6.!6.~6.{6.]6.^6./6.(6._6.:6.<6.[6.}6.|6.16.26.36.46.+^.56.66.76.86.96.06.a6.b6.c6.d6.e6.f6.g6.h6.i6.j6.k6.l6.m6.n6.o6.p6.q6.r6.s6.t6.u6.v6.w6.x6.y6.z6.J2. ", -" A6.+ + + + + + + + + + @ + + + + + + + + + + + + + @ + + + + + + + + + + + + + # + + + + $ + + m m m 5. B6.C6.)@ D# `} sp D6.eG E6.Z< F6.m m + < + + + = + + + + + @ + + + + + + # + + + + + + + + + + + + + + + + + + + + + + + h + + + + + + + + + + + + + + + + + + + + + + < + + + + + $ + + + + + + + + + + G6.H6.I6.J6.K6.L6.M6.N6.O6.P6.Q6.R6.S6.T6.U6.V6.W6.X6.Y6.p~.Z6.`6. 7..7.+7.@7.#7.$7.%7.&7.*7.=7.-7.;7.=;.>7.,7.'7.e3.)7.36.!7.~7.{7.]7.^7.=/./7.(7._7.:7.<7.[7.}7.|7.17.27.37.47.8|.57.C[.67.77.87.F1.97.n2.07.a7.b7.c7.d7.e7.f7.g7.h7.i7.j7.k7.l7.m7.n7.o7.p7.q7.r7.s7.t7.u7.v7.w7.x7.y7.z7.A7.B7.C7.D7.E7.F7.G7.H7.I7.J7.K7.L7.M7.N7.O7.P7.Q7.R7.S7.T7.U7.V7.W7.X7.Y7.ND Z7.`7. 8..8.+8.@8.#8.$8.%8.&8.*8.=8.-8.;8.>8.,8..(.'8.)8.!8.~8.{8.]8.^8./8.(8._8.:8.X<.<8.[8.}8.|8.18.28.38.48.58.68.78.88.{P 98.08.a8.b8.c8.d8.e8.f8.g8.h8.i8.j8.k8.l8.m8.n8.o8..{.p8.q8. I ", -" r8.+ + + + + b ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %. + + , + + + + + + + + < + + + + + + + + + + + + + + + + , # $ + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s8.t8.u8.v8.w8.x8.y8.z8.A8.B8.C8.D8.E8.F8.G8.H8.I8.J8.K8.L8.M8.N8.O8.P8.Q8.R8.S8.T8.U8.V8.W8.X8.Y8.Z8.`8. 9.'|.1(.m[..9.+9.@9.#9.$9.%9.&9.=8.*9.=9.-9.l0 ;9.>9.,9.'9.)9.!9.~9.{9.]9.^9./9.(9._9.:9.<9.[9.}9.|9.19.29.39.49.59.h7.69.79.89.99.09.a9.b9.c9.d9.e9.>*.f9.g9.h9.i9.j9.k9.l9.m9.n9.o9.p9.q9.r9.s9.t9.u9.v9.w9.x9.y9.z9.A9.B9.C9.D9.E9.F9.G9.H9.I9.J9.K9.L9.M9.N9.O9.-X P9.Q9.R9.S9.T9.U9.V9.W9.X9.Y9.Z9.`9.b6. 0..0.+0.@0.#0.$0.%0.DW &0.*0.=0.p&.-0.;0.>0.,0.'0.)0.!0.~0.{0.]0.^0./0.(0._0.:0.<0.[0.}0.|0.10.20.30.40.50.60.70.80.90.00.a0.b0.c0.d0.e0.A6. ", -" f0.+ + @ + + + + + @ { g0.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / / + + + + + + + b + + + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + h0.i0.j0.k0.l0.m0.n0.o0.p0.q0.r0.s0.t0.u0.v0.w0.x0.y0.z0.A0.B0.C0.D0.E0.F0.G0.H0.I0.J0.K0.L0.M0.N0.O0.P0.Q0.R0.S0.a[.T0.U0.V0.W0.X0.o=.Y0.Z0.`0. a..a.+a.@a.#a.$a.%a.&a.*a.=a.-a.;a.>a.,a.'a.)a.!a.X8.1..~a.{a.]a.^a./a.(a._a.:a.b.,b.'b.)b.!b.~b.{b.]b.^b./b.(b._b.:b.c.,c.'c.)c.!c.~c.{c.]c.^c./c.(c._c.:c.d.,d.*Q 'd.)d.!d.~d.{d.]d.^d./d.(d._d.:d.e.,e.'e.)e.!e.~e.:0.{e.]e.]e.e9.^e./e.(e._e.:e.f.,f.'f.)f.!f.~f.{f. ", -" ]f.= + + + + = + + + + + + + + + + + + + + & + + + + + + + + + + + + + + + + + + + + + , + + + # # + + + + + + + + + + ] + + + + + + @ + + + + # + # + + # + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # ) + + + + + + + + + + + + + + + + + + + + + + ^f./f.(f._f.:f.g.,g.'g.)g.!g.~g.{g.]g.^g./g.(g._g.:g.h.,h.'h.)h.!h.~h.{h.]h.^h./h.(h._h.:h.i.,i.'i.)i.0b.!i.~i.{i.]i.^i./i.(i._i.]8.:i.)d.j.,j.'j.)j.!j.~j.{j.]j.^j./j.(j.of._j.:j.k.,k.'k.)k.!k.~k.{k.|j.]k.^k./k.(k._k.:k.l.,l.'l.)l.0b.!l.0b.~l.{l.]l.Id.^l./l.@a.(l._l.>6.:l.m.,m.'m.)m.!m.~m.{m.]m.^m./m.(m._m.:m.0U n.,n.'n.%b.)n.!n.~n.{n.]n.^n./n.(n._n.:n.o.,o.'o.)o.!o.~o.{o.]o.^o./o.-o.(o._o.:o.p._Y ,p.'p.kl.)p.!p.~p.{p.]p.^p./p.(p._p.)p.:p.q.,q.'q.)q. ", -" il + + + + + + + + + + + + + + < @ + + + + + + + + + + + + + + # < + + + + + + + + + + + + + + = b + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + !q.~q.{q.mm.]q.^q./q.(q._q.:q.r.,r.'r.)r.!r.~r.{r.Wu ]r.^r./r.(r._r.:r.s.,s.'s.)s.!s.~s.{s.]s.^s./s.(s._s.:s.Mg.t.,t.'t.)t.!t.~t.{t.]t.^t.@o./t.(t._t.:t. + , + + + # + Z. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pt.qt.rt.st.tt.ut.vt.wt.xt.yt.zt.At.Kf. k.Bt.Ct.Dt.Et.Ft.Gt.Ht.It.Jt.|S Kt.Lt.Mt.Nt.Ot.Pt.Qt.Rt.St.We.Tt.Ut.Vt.Wt.Xt.Yt.Mn.ns.Mn.Zt.=m.`t. u.ps..u.+u.ns.@u.#u.Ss $u.%u.&u.*u.=u.-u.;u.lp.hk.>u.,u.'u.)u.vF $W !u.~u.{u.]u.^u.0W /u.(u._u.:u.v.,v.'v.)v.!v.~v.{v.]v.Xt.^v./v.(v._v.:v..f.r.Dv.Ev.[r.Fv.tp.Gv.Hv.S@ Iv.Jv.Kv.Lv.Mv.Nv.Ov.Pv.Qv.Rv.Sv.Tv.Uv.=p.Vv.Wv.Xv.Yv.Yv.w+ :j Zv.`v. w.e4 Xv..w.mp.+w.@w.#w.$w.%w.&w.*w.=w.-w.;w.>w.,w.,q.Pp.'w.;q.Gr.Hr.)w.!w.~w.yu.{w.]w.^w.au./w.(w._w.:w. + + + + + + + + + + + + + + + + + + + + , + + + + + + , + + > + + + + + + + + ] + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + iw.6I jw.kw.lw.'v.mw.nw.ow.~v.pw.qw.rw.sw.Et.tw.uw.vw.ww.x.%r.{&.,x.'x.Xq.)x.!x.~x.1r.{x.]x.>x.^x./x.(x._x.B. :x.q.1o.lx.mx.nx.ur.ox.px.qx.rx.sx.Eu.tx.ux.vx.wx.xx.yx.zx.Ax.Bx.zu.Cx.Dx.Nu.Ex.Fx.0w.Gx.Hx.+v.J) Ix.J) x' x' v.Jx.+v.J) Uu.x' cw.bw.0w.nx.Kx.Lx.+v.0w.Mx.Mx.Nx.bw.bw.Ox.Mx.Mx.Px.Mx.Px.Qx.Rx.Sx. K+ ", -" #w + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Z. + + + + + + + + + + + + + + + + + + + + + + + : + + + + + + $ $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + Tx.Ux.Vx.Wx.Xx.Yx.Zx.`x. y..y.+y.+y.@y.#y.$y.%y.&y.*y.=y.-y.;y.>y.zw.,y.'y.)y.:m.!y.~y.{y.]y.^y.Gi.wr./y.(y._y.:y.z.,z.'z.px.)z.J) Ox.Fx.Ox.Ix.Ix.bw.Ox.Px.!z.!z.Mx.Ix.Lx.bw.K+ Mx.Mx.Px.Px.Px.Rx.Px.Px.Px. ", -" 5Z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mx.~z.{z.]z.^z./z.(z._z.:z.q.kz.lz.mz.nz.oz.Ps.pz.qz.rz.sz.tz.uz.vz.wz.vx.xz.yz.zz.Az.Bz.Cz.Tq My.lr..z.{x.Dz.Ez.Fz.Ky.Gz.=w.Hz.mg.Eu.Iz.Jz.Kz.^Y |r.Lz.Mz.Nz.Oz.Pz.Qz.Rz.Sz.Tz.Uz.Vz.Wz.Xz.Yz.Zz.`z. A..A.pu.+A.@A. W #A.$A.%A.&A.*A.=A.-A.;A.>A.,A.'A.'A.)A.!A.~A.-q.7t.Gr.Gr.{A.~w.ox.]A.^A.nx.ew./A.Lx.(A.Lx._A.:A.A.wu.PA.QA.RA.SA.+A.TA.UA.VA.WA.V%.XA.YA.ZA.;A.`A.ny. B..{ .B.Bx.+B.@B.#B.$B.+B.%B.&B.*B.=B.-B.;B.Wz.My.>B.,B.'B.)B.|w.!B.~B.'A.{B.]B.^B./B.(B.)B._B.,z.:B.=z.(B.3w.:B.C.,C.'C.)C.!C.!C.~C.Lx.Dx.Lx.!B.Kx. F|. F|. F|. p F|. ", -" + + + + + + + + $ + + + + + + > + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + $ $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + J) {C.]C.^C./C.(C._C.:C.:o.A.CB.xC.yC.zC.fC.AC.BC.CC.Ty.DC.EC.FC.GC.rx.HC.IC.JC.KC.KC.LC.CN b' MC.NC.pC.gw.OC.PC.PC.QC.RC.SC.'z.TC.UC.VC.QC.WC.XC.hw. UC. p p I F|. p F|.I ", -" F|. $ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + YC.ZC.`C. D..D.+D.2y.@D.6z.#D.$D.%D.&D.*D.=D.-D.nA.;D.>D.%D.vr.Ir.#q.Pu.6t.9t.,D.ct.Qu.6t.Qu.Ru.'D.at.Uu.Uu.Tu.)D.!D.~D.~A.'D.MB.jt.7w.kt.{D.0w.+v.nx.Dx.hw.]w.Kx.fC.%z.]D.hC.+z.^D.pr.zx. A.Qz.(B.-C.GC.Ju.zu./D.(D.AC._D.7w.(D.:D.AC.tx.KC.E. ", -" I + + + + + + + + q8.,E.ln 'E.`*.)E.kx.+ + + # + , + + $ = + + + # + + + + + + !E.~E.~E.~E.~E.~E.{E.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , c + + + + + + + + + + ]E.^E.O> + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + = + + + + + + + + + + + + + I p p I /E.(E. p /E.(E.p I F|. p p F|.p I p 4o.E|._E.:E.. . . . . . . . . . . . :E. = [ + + + + !E.|E.n .. . . . . 1E.+ + + + + + + + + + + + + 2E.3E.+ 4E.5E.O> + + + + + + + + + + + + $ + + + + + + + + + O> 6E.7E.8E.+ + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + F|. p 9E.0E.aE. 9E.0E.aE. bE.cE. dE. F|. p I n I )q.D^.ln . . . . . . . . . . . . . . . . . . ~e eE.4o. I ", -" # + + + + + fE.. . . . . . . . gE.+ + # + + + & * & = - hE.iE.jE.kE.Z>.lE.mE.. . . . . . . nE.+ + + + + + + + + + + + + oE.pE.qE.rE.sE.tE.+ + + + + + + + + + + + + + + + + + + + + + + uE.vE.wE.+ + + + + + xE.yE.zE.O> + + 4E.AE.BE.CE.+ + + + + + + , DE.EE.FE.GE.+ + + + + + O> HE.IE.JE.O> + + + + + + KE.LE.ME.NE.OE.PE. QE.RE.SE.TE.UE.VE. bE.WE.XE. bE.WE.XE.F|. F|. p KE.LE.ME. QE.RE.SE. KE.YE.ZE.`E. F.PE. I p p I #w .F.,l . . . . . ln `>.+F.@F.1c.]e.]e.1c.@F.+F.`>.ln . . . . . ,l C(.#w I ", -" + + + + + #F.O#.. . . . . . . . . $F.+ + + + + + + = - ! %F.. . . . . . . . . . . . . &F.+ + + + + + + + + + + + + oE.*F.=F.-F.;F.~; >F.,F.'F.)F.O> oE.pE.!F.~F.{F.]F.yE.zE.^F./F.(F._F.*F.:F. + >F.,F.'F.)F.O> + gF.hF.iF.O> + / + + + = KE.LE.ME.NE.OE.PE.jF.kF.lF.mF. KE.LE.ME.NE.OE.PE.nF.oF.lF.pF.qF. QE.RE.SE.TE.UE.rF.sF.tF.uF.aE. vF.wF.xF.yF.zF.sF.tF.uF.aE. jF.kF.lF.mF. KE.YE.AF.BF.CF. vF.wF.xF.yF.zF. I F|. KE.LE.ME. QE.RE.SE. KE.LE.ME.DF.EF. F|. F|. FF..;.. . . . ~e GF.HF.O~ O~ HF.Z>.'E.. . . . .;.FF. ", -" I + + + + + IF.. . . . . . . . . . JF.+ + + + + + + = ( _ KF.. . . . . . . . . . . . . LF.+ + + + + + + + + + + + + oE.*F.=F.O> O> xE.yE.MF.^F.NF.OF._F.*F.:F. 6E.7E.8E.$ oE.*F.:F. WF.XF.YF.ZF.`F. G.+ + .G.+G.@G.+ < + + + + KE.LE.#G.NE.OE.$G.RE.SE.TE.UE.rF.KE.YE.%G.&G.*G.=G. TE.UE.rF. QE.RE.-G.TE.UE.rF. 9E.0E.aE. QE.RE.SE. 9E.0E.aE. QE.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.$G.RE.SE. I I p I KE.LE.ME. QE.RE.SE. KE.LE.ME. F|. F|.I I I q8.;G.. . . 'E.O!.em. em.O!.'E.. . . ;G.q8. ", -" + + + + + >G.. . . . . . . . . . ,G.+ + + + + + + [ } ! %F.. . . . . . . . . . . . . 'G.+ + + + + + + + + + + + + )G.!G.=F.~G.{G.xE.yE.zE.^F.NF.OF.oE.*F.:F. 6E.7E.8E.+ oE.*F.:F.(G.[F.7F.yE.zE.^F.NF.OF.4E._G.VF.CE.+ + + + + + + 4E.AE.VF.CE.O> xE.yE.zE.O> + + + + .G.+G.@G.+ + + + + + KE.LE.ME.:G.OE.$G.RE. 6E.7E.8E.+ oE.*F.:F. + + + + + 4E.AE.VF.CE.sG.F-.XF.YF.ZF.`F. G.+ + .G.+G.@G.+ + + + + + KE.tG.uG.vG. F.$G.RE.SE. KE.LE.ME. F|.QE.RE.SE.TE.UE.rF. QE.RE.wG.xG.yG.rF. 9E.0E.aE. I TE.UE.rF. 9E.0E.aE. QE.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.PE. I TE.UE.rF. zG.AG.BG.CG. KE.LE.ME.F|. QE.RE.-G. KE.LE.ME.NE.OE.PE. DG.EG.FG. p p F|. cG.:E.. . :E.C[. F|. C[.:E.. . :E.GG. I ", -" + + + + + + HG.. . . . . . . . ~e IG.+ + + + + + + + $ = JG.KG.LG.MG.'E.. . . . . . . . . NG.+ + + + + + + + + + + + + OG.PG.!F.QG.RG.SG.TG.UG.'F.9F.VG.oE.pE.!F.WG.@G.XG.TG.UG.'F.9F.0F.oE.YG.=F.+ + ZG.|F.1F.`G. H..H.4E.+H.!F.6F.sE.7F.yE.zE.^F.NF.OF.O> HE.@H.#H.$H.%H.+ + + + + O> &H.*H.=H.O> + >F.,F.'F.)F.-H.$ ;H.>H.,H.'H.+ + + + + )H.!H.~H.{H.p ]H.WG.xF.^H. KE.LE.ME. p ]H.WG.lF.3G.rF. /H.(H._H.:H. sF.tF. + + + + + + + + + + + + + O> + + / + + + + gF.hF.iF.hH.+ + + + + F|. iH.jH.kH. F|. p I F|. F|. nB ;G.. . 0l *g. f0.0l . . ;G.nB F|. p I ", -" + + + + + + + lH.0l . . . . mE.mH.#F.+ + + + + + + + + $ + 9 + + + nH.. . . . . . . . :E.+ + + + + + + + + + + + + + + + + + + + + + # # + oE.oH.pH.= O> qH.rH.sH.tH.3E.+ + + + + + + + + $ + + uH.vH.wH.QG.RG.~; + + + + + + + + & + + + + @ + + + & xH.yH.zH.+ + + , , + O> AH.BH.CH.= + + + + + I F|. I I DH.EH.FH. p I I F|. I A] p F|. #w dG.. . :E.cH. F|. F|. cH.:E.. . }E.O~ I ", -" + + + + + + + + GH.KG.HH.Z*.IH.JH., + + + + + + + + + + + + + + + + KH.. . . . . . . . ln + + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + + + + # + + + + + + + + + + + + + + + @ + + + + + + + + $ + + , + + + + + + c + + + > + + + + + + + + + + + + + + + I p p F|. F|. F|. p p C(.. . . C[. I p p p C[.. . . C(. ", -" + + + + + + + + + , + + + + & + + + + + + + + + + + + + + + + LH.. . . . . . . . MH.+ + + + + + + + + + + + + + + + + + + + + + + + + @ + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + + + + + + + + + + + + + + F|. n I p p p F|. F|. NH.,l . . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9E.0E.aE. I p p p I I I F|. I p p F|. I 4o.ln . . mH. I F|. @h.&I.ln . . . . . . n .U%.. . . . N#.;G.. . . . . . :E.Z*.*I. O!.. . ln NH. F|. ", -" + + + lH.=I.:E.. . . . . . . . . . -I.$ ;I.N#.. . . . . . . . . . . . . . . . . . . . T%.+ + + + + = + + + + + + + + >I.,I.'I.)I.!I.~I.yE.zE.O> + + + 2E.{I.]I.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + O> F.^I./I.+ + + + + + + + + + + (I._I.:I. I bE.WE.XE. p xE.yE.bI.'F.9F.0F.uH.cI.dI.iF.O> O> eI.fI.wH.gI.hI.+ + + # + xE.yE.bI.'F.iI.jI.oE.*F.:F.F.,F.'F.)F.O> 4E.+H.!F.6F.sE.7F.yE.zE.^F.NF.OF.4E.+H.!F.WG.@G.ZG.kI.lI.mI.nI..H.+ + + + + + >F.,F.'F.mF. oI.AF.pI.6H.QE.RE.. A6.;G.. . . 'E.HI.2j. &v.. . . . Hk. II.I2.}E.. . . :E.8I. P!.. . Z*. ", -" I + + + JF.. . . . . . . . . . . . JI.n .. . . . . . . . . . . . . . . . . . . . . . KI.' + + + + + + + + + + + + + + gF.hF.iF.O> xE.yE.zE.^F.NF.OF.O> gF.hF.iF.LI.xE.yE.zE.O> < / + + + @ + xE.yE.zE.^F.NF.OF.oE.pE.RF.SF.TF.MI.yE.zE.^F.NF.OF.oE.*F.:F.F.^I./I.+ + + + + + + WF.XF.TI.ZF.UI.VI.KE.LE.GI.NE.OE.$G.RE.SE.TE.UE.rF. (I._I.:I. TE.UE.rF. 9E.0E.aE. QE.RE.SE.TE.UE.rF.KE.LE.ME. KE.LE.ME. QE.RE.SE.TE.UE.rF.qI.rI.sI.tI.}H.uI.jF.2I.3I.F|. KE.LE.WI.XI.EI.FI. TE.UE.rF.KE.YE.%G.&G.*G.YI.RE.SE.TE.UE.rF.I I F|. I F|. >E.:E.. . HF. G|.n .. . mE.&I.@I. p #w . . . . NH. ZI.N#.. . . IH.p `I.. . n .Hk. I ", -" + + + J.. . . . . . . . . . . ln JI.. . . . . . . . . Z*..J.&I.m .. . . . . . . . . . I+ + + + + + + + + + + + + + + + +J.hF.iF.O> xE.yE.zE.^F.NF.OF.O> gF.hF.iF.O> O> @J.#J.$J.%J.&J.+ + + + + xE.yE.zE.^F.NF.OF.oE.*F.=F.+ + xE.yE.zE.^F.NF.OF.oE.*F.:F. O> O> >F.^I./I.+ + + + + + + xE.yE.zE.O> KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF. (I._I.:I. 1G.2G.lF.3G.rF. 9E.0E.aE. QE.RE.SE.TE.UE.rF.yI.=J.-J.;J.>J. yI.=J.-J.;J.,J.QE.RE.SE.TE.UE.rF. (I._I.:I. jF.2I.3I. KE.LE.WI.XI.EI.'J.)J.2G.lF.3G.rF.KE.LE.ME. QE.RE..,l . . . . . . . . {J.RH.. . . . . . . 'E.nE.+ + + *w.]J.. . . . . . . . . RH.+ + + + + + + + + + + + + + + gF.hF.iF.O> xE.yE.zE.^F.NF.OF.O> gF.hF.iF.O> O> O> O> ^F.NF.OF.+ + + + + xE.yE.zE.^F.NF.OF.oE.*F.=F.+ + xE.yE.zE.^F.NF.OF.oE.*F.:F.F.^I./I.+ + + + + + + WF.XF.YF.ZF.UI.VI.KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF. (I._I.:I. QE.RE.SE.TE.UE.rF. 9E.0E.aE.I QE.RE.SE.TE.UE.rF. NE.OE.^J. NE.OE.$G.RE.SE.TE.UE.rF. (I._I.:I. jF.2I.3I. /J.(J._J.:J... . ;E.p p ", -" + + + + + + |J.,l . . . . . . ~e 1J.RH.. . . . . . . 2J.+ + + > + + KG.. . . . . . . . IH.+ + + + + + + + + + + + + + + gF.hF.iF.O> xE.yE.zE.^F.NF.OF.uH.3J.4J.5J.eF.6J.|F.wH.'F.9F.0F.+ + + + # xE.yE.bI.'F.)F.O> oE.*F.=F.+ + XG.TG.UG.'F.9F.0F.7J.8J.!F.6F.sE.9J.TG.UG.'F.0J.OF.4E.+H.!F.WG.@G.+ aJ.bJ.mI.nI..H., + + + + + >F.,F.'F.mF. 8H.9H.AF.BF.CF.QE.RE.SE.TE.UE.rF. )H.cJ.tI.}H.2H.]H.WG.lF.3G.rF.sF.tF. + + + + + + + + + $ + + : + + + + + + + + + + ) ] + + + + + + + + + + + + + + + + + + + F|. I F|. I F|. A] F|. U%.. . pJ. qJ.. . rJ. 'E.. . . II. 2j.. . eE. 5I.. . U%. ", -" + + + + + + + E|.. . . . . . sJ.+ RH.. . . . . . tJ.+ + + # - + + nJ.. . . . . . . . D^.+ + + + + + + b % + + + + + + , $ , + + + + + + + + + + + + + + + + + + + + + + + xE.yE.zE.O> + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + I I I F|. F|. I p F|. p I I p I ;G.. . cH.F|.TH.. . @h. F|.~e . . . 4o. I ;G.. mH. cH.. . .I. ", -" + + + + + + + uJ.. . . . . 0l kx.+ RH.. . . . . m .#F.+ + + b h + + nJ.. . . . . . . . )E.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + ^ + < , + + + + + + + + + + + + + > + + + + + + , + + + + + + + + + + F|.I F|. I I p I p A] ~e . . vJ. ]e.. . wJ. p 0l . . . Hk. I m .. xJ. vJ.. . ~e ", -" + + + + + + + yJ.. . . . . _E.+ + RH.. . . . . gE.+ + + + = + + + nJ.. . . . . . . . 0I.+ + + + + + + + + + + + + + + + + + + + + + + + + @ + + + + + + , + + l + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + + + > + + p F|. p I I A] p I I I ~e . . vJ. 5Z }J.. cG. p 0l . . . NH. F|. UH.. ZH.Qr. vJ.. . ~e ", -" + + + + + + + zJ.. . . . . Z>.+ + RH.. . . . . C(.+ g @ + + + + + nJ.. . . . . . . . 2J.+ + + + + + + + + @ + + + + + + + + + + + + , + + < + + + + + + + + + @ + + + + + # + + + + + + + + + + + c + + + + + + + + + + + + + + + , + + + + + + + + + + + # + + + + + + + /E.(E.I I I I I I F|. p F|. I ;G.. . cH. r8.n .}E.5Z p 0l . . . II. I I HI.mE.J4. cH.. . .I. p ", -" + + + + + + + AJ.. . . . . BJ.+ + RH.. . . . . CJ.+ + @ + + + + + nJ.. . . . . . . . DJ.+ + + + + + + + + + + + + + + + + , + + + + + + + + @ + + + + + + + + + + + + + + @ + + + + + # + + + + < % + + + + + & + + + + + > + + + + + + + + + + + + + + + + , + + + + + = p 9E.0E.aE. EJ. FJ.cE. I U%.. . mJ. F|.p GG.n .;E. p 0l . . . II. J2.n .E|. mJ.. . U%. ", -" F|. N@ . . . . . E^. RH.. . . . . GJ. F|. F|. O~ . . . . . . . . A6. (I._I.:I. QE.RE.SE. HJ.IJ.JJ.aE. nF.KJ.LJ.MJ.NJ. bE.OJ.XE. F|. TE.UE.rF. QE.RE.PJ.QJ.RJ.SJ. nF.KJ.LJ.MJ.NJ. (I._I.:I. p F|. p /H.(H._H.:H. F|. JI.. . E^. vJ.MH.E^.#w p 0l . . . 4o. F|. p 0I.m .1c. +F.. . JI. ", -" 'E.. . . . HI. RH.. . . . . cG. F|. O~ . . . . . . . . OH. qI.rI.sI.tI.}H.uI.jF.kF.lF.mF. oI.AF.pI.6H.QE.RE.K.kF.lF.mF.F|. F|. +F.. . Z*.I NH.[E.,E.,K. 0l . . . Hk. ]f.R'.&I.em. Z*.. . +F. ", -" O#.. . . . _E. RH.. . . . . C(. O~ . . . . . . . . {f.A] F|. (I._I.:I. QE.RE.SE.TE.UE.rF.'K.)K.ME.!K.~K.{K.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF. 9E.0E.aE. QE.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF. yI.zI.AI.BI.yF.zF.KE.YE.%G.&G.*G.YI.RE.SE.TE.UE.rF.KE.LE.WI.XI.EI.FI. I 9E.0E.aE. QE.RE.SE.TE.UE.rF. p ]K. ^K./K.(K. KE.LE.ME.NE.OE.3H.zI.AI.BI.yF.zF. (I._I.:I. QE.RE._K.:K.E. #w cG.m .. . . . . . . . . 4I.|d. F|. I I ]K. I sF.eJ.xF.BF.HK.IK.JK.KK.LK.cE. MK.NK.OK. F|. I I I I +F.. . 'E.lJ. F|. s7.. . h5. L2.'E.. . I1. ]K. ", -" I y:.4I.. . . . . . . . . O#.)q.O~ I2.-E.'E.. . . . ,l R'. ;.PK.. . . . . . . . . . . . . }J.B[. p p I F|. F|. F|. F|. I I F|. I Ui.0l . . +I.5Z I QK.. . ]e. L.,L.'L.)L. . p gE.PK.RH.RH.RH.dG..I. HF.. MH. 9E.0E.aE. QE.RE.SE.TE.UE.rF. 0H.-K.;K.F|.KE.LE.ME. 8L.4K.5K.6K.UI.VI.KE.LE.ME.NE.OE.$G.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.PE.I 0H.-K.;K. KE.LE.ME.NE.OE.yL.RE.SE.TE.UE.rF.KE.LE.ME.NE.OE.PE. (I._I.:I. 8L.4K.5K.6K.UI.VI. 9L.0L.6H. zL.AL.BL. jF.CL.DL.EL.%K.&K.(I.FL.GL.EI.FI.HL.CL.DL.EL.%K.&K. F|. 0H.-K.;K. KE.LE.ME.NE.OE.PE.p IL.JL.KL.LL.ML.YI.RE.SE.TE.UE.rF. (I._I.:I. jF.2I.NL. /J.(J._J.:J.. gE.AK.eE.eE.eE.dG.O#. I I wJ.TH. lH.. N#. I sF.tF.M.-E. &I.PK. vJ..;. E|.. ,E.p p I p TE.UE.rF. zG.,M.'M.)M. 9E.0E.aE. 9E.0E.aE. F|. p F|. F|. p iH.jH.kH. F|. F|.F|. em.E^.;G.. . . . . . . . . . . . . . . . . . ;G.I1.em. I ", -" +I.. . . ,K. O~ . . . X. !M.;G.eG. Pm.]L. *I.~e r+. ~M.Z*. rJ.. ;. p p p p yI.1H.xF.lF.pF.{M.]M.^M./M.(M. _M.:M.M.eE.eE.eE.mE.. . PL.eE.eE.eE.eE.eE..PK.RH.RH.RH.`*.. D^. p I p p p I I F|. I I ]K. F|. I I F|. p II.q8.GK.JI.`*..I.0l ,l MH.U%.-E.+F.1E.NH. F|. p ", -"F|. II.R'.0l . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . :E.O#.HI.N@ I I p p I F|. I I I p I I I I F|. p p F|. p I p I F|.", -" F|. I I p F|. p p p p F|. I p I p I p I p ", -" I F|. F|. p I p I I I I p F|. F|. I ]K. p F|. I F|. F|. p p p F|. F|. I p ", -" p p F|. I I p I I F|. F|. I I F|. ", -" I F|. F|. I I F|. F|. F|. F|. F|. p F|. p I F|. p ", -" I p F|. F|. I p p F|. I F|. p F|.I I F|. p F|. p p F|. F|. I I ", -" p p p F|. I F|. F|. F|. I I I I F|. p p p F|. F|. p ", -" F|. F|. p I F|. F|. F|. I F|. I F|.I F|. I p p I p F|. I ", -"p I p F|. I p p p p F|. p p p I F|. p I p F|. I p p F|. "}; diff --git a/resources/bitmaps/texture_browser.xpm b/resources/bitmaps/texture_browser.xpm deleted file mode 100644 index 21edf5e..0000000 --- a/resources/bitmaps/texture_browser.xpm +++ /dev/null @@ -1,83 +0,0 @@ -/* XPM */ -static char * texture_browser_xpm[] = { -"16 16 64 1", -" c None", -". c #00CBED", -"+ c #00CBEB", -"@ c #00C9F3", -"# c #86FFFF", -"$ c #88FFFF", -"% c #65F2FC", -"& c #66F2FC", -"* c #00C9F7", -"= c #8CFFFF", -"- c #8AFFFF", -"; c #69F1FD", -"> c #68F1FE", -", c #69F2FE", -"' c #69F1FE", -") c #00C7F7", -"! c #00C5FD", -"~ c #90FFFF", -"{ c #8EFFFF", -"] c #6CF1FF", -"^ c #00C5FF", -"/ c #00C1FF", -"( c #6BF0FF", -"_ c #00BDFF", -": c #69EFFF", -"< c #68EFFF", -"[ c #69EEFF", -"} c #00BBFF", -"| c #00B7FF", -"1 c #66EDFF", -"2 c #65EDFF", -"3 c #00B3FF", -"4 c #63ECFF", -"5 c #84FFFF", -"6 c #00B5FF", -"7 c #00ADFF", -"8 c #62EBFF", -"9 c #60EBFF", -"0 c #80FFFF", -"a c #82FFFF", -"b c #00AFFF", -"c c #00A9FF", -"d c #5FEAFF", -"e c #5DEAFF", -"f c #7CFFFF", -"g c #7EFFFF", -"h c #00A5FF", -"i c #5CE9FF", -"j c #5AE9FF", -"k c #5CE8FF", -"l c #7AFFFF", -"m c #00A3FF", -"n c #009FFF", -"o c #59E7FF", -"p c #5AE8FF", -"q c #76FFFF", -"r c #78FFFF", -"s c #009BFF", -"t c #56E6FF", -"u c #57E6FF", -"v c #72FFFF", -"w c #74FFFF", -"x c #0095FF", -"y c #0097FF", -" ", -" ...+.......... ", -" @##$$#$%%%&&%@ ", -" *==-===;>,,'') ", -" !~{~~~~]]]]]]^ ", -" /{{{{{{((((((/ ", -" _-===--:<<<<[} ", -" |#$##$#111211| ", -" 342444455#5556 ", -" 78999990aaa00b ", -" cddddeeffggggc ", -" hiijiikllllllm ", -" nooooopqqqqrqn ", -" stttuttvwvvwvs ", -" xxxxxxxxyxxxxx ", -" "}; diff --git a/resources/bitmaps/texture_lock.xpm b/resources/bitmaps/texture_lock.xpm deleted file mode 100644 index a7ebe72..0000000 --- a/resources/bitmaps/texture_lock.xpm +++ /dev/null @@ -1,37 +0,0 @@ -/* XPM */ -static char * texture_lock_xpm[] = { -"16 16 18 1", -" c None", -". c #000000", -"+ c #FFFFFF", -"@ c #87FFFF", -"# c #89FFFF", -"$ c #8CFFFF", -"% c #8FFFFF", -"& c #8EFFFF", -"* c #8BFFFF", -"= c #85FFFF", -"- c #FFFF00", -"; c #83FFFF", -"> c #81FFFF", -", c #7FFFFF", -"' c #7BFFFF", -") c #77FFFF", -"! c #72FFFF", -"~ c #75FFFF", -" ", -" .............. ", -" .++++++@@@##@. ", -" .++++....$$$$. ", -" .+++......%%%. ", -" .+++..+&..&&&. ", -" .+++..+$..**$. ", -" .++........##. ", -" .=@.------.++. ", -" .;>.--..--.++. ", -" .,,.--..--.++. ", -" .''.------.++. ", -" .))........++. ", -" .!!!~!!++++++. ", -" .............. ", -" "}; diff --git a/resources/bitmaps/textures_popup.xpm b/resources/bitmaps/textures_popup.xpm deleted file mode 100644 index cb402f2..0000000 --- a/resources/bitmaps/textures_popup.xpm +++ /dev/null @@ -1,66 +0,0 @@ -/* XPM */ -static char * textures_popup_xpm[] = { -"16 15 48 1", -" c None", -". c #007B82", -"+ c #FFFF00", -"@ c #000000", -"# c #31C6C9", -"$ c #007A84", -"% c #FFFFFF", -"& c #37C6CA", -"* c #007A85", -"= c #40C6CB", -"- c #3DC6CB", -"; c #007A86", -"> c #007986", -", c #007987", -"' c #45C6CB", -") c #43C6CB", -"! c #007988", -"~ c #4AC5CC", -"{ c #4AC6CC", -"] c #007888", -"^ c #48C5CC", -"/ c #007688", -"( c #45C4CC", -"_ c #43C4CC", -": c #007488", -"< c #3DC4CC", -"[ c #40C4CC", -"} c #3AC3CC", -"| c #3DC3CC", -"1 c #007388", -"2 c #007288", -"3 c #37C2CC", -"4 c #34C3CC", -"5 c #34C2CC", -"6 c #007088", -"7 c #31C2CC", -"8 c #2DC2CC", -"9 c #007188", -"0 c #006F88", -"a c #26C1CC", -"b c #2AC1CC", -"c c #006E88", -"d c #006C88", -"e c #26C0CC", -"f c #006D88", -"g c #006B88", -"h c #006988", -"i c #006A88", -" .+ @#.. ", -" $%$@+&&&$$$ ", -"+*+*+=-=---=*@ ", -";+%>,,@'')'',@ ", -"!%++~{~~~{{!!@ ", -"%]%^^]^^^^]]]@ ", -"+/%(%(%_(////@ ", -":%@%<%[<:::::@ ", -"}}%|%}%}1:11:@ ", -"2%3%4%452222@ ", -"67%7%7%8999@ ", -" 000a%bbc0@ ", -" dddef@ @@@", -" g@ @gg", -" @hi"}; diff --git a/resources/bitmaps/undo.xpm b/resources/bitmaps/undo.xpm deleted file mode 100644 index 2758d4e..0000000 --- a/resources/bitmaps/undo.xpm +++ /dev/null @@ -1,34 +0,0 @@ -/* XPM */ -static char * undo_xpm[] = { -"16 16 15 1", -" c None", -". c #47E0FF", -"+ c #47E1FF", -"@ c #45DEFF", -"# c #43DBFF", -"$ c #44DCFF", -"% c #44DBFF", -"& c #42D9FF", -"* c #43DAFF", -"= c #41D6FF", -"- c #40D7FF", -"; c #40D6FF", -"> c #3FD4FF", -", c #3ED5FF", -"' c #3DD1FF", -" ", -" ", -" ", -" ", -" ", -" ..+. ", -" @ @@ @ ", -" #$ # % ", -" &*& & ", -" =--; - ", -" >>>>, > ", -" ' ", -" ", -" ", -" ", -" "}; diff --git a/resources/bitmaps/view_cameratoggle.xpm b/resources/bitmaps/view_cameratoggle.xpm deleted file mode 100644 index a9cb932..0000000 --- a/resources/bitmaps/view_cameratoggle.xpm +++ /dev/null @@ -1,66 +0,0 @@ -/* XPM */ -static char * view_cameratoggle_xpm[] = { -"16 15 48 1", -" c None", -". c #CCCCCC", -"+ c #40E6F3", -"@ c #3FE6F4", -"# c #3FE6F3", -"$ c #3FE5F3", -"% c #41E5F6", -"& c #42E5F5", -"* c #42E5F6", -"= c #43E4F8", -"- c #44E4F9", -"; c #43E4F9", -"> c #44E5F9", -", c #44E4F8", -"' c #46E4FB", -") c #45E4FB", -"! c #46E3FB", -"~ c #45E3FC", -"{ c #46E3FC", -"] c #46E4FC", -"^ c #48E2FE", -"/ c #47E2FF", -"( c #48E3FE", -"_ c #48E2FF", -": c #48E3FF", -"< c #47E1FF", -"[ c #47E0FF", -"} c #FFFFFF", -"| c #45DEFF", -"1 c #46DEFF", -"2 c #FFFF00", -"3 c #43DBFF", -"4 c #44DCFF", -"5 c #44DBFF", -"6 c #42D9FF", -"7 c #43DAFF", -"8 c #41D6FF", -"9 c #40D7FF", -"0 c #40D6FF", -"a c #3FD4FF", -"b c #3ED5FF", -"c c #3DD2FF", -"d c #3CD2FF", -"e c #3BCFFF", -"f c #3BD0FF", -"g c #39CDFF", -"h c #3ACDFF", -"i c #37CAFF", -".+@#$# ", -"%%%%&*%% ", -"=-;=--=>;;;-, ", -"')!!~{'!!~]]{{ ", -"^^^/^(^_^(:(:^_ ", -"<[<[[[[<[[<[[}} ", -" ||111||1||2}}} ", -" 334335355}2}}3 ", -" 6766666}22}} ", -" 899090}22}}9 ", -" aaaab}22}}a ", -" ccdc222}}c ", -" eeee}}}}f ", -" gg}}}}h ", -" i}}i "}; diff --git a/resources/bitmaps/view_cameraupdate.xpm b/resources/bitmaps/view_cameraupdate.xpm deleted file mode 100644 index b5b0787..0000000 --- a/resources/bitmaps/view_cameraupdate.xpm +++ /dev/null @@ -1,61 +0,0 @@ -/* XPM */ -static char * view_cameraupdate_xpm[] = { -"16 15 43 1", -" c None", -". c #D4FFFF", -"+ c #40E6FF", -"@ c #3FE6FF", -"# c #94FFFF", -"$ c #41E5FF", -"% c #42E5FF", -"& c #95FFFF", -"* c #43E4FF", -"= c #44E4FF", -"- c #44E5FF", -"; c #97FFFF", -"> c #45E4FF", -", c #46E3FF", -"' c #45E3FF", -") c #46E4FF", -"! c #FFFFFF", -"~ c #48E2FF", -"{ c #47E2FF", -"] c #48E3FF", -"^ c #47E0FF", -"/ c #47E1FF", -"( c #45DEFF", -"_ c #46DEFF", -": c #96FCFF", -"< c #43DBFF", -"[ c #44DCFF", -"} c #95F8FF", -"| c #42D9FF", -"1 c #43DAFF", -"2 c #41D7FF", -"3 c #94F6FF", -"4 c #3FD4FF", -"5 c #94F4FF", -"6 c #3DD1FF", -"7 c #3DD2FF", -"8 c #93F1FF", -"9 c #3BD0FF", -"0 c #93F0FF", -"a c #39CDFF", -"b c #92EEFF", -"c c #38CAFF", -"d c #91ECFF", -".+@# ", -"$$$$%%$$& ", -"*=**==*-** ", -";>,,',),,! ", -" ~~{~]~~!! ", -" ^/^^^!!!! ", -" ((__!!!!: ", -" <<[!!!! ", -" }|1!!!} | ", -" !! 23 ", -" 45 ", -" 6777676 ", -" 8898000", -" ab ", -" cd "}; diff --git a/resources/bitmaps/view_change.xpm b/resources/bitmaps/view_change.xpm deleted file mode 100644 index acc7ddc..0000000 --- a/resources/bitmaps/view_change.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * view_change_xpm[] = { -"16 16 26 1", -" c None", -". c #41E5F6", -"+ c #42E5F6", -"@ c #43E4F9", -"# c #44E4F9", -"$ c #46E3FB", -"% c #45E3FC", -"& c #46E3FC", -"* c #47E2FF", -"= c #48E3FE", -"- c #48E2FE", -"; c #47E1FF", -"> c #47E0FF", -", c #45DEFF", -"' c #46DEFF", -") c #43DBFF", -"! c #42D9FF", -"~ c #40D7FF", -"{ c #41D7FF", -"] c #3ED4FF", -"^ c #3FD4FF", -"/ c #3DD2FF", -"( c #3BCFFF", -"_ c #39CDFF", -": c #37CAFF", -"< c #38CAFF", -" ", -" . + ", -" @ # ", -" $ % & ", -" * = - ", -" ; > ; > ", -" , ' , , ", -" ) ", -" !!!!! ! ", -" ~ { ", -" ] ^ ", -" / / ", -" ( ", -" _ ", -" :<<:< ", -" "}; diff --git a/resources/bitmaps/view_clipper.xpm b/resources/bitmaps/view_clipper.xpm deleted file mode 100644 index 6adc047..0000000 --- a/resources/bitmaps/view_clipper.xpm +++ /dev/null @@ -1,49 +0,0 @@ -/* XPM */ -static char * view_clipper_xpm[] = { -"16 16 30 1", -" c None", -". c #00CDFF", -"+ c #00CBFF", -"@ c #00CBED", -"# c #00CBEB", -"$ c #00C9F3", -"% c #00C9FF", -"& c #00C9F7", -"* c #00C7F7", -"= c #00C5FD", -"- c #00C7FF", -"; c #00C5FF", -"> c #00C1FF", -", c #00C3FF", -"' c #00BDFF", -") c #00BBFF", -"! c #00B7FF", -"~ c #00B3FF", -"{ c #00B5FF", -"] c #00ADFF", -"^ c #00AFFF", -"/ c #00A9FF", -"( c #00A5FF", -"_ c #00A3FF", -": c #009FFF", -"< c #009BFF", -"[ c #0097FF", -"} c #0095FF", -"| c #0091FF", -"1 c #008FFF", -" ..+", -" @@@#@@@@@@@@+++", -" $ %%%", -" & * ", -" = - ; ", -" > , > ", -" ' ) ", -" ! ! ! ", -" ~ ~ { ", -" ] ^ ", -" / / / ", -" ( ( _ ", -" : : ", -"<<< < ", -"[}}}}}}}}[}}}}} ", -"||1 "}; diff --git a/resources/bitmaps/view_cubicclipping.xpm b/resources/bitmaps/view_cubicclipping.xpm deleted file mode 100644 index 6e26d4b..0000000 --- a/resources/bitmaps/view_cubicclipping.xpm +++ /dev/null @@ -1,39 +0,0 @@ -/* XPM */ -static char * view_cubicclipping_xpm[] = { -"16 16 20 1", -" c None", -". c #41E5F6", -"+ c #C9FFFF", -"@ c #43E4F8", -"# c #CAFFFF", -"$ c #46E3FC", -"% c #48E3FE", -"& c #47E0FF", -"* c #47E1FF", -"= c #45DEFF", -"- c #44DBFF", -"; c #43D9FF", -"> c #C8FFFF", -", c #41D7FF", -"' c #3FD5FF", -") c #C7FFFF", -"! c #3DD2FF", -"~ c #3BD0FF", -"{ c #39CDFF", -"] c #38CAFF", -" ", -" . ", -" +++@ ", -" ###+##$# ", -" #########%## ", -" &*&&&&*&&*### ", -" +###++#+=++ ", -" +++++++-++ ", -" ++++++;++ ", -" >>>>>,>> ", -" >>>>'> ", -" )))!) ", -" ))~) ", -" ){) ", -" ] ", -" "}; diff --git a/resources/bitmaps/view_entity.xpm b/resources/bitmaps/view_entity.xpm deleted file mode 100644 index 64001ab..0000000 --- a/resources/bitmaps/view_entity.xpm +++ /dev/null @@ -1,65 +0,0 @@ -/* XPM */ -static char * view_entity_xpm[] = { -"16 15 47 1", -" c None", -". c #00FFFF", -"+ c #86FFFF", -"@ c #88FFFF", -"# c #11FFFF", -"$ c #8CFFFF", -"% c #8AFFFF", -"& c #15FFFF", -"* c #8EFFFF", -"= c #00C5FD", -"- c #00C7FD", -"; c #00C5FF", -"> c #90FFFF", -", c #19FFFF", -"' c #00FEFF", -") c #17FFFF", -"! c #00FAFF", -"~ c #00BDFF", -"{ c #00F8FF", -"] c #13FFFF", -"^ c #00F4FF", -"/ c #0FFFFF", -"( c #00F0FF", -"_ c #00B3FF", -": c #84FFFF", -"< c #00B5FF", -"[ c #0DFFFF", -"} c #00EAFF", -"| c #80FFFF", -"1 c #82FFFF", -"2 c #00ECFF", -"3 c #09FFFF", -"4 c #00E6FF", -"5 c #7EFFFF", -"6 c #00A9FF", -"7 c #7CFFFF", -"8 c #00ABFF", -"9 c #00E8FF", -"0 c #05FFFF", -"a c #00E2FF", -"b c #7AFFFF", -"c c #78FFFF", -"d c #03FFFF", -"e c #00DCFF", -"f c #76FFFF", -"g c #01FFFF", -"h c #00D8FF", -" ", -" ............ ", -" .+@@+@+++@@.# ", -" .$%$$$$%$$$.& ", -" .*=-=;=->->., ", -" .**********') ", -" !$~~~~~~%~%{] ", -" ^@++@+@@@+@^/ ", -" (+_:___<__:([ ", -" }||||||111|23 ", -" 4566768886590 ", -" abcbbbbbbbbad ", -" effffcffffceg ", -" hhhhhhhhhhhh. ", -" ............ "}; diff --git a/resources/bitmaps/white.xpm b/resources/bitmaps/white.xpm deleted file mode 100644 index 31b56ca..0000000 --- a/resources/bitmaps/white.xpm +++ /dev/null @@ -1,15 +0,0 @@ -/* XPM */ -static char *white[] = { -/* columns rows colors chars-per-pixel */ -"8 8 1 1 ", -" c white", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" " -}; diff --git a/resources/bitmaps/window1.xpm b/resources/bitmaps/window1.xpm deleted file mode 100644 index ae11c6f..0000000 --- a/resources/bitmaps/window1.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char *window1[] = { -/* columns rows colors chars-per-pixel */ -"32 32 5 1 ", -" c #0000C0", -". c black", -"X c white", -"o c #C0C0C0", -"O c #C00000", -/* pixels */ -" ", -" . ", -" ", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXOOOXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXOXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXOXXXXXXX.", -".XXXOXXXOXXXXXXXXXXoXXXOXXXXXXX.", -".XXXXOXOXXXXXXXXXXXoXXXXOOOXXXX.", -".XXXXXOXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXOXOXXXOXXXOXXXoXXXXXXXXXXX.", -".XXXOXXXOXXOXXXOXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXOXOXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXOXXXXXoooooooooooo.", -".XXXOOOOOXXXXOXXXXXoXXXXXXXXXXX.", -".XXXXXXOXXXXXOXXXXXoXXXXXXXXXXX.", -".XXXXXOXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXOXXXXXXXXXXXXXoXXXOOOOOXXX.", -".XXXOOOOOXXXXXXXXXXoXXXXXOXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXOXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXOXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXOXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXoXXXXXXXXXXX.", -".oooooooooooooooooooooooooooooo.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -"................................" -}; diff --git a/resources/bitmaps/window2.xpm b/resources/bitmaps/window2.xpm deleted file mode 100644 index 14a194e..0000000 --- a/resources/bitmaps/window2.xpm +++ /dev/null @@ -1,42 +0,0 @@ -/* XPM */ -static char *window2[] = { -/* columns rows colors chars-per-pixel */ -"32 32 4 1 ", -" c #0000C0", -". c black", -"X c white", -"o c #C00000", -/* pixels */ -" ", -" . ", -" ", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -".X XXX.", -".X XXX.", -".X.XXXXXXXXXXXXXXXXXXXXXXXX.XXX.", -".X.XXXXXXXXXXXXXXXXXX X.", -".X.XXoXXXoXXXXXXXXXXX X.", -".X.XXXoXoXXXXXXXXXXXX.XXXXXXX.X.", -".X.XXXXoXXXXXXXXXXXXX.XXXXXXX.X.", -".X.XXXoXoXXXoXXXoXXXX.XoooooX.X.", -".X.XXoXXXoXXoXXXoXXXX.XXXoXXX.X.", -".X.XXXXXXXXXXoXoXXXXX.XXXoXXX.X.", -".X.XXXXXXXXXXXoXXXXXX.XXXoXXX.X.", -".X.XXoooooXXXXoXXXXXX.XXXoXXX.X.", -".X.XXXXXoXXXXXoXXXXXX.XXXXXXX.X.", -".X.XXXXoXXXXXXXXXXXXX.XXXXXXX.X.", -".X.XXXoXXXXXXXXXXXXXX.XXXXXXX.X.", -".X.XXoooooXXXXXXXXXXX.........X.", -".X.XXXXXXXX XXXXXXX.XXX.", -".X.XXXXXXXX XXXXXXX.XXX.", -".X.XXXXXXXX.XXXXXXX.XXXXXXX.XXX.", -".X.XXXXXXXX.XXoooXX.XXXXXXX.XXX.", -".X.XXXXXXXX.XoXXXXX.XXXXXXX.XXX.", -".X.XXXXXXXX.XoXXXXX.XXXXXXX.XXX.", -".X.XXXXXXXX.XoXXXXX.XXXXXXX.XXX.", -".X..........XXoooXX.........XXX.", -".XXXXXXXXXX.XXXXXXX.XXXXXXXXXXX.", -".XXXXXXXXXX.........XXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -"................................" -}; diff --git a/resources/bitmaps/window3.xpm b/resources/bitmaps/window3.xpm deleted file mode 100644 index c1513c3..0000000 --- a/resources/bitmaps/window3.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char *window3[] = { -/* columns rows colors chars-per-pixel */ -"32 32 5 1 ", -" c #0000C0", -". c black", -"X c white", -"o c #C0C0C0", -"O c #C00000", -/* pixels */ -" ", -" . ", -" ", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXOOOXXXXXXoXXOXXXOXXXXXXXX.", -".XXXXOXXXXXXXXXoXXXOXOXXXXXXXXX.", -".XXXXOXXXXXXXXXoXXXXOXXXOXXXOXX.", -".XXXXOXXXXXXXXXoXXXOXOXXOXXXOXX.", -".XXXXXOOOXXXXXXoXXOXXXOXXOXOXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXOXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXOXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXOXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".oooooooooooooooooooooooooooooo.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XOXXXOXXXXXXXXoXXOXXXOXXXXXXXX.", -".XOXXXOXXXXXXXXoXXXOXOXXXXXXXXX.", -".XXOXOXXOOOOOXXoXXXXOXXXOOOOOXX.", -".XXXOXXXXXXOXXXoXXXOXOXXXXXOXXX.", -".XXXOXXXXXOXXXXoXXOXXXOXXXOXXXX.", -".XXXOXXXXOXXXXXoXXXXXXXXXOXXXXX.", -".XXXXXXXOOOOOXXoXXXXXXXXOOOOOXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXoXXXXXXXXXXXXXXX.", -"................................" -}; diff --git a/resources/bitmaps/window4.xpm b/resources/bitmaps/window4.xpm deleted file mode 100644 index 3336ed5..0000000 --- a/resources/bitmaps/window4.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char *window4[] = { -/* columns rows colors chars-per-pixel */ -"32 32 5 1 ", -" c #0000C0", -". c black", -"X c white", -"o c #C0C0C0", -"O c #C00000", -/* pixels */ -" ", -" . ", -" ", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXOOOXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXOXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXOXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXOXXXXXXXoXXXOXXXOXXXXXXXXXX.", -".XXXXOOOXXXXoXXXXOXOXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXOXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXOXOXXXOXXXOXXX.", -".XXXXXXXXXXXoXXXOXXXOXXOXXXOXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXOXOXXXX.", -".ooooooooooooXXXXXXXXXXXXOXXXXX.", -".XXXXXXXXXXXoXXXOOOOOXXXXOXXXXX.", -".XXXXXXXXXXXoXXXXXXOXXXXXOXXXXX.", -".XXXXXXXXXXXoXXXXXOXXXXXXXXXXXX.", -".XXXOOOOOXXXoXXXXOXXXXXXXXXXXXX.", -".XXXXXOXXXXXoXXXOOOOOXXXXXXXXXX.", -".XXXXXOXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXOXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXOXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXoXXXXXXXXXXXXXXXXXX.", -".oooooooooooooooooooooooooooooo.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -".XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.", -"................................" -}; diff --git a/resources/bitmaps/ws_icons.xcf b/resources/bitmaps/ws_icons.xcf deleted file mode 100644 index 858c277..0000000 Binary files a/resources/bitmaps/ws_icons.xcf and /dev/null differ diff --git a/resources/defaultkeys.ini b/resources/defaultkeys.ini deleted file mode 100644 index e80b07b..0000000 --- a/resources/defaultkeys.ini +++ /dev/null @@ -1,269 +0,0 @@ -[Version] -number=1.0-gtk-accelnames - -[Commands] -AddTag= -ArbitraryRotation= -ArbitraryScale= -Brush3Sided=3 -Brush4Sided=4 -Brush5Sided=5 -Brush6Sided=6 -Brush7Sided=7 -Brush8Sided=8 -Brush9Sided=9 -BrushCone= -BrushPrism= -BrushRock= -BrushSphere= -BuildMenuCustomize= -CSGMakeHollow= -CSGMakeRoom= -CSGMerge=u -CSGSubtract=u -CameraAngleDown=z -CameraAngleUp=a -CameraBack=Down -CameraDown=c -CameraForward=Up -CameraFreeMoveBack=Down -CameraFreeMoveDown=c -CameraFreeMoveForward=Up -CameraFreeMoveLeft=Left -CameraFreeMoveRight=Right -CameraFreeMoveUp=d -CameraLeft=Left -CameraRight=Right -CameraSpeedDec=KP_Subtract -CameraSpeedInc=KP_Add -CameraStrafeLeft=comma -CameraStrafeRight=period -CameraUp=d -CapCurrentCurve=c -CenterView=End -CenterXYView=Tab -ChooseBrushColor= -ChooseCameraBackgroundColor= -ChooseCameraSelectedBrushColor= -ChooseClipperColor= -ChooseGridBackgroundColor= -ChooseGridBlockColor= -ChooseGridMajorColor= -ChooseGridMinorColor= -ChooseGridTextColor= -ChooseOrthoViewNameColor= -ChooseSelectedBrushColor= -ChooseSmallGridMajorColor= -ChooseSmallGridMinorColor= -ChooseTextureBackgroundColor= -ClearPatchOverlays=l -ClipSelected=Return -CloneSelection=space -CloneSelectionAndMakeUnique=space -ColorSchemeBlackAndGreen= -ColorSchemeOriginal= -ColorSchemeQER= -ColorSchemeYdnar= -ConnectSelection=k -Copy=c -CopyTag= -CubicClipZoomIn=bracketleft -CubicClipZoomOut=bracketright -CycleCapTexturePatch=n -DeleteSelection=BackSpace -DeleteTag= -DownFloor=Page_Down -DragEdges=e -DragFaces=f -DragVertices=v -EnableAlpha= -EntityColor=k -EntityList=l -Exit= -ExpandSelectionToEntities=e -ExportSelected= -FaceCopyTexture= -FacePasteTexture= -FilterAreaportals=3 -FilterBotClips=m -FilterCaulk=6 -FilterClips=7 -FilterClusterportals=9 -FilterDecals=d -FilterDetails=d -FilterEntities=2 -FilterFallback= -FilterHintsSkips=h -FilterLightgrid= -FilterLights=0 -FilterLiquids=5 -FilterMissing= -FilterModels=m -FilterPatches=p -FilterPaths=8 -FilterStructural=d -FilterTranslucent=4 -FilterTriggers=t -FilterWorldBrushes=1 -FindBrush= -FindReplaceTextures= -FitTexture=b -FixedSize= -FlipClip=Return -GridDown=bracketleft -GridUp=bracketright -GroupSelection= -HideSelected=h -HideUnselected= -ImportMap= -InvertCurve=i -InvertCurveTextureX=i -InvertCurveTextureY=i -InvertFilters= -InvertSelection=i -KillConnectSelection=k -LookThroughCamera= -LookThroughSelected= -MakeDetail=m -MakeOverlayPatch=y -MakeStructural=s -MapInfo=m -MatrixTranspose=m -MirrorSelectionX= -MirrorSelectionY= -MirrorSelectionZ= -MouseDrag=q -MouseRotate=r -MouseScale= -MouseTranslate=w -MoveSelectionDOWN=KP_Subtract -MoveSelectionUP=KP_Add -NaturalizePatch=n -NewMap= -NextLeakSpot=k -NextView=Tab -NormalizeColor= -OpenMap=o -ParentSelection= -Paste=v -PasteTag= -PasteToCamera=v -PatchBevel= -PatchCone= -PatchCylinder= -PatchDeleteFirstColumn= -PatchDeleteFirstRow=KP_Subtract -PatchDeleteLastColumn=KP_Subtract -PatchDeleteLastRow= -PatchDenseCylinder= -PatchEndCap= -PatchInsertAddColumn= -PatchInsertAddRow= -PatchInsertInsertColumn=KP_Add -PatchInsertInsertRow=KP_Add -PatchInspector=s -PatchSphere= -PatchSquareBevel= -PatchSquareCylinder= -PatchSquareEndcap= -PatchVeryDenseCylinder= -PatchXactCone= -PatchXactCylinder= -PatchXactSphere= -Preferences=p -PrevLeakSpot=l -ProjectSettings= -RedisperseCols=e -RedisperseRows=e -Redo=y -RefreshReferences= -RefreshShaders= -RegionOff= -RegionSetBrush= -RegionSetSelection=r -RegionSetXY= -RenameTag= -ResetFilters= -RotateSelectionX= -RotateSelectionY= -RotateSelectionZ= -SaveMap=s -SaveMapAs= -SaveRegion= -SelectAllOfType=a -SelectInside= -SelectNudgeDown=Down -SelectNudgeLeft=Left -SelectNudgeRight=Right -SelectNudgeUp=Up -SelectTouching= -SetGrid0.125= -SetGrid0.25= -SetGrid0.5= -SetGrid1=1 -SetGrid128=8 -SetGrid16=5 -SetGrid2=2 -SetGrid256=9 -SetGrid32=6 -SetGrid4=3 -SetGrid64=7 -SetGrid8=4 -ShaderInfo= -ShowAllTextures=a -ShowAngles= -ShowAxes= -ShowBlocks= -ShowCoordinates= -ShowHidden=h -ShowInUse=u -ShowNames= -ShowStats= -ShowUntagged= -ShowWindowOutline= -ShowWorkzone= -SimplePatchMesh=p -Sleep=p -SmoothCols=w -SmoothRows=w -SnapToGrid=g -SplitSelected=Return -SurfaceInspector=s -TexRotateClock=Page_Down -TexRotateCounter=Page_Up -TexScaleDown=Down -TexScaleLeft=Left -TexScaleRight=Right -TexScaleUp=Up -TexShiftDown=Down -TexShiftLeft=Left -TexShiftRight=Right -TexShiftUp=Up -TogTexLock=t -ToggleCamera=c -ToggleClipper=x -ToggleConsole=o -ToggleCrosshairs=x -ToggleCubicClip=backslash -ToggleEntityInspector=n -ToggleFrontView= -ToggleGrid=0 -ToggleGridSnap= -TogglePointfile= -ToggleShowShaderlistOnly= -ToggleShowShaders= -ToggleSideView= -ToggleSizePaint=j -ToggleTextures=t -ToggleView=v -UnSelectSelection=Escape -Undo=z -UngroupSelection= -UpFloor=Page_Up -ViewEntityInfo=n -ViewFront=KP_End -ViewSide=KP_Page_Down -ViewTop=KP_Home -Zoom100= -ZoomIn=Delete -ZoomOut=Insert diff --git a/resources/games/goldsrc.game b/resources/games/goldsrc.game deleted file mode 100644 index 22a3a2d..0000000 --- a/resources/games/goldsrc.game +++ /dev/null @@ -1,28 +0,0 @@ - - diff --git a/resources/games/platform.game b/resources/games/platform.game deleted file mode 100644 index 48d85a0..0000000 --- a/resources/games/platform.game +++ /dev/null @@ -1,26 +0,0 @@ - - diff --git a/resources/gl/lighting_DBS_XY_Z_arbfp1.cg b/resources/gl/lighting_DBS_XY_Z_arbfp1.cg deleted file mode 100644 index f535dbb..0000000 --- a/resources/gl/lighting_DBS_XY_Z_arbfp1.cg +++ /dev/null @@ -1,92 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -#include "utils.cg" - -struct cg_vertex2fragment -{ - float4 position : TEXCOORD0; - float4 tex_diffuse_bump : TEXCOORD1; - float4 tex_specular : TEXCOORD2; - float4 tex_atten_xy_z : TEXCOORD3; - - float3 tangent : TEXCOORD4; - float3 binormal : TEXCOORD5; - float3 normal : TEXCOORD6; -}; - -struct cg_fragment2final -{ - float4 color : COLOR; -}; - - -cg_fragment2final main(cg_vertex2fragment IN, - uniform sampler2D diffusemap, - uniform sampler2D bumpmap, - uniform sampler2D specularmap, - uniform sampler2D attenuationmap_xy, - uniform sampler2D attenuationmap_z, - uniform float3 view_origin, - uniform float3 light_origin, - uniform float3 light_color, - uniform float bump_scale, - uniform float specular_exponent) -{ - cg_fragment2final OUT; - - // construct object-space-to-tangent-space 3x3 matrix - float3x3 rotation = float3x3(IN.tangent, IN.binormal, IN.normal); - - // compute view direction in tangent space - float3 V = normalize(mul(rotation, view_origin - IN.position.xyz)); - - // compute light direction in tangent space - float3 L = normalize(mul(rotation, (light_origin - IN.position.xyz))); - - // compute half angle in tangent space - float3 H = normalize(L + V); - - // compute normal in tangent space from bumpmap - float3 T = CG_Expand(tex2D(bumpmap, IN.tex_diffuse_bump.zw).xyz); - T.z *= bump_scale; - float3 N = normalize(T); - - // compute the diffuse term - float4 diffuse = tex2D(diffusemap, IN.tex_diffuse_bump.xy); - diffuse.rgb *= light_color * saturate(dot(N, L)); - - // compute the specular term - float3 specular = tex2D(specularmap, IN.tex_specular.xy).rgb * light_color * pow(saturate(dot(N, H)), specular_exponent); - - // compute attenuation - float3 attenuation_xy = tex2Dproj(attenuationmap_xy, float3(IN.tex_atten_xy_z.x, IN.tex_atten_xy_z.y, IN.tex_atten_xy_z.w)).rgb; - float3 attenuation_z = tex2D(attenuationmap_z, float2(IN.tex_atten_xy_z.z, 0)).rgb; - - // compute final color - OUT.color.rgba = diffuse; - OUT.color.rgb += specular; - OUT.color.rgb *= attenuation_xy; - OUT.color.rgb *= attenuation_z; - - return OUT; -} diff --git a/resources/gl/lighting_DBS_XY_Z_arbvp1.cg b/resources/gl/lighting_DBS_XY_Z_arbvp1.cg deleted file mode 100644 index 59a6fc7..0000000 --- a/resources/gl/lighting_DBS_XY_Z_arbvp1.cg +++ /dev/null @@ -1,78 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - - -struct cg_app2vertex -{ - float4 position : POSITION; - float4 tex0 : ATTR8; - - float3 tangent : ATTR9; - float3 binormal : ATTR10; - float3 normal : ATTR11; -}; - -struct cg_vertex2fragment -{ - float4 hposition : POSITION; - - float4 position : TEXCOORD0; - float4 tex_diffuse_bump : TEXCOORD1; - float4 tex_specular : TEXCOORD2; - float4 tex_atten_xy_z : TEXCOORD3; - - float3 tangent : TEXCOORD4; - float3 binormal : TEXCOORD5; - float3 normal : TEXCOORD6; -}; - - - -cg_vertex2fragment main(cg_app2vertex IN) -{ - cg_vertex2fragment OUT; - - // transform vertex position into homogenous clip-space - OUT.hposition = mul(glstate.matrix.mvp, IN.position); - - // assign position in object space - OUT.position = IN.position; - - // transform texcoords - OUT.tex_diffuse_bump.xy = mul(glstate.matrix.texture[0], IN.tex0).xy; - - // transform texcoords - OUT.tex_diffuse_bump.zw = mul(glstate.matrix.texture[1], IN.tex0).xy; - - // transform texcoords - OUT.tex_specular = mul(glstate.matrix.texture[2], IN.tex0); - - // transform vertex position into light space - OUT.tex_atten_xy_z = mul(glstate.matrix.texture[3], IN.position); - - // assign tangent space vectors - OUT.tangent = IN.tangent; - OUT.binormal = IN.binormal; - OUT.normal = IN.normal; - - return OUT; -} diff --git a/resources/gl/lighting_DBS_omni_fp.glp b/resources/gl/lighting_DBS_omni_fp.glp deleted file mode 100644 index 88dab8d..0000000 --- a/resources/gl/lighting_DBS_omni_fp.glp +++ /dev/null @@ -1,86 +0,0 @@ -!!ARBfp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbfp1 -# source file: ..\..\setup\data\tools\gl\lighting_DBS_XY_Z_arbfp1.cg -# source file: ..\..\setup\data\tools\gl/utils.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbfp1 -#program main -#semantic main.diffusemap -#semantic main.bumpmap -#semantic main.specularmap -#semantic main.attenuationmap_xy -#semantic main.attenuationmap_z -#semantic main.view_origin -#semantic main.light_origin -#semantic main.light_color -#semantic main.bump_scale -#semantic main.specular_exponent -#var float4 IN.position : $vin.TEX0 : TEX0 : 0 : 1 -#var float4 IN.tex_diffuse_bump : $vin.TEX1 : TEX1 : 0 : 1 -#var float4 IN.tex_specular : $vin.TEX2 : TEX2 : 0 : 1 -#var float4 IN.tex_atten_xy_z : $vin.TEX3 : TEX3 : 0 : 1 -#var float3 IN.tangent : $vin.TEX4 : TEX4 : 0 : 1 -#var float3 IN.binormal : $vin.TEX5 : TEX5 : 0 : 1 -#var float3 IN.normal : $vin.TEX6 : TEX6 : 0 : 1 -#var sampler2D diffusemap : : texunit 0 : 1 : 1 -#var sampler2D bumpmap : : texunit 1 : 2 : 1 -#var sampler2D specularmap : : texunit 2 : 3 : 1 -#var sampler2D attenuationmap_xy : : texunit 3 : 4 : 1 -#var sampler2D attenuationmap_z : : texunit 4 : 5 : 1 -#var float3 view_origin : : c[4] : 6 : 1 -#var float3 light_origin : : c[2] : 7 : 1 -#var float3 light_color : : c[3] : 8 : 1 -#var float bump_scale : : c[1] : 9 : 1 -#var float specular_exponent : : c[5] : 10 : 1 -#var float4 main.color : $vout.COL : COL : -1 : 1 -#const c[0] = 0.5 2 0 -PARAM c[6] = { { 0.5, 2, 0 }, - program.local[1..5] }; -TEMP R0; -TEMP R1; -TEMP R2; -ADD R1.xyz, -fragment.texcoord[0], c[2]; -DP3 R0.z, fragment.texcoord[6], R1; -DP3 R0.x, fragment.texcoord[4], R1; -DP3 R0.y, fragment.texcoord[5], R1; -ADD R1.xyz, -fragment.texcoord[0], c[4]; -DP3 R0.w, R0, R0; -DP3 R2.z, fragment.texcoord[6], R1; -DP3 R2.x, fragment.texcoord[4], R1; -DP3 R2.y, fragment.texcoord[5], R1; -RSQ R0.w, R0.w; -MUL R1.xyz, R0.w, R0; -DP3 R1.w, R2, R2; -RSQ R0.w, R1.w; -MUL R2.xyz, R0.w, R2; -ADD R2.xyz, R1, R2; -DP3 R0.w, R2, R2; -RSQ R2.w, R0.w; -TEX R0.xyz, fragment.texcoord[1].zwzw, texture[1], 2D; -ADD R0.xyz, R0, -c[0].x; -MUL R0.xyz, R0, c[0].y; -MUL R0.z, R0, c[1].x; -DP3 R1.w, R0, R0; -RSQ R0.w, R1.w; -MUL R0.xyz, R0.w, R0; -MUL R2.xyz, R2.w, R2; -DP3_SAT R0.w, R0, R2; -DP3_SAT R0.x, R0, R1; -TEX R2.xyz, fragment.texcoord[2], texture[2], 2D; -MUL R1.xyz, R2, c[3]; -POW R0.w, R0.w, c[5].x; -MUL R2.xyz, R1, R0.w; -MUL R1.xyz, R0.x, c[3]; -TEX R0, fragment.texcoord[1], texture[0], 2D; -MAD R2.xyz, R0, R1, R2; -TXP R0.xyz, fragment.texcoord[3], texture[3], 2D; -MOV R1.y, c[0].z; -MOV R1.x, fragment.texcoord[3].z; -TEX R1.xyz, R1, texture[4], 2D; -MUL R0.xyz, R2, R0; -MUL result.color.xyz, R0, R1; -MOV result.color.w, R0; -END -# 41 instructions, 3 R-regs diff --git a/resources/gl/lighting_DBS_omni_fp.glsl b/resources/gl/lighting_DBS_omni_fp.glsl deleted file mode 100644 index 7f80fea..0000000 --- a/resources/gl/lighting_DBS_omni_fp.glsl +++ /dev/null @@ -1,73 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "CONTRIBUTORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -uniform sampler2D u_diffusemap; -uniform sampler2D u_bumpmap; -uniform sampler2D u_specularmap; -uniform sampler2D u_attenuationmap_xy; -uniform sampler2D u_attenuationmap_z; -uniform vec3 u_view_origin; -uniform vec3 u_light_origin; -uniform vec3 u_light_color; -uniform float u_bump_scale; -uniform float u_specular_exponent; - -varying vec3 var_vertex; -varying vec4 var_tex_diffuse_bump; -varying vec2 var_tex_specular; -varying vec4 var_tex_atten_xy_z; -varying mat3 var_mat_os2ts; - -void main() -{ - // compute view direction in tangent space - vec3 V = normalize(var_mat_os2ts * (u_view_origin - var_vertex)); - - // compute light direction in tangent space - vec3 L = normalize(var_mat_os2ts * (u_light_origin - var_vertex)); - - // compute half angle in tangent space - vec3 H = normalize(L + V); - - // compute normal in tangent space from bumpmap - vec3 N = 2.0 * (texture2D(u_bumpmap, var_tex_diffuse_bump.pq).xyz - 0.5); - N.z *= u_bump_scale; - N = normalize(N); - - // compute the diffuse term - vec4 diffuse = texture2D(u_diffusemap, var_tex_diffuse_bump.st); - diffuse.rgb *= u_light_color * clamp(dot(N, L), 0.0, 1.0); - - // compute the specular term - vec3 specular = texture2D(u_specularmap, var_tex_specular).rgb * u_light_color * pow(clamp(dot(N, H), 0.0, 1.0), u_specular_exponent); - - // compute attenuation - vec3 attenuation_xy = texture2DProj(u_attenuationmap_xy, vec3(var_tex_atten_xy_z.x, var_tex_atten_xy_z.y, var_tex_atten_xy_z.w)).rgb; - vec3 attenuation_z = texture2D(u_attenuationmap_z, vec2(var_tex_atten_xy_z.z, 0)).rgb; - - // compute final color - gl_FragColor.rgba = diffuse; - gl_FragColor.rgb += specular; - gl_FragColor.rgb *= attenuation_xy; - gl_FragColor.rgb *= attenuation_z; -} - diff --git a/resources/gl/lighting_DBS_omni_vp.glp b/resources/gl/lighting_DBS_omni_vp.glp deleted file mode 100644 index b4472d7..0000000 --- a/resources/gl/lighting_DBS_omni_vp.glp +++ /dev/null @@ -1,410 +0,0 @@ -!!ARBvp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbvp1 -# source file: ..\..\setup\data\tools\gl\lighting_DBS_XY_Z_arbvp1.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbvp1 -#program main -#semantic glstate : STATE -#var float4 glstate.material.ambient : STATE.MATERIAL.AMBIENT : : -1 : 0 -#var float4 glstate.material.diffuse : STATE.MATERIAL.DIFFUSE : : -1 : 0 -#var float4 glstate.material.specular : STATE.MATERIAL.SPECULAR : : -1 : 0 -#var float4 glstate.material.emission : STATE.MATERIAL.EMISSION : : -1 : 0 -#var float4 glstate.material.shininess : STATE.MATERIAL.SHININESS : : -1 : 0 -#var float4 glstate.material.front.ambient : STATE.MATERIAL.FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.material.front.diffuse : STATE.MATERIAL.FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.material.front.specular : STATE.MATERIAL.FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.material.front.emission : STATE.MATERIAL.FRONT.EMISSION : : -1 : 0 -#var float4 glstate.material.front.shininess : STATE.MATERIAL.FRONT.SHININESS : : -1 : 0 -#var float4 glstate.material.back.ambient : STATE.MATERIAL.BACK.AMBIENT : : -1 : 0 -#var float4 glstate.material.back.diffuse : STATE.MATERIAL.BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.material.back.specular : STATE.MATERIAL.BACK.SPECULAR : : -1 : 0 -#var float4 glstate.material.back.emission : STATE.MATERIAL.BACK.EMISSION : : -1 : 0 -#var float4 glstate.material.back.shininess : STATE.MATERIAL.BACK.SHININESS : : -1 : 0 -#var float4 glstate.light[0].ambient : STATE.LIGHT[0].AMBIENT : : -1 : 0 -#var float4 glstate.light[0].diffuse : STATE.LIGHT[0].DIFFUSE : : -1 : 0 -#var float4 glstate.light[0].specular : STATE.LIGHT[0].SPECULAR : : -1 : 0 -#var float4 glstate.light[0].position : STATE.LIGHT[0].POSITION : : -1 : 0 -#var float4 glstate.light[0].attenuation : STATE.LIGHT[0].ATTENUATION : : -1 : 0 -#var float4 glstate.light[0].spot.direction : STATE.LIGHT[0].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[0].half : STATE.LIGHT[0].HALF : : -1 : 0 -#var float4 glstate.light[1].ambient : STATE.LIGHT[1].AMBIENT : : -1 : 0 -#var float4 glstate.light[1].diffuse : STATE.LIGHT[1].DIFFUSE : : -1 : 0 -#var float4 glstate.light[1].specular : STATE.LIGHT[1].SPECULAR : : -1 : 0 -#var float4 glstate.light[1].position : STATE.LIGHT[1].POSITION : : -1 : 0 -#var float4 glstate.light[1].attenuation : STATE.LIGHT[1].ATTENUATION : : -1 : 0 -#var float4 glstate.light[1].spot.direction : STATE.LIGHT[1].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[1].half : STATE.LIGHT[1].HALF : : -1 : 0 -#var float4 glstate.light[2].ambient : STATE.LIGHT[2].AMBIENT : : -1 : 0 -#var float4 glstate.light[2].diffuse : STATE.LIGHT[2].DIFFUSE : : -1 : 0 -#var float4 glstate.light[2].specular : STATE.LIGHT[2].SPECULAR : : -1 : 0 -#var float4 glstate.light[2].position : STATE.LIGHT[2].POSITION : : -1 : 0 -#var float4 glstate.light[2].attenuation : STATE.LIGHT[2].ATTENUATION : : -1 : 0 -#var float4 glstate.light[2].spot.direction : STATE.LIGHT[2].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[2].half : STATE.LIGHT[2].HALF : : -1 : 0 -#var float4 glstate.light[3].ambient : STATE.LIGHT[3].AMBIENT : : -1 : 0 -#var float4 glstate.light[3].diffuse : STATE.LIGHT[3].DIFFUSE : : -1 : 0 -#var float4 glstate.light[3].specular : STATE.LIGHT[3].SPECULAR : : -1 : 0 -#var float4 glstate.light[3].position : STATE.LIGHT[3].POSITION : : -1 : 0 -#var float4 glstate.light[3].attenuation : STATE.LIGHT[3].ATTENUATION : : -1 : 0 -#var float4 glstate.light[3].spot.direction : STATE.LIGHT[3].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[3].half : STATE.LIGHT[3].HALF : : -1 : 0 -#var float4 glstate.light[4].ambient : STATE.LIGHT[4].AMBIENT : : -1 : 0 -#var float4 glstate.light[4].diffuse : STATE.LIGHT[4].DIFFUSE : : -1 : 0 -#var float4 glstate.light[4].specular : STATE.LIGHT[4].SPECULAR : : -1 : 0 -#var float4 glstate.light[4].position : STATE.LIGHT[4].POSITION : : -1 : 0 -#var float4 glstate.light[4].attenuation : STATE.LIGHT[4].ATTENUATION : : -1 : 0 -#var float4 glstate.light[4].spot.direction : STATE.LIGHT[4].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[4].half : STATE.LIGHT[4].HALF : : -1 : 0 -#var float4 glstate.light[5].ambient : STATE.LIGHT[5].AMBIENT : : -1 : 0 -#var float4 glstate.light[5].diffuse : STATE.LIGHT[5].DIFFUSE : : -1 : 0 -#var float4 glstate.light[5].specular : STATE.LIGHT[5].SPECULAR : : -1 : 0 -#var float4 glstate.light[5].position : STATE.LIGHT[5].POSITION : : -1 : 0 -#var float4 glstate.light[5].attenuation : STATE.LIGHT[5].ATTENUATION : : -1 : 0 -#var float4 glstate.light[5].spot.direction : STATE.LIGHT[5].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[5].half : STATE.LIGHT[5].HALF : : -1 : 0 -#var float4 glstate.light[6].ambient : STATE.LIGHT[6].AMBIENT : : -1 : 0 -#var float4 glstate.light[6].diffuse : STATE.LIGHT[6].DIFFUSE : : -1 : 0 -#var float4 glstate.light[6].specular : STATE.LIGHT[6].SPECULAR : : -1 : 0 -#var float4 glstate.light[6].position : STATE.LIGHT[6].POSITION : : -1 : 0 -#var float4 glstate.light[6].attenuation : STATE.LIGHT[6].ATTENUATION : : -1 : 0 -#var float4 glstate.light[6].spot.direction : STATE.LIGHT[6].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[6].half : STATE.LIGHT[6].HALF : : -1 : 0 -#var float4 glstate.light[7].ambient : STATE.LIGHT[7].AMBIENT : : -1 : 0 -#var float4 glstate.light[7].diffuse : STATE.LIGHT[7].DIFFUSE : : -1 : 0 -#var float4 glstate.light[7].specular : STATE.LIGHT[7].SPECULAR : : -1 : 0 -#var float4 glstate.light[7].position : STATE.LIGHT[7].POSITION : : -1 : 0 -#var float4 glstate.light[7].attenuation : STATE.LIGHT[7].ATTENUATION : : -1 : 0 -#var float4 glstate.light[7].spot.direction : STATE.LIGHT[7].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[7].half : STATE.LIGHT[7].HALF : : -1 : 0 -#var float4 glstate.lightmodel.ambient : STATE.LIGHTMODEL.AMBIENT : : -1 : 0 -#var float4 glstate.lightmodel.scenecolor : STATE.LIGHTMODEL.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.front.scenecolor : STATE.LIGHTMODEL.FRONT.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.back.scenecolor : STATE.LIGHTMODEL.BACK.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightprod[0].ambient : STATE.LIGHTPROD[0].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].diffuse : STATE.LIGHTPROD[0].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].specular : STATE.LIGHTPROD[0].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].front.ambient : STATE.LIGHTPROD[0].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].front.diffuse : STATE.LIGHTPROD[0].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].front.specular : STATE.LIGHTPROD[0].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].back.ambient : STATE.LIGHTPROD[0].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].back.diffuse : STATE.LIGHTPROD[0].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].back.specular : STATE.LIGHTPROD[0].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].ambient : STATE.LIGHTPROD[1].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].diffuse : STATE.LIGHTPROD[1].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].specular : STATE.LIGHTPROD[1].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].front.ambient : STATE.LIGHTPROD[1].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].front.diffuse : STATE.LIGHTPROD[1].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].front.specular : STATE.LIGHTPROD[1].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].back.ambient : STATE.LIGHTPROD[1].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].back.diffuse : STATE.LIGHTPROD[1].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].back.specular : STATE.LIGHTPROD[1].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].ambient : STATE.LIGHTPROD[2].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].diffuse : STATE.LIGHTPROD[2].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].specular : STATE.LIGHTPROD[2].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].front.ambient : STATE.LIGHTPROD[2].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].front.diffuse : STATE.LIGHTPROD[2].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].front.specular : STATE.LIGHTPROD[2].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].back.ambient : STATE.LIGHTPROD[2].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].back.diffuse : STATE.LIGHTPROD[2].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].back.specular : STATE.LIGHTPROD[2].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].ambient : STATE.LIGHTPROD[3].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].diffuse : STATE.LIGHTPROD[3].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].specular : STATE.LIGHTPROD[3].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].front.ambient : STATE.LIGHTPROD[3].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].front.diffuse : STATE.LIGHTPROD[3].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].front.specular : STATE.LIGHTPROD[3].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].back.ambient : STATE.LIGHTPROD[3].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].back.diffuse : STATE.LIGHTPROD[3].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].back.specular : STATE.LIGHTPROD[3].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].ambient : STATE.LIGHTPROD[4].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].diffuse : STATE.LIGHTPROD[4].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].specular : STATE.LIGHTPROD[4].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].front.ambient : STATE.LIGHTPROD[4].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].front.diffuse : STATE.LIGHTPROD[4].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].front.specular : STATE.LIGHTPROD[4].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].back.ambient : STATE.LIGHTPROD[4].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].back.diffuse : STATE.LIGHTPROD[4].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].back.specular : STATE.LIGHTPROD[4].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].ambient : STATE.LIGHTPROD[5].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].diffuse : STATE.LIGHTPROD[5].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].specular : STATE.LIGHTPROD[5].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].front.ambient : STATE.LIGHTPROD[5].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].front.diffuse : STATE.LIGHTPROD[5].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].front.specular : STATE.LIGHTPROD[5].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].back.ambient : STATE.LIGHTPROD[5].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].back.diffuse : STATE.LIGHTPROD[5].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].back.specular : STATE.LIGHTPROD[5].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].ambient : STATE.LIGHTPROD[6].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].diffuse : STATE.LIGHTPROD[6].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].specular : STATE.LIGHTPROD[6].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].front.ambient : STATE.LIGHTPROD[6].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].front.diffuse : STATE.LIGHTPROD[6].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].front.specular : STATE.LIGHTPROD[6].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].back.ambient : STATE.LIGHTPROD[6].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].back.diffuse : STATE.LIGHTPROD[6].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].back.specular : STATE.LIGHTPROD[6].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].ambient : STATE.LIGHTPROD[7].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].diffuse : STATE.LIGHTPROD[7].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].specular : STATE.LIGHTPROD[7].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].front.ambient : STATE.LIGHTPROD[7].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].front.diffuse : STATE.LIGHTPROD[7].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].front.specular : STATE.LIGHTPROD[7].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].back.ambient : STATE.LIGHTPROD[7].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].back.diffuse : STATE.LIGHTPROD[7].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].back.specular : STATE.LIGHTPROD[7].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.texgen[0].eye.s : STATE.TEXGEN[0].EYE.S : : -1 : 0 -#var float4 glstate.texgen[0].eye.t : STATE.TEXGEN[0].EYE.T : : -1 : 0 -#var float4 glstate.texgen[0].eye.r : STATE.TEXGEN[0].EYE.R : : -1 : 0 -#var float4 glstate.texgen[0].eye.q : STATE.TEXGEN[0].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[0].object.s : STATE.TEXGEN[0].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[0].object.t : STATE.TEXGEN[0].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[0].object.r : STATE.TEXGEN[0].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[0].object.q : STATE.TEXGEN[0].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[1].eye.s : STATE.TEXGEN[1].EYE.S : : -1 : 0 -#var float4 glstate.texgen[1].eye.t : STATE.TEXGEN[1].EYE.T : : -1 : 0 -#var float4 glstate.texgen[1].eye.r : STATE.TEXGEN[1].EYE.R : : -1 : 0 -#var float4 glstate.texgen[1].eye.q : STATE.TEXGEN[1].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[1].object.s : STATE.TEXGEN[1].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[1].object.t : STATE.TEXGEN[1].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[1].object.r : STATE.TEXGEN[1].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[1].object.q : STATE.TEXGEN[1].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[2].eye.s : STATE.TEXGEN[2].EYE.S : : -1 : 0 -#var float4 glstate.texgen[2].eye.t : STATE.TEXGEN[2].EYE.T : : -1 : 0 -#var float4 glstate.texgen[2].eye.r : STATE.TEXGEN[2].EYE.R : : -1 : 0 -#var float4 glstate.texgen[2].eye.q : STATE.TEXGEN[2].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[2].object.s : STATE.TEXGEN[2].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[2].object.t : STATE.TEXGEN[2].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[2].object.r : STATE.TEXGEN[2].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[2].object.q : STATE.TEXGEN[2].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[3].eye.s : STATE.TEXGEN[3].EYE.S : : -1 : 0 -#var float4 glstate.texgen[3].eye.t : STATE.TEXGEN[3].EYE.T : : -1 : 0 -#var float4 glstate.texgen[3].eye.r : STATE.TEXGEN[3].EYE.R : : -1 : 0 -#var float4 glstate.texgen[3].eye.q : STATE.TEXGEN[3].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[3].object.s : STATE.TEXGEN[3].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[3].object.t : STATE.TEXGEN[3].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[3].object.r : STATE.TEXGEN[3].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[3].object.q : STATE.TEXGEN[3].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[4].eye.s : STATE.TEXGEN[4].EYE.S : : -1 : 0 -#var float4 glstate.texgen[4].eye.t : STATE.TEXGEN[4].EYE.T : : -1 : 0 -#var float4 glstate.texgen[4].eye.r : STATE.TEXGEN[4].EYE.R : : -1 : 0 -#var float4 glstate.texgen[4].eye.q : STATE.TEXGEN[4].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[4].object.s : STATE.TEXGEN[4].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[4].object.t : STATE.TEXGEN[4].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[4].object.r : STATE.TEXGEN[4].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[4].object.q : STATE.TEXGEN[4].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[5].eye.s : STATE.TEXGEN[5].EYE.S : : -1 : 0 -#var float4 glstate.texgen[5].eye.t : STATE.TEXGEN[5].EYE.T : : -1 : 0 -#var float4 glstate.texgen[5].eye.r : STATE.TEXGEN[5].EYE.R : : -1 : 0 -#var float4 glstate.texgen[5].eye.q : STATE.TEXGEN[5].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[5].object.s : STATE.TEXGEN[5].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[5].object.t : STATE.TEXGEN[5].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[5].object.r : STATE.TEXGEN[5].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[5].object.q : STATE.TEXGEN[5].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[6].eye.s : STATE.TEXGEN[6].EYE.S : : -1 : 0 -#var float4 glstate.texgen[6].eye.t : STATE.TEXGEN[6].EYE.T : : -1 : 0 -#var float4 glstate.texgen[6].eye.r : STATE.TEXGEN[6].EYE.R : : -1 : 0 -#var float4 glstate.texgen[6].eye.q : STATE.TEXGEN[6].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[6].object.s : STATE.TEXGEN[6].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[6].object.t : STATE.TEXGEN[6].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[6].object.r : STATE.TEXGEN[6].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[6].object.q : STATE.TEXGEN[6].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[7].eye.s : STATE.TEXGEN[7].EYE.S : : -1 : 0 -#var float4 glstate.texgen[7].eye.t : STATE.TEXGEN[7].EYE.T : : -1 : 0 -#var float4 glstate.texgen[7].eye.r : STATE.TEXGEN[7].EYE.R : : -1 : 0 -#var float4 glstate.texgen[7].eye.q : STATE.TEXGEN[7].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[7].object.s : STATE.TEXGEN[7].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[7].object.t : STATE.TEXGEN[7].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[7].object.r : STATE.TEXGEN[7].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[7].object.q : STATE.TEXGEN[7].OBJECT.Q : : -1 : 0 -#var float4 glstate.fog.color : STATE.FOG.COLOR : : -1 : 0 -#var float4 glstate.fog.params : STATE.FOG.PARAMS : : -1 : 0 -#var float4 glstate.clip[0].plane : STATE.CLIP[0].PLANE : : -1 : 0 -#var float4 glstate.clip[1].plane : STATE.CLIP[1].PLANE : : -1 : 0 -#var float4 glstate.clip[2].plane : STATE.CLIP[2].PLANE : : -1 : 0 -#var float4 glstate.clip[3].plane : STATE.CLIP[3].PLANE : : -1 : 0 -#var float4 glstate.clip[4].plane : STATE.CLIP[4].PLANE : : -1 : 0 -#var float4 glstate.clip[5].plane : STATE.CLIP[5].PLANE : : -1 : 0 -#var float4 glstate.clip[6].plane : STATE.CLIP[6].PLANE : : -1 : 0 -#var float4 glstate.clip[7].plane : STATE.CLIP[7].PLANE : : -1 : 0 -#var float glstate.point.size : STATE.POINT.SIZE : : -1 : 0 -#var float glstate.point.attenuation : STATE.POINT.ATTENUATION : : -1 : 0 -#var float4x4 glstate.matrix.modelview[0] : STATE.MATRIX.MODELVIEW[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[1] : STATE.MATRIX.MODELVIEW[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[2] : STATE.MATRIX.MODELVIEW[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[3] : STATE.MATRIX.MODELVIEW[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[4] : STATE.MATRIX.MODELVIEW[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[5] : STATE.MATRIX.MODELVIEW[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[6] : STATE.MATRIX.MODELVIEW[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[7] : STATE.MATRIX.MODELVIEW[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.projection : STATE.MATRIX.PROJECTION : , 4 : -1 : 0 -#var float4x4 glstate.matrix.mvp : STATE.MATRIX.MVP : c[0], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[0] : STATE.MATRIX.TEXTURE[0] : c[4], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[1] : STATE.MATRIX.TEXTURE[1] : c[8], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[2] : STATE.MATRIX.TEXTURE[2] : c[12], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[3] : STATE.MATRIX.TEXTURE[3] : c[16], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[4] : STATE.MATRIX.TEXTURE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[5] : STATE.MATRIX.TEXTURE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[6] : STATE.MATRIX.TEXTURE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[7] : STATE.MATRIX.TEXTURE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[0] : STATE.MATRIX.PALETTE[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[1] : STATE.MATRIX.PALETTE[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[2] : STATE.MATRIX.PALETTE[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[3] : STATE.MATRIX.PALETTE[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[4] : STATE.MATRIX.PALETTE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[5] : STATE.MATRIX.PALETTE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[6] : STATE.MATRIX.PALETTE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[7] : STATE.MATRIX.PALETTE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[0] : STATE.MATRIX.PROGRAM[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[1] : STATE.MATRIX.PROGRAM[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[2] : STATE.MATRIX.PROGRAM[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[3] : STATE.MATRIX.PROGRAM[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[4] : STATE.MATRIX.PROGRAM[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[5] : STATE.MATRIX.PROGRAM[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[6] : STATE.MATRIX.PROGRAM[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[7] : STATE.MATRIX.PROGRAM[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.projection : STATE.MATRIX.PROJECTION.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.mvp : STATE.MATRIX.MVP.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[0] : STATE.MATRIX.TEXTURE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[1] : STATE.MATRIX.TEXTURE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[2] : STATE.MATRIX.TEXTURE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[3] : STATE.MATRIX.TEXTURE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[4] : STATE.MATRIX.TEXTURE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[5] : STATE.MATRIX.TEXTURE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[6] : STATE.MATRIX.TEXTURE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[7] : STATE.MATRIX.TEXTURE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[0] : STATE.MATRIX.PALETTE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[1] : STATE.MATRIX.PALETTE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[2] : STATE.MATRIX.PALETTE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[3] : STATE.MATRIX.PALETTE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[4] : STATE.MATRIX.PALETTE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[5] : STATE.MATRIX.PALETTE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[6] : STATE.MATRIX.PALETTE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[7] : STATE.MATRIX.PALETTE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[0] : STATE.MATRIX.PROGRAM[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[1] : STATE.MATRIX.PROGRAM[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[2] : STATE.MATRIX.PROGRAM[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[3] : STATE.MATRIX.PROGRAM[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[4] : STATE.MATRIX.PROGRAM[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[5] : STATE.MATRIX.PROGRAM[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[6] : STATE.MATRIX.PROGRAM[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[7] : STATE.MATRIX.PROGRAM[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[0] : STATE.MATRIX.MODELVIEW[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[1] : STATE.MATRIX.MODELVIEW[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[2] : STATE.MATRIX.MODELVIEW[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[3] : STATE.MATRIX.MODELVIEW[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[4] : STATE.MATRIX.MODELVIEW[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[5] : STATE.MATRIX.MODELVIEW[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[6] : STATE.MATRIX.MODELVIEW[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[7] : STATE.MATRIX.MODELVIEW[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.projection : STATE.MATRIX.PROJECTION.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.mvp : STATE.MATRIX.MVP.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[0] : STATE.MATRIX.TEXTURE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[1] : STATE.MATRIX.TEXTURE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[2] : STATE.MATRIX.TEXTURE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[3] : STATE.MATRIX.TEXTURE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[4] : STATE.MATRIX.TEXTURE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[5] : STATE.MATRIX.TEXTURE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[6] : STATE.MATRIX.TEXTURE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[7] : STATE.MATRIX.TEXTURE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[0] : STATE.MATRIX.PALETTE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[1] : STATE.MATRIX.PALETTE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[2] : STATE.MATRIX.PALETTE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[3] : STATE.MATRIX.PALETTE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[4] : STATE.MATRIX.PALETTE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[5] : STATE.MATRIX.PALETTE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[6] : STATE.MATRIX.PALETTE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[7] : STATE.MATRIX.PALETTE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[0] : STATE.MATRIX.PROGRAM[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[1] : STATE.MATRIX.PROGRAM[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[2] : STATE.MATRIX.PROGRAM[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[3] : STATE.MATRIX.PROGRAM[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[4] : STATE.MATRIX.PROGRAM[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[5] : STATE.MATRIX.PROGRAM[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[6] : STATE.MATRIX.PROGRAM[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[7] : STATE.MATRIX.PROGRAM[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.projection : STATE.MATRIX.PROJECTION.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.mvp : STATE.MATRIX.MVP.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[0] : STATE.MATRIX.TEXTURE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[1] : STATE.MATRIX.TEXTURE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[2] : STATE.MATRIX.TEXTURE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[3] : STATE.MATRIX.TEXTURE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[4] : STATE.MATRIX.TEXTURE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[5] : STATE.MATRIX.TEXTURE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[6] : STATE.MATRIX.TEXTURE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[7] : STATE.MATRIX.TEXTURE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[0] : STATE.MATRIX.PALETTE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[1] : STATE.MATRIX.PALETTE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[2] : STATE.MATRIX.PALETTE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[3] : STATE.MATRIX.PALETTE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[4] : STATE.MATRIX.PALETTE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[5] : STATE.MATRIX.PALETTE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[6] : STATE.MATRIX.PALETTE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[7] : STATE.MATRIX.PALETTE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[0] : STATE.MATRIX.PROGRAM[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[1] : STATE.MATRIX.PROGRAM[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[2] : STATE.MATRIX.PROGRAM[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[3] : STATE.MATRIX.PROGRAM[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[4] : STATE.MATRIX.PROGRAM[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[5] : STATE.MATRIX.PROGRAM[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[6] : STATE.MATRIX.PROGRAM[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[7] : STATE.MATRIX.PROGRAM[7].INVTRANS : , 4 : -1 : 0 -#var float4 IN.position : $vin.POSITION : POSITION : 0 : 1 -#var float4 IN.tex0 : $vin.ATTR8 : ATTR8 : 0 : 1 -#var float3 IN.tangent : $vin.ATTR9 : ATTR9 : 0 : 1 -#var float3 IN.binormal : $vin.ATTR10 : ATTR10 : 0 : 1 -#var float3 IN.normal : $vin.ATTR11 : ATTR11 : 0 : 1 -#var float4 main.hposition : $vout.HPOS : HPOS : -1 : 1 -#var float4 main.position : $vout.TEX0 : TEX0 : -1 : 1 -#var float4 main.tex_diffuse_bump : $vout.TEX1 : TEX1 : -1 : 1 -#var float4 main.tex_specular : $vout.TEX2 : TEX2 : -1 : 1 -#var float4 main.tex_atten_xy_z : $vout.TEX3 : TEX3 : -1 : 1 -#var float3 main.tangent : $vout.TEX4 : TEX4 : -1 : 1 -#var float3 main.binormal : $vout.TEX5 : TEX5 : -1 : 1 -#var float3 main.normal : $vout.TEX6 : TEX6 : -1 : 1 -PARAM c[20] = { state.matrix.mvp, - state.matrix.texture[0], - state.matrix.texture[1], - state.matrix.texture[2], - state.matrix.texture[3] }; -TEMP R0; -DP4 result.position.w, vertex.position, c[3]; -DP4 result.position.z, vertex.position, c[2]; -DP4 result.position.y, vertex.position, c[1]; -DP4 result.position.x, vertex.position, c[0]; -DP4 R0.y, vertex.attrib[8], c[9]; -DP4 R0.x, vertex.attrib[8], c[8]; -MOV result.texcoord[0], vertex.position; -MOV result.texcoord[1].zw, R0.xyxy; -DP4 result.texcoord[1].y, vertex.attrib[8], c[5]; -DP4 result.texcoord[1].x, vertex.attrib[8], c[4]; -DP4 result.texcoord[2].w, vertex.attrib[8], c[15]; -DP4 result.texcoord[2].z, vertex.attrib[8], c[14]; -DP4 result.texcoord[2].y, vertex.attrib[8], c[13]; -DP4 result.texcoord[2].x, vertex.attrib[8], c[12]; -DP4 result.texcoord[3].w, vertex.position, c[19]; -DP4 result.texcoord[3].z, vertex.position, c[18]; -DP4 result.texcoord[3].y, vertex.position, c[17]; -DP4 result.texcoord[3].x, vertex.position, c[16]; -MOV result.texcoord[4].xyz, vertex.attrib[9]; -MOV result.texcoord[5].xyz, vertex.attrib[10]; -MOV result.texcoord[6].xyz, vertex.attrib[11]; -END -# 21 instructions, 1 R-regs diff --git a/resources/gl/lighting_DBS_omni_vp.glsl b/resources/gl/lighting_DBS_omni_vp.glsl deleted file mode 100644 index 6900b5a..0000000 --- a/resources/gl/lighting_DBS_omni_vp.glsl +++ /dev/null @@ -1,58 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "CONTRIBUTORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -attribute vec4 attr_TexCoord0; -attribute vec3 attr_Tangent; -attribute vec3 attr_Binormal; - -varying vec3 var_vertex; -varying vec4 var_tex_diffuse_bump; -varying vec2 var_tex_specular; -varying vec4 var_tex_atten_xy_z; -varying mat3 var_mat_os2ts; - -void main() -{ - // transform vertex position into homogenous clip-space - gl_Position = ftransform(); - - // assign position in object space - var_vertex = gl_Vertex.xyz; - - // transform texcoords into diffusemap texture space - var_tex_diffuse_bump.st = (gl_TextureMatrix[0] * attr_TexCoord0).st; - - // transform texcoords into bumpmap texture space - var_tex_diffuse_bump.pq = (gl_TextureMatrix[1] * attr_TexCoord0).st; - - // transform texcoords into specularmap texture space - var_tex_specular = (gl_TextureMatrix[2] * attr_TexCoord0).st; - - // calc light xy,z attenuation in light space - var_tex_atten_xy_z = gl_TextureMatrix[3] * gl_Vertex; - - - // construct object-space-to-tangent-space 3x3 matrix - var_mat_os2ts = mat3( attr_Tangent.x, attr_Binormal.x, gl_Normal.x, - attr_Tangent.y, attr_Binormal.y, gl_Normal.y, - attr_Tangent.z, attr_Binormal.z, gl_Normal.z ); -} diff --git a/resources/gl/utils.cg b/resources/gl/utils.cg deleted file mode 100644 index 63bfcb6..0000000 --- a/resources/gl/utils.cg +++ /dev/null @@ -1,36 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -// fresnel approximation -float fast_fresnel(float3 I, float3 N, float3 fresnel_values) -{ - float power = fresnel_values.x; - float scale = fresnel_values.y; - float bias = fresnel_values.z; - - return bias + pow(1.0 - dot(I, N), power) * scale; -} - -float3 CG_Expand(float3 v) -{ - return (v - 0.5) * 2; // expand a range-compressed vector -} diff --git a/resources/gl/zfill_arbfp1.cg b/resources/gl/zfill_arbfp1.cg deleted file mode 100644 index c80189c..0000000 --- a/resources/gl/zfill_arbfp1.cg +++ /dev/null @@ -1,47 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2003 Robert Beckebans -Copyright (C) 2003, 2004 contributors of the XreaL project -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - - -struct cg_vertex2fragment -{ - float4 position : POSITION; - float4 tex0 : TEXCOORD0; -}; - -struct cg_fragment2final -{ - float4 color : COLOR; -}; - - -cg_fragment2final main(in cg_vertex2fragment IN, - uniform sampler2D colormap) -{ - cg_fragment2final OUT; - - OUT.color.w = tex2D(colormap, IN.tex0.xy).a; - - OUT.color.xyz = 0; - - return OUT; -} diff --git a/resources/gl/zfill_arbvp1.cg b/resources/gl/zfill_arbvp1.cg deleted file mode 100644 index 4ffc6e2..0000000 --- a/resources/gl/zfill_arbvp1.cg +++ /dev/null @@ -1,49 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2003 Robert Beckebans -Copyright (C) 2003, 2004 contributors of the XreaL project -Please see the file "AUTHORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - - -struct cg_app2vertex -{ - float4 position : ATTR0; - float4 texcoord0 : ATTR8; -}; - -struct cg_vertex2fragment -{ - float4 position : POSITION; - float4 tex0 : TEXCOORD0; -}; - - -cg_vertex2fragment main(cg_app2vertex IN) -{ - cg_vertex2fragment OUT; - - // transform vertex position into homogenous clip-space - OUT.position = mul(glstate.matrix.mvp, IN.position); - - // transform texcoords into 1st texture space - OUT.tex0 = mul(glstate.matrix.texture[0], IN.texcoord0); - - return OUT; -} diff --git a/resources/gl/zfill_fp.glp b/resources/gl/zfill_fp.glp deleted file mode 100644 index 5eb8b12..0000000 --- a/resources/gl/zfill_fp.glp +++ /dev/null @@ -1,19 +0,0 @@ -!!ARBfp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbfp1 -# source file: ..\..\setup\data\tools\gl\zfill_arbfp1.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbfp1 -#program main -#semantic main.colormap -#var float4 IN.position : : : 0 : 0 -#var float4 IN.tex0 : $vin.TEX0 : TEX0 : 0 : 1 -#var sampler2D colormap : : texunit 0 : 1 : 1 -#var float4 main.color : $vout.COL : COL : -1 : 1 -#const c[0] = 0 -PARAM c[1] = { { 0 } }; -MOV result.color.xyz, c[0].x; -TEX result.color.w, fragment.texcoord[0], texture[0], 2D; -END -# 2 instructions, 0 R-regs diff --git a/resources/gl/zfill_fp.glsl b/resources/gl/zfill_fp.glsl deleted file mode 100644 index 537db67..0000000 --- a/resources/gl/zfill_fp.glsl +++ /dev/null @@ -1,29 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "CONTRIBUTORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -uniform sampler2D u_colormap; - -void main() -{ - gl_FragColor.a = texture2D(u_colormap, gl_TexCoord[0].st).a; - gl_FragColor.rgb = vec3(0.0, 0.0, 0.0); -} diff --git a/resources/gl/zfill_vp.glp b/resources/gl/zfill_vp.glp deleted file mode 100644 index f6eda0c..0000000 --- a/resources/gl/zfill_vp.glp +++ /dev/null @@ -1,384 +0,0 @@ -!!ARBvp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbvp1 -# source file: ..\..\setup\data\tools\gl\zfill_arbvp1.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbvp1 -#program main -#semantic glstate : STATE -#var float4 glstate.material.ambient : STATE.MATERIAL.AMBIENT : : -1 : 0 -#var float4 glstate.material.diffuse : STATE.MATERIAL.DIFFUSE : : -1 : 0 -#var float4 glstate.material.specular : STATE.MATERIAL.SPECULAR : : -1 : 0 -#var float4 glstate.material.emission : STATE.MATERIAL.EMISSION : : -1 : 0 -#var float4 glstate.material.shininess : STATE.MATERIAL.SHININESS : : -1 : 0 -#var float4 glstate.material.front.ambient : STATE.MATERIAL.FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.material.front.diffuse : STATE.MATERIAL.FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.material.front.specular : STATE.MATERIAL.FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.material.front.emission : STATE.MATERIAL.FRONT.EMISSION : : -1 : 0 -#var float4 glstate.material.front.shininess : STATE.MATERIAL.FRONT.SHININESS : : -1 : 0 -#var float4 glstate.material.back.ambient : STATE.MATERIAL.BACK.AMBIENT : : -1 : 0 -#var float4 glstate.material.back.diffuse : STATE.MATERIAL.BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.material.back.specular : STATE.MATERIAL.BACK.SPECULAR : : -1 : 0 -#var float4 glstate.material.back.emission : STATE.MATERIAL.BACK.EMISSION : : -1 : 0 -#var float4 glstate.material.back.shininess : STATE.MATERIAL.BACK.SHININESS : : -1 : 0 -#var float4 glstate.light[0].ambient : STATE.LIGHT[0].AMBIENT : : -1 : 0 -#var float4 glstate.light[0].diffuse : STATE.LIGHT[0].DIFFUSE : : -1 : 0 -#var float4 glstate.light[0].specular : STATE.LIGHT[0].SPECULAR : : -1 : 0 -#var float4 glstate.light[0].position : STATE.LIGHT[0].POSITION : : -1 : 0 -#var float4 glstate.light[0].attenuation : STATE.LIGHT[0].ATTENUATION : : -1 : 0 -#var float4 glstate.light[0].spot.direction : STATE.LIGHT[0].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[0].half : STATE.LIGHT[0].HALF : : -1 : 0 -#var float4 glstate.light[1].ambient : STATE.LIGHT[1].AMBIENT : : -1 : 0 -#var float4 glstate.light[1].diffuse : STATE.LIGHT[1].DIFFUSE : : -1 : 0 -#var float4 glstate.light[1].specular : STATE.LIGHT[1].SPECULAR : : -1 : 0 -#var float4 glstate.light[1].position : STATE.LIGHT[1].POSITION : : -1 : 0 -#var float4 glstate.light[1].attenuation : STATE.LIGHT[1].ATTENUATION : : -1 : 0 -#var float4 glstate.light[1].spot.direction : STATE.LIGHT[1].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[1].half : STATE.LIGHT[1].HALF : : -1 : 0 -#var float4 glstate.light[2].ambient : STATE.LIGHT[2].AMBIENT : : -1 : 0 -#var float4 glstate.light[2].diffuse : STATE.LIGHT[2].DIFFUSE : : -1 : 0 -#var float4 glstate.light[2].specular : STATE.LIGHT[2].SPECULAR : : -1 : 0 -#var float4 glstate.light[2].position : STATE.LIGHT[2].POSITION : : -1 : 0 -#var float4 glstate.light[2].attenuation : STATE.LIGHT[2].ATTENUATION : : -1 : 0 -#var float4 glstate.light[2].spot.direction : STATE.LIGHT[2].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[2].half : STATE.LIGHT[2].HALF : : -1 : 0 -#var float4 glstate.light[3].ambient : STATE.LIGHT[3].AMBIENT : : -1 : 0 -#var float4 glstate.light[3].diffuse : STATE.LIGHT[3].DIFFUSE : : -1 : 0 -#var float4 glstate.light[3].specular : STATE.LIGHT[3].SPECULAR : : -1 : 0 -#var float4 glstate.light[3].position : STATE.LIGHT[3].POSITION : : -1 : 0 -#var float4 glstate.light[3].attenuation : STATE.LIGHT[3].ATTENUATION : : -1 : 0 -#var float4 glstate.light[3].spot.direction : STATE.LIGHT[3].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[3].half : STATE.LIGHT[3].HALF : : -1 : 0 -#var float4 glstate.light[4].ambient : STATE.LIGHT[4].AMBIENT : : -1 : 0 -#var float4 glstate.light[4].diffuse : STATE.LIGHT[4].DIFFUSE : : -1 : 0 -#var float4 glstate.light[4].specular : STATE.LIGHT[4].SPECULAR : : -1 : 0 -#var float4 glstate.light[4].position : STATE.LIGHT[4].POSITION : : -1 : 0 -#var float4 glstate.light[4].attenuation : STATE.LIGHT[4].ATTENUATION : : -1 : 0 -#var float4 glstate.light[4].spot.direction : STATE.LIGHT[4].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[4].half : STATE.LIGHT[4].HALF : : -1 : 0 -#var float4 glstate.light[5].ambient : STATE.LIGHT[5].AMBIENT : : -1 : 0 -#var float4 glstate.light[5].diffuse : STATE.LIGHT[5].DIFFUSE : : -1 : 0 -#var float4 glstate.light[5].specular : STATE.LIGHT[5].SPECULAR : : -1 : 0 -#var float4 glstate.light[5].position : STATE.LIGHT[5].POSITION : : -1 : 0 -#var float4 glstate.light[5].attenuation : STATE.LIGHT[5].ATTENUATION : : -1 : 0 -#var float4 glstate.light[5].spot.direction : STATE.LIGHT[5].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[5].half : STATE.LIGHT[5].HALF : : -1 : 0 -#var float4 glstate.light[6].ambient : STATE.LIGHT[6].AMBIENT : : -1 : 0 -#var float4 glstate.light[6].diffuse : STATE.LIGHT[6].DIFFUSE : : -1 : 0 -#var float4 glstate.light[6].specular : STATE.LIGHT[6].SPECULAR : : -1 : 0 -#var float4 glstate.light[6].position : STATE.LIGHT[6].POSITION : : -1 : 0 -#var float4 glstate.light[6].attenuation : STATE.LIGHT[6].ATTENUATION : : -1 : 0 -#var float4 glstate.light[6].spot.direction : STATE.LIGHT[6].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[6].half : STATE.LIGHT[6].HALF : : -1 : 0 -#var float4 glstate.light[7].ambient : STATE.LIGHT[7].AMBIENT : : -1 : 0 -#var float4 glstate.light[7].diffuse : STATE.LIGHT[7].DIFFUSE : : -1 : 0 -#var float4 glstate.light[7].specular : STATE.LIGHT[7].SPECULAR : : -1 : 0 -#var float4 glstate.light[7].position : STATE.LIGHT[7].POSITION : : -1 : 0 -#var float4 glstate.light[7].attenuation : STATE.LIGHT[7].ATTENUATION : : -1 : 0 -#var float4 glstate.light[7].spot.direction : STATE.LIGHT[7].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[7].half : STATE.LIGHT[7].HALF : : -1 : 0 -#var float4 glstate.lightmodel.ambient : STATE.LIGHTMODEL.AMBIENT : : -1 : 0 -#var float4 glstate.lightmodel.scenecolor : STATE.LIGHTMODEL.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.front.scenecolor : STATE.LIGHTMODEL.FRONT.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.back.scenecolor : STATE.LIGHTMODEL.BACK.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightprod[0].ambient : STATE.LIGHTPROD[0].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].diffuse : STATE.LIGHTPROD[0].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].specular : STATE.LIGHTPROD[0].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].front.ambient : STATE.LIGHTPROD[0].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].front.diffuse : STATE.LIGHTPROD[0].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].front.specular : STATE.LIGHTPROD[0].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].back.ambient : STATE.LIGHTPROD[0].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].back.diffuse : STATE.LIGHTPROD[0].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].back.specular : STATE.LIGHTPROD[0].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].ambient : STATE.LIGHTPROD[1].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].diffuse : STATE.LIGHTPROD[1].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].specular : STATE.LIGHTPROD[1].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].front.ambient : STATE.LIGHTPROD[1].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].front.diffuse : STATE.LIGHTPROD[1].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].front.specular : STATE.LIGHTPROD[1].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].back.ambient : STATE.LIGHTPROD[1].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].back.diffuse : STATE.LIGHTPROD[1].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].back.specular : STATE.LIGHTPROD[1].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].ambient : STATE.LIGHTPROD[2].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].diffuse : STATE.LIGHTPROD[2].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].specular : STATE.LIGHTPROD[2].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].front.ambient : STATE.LIGHTPROD[2].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].front.diffuse : STATE.LIGHTPROD[2].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].front.specular : STATE.LIGHTPROD[2].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].back.ambient : STATE.LIGHTPROD[2].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].back.diffuse : STATE.LIGHTPROD[2].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].back.specular : STATE.LIGHTPROD[2].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].ambient : STATE.LIGHTPROD[3].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].diffuse : STATE.LIGHTPROD[3].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].specular : STATE.LIGHTPROD[3].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].front.ambient : STATE.LIGHTPROD[3].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].front.diffuse : STATE.LIGHTPROD[3].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].front.specular : STATE.LIGHTPROD[3].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].back.ambient : STATE.LIGHTPROD[3].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].back.diffuse : STATE.LIGHTPROD[3].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].back.specular : STATE.LIGHTPROD[3].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].ambient : STATE.LIGHTPROD[4].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].diffuse : STATE.LIGHTPROD[4].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].specular : STATE.LIGHTPROD[4].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].front.ambient : STATE.LIGHTPROD[4].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].front.diffuse : STATE.LIGHTPROD[4].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].front.specular : STATE.LIGHTPROD[4].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].back.ambient : STATE.LIGHTPROD[4].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].back.diffuse : STATE.LIGHTPROD[4].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].back.specular : STATE.LIGHTPROD[4].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].ambient : STATE.LIGHTPROD[5].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].diffuse : STATE.LIGHTPROD[5].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].specular : STATE.LIGHTPROD[5].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].front.ambient : STATE.LIGHTPROD[5].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].front.diffuse : STATE.LIGHTPROD[5].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].front.specular : STATE.LIGHTPROD[5].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].back.ambient : STATE.LIGHTPROD[5].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].back.diffuse : STATE.LIGHTPROD[5].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].back.specular : STATE.LIGHTPROD[5].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].ambient : STATE.LIGHTPROD[6].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].diffuse : STATE.LIGHTPROD[6].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].specular : STATE.LIGHTPROD[6].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].front.ambient : STATE.LIGHTPROD[6].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].front.diffuse : STATE.LIGHTPROD[6].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].front.specular : STATE.LIGHTPROD[6].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].back.ambient : STATE.LIGHTPROD[6].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].back.diffuse : STATE.LIGHTPROD[6].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].back.specular : STATE.LIGHTPROD[6].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].ambient : STATE.LIGHTPROD[7].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].diffuse : STATE.LIGHTPROD[7].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].specular : STATE.LIGHTPROD[7].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].front.ambient : STATE.LIGHTPROD[7].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].front.diffuse : STATE.LIGHTPROD[7].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].front.specular : STATE.LIGHTPROD[7].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].back.ambient : STATE.LIGHTPROD[7].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].back.diffuse : STATE.LIGHTPROD[7].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].back.specular : STATE.LIGHTPROD[7].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.texgen[0].eye.s : STATE.TEXGEN[0].EYE.S : : -1 : 0 -#var float4 glstate.texgen[0].eye.t : STATE.TEXGEN[0].EYE.T : : -1 : 0 -#var float4 glstate.texgen[0].eye.r : STATE.TEXGEN[0].EYE.R : : -1 : 0 -#var float4 glstate.texgen[0].eye.q : STATE.TEXGEN[0].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[0].object.s : STATE.TEXGEN[0].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[0].object.t : STATE.TEXGEN[0].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[0].object.r : STATE.TEXGEN[0].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[0].object.q : STATE.TEXGEN[0].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[1].eye.s : STATE.TEXGEN[1].EYE.S : : -1 : 0 -#var float4 glstate.texgen[1].eye.t : STATE.TEXGEN[1].EYE.T : : -1 : 0 -#var float4 glstate.texgen[1].eye.r : STATE.TEXGEN[1].EYE.R : : -1 : 0 -#var float4 glstate.texgen[1].eye.q : STATE.TEXGEN[1].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[1].object.s : STATE.TEXGEN[1].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[1].object.t : STATE.TEXGEN[1].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[1].object.r : STATE.TEXGEN[1].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[1].object.q : STATE.TEXGEN[1].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[2].eye.s : STATE.TEXGEN[2].EYE.S : : -1 : 0 -#var float4 glstate.texgen[2].eye.t : STATE.TEXGEN[2].EYE.T : : -1 : 0 -#var float4 glstate.texgen[2].eye.r : STATE.TEXGEN[2].EYE.R : : -1 : 0 -#var float4 glstate.texgen[2].eye.q : STATE.TEXGEN[2].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[2].object.s : STATE.TEXGEN[2].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[2].object.t : STATE.TEXGEN[2].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[2].object.r : STATE.TEXGEN[2].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[2].object.q : STATE.TEXGEN[2].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[3].eye.s : STATE.TEXGEN[3].EYE.S : : -1 : 0 -#var float4 glstate.texgen[3].eye.t : STATE.TEXGEN[3].EYE.T : : -1 : 0 -#var float4 glstate.texgen[3].eye.r : STATE.TEXGEN[3].EYE.R : : -1 : 0 -#var float4 glstate.texgen[3].eye.q : STATE.TEXGEN[3].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[3].object.s : STATE.TEXGEN[3].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[3].object.t : STATE.TEXGEN[3].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[3].object.r : STATE.TEXGEN[3].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[3].object.q : STATE.TEXGEN[3].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[4].eye.s : STATE.TEXGEN[4].EYE.S : : -1 : 0 -#var float4 glstate.texgen[4].eye.t : STATE.TEXGEN[4].EYE.T : : -1 : 0 -#var float4 glstate.texgen[4].eye.r : STATE.TEXGEN[4].EYE.R : : -1 : 0 -#var float4 glstate.texgen[4].eye.q : STATE.TEXGEN[4].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[4].object.s : STATE.TEXGEN[4].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[4].object.t : STATE.TEXGEN[4].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[4].object.r : STATE.TEXGEN[4].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[4].object.q : STATE.TEXGEN[4].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[5].eye.s : STATE.TEXGEN[5].EYE.S : : -1 : 0 -#var float4 glstate.texgen[5].eye.t : STATE.TEXGEN[5].EYE.T : : -1 : 0 -#var float4 glstate.texgen[5].eye.r : STATE.TEXGEN[5].EYE.R : : -1 : 0 -#var float4 glstate.texgen[5].eye.q : STATE.TEXGEN[5].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[5].object.s : STATE.TEXGEN[5].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[5].object.t : STATE.TEXGEN[5].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[5].object.r : STATE.TEXGEN[5].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[5].object.q : STATE.TEXGEN[5].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[6].eye.s : STATE.TEXGEN[6].EYE.S : : -1 : 0 -#var float4 glstate.texgen[6].eye.t : STATE.TEXGEN[6].EYE.T : : -1 : 0 -#var float4 glstate.texgen[6].eye.r : STATE.TEXGEN[6].EYE.R : : -1 : 0 -#var float4 glstate.texgen[6].eye.q : STATE.TEXGEN[6].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[6].object.s : STATE.TEXGEN[6].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[6].object.t : STATE.TEXGEN[6].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[6].object.r : STATE.TEXGEN[6].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[6].object.q : STATE.TEXGEN[6].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[7].eye.s : STATE.TEXGEN[7].EYE.S : : -1 : 0 -#var float4 glstate.texgen[7].eye.t : STATE.TEXGEN[7].EYE.T : : -1 : 0 -#var float4 glstate.texgen[7].eye.r : STATE.TEXGEN[7].EYE.R : : -1 : 0 -#var float4 glstate.texgen[7].eye.q : STATE.TEXGEN[7].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[7].object.s : STATE.TEXGEN[7].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[7].object.t : STATE.TEXGEN[7].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[7].object.r : STATE.TEXGEN[7].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[7].object.q : STATE.TEXGEN[7].OBJECT.Q : : -1 : 0 -#var float4 glstate.fog.color : STATE.FOG.COLOR : : -1 : 0 -#var float4 glstate.fog.params : STATE.FOG.PARAMS : : -1 : 0 -#var float4 glstate.clip[0].plane : STATE.CLIP[0].PLANE : : -1 : 0 -#var float4 glstate.clip[1].plane : STATE.CLIP[1].PLANE : : -1 : 0 -#var float4 glstate.clip[2].plane : STATE.CLIP[2].PLANE : : -1 : 0 -#var float4 glstate.clip[3].plane : STATE.CLIP[3].PLANE : : -1 : 0 -#var float4 glstate.clip[4].plane : STATE.CLIP[4].PLANE : : -1 : 0 -#var float4 glstate.clip[5].plane : STATE.CLIP[5].PLANE : : -1 : 0 -#var float4 glstate.clip[6].plane : STATE.CLIP[6].PLANE : : -1 : 0 -#var float4 glstate.clip[7].plane : STATE.CLIP[7].PLANE : : -1 : 0 -#var float glstate.point.size : STATE.POINT.SIZE : : -1 : 0 -#var float glstate.point.attenuation : STATE.POINT.ATTENUATION : : -1 : 0 -#var float4x4 glstate.matrix.modelview[0] : STATE.MATRIX.MODELVIEW[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[1] : STATE.MATRIX.MODELVIEW[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[2] : STATE.MATRIX.MODELVIEW[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[3] : STATE.MATRIX.MODELVIEW[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[4] : STATE.MATRIX.MODELVIEW[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[5] : STATE.MATRIX.MODELVIEW[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[6] : STATE.MATRIX.MODELVIEW[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[7] : STATE.MATRIX.MODELVIEW[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.projection : STATE.MATRIX.PROJECTION : , 4 : -1 : 0 -#var float4x4 glstate.matrix.mvp : STATE.MATRIX.MVP : c[0], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[0] : STATE.MATRIX.TEXTURE[0] : c[4], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[1] : STATE.MATRIX.TEXTURE[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[2] : STATE.MATRIX.TEXTURE[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[3] : STATE.MATRIX.TEXTURE[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[4] : STATE.MATRIX.TEXTURE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[5] : STATE.MATRIX.TEXTURE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[6] : STATE.MATRIX.TEXTURE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[7] : STATE.MATRIX.TEXTURE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[0] : STATE.MATRIX.PALETTE[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[1] : STATE.MATRIX.PALETTE[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[2] : STATE.MATRIX.PALETTE[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[3] : STATE.MATRIX.PALETTE[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[4] : STATE.MATRIX.PALETTE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[5] : STATE.MATRIX.PALETTE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[6] : STATE.MATRIX.PALETTE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[7] : STATE.MATRIX.PALETTE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[0] : STATE.MATRIX.PROGRAM[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[1] : STATE.MATRIX.PROGRAM[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[2] : STATE.MATRIX.PROGRAM[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[3] : STATE.MATRIX.PROGRAM[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[4] : STATE.MATRIX.PROGRAM[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[5] : STATE.MATRIX.PROGRAM[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[6] : STATE.MATRIX.PROGRAM[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[7] : STATE.MATRIX.PROGRAM[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.projection : STATE.MATRIX.PROJECTION.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.mvp : STATE.MATRIX.MVP.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[0] : STATE.MATRIX.TEXTURE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[1] : STATE.MATRIX.TEXTURE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[2] : STATE.MATRIX.TEXTURE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[3] : STATE.MATRIX.TEXTURE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[4] : STATE.MATRIX.TEXTURE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[5] : STATE.MATRIX.TEXTURE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[6] : STATE.MATRIX.TEXTURE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[7] : STATE.MATRIX.TEXTURE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[0] : STATE.MATRIX.PALETTE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[1] : STATE.MATRIX.PALETTE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[2] : STATE.MATRIX.PALETTE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[3] : STATE.MATRIX.PALETTE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[4] : STATE.MATRIX.PALETTE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[5] : STATE.MATRIX.PALETTE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[6] : STATE.MATRIX.PALETTE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[7] : STATE.MATRIX.PALETTE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[0] : STATE.MATRIX.PROGRAM[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[1] : STATE.MATRIX.PROGRAM[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[2] : STATE.MATRIX.PROGRAM[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[3] : STATE.MATRIX.PROGRAM[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[4] : STATE.MATRIX.PROGRAM[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[5] : STATE.MATRIX.PROGRAM[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[6] : STATE.MATRIX.PROGRAM[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[7] : STATE.MATRIX.PROGRAM[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[0] : STATE.MATRIX.MODELVIEW[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[1] : STATE.MATRIX.MODELVIEW[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[2] : STATE.MATRIX.MODELVIEW[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[3] : STATE.MATRIX.MODELVIEW[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[4] : STATE.MATRIX.MODELVIEW[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[5] : STATE.MATRIX.MODELVIEW[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[6] : STATE.MATRIX.MODELVIEW[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[7] : STATE.MATRIX.MODELVIEW[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.projection : STATE.MATRIX.PROJECTION.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.mvp : STATE.MATRIX.MVP.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[0] : STATE.MATRIX.TEXTURE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[1] : STATE.MATRIX.TEXTURE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[2] : STATE.MATRIX.TEXTURE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[3] : STATE.MATRIX.TEXTURE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[4] : STATE.MATRIX.TEXTURE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[5] : STATE.MATRIX.TEXTURE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[6] : STATE.MATRIX.TEXTURE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[7] : STATE.MATRIX.TEXTURE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[0] : STATE.MATRIX.PALETTE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[1] : STATE.MATRIX.PALETTE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[2] : STATE.MATRIX.PALETTE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[3] : STATE.MATRIX.PALETTE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[4] : STATE.MATRIX.PALETTE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[5] : STATE.MATRIX.PALETTE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[6] : STATE.MATRIX.PALETTE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[7] : STATE.MATRIX.PALETTE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[0] : STATE.MATRIX.PROGRAM[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[1] : STATE.MATRIX.PROGRAM[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[2] : STATE.MATRIX.PROGRAM[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[3] : STATE.MATRIX.PROGRAM[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[4] : STATE.MATRIX.PROGRAM[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[5] : STATE.MATRIX.PROGRAM[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[6] : STATE.MATRIX.PROGRAM[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[7] : STATE.MATRIX.PROGRAM[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.projection : STATE.MATRIX.PROJECTION.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.mvp : STATE.MATRIX.MVP.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[0] : STATE.MATRIX.TEXTURE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[1] : STATE.MATRIX.TEXTURE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[2] : STATE.MATRIX.TEXTURE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[3] : STATE.MATRIX.TEXTURE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[4] : STATE.MATRIX.TEXTURE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[5] : STATE.MATRIX.TEXTURE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[6] : STATE.MATRIX.TEXTURE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[7] : STATE.MATRIX.TEXTURE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[0] : STATE.MATRIX.PALETTE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[1] : STATE.MATRIX.PALETTE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[2] : STATE.MATRIX.PALETTE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[3] : STATE.MATRIX.PALETTE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[4] : STATE.MATRIX.PALETTE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[5] : STATE.MATRIX.PALETTE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[6] : STATE.MATRIX.PALETTE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[7] : STATE.MATRIX.PALETTE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[0] : STATE.MATRIX.PROGRAM[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[1] : STATE.MATRIX.PROGRAM[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[2] : STATE.MATRIX.PROGRAM[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[3] : STATE.MATRIX.PROGRAM[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[4] : STATE.MATRIX.PROGRAM[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[5] : STATE.MATRIX.PROGRAM[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[6] : STATE.MATRIX.PROGRAM[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[7] : STATE.MATRIX.PROGRAM[7].INVTRANS : , 4 : -1 : 0 -#var float4 IN.position : $vin.ATTR0 : ATTR0 : 0 : 1 -#var float4 IN.texcoord0 : $vin.ATTR8 : ATTR8 : 0 : 1 -#var float4 main.position : $vout.HPOS : HPOS : -1 : 1 -#var float4 main.tex0 : $vout.TEX0 : TEX0 : -1 : 1 -PARAM c[8] = { state.matrix.mvp, - state.matrix.texture[0] }; -DP4 result.position.w, vertex.attrib[0], c[3]; -DP4 result.position.z, vertex.attrib[0], c[2]; -DP4 result.position.y, vertex.attrib[0], c[1]; -DP4 result.position.x, vertex.attrib[0], c[0]; -DP4 result.texcoord[0].w, vertex.attrib[8], c[7]; -DP4 result.texcoord[0].z, vertex.attrib[8], c[6]; -DP4 result.texcoord[0].y, vertex.attrib[8], c[5]; -DP4 result.texcoord[0].x, vertex.attrib[8], c[4]; -END -# 8 instructions, 0 R-regs diff --git a/resources/gl/zfill_vp.glsl b/resources/gl/zfill_vp.glsl deleted file mode 100644 index 4c81280..0000000 --- a/resources/gl/zfill_vp.glsl +++ /dev/null @@ -1,35 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "CONTRIBUTORS" for a list of contributors - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -attribute vec4 attr_TexCoord0; - -void main() -{ - // transform vertex position into homogenous clip-space - gl_Position = ftransform(); - - // transform texcoords - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - - // assign color - gl_FrontColor = gl_Color; -} diff --git a/resources/goldsrc.game/default_build_menu.xml b/resources/goldsrc.game/default_build_menu.xml deleted file mode 100644 index 3c1637e..0000000 --- a/resources/goldsrc.game/default_build_menu.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - -"[RadiantPath]vmap" -v -connect [MonitorAddress] -game platform -fs_basepath "[EnginePath]" -fs_game [GameName] - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis -v -fast "[MapFile]" - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis -v -fast "[MapFile]" -[vmap] -light -custinfoparms -v -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]" - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis "[MapFile]" -[vmap] -light -custinfoparms -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]" - - - - - diff --git a/resources/platform.game/default_build_menu.xml b/resources/platform.game/default_build_menu.xml deleted file mode 100644 index 3c1637e..0000000 --- a/resources/platform.game/default_build_menu.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - -"[RadiantPath]vmap" -v -connect [MonitorAddress] -game platform -fs_basepath "[EnginePath]" -fs_game [GameName] - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis -v -fast "[MapFile]" - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis -v -fast "[MapFile]" -[vmap] -light -custinfoparms -v -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]" - - - -[vmap] -custinfoparms -threads 4 -samplesize 8 "[MapFile]" -[vmap] -vis "[MapFile]" -[vmap] -light -custinfoparms -samplesize 8 -fast -threads 4 -samples 4 -shade -shadeangle 60 -patchshadows "[MapFile]" - - - - - diff --git a/src/Makefile b/src/Makefile index 81c14ec..37a58f1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,221 +1,157 @@ -# WorldSpawn Makefile +# vmap Makefile -GTK_CFLAGS=$(shell pkg-config --cflags gtk+-2.0) -GTK_LDFLAGS=$(shell pkg-config --libs gtk+-2.0) +# ws libs vmap uses +LIBOBJS=../libs/libddslib.a \ + ../libs/libetclib.a \ + ../libs/libfilematch.a \ + ../libs/libl_net.a \ + ../libs/libmathlib.a \ + ../libs/libpicomodel.a GLIB_CFLAGS=$(shell pkg-config --cflags glib-2.0) -GLIB_LDLAGS=$(shell pkg-config --libs glib-2.0) +GLIB_LDFLAGS=$(shell pkg-config --libs glib-2.0) XML_CFLAGS=$(shell pkg-config --cflags libxml-2.0) XML_LDFLAGS=$(shell pkg-config --libs libxml-2.0) -GLEXT_CFLAGS=$(shell pkg-config --cflags gtkglext-1.0) -GLEXT_LDFLAGS=$(shell pkg-config --libs gtkglext-1.0) +MINIZIP_CFLAGS=$(shell pkg-config --cflags minizip) +MINIZIP_LDFLAGS=$(shell pkg-config --libs minizip) -PANGO_CFLAGS=$(shell pkg-config --cflags pango) -PANGO_LDFLAGS=$(shell pkg-config --libs pango) +JPEG_CFLAGS=$(shell pkg-config --cflags libjpeg) +JPEG_LDFLAGS=$(shell pkg-config --libs libjpeg) -PANGOFT2_CFLAGS=$(shell pkg-config --cflags pangoft2) -PANGOFT2_LDFLAGS=$(shell pkg-config --libs pangoft2) +PNG_CFLAGS=$(shell pkg-config --cflags libpng) +PNG_LDFLAGS=$(shell pkg-config --libs libpng) -WS_LIBS= ../libs/libcmdlib.a \ - ../libs/libcontainer.a \ - ../libs/libddslib.a \ - ../libs/libdebugging.a \ - ../libs/libetclib.a \ - ../libs/libgeneric.a \ - ../libs/libgtkutil.a \ - ../libs/libl_net.a \ - ../libs/libmath.a \ - ../libs/libmathlib.a \ - ../libs/libmodulesystem.a \ - ../libs/libos.a \ - ../libs/libpicomodel.a \ - ../libs/libprofile.a \ - ../libs/libscript.a \ - ../libs/libsignal.a \ - ../libs/libsplines.a \ - ../libs/libstream.a \ - ../libs/libstring.a \ - ../libs/libuilib.a \ - ../libs/libxmllib.a +VMAP_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS) $(MINIZIP_CFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) -I../include -I../common -I../libs +VMAP_LDFLAGS=$(LDFLAGS) -lm -lpthread -L../lib $(GLIB_LDFLAGS) $(XML_LDFLAGS) $(MINIZIP_LDFLAGS) $(JPEG_LDFLAGS) $(PNG_LDFLAGS) -WS_CFLAGS=$(CFLAGS) $(GTK_CFLAGS) $(XML_CFLAGS) $(GLEXT_CFLAGS) -I../include -I../libs -DGTK_TARGET=2 $(WS_VERSION) -WS_LDFLAGS=$(LDFLAGS) -lm $(GTK_LDFLAGS) $(GLIB_LDFLAGS) $(XML_LDFLAGS) $(PANGO_LDFLAGS) $(PANGOFT2_LDFLAGS) $(GLEXT_LDFLAGS) -L../lib +DO_CC=$(CC) $(VMAP_CFLAGS) -o $@ -c $< -DO_CXX=$(CXX) $(WS_CFLAGS) -o $@ -c $< +.c.o: + $(DO_CC) -.cpp.o: - $(DO_CXX) - -WS_OBJS = \ - autosave.o \ +VMAP_OBJS = \ + ../common/cmdlib.o \ + ../common/imagelib.o \ + ../common/inout.o \ + ../common/jpeg.o \ + ../common/md4.o \ + ../common/mutex.o \ + ../common/polylib.o \ + ../common/scriplib.o \ + ../common/matlib.o \ + ../common/threads.o \ + ../common/vfs.o \ brush.o \ brush_primit.o \ - brushmanip.o \ - brushmodule.o \ - brushnode.o \ - brushtokens.o \ - brushxml.o \ - build.o \ - camwindow.o \ - commands.o \ - console.o \ - csg.o \ - dialog.o \ - eclass.o \ - eclass_def.o \ - eclass_doom3.o \ - eclass_fgd.o \ - eclass_xml.o \ - entity.o \ - entityinspector.o \ - entitylist.o \ - environment.o \ - error.o \ - feedback.o \ - filetypes.o \ - filters.o \ - findtexturedialog.o \ - glwidget.o \ - grid.o \ - groupdialog.o \ - gtkdlgs.o \ - gtkmisc.o \ + bsp.o \ + bsp_analyze.o \ + bsp_info.o \ + bsp_scale.o \ + bspfile_abstract.o \ + bspfile_ibsp.o \ + bspfile_rbsp.o \ + convert_ase.o \ + convert_bsp.o \ + convert_map.o \ + convert_obj.o \ + decals.o \ + exportents.o \ + facebsp.o \ + fixaas.o \ + fog.o \ help.o \ image.o \ + leakfile.o \ + light.o \ + light_bounce.o \ + light_trace.o \ + light_ydnar.o \ + lightmaps_ydnar.o \ main.o \ - mainframe.o \ - multimon.o \ map.o \ - mru.o \ - nullmodel.o \ - parse.o \ + mesh.o \ + model.o \ patch.o \ - patchdialog.o \ - patchmanip.o \ - patchmodule.o \ - plugin.o \ - pluginapi.o \ - pluginmanager.o \ - pluginmenu.o \ - plugintoolbar.o \ - points.o \ - preferencedictionary.o \ - preferences.o \ - qe3.o \ - qgl.o \ - referencecache.o \ - renderer.o \ - renderstate.o \ - scenegraph.o \ - select.o \ - selection.o \ - server.o \ + path_init.o \ + portals.o \ + prtfile.o \ shaders.o \ - sockets.o \ - stacktrace.o \ - surfacedialog.o \ - texmanip.o \ - textureentry.o \ - textures.o \ - texwindow.o \ - timer.o \ - treemodel.o \ - undo.o \ - url.o \ - view.o \ - watchbsp.o \ - winding.o \ - windowobservers.o \ - xmlstuff.o \ - xywindow.o + surface.o \ + surface_extra.o \ + surface_foliage.o \ + surface_fur.o \ + surface_meta.o \ + tjunction.o \ + tree.o \ + vis.o \ + visflow.o \ + writebsp.o # binary target -../build/worldspawn: $(WS_OBJS) - $(CXX) -o $@ $(WS_OBJS) $(WS_LIBS) $(WS_LDFLAGS) +../vmap: $(VMAP_OBJS) + $(CXX) -o $@ $(VMAP_OBJS) $(LIBOBJS) $(VMAP_LDFLAGS) clean: - -rm -f *.o ../build/worldspawn + -rm -f ./../common/*.o + -rm -f ./*.o + -rm -f ../vmap # object files -autosave.o: autosave.cpp autosave.h -brush.o: brush.cpp brush.h -brush_primit.o: brush_primit.cpp brush_primit.h -brushmanip.o: brushmanip.cpp brushmanip.h -brushmodule.o: brushmodule.cpp brushmodule.h -brushnode.o: brushnode.cpp brushnode.h -brushtokens.o: brushtokens.cpp brushtokens.h -brushxml.o: brushxml.cpp brushxml.h -build.o: build.cpp build.h -camwindow.o: camwindow.cpp camwindow.h -commands.o: commands.cpp commands.h -console.o: console.cpp console.h -csg.o: csg.cpp csg.h -dialog.o: dialog.cpp dialog.h -eclass.o: eclass.cpp eclass.h -eclass_def.o: eclass_def.cpp eclass_def.h -eclass_doom3.o: eclass_doom3.cpp eclass_doom3.h -eclass_fgd.o: eclass_fgd.cpp eclass_fgd.h -eclass_xml.o: eclass_xml.cpp eclass_xml.h -entity.o: entity.cpp entity.h -entityinspector.o: entityinspector.cpp entityinspector.h -entitylist.o: entitylist.cpp entitylist.h -environment.o: environment.cpp environment.h -error.o: error.cpp error.h -feedback.o: feedback.cpp feedback.h -filetypes.o: filetypes.cpp filetypes.h -filters.o: filters.cpp filters.h -findtexturedialog.o: findtexturedialog.cpp findtexturedialog.h -glwidget.o: glwidget.cpp glwidget.h -grid.o: grid.cpp grid.h -groupdialog.o: groupdialog.cpp groupdialog.h -gtkdlgs.o: gtkdlgs.cpp gtkdlgs.h -gtkmisc.o: gtkmisc.cpp gtkmisc.h -help.o: help.cpp help.h -image.o: image.cpp image.h -main.o: main.cpp main.h -mainframe.o: mainframe.cpp mainframe.h -map.o: map.cpp map.h -mru.o: mru.cpp mru.h -nullmodel.o: nullmodel.cpp nullmodel.h -parse.o: parse.cpp parse.h -patch.o: patch.cpp patch.h -patchdialog.o: patchdialog.cpp patchdialog.h -patchmanip.o: patchmanip.cpp patchmanip.h -patchmodule.o: patchmodule.cpp patchmodule.h -plugin.o: plugin.cpp plugin.h -pluginapi.o: pluginapi.cpp pluginapi.h -pluginmanager.o: pluginmanager.cpp pluginmanager.h -pluginmenu.o: pluginmenu.cpp pluginmenu.h -plugintoolbar.o: plugintoolbar.cpp plugintoolbar.h -points.o: points.cpp points.h -preferencedictionary.o: preferencedictionary.cpp preferencedictionary.h -preferences.o: preferences.cpp preferences.h -qe3.o: qe3.cpp qe3.h -qgl.o: qgl.cpp qgl.h -referencecache.o: referencecache.cpp referencecache.h -renderer.o: renderer.cpp renderer.h -renderstate.o: renderstate.cpp renderstate.h -scenegraph.o: scenegraph.cpp scenegraph.h -select.o: select.cpp select.h -selection.o: selection.cpp selection.h -server.o: server.cpp server.h -shaders.o: shaders.cpp shaders.h -sockets.o: sockets.cpp sockets.h -stacktrace.o: stacktrace.cpp stacktrace.h -surfacedialog.o: surfacedialog.cpp surfacedialog.h -texmanip.o: texmanip.cpp texmanip.h -textureentry.o: textureentry.cpp textureentry.h -textures.o: textures.cpp textures.h -texwindow.o: texwindow.cpp texwindow.h -timer.o: timer.cpp timer.h -treemodel.o: treemodel.cpp treemodel.h -undo.o: undo.cpp undo.h -url.o: url.cpp url.h -view.o: view.cpp view.h -watchbsp.o: watchbsp.cpp watchbsp.h -winding.o: winding.cpp winding.h -windowobservers.o: windowobservers.cpp windowobservers.h -xmlstuff.o: xmlstuff.cpp xmlstuff.h -xywindow.o: xywindow.cpp xywindow.h +../common/cmdlib.o: ../common/cmdlib.c ../common/cmdlib.h +../common/imagelib.o: ../common/imagelib.c ../common/imagelib.h +../common/inout.o: ../common/inout.c ../common/inout.h +../common/jpeg.o: ../common/jpeg.c +../common/md4.o: ../common/md4.c ../common/md4.h +../common/mutex.o: ../common/mutex.c ../common/mutex.h +../common/polylib.o: ../common/polylib.c ../common/polylib.h +../common/scriplib.o: ../common/scriplib.c ../common/scriplib.h +../common/matlib.o: ../common/matlib.c ../common/matlib.h +../common/threads.o: ../common/threads.c +../common/vfs.o: ../common/vfs.c ../common/vfs.h +brush.o: brush.c +brush_primit.o: brush_primit.c +bsp.o: bsp.c +bsp_analyze.o: bsp_analyze.c +bsp_info.o: bsp_info.c +bsp_scale.o: bsp_scale.c +bspfile_abstract.o: bspfile_abstract.c +bspfile_ibsp.o: bspfile_ibsp.c +bspfile_rbsp.o: bspfile_rbsp.c +convert_ase.o: convert_ase.c +convert_bsp.o: convert_bsp.c +convert_map.o: convert_map.c +convert_obj.o: convert_obj.c +decals.o: decals.c +exportents.o: exportents.c +facebsp.o: facebsp.c +fixaas.o: fixaas.c +fog.o: fog.c +help.o: help.c +image.o: image.c +leakfile.o: leakfile.c +light.o: light.c +light_bounce.o: light_bounce.c +light_trace.o: light_trace.c +light_ydnar.o: light_ydnar.c +lightmaps_ydnar.o: lightmaps_ydnar.c +main.o: main.c +map.o: map.c +mesh.o: mesh.c +model.o: model.c +patch.o: patch.c +path_init.o: path_init.c +portals.o: portals.c +prtfile.o: prtfile.c +shaders.o: shaders.c +surface.o: surface.c +surface_extra.o: surface_extra.c +surface_foliage.o: surface_foliage.c +surface_fur.o: surface_fur.c +surface_meta.o: surface_meta.c +tjunction.o: tjunction.c +tree.o: tree.c +vis.o: vis.c +visflow.o: visflow.c +writebsp.o: writebsp.c diff --git a/src/autosave.cpp b/src/autosave.cpp deleted file mode 100644 index 29f7d90..0000000 --- a/src/autosave.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "autosave.h" -#include "globaldefs.h" - -#include "os/file.h" -#include "os/path.h" -#include "cmdlib.h" -#include "stream/stringstream.h" -#include "gtkutil/messagebox.h" -#include "scenelib.h" -#include "mapfile.h" - -#include "map.h" -#include "mainframe.h" -#include "qe3.h" -#include "preferences.h" - - -#if GDEF_OS_WINDOWS -#define PATH_MAX 260 -#endif - - -bool DoesFileExist(const char *name, std::size_t &size) -{ - if (file_exists(name)) { - size += file_size(name); - return true; - } - return false; -} - -void Map_Snapshot() -{ - // we need to do the following - // 1. make sure the snapshot directory exists (create it if it doesn't) - // 2. find out what the lastest save is based on number - // 3. inc that and save the map - const char *path = Map_Name(g_map); - const char *name = path_get_filename_start(path); - - StringOutputStream snapshotsDir(256); - snapshotsDir << StringRange(path, name) << "snapshots"; - - if (file_exists(snapshotsDir.c_str()) || Q_mkdir(snapshotsDir.c_str())) { - std::size_t lSize = 0; - StringOutputStream strNewPath(256); - strNewPath << snapshotsDir.c_str() << '/' << name; - - StringOutputStream snapshotFilename(256); - - for (int nCount = 0;; ++nCount) { - // The original map's filename is "/." - // The snapshot's filename will be "/snapshots/.." - const char *end = path_get_filename_base_end(strNewPath.c_str()); - snapshotFilename << StringRange(strNewPath.c_str(), end) << '.' << nCount << end; - - if (!DoesFileExist(snapshotFilename.c_str(), lSize)) { - break; - } - - snapshotFilename.clear(); - } - - // save in the next available slot - Map_SaveFile(snapshotFilename.c_str()); - - if (lSize > 50 * 1024 * 1024) { // total size of saves > 50 mb - globalOutputStream() << "The snapshot files in " << snapshotsDir.c_str() - << " total more than 50 megabytes. You might consider cleaning up."; - } - } else { - StringOutputStream strMsg(256); - strMsg << "Snapshot save failed.. unabled to create directory\n" << snapshotsDir.c_str(); - ui::alert(MainFrame_getWindow(), strMsg.c_str()); - } -} - -/* - =============== - QE_CheckAutoSave - - If five minutes have passed since making a change - and the map hasn't been saved, save it out. - =============== - */ - -bool g_AutoSave_Enabled = true; -int m_AutoSave_Frequency = 5; -bool g_SnapShots_Enabled = false; - -namespace { -time_t s_start = 0; -std::size_t s_changes = 0; -} - -void AutoSave_clear() -{ - s_changes = 0; -} - -scene::Node &Map_Node() -{ - return GlobalSceneGraph().root(); -} - -void QE_CheckAutoSave(void) -{ - if (!Map_Valid(g_map) || !ScreenUpdates_Enabled()) { - return; - } - - time_t now; - time(&now); - - if (s_start == 0 || s_changes == Node_getMapFile(Map_Node())->changes()) { - s_start = now; - } - - if ((now - s_start) > (60 * m_AutoSave_Frequency)) { - s_start = now; - s_changes = Node_getMapFile(Map_Node())->changes(); - - if (g_AutoSave_Enabled) { - const char *strMsg = g_SnapShots_Enabled ? "Autosaving snapshot..." : "Autosaving..."; - globalOutputStream() << strMsg << "\n"; - //Sys_Status(strMsg); - - // only snapshot if not working on a default map - if (g_SnapShots_Enabled && !Map_Unnamed(g_map)) { - Map_Snapshot(); - } else { - if (Map_Unnamed(g_map)) { - StringOutputStream autosave(256); - autosave << g_qeglobals.m_userGamePath.c_str() << "maps/"; - Q_mkdir(autosave.c_str()); - autosave << "autosave.map"; - Map_SaveFile(autosave.c_str()); - } else { - const char *name = Map_Name(g_map); - const char *extension = path_get_filename_base_end(name); - StringOutputStream autosave(256); - autosave << StringRange(name, extension) << ".autosave" << extension; - Map_SaveFile(autosave.c_str()); - } - } - } else { - globalOutputStream() << "Autosave skipped...\n"; - //Sys_Status ("Autosave skipped..."); - } - } -} - -void Autosave_constructPreferences(PreferencesPage &page) -{ - ui::CheckButton autosave_enabled = page.appendCheckBox("Autosave", "Enable Autosave", g_AutoSave_Enabled); - ui::SpinButton autosave_frequency = page.appendSpinner("Autosave Frequency (minutes)", m_AutoSave_Frequency, 1, 1, - 60); - Widget_connectToggleDependency(autosave_frequency, autosave_enabled); - page.appendCheckBox("", "Save Snapshots", g_SnapShots_Enabled); -} - -void Autosave_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Autosave", "Autosave Preferences")); - Autosave_constructPreferences(page); -} - -void Autosave_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Autosave_constructPage)); -} - - -#include "preferencesystem.h" -#include "stringio.h" - -void Autosave_Construct() -{ - GlobalPreferenceSystem().registerPreference("Autosave", make_property_string(g_AutoSave_Enabled)); - GlobalPreferenceSystem().registerPreference("AutosaveMinutes", make_property_string(m_AutoSave_Frequency)); - GlobalPreferenceSystem().registerPreference("Snapshots", make_property_string(g_SnapShots_Enabled)); - - Autosave_registerPreferencesPage(); -} - -void Autosave_Destroy() -{ -} diff --git a/src/autosave.h b/src/autosave.h deleted file mode 100644 index e7dc00e..0000000 --- a/src/autosave.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_AUTOSAVE_H ) -#define INCLUDED_AUTOSAVE_H - -extern bool g_SnapShots_Enabled; - -void AutoSave_clear(); - -void QE_CheckAutoSave(void); - -void Map_Snapshot(); - -void Autosave_Construct(); - -void Autosave_Destroy(); - - -#endif diff --git a/tools/vmap/brush.c b/src/brush.c similarity index 100% rename from tools/vmap/brush.c rename to src/brush.c diff --git a/src/brush.cpp b/src/brush.cpp deleted file mode 100644 index ed3f3c8..0000000 --- a/src/brush.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brush.h" -#include "signal/signal.h" - -Signal0 g_brushTextureChangedCallbacks; - -void Brush_addTextureChangedCallback(const SignalHandler &handler) -{ - g_brushTextureChangedCallbacks.connectLast(handler); -} - -void Brush_textureChanged() -{ - g_brushTextureChangedCallbacks(); -} - -QuantiseFunc Face::m_quantise; -EBrushType Face::m_type; -EBrushType FacePlane::m_type; -bool g_brush_texturelock_enabled = true; - -EBrushType Brush::m_type; -double Brush::m_maxWorldCoord = 0; -Shader *Brush::m_state_point; -Shader *BrushClipPlane::m_state = 0; -Shader *BrushInstance::m_state_selpoint; -Counter *BrushInstance::m_counter = 0; - -FaceInstanceSet g_SelectedFaceInstances; - - -struct SListNode { - SListNode *m_next; -}; - -class ProximalVertex { -public: -const SListNode *m_vertices; - -ProximalVertex(const SListNode *next) - : m_vertices(next) -{ -} - -bool operator<(const ProximalVertex &other) const -{ - if (!(operator==(other))) { - return m_vertices < other.m_vertices; - } - return false; -} - -bool operator==(const ProximalVertex &other) const -{ - const SListNode *v = m_vertices; - std::size_t DEBUG_LOOP = 0; - do { - if (v == other.m_vertices) { - return true; - } - v = v->m_next; - //ASSERT_MESSAGE(DEBUG_LOOP < c_brush_maxFaces, "infinite loop"); - if (!(DEBUG_LOOP < c_brush_maxFaces)) { - break; - } - ++DEBUG_LOOP; - } while (v != m_vertices); - return false; -} -}; - -typedef Array ProximalVertexArray; - -std::size_t ProximalVertexArray_index(const ProximalVertexArray &array, const ProximalVertex &vertex) -{ - return vertex.m_vertices - array.data(); -} - - -inline bool Brush_isBounded(const Brush &brush) -{ - for (Brush::const_iterator i = brush.begin(); i != brush.end(); ++i) { - if (!(*i)->is_bounded()) { - return false; - } - } - return true; -} - -void Brush::buildBRep() -{ - bool degenerate = buildWindings(); - - std::size_t faces_size = 0; - std::size_t faceVerticesCount = 0; - for (Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - if ((*i)->contributes()) { - ++faces_size; - } - faceVerticesCount += (*i)->getWinding().numpoints; - } - - if (degenerate || faces_size < 4 || faceVerticesCount != (faceVerticesCount >> 1) - << 1) { // sum of vertices for each face of a valid polyhedron is always even - m_uniqueVertexPoints.resize(0); - - vertex_clear(); - edge_clear(); - - m_edge_indices.resize(0); - m_edge_faces.resize(0); - - m_faceCentroidPoints.resize(0); - m_uniqueEdgePoints.resize(0); - m_uniqueVertexPoints.resize(0); - - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->getWinding().resize(0); - } - } else { - { - typedef std::vector FaceVertices; - FaceVertices faceVertices; - faceVertices.reserve(faceVerticesCount); - - { - for (std::size_t i = 0; i != m_faces.size(); ++i) { - for (std::size_t j = 0; j < m_faces[i]->getWinding().numpoints; ++j) { - faceVertices.push_back(FaceVertexId(i, j)); - } - } - } - - IndexBuffer uniqueEdgeIndices; - typedef VertexBuffer UniqueEdges; - UniqueEdges uniqueEdges; - - uniqueEdgeIndices.reserve(faceVertices.size()); - uniqueEdges.reserve(faceVertices.size()); - - { - ProximalVertexArray edgePairs; - edgePairs.resize(faceVertices.size()); - - { - for (std::size_t i = 0; i < faceVertices.size(); ++i) { - edgePairs[i].m_next = edgePairs.data() + absoluteIndex(next_edge(m_faces, faceVertices[i])); - } - } - - { - UniqueVertexBuffer inserter(uniqueEdges); - for (ProximalVertexArray::iterator i = edgePairs.begin(); i != edgePairs.end(); ++i) { - uniqueEdgeIndices.insert(inserter.insert(ProximalVertex(&(*i)))); - } - } - - { - edge_clear(); - m_select_edges.reserve(uniqueEdges.size()); - for (UniqueEdges::iterator i = uniqueEdges.begin(); i != uniqueEdges.end(); ++i) { - edge_push_back(faceVertices[ProximalVertexArray_index(edgePairs, *i)]); - } - } - - { - m_edge_faces.resize(uniqueEdges.size()); - for (std::size_t i = 0; i < uniqueEdges.size(); ++i) { - FaceVertexId faceVertex = faceVertices[ProximalVertexArray_index(edgePairs, uniqueEdges[i])]; - m_edge_faces[i] = EdgeFaces(faceVertex.getFace(), - m_faces[faceVertex.getFace()]->getWinding()[faceVertex.getVertex()].adjacent); - } - } - - { - m_uniqueEdgePoints.resize(uniqueEdges.size()); - for (std::size_t i = 0; i < uniqueEdges.size(); ++i) { - FaceVertexId faceVertex = faceVertices[ProximalVertexArray_index(edgePairs, uniqueEdges[i])]; - - const Winding &w = m_faces[faceVertex.getFace()]->getWinding(); - Vector3 edge = vector3_mid(w[faceVertex.getVertex()].vertex, - w[Winding_next(w, faceVertex.getVertex())].vertex); - m_uniqueEdgePoints[i] = pointvertex_for_windingpoint(edge, colour_vertex); - } - } - - } - - - IndexBuffer uniqueVertexIndices; - typedef VertexBuffer UniqueVertices; - UniqueVertices uniqueVertices; - - uniqueVertexIndices.reserve(faceVertices.size()); - uniqueVertices.reserve(faceVertices.size()); - - { - ProximalVertexArray vertexRings; - vertexRings.resize(faceVertices.size()); - - { - for (std::size_t i = 0; i < faceVertices.size(); ++i) { - vertexRings[i].m_next = - vertexRings.data() + absoluteIndex(next_vertex(m_faces, faceVertices[i])); - } - } - - { - UniqueVertexBuffer inserter(uniqueVertices); - for (ProximalVertexArray::iterator i = vertexRings.begin(); i != vertexRings.end(); ++i) { - uniqueVertexIndices.insert(inserter.insert(ProximalVertex(&(*i)))); - } - } - - { - vertex_clear(); - m_select_vertices.reserve(uniqueVertices.size()); - for (UniqueVertices::iterator i = uniqueVertices.begin(); i != uniqueVertices.end(); ++i) { - vertex_push_back(faceVertices[ProximalVertexArray_index(vertexRings, (*i))]); - } - } - - { - m_uniqueVertexPoints.resize(uniqueVertices.size()); - for (std::size_t i = 0; i < uniqueVertices.size(); ++i) { - FaceVertexId faceVertex = faceVertices[ProximalVertexArray_index(vertexRings, - uniqueVertices[i])]; - - const Winding &winding = m_faces[faceVertex.getFace()]->getWinding(); - m_uniqueVertexPoints[i] = pointvertex_for_windingpoint(winding[faceVertex.getVertex()].vertex, - colour_vertex); - } - } - } - - if ((uniqueVertices.size() + faces_size) - uniqueEdges.size() != 2) { - globalErrorStream() << "Final B-Rep: inconsistent vertex count\n"; - } - -#if BRUSH_CONNECTIVITY_DEBUG - if ( ( uniqueVertices.size() + faces_size ) - uniqueEdges.size() != 2 ) { - for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i ) - { - std::size_t faceIndex = std::distance( m_faces.begin(), i ); - - if ( !( *i )->contributes() ) { - globalOutputStream() << "face: " << Unsigned( faceIndex ) << " does not contribute\n"; - } - - Winding_printConnectivity( ( *i )->getWinding() ); - } - } -#endif - - // edge-index list for wireframe rendering - { - m_edge_indices.resize(uniqueEdgeIndices.size()); - - for (std::size_t i = 0, count = 0; i < m_faces.size(); ++i) { - const Winding &winding = m_faces[i]->getWinding(); - for (std::size_t j = 0; j < winding.numpoints; ++j) { - const RenderIndex edge_index = uniqueEdgeIndices[count + j]; - - m_edge_indices[edge_index].first = uniqueVertexIndices[count + j]; - m_edge_indices[edge_index].second = uniqueVertexIndices[count + Winding_next(winding, j)]; - } - count += winding.numpoints; - } - } - } - - { - m_faceCentroidPoints.resize(m_faces.size()); - for (std::size_t i = 0; i < m_faces.size(); ++i) { - m_faces[i]->construct_centroid(); - m_faceCentroidPoints[i] = pointvertex_for_windingpoint(m_faces[i]->centroid(), colour_vertex); - } - } - } -} - - -class FaceFilterWrapper : public Filter { -FaceFilter &m_filter; -bool m_active; -bool m_invert; -public: -FaceFilterWrapper(FaceFilter &filter, bool invert) : - m_filter(filter), - m_invert(invert) -{ -} - -void setActive(bool active) -{ - m_active = active; -} - -bool active() -{ - return m_active; -} - -bool filter(const Face &face) -{ - return m_invert ^ m_filter.filter(face); -} -}; - - -typedef std::list FaceFilters; -FaceFilters g_faceFilters; - -void add_face_filter(FaceFilter &filter, int mask, bool invert) -{ - g_faceFilters.push_back(FaceFilterWrapper(filter, invert)); - GlobalFilterSystem().addFilter(g_faceFilters.back(), mask); -} - -bool face_filtered(Face &face) -{ - for (FaceFilters::iterator i = g_faceFilters.begin(); i != g_faceFilters.end(); ++i) { - if ((*i).active() && (*i).filter(face)) { - return true; - } - } - return false; -} - - -class BrushFilterWrapper : public Filter { -bool m_active; -bool m_invert; -BrushFilter &m_filter; -public: -BrushFilterWrapper(BrushFilter &filter, bool invert) : m_invert(invert), m_filter(filter) -{ -} - -void setActive(bool active) -{ - m_active = active; -} - -bool active() -{ - return m_active; -} - -bool filter(const Brush &brush) -{ - return m_invert ^ m_filter.filter(brush); -} -}; - - -typedef std::list BrushFilters; -BrushFilters g_brushFilters; - -void add_brush_filter(BrushFilter &filter, int mask, bool invert) -{ - g_brushFilters.push_back(BrushFilterWrapper(filter, invert)); - GlobalFilterSystem().addFilter(g_brushFilters.back(), mask); -} - -bool brush_filtered(Brush &brush) -{ - for (BrushFilters::iterator i = g_brushFilters.begin(); i != g_brushFilters.end(); ++i) { - if ((*i).active() && (*i).filter(brush)) { - return true; - } - } - return false; -} diff --git a/src/brush.h b/src/brush.h deleted file mode 100644 index 118d97e..0000000 --- a/src/brush.h +++ /dev/null @@ -1,4075 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSH_H ) -#define INCLUDED_BRUSH_H - -/// \file -/// \brief The brush primitive. -/// -/// A collection of planes that define a convex polyhedron. -/// The Boundary-Representation of this primitive is a manifold polygonal mesh. -/// Each face polygon is represented by a list of vertices in a \c Winding. -/// Each vertex is associated with another face that is adjacent to the edge -/// formed by itself and the next vertex in the winding. This information can -/// be used to find edge-pairs and vertex-rings. - - -#include "debugging/debugging.h" - -#include "itexdef.h" -#include "iundo.h" -#include "iselection.h" -#include "irender.h" -#include "imap.h" -#include "ibrush.h" -#include "igl.h" -#include "ifilter.h" -#include "nameable.h" -#include "moduleobserver.h" - -#include - -#include "mathlib.h" -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" -#include "editable.h" -#include "mapfile.h" - -#include "math/frustum.h" -#include "selectionlib.h" -#include "render.h" -#include "texturelib.h" -#include "container/container.h" -#include "generic/bitfield.h" -#include "signal/signalfwd.h" - -#include "winding.h" -#include "brush_primit.h" - -const unsigned int BRUSH_DETAIL_FLAG = 27; -const unsigned int BRUSH_DETAIL_MASK = (1 << BRUSH_DETAIL_FLAG); - -#define BRUSH_CONNECTIVITY_DEBUG 0 -#define BRUSH_DEGENERATE_DEBUG 0 - -template -inline TextOuputStreamType &ostream_write(TextOuputStreamType &ostream, const Matrix4 &m) -{ - return ostream << "(" << m[0] << " " << m[1] << " " << m[2] << " " << m[3] << ", " - << m[4] << " " << m[5] << " " << m[6] << " " << m[7] << ", " - << m[8] << " " << m[9] << " " << m[10] << " " << m[11] << ", " - << m[12] << " " << m[13] << " " << m[14] << " " << m[15] << ")"; -} - -inline void print_vector3(const Vector3 &v) -{ - globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )\n"; -} - -inline void print_3x3(const Matrix4 &m) -{ - globalOutputStream() << "( " << m.xx() << " " << m.xy() << " " << m.xz() << " ) " - << "( " << m.yx() << " " << m.yy() << " " << m.yz() << " ) " - << "( " << m.zx() << " " << m.zy() << " " << m.zz() << " )\n"; -} - - -inline bool texdef_sane(const texdef_t &texdef) -{ - return fabs(texdef.shift[0]) < (1 << 16) - && fabs(texdef.shift[1]) < (1 << 16); -} - -inline void Winding_DrawWireframe(const Winding &winding) -{ - glVertexPointer(3, GL_FLOAT, sizeof(WindingVertex), &winding.points.data()->vertex); - glDrawArrays(GL_LINE_LOOP, 0, GLsizei(winding.numpoints)); -} - -inline void Winding_Draw(const Winding &winding, const Vector3 &normal, RenderStateFlags state) -{ - glVertexPointer(3, GL_FLOAT, sizeof(WindingVertex), &winding.points.data()->vertex); - - if ((state & RENDER_BUMP) != 0) { - Vector3 normals[c_brush_maxFaces]; - typedef Vector3 *Vector3Iter; - for (Vector3Iter i = normals, end = normals + winding.numpoints; i != end; ++i) { - *i = normal; - } - if (GlobalShaderCache().useShaderLanguage()) { - glNormalPointer(GL_FLOAT, sizeof(Vector3), normals); - glVertexAttribPointerARB(c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof(WindingVertex), - &winding.points.data()->texcoord); - glVertexAttribPointerARB(c_attr_Tangent, 3, GL_FLOAT, 0, sizeof(WindingVertex), - &winding.points.data()->tangent); - glVertexAttribPointerARB(c_attr_Binormal, 3, GL_FLOAT, 0, sizeof(WindingVertex), - &winding.points.data()->bitangent); - } else { - glVertexAttribPointerARB(11, 3, GL_FLOAT, 0, sizeof(Vector3), normals); - glVertexAttribPointerARB(8, 2, GL_FLOAT, 0, sizeof(WindingVertex), &winding.points.data()->texcoord); - glVertexAttribPointerARB(9, 3, GL_FLOAT, 0, sizeof(WindingVertex), &winding.points.data()->tangent); - glVertexAttribPointerARB(10, 3, GL_FLOAT, 0, sizeof(WindingVertex), &winding.points.data()->bitangent); - } - } else { - if (state & RENDER_LIGHTING) { - Vector3 normals[c_brush_maxFaces]; - typedef Vector3 *Vector3Iter; - for (Vector3Iter i = normals, last = normals + winding.numpoints; i != last; ++i) { - *i = normal; - } - glNormalPointer(GL_FLOAT, sizeof(Vector3), normals); - } - - if (state & RENDER_TEXTURE) { - glTexCoordPointer(2, GL_FLOAT, sizeof(WindingVertex), &winding.points.data()->texcoord); - } - } -#if 0 - if ( state & RENDER_FILL ) { - glDrawArrays( GL_TRIANGLE_FAN, 0, GLsizei( winding.numpoints ) ); - } - else - { - glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) ); - } -#else - glDrawArrays(GL_POLYGON, 0, GLsizei(winding.numpoints)); -#endif - -#if 0 - const Winding& winding = winding; - - if ( state & RENDER_FILL ) { - glBegin( GL_POLYGON ); - } - else - { - glBegin( GL_LINE_LOOP ); - } - - if ( state & RENDER_LIGHTING ) { - glNormal3fv( normal ); - } - - for ( int i = 0; i < winding.numpoints; ++i ) - { - if ( state & RENDER_TEXTURE ) { - glTexCoord2fv( &winding.points[i][3] ); - } - glVertex3fv( winding.points[i] ); - } - glEnd(); -#endif -} - - -#include "shaderlib.h" - -typedef DoubleVector3 PlanePoints[3]; - -inline bool planepts_equal(const PlanePoints planepts, const PlanePoints other) -{ - return planepts[0] == other[0] && planepts[1] == other[1] && planepts[2] == other[2]; -} - -inline void planepts_assign(PlanePoints planepts, const PlanePoints other) -{ - planepts[0] = other[0]; - planepts[1] = other[1]; - planepts[2] = other[2]; -} - -inline void planepts_quantise(PlanePoints planepts, double snap) -{ - vector3_snap(planepts[0], snap); - vector3_snap(planepts[1], snap); - vector3_snap(planepts[2], snap); -} - -inline float vector3_max_component(const Vector3 &vec3) -{ - return std::max(fabsf(vec3[0]), std::max(fabsf(vec3[1]), fabsf(vec3[2]))); -} - -inline void edge_snap(Vector3 &edge, double snap) -{ - float scale = static_cast( ceil(fabs(snap / vector3_max_component(edge)))); - if (scale > 0.0f) { - vector3_scale(edge, scale); - } - vector3_snap(edge, snap); -} - -inline void planepts_snap(PlanePoints planepts, double snap) -{ - Vector3 edge01(vector3_subtracted(planepts[1], planepts[0])); - Vector3 edge12(vector3_subtracted(planepts[2], planepts[1])); - Vector3 edge20(vector3_subtracted(planepts[0], planepts[2])); - - double length_squared_01 = vector3_dot(edge01, edge01); - double length_squared_12 = vector3_dot(edge12, edge12); - double length_squared_20 = vector3_dot(edge20, edge20); - - vector3_snap(planepts[0], snap); - - if (length_squared_01 < length_squared_12) { - if (length_squared_12 < length_squared_20) { - edge_snap(edge01, snap); - edge_snap(edge12, snap); - planepts[1] = vector3_added(planepts[0], edge01); - planepts[2] = vector3_added(planepts[1], edge12); - } else { - edge_snap(edge20, snap); - edge_snap(edge01, snap); - planepts[1] = vector3_added(planepts[0], edge20); - planepts[2] = vector3_added(planepts[1], edge01); - } - } else { - if (length_squared_01 < length_squared_20) { - edge_snap(edge01, snap); - edge_snap(edge12, snap); - planepts[1] = vector3_added(planepts[0], edge01); - planepts[2] = vector3_added(planepts[1], edge12); - } else { - edge_snap(edge12, snap); - edge_snap(edge20, snap); - planepts[1] = vector3_added(planepts[0], edge12); - planepts[2] = vector3_added(planepts[1], edge20); - } - } -} - -inline PointVertex pointvertex_for_planept(const DoubleVector3 &point, const Colour4b &colour) -{ - return PointVertex( - Vertex3f( - static_cast( point.x()), - static_cast( point.y()), - static_cast( point.z()) - ), - colour - ); -} - -inline PointVertex pointvertex_for_windingpoint(const Vector3 &point, const Colour4b &colour) -{ - return PointVertex( - vertex3f_for_vector3(point), - colour - ); -} - -inline bool check_plane_is_integer(const PlanePoints &planePoints) -{ - return !float_is_integer(planePoints[0][0]) - || !float_is_integer(planePoints[0][1]) - || !float_is_integer(planePoints[0][2]) - || !float_is_integer(planePoints[1][0]) - || !float_is_integer(planePoints[1][1]) - || !float_is_integer(planePoints[1][2]) - || !float_is_integer(planePoints[2][0]) - || !float_is_integer(planePoints[2][1]) - || !float_is_integer(planePoints[2][2]); -} - -inline void brush_check_shader(const char *name) -{ - if (!shader_valid(name)) { - globalErrorStream() << "brush face has invalid texture name: '" << name << "'\n"; - } -} - -class FaceShaderObserver { -public: -virtual void realiseShader() = 0; - -virtual void unrealiseShader() = 0; -}; - -typedef ReferencePair FaceShaderObserverPair; - - -class ContentsFlagsValue { -public: -ContentsFlagsValue() -{ -} - -ContentsFlagsValue(int surfaceFlags, int contentFlags, int value, bool specified) : - m_surfaceFlags(surfaceFlags), - m_contentFlags(contentFlags), - m_value(value), - m_specified(specified) -{ -} - -int m_surfaceFlags; -int m_contentFlags; -int m_value; -bool m_specified; -}; - -inline void ContentsFlagsValue_assignMasked(ContentsFlagsValue &flags, const ContentsFlagsValue &other) -{ - bool detail = bitfield_enabled(flags.m_contentFlags, BRUSH_DETAIL_MASK); - flags = other; - if (detail) { - flags.m_contentFlags = bitfield_enable(flags.m_contentFlags, BRUSH_DETAIL_MASK); - } else { - flags.m_contentFlags = bitfield_disable(flags.m_contentFlags, BRUSH_DETAIL_MASK); - } -} - - -class FaceShader : public ModuleObserver { -public: -class SavedState { -public: -CopiedString m_shader; -ContentsFlagsValue m_flags; - -SavedState(const FaceShader &faceShader) -{ - m_shader = faceShader.getShader(); - m_flags = faceShader.m_flags; -} - -void exportState(FaceShader &faceShader) const -{ - faceShader.setShader(m_shader.c_str()); - faceShader.setFlags(m_flags); -} -}; - -CopiedString m_shader; -Shader *m_state; -ContentsFlagsValue m_flags; -FaceShaderObserverPair m_observers; -bool m_instanced; -bool m_realised; - -FaceShader(const char *shader, const ContentsFlagsValue &flags = ContentsFlagsValue(0, 0, 0, false)) : - m_shader(shader), - m_state(0), - m_flags(flags), - m_instanced(false), - m_realised(false) -{ - captureShader(); -} - -~FaceShader() -{ - releaseShader(); -} - -// copy-construction not supported -FaceShader(const FaceShader &other); - -void instanceAttach() -{ - m_instanced = true; - m_state->incrementUsed(); -} - -void instanceDetach() -{ - m_state->decrementUsed(); - m_instanced = false; -} - -void captureShader() -{ - ASSERT_MESSAGE(m_state == 0, "shader cannot be captured"); - brush_check_shader(m_shader.c_str()); - m_state = GlobalShaderCache().capture(m_shader.c_str()); - m_state->attach(*this); -} - -void releaseShader() -{ - ASSERT_MESSAGE(m_state != 0, "shader cannot be released"); - m_state->detach(*this); - GlobalShaderCache().release(m_shader.c_str()); - m_state = 0; -} - -void realise() -{ - ASSERT_MESSAGE(!m_realised, "FaceTexdef::realise: already realised"); - m_realised = true; - m_observers.forEach([](FaceShaderObserver &observer) { - observer.realiseShader(); - }); -} - -void unrealise() -{ - ASSERT_MESSAGE(m_realised, "FaceTexdef::unrealise: already unrealised"); - m_observers.forEach([](FaceShaderObserver &observer) { - observer.unrealiseShader(); - }); - m_realised = false; -} - -void attach(FaceShaderObserver &observer) -{ - m_observers.attach(observer); - if (m_realised) { - observer.realiseShader(); - } -} - -void detach(FaceShaderObserver &observer) -{ - if (m_realised) { - observer.unrealiseShader(); - } - m_observers.detach(observer); -} - -const char *getShader() const -{ - return m_shader.c_str(); -} - -void setShader(const char *name) -{ - if (m_instanced) { - m_state->decrementUsed(); - } - releaseShader(); - m_shader = name; - captureShader(); - if (m_instanced) { - m_state->incrementUsed(); - } -} - -ContentsFlagsValue getFlags() const -{ - ASSERT_MESSAGE(m_realised, "FaceShader::getFlags: flags not valid when unrealised"); - if (!m_flags.m_specified) { - return ContentsFlagsValue( - m_state->getTexture().surfaceFlags, - m_state->getTexture().contentFlags, - m_state->getTexture().value, - true - ); - } - return m_flags; -} - -void setFlags(const ContentsFlagsValue &flags) -{ - ASSERT_MESSAGE(m_realised, "FaceShader::setFlags: flags not valid when unrealised"); - ContentsFlagsValue_assignMasked(m_flags, flags); -} - -Shader *state() const -{ - return m_state; -} - -std::size_t width() const -{ - if (m_realised) { - return m_state->getTexture().width; - } - return 1; -} - -std::size_t height() const -{ - if (m_realised) { - return m_state->getTexture().height; - } - return 1; -} - -unsigned int shaderFlags() const -{ - if (m_realised) { - return m_state->getFlags(); - } - return 0; -} -}; - - -class FaceTexdef : public FaceShaderObserver { -// not copyable -FaceTexdef(const FaceTexdef &other); - -// not assignable -FaceTexdef &operator=(const FaceTexdef &other); - -public: -class SavedState { -public: -TextureProjection m_projection; - -SavedState(const FaceTexdef &faceTexdef) -{ - m_projection = faceTexdef.m_projection; -} - -void exportState(FaceTexdef &faceTexdef) const -{ - Texdef_Assign(faceTexdef.m_projection, m_projection); -} -}; - -FaceShader &m_shader; -TextureProjection m_projection; -bool m_projectionInitialised; -bool m_scaleApplied; - -FaceTexdef( - FaceShader &shader, - const TextureProjection &projection, - bool projectionInitialised = true - ) : - m_shader(shader), - m_projection(projection), - m_projectionInitialised(projectionInitialised), - m_scaleApplied(false) -{ - m_shader.attach(*this); -} - -~FaceTexdef() -{ - m_shader.detach(*this); -} - -void addScale() -{ - ASSERT_MESSAGE(!m_scaleApplied, "texture scale aready added"); - m_scaleApplied = true; - m_projection.m_brushprimit_texdef.addScale(m_shader.width(), m_shader.height()); -} - -void removeScale() -{ - ASSERT_MESSAGE(m_scaleApplied, "texture scale aready removed"); - m_scaleApplied = false; - m_projection.m_brushprimit_texdef.removeScale(m_shader.width(), m_shader.height()); -} - -void realiseShader() -{ - if (m_projectionInitialised && !m_scaleApplied) { - addScale(); - } -} - -void unrealiseShader() -{ - if (m_projectionInitialised && m_scaleApplied) { - removeScale(); - } -} - -void setTexdef(const TextureProjection &projection) -{ - removeScale(); - Texdef_Assign(m_projection, projection); - addScale(); -} - -void shift(float s, float t) -{ - ASSERT_MESSAGE(texdef_sane(m_projection.m_texdef), "FaceTexdef::shift: bad texdef"); - removeScale(); - Texdef_Shift(m_projection, s, t); - addScale(); -} - -void scale(float s, float t) -{ - removeScale(); - Texdef_Scale(m_projection, s, t); - addScale(); -} - -void rotate(float angle) -{ - removeScale(); - Texdef_Rotate(m_projection, angle); - addScale(); -} - -void fit(const Vector3 &normal, const Winding &winding, float s_repeat, float t_repeat) -{ - Texdef_FitTexture(m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat); -} -void align(const Plane3 &plane, const Vector3 &normal, const Winding &winding, int alignment) -{ - Texdef_AlignTexture(m_projection, plane, normal, winding, m_shader.width(), m_shader.height(), alignment); -} - -void emitTextureCoordinates(Winding &winding, const Vector3 &normal, const Matrix4 &localToWorld) -{ - Texdef_EmitTextureCoordinates(m_projection, m_shader.width(), m_shader.height(), winding, normal, localToWorld); -} - -void transform(const Plane3 &plane, const Matrix4 &matrix) -{ - removeScale(); - Texdef_transformLocked(m_projection, m_shader.width(), m_shader.height(), plane, matrix); - addScale(); -} - -TextureProjection normalised() const -{ - brushprimit_texdef_t tmp(m_projection.m_brushprimit_texdef); - tmp.removeScale(m_shader.width(), m_shader.height()); - return TextureProjection(m_projection.m_texdef, tmp, m_projection.m_basis_s, m_projection.m_basis_t); -} - -void setBasis(const Vector3 &normal) -{ - Matrix4 basis; - Normal_GetTransform(normal, basis); - m_projection.m_basis_s = Vector3(basis.xx(), basis.yx(), basis.zx()); - m_projection.m_basis_t = Vector3(-basis.xy(), -basis.yy(), -basis.zy()); - - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_HALFLIFE ) { - Vector3 s = m_projection.m_basis_s, t = m_projection.m_basis_t; - RotatePointAroundVector(m_projection.m_basis_s.data(), normal.data(), s.data(), m_projection.m_texdef.rotate); - RotatePointAroundVector(m_projection.m_basis_t.data(), normal.data(), t.data(), m_projection.m_texdef.rotate); - } -} -}; - -inline void planepts_print(const PlanePoints &planePoints, TextOutputStream &ostream) -{ - ostream << "( " << planePoints[0][0] << " " << planePoints[0][1] << " " << planePoints[0][2] << " ) " - << "( " << planePoints[1][0] << " " << planePoints[1][1] << " " << planePoints[1][2] << " ) " - << "( " << planePoints[2][0] << " " << planePoints[2][1] << " " << planePoints[2][2] << " )"; -} - - -inline Plane3 Plane3_applyTranslation(const Plane3 &plane, const Vector3 &translation) -{ - Plane3 tmp(plane3_translated(Plane3(plane.normal(), -plane.dist()), translation)); - return Plane3(tmp.normal(), -tmp.dist()); -} - -inline Plane3 Plane3_applyTransform(const Plane3 &plane, const Matrix4 &matrix) -{ - Plane3 tmp(plane3_transformed(Plane3(plane.normal(), -plane.dist()), matrix)); - return Plane3(tmp.normal(), -tmp.dist()); -} - -class FacePlane { -PlanePoints m_planepts; -Plane3 m_planeCached; -Plane3 m_plane; -public: -Vector3 m_funcStaticOrigin; - -static EBrushType m_type; - -static bool isDoom3Plane() -{ - return FacePlane::m_type == eBrushTypeDoom3 || FacePlane::m_type == eBrushTypeQuake4; -} - -class SavedState { -public: -PlanePoints m_planepts; -Plane3 m_plane; - -SavedState(const FacePlane &facePlane) -{ - if (facePlane.isDoom3Plane()) { - m_plane = facePlane.m_plane; - } else { - planepts_assign(m_planepts, facePlane.planePoints()); - } -} - -void exportState(FacePlane &facePlane) const -{ - if (facePlane.isDoom3Plane()) { - facePlane.m_plane = m_plane; - facePlane.updateTranslated(); - } else { - planepts_assign(facePlane.planePoints(), m_planepts); - facePlane.MakePlane(); - } -} -}; - -FacePlane() : m_funcStaticOrigin(0, 0, 0) -{ -} - -FacePlane(const FacePlane &other) : m_funcStaticOrigin(0, 0, 0) -{ - if (!isDoom3Plane()) { - planepts_assign(m_planepts, other.m_planepts); - MakePlane(); - } else { - m_plane = other.m_plane; - updateTranslated(); - } -} - -void MakePlane() -{ - if (!isDoom3Plane()) { -#if 0 - if ( check_plane_is_integer( m_planepts ) ) { - globalErrorStream() << "non-integer planepts: "; - planepts_print( m_planepts, globalErrorStream() ); - globalErrorStream() << "\n"; - } -#endif - m_planeCached = plane3_for_points(m_planepts); - } -} - -void reverse() -{ - if (!isDoom3Plane()) { - vector3_swap(m_planepts[0], m_planepts[2]); - MakePlane(); - } else { - m_planeCached = plane3_flipped(m_plane); - updateSource(); - } -} - -void transform(const Matrix4 &matrix, bool mirror) -{ - if (!isDoom3Plane()) { - -#if 0 - bool off = check_plane_is_integer( planePoints() ); -#endif - - matrix4_transform_point(matrix, m_planepts[0]); - matrix4_transform_point(matrix, m_planepts[1]); - matrix4_transform_point(matrix, m_planepts[2]); - - if (mirror) { - reverse(); - } - -#if 0 - if ( check_plane_is_integer( planePoints() ) ) { - if ( !off ) { - globalErrorStream() << "caused by transform\n"; - } - } -#endif - MakePlane(); - } else { - m_planeCached = Plane3_applyTransform(m_planeCached, matrix); - updateSource(); - } -} - -void offset(float offset) -{ - if (!isDoom3Plane()) { - Vector3 move(vector3_scaled(m_planeCached.normal(), -offset)); - - vector3_subtract(m_planepts[0], move); - vector3_subtract(m_planepts[1], move); - vector3_subtract(m_planepts[2], move); - - MakePlane(); - } else { - m_planeCached.d += offset; - updateSource(); - } -} - -void updateTranslated() -{ - m_planeCached = Plane3_applyTranslation(m_plane, m_funcStaticOrigin); -} - -void updateSource() -{ - m_plane = Plane3_applyTranslation(m_planeCached, vector3_negated(m_funcStaticOrigin)); -} - - -PlanePoints &planePoints() -{ - return m_planepts; -} - -const PlanePoints &planePoints() const -{ - return m_planepts; -} - -const Plane3 &plane3() const -{ - return m_planeCached; -} - -void setDoom3Plane(const Plane3 &plane) -{ - m_plane = plane; - updateTranslated(); -} - -const Plane3 &getDoom3Plane() const -{ - return m_plane; -} - -void copy(const FacePlane &other) -{ - if (!isDoom3Plane()) { - planepts_assign(m_planepts, other.m_planepts); - MakePlane(); - } else { - m_planeCached = other.m_plane; - updateSource(); - } -} - -void copy(const Vector3 &p0, const Vector3 &p1, const Vector3 &p2) -{ - if (!isDoom3Plane()) { - m_planepts[0] = p0; - m_planepts[1] = p1; - m_planepts[2] = p2; - MakePlane(); - } else { - m_planeCached = plane3_for_points(p2, p1, p0); - updateSource(); - } -} -}; - -inline void Winding_testSelect(Winding &winding, SelectionTest &test, SelectionIntersection &best) -{ - test.TestPolygon(VertexPointer(reinterpret_cast( &winding.points.data()->vertex ), - sizeof(WindingVertex)), winding.numpoints, best); -} - -const double GRID_MIN = 0.125; - -inline double quantiseInteger(double f) -{ - return float_to_integer(f); -} - -inline double quantiseFloating(double f) -{ - return float_snapped(f, 1.f / (1 << 16)); -} - -typedef double ( *QuantiseFunc )(double f); - -class Face; - -class FaceFilter { -public: -virtual bool filter(const Face &face) const = 0; -}; - -bool face_filtered(Face &face); - -void add_face_filter(FaceFilter &filter, int mask, bool invert = false); - -void Brush_addTextureChangedCallback(const SignalHandler &callback); - -void Brush_textureChanged(); - - -extern bool g_brush_texturelock_enabled; - -class FaceObserver { -public: -virtual void planeChanged() = 0; - -virtual void connectivityChanged() = 0; - -virtual void shaderChanged() = 0; - -virtual void evaluateTransform() = 0; -}; - -class Face : - public OpenGLRenderable, - public Filterable, - public Undoable, - public FaceShaderObserver { -std::size_t m_refcount; - -class SavedState : public UndoMemento { -public: -FacePlane::SavedState m_planeState; -FaceTexdef::SavedState m_texdefState; -FaceShader::SavedState m_shaderState; - -SavedState(const Face &face) : m_planeState(face.getPlane()), m_texdefState(face.getTexdef()), - m_shaderState(face.getShader()) -{ -} - -void exportState(Face &face) const -{ - m_planeState.exportState(face.getPlane()); - m_shaderState.exportState(face.getShader()); - m_texdefState.exportState(face.getTexdef()); -} - -void release() -{ - delete this; -} -}; - -public: -static QuantiseFunc m_quantise; -static EBrushType m_type; - -PlanePoints m_move_planepts; -PlanePoints m_move_planeptsTransformed; -private: -FacePlane m_plane; -FacePlane m_planeTransformed; -FaceShader m_shader; -FaceTexdef m_texdef; -TextureProjection m_texdefTransformed; - -Winding m_winding; -Vector3 m_centroid; -bool m_filtered; - -FaceObserver *m_observer; -UndoObserver *m_undoable_observer; -MapFile *m_map; - -// assignment not supported -Face &operator=(const Face &other); - -// copy-construction not supported -Face(const Face &other); - -public: - -Face(FaceObserver *observer) : - m_refcount(0), - m_shader(texdef_name_default()), - m_texdef(m_shader, TextureProjection(), false), - m_filtered(false), - m_observer(observer), - m_undoable_observer(0), - m_map(0) -{ - m_shader.attach(*this); - m_plane.copy(Vector3(0, 0, 0), Vector3(64, 0, 0), Vector3(0, 64, 0)); - m_texdef.setBasis(m_plane.plane3().normal()); - planeChanged(); -} - -Face( - const Vector3 &p0, - const Vector3 &p1, - const Vector3 &p2, - const char *shader, - const TextureProjection &projection, - FaceObserver *observer - ) : - m_refcount(0), - m_shader(shader), - m_texdef(m_shader, projection), - m_observer(observer), - m_undoable_observer(0), - m_map(0) -{ - m_shader.attach(*this); - m_plane.copy(p0, p1, p2); - m_texdef.setBasis(m_plane.plane3().normal()); - planeChanged(); - updateFiltered(); -} - -Face(const Face &other, FaceObserver *observer) : - m_refcount(0), - m_shader(other.m_shader.getShader(), other.m_shader.m_flags), - m_texdef(m_shader, other.getTexdef().normalised()), - m_observer(observer), - m_undoable_observer(0), - m_map(0) -{ - m_shader.attach(*this); - m_plane.copy(other.m_plane); - planepts_assign(m_move_planepts, other.m_move_planepts); -// if (g_bp_globals.m_texdefTypeId != TEXDEFTYPEID_HALFLIFE) { -// m_texdef.setBasis(m_plane.plane3().normal()); -// } - planeChanged(); - updateFiltered(); -} - -~Face() -{ - m_shader.detach(*this); -} - -void planeChanged() -{ - revertTransform(); - m_observer->planeChanged(); -} - -void realiseShader() -{ - m_observer->shaderChanged(); -} - -void unrealiseShader() -{ -} - -void instanceAttach(MapFile *map) -{ - m_shader.instanceAttach(); - m_map = map; - m_undoable_observer = GlobalUndoSystem().observer(this); - GlobalFilterSystem().registerFilterable(*this); -} - -void instanceDetach(MapFile *map) -{ - GlobalFilterSystem().unregisterFilterable(*this); - m_undoable_observer = 0; - GlobalUndoSystem().release(this); - m_map = 0; - m_shader.instanceDetach(); -} - -void render(RenderStateFlags state) const -{ - Winding_Draw(m_winding, m_planeTransformed.plane3().normal(), state); -} - -void updateFiltered() -{ - m_filtered = face_filtered(*this); -} - -bool isFiltered() const -{ - return m_filtered; -} - -void undoSave() -{ - if (m_map != 0) { - m_map->changed(); - } - if (m_undoable_observer != 0) { - m_undoable_observer->save(this); - } -} - -// undoable -UndoMemento *exportState() const -{ - return new SavedState(*this); -} - -void importState(const UndoMemento *data) -{ - undoSave(); - - static_cast( data )->exportState(*this); - - planeChanged(); - m_observer->connectivityChanged(); - texdefChanged(); - m_observer->shaderChanged(); - updateFiltered(); -} - -void IncRef() -{ - ++m_refcount; -} - -void DecRef() -{ - if (--m_refcount == 0) { - delete this; - } -} - -void flipWinding() -{ - m_plane.reverse(); - planeChanged(); -} - -bool intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return volume.TestPlane(Plane3(plane3().normal(), -plane3().dist()), localToWorld); -} - -void render(Renderer &renderer, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_shader.state(), Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); -} - -void transform(const Matrix4 &matrix, bool mirror) -{ - if (g_brush_texturelock_enabled) { - Texdef_transformLocked(m_texdefTransformed, m_shader.width(), m_shader.height(), m_plane.plane3(), matrix); - } - - m_planeTransformed.transform(matrix, mirror); - -#if 0 - ASSERT_MESSAGE( projectionaxis_for_normal( normal ) == projectionaxis_for_normal( plane3().normal() ), "bleh" ); -#endif - m_observer->planeChanged(); - - if (g_brush_texturelock_enabled) { - Brush_textureChanged(); - } -} - -void assign_planepts(const PlanePoints planepts) -{ - m_planeTransformed.copy(planepts[0], planepts[1], planepts[2]); - m_observer->planeChanged(); -} - -/// \brief Reverts the transformable state of the brush to identity. -void revertTransform() -{ - m_planeTransformed = m_plane; - planepts_assign(m_move_planeptsTransformed, m_move_planepts); - m_texdefTransformed = m_texdef.m_projection; -} - -void freezeTransform() -{ - undoSave(); - m_plane = m_planeTransformed; - planepts_assign(m_move_planepts, m_move_planeptsTransformed); - m_texdef.m_projection = m_texdefTransformed; -} - -void update_move_planepts_vertex(std::size_t index, PlanePoints planePoints) -{ - std::size_t numpoints = getWinding().numpoints; - ASSERT_MESSAGE(index < numpoints, "update_move_planepts_vertex: invalid index"); - - std::size_t opposite = Winding_Opposite(getWinding(), index); - std::size_t adjacent = Winding_wrap(getWinding(), opposite + numpoints - 1); - planePoints[0] = getWinding()[opposite].vertex; - planePoints[1] = getWinding()[index].vertex; - planePoints[2] = getWinding()[adjacent].vertex; - // winding points are very inaccurate, so they must be quantised before using them to generate the face-plane - planepts_quantise(planePoints, GRID_MIN); -} - -void snapto(float snap) -{ - if (contributes()) { -#if 0 - ASSERT_MESSAGE( plane3_valid( m_plane.plane3() ), "invalid plane before snap to grid" ); - planepts_snap( m_plane.planePoints(), snap ); - ASSERT_MESSAGE( plane3_valid( m_plane.plane3() ), "invalid plane after snap to grid" ); -#else - PlanePoints planePoints; - update_move_planepts_vertex(0, planePoints); - vector3_snap(planePoints[0], snap); - vector3_snap(planePoints[1], snap); - vector3_snap(planePoints[2], snap); - assign_planepts(planePoints); - freezeTransform(); -#endif - SceneChangeNotify(); - if (!plane3_valid(m_plane.plane3())) { - globalErrorStream() << "WARNING: invalid plane after snap to grid\n"; - } - } -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - Winding_testSelect(m_winding, test, best); -} - -void testSelect_centroid(SelectionTest &test, SelectionIntersection &best) -{ - test.TestPoint(m_centroid, best); -} - -void shaderChanged() -{ - EmitTextureCoordinates(); - Brush_textureChanged(); - m_observer->shaderChanged(); - updateFiltered(); - planeChanged(); - SceneChangeNotify(); -} - -const char *GetShader() const -{ - return m_shader.getShader(); -} - -void SetShader(const char *name) -{ - undoSave(); - m_shader.setShader(name); - shaderChanged(); -} - -void revertTexdef() -{ - m_texdefTransformed = m_texdef.m_projection; -} - -void texdefChanged() -{ - revertTexdef(); - EmitTextureCoordinates(); - Brush_textureChanged(); -} - -void GetTexdef(TextureProjection &projection) const -{ - projection = m_texdef.normalised(); -} - -void SetTexdef(const TextureProjection &projection, bool ignorebasis) -{ - undoSave(); - m_texdef.setTexdef(projection); - if (ignorebasis) - m_texdef.setBasis(m_plane.plane3().normal()); - texdefChanged(); -} - -void GetFlags(ContentsFlagsValue &flags) const -{ - flags = m_shader.getFlags(); -} - -void SetFlags(const ContentsFlagsValue &flags) -{ - undoSave(); - m_shader.setFlags(flags); - m_observer->shaderChanged(); - updateFiltered(); -} - -void ShiftTexdef(float s, float t) -{ - undoSave(); - m_texdef.shift(s, t); - texdefChanged(); -} - -void ScaleTexdef(float s, float t) -{ - undoSave(); - m_texdef.scale(s, t); - texdefChanged(); -} - -void RotateTexdef(float angle) -{ - undoSave(); - m_texdef.rotate(angle); - texdefChanged(); -} - -void FitTexture(float s_repeat, float t_repeat) -{ - undoSave(); - m_texdef.fit(m_plane.plane3().normal(), m_winding, s_repeat, t_repeat); - texdefChanged(); -} - -void AlignTexture(int alignment) -{ - undoSave(); - m_texdef.align(m_plane.plane3(), m_plane.plane3().normal(), m_winding, alignment); - texdefChanged(); -} - -void EmitTextureCoordinates() -{ - Texdef_EmitTextureCoordinates(m_texdefTransformed, m_shader.width(), m_shader.height(), m_winding, - plane3().normal(), g_matrix4_identity); -} - - -const Vector3 ¢roid() const -{ - return m_centroid; -} - -void construct_centroid() -{ - Winding_Centroid(m_winding, plane3(), m_centroid); -} - -const Winding &getWinding() const -{ - return m_winding; -} - -Winding &getWinding() -{ - return m_winding; -} - -const Plane3 &plane3() const -{ - m_observer->evaluateTransform(); - return m_planeTransformed.plane3(); -} - -FacePlane &getPlane() -{ - return m_plane; -} - -const FacePlane &getPlane() const -{ - return m_plane; -} - -FaceTexdef &getTexdef() -{ - return m_texdef; -} - -const FaceTexdef &getTexdef() const -{ - return m_texdef; -} - -FaceShader &getShader() -{ - return m_shader; -} - -const FaceShader &getShader() const -{ - return m_shader; -} - -bool isDetail() const -{ - return (m_shader.m_flags.m_contentFlags & BRUSH_DETAIL_MASK) != 0; -} - -void setDetail(bool detail) -{ - undoSave(); - if (detail && !isDetail()) { - m_shader.m_flags.m_contentFlags |= BRUSH_DETAIL_MASK; - } else if (!detail && isDetail()) { - m_shader.m_flags.m_contentFlags &= ~BRUSH_DETAIL_MASK; - } - m_observer->shaderChanged(); -} - -bool contributes() const -{ - return m_winding.numpoints > 2; -} - -bool is_bounded() const -{ - for (Winding::const_iterator i = m_winding.begin(); i != m_winding.end(); ++i) { - if ((*i).adjacent == c_brush_maxFaces) { - return false; - } - } - return true; -} -}; - - -class FaceVertexId { -std::size_t m_face; -std::size_t m_vertex; - -public: -FaceVertexId(std::size_t face, std::size_t vertex) - : m_face(face), m_vertex(vertex) -{ -} - -std::size_t getFace() const -{ - return m_face; -} - -std::size_t getVertex() const -{ - return m_vertex; -} -}; - -typedef std::size_t faceIndex_t; - -struct EdgeRenderIndices { - RenderIndex first; - RenderIndex second; - - EdgeRenderIndices() - : first(0), second(0) - { - } - - EdgeRenderIndices(const RenderIndex _first, const RenderIndex _second) - : first(_first), second(_second) - { - } -}; - -struct EdgeFaces { - faceIndex_t first; - faceIndex_t second; - - EdgeFaces() - : first(c_brush_maxFaces), second(c_brush_maxFaces) - { - } - - EdgeFaces(const faceIndex_t _first, const faceIndex_t _second) - : first(_first), second(_second) - { - } -}; - -class RenderableWireframe : public OpenGLRenderable { -public: -void render(RenderStateFlags state) const -{ -#if 1 - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_vertices->colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_vertices->vertex); - glDrawElements(GL_LINES, GLsizei(m_size << 1), RenderIndexTypeID, m_faceVertex.data()); -#else - glBegin( GL_LINES ); - for ( std::size_t i = 0; i < m_size; ++i ) - { - glVertex3fv( &m_vertices[m_faceVertex[i].first].vertex.x ); - glVertex3fv( &m_vertices[m_faceVertex[i].second].vertex.x ); - } - glEnd(); -#endif -} - -Array m_faceVertex; -std::size_t m_size; -const PointVertex *m_vertices; -}; - -class Brush; - -typedef std::vector brush_vector_t; - -class BrushFilter { -public: -virtual bool filter(const Brush &brush) const = 0; -}; - -bool brush_filtered(Brush &brush); - -void add_brush_filter(BrushFilter &filter, int mask, bool invert = false); - - -/// \brief Returns true if 'self' takes priority when building brush b-rep. -inline bool plane3_inside(const Plane3 &self, const Plane3 &other, bool selfIsLater) -{ - if (vector3_equal_epsilon(self.normal(), other.normal(), 0.001)) { - // same plane? prefer the one with smaller index - if (self.dist() == other.dist()) { - return selfIsLater; - } - return self.dist() < other.dist(); - } - return true; -} - -typedef SmartPointer FaceSmartPointer; -typedef std::vector Faces; - -/// \brief Returns the unique-id of the edge adjacent to \p faceVertex in the edge-pair for the set of \p faces. -inline FaceVertexId next_edge(const Faces &faces, FaceVertexId faceVertex) -{ - std::size_t adjacent_face = faces[faceVertex.getFace()]->getWinding()[faceVertex.getVertex()].adjacent; - std::size_t adjacent_vertex = Winding_FindAdjacent(faces[adjacent_face]->getWinding(), faceVertex.getFace()); - - ASSERT_MESSAGE(adjacent_vertex != c_brush_maxFaces, "connectivity data invalid"); - if (adjacent_vertex == c_brush_maxFaces) { - return faceVertex; - } - - return FaceVertexId(adjacent_face, adjacent_vertex); -} - -/// \brief Returns the unique-id of the vertex adjacent to \p faceVertex in the vertex-ring for the set of \p faces. -inline FaceVertexId next_vertex(const Faces &faces, FaceVertexId faceVertex) -{ - FaceVertexId nextEdge = next_edge(faces, faceVertex); - return FaceVertexId(nextEdge.getFace(), - Winding_next(faces[nextEdge.getFace()]->getWinding(), nextEdge.getVertex())); -} - -class SelectableEdge { -Vector3 getEdge() const -{ - const Winding &winding = getFace().getWinding(); - return vector3_mid(winding[m_faceVertex.getVertex()].vertex, - winding[Winding_next(winding, m_faceVertex.getVertex())].vertex); -} - -public: -Faces &m_faces; -FaceVertexId m_faceVertex; - -SelectableEdge(Faces &faces, FaceVertexId faceVertex) - : m_faces(faces), m_faceVertex(faceVertex) -{ -} - -SelectableEdge &operator=(const SelectableEdge &other) -{ - m_faceVertex = other.m_faceVertex; - return *this; -} - -Face &getFace() const -{ - return *m_faces[m_faceVertex.getFace()]; -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - test.TestPoint(getEdge(), best); -} -}; - -class SelectableVertex { -Vector3 getVertex() const -{ - return getFace().getWinding()[m_faceVertex.getVertex()].vertex; -} - -public: -Faces &m_faces; -FaceVertexId m_faceVertex; - -SelectableVertex(Faces &faces, FaceVertexId faceVertex) - : m_faces(faces), m_faceVertex(faceVertex) -{ -} - -SelectableVertex &operator=(const SelectableVertex &other) -{ - m_faceVertex = other.m_faceVertex; - return *this; -} - -Face &getFace() const -{ - return *m_faces[m_faceVertex.getFace()]; -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - test.TestPoint(getVertex(), best); -} -}; - -class BrushObserver { -public: -virtual void reserve(std::size_t size) = 0; - -virtual void clear() = 0; - -virtual void push_back(Face &face) = 0; - -virtual void pop_back() = 0; - -virtual void erase(std::size_t index) = 0; - -virtual void connectivityChanged() = 0; - -virtual void edge_clear() = 0; - -virtual void edge_push_back(SelectableEdge &edge) = 0; - -virtual void vertex_clear() = 0; - -virtual void vertex_push_back(SelectableVertex &vertex) = 0; - -virtual void DEBUG_verify() const = 0; -}; - -class BrushVisitor { -public: -virtual void visit(Face &face) const = 0; -}; - -class Brush : - public TransformNode, - public Bounded, - public Cullable, - public Snappable, - public Undoable, - public FaceObserver, - public Filterable, - public Nameable, - public BrushDoom3 { -private: -scene::Node *m_node; -typedef UniqueSet Observers; -Observers m_observers; -UndoObserver *m_undoable_observer; -MapFile *m_map; - -// state -Faces m_faces; -// ---- - -// cached data compiled from state -Array m_faceCentroidPoints; -RenderablePointArray m_render_faces; - -Array m_uniqueVertexPoints; -typedef std::vector SelectableVertices; -SelectableVertices m_select_vertices; -RenderablePointArray m_render_vertices; - -Array m_uniqueEdgePoints; -typedef std::vector SelectableEdges; -SelectableEdges m_select_edges; -RenderablePointArray m_render_edges; - -Array m_edge_indices; -Array m_edge_faces; - -AABB m_aabb_local; -// ---- - -Callback m_evaluateTransform; -Callback m_boundsChanged; - -mutable bool m_planeChanged; // b-rep evaluation required -mutable bool m_transformChanged; // transform evaluation required -// ---- - -public: -STRING_CONSTANT(Name, "Brush"); - -Callback m_lightsChanged; - -// static data -static Shader *m_state_point; -// ---- - -static EBrushType m_type; -static double m_maxWorldCoord; - -Brush(scene::Node &node, const Callback &evaluateTransform, const Callback &boundsChanged) : - m_node(&node), - m_undoable_observer(0), - m_map(0), - m_render_faces(m_faceCentroidPoints, GL_POINTS), - m_render_vertices(m_uniqueVertexPoints, GL_POINTS), - m_render_edges(m_uniqueEdgePoints, GL_POINTS), - m_evaluateTransform(evaluateTransform), - m_boundsChanged(boundsChanged), - m_planeChanged(false), - m_transformChanged(false) -{ - planeChanged(); -} - -Brush(const Brush &other, scene::Node &node, const Callback &evaluateTransform, - const Callback &boundsChanged) : - m_node(&node), - m_undoable_observer(0), - m_map(0), - m_render_faces(m_faceCentroidPoints, GL_POINTS), - m_render_vertices(m_uniqueVertexPoints, GL_POINTS), - m_render_edges(m_uniqueEdgePoints, GL_POINTS), - m_evaluateTransform(evaluateTransform), - m_boundsChanged(boundsChanged), - m_planeChanged(false), - m_transformChanged(false) -{ - copy(other); -} - -Brush(const Brush &other) : - TransformNode(other), - Bounded(other), - Cullable(other), - Snappable(), - Undoable(other), - FaceObserver(other), - Filterable(other), - Nameable(other), - BrushDoom3(other), - m_node(0), - m_undoable_observer(0), - m_map(0), - m_render_faces(m_faceCentroidPoints, GL_POINTS), - m_render_vertices(m_uniqueVertexPoints, GL_POINTS), - m_render_edges(m_uniqueEdgePoints, GL_POINTS), - m_planeChanged(false), - m_transformChanged(false) -{ - copy(other); -} - -~Brush() -{ - ASSERT_MESSAGE(m_observers.empty(), "Brush::~Brush: observers still attached"); -} - -// assignment not supported -Brush &operator=(const Brush &other); - -void setDoom3GroupOrigin(const Vector3 &origin) -{ - //globalOutputStream() << "func_static origin before: " << m_funcStaticOrigin << " after: " << origin << "\n"; - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->getPlane().m_funcStaticOrigin = origin; - (*i)->getPlane().updateTranslated(); - (*i)->planeChanged(); - } - planeChanged(); -} - -void attach(BrushObserver &observer) -{ - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - observer.push_back(*(*i)); - } - - for (SelectableEdges::iterator i = m_select_edges.begin(); i != m_select_edges.end(); ++i) { - observer.edge_push_back(*i); - } - - for (SelectableVertices::iterator i = m_select_vertices.begin(); i != m_select_vertices.end(); ++i) { - observer.vertex_push_back(*i); - } - - m_observers.insert(&observer); -} - -void detach(BrushObserver &observer) -{ - m_observers.erase(&observer); -} - -void forEachFace(const BrushVisitor &visitor) const -{ - for (Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - visitor.visit(*(*i)); - } -} - -void forEachFace_instanceAttach(MapFile *map) const -{ - for (Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->instanceAttach(map); - } -} - -void forEachFace_instanceDetach(MapFile *map) const -{ - for (Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->instanceDetach(map); - } -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_map = path_find_mapfile(path.begin(), path.end()); - m_undoable_observer = GlobalUndoSystem().observer(this); - GlobalFilterSystem().registerFilterable(*this); - forEachFace_instanceAttach(m_map); - } else { - ASSERT_MESSAGE(path_find_mapfile(path.begin(), path.end()) == m_map, - "node is instanced across more than one file"); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - forEachFace_instanceDetach(m_map); - GlobalFilterSystem().unregisterFilterable(*this); - m_map = 0; - m_undoable_observer = 0; - GlobalUndoSystem().release(this); - } -} - -// nameable -const char *name() const -{ - return "brush"; -} - -void attach(const NameCallback &callback) -{ -} - -void detach(const NameCallback &callback) -{ -} - -// filterable -void updateFiltered() -{ - if (m_node != 0) { - if (brush_filtered(*this)) { - m_node->enable(scene::Node::eFiltered); - } else { - m_node->disable(scene::Node::eFiltered); - } - } -} - -// observer -void planeChanged() -{ - m_planeChanged = true; - aabbChanged(); - m_lightsChanged(); -} - -void shaderChanged() -{ - updateFiltered(); - planeChanged(); -} - -void evaluateBRep() const -{ - if (m_planeChanged) { - m_planeChanged = false; - const_cast( this )->buildBRep(); - } -} - -void transformChanged() -{ - m_transformChanged = true; - planeChanged(); -} - -typedef MemberCaller TransformChangedCaller; - -void evaluateTransform() -{ - if (m_transformChanged) { - m_transformChanged = false; - revertTransform(); - m_evaluateTransform(); - } -} - -const Matrix4 &localToParent() const -{ - return g_matrix4_identity; -} - -void aabbChanged() -{ - m_boundsChanged(); -} - -const AABB &localAABB() const -{ - evaluateBRep(); - return m_aabb_local; -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -void renderComponents(SelectionSystem::EComponentMode mode, Renderer &renderer, const VolumeTest &volume, - const Matrix4 &localToWorld) const -{ - switch (mode) { - case SelectionSystem::eVertex: - renderer.addRenderable(m_render_vertices, localToWorld); - break; - case SelectionSystem::eEdge: - renderer.addRenderable(m_render_edges, localToWorld); - break; - case SelectionSystem::eFace: - renderer.addRenderable(m_render_faces, localToWorld); - break; - default: - break; - } -} - -void transform(const Matrix4 &matrix) -{ - bool mirror = matrix4_handedness(matrix) == MATRIX4_LEFTHANDED; - - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->transform(matrix, mirror); - } -} - -void snapto(float snap) -{ - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->snapto(snap); - } -} - -void revertTransform() -{ - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->revertTransform(); - } -} - -void freezeTransform() -{ - for (Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i) { - (*i)->freezeTransform(); - } -} - -/// \brief Returns the absolute index of the \p faceVertex. -std::size_t absoluteIndex(FaceVertexId faceVertex) -{ - std::size_t index = 0; - for (std::size_t i = 0; i < faceVertex.getFace(); ++i) { - index += m_faces[i]->getWinding().numpoints; - } - return index + faceVertex.getVertex(); -} - -void appendFaces(const Faces &other) -{ - clear(); - for (Faces::const_iterator i = other.begin(); i != other.end(); ++i) { - push_back(*i); - } -} - -/// \brief The undo memento for a brush stores only the list of face references - the faces are not copied. -class BrushUndoMemento : public UndoMemento { -public: -BrushUndoMemento(const Faces &faces) : m_faces(faces) -{ -} - -void release() -{ - delete this; -} - -Faces m_faces; -}; - -void undoSave() -{ - if (m_map != 0) { - m_map->changed(); - } - if (m_undoable_observer != 0) { - m_undoable_observer->save(this); - } -} - -UndoMemento *exportState() const -{ - return new BrushUndoMemento(m_faces); -} - -void importState(const UndoMemento *state) -{ - undoSave(); - appendFaces(static_cast( state )->m_faces); - planeChanged(); - - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->DEBUG_verify(); - } -} - -bool isDetail() -{ - return !m_faces.empty() && m_faces.front()->isDetail(); -} - -/// \brief Appends a copy of \p face to the end of the face list. -Face *addFace(const Face &face) -{ - if (m_faces.size() == c_brush_maxFaces) { - return 0; - } - undoSave(); - push_back(FaceSmartPointer(new Face(face, this))); - m_faces.back()->setDetail(isDetail()); - planeChanged(); - return m_faces.back(); -} - -/// \brief Appends a new face constructed from the parameters to the end of the face list. -Face *addPlane(const Vector3 &p0, const Vector3 &p1, const Vector3 &p2, const char *shader, - const TextureProjection &projection) -{ - if (m_faces.size() == c_brush_maxFaces) { - return 0; - } - undoSave(); - push_back(FaceSmartPointer(new Face(p0, p1, p2, shader, projection, this))); - m_faces.back()->setDetail(isDetail()); - planeChanged(); - return m_faces.back(); -} - -static void constructStatic(EBrushType type) -{ - m_type = type; - Face::m_type = type; - FacePlane::m_type = type; - - g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_QUAKE; - if (m_type == eBrushTypeQuake3BP || m_type == eBrushTypeDoom3 || m_type == eBrushTypeQuake4) { - g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_BRUSHPRIMITIVES; - // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting - } else if (m_type == eBrushTypeHalfLife || m_type == eBrushTypeQuake3Valve) { - g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_HALFLIFE; - // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting - } - - Face::m_quantise = (m_type == eBrushTypeQuake) ? quantiseInteger : quantiseFloating; - - m_state_point = GlobalShaderCache().capture("$POINT"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$POINT"); -} - -std::size_t DEBUG_size() -{ - return m_faces.size(); -} - -typedef Faces::const_iterator const_iterator; - -const_iterator begin() const -{ - return m_faces.begin(); -} - -const_iterator end() const -{ - return m_faces.end(); -} - -Face *back() -{ - return m_faces.back(); -} - -const Face *back() const -{ - return m_faces.back(); -} - -void reserve(std::size_t count) -{ - m_faces.reserve(count); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->reserve(count); - } -} - -void push_back(Faces::value_type face) -{ - m_faces.push_back(face); - if (m_instanceCounter.m_count != 0) { - m_faces.back()->instanceAttach(m_map); - } - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->push_back(*face); - (*i)->DEBUG_verify(); - } -} - -void pop_back() -{ - if (m_instanceCounter.m_count != 0) { - m_faces.back()->instanceDetach(m_map); - } - m_faces.pop_back(); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->pop_back(); - (*i)->DEBUG_verify(); - } -} - -void erase(std::size_t index) -{ - if (m_instanceCounter.m_count != 0) { - m_faces[index]->instanceDetach(m_map); - } - m_faces.erase(m_faces.begin() + index); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->erase(index); - (*i)->DEBUG_verify(); - } -} - -void connectivityChanged() -{ - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->connectivityChanged(); - } -} - - -void clear() -{ - undoSave(); - if (m_instanceCounter.m_count != 0) { - forEachFace_instanceDetach(m_map); - } - m_faces.clear(); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->clear(); - (*i)->DEBUG_verify(); - } -} - -std::size_t size() const -{ - return m_faces.size(); -} - -bool empty() const -{ - return m_faces.empty(); -} - -/// \brief Returns true if any face of the brush contributes to the final B-Rep. -bool hasContributingFaces() const -{ - for (const_iterator i = begin(); i != end(); ++i) { - if ((*i)->contributes()) { - return true; - } - } - return false; -} - -/// \brief Removes faces that do not contribute to the brush. This is useful for cleaning up after CSG operations on the brush. -/// Note: removal of empty faces is not performed during direct brush manipulations, because it would make a manipulation irreversible if it created an empty face. -void removeEmptyFaces() -{ - evaluateBRep(); - - { - std::size_t i = 0; - while (i < m_faces.size()) { - if (!m_faces[i]->contributes()) { - erase(i); - planeChanged(); - } else { - ++i; - } - } - } -} - -/// \brief Constructs \p winding from the intersection of \p plane with the other planes of the brush. -void windingForClipPlane(Winding &winding, const Plane3 &plane) const -{ - FixedWinding buffer[2]; - bool swap = false; - - // get a poly that covers an effectively infinite area - Winding_createInfinite(buffer[swap], plane, m_maxWorldCoord + 1); - - // chop the poly by all of the other faces - { - for (std::size_t i = 0; i < m_faces.size(); ++i) { - const Face &clip = *m_faces[i]; - - if (plane3_equal(clip.plane3(), plane) - || !plane3_valid(clip.plane3()) || !plane_unique(i) - || plane3_opposing(plane, clip.plane3())) { - continue; - } - - buffer[!swap].clear(); - -#if BRUSH_CONNECTIVITY_DEBUG - globalOutputStream() << "clip vs face: " << i << "\n"; -#endif - - { - // flip the plane, because we want to keep the back side - Plane3 clipPlane(vector3_negated(clip.plane3().normal()), -clip.plane3().dist()); - Winding_Clip(buffer[swap], plane, clipPlane, i, buffer[!swap]); - } - -#if BRUSH_CONNECTIVITY_DEBUG - for ( FixedWinding::Points::iterator k = buffer[!swap].points.begin(), j = buffer[!swap].points.end() - 1; k != buffer[!swap].points.end(); j = k, ++k ) - { - if ( vector3_length_squared( vector3_subtracted( ( *k ).vertex, ( *j ).vertex ) ) < 1 ) { - globalOutputStream() << "v: " << std::distance( buffer[!swap].points.begin(), j ) << " tiny edge adjacent to face " << ( *j ).adjacent << "\n"; - } - } -#endif - - //ASSERT_MESSAGE(buffer[!swap].numpoints != 1, "created single-point winding"); - - swap = !swap; - } - } - - Winding_forFixedWinding(winding, buffer[swap]); - -#if BRUSH_CONNECTIVITY_DEBUG - Winding_printConnectivity( winding ); - - for ( Winding::iterator i = winding.begin(), j = winding.end() - 1; i != winding.end(); j = i, ++i ) - { - if ( vector3_length_squared( vector3_subtracted( ( *i ).vertex, ( *j ).vertex ) ) < 1 ) { - globalOutputStream() << "v: " << std::distance( winding.begin(), j ) << " tiny edge adjacent to face " << ( *j ).adjacent << "\n"; - } - } -#endif -} - -void update_wireframe(RenderableWireframe &wire, const bool *faces_visible) const -{ - wire.m_faceVertex.resize(m_edge_indices.size()); - wire.m_vertices = m_uniqueVertexPoints.data(); - wire.m_size = 0; - for (std::size_t i = 0; i < m_edge_faces.size(); ++i) { - if (faces_visible[m_edge_faces[i].first] - || faces_visible[m_edge_faces[i].second]) { - wire.m_faceVertex[wire.m_size++] = m_edge_indices[i]; - } - } -} - - -void update_faces_wireframe(Array &wire, const bool *faces_visible) const -{ - std::size_t count = 0; - for (std::size_t i = 0; i < m_faceCentroidPoints.size(); ++i) { - if (faces_visible[i]) { - ++count; - } - } - - wire.resize(count); - Array::iterator p = wire.begin(); - for (std::size_t i = 0; i < m_faceCentroidPoints.size(); ++i) { - if (faces_visible[i]) { - *p++ = m_faceCentroidPoints[i]; - } - } -} - -/// \brief Makes this brush a deep-copy of the \p other. -void copy(const Brush &other) -{ - for (Faces::const_iterator i = other.m_faces.begin(); i != other.m_faces.end(); ++i) { - addFace(*(*i)); - } - planeChanged(); -} - -private: -void edge_push_back(FaceVertexId faceVertex) -{ - m_select_edges.push_back(SelectableEdge(m_faces, faceVertex)); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->edge_push_back(m_select_edges.back()); - } -} - -void edge_clear() -{ - m_select_edges.clear(); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->edge_clear(); - } -} - -void vertex_push_back(FaceVertexId faceVertex) -{ - m_select_vertices.push_back(SelectableVertex(m_faces, faceVertex)); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->vertex_push_back(m_select_vertices.back()); - } -} - -void vertex_clear() -{ - m_select_vertices.clear(); - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->vertex_clear(); - } -} - -/// \brief Returns true if the face identified by \p index is preceded by another plane that takes priority over it. -bool plane_unique(std::size_t index) const -{ - // duplicate plane - for (std::size_t i = 0; i < m_faces.size(); ++i) { - if (index != i && !plane3_inside(m_faces[index]->plane3(), m_faces[i]->plane3(), index < i)) { - return false; - } - } - return true; -} - -/// \brief Removes edges that are smaller than the tolerance used when generating brush windings. -void removeDegenerateEdges() -{ - for (std::size_t i = 0; i < m_faces.size(); ++i) { - Winding &winding = m_faces[i]->getWinding(); - for (Winding::iterator j = winding.begin(); j != winding.end();) { - std::size_t index = std::distance(winding.begin(), j); - std::size_t next = Winding_next(winding, index); - if (Edge_isDegenerate(winding[index].vertex, winding[next].vertex)) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": degenerate edge adjacent to " << winding[index].adjacent << "\n"; -#endif - Winding &other = m_faces[winding[index].adjacent]->getWinding(); - std::size_t adjacent = Winding_FindAdjacent(other, i); - if (adjacent != c_brush_maxFaces) { - other.erase(other.begin() + adjacent); - } - winding.erase(j); - } else { - ++j; - } - } - } -} - -/// \brief Invalidates faces that have only two vertices in their winding, while preserving edge-connectivity information. -void removeDegenerateFaces() -{ - // save adjacency info for degenerate faces - for (std::size_t i = 0; i < m_faces.size(); ++i) { - Winding °en = m_faces[i]->getWinding(); - - if (degen.numpoints == 2) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": degenerate winding adjacent to " << degen[0].adjacent << ", " << degen[1].adjacent << "\n"; -#endif - // this is an "edge" face, where the plane touches the edge of the brush - { - Winding &winding = m_faces[degen[0].adjacent]->getWinding(); - std::size_t index = Winding_FindAdjacent(winding, i); - if (index != c_brush_maxFaces) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << degen[0].adjacent << ": remapping adjacent " << winding[index].adjacent << " to " << degen[1].adjacent << "\n"; -#endif - winding[index].adjacent = degen[1].adjacent; - } - } - - { - Winding &winding = m_faces[degen[1].adjacent]->getWinding(); - std::size_t index = Winding_FindAdjacent(winding, i); - if (index != c_brush_maxFaces) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << degen[1].adjacent << ": remapping adjacent " << winding[index].adjacent << " to " << degen[0].adjacent << "\n"; -#endif - winding[index].adjacent = degen[0].adjacent; - } - } - - degen.resize(0); - } - } -} - -/// \brief Removes edges that have the same adjacent-face as their immediate neighbour. -void removeDuplicateEdges() -{ - // verify face connectivity graph - for (std::size_t i = 0; i < m_faces.size(); ++i) { - //if(m_faces[i]->contributes()) - { - Winding &winding = m_faces[i]->getWinding(); - for (std::size_t j = 0; j != winding.numpoints;) { - std::size_t next = Winding_next(winding, j); - if (winding[j].adjacent == winding[next].adjacent) { -#if BRUSH_DEGENERATE_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": removed duplicate edge adjacent to face " << winding[j].adjacent << "\n"; -#endif - winding.erase(winding.begin() + next); - } else { - ++j; - } - } - } - } -} - -/// \brief Removes edges that do not have a matching pair in their adjacent-face. -void verifyConnectivityGraph() -{ - // verify face connectivity graph - for (std::size_t i = 0; i < m_faces.size(); ++i) { - //if(m_faces[i]->contributes()) - { - Winding &winding = m_faces[i]->getWinding(); - for (Winding::iterator j = winding.begin(); j != winding.end();) { -#if BRUSH_CONNECTIVITY_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": adjacent to face " << ( *j ).adjacent << "\n"; -#endif - // remove unidirectional graph edges - if ((*j).adjacent == c_brush_maxFaces - || Winding_FindAdjacent(m_faces[(*j).adjacent]->getWinding(), i) == c_brush_maxFaces) { -#if BRUSH_CONNECTIVITY_DEBUG - globalOutputStream() << "Brush::buildWindings: face " << i << ": removing unidirectional connectivity graph edge adjacent to face " << ( *j ).adjacent << "\n"; -#endif - winding.erase(j); - } else { - ++j; - } - } - } - } -} - -/// \brief Returns true if the brush is a finite volume. A brush without a finite volume extends past the maximum world bounds and is not valid. -bool isBounded() -{ - for (const_iterator i = begin(); i != end(); ++i) { - if (!(*i)->is_bounded()) { - return false; - } - } - return true; -} - -/// \brief Constructs the polygon windings for each face of the brush. Also updates the brush bounding-box and face texture-coordinates. -bool buildWindings() -{ - - { - m_aabb_local = AABB(); - - for (std::size_t i = 0; i < m_faces.size(); ++i) { - Face &f = *m_faces[i]; - - if (!plane3_valid(f.plane3()) || !plane_unique(i)) { - f.getWinding().resize(0); - } else { -#if BRUSH_CONNECTIVITY_DEBUG - globalOutputStream() << "face: " << i << "\n"; -#endif - windingForClipPlane(f.getWinding(), f.plane3()); - - // update brush bounds - const Winding &winding = f.getWinding(); - for (Winding::const_iterator i = winding.begin(); i != winding.end(); ++i) { - aabb_extend_by_point_safe(m_aabb_local, (*i).vertex); - } - - // update texture coordinates - f.EmitTextureCoordinates(); - } - } - } - - bool degenerate = !isBounded(); - - if (!degenerate) { - // clean up connectivity information. - // these cleanups must be applied in a specific order. - removeDegenerateEdges(); - removeDegenerateFaces(); - removeDuplicateEdges(); - verifyConnectivityGraph(); - } - - return degenerate; -} - -/// \brief Constructs the face windings and updates anything that depends on them. -void buildBRep(); -}; - - -class FaceInstance; - -class FaceInstanceSet { -typedef SelectionList FaceInstances; -FaceInstances m_faceInstances; -public: -void insert(FaceInstance &faceInstance) -{ - m_faceInstances.append(faceInstance); -} - -void erase(FaceInstance &faceInstance) -{ - m_faceInstances.erase(faceInstance); -} - -template -void foreach(Functor functor) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - functor(*(*i)); - } -} - -bool empty() const -{ - return m_faceInstances.empty(); -} - -FaceInstance &last() const -{ - return m_faceInstances.back(); -} -}; - -extern FaceInstanceSet g_SelectedFaceInstances; - -typedef std::list VertexSelection; - -inline VertexSelection::iterator VertexSelection_find(VertexSelection &self, std::size_t value) -{ - return std::find(self.begin(), self.end(), value); -} - -inline VertexSelection::const_iterator VertexSelection_find(const VertexSelection &self, std::size_t value) -{ - return std::find(self.begin(), self.end(), value); -} - -inline VertexSelection::iterator VertexSelection_insert(VertexSelection &self, std::size_t value) -{ - VertexSelection::iterator i = VertexSelection_find(self, value); - if (i == self.end()) { - self.push_back(value); - return --self.end(); - } - return i; -} - -inline void VertexSelection_erase(VertexSelection &self, std::size_t value) -{ - VertexSelection::iterator i = VertexSelection_find(self, value); - if (i != self.end()) { - self.erase(i); - } -} - -inline bool triangle_reversed(std::size_t x, std::size_t y, std::size_t z) -{ - return !((x < y && y < z) || (z < x && x < y) || (y < z && z < x)); -} - -template -inline Vector3 -triangle_cross(const BasicVector3 &x, const BasicVector3 y, const BasicVector3 &z) -{ - return vector3_cross(y - x, z - x); -} - -template -inline bool -triangles_same_winding(const BasicVector3 &x1, const BasicVector3 y1, const BasicVector3 &z1, - const BasicVector3 &x2, const BasicVector3 y2, const BasicVector3 &z2) -{ - return vector3_dot(triangle_cross(x1, y1, z1), triangle_cross(x2, y2, z2)) > 0; -} - - -typedef const Plane3 *PlanePointer; -typedef PlanePointer *PlanesIterator; - -class VectorLightList : public LightList { -typedef std::vector Lights; -Lights m_lights; -public: -void addLight(const RendererLight &light) -{ - m_lights.push_back(&light); -} - -void clear() -{ - m_lights.clear(); -} - -void evaluateLights() const -{ -} - -void lightsChanged() const -{ -} - -void forEachLight(const RendererLightCallback &callback) const -{ - for (Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i) { - callback(*(*i)); - } -} -}; - -class FaceInstance { -Face *m_face; -ObservedSelectable m_selectable; -ObservedSelectable m_selectableVertices; -ObservedSelectable m_selectableEdges; -SelectionChangeCallback m_selectionChanged; - -VertexSelection m_vertexSelection; -VertexSelection m_edgeSelection; - -public: -mutable VectorLightList m_lights; - -FaceInstance(Face &face, const SelectionChangeCallback &observer) : - m_face(&face), - m_selectable(SelectedChangedCaller(*this)), - m_selectableVertices(observer), - m_selectableEdges(observer), - m_selectionChanged(observer) -{ -} - -FaceInstance(const FaceInstance &other) : - m_face(other.m_face), - m_selectable(SelectedChangedCaller(*this)), - m_selectableVertices(other.m_selectableVertices), - m_selectableEdges(other.m_selectableEdges), - m_selectionChanged(other.m_selectionChanged) -{ -} - -FaceInstance &operator=(const FaceInstance &other) -{ - m_face = other.m_face; - return *this; -} - -Face &getFace() -{ - return *m_face; -} - -const Face &getFace() const -{ - return *m_face; -} - -void selectedChanged(const Selectable &selectable) -{ - if (selectable.isSelected()) { - g_SelectedFaceInstances.insert(*this); - } else { - g_SelectedFaceInstances.erase(*this); - } - m_selectionChanged(selectable); -} - -typedef MemberCaller SelectedChangedCaller; - -bool selectedVertices() const -{ - return !m_vertexSelection.empty(); -} - -bool selectedEdges() const -{ - return !m_edgeSelection.empty(); -} - -bool isSelected() const -{ - return m_selectable.isSelected(); -} - -bool selectedComponents() const -{ - return selectedVertices() || selectedEdges() || isSelected(); -} - -bool selectedComponents(SelectionSystem::EComponentMode mode) const -{ - switch (mode) { - case SelectionSystem::eVertex: - return selectedVertices(); - case SelectionSystem::eEdge: - return selectedEdges(); - case SelectionSystem::eFace: - return isSelected(); - default: - return false; - } -} - -void setSelected(SelectionSystem::EComponentMode mode, bool select) -{ - switch (mode) { - case SelectionSystem::eFace: - m_selectable.setSelected(select); - break; - case SelectionSystem::eVertex: - ASSERT_MESSAGE(!select, "select-all not supported"); - - m_vertexSelection.clear(); - m_selectableVertices.setSelected(false); - break; - case SelectionSystem::eEdge: - ASSERT_MESSAGE(!select, "select-all not supported"); - - m_edgeSelection.clear(); - m_selectableEdges.setSelected(false); - break; - default: - break; - } -} - -template -void SelectedVertices_foreach(Functor functor) const -{ - for (VertexSelection::const_iterator i = m_vertexSelection.begin(); i != m_vertexSelection.end(); ++i) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *i); - if (index != c_brush_maxFaces) { - functor(getFace().getWinding()[index].vertex); - } - } -} - -template -void SelectedEdges_foreach(Functor functor) const -{ - for (VertexSelection::const_iterator i = m_edgeSelection.begin(); i != m_edgeSelection.end(); ++i) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *i); - if (index != c_brush_maxFaces) { - const Winding &winding = getFace().getWinding(); - std::size_t adjacent = Winding_next(winding, index); - functor(vector3_mid(winding[index].vertex, winding[adjacent].vertex)); - } - } -} - -template -void SelectedFaces_foreach(Functor functor) const -{ - if (isSelected()) { - functor(centroid()); - } -} - -template -void SelectedComponents_foreach(Functor functor) const -{ - SelectedVertices_foreach(functor); - SelectedEdges_foreach(functor); - SelectedFaces_foreach(functor); -} - -void iterate_selected(AABB &aabb) const -{ - SelectedComponents_foreach([&](const Vector3 &point) { - aabb_extend_by_point_safe(aabb, point); - }); -} - -void iterate_selected(RenderablePointVector &points) const -{ - SelectedComponents_foreach([&](const Vector3 &point) { - const Colour4b colour_selected(0, 0, 255, 255); - points.push_back(pointvertex_for_windingpoint(point, colour_selected)); - }); -} - -bool intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return m_face->intersectVolume(volume, localToWorld); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - if (!m_face->isFiltered() && m_face->contributes() && intersectVolume(volume, localToWorld)) { - renderer.PushState(); - if (selectedComponents()) { - renderer.Highlight(Renderer::eFace); - } - m_face->render(renderer, localToWorld); - renderer.PopState(); - } -} - -void testSelect(SelectionTest &test, SelectionIntersection &best) -{ - if (!m_face->isFiltered()) { - m_face->testSelect(test, best); - } -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - testSelect(test, best); - if (best.valid()) { - Selector_add(selector, m_selectable, best); - } -} - -void testSelect_centroid(Selector &selector, SelectionTest &test) -{ - if (m_face->contributes() && !m_face->isFiltered()) { - SelectionIntersection best; - m_face->testSelect_centroid(test, best); - if (best.valid()) { - Selector_add(selector, m_selectable, best); - } - } -} - -void selectPlane(Selector &selector, const Line &line, PlanesIterator first, PlanesIterator last, - const PlaneCallback &selectedPlaneCallback) -{ - for (Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i) { - Vector3 v(vector3_subtracted(line_closest_point(line, (*i).vertex), (*i).vertex)); - double dot = vector3_dot(getFace().plane3().normal(), v); - if (dot <= 0) { - return; - } - } - - Selector_add(selector, m_selectable); - - selectedPlaneCallback(getFace().plane3()); -} - -void selectReversedPlane(Selector &selector, const SelectedPlanes &selectedPlanes) -{ - if (selectedPlanes.contains(plane3_flipped(getFace().plane3()))) { - Selector_add(selector, m_selectable); - } -} - -void transformComponents(const Matrix4 &matrix) -{ - if (isSelected()) { - m_face->transform(matrix, false); - } - if (selectedVertices()) { - if (m_vertexSelection.size() == 1) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } else if (m_vertexSelection.size() == 2) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[2]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } else if (m_vertexSelection.size() >= 3) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[0]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[2]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } - } - if (selectedEdges()) { - if (m_edgeSelection.size() == 1) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[0]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } else if (m_edgeSelection.size() >= 2) { - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[0]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[1]); - matrix4_transform_point(matrix, m_face->m_move_planeptsTransformed[2]); - m_face->assign_planepts(m_face->m_move_planeptsTransformed); - } - } -} - -void snapto(float snap) -{ - m_face->snapto(snap); -} - -void snapComponents(float snap) -{ - if (isSelected()) { - snapto(snap); - } - if (selectedVertices()) { - vector3_snap(m_face->m_move_planepts[0], snap); - vector3_snap(m_face->m_move_planepts[1], snap); - vector3_snap(m_face->m_move_planepts[2], snap); - m_face->assign_planepts(m_face->m_move_planepts); - planepts_assign(m_face->m_move_planeptsTransformed, m_face->m_move_planepts); - m_face->freezeTransform(); - } - if (selectedEdges()) { - vector3_snap(m_face->m_move_planepts[0], snap); - vector3_snap(m_face->m_move_planepts[1], snap); - vector3_snap(m_face->m_move_planepts[2], snap); - m_face->assign_planepts(m_face->m_move_planepts); - planepts_assign(m_face->m_move_planeptsTransformed, m_face->m_move_planepts); - m_face->freezeTransform(); - } -} - -void update_move_planepts_vertex(std::size_t index) -{ - m_face->update_move_planepts_vertex(index, m_face->m_move_planepts); -} - -void update_move_planepts_vertex2(std::size_t index, std::size_t other) -{ - const std::size_t numpoints = m_face->getWinding().numpoints; - ASSERT_MESSAGE(index < numpoints, "select_vertex: invalid index"); - - const std::size_t opposite = Winding_Opposite(m_face->getWinding(), index, other); - - if (triangle_reversed(index, other, opposite)) { - std::swap(index, other); - } - - ASSERT_MESSAGE( - triangles_same_winding( - m_face->getWinding()[opposite].vertex, - m_face->getWinding()[index].vertex, - m_face->getWinding()[other].vertex, - m_face->getWinding()[0].vertex, - m_face->getWinding()[1].vertex, - m_face->getWinding()[2].vertex - ), - "update_move_planepts_vertex2: error" - ); - - m_face->m_move_planepts[0] = m_face->getWinding()[opposite].vertex; - m_face->m_move_planepts[1] = m_face->getWinding()[index].vertex; - m_face->m_move_planepts[2] = m_face->getWinding()[other].vertex; - planepts_quantise(m_face->m_move_planepts, GRID_MIN); // winding points are very inaccurate -} - -void update_selection_vertex() -{ - if (m_vertexSelection.size() == 0) { - m_selectableVertices.setSelected(false); - } else { - m_selectableVertices.setSelected(true); - - if (m_vertexSelection.size() == 1) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *m_vertexSelection.begin()); - - if (index != c_brush_maxFaces) { - update_move_planepts_vertex(index); - } - } else if (m_vertexSelection.size() == 2) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *m_vertexSelection.begin()); - std::size_t other = Winding_FindAdjacent(getFace().getWinding(), *(++m_vertexSelection.begin())); - - if (index != c_brush_maxFaces - && other != c_brush_maxFaces) { - update_move_planepts_vertex2(index, other); - } - } - } -} - -void select_vertex(std::size_t index, bool select) -{ - if (select) { - VertexSelection_insert(m_vertexSelection, getFace().getWinding()[index].adjacent); - } else { - VertexSelection_erase(m_vertexSelection, getFace().getWinding()[index].adjacent); - } - - SceneChangeNotify(); - update_selection_vertex(); -} - -bool selected_vertex(std::size_t index) const -{ - return VertexSelection_find(m_vertexSelection, getFace().getWinding()[index].adjacent) != - m_vertexSelection.end(); -} - -void update_move_planepts_edge(std::size_t index) -{ - std::size_t numpoints = m_face->getWinding().numpoints; - ASSERT_MESSAGE(index < numpoints, "select_edge: invalid index"); - - std::size_t adjacent = Winding_next(m_face->getWinding(), index); - std::size_t opposite = Winding_Opposite(m_face->getWinding(), index); - m_face->m_move_planepts[0] = m_face->getWinding()[index].vertex; - m_face->m_move_planepts[1] = m_face->getWinding()[adjacent].vertex; - m_face->m_move_planepts[2] = m_face->getWinding()[opposite].vertex; - planepts_quantise(m_face->m_move_planepts, GRID_MIN); // winding points are very inaccurate -} - -void update_selection_edge() -{ - if (m_edgeSelection.size() == 0) { - m_selectableEdges.setSelected(false); - } else { - m_selectableEdges.setSelected(true); - - if (m_edgeSelection.size() == 1) { - std::size_t index = Winding_FindAdjacent(getFace().getWinding(), *m_edgeSelection.begin()); - - if (index != c_brush_maxFaces) { - update_move_planepts_edge(index); - } - } - } -} - -void select_edge(std::size_t index, bool select) -{ - if (select) { - VertexSelection_insert(m_edgeSelection, getFace().getWinding()[index].adjacent); - } else { - VertexSelection_erase(m_edgeSelection, getFace().getWinding()[index].adjacent); - } - - SceneChangeNotify(); - update_selection_edge(); -} - -bool selected_edge(std::size_t index) const -{ - return VertexSelection_find(m_edgeSelection, getFace().getWinding()[index].adjacent) != m_edgeSelection.end(); -} - -const Vector3 ¢roid() const -{ - return m_face->centroid(); -} - -void connectivityChanged() -{ - // This occurs when a face is added or removed. - // The current vertex and edge selections no longer valid and must be cleared. - m_vertexSelection.clear(); - m_selectableVertices.setSelected(false); - m_edgeSelection.clear(); - m_selectableEdges.setSelected(false); -} -}; - -class BrushClipPlane : public OpenGLRenderable { -Plane3 m_plane; -Winding m_winding; -static Shader *m_state; -public: -static void constructStatic() -{ - m_state = GlobalShaderCache().capture("$CLIPPER_OVERLAY"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$CLIPPER_OVERLAY"); -} - -void setPlane(const Brush &brush, const Plane3 &plane) -{ - m_plane = plane; - if (plane3_valid(m_plane)) { - brush.windingForClipPlane(m_winding, m_plane); - } else { - m_winding.resize(0); - } -} - -void render(RenderStateFlags state) const -{ - if ((state & RENDER_FILL) != 0) { - Winding_Draw(m_winding, m_plane.normal(), state); - } else { - Winding_DrawWireframe(m_winding); - - // also draw a line indicating the direction of the cut - Vector3 lineverts[2]; - Winding_Centroid(m_winding, m_plane, lineverts[0]); - lineverts[1] = vector3_added(lineverts[0], vector3_scaled(m_plane.normal(), Brush::m_maxWorldCoord * 4)); - - glVertexPointer(3, GL_FLOAT, sizeof(Vector3), &lineverts[0]); - glDrawArrays(GL_LINES, 0, GLsizei(2)); - } -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state, Renderer::eWireframeOnly); - renderer.SetState(m_state, Renderer::eFullMaterials); - renderer.addRenderable(*this, localToWorld); -} -}; - -inline void Face_addLight(const FaceInstance &face, const Matrix4 &localToWorld, const RendererLight &light) -{ - const Plane3 &facePlane = face.getFace().plane3(); - const Vector3 &origin = light.aabb().origin; - Plane3 tmp(plane3_transformed(Plane3(facePlane.normal(), -facePlane.dist()), localToWorld)); - if (!plane3_test_point(tmp, origin) - || !plane3_test_point(tmp, vector3_added(origin, light.offset()))) { - face.m_lights.addLight(light); - } -} - - -typedef std::vector FaceInstances; - -class EdgeInstance : public Selectable { -FaceInstances &m_faceInstances; -SelectableEdge *m_edge; - -void select_edge(bool select) -{ - FaceVertexId faceVertex = m_edge->m_faceVertex; - m_faceInstances[faceVertex.getFace()].select_edge(faceVertex.getVertex(), select); - faceVertex = next_edge(m_edge->m_faces, faceVertex); - m_faceInstances[faceVertex.getFace()].select_edge(faceVertex.getVertex(), select); -} - -bool selected_edge() const -{ - FaceVertexId faceVertex = m_edge->m_faceVertex; - if (!m_faceInstances[faceVertex.getFace()].selected_edge(faceVertex.getVertex())) { - return false; - } - faceVertex = next_edge(m_edge->m_faces, faceVertex); - if (!m_faceInstances[faceVertex.getFace()].selected_edge(faceVertex.getVertex())) { - return false; - } - - return true; -} - -public: -EdgeInstance(FaceInstances &faceInstances, SelectableEdge &edge) - : m_faceInstances(faceInstances), m_edge(&edge) -{ -} - -EdgeInstance &operator=(const EdgeInstance &other) -{ - m_edge = other.m_edge; - return *this; -} - -void setSelected(bool select) -{ - select_edge(select); -} - -bool isSelected() const -{ - return selected_edge(); -} - - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - m_edge->testSelect(test, best); - if (best.valid()) { - Selector_add(selector, *this, best); - } -} -}; - -class VertexInstance : public Selectable { -FaceInstances &m_faceInstances; -SelectableVertex *m_vertex; - -void select_vertex(bool select) -{ - FaceVertexId faceVertex = m_vertex->m_faceVertex; - do { - m_faceInstances[faceVertex.getFace()].select_vertex(faceVertex.getVertex(), select); - faceVertex = next_vertex(m_vertex->m_faces, faceVertex); - } while (faceVertex.getFace() != m_vertex->m_faceVertex.getFace()); -} - -bool selected_vertex() const -{ - FaceVertexId faceVertex = m_vertex->m_faceVertex; - do { - if (!m_faceInstances[faceVertex.getFace()].selected_vertex(faceVertex.getVertex())) { - return false; - } - faceVertex = next_vertex(m_vertex->m_faces, faceVertex); - } while (faceVertex.getFace() != m_vertex->m_faceVertex.getFace()); - return true; -} - -public: -VertexInstance(FaceInstances &faceInstances, SelectableVertex &vertex) - : m_faceInstances(faceInstances), m_vertex(&vertex) -{ -} - -VertexInstance &operator=(const VertexInstance &other) -{ - m_vertex = other.m_vertex; - return *this; -} - -void setSelected(bool select) -{ - select_vertex(select); -} - -bool isSelected() const -{ - return selected_vertex(); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - m_vertex->testSelect(test, best); - if (best.valid()) { - Selector_add(selector, *this, best); - } -} -}; - -class BrushInstanceVisitor { -public: -virtual void visit(FaceInstance &face) const = 0; -}; - -class BrushInstance : - public BrushObserver, - public scene::Instance, - public Selectable, - public Renderable, - public SelectionTestable, - public ComponentSelectionTestable, - public ComponentEditable, - public ComponentSnappable, - public PlaneSelectable, - public LightCullable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceStaticCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); - InstanceContainedCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - - -Brush &m_brush; - -FaceInstances m_faceInstances; - -typedef std::vector EdgeInstances; -EdgeInstances m_edgeInstances; -typedef std::vector VertexInstances; -VertexInstances m_vertexInstances; - -ObservedSelectable m_selectable; - -mutable RenderableWireframe m_render_wireframe; -mutable RenderablePointVector m_render_selected; -mutable AABB m_aabb_component; -mutable Array m_faceCentroidPointsCulled; -RenderablePointArray m_render_faces_wireframe; -mutable bool m_viewChanged; // requires re-evaluation of view-dependent cached data - -BrushClipPlane m_clipPlane; - -static Shader *m_state_selpoint; - -const LightList *m_lightList; - -TransformModifier m_transform; - -BrushInstance(const BrushInstance &other); // NOT COPYABLE -BrushInstance &operator=(const BrushInstance &other); // NOT ASSIGNABLE -public: -static Counter *m_counter; - -typedef LazyStatic StaticTypeCasts; - -void lightsChanged() -{ - m_lightList->lightsChanged(); -} - -typedef MemberCaller LightsChangedCaller; - -STRING_CONSTANT(Name, "BrushInstance"); - -BrushInstance(const scene::Path &path, scene::Instance *parent, Brush &brush) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_brush(brush), - m_selectable(SelectedChangedCaller(*this)), - m_render_selected(GL_POINTS), - m_render_faces_wireframe(m_faceCentroidPointsCulled, GL_POINTS), - m_viewChanged(false), - m_transform(Brush::TransformChangedCaller(m_brush), ApplyTransformCaller(*this)) -{ - m_brush.instanceAttach(Instance::path()); - m_brush.attach(*this); - m_counter->increment(); - - m_lightList = &GlobalShaderCache().attach(*this); - m_brush.m_lightsChanged = LightsChangedCaller(*this); ///\todo Make this work with instancing. - - Instance::setTransformChangedCallback(LightsChangedCaller(*this)); -} - -~BrushInstance() -{ - Instance::setTransformChangedCallback(Callback()); - - m_brush.m_lightsChanged = Callback(); - GlobalShaderCache().detach(*this); - - m_counter->decrement(); - m_brush.detach(*this); - m_brush.instanceDetach(Instance::path()); -} - -Brush &getBrush() -{ - return m_brush; -} - -const Brush &getBrush() const -{ - return m_brush; -} - -Bounded &get(NullType) -{ - return m_brush; -} - -Cullable &get(NullType) -{ - return m_brush; -} - -Transformable &get(NullType) -{ - return m_transform; -} - -void selectedChanged(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::ePrimitive)(selectable); - GlobalSelectionSystem().onSelectedChanged(*this, selectable); - - Instance::selectedChanged(); -} - -typedef MemberCaller SelectedChangedCaller; - -void selectedChangedComponent(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); - GlobalSelectionSystem().onComponentSelection(*this, selectable); -} - -typedef MemberCaller SelectedChangedComponentCaller; - -const BrushInstanceVisitor &forEachFaceInstance(const BrushInstanceVisitor &visitor) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - visitor.visit(*i); - } - return visitor; -} - -static void constructStatic() -{ - m_state_selpoint = GlobalShaderCache().capture("$SELPOINT"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$SELPOINT"); -} - -void clear() -{ - m_faceInstances.clear(); -} - -void reserve(std::size_t size) -{ - m_faceInstances.reserve(size); -} - -void push_back(Face &face) -{ - m_faceInstances.push_back(FaceInstance(face, SelectedChangedComponentCaller(*this))); -} - -void pop_back() -{ - ASSERT_MESSAGE(!m_faceInstances.empty(), "erasing invalid element"); - m_faceInstances.pop_back(); -} - -void erase(std::size_t index) -{ - ASSERT_MESSAGE(index < m_faceInstances.size(), "erasing invalid element"); - m_faceInstances.erase(m_faceInstances.begin() + index); -} - -void connectivityChanged() -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).connectivityChanged(); - } -} - -void edge_clear() -{ - m_edgeInstances.clear(); -} - -void edge_push_back(SelectableEdge &edge) -{ - m_edgeInstances.push_back(EdgeInstance(m_faceInstances, edge)); -} - -void vertex_clear() -{ - m_vertexInstances.clear(); -} - -void vertex_push_back(SelectableVertex &vertex) -{ - m_vertexInstances.push_back(VertexInstance(m_faceInstances, vertex)); -} - -void DEBUG_verify() const -{ - ASSERT_MESSAGE(m_faceInstances.size() == m_brush.DEBUG_size(), "FATAL: mismatch"); -} - -bool isSelected() const -{ - return m_selectable.isSelected(); -} - -void setSelected(bool select) -{ - m_selectable.setSelected(select); -} - -void update_selected() const -{ - m_render_selected.clear(); - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - if ((*i).getFace().contributes()) { - (*i).iterate_selected(m_render_selected); - } - } -} - -void evaluateViewDependent(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - if (m_viewChanged) { - m_viewChanged = false; - - bool faces_visible[c_brush_maxFaces]; - { - bool *j = faces_visible; - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i, ++j) { - *j = (*i).intersectVolume(volume, localToWorld); - } - } - - m_brush.update_wireframe(m_render_wireframe, faces_visible); - m_brush.update_faces_wireframe(m_faceCentroidPointsCulled, faces_visible); - } -} - -void renderComponentsSelected(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - m_brush.evaluateBRep(); - - update_selected(); - if (!m_render_selected.empty()) { - renderer.Highlight(Renderer::ePrimitive, false); - renderer.SetState(m_state_selpoint, Renderer::eWireframeOnly); - renderer.SetState(m_state_selpoint, Renderer::eFullMaterials); - renderer.addRenderable(m_render_selected, localToWorld); - } -} - -void renderComponents(Renderer &renderer, const VolumeTest &volume) const -{ - m_brush.evaluateBRep(); - - const Matrix4 &localToWorld = Instance::localToWorld(); - - renderer.SetState(m_brush.m_state_point, Renderer::eWireframeOnly); - renderer.SetState(m_brush.m_state_point, Renderer::eFullMaterials); - - if (volume.fill() && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace) { - evaluateViewDependent(volume, localToWorld); - renderer.addRenderable(m_render_faces_wireframe, localToWorld); - } else { - m_brush.renderComponents(GlobalSelectionSystem().ComponentMode(), renderer, volume, localToWorld); - } -} - -void renderClipPlane(Renderer &renderer, const VolumeTest &volume) const -{ - if (GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && isSelected()) { - m_clipPlane.render(renderer, volume, localToWorld()); - } -} - -void renderCommon(Renderer &renderer, const VolumeTest &volume) const -{ - bool componentMode = GlobalSelectionSystem().Mode() == SelectionSystem::eComponent; - - if (componentMode && isSelected()) { - renderComponents(renderer, volume); - } - - if (parentSelected()) { - if (!componentMode) { - renderer.Highlight(Renderer::eFace); - } - renderer.Highlight(Renderer::ePrimitive); - } -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - //renderCommon(renderer, volume); - - m_lightList->evaluateLights(); - - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - renderer.setLights((*i).m_lights); - (*i).render(renderer, volume, localToWorld); - } - - renderComponentsSelected(renderer, volume, localToWorld); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - //renderCommon(renderer, volume); - - evaluateViewDependent(volume, localToWorld); - - if (m_render_wireframe.m_size != 0) { - renderer.addRenderable(m_render_wireframe, localToWorld); - } - - renderComponentsSelected(renderer, volume, localToWorld); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_brush.evaluateBRep(); - - renderClipPlane(renderer, volume); - - renderSolid(renderer, volume, localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_brush.evaluateBRep(); - - renderClipPlane(renderer, volume); - - renderWireframe(renderer, volume, localToWorld()); -} - -void viewChanged() const -{ - m_viewChanged = true; -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - test.BeginMesh(localToWorld()); - - SelectionIntersection best; - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).testSelect(test, best); - } - if (best.valid()) { - selector.addIntersection(best); - } -} - -bool isSelectedComponents() const -{ - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - if ((*i).selectedComponents()) { - return true; - } - } - return false; -} - -void setSelectedComponents(bool select, SelectionSystem::EComponentMode mode) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).setSelected(mode, select); - } -} - -void testSelectComponents(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) -{ - test.BeginMesh(localToWorld()); - - switch (mode) { - case SelectionSystem::eVertex: { - for (VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i) { - (*i).testSelect(selector, test); - } - } - break; - case SelectionSystem::eEdge: { - for (EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i) { - (*i).testSelect(selector, test); - } - } - break; - case SelectionSystem::eFace: { - if (test.getVolume().fill()) { - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).testSelect(selector, test); - } - } else { - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).testSelect_centroid(selector, test); - } - } - } - break; - default: - break; - } -} - -void selectPlanes(Selector &selector, SelectionTest &test, const PlaneCallback &selectedPlaneCallback) -{ - test.BeginMesh(localToWorld()); - - PlanePointer brushPlanes[c_brush_maxFaces]; - PlanesIterator j = brushPlanes; - - for (Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i) { - *j++ = &(*i)->plane3(); - } - - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).selectPlane(selector, Line(test.getNear(), test.getFar()), brushPlanes, j, selectedPlaneCallback); - } -} - -void selectReversedPlanes(Selector &selector, const SelectedPlanes &selectedPlanes) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).selectReversedPlane(selector, selectedPlanes); - } -} - - -void transformComponents(const Matrix4 &matrix) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).transformComponents(matrix); - } -} - -const AABB &getSelectedComponentsBounds() const -{ - m_aabb_component = AABB(); - - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).iterate_selected(m_aabb_component); - } - - return m_aabb_component; -} - -void snapComponents(float snap) -{ - for (FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).snapComponents(snap); - } -} - -void evaluateTransform() -{ - Matrix4 matrix(m_transform.calculateTransform()); - //globalOutputStream() << "matrix: " << matrix << "\n"; - - if (m_transform.getType() == TRANSFORM_PRIMITIVE) { - m_brush.transform(matrix); - } else { - transformComponents(matrix); - } -} - -void applyTransform() -{ - m_brush.revertTransform(); - evaluateTransform(); - m_brush.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; - -void setClipPlane(const Plane3 &plane) -{ - m_clipPlane.setPlane(m_brush, plane); -} - -bool testLight(const RendererLight &light) const -{ - return light.testAABB(worldAABB()); -} - -void insertLight(const RendererLight &light) -{ - const Matrix4 &localToWorld = Instance::localToWorld(); - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - Face_addLight(*i, localToWorld, light); - } -} - -void clearLights() -{ - for (FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i) { - (*i).m_lights.clear(); - } -} -}; - -inline BrushInstance *Instance_getBrush(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - - -template -class BrushSelectedVisitor : public SelectionSystem::Visitor { -const Functor &m_functor; -public: -BrushSelectedVisitor(const Functor &functor) : m_functor(functor) -{ -} - -void visit(scene::Instance &instance) const -{ - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0) { - m_functor(*brush); - } -} -}; - -template -inline const Functor &Scene_forEachSelectedBrush(const Functor &functor) -{ - GlobalSelectionSystem().foreachSelected(BrushSelectedVisitor(functor)); - return functor; -} - -template -class BrushVisibleSelectedVisitor : public SelectionSystem::Visitor { -const Functor &m_functor; -public: -BrushVisibleSelectedVisitor(const Functor &functor) : m_functor(functor) -{ -} - -void visit(scene::Instance &instance) const -{ - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0 - && instance.path().top().get().visible()) { - m_functor(*brush); - } -} -}; - -template -inline const Functor &Scene_forEachVisibleSelectedBrush(const Functor &functor) -{ - GlobalSelectionSystem().foreachSelected(BrushVisibleSelectedVisitor(functor)); - return functor; -} - -class BrushForEachFace { -const BrushInstanceVisitor &m_visitor; -public: -BrushForEachFace(const BrushInstanceVisitor &visitor) : m_visitor(visitor) -{ -} - -void operator()(BrushInstance &brush) const -{ - brush.forEachFaceInstance(m_visitor); -} -}; - -template -class FaceInstanceVisitFace : public BrushInstanceVisitor { -const Functor &functor; -public: -FaceInstanceVisitFace(const Functor &functor) - : functor(functor) -{ -} - -void visit(FaceInstance &face) const -{ - functor(face.getFace()); -} -}; - -template -inline const Functor &Brush_forEachFace(BrushInstance &brush, const Functor &functor) -{ - brush.forEachFaceInstance(FaceInstanceVisitFace(functor)); - return functor; -} - -template -class FaceVisitAll : public BrushVisitor { -const Functor &functor; -public: -FaceVisitAll(const Functor &functor) - : functor(functor) -{ -} - -void visit(Face &face) const -{ - functor(face); -} -}; - -template -inline const Functor &Brush_forEachFace(const Brush &brush, const Functor &functor) -{ - brush.forEachFace(FaceVisitAll(functor)); - return functor; -} - -template -inline const Functor &Brush_forEachFace(Brush &brush, const Functor &functor) -{ - brush.forEachFace(FaceVisitAll(functor)); - return functor; -} - -template -class FaceInstanceVisitAll : public BrushInstanceVisitor { -const Functor &functor; -public: -FaceInstanceVisitAll(const Functor &functor) - : functor(functor) -{ -} - -void visit(FaceInstance &face) const -{ - functor(face); -} -}; - -template -inline const Functor &Brush_ForEachFaceInstance(BrushInstance &brush, const Functor &functor) -{ - brush.forEachFaceInstance(FaceInstanceVisitAll(functor)); - return functor; -} - -template -inline const Functor &Scene_forEachBrush(scene::Graph &graph, const Functor &functor) -{ - graph.traverse(InstanceWalker >(functor)); - return functor; -} - -template -class InstanceIfVisible : public Functor { -public: -InstanceIfVisible(const Functor &functor) : Functor(functor) -{ -} - -void operator()(scene::Instance &instance) -{ - if (instance.path().top().get().visible()) { - Functor::operator()(instance); - } -} -}; - -template -class BrushVisibleWalker : public scene::Graph::Walker { -const Functor &m_functor; -public: -BrushVisibleWalker(const Functor &functor) : m_functor(functor) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0) { - m_functor(*brush); - } - } - return true; -} -}; - -template -inline const Functor &Scene_forEachVisibleBrush(scene::Graph &graph, const Functor &functor) -{ - graph.traverse(BrushVisibleWalker(functor)); - return functor; -} - -template -inline const Functor &Scene_ForEachBrush_ForEachFace(scene::Graph &graph, const Functor &functor) -{ - Scene_forEachBrush(graph, BrushForEachFace(FaceInstanceVisitFace(functor))); - return functor; -} - -// d1223m -template -inline const Functor &Scene_ForEachBrush_ForEachFaceInstance(scene::Graph &graph, const Functor &functor) -{ - Scene_forEachBrush(graph, BrushForEachFace(FaceInstanceVisitAll(functor))); - return functor; -} - -template -inline const Functor &Scene_ForEachSelectedBrush_ForEachFace(scene::Graph &graph, const Functor &functor) -{ - Scene_forEachSelectedBrush(BrushForEachFace(FaceInstanceVisitFace(functor))); - return functor; -} - -template -inline const Functor &Scene_ForEachSelectedBrush_ForEachFaceInstance(scene::Graph &graph, const Functor &functor) -{ - Scene_forEachSelectedBrush(BrushForEachFace(FaceInstanceVisitAll(functor))); - return functor; -} - -template -class FaceVisitorWrapper { -const Functor &functor; -public: -FaceVisitorWrapper(const Functor &functor) : functor(functor) -{ -} - -void operator()(FaceInstance &faceInstance) const -{ - functor(faceInstance.getFace()); -} -}; - -template -inline const Functor &Scene_ForEachSelectedBrushFace(scene::Graph &graph, const Functor &functor) -{ - g_SelectedFaceInstances.foreach(FaceVisitorWrapper(functor)); - return functor; -} - - -#endif diff --git a/tools/vmap/brush_primit.c b/src/brush_primit.c similarity index 100% rename from tools/vmap/brush_primit.c rename to src/brush_primit.c diff --git a/src/brush_primit.cpp b/src/brush_primit.cpp deleted file mode 100644 index ca48f06..0000000 --- a/src/brush_primit.cpp +++ /dev/null @@ -1,1484 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brush_primit.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include "itexdef.h" -#include "itextures.h" - -#include - -#include "stringio.h" -#include "texturelib.h" -#include "math/matrix.h" -#include "math/plane.h" -#include "math/aabb.h" - -#include "winding.h" -#include "preferences.h" - - -/*! - \brief Construct a transform from XYZ space to ST space (3d to 2d). - This will be one of three axis-aligned spaces, depending on the surface normal. - NOTE: could also be done by swapping values. - */ -void Normal_GetTransform(const Vector3 &normal, Matrix4 &transform) -{ - switch (projectionaxis_for_normal(normal)) { - case eProjectionAxisZ: - transform[0] = 1; - transform[1] = 0; - transform[2] = 0; - - transform[4] = 0; - transform[5] = 1; - transform[6] = 0; - - transform[8] = 0; - transform[9] = 0; - transform[10] = 1; - break; - case eProjectionAxisY: - transform[0] = 1; - transform[1] = 0; - transform[2] = 0; - - transform[4] = 0; - transform[5] = 0; - transform[6] = -1; - - transform[8] = 0; - transform[9] = 1; - transform[10] = 0; - break; - case eProjectionAxisX: - transform[0] = 0; - transform[1] = 0; - transform[2] = 1; - - transform[4] = 1; - transform[5] = 0; - transform[6] = 0; - - transform[8] = 0; - transform[9] = 1; - transform[10] = 0; - break; - } - transform[3] = transform[7] = transform[11] = transform[12] = transform[13] = transform[14] = 0; - transform[15] = 1; -} - -/*! - \brief Construct a transform in ST space from the texdef. - Transforms constructed from quake's texdef format are (-shift)*(1/scale)*(-rotate) with x translation sign flipped. - This would really make more sense if it was inverseof(shift*rotate*scale).. oh well. - */ -inline void Texdef_toTransform(const texdef_t &texdef, float width, float height, Matrix4 &transform) -{ - double inverse_scale[2]; - - // transform to texdef shift/scale/rotate - inverse_scale[0] = 1 / (texdef.scale[0] * width); - inverse_scale[1] = 1 / (texdef.scale[1] * -height); - transform[12] = texdef.shift[0] / width; - transform[13] = -texdef.shift[1] / -height; - double c = cos(degrees_to_radians(-texdef.rotate)); - double s = sin(degrees_to_radians(-texdef.rotate)); - transform[0] = static_cast( c * inverse_scale[0] ); - transform[1] = static_cast( s * inverse_scale[1] ); - transform[4] = static_cast( -s * inverse_scale[0] ); - transform[5] = static_cast( c * inverse_scale[1] ); - transform[2] = transform[3] = transform[6] = transform[7] = transform[8] = transform[9] = transform[11] = transform[14] = 0; - transform[10] = transform[15] = 1; -} - -inline void BPTexdef_toTransform(const brushprimit_texdef_t &bp_texdef, Matrix4 &transform) -{ - transform = g_matrix4_identity; - transform.xx() = bp_texdef.coords[0][0]; - transform.yx() = bp_texdef.coords[0][1]; - transform.tx() = bp_texdef.coords[0][2]; - transform.xy() = bp_texdef.coords[1][0]; - transform.yy() = bp_texdef.coords[1][1]; - transform.ty() = bp_texdef.coords[1][2]; -} - -inline void Texdef_toTransform(const TextureProjection &projection, float width, float height, Matrix4 &transform) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_toTransform(projection.m_brushprimit_texdef, transform); - } else { - Texdef_toTransform(projection.m_texdef, width, height, transform); - } -} - -// handles degenerate cases, just in case library atan2 doesn't -inline double arctangent_yx(double y, double x) -{ - if (fabs(x) > 1.0E-6) { - return atan2(y, x); - } else if (y > 0) { - return c_half_pi; - } else { - return -c_half_pi; - } -} - -inline void Texdef_fromTransform(texdef_t &texdef, float width, float height, const Matrix4 &transform) -{ - texdef.scale[0] = static_cast((1.0 / vector2_length(Vector2(transform[0], transform[4]))) / width ); - texdef.scale[1] = static_cast((1.0 / vector2_length(Vector2(transform[1], transform[5]))) / height ); - - texdef.rotate = static_cast( -radians_to_degrees(arctangent_yx(-transform[4], transform[0]))); - - if (texdef.rotate == -180.0f) { - texdef.rotate = 180.0f; - } - - texdef.shift[0] = transform[12] * width; - texdef.shift[1] = transform[13] * height; - - // If the 2d cross-product of the x and y axes is positive, one of the axes has a negative scale. - if (vector2_cross(Vector2(transform[0], transform[4]), Vector2(transform[1], transform[5])) > 0) { - if (texdef.rotate >= 180.0f) { - texdef.rotate -= 180.0f; - texdef.scale[0] = -texdef.scale[0]; - } else { - texdef.scale[1] = -texdef.scale[1]; - } - } - //globalOutputStream() << "fromTransform: " << texdef.shift[0] << " " << texdef.shift[1] << " " << texdef.scale[0] << " " << texdef.scale[1] << " " << texdef.rotate << "\n"; -} - -inline void BPTexdef_fromTransform(brushprimit_texdef_t &bp_texdef, const Matrix4 &transform) -{ - bp_texdef.coords[0][0] = transform.xx(); - bp_texdef.coords[0][1] = transform.yx(); - bp_texdef.coords[0][2] = transform.tx(); - bp_texdef.coords[1][0] = transform.xy(); - bp_texdef.coords[1][1] = transform.yy(); - bp_texdef.coords[1][2] = transform.ty(); -} - -inline void Texdef_fromTransform(TextureProjection &projection, float width, float height, const Matrix4 &transform) -{ - ASSERT_MESSAGE((transform[0] != 0 || transform[4] != 0) - && (transform[1] != 0 || transform[5] != 0), "invalid texture matrix"); - - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_fromTransform(projection.m_brushprimit_texdef, transform); - } else { - Texdef_fromTransform(projection.m_texdef, width, height, transform); - } -} - -inline void Texdef_normalise(texdef_t &texdef, float width, float height) -{ - // it may be useful to also normalise the rotation here, if this function is used elsewhere. - texdef.shift[0] = float_mod(texdef.shift[0], width); - texdef.shift[1] = float_mod(texdef.shift[1], height); - //globalOutputStream() << "normalise: " << texdef.shift[0] << " " << texdef.shift[1] << " " << texdef.scale[0] << " " << texdef.scale[1] << " " << texdef.rotate << "\n"; -} - -inline void BPTexdef_normalise(brushprimit_texdef_t &bp_texdef, float width, float height) -{ - bp_texdef.coords[0][2] = float_mod(bp_texdef.coords[0][2], width); - bp_texdef.coords[1][2] = float_mod(bp_texdef.coords[1][2], height); -} - -/// \brief Normalise \p projection for a given texture \p width and \p height. -/// -/// All texture-projection translation (shift) values are congruent modulo the dimensions of the texture. -/// This function normalises shift values to the smallest positive congruent values. -void Texdef_normalise(TextureProjection &projection, float width, float height) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_normalise(projection.m_brushprimit_texdef, width, height); - } else { - Texdef_normalise(projection.m_texdef, width, height); - } -} - -void ComputeAxisBase(const Vector3 &normal, Vector3 &texS, Vector3 &texT); - -inline void DebugAxisBase(const Vector3 &normal) -{ - Vector3 x, y; - ComputeAxisBase(normal, x, y); - globalOutputStream() << "BP debug: " << x << y << normal << "\n"; -} - -void Texdef_basisForNormal(const TextureProjection &projection, const Vector3 &normal, Matrix4 &basis) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - basis = g_matrix4_identity; - ComputeAxisBase(normal, vector4_to_vector3(basis.x()), vector4_to_vector3(basis.y())); - vector4_to_vector3(basis.z()) = normal; - matrix4_transpose(basis); - //DebugAxisBase(normal); - } else if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_HALFLIFE) { - basis = g_matrix4_identity; - vector4_to_vector3(basis.x()) = projection.m_basis_s; - vector4_to_vector3(basis.y()) = vector3_negated(projection.m_basis_t); - vector4_to_vector3(basis.z()) = vector3_normalised( - vector3_cross(vector4_to_vector3(basis.x()), vector4_to_vector3(basis.y()))); - matrix4_multiply_by_matrix4(basis, matrix4_rotation_for_z_degrees(-projection.m_texdef.rotate)); - //globalOutputStream() << "debug: " << projection.m_basis_s << projection.m_basis_t << normal << "\n"; - matrix4_transpose(basis); - } else { - Normal_GetTransform(normal, basis); - } -} - -void -Texdef_EmitTextureCoordinates(const TextureProjection &projection, std::size_t width, std::size_t height, Winding &w, - const Vector3 &normal, const Matrix4 &localToWorld) -{ - if (w.numpoints < 3) { - return; - } - //globalOutputStream() << "normal: " << normal << "\n"; - - Matrix4 local2tex; - Texdef_toTransform(projection, (float) width, (float) height, local2tex); - //globalOutputStream() << "texdef: " << static_cast(local2tex.x()) << static_cast(local2tex.y()) << "\n"; - -#if 0 - { - TextureProjection tmp; - Texdef_fromTransform( tmp, (float)width, (float)height, local2tex ); - Matrix4 tmpTransform; - Texdef_toTransform( tmp, (float)width, (float)height, tmpTransform ); - ASSERT_MESSAGE( matrix4_equal_epsilon( local2tex, tmpTransform, 0.0001f ), "bleh" ); - } -#endif - - { - Matrix4 xyz2st; - // we don't care if it's not normalised... - Texdef_basisForNormal(projection, matrix4_transformed_direction(localToWorld, normal), xyz2st); - //globalOutputStream() << "basis: " << static_cast(xyz2st.x()) << static_cast(xyz2st.y()) << static_cast(xyz2st.z()) << "\n"; - matrix4_multiply_by_matrix4(local2tex, xyz2st); - } - - Vector3 tangent(vector3_normalised(vector4_to_vector3(matrix4_transposed(local2tex).x()))); - Vector3 bitangent(vector3_normalised(vector4_to_vector3(matrix4_transposed(local2tex).y()))); - - matrix4_multiply_by_matrix4(local2tex, localToWorld); - - for (Winding::iterator i = w.begin(); i != w.end(); ++i) { - Vector3 texcoord = matrix4_transformed_point(local2tex, (*i).vertex); - (*i).texcoord[0] = texcoord[0]; - (*i).texcoord[1] = texcoord[1]; - - (*i).tangent = tangent; - (*i).bitangent = bitangent; - } -} - -/*! - \brief Provides the axis-base of the texture ST space for this normal, - as they had been transformed to world XYZ space. - */ -void TextureAxisFromNormal(const Vector3 &normal, Vector3 &s, Vector3 &t) -{ - switch (projectionaxis_for_normal(normal)) { - case eProjectionAxisZ: - s[0] = 1; - s[1] = 0; - s[2] = 0; - - t[0] = 0; - t[1] = -1; - t[2] = 0; - - break; - case eProjectionAxisY: - s[0] = 1; - s[1] = 0; - s[2] = 0; - - t[0] = 0; - t[1] = 0; - t[2] = -1; - - break; - case eProjectionAxisX: - s[0] = 0; - s[1] = 1; - s[2] = 0; - - t[0] = 0; - t[1] = 0; - t[2] = -1; - - break; - } -} - -void Texdef_Assign(texdef_t &td, const texdef_t &other) -{ - td = other; -} - -void Texdef_Shift(texdef_t &td, float s, float t) -{ - td.shift[0] += s; - td.shift[1] += t; -} - -void Texdef_Scale(texdef_t &td, float s, float t) -{ - td.scale[0] += s; - td.scale[1] += t; -} - -void Texdef_Rotate(texdef_t &td, float angle) -{ - td.rotate += angle; - td.rotate = static_cast( float_to_integer(td.rotate) % 360 ); -} - -// NOTE: added these from Ritual's Q3Radiant -void ClearBounds(Vector3 &mins, Vector3 &maxs) -{ - mins[0] = mins[1] = mins[2] = 99999; - maxs[0] = maxs[1] = maxs[2] = -99999; -} - -void AddPointToBounds(const Vector3 &v, Vector3 &mins, Vector3 &maxs) -{ - int i; - float val; - - for (i = 0; i < 3; i++) { - val = v[i]; - if (val < mins[i]) { - mins[i] = val; - } - if (val > maxs[i]) { - maxs[i] = val; - } - } -} - -template -inline BasicVector3 vector3_inverse(const BasicVector3 &self) -{ - return BasicVector3( - Element(1.0 / self.x()), - Element(1.0 / self.y()), - Element(1.0 / self.z()) - ); -} - -// low level functions .. put in mathlib? -#define BPMatCopy(a, b) {b[0][0] = a[0][0]; b[0][1] = a[0][1]; b[0][2] = a[0][2]; b[1][0] = a[1][0]; b[1][1] = a[1][1]; b[1][2] = a[1][2]; } -// apply a scale transformation to the BP matrix -#define BPMatScale(m, sS, sT) {m[0][0] *= sS; m[1][0] *= sS; m[0][1] *= sT; m[1][1] *= sT; } -// apply a translation transformation to a BP matrix -#define BPMatTranslate(m, s, t) {m[0][2] += m[0][0] * s + m[0][1] * t; m[1][2] += m[1][0] * s + m[1][1] * t; } - -// 2D homogeneous matrix product C = A*B -void BPMatMul(float A[2][3], float B[2][3], float C[2][3]); - -// apply a rotation (degrees) -void BPMatRotate(float A[2][3], float theta); - -#if GDEF_DEBUG - -void BPMatDump(float A[2][3]); - -#endif - -#if GDEF_DEBUG -//#define DBG_BP -#endif - - -bp_globals_t g_bp_globals; -float g_texdef_default_scale; - -// compute a determinant using Sarrus rule -//++timo "inline" this with a macro -// NOTE : the three vectors are understood as columns of the matrix -inline float SarrusDet(const Vector3 &a, const Vector3 &b, const Vector3 &c) -{ - return a[0] * b[1] * c[2] + b[0] * c[1] * a[2] + c[0] * a[1] * b[2] - - c[0] * b[1] * a[2] - a[1] * b[0] * c[2] - a[0] * b[2] * c[1]; -} - -// in many case we know three points A,B,C in two axis base B1 and B2 -// and we want the matrix M so that A(B1) = T * A(B2) -// NOTE: 2D homogeneous space stuff -// NOTE: we don't do any check to see if there's a solution or we have a particular case .. need to make sure before calling -// NOTE: the third coord of the A,B,C point is ignored -// NOTE: see the commented out section to fill M and D -//++timo TODO: update the other members to use this when possible -void MatrixForPoints(Vector3 M[3], Vector3 D[2], brushprimit_texdef_t *T) -{ -// Vector3 M[3]; // columns of the matrix .. easier that way (the indexing is not standard! it's column-line .. later computations are easier that way) - float det; -// Vector3 D[2]; - M[2][0] = 1.0f; - M[2][1] = 1.0f; - M[2][2] = 1.0f; -#if 0 - // fill the data vectors - M[0][0] = A2[0]; M[0][1] = B2[0]; M[0][2] = C2[0]; - M[1][0] = A2[1]; M[1][1] = B2[1]; M[1][2] = C2[1]; - M[2][0] = 1.0f; M[2][1] = 1.0f; M[2][2] = 1.0f; - D[0][0] = A1[0]; - D[0][1] = B1[0]; - D[0][2] = C1[0]; - D[1][0] = A1[1]; - D[1][1] = B1[1]; - D[1][2] = C1[1]; -#endif - // solve - det = SarrusDet(M[0], M[1], M[2]); - T->coords[0][0] = SarrusDet(D[0], M[1], M[2]) / det; - T->coords[0][1] = SarrusDet(M[0], D[0], M[2]) / det; - T->coords[0][2] = SarrusDet(M[0], M[1], D[0]) / det; - T->coords[1][0] = SarrusDet(D[1], M[1], M[2]) / det; - T->coords[1][1] = SarrusDet(M[0], D[1], M[2]) / det; - T->coords[1][2] = SarrusDet(M[0], M[1], D[1]) / det; -} - -//++timo replace everywhere texX by texS etc. ( ----> and in q3map !) -// NOTE : ComputeAxisBase here and in q3map code must always BE THE SAME ! -// WARNING : special case behaviour of atan2(y,x) <-> atan(y/x) might not be the same everywhere when x == 0 -// rotation by (0,RotY,RotZ) assigns X to normal -void ComputeAxisBase(const Vector3 &normal, Vector3 &texS, Vector3 &texT) -{ -#if 1 - const Vector3 up(0, 0, 1); - const Vector3 down(0, 0, -1); - - if (vector3_equal_epsilon(normal, up, float(1e-6))) { - texS = Vector3(0, 1, 0); - texT = Vector3(1, 0, 0); - } else if (vector3_equal_epsilon(normal, down, float(1e-6))) { - texS = Vector3(0, 1, 0); - texT = Vector3(-1, 0, 0); - } else { - texS = vector3_normalised(vector3_cross(normal, up)); - texT = vector3_normalised(vector3_cross(normal, texS)); - vector3_negate(texS); - } - -#else - float RotY,RotZ; - // do some cleaning - /* - if (fabs(normal[0])<1e-6) - normal[0]=0.0f; - if (fabs(normal[1])<1e-6) - normal[1]=0.0f; - if (fabs(normal[2])<1e-6) - normal[2]=0.0f; - */ - RotY = -atan2( normal[2],sqrt( normal[1] * normal[1] + normal[0] * normal[0] ) ); - RotZ = atan2( normal[1],normal[0] ); - // rotate (0,1,0) and (0,0,1) to compute texS and texT - texS[0] = -sin( RotZ ); - texS[1] = cos( RotZ ); - texS[2] = 0; - // the texT vector is along -Z ( T texture coorinates axis ) - texT[0] = -sin( RotY ) * cos( RotZ ); - texT[1] = -sin( RotY ) * sin( RotZ ); - texT[2] = -cos( RotY ); -#endif -} - -#if 0 // texdef conversion -void FaceToBrushPrimitFace( face_t *f ){ - Vector3 texX,texY; - Vector3 proj; - // ST of (0,0) (1,0) (0,1) - float ST[3][5]; // [ point index ] [ xyz ST ] - //++timo not used as long as brushprimit_texdef and texdef are static -/* f->brushprimit_texdef.contents=f->texdef.contents; - f->brushprimit_texdef.flags=f->texdef.flags; - f->brushprimit_texdef.value=f->texdef.value; - strcpy(f->brushprimit_texdef.name,f->texdef.name); */ -#ifdef DBG_BP - if ( f->plane.normal[0] == 0.0f && f->plane.normal[1] == 0.0f && f->plane.normal[2] == 0.0f ) { - globalOutputStream() << "Warning : f->plane.normal is (0,0,0) in FaceToBrushPrimitFace\n"; - } - // check d_texture - if ( !f->d_texture ) { - globalOutputStream() << "Warning : f.d_texture is 0 in FaceToBrushPrimitFace\n"; - return; - } -#endif - // compute axis base - ComputeAxisBase( f->plane.normal,texX,texY ); - // compute projection vector - VectorCopy( f->plane.normal,proj ); - VectorScale( proj,f->plane.dist,proj ); - // (0,0) in plane axis base is (0,0,0) in world coordinates + projection on the affine plane - // (1,0) in plane axis base is texX in world coordinates + projection on the affine plane - // (0,1) in plane axis base is texY in world coordinates + projection on the affine plane - // use old texture code to compute the ST coords of these points - VectorCopy( proj,ST[0] ); - EmitTextureCoordinates( ST[0], f->pShader->getTexture(), f ); - VectorCopy( texX,ST[1] ); - VectorAdd( ST[1],proj,ST[1] ); - EmitTextureCoordinates( ST[1], f->pShader->getTexture(), f ); - VectorCopy( texY,ST[2] ); - VectorAdd( ST[2],proj,ST[2] ); - EmitTextureCoordinates( ST[2], f->pShader->getTexture(), f ); - // compute texture matrix - f->brushprimit_texdef.coords[0][2] = ST[0][3]; - f->brushprimit_texdef.coords[1][2] = ST[0][4]; - f->brushprimit_texdef.coords[0][0] = ST[1][3] - f->brushprimit_texdef.coords[0][2]; - f->brushprimit_texdef.coords[1][0] = ST[1][4] - f->brushprimit_texdef.coords[1][2]; - f->brushprimit_texdef.coords[0][1] = ST[2][3] - f->brushprimit_texdef.coords[0][2]; - f->brushprimit_texdef.coords[1][1] = ST[2][4] - f->brushprimit_texdef.coords[1][2]; -} - -// compute texture coordinates for the winding points -void EmitBrushPrimitTextureCoordinates( face_t * f, Winding * w ){ - Vector3 texX,texY; - float x,y; - // compute axis base - ComputeAxisBase( f->plane.normal,texX,texY ); - // in case the texcoords matrix is empty, build a default one - // same behaviour as if scale[0]==0 && scale[1]==0 in old code - if ( f->brushprimit_texdef.coords[0][0] == 0 && f->brushprimit_texdef.coords[1][0] == 0 && f->brushprimit_texdef.coords[0][1] == 0 && f->brushprimit_texdef.coords[1][1] == 0 ) { - f->brushprimit_texdef.coords[0][0] = 1.0f; - f->brushprimit_texdef.coords[1][1] = 1.0f; - ConvertTexMatWithQTexture( &f->brushprimit_texdef, 0, &f->brushprimit_texdef, f->pShader->getTexture() ); - } - int i; - for ( i = 0; i < w.numpoints; i++ ) - { - x = vector3_dot( w.point_at( i ),texX ); - y = vector3_dot( w.point_at( i ),texY ); -#if 0 -#ifdef DBG_BP - if ( g_bp_globals.bNeedConvert ) { - // check we compute the same ST as the traditional texture computation used before - float S = f->brushprimit_texdef.coords[0][0] * x + f->brushprimit_texdef.coords[0][1] * y + f->brushprimit_texdef.coords[0][2]; - float T = f->brushprimit_texdef.coords[1][0] * x + f->brushprimit_texdef.coords[1][1] * y + f->brushprimit_texdef.coords[1][2]; - if ( fabs( S - w.point_at( i )[3] ) > 1e-2 || fabs( T - w.point_at( i )[4] ) > 1e-2 ) { - if ( fabs( S - w.point_at( i )[3] ) > 1e-4 || fabs( T - w.point_at( i )[4] ) > 1e-4 ) { - globalOutputStream() << "Warning : precision loss in brush -> brush primitive texture computation\n"; - } - else{ - globalOutputStream() << "Warning : brush -> brush primitive texture computation bug detected\n"; - } - } - } -#endif -#endif - w.point_at( i )[3] = f->brushprimit_texdef.coords[0][0] * x + f->brushprimit_texdef.coords[0][1] * y + f->brushprimit_texdef.coords[0][2]; - w.point_at( i )[4] = f->brushprimit_texdef.coords[1][0] * x + f->brushprimit_texdef.coords[1][1] * y + f->brushprimit_texdef.coords[1][2]; - } -} -#endif - -typedef float texmat_t[2][3]; - -void TexMat_Scale(texmat_t texmat, float s, float t) -{ - texmat[0][0] *= s; - texmat[0][1] *= s; - texmat[0][2] *= s; - texmat[1][0] *= t; - texmat[1][1] *= t; - texmat[1][2] *= t; -} - -void TexMat_Assign(texmat_t texmat, const texmat_t other) -{ - texmat[0][0] = other[0][0]; - texmat[0][1] = other[0][1]; - texmat[0][2] = other[0][2]; - texmat[1][0] = other[1][0]; - texmat[1][1] = other[1][1]; - texmat[1][2] = other[1][2]; -} - -void ConvertTexMatWithDimensions(const texmat_t texmat1, std::size_t w1, std::size_t h1, - texmat_t texmat2, std::size_t w2, std::size_t h2) -{ - TexMat_Assign(texmat2, texmat1); - TexMat_Scale(texmat2, static_cast( w1 ) / static_cast( w2 ), - static_cast( h1 ) / static_cast( h2 )); -} - -#if 0 -// convert a texture matrix between two qtexture_t -// if 0 for qtexture_t, basic 2x2 texture is assumed ( straight mapping between s/t coordinates and geometric coordinates ) -void ConvertTexMatWithQTexture( const float texMat1[2][3], const qtexture_t *qtex1, float texMat2[2][3], const qtexture_t *qtex2 ){ - ConvertTexMatWithDimensions( texMat1, ( qtex1 ) ? qtex1->width : 2, ( qtex1 ) ? qtex1->height : 2, - texMat2, ( qtex2 ) ? qtex2->width : 2, ( qtex2 ) ? qtex2->height : 2 ); -} - -void ConvertTexMatWithQTexture( const brushprimit_texdef_t *texMat1, const qtexture_t *qtex1, brushprimit_texdef_t *texMat2, const qtexture_t *qtex2 ){ - ConvertTexMatWithQTexture( texMat1->coords, qtex1, texMat2->coords, qtex2 ); -} -#endif - -// compute a fake shift scale rot representation from the texture matrix -// these shift scale rot values are to be understood in the local axis base -// Note: this code looks similar to Texdef_fromTransform, but the algorithm is slightly different. - -void TexMatToFakeTexCoords(const brushprimit_texdef_t &bp_texdef, texdef_t &texdef) -{ - texdef.scale[0] = static_cast( 1.0 / - vector2_length(Vector2(bp_texdef.coords[0][0], bp_texdef.coords[1][0]))); - texdef.scale[1] = static_cast( 1.0 / - vector2_length(Vector2(bp_texdef.coords[0][1], bp_texdef.coords[1][1]))); - - texdef.rotate = -static_cast( radians_to_degrees( - arctangent_yx(bp_texdef.coords[1][0], bp_texdef.coords[0][0]))); - - texdef.shift[0] = -bp_texdef.coords[0][2]; - texdef.shift[1] = bp_texdef.coords[1][2]; - - // determine whether or not an axis is flipped using a 2d cross-product - double cross = vector2_cross(Vector2(bp_texdef.coords[0][0], bp_texdef.coords[0][1]), - Vector2(bp_texdef.coords[1][0], bp_texdef.coords[1][1])); - if (cross < 0) { - // This is a bit of a compromise when using BPs--since we don't know *which* axis was flipped, - // we pick one (rather arbitrarily) using the following convention: If the X-axis is between - // 0 and 180, we assume it's the Y-axis that flipped, otherwise we assume it's the X-axis and - // subtract out 180 degrees to compensate. - if (texdef.rotate >= 180.0f) { - texdef.rotate -= 180.0f; - texdef.scale[0] = -texdef.scale[0]; - } else { - texdef.scale[1] = -texdef.scale[1]; - } - } -} - -// compute back the texture matrix from fake shift scale rot -void FakeTexCoordsToTexMat(const texdef_t &texdef, brushprimit_texdef_t &bp_texdef) -{ - double r = degrees_to_radians(-texdef.rotate); - double c = cos(r); - double s = sin(r); - double x = 1.0f / texdef.scale[0]; - double y = 1.0f / texdef.scale[1]; - bp_texdef.coords[0][0] = static_cast( x * c ); - bp_texdef.coords[1][0] = static_cast( x * s ); - bp_texdef.coords[0][1] = static_cast( y * -s ); - bp_texdef.coords[1][1] = static_cast( y * c ); - bp_texdef.coords[0][2] = -texdef.shift[0]; - bp_texdef.coords[1][2] = texdef.shift[1]; -} - -#if 0 // texture locking (brush primit) -// used for texture locking -// will move the texture according to a geometric vector -void ShiftTextureGeometric_BrushPrimit( face_t *f, Vector3& delta ){ - Vector3 texS,texT; - float tx,ty; - Vector3 M[3]; // columns of the matrix .. easier that way - float det; - Vector3 D[2]; - // compute plane axis base ( doesn't change with translation ) - ComputeAxisBase( f->plane.normal, texS, texT ); - // compute translation vector in plane axis base - tx = vector3_dot( delta, texS ); - ty = vector3_dot( delta, texT ); - // fill the data vectors - M[0][0] = tx; M[0][1] = 1.0f + tx; M[0][2] = tx; - M[1][0] = ty; M[1][1] = ty; M[1][2] = 1.0f + ty; - M[2][0] = 1.0f; M[2][1] = 1.0f; M[2][2] = 1.0f; - D[0][0] = f->brushprimit_texdef.coords[0][2]; - D[0][1] = f->brushprimit_texdef.coords[0][0] + f->brushprimit_texdef.coords[0][2]; - D[0][2] = f->brushprimit_texdef.coords[0][1] + f->brushprimit_texdef.coords[0][2]; - D[1][0] = f->brushprimit_texdef.coords[1][2]; - D[1][1] = f->brushprimit_texdef.coords[1][0] + f->brushprimit_texdef.coords[1][2]; - D[1][2] = f->brushprimit_texdef.coords[1][1] + f->brushprimit_texdef.coords[1][2]; - // solve - det = SarrusDet( M[0], M[1], M[2] ); - f->brushprimit_texdef.coords[0][0] = SarrusDet( D[0], M[1], M[2] ) / det; - f->brushprimit_texdef.coords[0][1] = SarrusDet( M[0], D[0], M[2] ) / det; - f->brushprimit_texdef.coords[0][2] = SarrusDet( M[0], M[1], D[0] ) / det; - f->brushprimit_texdef.coords[1][0] = SarrusDet( D[1], M[1], M[2] ) / det; - f->brushprimit_texdef.coords[1][1] = SarrusDet( M[0], D[1], M[2] ) / det; - f->brushprimit_texdef.coords[1][2] = SarrusDet( M[0], M[1], D[1] ) / det; -} - -// shift a texture (texture adjustments) along it's current texture axes -// x and y are geometric values, which we must compute as ST increments -// this depends on the texture size and the pixel/texel ratio -void ShiftTextureRelative_BrushPrimit( face_t *f, float x, float y ){ - float s,t; - // as a ratio against texture size - // the scale of the texture is not relevant here (we work directly on a transformation from the base vectors) - s = ( x * 2.0 ) / (float)f->pShader->getTexture().width; - t = ( y * 2.0 ) / (float)f->pShader->getTexture().height; - f->brushprimit_texdef.coords[0][2] -= s; - f->brushprimit_texdef.coords[1][2] -= t; -} -#endif - -// TTimo: FIXME: I don't like that, it feels broken -// (and it's likely that it's not used anymore) -// best fitted 2D vector is x.X+y.Y -void ComputeBest2DVector(Vector3 &v, Vector3 &X, Vector3 &Y, int &x, int &y) -{ - double sx, sy; - sx = vector3_dot(v, X); - sy = vector3_dot(v, Y); - if (fabs(sy) > fabs(sx)) { - x = 0; - if (sy > 0.0) { - y = 1; - } else { - y = -1; - } - } else { - y = 0; - if (sx > 0.0) { - x = 1; - } else { - x = -1; - } - } -} - - -#if 0 // texdef conversion -void BrushPrimitFaceToFace( face_t *face ){ - // we have parsed brush primitives and need conversion back to standard format - // NOTE: converting back is a quick hack, there's some information lost and we can't do anything about it - // FIXME: if we normalize the texture matrix to a standard 2x2 size, we end up with wrong scaling - // I tried various tweaks, no luck .. seems shifting is lost - brushprimit_texdef_t aux; - ConvertTexMatWithQTexture( &face->brushprimit_texdef, face->pShader->getTexture(), &aux, 0 ); - TexMatToFakeTexCoords( aux.coords, face->texdef.shift, &face->texdef.rotate, face->texdef.scale ); - face->texdef.scale[0] /= 2.0; - face->texdef.scale[1] /= 2.0; -} -#endif - - -#if 0 // texture locking (brush primit) -// TEXTURE LOCKING ----------------------------------------------------------------------------------------------------- -// (Relevant to the editor only?) - -// internally used for texture locking on rotation and flipping -// the general algorithm is the same for both lockings, it's only the geometric transformation part that changes -// so I wanted to keep it in a single function -// if there are more linear transformations that need the locking, going to a C++ or code pointer solution would be best -// (but right now I want to keep brush_primit.cpp striclty C) - -bool txlock_bRotation; - -// rotation locking params -int txl_nAxis; -float txl_fDeg; -Vector3 txl_vOrigin; - -// flip locking params -Vector3 txl_matrix[3]; -Vector3 txl_origin; - -void TextureLockTransformation_BrushPrimit( face_t *f ){ - Vector3 Orig,texS,texT; // axis base of initial plane - // used by transformation algo - Vector3 temp; int j; - Vector3 vRotate; // rotation vector - - Vector3 rOrig,rvecS,rvecT; // geometric transformation of (0,0) (1,0) (0,1) { initial plane axis base } - Vector3 rNormal,rtexS,rtexT; // axis base for the transformed plane - Vector3 lOrig,lvecS,lvecT; // [2] are not used ( but usefull for debugging ) - Vector3 M[3]; - float det; - Vector3 D[2]; - - // compute plane axis base - ComputeAxisBase( f->plane.normal, texS, texT ); - VectorSet( Orig, 0.0f, 0.0f, 0.0f ); - - // compute coordinates of (0,0) (1,0) (0,1) ( expressed in initial plane axis base ) after transformation - // (0,0) (1,0) (0,1) ( expressed in initial plane axis base ) <-> (0,0,0) texS texT ( expressed world axis base ) - // input: Orig, texS, texT (and the global locking params) - // ouput: rOrig, rvecS, rvecT, rNormal - if ( txlock_bRotation ) { - // rotation vector - VectorSet( vRotate, 0.0f, 0.0f, 0.0f ); - vRotate[txl_nAxis] = txl_fDeg; - VectorRotateOrigin( Orig, vRotate, txl_vOrigin, rOrig ); - VectorRotateOrigin( texS, vRotate, txl_vOrigin, rvecS ); - VectorRotateOrigin( texT, vRotate, txl_vOrigin, rvecT ); - // compute normal of plane after rotation - VectorRotate( f->plane.normal, vRotate, rNormal ); - } - else - { - for ( j = 0; j < 3; j++ ) - rOrig[j] = vector3_dot( vector3_subtracted( Orig, txl_origin ), txl_matrix[j] ) + txl_origin[j]; - for ( j = 0; j < 3; j++ ) - rvecS[j] = vector3_dot( vector3_subtracted( texS, txl_origin ), txl_matrix[j] ) + txl_origin[j]; - for ( j = 0; j < 3; j++ ) - rvecT[j] = vector3_dot( vector3_subtracted( texT, txl_origin ), txl_matrix[j] ) + txl_origin[j]; - // we also need the axis base of the target plane, apply the transformation matrix to the normal too.. - for ( j = 0; j < 3; j++ ) - rNormal[j] = vector3_dot( f->plane.normal, txl_matrix[j] ); - } - - // compute rotated plane axis base - ComputeAxisBase( rNormal, rtexS, rtexT ); - // compute S/T coordinates of the three points in rotated axis base ( in M matrix ) - lOrig[0] = vector3_dot( rOrig, rtexS ); - lOrig[1] = vector3_dot( rOrig, rtexT ); - lvecS[0] = vector3_dot( rvecS, rtexS ); - lvecS[1] = vector3_dot( rvecS, rtexT ); - lvecT[0] = vector3_dot( rvecT, rtexS ); - lvecT[1] = vector3_dot( rvecT, rtexT ); - M[0][0] = lOrig[0]; M[1][0] = lOrig[1]; M[2][0] = 1.0f; - M[0][1] = lvecS[0]; M[1][1] = lvecS[1]; M[2][1] = 1.0f; - M[0][2] = lvecT[0]; M[1][2] = lvecT[1]; M[2][2] = 1.0f; - // fill data vector - D[0][0] = f->brushprimit_texdef.coords[0][2]; - D[0][1] = f->brushprimit_texdef.coords[0][0] + f->brushprimit_texdef.coords[0][2]; - D[0][2] = f->brushprimit_texdef.coords[0][1] + f->brushprimit_texdef.coords[0][2]; - D[1][0] = f->brushprimit_texdef.coords[1][2]; - D[1][1] = f->brushprimit_texdef.coords[1][0] + f->brushprimit_texdef.coords[1][2]; - D[1][2] = f->brushprimit_texdef.coords[1][1] + f->brushprimit_texdef.coords[1][2]; - // solve - det = SarrusDet( M[0], M[1], M[2] ); - f->brushprimit_texdef.coords[0][0] = SarrusDet( D[0], M[1], M[2] ) / det; - f->brushprimit_texdef.coords[0][1] = SarrusDet( M[0], D[0], M[2] ) / det; - f->brushprimit_texdef.coords[0][2] = SarrusDet( M[0], M[1], D[0] ) / det; - f->brushprimit_texdef.coords[1][0] = SarrusDet( D[1], M[1], M[2] ) / det; - f->brushprimit_texdef.coords[1][1] = SarrusDet( M[0], D[1], M[2] ) / det; - f->brushprimit_texdef.coords[1][2] = SarrusDet( M[0], M[1], D[1] ) / det; -} - -// texture locking -// called before the points on the face are actually rotated -void RotateFaceTexture_BrushPrimit( face_t *f, int nAxis, float fDeg, Vector3& vOrigin ){ - // this is a placeholder to call the general texture locking algorithm - txlock_bRotation = true; - txl_nAxis = nAxis; - txl_fDeg = fDeg; - VectorCopy( vOrigin, txl_vOrigin ); - TextureLockTransformation_BrushPrimit( f ); -} - -// compute the new brush primit texture matrix for a transformation matrix and a flip order flag (change plane orientation) -// this matches the select_matrix algo used in select.cpp -// this needs to be called on the face BEFORE any geometric transformation -// it will compute the texture matrix that will represent the same texture on the face after the geometric transformation is done -void ApplyMatrix_BrushPrimit( face_t *f, Vector3 matrix[3], Vector3& origin ){ - // this is a placeholder to call the general texture locking algorithm - txlock_bRotation = false; - VectorCopy( matrix[0], txl_matrix[0] ); - VectorCopy( matrix[1], txl_matrix[1] ); - VectorCopy( matrix[2], txl_matrix[2] ); - VectorCopy( origin, txl_origin ); - TextureLockTransformation_BrushPrimit( f ); -} -#endif - -// don't do C==A! -void BPMatMul(float A[2][3], float B[2][3], float C[2][3]) -{ - C[0][0] = A[0][0] * B[0][0] + A[0][1] * B[1][0]; - C[1][0] = A[1][0] * B[0][0] + A[1][1] * B[1][0]; - C[0][1] = A[0][0] * B[0][1] + A[0][1] * B[1][1]; - C[1][1] = A[1][0] * B[0][1] + A[1][1] * B[1][1]; - C[0][2] = A[0][0] * B[0][2] + A[0][1] * B[1][2] + A[0][2]; - C[1][2] = A[1][0] * B[0][2] + A[1][1] * B[1][2] + A[1][2]; -} - -void BPMatDump(float A[2][3]) -{ - globalOutputStream() << "" << A[0][0] - << " " << A[0][1] - << " " << A[0][2] - << "\n" << A[1][0] - << " " << A[1][2] - << " " << A[1][2] - << "\n0 0 1\n"; -} - -void BPMatRotate(float A[2][3], float theta) -{ - float m[2][3]; - float aux[2][3]; - memset(&m, 0, sizeof(float) * 6); - m[0][0] = static_cast( cos(degrees_to_radians(theta))); - m[0][1] = static_cast( -sin(degrees_to_radians(theta))); - m[1][0] = -m[0][1]; - m[1][1] = m[0][0]; - BPMatMul(A, m, aux); - BPMatCopy(aux, A); -} - -#if 0 // camera-relative texture shift -// get the relative axes of the current texturing -void BrushPrimit_GetRelativeAxes( face_t *f, Vector3& vecS, Vector3& vecT ){ - float vS[2],vT[2]; - // first we compute them as expressed in plane axis base - // BP matrix has coordinates of plane axis base expressed in geometric axis base - // so we use the line vectors - vS[0] = f->brushprimit_texdef.coords[0][0]; - vS[1] = f->brushprimit_texdef.coords[0][1]; - vT[0] = f->brushprimit_texdef.coords[1][0]; - vT[1] = f->brushprimit_texdef.coords[1][1]; - // now compute those vectors in geometric space - Vector3 texS, texT; // axis base of the plane (geometric) - ComputeAxisBase( f->plane.normal, texS, texT ); - // vecS[] = vS[0].texS[] + vS[1].texT[] - // vecT[] = vT[0].texS[] + vT[1].texT[] - vecS[0] = vS[0] * texS[0] + vS[1] * texT[0]; - vecS[1] = vS[0] * texS[1] + vS[1] * texT[1]; - vecS[2] = vS[0] * texS[2] + vS[1] * texT[2]; - vecT[0] = vT[0] * texS[0] + vT[1] * texT[0]; - vecT[1] = vT[0] * texS[1] + vT[1] * texT[1]; - vecT[2] = vT[0] * texS[2] + vT[1] * texT[2]; -} - -// brush primitive texture adjustments, use the camera view to map adjustments -// ShiftTextureRelative_BrushPrimit ( s , t ) will shift relative to the texture -void ShiftTextureRelative_Camera( face_t *f, int x, int y ){ - Vector3 vecS, vecT; - float XY[2]; // the values we are going to send for translation - float sgn[2]; // +1 or -1 - int axis[2]; - CamWnd* pCam; - - // get the two relative texture axes for the current texturing - BrushPrimit_GetRelativeAxes( f, vecS, vecT ); - - // center point of the face, project it on the camera space - Vector3 C; - VectorClear( C ); - int i; - for ( i = 0; i < f->face_winding->numpoints; i++ ) - { - VectorAdd( C,f->face_winding->point_at( i ),C ); - } - VectorScale( C,1.0 / f->face_winding->numpoints,C ); - - pCam = g_pParentWnd->GetCamWnd(); - pCam->MatchViewAxes( C, vecS, axis[0], sgn[0] ); - pCam->MatchViewAxes( C, vecT, axis[1], sgn[1] ); - - // this happens when the two directions can't be mapped on two different directions on the screen - // then the move will occur against a single axis - // (i.e. the user is not positioned well enough to send understandable shift commands) - // NOTE: in most cases this warning is not very relevant because the user would use one of the two axes - // for which the solution is easy (the other one being unknown) - // so this warning could be removed - if ( axis[0] == axis[1] ) { - globalOutputStream() << "Warning: degenerate in ShiftTextureRelative_Camera\n"; - } - - // compute the X Y geometric increments - // those geometric increments will be applied along the texture axes (the ones we computed above) - XY[0] = 0; - XY[1] = 0; - if ( x != 0 ) { - // moving right/left - XY[axis[0]] += sgn[0] * x; - } - if ( y != 0 ) { - XY[axis[1]] += sgn[1] * y; - } - // we worked out a move along vecS vecT, and we now it's geometric amplitude - // apply it - ShiftTextureRelative_BrushPrimit( f, XY[0], XY[1] ); -} -#endif - - -void BPTexdef_Assign(brushprimit_texdef_t &bp_td, const brushprimit_texdef_t &bp_other) -{ - bp_td = bp_other; -} - -void BPTexdef_Shift(brushprimit_texdef_t &bp_td, float s, float t) -{ - // shift a texture (texture adjustments) along it's current texture axes - // x and y are geometric values, which we must compute as ST increments - // this depends on the texture size and the pixel/texel ratio - // as a ratio against texture size - // the scale of the texture is not relevant here (we work directly on a transformation from the base vectors) - bp_td.coords[0][2] -= s; - bp_td.coords[1][2] += t; -} - -void BPTexdef_Scale(brushprimit_texdef_t &bp_td, float s, float t) -{ - // apply same scale as the spinner button of the surface inspector - texdef_t texdef; - // compute fake shift scale rot - TexMatToFakeTexCoords(bp_td, texdef); - // update - texdef.scale[0] += s; - texdef.scale[1] += t; - // compute new normalized texture matrix - FakeTexCoordsToTexMat(texdef, bp_td); -} - -void BPTexdef_Rotate(brushprimit_texdef_t &bp_td, float angle) -{ - // apply same scale as the spinner button of the surface inspector - texdef_t texdef; - // compute fake shift scale rot - TexMatToFakeTexCoords(bp_td, texdef); - // update - texdef.rotate += angle; - // compute new normalized texture matrix - FakeTexCoordsToTexMat(texdef, bp_td); -} - -void BPTexdef_Construct(brushprimit_texdef_t &bp_td, std::size_t width, std::size_t height) -{ - bp_td.coords[0][0] = 1.0f; - bp_td.coords[1][1] = 1.0f; - ConvertTexMatWithDimensions(bp_td.coords, 2, 2, bp_td.coords, width, height); -} - -void Texdef_Assign(TextureProjection &projection, const TextureProjection &other) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_Assign(projection.m_brushprimit_texdef, other.m_brushprimit_texdef); - } else { - Texdef_Assign(projection.m_texdef, other.m_texdef); - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_HALFLIFE) { - projection.m_basis_s = other.m_basis_s; - projection.m_basis_t = other.m_basis_t; - } - } -} - -void Texdef_Shift(TextureProjection &projection, float s, float t) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_Shift(projection.m_brushprimit_texdef, s, t); - } else { - Texdef_Shift(projection.m_texdef, s, t); - } -} - -void Texdef_Scale(TextureProjection &projection, float s, float t) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_Scale(projection.m_brushprimit_texdef, s, t); - } else { - Texdef_Scale(projection.m_texdef, s, t); - } -} - -void Texdef_Rotate(TextureProjection &projection, float angle) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - BPTexdef_Rotate(projection.m_brushprimit_texdef, angle); - } else { - Texdef_Rotate(projection.m_texdef, angle); - } -} - -void Texdef_FitTexture(TextureProjection &projection, std::size_t width, std::size_t height, const Vector3 &normal, - const Winding &w, float s_repeat, float t_repeat) -{ - if (w.numpoints < 3) { - return; - } - - Matrix4 st2tex; - Texdef_toTransform(projection, (float) width, (float) height, st2tex); - - // the current texture transform - Matrix4 local2tex = st2tex; - { - Matrix4 xyz2st; - Texdef_basisForNormal(projection, normal, xyz2st); - matrix4_multiply_by_matrix4(local2tex, xyz2st); - } - - // the bounds of the current texture transform - AABB bounds; - for (Winding::const_iterator i = w.begin(); i != w.end(); ++i) { - Vector3 texcoord = matrix4_transformed_point(local2tex, (*i).vertex); - aabb_extend_by_point_safe(bounds, texcoord); - } - bounds.origin.z() = 0; - bounds.extents.z() = 1; - - // the bounds of a perfectly fitted texture transform - AABB perfect(Vector3(s_repeat * 0.5, t_repeat * 0.5, 0), Vector3(s_repeat * 0.5, t_repeat * 0.5, 1)); - - // the difference between the current texture transform and the perfectly fitted transform - Matrix4 matrix(matrix4_translation_for_vec3(bounds.origin - perfect.origin)); - matrix4_pivoted_scale_by_vec3(matrix, bounds.extents / perfect.extents, perfect.origin); - matrix4_affine_invert(matrix); - - // apply the difference to the current texture transform - matrix4_premultiply_by_matrix4(st2tex, matrix); - - Texdef_fromTransform(projection, (float) width, (float) height, st2tex); - Texdef_normalise(projection, (float) width, (float) height); -} - - -void Texdef_AlignTexture(TextureProjection &projection, const Plane3 &plane, const Vector3 &normal, const Winding &w, std::size_t width, std::size_t height, int alignment) -{ - if (w.numpoints < 3) { - return; - } - - Matrix4 st2tex; - Texdef_toTransform(projection, (float) width, (float) height, st2tex); - - // the current texture transform - Matrix4 local2tex = st2tex; - { - Matrix4 xyz2st; - Texdef_basisForNormal(projection, normal, xyz2st); - matrix4_multiply_by_matrix4(local2tex, xyz2st); - } - - // the bounds of the current texture transform - AABB bounds; - for (Winding::const_iterator i = w.begin(); i != w.end(); ++i) { - Vector3 texcoord = matrix4_transformed_point(local2tex, (*i).vertex); - aabb_extend_by_point_safe(bounds, texcoord); - } - bounds.extents.z() = 1; - - AABB perfect; - perfect.extents = bounds.extents; - printf("Bounds: %f %f %f\n", bounds.origin.x(), bounds.origin.y(), bounds.origin.z()); - - switch (alignment) { - case 0: - printf("Top Left\n"); - perfect.origin = Vector3(0, 0, 0); - break; - case 1: - printf("Top Center\n"); - perfect.origin = Vector3(width /2, 0, 0); - break; - case 2: - printf("Top Right\n"); - perfect.origin = Vector3(width, 0, 0); - break; - case 3: - printf("Middle Left\n"); - perfect.origin = Vector3(0.0, 0.5, 0); - break; - case 4: - printf("Middle Center\n"); - perfect.origin = Vector3(0.5, 0.5, 0); - break; - case 5: - printf("Middle Right\n"); - perfect.origin = Vector3(1.0, 0.5, 0); - break; - case 6: - printf("Bottom Left\n"); - perfect.origin = Vector3(0.0, 1.0, 0); - break; - case 7: - printf("Bottom Center\n"); - perfect.origin = Vector3(0.5, 1.0, 0); - break; - case 8: - printf("Bottom Right\n"); - perfect.origin = Vector3(1.0, 1.0, 0); - break; - } - - // the difference between the current texture transform and the perfectly fitted transform - Matrix4 matrix(matrix4_translation_for_vec3(bounds.origin - perfect.origin)); - - /* - matrix4_pivoted_scale_by_vec3(matrix, bounds.extents, perfect.origin); - matrix4_affine_invert(matrix); - */ - - // apply the difference to the current texture transform - matrix4_premultiply_by_matrix4(st2tex, matrix); - Texdef_fromTransform(projection, (float) width, (float) height, st2tex); - Texdef_normalise(projection, (float) width, (float) height); -} - -float Texdef_getDefaultTextureScale() -{ - return g_texdef_default_scale; -} - -void TexDef_Construct_Default(TextureProjection &projection) -{ - projection.m_texdef.scale[0] = Texdef_getDefaultTextureScale(); - projection.m_texdef.scale[1] = Texdef_getDefaultTextureScale(); - - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - FakeTexCoordsToTexMat(projection.m_texdef, projection.m_brushprimit_texdef); - } -} - - -void ShiftScaleRotate_fromFace(texdef_t &shiftScaleRotate, const TextureProjection &projection) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - TexMatToFakeTexCoords(projection.m_brushprimit_texdef, shiftScaleRotate); - } else { - shiftScaleRotate = projection.m_texdef; - } -} - -void ShiftScaleRotate_toFace(const texdef_t &shiftScaleRotate, TextureProjection &projection) -{ - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES) { - // compute texture matrix - // the matrix returned must be understood as a qtexture_t with width=2 height=2 - FakeTexCoordsToTexMat(shiftScaleRotate, projection.m_brushprimit_texdef); - } else { - projection.m_texdef = shiftScaleRotate; - } -} - - -inline void print_vector3(const Vector3 &v) -{ - globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )\n"; -} - -inline void print_3x3(const Matrix4 &m) -{ - globalOutputStream() << "( " << m.xx() << " " << m.xy() << " " << m.xz() << " ) " - << "( " << m.yx() << " " << m.yy() << " " << m.yz() << " ) " - << "( " << m.zx() << " " << m.zy() << " " << m.zz() << " )\n"; -} - - -inline Matrix4 matrix4_rotation_for_vector3(const Vector3 &x, const Vector3 &y, const Vector3 &z) -{ - return Matrix4( - x.x(), x.y(), x.z(), 0, - y.x(), y.y(), y.z(), 0, - z.x(), z.y(), z.z(), 0, - 0, 0, 0, 1 - ); -} - -inline Matrix4 matrix4_swap_axes(const Vector3 &from, const Vector3 &to) -{ - if (from.x() != 0 && to.y() != 0) { - return matrix4_rotation_for_vector3(to, from, g_vector3_axis_z); - } - - if (from.x() != 0 && to.z() != 0) { - return matrix4_rotation_for_vector3(to, g_vector3_axis_y, from); - } - - if (from.y() != 0 && to.z() != 0) { - return matrix4_rotation_for_vector3(g_vector3_axis_x, to, from); - } - - if (from.y() != 0 && to.x() != 0) { - return matrix4_rotation_for_vector3(from, to, g_vector3_axis_z); - } - - if (from.z() != 0 && to.x() != 0) { - return matrix4_rotation_for_vector3(from, g_vector3_axis_y, to); - } - - if (from.z() != 0 && to.y() != 0) { - return matrix4_rotation_for_vector3(g_vector3_axis_x, from, to); - } - - ERROR_MESSAGE("unhandled axis swap case"); - - return g_matrix4_identity; -} - -inline Matrix4 matrix4_reflection_for_plane(const Plane3 &plane) -{ - return Matrix4( - static_cast( 1 - (2 * plane.a * plane.a)), - static_cast( -2 * plane.a * plane.b ), - static_cast( -2 * plane.a * plane.c ), - 0, - static_cast( -2 * plane.b * plane.a ), - static_cast( 1 - (2 * plane.b * plane.b)), - static_cast( -2 * plane.b * plane.c ), - 0, - static_cast( -2 * plane.c * plane.a ), - static_cast( -2 * plane.c * plane.b ), - static_cast( 1 - (2 * plane.c * plane.c)), - 0, - static_cast( -2 * plane.d * plane.a ), - static_cast( -2 * plane.d * plane.b ), - static_cast( -2 * plane.d * plane.c ), - 1 - ); -} - -inline Matrix4 matrix4_reflection_for_plane45(const Plane3 &plane, const Vector3 &from, const Vector3 &to) -{ - Vector3 first = from; - Vector3 second = to; - - if ((vector3_dot(from, plane.normal()) > 0) == (vector3_dot(to, plane.normal()) > 0)) { - first = vector3_negated(first); - second = vector3_negated(second); - } - -#if 0 - globalOutputStream() << "normal: "; - print_vector3( plane.normal() ); - - globalOutputStream() << "from: "; - print_vector3( first ); - - globalOutputStream() << "to: "; - print_vector3( second ); -#endif - - Matrix4 swap = matrix4_swap_axes(first, second); - - swap.tx() = -static_cast( -2 * plane.a * plane.d ); - swap.ty() = -static_cast( -2 * plane.b * plane.d ); - swap.tz() = -static_cast( -2 * plane.c * plane.d ); - - return swap; -} - -void Texdef_transformLocked(TextureProjection &projection, std::size_t width, std::size_t height, const Plane3 &plane, - const Matrix4 &identity2transformed) -{ - //globalOutputStream() << "identity2transformed: " << identity2transformed << "\n"; - - //globalOutputStream() << "plane.normal(): " << plane.normal() << "\n"; - - Vector3 normalTransformed(matrix4_transformed_direction(identity2transformed, plane.normal())); - - //globalOutputStream() << "normalTransformed: " << normalTransformed << "\n"; - - // identity: identity space - // transformed: transformation - // stIdentity: base st projection space before transformation - // stTransformed: base st projection space after transformation - // stOriginal: original texdef space - - // stTransformed2stOriginal = stTransformed -> transformed -> identity -> stIdentity -> stOriginal - - Matrix4 identity2stIdentity; - Texdef_basisForNormal(projection, plane.normal(), identity2stIdentity); - //globalOutputStream() << "identity2stIdentity: " << identity2stIdentity << "\n"; - - if (g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_HALFLIFE) { - matrix4_transform_direction(identity2transformed, projection.m_basis_s); - matrix4_transform_direction(identity2transformed, projection.m_basis_t); - } - - Matrix4 transformed2stTransformed; - Texdef_basisForNormal(projection, normalTransformed, transformed2stTransformed); - - Matrix4 stTransformed2identity( - matrix4_affine_inverse(matrix4_multiplied_by_matrix4(transformed2stTransformed, identity2transformed))); - - Vector3 originalProjectionAxis(vector4_to_vector3(matrix4_affine_inverse(identity2stIdentity).z())); - - Vector3 transformedProjectionAxis(vector4_to_vector3(stTransformed2identity.z())); - - Matrix4 stIdentity2stOriginal; - Texdef_toTransform(projection, (float) width, (float) height, stIdentity2stOriginal); - Matrix4 identity2stOriginal(matrix4_multiplied_by_matrix4(stIdentity2stOriginal, identity2stIdentity)); - - //globalOutputStream() << "originalProj: " << originalProjectionAxis << "\n"; - //globalOutputStream() << "transformedProj: " << transformedProjectionAxis << "\n"; - double dot = vector3_dot(originalProjectionAxis, transformedProjectionAxis); - //globalOutputStream() << "dot: " << dot << "\n"; - if (dot == 0) { - // The projection axis chosen for the transformed normal is at 90 degrees - // to the transformed projection axis chosen for the original normal. - // This happens when the projection axis is ambiguous - e.g. for the plane - // 'X == Y' the projection axis could be either X or Y. - //globalOutputStream() << "flipped\n"; -#if 0 - globalOutputStream() << "projection off by 90\n"; - globalOutputStream() << "normal: "; - print_vector3( plane.normal() ); - globalOutputStream() << "original projection: "; - print_vector3( originalProjectionAxis ); - globalOutputStream() << "transformed projection: "; - print_vector3( transformedProjectionAxis ); -#endif - - Matrix4 identityCorrected = matrix4_reflection_for_plane45(plane, originalProjectionAxis, - transformedProjectionAxis); - - identity2stOriginal = matrix4_multiplied_by_matrix4(identity2stOriginal, identityCorrected); - } - - Matrix4 stTransformed2stOriginal = matrix4_multiplied_by_matrix4(identity2stOriginal, stTransformed2identity); - - Texdef_fromTransform(projection, (float) width, (float) height, stTransformed2stOriginal); - Texdef_normalise(projection, (float) width, (float) height); -} - -#if 1 - -void Q3_to_matrix(const texdef_t &texdef, float width, float height, const Vector3 &normal, Matrix4 &matrix) -{ - Normal_GetTransform(normal, matrix); - - Matrix4 transform; - - Texdef_toTransform(texdef, width, height, transform); - - matrix4_multiply_by_matrix4(matrix, transform); -} - -void BP_from_matrix(brushprimit_texdef_t &bp_texdef, const Vector3 &normal, const Matrix4 &transform) -{ - Matrix4 basis; - basis = g_matrix4_identity; - ComputeAxisBase(normal, vector4_to_vector3(basis.x()), vector4_to_vector3(basis.y())); - vector4_to_vector3(basis.z()) = normal; - matrix4_transpose(basis); - matrix4_affine_invert(basis); - - Matrix4 basis2texture = matrix4_multiplied_by_matrix4(basis, transform); - - BPTexdef_fromTransform(bp_texdef, basis2texture); -} - -void Q3_to_BP(const texdef_t &texdef, float width, float height, const Vector3 &normal, brushprimit_texdef_t &bp_texdef) -{ - Matrix4 matrix; - Q3_to_matrix(texdef, width, height, normal, matrix); - BP_from_matrix(bp_texdef, normal, matrix); -} - -#endif diff --git a/src/brush_primit.h b/src/brush_primit.h deleted file mode 100644 index 0714996..0000000 --- a/src/brush_primit.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSH_PRIMIT_H ) -#define INCLUDED_BRUSH_PRIMIT_H - -#include "math/vector.h" -#include "itexdef.h" -#include "debugging/debugging.h" - -// Timo -// new brush primitive texdef -struct brushprimit_texdef_t { - brushprimit_texdef_t() - { - coords[0][0] = 2.0f; - coords[0][1] = 0.f; - coords[0][2] = 0.f; - coords[1][0] = 0.f; - coords[1][1] = 2.0f; - coords[1][2] = 0.f; - } - - void removeScale(std::size_t width, std::size_t height) - { -#if 1 - coords[0][0] *= width; - coords[0][1] *= width; - coords[0][2] *= width; - coords[1][0] *= height; - coords[1][1] *= height; - coords[1][2] *= height; -#endif - } - - void addScale(std::size_t width, std::size_t height) - { -#if 1 - ASSERT_MESSAGE(width > 0, "shader-width is 0"); - ASSERT_MESSAGE(height > 0, "shader-height is 0"); - coords[0][0] /= width; - coords[0][1] /= width; - coords[0][2] /= width; - coords[1][0] /= height; - coords[1][1] /= height; - coords[1][2] /= height; -#endif - } - - float coords[2][3]; -}; - -class TextureProjection { -public: -texdef_t m_texdef; -brushprimit_texdef_t m_brushprimit_texdef; -Vector3 m_basis_s; -Vector3 m_basis_t; - -TextureProjection() -{ -} - -TextureProjection( - const texdef_t &texdef, - const brushprimit_texdef_t &brushprimit_texdef, - const Vector3 &basis_s, - const Vector3 &basis_t - ) : - m_texdef(texdef), - m_brushprimit_texdef(brushprimit_texdef), - m_basis_s(basis_s), - m_basis_t(basis_t) -{ -} -}; - -float Texdef_getDefaultTextureScale(); - -class texdef_t; - -struct Winding; - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -template -class BasicVector4; - -typedef BasicVector4 Vector4; -typedef Vector4 Quaternion; - -class Matrix4; - -class Plane3; - -void Normal_GetTransform(const Vector3 &normal, Matrix4 &transform); - -void TexDef_Construct_Default(TextureProjection &projection); - -void Texdef_Assign(TextureProjection &projection, const TextureProjection &other); - -void Texdef_Shift(TextureProjection &projection, float s, float t); - -void Texdef_Scale(TextureProjection &projection, float s, float t); - -void Texdef_Rotate(TextureProjection &projection, float angle); - -void Texdef_FitTexture(TextureProjection &projection, std::size_t width, std::size_t height, const Vector3 &normal, - const Winding &w, float s_repeat, float t_repeat); -void Texdef_AlignTexture(TextureProjection &projection, const Plane3 &plane, const Vector3 &normal, const Winding &w, std::size_t width, std::size_t height, int alignment); - -void -Texdef_EmitTextureCoordinates(const TextureProjection &projection, std::size_t width, std::size_t height, Winding &w, - const Vector3 &normal, const Matrix4 &localToWorld); - -void ShiftScaleRotate_fromFace(texdef_t &shiftScaleRotate, const TextureProjection &projection); - -void ShiftScaleRotate_toFace(const texdef_t &shiftScaleRotate, TextureProjection &projection); - -void Texdef_transformLocked(TextureProjection &projection, std::size_t width, std::size_t height, const Plane3 &plane, - const Matrix4 &transform); - -void Texdef_normalise(TextureProjection &projection, float width, float height); - -enum TexdefTypeId { - TEXDEFTYPEID_QUAKE, - TEXDEFTYPEID_BRUSHPRIMITIVES, - TEXDEFTYPEID_HALFLIFE, -}; - -struct bp_globals_t { - // tells if we are internally using brush primitive (texture coordinates and map format) - // this is a shortcut for IntForKey( g_qeglobals.d_project_entity, "brush_primit" ) - // NOTE: must keep the two ones in sync - TexdefTypeId m_texdefTypeId; -}; - -extern bp_globals_t g_bp_globals; -extern float g_texdef_default_scale; - -void ComputeAxisBase(const Vector3 &normal, Vector3 &texS, Vector3 &texT); - -#endif diff --git a/src/brushmanip.cpp b/src/brushmanip.cpp deleted file mode 100644 index b94a909..0000000 --- a/src/brushmanip.cpp +++ /dev/null @@ -1,1388 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushmanip.h" - - -#include "gtkutil/widget.h" -#include "gtkutil/menu.h" -#include "gtkmisc.h" -#include "brushnode.h" -#include "map.h" -#include "texwindow.h" -#include "gtkdlgs.h" -#include "commands.h" -#include "mainframe.h" -#include "dialog.h" -#include "xywindow.h" -#include "preferences.h" - -#include -#include - -void Brush_ConstructCuboid(Brush &brush, const AABB &bounds, const char *shader, const TextureProjection &projection) -{ - const unsigned char box[3][2] = {{0, 1}, - {2, 0}, - {1, 2}}; - Vector3 mins(vector3_subtracted(bounds.origin, bounds.extents)); - Vector3 maxs(vector3_added(bounds.origin, bounds.extents)); - - brush.clear(); - brush.reserve(6); - - { - for (int i = 0; i < 3; ++i) { - Vector3 planepts1(maxs); - Vector3 planepts2(maxs); - planepts2[box[i][0]] = mins[box[i][0]]; - planepts1[box[i][1]] = mins[box[i][1]]; - - brush.addPlane(maxs, planepts1, planepts2, shader, projection); - } - } - { - for (int i = 0; i < 3; ++i) { - Vector3 planepts1(mins); - Vector3 planepts2(mins); - planepts1[box[i][0]] = maxs[box[i][0]]; - planepts2[box[i][1]] = maxs[box[i][1]]; - - brush.addPlane(mins, planepts1, planepts2, shader, projection); - } - } -} - -inline float max_extent(const Vector3 &extents) -{ - return std::max(std::max(extents[0], extents[1]), extents[2]); -} - -inline float max_extent_2d(const Vector3 &extents, int axis) -{ - switch (axis) { - case 0: - return std::max(extents[1], extents[2]); - case 1: - return std::max(extents[0], extents[2]); - default: - return std::max(extents[0], extents[1]); - } -} - -const std::size_t c_brushPrism_minSides = 3; -const std::size_t c_brushPrism_maxSides = c_brush_maxFaces - 2; -const char *const c_brushPrism_name = "brushPrism"; - -void Brush_ConstructPrism(Brush &brush, const AABB &bounds, std::size_t sides, int axis, const char *shader, - const TextureProjection &projection) -{ - if (sides < c_brushPrism_minSides) { - globalErrorStream() << c_brushPrism_name << ": sides " << Unsigned(sides) << ": too few sides, minimum is " - << Unsigned(c_brushPrism_minSides) << "\n"; - return; - } - if (sides > c_brushPrism_maxSides) { - globalErrorStream() << c_brushPrism_name << ": sides " << Unsigned(sides) << ": too many sides, maximum is " - << Unsigned(c_brushPrism_maxSides) << "\n"; - return; - } - - brush.clear(); - brush.reserve(sides + 2); - - Vector3 mins(vector3_subtracted(bounds.origin, bounds.extents)); - Vector3 maxs(vector3_added(bounds.origin, bounds.extents)); - - float radius = max_extent_2d(bounds.extents, axis); - const Vector3 &mid = bounds.origin; - Vector3 planepts[3]; - - planepts[2][(axis + 1) % 3] = mins[(axis + 1) % 3]; - planepts[2][(axis + 2) % 3] = mins[(axis + 2) % 3]; - planepts[2][axis] = maxs[axis]; - planepts[1][(axis + 1) % 3] = maxs[(axis + 1) % 3]; - planepts[1][(axis + 2) % 3] = mins[(axis + 2) % 3]; - planepts[1][axis] = maxs[axis]; - planepts[0][(axis + 1) % 3] = maxs[(axis + 1) % 3]; - planepts[0][(axis + 2) % 3] = maxs[(axis + 2) % 3]; - planepts[0][axis] = maxs[axis]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - - planepts[0][(axis + 1) % 3] = mins[(axis + 1) % 3]; - planepts[0][(axis + 2) % 3] = mins[(axis + 2) % 3]; - planepts[0][axis] = mins[axis]; - planepts[1][(axis + 1) % 3] = maxs[(axis + 1) % 3]; - planepts[1][(axis + 2) % 3] = mins[(axis + 2) % 3]; - planepts[1][axis] = mins[axis]; - planepts[2][(axis + 1) % 3] = maxs[(axis + 1) % 3]; - planepts[2][(axis + 2) % 3] = maxs[(axis + 2) % 3]; - planepts[2][axis] = mins[axis]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - - for (std::size_t i = 0; i < sides; ++i) { - double sv = sin(i * 3.14159265 * 2 / sides); - double cv = cos(i * 3.14159265 * 2 / sides); - - planepts[0][(axis + 1) % 3] = static_cast( floor(mid[(axis + 1) % 3] + radius * cv + 0.5)); - planepts[0][(axis + 2) % 3] = static_cast( floor(mid[(axis + 2) % 3] + radius * sv + 0.5)); - planepts[0][axis] = mins[axis]; - - planepts[1][(axis + 1) % 3] = planepts[0][(axis + 1) % 3]; - planepts[1][(axis + 2) % 3] = planepts[0][(axis + 2) % 3]; - planepts[1][axis] = maxs[axis]; - - planepts[2][(axis + 1) % 3] = static_cast( floor(planepts[0][(axis + 1) % 3] - radius * sv + 0.5)); - planepts[2][(axis + 2) % 3] = static_cast( floor(planepts[0][(axis + 2) % 3] + radius * cv + 0.5)); - planepts[2][axis] = maxs[axis]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } -} - -const std::size_t c_brushCone_minSides = 3; -const std::size_t c_brushCone_maxSides = 32; -const char *const c_brushCone_name = "brushCone"; - -void Brush_ConstructCone(Brush &brush, const AABB &bounds, std::size_t sides, const char *shader, - const TextureProjection &projection) -{ - if (sides < c_brushCone_minSides) { - globalErrorStream() << c_brushCone_name << ": sides " << Unsigned(sides) << ": too few sides, minimum is " - << Unsigned(c_brushCone_minSides) << "\n"; - return; - } - if (sides > c_brushCone_maxSides) { - globalErrorStream() << c_brushCone_name << ": sides " << Unsigned(sides) << ": too many sides, maximum is " - << Unsigned(c_brushCone_maxSides) << "\n"; - return; - } - - brush.clear(); - brush.reserve(sides + 1); - - Vector3 mins(vector3_subtracted(bounds.origin, bounds.extents)); - Vector3 maxs(vector3_added(bounds.origin, bounds.extents)); - - float radius = max_extent(bounds.extents); - const Vector3 &mid = bounds.origin; - Vector3 planepts[3]; - - planepts[0][0] = mins[0]; - planepts[0][1] = mins[1]; - planepts[0][2] = mins[2]; - planepts[1][0] = maxs[0]; - planepts[1][1] = mins[1]; - planepts[1][2] = mins[2]; - planepts[2][0] = maxs[0]; - planepts[2][1] = maxs[1]; - planepts[2][2] = mins[2]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - - for (std::size_t i = 0; i < sides; ++i) { - double sv = sin(i * 3.14159265 * 2 / sides); - double cv = cos(i * 3.14159265 * 2 / sides); - - planepts[0][0] = static_cast( floor(mid[0] + radius * cv + 0.5)); - planepts[0][1] = static_cast( floor(mid[1] + radius * sv + 0.5)); - planepts[0][2] = mins[2]; - - planepts[1][0] = mid[0]; - planepts[1][1] = mid[1]; - planepts[1][2] = maxs[2]; - - planepts[2][0] = static_cast( floor(planepts[0][0] - radius * sv + 0.5)); - planepts[2][1] = static_cast( floor(planepts[0][1] + radius * cv + 0.5)); - planepts[2][2] = maxs[2]; - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } -} - -const std::size_t c_brushSphere_minSides = 3; -const std::size_t c_brushSphere_maxSides = 31; -const char *const c_brushSphere_name = "brushSphere"; - -void Brush_ConstructSphere(Brush &brush, const AABB &bounds, std::size_t sides, const char *shader, - const TextureProjection &projection) -{ - if (sides < c_brushSphere_minSides) { - globalErrorStream() << c_brushSphere_name << ": sides " << Unsigned(sides) << ": too few sides, minimum is " - << Unsigned(c_brushSphere_minSides) << "\n"; - return; - } - if (sides > c_brushSphere_maxSides) { - globalErrorStream() << c_brushSphere_name << ": sides " << Unsigned(sides) << ": too many sides, maximum is " - << Unsigned(c_brushSphere_maxSides) << "\n"; - return; - } - - brush.clear(); - brush.reserve(sides * sides); - - float radius = max_extent(bounds.extents); - const Vector3 &mid = bounds.origin; - Vector3 planepts[3]; - - double dt = 2 * c_pi / sides; - double dp = c_pi / sides; - for (std::size_t i = 0; i < sides; i++) { - for (std::size_t j = 0; j < sides - 1; j++) { - double t = i * dt; - double p = float(j * dp - c_pi / 2); - - planepts[0] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t, p), radius)); - planepts[1] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t, p + dp), radius)); - planepts[2] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius)); - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } - } - - { - double p = (sides - 1) * dp - c_pi / 2; - for (std::size_t i = 0; i < sides; i++) { - double t = i * dt; - - planepts[0] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t, p), radius)); - planepts[1] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius)); - planepts[2] = vector3_added(mid, vector3_scaled(vector3_for_spherical(t + dt, p), radius)); - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } - } -} - -const std::size_t c_brushRock_minSides = 10; -const std::size_t c_brushRock_maxSides = 1000; -const char *const c_brushRock_name = "brushRock"; - -void Brush_ConstructRock(Brush &brush, const AABB &bounds, std::size_t sides, const char *shader, - const TextureProjection &projection) -{ - if (sides < c_brushRock_minSides) { - globalErrorStream() << c_brushRock_name << ": sides " << Unsigned(sides) << ": too few sides, minimum is " - << Unsigned(c_brushRock_minSides) << "\n"; - return; - } - if (sides > c_brushRock_maxSides) { - globalErrorStream() << c_brushRock_name << ": sides " << Unsigned(sides) << ": too many sides, maximum is " - << Unsigned(c_brushRock_maxSides) << "\n"; - return; - } - - brush.clear(); - brush.reserve(sides * sides); - - float radius = max_extent(bounds.extents); - const Vector3 &mid = bounds.origin; - Vector3 planepts[3]; - - for (std::size_t j = 0; j < sides; j++) { - planepts[0][0] = rand() - (RAND_MAX / 2); - planepts[0][1] = rand() - (RAND_MAX / 2); - planepts[0][2] = rand() - (RAND_MAX / 2); - vector3_normalise(planepts[0]); - - // find two vectors that are perpendicular to planepts[0] - ComputeAxisBase(planepts[0], planepts[1], planepts[2]); - - planepts[0] = vector3_added(mid, vector3_scaled(planepts[0], radius)); - planepts[1] = vector3_added(planepts[0], vector3_scaled(planepts[1], radius)); - planepts[2] = vector3_added(planepts[0], vector3_scaled(planepts[2], radius)); - -#if 0 - // make sure the orientation is right - if ( vector3_dot( vector3_subtracted( planepts[0], mid ), vector3_cross( vector3_subtracted( planepts[1], mid ), vector3_subtracted( planepts[2], mid ) ) ) > 0 ) { - Vector3 h; - h = planepts[1]; - planepts[1] = planepts[2]; - planepts[2] = h; - globalOutputStream() << "flip\n"; - } - else{ - globalOutputStream() << "no flip\n"; - } -#endif - - brush.addPlane(planepts[0], planepts[1], planepts[2], shader, projection); - } -} - -int GetViewAxis() -{ - switch (GlobalXYWnd_getCurrentViewType()) { - case XY: - return 2; - case XZ: - return 1; - case YZ: - return 0; - } - return 2; -} - -void Brush_ConstructPrefab(Brush &brush, EBrushPrefab type, const AABB &bounds, std::size_t sides, const char *shader, - const TextureProjection &projection) -{ - switch (type) { - case eBrushCuboid: { - UndoableCommand undo("brushCuboid"); - - Brush_ConstructCuboid(brush, bounds, shader, projection); - } - break; - case eBrushPrism: { - int axis = GetViewAxis(); - StringOutputStream command; - command << c_brushPrism_name << " -sides " << Unsigned(sides) << " -axis " << axis; - UndoableCommand undo(command.c_str()); - - Brush_ConstructPrism(brush, bounds, sides, axis, shader, projection); - } - break; - case eBrushCone: { - StringOutputStream command; - command << c_brushCone_name << " -sides " << Unsigned(sides); - UndoableCommand undo(command.c_str()); - - Brush_ConstructCone(brush, bounds, sides, shader, projection); - } - break; - case eBrushSphere: { - StringOutputStream command; - command << c_brushSphere_name << " -sides " << Unsigned(sides); - UndoableCommand undo(command.c_str()); - - Brush_ConstructSphere(brush, bounds, sides, shader, projection); - } - break; - case eBrushRock: { - StringOutputStream command; - command << c_brushRock_name << " -sides " << Unsigned(sides); - UndoableCommand undo(command.c_str()); - - Brush_ConstructRock(brush, bounds, sides, shader, projection); - } - break; - } -} - - -void ConstructRegionBrushes(scene::Node *brushes[6], const Vector3 ®ion_mins, const Vector3 ®ion_maxs) -{ - { - // set mins - Vector3 mins(region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32); - - // vary maxs - for (std::size_t i = 0; i < 3; i++) { - Vector3 maxs(region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32); - maxs[i] = region_mins[i]; - Brush_ConstructCuboid(*Node_getBrush(*brushes[i]), aabb_for_minmax(mins, maxs), texdef_name_default(), - TextureProjection()); - } - } - - { - // set maxs - Vector3 maxs(region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32); - - // vary mins - for (std::size_t i = 0; i < 3; i++) { - Vector3 mins(region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32); - mins[i] = region_maxs[i]; - Brush_ConstructCuboid(*Node_getBrush(*brushes[i + 3]), aabb_for_minmax(mins, maxs), texdef_name_default(), - TextureProjection()); - } - } -} - - -void Scene_BrushSetTexdef_Selected(scene::Graph &graph, const TextureProjection &projection, bool ignorebasis) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.SetTexdef(projection, ignorebasis); - }); - SceneChangeNotify(); -} - -void Scene_BrushSetTexdef_Component_Selected(scene::Graph &graph, const TextureProjection &projection, bool ignorebasis) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.SetTexdef(projection, ignorebasis); - }); - SceneChangeNotify(); -} - - -void Scene_BrushSetFlags_Selected(scene::Graph &graph, const ContentsFlagsValue &flags) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.SetFlags(flags); - }); - SceneChangeNotify(); -} - -void Scene_BrushSetFlags_Component_Selected(scene::Graph &graph, const ContentsFlagsValue &flags) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.SetFlags(flags); - }); - SceneChangeNotify(); -} - -void Scene_BrushShiftTexdef_Selected(scene::Graph &graph, float s, float t) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.ShiftTexdef(s, t); - }); - SceneChangeNotify(); -} - -void Scene_BrushShiftTexdef_Component_Selected(scene::Graph &graph, float s, float t) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.ShiftTexdef(s, t); - }); - SceneChangeNotify(); -} - -void Scene_BrushScaleTexdef_Selected(scene::Graph &graph, float s, float t) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.ScaleTexdef(s, t); - }); - SceneChangeNotify(); -} - -void Scene_BrushScaleTexdef_Component_Selected(scene::Graph &graph, float s, float t) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.ScaleTexdef(s, t); - }); - SceneChangeNotify(); -} - -void Scene_BrushRotateTexdef_Selected(scene::Graph &graph, float angle) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.RotateTexdef(angle); - }); - SceneChangeNotify(); -} - -void Scene_BrushRotateTexdef_Component_Selected(scene::Graph &graph, float angle) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.RotateTexdef(angle); - }); - SceneChangeNotify(); -} - - -void Scene_BrushSetShader_Selected(scene::Graph &graph, const char *name) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.SetShader(name); - }); - SceneChangeNotify(); -} - -void Scene_BrushSetShader_Component_Selected(scene::Graph &graph, const char *name) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.SetShader(name); - }); - SceneChangeNotify(); -} - -void Scene_BrushSetDetail_Selected(scene::Graph &graph, bool detail) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.setDetail(detail); - }); - SceneChangeNotify(); -} - -bool Face_FindReplaceShader(Face &face, const char *find, const char *replace) -{ - if (shader_equal(face.GetShader(), find)) { - face.SetShader(replace); - return true; - } - return false; -} - -bool DoingSearch(const char *repl) -{ - return (repl == NULL || (strcmp("textures/", repl) == 0)); -} - -void Scene_BrushFindReplaceShader(scene::Graph &graph, const char *find, const char *replace) -{ - if (DoingSearch(replace)) { - Scene_ForEachBrush_ForEachFaceInstance(graph, [&](FaceInstance &faceinst) { - if (shader_equal(faceinst.getFace().GetShader(), find)) { - faceinst.setSelected(SelectionSystem::eFace, true); - } - }); - } else { - Scene_ForEachBrush_ForEachFace(graph, [&](Face &face) { - Face_FindReplaceShader(face, find, replace); - }); - } -} - -void Scene_BrushFindReplaceShader_Selected(scene::Graph &graph, const char *find, const char *replace) -{ - if (DoingSearch(replace)) { - Scene_ForEachSelectedBrush_ForEachFaceInstance(graph, [&](FaceInstance &faceinst) { - if (shader_equal(faceinst.getFace().GetShader(), find)) { - faceinst.setSelected(SelectionSystem::eFace, true); - } - }); - } else { - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - Face_FindReplaceShader(face, find, replace); - }); - } -} - -// TODO: find for components -// d1223m: dont even know what they are... -void Scene_BrushFindReplaceShader_Component_Selected(scene::Graph &graph, const char *find, const char *replace) -{ - if (DoingSearch(replace)) { - - } else { - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - Face_FindReplaceShader(face, find, replace); - }); - } -} - - -void Scene_BrushFitTexture_Selected(scene::Graph &graph, float s_repeat, float t_repeat) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.FitTexture(s_repeat, t_repeat); - }); - SceneChangeNotify(); -} -void Scene_BrushFitTexture_Component_Selected(scene::Graph &graph, float s_repeat, float t_repeat) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.FitTexture(s_repeat, t_repeat); - }); - SceneChangeNotify(); -} - -void Scene_BrushAlignTexture_Selected(scene::Graph &graph, int alignment) -{ - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - face.AlignTexture(alignment); - }); - SceneChangeNotify(); -} -void Scene_BrushAlignTexture_Component_Selected(scene::Graph &graph, int alignment) -{ - Scene_ForEachSelectedBrushFace(graph, [&](Face &face) { - face.AlignTexture(alignment); - }); - SceneChangeNotify(); -} - -TextureProjection g_defaultTextureProjection; - -const TextureProjection &TextureTransform_getDefault() -{ - TexDef_Construct_Default(g_defaultTextureProjection); - return g_defaultTextureProjection; -} - -void Scene_BrushConstructPrefab(scene::Graph &graph, EBrushPrefab type, std::size_t sides, const char *shader) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - - Brush *brush = Node_getBrush(path.top()); - if (brush != 0) { - AABB bounds = brush->localAABB(); // copy bounds because the brush will be modified - Brush_ConstructPrefab(*brush, type, bounds, sides, shader, TextureTransform_getDefault()); - SceneChangeNotify(); - } - } -} - -void Scene_BrushResize_Selected(scene::Graph &graph, const AABB &bounds, const char *shader) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - - Brush *brush = Node_getBrush(path.top()); - if (brush != 0) { - Brush_ConstructCuboid(*brush, bounds, shader, TextureTransform_getDefault()); - SceneChangeNotify(); - } - } -} - -bool Brush_hasShader(const Brush &brush, const char *name) -{ - for (Brush::const_iterator i = brush.begin(); i != brush.end(); ++i) { - if (shader_equal((*i)->GetShader(), name)) { - return true; - } - } - return false; -} - -class BrushSelectByShaderWalker : public scene::Graph::Walker { -const char *m_name; -public: -BrushSelectByShaderWalker(const char *name) - : m_name(name) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 && Brush_hasShader(*brush, m_name)) { - Instance_getSelectable(instance)->setSelected(true); - } - } - return true; -} -}; - -void Scene_BrushSelectByShader(scene::Graph &graph, const char *name) -{ - graph.traverse(BrushSelectByShaderWalker(name)); -} - -void Scene_BrushSelectByShader_Component(scene::Graph &graph, const char *name) -{ - Scene_ForEachSelectedBrush_ForEachFaceInstance(graph, [&](FaceInstance &face) { - printf("checking %s = %s\n", face.getFace().GetShader(), name); - if (shader_equal(face.getFace().GetShader(), name)) { - face.setSelected(SelectionSystem::eFace, true); - } - }); -} - -void Scene_BrushGetTexdef_Selected(scene::Graph &graph, TextureProjection &projection) -{ - bool done = false; - Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) { - if (!done) { - done = true; - face.GetTexdef(projection); - } - }); -} - -void Scene_BrushGetTexdef_Component_Selected(scene::Graph &graph, TextureProjection &projection) -{ -#if 1 - if (!g_SelectedFaceInstances.empty()) { - FaceInstance &faceInstance = g_SelectedFaceInstances.last(); - faceInstance.getFace().GetTexdef(projection); - } -#else - FaceGetTexdef visitor( projection ); - Scene_ForEachSelectedBrushFace( graph, visitor ); -#endif -} - -void Scene_BrushGetShaderSize_Component_Selected(scene::Graph &graph, size_t &width, size_t &height) -{ - if (!g_SelectedFaceInstances.empty()) { - FaceInstance &faceInstance = g_SelectedFaceInstances.last(); - width = faceInstance.getFace().getShader().width(); - height = faceInstance.getFace().getShader().height(); - } -} - - -void Scene_BrushGetFlags_Selected(scene::Graph &graph, ContentsFlagsValue &flags) -{ -#if 1 - if (GlobalSelectionSystem().countSelected() != 0) { - BrushInstance *brush = Instance_getBrush(GlobalSelectionSystem().ultimateSelected()); - if (brush != 0) { - bool done = false; - Brush_forEachFace(*brush, [&](Face &face) { - if (!done) { - done = true; - face.GetFlags(flags); - } - }); - } - } -#else - Scene_ForEachSelectedBrush_ForEachFace( graph, FaceGetFlags( flags ) ); -#endif -} - -void Scene_BrushGetFlags_Component_Selected(scene::Graph &graph, ContentsFlagsValue &flags) -{ -#if 1 - if (!g_SelectedFaceInstances.empty()) { - FaceInstance &faceInstance = g_SelectedFaceInstances.last(); - faceInstance.getFace().GetFlags(flags); - } -#else - Scene_ForEachSelectedBrushFace( graph, FaceGetFlags( flags ) ); -#endif -} - - -void Scene_BrushGetShader_Selected(scene::Graph &graph, CopiedString &shader) -{ -#if 1 - if (GlobalSelectionSystem().countSelected() != 0) { - BrushInstance *brush = Instance_getBrush(GlobalSelectionSystem().ultimateSelected()); - if (brush != 0) { - bool done = false; - Brush_forEachFace(*brush, [&](Face &face) { - if (!done) { - done = true; - shader = face.GetShader(); - } - }); - } - } -#else - Scene_ForEachSelectedBrush_ForEachFace( graph, FaceGetShader( shader ) ); -#endif -} - -void Scene_BrushGetShader_Component_Selected(scene::Graph &graph, CopiedString &shader) -{ -#if 1 - if (!g_SelectedFaceInstances.empty()) { - FaceInstance &faceInstance = g_SelectedFaceInstances.last(); - shader = faceInstance.getFace().GetShader(); - } -#else - FaceGetShader visitor( shader ); - Scene_ForEachSelectedBrushFace( graph, visitor ); -#endif -} - - -class filter_face_shader : public FaceFilter { -const char *m_shader; -public: -filter_face_shader(const char *shader) : m_shader(shader) -{ -} - -bool filter(const Face &face) const -{ - return shader_equal(face.GetShader(), m_shader); -} -}; - -class filter_face_shader_prefix : public FaceFilter { -const char *m_prefix; -public: -filter_face_shader_prefix(const char *prefix) : m_prefix(prefix) -{ -} - -bool filter(const Face &face) const -{ - return shader_equal_n(face.GetShader(), m_prefix, strlen(m_prefix)); -} -}; - -class filter_face_flags : public FaceFilter { -int m_flags; -public: -filter_face_flags(int flags) : m_flags(flags) -{ -} - -bool filter(const Face &face) const -{ - return (face.getShader().shaderFlags() & m_flags) != 0; -} -}; - -class filter_face_contents : public FaceFilter { -int m_contents; -public: -filter_face_contents(int contents) : m_contents(contents) -{ -} - -bool filter(const Face &face) const -{ - return (face.getShader().m_flags.m_contentFlags & m_contents) != 0; -} -}; - - -class filter_brush_any_face : public BrushFilter { -FaceFilter *m_filter; -public: -filter_brush_any_face(FaceFilter *filter) : m_filter(filter) -{ -} - -bool filter(const Brush &brush) const -{ - bool filtered = false; - Brush_forEachFace(brush, [&](Face &face) { - if (m_filter->filter(face)) { - filtered = true; - } - }); - return filtered; -} -}; - -class filter_brush_all_faces : public BrushFilter { -FaceFilter *m_filter; -public: -filter_brush_all_faces(FaceFilter *filter) : m_filter(filter) -{ -} - -bool filter(const Brush &brush) const -{ - bool filtered = true; - Brush_forEachFace(brush, [&](Face &face) { - if (!m_filter->filter(face)) { - filtered = false; - } - }); - return filtered; -} -}; - - -filter_face_flags g_filter_face_clip(QER_CLIP); -filter_brush_all_faces g_filter_brush_clip(&g_filter_face_clip); - -filter_face_shader g_filter_face_clip_q2("textures/clip"); -filter_brush_all_faces g_filter_brush_clip_q2(&g_filter_face_clip_q2); - -filter_face_shader g_filter_face_weapclip("textures/common/weapclip"); -filter_brush_all_faces g_filter_brush_weapclip(&g_filter_face_weapclip); - -filter_face_shader g_filter_face_commonclip("textures/common/clip"); -filter_brush_all_faces g_filter_brush_commonclip(&g_filter_face_commonclip); - -filter_face_shader g_filter_face_fullclip("textures/common/fullclip"); -filter_brush_all_faces g_filter_brush_fullclip(&g_filter_face_fullclip); - -filter_face_shader g_filter_face_botclip("textures/common/botclip"); -filter_brush_all_faces g_filter_brush_botclip(&g_filter_face_botclip); - -filter_face_shader_prefix g_filter_face_caulk("textures/common/caulk"); -filter_brush_all_faces g_filter_brush_caulk(&g_filter_face_caulk); - -filter_face_shader_prefix g_filter_face_caulk_ja("textures/system/caulk"); -filter_brush_all_faces g_filter_brush_caulk_ja(&g_filter_face_caulk_ja); - -filter_face_shader_prefix g_filter_face_liquids("textures/liquids/"); -filter_brush_any_face g_filter_brush_liquids(&g_filter_face_liquids); - -filter_face_shader g_filter_face_hint("textures/common/hint"); -filter_brush_any_face g_filter_brush_hint(&g_filter_face_hint); - -filter_face_shader g_filter_face_hint_q2("textures/hint"); -filter_brush_any_face g_filter_brush_hint_q2(&g_filter_face_hint_q2); - -filter_face_shader g_filter_face_hint_ja("textures/system/hint"); -filter_brush_any_face g_filter_brush_hint_ja(&g_filter_face_hint_ja); - -filter_face_shader g_filter_face_areaportal("textures/common/areaportal"); -filter_brush_all_faces g_filter_brush_areaportal(&g_filter_face_areaportal); - -filter_face_shader g_filter_face_visportal("textures/editor/visportal"); -filter_brush_any_face g_filter_brush_visportal(&g_filter_face_visportal); - -filter_face_shader g_filter_face_clusterportal("textures/common/clusterportal"); -filter_brush_all_faces g_filter_brush_clusterportal(&g_filter_face_clusterportal); - -filter_face_shader g_filter_face_lightgrid("textures/common/lightgrid"); -filter_brush_all_faces g_filter_brush_lightgrid(&g_filter_face_lightgrid); - -filter_face_flags g_filter_face_translucent(QER_TRANS); -filter_brush_all_faces g_filter_brush_translucent(&g_filter_face_translucent); - -filter_face_contents g_filter_face_detail(BRUSH_DETAIL_MASK); -filter_brush_all_faces g_filter_brush_detail(&g_filter_face_detail); - -filter_face_shader_prefix g_filter_face_decals("textures/decals/"); -filter_brush_any_face g_filter_brush_decals(&g_filter_face_decals); - - -void BrushFilters_construct() -{ - add_brush_filter(g_filter_brush_clip, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_clip_q2, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_weapclip, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_fullclip, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_commonclip, EXCLUDE_CLIP); - add_brush_filter(g_filter_brush_botclip, EXCLUDE_BOTCLIP); - add_brush_filter(g_filter_brush_caulk, EXCLUDE_CAULK); - add_brush_filter(g_filter_brush_caulk_ja, EXCLUDE_CAULK); - add_face_filter(g_filter_face_caulk, EXCLUDE_CAULK); - add_face_filter(g_filter_face_caulk_ja, EXCLUDE_CAULK); - add_brush_filter(g_filter_brush_liquids, EXCLUDE_LIQUIDS); - add_brush_filter(g_filter_brush_hint, EXCLUDE_HINTSSKIPS); - add_brush_filter(g_filter_brush_hint_q2, EXCLUDE_HINTSSKIPS); - add_brush_filter(g_filter_brush_hint_ja, EXCLUDE_HINTSSKIPS); - add_brush_filter(g_filter_brush_clusterportal, EXCLUDE_CLUSTERPORTALS); - add_brush_filter(g_filter_brush_visportal, EXCLUDE_VISPORTALS); - add_brush_filter(g_filter_brush_areaportal, EXCLUDE_AREAPORTALS); - add_brush_filter(g_filter_brush_translucent, EXCLUDE_TRANSLUCENT); - add_brush_filter(g_filter_brush_detail, EXCLUDE_DETAILS); - add_brush_filter(g_filter_brush_detail, EXCLUDE_STRUCTURAL, true); - add_brush_filter(g_filter_brush_lightgrid, EXCLUDE_LIGHTGRID); - add_brush_filter(g_filter_brush_decals, EXCLUDE_DECALS); -} - -#if 0 - -void normalquantisation_draw(){ - glPointSize( 1 ); - glBegin( GL_POINTS ); - for ( std::size_t i = 0; i <= c_quantise_normal; ++i ) - { - for ( std::size_t j = 0; j <= c_quantise_normal; ++j ) - { - Normal3f vertex( normal3f_normalised( Normal3f( - static_cast( c_quantise_normal - j - i ), - static_cast( i ), - static_cast( j ) - ) ) ); - VectorScale( normal3f_to_array( vertex ), 64.f, normal3f_to_array( vertex ) ); - glVertex3fv( normal3f_to_array( vertex ) ); - vertex.x = -vertex.x; - glVertex3fv( normal3f_to_array( vertex ) ); - } - } - glEnd(); -} - -class RenderableNormalQuantisation : public OpenGLRenderable -{ -public: -void render( RenderStateFlags state ) const { - normalquantisation_draw(); -} -}; - -const float g_test_quantise_normal = 1.f / static_cast( 1 << 3 ); - -class TestNormalQuantisation -{ -void check_normal( const Normal3f& normal, const Normal3f& other ){ - spherical_t spherical = spherical_from_normal3f( normal ); - double longditude = RAD2DEG( spherical.longditude ); - double latitude = RAD2DEG( spherical.latitude ); - double x = cos( spherical.longditude ) * sin( spherical.latitude ); - double y = sin( spherical.longditude ) * sin( spherical.latitude ); - double z = cos( spherical.latitude ); - - ASSERT_MESSAGE( normal3f_dot( normal, other ) > 0.99, "bleh" ); -} - -void test_normal( const Normal3f& normal ){ - Normal3f test = normal3f_from_spherical( spherical_from_normal3f( normal ) ); - check_normal( normal, test ); - - EOctant octant = normal3f_classify_octant( normal ); - Normal3f folded = normal3f_fold_octant( normal, octant ); - ESextant sextant = normal3f_classify_sextant( folded ); - folded = normal3f_fold_sextant( folded, sextant ); - - double scale = static_cast( c_quantise_normal ) / ( folded.x + folded.y + folded.z ); - - double zbits = folded.z * scale; - double ybits = folded.y * scale; - - std::size_t zbits_q = static_cast( zbits ); - std::size_t ybits_q = static_cast( ybits ); - - ASSERT_MESSAGE( zbits_q <= ( c_quantise_normal / 8 ) * 3, "bleh" ); - ASSERT_MESSAGE( ybits_q <= ( c_quantise_normal / 2 ), "bleh" ); - ASSERT_MESSAGE( zbits_q + ( ( c_quantise_normal / 2 ) - ybits_q ) <= ( c_quantise_normal / 2 ), "bleh" ); - - std::size_t y_t = ( zbits_q < ( c_quantise_normal / 4 ) ) ? ybits_q : ( c_quantise_normal / 2 ) - ybits_q; - std::size_t z_t = ( zbits_q < ( c_quantise_normal / 4 ) ) ? zbits_q : ( c_quantise_normal / 2 ) - zbits_q; - std::size_t index = ( c_quantise_normal / 4 ) * y_t + z_t; - ASSERT_MESSAGE( index <= ( c_quantise_normal / 4 ) * ( c_quantise_normal / 2 ), "bleh" ); - - Normal3f tmp( c_quantise_normal - zbits_q - ybits_q, ybits_q, zbits_q ); - tmp = normal3f_normalised( tmp ); - - Normal3f unfolded = normal3f_unfold_octant( normal3f_unfold_sextant( tmp, sextant ), octant ); - - check_normal( normal, unfolded ); - - double dot = normal3f_dot( normal, unfolded ); - float length = VectorLength( normal3f_to_array( unfolded ) ); - float inv_length = 1 / length; - - Normal3f quantised = normal3f_quantised( normal ); - check_normal( normal, quantised ); -} -void test2( const Normal3f& normal, const Normal3f& other ){ - if ( normal3f_quantised( normal ) != normal3f_quantised( other ) ) { - int bleh = 0; - } -} - -static Normal3f normalise( float x, float y, float z ){ - return normal3f_normalised( Normal3f( x, y, z ) ); -} - -float vec_rand(){ - return static_cast( rand() - ( RAND_MAX / 2 ) ); -} - -Normal3f normal3f_rand(){ - return normalise( vec_rand(), vec_rand(), vec_rand() ); -} - -public: -TestNormalQuantisation(){ - for ( int i = 4096; i > 0; --i ) - test_normal( normal3f_rand() ); - - test_normal( normalise( 1, 0, 0 ) ); - test_normal( normalise( 0, 1, 0 ) ); - test_normal( normalise( 0, 0, 1 ) ); - test_normal( normalise( 1, 1, 0 ) ); - test_normal( normalise( 1, 0, 1 ) ); - test_normal( normalise( 0, 1, 1 ) ); - - test_normal( normalise( 10000, 10000, 10000 ) ); - test_normal( normalise( 10000, 10000, 10001 ) ); - test_normal( normalise( 10000, 10000, 10002 ) ); - test_normal( normalise( 10000, 10000, 10010 ) ); - test_normal( normalise( 10000, 10000, 10020 ) ); - test_normal( normalise( 10000, 10000, 10030 ) ); - test_normal( normalise( 10000, 10000, 10100 ) ); - test_normal( normalise( 10000, 10000, 10101 ) ); - test_normal( normalise( 10000, 10000, 10102 ) ); - test_normal( normalise( 10000, 10000, 10200 ) ); - test_normal( normalise( 10000, 10000, 10201 ) ); - test_normal( normalise( 10000, 10000, 10202 ) ); - test_normal( normalise( 10000, 10000, 10203 ) ); - test_normal( normalise( 10000, 10000, 10300 ) ); - - - test2( normalise( 10000, 10000, 10000 ), normalise( 10000, 10000, 10001 ) ); - test2( normalise( 10000, 10000, 10001 ), normalise( 10000, 10001, 10000 ) ); -} -}; - -TestNormalQuantisation g_testNormalQuantisation; - - -#endif - -#if 0 -class TestSelectableObserver : public observer_template -{ -public: -void notify( const Selectable& arguments ){ - bool bleh = arguments.isSelected(); -} -}; - -inline void test_bleh(){ - TestSelectableObserver test; - ObservableSelectableInstance< SingleObservable< SelectionChangeCallback > > bleh; - bleh.attach( test ); - bleh.setSelected( true ); - bleh.detach( test ); -} - -class TestBleh -{ -public: -TestBleh(){ - test_bleh(); -} -}; - -const TestBleh testbleh; -#endif - - -#if 0 -class TestRefcountedString -{ -public: -TestRefcountedString(){ - { - // copy construct - SmartString string1( "string1" ); - SmartString string2( string1 ); - SmartString string3( string2 ); - } - { - // refcounted assignment - SmartString string1( "string1" ); - SmartString string2( "string2" ); - string1 = string2; - } - { - // copy assignment - SmartString string1( "string1" ); - SmartString string2( "string2" ); - string1 = string2.c_str(); - } - { - // self-assignment - SmartString string1( "string1" ); - string1 = string1; - } - { - // self-assignment via another reference - SmartString string1( "string1" ); - SmartString string2( string1 ); - string1 = string2; - } -} -}; - -const TestRefcountedString g_testRefcountedString; - -#endif - -void Select_MakeDetail() -{ - UndoableCommand undo("brushSetDetail"); - Scene_BrushSetDetail_Selected(GlobalSceneGraph(), true); -} - -void Select_MakeStructural() -{ - UndoableCommand undo("brushClearDetail"); - Scene_BrushSetDetail_Selected(GlobalSceneGraph(), false); -} - -class BrushMakeSided { -std::size_t m_count; -public: -BrushMakeSided(std::size_t count) - : m_count(count) -{ -} - -void set() -{ - Scene_BrushConstructPrefab(GlobalSceneGraph(), eBrushPrism, m_count, - TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); -} - -typedef MemberCaller SetCaller; -}; - - -BrushMakeSided g_brushmakesided3(3); -BrushMakeSided g_brushmakesided4(4); -BrushMakeSided g_brushmakesided5(5); -BrushMakeSided g_brushmakesided6(6); -BrushMakeSided g_brushmakesided7(7); -BrushMakeSided g_brushmakesided8(8); -BrushMakeSided g_brushmakesided9(9); - -inline int axis_for_viewtype(int viewtype) -{ - switch (viewtype) { - case XY: - return 2; - case XZ: - return 1; - case YZ: - return 0; - } - return 2; -} - -class BrushPrefab { -EBrushPrefab m_type; -public: -BrushPrefab(EBrushPrefab type) - : m_type(type) -{ -} - -void set() -{ - DoSides(m_type, axis_for_viewtype(GetViewAxis())); -} - -typedef MemberCaller SetCaller; -}; - -BrushPrefab g_brushprism(eBrushPrism); -BrushPrefab g_brushcone(eBrushCone); -BrushPrefab g_brushsphere(eBrushSphere); -BrushPrefab g_brushrock(eBrushRock); - - -void FlipClip(); - -void SplitClip(); - -void Clip(); - -void OnClipMode(bool enable); - -bool ClipMode(); - - -void ClipSelected() -{ - if (ClipMode()) { - UndoableCommand undo("clipperClip"); - Clip(); - } -} - -void SplitSelected() -{ - if (ClipMode()) { - UndoableCommand undo("clipperSplit"); - SplitClip(); - } -} - -void FlipClipper() -{ - FlipClip(); -} - - -Callback g_texture_lock_status_changed; -ConstReferenceCaller &), PropertyImpl::Export> g_texdef_movelock_caller( - g_brush_texturelock_enabled); -ToggleItem g_texdef_movelock_item(g_texdef_movelock_caller); - -void Texdef_ToggleMoveLock() -{ - g_brush_texturelock_enabled = !g_brush_texturelock_enabled; - g_texdef_movelock_item.update(); - g_texture_lock_status_changed(); -} - - -void Brush_registerCommands() -{ - GlobalToggles_insert("TogTexLock", makeCallbackF(Texdef_ToggleMoveLock), - ToggleItem::AddCallbackCaller(g_texdef_movelock_item), - Accelerator('T', (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalCommands_insert("BrushPrism", BrushPrefab::SetCaller(g_brushprism)); - GlobalCommands_insert("BrushCone", BrushPrefab::SetCaller(g_brushcone)); - GlobalCommands_insert("BrushSphere", BrushPrefab::SetCaller(g_brushsphere)); - GlobalCommands_insert("BrushRock", BrushPrefab::SetCaller(g_brushrock)); - - GlobalCommands_insert("Brush3Sided", BrushMakeSided::SetCaller(g_brushmakesided3), - Accelerator('3', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush4Sided", BrushMakeSided::SetCaller(g_brushmakesided4), - Accelerator('4', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush5Sided", BrushMakeSided::SetCaller(g_brushmakesided5), - Accelerator('5', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush6Sided", BrushMakeSided::SetCaller(g_brushmakesided6), - Accelerator('6', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush7Sided", BrushMakeSided::SetCaller(g_brushmakesided7), - Accelerator('7', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush8Sided", BrushMakeSided::SetCaller(g_brushmakesided8), - Accelerator('8', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Brush9Sided", BrushMakeSided::SetCaller(g_brushmakesided9), - Accelerator('9', (GdkModifierType) GDK_CONTROL_MASK)); - - GlobalCommands_insert("ClipSelected", makeCallbackF(ClipSelected), Accelerator(GDK_KEY_Return)); - GlobalCommands_insert("SplitSelected", makeCallbackF(SplitSelected), - Accelerator(GDK_KEY_Return, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("FlipClip", makeCallbackF(FlipClipper), - Accelerator(GDK_KEY_Return, (GdkModifierType) GDK_CONTROL_MASK)); - - GlobalCommands_insert("MakeDetail", makeCallbackF(Select_MakeDetail), - Accelerator('M', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("MakeStructural", makeCallbackF(Select_MakeStructural), - Accelerator('S', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); -} - -void Brush_constructMenu(ui::Menu menu) -{ - create_menu_item_with_mnemonic(menu, "Prism...", "BrushPrism"); - create_menu_item_with_mnemonic(menu, "Cone...", "BrushCone"); - create_menu_item_with_mnemonic(menu, "Sphere...", "BrushSphere"); - create_menu_item_with_mnemonic(menu, "Rock...", "BrushRock"); - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "CSG"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Make _Hollow", "CSGMakeHollow"); - create_menu_item_with_mnemonic(menu_in_menu, "Make _Room", "CSGMakeRoom"); - create_menu_item_with_mnemonic(menu_in_menu, "CSG _Subtract", "CSGSubtract"); - create_menu_item_with_mnemonic(menu_in_menu, "CSG _Merge", "CSGMerge"); - } - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Clipper"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - - create_menu_item_with_mnemonic(menu_in_menu, "Clip selection", "ClipSelected"); - create_menu_item_with_mnemonic(menu_in_menu, "Split selection", "SplitSelected"); - create_menu_item_with_mnemonic(menu_in_menu, "Flip Clip orientation", "FlipClip"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Make detail", "MakeDetail"); - create_menu_item_with_mnemonic(menu, "Make structural", "MakeStructural"); - create_menu_item_with_mnemonic(menu, "Snap selection to _grid", "SnapToGrid"); - - create_check_menu_item_with_mnemonic(menu, "Texture Lock", "TogTexLock"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Copy Face Texture", "FaceCopyTexture"); - create_menu_item_with_mnemonic(menu, "Paste Face Texture", "FacePasteTexture"); - - command_connect_accelerator("Brush3Sided"); - command_connect_accelerator("Brush4Sided"); - command_connect_accelerator("Brush5Sided"); - command_connect_accelerator("Brush6Sided"); - command_connect_accelerator("Brush7Sided"); - command_connect_accelerator("Brush8Sided"); - command_connect_accelerator("Brush9Sided"); -} diff --git a/src/brushmanip.h b/src/brushmanip.h deleted file mode 100644 index 0ac2c65..0000000 --- a/src/brushmanip.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_BRUSHWRAPPER_H ) -#define INCLUDED_BRUSHWRAPPER_H - -#include -#include -#include "string/stringfwd.h" -#include "generic/callback.h" - -enum EBrushPrefab { - eBrushCuboid, - eBrushPrism, - eBrushCone, - eBrushSphere, - eBrushRock, -}; - -class TextureProjection; - -class ContentsFlagsValue; -namespace scene { -class Graph; -} - -void Scene_BrushConstructPrefab(scene::Graph &graph, EBrushPrefab type, std::size_t sides, const char *shader); - -class AABB; - -void Scene_BrushResize_Selected(scene::Graph &graph, const AABB &bounds, const char *shader); - -void Scene_BrushSetTexdef_Selected(scene::Graph &graph, const TextureProjection &projection, bool ignorebasis); - -void Scene_BrushSetTexdef_Component_Selected(scene::Graph &graph, const TextureProjection &projection, bool ignorebasis); - -void Scene_BrushGetTexdef_Selected(scene::Graph &graph, TextureProjection &projection); - -void Scene_BrushGetTexdef_Component_Selected(scene::Graph &graph, TextureProjection &projection); - -void Scene_BrushGetShaderSize_Component_Selected(scene::Graph &graph, size_t &width, size_t &height); - -void Scene_BrushSetFlags_Selected(scene::Graph &graph, const ContentsFlagsValue &flags); - -void Scene_BrushSetFlags_Component_Selected(scene::Graph &graph, const ContentsFlagsValue &flags); - -void Scene_BrushGetFlags_Selected(scene::Graph &graph, ContentsFlagsValue &flags); - -void Scene_BrushGetFlags_Component_Selected(scene::Graph &graph, ContentsFlagsValue &flags); - -void Scene_BrushShiftTexdef_Selected(scene::Graph &graph, float s, float t); - -void Scene_BrushShiftTexdef_Component_Selected(scene::Graph &graph, float s, float t); - -void Scene_BrushScaleTexdef_Selected(scene::Graph &graph, float s, float t); - -void Scene_BrushScaleTexdef_Component_Selected(scene::Graph &graph, float s, float t); - -void Scene_BrushRotateTexdef_Selected(scene::Graph &graph, float angle); - -void Scene_BrushRotateTexdef_Component_Selected(scene::Graph &graph, float angle); - -void Scene_BrushSetShader_Selected(scene::Graph &graph, const char *name); - -void Scene_BrushSetShader_Component_Selected(scene::Graph &graph, const char *name); - -void Scene_BrushGetShader_Selected(scene::Graph &graph, CopiedString &shader); - -void Scene_BrushGetShader_Component_Selected(scene::Graph &graph, CopiedString &shader); - -void Scene_BrushFindReplaceShader(scene::Graph &graph, const char *find, const char *replace); - -void Scene_BrushFindReplaceShader_Selected(scene::Graph &graph, const char *find, const char *replace); - -void Scene_BrushFindReplaceShader_Component_Selected(scene::Graph &graph, const char *find, const char *replace); - -void Scene_BrushSelectByShader(scene::Graph &graph, const char *name); - -void Scene_BrushSelectByShader_Component(scene::Graph &graph, const char *name); - -void Scene_BrushFitTexture_Selected(scene::Graph &graph, float s_repeat, float t_repeat); - -void Scene_BrushFitTexture_Component_Selected(scene::Graph &graph, float s_repeat, float t_repeat); - -void Scene_BrushAlignTexture_Selected(scene::Graph &graph, int alignment); -void Scene_BrushAlignTexture_Component_Selected(scene::Graph &graph, int alignment); - -void Brush_constructMenu(ui::Menu menu); - -extern Callback g_texture_lock_status_changed; - -void BrushFilters_construct(); - -void Brush_registerCommands(); - -#endif diff --git a/src/brushmodule.cpp b/src/brushmodule.cpp deleted file mode 100644 index c9acb28..0000000 --- a/src/brushmodule.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushmodule.h" - -#include "qerplugin.h" - -#include "brushnode.h" -#include "brushmanip.h" - -#include "preferencesystem.h" -#include "stringio.h" - -#include "map.h" -#include "qe3.h" -#include "mainframe.h" -#include "preferences.h" - -LatchedValue g_useAlternativeTextureProjection(false, "Use alternative texture-projection (\"brush primitives\")"); -static int g_numbrushtypes = 0; -static int g_selectedbrushtype; -static EBrushType g_brushTypes[8], g_brushType; -//bool g_showAlternativeTextureProjectionOption = false; -bool g_brush_always_caulk = true; - -bool getTextureLockEnabled() -{ - return g_brush_texturelock_enabled; -} - -struct Face_SnapPlanes { - static void Export(const QuantiseFunc &self, const Callback &returnz) - { - returnz(self == quantiseInteger); - } - - static void Import(QuantiseFunc &self, bool value) - { - self = value ? quantiseInteger : quantiseFloating; - } -}; - -const char* BrushType_getName( EBrushType type ){ - switch ( type ) - { - case eBrushTypeQuake: - case eBrushTypeQuake2: - case eBrushTypeQuake3: - return "Axial Projection"; - case eBrushTypeQuake3BP: - return "Brush Primitives"; - case eBrushTypeQuake3Valve: - case eBrushTypeHalfLife: - return "Valve 220"; - case eBrushTypeDoom3: - return "Doom3"; - case eBrushTypeQuake4: - return "Quake4"; - default: - return "unknown"; - } -} - -void Brush_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox( - "", "Snap planes to integer grid", - make_property(Face::m_quantise) - ); - page.appendEntry( - "Default texture scale", - g_texdef_default_scale - ); - if (g_numbrushtypes > 1) { - const char *names[8]; - for(int i = 0; i < g_numbrushtypes; i++) - names[i] = BrushType_getName(g_brushTypes[i]); - page.appendCombo("Default Brush Type", g_selectedbrushtype, StringArrayRange(names, names+g_numbrushtypes)); - } - // d1223m - page.appendCheckBox("", - "Always use caulk for new brushes", - g_brush_always_caulk - ); -} - -void Brush_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Brush", "Brush Settings")); - Brush_constructPreferences(page); -} - -void Brush_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Brush_constructPage)); -} - -void Brush_unlatchPreferences() -{ - Brush_toggleFormat(0); -} - -void Brush_setFormat(EBrushType t) -{ - if (g_numbrushtypes) { -// g_useAlternativeTextureProjection.m_value = g_useAlternativeTextureProjection.m_latched ^ i; - Brush::destroyStatic(); - g_brushType = t; - Brush::constructStatic(t); - } -} -void Brush_toggleFormat(int i) -{ - if (g_numbrushtypes) { -// g_useAlternativeTextureProjection.m_value = g_useAlternativeTextureProjection.m_latched ^ i; - Brush::destroyStatic(); - g_brushType = g_brushTypes[i]; - Brush::constructStatic(g_brushType); - } -} - -int Brush_toggleFormatCount() -{ - if (g_numbrushtypes) { - return g_numbrushtypes; - } - return 1; -} - -static void Brush_Construct(void) -{ - EBrushType type = g_brushType = g_brushTypes[g_selectedbrushtype]; - - // d1223m - GlobalPreferenceSystem().registerPreference( - "BrushAlwaysCaulk", - make_property_string(g_brush_always_caulk) - ); - - Brush_registerCommands(); - Brush_registerPreferencesPage(); - - BrushFilters_construct(); - - BrushClipPlane::constructStatic(); - BrushInstance::constructStatic(); - Brush::constructStatic(type); - - Brush::m_maxWorldCoord = g_MaxWorldCoord; - BrushInstance::m_counter = &g_brushCount; - - g_texdef_default_scale = 0.5f; - const char *value = g_pGameDescription->getKeyValue("default_scale"); - if (!string_empty(value)) { - float scale = static_cast( atof(value)); - if (scale != 0) { - g_texdef_default_scale = scale; - } else { - globalErrorStream() << "error parsing \"default_scale\" attribute\n"; - } - } - - GlobalPreferenceSystem().registerPreference("TextureLock", make_property_string(g_brush_texturelock_enabled)); - GlobalPreferenceSystem().registerPreference("BrushSnapPlanes", - make_property_string(Face::m_quantise)); - GlobalPreferenceSystem().registerPreference("TexdefDefaultScale", make_property_string(g_texdef_default_scale)); - - GridStatus_getTextureLockEnabled = getTextureLockEnabled; - g_texture_lock_status_changed = makeCallbackF(GridStatus_onTextureLockEnabledChanged); -} -static void Brush_Construct(EBrushType type0, EBrushType type1, EBrushType type2) -{ - g_numbrushtypes = 0; - g_brushTypes[g_numbrushtypes++] = type0; - if (type1 != type0) - g_brushTypes[g_numbrushtypes++] = type1; - if (type2 != type0 && type2 != type1) - g_brushTypes[g_numbrushtypes++] = type2; - - if (g_numbrushtypes) { - const char *value = g_pGameDescription->getKeyValue("brush_primit"); - if (!string_empty(value)) { - g_selectedbrushtype = atoi(value); - if (g_selectedbrushtype < 0 || g_selectedbrushtype >= g_numbrushtypes) - g_selectedbrushtype = 0; - } - -// GlobalPreferenceSystem().registerPreference( -// "BrushType", -// make_property(g_selectedbrushtype) -// ); - } - - Brush_Construct(); -} -static void Brush_Construct(EBrushType type0, EBrushType type1) -{ - Brush_Construct(type0, type1, type0); -} -static void Brush_Construct(EBrushType type0) -{ - Brush_Construct(type0, type0, type0); -} - -void Brush_Destroy() -{ - Brush::m_maxWorldCoord = 0; - BrushInstance::m_counter = 0; - - Brush::destroyStatic(); - BrushInstance::destroyStatic(); - BrushClipPlane::destroyStatic(); -} - -void Brush_clipperColourChanged() -{ - BrushClipPlane::destroyStatic(); - BrushClipPlane::constructStatic(); -} - -void BrushFaceData_fromFace(const BrushFaceDataCallback &callback, Face &face) -{ - _QERFaceData faceData; - faceData.m_p0 = face.getPlane().planePoints()[0]; - faceData.m_p1 = face.getPlane().planePoints()[1]; - faceData.m_p2 = face.getPlane().planePoints()[2]; - faceData.m_shader = face.GetShader(); - faceData.m_texdef = face.getTexdef().m_projection.m_texdef; - faceData.contents = face.getShader().m_flags.m_contentFlags; - faceData.flags = face.getShader().m_flags.m_surfaceFlags; - faceData.value = face.getShader().m_flags.m_value; - callback(faceData); -} - -typedef ConstReferenceCaller BrushFaceDataFromFaceCaller; -typedef Callback FaceCallback; - -class Quake3BrushCreator : public BrushCreator { -public: -scene::Node &createBrush() -{ - return (new BrushNode)->node(); -} - -virtual EBrushType getBrushType() -{ - return g_brushType; -} -virtual void setBrushType(EBrushType t) -{ - if (g_brushType != t) - Brush_setFormat(t); -} - -void Brush_forEachFace(scene::Node &brush, const BrushFaceDataCallback &callback) -{ - ::Brush_forEachFace(*Node_getBrush(brush), FaceCallback(BrushFaceDataFromFaceCaller(callback))); -} - -bool Brush_addFace(scene::Node &brush, const _QERFaceData &faceData) -{ - Node_getBrush(brush)->undoSave(); - return Node_getBrush(brush)->addPlane(faceData.m_p0, faceData.m_p1, faceData.m_p2, faceData.m_shader, - TextureProjection(faceData.m_texdef, brushprimit_texdef_t(), - Vector3(0, 0, 0), Vector3(0, 0, 0))) != 0; -} -}; - -Quake3BrushCreator g_Quake3BrushCreator; - -BrushCreator &GetBrushCreator() -{ - return g_Quake3BrushCreator; -} - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - - -class BrushDependencies : - public GlobalRadiantModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalFilterModuleRef { -}; - -class BrushDoom3API : public TypeSystemRef { -BrushCreator *m_brushdoom3; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "doom3"); - -BrushDoom3API() -{ - Brush_Construct(eBrushTypeDoom3); - - m_brushdoom3 = &GetBrushCreator(); -} - -~BrushDoom3API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushdoom3; -} -}; - -typedef SingletonModule BrushDoom3Module; -typedef Static StaticBrushDoom3Module; -StaticRegisterModule staticRegisterBrushDoom3(StaticBrushDoom3Module::instance()); - - -class BrushQuake4API : public TypeSystemRef { -BrushCreator *m_brushquake4; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "quake4"); - -BrushQuake4API() -{ - Brush_Construct(eBrushTypeQuake4); - - m_brushquake4 = &GetBrushCreator(); -} - -~BrushQuake4API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushquake4; -} -}; - -typedef SingletonModule BrushQuake4Module; -typedef Static StaticBrushQuake4Module; -StaticRegisterModule staticRegisterBrushQuake4(StaticBrushQuake4Module::instance()); - - -class BrushQuake3API : public TypeSystemRef { -BrushCreator *m_brushquake3; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "quake3"); - -BrushQuake3API() -{ - Brush_Construct(eBrushTypeQuake3, eBrushTypeQuake3BP, eBrushTypeQuake3Valve); - - m_brushquake3 = &GetBrushCreator(); -} - -~BrushQuake3API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushquake3; -} -}; - -typedef SingletonModule BrushQuake3Module; -typedef Static StaticBrushQuake3Module; -StaticRegisterModule staticRegisterBrushQuake3(StaticBrushQuake3Module::instance()); - - -class BrushQuake2API : public TypeSystemRef { -BrushCreator *m_brushquake2; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "quake2"); - -BrushQuake2API() -{ - Brush_Construct(eBrushTypeQuake2); - - m_brushquake2 = &GetBrushCreator(); -} - -~BrushQuake2API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushquake2; -} -}; - -typedef SingletonModule BrushQuake2Module; -typedef Static StaticBrushQuake2Module; -StaticRegisterModule staticRegisterBrushQuake2(StaticBrushQuake2Module::instance()); - - -class BrushQuake1API : public TypeSystemRef { -BrushCreator *m_brushquake1; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "quake"); - -BrushQuake1API() -{ - Brush_Construct(eBrushTypeQuake, eBrushTypeHalfLife); - - m_brushquake1 = &GetBrushCreator(); -} - -~BrushQuake1API() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushquake1; -} -}; - -typedef SingletonModule BrushQuake1Module; -typedef Static StaticBrushQuake1Module; -StaticRegisterModule staticRegisterBrushQuake1(StaticBrushQuake1Module::instance()); - - -class BrushHalfLifeAPI : public TypeSystemRef { -BrushCreator *m_brushhalflife; -public: -typedef BrushCreator Type; - -STRING_CONSTANT(Name, "halflife"); - -BrushHalfLifeAPI() -{ - Brush_Construct(eBrushTypeHalfLife); - - m_brushhalflife = &GetBrushCreator(); -} - -~BrushHalfLifeAPI() -{ - Brush_Destroy(); -} - -BrushCreator *getTable() -{ - return m_brushhalflife; -} -}; - -typedef SingletonModule BrushHalfLifeModule; -typedef Static StaticBrushHalfLifeModule; -StaticRegisterModule staticRegisterBrushHalfLife(StaticBrushHalfLifeModule::instance()); diff --git a/src/brushmodule.h b/src/brushmodule.h deleted file mode 100644 index 9501247..0000000 --- a/src/brushmodule.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSHMODULE_H ) -#define INCLUDED_BRUSHMODULE_H - -#include "brush.h" - -void Brush_clipperColourChanged(); - -void Brush_unlatchPreferences(); - -int Brush_toggleFormatCount(); - -void Brush_toggleFormat(int i); -void Brush_setFormat(EBrushType t); - -#endif diff --git a/src/brushnode.cpp b/src/brushnode.cpp deleted file mode 100644 index aed252d..0000000 --- a/src/brushnode.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushnode.h" diff --git a/src/brushnode.h b/src/brushnode.h deleted file mode 100644 index 2f20505..0000000 --- a/src/brushnode.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSHNODE_H ) -#define INCLUDED_BRUSHNODE_H - -#include "instancelib.h" -#include "brush.h" -#include "brushtokens.h" -#include "brushxml.h" - -class BrushNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Brush m_brush; -BrushTokenImporter m_mapImporter; -BrushTokenExporter m_mapExporter; -BrushXMLImporter m_xmlImporter; -BrushXMLExporter m_xmlExporter; - -public: - -typedef LazyStatic StaticTypeCasts; - -Snappable &get(NullType) -{ - return m_brush; -} - -TransformNode &get(NullType) -{ - return m_brush; -} - -Brush &get(NullType) -{ - return m_brush; -} - -XMLImporter &get(NullType) -{ - return m_xmlImporter; -} - -XMLExporter &get(NullType) -{ - return m_xmlExporter; -} - -MapImporter &get(NullType) -{ - return m_mapImporter; -} - -MapExporter &get(NullType) -{ - return m_mapExporter; -} - -Nameable &get(NullType) -{ - return m_brush; -} - -BrushDoom3 &get(NullType) -{ - return m_brush; -} - -BrushNode() : - m_node(this, this, StaticTypeCasts::instance().get()), - m_brush(m_node, InstanceSetEvaluateTransform::Caller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances)), - m_mapImporter(m_brush), - m_mapExporter(m_brush), - m_xmlImporter(m_brush), - m_xmlExporter(m_brush) -{ -} - -BrushNode(const BrushNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_brush(other.m_brush, m_node, InstanceSetEvaluateTransform::Caller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances)), - m_mapImporter(m_brush), - m_mapExporter(m_brush), - m_xmlImporter(m_brush), - m_xmlExporter(m_brush) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Node &clone() const -{ - return (new BrushNode(*this))->node(); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new BrushInstance(path, parent, m_brush); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -inline Brush *Node_getBrush(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -#endif diff --git a/src/brushtokens.cpp b/src/brushtokens.cpp deleted file mode 100644 index 3a3d970..0000000 --- a/src/brushtokens.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushtokens.h" diff --git a/src/brushtokens.h b/src/brushtokens.h deleted file mode 100644 index 554544b..0000000 --- a/src/brushtokens.h +++ /dev/null @@ -1,755 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSHTOKENS_H ) -#define INCLUDED_BRUSHTOKENS_H - -#include "stringio.h" -#include "stream/stringstream.h" -#include "brush.h" - -inline bool FaceShader_importContentsFlagsValue(FaceShader &faceShader, Tokeniser &tokeniser) -{ - //don't break if they're omitted. Yes, this might mean that it silently accepts quake-format maps where q3 maps were expected. - if (Tokeniser_nextTokenIsDigit(tokeniser)) - { - // parse the optional contents/flags/value - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, faceShader.m_flags.m_contentFlags)); - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, faceShader.m_flags.m_surfaceFlags)); - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, faceShader.m_flags.m_value)); - } - return true; -} - -inline bool FaceTexdef_HalfLife_importTokens(FaceTexdef &texdef, Tokeniser &tokeniser) -{ - // parse texdef - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "[")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_s.x())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_s.y())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_s.z())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "]")); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "[")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_t.x())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_t.y())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_t.z())); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[1])); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "]")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.rotate)); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[1])); - - texdef.m_projection.m_texdef.rotate = -texdef.m_projection.m_texdef.rotate; - - ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_importTokens: bad texdef"); - return true; -} - -inline bool FaceTexdef_importTokens(FaceTexdef &texdef, Tokeniser &tokeniser) -{ -/* //pass it on to halflife parsing if we unexpectedly find it in one of the other formats (blame J.A.C.K.) - const char* token = tokeniser.getToken(); - if ( token && *token == '[' ) - { - tokeniser.ungetToken(); - texdef.m_scaleApplied = true; - return FaceTexdef_HalfLife_importTokens(texdef, tokeniser); - } - tokeniser.ungetToken(); - */ - // parse texdef - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[1])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.rotate)); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[1])); - - ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_importTokens: bad texdef"); - return true; -} - -inline bool FaceTexdef_BP_importTokens(FaceTexdef &texdef, Tokeniser &tokeniser) -{ - // parse alternate texdef - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - { - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][1])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][2])); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - { - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][1])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][2])); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - return true; -} - -inline bool FacePlane_importTokens(FacePlane &facePlane, Tokeniser &tokeniser) -{ - // parse planepts - for (std::size_t i = 0; i < 3; i++) { - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - for (std::size_t j = 0; j < 3; ++j) { - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, facePlane.planePoints()[i][j])); - } - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - facePlane.MakePlane(); - return true; -} - -inline bool FacePlane_Doom3_importTokens(FacePlane &facePlane, Tokeniser &tokeniser) -{ - Plane3 plane; - // parse plane equation - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.a)); - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.b)); - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.c)); - RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.d)); - plane.d = -plane.d; - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - - facePlane.setDoom3Plane(plane); - return true; -} - -inline bool FaceShader_Doom3_importTokens(FaceShader &faceShader, Tokeniser &tokeniser) -{ - const char *shader = tokeniser.getToken(); - if (shader == 0) { - Tokeniser_unexpectedError(tokeniser, shader, "#shader-name"); - return false; - } - if (string_equal(shader, "_emptyname")) { - shader = texdef_name_default(); - } - faceShader.setShader(shader); - return true; -} - -inline bool FaceShader_importTokens(FaceShader &faceShader, Tokeniser &tokeniser) -{ - const char *texture = tokeniser.getToken(); - if (texture == 0) { - Tokeniser_unexpectedError(tokeniser, texture, "#texture-name"); - return false; - } - if (string_equal(texture, "NULL")) { - faceShader.setShader(texdef_name_default()); - } else { - StringOutputStream shader(string_length(GlobalTexturePrefix_get()) + string_length(texture)); - shader << GlobalTexturePrefix_get() << texture; - faceShader.setShader(shader.c_str()); - } - return true; -} - - -class Doom3FaceTokenImporter { -Face &m_face; -public: -Doom3FaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_Doom3_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_BP_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_Doom3_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - - m_face.getTexdef().m_projectionInitialised = true; - m_face.getTexdef().m_scaleApplied = true; - - return true; -} -}; - -class Quake4FaceTokenImporter { -Face &m_face; -public: -Quake4FaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_Doom3_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_BP_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_Doom3_importTokens(m_face.getShader(), tokeniser)); - - m_face.getTexdef().m_projectionInitialised = true; - m_face.getTexdef().m_scaleApplied = true; - - return true; -} -}; - -class Quake2FaceTokenImporter { -Face &m_face; -public: -Quake2FaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_importTokens(m_face.getTexdef(), tokeniser)); - if (Tokeniser_nextTokenIsDigit(tokeniser)) { - m_face.getShader().m_flags.m_specified = true; - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - } - m_face.getTexdef().m_scaleApplied = true; - return true; -} -}; - -class Quake3FaceTokenImporter { -Face &m_face; -public: -Quake3FaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - m_face.getTexdef().m_scaleApplied = true; - return true; -} -}; - -class Quake3BPFaceTokenImporter { -Face &m_face; -public: -Quake3BPFaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_BP_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - - m_face.getTexdef().m_projectionInitialised = true; - m_face.getTexdef().m_scaleApplied = true; - - return true; -} -}; - -class Quake3ValveFaceTokenImporter { -Face &m_face; -public: -Quake3ValveFaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_HalfLife_importTokens(m_face.getTexdef(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser)); - - m_face.getTexdef().m_scaleApplied = true; - - return true; -} -}; - -class QuakeFaceTokenImporter { -Face &m_face; -public: -QuakeFaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_importTokens(m_face.getTexdef(), tokeniser)); - m_face.getTexdef().m_scaleApplied = true; - return true; -} -}; - -class HalfLifeFaceTokenImporter { -Face &m_face; -public: -HalfLifeFaceTokenImporter(Face &face) : m_face(face) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser)); - RETURN_FALSE_IF_FAIL(FaceTexdef_HalfLife_importTokens(m_face.getTexdef(), tokeniser)); - m_face.getTexdef().m_scaleApplied = true; - return true; -} -}; - - -inline void FacePlane_Doom3_exportTokens(const FacePlane &facePlane, TokenWriter &writer) -{ - // write plane equation - writer.writeToken("("); - writer.writeFloat(facePlane.getDoom3Plane().a); - writer.writeFloat(facePlane.getDoom3Plane().b); - writer.writeFloat(facePlane.getDoom3Plane().c); - writer.writeFloat(-facePlane.getDoom3Plane().d); - writer.writeToken(")"); -} - -inline void FacePlane_exportTokens(const FacePlane &facePlane, TokenWriter &writer) -{ - // write planepts - for (std::size_t i = 0; i < 3; i++) { - writer.writeToken("("); - for (std::size_t j = 0; j < 3; j++) { - writer.writeFloat(Face::m_quantise(facePlane.planePoints()[i][j])); - } - writer.writeToken(")"); - } -} - -inline void FaceTexdef_BP_exportTokens(const FaceTexdef &faceTexdef, TokenWriter &writer) -{ - // write alternate texdef - writer.writeToken("("); - { - writer.writeToken("("); - for (std::size_t i = 0; i < 3; i++) { - writer.writeFloat(faceTexdef.m_projection.m_brushprimit_texdef.coords[0][i]); - } - writer.writeToken(")"); - } - { - writer.writeToken("("); - for (std::size_t i = 0; i < 3; i++) { - writer.writeFloat(faceTexdef.m_projection.m_brushprimit_texdef.coords[1][i]); - } - writer.writeToken(")"); - } - writer.writeToken(")"); -} - -inline void FaceTexdef_exportTokens(const FaceTexdef &faceTexdef, TokenWriter &writer) -{ - ASSERT_MESSAGE(texdef_sane(faceTexdef.m_projection.m_texdef), "FaceTexdef_exportTokens: bad texdef"); - // write texdef - writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[0]); - writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[1]); - writer.writeFloat(faceTexdef.m_projection.m_texdef.rotate); - writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[0]); - writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[1]); -} - -inline void FaceTexdef_HalfLife_exportTokens(const FaceTexdef &faceTexdef, TokenWriter &writer) -{ - ASSERT_MESSAGE(texdef_sane(faceTexdef.m_projection.m_texdef), "FaceTexdef_exportTokens: bad texdef"); - // write texdef - writer.writeToken("["); - writer.writeFloat(faceTexdef.m_projection.m_basis_s.x()); - writer.writeFloat(faceTexdef.m_projection.m_basis_s.y()); - writer.writeFloat(faceTexdef.m_projection.m_basis_s.z()); - writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[0]); - writer.writeToken("]"); - writer.writeToken("["); - writer.writeFloat(faceTexdef.m_projection.m_basis_t.x()); - writer.writeFloat(faceTexdef.m_projection.m_basis_t.y()); - writer.writeFloat(faceTexdef.m_projection.m_basis_t.z()); - writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[1]); - writer.writeToken("]"); - writer.writeFloat(-faceTexdef.m_projection.m_texdef.rotate); - writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[0]); - writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[1]); -} - -inline void FaceShader_ContentsFlagsValue_exportTokens(const FaceShader &faceShader, TokenWriter &writer) -{ - // write surface flags - writer.writeInteger(faceShader.m_flags.m_contentFlags); - writer.writeInteger(faceShader.m_flags.m_surfaceFlags); - writer.writeInteger(faceShader.m_flags.m_value); -} - -inline void FaceShader_exportTokens(const FaceShader &faceShader, TokenWriter &writer) -{ - // write shader name - if (string_empty(shader_get_textureName(faceShader.getShader()))) { - writer.writeToken("NULL"); - } else { - writer.writeToken(shader_get_textureName(faceShader.getShader())); - } -} - -inline void FaceShader_Doom3_exportTokens(const FaceShader &faceShader, TokenWriter &writer) -{ - // write shader name - if (string_empty(shader_get_textureName(faceShader.getShader()))) { - writer.writeString("_emptyname"); - } else { - writer.writeString(faceShader.getShader()); - } -} - -class Doom3FaceTokenExporter { -const Face &m_face; -public: -Doom3FaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_Doom3_exportTokens(m_face.getPlane(), writer); - FaceTexdef_BP_exportTokens(m_face.getTexdef(), writer); - FaceShader_Doom3_exportTokens(m_face.getShader(), writer); - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class Quake4FaceTokenExporter { -const Face &m_face; -public: -Quake4FaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_Doom3_exportTokens(m_face.getPlane(), writer); - FaceTexdef_BP_exportTokens(m_face.getTexdef(), writer); - FaceShader_Doom3_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class Quake2FaceTokenExporter { -const Face &m_face; -public: -Quake2FaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_exportTokens(m_face.getTexdef(), writer); - if (m_face.getShader().m_flags.m_specified || m_face.isDetail()) { - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - } - writer.nextLine(); -} -}; - -class Quake3FaceTokenExporter { -const Face &m_face; -public: -Quake3FaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_exportTokens(m_face.getTexdef(), writer); - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class Quake3BPFaceTokenExporter { -const Face &m_face; -public: -Quake3BPFaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceTexdef_BP_exportTokens(m_face.getTexdef(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class Quake3ValveFaceTokenExporter { -const Face &m_face; -public: -Quake3ValveFaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_HalfLife_exportTokens(m_face.getTexdef(), writer); - FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer); - writer.nextLine(); -} -}; - -class QuakeFaceTokenExporter { -const Face &m_face; -public: -QuakeFaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_exportTokens(m_face.getTexdef(), writer); - writer.nextLine(); -} -}; - -class HalfLifeFaceTokenExporter { -const Face &m_face; -public: -HalfLifeFaceTokenExporter(const Face &face) : m_face(face) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - FacePlane_exportTokens(m_face.getPlane(), writer); - FaceShader_exportTokens(m_face.getShader(), writer); - FaceTexdef_HalfLife_exportTokens(m_face.getTexdef(), writer); - writer.nextLine(); -} -}; - - -class BrushTokenImporter : public MapImporter { -Brush &m_brush; - -public: -BrushTokenImporter(Brush &brush) : m_brush(brush) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - if (Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || - Brush::m_type == eBrushTypeQuake4) { - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "{")); - } - while (1) { - // check for end of brush - tokeniser.nextLine(); - const char *token = tokeniser.getToken(); - if (string_equal(token, "}")) { - break; - } - - tokeniser.ungetToken(); - - m_brush.push_back(FaceSmartPointer(new Face(&m_brush))); - - //!todo BP support - tokeniser.nextLine(); - - Face &face = *m_brush.back(); - - switch (Brush::m_type) { - case eBrushTypeDoom3: { - Doom3FaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake4: { - Quake4FaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake2: { - Quake2FaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake3: { - Quake3FaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake3BP: { - Quake3BPFaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake3Valve: { - Quake3ValveFaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeQuake: { - QuakeFaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - case eBrushTypeHalfLife: { - HalfLifeFaceTokenImporter importer(face); - RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser)); - } - break; - } - face.planeChanged(); - } - if (Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || - Brush::m_type == eBrushTypeQuake4) { - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "}")); - } - - m_brush.planeChanged(); - m_brush.shaderChanged(); - - return true; -} -}; - - -class BrushTokenExporter : public MapExporter { -const Brush &m_brush; - -public: -BrushTokenExporter(const Brush &brush) : m_brush(brush) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - m_brush.evaluateBRep(); // ensure b-rep is up-to-date, so that non-contributing faces can be identified. - - if (!m_brush.hasContributingFaces()) { - return; - } - - writer.writeToken("{"); - writer.nextLine(); - - if (Brush::m_type == eBrushTypeQuake3BP) { - writer.writeToken("brushDef"); - writer.nextLine(); - writer.writeToken("{"); - writer.nextLine(); - } - - if (Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4) { - writer.writeToken("brushDef3"); - writer.nextLine(); - writer.writeToken("{"); - writer.nextLine(); - } - - for (Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i) { - const Face &face = *(*i); - - if (face.contributes()) { - switch (Brush::m_type) { - case eBrushTypeDoom3: { - Doom3FaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake4: { - Quake4FaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake2: { - Quake2FaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake3: { - Quake3FaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake3BP: { - Quake3BPFaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - break; - case eBrushTypeQuake3Valve: { - Quake3ValveFaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeQuake: { - QuakeFaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - case eBrushTypeHalfLife: { - HalfLifeFaceTokenExporter exporter(face); - exporter.exportTokens(writer); - } - break; - } - } - } - - if (Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || - Brush::m_type == eBrushTypeQuake4) { - writer.writeToken("}"); - writer.nextLine(); - } - - writer.writeToken("}"); - writer.nextLine(); -} -}; - - -#endif diff --git a/src/brushxml.cpp b/src/brushxml.cpp deleted file mode 100644 index bca6877..0000000 --- a/src/brushxml.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "brushxml.h" diff --git a/src/brushxml.h b/src/brushxml.h deleted file mode 100644 index 58a138b..0000000 --- a/src/brushxml.h +++ /dev/null @@ -1,435 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_BRUSHXML_H ) -#define INCLUDED_BRUSHXML_H - -#include "stream/stringstream.h" -#include "xml/xmlelement.h" - -#include "brush.h" - -inline void FaceTexdef_BP_importXML(FaceTexdef &texdef, const char *xmlContent) -{ - StringTokeniser content(xmlContent); - - texdef.m_projection.m_brushprimit_texdef.coords[0][0] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[0][1] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[0][2] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[1][0] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[1][1] = static_cast( atof(content.getToken())); - texdef.m_projection.m_brushprimit_texdef.coords[1][2] = static_cast( atof(content.getToken())); -} - -inline void FaceTexdef_importXML(FaceTexdef &texdef, const char *xmlContent) -{ - StringTokeniser content(xmlContent); - - texdef.m_projection.m_texdef.shift[0] = static_cast( atof(content.getToken())); - texdef.m_projection.m_texdef.shift[1] = static_cast( atof(content.getToken())); - texdef.m_projection.m_texdef.rotate = static_cast( atof(content.getToken())); - texdef.m_projection.m_texdef.scale[0] = static_cast( atof(content.getToken())); - texdef.m_projection.m_texdef.scale[1] = static_cast( atof(content.getToken())); - - ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_importXML: bad texdef"); -} - -inline void FacePlane_importXML(FacePlane &facePlane, const char *xmlContent) -{ - StringTokeniser content(xmlContent); - - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - facePlane.planePoints()[i][j] = atof(content.getToken()); - } - } - facePlane.MakePlane(); -} - - -class FaceXMLImporter { -struct xml_state_t { - enum EState { - eDefault, - ePlanePts, - eTexdef, - eBPMatrix, - eFlags, - eShader, - }; - - EState m_state; - StringOutputStream m_content; - - xml_state_t(EState state) - : m_state(state) - { - } - - EState state() const - { - return m_state; - } - - const char *content() const - { - return m_content.c_str(); - } - - std::size_t write(const char *buffer, std::size_t length) - { - return m_content.write(buffer, length); - } -}; - -std::vector m_xml_state; -Face &m_face; -public: -FaceXMLImporter(Face &face) : m_face(face) -{ - m_xml_state.push_back(xml_state_t::eDefault); -} - -~FaceXMLImporter() -{ - m_face.planeChanged(); -} - -void pushElement(const XMLElement &element) -{ - ASSERT_MESSAGE(m_xml_state.back().state() == xml_state_t::eDefault, "parse error"); - - if (strcmp(element.name(), "planepts") == 0) { - m_xml_state.push_back(xml_state_t::ePlanePts); - } else if (strcmp(element.name(), "texdef") == 0) { - m_xml_state.push_back(xml_state_t::eTexdef); - } else if (strcmp(element.name(), "bpmatrix") == 0) { - m_xml_state.push_back(xml_state_t::eBPMatrix); - } else if (strcmp(element.name(), "flags") == 0) { - m_xml_state.push_back(xml_state_t::eFlags); - } else if (strcmp(element.name(), "shader") == 0) { - m_xml_state.push_back(xml_state_t::eShader); - } -} - -void popElement(const char *name) -{ - ASSERT_MESSAGE(m_xml_state.back().state() != xml_state_t::eDefault, "parse error"); - - switch (m_xml_state.back().state()) { - case xml_state_t::ePlanePts: { - FacePlane_importXML(m_face.getPlane(), m_xml_state.back().content()); - } - break; - case xml_state_t::eTexdef: { - FaceTexdef_importXML(m_face.getTexdef(), m_xml_state.back().content()); - } - break; - case xml_state_t::eBPMatrix: { - FaceTexdef_BP_importXML(m_face.getTexdef(), m_xml_state.back().content()); - } - break; - case xml_state_t::eFlags: { - StringTokeniser content(m_xml_state.back().content()); - - m_face.getShader().m_flags.m_contentFlags = atoi(content.getToken()); - m_face.getShader().m_flags.m_surfaceFlags = atoi(content.getToken()); - m_face.getShader().m_flags.m_value = atoi(content.getToken()); - } - break; - case xml_state_t::eShader: { - m_face.getShader().setShader(m_xml_state.back().content()); - } - break; - default: - break; - } - - m_xml_state.pop_back(); -} - -std::size_t write(const char *data, std::size_t length) -{ - ASSERT_MESSAGE(!m_xml_state.empty(), "parse error"); - return m_xml_state.back().write(data, length); -} -}; - - -inline void FaceTexdef_exportXML(const FaceTexdef &texdef, XMLImporter &importer) -{ - StaticElement element("texdef"); - importer.pushElement(element); - - ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_exportXML: bad texdef"); - - importer << texdef.m_projection.m_texdef.shift[0] - << ' ' << texdef.m_projection.m_texdef.shift[1] - << ' ' << texdef.m_projection.m_texdef.rotate - << ' ' << texdef.m_projection.m_texdef.scale[0] - << ' ' << texdef.m_projection.m_texdef.scale[1]; - - importer.popElement(element.name()); -} - -inline void FaceTexdef_BP_exportXML(const FaceTexdef &texdef, XMLImporter &importer) -{ - StaticElement element("texdef"); - importer.pushElement(element); - - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < 3; ++j) { - importer << texdef.m_projection.m_brushprimit_texdef.coords[i][j] << ' '; - } - } - - importer.popElement(element.name()); -} - -inline void FaceShader_ContentsFlagsValue_exportXML(const FaceShader &faceShader, XMLImporter &importer) -{ - StaticElement element("flags"); - importer.pushElement(element); - - { - importer << faceShader.m_flags.m_contentFlags - << ' ' << faceShader.m_flags.m_surfaceFlags - << ' ' << faceShader.m_flags.m_value; - } - - importer.popElement(element.name()); -} - -inline void FacePlane_exportXML(const FacePlane &facePlane, XMLImporter &importer) -{ - StaticElement element("planepts"); - importer.pushElement(element); - - { - // write planepts - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - importer << Face::m_quantise(facePlane.planePoints()[i][j]) << ' '; - } - } - } - - importer.popElement(element.name()); -} - -inline void FacePolygon_exportXML(const Winding &w, const BasicVector3 &normal, XMLImporter &importer) -{ - DynamicElement element("polygon"); - - char tmp[32]; - - sprintf(tmp, "%f", normal.x()); - element.insertAttribute("nx", tmp); - - sprintf(tmp, "%f", normal.y()); - element.insertAttribute("ny", tmp); - - sprintf(tmp, "%f", normal.z()); - element.insertAttribute("nz", tmp); - - importer.pushElement(element); - - for (unsigned int i = 0; i < w.numpoints; ++i) { - DynamicElement c("vertex"); - - sprintf(tmp, "%f", w.points[i].vertex.x()); - c.insertAttribute("x", tmp); - - sprintf(tmp, "%f", w.points[i].vertex.y()); - c.insertAttribute("y", tmp); - - sprintf(tmp, "%f", w.points[i].vertex.z()); - c.insertAttribute("z", tmp); - - sprintf(tmp, "%f", w.points[i].texcoord.x()); - c.insertAttribute("s", tmp); - - sprintf(tmp, "%f", w.points[i].texcoord.y()); - c.insertAttribute("t", tmp); - - importer.pushElement(c); - importer.popElement(c.name()); - } - - importer.popElement(element.name()); -} - -class FaceXMLExporter { -const Face &m_face; -public: -FaceXMLExporter(const Face &face) : m_face(face) -{ -} - -void exportXML(XMLImporter &importer) -{ - bool bAlternateTexdef = (Face::m_type == eBrushTypeQuake3BP || Face::m_type == eBrushTypeDoom3 || - Face::m_type == eBrushTypeQuake4); - - // write shader - { - StaticElement element("shader"); - importer.pushElement(element); - importer << m_face.getShader().getShader(); - importer.popElement(element.name()); - } - - FacePolygon_exportXML(m_face.getWinding(), m_face.getPlane().plane3().normal(), importer); - FacePlane_exportXML(m_face.getPlane(), importer); - - if (!bAlternateTexdef) { - FaceTexdef_exportXML(m_face.getTexdef(), importer); - } else { - FaceTexdef_BP_exportXML(m_face.getTexdef(), importer); - } - - FaceShader_ContentsFlagsValue_exportXML(m_face.getShader(), importer); -} -}; - - -class BrushXMLImporter : public XMLImporter { -class xml_state_t { -public: -enum EState { - eDefault, - eBrush, - eFace, -}; - -private: -EState m_state; - -public: -xml_state_t(EState state) - : m_state(state) -{ -} - -EState state() const -{ - return m_state; -} -}; - -std::vector m_xml_state; -char m_faceImporter[sizeof(FaceXMLImporter)]; -Brush &m_brush; - -FaceXMLImporter &faceImporter() -{ - return *reinterpret_cast( m_faceImporter ); -} - -public: -BrushXMLImporter(Brush &brush) : m_brush(brush) -{ - m_xml_state.push_back(xml_state_t::eDefault); -} - -void pushElement(const XMLElement &element) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - ASSERT_MESSAGE(strcmp(element.name(), "brush") == 0, "parse error"); - m_xml_state.push_back(xml_state_t::eBrush); - break; - case xml_state_t::eBrush: - ASSERT_MESSAGE(strcmp(element.name(), "plane") == 0, "parse error"); - m_xml_state.push_back(xml_state_t::eFace); - m_brush.push_back(FaceSmartPointer(new Face(&m_brush))); - constructor(faceImporter(), makeReference(*m_brush.back())); - m_brush.planeChanged(); - m_brush.shaderChanged(); - break; - case xml_state_t::eFace: - m_xml_state.push_back(xml_state_t::eFace); - faceImporter().pushElement(element); - break; - } -} - -void popElement(const char *name) -{ - ASSERT_MESSAGE(!m_xml_state.empty(), "parse error"); - m_xml_state.pop_back(); - - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - break; - case xml_state_t::eBrush: - destructor(faceImporter()); - break; - case xml_state_t::eFace: - faceImporter().popElement(name); - break; - } -} - -std::size_t write(const char *data, std::size_t length) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eFace: - return faceImporter().write(data, length); - break; - default: - break; - } - return length; -} -}; - -class BrushXMLExporter : public XMLExporter { -const Brush &m_brush; - -public: -BrushXMLExporter(const Brush &brush) : m_brush(brush) -{ -} - -void exportXML(XMLImporter &importer) -{ - m_brush.evaluateBRep(); // ensure b-rep is up-to-date, so that non-contributing faces can be identified. - ASSERT_MESSAGE(m_brush.hasContributingFaces(), "exporting an empty brush"); - - const StaticElement brushElement("brush"); - importer.pushElement(brushElement); - - for (Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i) { - if ((*i)->contributes()) { - const StaticElement element("plane"); - importer.pushElement(element); - FaceXMLExporter(*(*i)).exportXML(importer); - importer.popElement(element.name()); - } - } - - importer.popElement(brushElement.name()); -} -}; - - -#endif diff --git a/tools/vmap/bsp.c b/src/bsp.c similarity index 100% rename from tools/vmap/bsp.c rename to src/bsp.c diff --git a/tools/vmap/bsp_analyze.c b/src/bsp_analyze.c similarity index 100% rename from tools/vmap/bsp_analyze.c rename to src/bsp_analyze.c diff --git a/tools/vmap/bsp_info.c b/src/bsp_info.c similarity index 100% rename from tools/vmap/bsp_info.c rename to src/bsp_info.c diff --git a/tools/vmap/bsp_scale.c b/src/bsp_scale.c similarity index 100% rename from tools/vmap/bsp_scale.c rename to src/bsp_scale.c diff --git a/tools/vmap/bspfile_abstract.c b/src/bspfile_abstract.c similarity index 100% rename from tools/vmap/bspfile_abstract.c rename to src/bspfile_abstract.c diff --git a/tools/vmap/bspfile_ibsp.c b/src/bspfile_ibsp.c similarity index 100% rename from tools/vmap/bspfile_ibsp.c rename to src/bspfile_ibsp.c diff --git a/tools/vmap/bspfile_rbsp.c b/src/bspfile_rbsp.c similarity index 100% rename from tools/vmap/bspfile_rbsp.c rename to src/bspfile_rbsp.c diff --git a/src/build.cpp b/src/build.cpp deleted file mode 100644 index 4be1a68..0000000 --- a/src/build.cpp +++ /dev/null @@ -1,1104 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "build.h" -#include "debugging/debugging.h" - -#include -#include -#include -#include "stream/stringstream.h" -#include "versionlib.h" - -#include "mainframe.h" - -typedef std::map Variables; -Variables g_build_variables; - -void build_clear_variables() -{ - g_build_variables.clear(); -} - -void build_set_variable(const char *name, const char *value) -{ - g_build_variables[name] = value; -} - -const char *build_get_variable(const char *name) -{ - Variables::iterator i = g_build_variables.find(name); - if (i != g_build_variables.end()) { - return (*i).second.c_str(); - } - globalErrorStream() << "undefined build variable: " << makeQuoted(name) << "\n"; - return ""; -} - -#include "xml/ixml.h" -#include "xml/xmlelement.h" - -class Evaluatable { -public: -virtual ~Evaluatable() = default; - -virtual void evaluate(StringBuffer &output) = 0; - -virtual void exportXML(XMLImporter &importer) = 0; -}; - -class VariableString : public Evaluatable { -CopiedString m_string; -public: -VariableString() : m_string() -{ -} - -VariableString(const char *string) : m_string(string) -{ -} - -const char *c_str() const -{ - return m_string.c_str(); -} - -void setString(const char *string) -{ - m_string = string; -} - -void evaluate(StringBuffer &output) -{ - StringBuffer variable; - bool in_variable = false; - for (const char *i = m_string.c_str(); *i != '\0'; ++i) { - if (!in_variable) { - switch (*i) { - case '[': - in_variable = true; - break; - default: - output.push_back(*i); - break; - } - } else { - switch (*i) { - case ']': - in_variable = false; - output.push_string(build_get_variable(variable.c_str())); - variable.clear(); - break; - default: - variable.push_back(*i); - break; - } - } - } -} - -void exportXML(XMLImporter &importer) -{ - importer << c_str(); -} -}; - -class Conditional : public Evaluatable { -VariableString *m_test; -public: -Evaluatable *m_result; - -Conditional(VariableString *test) : m_test(test) -{ -} - -~Conditional() -{ - 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); - } -} - -void exportXML(XMLImporter &importer) -{ - StaticElement conditionElement("cond"); - conditionElement.insertAttribute("value", m_test->c_str()); - importer.pushElement(conditionElement); - m_result->exportXML(importer); - importer.popElement(conditionElement.name()); -} -}; - -typedef std::vector Evaluatables; - -class Tool : public Evaluatable { -Evaluatables m_evaluatables; -public: -~Tool() -{ - for (Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i) { - delete (*i); - } -} - -void push_back(Evaluatable *evaluatable) -{ - m_evaluatables.push_back(evaluatable); -} - -void evaluate(StringBuffer &output) -{ - for (Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i) { - (*i)->evaluate(output); - } -} - -void exportXML(XMLImporter &importer) -{ - for (Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i) { - (*i)->exportXML(importer); - } -} -}; - -#include "xml/ixml.h" - -class XMLElementParser : public TextOutputStream { -public: -virtual ~XMLElementParser() = default; - -virtual XMLElementParser &pushElement(const XMLElement &element) = 0; - -virtual void popElement(const char *name) = 0; -}; - -class VariableStringXMLConstructor : public XMLElementParser { -StringBuffer m_buffer; -VariableString &m_variableString; -public: -VariableStringXMLConstructor(VariableString &variableString) : m_variableString(variableString) -{ -} - -~VariableStringXMLConstructor() -{ - m_variableString.setString(m_buffer.c_str()); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - m_buffer.push_range(buffer, buffer + length); - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE("parse error: invalid element \"" << element.name() << "\""); - return *this; -} - -void popElement(const char *name) -{ -} -}; - -class ConditionalXMLConstructor : public XMLElementParser { -StringBuffer m_buffer; -Conditional &m_conditional; -public: -ConditionalXMLConstructor(Conditional &conditional) : m_conditional(conditional) -{ -} - -~ConditionalXMLConstructor() -{ - m_conditional.m_result = new VariableString(m_buffer.c_str()); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - m_buffer.push_range(buffer, buffer + length); - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE("parse error: invalid element \"" << element.name() << "\""); - return *this; -} - -void popElement(const char *name) -{ -} -}; - -class ToolXMLConstructor : public XMLElementParser { -StringBuffer m_buffer; -Tool &m_tool; -ConditionalXMLConstructor *m_conditional; -public: -ToolXMLConstructor(Tool &tool) : m_tool(tool) -{ -} - -~ToolXMLConstructor() -{ - flush(); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - m_buffer.push_range(buffer, buffer + length); - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), "cond")) { - flush(); - Conditional *conditional = new Conditional(new VariableString(element.attribute("value"))); - m_tool.push_back(conditional); - m_conditional = new ConditionalXMLConstructor(*conditional); - return *m_conditional; - } else { - ERROR_MESSAGE("parse error: invalid element \"" << element.name() << "\""); - return *this; - } -} - -void popElement(const char *name) -{ - if (string_equal(name, "cond")) { - delete m_conditional; - } -} - -void flush() -{ - if (!m_buffer.empty()) { - m_tool.push_back(new VariableString(m_buffer.c_str())); - m_buffer.clear(); - } -} -}; - -typedef VariableString BuildCommand; -typedef std::list Build; - -class BuildXMLConstructor : public XMLElementParser { -VariableStringXMLConstructor *m_variableString; -Build &m_build; -public: -BuildXMLConstructor(Build &build) : m_build(build) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), "command")) { - m_build.push_back(BuildCommand()); - m_variableString = new VariableStringXMLConstructor(m_build.back()); - return *m_variableString; - } else { - ERROR_MESSAGE("parse error: invalid element"); - return *this; - } -} - -void popElement(const char *name) -{ - delete m_variableString; -} -}; - -typedef std::pair BuildPair; -const char *SEPARATOR_STRING = "-"; - -static bool is_separator(const BuildPair &p) -{ - if (!string_equal(p.first.c_str(), SEPARATOR_STRING)) { - return false; - } - for (Build::const_iterator j = p.second.begin(); j != p.second.end(); ++j) { - if (!string_equal((*j).c_str(), "")) { - return false; - } - } - return true; -} - - -typedef std::list Project; - -Project::iterator Project_find(Project &project, const char *name) -{ - return std::find_if(project.begin(), project.end(), [&](const BuildPair &self) { - return string_equal(self.first.c_str(), name); - }); -} - -Project::iterator Project_find(Project &project, std::size_t index) -{ - Project::iterator i = project.begin(); - while (index-- != 0 && i != project.end()) { - ++i; - } - return i; -} - -Build &project_find(Project &project, const char *build) -{ - Project::iterator i = Project_find(project, build); - ASSERT_MESSAGE(i != project.end(), "error finding build command"); - return (*i).second; -} - -Build::iterator Build_find(Build &build, std::size_t index) -{ - Build::iterator i = build.begin(); - while (index-- != 0 && i != build.end()) { - ++i; - } - return i; -} - -typedef std::map Tools; - -class ProjectXMLConstructor : public XMLElementParser { -ToolXMLConstructor *m_tool; -BuildXMLConstructor *m_build; -Project &m_project; -Tools &m_tools; -public: -ProjectXMLConstructor(Project &project, Tools &tools) : m_project(project), m_tools(tools) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), "var")) { - Tools::iterator i = m_tools.insert(Tools::value_type(element.attribute("name"), Tool())).first; - m_tool = new ToolXMLConstructor((*i).second); - return *m_tool; - } else if (string_equal(element.name(), "build")) { - m_project.push_back(Project::value_type(element.attribute("name"), Build())); - m_build = new BuildXMLConstructor(m_project.back().second); - return *m_build; - } else if (string_equal(element.name(), "separator")) { - m_project.push_back(Project::value_type(SEPARATOR_STRING, Build())); - return *this; - } else { - ERROR_MESSAGE("parse error: invalid element"); - return *this; - } -} - -void popElement(const char *name) -{ - if (string_equal(name, "var")) { - delete m_tool; - } else if (string_equal(name, "build")) { - delete m_build; - } -} -}; - -class SkipAllParser : public XMLElementParser { -public: -std::size_t write(const char *buffer, std::size_t length) -{ - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - return *this; -} - -void popElement(const char *name) -{ -} -}; - -class RootXMLConstructor : public XMLElementParser { -CopiedString m_elementName; -XMLElementParser &m_parser; -SkipAllParser m_skip; -Version m_version; -bool m_compatible; -public: -RootXMLConstructor(const char *elementName, XMLElementParser &parser, const char *version) : - m_elementName(elementName), - m_parser(parser), - m_version(version_parse(version)), - m_compatible(false) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return length; -} - -XMLElementParser &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), m_elementName.c_str())) { - Version dataVersion(version_parse(element.attribute("version"))); - if (version_compatible(m_version, dataVersion)) { - m_compatible = true; - return m_parser; - } else { - return m_skip; - } - } else { - //ERROR_MESSAGE("parse error: invalid element \"" << element.name() << "\""); - return *this; - } -} - -void popElement(const char *name) -{ -} - -bool versionCompatible() const -{ - return m_compatible; -} -}; - -namespace { -Project g_build_project; -Tools g_build_tools; -bool g_build_changed = false; -} - -void build_error_undefined_tool(const char *build, const char *tool) -{ - globalErrorStream() << "build " << makeQuoted(build) << " refers to undefined tool " << makeQuoted(tool) << '\n'; -} - -void project_verify(Project &project, Tools &tools) -{ -#if 0 - for ( Project::iterator i = project.begin(); i != project.end(); ++i ) - { - Build& build = ( *i ).second; - for ( Build::iterator j = build.begin(); j != build.end(); ++j ) - { - Tools::iterator k = tools.find( ( *j ).first ); - if ( k == g_build_tools.end() ) { - build_error_undefined_tool( ( *i ).first.c_str(), ( *j ).first.c_str() ); - } - } - } -#endif -} - -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); - build_set_variable((*i).first.c_str(), output.c_str()); - } - - { - Project::iterator i = Project_find(g_build_project, name); - if (i != g_build_project.end()) { - Build &build = (*i).second; - for (Build::iterator j = build.begin(); j != build.end(); ++j) { - StringBuffer output; - (*j).evaluate(output); - listener.execute(output.c_str()); - } - } else { - globalErrorStream() << "build " << makeQuoted(name) << " not defined"; - } - } -} - - -typedef std::vector XMLElementStack; - -class XMLParser : public XMLImporter { -XMLElementStack m_stack; -public: -XMLParser(XMLElementParser &parser) -{ - m_stack.push_back(&parser); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return m_stack.back()->write(buffer, length); -} - -void pushElement(const XMLElement &element) -{ - m_stack.push_back(&m_stack.back()->pushElement(element)); -} - -void popElement(const char *name) -{ - m_stack.pop_back(); - m_stack.back()->popElement(name); -} -}; - -#include "stream/textfilestream.h" -#include "xml/xmlparser.h" - -const char *const BUILDMENU_VERSION = "2.0"; - -bool build_commands_parse(const char *filename) -{ - TextFileInputStream projectFile(filename); - if (!projectFile.failed()) { - ProjectXMLConstructor projectConstructor(g_build_project, g_build_tools); - RootXMLConstructor rootConstructor("project", projectConstructor, BUILDMENU_VERSION); - XMLParser importer(rootConstructor); - XMLStreamParser parser(projectFile); - parser.exportXML(importer); - - if (rootConstructor.versionCompatible()) { - project_verify(g_build_project, g_build_tools); - - return true; - } - globalErrorStream() << "failed to parse build menu: " << makeQuoted(filename) << "\n"; - } - return false; -} - -void build_commands_clear() -{ - g_build_project.clear(); - g_build_tools.clear(); -} - -class BuildXMLExporter { -Build &m_build; -public: -BuildXMLExporter(Build &build) : m_build(build) -{ -} - -void exportXML(XMLImporter &importer) -{ - importer << "\n"; - for (Build::iterator i = m_build.begin(); i != m_build.end(); ++i) { - StaticElement commandElement("command"); - importer.pushElement(commandElement); - (*i).exportXML(importer); - importer.popElement(commandElement.name()); - importer << "\n"; - } -} -}; - -class ProjectXMLExporter { -Project &m_project; -Tools &m_tools; -public: -ProjectXMLExporter(Project &project, Tools &tools) : m_project(project), m_tools(tools) -{ -} - -void exportXML(XMLImporter &importer) -{ - StaticElement projectElement("project"); - projectElement.insertAttribute("version", BUILDMENU_VERSION); - importer.pushElement(projectElement); - importer << "\n"; - - for (Tools::iterator i = m_tools.begin(); i != m_tools.end(); ++i) { - StaticElement toolElement("var"); - toolElement.insertAttribute("name", (*i).first.c_str()); - importer.pushElement(toolElement); - (*i).second.exportXML(importer); - importer.popElement(toolElement.name()); - importer << "\n"; - } - for (Project::iterator i = m_project.begin(); i != m_project.end(); ++i) { - if (is_separator(*i)) { - StaticElement buildElement("separator"); - importer.pushElement(buildElement); - importer.popElement(buildElement.name()); - importer << "\n"; - } else { - StaticElement buildElement("build"); - buildElement.insertAttribute("name", (*i).first.c_str()); - importer.pushElement(buildElement); - BuildXMLExporter buildExporter((*i).second); - buildExporter.exportXML(importer); - importer.popElement(buildElement.name()); - importer << "\n"; - } - } - importer.popElement(projectElement.name()); -} -}; - -#include "xml/xmlwriter.h" - -void build_commands_write(const char *filename) -{ - TextFileOutputStream projectFile(filename); - if (!projectFile.failed()) { - XMLStreamWriter writer(projectFile); - ProjectXMLExporter projectExporter(g_build_project, g_build_tools); - writer << "\n"; - projectExporter.exportXML(writer); - writer << "\n"; - } -} - - -#include - -#include "gtkutil/dialog.h" -#include "gtkutil/closure.h" -#include "gtkutil/window.h" -#include "gtkdlgs.h" - -void Build_refreshMenu(ui::Menu menu); - - -void BSPCommandList_Construct(ui::ListStore store, Project &project) -{ - store.clear(); - - for (Project::iterator i = project.begin(); i != project.end(); ++i) { - store.append(0, (*i).first.c_str()); - } - - store.append(); -} - -class ProjectList { -public: -Project &m_project; -ui::ListStore m_store{ui::null}; -bool m_changed; - -ProjectList(Project &project) : m_project(project), m_changed(false) -{ -} -}; - -gboolean project_cell_edited(ui::CellRendererText cell, gchar *path_string, gchar *new_text, ProjectList *projectList) -{ - Project &project = projectList->m_project; - - auto path = ui::TreePath(path_string); - - ASSERT_MESSAGE(gtk_tree_path_get_depth(path) == 1, "invalid path length"); - - GtkTreeIter iter; - gtk_tree_model_get_iter(projectList->m_store, &iter, path); - - Project::iterator i = Project_find(project, gtk_tree_path_get_indices(path)[0]); - if (i != project.end()) { - projectList->m_changed = true; - if (string_empty(new_text)) { - project.erase(i); - gtk_list_store_remove(projectList->m_store, &iter); - } else { - (*i).first = new_text; - gtk_list_store_set(projectList->m_store, &iter, 0, new_text, -1); - } - } else if (!string_empty(new_text)) { - projectList->m_changed = true; - project.push_back(Project::value_type(new_text, Build())); - - gtk_list_store_set(projectList->m_store, &iter, 0, new_text, -1); - projectList->m_store.append(); - } - - gtk_tree_path_free(path); - - Build_refreshMenu(g_bsp_menu); - - return FALSE; -} - -gboolean project_key_press(ui::TreeView widget, GdkEventKey *event, ProjectList *projectList) -{ - Project &project = projectList->m_project; - - if (event->keyval == GDK_KEY_Delete) { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(widget)); - GtkTreeIter iter; - GtkTreeModel *model; - if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - auto path = gtk_tree_model_get_path(model, &iter); - Project::iterator x = Project_find(project, gtk_tree_path_get_indices(path)[0]); - gtk_tree_path_free(path); - - if (x != project.end()) { - projectList->m_changed = true; - project.erase(x); - Build_refreshMenu(g_bsp_menu); - - gtk_list_store_remove(projectList->m_store, &iter); - } - } - } - return FALSE; -} - - -Build *g_current_build = 0; - -gboolean project_selection_changed(ui::TreeSelection selection, ui::ListStore store) -{ - Project &project = g_build_project; - - store.clear(); - - GtkTreeIter iter; - GtkTreeModel *model; - if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - auto path = gtk_tree_model_get_path(model, &iter); - Project::iterator x = Project_find(project, gtk_tree_path_get_indices(path)[0]); - gtk_tree_path_free(path); - - if (x != project.end()) { - Build &build = (*x).second; - g_current_build = &build; - - for (Build::iterator i = build.begin(); i != build.end(); ++i) { - store.append(0, (*i).c_str()); - } - store.append(); - } else { - g_current_build = 0; - } - } else { - g_current_build = 0; - } - - return FALSE; -} - -gboolean commands_cell_edited(ui::CellRendererText cell, gchar *path_string, gchar *new_text, ui::ListStore store) -{ - if (g_current_build == 0) { - return FALSE; - } - Build &build = *g_current_build; - - auto path = ui::TreePath(path_string); - - ASSERT_MESSAGE(gtk_tree_path_get_depth(path) == 1, "invalid path length"); - - GtkTreeIter iter; - gtk_tree_model_get_iter(store, &iter, path); - - Build::iterator i = Build_find(build, gtk_tree_path_get_indices(path)[0]); - if (i != build.end()) { - g_build_changed = true; - (*i).setString(new_text); - - gtk_list_store_set(store, &iter, 0, new_text, -1); - } else if (!string_empty(new_text)) { - g_build_changed = true; - build.push_back(Build::value_type(VariableString(new_text))); - - gtk_list_store_set(store, &iter, 0, new_text, -1); - - store.append(); - } - - gtk_tree_path_free(path); - - Build_refreshMenu(g_bsp_menu); - - return FALSE; -} - -gboolean commands_key_press(ui::TreeView widget, GdkEventKey *event, ui::ListStore store) -{ - if (g_current_build == 0) { - return FALSE; - } - Build &build = *g_current_build; - - if (event->keyval == GDK_KEY_Delete) { - auto selection = gtk_tree_view_get_selection(widget); - GtkTreeIter iter; - GtkTreeModel *model; - if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - auto path = gtk_tree_model_get_path(model, &iter); - Build::iterator i = Build_find(build, gtk_tree_path_get_indices(path)[0]); - gtk_tree_path_free(path); - - if (i != build.end()) { - g_build_changed = true; - build.erase(i); - - gtk_list_store_remove(store, &iter); - } - } - } - 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); - - { - auto table1 = create_dialog_table(2, 2, 4, 4, 4); - window.add(table1); - { - auto vbox = create_dialog_vbox(4); - table1.attach(vbox, {1, 2, 0, 1}, {GTK_FILL, GTK_FILL}); - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &modal); - vbox.pack_start(button, FALSE, FALSE, 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &modal); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - auto buildViewStore = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - auto buildView = ui::TreeView(ui::TreeModel::from(buildViewStore._handle)); - { - auto frame = create_dialog_frame("Build menu"); - table1.attach(frame, {0, 1, 0, 1}); - { - auto scr = create_scrolled_window(ui::Policy::NEVER, ui::Policy::AUTOMATIC, 4); - frame.add(scr); - - { - auto view = buildView; - auto store = buildViewStore; - gtk_tree_view_set_headers_visible(view, FALSE); - - auto renderer = ui::CellRendererText(ui::New); - object_set_boolean_property(G_OBJECT(renderer), "editable", TRUE); - renderer.connect("edited", G_CALLBACK(project_cell_edited), &projectList); - - auto column = ui::TreeViewColumn("", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - - auto selection = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); - - view.show(); - - projectList.m_store = store; - scr.add(view); - - view.connect("key_press_event", G_CALLBACK(project_key_press), &projectList); - - store.unref(); - } - } - } - { - auto frame = create_dialog_frame("Commandline"); - table1.attach(frame, {0, 1, 1, 2}); - { - auto scr = create_scrolled_window(ui::Policy::NEVER, ui::Policy::AUTOMATIC, 4); - frame.add(scr); - - { - auto store = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_headers_visible(view, FALSE); - - auto renderer = ui::CellRendererText(ui::New); - object_set_boolean_property(G_OBJECT(renderer), "editable", TRUE); - renderer.connect("edited", G_CALLBACK(commands_cell_edited), store); - - auto column = ui::TreeViewColumn("", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - - auto selection = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); - - view.show(); - - scr.add(view); - - store.unref(); - - view.connect("key_press_event", G_CALLBACK(commands_key_press), store); - - auto sel = ui::TreeSelection::from(gtk_tree_view_get_selection(buildView)); - sel.connect("changed", G_CALLBACK(project_selection_changed), store); - } - } - } - } - - BSPCommandList_Construct(projectList.m_store, g_build_project); - - return window; -} - -namespace { -CopiedString g_buildMenu; -} - -void LoadBuildMenu(); - -void DoBuildMenu() -{ - ModalDialog modal; - - ProjectList projectList(g_build_project); - - ui::Window window = BuildMenuDialog_construct(modal, projectList); - - if (modal_dialog_show(window, modal) == eIDCANCEL) { - build_commands_clear(); - LoadBuildMenu(); - - Build_refreshMenu(g_bsp_menu); - } else if (projectList.m_changed) { - g_build_changed = true; - } - - window.destroy(); -} - - -#include "gtkutil/menu.h" -#include "mainframe.h" -#include "preferences.h" -#include "qe3.h" - -class BuildMenuItem { -const char *m_name; -public: -ui::MenuItem m_item; - -BuildMenuItem(const char *name, ui::MenuItem item) - : m_name(name), m_item(item) -{ -} - -void run() -{ - RunBSP(m_name); -} - -typedef MemberCaller RunCaller; -}; - -typedef std::list BuildMenuItems; -BuildMenuItems g_BuildMenuItems; - - -ui::Menu g_bsp_menu{ui::null}; - -void Build_constructMenu(ui::Menu menu) -{ - for (Project::iterator i = g_build_project.begin(); i != g_build_project.end(); ++i) { - g_BuildMenuItems.push_back(BuildMenuItem((*i).first.c_str(), ui::MenuItem(ui::null))); - if (is_separator(*i)) { - g_BuildMenuItems.back().m_item = menu_separator(menu); - } else { - g_BuildMenuItems.back().m_item = create_menu_item_with_mnemonic(menu, (*i).first.c_str(), - BuildMenuItem::RunCaller( - g_BuildMenuItems.back())); - } - } -} - - -void Build_refreshMenu(ui::Menu menu) -{ - for (auto i = g_BuildMenuItems.begin(); i != g_BuildMenuItems.end(); ++i) { - menu.remove(ui::MenuItem(i->m_item)); - } - - g_BuildMenuItems.clear(); - - Build_constructMenu(menu); -} - - -void LoadBuildMenu() -{ - if (string_empty(g_buildMenu.c_str()) || !build_commands_parse(g_buildMenu.c_str())) { - { - StringOutputStream buffer(256); - buffer << GameToolsPath_get() << "default_build_menu.xml"; - - bool success = build_commands_parse(buffer.c_str()); - ASSERT_MESSAGE(success, "failed to parse default build commands: " << buffer.c_str()); - } - { - StringOutputStream buffer(256); - buffer << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/build_menu.xml"; - - g_buildMenu = buffer.c_str(); - } - } -} - -void SaveBuildMenu() -{ - if (g_build_changed) { - g_build_changed = false; - build_commands_write(g_buildMenu.c_str()); - } -} - -#include "preferencesystem.h" -#include "stringio.h" - -void BuildMenu_Construct() -{ - GlobalPreferenceSystem().registerPreference("BuildMenu", make_property_string(g_buildMenu)); - LoadBuildMenu(); -} - -void BuildMenu_Destroy() -{ - SaveBuildMenu(); -} diff --git a/src/build.h b/src/build.h deleted file mode 100644 index 7597328..0000000 --- a/src/build.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include - -#if !defined( INCLUDED_BUILD_H ) -#define INCLUDED_BUILD_H - -void build_set_variable(const char *name, const char *value); - -void build_clear_variables(); - -class CommandListener { -public: -virtual void execute(const char *command) = 0; -}; - -void build_run(const char *name, CommandListener &listener); - -void DoBuildMenu(); - -void BuildMenu_Construct(); - -void BuildMenu_Destroy(); - -void Build_constructMenu(ui::Menu menu); - -extern ui::Menu g_bsp_menu; - - -#endif diff --git a/src/camwindow.cpp b/src/camwindow.cpp deleted file mode 100644 index d20b074..0000000 --- a/src/camwindow.cpp +++ /dev/null @@ -1,2248 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Camera Window -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "camwindow.h" - -#include -#include - -#include "debugging/debugging.h" - -#include "iscenegraph.h" -#include "irender.h" -#include "igl.h" -#include "icamera.h" -#include "cullable.h" -#include "renderable.h" -#include "preferencesystem.h" - -#include "signal/signal.h" -#include "container/array.h" -#include "scenelib.h" -#include "render.h" -#include "cmdlib.h" -#include "math/frustum.h" - -#include "gtkutil/widget.h" -#include "gtkutil/button.h" -#include "gtkutil/toolbar.h" -#include "gtkutil/glwidget.h" -#include "gtkutil/xorrectangle.h" -#include "gtkmisc.h" -#include "selection.h" -#include "mainframe.h" -#include "preferences.h" -#include "commands.h" -#include "xywindow.h" -#include "windowobservers.h" -#include "renderstate.h" - -#include "timer.h" - -Signal0 g_cameraMoved_callbacks; - -void AddCameraMovedCallback(const SignalHandler &handler) -{ - g_cameraMoved_callbacks.connectLast(handler); -} - -void CameraMovedNotify() -{ - g_cameraMoved_callbacks(); -} - - -struct camwindow_globals_private_t { - int m_nMoveSpeed; - bool m_bCamLinkSpeed; - int m_nAngleSpeed; - bool m_bCamInverseMouse; - bool m_bCamDiscrete; - bool m_bCubicClipping; - bool m_showStats; - bool m_showLighting; - bool m_showAlpha; - bool m_showPatchBalls; - int m_nStrafeMode; - - camwindow_globals_private_t() : - m_nMoveSpeed(50), - m_bCamLinkSpeed(true), - m_nAngleSpeed(3), - m_bCamInverseMouse(false), - m_bCamDiscrete(true), - m_bCubicClipping(true), - m_showStats(false), - m_showLighting(false), - m_showAlpha(true), - m_showPatchBalls(true), - m_nStrafeMode(0) - { - } - -}; - -camwindow_globals_private_t g_camwindow_globals_private; - - -const Matrix4 g_opengl2radiant( - 0, 0, -1, 0, - -1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 1 - ); - -const Matrix4 g_radiant2opengl( - 0, -1, 0, 0, - 0, 0, 1, 0, - -1, 0, 0, 0, - 0, 0, 0, 1 - ); - -struct camera_t; - -void Camera_mouseMove(camera_t &camera, int x, int y); - -enum camera_draw_mode { - cd_wire, - cd_solid, - cd_texture, - cd_lighting -}; - -struct camera_t { - int width, height; - - bool timing; - - Vector3 origin; - Vector3 angles; - - Vector3 color; // background - - Vector3 forward, right; // move matrix (TTimo: used to have up but it was not updated) - Vector3 vup, vpn, vright; // view matrix (taken from the modelview matrix) - - Matrix4 projection; - Matrix4 modelview; - - bool m_strafe; // true when in strafemode toggled by the ctrl-key - bool m_strafe_forward; // true when in strafemode by ctrl-key and shift is pressed for forward strafing - - unsigned int movementflags; // movement flags - Timer m_keycontrol_timer; - guint m_keymove_handler; - - - float fieldOfView; - - DeferredMotionDelta m_mouseMove; - - static void motionDelta(int x, int y, void *data) - { - Camera_mouseMove(*reinterpret_cast( data ), x, y); - } - - View *m_view; - Callback m_update; - - static camera_draw_mode draw_mode; - - camera_t(View *view, const Callback &update) - : width(0), - height(0), - timing(false), - origin(0, 0, 0), - angles(0, 0, 0), - color(0, 0, 0), - movementflags(0), - m_keymove_handler(0), - fieldOfView(75.0f), - m_mouseMove(motionDelta, this), - m_view(view), - m_update(update) - { - } -}; - -camera_draw_mode camera_t::draw_mode = cd_texture; - -inline Matrix4 projection_for_camera(float near_z, float far_z, float fieldOfView, int width, int height) -{ - const float half_width = static_cast( near_z * tan(degrees_to_radians(fieldOfView * 0.5))); - const float half_height = half_width * (static_cast( width ) / static_cast( height )); - - return matrix4_frustum( - -half_height, - half_height, - -half_width, - half_width, - near_z, - far_z - ); -} - -float Camera_getFarClipPlane(camera_t &camera) -{ - return (g_camwindow_globals_private.m_bCubicClipping) ? pow(2.0, (g_camwindow_globals.m_nCubicScale + 7) / 2.0) - : 32768.0f; -} - -void Camera_updateProjection(camera_t &camera) -{ - float farClip = Camera_getFarClipPlane(camera); - camera.projection = projection_for_camera(farClip / 4096.0f, farClip, camera.fieldOfView, camera.width, - camera.height); - - camera.m_view->Construct(camera.projection, camera.modelview, camera.width, camera.height); -} - -void Camera_updateVectors(camera_t &camera) -{ - for (int i = 0; i < 3; i++) { - camera.vright[i] = camera.modelview[(i << 2) + 0]; - camera.vup[i] = camera.modelview[(i << 2) + 1]; - camera.vpn[i] = camera.modelview[(i << 2) + 2]; - } -} - -void Camera_updateModelview(camera_t &camera) -{ - camera.modelview = g_matrix4_identity; - - // roll, pitch, yaw - Vector3 radiant_eulerXYZ(0, -camera.angles[CAMERA_PITCH], camera.angles[CAMERA_YAW]); - - matrix4_translate_by_vec3(camera.modelview, camera.origin); - matrix4_rotate_by_euler_xyz_degrees(camera.modelview, radiant_eulerXYZ); - matrix4_multiply_by_matrix4(camera.modelview, g_radiant2opengl); - matrix4_affine_invert(camera.modelview); - - Camera_updateVectors(camera); - - camera.m_view->Construct(camera.projection, camera.modelview, camera.width, camera.height); -} - - -void Camera_Move_updateAxes(camera_t &camera) -{ - double ya = degrees_to_radians(camera.angles[CAMERA_YAW]); - - // the movement matrix is kept 2d - camera.forward[0] = static_cast( cos(ya)); - camera.forward[1] = static_cast( sin(ya)); - camera.forward[2] = 0; - camera.right[0] = camera.forward[1]; - camera.right[1] = -camera.forward[0]; -} - -void Camera_Freemove_updateAxes(camera_t &camera) -{ - camera.right = camera.vright; - camera.forward = vector3_negated(camera.vpn); -} - -const Vector3 &Camera_getOrigin(camera_t &camera) -{ - return camera.origin; -} - -void Camera_setOrigin(camera_t &camera, const Vector3 &origin) -{ - camera.origin = origin; - Camera_updateModelview(camera); - camera.m_update(); - CameraMovedNotify(); -} - -const Vector3 &Camera_getAngles(camera_t &camera) -{ - return camera.angles; -} - -void Camera_setAngles(camera_t &camera, const Vector3 &angles) -{ - camera.angles = angles; - Camera_updateModelview(camera); - camera.m_update(); - CameraMovedNotify(); -} - - -void Camera_FreeMove(camera_t &camera, int dx, int dy) -{ - // free strafe mode, toggled by the ctrl key with optional shift for forward movement - if (camera.m_strafe) { - float strafespeed = 0.65f; - - if (g_camwindow_globals_private.m_bCamLinkSpeed) { - strafespeed = (float) g_camwindow_globals_private.m_nMoveSpeed / 100; - } - - camera.origin -= camera.vright * strafespeed * dx; - if (camera.m_strafe_forward) { - camera.origin += camera.vpn * strafespeed * dy; - } else { - camera.origin += camera.vup * strafespeed * dy; - } - } else // free rotation - { -#if 1 - const float dtime = 0.05f; -#else - float dtime = camera.m_keycontrol_timer.elapsed_msec() / static_cast( msec_per_sec ); - dtime *= 0.01f; -#endif - - if (g_camwindow_globals_private.m_bCamInverseMouse) { - camera.angles[CAMERA_PITCH] -= (dy * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - } else { - camera.angles[CAMERA_PITCH] += (dy * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - } - - camera.angles[CAMERA_YAW] += (dx * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - - if (camera.angles[CAMERA_PITCH] > 90) { - camera.angles[CAMERA_PITCH] = 90; - } else if (camera.angles[CAMERA_PITCH] < -90) { - camera.angles[CAMERA_PITCH] = -90; - } - - if (camera.angles[CAMERA_YAW] >= 360) { - camera.angles[CAMERA_YAW] -= 360; - } else if (camera.angles[CAMERA_YAW] <= 0) { - camera.angles[CAMERA_YAW] += 360; - } - } - - Camera_updateModelview(camera); - Camera_Freemove_updateAxes(camera); -} - -void Cam_MouseControl(camera_t &camera, int x, int y) -{ - float xf = (float) (x - camera.width / 2) / (camera.width / 2); - float yf = (float) (y - camera.height / 2) / (camera.height / 2); - - xf *= 1.0f - fabsf(yf); - if (xf < 0) { - xf += 0.1f; - if (xf > 0) { - xf = 0; - } - } else { - xf -= 0.1f; - if (xf < 0) { - xf = 0; - } - } - - vector3_add(camera.origin, vector3_scaled(camera.forward, yf * 0.1f * g_camwindow_globals_private.m_nMoveSpeed)); - camera.angles[CAMERA_YAW] += xf * -0.1f * g_camwindow_globals_private.m_nAngleSpeed; - - Camera_updateModelview(camera); -} - -void Camera_mouseMove(camera_t &camera, int x, int y) -{ - //globalOutputStream() << "mousemove... "; - Camera_FreeMove(camera, -x, -y); - camera.m_update(); - CameraMovedNotify(); -} - -const unsigned int MOVE_NONE = 0; -const unsigned int MOVE_FORWARD = 1 << 0; -const unsigned int MOVE_BACK = 1 << 1; -const unsigned int MOVE_ROTRIGHT = 1 << 2; -const unsigned int MOVE_ROTLEFT = 1 << 3; -const unsigned int MOVE_STRAFERIGHT = 1 << 4; -const unsigned int MOVE_STRAFELEFT = 1 << 5; -const unsigned int MOVE_UP = 1 << 6; -const unsigned int MOVE_DOWN = 1 << 7; -const unsigned int MOVE_PITCHUP = 1 << 8; -const unsigned int MOVE_PITCHDOWN = 1 << 9; -const unsigned int MOVE_ALL = - MOVE_FORWARD | MOVE_BACK | MOVE_ROTRIGHT | MOVE_ROTLEFT | MOVE_STRAFERIGHT | MOVE_STRAFELEFT | MOVE_UP | - MOVE_DOWN | MOVE_PITCHUP | MOVE_PITCHDOWN; - -void Cam_KeyControl(camera_t &camera, float dtime) -{ - // Update angles - if (camera.movementflags & MOVE_ROTLEFT) { - camera.angles[CAMERA_YAW] += (15 * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - } - if (camera.movementflags & MOVE_ROTRIGHT) { - camera.angles[CAMERA_YAW] -= (15 * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - } - if (camera.movementflags & MOVE_PITCHUP) { - camera.angles[CAMERA_PITCH] += (15 * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - if (camera.angles[CAMERA_PITCH] > 90) { - camera.angles[CAMERA_PITCH] = 90; - } - } - if (camera.movementflags & MOVE_PITCHDOWN) { - camera.angles[CAMERA_PITCH] -= (15 * g_camwindow_globals_private.m_nAngleSpeed) * dtime; - if (camera.angles[CAMERA_PITCH] < -90) { - camera.angles[CAMERA_PITCH] = -90; - } - } - - Camera_updateModelview(camera); - Camera_Freemove_updateAxes(camera); - - // Update position - if (camera.movementflags & MOVE_FORWARD) { - vector3_add(camera.origin, vector3_scaled(camera.forward, dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_BACK) { - vector3_add(camera.origin, vector3_scaled(camera.forward, -dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_STRAFELEFT) { - vector3_add(camera.origin, vector3_scaled(camera.right, -dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_STRAFERIGHT) { - vector3_add(camera.origin, vector3_scaled(camera.right, dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_UP) { - vector3_add(camera.origin, vector3_scaled(g_vector3_axis_z, dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - if (camera.movementflags & MOVE_DOWN) { - vector3_add(camera.origin, vector3_scaled(g_vector3_axis_z, -dtime * g_camwindow_globals_private.m_nMoveSpeed)); - } - - Camera_updateModelview(camera); -} - -void Camera_keyMove(camera_t &camera) -{ - camera.m_mouseMove.flush(); - - //globalOutputStream() << "keymove... "; - float time_seconds = camera.m_keycontrol_timer.elapsed_msec() / static_cast( msec_per_sec ) * 0.01; - camera.m_keycontrol_timer.start(); - Cam_KeyControl(camera, 0.016f); - - camera.m_update(); - CameraMovedNotify(); -} - -gboolean camera_keymove(gpointer data) -{ - Camera_keyMove(*reinterpret_cast( data )); - return TRUE; -} - -void Camera_setMovementFlags(camera_t &camera, unsigned int mask) -{ - if ((~camera.movementflags & mask) != 0 && camera.movementflags == 0) { - camera.m_keymove_handler = g_idle_add(camera_keymove, &camera); - } - camera.movementflags |= mask; -} - -void Camera_clearMovementFlags(camera_t &camera, unsigned int mask) -{ - if ((camera.movementflags & ~mask) == 0 && camera.movementflags != 0) { - g_source_remove(camera.m_keymove_handler); - camera.m_keymove_handler = 0; - } - camera.movementflags &= ~mask; -} - -void Camera_MoveForward_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_FORWARD); -} - -void Camera_MoveForward_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_FORWARD); -} - -void Camera_MoveBack_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_BACK); -} - -void Camera_MoveBack_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_BACK); -} - -void Camera_MoveLeft_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_STRAFELEFT); -} - -void Camera_MoveLeft_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_STRAFELEFT); -} - -void Camera_MoveRight_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_STRAFERIGHT); -} - -void Camera_MoveRight_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_STRAFERIGHT); -} - -void Camera_MoveUp_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_UP); -} - -void Camera_MoveUp_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_UP); -} - -void Camera_MoveDown_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_DOWN); -} - -void Camera_MoveDown_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_DOWN); -} - -void Camera_RotateLeft_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_ROTLEFT); -} - -void Camera_RotateLeft_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_ROTLEFT); -} - -void Camera_RotateRight_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_ROTRIGHT); -} - -void Camera_RotateRight_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_ROTRIGHT); -} - -void Camera_PitchUp_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_PITCHUP); -} - -void Camera_PitchUp_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_PITCHUP); -} - -void Camera_PitchDown_KeyDown(camera_t &camera) -{ - Camera_setMovementFlags(camera, MOVE_PITCHDOWN); -} - -void Camera_PitchDown_KeyUp(camera_t &camera) -{ - Camera_clearMovementFlags(camera, MOVE_PITCHDOWN); -} - - -typedef ReferenceCaller FreeMoveCameraMoveForwardKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveForwardKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveBackKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveBackKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveLeftKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveLeftKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveRightKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveRightKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveUpKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveUpKeyUpCaller; -typedef ReferenceCaller FreeMoveCameraMoveDownKeyDownCaller; -typedef ReferenceCaller FreeMoveCameraMoveDownKeyUpCaller; - - -const float SPEED_MOVE = 32; -const float SPEED_TURN = 22.5; -const float MIN_CAM_SPEED = 10; -const float MAX_CAM_SPEED = 610; -const float CAM_SPEED_STEP = 50; - -void Camera_MoveForward_Discrete(camera_t &camera) -{ - Camera_Move_updateAxes(camera); - Camera_setOrigin(camera, vector3_added(Camera_getOrigin(camera), vector3_scaled(camera.forward, SPEED_MOVE))); -} - -void Camera_MoveBack_Discrete(camera_t &camera) -{ - Camera_Move_updateAxes(camera); - Camera_setOrigin(camera, vector3_added(Camera_getOrigin(camera), vector3_scaled(camera.forward, -SPEED_MOVE))); -} - -void Camera_MoveUp_Discrete(camera_t &camera) -{ - Vector3 origin(Camera_getOrigin(camera)); - origin[2] += SPEED_MOVE; - Camera_setOrigin(camera, origin); -} - -void Camera_MoveDown_Discrete(camera_t &camera) -{ - Vector3 origin(Camera_getOrigin(camera)); - origin[2] -= SPEED_MOVE; - Camera_setOrigin(camera, origin); -} - -void Camera_MoveLeft_Discrete(camera_t &camera) -{ - Camera_Move_updateAxes(camera); - Camera_setOrigin(camera, vector3_added(Camera_getOrigin(camera), vector3_scaled(camera.right, -SPEED_MOVE))); -} - -void Camera_MoveRight_Discrete(camera_t &camera) -{ - Camera_Move_updateAxes(camera); - Camera_setOrigin(camera, vector3_added(Camera_getOrigin(camera), vector3_scaled(camera.right, SPEED_MOVE))); -} - -void Camera_RotateLeft_Discrete(camera_t &camera) -{ - Vector3 angles(Camera_getAngles(camera)); - angles[CAMERA_YAW] += SPEED_TURN; - Camera_setAngles(camera, angles); -} - -void Camera_RotateRight_Discrete(camera_t &camera) -{ - Vector3 angles(Camera_getAngles(camera)); - angles[CAMERA_YAW] -= SPEED_TURN; - Camera_setAngles(camera, angles); -} - -void Camera_PitchUp_Discrete(camera_t &camera) -{ - Vector3 angles(Camera_getAngles(camera)); - angles[CAMERA_PITCH] += SPEED_TURN; - if (angles[CAMERA_PITCH] > 90) { - angles[CAMERA_PITCH] = 90; - } - Camera_setAngles(camera, angles); -} - -void Camera_PitchDown_Discrete(camera_t &camera) -{ - Vector3 angles(Camera_getAngles(camera)); - angles[CAMERA_PITCH] -= SPEED_TURN; - if (angles[CAMERA_PITCH] < -90) { - angles[CAMERA_PITCH] = -90; - } - Camera_setAngles(camera, angles); -} - - -class RadiantCameraView : public CameraView { -camera_t &m_camera; -View *m_view; -Callback m_update; -public: -RadiantCameraView(camera_t &camera, View *view, const Callback &update) : m_camera(camera), m_view(view), - m_update(update) -{ -} - -void update() -{ - m_view->Construct(m_camera.projection, m_camera.modelview, m_camera.width, m_camera.height); - m_update(); -} - -void setModelview(const Matrix4 &modelview) -{ - m_camera.modelview = modelview; - matrix4_multiply_by_matrix4(m_camera.modelview, g_radiant2opengl); - matrix4_affine_invert(m_camera.modelview); - Camera_updateVectors(m_camera); - update(); -} - -void setFieldOfView(float fieldOfView) -{ - float farClip = Camera_getFarClipPlane(m_camera); - m_camera.projection = projection_for_camera(farClip / 4096.0f, farClip, fieldOfView, m_camera.width, - m_camera.height); - update(); -} -}; - - -void Camera_motionDelta(int x, int y, unsigned int state, void *data) -{ - camera_t *cam = reinterpret_cast( data ); - - cam->m_mouseMove.motion_delta(x, y, state); - - switch (g_camwindow_globals_private.m_nStrafeMode) { - case 0: - cam->m_strafe = (state & GDK_SHIFT_MASK) != 0; - if (cam->m_strafe) { - cam->m_strafe_forward = (state & GDK_CONTROL_MASK) != 0; - } else { - cam->m_strafe_forward = false; - } - break; - case 1: - cam->m_strafe = (state & GDK_CONTROL_MASK) != 0 && (state & GDK_SHIFT_MASK) == 0; - cam->m_strafe_forward = false; - break; - case 2: - cam->m_strafe = (state & GDK_CONTROL_MASK) != 0 && (state & GDK_SHIFT_MASK) == 0; - cam->m_strafe_forward = cam->m_strafe; - break; - } -} - -class CamWnd { -View m_view; -camera_t m_Camera; -RadiantCameraView m_cameraview; -#if 0 -int m_PositionDragCursorX; -int m_PositionDragCursorY; -#endif - -guint m_freemove_handle_focusout; - -static Shader *m_state_select1; -static Shader *m_state_select2; - -FreezePointer m_freezePointer; - -public: -ui::GLArea m_gl_widget; -ui::Window m_parent{ui::null}; - -SelectionSystemWindowObserver *m_window_observer; -XORRectangle m_XORRectangle; - -DeferredDraw m_deferredDraw; -DeferredMotion m_deferred_motion; - -guint m_selection_button_press_handler; -guint m_selection_button_release_handler; -guint m_selection_motion_handler; - -guint m_freelook_button_press_handler; -guint m_freelook_key_press_handler; - -guint m_sizeHandler; -guint m_exposeHandler; - -CamWnd(); - -~CamWnd(); - -bool m_drawing; - -void queue_draw() -{ - //ASSERT_MESSAGE(!m_drawing, "CamWnd::queue_draw(): called while draw is already in progress"); - if (m_drawing) { - return; - } - //globalOutputStream() << "queue... "; - m_deferredDraw.draw(); -} - -void draw(); - -static void captureStates() -{ - m_state_select1 = GlobalShaderCache().capture("$CAM_HIGHLIGHT"); - m_state_select2 = GlobalShaderCache().capture("$CAM_OVERLAY"); -} - -static void releaseStates() -{ - GlobalShaderCache().release("$CAM_HIGHLIGHT"); - GlobalShaderCache().release("$CAM_OVERLAY"); -} - -camera_t &getCamera() -{ - return m_Camera; -}; - -void BenchMark(); - -void Cam_ChangeFloor(bool up); - -void DisableFreeMove(); - -void EnableFreeMove(); - -bool m_bFreeMove; - -CameraView &getCameraView() -{ - return m_cameraview; -} - -private: -void Cam_Draw(); -}; - -typedef MemberCaller CamWndQueueDraw; - -Shader *CamWnd::m_state_select1 = 0; -Shader *CamWnd::m_state_select2 = 0; - -CamWnd *NewCamWnd() -{ - return new CamWnd; -} - -void DeleteCamWnd(CamWnd *camwnd) -{ - delete camwnd; -} - -void CamWnd_constructStatic() -{ - CamWnd::captureStates(); -} - -void CamWnd_destroyStatic() -{ - CamWnd::releaseStates(); -} - -static CamWnd *g_camwnd = 0; - -void GlobalCamera_setCamWnd(CamWnd &camwnd) -{ - g_camwnd = &camwnd; -} - - -ui::GLArea CamWnd_getWidget(CamWnd &camwnd) -{ - return camwnd.m_gl_widget; -} - -ui::Window CamWnd_getParent(CamWnd &camwnd) -{ - return camwnd.m_parent; -} - -ToggleShown g_camera_shown(true); - -void CamWnd_setParent(CamWnd &camwnd, ui::Window parent) -{ - camwnd.m_parent = parent; - g_camera_shown.connect(camwnd.m_parent); -} - -void CamWnd_Update(CamWnd &camwnd) -{ - camwnd.queue_draw(); -} - - -camwindow_globals_t g_camwindow_globals; - -const Vector3 &Camera_getOrigin(CamWnd &camwnd) -{ - return Camera_getOrigin(camwnd.getCamera()); -} - -void Camera_setOrigin(CamWnd &camwnd, const Vector3 &origin) -{ - Camera_setOrigin(camwnd.getCamera(), origin); -} - -const Vector3 &Camera_getAngles(CamWnd &camwnd) -{ - return Camera_getAngles(camwnd.getCamera()); -} - -void Camera_setAngles(CamWnd &camwnd, const Vector3 &angles) -{ - Camera_setAngles(camwnd.getCamera(), angles); -} - - -// ============================================================================= -// CamWnd class - -gboolean enable_freelook_button_press(ui::Widget widget, GdkEventButton *event, CamWnd *camwnd) -{ - if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - camwnd->EnableFreeMove(); - return TRUE; - } - return FALSE; -} - -gboolean disable_freelook_button_press(ui::Widget widget, GdkEventButton *event, CamWnd *camwnd) -{ - if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - camwnd->DisableFreeMove(); - return TRUE; - } - return FALSE; -} - -static gint disable_freelook_key_press(ui::Entry widget, GdkEventKey *event, CamWnd *camwnd) -{ - if (event->keyval == GDK_KEY_Escape) { - camwnd->DisableFreeMove(); - return TRUE; - } - return FALSE; -} - -#if 0 -gboolean mousecontrol_button_press( ui::Widget widget, GdkEventButton* event, CamWnd* camwnd ){ - if ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) { - Cam_MouseControl( camwnd->getCamera(), event->x, widget->allocation.height - 1 - event->y ); - } - return FALSE; -} -#endif - -void camwnd_update_xor_rectangle(CamWnd &self, rect_t area) -{ - if (self.m_gl_widget.visible()) { - self.m_XORRectangle.set( - rectangle_from_area(area.min, area.max, self.getCamera().width, self.getCamera().height)); - } -} - - -gboolean selection_button_press(ui::Widget widget, GdkEventButton *event, WindowObserver *observer) -{ - if (event->type == GDK_BUTTON_PRESS) { - observer->onMouseDown(WindowVector_forDouble(event->x, event->y), button_for_button(event->button), - modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean selection_button_release(ui::Widget widget, GdkEventButton *event, WindowObserver *observer) -{ - if (event->type == GDK_BUTTON_RELEASE) { - observer->onMouseUp(WindowVector_forDouble(event->x, event->y), button_for_button(event->button), - modifiers_for_state(event->state)); - } - return FALSE; -} - -void selection_motion(gdouble x, gdouble y, guint state, void *data) -{ - //globalOutputStream() << "motion... "; - reinterpret_cast( data )->onMouseMotion(WindowVector_forDouble(x, y), modifiers_for_state(state)); -} - -inline WindowVector windowvector_for_widget_centre(ui::Widget widget) -{ - auto allocation = widget.dimensions(); - return WindowVector(static_cast( allocation.width / 2 ), static_cast(allocation.height / 2 )); -} - -gboolean selection_button_press_freemove(ui::Widget widget, GdkEventButton *event, WindowObserver *observer) -{ - if (event->type == GDK_BUTTON_PRESS) { - observer->onMouseDown(windowvector_for_widget_centre(widget), button_for_button(event->button), - modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean selection_button_release_freemove(ui::Widget widget, GdkEventButton *event, WindowObserver *observer) -{ - if (event->type == GDK_BUTTON_RELEASE) { - observer->onMouseUp(windowvector_for_widget_centre(widget), button_for_button(event->button), - modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean selection_motion_freemove(ui::Widget widget, GdkEventMotion *event, WindowObserver *observer) -{ - observer->onMouseMotion(windowvector_for_widget_centre(widget), modifiers_for_state(event->state)); - return FALSE; -} - -gboolean wheelmove_scroll(ui::Widget widget, GdkEventScroll *event, CamWnd *camwnd) -{ - if (event->direction == GDK_SCROLL_UP) { - Camera_Freemove_updateAxes(camwnd->getCamera()); - Camera_setOrigin(*camwnd, vector3_added(Camera_getOrigin(*camwnd), vector3_scaled(camwnd->getCamera().forward, - static_cast( g_camwindow_globals_private.m_nMoveSpeed )))); - } else if (event->direction == GDK_SCROLL_DOWN) { - Camera_Freemove_updateAxes(camwnd->getCamera()); - Camera_setOrigin(*camwnd, vector3_added(Camera_getOrigin(*camwnd), vector3_scaled(camwnd->getCamera().forward, - -static_cast( g_camwindow_globals_private.m_nMoveSpeed )))); - } - - return FALSE; -} - -gboolean camera_size_allocate(ui::Widget widget, GtkAllocation *allocation, CamWnd *camwnd) -{ - camwnd->getCamera().width = allocation->width; - camwnd->getCamera().height = allocation->height; - Camera_updateProjection(camwnd->getCamera()); - camwnd->m_window_observer->onSizeChanged(camwnd->getCamera().width, camwnd->getCamera().height); - camwnd->queue_draw(); - return FALSE; -} - -gboolean camera_expose(ui::Widget widget, GdkEventExpose *event, gpointer data) -{ - reinterpret_cast( data )->draw(); - return FALSE; -} - -void KeyEvent_connect(const char *name) -{ - const KeyEvent &keyEvent = GlobalKeyEvents_find(name); - keydown_accelerators_add(keyEvent.m_accelerator, keyEvent.m_keyDown); - keyup_accelerators_add(keyEvent.m_accelerator, keyEvent.m_keyUp); -} - -void KeyEvent_disconnect(const char *name) -{ - const KeyEvent &keyEvent = GlobalKeyEvents_find(name); - keydown_accelerators_remove(keyEvent.m_accelerator); - keyup_accelerators_remove(keyEvent.m_accelerator); -} - -void CamWnd_registerCommands(CamWnd &camwnd) -{ - GlobalKeyEvents_insert("CameraForward", Accelerator(GDK_KEY_Up), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraBack", Accelerator(GDK_KEY_Down), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraLeft", Accelerator(GDK_KEY_Left), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraRight", Accelerator(GDK_KEY_Right), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraStrafeRight", Accelerator(GDK_KEY_period), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraStrafeLeft", Accelerator(GDK_KEY_comma), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraUp", Accelerator('D'), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraDown", Accelerator('C'), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraAngleDown", Accelerator('A'), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraAngleUp", Accelerator('Z'), - ReferenceCaller(camwnd.getCamera()), - ReferenceCaller(camwnd.getCamera()) - ); - - GlobalKeyEvents_insert("CameraFreeMoveForward", Accelerator(GDK_KEY_Up), - FreeMoveCameraMoveForwardKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveForwardKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveBack", Accelerator(GDK_KEY_Down), - FreeMoveCameraMoveBackKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveBackKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveLeft", Accelerator(GDK_KEY_Left), - FreeMoveCameraMoveLeftKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveLeftKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveRight", Accelerator(GDK_KEY_Right), - FreeMoveCameraMoveRightKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveRightKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveUp", Accelerator('D'), - FreeMoveCameraMoveUpKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveUpKeyUpCaller(camwnd.getCamera()) - ); - GlobalKeyEvents_insert("CameraFreeMoveDown", Accelerator('C'), - FreeMoveCameraMoveDownKeyDownCaller(camwnd.getCamera()), - FreeMoveCameraMoveDownKeyUpCaller(camwnd.getCamera()) - ); - - GlobalCommands_insert("CameraForward", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_Up)); - GlobalCommands_insert("CameraBack", ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_Down)); - GlobalCommands_insert("CameraLeft", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_Left)); - GlobalCommands_insert("CameraRight", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_Right)); - GlobalCommands_insert("CameraStrafeRight", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_period)); - GlobalCommands_insert("CameraStrafeLeft", - ReferenceCaller(camwnd.getCamera()), - Accelerator(GDK_KEY_comma)); - - GlobalCommands_insert("CameraUp", ReferenceCaller(camwnd.getCamera()), - Accelerator('D')); - GlobalCommands_insert("CameraDown", ReferenceCaller(camwnd.getCamera()), - Accelerator('C')); - GlobalCommands_insert("CameraAngleUp", - ReferenceCaller(camwnd.getCamera()), - Accelerator('A')); - GlobalCommands_insert("CameraAngleDown", - ReferenceCaller(camwnd.getCamera()), - Accelerator('Z')); -} - -void CamWnd_Move_Enable(CamWnd &camwnd) -{ - KeyEvent_connect("CameraForward"); - KeyEvent_connect("CameraBack"); - KeyEvent_connect("CameraLeft"); - KeyEvent_connect("CameraRight"); - KeyEvent_connect("CameraStrafeRight"); - KeyEvent_connect("CameraStrafeLeft"); - KeyEvent_connect("CameraUp"); - KeyEvent_connect("CameraDown"); - KeyEvent_connect("CameraAngleUp"); - KeyEvent_connect("CameraAngleDown"); -} - -void CamWnd_Move_Disable(CamWnd &camwnd) -{ - KeyEvent_disconnect("CameraForward"); - KeyEvent_disconnect("CameraBack"); - KeyEvent_disconnect("CameraLeft"); - KeyEvent_disconnect("CameraRight"); - KeyEvent_disconnect("CameraStrafeRight"); - KeyEvent_disconnect("CameraStrafeLeft"); - KeyEvent_disconnect("CameraUp"); - KeyEvent_disconnect("CameraDown"); - KeyEvent_disconnect("CameraAngleUp"); - KeyEvent_disconnect("CameraAngleDown"); -} - -void CamWnd_Move_Discrete_Enable(CamWnd &camwnd) -{ - command_connect_accelerator("CameraForward"); - command_connect_accelerator("CameraBack"); - command_connect_accelerator("CameraLeft"); - command_connect_accelerator("CameraRight"); - command_connect_accelerator("CameraStrafeRight"); - command_connect_accelerator("CameraStrafeLeft"); - command_connect_accelerator("CameraUp"); - command_connect_accelerator("CameraDown"); - command_connect_accelerator("CameraAngleUp"); - command_connect_accelerator("CameraAngleDown"); -} - -void CamWnd_Move_Discrete_Disable(CamWnd &camwnd) -{ - command_disconnect_accelerator("CameraForward"); - command_disconnect_accelerator("CameraBack"); - command_disconnect_accelerator("CameraLeft"); - command_disconnect_accelerator("CameraRight"); - command_disconnect_accelerator("CameraStrafeRight"); - command_disconnect_accelerator("CameraStrafeLeft"); - command_disconnect_accelerator("CameraUp"); - command_disconnect_accelerator("CameraDown"); - command_disconnect_accelerator("CameraAngleUp"); - command_disconnect_accelerator("CameraAngleDown"); -} - -struct CamWnd_Move_Discrete { - static void Export(const Callback &returnz) - { - returnz(g_camwindow_globals_private.m_bCamDiscrete); - } - - static void Import(bool value) - { - if (g_camwnd) { - Import_(*g_camwnd, value); - } else { - g_camwindow_globals_private.m_bCamDiscrete = value; - } - } - - static void Import_(CamWnd &camwnd, bool value) - { - if (g_camwindow_globals_private.m_bCamDiscrete) { - CamWnd_Move_Discrete_Disable(camwnd); - } else { - CamWnd_Move_Disable(camwnd); - } - - g_camwindow_globals_private.m_bCamDiscrete = value; - - if (g_camwindow_globals_private.m_bCamDiscrete) { - CamWnd_Move_Discrete_Enable(camwnd); - } else { - CamWnd_Move_Enable(camwnd); - } - } -}; - - -void CamWnd_Add_Handlers_Move(CamWnd &camwnd) -{ - camwnd.m_selection_button_press_handler = camwnd.m_gl_widget.connect("button_press_event", - G_CALLBACK(selection_button_press), - camwnd.m_window_observer); - camwnd.m_selection_button_release_handler = camwnd.m_gl_widget.connect("button_release_event", - G_CALLBACK(selection_button_release), - camwnd.m_window_observer); - camwnd.m_selection_motion_handler = camwnd.m_gl_widget.connect("motion_notify_event", - G_CALLBACK(DeferredMotion::gtk_motion), - &camwnd.m_deferred_motion); - - camwnd.m_freelook_button_press_handler = camwnd.m_gl_widget.connect("button_press_event", - G_CALLBACK(enable_freelook_button_press), - &camwnd); - - if (g_camwindow_globals_private.m_bCamDiscrete) { - CamWnd_Move_Discrete_Enable(camwnd); - } else { - CamWnd_Move_Enable(camwnd); - } -} - -void CamWnd_Remove_Handlers_Move(CamWnd &camwnd) -{ - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_button_press_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_button_release_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_motion_handler); - - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_freelook_button_press_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_freelook_key_press_handler); - - if (g_camwindow_globals_private.m_bCamDiscrete) { - CamWnd_Move_Discrete_Disable(camwnd); - } else { - CamWnd_Move_Disable(camwnd); - } -} - -void CamWnd_Add_Handlers_FreeMove(CamWnd &camwnd) -{ - camwnd.m_selection_button_press_handler = camwnd.m_gl_widget.connect( - "button_press_event", - G_CALLBACK(selection_button_press_freemove), - camwnd.m_window_observer); - camwnd.m_selection_button_release_handler = camwnd.m_gl_widget.connect( - "button_release_event", - G_CALLBACK(selection_button_release_freemove), - camwnd.m_window_observer); - camwnd.m_selection_motion_handler = camwnd.m_gl_widget.connect( - "motion_notify_event", - G_CALLBACK(selection_motion_freemove), - camwnd.m_window_observer); - camwnd.m_freelook_button_press_handler = camwnd.m_gl_widget.connect( - "button_press_event", - G_CALLBACK(disable_freelook_button_press), - &camwnd); - camwnd.m_freelook_key_press_handler = camwnd.m_gl_widget.connect( - "key_press_event", - G_CALLBACK(disable_freelook_key_press), - &camwnd); - - KeyEvent_connect("CameraFreeMoveForward"); - KeyEvent_connect("CameraFreeMoveBack"); - KeyEvent_connect("CameraFreeMoveLeft"); - KeyEvent_connect("CameraFreeMoveRight"); - KeyEvent_connect("CameraFreeMoveUp"); - KeyEvent_connect("CameraFreeMoveDown"); -} - -void CamWnd_Remove_Handlers_FreeMove(CamWnd &camwnd) -{ - KeyEvent_disconnect("CameraFreeMoveForward"); - KeyEvent_disconnect("CameraFreeMoveBack"); - KeyEvent_disconnect("CameraFreeMoveLeft"); - KeyEvent_disconnect("CameraFreeMoveRight"); - KeyEvent_disconnect("CameraFreeMoveUp"); - KeyEvent_disconnect("CameraFreeMoveDown"); - - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_button_press_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_button_release_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_selection_motion_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_freelook_button_press_handler); - g_signal_handler_disconnect(G_OBJECT(camwnd.m_gl_widget), camwnd.m_freelook_key_press_handler); -} - -CamWnd::CamWnd() : - m_view(true), - m_Camera(&m_view, CamWndQueueDraw(*this)), - m_cameraview(m_Camera, &m_view, ReferenceCaller(*this)), - m_gl_widget(glwidget_new(TRUE)), - m_window_observer(NewWindowObserver()), - m_XORRectangle(m_gl_widget), - m_deferredDraw(WidgetQueueDrawCaller(m_gl_widget)), - m_deferred_motion(selection_motion, m_window_observer), - m_selection_button_press_handler(0), - m_selection_button_release_handler(0), - m_selection_motion_handler(0), - m_freelook_button_press_handler(0), - m_freelook_key_press_handler(0), - m_drawing(false) -{ - m_bFreeMove = false; - - GlobalWindowObservers_add(m_window_observer); - GlobalWindowObservers_connectWidget(m_gl_widget); - - m_window_observer->setRectangleDrawCallback( - ReferenceCaller(*this)); - m_window_observer->setView(m_view); - - g_object_ref(m_gl_widget._handle); - - gtk_widget_set_events(m_gl_widget, - GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK); - gtk_widget_set_can_focus(m_gl_widget, true); - - m_sizeHandler = m_gl_widget.connect("size_allocate", G_CALLBACK(camera_size_allocate), this); - m_exposeHandler = m_gl_widget.on_render(G_CALLBACK(camera_expose), this); - - Map_addValidCallback(g_map, DeferredDrawOnMapValidChangedCaller(m_deferredDraw)); - - CamWnd_registerCommands(*this); - - CamWnd_Add_Handlers_Move(*this); - - m_gl_widget.connect("scroll_event", G_CALLBACK(wheelmove_scroll), this); - - AddSceneChangeCallback(ReferenceCaller(*this)); - - PressedButtons_connect(g_pressedButtons, m_gl_widget); -} - -CamWnd::~CamWnd() -{ - if (m_bFreeMove) { - DisableFreeMove(); - } - - CamWnd_Remove_Handlers_Move(*this); - - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_sizeHandler); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_exposeHandler); - - m_gl_widget.unref(); - - m_window_observer->release(); -} - -class FloorHeightWalker : public scene::Graph::Walker { -float m_current; -float &m_bestUp; -float &m_bestDown; -public: -FloorHeightWalker(float current, float &bestUp, float &bestDown) : - m_current(current), m_bestUp(bestUp), m_bestDown(bestDown) -{ - bestUp = g_MaxWorldCoord; - bestDown = -g_MaxWorldCoord; -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible() - && Node_isBrush(path.top())) { // this node is a floor - const AABB &aabb = instance.worldAABB(); - float floorHeight = aabb.origin.z() + aabb.extents.z(); - if (floorHeight > m_current && floorHeight < m_bestUp) { - m_bestUp = floorHeight; - } - if (floorHeight < m_current && floorHeight > m_bestDown) { - m_bestDown = floorHeight; - } - } - return true; -} -}; - -void CamWnd::Cam_ChangeFloor(bool up) -{ - float current = m_Camera.origin[2] - 48; - float bestUp; - float bestDown; - GlobalSceneGraph().traverse(FloorHeightWalker(current, bestUp, bestDown)); - - if (up && bestUp != g_MaxWorldCoord) { - current = bestUp; - } - if (!up && bestDown != -g_MaxWorldCoord) { - current = bestDown; - } - - m_Camera.origin[2] = current + 48; - Camera_updateModelview(getCamera()); - CamWnd_Update(*this); - CameraMovedNotify(); -} - - -#if 0 - -// button_press -Sys_GetCursorPos( &m_PositionDragCursorX, &m_PositionDragCursorY ); - -// motion -if ( ( m_bFreeMove && ( buttons == ( RAD_CONTROL | RAD_SHIFT ) ) ) - || ( !m_bFreeMove && ( buttons == ( RAD_RBUTTON | RAD_CONTROL ) ) ) ) { - Cam_PositionDrag(); - CamWnd_Update( camwnd ); - CameraMovedNotify(); - return; -} - -void CamWnd::Cam_PositionDrag(){ - int x, y; - - Sys_GetCursorPos( m_gl_widget, &x, &y ); - if ( x != m_PositionDragCursorX || y != m_PositionDragCursorY ) { - x -= m_PositionDragCursorX; - vector3_add( m_Camera.origin, vector3_scaled( m_Camera.vright, x ) ); - y -= m_PositionDragCursorY; - m_Camera.origin[2] -= y; - Camera_updateModelview(); - CamWnd_Update( camwnd ); - CameraMovedNotify(); - - Sys_SetCursorPos( m_parent, m_PositionDragCursorX, m_PositionDragCursorY ); - } -} -#endif - - -// NOTE TTimo if there's an OS-level focus out of the application -// then we can release the camera cursor grab -static gboolean camwindow_freemove_focusout(ui::Widget widget, GdkEventFocus *event, gpointer data) -{ - reinterpret_cast( data )->DisableFreeMove(); - return FALSE; -} - -void CamWnd::EnableFreeMove() -{ - //globalOutputStream() << "EnableFreeMove\n"; - - ASSERT_MESSAGE(!m_bFreeMove, "EnableFreeMove: free-move was already enabled"); - m_bFreeMove = true; - Camera_clearMovementFlags(getCamera(), MOVE_ALL); - - CamWnd_Remove_Handlers_Move(*this); - CamWnd_Add_Handlers_FreeMove(*this); - - gtk_window_set_focus(m_parent, m_gl_widget); - m_freemove_handle_focusout = m_gl_widget.connect("focus_out_event", G_CALLBACK(camwindow_freemove_focusout), this); - m_freezePointer.freeze_pointer(m_parent, Camera_motionDelta, &m_Camera); - - CamWnd_Update(*this); -} - -void CamWnd::DisableFreeMove() -{ - //globalOutputStream() << "DisableFreeMove\n"; - - //ASSERT_MESSAGE(m_bFreeMove, "DisableFreeMove: free-move was not enabled"); - if (m_bFreeMove == false) { - return; - } - m_bFreeMove = false; - Camera_clearMovementFlags(getCamera(), MOVE_ALL); - - CamWnd_Remove_Handlers_FreeMove(*this); - CamWnd_Add_Handlers_Move(*this); - - m_freezePointer.unfreeze_pointer(m_parent); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_freemove_handle_focusout); - - CamWnd_Update(*this); -} - - -#include "renderer.h" - -class CamRenderer : public Renderer { -struct state_type { - state_type() : m_highlight(0), m_state(0), m_lights(0) - { - } - - unsigned int m_highlight; - Shader *m_state; - const LightList *m_lights; -}; - -std::vector m_state_stack; -RenderStateFlags m_globalstate; -Shader *m_state_select0; -Shader *m_state_select1; -const Vector3 &m_viewer; - -public: -CamRenderer(RenderStateFlags globalstate, Shader *select0, Shader *select1, const Vector3 &viewer) : - m_globalstate(globalstate), - m_state_select0(select0), - m_state_select1(select1), - m_viewer(viewer) -{ - ASSERT_NOTNULL(select0); - ASSERT_NOTNULL(select1); - m_state_stack.push_back(state_type()); -} - -void SetState(Shader *state, EStyle style) -{ - ASSERT_NOTNULL(state); - if (style == eFullMaterials) { - m_state_stack.back().m_state = state; - } -} - -EStyle getStyle() const -{ - return eFullMaterials; -} - -void PushState() -{ - m_state_stack.push_back(m_state_stack.back()); -} - -void PopState() -{ - ASSERT_MESSAGE(!m_state_stack.empty(), "popping empty stack"); - m_state_stack.pop_back(); -} - -void Highlight(EHighlightMode mode, bool bEnable = true) -{ - (bEnable) - ? m_state_stack.back().m_highlight |= mode - : m_state_stack.back().m_highlight &= ~mode; -} - -void setLights(const LightList &lights) -{ - m_state_stack.back().m_lights = &lights; -} - -void addRenderable(const OpenGLRenderable &renderable, const Matrix4 &world) -{ - if (m_state_stack.back().m_highlight & ePrimitive) { - m_state_select0->addRenderable(renderable, world, m_state_stack.back().m_lights); - } - if (m_state_stack.back().m_highlight & eFace) { - m_state_select1->addRenderable(renderable, world, m_state_stack.back().m_lights); - } - - m_state_stack.back().m_state->addRenderable(renderable, world, m_state_stack.back().m_lights); -} - -void render(const Matrix4 &modelview, const Matrix4 &projection) -{ - GlobalShaderCache().render(m_globalstate, modelview, projection, m_viewer); -} -}; - -/* - ============== - Cam_Draw - ============== - */ - -void ShowStatsToggle() -{ - g_camwindow_globals_private.m_showStats ^= 1; -} -void ShowStatsExport(const Callback &importer) -{ - importer(g_camwindow_globals_private.m_showStats); -} -FreeCaller &), ShowStatsExport> g_show_stats_caller; -Callback &)> g_show_stats_callback(g_show_stats_caller); -ToggleItem g_show_stats(g_show_stats_callback); - -void ShowLightToggle() -{ - g_camwindow_globals_private.m_showLighting ^= 1; -} -void ShowLightExport(const Callback &importer) -{ - importer(g_camwindow_globals_private.m_showLighting); -} -FreeCaller &), ShowLightExport> g_show_light_caller; -Callback &)> g_show_light_callback(g_show_light_caller); -ToggleItem g_show_light(g_show_light_callback); - -void ShowAlphaToggle() -{ - g_camwindow_globals_private.m_showAlpha ^= 1; -} -void ShowAlphaExport(const Callback &importer) -{ - importer(g_camwindow_globals_private.m_showAlpha); -} -FreeCaller &), ShowAlphaExport> g_show_alpha_caller; -Callback &)> g_show_alpha_callback(g_show_alpha_caller); -ToggleItem g_show_alpha(g_show_alpha_callback); - -/* Show Patch Balls */ -void ShowPatchBallsToggle() -{ - g_camwindow_globals_private.m_showPatchBalls ^= 1; -} -void ShowPatchBallsExport(const Callback &importer) -{ - importer(g_camwindow_globals_private.m_showPatchBalls); -} -FreeCaller &), ShowPatchBallsExport> g_show_patchballs_caller; -Callback &)> g_show_patchballs_callback(g_show_patchballs_caller); -ToggleItem g_show_patchballs(g_show_patchballs_callback); - -bool -PatchBalls_Visible(void) -{ - return g_camwindow_globals_private.m_showPatchBalls; -} - -void CamWnd::Cam_Draw() -{ - glViewport(0, 0, m_Camera.width, m_Camera.height); - glScissor(0, 0, m_Camera.width, m_Camera.height); - glEnable(GL_SCISSOR_TEST); - #if 0 - GLint viewprt[4]; - glGetIntegerv( GL_VIEWPORT, viewprt ); - #endif - - // enable depth buffer writes - glDepthMask(GL_TRUE); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - Vector3 clearColour(0, 0, 0); - if (m_Camera.draw_mode != cd_lighting) { - clearColour = g_camwindow_globals.color_cameraback; - } - - glClearColor(clearColour[0], clearColour[1], clearColour[2], 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - extern void Renderer_ResetStats(); - Renderer_ResetStats(); - extern void Cull_ResetStats(); - Cull_ResetStats(); - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(reinterpret_cast( &m_Camera.projection )); - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(reinterpret_cast( &m_Camera.modelview )); - - - /* | RENDER_POLYGONSMOOTH | RENDER_LINESMOOTH */ - unsigned int globalstate = - /*RENDER_DEPTHTEST | RENDER_COLOURWRITE | | - RENDER_COLOURARRAY | RENDER_OFFSETLINE | RENDER_FOG | RENDER_COLOURCHANGE |*/ - RENDER_DEPTHTEST | RENDER_CULLFACE | RENDER_POLYOFS | RENDER_DEPTHWRITE; - - if (g_camwindow_globals_private.m_showAlpha) { - globalstate |= RENDER_ALPHATEST | RENDER_BLEND; - } - - if (g_camwindow_globals_private.m_showLighting) { - GLfloat inverse_cam_dir[4], ambient[4], diffuse[4]; - ambient[0] = ambient[1] = ambient[2] = 0.25f; - ambient[3] = 1.0f; - diffuse[0] = diffuse[1] = diffuse[2] = 1.0f; - diffuse[3] = 1.0f; - inverse_cam_dir[0] = m_Camera.vpn[0]; - inverse_cam_dir[1] = m_Camera.vpn[1]; - inverse_cam_dir[2] = m_Camera.vpn[2]; - inverse_cam_dir[3] = 0; - glLightfv(GL_LIGHT0, GL_POSITION, inverse_cam_dir); - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); - glEnable(GL_LIGHT0); - globalstate |= RENDER_LIGHTING; - } - - switch (m_Camera.draw_mode) { - case cd_wire: - break; - case cd_solid: - globalstate |= RENDER_FILL - | RENDER_SCALED; - break; - case cd_texture: - globalstate |= RENDER_FILL - | RENDER_TEXTURE - | RENDER_SMOOTH - | RENDER_SCALED; - break; - case cd_lighting: - globalstate |= RENDER_FILL - | RENDER_TEXTURE - | RENDER_SMOOTH - | RENDER_SCALED - | RENDER_BUMP - | RENDER_PROGRAM - | RENDER_SCREEN; - break; - default: - globalstate = 0; - break; - } - - if (!g_xywindow_globals.m_bNoStipple) { - globalstate |= RENDER_LINESTIPPLE | RENDER_POLYGONSTIPPLE; - } - - /* render */ - { - CamRenderer renderer(globalstate, m_state_select2, m_state_select1, m_view.getViewer()); - Scene_Render(renderer, m_view); - renderer.render(m_Camera.modelview, m_Camera.projection); - } - - // prepare for 2d stuff - glColor4f(1, 1, 1, 1); - glDisable(GL_BLEND); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, (float) m_Camera.width, 0, (float) m_Camera.height, -100, 100); - glScalef(1, -1, 1); - glTranslatef(0, -(float) m_Camera.height, 0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - if (GlobalOpenGL().GL_1_3()) { - glClientActiveTexture(GL_TEXTURE0); - glActiveTexture(GL_TEXTURE0); - } - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_DEPTH_TEST); - glColor3f(1.f, 1.f, 1.f); - glLineWidth(1); - - // draw the crosshair - if (m_bFreeMove) { - glBegin(GL_LINES); - glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f + 6); - glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f + 2); - glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f - 6); - glVertex2f((float) m_Camera.width / 2.f, (float) m_Camera.height / 2.f - 2); - glVertex2f((float) m_Camera.width / 2.f + 6, (float) m_Camera.height / 2.f); - glVertex2f((float) m_Camera.width / 2.f + 2, (float) m_Camera.height / 2.f); - glVertex2f((float) m_Camera.width / 2.f - 6, (float) m_Camera.height / 2.f); - glVertex2f((float) m_Camera.width / 2.f - 2, (float) m_Camera.height / 2.f); - glEnd(); - } - - if (g_camwindow_globals_private.m_showStats) { - glRasterPos3f(1.0f, static_cast( m_Camera.height ) - GlobalOpenGL().m_font->getPixelDescent(), 0.0f); - extern const char *Renderer_GetStats(); - GlobalOpenGL().drawString(Renderer_GetStats()); - - glRasterPos3f(1.0f, static_cast( m_Camera.height ) - GlobalOpenGL().m_font->getPixelDescent() - - GlobalOpenGL().m_font->getPixelHeight(), 0.0f); - extern const char *Cull_GetStats(); - GlobalOpenGL().drawString(Cull_GetStats()); - } - - // bind back to the default texture so that we don't have problems - // elsewhere using/modifying texture maps between contexts - glBindTexture(GL_TEXTURE_2D, 0); -} - -void CamWnd::draw() -{ - m_drawing = true; - - if (glwidget_make_current(m_gl_widget) != FALSE) { - if (Map_Valid(g_map) && ScreenUpdates_Enabled()) { - GlobalOpenGL_debugAssertNoErrors(); - Cam_Draw(); - GlobalOpenGL_debugAssertNoErrors(); - m_XORRectangle.set(rectangle_t()); - } - - glwidget_swap_buffers(m_gl_widget); - } - - m_drawing = false; -} - -void CamWnd::BenchMark() -{ - double dStart = Sys_DoubleTime(); - for (int i = 0; i < 100; i++) { - Vector3 angles; - angles[CAMERA_ROLL] = 0; - angles[CAMERA_PITCH] = 0; - angles[CAMERA_YAW] = static_cast( i * (360.0 / 100.0)); - Camera_setAngles(*this, angles); - } - double dEnd = Sys_DoubleTime(); - globalOutputStream() << FloatFormat(dEnd - dStart, 5, 2) << " seconds\n"; -} - - -void fill_view_camera_menu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "Camera View", "ToggleCamera"); -} - -void GlobalCamera_ResetAngles() -{ - CamWnd &camwnd = *g_camwnd; - Vector3 angles; - angles[CAMERA_ROLL] = angles[CAMERA_PITCH] = 0; - angles[CAMERA_YAW] = static_cast( 22.5 * floor((Camera_getAngles(camwnd)[CAMERA_YAW] + 11) / 22.5)); - Camera_setAngles(camwnd, angles); -} - -void Camera_ChangeFloorUp() -{ - CamWnd &camwnd = *g_camwnd; - camwnd.Cam_ChangeFloor(true); -} - -void Camera_ChangeFloorDown() -{ - CamWnd &camwnd = *g_camwnd; - camwnd.Cam_ChangeFloor(false); -} - -void Camera_CubeIn() -{ - CamWnd &camwnd = *g_camwnd; - g_camwindow_globals.m_nCubicScale--; - if (g_camwindow_globals.m_nCubicScale < 1) { - g_camwindow_globals.m_nCubicScale = 1; - } - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); - g_pParentWnd->SetGridStatus(); -} - -void Camera_CubeOut() -{ - CamWnd &camwnd = *g_camwnd; - g_camwindow_globals.m_nCubicScale++; - if (g_camwindow_globals.m_nCubicScale > 23) { - g_camwindow_globals.m_nCubicScale = 23; - } - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); - g_pParentWnd->SetGridStatus(); -} - -bool Camera_GetFarClip() -{ - return g_camwindow_globals_private.m_bCubicClipping; -} - -ConstReferenceCaller &), PropertyImpl::Export> g_getfarclip_caller( - g_camwindow_globals_private.m_bCubicClipping); -ToggleItem g_getfarclip_item(g_getfarclip_caller); - -void Camera_SetFarClip(bool value) -{ - CamWnd &camwnd = *g_camwnd; - g_camwindow_globals_private.m_bCubicClipping = value; - g_getfarclip_item.update(); - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); -} - -struct Camera_FarClip { - static void Export(const Callback &returnz) - { - returnz(g_camwindow_globals_private.m_bCubicClipping); - } - - static void Import(bool value) - { - Camera_SetFarClip(value); - } -}; - -void Camera_ToggleFarClip() -{ - Camera_SetFarClip(!Camera_GetFarClip()); -} - - -void CamWnd_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_toggle_button(toolbar, "Cubic clip the camera view", "view_cubicclipping.xpm", - "ToggleCubicClip"); -} - -void CamWnd_registerShortcuts() -{ - toggle_add_accelerator("ToggleCubicClip"); - command_connect_accelerator("CameraSpeedInc"); - command_connect_accelerator("CameraSpeedDec"); -} - - -void GlobalCamera_Benchmark() -{ - CamWnd &camwnd = *g_camwnd; - camwnd.BenchMark(); -} - -void GlobalCamera_Update() -{ - CamWnd &camwnd = *g_camwnd; - CamWnd_Update(camwnd); -} - -camera_draw_mode CamWnd_GetMode() -{ - return camera_t::draw_mode; -} - -void CamWnd_SetMode(camera_draw_mode mode) -{ - ShaderCache_setBumpEnabled(mode == cd_lighting); - camera_t::draw_mode = mode; - if (g_camwnd != 0) { - CamWnd_Update(*g_camwnd); - } -} - -void CamWnd_TogglePreview(void) -{ - // switch between textured and lighting mode - CamWnd_SetMode((CamWnd_GetMode() == cd_lighting) ? cd_texture : cd_lighting); -} - - -CameraModel *g_camera_model = 0; - -void CamWnd_LookThroughCamera(CamWnd &camwnd) -{ - if (g_camera_model != 0) { - CamWnd_Add_Handlers_Move(camwnd); - g_camera_model->setCameraView(0, Callback()); - g_camera_model = 0; - Camera_updateModelview(camwnd.getCamera()); - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); - } -} - -inline CameraModel *Instance_getCameraModel(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -void CamWnd_LookThroughSelected(CamWnd &camwnd) -{ - if (g_camera_model != 0) { - CamWnd_LookThroughCamera(camwnd); - } - - if (GlobalSelectionSystem().countSelected() != 0) { - scene::Instance &instance = GlobalSelectionSystem().ultimateSelected(); - CameraModel *cameraModel = Instance_getCameraModel(instance); - if (cameraModel != 0) { - CamWnd_Remove_Handlers_Move(camwnd); - g_camera_model = cameraModel; - g_camera_model->setCameraView(&camwnd.getCameraView(), - ReferenceCaller(camwnd)); - } - } -} - -void GlobalCamera_LookThroughSelected() -{ - CamWnd_LookThroughSelected(*g_camwnd); -} - -void GlobalCamera_LookThroughCamera() -{ - CamWnd_LookThroughCamera(*g_camwnd); -} - -/* sets origin and angle to 0,0,0 coords */ -void XYZ_SetOrigin(const Vector3 &origin); -void GlobalCamera_GoToZero(void) -{ - CamWnd &camwnd = *g_camwnd; - Vector3 zero; - zero[0] = 0; - zero[1] = 0; - zero[2] = 0; - Camera_setAngles(camwnd, zero); - Camera_setOrigin(camwnd, zero); - Camera_updateModelview(camwnd.getCamera()); - Camera_updateProjection(camwnd.getCamera()); - CamWnd_Update(camwnd); - XYZ_SetOrigin(zero); -} - -struct RenderMode { - static void Export(const Callback &returnz) - { - switch (CamWnd_GetMode()) { - case cd_wire: - returnz(0); - break; - case cd_solid: - returnz(1); - break; - case cd_texture: - returnz(2); - break; - case cd_lighting: - returnz(3); - break; - } - } - - static void Import(int value) - { - switch (value) { - case 0: - CamWnd_SetMode(cd_wire); - break; - case 1: - CamWnd_SetMode(cd_solid); - break; - case 2: - CamWnd_SetMode(cd_texture); - break; - case 3: - CamWnd_SetMode(cd_lighting); - break; - default: - CamWnd_SetMode(cd_texture); - } - } -}; - -void Camera_constructPreferences(PreferencesPage &page) -{ - page.appendSlider("Movement Speed", g_camwindow_globals_private.m_nMoveSpeed, TRUE, 0, 0, 100, MIN_CAM_SPEED, - MAX_CAM_SPEED, 1, 10); - page.appendCheckBox("", "Link strafe speed to movement speed", g_camwindow_globals_private.m_bCamLinkSpeed); - page.appendSlider("Rotation Speed", g_camwindow_globals_private.m_nAngleSpeed, TRUE, 0, 0, 3, 1, 180, 1, 10); - page.appendCheckBox("", "Invert mouse vertical axis", g_camwindow_globals_private.m_bCamInverseMouse); - page.appendCheckBox( - "", "Discrete movement", - make_property() - ); - page.appendCheckBox( - "", "Enable far-clip plane", - make_property() - ); - - - const char *render_mode[] = {"Wireframe", "Flatshade", "Textured"}; - - page.appendCombo( - "Render Mode", - STRING_ARRAY_RANGE(render_mode), - make_property() - ); - - - const char *strafe_mode[] = {"Both", "Forward", "Up"}; - - page.appendCombo( - "Strafe Mode", - g_camwindow_globals_private.m_nStrafeMode, - STRING_ARRAY_RANGE(strafe_mode) - ); -} - -void Camera_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Camera", "Camera View Preferences")); - Camera_constructPreferences(page); -} - -void Camera_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Camera_constructPage)); -} - -#include "preferencesystem.h" -#include "stringio.h" -#include "dialog.h" - -void CameraSpeed_increase() -{ - if (g_camwindow_globals_private.m_nMoveSpeed <= (MAX_CAM_SPEED - CAM_SPEED_STEP - 10)) { - g_camwindow_globals_private.m_nMoveSpeed += CAM_SPEED_STEP; - } else { - g_camwindow_globals_private.m_nMoveSpeed = MAX_CAM_SPEED - 10; - } -} - -void CameraSpeed_decrease() -{ - if (g_camwindow_globals_private.m_nMoveSpeed >= (MIN_CAM_SPEED + CAM_SPEED_STEP)) { - g_camwindow_globals_private.m_nMoveSpeed -= CAM_SPEED_STEP; - } else { - g_camwindow_globals_private.m_nMoveSpeed = MIN_CAM_SPEED; - } -} - -/// \brief Initialisation for things that have the same lifespan as this module. -void CamWnd_Construct() -{ - GlobalCommands_insert("CenterView", makeCallbackF(GlobalCamera_ResetAngles), Accelerator(GDK_KEY_End)); - GlobalCommands_insert("GoToZero", makeCallbackF(GlobalCamera_GoToZero)); - - GlobalToggles_insert("ToggleCubicClip", makeCallbackF(Camera_ToggleFarClip), - ToggleItem::AddCallbackCaller(g_getfarclip_item), - Accelerator('\\', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("CubicClipZoomIn", makeCallbackF(Camera_CubeIn), - Accelerator('[', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("CubicClipZoomOut", makeCallbackF(Camera_CubeOut), - Accelerator(']', (GdkModifierType) GDK_CONTROL_MASK)); - - GlobalCommands_insert("UpFloor", makeCallbackF(Camera_ChangeFloorUp), Accelerator(GDK_KEY_Prior)); - GlobalCommands_insert("DownFloor", makeCallbackF(Camera_ChangeFloorDown), Accelerator(GDK_KEY_Next)); - - GlobalToggles_insert("ToggleCamera", ToggleShown::ToggleCaller(g_camera_shown), - ToggleItem::AddCallbackCaller(g_camera_shown.m_item), - Accelerator('C', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("LookThroughSelected", makeCallbackF(GlobalCamera_LookThroughSelected)); - GlobalCommands_insert("LookThroughCamera", makeCallbackF(GlobalCamera_LookThroughCamera)); - - GlobalCommands_insert("CameraSpeedInc", makeCallbackF(CameraSpeed_increase), - Accelerator(GDK_KEY_KP_Add, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("CameraSpeedDec", makeCallbackF(CameraSpeed_decrease), - Accelerator(GDK_KEY_KP_Subtract, (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalShortcuts_insert("CameraForward", Accelerator(GDK_KEY_Up)); - GlobalShortcuts_insert("CameraBack", Accelerator(GDK_KEY_Down)); - GlobalShortcuts_insert("CameraLeft", Accelerator(GDK_KEY_Left)); - GlobalShortcuts_insert("CameraRight", Accelerator(GDK_KEY_Right)); - GlobalShortcuts_insert("CameraStrafeRight", Accelerator(GDK_KEY_period)); - GlobalShortcuts_insert("CameraStrafeLeft", Accelerator(GDK_KEY_comma)); - - GlobalShortcuts_insert("CameraUp", Accelerator('D')); - GlobalShortcuts_insert("CameraDown", Accelerator('C')); - GlobalShortcuts_insert("CameraAngleUp", Accelerator('A')); - GlobalShortcuts_insert("CameraAngleDown", Accelerator('Z')); - - GlobalShortcuts_insert("CameraFreeMoveForward", Accelerator(GDK_KEY_Up)); - GlobalShortcuts_insert("CameraFreeMoveBack", Accelerator(GDK_KEY_Down)); - GlobalShortcuts_insert("CameraFreeMoveLeft", Accelerator(GDK_KEY_Left)); - GlobalShortcuts_insert("CameraFreeMoveRight", Accelerator(GDK_KEY_Right)); - - GlobalToggles_insert("ShowStats", makeCallbackF(ShowStatsToggle), ToggleItem::AddCallbackCaller(g_show_stats)); - GlobalToggles_insert("ShowLighting", makeCallbackF(ShowLightToggle), ToggleItem::AddCallbackCaller(g_show_light)); - GlobalToggles_insert("ShowAlpha", makeCallbackF(ShowAlphaToggle), ToggleItem::AddCallbackCaller(g_show_alpha)); - GlobalToggles_insert("ShowPatchBalls", makeCallbackF(ShowPatchBallsToggle), ToggleItem::AddCallbackCaller(g_show_patchballs)); - - GlobalPreferenceSystem().registerPreference("ShowStats", - make_property_string(g_camwindow_globals_private.m_showStats)); - GlobalPreferenceSystem().registerPreference("ShowLighting", - make_property_string(g_camwindow_globals_private.m_showLighting)); - GlobalPreferenceSystem().registerPreference("ShowAlpha", - make_property_string(g_camwindow_globals_private.m_showAlpha)); - GlobalPreferenceSystem().registerPreference("ShowPatchBalls", - make_property_string(g_camwindow_globals_private.m_showPatchBalls)); - GlobalPreferenceSystem().registerPreference("MoveSpeed", - make_property_string(g_camwindow_globals_private.m_nMoveSpeed)); - GlobalPreferenceSystem().registerPreference("CamLinkSpeed", - make_property_string(g_camwindow_globals_private.m_bCamLinkSpeed)); - GlobalPreferenceSystem().registerPreference("AngleSpeed", - make_property_string(g_camwindow_globals_private.m_nAngleSpeed)); - GlobalPreferenceSystem().registerPreference("CamInverseMouse", - make_property_string(g_camwindow_globals_private.m_bCamInverseMouse)); - GlobalPreferenceSystem().registerPreference("CamDiscrete", make_property_string()); - GlobalPreferenceSystem().registerPreference("CubicClipping", - make_property_string(g_camwindow_globals_private.m_bCubicClipping)); - GlobalPreferenceSystem().registerPreference("CubicScale", make_property_string(g_camwindow_globals.m_nCubicScale)); - GlobalPreferenceSystem().registerPreference("SI_Colors4", - make_property_string(g_camwindow_globals.color_cameraback)); - GlobalPreferenceSystem().registerPreference("SI_Colors12", - make_property_string(g_camwindow_globals.color_selbrushes3d)); - GlobalPreferenceSystem().registerPreference("CameraRenderMode", make_property_string()); - GlobalPreferenceSystem().registerPreference("StrafeMode", - make_property_string(g_camwindow_globals_private.m_nStrafeMode)); - - CamWnd_constructStatic(); - - Camera_registerPreferencesPage(); -} - -void CamWnd_Destroy() -{ - CamWnd_destroyStatic(); -} - -void CamWnd_DisableMovement() -{ - g_camwnd->DisableFreeMove(); -} diff --git a/src/camwindow.h b/src/camwindow.h deleted file mode 100644 index 4c832e4..0000000 --- a/src/camwindow.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CAMWINDOW_H ) -#define INCLUDED_CAMWINDOW_H - -#include -#include "math/vector.h" -#include "signal/signalfwd.h" - -class CamWnd; - -CamWnd *NewCamWnd(); - -void DeleteCamWnd(CamWnd *camwnd); - -void AddCameraMovedCallback(const SignalHandler &handler); - -void CamWnd_Update(CamWnd &camwnd); - -ui::GLArea CamWnd_getWidget(CamWnd &camwnd); - -void CamWnd_setParent(CamWnd &camwnd, ui::Window parent); - -void GlobalCamera_setCamWnd(CamWnd &camwnd); - -void fill_view_camera_menu(ui::Menu menu); - -void CamWnd_constructToolbar(ui::Toolbar toolbar); - -void CamWnd_registerShortcuts(); - -void GlobalCamera_Benchmark(); - -const Vector3 &Camera_getOrigin(CamWnd &camwnd); - -void Camera_setOrigin(CamWnd &camwnd, const Vector3 &origin); - -enum { - CAMERA_PITCH = 0, // up / down - CAMERA_YAW = 1, // left / right - CAMERA_ROLL = 2, // fall over -}; - -const Vector3 &Camera_getAngles(CamWnd &camwnd); - -void Camera_setAngles(CamWnd &camwnd, const Vector3 &angles); - - -struct camwindow_globals_t { - Vector3 color_cameraback; - Vector3 color_selbrushes3d; - - int m_nCubicScale; - - camwindow_globals_t() : - color_cameraback(0.15f, 0.15f, 0.15f), - color_selbrushes3d(1.0f, 0.0f, 0.0f), - m_nCubicScale(13) - { - } - -}; - -extern camwindow_globals_t g_camwindow_globals; - -void CamWnd_Construct(); - -void CamWnd_Destroy(); - -#endif diff --git a/src/commands.cpp b/src/commands.cpp deleted file mode 100644 index 8add75b..0000000 --- a/src/commands.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "commands.h" - -#include "gtk/gtk.h" -#include "debugging/debugging.h" -#include "warnings.h" - -#include -#include "string/string.h" -#include "versionlib.h" -#include "gtkutil/messagebox.h" -#include "gtkmisc.h" - -typedef std::pair ShortcutValue; // accelerator, isRegistered -typedef std::map Shortcuts; - -void Shortcuts_foreach(Shortcuts &shortcuts, CommandVisitor &visitor) -{ - for (Shortcuts::iterator i = shortcuts.begin(); i != shortcuts.end(); ++i) { - visitor.visit((*i).first.c_str(), (*i).second.first); - } -} - -Shortcuts g_shortcuts; - -const Accelerator &GlobalShortcuts_insert(const char *name, const Accelerator &accelerator) -{ - return (*g_shortcuts.insert(Shortcuts::value_type(name, ShortcutValue(accelerator, false))).first).second.first; -} - -void GlobalShortcuts_foreach(CommandVisitor &visitor) -{ - Shortcuts_foreach(g_shortcuts, visitor); -} - -void GlobalShortcuts_register(const char *name, int type) -{ - Shortcuts::iterator i = g_shortcuts.find(name); - if (i != g_shortcuts.end()) { - (*i).second.second = type; - } -} - -void GlobalShortcuts_reportUnregistered() -{ - for (Shortcuts::iterator i = g_shortcuts.begin(); i != g_shortcuts.end(); ++i) { - if ((*i).second.first.key != 0 && !(*i).second.second) { - globalOutputStream() << "shortcut not registered: " << (*i).first.c_str() << "\n"; - } - } -} - -typedef std::map Commands; - -Commands g_commands; - -void GlobalCommands_insert(const char *name, const Callback &callback, const Accelerator &accelerator) -{ - bool added = g_commands.insert( - Commands::value_type(name, Command(callback, GlobalShortcuts_insert(name, accelerator)))).second; - ASSERT_MESSAGE(added, "command already registered: " << makeQuoted(name)); -} - -const Command &GlobalCommands_find(const char *command) -{ - Commands::iterator i = g_commands.find(command); - ASSERT_MESSAGE(i != g_commands.end(), "failed to lookup command " << makeQuoted(command)); - return (*i).second; -} - -typedef std::map Toggles; - - -Toggles g_toggles; - -void GlobalToggles_insert(const char *name, const Callback &callback, - const Callback &)> &exportCallback, - const Accelerator &accelerator) -{ - bool added = g_toggles.insert(Toggles::value_type(name, Toggle(callback, GlobalShortcuts_insert(name, accelerator), - exportCallback))).second; - ASSERT_MESSAGE(added, "toggle already registered: " << makeQuoted(name)); -} - -const Toggle &GlobalToggles_find(const char *name) -{ - Toggles::iterator i = g_toggles.find(name); - ASSERT_MESSAGE(i != g_toggles.end(), "failed to lookup toggle " << makeQuoted(name)); - return (*i).second; -} - -typedef std::map KeyEvents; - - -KeyEvents g_keyEvents; - -void GlobalKeyEvents_insert(const char *name, const Accelerator &accelerator, const Callback &keyDown, - const Callback &keyUp) -{ - bool added = g_keyEvents.insert( - KeyEvents::value_type(name, KeyEvent(GlobalShortcuts_insert(name, accelerator), keyDown, keyUp))).second; - ASSERT_MESSAGE(added, "command already registered: " << makeQuoted(name)); -} - -const KeyEvent &GlobalKeyEvents_find(const char *name) -{ - KeyEvents::iterator i = g_keyEvents.find(name); - ASSERT_MESSAGE(i != g_keyEvents.end(), "failed to lookup keyEvent " << makeQuoted(name)); - return (*i).second; -} - - -void disconnect_accelerator(const char *name) -{ - Shortcuts::iterator i = g_shortcuts.find(name); - if (i != g_shortcuts.end()) { - switch ((*i).second.second) { - case 1: - // command - command_disconnect_accelerator(name); - break; - case 2: - // toggle - toggle_remove_accelerator(name); - break; - } - } -} - -void connect_accelerator(const char *name) -{ - Shortcuts::iterator i = g_shortcuts.find(name); - if (i != g_shortcuts.end()) { - switch ((*i).second.second) { - case 1: - // command - command_connect_accelerator(name); - break; - case 2: - // toggle - toggle_add_accelerator(name); - break; - } - } -} - - -#include -#include - -#include "gtkutil/dialog.h" -#include "mainframe.h" - -#include "stream/textfilestream.h" -#include "stream/stringstream.h" - - -struct command_list_dialog_t : public ModalDialog { - command_list_dialog_t() - : m_close_button(*this, eIDCANCEL), m_list(ui::null), m_command_iter(), m_model(ui::null), - m_waiting_for_key(false) - { - } - - ModalDialogButton m_close_button; - - ui::TreeView m_list; - GtkTreeIter m_command_iter; - ui::TreeModel m_model; - bool m_waiting_for_key; -}; - -void accelerator_clear_button_clicked(ui::Button btn, gpointer dialogptr) -{ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - if (dialog.m_waiting_for_key) { - // just unhighlight, user wanted to cancel - dialog.m_waiting_for_key = false; - gtk_list_store_set(ui::ListStore::from(dialog.m_model), &dialog.m_command_iter, 2, false, -1); - gtk_widget_set_sensitive(dialog.m_list, true); - dialog.m_model = ui::TreeModel(ui::null); - return; - } - - auto sel = gtk_tree_view_get_selection(dialog.m_list); - GtkTreeModel *model; - GtkTreeIter iter; - if (!gtk_tree_selection_get_selected(sel, &model, &iter)) { - return; - } - - GValue val; - memset(&val, 0, sizeof(val)); - gtk_tree_model_get_value(model, &iter, 0, &val); - const char *commandName = g_value_get_string(&val);; - - // clear the ACTUAL accelerator too! - disconnect_accelerator(commandName); - - Shortcuts::iterator thisShortcutIterator = g_shortcuts.find(commandName); - if (thisShortcutIterator == g_shortcuts.end()) { - return; - } - thisShortcutIterator->second.first = accelerator_null(); - - gtk_list_store_set(ui::ListStore::from(model), &iter, 1, "", -1); - - g_value_unset(&val); -} - -void accelerator_edit_button_clicked(ui::Button btn, gpointer dialogptr) -{ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - // 1. find selected row - auto sel = gtk_tree_view_get_selection(dialog.m_list); - GtkTreeModel *model; - GtkTreeIter iter; - if (!gtk_tree_selection_get_selected(sel, &model, &iter)) { - return; - } - dialog.m_command_iter = iter; - dialog.m_model = ui::TreeModel::from(model); - - // 2. disallow changing the row - //gtk_widget_set_sensitive(dialog.m_list, false); - - // 3. highlight the row - gtk_list_store_set(ui::ListStore::from(model), &iter, 2, true, -1); - - // 4. grab keyboard focus - dialog.m_waiting_for_key = true; -} - -bool accelerator_window_key_press(ui::Window widget, GdkEventKey *event, gpointer dialogptr) -{ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - if (!dialog.m_waiting_for_key) { - return false; - } - -#if 0 - if ( event->is_modifier ) { - return false; - } -#else - switch (event->keyval) { - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - case GDK_KEY_Caps_Lock: - case GDK_KEY_Shift_Lock: - case GDK_KEY_Meta_L: - case GDK_KEY_Meta_R: - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - case GDK_KEY_Super_L: - case GDK_KEY_Super_R: - case GDK_KEY_Hyper_L: - case GDK_KEY_Hyper_R: - return false; - } -#endif - - dialog.m_waiting_for_key = false; - - // 7. find the name of the accelerator - GValue val; - memset(&val, 0, sizeof(val)); - gtk_tree_model_get_value(dialog.m_model, &dialog.m_command_iter, 0, &val); - const char *commandName = g_value_get_string(&val);; - Shortcuts::iterator thisShortcutIterator = g_shortcuts.find(commandName); - if (thisShortcutIterator == g_shortcuts.end()) { - gtk_list_store_set(ui::ListStore::from(dialog.m_model), &dialog.m_command_iter, 2, false, -1); - gtk_widget_set_sensitive(dialog.m_list, true); - return true; - } - - // 8. build an Accelerator - Accelerator newAccel(event->keyval, (GdkModifierType) event->state); - - // 8. verify the key is still free, show a dialog to ask what to do if not - class VerifyAcceleratorNotTaken : public CommandVisitor { - const char *commandName; - const Accelerator &newAccel; - ui::Widget widget; - ui::TreeModel model; -public: - bool allow; - - VerifyAcceleratorNotTaken(const char *name, const Accelerator &accelerator, ui::Widget w, ui::TreeModel m) - : commandName(name), newAccel(accelerator), widget(w), model(m), allow(true) - { - } - - void visit(const char *name, Accelerator &accelerator) - { - if (!strcmp(name, commandName)) { - return; - } - if (!allow) { - return; - } - if (accelerator.key == 0) { - return; - } - if (accelerator == newAccel) { - StringOutputStream msg; - msg << "The command " << name << " is already assigned to the key " << accelerator << ".\n\n" - << "Do you want to unassign " << name << " first?"; - auto r = ui::alert(widget.window(), msg.c_str(), "Key already used", ui::alert_type::YESNOCANCEL); - if (r == ui::alert_response::YES) { - // clear the ACTUAL accelerator too! - disconnect_accelerator(name); - // delete the modifier - accelerator = accelerator_null(); - // empty the cell of the key binds dialog - GtkTreeIter i; - if (gtk_tree_model_get_iter_first(model, &i)) { - for (;;) { - GValue val; - memset(&val, 0, sizeof(val)); - gtk_tree_model_get_value(model, &i, 0, &val); - const char *thisName = g_value_get_string(&val);; - if (!strcmp(thisName, name)) { - gtk_list_store_set(ui::ListStore::from(model), &i, 1, "", -1); - } - g_value_unset(&val); - if (!gtk_tree_model_iter_next(model, &i)) { - break; - } - } - } - } else if (r == ui::alert_response::CANCEL) { - // aborted - allow = false; - } - } - } - } verify_visitor(commandName, newAccel, widget, dialog.m_model); - GlobalShortcuts_foreach(verify_visitor); - - gtk_list_store_set(ui::ListStore::from(dialog.m_model), &dialog.m_command_iter, 2, false, -1); - gtk_widget_set_sensitive(dialog.m_list, true); - - if (verify_visitor.allow) { - // clear the ACTUAL accelerator first - disconnect_accelerator(commandName); - - thisShortcutIterator->second.first = newAccel; - - // write into the cell - StringOutputStream modifiers; - modifiers << newAccel; - gtk_list_store_set(ui::ListStore::from(dialog.m_model), &dialog.m_command_iter, 1, modifiers.c_str(), -1); - - // set the ACTUAL accelerator too! - connect_accelerator(commandName); - } - - g_value_unset(&val); - - dialog.m_model = ui::TreeModel(ui::null); - - return true; -} - -/* - GtkTreeIter row; - GValue val; - if(!model) {g_error("Unable to get model from cell renderer");} - gtk_tree_model_get_iter_from_string(model, &row, path_string); - - gtk_tree_model_get_value(model, &row, 0, &val); - const char *name = g_value_get_string(&val); - Shortcuts::iterator i = g_shortcuts.find(name); - if(i != g_shortcuts.end()) - { - accelerator_parse(i->second.first, new_text); - StringOutputStream modifiers; - modifiers << i->second.first; - gtk_list_store_set(ui::ListStore::from(model), &row, 1, modifiers.c_str(), -1); - } - }; - */ - -void DoCommandListDlg() -{ - command_list_dialog_t dialog; - - ui::Window window = MainFrame_getWindow().create_modal_dialog_window("Mapped Commands", dialog, -1, 400); - window.on_key_press([](ui::Widget widget, GdkEventKey *event, gpointer dialogptr) { - return accelerator_window_key_press(ui::Window::from(widget), event, dialogptr); - }, &dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - - { - auto scr = create_scrolled_window(ui::Policy::NEVER, ui::Policy::AUTOMATIC); - hbox.pack_start(scr, TRUE, TRUE, 0); - - { - auto store = ui::ListStore::from( - gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - dialog.m_list = view; - - gtk_tree_view_set_enable_search(view, false); // annoying - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Command", renderer, {{"text", 0}, - {"weight-set", 2}, - {"weight", 3}}); - gtk_tree_view_append_column(view, column); - } - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Key", renderer, {{"text", 1}, - {"weight-set", 2}, - {"weight", 3}}); - gtk_tree_view_append_column(view, column); - } - - view.show(); - scr.add(view); - - { - // Initialize dialog - StringOutputStream path(256); - path << SettingsPath_get() << "commandlist.txt"; - globalOutputStream() << "Writing the command list to " << path.c_str() << "\n"; - class BuildCommandList : public CommandVisitor { - TextFileOutputStream m_commandList; - ui::ListStore m_store; -public: - BuildCommandList(const char *filename, ui::ListStore store) : m_commandList(filename), - m_store(store) - { - } - - void visit(const char *name, Accelerator &accelerator) - { - StringOutputStream modifiers; - modifiers << accelerator; - - m_store.append(0, name, 1, modifiers.c_str(), 2, false, 3, 800); - - if (!m_commandList.failed()) { - int l = strlen(name); - m_commandList << name; - while (l++ < 25) { - m_commandList << ' '; - } - m_commandList << modifiers.c_str() << '\n'; - } - } - } visitor(path.c_str(), store); - - GlobalShortcuts_foreach(visitor); - } - - store.unref(); - } - } - - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto editbutton = create_dialog_button("Edit", (GCallback) accelerator_edit_button_clicked, &dialog); - vbox.pack_start(editbutton, FALSE, FALSE, 0); - - auto clearbutton = create_dialog_button("Clear", (GCallback) accelerator_clear_button_clicked, &dialog); - vbox.pack_start(clearbutton, FALSE, FALSE, 0); - - ui::Widget spacer = ui::Image(ui::New); - spacer.show(); - vbox.pack_start(spacer, TRUE, TRUE, 0); - - auto button = create_modal_dialog_button("Close", dialog.m_close_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_grab_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, (GtkAccelFlags) 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, (GtkAccelFlags) 0); - } - - modal_dialog_show(window, dialog); - window.destroy(); -} - -#include "profile/profile.h" - -const char *const COMMANDS_VERSION = "1.0-gtk-accelnames"; - -void SaveCommandMap(const char *path) -{ - StringOutputStream strINI(256); - strINI << path << "shortcuts.ini"; - - TextFileOutputStream file(strINI.c_str()); - if (!file.failed()) { - file << "[Version]\n"; - file << "number=" << COMMANDS_VERSION << "\n"; - file << "\n"; - file << "[Commands]\n"; - class WriteCommandMap : public CommandVisitor { - TextFileOutputStream &m_file; -public: - WriteCommandMap(TextFileOutputStream &file) : m_file(file) - { - } - - void visit(const char *name, Accelerator &accelerator) - { - m_file << name << "="; - - const char *key = gtk_accelerator_name(accelerator.key, accelerator.modifiers); - m_file << key; - m_file << "\n"; - } - } visitor(file); - GlobalShortcuts_foreach(visitor); - } -} - -const char *stringrange_find(const char *first, const char *last, char c) -{ - const char *p = strchr(first, '+'); - if (p == 0) { - return last; - } - return p; -} - -class ReadCommandMap : public CommandVisitor { -const char *m_filename; -std::size_t m_count; -public: -ReadCommandMap(const char *filename) : m_filename(filename), m_count(0) -{ -} - -void visit(const char *name, Accelerator &accelerator) -{ - char value[1024]; - if (read_var(m_filename, "Commands", name, value)) { - if (string_empty(value)) { - accelerator.key = 0; - accelerator.modifiers = (GdkModifierType) 0; - return; - } - - gtk_accelerator_parse(value, &accelerator.key, &accelerator.modifiers); - accelerator = accelerator; // fix modifiers - - if (accelerator.key != 0) { - ++m_count; - } else { - globalOutputStream() << "WARNING: failed to parse user command " << makeQuoted(name) << ": unknown key " - << makeQuoted(value) << "\n"; - } - } -} - -std::size_t count() const -{ - return m_count; -} -}; - -void LoadCommandMap_ReadFile(const char *path) -{ - globalOutputStream() << "loading custom shortcuts list from " << makeQuoted(path) << "\n"; - - Version version = version_parse(COMMANDS_VERSION); - Version dataVersion = {0, 0}; - - { - char value[1024]; - if (read_var(path, "Version", "number", value)) { - dataVersion = version_parse(value); - } - } - - if (version_compatible(version, dataVersion)) { - globalOutputStream() << "commands import: data version " << dataVersion - << " is compatible with code version " << version << "\n"; - ReadCommandMap visitor(path); - GlobalShortcuts_foreach(visitor); - globalOutputStream() << "parsed " << Unsigned(visitor.count()) << " custom shortcuts\n"; - } else { - globalOutputStream() << "commands import: data version " << dataVersion - << " is not compatible with code version " << version << "\n"; - } -} - -void LoadCommandMap(const char *path, const char *defaultpath) -{ - StringOutputStream strINI(256); - StringOutputStream strDefault(256); - strDefault << defaultpath << "defaultkeys.ini"; - strINI << path << "shortcuts.ini"; - - FILE *f = fopen(strINI.c_str(), "r"); - if (f != 0) { - fclose(f); - LoadCommandMap_ReadFile(strINI.c_str()); - } else { - /* load the default */ - FILE *f = fopen(strDefault.c_str(), "r"); - if (f != 0) { - fclose(f); - LoadCommandMap_ReadFile(strDefault.c_str()); - } else { - globalOutputStream() << "failed to load custom shortcuts from " << makeQuoted(strDefault.c_str()) << "\n"; - } - } -} diff --git a/src/commands.h b/src/commands.h deleted file mode 100644 index 6050851..0000000 --- a/src/commands.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_COMMANDS_H ) -#define INCLUDED_COMMANDS_H - -#include "gtkutil/accelerator.h" - - -const Accelerator &GlobalShortcuts_insert(const char *name, const Accelerator &accelerator); - -void GlobalShortcuts_register(const char *name, int type); // 1 = command, 2 = toggle -void GlobalShortcuts_reportUnregistered(); - -class CommandVisitor { -public: -virtual void visit(const char *name, Accelerator &accelerator) = 0; -}; - -void GlobalCommands_insert(const char *name, const Callback &callback, - const Accelerator &accelerator = accelerator_null()); - -const Command &GlobalCommands_find(const char *name); - -void GlobalToggles_insert(const char *name, const Callback &callback, - const Callback &)> &exportCallback, - const Accelerator &accelerator = accelerator_null()); - -const Toggle &GlobalToggles_find(const char *name); - -void GlobalKeyEvents_insert(const char *name, const Accelerator &accelerator, const Callback &keyDown, - const Callback &keyUp); - -const KeyEvent &GlobalKeyEvents_find(const char *name); - - -void DoCommandListDlg(); - -void LoadCommandMap(const char *path, const char* defaultpath); - -void SaveCommandMap(const char *path); - - -#endif diff --git a/src/console.cpp b/src/console.cpp deleted file mode 100644 index bb9050e..0000000 --- a/src/console.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "console.h" - -#include -#include - -#include "stream/stringstream.h" -#include "convert.h" - -#include "mainframe.h" - -std::size_t Sys_Print(int level, const char *buf, std::size_t length) -{ - StringOutputStream name(256); - name << StringRange(buf, buf + length); - printf(name.c_str()); - return length; -} - - -class SysPrintOutputStream : public TextOutputStream { -public: -std::size_t write(const char *buffer, std::size_t length) -{ - return Sys_Print(SYS_STD, buffer, length); -} -}; - -class SysPrintErrorStream : public TextOutputStream { -public: -std::size_t write(const char *buffer, std::size_t length) -{ - return Sys_Print(SYS_ERR, buffer, length); -} -}; - -SysPrintOutputStream g_outputStream; - -TextOutputStream &getSysPrintOutputStream() -{ - return g_outputStream; -} - -SysPrintErrorStream g_errorStream; - -TextOutputStream &getSysPrintErrorStream() -{ - return g_errorStream; -} diff --git a/src/console.h b/src/console.h deleted file mode 100644 index d9fb2ed..0000000 --- a/src/console.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CONSOLE_H ) -#define INCLUDED_CONSOLE_H - -#include -#include - -#define SYS_VRB 0 ///< verbose support (on/off) -#define SYS_STD 1 ///< standard print level - this is the default -#define SYS_WRN 2 ///< warnings -#define SYS_ERR 3 ///< error -#define SYS_NOCON 4 ///< no console, only print to the file (useful whenever Sys_Printf and output IS the problem) - -std::size_t Sys_Print(int level, const char *buf, std::size_t length); - -class TextOutputStream; - -TextOutputStream &getSysPrintOutputStream(); - -TextOutputStream &getSysPrintErrorStream(); - -#endif diff --git a/tools/vmap/convert_ase.c b/src/convert_ase.c similarity index 100% rename from tools/vmap/convert_ase.c rename to src/convert_ase.c diff --git a/tools/vmap/convert_bsp.c b/src/convert_bsp.c similarity index 100% rename from tools/vmap/convert_bsp.c rename to src/convert_bsp.c diff --git a/tools/vmap/convert_map.c b/src/convert_map.c similarity index 100% rename from tools/vmap/convert_map.c rename to src/convert_map.c diff --git a/tools/vmap/convert_obj.c b/src/convert_obj.c similarity index 100% rename from tools/vmap/convert_obj.c rename to src/convert_obj.c diff --git a/src/csg.cpp b/src/csg.cpp deleted file mode 100644 index b68c17e..0000000 --- a/src/csg.cpp +++ /dev/null @@ -1,653 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "csg.h" - -#include "debugging/debugging.h" - -#include - -#include "map.h" -#include "brushmanip.h" -#include "brushnode.h" -#include "grid.h" - -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); - if (newFace != 0) { - newFace->flipWinding(); - newFace->getPlane().offset(offset); - newFace->planeChanged(); - } - } -} - -void Face_makeRoom(Face &face, const Brush &brush, brush_vector_t &out, float offset) -{ - if (face.contributes()) { - face.getPlane().offset(offset); - out.push_back(new Brush(brush)); - face.getPlane().offset(-offset); - Face *newFace = out.back()->addFace(face); - if (newFace != 0) { - newFace->flipWinding(); - newFace->planeChanged(); - } - } -} - -void Brush_makeHollow(const Brush &brush, brush_vector_t &out, float offset) -{ - Brush_forEachFace(brush, [&](Face &face) { - Face_makeBrush(face, brush, out, offset); - }); -} - -void Brush_makeRoom(const Brush &brush, brush_vector_t &out, float offset) -{ - Brush_forEachFace(brush, [&](Face &face) { - Face_makeRoom(face, brush, out, offset); - }); -} - -class BrushHollowSelectedWalker : public scene::Graph::Walker { -float m_offset; -bool m_makeRoom; -public: -BrushHollowSelectedWalker(float offset, bool makeRoom) - : m_offset(offset), m_makeRoom(makeRoom) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && Instance_getSelectable(instance)->isSelected() - && path.size() > 1) { - brush_vector_t out; - - if (m_makeRoom) { - Brush_makeRoom(*brush, out, m_offset); - } - else { - Brush_makeHollow(*brush, out, m_offset); - } - - for (brush_vector_t::const_iterator i = out.begin(); i != out.end(); ++i) { - (*i)->removeEmptyFaces(); - NodeSmartReference node((new BrushNode())->node()); - Node_getBrush(node)->copy(*(*i)); - delete (*i); - Node_getTraversable(path.parent())->insert(node); - } - } - } - return true; -} -}; - -typedef std::list brushlist_t; - -class BrushGatherSelected : public scene::Graph::Walker { -brush_vector_t &m_brushlist; -public: -BrushGatherSelected(brush_vector_t &brushlist) - : m_brushlist(brushlist) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && Instance_getSelectable(instance)->isSelected()) { - m_brushlist.push_back(brush); - } - } - return true; -} -}; - -class BrushDeleteSelected : public scene::Graph::Walker { -public: -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && Instance_getSelectable(instance)->isSelected() - && path.size() > 1) { - Path_deleteTop(path); - } - } -} -}; - -void Scene_BrushMakeHollow_Selected(scene::Graph &graph, bool makeRoom) -{ - GlobalSceneGraph().traverse(BrushHollowSelectedWalker(GetGridSize(), makeRoom)); - GlobalSceneGraph().traverse(BrushDeleteSelected()); -} - -/* - ============= - CSG_MakeHollow - ============= - */ - -void CSG_MakeHollow(void) -{ - UndoableCommand undo("brushHollow"); - - Scene_BrushMakeHollow_Selected(GlobalSceneGraph(), false); - - SceneChangeNotify(); -} - -void CSG_MakeRoom(void) -{ - UndoableCommand undo("brushRoom"); - - Scene_BrushMakeHollow_Selected(GlobalSceneGraph(), true); - - SceneChangeNotify(); -} - -template -class RemoveReference { -public: -typedef Type type; -}; - -template -class RemoveReference { -public: -typedef Type type; -}; - -template -class Dereference { -const Functor &functor; -public: -Dereference(const Functor &functor) : functor(functor) -{ -} - -get_result_type operator()(typename RemoveReference >::type *firstArgument) const -{ - return functor(*firstArgument); -} -}; - -template -inline Dereference makeDereference(const Functor &functor) -{ - return Dereference(functor); -} - -typedef Face *FacePointer; -const FacePointer c_nullFacePointer = 0; - -template -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 -class BindArguments1 { -typedef get_argument FirstBound; -FirstBound firstBound; -public: -BindArguments1(FirstBound firstBound) - : firstBound(firstBound) -{ -} - -get_result_type operator()(get_argument firstArgument) const -{ - return Caller::call(firstArgument, firstBound); -} -}; - -template -class BindArguments2 { -typedef get_argument FirstBound; -typedef get_argument SecondBound; -FirstBound firstBound; -SecondBound secondBound; -public: -BindArguments2(FirstBound firstBound, SecondBound secondBound) - : firstBound(firstBound), secondBound(secondBound) -{ -} - -get_result_type operator()(get_argument firstArgument) const -{ - return Caller::call(firstArgument, firstBound, secondBound); -} -}; - -template -BindArguments2 bindArguments(const Caller &caller, FirstBound firstBound, SecondBound secondBound) -{ - return BindArguments2(firstBound, secondBound); -} - -inline bool Face_testPlane(const Face &face, const Plane3 &plane, bool flipped) -{ - return face.contributes() && !Winding_TestPlane(face.getWinding(), plane, flipped); -} - -typedef Function FaceTestPlane; - - -/// \brief Returns true if -/// \li !flipped && brush is BACK or ON -/// \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 false; - } - } - return true; -#else - return Brush_findIf( brush, bindArguments( FaceTestPlane(), makeReference( plane ), flipped ) ) == 0; -#endif -} - -brushsplit_t Brush_classifyPlane(const Brush &brush, const Plane3 &plane) -{ - brush.evaluateBRep(); - brushsplit_t split; - for (Brush::const_iterator i(brush.begin()); i != brush.end(); ++i) { - if ((*i)->contributes()) { - split += Winding_ClassifyPlane((*i)->getWinding(), plane); - } - } - return split; -} - -bool Brush_subtract(const Brush &brush, const Brush &other, brush_vector_t &ret_fragments) -{ - if (aabb_intersects_aabb(brush.localAABB(), other.localAABB())) { - brush_vector_t fragments; - fragments.reserve(other.size()); - Brush back(brush); - - for (Brush::const_iterator i(other.begin()); i != other.end(); ++i) { - if ((*i)->contributes()) { - brushsplit_t split = Brush_classifyPlane(back, (*i)->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) { - newFace->flipWinding(); - } - back.addFace(*(*i)); - } else if (split.counts[ePlaneBack] == 0) { - for (brush_vector_t::iterator i = fragments.begin(); i != fragments.end(); ++i) { - delete (*i); - } - return false; - } - } - } - ret_fragments.insert(ret_fragments.end(), fragments.begin(), fragments.end()); - return true; - } - return false; -} - -class SubtractBrushesFromUnselected : public scene::Graph::Walker { -const brush_vector_t &m_brushlist; -std::size_t &m_before; -std::size_t &m_after; -public: -SubtractBrushesFromUnselected(const brush_vector_t &brushlist, std::size_t &before, std::size_t &after) - : m_brushlist(brushlist), m_before(before), m_after(after) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && !Instance_getSelectable(instance)->isSelected()) { - brush_vector_t buffer[2]; - bool swap = false; - Brush *original = new Brush(*brush); - buffer[static_cast( swap )].push_back(original); - - { - for (brush_vector_t::const_iterator i(m_brushlist.begin()); i != m_brushlist.end(); ++i) { - for (brush_vector_t::iterator j(buffer[static_cast( swap )].begin()); - j != buffer[static_cast( swap )].end(); ++j) { - if (Brush_subtract(*(*j), *(*i), buffer[static_cast( !swap )])) { - delete (*j); - } else { - buffer[static_cast( !swap )].push_back((*j)); - } - } - buffer[static_cast( swap )].clear(); - swap = !swap; - } - } - - brush_vector_t &out = buffer[static_cast( swap )]; - - if (out.size() == 1 && out.back() == original) { - delete original; - } else { - ++m_before; - for (brush_vector_t::const_iterator i = out.begin(); i != out.end(); ++i) { - ++m_after; - (*i)->removeEmptyFaces(); - if (!(*i)->empty()) { - NodeSmartReference node((new BrushNode())->node()); - Node_getBrush(node)->copy(*(*i)); - delete (*i); - Node_getTraversable(path.parent())->insert(node); - } else { - delete (*i); - } - } - Path_deleteTop(path); - } - } - } -} -}; - -void CSG_Subtract() -{ - brush_vector_t selected_brushes; - GlobalSceneGraph().traverse(BrushGatherSelected(selected_brushes)); - - if (selected_brushes.empty()) { - globalOutputStream() << "CSG Subtract: No brushes selected.\n"; - } else { - globalOutputStream() << "CSG Subtract: Subtracting " << Unsigned(selected_brushes.size()) << " brushes.\n"; - - UndoableCommand undo("brushSubtract"); - - // subtract selected from unselected - std::size_t before = 0; - std::size_t after = 0; - GlobalSceneGraph().traverse(SubtractBrushesFromUnselected(selected_brushes, before, after)); - globalOutputStream() << "CSG Subtract: Result: " - << Unsigned(after) << " fragment" << (after == 1 ? "" : "s") - << " from " << Unsigned(before) << " brush" << (before == 1 ? "" : "es") << ".\n"; - - SceneChangeNotify(); - } -} - -class BrushSplitByPlaneSelected : public scene::Graph::Walker { -const Vector3 &m_p0; -const Vector3 &m_p1; -const Vector3 &m_p2; -const char *m_shader; -const TextureProjection &m_projection; -EBrushSplit m_split; -public: -BrushSplitByPlaneSelected(const Vector3 &p0, const Vector3 &p1, const Vector3 &p2, const char *shader, - const TextureProjection &projection, EBrushSplit split) - : m_p0(p0), m_p1(p1), m_p2(p2), m_shader(shader), m_projection(projection), m_split(split) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Brush *brush = Node_getBrush(path.top()); - if (brush != 0 - && Instance_getSelectable(instance)->isSelected()) { - Plane3 plane(plane3_for_points(m_p0, m_p1, m_p2)); - if (plane3_valid(plane)) { - 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 - if (m_split == eFrontAndBack) { - 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); - if (newFace != 0 && m_split != eFront) { - newFace->flipWinding(); - } - fragment->removeEmptyFaces(); - ASSERT_MESSAGE(!fragment->empty(), "brush left with no faces after split"); - - Node_getTraversable(path.parent())->insert(node); - { - scene::Path fragmentPath = path; - fragmentPath.top() = makeReference(node.get()); - selectPath(fragmentPath, true); - } - } - - Face *newFace = brush->addPlane(m_p0, m_p1, m_p2, m_shader, m_projection); - if (newFace != 0 && m_split == eFront) { - newFace->flipWinding(); - } - brush->removeEmptyFaces(); - ASSERT_MESSAGE(!brush->empty(), "brush left with no faces after split"); - } else - // the plane does not intersect this brush - if (m_split != eFrontAndBack && split.counts[ePlaneBack] != 0) { - // the brush is "behind" the plane - Path_deleteTop(path); - } - } - } - } -} -}; - -void Scene_BrushSplitByPlane(scene::Graph &graph, const Vector3 &p0, const Vector3 &p1, const Vector3 &p2, - const char *shader, EBrushSplit split) -{ - TextureProjection projection; - TexDef_Construct_Default(projection); - graph.traverse(BrushSplitByPlaneSelected(p0, p1, p2, shader, projection, split)); - SceneChangeNotify(); -} - - -class BrushInstanceSetClipPlane : public scene::Graph::Walker { -Plane3 m_plane; -public: -BrushInstanceSetClipPlane(const Plane3 &plane) - : m_plane(plane) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0 - && path.top().get().visible() - && brush->isSelected()) { - BrushInstance &brushInstance = *brush; - brushInstance.setClipPlane(m_plane); - } - return true; -} -}; - -void Scene_BrushSetClipPlane(scene::Graph &graph, const Plane3 &plane) -{ - graph.traverse(BrushInstanceSetClipPlane(plane)); -} - -/* - ============= - CSG_Merge - ============= - */ -bool Brush_merge(Brush &brush, const brush_vector_t &in, bool onlyshape) -{ - // gather potential outer faces - - { - typedef std::vector Faces; - Faces faces; - for (brush_vector_t::const_iterator i(in.begin()); i != in.end(); ++i) { - (*i)->evaluateBRep(); - for (Brush::const_iterator j((*i)->begin()); j != (*i)->end(); ++j) { - if (!(*j)->contributes()) { - continue; - } - - const Face &face1 = *(*j); - - bool skip = false; - // test faces of all input brushes - //!\todo SPEEDUP: Flag already-skip faces and only test brushes from i+1 upwards. - for (brush_vector_t::const_iterator k(in.begin()); !skip && k != in.end(); ++k) { - if (k != i) { // don't test a brush against itself - for (Brush::const_iterator l((*k)->begin()); !skip && l != (*k)->end(); ++l) { - const Face &face2 = *(*l); - - // face opposes another face - if (plane3_opposing(face1.plane3(), face2.plane3())) { - // skip opposing planes - skip = true; - break; - } - } - } - } - - // check faces already stored - for (Faces::const_iterator m = faces.begin(); !skip && m != faces.end(); ++m) { - const Face &face2 = *(*m); - - // face equals another face - if (plane3_equal(face1.plane3(), face2.plane3())) { - //if the texture/shader references should be the same but are not - if (!onlyshape && !shader_equal(face1.getShader().getShader(), face2.getShader().getShader())) { - return false; - } - // skip duplicate planes - skip = true; - break; - } - - // face1 plane intersects face2 winding or vice versa - if (Winding_PlanesConcave(face1.getWinding(), face2.getWinding(), face1.plane3(), face2.plane3())) { - // result would not be convex - return false; - } - } - - if (!skip) { - faces.push_back(&face1); - } - } - } - for (Faces::const_iterator i = faces.begin(); i != faces.end(); ++i) { - if (!brush.addFace(*(*i))) { - // result would have too many sides - return false; - } - } - } - - brush.removeEmptyFaces(); - - return true; -} - -void CSG_Merge(void) -{ - brush_vector_t selected_brushes; - - // remove selected - GlobalSceneGraph().traverse(BrushGatherSelected(selected_brushes)); - - if (selected_brushes.empty()) { - globalOutputStream() << "CSG Merge: No brushes selected.\n"; - return; - } - - if (selected_brushes.size() < 2) { - globalOutputStream() << "CSG Merge: At least two brushes have to be selected.\n"; - return; - } - - globalOutputStream() << "CSG Merge: Merging " << Unsigned(selected_brushes.size()) << " brushes.\n"; - - UndoableCommand undo("brushMerge"); - - scene::Path merged_path = GlobalSelectionSystem().ultimateSelected().path(); - - NodeSmartReference node((new BrushNode())->node()); - Brush *brush = Node_getBrush(node); - // if the new brush would not be convex - if (!Brush_merge(*brush, selected_brushes, true)) { - globalOutputStream() << "CSG Merge: Failed - result would not be convex.\n"; - } else { - ASSERT_MESSAGE(!brush->empty(), "brush left with no faces after merge"); - - // free the original brushes - GlobalSceneGraph().traverse(BrushDeleteSelected()); - - merged_path.pop(); - Node_getTraversable(merged_path.top())->insert(node); - merged_path.push(makeReference(node.get())); - - selectPath(merged_path, true); - - globalOutputStream() << "CSG Merge: Succeeded.\n"; - SceneChangeNotify(); - } -} diff --git a/src/csg.h b/src/csg.h deleted file mode 100644 index 051df21..0000000 --- a/src/csg.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_CSG_H ) -#define INCLUDED_CSG_H - -void CSG_MakeHollow(void); - -void CSG_MakeRoom(void); - -void CSG_Subtract(void); - -void CSG_Merge(void); - -namespace scene { -class Graph; -} -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -class Plane3; - -void Scene_BrushSetClipPlane(scene::Graph &graph, const Plane3 &plane); - -enum EBrushSplit { - eFront, - eBack, - eFrontAndBack, -}; - -void Scene_BrushSplitByPlane(scene::Graph &graph, const Vector3 &p0, const Vector3 &p1, const Vector3 &p2, - const char *shader, EBrushSplit split); - -#endif diff --git a/tools/vmap/decals.c b/src/decals.c similarity index 100% rename from tools/vmap/decals.c rename to src/decals.c diff --git a/src/dialog.cpp b/src/dialog.cpp deleted file mode 100644 index e45cbb8..0000000 --- a/src/dialog.cpp +++ /dev/null @@ -1,717 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Base dialog class, provides a way to run modal dialogs and -// set/get the widget values in member variables. -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "dialog.h" - -#include - -#include "debugging/debugging.h" - - -#include "mainframe.h" - -#include - -#include "stream/stringstream.h" -#include "convert.h" -#include "gtkutil/dialog.h" -#include "gtkutil/button.h" -#include "gtkutil/entry.h" -#include "gtkutil/image.h" - -#include "gtkmisc.h" - - -ui::Entry DialogEntry_new() -{ - auto entry = ui::Entry(ui::New); - entry.show(); - entry.dimensions(64, -1); - return entry; -} - -class DialogEntryRow { -public: -DialogEntryRow(ui::Widget row, ui::Entry entry) : m_row(row), m_entry(entry) -{ -} - -ui::Widget m_row; -ui::Entry m_entry; -}; - -DialogEntryRow DialogEntryRow_new(const char *name) -{ - auto alignment = ui::Alignment(0.0, 0.5, 0.0, 0.0); - alignment.show(); - - auto entry = DialogEntry_new(); - alignment.add(entry); - - return DialogEntryRow(ui::Widget(DialogRow_new(name, alignment)), entry); -} - - -ui::SpinButton DialogSpinner_new(double value, double lower, double upper, int fraction) -{ - double step = 1.0 / double(fraction); - unsigned int digits = 0; - for (; fraction > 1; fraction /= 10) { - ++digits; - } - auto spin = ui::SpinButton(ui::Adjustment(value, lower, upper, step, 10, 0), step, digits); - spin.show(); - spin.dimensions(64, -1); - return spin; -} - -class DialogSpinnerRow { -public: -DialogSpinnerRow(ui::Widget row, ui::SpinButton spin) : m_row(row), m_spin(spin) -{ -} - -ui::Widget m_row; -ui::SpinButton m_spin; -}; - -DialogSpinnerRow DialogSpinnerRow_new(const char *name, double value, double lower, double upper, int fraction) -{ - auto alignment = ui::Alignment(0.0, 0.5, 0.0, 0.0); - alignment.show(); - - auto spin = DialogSpinner_new(value, lower, upper, fraction); - alignment.add(spin); - - return DialogSpinnerRow(ui::Widget(DialogRow_new(name, alignment)), spin); -} - - -struct BoolToggle { - static void Export(const ui::ToggleButton &self, const Callback &returnz) - { - returnz(self.active()); - } - - static void Import(ui::ToggleButton &self, bool value) - { - self.active(value); - } -}; - -using BoolToggleImportExport = PropertyAdaptor; - -struct IntEntry { - static void Export(const ui::Entry &self, const Callback &returnz) - { - returnz(atoi(gtk_entry_get_text(self))); - } - - static void Import(ui::Entry &self, int value) - { - entry_set_int(self, value); - } -}; - -using IntEntryImportExport = PropertyAdaptor; - -struct IntRadio { - static void Export(const ui::RadioButton &self, const Callback &returnz) - { - returnz(radio_button_get_active(self)); - } - - static void Import(ui::RadioButton &self, int value) - { - radio_button_set_active(self, value); - } -}; - -using IntRadioImportExport = PropertyAdaptor; - -struct IntCombo { - static void Export(const ui::ComboBox &self, const Callback &returnz) - { - returnz(gtk_combo_box_get_active(self)); - } - - static void Import(ui::ComboBox &self, int value) - { - gtk_combo_box_set_active(self, value); - } -}; - -using IntComboImportExport = PropertyAdaptor; - -struct IntAdjustment { - static void Export(const ui::Adjustment &self, const Callback &returnz) - { - returnz(int(gtk_adjustment_get_value(self))); - } - - static void Import(ui::Adjustment &self, int value) - { - gtk_adjustment_set_value(self, value); - } -}; - -using IntAdjustmentImportExport = PropertyAdaptor; - -struct IntSpinner { - static void Export(const ui::SpinButton &self, const Callback &returnz) - { - returnz(gtk_spin_button_get_value_as_int(self)); - } - - static void Import(ui::SpinButton &self, int value) - { - gtk_spin_button_set_value(self, value); - } -}; - -using IntSpinnerImportExport = PropertyAdaptor; - -struct TextEntry { - static void Export(const ui::Entry &self, const Callback &returnz) - { - returnz(gtk_entry_get_text(self)); - } - - static void Import(ui::Entry &self, const char *value) - { - self.text(value); - } -}; - -using TextEntryImportExport = PropertyAdaptor; - -struct SizeEntry { - static void Export(const ui::Entry &self, const Callback &returnz) - { - int value = atoi(gtk_entry_get_text(self)); - if (value < 0) { - value = 0; - } - returnz(value); - } - - static void Import(ui::Entry &self, std::size_t value) - { - entry_set_int(self, int(value)); - } -}; - -using SizeEntryImportExport = PropertyAdaptor; - -struct FloatEntry { - static void Export(const ui::Entry &self, const Callback &returnz) - { - returnz(float(atof(gtk_entry_get_text(self)))); - } - - static void Import(ui::Entry &self, float value) - { - entry_set_float(self, value); - } -}; - -using FloatEntryImportExport = PropertyAdaptor; - -struct FloatSpinner { - static void Export(const ui::SpinButton &self, const Callback &returnz) - { - returnz(float(gtk_spin_button_get_value(self))); - } - - static void Import(ui::SpinButton &self, float value) - { - gtk_spin_button_set_value(self, value); - } -}; - -using FloatSpinnerImportExport = PropertyAdaptor; - - -template -class CallbackDialogData : public DLG_DATA { -Property m_pWidget; -Property m_pData; - -public: -CallbackDialogData(const Property &pWidget, const Property &pData) - : m_pWidget(pWidget), m_pData(pData) -{ -} - -void release() -{ - delete this; -} - -void importData() const -{ - m_pData.get(m_pWidget.set); -} - -void exportData() const -{ - m_pWidget.get(m_pData.set); -} -}; - -template -struct AddDataCustom_Wrapper { - static void Export(const native &self, const Callback &returnz) { - native *p = &const_cast(self); - auto widget = Self::from(p); - Widget::Get::thunk_(widget, returnz); - } - - static void Import(native &self, T value) { - native *p = &self; - auto widget = Self::from(p); - Widget::Set::thunk_(widget, value); - } -}; - -template -void AddDataCustom(DialogDataList &self, typename Widget::Type widget, Property const &property) -{ - using Self = typename Widget::Type; - using T = typename Widget::Other; - using native = typename std::remove_pointer::type; - using Wrapper = AddDataCustom_Wrapper; - self.push_back(new CallbackDialogData( - make_property >(*static_cast(widget)), - property - )); -} - -template -void AddData(DialogDataList &self, typename Widget::Type widget, D &data) -{ - AddDataCustom(self, widget, make_property >(data)); -} - -// ============================================================================= -// Dialog class - -Dialog::Dialog() : m_window(ui::null), m_parent(ui::null) -{ -} - -Dialog::~Dialog() -{ - for (DialogDataList::iterator i = m_data.begin(); i != m_data.end(); ++i) { - (*i)->release(); - } - - ASSERT_MESSAGE(!m_window, "dialog window not destroyed"); -} - -void Dialog::ShowDlg() -{ - ASSERT_MESSAGE(m_window, "dialog was not constructed"); - importData(); - m_window.show(); -} - -void Dialog::HideDlg() -{ - ASSERT_MESSAGE(m_window, "dialog was not constructed"); - exportData(); - m_window.hide(); -} - -static gint delete_event_callback(ui::Widget widget, GdkEvent *event, gpointer data) -{ - reinterpret_cast

( data )->HideDlg(); - reinterpret_cast( data )->EndModal(eIDCANCEL); - return TRUE; -} - -void Dialog::Create() -{ - ASSERT_MESSAGE(!m_window, "dialog cannot be constructed"); - - m_window = BuildDialog(); - m_window.connect("delete_event", G_CALLBACK(delete_event_callback), this); -} - -void Dialog::Destroy() -{ - ASSERT_MESSAGE(m_window, "dialog cannot be destroyed"); - - m_window.destroy(); - m_window = ui::Window{ui::null}; -} - - -void Dialog::AddBoolToggleData(ui::ToggleButton widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntRadioData(ui::RadioButton widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddTextEntryData(ui::Entry widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntEntryData(ui::Entry widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddSizeEntryData(ui::Entry widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddFloatEntryData(ui::Entry widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddFloatSpinnerData(ui::SpinButton widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntSpinnerData(ui::SpinButton widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntAdjustmentData(ui::Adjustment widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - -void Dialog::AddIntComboData(ui::ComboBox widget, Property const &cb) -{ - AddDataCustom(m_data, widget, cb); -} - - -void Dialog::AddDialogData(ui::ToggleButton widget, bool &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::RadioButton widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Entry widget, CopiedString &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Entry widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Entry widget, std::size_t &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Entry widget, float &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::SpinButton widget, float &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::SpinButton widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::Adjustment widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::AddDialogData(ui::ComboBox widget, int &data) -{ - AddData(m_data, widget, data); -} - -void Dialog::exportData() -{ - for (DialogDataList::iterator i = m_data.begin(); i != m_data.end(); ++i) { - (*i)->exportData(); - } -} - -void Dialog::importData() -{ - for (DialogDataList::iterator i = m_data.begin(); i != m_data.end(); ++i) { - (*i)->importData(); - } -} - -void Dialog::EndModal(EMessageBoxReturn code) -{ - m_modal.loop = 0; - m_modal.ret = code; -} - -EMessageBoxReturn Dialog::DoModal() -{ - importData(); - - PreModal(); - - EMessageBoxReturn ret = modal_dialog_show(m_window, m_modal); - ASSERT_TRUE((bool) m_window); - if (ret == eIDOK) { - exportData(); - } - - m_window.hide(); - - PostModal(m_modal.ret); - - return m_modal.ret; -} - - -ui::CheckButton Dialog::addCheckBox(ui::VBox vbox, const char *name, const char *flag, Property const &cb) -{ - auto check = ui::CheckButton(flag); - check.show(); - AddBoolToggleData(check, cb); - - DialogVBox_packRow(vbox, ui::Widget(DialogRow_new(name, check))); - return check; -} - -ui::CheckButton Dialog::addCheckBox(ui::VBox vbox, const char *name, const char *flag, bool &data) -{ - return addCheckBox(vbox, name, flag, make_property(data)); -} - -void Dialog::addCombo(ui::VBox vbox, const char *name, StringArrayRange values, Property const &cb) -{ - auto alignment = ui::Alignment(0.0, 0.5, 0.0, 0.0); - alignment.show(); - { - auto combo = ui::ComboBoxText(ui::New); - - for (StringArrayRange::Iterator i = values.first; i != values.last; ++i) { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), *i); - } - - AddIntComboData(combo, cb); - - combo.show(); - alignment.add(combo); - } - - auto row = DialogRow_new(name, alignment); - DialogVBox_packRow(vbox, row); -} - -void Dialog::addCombo(ui::VBox vbox, const char *name, int &data, StringArrayRange values) -{ - addCombo(vbox, name, values, make_property(data)); -} - -void -Dialog::addSlider(ui::VBox vbox, const char *name, int &data, gboolean draw_value, const char *low, const char *high, - double value, double lower, double upper, double step_increment, double page_increment) -{ -#if 0 - if ( draw_value == FALSE ) { - auto hbox2 = ui::HBox( FALSE, 0 ); - hbox2.show(); - vbox.pack_start( hbox2, FALSE, FALSE, 0 ); - { - ui::Widget label = ui::Label( low ); - label.show(); - hbox2.pack_start( label, FALSE, FALSE, 0 ); - } - { - ui::Widget label = ui::Label( high ); - label.show(); - hbox2.pack_end(label, FALSE, FALSE, 0); - } - } -#endif - - // adjustment - auto adj = ui::Adjustment(value, lower, upper, step_increment, page_increment, 0); - AddIntAdjustmentData(adj, make_property(data)); - - // scale - auto alignment = ui::Alignment(0.0, 0.5, 1.0, 0.0); - alignment.show(); - - ui::Widget scale = ui::HScale(adj); - gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_LEFT); - scale.show(); - alignment.add(scale); - - gtk_scale_set_draw_value(GTK_SCALE(scale), draw_value); - gtk_scale_set_digits(GTK_SCALE(scale), 0); - - auto row = DialogRow_new(name, alignment); - DialogVBox_packRow(vbox, row); -} - -void Dialog::addRadio(ui::VBox vbox, const char *name, StringArrayRange names, Property const &cb) -{ - auto alignment = ui::Alignment(0.0, 0.5, 0.0, 0.0); - alignment.show();; - { - RadioHBox radioBox = RadioHBox_new(names); - alignment.add(radioBox.m_hbox); - AddIntRadioData(radioBox.m_radio, cb); - } - - auto row = DialogRow_new(name, alignment); - DialogVBox_packRow(vbox, row); -} - -void Dialog::addRadio(ui::VBox vbox, const char *name, int &data, StringArrayRange names) -{ - addRadio(vbox, name, names, make_property(data)); -} - -void Dialog::addRadioIcons(ui::VBox vbox, const char *name, StringArrayRange icons, Property const &cb) -{ - auto table = ui::Table(2, icons.last - icons.first, FALSE); - table.show(); - - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - GSList *group = 0; - ui::RadioButton radio{ui::null}; - for (StringArrayRange::Iterator icon = icons.first; icon != icons.last; ++icon) { - guint pos = static_cast( icon - icons.first ); - auto image = new_local_image(*icon); - image.show(); - table.attach(image, {pos, pos + 1, 0, 1}, {0, 0}); - - radio = ui::RadioButton::from(gtk_radio_button_new(group)); - radio.show(); - table.attach(radio, {pos, pos + 1, 1, 2}, {0, 0}); - - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio)); - } - - AddIntRadioData(radio, cb); - - DialogVBox_packRow(vbox, DialogRow_new(name, table)); -} - -void Dialog::addRadioIcons(ui::VBox vbox, const char *name, int &data, StringArrayRange icons) -{ - addRadioIcons(vbox, name, icons, make_property(data)); -} - -ui::Widget Dialog::addIntEntry(ui::VBox vbox, const char *name, Property const &cb) -{ - DialogEntryRow row(DialogEntryRow_new(name)); - AddIntEntryData(row.m_entry, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_row; -} - -ui::Widget Dialog::addSizeEntry(ui::VBox vbox, const char *name, Property const &cb) -{ - DialogEntryRow row(DialogEntryRow_new(name)); - AddSizeEntryData(row.m_entry, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_row; -} - -ui::Widget Dialog::addFloatEntry(ui::VBox vbox, const char *name, Property const &cb) -{ - DialogEntryRow row(DialogEntryRow_new(name)); - AddFloatEntryData(row.m_entry, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_row; -} - -ui::Widget -Dialog::addPathEntry(ui::VBox vbox, const char *name, bool browse_directory, Property const &cb) -{ - PathEntry pathEntry = PathEntry_new(); - pathEntry.m_button.connect("clicked", G_CALLBACK( - browse_directory ? button_clicked_entry_browse_directory : button_clicked_entry_browse_file), - pathEntry.m_entry); - - AddTextEntryData(pathEntry.m_entry, cb); - - auto row = DialogRow_new(name, ui::Widget(pathEntry.m_frame)); - DialogVBox_packRow(vbox, row); - - return row; -} - -ui::Widget Dialog::addPathEntry(ui::VBox vbox, const char *name, CopiedString &data, bool browse_directory) -{ - return addPathEntry(vbox, name, browse_directory, make_property(data)); -} - -ui::SpinButton -Dialog::addSpinner(ui::VBox vbox, const char *name, double value, double lower, double upper, Property const &cb) -{ - DialogSpinnerRow row(DialogSpinnerRow_new(name, value, lower, upper, 1)); - AddIntSpinnerData(row.m_spin, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_spin; -} - -ui::SpinButton Dialog::addSpinner(ui::VBox vbox, const char *name, int &data, double value, double lower, double upper) -{ - return addSpinner(vbox, name, value, lower, upper, make_property(data)); -} - -ui::SpinButton -Dialog::addSpinner(ui::VBox vbox, const char *name, double value, double lower, double upper, Property const &cb) -{ - DialogSpinnerRow row(DialogSpinnerRow_new(name, value, lower, upper, 10)); - AddFloatSpinnerData(row.m_spin, cb); - DialogVBox_packRow(vbox, row.m_row); - return row.m_spin; -} diff --git a/src/dialog.h b/src/dialog.h deleted file mode 100644 index 102bb51..0000000 --- a/src/dialog.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_DIALOG_H ) -#define INCLUDED_DIALOG_H - -#include -#include -#include "property.h" - -#include "generic/callback.h" -#include "gtkutil/dialog.h" -#include "generic/callback.h" -#include "string/string.h" - -struct DLG_DATA { - virtual ~DLG_DATA() = default; - - virtual void release() = 0; - - virtual void importData() const = 0; - - virtual void exportData() const = 0; -}; - - -template -class CallbackDialogData; - -typedef std::list DialogDataList; - -class Dialog { -ui::Window m_window; -DialogDataList m_data; -public: -ModalDialog m_modal; -ui::Window m_parent; - -Dialog(); - -virtual ~Dialog(); - -/*! - start modal dialog box - you need to use AddModalButton to select eIDOK eIDCANCEL buttons - */ -EMessageBoxReturn DoModal(); - -void EndModal(EMessageBoxReturn code); - -virtual ui::Window BuildDialog() = 0; - -virtual void exportData(); - -virtual void importData(); - -virtual void PreModal() -{ -}; - -virtual void PostModal(EMessageBoxReturn code) -{ -}; - -virtual void ShowDlg(); - -virtual void HideDlg(); - -void Create(); - -void Destroy(); - -ui::Window GetWidget() -{ - return m_window; -} - -const ui::Window GetWidget() const -{ - return m_window; -} - -ui::CheckButton addCheckBox(ui::VBox vbox, const char *name, const char *flag, Property const &cb); - -ui::CheckButton addCheckBox(ui::VBox vbox, const char *name, const char *flag, bool &data); - -void addCombo(ui::VBox vbox, const char *name, StringArrayRange values, Property const &cb); - -void addCombo(ui::VBox vbox, const char *name, int &data, StringArrayRange values); - -void addSlider(ui::VBox vbox, const char *name, int &data, gboolean draw_value, const char *low, const char *high, - double value, double lower, double upper, double step_increment, double page_increment); - -void addRadio(ui::VBox vbox, const char *name, StringArrayRange names, Property const &cb); - -void addRadio(ui::VBox vbox, const char *name, int &data, StringArrayRange names); - -void addRadioIcons(ui::VBox vbox, const char *name, StringArrayRange icons, Property const &cb); - -void addRadioIcons(ui::VBox vbox, const char *name, int &data, StringArrayRange icons); - -ui::Widget addIntEntry(ui::VBox vbox, const char *name, Property const &cb); - -ui::Widget addEntry(ui::VBox vbox, const char *name, int &data) -{ - return addIntEntry(vbox, name, make_property(data)); -} - -ui::Widget addSizeEntry(ui::VBox vbox, const char *name, Property const &cb); - -ui::Widget addEntry(ui::VBox vbox, const char *name, std::size_t &data) -{ - return addSizeEntry(vbox, name, make_property(data)); -} - -ui::Widget addFloatEntry(ui::VBox vbox, const char *name, Property const &cb); - -ui::Widget addEntry(ui::VBox vbox, const char *name, float &data) -{ - return addFloatEntry(vbox, name, make_property(data)); -} - -ui::Widget addPathEntry(ui::VBox vbox, const char *name, bool browse_directory, Property const &cb); - -ui::Widget addPathEntry(ui::VBox vbox, const char *name, CopiedString &data, bool directory); - -ui::SpinButton addSpinner(ui::VBox vbox, const char *name, int &data, double value, double lower, double upper); - -ui::SpinButton -addSpinner(ui::VBox vbox, const char *name, double value, double lower, double upper, Property const &cb); - -ui::SpinButton -addSpinner(ui::VBox vbox, const char *name, double value, double lower, double upper, Property const &cb); - -protected: - -void AddBoolToggleData(ui::ToggleButton object, Property const &cb); - -void AddIntRadioData(ui::RadioButton object, Property const &cb); - -void AddTextEntryData(ui::Entry object, Property const &cb); - -void AddIntEntryData(ui::Entry object, Property const &cb); - -void AddSizeEntryData(ui::Entry object, Property const &cb); - -void AddFloatEntryData(ui::Entry object, Property const &cb); - -void AddFloatSpinnerData(ui::SpinButton object, Property const &cb); - -void AddIntSpinnerData(ui::SpinButton object, Property const &cb); - -void AddIntAdjustmentData(ui::Adjustment object, Property const &cb); - -void AddIntComboData(ui::ComboBox object, Property const &cb); - -void AddDialogData(ui::ToggleButton object, bool &data); - -void AddDialogData(ui::RadioButton object, int &data); - -void AddDialogData(ui::Entry object, CopiedString &data); - -void AddDialogData(ui::Entry object, int &data); - -void AddDialogData(ui::Entry object, std::size_t &data); - -void AddDialogData(ui::Entry object, float &data); - -void AddDialogData(ui::SpinButton object, float &data); - -void AddDialogData(ui::SpinButton object, int &data); - -void AddDialogData(ui::Adjustment object, int &data); - -void AddDialogData(ui::ComboBox object, int &data); -}; - -#endif diff --git a/src/eclass.cpp b/src/eclass.cpp deleted file mode 100644 index c344c18..0000000 --- a/src/eclass.cpp +++ /dev/null @@ -1,399 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "eclass.h" - -#include "debugging/debugging.h" - -#include - -#include "ifilesystem.h" - -#include "string/string.h" -#include "eclasslib.h" -#include "os/path.h" -#include "os/dir.h" -#include "stream/stringstream.h" -#include "moduleobservers.h" - -#include "cmdlib.h" - -#include "preferences.h" -#include "mainframe.h" - - -namespace { -typedef std::map EntityClasses; -EntityClasses g_entityClasses; -EntityClass *eclass_bad = 0; -char eclass_directory[1024]; -typedef std::map ListAttributeTypes; -ListAttributeTypes g_listTypes; -} - -EClassModules &EntityClassManager_getEClassModules(); - -/*! - implementation of the EClass manager API - */ - -void CleanEntityList(EntityClasses &entityClasses) -{ - for (EntityClasses::iterator i = entityClasses.begin(); i != entityClasses.end(); ++i) { - (*i).second->free((*i).second); - } - entityClasses.clear(); -} - -void Eclass_Clear() -{ - CleanEntityList(g_entityClasses); - g_listTypes.clear(); -} - -EntityClass *EClass_InsertSortedList(EntityClasses &entityClasses, EntityClass *entityClass) -{ - std::pair result = entityClasses.insert( - EntityClasses::value_type(entityClass->name(), entityClass)); - if (!result.second) { - entityClass->free(entityClass); - } - return (*result.first).second; -} - -EntityClass *Eclass_InsertAlphabetized(EntityClass *e) -{ - return EClass_InsertSortedList(g_entityClasses, e); -} - -void Eclass_forEach(EntityClassVisitor &visitor) -{ - for (EntityClasses::iterator i = g_entityClasses.begin(); i != g_entityClasses.end(); ++i) { - visitor.visit((*i).second); - } -} - -void Eclass_forEachPoint(EntityClassVisitor &visitor) -{ - for (EntityClasses::iterator i = g_entityClasses.begin(); i != g_entityClasses.end(); ++i) { - if ((*i).second->fixedsize == true) { - visitor.visit((*i).second); - } - } -} - - -class RadiantEclassCollector : public EntityClassCollector { -public: -void insert(EntityClass *eclass) -{ - Eclass_InsertAlphabetized(eclass); -} - -void insert(const char *name, const ListAttributeType &list) -{ - g_listTypes.insert(ListAttributeTypes::value_type(name, list)); -} -}; - -RadiantEclassCollector g_collector; - -const ListAttributeType *EntityClass_findListType(const char *name) -{ - ListAttributeTypes::iterator i = g_listTypes.find(name); - if (i != g_listTypes.end()) { - return &(*i).second; - } - return 0; -} - - -class EntityClassFilterMode { -public: -bool filter_mp_sp; -const char *mp_ignore_prefix; -const char *sp_ignore_prefix; - -EntityClassFilterMode() : - filter_mp_sp(!string_empty(g_pGameDescription->getKeyValue("eclass_filter_gamemode"))), - mp_ignore_prefix(g_pGameDescription->getKeyValue("eclass_sp_prefix")), - sp_ignore_prefix(g_pGameDescription->getKeyValue("eclass_mp_prefix")) -{ - if (string_empty(mp_ignore_prefix)) { - mp_ignore_prefix = "sp_"; - } - if (string_empty(sp_ignore_prefix)) { - sp_ignore_prefix = "mp_"; - } -} -}; - -class EntityClassesLoadFile { -const EntityClassScanner &scanner; -const char *m_directory; -public: -EntityClassesLoadFile(const EntityClassScanner &scanner, const char *directory) : scanner(scanner), - m_directory(directory) -{ -} - -void operator()(const char *name) const -{ - EntityClassFilterMode filterMode; - - if (filterMode.filter_mp_sp) { - if (string_empty(GlobalRadiant().getGameMode()) || string_equal(GlobalRadiant().getGameMode(), "sp")) { - if (string_equal_n(name, filterMode.sp_ignore_prefix, strlen(filterMode.sp_ignore_prefix))) { - globalOutputStream() << "Ignoring '" << name << "'\n"; - return; - } - } else { - if (string_equal_n(name, filterMode.mp_ignore_prefix, strlen(filterMode.mp_ignore_prefix))) { - globalOutputStream() << "Ignoring '" << name << "'\n"; - return; - } - } - } - - // for a given name, we grab the first .def in the vfs - // this allows to override baseq3/scripts/entities.def for instance - StringOutputStream relPath(256); - relPath << m_directory << name; - - scanner.scanFile(g_collector, relPath.c_str()); -} -}; - -struct PathLess { - bool operator()(const CopiedString &path, const CopiedString &other) const - { - return path_less(path.c_str(), other.c_str()); - } -}; - -typedef std::map Paths; - -void EntityClassQuake3_constructDirectory(const char *directory, const char *extension, Paths &paths) -{ - globalOutputStream() << "EntityClass: searching " << makeQuoted(directory) << " for *." << extension << '\n'; - Directory_forEach(directory, matchFileExtension(extension, [&](const char *name) { - paths.insert(Paths::value_type(name, directory)); - })); -} - - -void EntityClassQuake3_Construct() -{ - StringOutputStream baseDirectory(256); - StringOutputStream gameDirectory(256); - const char *basegame = GlobalRadiant().getRequiredGameDescriptionKeyValue("basegame"); - const char *gamename = GlobalRadiant().getGameName(); - baseDirectory << GlobalRadiant().getEnginePath() << basegame << '/'; - gameDirectory << GlobalRadiant().getEnginePath() << gamename << '/'; - - class LoadEntityDefinitionsVisitor : public EClassModules::Visitor { - const char *baseDirectory; - const char *gameDirectory; -public: - LoadEntityDefinitionsVisitor(const char *baseDirectory, const char *gameDirectory) - : baseDirectory(baseDirectory), gameDirectory(gameDirectory) - { - } - - void visit(const char *name, const EntityClassScanner &table) const - { - Paths paths; - if (!string_equal(baseDirectory, gameDirectory)) - EntityClassQuake3_constructDirectory(gameDirectory, table.getExtension(), paths); - else - EntityClassQuake3_constructDirectory(baseDirectory, table.getExtension(), paths); - - for (Paths::iterator i = paths.begin(); i != paths.end(); ++i) { - EntityClassesLoadFile(table, (*i).second)((*i).first.c_str()); - } - } - }; - - EntityClassManager_getEClassModules().foreachModule( - LoadEntityDefinitionsVisitor(baseDirectory.c_str(), gameDirectory.c_str())); -} - -EntityClass *Eclass_ForName(const char *name, bool has_brushes) -{ - ASSERT_NOTNULL(name); - - if (string_empty(name)) { - return eclass_bad; - } - - EntityClasses::iterator i = g_entityClasses.find(name); - if (i != g_entityClasses.end() && string_equal((*i).first, name)) { - return (*i).second; - } - - EntityClass *e = EntityClass_Create_Default(name, has_brushes); - return Eclass_InsertAlphabetized(e); -} - -class EntityClassQuake3 : public ModuleObserver { -std::size_t m_unrealised; -ModuleObservers m_observers; -public: -EntityClassQuake3() : m_unrealised(4) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - //globalOutputStream() << "Entity Classes: realise\n"; - EntityClassQuake3_Construct(); - m_observers.realise(); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - m_observers.unrealise(); - //globalOutputStream() << "Entity Classes: unrealise\n"; - Eclass_Clear(); - } -} - -void attach(ModuleObserver &observer) -{ - m_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - m_observers.detach(observer); -} -}; - -EntityClassQuake3 g_EntityClassQuake3; - -void EntityClass_attach(ModuleObserver &observer) -{ - g_EntityClassQuake3.attach(observer); -} - -void EntityClass_detach(ModuleObserver &observer) -{ - g_EntityClassQuake3.detach(observer); -} - -void EntityClass_realise() -{ - g_EntityClassQuake3.realise(); -} - -void EntityClass_unrealise() -{ - g_EntityClassQuake3.unrealise(); -} - -void EntityClassQuake3_construct() -{ - // start by creating the default unknown eclass - eclass_bad = EClass_Create("UNKNOWN_CLASS", Vector3(0.0f, 0.5f, 0.0f), ""); - - EntityClass_realise(); -} - -void EntityClassQuake3_destroy() -{ - EntityClass_unrealise(); - - eclass_bad->free(eclass_bad); -} - -#include "modulesystem/modulesmap.h" - -class EntityClassQuake3Dependencies : - public GlobalRadiantModuleRef, - public GlobalFileSystemModuleRef, - public GlobalShaderCacheModuleRef { -EClassModulesRef m_eclass_modules; -public: -EntityClassQuake3Dependencies() : - m_eclass_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("entityclasstype")) -{ -} - -EClassModules &getEClassModules() -{ - return m_eclass_modules.get(); -} -}; - -class EclassManagerAPI { -EntityClassManager m_eclassmanager; -public: -typedef EntityClassManager Type; - -STRING_CONSTANT(Name, "quake3"); - -EclassManagerAPI() -{ - EntityClassQuake3_construct(); - - m_eclassmanager.findOrInsert = &Eclass_ForName; - m_eclassmanager.findListType = &EntityClass_findListType; - m_eclassmanager.forEach = &Eclass_forEach; - m_eclassmanager.forEachPoint = &Eclass_forEachPoint; - m_eclassmanager.attach = &EntityClass_attach; - m_eclassmanager.detach = &EntityClass_detach; - m_eclassmanager.realise = &EntityClass_realise; - m_eclassmanager.unrealise = &EntityClass_unrealise; - - Radiant_attachGameToolsPathObserver(g_EntityClassQuake3); - Radiant_attachGameModeObserver(g_EntityClassQuake3); - Radiant_attachGameNameObserver(g_EntityClassQuake3); -} - -~EclassManagerAPI() -{ - Radiant_detachGameNameObserver(g_EntityClassQuake3); - Radiant_detachGameModeObserver(g_EntityClassQuake3); - Radiant_detachGameToolsPathObserver(g_EntityClassQuake3); - - EntityClassQuake3_destroy(); -} - -EntityClassManager *getTable() -{ - return &m_eclassmanager; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule EclassManagerModule; -typedef Static StaticEclassManagerModule; -StaticRegisterModule staticRegisterEclassManager(StaticEclassManagerModule::instance()); - -EClassModules &EntityClassManager_getEClassModules() -{ - return StaticEclassManagerModule::instance().getDependencies().getEClassModules(); -} diff --git a/src/eclass.h b/src/eclass.h deleted file mode 100644 index d4bfd1f..0000000 --- a/src/eclass.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_H ) -#define INCLUDED_ECLASS_H - -#endif diff --git a/src/eclass_def.cpp b/src/eclass_def.cpp deleted file mode 100644 index 7baf042..0000000 --- a/src/eclass_def.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "eclass_def.h" - -#include "iscriplib.h" -#include "ifilesystem.h" -#include "iarchive.h" - -#include "eclasslib.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" -#include "modulesystem/moduleregistry.h" -#include "os/path.h" - -const char *EClass_GetExtension() -{ - return "def"; -} - -void Eclass_ScanFile(EntityClassCollector &collector, const char *filename); - - -#include "modulesystem/singletonmodule.h" - -class EntityClassDefDependencies : public GlobalShaderCacheModuleRef, public GlobalScripLibModuleRef { -}; - -class EclassDefAPI { -EntityClassScanner m_eclassdef; -public: -typedef EntityClassScanner Type; - -STRING_CONSTANT(Name, "def"); - -EclassDefAPI() -{ - m_eclassdef.scanFile = &Eclass_ScanFile; - m_eclassdef.getExtension = &EClass_GetExtension; -} - -EntityClassScanner *getTable() -{ - return &m_eclassdef; -} -}; - -typedef SingletonModule EclassDefModule; -typedef Static StaticEclassDefModule; -StaticRegisterModule staticRegisterEclassDef(StaticEclassDefModule::instance()); - - -#include "string/string.h" - -#include - - -char com_token[1024]; -bool com_eof; - -/* - ============== - COM_Parse - - Parse a token out of a string - ============== - */ -const char *COM_Parse(const char *data) -{ - int c; - int len; - - len = 0; - com_token[0] = 0; - - if (!data) { - return 0; - } - -// skip whitespace -skipwhite: - while ((c = *data) <= ' ') { - if (c == 0) { - com_eof = true; - return 0; // end of file; - } - data++; - } - -// skip // comments - if (c == '/' && data[1] == '/') { - while (*data && *data != '\n') { - data++; - } - goto skipwhite; - } - - -// handle quoted strings specially - if (c == '\"') { - data++; - do { - c = *data++; - if (c == '\"') { - com_token[len] = 0; - return data; - } - com_token[len] = c; - len++; - } while (1); - } - -// parse single characters - if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':') { - com_token[len] = c; - len++; - com_token[len] = 0; - return data + 1; - } - -// parse a regular word - do { - com_token[len] = c; - data++; - len++; - c = *data; - if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':') { - break; - } - } while (c > 32); - - com_token[len] = 0; - return data; -} - -const char *Get_COM_Token() -{ - return com_token; -} - - -const char *debugname; - -void setSpecialLoad(EntityClass *e, const char *pWhat, CopiedString &p) -{ - // Hydra: removed some amazingly bad cstring usage, whoever wrote that - // needs to be taken out and shot. - - const char *pText = 0; - const char *where = 0; - - where = strstr(e->comments(), pWhat); - if (!where) { - return; - } - - pText = where + strlen(pWhat); - if (*pText == '\"') { - pText++; - } - - where = strchr(pText, '\"'); - if (where) { - p = StringRange(pText, where); - } else { - p = pText; - } -} - -#include "eclasslib.h" - -/* - - the classname, color triple, and bounding box are parsed out of comments - A ? size means take the exact brush size. - - / *QUAKED (0 0 0) ? - / *QUAKED (0 0 0) (-8 -8 -8) (8 8 8) - - Flag names can follow the size description: - - / *QUAKED func_door (0 .5 .8) ? START_OPEN STONE_SOUND DOOR_DONT_LINK GOLD_KEY SILVER_KEY - - */ - -EntityClass *Eclass_InitFromText(const char *text) -{ - EntityClass *e = Eclass_Alloc(); - e->free = &Eclass_Free; - - // grab the name - text = COM_Parse(text); - e->m_name = Get_COM_Token(); - debugname = e->name(); - - { - // grab the color, reformat as texture name - int r = sscanf(text, " (%f %f %f)", &e->color[0], &e->color[1], &e->color[2]); - if (r != 3) { - return e; - } - eclass_capture_state(e); - } - - while (*text != ')') { - if (!*text) { - return 0; - } - text++; - } - text++; - - // get the size - text = COM_Parse(text); - if (Get_COM_Token()[0] == '(') { // parse the size as two vectors - e->fixedsize = true; - int r = sscanf(text, "%f %f %f) (%f %f %f)", &e->mins[0], &e->mins[1], &e->mins[2], - &e->maxs[0], &e->maxs[1], &e->maxs[2]); - if (r != 6) { - return 0; - } - - for (int i = 0; i < 2; i++) { - while (*text != ')') { - if (!*text) { - return 0; - } - text++; - } - text++; - } - } - - char parms[256]; - // get the flags - { - // copy to the first /n - char *p = parms; - while (*text && *text != '\n') { - *p++ = *text++; - } - *p = 0; - text++; - } - - { - // any remaining words are parm flags - const char *p = parms; - for (std::size_t i = 0; i < MAX_FLAGS; i++) { - p = COM_Parse(p); - if (!p) { - break; - } - strcpy(e->flagnames[i], Get_COM_Token()); - } - } - - e->m_comments = text; - - setSpecialLoad(e, "model=", e->m_modelpath); - StringOutputStream buffer(string_length(e->m_modelpath.c_str())); - buffer << PathCleaned(e->m_modelpath.c_str()); - e->m_modelpath = buffer.c_str(); - - if (!e->fixedsize) { - EntityClass_insertAttribute(*e, "angle", EntityClassAttribute("direction", "Direction", "0")); - } else { - EntityClass_insertAttribute(*e, "angle", EntityClassAttribute("angle", "Yaw Angle", "0")); - } - EntityClass_insertAttribute(*e, "model", EntityClassAttribute("model", "Model")); - EntityClass_insertAttribute(*e, "noise", EntityClassAttribute("sound", "Sound")); - - return e; -} - -void Eclass_ScanFile(EntityClassCollector &collector, const char *filename) -{ - EntityClass *e; - - TextFileInputStream inputFile(filename); - if (inputFile.failed()) { - globalErrorStream() << "ScanFile: " << filename << " not found\n"; - return; - } - globalOutputStream() << "ScanFile: " << filename << "\n"; - - enum EParserState { - eParseDefault, - eParseSolidus, - eParseComment, - eParseQuakeED, - eParseEntityClass, - eParseEntityClassEnd, - } state = eParseDefault; - const char *quakeEd = "QUAKED"; - const char *p = 0; - StringBuffer buffer; - SingleCharacterInputStream bufferedInput(inputFile); - for (;;) { - char c; - if (!bufferedInput.readChar(c)) { - break; - } - - switch (state) { - case eParseDefault: - if (c == '/') { - state = eParseSolidus; - } - break; - case eParseSolidus: - if (c == '/') { - state = eParseComment; - } else if (c == '*') { - p = quakeEd; - state = eParseQuakeED; - } - break; - case eParseComment: - if (c == '\n') { - state = eParseDefault; - } - break; - case eParseQuakeED: - if (c == *p) { - if (*(++p) == '\0') { - state = eParseEntityClass; - } - } else { - state = eParseDefault; - } - break; - case eParseEntityClass: - if (c == '*') { - state = eParseEntityClassEnd; - } else { - buffer.push_back(c); - } - break; - case eParseEntityClassEnd: - if (c == '/') { - e = Eclass_InitFromText(buffer.c_str()); - state = eParseDefault; - if (e) { - collector.insert(e); - } else { - globalErrorStream() << "Error parsing: " << debugname << " in " << filename << "\n"; - } - - buffer.clear(); - state = eParseDefault; - } else { - buffer.push_back('*'); - buffer.push_back(c); - state = eParseEntityClass; - } - break; - } - } -} diff --git a/src/eclass_def.h b/src/eclass_def.h deleted file mode 100644 index 102fe4f..0000000 --- a/src/eclass_def.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_DEF_H ) -#define INCLUDED_ECLASS_DEF_H - -#endif diff --git a/src/eclass_doom3.cpp b/src/eclass_doom3.cpp deleted file mode 100644 index ffbcfef..0000000 --- a/src/eclass_doom3.cpp +++ /dev/null @@ -1,827 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "eclass_doom3.h" - -#include "debugging/debugging.h" - -#include - -#include "ifilesystem.h" -#include "iscriplib.h" -#include "iarchive.h" -#include "qerplugin.h" - -#include "generic/callback.h" -#include "string/string.h" -#include "eclasslib.h" -#include "os/path.h" -#include "os/dir.h" -#include "stream/stringstream.h" -#include "moduleobservers.h" -#include "stringio.h" - -class RawString { -const char *m_value; -public: -RawString(const char *value) : m_value(value) -{ -} - -const char *c_str() const -{ - return m_value; -} -}; - -inline bool operator<(const RawString &self, const RawString &other) -{ - return string_less_nocase(self.c_str(), other.c_str()); -} - -typedef std::map EntityClasses; -EntityClasses g_EntityClassDoom3_classes; -EntityClass *g_EntityClassDoom3_bad = 0; - - -void EntityClassDoom3_clear() -{ - for (EntityClasses::iterator i = g_EntityClassDoom3_classes.begin(); i != g_EntityClassDoom3_classes.end(); ++i) { - (*i).second->free((*i).second); - } - g_EntityClassDoom3_classes.clear(); -} - -// entityClass will be inserted only if another of the same name does not already exist. -// if entityClass was inserted, the same object is returned, otherwise the already-existing object is returned. -EntityClass *EntityClassDoom3_insertUnique(EntityClass *entityClass) -{ - return (*g_EntityClassDoom3_classes.insert( - EntityClasses::value_type(entityClass->name(), entityClass)).first).second; -} - -void EntityClassDoom3_forEach(EntityClassVisitor &visitor) -{ - for (EntityClasses::iterator i = g_EntityClassDoom3_classes.begin(); i != g_EntityClassDoom3_classes.end(); ++i) { - visitor.visit((*i).second); - } -} - -inline void printParseError(const char *message) -{ - globalErrorStream() << message; -} - -#define PARSE_RETURN_FALSE_IF_FAIL(expression) do { if (!( expression)) { printParseError(FILE_LINE "\nparse failed: " #expression "\n"); return false; } } while (0) - -bool EntityClassDoom3_parseToken(Tokeniser &tokeniser) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - return true; -} - -bool EntityClassDoom3_parseToken(Tokeniser &tokeniser, const char *string) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - return string_equal(token, string); -} - -bool EntityClassDoom3_parseString(Tokeniser &tokeniser, const char *&s) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - s = token; - return true; -} - -bool EntityClassDoom3_parseString(Tokeniser &tokeniser, CopiedString &s) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - s = token; - return true; -} - -bool EntityClassDoom3_parseString(Tokeniser &tokeniser, StringOutputStream &s) -{ - const char *token = tokeniser.getToken(); - PARSE_RETURN_FALSE_IF_FAIL(token != 0); - s << token; - return true; -} - -bool EntityClassDoom3_parseUnknown(Tokeniser &tokeniser) -{ - //const char* name = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - - //globalOutputStream() << "parsing unknown block " << makeQuoted(name) << "\n"; - - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "{")); - tokeniser.nextLine(); - - std::size_t depth = 1; - for (;;) { - const char *token; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - if (string_equal(token, "}")) { - if (--depth == 0) { - tokeniser.nextLine(); - break; - } - } else if (string_equal(token, "{")) { - ++depth; - } - tokeniser.nextLine(); - } - return true; -} - - -class Model { -public: -bool m_resolved; -CopiedString m_mesh; -CopiedString m_skin; -CopiedString m_parent; -typedef std::map Anims; -Anims m_anims; - -Model() : m_resolved(false) -{ -} -}; - -typedef std::map Models; - -Models g_models; - -void Model_resolveInheritance(const char *name, Model &model) -{ - if (model.m_resolved == false) { - model.m_resolved = true; - - if (!string_empty(model.m_parent.c_str())) { - Models::iterator i = g_models.find(model.m_parent); - if (i == g_models.end()) { - globalErrorStream() << "model " << name << " inherits unknown model " << model.m_parent.c_str() << "\n"; - } else { - Model_resolveInheritance((*i).first.c_str(), (*i).second); - model.m_mesh = (*i).second.m_mesh; - model.m_skin = (*i).second.m_skin; - } - } - } -} - -bool EntityClassDoom3_parseModel(Tokeniser &tokeniser) -{ - const char *name; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, name)); - - Model &model = g_models[name]; - - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "{")); - tokeniser.nextLine(); - - for (;;) { - const char *parameter; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, parameter)); - if (string_equal(parameter, "}")) { - tokeniser.nextLine(); - break; - } else if (string_equal(parameter, "inherit")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, model.m_parent)); - tokeniser.nextLine(); - } else if (string_equal(parameter, "remove")) { - //const char* remove = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - tokeniser.nextLine(); - } else if (string_equal(parameter, "mesh")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, model.m_mesh)); - tokeniser.nextLine(); - } else if (string_equal(parameter, "skin")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, model.m_skin)); - tokeniser.nextLine(); - } else if (string_equal(parameter, "offset")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "(")); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, ")")); - tokeniser.nextLine(); - } else if (string_equal(parameter, "channel")) { - //const char* channelName = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "(")); - for (;;) { - const char *end; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, end)); - if (string_equal(end, ")")) { - tokeniser.nextLine(); - break; - } - } - } else if (string_equal(parameter, "anim")) { - CopiedString animName; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, animName)); - const char *animFile; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, animFile)); - model.m_anims.insert(Model::Anims::value_type(animName, animFile)); - - const char *token; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - - while (string_equal(token, ",")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, animFile)); - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - } - - if (string_equal(token, "{")) { - for (;;) { - const char *end; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, end)); - if (string_equal(end, "}")) { - tokeniser.nextLine(); - break; - } - tokeniser.nextLine(); - } - } else { - tokeniser.ungetToken(); - } - } else { - globalErrorStream() << "unknown model parameter: " << makeQuoted(parameter) << "\n"; - return false; - } - tokeniser.nextLine(); - } - return true; -} - -inline bool char_isSpaceOrTab(char c) -{ - return c == ' ' || c == '\t'; -} - -inline bool char_isNotSpaceOrTab(char c) -{ - return !char_isSpaceOrTab(c); -} - -template -inline const char *string_find_if(const char *string, Predicate predicate) -{ - for (; *string != 0; ++string) { - if (predicate(*string)) { - return string; - } - } - return string; -} - -inline const char *string_findFirstSpaceOrTab(const char *string) -{ - return string_find_if(string, char_isSpaceOrTab); -} - -inline const char *string_findFirstNonSpaceOrTab(const char *string) -{ - return string_find_if(string, char_isNotSpaceOrTab); -} - - -static bool EntityClass_parse(EntityClass &entityClass, Tokeniser &tokeniser) -{ - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, entityClass.m_name)); - - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser, "{")); - tokeniser.nextLine(); - - StringOutputStream usage(256); - StringOutputStream description(256); - CopiedString *currentDescription = 0; - StringOutputStream *currentString = 0; - - for (;;) { - const char *key; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, key)); - - const char *last = string_findFirstSpaceOrTab(key); - CopiedString first(StringRange(key, last)); - - if (!string_empty(last)) { - last = string_findFirstNonSpaceOrTab(last); - } - - if (currentString != 0 && string_equal(key, "\\")) { - tokeniser.nextLine(); - *currentString << " "; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, *currentString)); - continue; - } - - if (currentDescription != 0) { - *currentDescription = description.c_str(); - description.clear(); - currentDescription = 0; - } - currentString = 0; - - if (string_equal(key, "}")) { - tokeniser.nextLine(); - break; - } else if (string_equal(key, "model")) { - const char *token; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - entityClass.fixedsize = true; - StringOutputStream buffer(256); - buffer << PathCleaned(token); - entityClass.m_modelpath = buffer.c_str(); - } else if (string_equal(key, "editor_color")) { - const char *value; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, value)); - if (!string_empty(value)) { - entityClass.colorSpecified = true; - bool success = string_parse_vector3(value, entityClass.color); - ASSERT_MESSAGE(success, "editor_color: parse error"); - } - } else if (string_equal(key, "editor_ragdoll")) { - //bool ragdoll = atoi(tokeniser.getToken()) != 0; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } else if (string_equal(key, "editor_mins")) { - entityClass.sizeSpecified = true; - const char *value; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, value)); - if (!string_empty(value) && !string_equal(value, "?")) { - entityClass.fixedsize = true; - bool success = string_parse_vector3(value, entityClass.mins); - ASSERT_MESSAGE(success, "editor_mins: parse error"); - } - } else if (string_equal(key, "editor_maxs")) { - entityClass.sizeSpecified = true; - const char *value; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, value)); - if (!string_empty(value) && !string_equal(value, "?")) { - entityClass.fixedsize = true; - bool success = string_parse_vector3(value, entityClass.maxs); - ASSERT_MESSAGE(success, "editor_maxs: parse error"); - } - } else if (string_equal(key, "editor_usage")) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, usage)); - currentString = &usage; - } else if (string_equal_n(key, "editor_usage", 12)) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, usage)); - currentString = &usage; - } else if (string_equal(key, "editor_rotatable") - || string_equal(key, "editor_showangle") - || string_equal(key, "editor_showangles") // typo? in prey movables.def - || string_equal(key, "editor_mover") - || string_equal(key, "editor_model") - || string_equal(key, "editor_material") - || string_equal(key, "editor_combatnode") - || (!string_empty(last) && string_equal(first.c_str(), "editor_gui")) - || string_equal_n(key, "editor_copy", 11)) { - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } else if (!string_empty(last) && - (string_equal(first.c_str(), "editor_var") || string_equal(first.c_str(), "editor_string"))) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "string"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_float")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "string"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_snd")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "sound"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_bool")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "boolean"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_int")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "integer"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_model")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "model"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && string_equal(first.c_str(), "editor_color")) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "color"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (!string_empty(last) && - (string_equal(first.c_str(), "editor_material") || string_equal(first.c_str(), "editor_mat"))) { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, last).second; - attribute.m_type = "shader"; - currentDescription = &attribute.m_description; - currentString = &description; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, description)); - } else if (string_equal(key, "inherit")) { - entityClass.inheritanceResolved = false; - ASSERT_MESSAGE(entityClass.m_parent.empty(), "only one 'inherit' supported per entityDef"); - const char *token; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, token)); - entityClass.m_parent.push_back(token); - } - // begin quake4-specific keys - else if (string_equal(key, "editor_targetonsel")) { - //const char* value = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } else if (string_equal(key, "editor_menu")) { - //const char* value = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } else if (string_equal(key, "editor_ignore")) { - //const char* value = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } - // end quake4-specific keys - // begin ignore prey (unknown/unused?) entity keys - else if (string_equal(key, "editor_light") - || string_equal(key, "editor_def def_debrisspawner") - || string_equal(key, "editor_def def_drop") - || string_equal(key, "editor_def def_guihand") - || string_equal(key, "editor_def def_mine")) { - //const char* value = - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseToken(tokeniser)); - } - // end ignore prey entity keys - else { - CopiedString tmp(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; - PARSE_RETURN_FALSE_IF_FAIL(EntityClassDoom3_parseString(tokeniser, value)); - if (string_equal(value, "}")) { // hack for quake4 powerups.def bug - globalErrorStream() << "entityDef " << makeQuoted(entityClass.m_name.c_str()) << " key " - << makeQuoted(tmp.c_str()) << " has no value\n"; - break; - } else { - attribute.m_value = value; - } - } - tokeniser.nextLine(); - } - - entityClass.m_comments = usage.c_str(); - - if (string_equal(entityClass.m_name.c_str(), "light")) { - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "light_radius").second; - attribute.m_type = "vector3"; - attribute.m_value = "300 300 300"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "light_center").second; - attribute.m_type = "vector3"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "noshadows").second; - attribute.m_type = "boolean"; - attribute.m_value = "0"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "nospecular").second; - attribute.m_type = "boolean"; - attribute.m_value = "0"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "nodiffuse").second; - attribute.m_type = "boolean"; - attribute.m_value = "0"; - } - { - EntityClassAttribute &attribute = EntityClass_insertAttribute(entityClass, "falloff").second; - attribute.m_type = "real"; - } - } - - return true; -} - -bool EntityClassDoom3_parseEntityDef(Tokeniser &tokeniser) -{ - EntityClass *entityClass = Eclass_Alloc(); - entityClass->free = &Eclass_Free; - - if (!EntityClass_parse(*entityClass, tokeniser)) { - eclass_capture_state(entityClass); // finish constructing the entity so that it can be destroyed cleanly. - entityClass->free(entityClass); - return false; - } - - EntityClass *inserted = EntityClassDoom3_insertUnique(entityClass); - if (inserted != entityClass) { - globalErrorStream() << "entityDef " << entityClass->name() - << " is already defined, second definition ignored\n"; - eclass_capture_state(entityClass); // finish constructing the entity so that it can be destroyed cleanly. - entityClass->free(entityClass); - } - return true; -} - -bool EntityClassDoom3_parseBlock(Tokeniser &tokeniser, const char *blockType) -{ - if (string_equal(blockType, "entityDef")) { - return EntityClassDoom3_parseEntityDef(tokeniser); - } else if (string_equal(blockType, "model")) { - return EntityClassDoom3_parseModel(tokeniser); - } else { - return EntityClassDoom3_parseUnknown(tokeniser); - } -} - -bool EntityClassDoom3_parse(TextInputStream &inputStream, const char *filename) -{ - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser(inputStream); - - tokeniser.nextLine(); - - for (;;) { - const char *blockType = tokeniser.getToken(); - if (blockType == 0) { - return true; - } - CopiedString tmp(blockType); - if (!EntityClassDoom3_parseBlock(tokeniser, tmp.c_str())) { - globalErrorStream() << GlobalFileSystem().findFile(filename) << filename << ":" - << (unsigned int) tokeniser.getLine() << ": " << tmp.c_str() - << " parse failed, skipping rest of file\n"; - return false; - } - } - - tokeniser.release(); -} - - -void EntityClassDoom3_loadFile(const char *filename) -{ - globalOutputStream() << "parsing entity classes from " << makeQuoted(filename) << "\n"; - - StringOutputStream fullname(256); - fullname << "def/" << filename; - - ArchiveTextFile *file = GlobalFileSystem().openTextFile(fullname.c_str()); - if (file != 0) { - EntityClassDoom3_parse(file->getInputStream(), fullname.c_str()); - file->release(); - } -} - -EntityClass *EntityClassDoom3_findOrInsert(const char *name, bool has_brushes) -{ - ASSERT_NOTNULL(name); - - if (string_empty(name)) { - return g_EntityClassDoom3_bad; - } - - EntityClasses::iterator i = g_EntityClassDoom3_classes.find(name); - if (i != g_EntityClassDoom3_classes.end() - //&& string_equal((*i).first, name) - ) { - return (*i).second; - } - - EntityClass *e = EntityClass_Create_Default(name, has_brushes); - EntityClass *inserted = EntityClassDoom3_insertUnique(e); - ASSERT_MESSAGE(inserted == e, ""); - return inserted; -} - -const ListAttributeType *EntityClassDoom3_findListType(const char *name) -{ - return 0; -} - - -void EntityClass_resolveInheritance(EntityClass *derivedClass) -{ - if (derivedClass->inheritanceResolved == false) { - derivedClass->inheritanceResolved = true; - EntityClasses::iterator i = g_EntityClassDoom3_classes.find(derivedClass->m_parent.front().c_str()); - if (i == g_EntityClassDoom3_classes.end()) { - globalErrorStream() << "failed to find entityDef " << makeQuoted(derivedClass->m_parent.front().c_str()) - << " inherited by " << makeQuoted(derivedClass->m_name.c_str()) << "\n"; - } else { - EntityClass *parentClass = (*i).second; - EntityClass_resolveInheritance(parentClass); - if (!derivedClass->colorSpecified) { - derivedClass->colorSpecified = parentClass->colorSpecified; - derivedClass->color = parentClass->color; - } - if (!derivedClass->sizeSpecified) { - derivedClass->sizeSpecified = parentClass->sizeSpecified; - derivedClass->mins = parentClass->mins; - derivedClass->maxs = parentClass->maxs; - derivedClass->fixedsize = parentClass->fixedsize; - } - - for (EntityClassAttributes::iterator j = parentClass->m_attributes.begin(); - j != parentClass->m_attributes.end(); ++j) { - EntityClass_insertAttribute(*derivedClass, (*j).first.c_str(), (*j).second); - } - } - } -} - -class EntityClassDoom3 : public ModuleObserver { -std::size_t m_unrealised; -ModuleObservers m_observers; -public: -EntityClassDoom3() : m_unrealised(2) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - globalOutputStream() << "searching vfs directory " << makeQuoted("def") << " for *.def\n"; - GlobalFileSystem().forEachFile("def/", "def", makeCallbackF(EntityClassDoom3_loadFile)); - - { - for (Models::iterator i = g_models.begin(); i != g_models.end(); ++i) { - Model_resolveInheritance((*i).first.c_str(), (*i).second); - } - } - { - for (EntityClasses::iterator i = g_EntityClassDoom3_classes.begin(); - i != g_EntityClassDoom3_classes.end(); ++i) { - EntityClass_resolveInheritance((*i).second); - if (!string_empty((*i).second->m_modelpath.c_str())) { - Models::iterator j = g_models.find((*i).second->m_modelpath); - if (j != g_models.end()) { - (*i).second->m_modelpath = (*j).second.m_mesh; - (*i).second->m_skin = (*j).second.m_skin; - } - } - eclass_capture_state((*i).second); - - StringOutputStream usage(256); - - usage << "-------- NOTES --------\n"; - - if (!string_empty((*i).second->m_comments.c_str())) { - usage << (*i).second->m_comments.c_str() << "\n"; - } - - usage << "\n-------- KEYS --------\n"; - - for (EntityClassAttributes::iterator j = (*i).second->m_attributes.begin(); - j != (*i).second->m_attributes.end(); ++j) { - const char *name = EntityClassAttributePair_getName(*j); - const char *description = EntityClassAttributePair_getDescription(*j); - if (!string_equal(name, description)) { - usage << EntityClassAttributePair_getName(*j) << " : " - << EntityClassAttributePair_getDescription(*j) << "\n"; - } - } - - (*i).second->m_comments = usage.c_str(); - } - } - - m_observers.realise(); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - m_observers.unrealise(); - EntityClassDoom3_clear(); - } -} - -void attach(ModuleObserver &observer) -{ - m_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - m_observers.detach(observer); -} -}; - -EntityClassDoom3 g_EntityClassDoom3; - -void EntityClassDoom3_attach(ModuleObserver &observer) -{ - g_EntityClassDoom3.attach(observer); -} - -void EntityClassDoom3_detach(ModuleObserver &observer) -{ - g_EntityClassDoom3.detach(observer); -} - -void EntityClassDoom3_realise() -{ - g_EntityClassDoom3.realise(); -} - -void EntityClassDoom3_unrealise() -{ - g_EntityClassDoom3.unrealise(); -} - -void EntityClassDoom3_construct() -{ - GlobalFileSystem().attach(g_EntityClassDoom3); - - // start by creating the default unknown eclass - g_EntityClassDoom3_bad = EClass_Create("UNKNOWN_CLASS", Vector3(0.0f, 0.5f, 0.0f), ""); - - EntityClassDoom3_realise(); -} - -void EntityClassDoom3_destroy() -{ - EntityClassDoom3_unrealise(); - - g_EntityClassDoom3_bad->free(g_EntityClassDoom3_bad); - - GlobalFileSystem().detach(g_EntityClassDoom3); -} - -class EntityClassDoom3Dependencies : public GlobalFileSystemModuleRef, public GlobalShaderCacheModuleRef { -}; - -class EntityClassDoom3API { -EntityClassManager m_eclassmanager; -public: -typedef EntityClassManager Type; - -STRING_CONSTANT(Name, "doom3"); - -EntityClassDoom3API() -{ - EntityClassDoom3_construct(); - - m_eclassmanager.findOrInsert = &EntityClassDoom3_findOrInsert; - m_eclassmanager.findListType = &EntityClassDoom3_findListType; - m_eclassmanager.forEach = &EntityClassDoom3_forEach; - m_eclassmanager.attach = &EntityClassDoom3_attach; - m_eclassmanager.detach = &EntityClassDoom3_detach; - m_eclassmanager.realise = &EntityClassDoom3_realise; - m_eclassmanager.unrealise = &EntityClassDoom3_unrealise; -} - -~EntityClassDoom3API() -{ - EntityClassDoom3_destroy(); -} - -EntityClassManager *getTable() -{ - return &m_eclassmanager; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule EntityClassDoom3Module; -typedef Static StaticEntityClassDoom3Module; -StaticRegisterModule staticRegisterEntityClassDoom3(StaticEntityClassDoom3Module::instance()); diff --git a/src/eclass_doom3.h b/src/eclass_doom3.h deleted file mode 100644 index 9dcd8bb..0000000 --- a/src/eclass_doom3.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_DOOM3_H ) -#define INCLUDED_ECLASS_DOOM3_H - -#endif diff --git a/src/eclass_fgd.cpp b/src/eclass_fgd.cpp deleted file mode 100644 index e420106..0000000 --- a/src/eclass_fgd.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "eclass_fgd.h" - -#include "debugging/debugging.h" - -#include - -#include "ifilesystem.h" -#include "iscriplib.h" -#include "qerplugin.h" -#include "mainframe.h" - -#include "string/string.h" -#include "eclasslib.h" -#include "os/path.h" -#include "os/dir.h" -#include "stream/stringstream.h" -#include "moduleobservers.h" -#include "stringio.h" -#include "stream/textfilestream.h" - -namespace { -typedef std::map EntityClasses; -EntityClasses g_EntityClassFGD_classes; -typedef std::map BaseClasses; -BaseClasses g_EntityClassFGD_bases; -EntityClass *g_EntityClassFGD_bad = 0; -typedef std::map ListAttributeTypes; -ListAttributeTypes g_listTypesFGD; -} - - -void EntityClassFGD_clear() -{ - for (BaseClasses::iterator i = g_EntityClassFGD_bases.begin(); i != g_EntityClassFGD_bases.end(); ++i) { - (*i).second->free((*i).second); - } - g_EntityClassFGD_bases.clear(); - g_listTypesFGD.clear(); -} - -EntityClass *EntityClassFGD_insertUniqueBase(EntityClass *entityClass) -{ - std::pair result = g_EntityClassFGD_bases.insert( - BaseClasses::value_type(entityClass->name(), entityClass)); - if (!result.second) { - globalErrorStream() << "duplicate base class: " << makeQuoted(entityClass->name()) << "\n"; - //eclass_capture_state(entityClass); - //entityClass->free(entityClass); - } - return (*result.first).second; -} - -EntityClass *EntityClassFGD_insertUnique(EntityClass *entityClass) -{ - EntityClassFGD_insertUniqueBase(entityClass); - std::pair result = g_EntityClassFGD_classes.insert( - EntityClasses::value_type(entityClass->name(), entityClass)); - if (!result.second) { - globalErrorStream() << "duplicate entity class: " << makeQuoted(entityClass->name()) << "\n"; - eclass_capture_state(entityClass); - entityClass->free(entityClass); - } - return (*result.first).second; -} - -void EntityClassFGD_forEach(EntityClassVisitor &visitor) -{ - for (EntityClasses::iterator i = g_EntityClassFGD_classes.begin(); i != g_EntityClassFGD_classes.end(); ++i) { - visitor.visit((*i).second); - } -} - -inline bool EntityClassFGD_parseToken(Tokeniser &tokeniser, const char *token) -{ - return string_equal(tokeniser.getToken(), token); -} - -const char *PARSE_ERROR = "error parsing entity class definition"; - -void EntityClassFGD_parseSplitString(Tokeniser &tokeniser, CopiedString &string) -{ - StringOutputStream buffer(256); - for (;;) { - buffer << tokeniser.getToken(); - if (!string_equal(tokeniser.getToken(), "+")) { - tokeniser.ungetToken(); - string = buffer.c_str(); - return; - } - } -} - -void EntityClassFGD_parseClass(Tokeniser &tokeniser, bool fixedsize, bool isBase) -{ - EntityClass *entityClass = Eclass_Alloc(); - entityClass->free = &Eclass_Free; - entityClass->fixedsize = fixedsize; - entityClass->inheritanceResolved = false; - entityClass->mins = Vector3(-8, -8, -8); - entityClass->maxs = Vector3(8, 8, 8); - - for (;;) { - const char *property = tokeniser.getToken(); - if (string_equal(property, "=")) { - break; - } else if (string_equal(property, "base")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - for (;;) { - const char *base = tokeniser.getToken(); - if (string_equal(base, ")")) { - break; - } else if (!string_equal(base, ",")) { - entityClass->m_parent.push_back(base); - } - } - } else if (string_equal(property, "size")) { - entityClass->sizeSpecified = true; - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - Tokeniser_getFloat(tokeniser, entityClass->mins.x()); - Tokeniser_getFloat(tokeniser, entityClass->mins.y()); - Tokeniser_getFloat(tokeniser, entityClass->mins.z()); - const char *token = tokeniser.getToken(); - if (string_equal(token, ",")) { - Tokeniser_getFloat(tokeniser, entityClass->maxs.x()); - Tokeniser_getFloat(tokeniser, entityClass->maxs.y()); - Tokeniser_getFloat(tokeniser, entityClass->maxs.z()); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else { - entityClass->maxs = entityClass->mins; - vector3_negate(entityClass->mins); - ASSERT_MESSAGE(string_equal(token, ")"), ""); - } - } else if (string_equal(property, "color")) { - entityClass->colorSpecified = true; - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - Tokeniser_getFloat(tokeniser, entityClass->color.x()); - entityClass->color.x() /= 256.0; - Tokeniser_getFloat(tokeniser, entityClass->color.y()); - entityClass->color.y() /= 256.0; - Tokeniser_getFloat(tokeniser, entityClass->color.z()); - entityClass->color.z() /= 256.0; - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "iconsprite")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - StringOutputStream buffer(256); - buffer << PathCleaned(tokeniser.getToken()); - entityClass->m_modelpath = buffer.c_str(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "sprite") - || string_equal(property, "decal") - // hl2 below - || string_equal(property, "overlay") - || string_equal(property, "light") - || string_equal(property, "keyframe") - || string_equal(property, "animator") - || string_equal(property, "quadbounds")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } - // hl2 below - else if (string_equal(property, "sphere") - || string_equal(property, "sweptplayerhull") - || string_equal(property, "studio") - || string_equal(property, "studioprop") - || string_equal(property, "lightprop") - || string_equal(property, "lightcone") - || string_equal(property, "sidelist")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - if (string_equal(tokeniser.getToken(), ")")) { - tokeniser.ungetToken(); - } - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "line") - || string_equal(property, "cylinder")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - //const char* r = - tokeniser.getToken(); - //const char* g = - tokeniser.getToken(); - //const char* b = - tokeniser.getToken(); - for (;;) { - if (string_equal(tokeniser.getToken(), ")")) { - tokeniser.ungetToken(); - break; - } - //const char* name = - tokeniser.getToken(); - } - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "wirebox")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - //const char* mins = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ","), PARSE_ERROR); - //const char* maxs = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else if (string_equal(property, "halfgridsnap")) { - } else { - ERROR_MESSAGE(PARSE_ERROR); - } - } - - entityClass->m_name = tokeniser.getToken(); - - if (!isBase) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - - EntityClassFGD_parseSplitString(tokeniser, entityClass->m_comments); - } - - tokeniser.nextLine(); - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "["), PARSE_ERROR); - - tokeniser.nextLine(); - - for (;;) { - CopiedString key = tokeniser.getToken(); - if (string_equal(key.c_str(), "]")) { - tokeniser.nextLine(); - break; - } - - if (string_equal_nocase(key.c_str(), "input") - || string_equal_nocase(key.c_str(), "output")) { - const char *name = tokeniser.getToken(); - if (!string_equal(name, "(")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - //const char* type = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - const char *descriptionSeparator = tokeniser.getToken(); - if (string_equal(descriptionSeparator, ":")) { - CopiedString description; - EntityClassFGD_parseSplitString(tokeniser, description); - } else { - tokeniser.ungetToken(); - } - tokeniser.nextLine(); - continue; - } - } - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - CopiedString type = tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - - if (string_equal_nocase(type.c_str(), "flags")) { - EntityClassAttribute attribute; - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "="), PARSE_ERROR); - tokeniser.nextLine(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "["), PARSE_ERROR); - tokeniser.nextLine(); - for (;;) { - const char *flag = tokeniser.getToken(); - if (string_equal(flag, "]")) { - tokeniser.nextLine(); - break; - } else { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - //const char* name = - tokeniser.getToken(); - { - const char *defaultSeparator = tokeniser.getToken(); - if (string_equal(defaultSeparator, ":")) { - tokeniser.getToken(); - { - const char *descriptionSeparator = tokeniser.getToken(); - if (string_equal(descriptionSeparator, ":")) { - EntityClassFGD_parseSplitString(tokeniser, attribute.m_description); - } else { - tokeniser.ungetToken(); - } - } - } else { - tokeniser.ungetToken(); - } - } - } - tokeniser.nextLine(); - } - EntityClass_insertAttribute(*entityClass, key.c_str(), attribute); - } else if (string_equal_nocase(type.c_str(), "choices")) { - EntityClassAttribute attribute; - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - attribute.m_name = tokeniser.getToken(); - const char *valueSeparator = tokeniser.getToken(); - if (string_equal(valueSeparator, ":")) { - const char *value = tokeniser.getToken(); - if (!string_equal(value, ":")) { - attribute.m_value = value; - } else { - tokeniser.ungetToken(); - } - { - const char *descriptionSeparator = tokeniser.getToken(); - if (string_equal(descriptionSeparator, ":")) { - EntityClassFGD_parseSplitString(tokeniser, attribute.m_description); - } else { - tokeniser.ungetToken(); - } - } - } else { - tokeniser.ungetToken(); - } - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "="), PARSE_ERROR); - tokeniser.nextLine(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "["), PARSE_ERROR); - tokeniser.nextLine(); - - StringOutputStream listTypeName(64); - listTypeName << entityClass->m_name.c_str() << "_" << attribute.m_name.c_str(); - attribute.m_type = listTypeName.c_str(); - - ListAttributeType &listType = g_listTypesFGD[listTypeName.c_str()]; - - for (;;) { - const char *value = tokeniser.getToken(); - if (string_equal(value, "]")) { - tokeniser.nextLine(); - break; - } else { - CopiedString tmp(value); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - const char *name = tokeniser.getToken(); - listType.push_back(name, tmp.c_str()); - } - tokeniser.nextLine(); - } - - for (ListAttributeType::const_iterator i = listType.begin(); i != listType.end(); ++i) { - if (string_equal(attribute.m_value.c_str(), (*i).first.c_str())) { - attribute.m_value = (*i).second.c_str(); - } - } - - EntityClass_insertAttribute(*entityClass, key.c_str(), attribute); - } else if (string_equal_nocase(type.c_str(), "decal")) { - } else if (string_equal_nocase(type.c_str(), "string") - || string_equal_nocase(type.c_str(), "integer") - || string_equal_nocase(type.c_str(), "studio") - || string_equal_nocase(type.c_str(), "sprite") - || string_equal_nocase(type.c_str(), "color255") - || string_equal_nocase(type.c_str(), "target_source") - || string_equal_nocase(type.c_str(), "target_destination") - || string_equal_nocase(type.c_str(), "sound") - // hl2 below - || string_equal_nocase(type.c_str(), "angle") - || string_equal_nocase(type.c_str(), "origin") - || string_equal_nocase(type.c_str(), "float") - || string_equal_nocase(type.c_str(), "node_dest") - || string_equal_nocase(type.c_str(), "filterclass") - || string_equal_nocase(type.c_str(), "vector") - || string_equal_nocase(type.c_str(), "sidelist") - || string_equal_nocase(type.c_str(), "material") - || string_equal_nocase(type.c_str(), "vecline") - || string_equal_nocase(type.c_str(), "axis") - || string_equal_nocase(type.c_str(), "npcclass") - || string_equal_nocase(type.c_str(), "target_name_or_class") - || string_equal_nocase(type.c_str(), "pointentityclass") - || string_equal_nocase(type.c_str(), "scene")) { - if (!string_equal(tokeniser.getToken(), "readonly")) { - tokeniser.ungetToken(); - } - - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ":"), PARSE_ERROR); - const char *attributeType = "string"; - if (string_equal_nocase(type.c_str(), "studio")) { - attributeType = "model"; - } - - EntityClassAttribute attribute; - attribute.m_type = attributeType; - attribute.m_name = tokeniser.getToken(); - - const char *defaultSeparator = tokeniser.getToken(); - if (string_equal(defaultSeparator, ":")) { - const char *value = tokeniser.getToken(); - if (!string_equal(value, ":")) { - attribute.m_value = value; - } else { - tokeniser.ungetToken(); - } - - { - const char *descriptionSeparator = tokeniser.getToken(); - if (string_equal(descriptionSeparator, ":")) { - EntityClassFGD_parseSplitString(tokeniser, attribute.m_description); - } else { - tokeniser.ungetToken(); - } - } - } else { - tokeniser.ungetToken(); - } - EntityClass_insertAttribute(*entityClass, key.c_str(), attribute); - } else { - ERROR_MESSAGE("unknown key type: " << makeQuoted(type.c_str())); - } - tokeniser.nextLine(); - } - - if (isBase) { - EntityClassFGD_insertUniqueBase(entityClass); - } else { - EntityClassFGD_insertUnique(entityClass); - } -} - -void EntityClassFGD_loadFile(const char *filename); - -void EntityClassFGD_parse(TextInputStream &inputStream, const char *path) -{ - Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewScriptTokeniser(inputStream); - - tokeniser.nextLine(); - - for (;;) { - const char *blockType = tokeniser.getToken(); - if (blockType == 0) { - break; - } - if (string_equal(blockType, "@SolidClass")) { - EntityClassFGD_parseClass(tokeniser, false, false); - } else if (string_equal(blockType, "@BaseClass")) { - EntityClassFGD_parseClass(tokeniser, false, true); - } else if (string_equal(blockType, "@PointClass") - // hl2 below - || string_equal(blockType, "@KeyFrameClass") - || string_equal(blockType, "@MoveClass") - || string_equal(blockType, "@FilterClass") - || string_equal(blockType, "@NPCClass")) { - EntityClassFGD_parseClass(tokeniser, true, false); - } - // hl2 below - else if (string_equal(blockType, "@include")) { - StringOutputStream includePath(256); - includePath << StringRange(path, path_get_filename_start(path)); - includePath << tokeniser.getToken(); - EntityClassFGD_loadFile(includePath.c_str()); - } else if (string_equal(blockType, "@mapsize")) { - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, "("), PARSE_ERROR); - //const char* min = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ","), PARSE_ERROR); - //const char* max = - tokeniser.getToken(); - ASSERT_MESSAGE(EntityClassFGD_parseToken(tokeniser, ")"), PARSE_ERROR); - } else { - ERROR_MESSAGE("unknown block type: " << makeQuoted(blockType)); - } - } - - tokeniser.release(); -} - - -void EntityClassFGD_loadFile(const char *filename) -{ - TextFileInputStream file(filename); - if (!file.failed()) { - globalOutputStream() << "parsing entity classes from " << makeQuoted(filename) << "\n"; - - EntityClassFGD_parse(file, filename); - } -} - -EntityClass *EntityClassFGD_findOrInsert(const char *name, bool has_brushes) -{ - ASSERT_NOTNULL(name); - - if (string_empty(name)) { - return g_EntityClassFGD_bad; - } - - EntityClasses::iterator i = g_EntityClassFGD_classes.find(name); - if (i != g_EntityClassFGD_classes.end() - //&& string_equal((*i).first, name) - ) { - return (*i).second; - } - - EntityClass *e = EntityClass_Create_Default(name, has_brushes); - return EntityClassFGD_insertUnique(e); -} - -const ListAttributeType *EntityClassFGD_findListType(const char *name) -{ - ListAttributeTypes::iterator i = g_listTypesFGD.find(name); - if (i != g_listTypesFGD.end()) { - return &(*i).second; - } - return 0; - -} - - -void EntityClassFGD_resolveInheritance(EntityClass *derivedClass) -{ - if (derivedClass->inheritanceResolved == false) { - derivedClass->inheritanceResolved = true; - for (StringList::iterator j = derivedClass->m_parent.begin(); j != derivedClass->m_parent.end(); ++j) { - BaseClasses::iterator i = g_EntityClassFGD_bases.find((*j).c_str()); - if (i == g_EntityClassFGD_bases.end()) { - globalErrorStream() << "failed to find entityDef " << makeQuoted((*j).c_str()) << " inherited by " - << makeQuoted(derivedClass->m_name.c_str()) << "\n"; - } else { - EntityClass *parentClass = (*i).second; - EntityClassFGD_resolveInheritance(parentClass); - if (!derivedClass->colorSpecified) { - derivedClass->colorSpecified = parentClass->colorSpecified; - derivedClass->color = parentClass->color; - } - if (!derivedClass->sizeSpecified) { - derivedClass->sizeSpecified = parentClass->sizeSpecified; - derivedClass->mins = parentClass->mins; - derivedClass->maxs = parentClass->maxs; - } - - for (EntityClassAttributes::iterator k = parentClass->m_attributes.begin(); - k != parentClass->m_attributes.end(); ++k) { - EntityClass_insertAttribute(*derivedClass, (*k).first.c_str(), (*k).second); - } - } - } - } -} - -class EntityClassFGD : public ModuleObserver { -std::size_t m_unrealised; -ModuleObservers m_observers; -public: -EntityClassFGD() : m_unrealised(3) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - StringOutputStream filename(256); - filename << GlobalRadiant().getGameToolsPath() << GlobalRadiant().getGameName() << "/entities.fgd"; - EntityClassFGD_loadFile(filename.c_str()); - - { - for (EntityClasses::iterator i = g_EntityClassFGD_classes.begin(); - i != g_EntityClassFGD_classes.end(); ++i) { - EntityClassFGD_resolveInheritance((*i).second); - if ((*i).second->fixedsize && string_empty((*i).second->m_modelpath.c_str())) { - if (!(*i).second->sizeSpecified) { - globalErrorStream() << "size not specified for entity class: " - << makeQuoted((*i).second->m_name.c_str()) << '\n'; - } - if (!(*i).second->colorSpecified) { - globalErrorStream() << "color not specified for entity class: " - << makeQuoted((*i).second->m_name.c_str()) << '\n'; - } - } - } - } - { - for (BaseClasses::iterator i = g_EntityClassFGD_bases.begin(); i != g_EntityClassFGD_bases.end(); ++i) { - eclass_capture_state((*i).second); - } - } - - m_observers.realise(); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - m_observers.unrealise(); - EntityClassFGD_clear(); - } -} - -void attach(ModuleObserver &observer) -{ - m_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - m_observers.detach(observer); -} -}; - -EntityClassFGD g_EntityClassFGD; - -void EntityClassFGD_attach(ModuleObserver &observer) -{ - g_EntityClassFGD.attach(observer); -} - -void EntityClassFGD_detach(ModuleObserver &observer) -{ - g_EntityClassFGD.detach(observer); -} - -void EntityClassFGD_realise() -{ - g_EntityClassFGD.realise(); -} - -void EntityClassFGD_unrealise() -{ - g_EntityClassFGD.unrealise(); -} - -void EntityClassFGD_construct() -{ - // start by creating the default unknown eclass - g_EntityClassFGD_bad = EClass_Create("UNKNOWN_CLASS", Vector3(0.0f, 0.5f, 0.0f), ""); - - EntityClassFGD_realise(); -} - -void EntityClassFGD_destroy() -{ - EntityClassFGD_unrealise(); - - g_EntityClassFGD_bad->free(g_EntityClassFGD_bad); -} - -class EntityClassFGDDependencies - : public GlobalFileSystemModuleRef, public GlobalShaderCacheModuleRef, public GlobalRadiantModuleRef { -}; - -class EntityClassFGDAPI { -EntityClassManager m_eclassmanager; -public: -typedef EntityClassManager Type; - -STRING_CONSTANT(Name, "halflife"); - -EntityClassFGDAPI() -{ - EntityClassFGD_construct(); - - m_eclassmanager.findOrInsert = &EntityClassFGD_findOrInsert; - m_eclassmanager.findListType = &EntityClassFGD_findListType; - m_eclassmanager.forEach = &EntityClassFGD_forEach; - m_eclassmanager.attach = &EntityClassFGD_attach; - m_eclassmanager.detach = &EntityClassFGD_detach; - m_eclassmanager.realise = &EntityClassFGD_realise; - m_eclassmanager.unrealise = &EntityClassFGD_unrealise; - - Radiant_attachGameToolsPathObserver(g_EntityClassFGD); - Radiant_attachGameNameObserver(g_EntityClassFGD); -} - -~EntityClassFGDAPI() -{ - Radiant_detachGameNameObserver(g_EntityClassFGD); - Radiant_detachGameToolsPathObserver(g_EntityClassFGD); - - EntityClassFGD_destroy(); -} - -EntityClassManager *getTable() -{ - return &m_eclassmanager; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule EntityClassFGDModule; -typedef Static StaticEntityClassFGDModule; -StaticRegisterModule staticRegisterEntityClassFGD(StaticEntityClassFGDModule::instance()); diff --git a/src/eclass_fgd.h b/src/eclass_fgd.h deleted file mode 100644 index 9eafc54..0000000 --- a/src/eclass_fgd.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_FGD_H ) -#define INCLUDED_ECLASS_FGD_H - -#endif diff --git a/src/eclass_xml.cpp b/src/eclass_xml.cpp deleted file mode 100644 index 54bcd3e..0000000 --- a/src/eclass_xml.cpp +++ /dev/null @@ -1,598 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -///\file -///\brief EntityClass plugin that supports the .ent xml entity-definition format. -/// -/// the .ent xml format expresses entity-definitions. -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// the attributes of an entity type are defined like this: -/// -/// <[name of attribute type] -/// key="[entity key name]" -/// name="[name shown in gui]" -/// value="[default entity key value]" -/// >[comment text shown in gui] -/// -/// each attribute type has a specialised attribute-editor GUI -/// -/// currently-supported attribute types: -/// -/// string a string -/// array an array of strings - value is a semi-colon-delimited string -/// integer an integer value -/// boolean an integer - shows as a checkbox - true = non-zero -/// integer2 two integer values -/// integer3 three integer values -/// real3 three floating-point values -/// angle specialisation of real - Yaw angle -/// direction specialisation of real - Yaw angle, -1 = down, -2 = up -/// angles specialisation of real3 - Pitch Yaw Roll -/// color specialisation of real3 - RGB floating-point colour -/// target a string that uniquely identifies an entity or group of entities -/// targetname a string that uniquely identifies an entity or group of entities -/// sound the VFS path to a sound file -/// texture the VFS path to a texture file or a shader name -/// model the VFS path to a model file -/// skin the VFS path to a skin file -/// -/// -/// flag attributes define a flag in the "spawnflags" key: -/// -/// [comment text shown in gui] -/// -/// the default value for a flag bit is always 0. -/// -/// -/// List attributes have a set of valid values. -/// Create new list attribute types like this: -/// -/// -/// -/// -/// -/// -/// these can then be used as attribute types. -/// -/// -/// An attribute definition should specify a default value that corresponds -/// with the default value given by the game. If the default value is not -/// specified in the attribute definition, it is assumed to be an empty string. -/// -/// If the currently-selected entity in Radiant does not specify a value for -/// the key of an attribute, the default value from the attribute-definition -/// will be displayed in the attribute-editor and used when visualising the -/// entity in the preview windows. E.g. the Doom3 "light" entity has a -/// "light_radius" key. Light entities without a "light_radius" key are -/// displayed in Doom3 with a radius of 300. The default value for the -/// "light_radius" attribute definition should be specified as "300 300 300". -/// - - - - -#include "eclass_xml.h" - -#include "ieclass.h" -#include "irender.h" -#include "ifilesystem.h" -#include "iarchive.h" - -#include "xml/xmlparser.h" -#include "generic/object.h" -#include "generic/reference.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" -#include "os/path.h" -#include "eclasslib.h" -#include "modulesystem/moduleregistry.h" -#include "stringio.h" - -#define PARSE_ERROR(elementName, name) makeQuoted( elementName ) << " is not a valid child of " << makeQuoted( name ) - -class IgnoreBreaks { -public: -const char *m_first; -const char *m_last; - -IgnoreBreaks(const char *first, const char *last) : m_first(first), m_last(last) -{ -} -}; - -template -TextOutputStreamType &ostream_write(TextOutputStreamType &ostream, const IgnoreBreaks &ignoreBreaks) -{ - for (const char *i = ignoreBreaks.m_first; i != ignoreBreaks.m_last; ++i) { - if (*i != '\n') { - ostream << *i; - } - } - return ostream; -} - -namespace { - -class TreeXMLImporter : public TextOutputStream { -public: -virtual TreeXMLImporter &pushElement(const XMLElement &element) = 0; - -virtual void popElement(const char *name) = 0; -}; - -template -class Storage { -char m_storage[sizeof(Type)]; -public: -Type &get() -{ - return *reinterpret_cast( m_storage ); -} - -const Type &get() const -{ - return *reinterpret_cast( m_storage ); -} -}; - -class BreakImporter : public TreeXMLImporter { -public: -BreakImporter(StringOutputStream &comment) -{ - comment << '\n'; -} - -static const char *name() -{ - return "n"; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE(PARSE_ERROR(element.name(), name())); - return *this; -} - -void popElement(const char *elementName) -{ - ERROR_MESSAGE(PARSE_ERROR(elementName, name())); -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -class AttributeImporter : public TreeXMLImporter { -StringOutputStream &m_comment; - -public: -AttributeImporter(StringOutputStream &comment, EntityClass *entityClass, const XMLElement &element) : m_comment( - comment) -{ - const char *type = element.name(); - const char *key = element.attribute("key"); - const char *name = element.attribute("name"); - const char *value = element.attribute("value"); - - ASSERT_MESSAGE(!string_empty(key), "key attribute not specified"); - ASSERT_MESSAGE(!string_empty(name), "name attribute not specified"); - - if (string_equal(type, "flag")) { - std::size_t bit = atoi(element.attribute("bit")); - ASSERT_MESSAGE(bit < MAX_FLAGS, "invalid flag bit"); - ASSERT_MESSAGE(string_empty(entityClass->flagnames[bit]), "non-unique flag bit"); - strcpy(entityClass->flagnames[bit], key); - } - - m_comment << key; - m_comment << " : "; - - EntityClass_insertAttribute(*entityClass, key, EntityClassAttribute(type, name, value)); -} - -~AttributeImporter() -{ -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE(PARSE_ERROR(element.name(), "attribute")); - return *this; -} - -void popElement(const char *elementName) -{ - ERROR_MESSAGE(PARSE_ERROR(elementName, "attribute")); -} - -std::size_t write(const char *data, std::size_t length) -{ - return m_comment.write(data, length); -} -}; - -bool attributeSupported(const char *name) -{ - return string_equal(name, "real") - || string_equal(name, "integer") - || string_equal(name, "boolean") - || string_equal(name, "string") - || string_equal(name, "array") - || string_equal(name, "flag") - || string_equal(name, "real3") - || string_equal(name, "integer3") - || string_equal(name, "direction") - || string_equal(name, "angle") - || string_equal(name, "angles") - || string_equal(name, "color") - || string_equal(name, "target") - || string_equal(name, "targetname") - || string_equal(name, "sound") - || string_equal(name, "texture") - || string_equal(name, "model") - || string_equal(name, "skin") - || string_equal(name, "integer2"); -} - -typedef std::map ListAttributeTypes; - -bool listAttributeSupported(ListAttributeTypes &listTypes, const char *name) -{ - return listTypes.find(name) != listTypes.end(); -} - - -class ClassImporter : public TreeXMLImporter { -EntityClassCollector &m_collector; -EntityClass *m_eclass; -StringOutputStream m_comment; -Storage m_attribute; -ListAttributeTypes &m_listTypes; - -public: -ClassImporter(EntityClassCollector &collector, ListAttributeTypes &listTypes, const XMLElement &element) - : m_collector(collector), m_listTypes(listTypes) -{ - m_eclass = Eclass_Alloc(); - m_eclass->free = &Eclass_Free; - - const char *name = element.attribute("name"); - ASSERT_MESSAGE(!string_empty(name), "name attribute not specified for class"); - m_eclass->m_name = name; - - const char *color = element.attribute("color"); - ASSERT_MESSAGE(!string_empty(name), "color attribute not specified for class " << name); - string_parse_vector3(color, m_eclass->color); - eclass_capture_state(m_eclass); - - const char *model = element.attribute("model"); - if (!string_empty(model)) { - StringOutputStream buffer(256); - buffer << PathCleaned(model); - m_eclass->m_modelpath = buffer.c_str(); - } - - const char *type = element.name(); - if (string_equal(type, "point")) { - const char *box = element.attribute("box"); - ASSERT_MESSAGE(!string_empty(box), "box attribute not found for class " << name); - m_eclass->fixedsize = true; - string_parse_vector(box, &m_eclass->mins.x(), &m_eclass->mins.x() + 6); - } -} - -~ClassImporter() -{ - m_eclass->m_comments = m_comment.c_str(); - m_collector.insert(m_eclass); - - for (ListAttributeTypes::iterator i = m_listTypes.begin(); i != m_listTypes.end(); ++i) { - m_collector.insert((*i).first.c_str(), (*i).second); - } -} - -static const char *name() -{ - return "class"; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - if (attributeSupported(element.name()) || listAttributeSupported(m_listTypes, element.name())) { - constructor(m_attribute.get(), makeReference(m_comment), m_eclass, element); - return m_attribute.get(); - } else { - ERROR_MESSAGE(PARSE_ERROR(element.name(), name())); - return *this; - } -} - -void popElement(const char *elementName) -{ - if (attributeSupported(elementName) || listAttributeSupported(m_listTypes, elementName)) { - destructor(m_attribute.get()); - } else { - ERROR_MESSAGE(PARSE_ERROR(elementName, name())); - } -} - -std::size_t write(const char *data, std::size_t length) -{ - return m_comment.write(data, length); -} -}; - -class ItemImporter : public TreeXMLImporter { -public: -ItemImporter(ListAttributeType &list, const XMLElement &element) -{ - const char *name = element.attribute("name"); - const char *value = element.attribute("value"); - list.push_back(name, value); -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - ERROR_MESSAGE(PARSE_ERROR(element.name(), "item")); - return *this; -} - -void popElement(const char *elementName) -{ - ERROR_MESSAGE(PARSE_ERROR(elementName, "item")); -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -bool isItem(const char *name) -{ - return string_equal(name, "item"); -} - -class ListAttributeImporter : public TreeXMLImporter { -ListAttributeType *m_listType; -Storage m_item; -public: -ListAttributeImporter(ListAttributeTypes &listTypes, const XMLElement &element) -{ - const char *name = element.attribute("name"); - m_listType = &listTypes[name]; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - if (isItem(element.name())) { - constructor(m_item.get(), makeReference(*m_listType), element); - return m_item.get(); - } else { - ERROR_MESSAGE(PARSE_ERROR(element.name(), "list")); - return *this; - } -} - -void popElement(const char *elementName) -{ - if (isItem(elementName)) { - destructor(m_item.get()); - } else { - ERROR_MESSAGE(PARSE_ERROR(elementName, "list")); - } -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -bool classSupported(const char *name) -{ - return string_equal(name, "group") - || string_equal(name, "point"); -} - -bool listSupported(const char *name) -{ - return string_equal(name, "list"); -} - -class ClassesImporter : public TreeXMLImporter { -EntityClassCollector &m_collector; -Storage m_class; -Storage m_list; -ListAttributeTypes m_listTypes; - -public: -ClassesImporter(EntityClassCollector &collector) : m_collector(collector) -{ -} - -static const char *name() -{ - return "classes"; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - if (classSupported(element.name())) { - constructor(m_class.get(), makeReference(m_collector), makeReference(m_listTypes), element); - return m_class.get(); - } else if (listSupported(element.name())) { - constructor(m_list.get(), makeReference(m_listTypes), element); - return m_list.get(); - } else { - ERROR_MESSAGE(PARSE_ERROR(element.name(), name())); - return *this; - } -} - -void popElement(const char *elementName) -{ - if (classSupported(elementName)) { - destructor(m_class.get()); - } else if (listSupported(elementName)) { - destructor(m_list.get()); - } else { - ERROR_MESSAGE(PARSE_ERROR(elementName, name())); - } -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -class EclassXMLImporter : public TreeXMLImporter { -EntityClassCollector &m_collector; -Storage m_classes; - -public: -EclassXMLImporter(EntityClassCollector &collector) : m_collector(collector) -{ -} - -static const char *name() -{ - return "classes"; -} - -TreeXMLImporter &pushElement(const XMLElement &element) -{ - if (string_equal(element.name(), ClassesImporter::name())) { - constructor(m_classes.get(), makeReference(m_collector)); - return m_classes.get(); - } else { - ERROR_MESSAGE(PARSE_ERROR(element.name(), name())); - return *this; - } -} - -void popElement(const char *elementName) -{ - if (string_equal(elementName, ClassesImporter::name())) { - destructor(m_classes.get()); - } else { - ERROR_MESSAGE(PARSE_ERROR(elementName, name())); - } -} - -std::size_t write(const char *data, std::size_t length) -{ - return length; -} -}; - -class TreeXMLImporterStack : public XMLImporter { -std::vector > m_importers; -public: -TreeXMLImporterStack(TreeXMLImporter &importer) -{ - m_importers.push_back(makeReference(importer)); -} - -void pushElement(const XMLElement &element) -{ - m_importers.push_back(makeReference(m_importers.back().get().pushElement(element))); -} - -void popElement(const char *name) -{ - m_importers.pop_back(); - m_importers.back().get().popElement(name); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return m_importers.back().get().write(buffer, length); -} -}; - - -const char *GetExtension() -{ - return "ent"; -} - -void ScanFile(EntityClassCollector &collector, const char *filename) -{ - TextFileInputStream inputFile(filename); - if (!inputFile.failed()) { - XMLStreamParser parser(inputFile); - - EclassXMLImporter importer(collector); - TreeXMLImporterStack stack(importer); - parser.exportXML(stack); - } -} - - -} - -#include "modulesystem/singletonmodule.h" - -class EntityClassXMLDependencies : public GlobalFileSystemModuleRef, public GlobalShaderCacheModuleRef { -}; - -class EclassXMLAPI { -EntityClassScanner m_eclassxml; -public: -typedef EntityClassScanner Type; - -STRING_CONSTANT(Name, "xml"); - -EclassXMLAPI() -{ - m_eclassxml.scanFile = &ScanFile; - m_eclassxml.getExtension = &GetExtension; -} - -EntityClassScanner *getTable() -{ - return &m_eclassxml; -} -}; - -typedef SingletonModule EclassXMLModule; -typedef Static StaticEclassXMLModule; -StaticRegisterModule staticRegisterEclassXML(StaticEclassXMLModule::instance()); diff --git a/src/eclass_xml.h b/src/eclass_xml.h deleted file mode 100644 index 9b6f9dd..0000000 --- a/src/eclass_xml.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ECLASS_XML_H ) -#define INCLUDED_ECLASS_XML_H - -#endif diff --git a/src/entity.cpp b/src/entity.cpp deleted file mode 100644 index 5c8342b..0000000 --- a/src/entity.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "entity.h" - -#include "ientity.h" -#include "iselection.h" -#include "imodel.h" -#include "ifilesystem.h" -#include "iundo.h" -#include "editable.h" - -#include "eclasslib.h" -#include "scenelib.h" -#include "os/path.h" -#include "os/file.h" -#include "stream/stringstream.h" -#include "stringio.h" - -#include "gtkutil/filechooser.h" -#include "gtkmisc.h" -#include "select.h" -#include "map.h" -#include "preferences.h" -#include "gtkdlgs.h" -#include "mainframe.h" -#include "qe3.h" -#include "commands.h" - -#include "uilib/uilib.h" - -struct entity_globals_t { - Vector3 color_entity; - - entity_globals_t() : - color_entity(0.0f, 0.0f, 0.0f) - { - } -}; - -entity_globals_t g_entity_globals; - -class EntitySetKeyValueSelected : public scene::Graph::Walker { -const char *m_key; -const char *m_value; -public: -EntitySetKeyValueSelected(const char *key, const char *value) - : m_key(key), m_value(value) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && (instance.childSelected() || Instance_getSelectable(instance)->isSelected())) { - entity->setKeyValue(m_key, m_value); - } -} -}; - -class EntitySetClassnameSelected : public scene::Graph::Walker { -const char *m_classname; -public: -EntitySetClassnameSelected(const char *classname) - : m_classname(classname) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && (instance.childSelected() || Instance_getSelectable(instance)->isSelected())) { - NodeSmartReference node(GlobalEntityCreator().createEntity( - GlobalEntityClassManager().findOrInsert(m_classname, node_is_group(path.top())))); - - EntityCopyingVisitor visitor(*Node_getEntity(node)); - - entity->forEachKeyValue(visitor); - - NodeSmartReference child(path.top().get()); - NodeSmartReference parent(path.parent().get()); - Node_getTraversable(parent)->erase(child); - if (Node_getTraversable(child) != 0 - && Node_getTraversable(node) != 0 - && node_is_group(node)) { - parentBrushes(child, node); - } - Node_getTraversable(parent)->insert(node); - } -} -}; - -void Scene_EntitySetKeyValue_Selected(const char *key, const char *value) -{ - GlobalSceneGraph().traverse(EntitySetKeyValueSelected(key, value)); -} - -void Scene_EntitySetClassname_Selected(const char *classname) -{ - GlobalSceneGraph().traverse(EntitySetClassnameSelected(classname)); -} - -/* to worldspawn */ -void Entity_ungroupSelected() -{ - if (GlobalSelectionSystem().countSelected() < 1) { - return; - } - - UndoableCommand undo("ungroupSelectedEntities"); - - /* to auto-select */ - /*scene::Path entitypath(makeReference(GlobalSceneGraph().root())); - scene::Instance& einstance = findInstance(entitypath);*/ - - while (GlobalSelectionSystem().countSelected()) { - scene::Path world_path(makeReference(GlobalSceneGraph().root())); - world_path.push(makeReference(Map_FindOrInsertWorldspawn(g_map))); - scene::Instance &instance = GlobalSelectionSystem().ultimateSelected(); - scene::Path path = instance.path(); - - /* remove it from the path if its not an ent? */ - if (!Node_isEntity(path.top())) { - path.pop(); - } - - /* we'll cause a crash otherwise */ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 && entity->getEntityClass().fixedsize) { - /* Unselect us */ - Instance_setSelected(instance, false); - continue; - } - - /* this will sadly unselect anything it touches (merge to world) */ - if (entity != 0 && node_is_group(path.top())) { - if (world_path.top().get_pointer() != path.top().get_pointer()) { - parentBrushes(path.top(), world_path.top()); - Path_deleteTop(path); - } - } - } - - /*Scene_forEachChildSelectable(SelectableSetSelected(true), einstance.path());*/ -} - - -class EntityFindSelected : public scene::Graph::Walker { -public: -mutable const scene::Path *groupPath; -mutable scene::Instance *groupInstance; - -EntityFindSelected() : groupPath(0), groupInstance(0) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && Instance_getSelectable(instance)->isSelected() - && node_is_group(path.top()) - && !groupPath) { - groupPath = &path; - groupInstance = &instance; - } -} -}; - -class EntityGroupSelected : public scene::Graph::Walker { -NodeSmartReference group, worldspawn; -//typedef std::pair DeletionPair; -//Stack deleteme; -public: -EntityGroupSelected(const scene::Path &p) : group(p.top().get()), worldspawn(Map_FindOrInsertWorldspawn(g_map)) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - - if (selectable && selectable->isSelected()) { - Entity *entity = Node_getEntity(path.top()); - if (entity == 0 && Node_isPrimitive(path.top())) { - NodeSmartReference child(path.top().get()); - NodeSmartReference parent(path.parent().get()); - - if (path.size() >= 3 && parent != worldspawn) { - NodeSmartReference parentparent(path[path.size() - 3].get()); - - Node_getTraversable(parent)->erase(child); - Node_getTraversable(group)->insert(child); - - if (Node_getTraversable(parent)->empty()) { - //deleteme.push(DeletionPair(parentparent, parent)); - Node_getTraversable(parentparent)->erase(parent); - } - } else { - Node_getTraversable(parent)->erase(child); - Node_getTraversable(group)->insert(child); - } - } - } -} -}; - -void Scene_DeleteEmpty(); -void Entity_groupSelected() -{ - if (GlobalSelectionSystem().countSelected() < 1) { - return; - } - - UndoableCommand undo("groupSelectedEntities"); - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - - Entity *entity = Node_getEntity(path.top()); - - if (entity != 0) { - const char *strClassname = entity->getKeyValue("classname"); - if (!string_empty(strClassname)) { - Entity_createFromSelection(strClassname, g_vector3_identity); - } - } -} - -void Entity_groupMake() -{ - if (GlobalSelectionSystem().countSelected() < 1) { - return; - } - - UndoableCommand undo("entityCreate -class func_group" ); - Entity_createFromSelection("func_group", g_vector3_identity); - /*Scene_DeleteEmpty();*/ -} - - -void Entity_connectSelected() -{ - if (GlobalSelectionSystem().countSelected() == 2) { - GlobalEntityCreator().connectEntities( - GlobalSelectionSystem().penultimateSelected().path(), - GlobalSelectionSystem().ultimateSelected().path(), - 0 - ); - } else { - globalErrorStream() << "entityConnectSelected: exactly two instances must be selected\n"; - } -} - -void Entity_killconnectSelected() -{ - if (GlobalSelectionSystem().countSelected() == 2) { - GlobalEntityCreator().connectEntities( - GlobalSelectionSystem().penultimateSelected().path(), - GlobalSelectionSystem().ultimateSelected().path(), - 1 - ); - } else { - globalErrorStream() << "entityKillConnectSelected: exactly two instances must be selected\n"; - } -} - -AABB Doom3Light_getBounds(const AABB &workzone) -{ - AABB aabb(workzone); - - Vector3 defaultRadius(300, 300, 300); - if (!string_parse_vector3( - EntityClass_valueForKey(*GlobalEntityClassManager().findOrInsert("light", false), "light_radius"), - defaultRadius)) { - globalErrorStream() << "Doom3Light_getBounds: failed to parse default light radius\n"; - } - - if (aabb.extents[0] == 0) { - aabb.extents[0] = defaultRadius[0]; - } - if (aabb.extents[1] == 0) { - aabb.extents[1] = defaultRadius[1]; - } - if (aabb.extents[2] == 0) { - aabb.extents[2] = defaultRadius[2]; - } - - if (aabb_valid(aabb)) { - return aabb; - } - return AABB(Vector3(0, 0, 0), Vector3(64, 64, 64)); -} - -int g_iLastLightIntensity; - -bool -Entity_isModelEntity(const char *name) -{ - if (string_equal_nocase(name, "prop_static")) - return true; - else if (string_equal_nocase(name, "prop_dynamic")) - return true; - - return false; -} - -void Entity_createFromSelection(const char *name, const Vector3 &origin) -{ - EntityClass *entityClass = GlobalEntityClassManager().findOrInsert(name, true); - - bool isModel = Entity_isModelEntity(name); - bool brushesSelected = Scene_countSelectedBrushes(GlobalSceneGraph()) != 0; - - if (!(entityClass->fixedsize || isModel) && !brushesSelected) { - globalErrorStream() << "failed to create a group entity - no brushes are selected\n"; - return; - } - - AABB workzone(aabb_for_minmax(Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max)); - - /* this is where ghost entities happen */ - NodeSmartReference node(GlobalEntityCreator().createEntity(entityClass)); - Node_getTraversable(GlobalSceneGraph().root())->insert(node); - scene::Path entitypath(makeReference(GlobalSceneGraph().root())); - entitypath.push(makeReference(node.get())); - scene::Instance& instance = findInstance(entitypath); - - if (entityClass->fixedsize) - { - Select_Delete(); - Transformable* transform = Instance_getTransformable(instance); - if(transform != 0) - { - transform->setType(TRANSFORM_PRIMITIVE); - transform->setTranslation(origin); - transform->freezeTransform(); - } - - GlobalSelectionSystem().setSelectedAll(false); - Instance_setSelected(instance, true); - } else { - Scene_parentSelectedBrushesToEntity(GlobalSceneGraph(), node); - Scene_forEachChildSelectable(SelectableSetSelected(true), instance.path()); - Scene_DeleteEmpty(); - } - - // tweaking: when right clic dropping a light entity, ask for light value in a custom dialog box - // see SF bug 105383 - - if (g_pGameDescription->mGameType == "hl") { - // FIXME - Hydra: really we need a combined light AND color dialog for halflife. - if (string_equal_nocase(name, "light") - || string_equal_nocase(name, "light_environment") - || string_equal_nocase(name, "light_spot")) { - int intensity = g_iLastLightIntensity; - - if (DoLightIntensityDlg(&intensity) == eIDOK) { - g_iLastLightIntensity = intensity; - char buf[30]; - sprintf(buf, "255 255 255 %d", intensity); - Node_getEntity(node)->setKeyValue("_light", buf); - } - } - } else if (string_equal_nocase(name, "light")) { - if (g_pGameDescription->mGameType != "doom3") { - int intensity = g_iLastLightIntensity; - - if (DoLightIntensityDlg(&intensity) == eIDOK) { - g_iLastLightIntensity = intensity; - char buf[10]; - sprintf(buf, "%d", intensity); - Node_getEntity(node)->setKeyValue("light", buf); - } - } else if (brushesSelected) { // use workzone to set light position/size for doom3 lights, if there are brushes selected - AABB bounds(Doom3Light_getBounds(workzone)); - StringOutputStream key(64); - key << bounds.origin[0] << " " << bounds.origin[1] << " " << bounds.origin[2]; - Node_getEntity(node)->setKeyValue("origin", key.c_str()); - key.clear(); - key << bounds.extents[0] << " " << bounds.extents[1] << " " << bounds.extents[2]; - Node_getEntity(node)->setKeyValue("light_radius", key.c_str()); - } - } - - if (isModel) { - const char *model = misc_model_dialog(MainFrame_getWindow()); - if (model != 0) { - Node_getEntity(node)->setKeyValue("model", model); - } - } -} - -#if 0 -bool DoNormalisedColor( Vector3& color ){ - if ( !color_dialog( MainFrame_getWindow( ), color ) ) { - return false; - } - /* - ** scale colors so that at least one component is at 1.0F - */ - - float largest = 0.0F; - - if ( color[0] > largest ) { - largest = color[0]; - } - if ( color[1] > largest ) { - largest = color[1]; - } - if ( color[2] > largest ) { - largest = color[2]; - } - - if ( largest == 0.0F ) { - color[0] = 1.0F; - color[1] = 1.0F; - color[2] = 1.0F; - } - else - { - float scaler = 1.0F / largest; - - color[0] *= scaler; - color[1] *= scaler; - color[2] *= scaler; - } - - return true; -} -#endif - -void NormalizeColor(Vector3 &color) -{ - // scale colors so that at least one component is at 1.0F - - float largest = 0.0F; - - if (color[0] > largest) { - largest = color[0]; - } - if (color[1] > largest) { - largest = color[1]; - } - if (color[2] > largest) { - largest = color[2]; - } - - if (largest == 0.0F) { - color[0] = 1.0F; - color[1] = 1.0F; - color[2] = 1.0F; - } else { - float scaler = 1.0F / largest; - - color[0] *= scaler; - color[1] *= scaler; - color[2] *= scaler; - } -} - -void Entity_normalizeColor() -{ - if (GlobalSelectionSystem().countSelected() != 0) { - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - Entity *entity = Node_getEntity(path.top()); - - if (entity != 0) { - const char *strColor = entity->getKeyValue("_color"); - if (!string_empty(strColor)) { - Vector3 rgb; - if (string_parse_vector3(strColor, rgb)) { - g_entity_globals.color_entity = rgb; - NormalizeColor(g_entity_globals.color_entity); - - char buffer[128]; - sprintf(buffer, "%g %g %g", g_entity_globals.color_entity[0], - g_entity_globals.color_entity[1], - g_entity_globals.color_entity[2]); - - Scene_EntitySetKeyValue_Selected("_color", buffer); - } - } - } - } -} - -void Entity_setColour() -{ - if (GlobalSelectionSystem().countSelected() != 0) { - bool normalize = false; - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - Entity *entity = Node_getEntity(path.top()); - - if (entity != 0) { - const char *strColor = entity->getKeyValue("_color"); - if (!string_empty(strColor)) { - Vector3 rgb; - if (string_parse_vector3(strColor, rgb)) { - g_entity_globals.color_entity = rgb; - } - } - - if (color_dialog(MainFrame_getWindow(), g_entity_globals.color_entity)) { - if (normalize) { - NormalizeColor(g_entity_globals.color_entity); - } - - char buffer[128]; - sprintf(buffer, "%g %g %g", g_entity_globals.color_entity[0], - g_entity_globals.color_entity[1], - g_entity_globals.color_entity[2]); - - Scene_EntitySetKeyValue_Selected("_color", buffer); - } - } - } -} - -const char *misc_model_dialog(ui::Widget parent) -{ - StringOutputStream buffer(1024); - - buffer << g_qeglobals.m_userGamePath.c_str() << "models/"; - - if (!file_readable(buffer.c_str())) { - // just go to fsmain - buffer.clear(); - buffer << g_qeglobals.m_userGamePath.c_str() << "/"; - } - - const char *filename = parent.file_dialog(TRUE, "Choose Model", buffer.c_str(), ModelLoader::Name()); - if (filename != 0) { - // use VFS to get the correct relative path - const char *relative = path_make_relative(filename, GlobalFileSystem().findRoot(filename)); - if (relative == filename) { - globalOutputStream() << "WARNING: could not extract the relative path, using full path instead\n"; - } - return relative; - } - return 0; -} - -struct LightRadii { - static void Export(const EntityCreator &self, const Callback &returnz) - { - returnz(self.getLightRadii()); - } - - static void Import(EntityCreator &self, bool value) - { - self.setLightRadii(value); - } -}; - -void Entity_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox( - "Show", "Light Radii", - make_property(GlobalEntityCreator()) - ); -} - -void Entity_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Entities", "Entity Display Preferences")); - Entity_constructPreferences(page); -} - -void Entity_registerPreferencesPage() -{ - PreferencesDialog_addDisplayPage(makeCallbackF(Entity_constructPage)); -} - - -void Entity_constructMenu(ui::Menu menu) -{ - create_menu_item_with_mnemonic(menu, "_To Worldspawn", "UngroupSelection"); - create_menu_item_with_mnemonic(menu, "_Regroup", "GroupSelection"); - create_menu_item_with_mnemonic(menu, "_Connect", "ConnectSelection"); - create_menu_item_with_mnemonic(menu, "_KillConnect", "KillConnectSelection"); - create_menu_item_with_mnemonic(menu, "_Select Color...", "EntityColor"); - create_menu_item_with_mnemonic(menu, "_Normalize Color...", "NormalizeColor"); -} - - -#include "preferencesystem.h" -#include "stringio.h" - -void Entity_Construct() -{ - GlobalCommands_insert("EntityColor", makeCallbackF(Entity_setColour), Accelerator('K')); - GlobalCommands_insert("NormalizeColor", makeCallbackF(Entity_normalizeColor)); - GlobalCommands_insert("ConnectSelection", makeCallbackF(Entity_connectSelected), - Accelerator('K', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("KillConnectSelection", makeCallbackF(Entity_killconnectSelected), - Accelerator('K', (GdkModifierType) (GDK_SHIFT_MASK))); - GlobalCommands_insert("GroupSelection", makeCallbackF(Entity_groupSelected)); - GlobalCommands_insert("UngroupSelection", makeCallbackF(Entity_ungroupSelected)); - GlobalCommands_insert("CreateFuncGroup", makeCallbackF(Entity_groupMake)); - - GlobalPreferenceSystem().registerPreference("SI_Colors5", make_property_string(g_entity_globals.color_entity)); - GlobalPreferenceSystem().registerPreference("LastLightIntensity", make_property_string(g_iLastLightIntensity)); - - Entity_registerPreferencesPage(); -} - -void Entity_Destroy() -{ -} diff --git a/src/entity.h b/src/entity.h deleted file mode 100644 index a2a9f75..0000000 --- a/src/entity.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ENTITY_H ) -#define INCLUDED_ENTITY_H - -#include - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -void Entity_createFromSelection(const char *name, const Vector3 &origin); - -void Scene_EntitySetKeyValue_Selected(const char *key, const char *value); - -void Scene_EntitySetClassname_Selected(const char *classname); - - -const char *misc_model_dialog(ui::Widget parent); - -void Entity_constructMenu(ui::Menu menu); - -void Entity_Construct(); - -void Entity_Destroy(); - -#endif diff --git a/src/entityinspector.cpp b/src/entityinspector.cpp deleted file mode 100644 index d398d73..0000000 --- a/src/entityinspector.cpp +++ /dev/null @@ -1,1756 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "entityinspector.h" - -#include "debugging/debugging.h" -#include - -#include "ientity.h" -#include "ifilesystem.h" -#include "imodel.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "iundo.h" - -#include -#include -#include -#include - - -#include "os/path.h" -#include "eclasslib.h" -#include "scenelib.h" -#include "generic/callback.h" -#include "os/file.h" -#include "stream/stringstream.h" -#include "moduleobserver.h" -#include "convert.h" -#include "stringio.h" - -#include "gtkutil/accelerator.h" -#include "gtkutil/dialog.h" -#include "gtkutil/filechooser.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/nonmodal.h" -#include "gtkutil/button.h" -#include "gtkutil/entry.h" -#include "gtkutil/container.h" - -#include "qe3.h" -#include "gtkmisc.h" -#include "gtkdlgs.h" -#include "entity.h" -#include "mainframe.h" -#include "textureentry.h" -#include "groupdialog.h" - -ui::Entry numeric_entry_new() -{ - auto entry = ui::Entry(ui::New); - entry.show(); - entry.dimensions(64, -1); - return entry; -} - -namespace { -typedef std::map KeyValues; -KeyValues g_selectedKeyValues; -KeyValues g_selectedDefaultKeyValues; -} - -const char *SelectedEntity_getValueForKey(const char *key) -{ - { - KeyValues::const_iterator i = g_selectedKeyValues.find(key); - if (i != g_selectedKeyValues.end()) { - return (*i).second.c_str(); - } - } - { - KeyValues::const_iterator i = g_selectedDefaultKeyValues.find(key); - if (i != g_selectedDefaultKeyValues.end()) { - return (*i).second.c_str(); - } - } - return ""; -} - -void Scene_EntitySetKeyValue_Selected_Undoable(const char *key, const char *value) -{ - StringOutputStream command(256); - command << "entitySetKeyValue -key " << makeQuoted(key) << " -value " << makeQuoted(value); - UndoableCommand undo(command.c_str()); - Scene_EntitySetKeyValue_Selected(key, value); -} - -class EntityAttribute { -public: -virtual ~EntityAttribute() = default; - -virtual ui::Widget getWidget() const = 0; - -virtual void update() = 0; - -virtual void release() = 0; -}; - -class BooleanAttribute : public EntityAttribute { -CopiedString m_key; -ui::CheckButton m_check; - -static gboolean toggled(ui::Widget widget, BooleanAttribute *self) -{ - self->apply(); - return FALSE; -} - -public: -BooleanAttribute(const char *key) : - m_key(key), - m_check(ui::null) -{ - auto check = ui::CheckButton(ui::New); - check.show(); - - m_check = check; - - guint handler = check.connect("toggled", G_CALLBACK(toggled), this); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer(handler)); - - update(); -} - -ui::Widget getWidget() const -{ - return m_check; -} - -void release() -{ - delete this; -} - -void apply() -{ - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), m_check.active() ? "1" : "0"); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - toggle_button_set_active_no_signal(m_check, atoi(value) != 0); - } else { - toggle_button_set_active_no_signal(m_check, false); - } -} - -typedef MemberCaller UpdateCaller; -}; - - -class StringAttribute : public EntityAttribute { -CopiedString m_key; -ui::Entry m_entry; -NonModalEntry m_nonModal; -public: -StringAttribute(const char *key) : - m_key(key), - m_entry(ui::null), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - auto entry = ui::Entry(ui::New); - entry.show(); - entry.dimensions(50, -1); - - m_entry = entry; - m_nonModal.connect(m_entry); -} - -ui::Widget getWidget() const -{ - return m_entry; -} - -ui::Entry getEntry() const -{ - return m_entry; -} - -void release() -{ - delete this; -} - -void apply() -{ - StringOutputStream value(64); - value << m_entry.text(); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), value.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream value(64); - value << SelectedEntity_getValueForKey(m_key.c_str()); - m_entry.text(value.c_str()); -} - -typedef MemberCaller UpdateCaller; -}; - -class ShaderAttribute : public StringAttribute { -public: -ShaderAttribute(const char *key) : StringAttribute(key) -{ - GlobalShaderEntryCompletion::instance().connect(StringAttribute::getEntry()); -} -}; - - -class ModelAttribute : public EntityAttribute { -CopiedString m_key; -BrowsedPathEntry m_entry; -NonModalEntry m_nonModal; -public: -ModelAttribute(const char *key) : - m_key(key), - m_entry(BrowseCaller(*this)), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - m_nonModal.connect(m_entry.m_entry.m_entry); -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return m_entry.m_entry.m_frame; -} - -void apply() -{ - StringOutputStream value(64); - value << m_entry.m_entry.m_entry.text(); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), value.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream value(64); - value << SelectedEntity_getValueForKey(m_key.c_str()); - m_entry.m_entry.m_entry.text(value.c_str()); -} - -typedef MemberCaller UpdateCaller; - -void browse(const BrowsedPathEntry::SetPathCallback &setPath) -{ - const char *filename = misc_model_dialog(m_entry.m_entry.m_frame.window()); - - if (filename != 0) { - setPath(filename); - apply(); - } -} - -typedef MemberCaller BrowseCaller; -}; - -const char *browse_sound(ui::Widget parent) -{ - StringOutputStream buffer(1024); - - buffer << g_qeglobals.m_userGamePath.c_str() << "sound/"; - - if (!file_readable(buffer.c_str())) { - // just go to fsmain - buffer.clear(); - buffer << g_qeglobals.m_userGamePath.c_str() << "/"; - } - - const char *filename = parent.file_dialog(TRUE, "Open Wav File", buffer.c_str(), "sound"); - if (filename != 0) { - const char *relative = path_make_relative(filename, GlobalFileSystem().findRoot(filename)); - if (relative == filename) { - globalOutputStream() << "WARNING: could not extract the relative path, using full path instead\n"; - } - return relative; - } - return filename; -} - -class SoundAttribute : public EntityAttribute { -CopiedString m_key; -BrowsedPathEntry m_entry; -NonModalEntry m_nonModal; -public: -SoundAttribute(const char *key) : - m_key(key), - m_entry(BrowseCaller(*this)), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - m_nonModal.connect(m_entry.m_entry.m_entry); -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_entry.m_entry.m_frame); -} - -void apply() -{ - StringOutputStream value(64); - value << m_entry.m_entry.m_entry.text(); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), value.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream value(64); - value << SelectedEntity_getValueForKey(m_key.c_str()); - m_entry.m_entry.m_entry.text(value.c_str()); -} - -typedef MemberCaller UpdateCaller; - -void browse(const BrowsedPathEntry::SetPathCallback &setPath) -{ - const char *filename = browse_sound(m_entry.m_entry.m_frame.window()); - - if (filename != 0) { - setPath(filename); - apply(); - } -} - -typedef MemberCaller BrowseCaller; -}; - -inline double angle_normalised(double angle) -{ - return float_mod(angle, 360.0); -} - -class AngleAttribute : public EntityAttribute { -CopiedString m_key; -ui::Entry m_entry; -NonModalEntry m_nonModal; -public: -AngleAttribute(const char *key) : - m_key(key), - m_entry(ui::null), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - auto entry = numeric_entry_new(); - m_entry = entry; - m_nonModal.connect(m_entry); -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_entry); -} - -void apply() -{ - StringOutputStream angle(32); - angle << angle_normalised(entry_get_float(m_entry)); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), angle.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - StringOutputStream angle(32); - angle << angle_normalised(atof(value)); - m_entry.text(angle.c_str()); - } else { - m_entry.text("0"); - } -} - -typedef MemberCaller UpdateCaller; -}; - -namespace { -typedef const char *String; -const String buttons[] = {"up", "down", "z-axis"}; -} - -class DirectionAttribute : public EntityAttribute { -CopiedString m_key; -ui::Entry m_entry; -NonModalEntry m_nonModal; -RadioHBox m_radio; -NonModalRadio m_nonModalRadio; -ui::HBox m_hbox{ui::null}; -public: -DirectionAttribute(const char *key) : - m_key(key), - m_entry(ui::null), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)), - m_radio(RadioHBox_new(STRING_ARRAY_RANGE(buttons))), - m_nonModalRadio(ApplyRadioCaller(*this)) -{ - auto entry = numeric_entry_new(); - m_entry = entry; - m_nonModal.connect(m_entry); - - m_nonModalRadio.connect(m_radio.m_radio); - - m_hbox = ui::HBox(FALSE, 4); - m_hbox.show(); - - m_hbox.pack_start(m_radio.m_hbox, TRUE, TRUE, 0); - m_hbox.pack_start(m_entry, TRUE, TRUE, 0); -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_hbox); -} - -void apply() -{ - StringOutputStream angle(32); - angle << angle_normalised(entry_get_float(m_entry)); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), angle.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - float f = float(atof(value)); - if (f == -1) { - gtk_widget_set_sensitive(m_entry, FALSE); - radio_button_set_active_no_signal(m_radio.m_radio, 0); - m_entry.text(""); - } else if (f == -2) { - gtk_widget_set_sensitive(m_entry, FALSE); - radio_button_set_active_no_signal(m_radio.m_radio, 1); - m_entry.text(""); - } else { - gtk_widget_set_sensitive(m_entry, TRUE); - radio_button_set_active_no_signal(m_radio.m_radio, 2); - StringOutputStream angle(32); - angle << angle_normalised(f); - m_entry.text(angle.c_str()); - } - } else { - m_entry.text("0"); - } -} - -typedef MemberCaller UpdateCaller; - -void applyRadio() -{ - int index = radio_button_get_active(m_radio.m_radio); - if (index == 0) { - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), "-1"); - } else if (index == 1) { - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), "-2"); - } else if (index == 2) { - apply(); - } -} - -typedef MemberCaller ApplyRadioCaller; -}; - - -class AnglesEntry { -public: -ui::Entry m_roll; -ui::Entry m_pitch; -ui::Entry m_yaw; - -AnglesEntry() : m_roll(ui::null), m_pitch(ui::null), m_yaw(ui::null) -{ -} -}; - -typedef BasicVector3 DoubleVector3; - -class AnglesAttribute : public EntityAttribute { -CopiedString m_key; -AnglesEntry m_angles; -NonModalEntry m_nonModal; -ui::HBox m_hbox; -public: -AnglesAttribute(const char *key) : - m_key(key), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)), - m_hbox(ui::HBox(TRUE, 4)) -{ - m_hbox.show(); - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_angles.m_pitch = entry; - m_nonModal.connect(m_angles.m_pitch); - } - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_angles.m_yaw = entry; - m_nonModal.connect(m_angles.m_yaw); - } - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_angles.m_roll = entry; - m_nonModal.connect(m_angles.m_roll); - } -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_hbox); -} - -void apply() -{ - StringOutputStream angles(64); - angles << angle_normalised(entry_get_float(m_angles.m_pitch)) - << " " << angle_normalised(entry_get_float(m_angles.m_yaw)) - << " " << angle_normalised(entry_get_float(m_angles.m_roll)); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), angles.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream angle(32); - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - DoubleVector3 pitch_yaw_roll; - if (!string_parse_vector3(value, pitch_yaw_roll)) { - pitch_yaw_roll = DoubleVector3(0, 0, 0); - } - - angle << angle_normalised(pitch_yaw_roll.x()); - m_angles.m_pitch.text(angle.c_str()); - angle.clear(); - - angle << angle_normalised(pitch_yaw_roll.y()); - m_angles.m_yaw.text(angle.c_str()); - angle.clear(); - - angle << angle_normalised(pitch_yaw_roll.z()); - m_angles.m_roll.text(angle.c_str()); - angle.clear(); - } else { - m_angles.m_pitch.text("0"); - m_angles.m_yaw.text("0"); - m_angles.m_roll.text("0"); - } -} - -typedef MemberCaller UpdateCaller; -}; - -class Vector3Entry { -public: -ui::Entry m_x; -ui::Entry m_y; -ui::Entry m_z; - -Vector3Entry() : m_x(ui::null), m_y(ui::null), m_z(ui::null) -{ -} -}; - -class Vector3Attribute : public EntityAttribute { -CopiedString m_key; -Vector3Entry m_vector3; -NonModalEntry m_nonModal; -ui::Box m_hbox{ui::null}; -public: -Vector3Attribute(const char *key) : - m_key(key), - m_nonModal(ApplyCaller(*this), UpdateCaller(*this)) -{ - m_hbox = ui::HBox(TRUE, 4); - m_hbox.show(); - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_vector3.m_x = entry; - m_nonModal.connect(m_vector3.m_x); - } - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_vector3.m_y = entry; - m_nonModal.connect(m_vector3.m_y); - } - { - auto entry = numeric_entry_new(); - m_hbox.pack_start(entry, TRUE, TRUE, 0); - m_vector3.m_z = entry; - m_nonModal.connect(m_vector3.m_z); - } -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_hbox); -} - -void apply() -{ - StringOutputStream vector3(64); - vector3 << entry_get_float(m_vector3.m_x) - << " " << entry_get_float(m_vector3.m_y) - << " " << entry_get_float(m_vector3.m_z); - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), vector3.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - StringOutputStream buffer(32); - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - if (!string_empty(value)) { - DoubleVector3 x_y_z; - if (!string_parse_vector3(value, x_y_z)) { - x_y_z = DoubleVector3(0, 0, 0); - } - - buffer << x_y_z.x(); - m_vector3.m_x.text(buffer.c_str()); - buffer.clear(); - - buffer << x_y_z.y(); - m_vector3.m_y.text(buffer.c_str()); - buffer.clear(); - - buffer << x_y_z.z(); - m_vector3.m_z.text(buffer.c_str()); - buffer.clear(); - } else { - m_vector3.m_x.text("0"); - m_vector3.m_y.text("0"); - m_vector3.m_z.text("0"); - } -} - -typedef MemberCaller UpdateCaller; -}; - -class NonModalComboBox { -Callback m_changed; -guint m_changedHandler; - -static gboolean changed(ui::ComboBox widget, NonModalComboBox *self) -{ - self->m_changed(); - return FALSE; -} - -public: -NonModalComboBox(const Callback &changed) : m_changed(changed), m_changedHandler(0) -{ -} - -void connect(ui::ComboBox combo) -{ - m_changedHandler = combo.connect("changed", G_CALLBACK(changed), this); -} - -void setActive(ui::ComboBox combo, int value) -{ - g_signal_handler_disconnect(G_OBJECT(combo), m_changedHandler); - gtk_combo_box_set_active(combo, value); - connect(combo); -} -}; - -class ListAttribute : public EntityAttribute { -CopiedString m_key; -ui::ComboBox m_combo; -NonModalComboBox m_nonModal; -const ListAttributeType &m_type; -public: -ListAttribute(const char *key, const ListAttributeType &type) : - m_key(key), - m_combo(ui::null), - m_nonModal(ApplyCaller(*this)), - m_type(type) -{ - auto combo = ui::ComboBoxText(ui::New); - - for (ListAttributeType::const_iterator i = type.begin(); i != type.end(); ++i) { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), (*i).first.c_str()); - } - - combo.show(); - m_nonModal.connect(combo); - - m_combo = combo; -} - -void release() -{ - delete this; -} - -ui::Widget getWidget() const -{ - return ui::Widget(m_combo); -} - -void apply() -{ - Scene_EntitySetKeyValue_Selected_Undoable(m_key.c_str(), - m_type[gtk_combo_box_get_active(m_combo)].second.c_str()); -} - -typedef MemberCaller ApplyCaller; - -void update() -{ - const char *value = SelectedEntity_getValueForKey(m_key.c_str()); - ListAttributeType::const_iterator i = m_type.findValue(value); - if (i != m_type.end()) { - m_nonModal.setActive(m_combo, static_cast( std::distance(m_type.begin(), i))); - } else { - m_nonModal.setActive(m_combo, 0); - } -} - -typedef MemberCaller UpdateCaller; -}; - - -namespace { -ui::Widget g_entity_split1{ui::null}; -ui::Widget g_entity_split2{ui::null}; -int g_entitysplit1_position; -int g_entitysplit2_position; - -bool g_entityInspector_windowConstructed = false; - -ui::TreeView g_entityClassList{ui::null}; -ui::TextView g_entityClassComment{ui::null}; - -GtkCheckButton *g_entitySpawnflagsCheck[MAX_FLAGS]; - -ui::Entry g_entityKeyEntry{ui::null}; -ui::Entry g_entityValueEntry{ui::null}; - -ui::ListStore g_entlist_store{ui::null}; -ui::ListStore g_entprops_store{ui::null}; -const EntityClass *g_current_flags = 0; -const EntityClass *g_current_comment = 0; -const EntityClass *g_current_attributes = 0; - -// the number of active spawnflags -int g_spawnflag_count; -// table: index, match spawnflag item to the spawnflag index (i.e. which bit) -int spawn_table[MAX_FLAGS]; -// we change the layout depending on how many spawn flags we need to display -// the table is a 4x4 in which we need to put the comment box g_entityClassComment and the spawn flags.. -ui::Table g_spawnflagsTable{ui::null}; - -ui::VBox g_attributeBox{ui::null}; -typedef std::vector EntityAttributes; -EntityAttributes g_entityAttributes; -} - -void GlobalEntityAttributes_clear() -{ - for (EntityAttributes::iterator i = g_entityAttributes.begin(); i != g_entityAttributes.end(); ++i) { - (*i)->release(); - } - g_entityAttributes.clear(); -} - -class GetKeyValueVisitor : public Entity::Visitor { -KeyValues &m_keyvalues; -public: -GetKeyValueVisitor(KeyValues &keyvalues) - : m_keyvalues(keyvalues) -{ -} - -void visit(const char *key, const char *value) -{ - m_keyvalues.insert(KeyValues::value_type(CopiedString(key), CopiedString(value))); -} - -}; - -void Entity_GetKeyValues(const Entity &entity, KeyValues &keyvalues, KeyValues &defaultValues) -{ - GetKeyValueVisitor visitor(keyvalues); - - entity.forEachKeyValue(visitor); - - const EntityClassAttributes &attributes = entity.getEntityClass().m_attributes; - - for (EntityClassAttributes::const_iterator i = attributes.begin(); i != attributes.end(); ++i) { - defaultValues.insert(KeyValues::value_type((*i).first, (*i).second.m_value)); - } -} - -void Entity_GetKeyValues_Selected(KeyValues &keyvalues, KeyValues &defaultValues) -{ - class EntityGetKeyValues : public SelectionSystem::Visitor { - KeyValues &m_keyvalues; - KeyValues &m_defaultValues; - mutable std::set m_visited; -public: - EntityGetKeyValues(KeyValues &keyvalues, KeyValues &defaultValues) - : m_keyvalues(keyvalues), m_defaultValues(defaultValues) - { - } - - void visit(scene::Instance &instance) const - { - Entity *entity = Node_getEntity(instance.path().top()); - if (entity == 0 && instance.path().size() != 1) { - entity = Node_getEntity(instance.path().parent()); - } - if (entity != 0 && m_visited.insert(entity).second) { - Entity_GetKeyValues(*entity, m_keyvalues, m_defaultValues); - } - } - } visitor(keyvalues, defaultValues); - GlobalSelectionSystem().foreachSelected(visitor); -} - -const char *keyvalues_valueforkey(KeyValues &keyvalues, const char *key) -{ - KeyValues::iterator i = keyvalues.find(CopiedString(key)); - if (i != keyvalues.end()) { - return (*i).second.c_str(); - } - return ""; -} - -class EntityClassListStoreAppend : public EntityClassVisitor { -ui::ListStore store; -public: -EntityClassListStoreAppend(ui::ListStore store_) : store(store_) -{ -} - -void visit(EntityClass *e) -{ - store.append(0, e->name(), 1, e); -} -}; - -void EntityClassList_fill() -{ - EntityClassListStoreAppend append(g_entlist_store); - GlobalEntityClassManager().forEach(append); -} - -void EntityClassList_clear() -{ - g_entlist_store.clear(); -} - -void SetComment(EntityClass *eclass) -{ - if (eclass == g_current_comment) { - return; - } - - g_current_comment = eclass; - - g_entityClassComment.text(eclass->comments()); -} - -void SurfaceFlags_setEntityClass(EntityClass *eclass) -{ - if (eclass == g_current_flags) { - return; - } - - g_current_flags = eclass; - - unsigned int spawnflag_count = 0; - - { - // do a first pass to count the spawn flags, don't touch the widgets, we don't know in what state they are - for (int i = 0; i < MAX_FLAGS; i++) { - if (eclass->flagnames[i] && eclass->flagnames[i][0] != 0 && strcmp(eclass->flagnames[i], "-")) { - spawn_table[spawnflag_count] = i; - spawnflag_count++; - } - } - } - - // disable all remaining boxes - // NOTE: these boxes might not even be on display - { - for (int i = 0; i < g_spawnflag_count; ++i) { - auto widget = ui::CheckButton::from(g_entitySpawnflagsCheck[i]); - auto label = ui::Label::from(gtk_bin_get_child(GTK_BIN(widget))); - label.text(" "); - widget.hide(); - widget.ref(); - g_spawnflagsTable.remove(widget); - } - } - - g_spawnflag_count = spawnflag_count; - - { - for (unsigned int i = 0; (int) i < g_spawnflag_count; ++i) { - auto widget = ui::CheckButton::from(g_entitySpawnflagsCheck[i]); - widget.show(); - - StringOutputStream str(16); - str << LowerCase(eclass->flagnames[spawn_table[i]]); - - g_spawnflagsTable.attach(widget, {i % 4, i % 4 + 1, i / 4, i / 4 + 1}, {GTK_FILL, GTK_FILL}); - widget.unref(); - - auto label = ui::Label::from(gtk_bin_get_child(GTK_BIN(widget))); - label.text(str.c_str()); - } - } -} - -void EntityClassList_selectEntityClass(EntityClass *eclass) -{ - auto model = g_entlist_store; - GtkTreeIter iter; - for (gboolean good = gtk_tree_model_get_iter_first(model, &iter); - good != FALSE; good = gtk_tree_model_iter_next(model, &iter)) { - char *text; - gtk_tree_model_get(model, &iter, 0, &text, -1); - if (strcmp(text, eclass->name()) == 0) { - auto view = ui::TreeView(g_entityClassList); - auto path = gtk_tree_model_get_path(model, &iter); - gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path); - if (gtk_widget_get_realized(view)) { - gtk_tree_view_scroll_to_cell(view, path, 0, FALSE, 0, 0); - } - gtk_tree_path_free(path); - good = FALSE; - } - g_free(text); - } -} - -void EntityInspector_appendAttribute(const char *name, EntityAttribute &attribute) -{ - auto row = DialogRow_new(name, attribute.getWidget()); - DialogVBox_packRow(ui::VBox(g_attributeBox), row); -} - - -template -class StatelessAttributeCreator { -public: -static EntityAttribute *create(const char *name) -{ - return new Attribute(name); -} -}; - -class EntityAttributeFactory { -typedef EntityAttribute *( *CreateFunc )(const char *name); - -typedef std::map Creators; -Creators m_creators; -public: -EntityAttributeFactory() -{ - m_creators.insert(Creators::value_type("string", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("color", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("integer", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("real", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("shader", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("boolean", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("angle", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("direction", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("angles", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("model", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("sound", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("vector3", &StatelessAttributeCreator::create)); - m_creators.insert(Creators::value_type("real3", &StatelessAttributeCreator::create)); -} - -EntityAttribute *create(const char *type, const char *name) -{ - Creators::iterator i = m_creators.find(type); - if (i != m_creators.end()) { - return (*i).second(name); - } - const ListAttributeType *listType = GlobalEntityClassManager().findListType(type); - if (listType != 0) { - return new ListAttribute(name, *listType); - } - return 0; -} -}; - -typedef Static GlobalEntityAttributeFactory; - -void EntityInspector_setEntityClass(EntityClass *eclass) -{ - EntityClassList_selectEntityClass(eclass); - SurfaceFlags_setEntityClass(eclass); - - if (eclass != g_current_attributes) { - g_current_attributes = eclass; - - container_remove_all(g_attributeBox); - GlobalEntityAttributes_clear(); - - for (EntityClassAttributes::const_iterator i = eclass->m_attributes.begin(); - i != eclass->m_attributes.end(); ++i) { - EntityAttribute *attribute = GlobalEntityAttributeFactory::instance().create((*i).second.m_type.c_str(), - (*i).first.c_str()); - if (attribute != 0) { - g_entityAttributes.push_back(attribute); - EntityInspector_appendAttribute(EntityClassAttributePair_getName(*i), *g_entityAttributes.back()); - } - } - } -} - -void EntityInspector_updateSpawnflags() -{ - { - int f = atoi(SelectedEntity_getValueForKey("spawnflags")); - for (int i = 0; i < g_spawnflag_count; ++i) { - int v = !!(f & (1 << spawn_table[i])); - - toggle_button_set_active_no_signal(ui::ToggleButton::from(g_entitySpawnflagsCheck[i]), v); - } - } - { - // take care of the remaining ones - for (int i = g_spawnflag_count; i < MAX_FLAGS; ++i) { - toggle_button_set_active_no_signal(ui::ToggleButton::from(g_entitySpawnflagsCheck[i]), FALSE); - } - } -} - -void EntityInspector_applySpawnflags() -{ - int f, i, v; - char sz[32]; - - f = 0; - for (i = 0; i < g_spawnflag_count; ++i) { - v = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_entitySpawnflagsCheck[i])); - f |= v << spawn_table[i]; - } - - sprintf(sz, "%i", f); - const char *value = (f == 0) ? "" : sz; - - { - StringOutputStream command; - command << "entitySetFlags -flags " << f; - UndoableCommand undo("entitySetSpawnflags"); - - Scene_EntitySetKeyValue_Selected("spawnflags", value); - } -} - - -void EntityInspector_updateKeyValues() -{ - g_selectedKeyValues.clear(); - g_selectedDefaultKeyValues.clear(); - Entity_GetKeyValues_Selected(g_selectedKeyValues, g_selectedDefaultKeyValues); - - EntityInspector_setEntityClass( - GlobalEntityClassManager().findOrInsert(keyvalues_valueforkey(g_selectedKeyValues, "classname"), false)); - - EntityInspector_updateSpawnflags(); - - ui::ListStore store = g_entprops_store; - - // save current key/val pair around filling epair box - // row_select wipes it and sets to first in list - CopiedString strKey(g_entityKeyEntry.text()); - CopiedString strVal(g_entityValueEntry.text()); - - store.clear(); - // Walk through list and add pairs - for (KeyValues::iterator i = g_selectedKeyValues.begin(); i != g_selectedKeyValues.end(); ++i) { - StringOutputStream key(64); - key << (*i).first.c_str(); - StringOutputStream value(64); - value << (*i).second.c_str(); - store.append(0, key.c_str(), 1, value.c_str()); - } - - g_entityKeyEntry.text(strKey.c_str()); - g_entityValueEntry.text(strVal.c_str()); - - for (EntityAttributes::const_iterator i = g_entityAttributes.begin(); i != g_entityAttributes.end(); ++i) { - (*i)->update(); - } -} - -class EntityInspectorDraw { -IdleDraw m_idleDraw; -public: -EntityInspectorDraw() : m_idleDraw(makeCallbackF(EntityInspector_updateKeyValues)) -{ -} - -void queueDraw() -{ - m_idleDraw.queueDraw(); -} -}; - -EntityInspectorDraw g_EntityInspectorDraw; - - -void EntityInspector_keyValueChanged() -{ - g_EntityInspectorDraw.queueDraw(); -} - -void EntityInspector_selectionChanged(const Selectable &) -{ - EntityInspector_keyValueChanged(); -} - -// Creates a new entity based on the currently selected brush and entity type. -// -void EntityClassList_createEntity() -{ - auto view = g_entityClassList; - - // find out what type of entity we are trying to create - GtkTreeModel *model; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(g_entityClassList), &model, &iter) == FALSE) { - ui::alert(view.window(), "You must have a selected class to create an entity", "info"); - return; - } - - char *text; - gtk_tree_model_get(model, &iter, 0, &text, -1); - - { - StringOutputStream command; - command << "entityCreate -class " << text; - printf(command.c_str()); - printf("\n"); - UndoableCommand undo(command.c_str()); - - Entity_createFromSelection(text, g_vector3_identity); - } - g_free(text); -} - -void EntityInspector_applyKeyValue() -{ - // Get current selection text - StringOutputStream key(64); - key << gtk_entry_get_text(g_entityKeyEntry); - StringOutputStream value(64); - value << gtk_entry_get_text(g_entityValueEntry); - - - // TTimo: if you change the classname to worldspawn you won't merge back in the structural brushes but create a parasite entity - if (!strcmp(key.c_str(), "classname") && !strcmp(value.c_str(), "worldspawn")) { - ui::alert(g_entityKeyEntry.window(), "Cannot change \"classname\" key back to worldspawn.", 0, - ui::alert_type::OK); - return; - } - - - // RR2DO2: we don't want spaces in entity keys - if (strstr(key.c_str(), " ")) { - ui::alert(g_entityKeyEntry.window(), "No spaces are allowed in entity keys.", 0, ui::alert_type::OK); - return; - } - - if (strcmp(key.c_str(), "classname") == 0) { - StringOutputStream command; - command << "entitySetClass -class " << value.c_str(); - UndoableCommand undo(command.c_str()); - Scene_EntitySetClassname_Selected(value.c_str()); - } else { - Scene_EntitySetKeyValue_Selected_Undoable(key.c_str(), value.c_str()); - } -} - -void EntityInspector_clearKeyValue() -{ - // Get current selection text - StringOutputStream key(64); - key << gtk_entry_get_text(g_entityKeyEntry); - - if (strcmp(key.c_str(), "classname") != 0) { - StringOutputStream command; - command << "entityDeleteKey -key " << key.c_str(); - UndoableCommand undo(command.c_str()); - Scene_EntitySetKeyValue_Selected(key.c_str(), ""); - } -} - -void EntityInspector_clearAllKeyValues() -{ - UndoableCommand undo("entityClear"); - - // remove all keys except classname - for (KeyValues::iterator i = g_selectedKeyValues.begin(); i != g_selectedKeyValues.end(); ++i) { - if (strcmp((*i).first.c_str(), "classname") != 0) { - Scene_EntitySetKeyValue_Selected((*i).first.c_str(), ""); - } - } -} - -// ============================================================================= -// callbacks - -static void EntityClassList_selection_changed(ui::TreeSelection selection, gpointer data) -{ - GtkTreeModel *model; - GtkTreeIter selected; - if (gtk_tree_selection_get_selected(selection, &model, &selected)) { - EntityClass *eclass; - gtk_tree_model_get(model, &selected, 1, &eclass, -1); - if (eclass != 0) { - SetComment(eclass); - } - } -} - -static gint EntityClassList_button_press(ui::Widget widget, GdkEventButton *event, gpointer data) -{ - if (event->type == GDK_2BUTTON_PRESS) { - /* If we're worldspawn - DO NOT ALLOW RENAMING! */ - StringOutputStream value(64); - value << SelectedEntity_getValueForKey("classname"); - - if (!strcmp(value.c_str(), "worldspawn")) { - EntityClassList_createEntity(); - return TRUE; - } - - auto view = g_entityClassList; - GtkTreeModel *model; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(g_entityClassList), &model, &iter) == FALSE) { - ui::alert(view.window(), "You must have a selected class to change an entity", "info"); - return FALSE; - } - - char *text; - gtk_tree_model_get(model, &iter, 0, &text, -1); - - StringOutputStream command; - command << "entitySetClass -class " << text; - UndoableCommand undo(command.c_str()); - Scene_EntitySetClassname_Selected(text); - g_free(text); - return TRUE; - } - return FALSE; -} - -static gint EntityClassList_keypress(ui::Widget widget, GdkEventKey *event, gpointer data) -{ - unsigned int code = gdk_keyval_to_upper(event->keyval); - - /* -eukara */ - /*if (event->keyval == GDK_KEY_Return) { - EntityClassList_createEntity(); - return TRUE; - }*/ - - // select the entity that starts with the key pressed - if (code <= 'Z' && code >= 'A') { - auto view = ui::TreeView(g_entityClassList); - GtkTreeModel *model; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(view), &model, &iter) == FALSE - || gtk_tree_model_iter_next(model, &iter) == FALSE) { - gtk_tree_model_get_iter_first(model, &iter); - } - - for (std::size_t count = gtk_tree_model_iter_n_children(model, 0); count > 0; --count) { - char *text; - gtk_tree_model_get(model, &iter, 0, &text, -1); - - if (toupper(text[0]) == (int) code) { - auto path = gtk_tree_model_get_path(model, &iter); - gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path); - if (gtk_widget_get_realized(view)) { - gtk_tree_view_scroll_to_cell(view, path, 0, FALSE, 0, 0); - } - gtk_tree_path_free(path); - count = 1; - } - - g_free(text); - - if (gtk_tree_model_iter_next(model, &iter) == FALSE) { - gtk_tree_model_get_iter_first(model, &iter); - } - } - - return TRUE; - } - return FALSE; -} - -static void EntityProperties_selection_changed(ui::TreeSelection selection, gpointer data) -{ - // find out what type of entity we are trying to create - GtkTreeModel *model; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE) { - return; - } - - char *key; - char *val; - gtk_tree_model_get(model, &iter, 0, &key, 1, &val, -1); - - g_entityKeyEntry.text(key); - g_entityValueEntry.text(val); - - g_free(key); - g_free(val); -} - -static void SpawnflagCheck_toggled(ui::Widget widget, gpointer data) -{ - EntityInspector_applySpawnflags(); -} - -static gint EntityEntry_keypress(ui::Entry widget, GdkEventKey *event, gpointer data) -{ - StringOutputStream key(64); - key << gtk_entry_get_text(g_entityKeyEntry); - StringOutputStream value(64); - value << gtk_entry_get_text(g_entityValueEntry); - - if (event->keyval == GDK_KEY_Return) { - if (widget._handle == g_entityKeyEntry._handle) { - g_entityValueEntry.text(""); - gtk_window_set_focus(widget.window(), g_entityValueEntry); - } else { - if (!strcmp(key.c_str(), "classname")) { - ui::alert(widget.window(), "Do not rename classnames. Pick a new entity from the list instead.", "info"); - return FALSE; - } else { - EntityInspector_applyKeyValue(); - } - } - return TRUE; - } - if (event->keyval == GDK_KEY_Escape) { - gtk_window_set_focus(widget.window(), NULL); - return TRUE; - } - - return FALSE; -} - -void EntityInspector_destroyWindow(ui::Widget widget, gpointer data) -{ - g_entitysplit1_position = gtk_paned_get_position(GTK_PANED(g_entity_split1)); - g_entitysplit2_position = gtk_paned_get_position(GTK_PANED(g_entity_split2)); - - g_entityInspector_windowConstructed = false; - GlobalEntityAttributes_clear(); -} - -ui::Widget EntityInspector_constructWindow(ui::Window toplevel) -{ - auto hbox = ui::HBox(FALSE, 2); - hbox.show(); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); - hbox.connect("destroy", G_CALLBACK(EntityInspector_destroyWindow), 0); - - auto vbox = ui::VBox(FALSE, 2); - vbox.show(); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - { - auto split1 = ui::VPaned(ui::New); - vbox.pack_start(split1, TRUE, TRUE, 0); - split1.show(); - - g_entity_split1 = split1; - - { - ui::Widget split2 = ui::VPaned(ui::New); - gtk_paned_add1(GTK_PANED(split1), split2); - split2.show(); - - g_entity_split2 = split2; - - { - // class list - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - gtk_paned_add1(GTK_PANED(split2), scr); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - - { - ui::ListStore store = ui::ListStore::from(gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_enable_search(view, FALSE); - gtk_tree_view_set_headers_visible(view, FALSE); - view.connect("button_press_event", G_CALLBACK(EntityClassList_button_press), 0); - view.connect("key_press_event", G_CALLBACK(EntityClassList_keypress), 0); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Key", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - } - - { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - selection.connect("changed", G_CALLBACK(EntityClassList_selection_changed), 0); - } - - view.show(); - - scr.add(view); - - store.unref(); - g_entityClassList = view; - g_entlist_store = store; - } - } - - /* this is the QUAKEED text */ - { - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - hbox.pack_start(scr, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - { - auto text = ui::TextView(ui::New); - text.dimensions(0, -1); // allow shrinking - gtk_text_view_set_wrap_mode(text, GTK_WRAP_WORD); - gtk_text_view_set_editable(text, FALSE); - text.show(); - scr.add(text); - g_entityClassComment = text; - } - } - } - - { - ui::Widget split2 = ui::VPaned(ui::New); - gtk_paned_add2(GTK_PANED(split1), split2); - split2.show(); - - { - auto vbox2 = ui::VBox(FALSE, 2); - vbox2.show(); - gtk_paned_pack1(GTK_PANED(split2), vbox2, FALSE, FALSE); - - { - // Spawnflags (4 colums wide max, or window gets too wide.) - auto table = ui::Table(4, 4, FALSE); - vbox2.pack_start(table, FALSE, TRUE, 0); - table.show(); - - g_spawnflagsTable = table; - - for (int i = 0; i < MAX_FLAGS; i++) { - auto check = ui::CheckButton(""); - check.ref(); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer( - check.connect("toggled", G_CALLBACK(SpawnflagCheck_toggled), 0))); - g_entitySpawnflagsCheck[i] = check; - } - } - - { - // key/value list - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - vbox2.pack_start(scr, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - - { - ui::ListStore store = ui::ListStore::from(gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_enable_search(view, FALSE); - gtk_tree_view_set_headers_visible(view, FALSE); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - } - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("", renderer, {{"text", 1}}); - gtk_tree_view_append_column(view, column); - } - - { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - selection.connect("changed", G_CALLBACK(EntityProperties_selection_changed), 0); - } - - view.show(); - - scr.add(view); - - store.unref(); - - g_entprops_store = store; - } - } - - { - // key/value entry - auto table = ui::Table(2, 2, FALSE); - table.show(); - vbox2.pack_start(table, FALSE, TRUE, 0); - gtk_table_set_row_spacings(table, 3); - gtk_table_set_col_spacings(table, 5); - - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_widget_set_events(entry, GDK_KEY_PRESS_MASK); - entry.connect("key_press_event", G_CALLBACK(EntityEntry_keypress), 0); - g_entityKeyEntry = entry; - } - - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_widget_set_events(entry, GDK_KEY_PRESS_MASK); - entry.connect("key_press_event", G_CALLBACK(EntityEntry_keypress), 0); - g_entityValueEntry = entry; - } - - { - auto label = ui::Label("Value"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - - { - auto label = ui::Label("Key"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - } - - { - auto hbox = ui::HBox(TRUE, 4); - hbox.show(); - vbox2.pack_start(hbox, FALSE, TRUE, 0); - - { - auto button = ui::Button("Clear All"); - button.show(); - button.connect("clicked", G_CALLBACK(EntityInspector_clearAllKeyValues), 0); - hbox.pack_start(button, TRUE, TRUE, 0); - } - { - auto button = ui::Button("Delete Key"); - button.show(); - button.connect("clicked", G_CALLBACK(EntityInspector_clearKeyValue), 0); - hbox.pack_start(button, TRUE, TRUE, 0); - } - } - } - - // Let's keep it simple, okay? - /*{ - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - - auto viewport = ui::Container::from(gtk_viewport_new(0, 0)); - viewport.show(); - gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE); - - g_attributeBox = ui::VBox(FALSE, 2); - g_attributeBox.show(); - - viewport.add(g_attributeBox); - scr.add(viewport); - gtk_paned_pack2(GTK_PANED(split2), scr, FALSE, FALSE); - }*/ - } - } - - - { - // show the sliders in any case - if (g_entitysplit2_position > 22) { - gtk_paned_set_position(GTK_PANED(g_entity_split2), g_entitysplit2_position); - } else { - g_entitysplit2_position = 22; - gtk_paned_set_position(GTK_PANED(g_entity_split2), 22); - } - if ((g_entitysplit1_position - g_entitysplit2_position) > 27) { - gtk_paned_set_position(GTK_PANED(g_entity_split1), g_entitysplit1_position); - } else { - gtk_paned_set_position(GTK_PANED(g_entity_split1), g_entitysplit2_position + 27); - } - } - - g_entityInspector_windowConstructed = true; - EntityClassList_fill(); - - typedef FreeCaller EntityInspectorSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(EntityInspectorSelectionChangedCaller()); - GlobalEntityCreator().setKeyValueChangedFunc(EntityInspector_keyValueChanged); - - // hack - gtk_container_set_focus_chain(GTK_CONTAINER(vbox), NULL); - - return hbox; -} - -class EntityInspector : public ModuleObserver { -std::size_t m_unrealised; -public: -EntityInspector() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - if (g_entityInspector_windowConstructed) { - //globalOutputStream() << "Entity Inspector: realise\n"; - EntityClassList_fill(); - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - if (g_entityInspector_windowConstructed) { - //globalOutputStream() << "Entity Inspector: unrealise\n"; - EntityClassList_clear(); - } - } -} -}; - -EntityInspector g_EntityInspector; - -#include "preferencesystem.h" -#include "stringio.h" - -void EntityInspector_construct() -{ - GlobalEntityClassManager().attach(g_EntityInspector); - - GlobalPreferenceSystem().registerPreference("EntitySplit1", make_property_string(g_entitysplit1_position)); - GlobalPreferenceSystem().registerPreference("EntitySplit2", make_property_string(g_entitysplit2_position)); - -} - -void EntityInspector_destroy() -{ - GlobalEntityClassManager().detach(g_EntityInspector); -} - -const char *EntityInspector_getCurrentKey() -{ - if (!GroupDialog_isShown()) { - return 0; - } - if (GroupDialog_getPage() != g_page_entity) { - return 0; - } - return gtk_entry_get_text(g_entityKeyEntry); -} diff --git a/src/entityinspector.h b/src/entityinspector.h deleted file mode 100644 index 4b200a8..0000000 --- a/src/entityinspector.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_ENTITYINSPECTOR_H ) -#define INCLUDED_ENTITYINSPECTOR_H - -ui::Widget EntityInspector_constructWindow(ui::Window parent); - -void EntityInspector_construct(); - -void EntityInspector_destroy(); - -const char *EntityInspector_getCurrentKey(); - -#endif diff --git a/src/entitylist.cpp b/src/entitylist.cpp deleted file mode 100644 index 50ca626..0000000 --- a/src/entitylist.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "entitylist.h" - -#include "iselection.h" - -#include -#include - -#include "string/string.h" -#include "scenelib.h" -#include "nameable.h" -#include "signal/isignal.h" -#include "generic/object.h" - -#include "gtkutil/widget.h" -#include "gtkutil/window.h" -#include "gtkutil/idledraw.h" -#include "gtkutil/accelerator.h" -#include "gtkutil/closure.h" - -#include "treemodel.h" - -void RedrawEntityList(); - -typedef FreeCaller RedrawEntityListCaller; - - -class EntityList { -public: -enum EDirty { - eDefault, - eSelection, - eInsertRemove, -}; - -EDirty m_dirty; - -IdleDraw m_idleDraw; -WindowPositionTracker m_positionTracker; - -ui::Window m_window; -ui::TreeView m_tree_view{ui::null}; -ui::TreeModel m_tree_model{ui::null}; -bool m_selection_disabled; - -EntityList() : - m_dirty(EntityList::eDefault), - m_idleDraw(RedrawEntityListCaller()), - m_window(ui::null), - m_selection_disabled(false) -{ -} - -bool visible() -{ - return m_window.visible(); -} -}; - -namespace { -EntityList *g_EntityList; - -inline EntityList &getEntityList() -{ - ASSERT_NOTNULL(g_EntityList); - return *g_EntityList; -} -} - - -inline Nameable *Node_getNameable(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -const char *node_get_name(scene::Node &node) -{ - Nameable *nameable = Node_getNameable(node); - return (nameable != 0) - ? nameable->name() - : "node"; -} - -template -inline void gtk_tree_model_get_pointer(ui::TreeModel model, GtkTreeIter *iter, gint column, value_type **pointer) -{ - GValue value = GValue_default(); - gtk_tree_model_get_value(model, iter, column, &value); - *pointer = (value_type *) g_value_get_pointer(&value); -} - - -void entitylist_treeviewcolumn_celldatafunc(ui::TreeViewColumn column, ui::CellRenderer renderer, ui::TreeModel model, - GtkTreeIter *iter, gpointer data) -{ - scene::Node *node; - gtk_tree_model_get_pointer(model, iter, 0, &node); - scene::Instance *instance; - gtk_tree_model_get_pointer(model, iter, 1, &instance); - if (node != 0) { - gtk_cell_renderer_set_fixed_size(renderer, -1, -1); - char *name = const_cast( node_get_name(*node)); - g_object_set(G_OBJECT(renderer), "text", name, "visible", TRUE, NULL); - - //globalOutputStream() << "rendering cell " << makeQuoted(name) << "\n"; - auto style = gtk_widget_get_style(ui::TreeView(getEntityList().m_tree_view)); - if (instance->childSelected()) { - g_object_set(G_OBJECT(renderer), "cell-background-gdk", &style->base[GTK_STATE_ACTIVE], NULL); - } else { - g_object_set(G_OBJECT(renderer), "cell-background-gdk", &style->base[GTK_STATE_NORMAL], NULL); - } - } else { - gtk_cell_renderer_set_fixed_size(renderer, -1, 0); - g_object_set(G_OBJECT(renderer), "text", "", "visible", FALSE, NULL); - } -} - -static gboolean entitylist_tree_select(ui::TreeSelection selection, ui::TreeModel model, ui::TreePath path, - gboolean path_currently_selected, gpointer data) -{ - GtkTreeIter iter; - gtk_tree_model_get_iter(model, &iter, path); - scene::Node *node; - gtk_tree_model_get_pointer(model, &iter, 0, &node); - scene::Instance *instance; - gtk_tree_model_get_pointer(model, &iter, 1, &instance); - Selectable *selectable = Instance_getSelectable(*instance); - - if (node == 0) { - if (path_currently_selected != FALSE) { - getEntityList().m_selection_disabled = true; - GlobalSelectionSystem().setSelectedAll(false); - getEntityList().m_selection_disabled = false; - } - } else if (selectable != 0) { - getEntityList().m_selection_disabled = true; - selectable->setSelected(path_currently_selected == FALSE); - getEntityList().m_selection_disabled = false; - return TRUE; - } - - return FALSE; -} - -static gboolean entitylist_tree_select_null(ui::TreeSelection selection, ui::TreeModel model, ui::TreePath path, - gboolean path_currently_selected, gpointer data) -{ - return TRUE; -} - -void EntityList_ConnectSignals(ui::TreeView view) -{ - auto select = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_select_function(select, reinterpret_cast(entitylist_tree_select), NULL, - 0); -} - -void EntityList_DisconnectSignals(ui::TreeView view) -{ - auto select = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_select_function(select, reinterpret_cast(entitylist_tree_select_null), - 0, 0); -} - - -gboolean treemodel_update_selection(ui::TreeModel model, ui::TreePath path, GtkTreeIter *iter, gpointer data) -{ - auto view = ui::TreeView::from(data); - - scene::Instance *instance; - gtk_tree_model_get_pointer(model, iter, 1, &instance); - Selectable *selectable = Instance_getSelectable(*instance); - - if (selectable != 0) { - auto selection = gtk_tree_view_get_selection(view); - if (selectable->isSelected()) { - gtk_tree_selection_select_path(selection, path); - } else { - gtk_tree_selection_unselect_path(selection, path); - } - } - - return FALSE; -} - -void EntityList_UpdateSelection(ui::TreeModel model, ui::TreeView view) -{ - EntityList_DisconnectSignals(view); - gtk_tree_model_foreach(model, reinterpret_cast(treemodel_update_selection), view._handle); - EntityList_ConnectSignals(view); -} - - -void RedrawEntityList() -{ - switch (getEntityList().m_dirty) { - case EntityList::eInsertRemove: - case EntityList::eSelection: - EntityList_UpdateSelection(getEntityList().m_tree_model, getEntityList().m_tree_view); - default: - break; - } - getEntityList().m_dirty = EntityList::eDefault; -} - -void entitylist_queue_draw() -{ - getEntityList().m_idleDraw.queueDraw(); -} - -void EntityList_SelectionUpdate() -{ - if (getEntityList().m_selection_disabled) { - return; - } - - if (getEntityList().m_dirty < EntityList::eSelection) { - getEntityList().m_dirty = EntityList::eSelection; - } - entitylist_queue_draw(); -} - -void EntityList_SelectionChanged(const Selectable &selectable) -{ - EntityList_SelectionUpdate(); -} - -void entitylist_treeview_rowcollapsed(ui::TreeView view, GtkTreeIter *iter, ui::TreePath path, gpointer user_data) -{ -} - -void entitylist_treeview_row_expanded(ui::TreeView view, GtkTreeIter *iter, ui::TreePath path, gpointer user_data) -{ - EntityList_SelectionUpdate(); -} - - -void EntityList_SetShown(bool shown) -{ - getEntityList().m_window.visible(shown); -} - -void EntityList_toggleShown() -{ - EntityList_SetShown(!getEntityList().visible()); -} - -gint graph_tree_model_compare_name(ui::TreeModel model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data) -{ - scene::Node *first; - gtk_tree_model_get(model, a, 0, (gpointer *) &first, -1); - scene::Node *second; - gtk_tree_model_get(model, b, 0, (gpointer *) &second, -1); - int result = 0; - if (first != 0 && second != 0) { - result = string_compare(node_get_name(*first), node_get_name(*second)); - } - if (result == 0) { - return (first < second) ? -1 : (second < first) ? 1 : 0; - } - return result; -} - -extern GraphTreeModel *scene_graph_get_tree_model(); - -void AttachEntityTreeModel() -{ - getEntityList().m_tree_model = ui::TreeModel::from(scene_graph_get_tree_model()); - - gtk_tree_view_set_model(getEntityList().m_tree_view, getEntityList().m_tree_model); -} - -void DetachEntityTreeModel() -{ - getEntityList().m_tree_model = ui::TreeModel(ui::null); - - gtk_tree_view_set_model(getEntityList().m_tree_view, 0); -} - -void EntityList_constructWindow(ui::Window main_window) -{ - ASSERT_TRUE(!getEntityList().m_window); - - auto window = ui::Window(create_persistent_floating_window("Entity List", main_window)); - - window.add_accel_group(global_accel); - - getEntityList().m_positionTracker.connect(window); - - - getEntityList().m_window = window; - - { - auto scr = create_scrolled_window(ui::Policy::AUTOMATIC, ui::Policy::AUTOMATIC); - window.add(scr); - - { - auto view = ui::TreeView(ui::New); - gtk_tree_view_set_headers_visible(view, FALSE); - - auto renderer = ui::CellRendererText(ui::New); - auto column = gtk_tree_view_column_new(); - gtk_tree_view_column_pack_start(column, renderer, TRUE); - gtk_tree_view_column_set_cell_data_func(column, renderer, - reinterpret_cast(entitylist_treeviewcolumn_celldatafunc), - 0, 0); - - auto select = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(select, GTK_SELECTION_MULTIPLE); - - view.connect("row_expanded", G_CALLBACK(entitylist_treeview_row_expanded), 0); - view.connect("row_collapsed", G_CALLBACK(entitylist_treeview_rowcollapsed), 0); - - gtk_tree_view_append_column(view, column); - - view.show(); - scr.add(view); - getEntityList().m_tree_view = view; - } - } - - EntityList_ConnectSignals(getEntityList().m_tree_view); - AttachEntityTreeModel(); -} - -void EntityList_destroyWindow() -{ - DetachEntityTreeModel(); - EntityList_DisconnectSignals(getEntityList().m_tree_view); - destroy_floating_window(getEntityList().m_window); -} - -#include "preferencesystem.h" - -#include "iselection.h" - -namespace { -scene::Node *nullNode = 0; -} - -class NullSelectedInstance : public scene::Instance, public Selectable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceStaticCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -public: -typedef LazyStatic StaticTypeCasts; - -NullSelectedInstance() : Instance(scene::Path(makeReference(*nullNode)), 0, this, StaticTypeCasts::instance().get()) -{ -} - -void setSelected(bool select) -{ - ERROR_MESSAGE("error"); -} - -bool isSelected() const -{ - return true; -} -}; - -typedef LazyStatic StaticNullSelectedInstance; - - -void EntityList_Construct() -{ - graph_tree_model_insert(scene_graph_get_tree_model(), StaticNullSelectedInstance::instance()); - - g_EntityList = new EntityList; - - getEntityList().m_positionTracker.setPosition(c_default_window_pos); - - GlobalPreferenceSystem().registerPreference("EntityInfoDlg", make_property( - getEntityList().m_positionTracker)); - - typedef FreeCaller EntityListSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(EntityListSelectionChangedCaller()); -} - -void EntityList_Destroy() -{ - delete g_EntityList; - - graph_tree_model_erase(scene_graph_get_tree_model(), StaticNullSelectedInstance::instance()); -} diff --git a/src/entitylist.h b/src/entitylist.h deleted file mode 100644 index 38ee587..0000000 --- a/src/entitylist.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_ENTITYLIST_H ) -#define INCLUDED_ENTITYLIST_H - -void EntityList_Construct(); - -void EntityList_Destroy(); - -void EntityList_constructWindow(ui::Window main_window); - -void EntityList_destroyWindow(); - -void EntityList_toggleShown(); - -#endif diff --git a/src/environment.cpp b/src/environment.cpp deleted file mode 100644 index 3d87ef2..0000000 --- a/src/environment.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "environment.h" -#include "globaldefs.h" - -#include "stream/textstream.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "debugging/debugging.h" -#include "os/path.h" -#include "os/file.h" -#include "cmdlib.h" - -int g_argc; -char const **g_argv; - -void args_init(int argc, char const *argv[]) -{ - int i, j, k; - - for (i = 1; i < argc; i++) { - for (k = i; k < argc; k++) { - if (argv[k] != 0) { - break; - } - } - - if (k > i) { - k -= i; - for (j = i + k; j < argc; j++) { - argv[j - k] = argv[j]; - } - argc -= k; - } - } - - g_argc = argc; - g_argv = argv; -} - -char const *gamedetect_argv_buffer[1024]; - -void gamedetect_found_game(char const *game, char *path) -{ - int argc; - static char buf[128]; - - if (g_argv == gamedetect_argv_buffer) { - return; - } - - globalOutputStream() << "Detected game " << game << " in " << path << "\n"; - - sprintf(buf, "-%s-EnginePath", game); - argc = 0; - gamedetect_argv_buffer[argc++] = "-global-gamefile"; - gamedetect_argv_buffer[argc++] = game; - gamedetect_argv_buffer[argc++] = buf; - gamedetect_argv_buffer[argc++] = path; - if ((size_t) (argc + g_argc) >= sizeof(gamedetect_argv_buffer) / sizeof(*gamedetect_argv_buffer) - 1) { - g_argc = sizeof(gamedetect_argv_buffer) / sizeof(*gamedetect_argv_buffer) - g_argc - 1; - } - memcpy(gamedetect_argv_buffer + 4, g_argv, sizeof(*gamedetect_argv_buffer) * g_argc); - g_argc += argc; - g_argv = gamedetect_argv_buffer; -} - -bool gamedetect_check_game(char const *gamefile, const char *checkfile1, const char *checkfile2, - char *buf /* must have 64 bytes free after bufpos */, int bufpos) -{ - buf[bufpos] = '/'; - - strcpy(buf + bufpos + 1, checkfile1); - globalOutputStream() << "Checking for a game file in " << buf << "\n"; - if (!file_exists(buf)) { - return false; - } - - if (checkfile2) { - strcpy(buf + bufpos + 1, checkfile2); - globalOutputStream() << "Checking for a game file in " << buf << "\n"; - if (!file_exists(buf)) { - return false; - } - } - - buf[bufpos + 1] = 0; - gamedetect_found_game(gamefile, buf); - return true; -} - -void gamedetect() -{ - // if we're inside a Nexuiz install - // default to nexuiz.game (unless the user used an option to inhibit this) - bool nogamedetect = false; - int i; - for (i = 1; i < g_argc - 1; ++i) { - if (g_argv[i][0] == '-') { - if (!strcmp(g_argv[i], "-gamedetect")) { - nogamedetect = !strcmp(g_argv[i + 1], "false"); - } - ++i; - } - } - if (!nogamedetect) { - static char buf[1024 + 64]; - strncpy(buf, environment_get_app_path(), sizeof(buf)); - buf[sizeof(buf) - 1 - 64] = 0; - if (!strlen(buf)) { - return; - } - - char *p = buf + strlen(buf) - 1; // point directly on the slash of get_app_path - while (p != buf) { - // we found nothing - // go backwards - --p; - while (p != buf && *p != '/' && *p != '\\') { - --p; - } - } - } -} - -namespace { -CopiedString app_path; -} - -const char *environment_get_app_path() -{ - return app_path.c_str(); -} - -bool portable_app_setup() -{ - StringOutputStream confdir(256); - confdir << app_path.c_str() << "settings/"; - if (file_exists(confdir.c_str())) { - return true; - } - return false; -} - -#if GDEF_OS_POSIX - -#include -#include -#include - -#include - -const char *LINK_NAME = -#if GDEF_OS_LINUX - "/proc/self/exe" -#else // FreeBSD and OSX - "/proc/curproc/file" -#endif -; - -/// brief Returns the filename of the executable belonging to the current process, or 0 if not found. -char const *getexename(char *buf) -{ - /* Now read the symbolic link */ - 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) { - /* In case of an error, leave the handling up to the caller */ - return ""; - } - } - - /* Ensure proper NUL termination */ - buf[ret] = 0; - - /* delete the program name */ - *(strrchr(buf, '/')) = '\0'; - - // NOTE: we build app path with a trailing '/' - // it's a general convention in Radiant to have the slash at the end of directories - if (buf[strlen(buf) - 1] != '/') { - strcat(buf, "/"); - } - - return buf; -} - -void environment_init(int argc, char const *argv[]) -{ - // Give away unnecessary root privileges. - // Important: must be done before calling gtk_init(). - char *loginname; - struct passwd *pw; - seteuid(getuid()); - if (geteuid() == 0 && (loginname = getlogin()) != 0 && - (pw = getpwnam(loginname)) != 0) { - setuid(pw->pw_uid); - } - - args_init(argc, argv); - - { - char real[PATH_MAX]; - app_path = getexename(real); - ASSERT_MESSAGE(!string_empty(app_path.c_str()), "failed to deduce app path"); - } - - gamedetect(); -} - -#elif GDEF_OS_WINDOWS - -#include - -void environment_init( int argc, char const* argv[] ){ - args_init( argc, argv ); - - // get path to the editor - char filename[MAX_PATH + 1]; - GetModuleFileName( 0, filename, MAX_PATH ); - char* last_separator = strrchr( filename, '\\' ); - if ( last_separator != 0 ) { - *( last_separator + 1 ) = '\0'; - } else { - filename[0] = '\0'; - } - - StringOutputStream app( 256 ); - app << PathCleaned( filename ); - app_path = app.c_str(); - gamedetect(); -} - -#else -#error "unsupported platform" -#endif diff --git a/src/environment.h b/src/environment.h deleted file mode 100644 index 173c2ab..0000000 --- a/src/environment.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ENVIRONMENT_H ) -#define INCLUDED_ENVIRONMENT_H - -void environment_init(int argc, char const *argv[]); - -const char *environment_get_home_path(); - -const char *environment_get_app_path(); - -extern int g_argc; -extern char const **g_argv; - -#endif diff --git a/src/error.cpp b/src/error.cpp deleted file mode 100644 index d867d7b..0000000 --- a/src/error.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "error.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" -#include "igl.h" - -#include "gtkutil/messagebox.h" -#include "console.h" -#include "preferences.h" - - -#if GDEF_OS_WINDOWS -#define UNICODE -#include -#else - -#include -#include - -#endif - - - -/* - ================= - Error - - For abnormal program terminations - ================= - */ - -/*! - \todo - FIXME the prompt wether to do prefs dialog, may not even be possible - if the crash happens before the game is loaded - */ - -void Error(const char *error, ...) -{ - va_list argptr; - char text[4096]; - - va_start(argptr, error); - vsprintf(text, error, argptr); - va_end(argptr); - - strcat(text, "\n"); - -#if GDEF_OS_WINDOWS - if ( GetLastError() != 0 ) { - LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - 0, - GetLastError(), - MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language - (LPTSTR) &lpMsgBuf, - 0, - 0 - ); - strcat( text, "GetLastError: " ); - /* - Gtk will only crunch 0<=char<=127 - this is a bit hackish, but I didn't find useful functions in win32 API for this - http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=516 - */ - TCHAR *scan, *next = (TCHAR*)lpMsgBuf; - do - { - scan = next; - text[strlen( text ) + 1] = '\0'; - if ( ( scan[0] >= 0 ) && ( scan[0] <= 127 ) ) { - text[strlen( text )] = char(scan[0]); - } - else{ - text[strlen( text )] = '?'; - } - next = CharNext( scan ); - } while ( next != scan ); - strcat( text, "\n" ); - LocalFree( lpMsgBuf ); - } -#else - if (errno != 0) { - strcat(text, "errno: "); - strcat(text, strerror(errno)); - strcat(text, "\n"); - } -#endif - - -#if 0 - // we need to have a current context to call glError() - if ( g_glwindow_globals.d_glBase != 0 ) { - // glGetError .. can record several errors, clears after calling - //++timo TODO: be able to deal with several errors if necessary, for now I'm just warning about pending error messages - // NOTE: forget that, most boards don't seem to follow the OpenGL standard - GLenum iGLError = glGetError(); - if ( iGLError != GL_NO_ERROR ) { - // use our own gluErrorString - strcat( text, "gluErrorString: " ); - strcat( text, (char*)gluErrorString( iGLError ) ); - strcat( text, "\n" ); - } - } -#endif - - strcat(text, "An unrecoverable error has occured.\n"); - - ERROR_MESSAGE(text); - - _exit(1); -} diff --git a/src/error.h b/src/error.h deleted file mode 100644 index 43acdb5..0000000 --- a/src/error.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_ERROR_H ) -#define INCLUDED_ERROR_H - -void Error(const char *error, ...); - -#endif diff --git a/tools/vmap/exportents.c b/src/exportents.c similarity index 100% rename from tools/vmap/exportents.c rename to src/exportents.c diff --git a/tools/vmap/facebsp.c b/src/facebsp.c similarity index 100% rename from tools/vmap/facebsp.c rename to src/facebsp.c diff --git a/src/feedback.cpp b/src/feedback.cpp deleted file mode 100644 index d1164b5..0000000 --- a/src/feedback.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//----------------------------------------------------------------------------- -// -// DESCRIPTION: -// classes used for describing geometry information from q3map feedback -// - -#include "feedback.h" - -#include - -#include "debugging/debugging.h" - -#include "igl.h" -#include "iselection.h" - -#include "map.h" -#include "dialog.h" -#include "mainframe.h" - - -CDbgDlg g_DbgDlg; - -void Feedback_draw2D(VIEWTYPE viewType) -{ - g_DbgDlg.draw2D(viewType); -} - -void CSelectMsg::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) -{ - if (string_equal(reinterpret_cast( name ), "select")) { - // read the message - ESelectState = SELECT_MESSAGE; - } else { - // read the brush - ASSERT_MESSAGE(string_equal(reinterpret_cast( name ), "brush"), "FEEDBACK PARSE ERROR"); - ASSERT_MESSAGE(ESelectState == SELECT_MESSAGE, "FEEDBACK PARSE ERROR"); - ESelectState = SELECT_BRUSH; - globalOutputStream() << message.c_str() << '\n'; - } -} - -void CSelectMsg::saxEndElement(message_info_t *ctx, const xmlChar *name) -{ - if (string_equal(reinterpret_cast( name ), "select")) { - } -} - -void CSelectMsg::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) -{ - if (ESelectState == SELECT_MESSAGE) { - message.write(reinterpret_cast( ch ), len); - } else { - brush.write(reinterpret_cast( ch ), len); - } -} - -IGL2DWindow *CSelectMsg::Highlight() -{ - GlobalSelectionSystem().setSelectedAll(false); - int entitynum, brushnum; - if (sscanf(reinterpret_cast( brush.c_str()), "%i %i", &entitynum, &brushnum) == 2) { - SelectBrush(entitynum, brushnum); - } - return 0; -} - -void CPointMsg::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) -{ - if (string_equal(reinterpret_cast( name ), "pointmsg")) { - // read the message - EPointState = POINT_MESSAGE; - } else { - // read the brush - ASSERT_MESSAGE(string_equal(reinterpret_cast( name ), "point"), "FEEDBACK PARSE ERROR"); - ASSERT_MESSAGE(EPointState == POINT_MESSAGE, "FEEDBACK PARSE ERROR"); - EPointState = POINT_POINT; - globalOutputStream() << message.c_str() << '\n'; - } -} - -void CPointMsg::saxEndElement(message_info_t *ctx, const xmlChar *name) -{ - if (string_equal(reinterpret_cast( name ), "pointmsg")) { - } else if (string_equal(reinterpret_cast( name ), "point")) { - sscanf(point.c_str(), "%g %g %g", &(pt[0]), &(pt[1]), &(pt[2])); - point.clear(); - } -} - -void CPointMsg::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) -{ - if (EPointState == POINT_MESSAGE) { - message.write(reinterpret_cast( ch ), len); - } else { - ASSERT_MESSAGE(EPointState == POINT_POINT, "FEEDBACK PARSE ERROR"); - point.write(reinterpret_cast( ch ), len); - } -} - -IGL2DWindow *CPointMsg::Highlight() -{ - return this; -} - -void CPointMsg::DropHighlight() -{ -} - -void CPointMsg::Draw2D(VIEWTYPE vt) -{ - int nDim1 = (vt == YZ) ? 1 : 0; - int nDim2 = (vt == XY) ? 1 : 2; - glPointSize(4); - glColor3f(1.0f, 0.0f, 0.0f); - glBegin(GL_POINTS); - glVertex2f(pt[nDim1], pt[nDim2]); - glEnd(); - glBegin(GL_LINE_LOOP); - glVertex2f(pt[nDim1] - 8, pt[nDim2] - 8); - glVertex2f(pt[nDim1] + 8, pt[nDim2] - 8); - glVertex2f(pt[nDim1] + 8, pt[nDim2] + 8); - glVertex2f(pt[nDim1] - 8, pt[nDim2] + 8); - glEnd(); -} - -void CWindingMsg::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) -{ - if (string_equal(reinterpret_cast( name ), "windingmsg")) { - // read the message - EPointState = WINDING_MESSAGE; - } else { - // read the brush - ASSERT_MESSAGE(string_equal(reinterpret_cast( name ), "winding"), "FEEDBACK PARSE ERROR"); - ASSERT_MESSAGE(EPointState == WINDING_MESSAGE, "FEEDBACK PARSE ERROR"); - EPointState = WINDING_WINDING; - globalOutputStream() << message.c_str() << '\n'; - } -} - -void CWindingMsg::saxEndElement(message_info_t *ctx, const xmlChar *name) -{ - if (string_equal(reinterpret_cast( name ), "windingmsg")) { - } else if (string_equal(reinterpret_cast( name ), "winding")) { - const char *c = winding.c_str(); - sscanf(c, "%i ", &numpoints); - - int i = 0; - for (; i < numpoints; i++) { - c = strchr(c + 1, '('); - if (c) { // even if we are given the number of points when the cycle begins .. don't trust it too much - sscanf(c, "(%g %g %g)", &wt[i][0], &wt[i][1], &wt[i][2]); - } else { - break; - } - } - numpoints = i; - } -} - -void CWindingMsg::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) -{ - if (EPointState == WINDING_MESSAGE) { - message.write(reinterpret_cast( ch ), len); - } else { - ASSERT_MESSAGE(EPointState == WINDING_WINDING, "FEEDBACK PARSE ERROR"); - winding.write(reinterpret_cast( ch ), len); - } -} - -IGL2DWindow *CWindingMsg::Highlight() -{ - return this; -} - -void CWindingMsg::DropHighlight() -{ -} - -void CWindingMsg::Draw2D(VIEWTYPE vt) -{ - int i; - - int nDim1 = (vt == YZ) ? 1 : 0; - int nDim2 = (vt == XY) ? 1 : 2; - glColor3f(1.0f, 0.f, 0.0f); - - glPointSize(4); - glBegin(GL_POINTS); - for (i = 0; i < numpoints; i++) - glVertex2f(wt[i][nDim1], wt[i][nDim2]); - glEnd(); - glPointSize(1); - - glEnable(GL_BLEND); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0.133f, 0.4f, 1.0f, 0.5f); - glBegin(GL_POLYGON); - for (i = 0; i < numpoints; i++) - glVertex2f(wt[i][nDim1], wt[i][nDim2]); - glEnd(); - glDisable(GL_BLEND); -} - -// triggered when the user selects an entry in the feedback box -static void feedback_selection_changed(ui::TreeSelection selection, gpointer data) -{ - g_DbgDlg.DropHighlight(); - - GtkTreeModel *model; - GtkTreeIter selected; - if (gtk_tree_selection_get_selected(selection, &model, &selected)) { - auto path = gtk_tree_model_get_path(model, &selected); - g_DbgDlg.SetHighlight(gtk_tree_path_get_indices(path)[0]); - gtk_tree_path_free(path); - } -} - -void CDbgDlg::DropHighlight() -{ - if (m_pHighlight != 0) { - m_pHighlight->DropHighlight(); - m_pHighlight = 0; - m_pDraw2D = 0; - } -} - -void CDbgDlg::SetHighlight(gint row) -{ - ISAXHandler *h = GetElement(row); - if (h != NULL) { - m_pDraw2D = h->Highlight(); - m_pHighlight = h; - } -} - -ISAXHandler *CDbgDlg::GetElement(std::size_t row) -{ - return static_cast(g_ptr_array_index(m_pFeedbackElements, gint( row )) ); -} - -void CDbgDlg::Init() -{ - DropHighlight(); - - // free all the ISAXHandler*, clean it - while (m_pFeedbackElements->len) { - static_cast(g_ptr_array_index(m_pFeedbackElements, 0) )->Release(); - g_ptr_array_remove_index(m_pFeedbackElements, 0); - } - - if (m_clist) { - m_clist.clear(); - } -} - -void CDbgDlg::Push(ISAXHandler *pHandler) -{ - // push in the list - g_ptr_array_add(m_pFeedbackElements, (void *) pHandler); - - if (!GetWidget()) { - Create(); - } - - // put stuff in the list - m_clist.clear(); - for (std::size_t i = 0; i < static_cast( m_pFeedbackElements->len ); ++i) { - m_clist.append(0, GetElement(i)->getName()); - } - - ShowDlg(); -} - -ui::Window CDbgDlg::BuildDialog() -{ - auto window = MainFrame_getWindow().create_floating_window("Q3Map debug window"); - - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - window.add(scr); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - - { - ui::ListStore store = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_headers_visible(view, FALSE); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - } - - { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); - selection.connect("changed", G_CALLBACK(feedback_selection_changed), NULL); - } - - view.show(); - - scr.add(view); - - store.unref(); - - m_clist = store; - } - - return window; -} diff --git a/src/feedback.h b/src/feedback.h deleted file mode 100644 index 56c2d7f..0000000 --- a/src/feedback.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//----------------------------------------------------------------------------- -// -// DESCRIPTION: -// classes used for describing geometry information from q3map feedback -// - -#ifndef __Q3MAP_FEEDBACK__ -#define __Q3MAP_FEEDBACK__ - -#include "math/vector.h" -#include "stream/stringstream.h" -#include "xmlstuff.h" -#include "dialog.h" -#include "xywindow.h" - -// we use these classes to let plugins draw inside the Radiant windows -// 2D window like YZ XZ XY -class IGL2DWindow { -public: -virtual ~IGL2DWindow() = default; - -// Increment the number of references to this object -virtual void IncRef() = 0; - -// Decrement the reference count -virtual void DecRef() = 0; - -virtual void Draw2D(VIEWTYPE vt) = 0; -}; - -// 3D window -class IGL3DWindow { -public: -// Increment the number of references to this object -virtual void IncRef() = 0; - -// Decrement the reference count -virtual void DecRef() = 0; - -virtual void Draw3D() = 0; -}; - -// a select message with a brush/entity select information -class CSelectMsg : public ISAXHandler { -enum { SELECT_MESSAGE, SELECT_BRUSH } ESelectState; -StringOutputStream message; -StringOutputStream brush; -public: -CSelectMsg() -{ - ESelectState = SELECT_MESSAGE; -} - -// SAX interface -void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs); - -void saxEndElement(message_info_t *ctx, const xmlChar *name); - -void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len); - -// for use in the dialog window -const char *getName() -{ - return message.c_str(); -} - -IGL2DWindow *Highlight(); - -void DropHighlight() -{ -} -}; - -class CPointMsg : public ISAXHandler, public IGL2DWindow { -enum { POINT_MESSAGE, POINT_POINT } EPointState; -StringOutputStream message; -StringOutputStream point; -Vector3 pt; -int refCount; -public: -CPointMsg() -{ - EPointState = POINT_MESSAGE; - refCount = 0; -} - -// SAX interface -void Release() -{ - delete this; -} - -void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs); - -void saxEndElement(message_info_t *ctx, const xmlChar *name); - -void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len); - -// for use in the dialog window -const char *getName() -{ - return message.c_str(); -} - -IGL2DWindow *Highlight(); - -void DropHighlight(); - -// IGL2DWindow interface -------------------------------- -// Increment the number of references to this object -void IncRef() -{ - refCount++; -} - -// Decrement the reference count -void DecRef() -{ - refCount--; - if (refCount <= 0) { - delete this; - } -} - -void Draw2D(VIEWTYPE vt); -}; - -class CWindingMsg : public ISAXHandler, public IGL2DWindow { -enum { WINDING_MESSAGE, WINDING_WINDING } EPointState; -StringOutputStream message; -StringOutputStream winding; -Vector3 wt[256]; -int numpoints; -int refCount; -public: -CWindingMsg() -{ - EPointState = WINDING_MESSAGE; - refCount = 0; - numpoints = 0; -} - -// SAX interface -void Release() -{ - delete this; -} - -void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs); - -void saxEndElement(message_info_t *ctx, const xmlChar *name); - -void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len); - -// for use in the dialog window -const char *getName() -{ - return message.c_str(); -} - -IGL2DWindow *Highlight(); - -void DropHighlight(); - -// IGL2DWindow interface -------------------------------- -// Increment the number of references to this object -void IncRef() -{ - refCount++; -} - -// Decrement the reference count -void DecRef() -{ - refCount--; - if (refCount <= 0) { - delete this; - } -} - -void Draw2D(VIEWTYPE vt); -}; - - -class CDbgDlg : public Dialog { -GPtrArray *m_pFeedbackElements; -// the list widget we use in the dialog -ui::ListStore m_clist{ui::null}; -ISAXHandler *m_pHighlight; -IGL2DWindow *m_pDraw2D; -public: -CDbgDlg() -{ - m_pFeedbackElements = g_ptr_array_new(); - m_pHighlight = NULL; - m_pDraw2D = NULL; -} - -// refresh items -void Push(ISAXHandler *); - -// clean the debug window, release all ISAXHanlders we have -void Init(); - -ISAXHandler *GetElement(std::size_t row); - -void SetHighlight(gint row); - -void DropHighlight(); - -void draw2D(VIEWTYPE viewType) -{ - if (m_pDraw2D != 0) { - m_pDraw2D->Draw2D(viewType); - } -} - -void destroyWindow() -{ - if (GetWidget()) { - Destroy(); - } -} -// void HideDlg(); -protected: -ui::Window BuildDialog(); -}; - -extern CDbgDlg g_DbgDlg; - -void Feedback_draw2D(VIEWTYPE viewType); - -#endif diff --git a/src/filetypes.cpp b/src/filetypes.cpp deleted file mode 100644 index d0c985b..0000000 --- a/src/filetypes.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "filetypes.h" - -#include "debugging/debugging.h" - -#include "ifiletypes.h" - -#include "string/string.h" -#include "os/path.h" -#include -#include - -class RadiantFileTypeRegistry : public IFileTypeRegistry { -struct filetype_copy_t { - filetype_copy_t(const char *moduleName, const filetype_t other) - : m_can_load(other.can_load), m_can_import(other.can_import), m_can_save(other.can_save), - m_moduleName(moduleName), m_name(other.name), m_pattern(other.pattern) - { - } - - const char *getModuleName() const - { - return m_moduleName.c_str(); - } - - filetype_t getType() const - { - return filetype_t(m_name.c_str(), m_pattern.c_str(), m_can_load, m_can_save, m_can_import); - } - - bool m_can_load; - bool m_can_import; - bool m_can_save; -private: - CopiedString m_moduleName; - CopiedString m_name; - CopiedString m_pattern; -}; - -typedef std::vector filetype_list_t; -std::map m_typelists; -public: -RadiantFileTypeRegistry() -{ - addType("*", "*", filetype_t("All Files", "*.*")); -} - -void addType(const char *moduleType, const char *moduleName, filetype_t type) -{ - m_typelists[moduleType].push_back(filetype_copy_t(moduleName, type)); -} - -void getTypeList(const char *moduleType, IFileTypeList *typelist, bool want_load, bool want_import, bool want_save) -{ - filetype_list_t &list_ref = m_typelists[moduleType]; - for (filetype_list_t::iterator i = list_ref.begin(); i != list_ref.end(); ++i) { - if (want_load && !(*i).m_can_load) { - return; - } - if (want_import && !(*i).m_can_import) { - return; - } - if (want_save && !(*i).m_can_save) { - return; - } - typelist->addType((*i).getModuleName(), (*i).getType()); - } -} -}; - -static RadiantFileTypeRegistry g_patterns; - -IFileTypeRegistry *GetFileTypeRegistry() -{ - return &g_patterns; -} - -const char *findModuleName(IFileTypeRegistry *registry, const char *moduleType, const char *extension) -{ - class SearchFileTypeList : public IFileTypeList { - char m_pattern[128]; - const char *m_moduleName; -public: - SearchFileTypeList(const char *ext) - : m_moduleName("") - { - m_pattern[0] = '*'; - m_pattern[1] = '.'; - strncpy(m_pattern + 2, ext, 125); - m_pattern[127] = '\0'; - } - - void addType(const char *moduleName, filetype_t type) - { - if (extension_equal(m_pattern, type.pattern)) { - m_moduleName = moduleName; - } - } - - const char *getModuleName() - { - return m_moduleName; - } - } search(extension); - registry->getTypeList(moduleType, &search); - return search.getModuleName(); -} - - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class FiletypesAPI { -IFileTypeRegistry *m_filetypes; -public: -typedef IFileTypeRegistry Type; - -STRING_CONSTANT(Name, "*"); - -FiletypesAPI() -{ - m_filetypes = GetFileTypeRegistry(); -} - -IFileTypeRegistry *getTable() -{ - return m_filetypes; -} -}; - -typedef SingletonModule FiletypesModule; -typedef Static StaticFiletypesModule; -StaticRegisterModule staticRegisterFiletypes(StaticFiletypesModule::instance()); diff --git a/src/filetypes.h b/src/filetypes.h deleted file mode 100644 index 60cabca..0000000 --- a/src/filetypes.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_FILETYPES_H ) -#define INCLUDED_FILETYPES_H - -class IFileTypeRegistry; - -IFileTypeRegistry *GetFileTypeRegistry(); - -const char *findModuleName(IFileTypeRegistry *registry, const char *moduleType, const char *extension); - -#endif diff --git a/src/filters.cpp b/src/filters.cpp deleted file mode 100644 index 78cb0ea..0000000 --- a/src/filters.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "filters.h" - -#include "debugging/debugging.h" - -#include "ifilter.h" - -#include "scenelib.h" - -#include -#include - -#include "gtkutil/widget.h" -#include "gtkutil/menu.h" -#include "gtkmisc.h" -#include "mainframe.h" -#include "commands.h" -#include "preferences.h" - -struct filters_globals_t { - std::size_t exclude; - - filters_globals_t() : - exclude(0) - { - } -}; - -filters_globals_t g_filters_globals; - -inline bool filter_active(int mask) -{ - return (g_filters_globals.exclude & mask) > 0; -} - -class FilterWrapper { -public: -FilterWrapper(Filter &filter, int mask) : m_filter(filter), m_mask(mask) -{ -} - -void update() -{ - m_filter.setActive(filter_active(m_mask)); -} - -private: -Filter &m_filter; -int m_mask; -}; - -typedef std::list Filters; -Filters g_filters; - -typedef std::set Filterables; -Filterables g_filterables; - -void UpdateFilters() -{ - { - for (Filters::iterator i = g_filters.begin(); i != g_filters.end(); ++i) { - (*i).update(); - } - } - - { - for (Filterables::iterator i = g_filterables.begin(); i != g_filterables.end(); ++i) { - (*i)->updateFiltered(); - } - } -} - - -class BasicFilterSystem : public FilterSystem { -public: -void addFilter(Filter &filter, int mask) -{ - g_filters.push_back(FilterWrapper(filter, mask)); - g_filters.back().update(); -} - -void registerFilterable(Filterable &filterable) -{ - ASSERT_MESSAGE(g_filterables.find(&filterable) == g_filterables.end(), "filterable already registered"); - filterable.updateFiltered(); - g_filterables.insert(&filterable); -} - -void unregisterFilterable(Filterable &filterable) -{ - ASSERT_MESSAGE(g_filterables.find(&filterable) != g_filterables.end(), "filterable not registered"); - g_filterables.erase(&filterable); -} -}; - -BasicFilterSystem g_FilterSystem; - -FilterSystem &GetFilterSystem() -{ - return g_FilterSystem; -} - -void PerformFiltering() -{ - UpdateFilters(); - SceneChangeNotify(); -} - -class ToggleFilterFlag { -const unsigned int m_mask; -public: -ToggleItem m_item; - -ToggleFilterFlag(unsigned int mask) : m_mask(mask), m_item(ActiveCaller(*this)) -{ -} - -ToggleFilterFlag(const ToggleFilterFlag &other) : m_mask(other.m_mask), m_item(ActiveCaller(*this)) -{ -} - -void active(const Callback &importCallback) -{ - importCallback((g_filters_globals.exclude & m_mask) != 0); -} - -typedef MemberCaller &), &ToggleFilterFlag::active> ActiveCaller; - -void toggle() -{ - g_filters_globals.exclude ^= m_mask; - m_item.update(); - PerformFiltering(); -} - -void reset() -{ - g_filters_globals.exclude = 0; - m_item.update(); - PerformFiltering(); -} - -typedef MemberCaller ToggleCaller; -}; - - -typedef std::list ToggleFilterFlags; -ToggleFilterFlags g_filter_items; - -void add_filter_command(unsigned int flag, const char *command, const Accelerator &accelerator) -{ - g_filter_items.push_back(ToggleFilterFlag(flag)); - GlobalToggles_insert(command, ToggleFilterFlag::ToggleCaller(g_filter_items.back()), - ToggleItem::AddCallbackCaller(g_filter_items.back().m_item), accelerator); -} - -void InvertFilters() -{ - std::list::iterator iter; - - for (iter = g_filter_items.begin(); iter != g_filter_items.end(); ++iter) { - iter->toggle(); - } -} - -void ResetFilters() -{ - std::list::iterator iter; - - for (iter = g_filter_items.begin(); iter != g_filter_items.end(); ++iter) { - iter->reset(); - } -} - -void Filters_constructMenu(ui::Menu menu_in_menu) -{ - create_check_menu_item_with_mnemonic(menu_in_menu, "World", "FilterWorldBrushes"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Groups", "FilterGroupBrushes"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Entities", "FilterEntities"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Areaportals", "FilterAreaportals"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Translucent", "FilterTranslucent"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Liquids", "FilterLiquids"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Caulk", "FilterCaulk"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Clips", "FilterClips"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Paths", "FilterPaths"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Clusterportals", "FilterClusterportals"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Lights", "FilterLights"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Structural", "FilterStructural"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Lightgrid", "FilterLightgrid"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Patches", "FilterPatches"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Details", "FilterDetails"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Hints", "FilterHintsSkips"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Models", "FilterModels"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Triggers", "FilterTriggers"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Botclips", "FilterBotClips"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Decals", "FilterDecals"); - - // filter manipulation - menu_separator(menu_in_menu); - create_menu_item_with_mnemonic(menu_in_menu, "Invert filters", "InvertFilters"); - create_menu_item_with_mnemonic(menu_in_menu, "Reset filters", "ResetFilters"); -} - - -#include "preferencesystem.h" -#include "stringio.h" - -void ConstructFilters() -{ - GlobalPreferenceSystem().registerPreference("SI_Exclude", make_property_string(g_filters_globals.exclude)); - - GlobalCommands_insert("InvertFilters", makeCallbackF(InvertFilters)); - GlobalCommands_insert("ResetFilters", makeCallbackF(ResetFilters)); - - add_filter_command(EXCLUDE_WORLD, "FilterWorldBrushes", Accelerator('1', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_GROUP, "FilterGroupBrushes", accelerator_null()); - add_filter_command(EXCLUDE_ENT, "FilterEntities", Accelerator('2', (GdkModifierType) GDK_MOD1_MASK)); - if (g_pGameDescription->mGameType == "doom3") { - add_filter_command(EXCLUDE_VISPORTALS, "FilterVisportals", Accelerator('3', (GdkModifierType) GDK_MOD1_MASK)); - } else { - add_filter_command(EXCLUDE_AREAPORTALS, "FilterAreaportals", Accelerator('3', (GdkModifierType) GDK_MOD1_MASK)); - } - add_filter_command(EXCLUDE_TRANSLUCENT, "FilterTranslucent", Accelerator('4', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_LIQUIDS, "FilterLiquids", Accelerator('5', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_CAULK, "FilterCaulk", Accelerator('6', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_CLIP, "FilterClips", Accelerator('7', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_PATHS, "FilterPaths", Accelerator('8', (GdkModifierType) GDK_MOD1_MASK)); - if (g_pGameDescription->mGameType != "doom3") { - add_filter_command(EXCLUDE_CLUSTERPORTALS, "FilterClusterportals", - Accelerator('9', (GdkModifierType) GDK_MOD1_MASK)); - } - add_filter_command(EXCLUDE_LIGHTS, "FilterLights", Accelerator('0', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_STRUCTURAL, "FilterStructural", - Accelerator('D', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - if (g_pGameDescription->mGameType != "doom3") { - add_filter_command(EXCLUDE_LIGHTGRID, "FilterLightgrid", accelerator_null()); - } - add_filter_command(EXCLUDE_CURVES, "FilterPatches", Accelerator('P', (GdkModifierType) GDK_CONTROL_MASK)); - add_filter_command(EXCLUDE_DETAILS, "FilterDetails", Accelerator('D', (GdkModifierType) GDK_CONTROL_MASK)); - add_filter_command(EXCLUDE_HINTSSKIPS, "FilterHintsSkips", Accelerator('H', (GdkModifierType) GDK_CONTROL_MASK)); - add_filter_command(EXCLUDE_MODELS, "FilterModels", Accelerator('M', (GdkModifierType) GDK_SHIFT_MASK)); - add_filter_command(EXCLUDE_TRIGGERS, "FilterTriggers", - Accelerator('T', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - if (g_pGameDescription->mGameType != "doom3") { - add_filter_command(EXCLUDE_BOTCLIP, "FilterBotClips", Accelerator('M', (GdkModifierType) GDK_MOD1_MASK)); - add_filter_command(EXCLUDE_DECALS, "FilterDecals", Accelerator('D', (GdkModifierType) GDK_SHIFT_MASK)); - } - - PerformFiltering(); -} - -void DestroyFilters() -{ - g_filters.clear(); -} - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class FilterAPI { -FilterSystem *m_filter; -public: -typedef FilterSystem Type; - -STRING_CONSTANT(Name, "*"); - -FilterAPI() -{ - ConstructFilters(); - - m_filter = &GetFilterSystem(); -} - -~FilterAPI() -{ - DestroyFilters(); -} - -FilterSystem *getTable() -{ - return m_filter; -} -}; - -typedef SingletonModule FilterModule; -typedef Static StaticFilterModule; -StaticRegisterModule staticRegisterFilter(StaticFilterModule::instance()); diff --git a/src/filters.h b/src/filters.h deleted file mode 100644 index 12c71cd..0000000 --- a/src/filters.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_FILTERS_H ) -#define INCLUDED_FILTERS_H - -void Filters_constructMenu(ui::Menu menu_in_menu); - -#endif diff --git a/src/findtexturedialog.cpp b/src/findtexturedialog.cpp deleted file mode 100644 index 4c7a4f3..0000000 --- a/src/findtexturedialog.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Find/Replace textures dialogs -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "findtexturedialog.h" - -#include - -#include "debugging/debugging.h" - -#include "ishaders.h" - -#include "gtkutil/window.h" -#include "stream/stringstream.h" - -#include "commands.h" -#include "dialog.h" -#include "select.h" -#include "textureentry.h" - - -class FindTextureDialog : public Dialog { -public: -static void setReplaceStr(const char *name); - -static void setFindStr(const char *name); - -static bool isOpen(); - -static void show(); - -typedef FreeCaller ShowCaller; - -static void updateTextures(const char *name); - -FindTextureDialog(); - -virtual ~FindTextureDialog(); - -ui::Window BuildDialog(); - -void constructWindow(ui::Window parent) -{ - m_parent = parent; - Create(); -} - -void destroyWindow() -{ - Destroy(); -} - - -bool m_bSelectedOnly; -CopiedString m_strFind; -CopiedString m_strReplace; -}; - -FindTextureDialog g_FindTextureDialog; -static bool g_bFindActive = true; - -namespace { -void FindTextureDialog_apply() -{ - StringOutputStream find(256); - StringOutputStream replace(256); - - find << "textures/" << g_FindTextureDialog.m_strFind.c_str(); - replace << "textures/" << g_FindTextureDialog.m_strReplace.c_str(); - FindReplaceTextures(find.c_str(), replace.c_str(), g_FindTextureDialog.m_bSelectedOnly); -} - -static void OnApply(ui::Widget widget, gpointer data) -{ - g_FindTextureDialog.exportData(); - FindTextureDialog_apply(); -} - -static void OnFind(ui::Widget widget, gpointer data) -{ - g_FindTextureDialog.exportData(); - FindTextureDialog_apply(); -} - -static void OnOK(ui::Widget widget, gpointer data) -{ - g_FindTextureDialog.exportData(); - FindTextureDialog_apply(); - g_FindTextureDialog.HideDlg(); -} - -static void OnClose(ui::Widget widget, gpointer data) -{ - g_FindTextureDialog.HideDlg(); -} - - -static gint find_focus_in(ui::Widget widget, GdkEventFocus *event, gpointer data) -{ - g_bFindActive = true; - return FALSE; -} - -static gint replace_focus_in(ui::Widget widget, GdkEventFocus *event, gpointer data) -{ - g_bFindActive = false; - return FALSE; -} -} - -// ============================================================================= -// FindTextureDialog class - -FindTextureDialog::FindTextureDialog() -{ - m_bSelectedOnly = FALSE; -} - -FindTextureDialog::~FindTextureDialog() -{ -} - -ui::Window FindTextureDialog::BuildDialog() -{ - ui::Widget label{ui::null}; - ui::Widget button{ui::null}; - ui::Entry entry{ui::null}; - - auto dlg = ui::Window(create_floating_window("Find / Replace Texture(s)", m_parent)); - - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - dlg.add(hbox); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); - - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - hbox.pack_start(vbox, TRUE, TRUE, 0); - - auto table = ui::Table(2, 2, FALSE); - table.show(); - vbox.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - label = ui::Label("Find:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - - label = ui::Label("Replace:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - - entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - entry.connect("focus_in_event", - G_CALLBACK(find_focus_in), 0); - AddDialogData(entry, m_strFind); - GlobalTextureEntryCompletion::instance().connect(entry); - - entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - entry.connect("focus_in_event", - G_CALLBACK(replace_focus_in), 0); - AddDialogData(entry, m_strReplace); - GlobalTextureEntryCompletion::instance().connect(entry); - - auto check = ui::CheckButton("Within selected brushes only"); - check.show(); - vbox.pack_start(check, TRUE, TRUE, 0); - AddDialogData(check, m_bSelectedOnly); - - vbox = ui::VBox(FALSE, 5); - vbox.show(); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - button = ui::Button("Apply"); - button.show(); - vbox.pack_start(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(OnApply), 0); - button.dimensions(60, -1); - - button = ui::Button("Close"); - button.show(); - vbox.pack_start(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(OnClose), 0); - button.dimensions(60, -1); - - return dlg; -} - -void FindTextureDialog::updateTextures(const char *name) -{ - if (isOpen()) { - if (g_bFindActive) { - setFindStr(name + 9); - } else { - setReplaceStr(name + 9); - } - } -} - -bool FindTextureDialog::isOpen() -{ - return g_FindTextureDialog.GetWidget().visible(); -} - -void FindTextureDialog::setFindStr(const char *name) -{ - g_FindTextureDialog.exportData(); - g_FindTextureDialog.m_strFind = name; - g_FindTextureDialog.importData(); -} - -void FindTextureDialog::setReplaceStr(const char *name) -{ - g_FindTextureDialog.exportData(); - g_FindTextureDialog.m_strReplace = name; - g_FindTextureDialog.importData(); -} - -void FindTextureDialog::show() -{ - g_FindTextureDialog.ShowDlg(); -} - - -void FindTextureDialog_constructWindow(ui::Window main_window) -{ - g_FindTextureDialog.constructWindow(main_window); -} - -void FindTextureDialog_destroyWindow() -{ - g_FindTextureDialog.destroyWindow(); -} - -bool FindTextureDialog_isOpen() -{ - return g_FindTextureDialog.isOpen(); -} - -void FindTextureDialog_selectTexture(const char *name) -{ - g_FindTextureDialog.updateTextures(name); -} - -void FindTextureDialog_Construct() -{ - GlobalCommands_insert("FindReplaceTextures", FindTextureDialog::ShowCaller()); -} - -void FindTextureDialog_Destroy() -{ -} diff --git a/src/findtexturedialog.h b/src/findtexturedialog.h deleted file mode 100644 index a367c15..0000000 --- a/src/findtexturedialog.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_FINDTEXTUREDIALOG_H ) -#define INCLUDED_FINDTEXTUREDIALOG_H - -void FindTextureDialog_Construct(); - -void FindTextureDialog_Destroy(); - -void FindTextureDialog_constructWindow(ui::Window main_window); - -void FindTextureDialog_destroyWindow(); - -bool FindTextureDialog_isOpen(); - -void FindTextureDialog_selectTexture(const char *name); - -#endif diff --git a/tools/vmap/fixaas.c b/src/fixaas.c similarity index 100% rename from tools/vmap/fixaas.c rename to src/fixaas.c diff --git a/tools/vmap/fog.c b/src/fog.c similarity index 100% rename from tools/vmap/fog.c rename to src/fog.c diff --git a/tools/vmap/game__null.h b/src/game__null.h similarity index 100% rename from tools/vmap/game__null.h rename to src/game__null.h diff --git a/tools/vmap/game_fte.h b/src/game_fte.h similarity index 100% rename from tools/vmap/game_fte.h rename to src/game_fte.h diff --git a/src/glwidget.cpp b/src/glwidget.cpp deleted file mode 100644 index 59d53cf..0000000 --- a/src/glwidget.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "glwidget.h" - -#include "igtkgl.h" -#include "modulesystem.h" -#include "gtkutil/glwidget.h" - -class GtkGLAPI { -_QERGtkGLTable m_gtkgl; -public: -typedef _QERGtkGLTable Type; - -STRING_CONSTANT(Name, "*"); - -GtkGLAPI() -{ - m_gtkgl.glwidget_new = &glwidget_new; - m_gtkgl.glwidget_swap_buffers = &glwidget_swap_buffers; - m_gtkgl.glwidget_make_current = &glwidget_make_current; - m_gtkgl.glwidget_destroy_context = &glwidget_destroy_context; - m_gtkgl.glwidget_create_context = &glwidget_create_context; -} - -_QERGtkGLTable *getTable() -{ - return &m_gtkgl; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule GtkGLModule; -typedef Static StaticGtkGLModule; -StaticRegisterModule staticRegisterGtkGL(StaticGtkGLModule::instance()); diff --git a/src/glwidget.h b/src/glwidget.h deleted file mode 100644 index 0adad26..0000000 --- a/src/glwidget.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GLWIDGET_H ) -#define INCLUDED_GLWIDGET_H - -#endif diff --git a/src/grid.cpp b/src/grid.cpp deleted file mode 100644 index 57cc84b..0000000 --- a/src/grid.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "grid.h" - -#include -#include -#include - -#include "preferencesystem.h" - -#include "gtkutil/widget.h" -#include "signal/signal.h" -#include "stringio.h" - -#include "gtkmisc.h" -#include "commands.h" -#include "preferences.h" - - -Signal0 g_gridChange_callbacks; - -void AddGridChangeCallback(const SignalHandler &handler) -{ - g_gridChange_callbacks.connectLast(handler); - handler(); -} - -void GridChangeNotify() -{ - g_gridChange_callbacks(); -} - -enum GridPower { - GRIDPOWER_0125 = -3, - GRIDPOWER_025 = -2, - GRIDPOWER_05 = -1, - GRIDPOWER_1 = 0, - GRIDPOWER_2 = 1, - GRIDPOWER_4 = 2, - GRIDPOWER_8 = 3, - GRIDPOWER_16 = 4, - GRIDPOWER_32 = 5, - GRIDPOWER_64 = 6, - GRIDPOWER_128 = 7, - GRIDPOWER_256 = 8, -}; - - -typedef const char *GridName; -// this must match the GridPower enumeration -const GridName g_gridnames[] = { - "0.125", - "0.25", - "0.5", - "1", - "2", - "4", - "8", - "16", - "32", - "64", - "128", - "256", -}; - -inline GridPower GridPower_forGridDefault(int gridDefault) -{ - return static_cast( gridDefault - 3 ); -} - -inline int GridDefault_forGridPower(GridPower gridPower) -{ - return gridPower + 3; -} - -int g_grid_default = GridDefault_forGridPower(GRIDPOWER_8); - -int g_grid_power = GridPower_forGridDefault(g_grid_default); - -bool g_grid_snap = true; - -int Grid_getPower() -{ - return g_grid_power; -} - -inline float GridSize_forGridPower(int gridPower) -{ - return pow(2.0f, gridPower); -} - -float g_gridsize = GridSize_forGridPower(g_grid_power); - -float GetSnapGridSize() -{ - return g_grid_snap ? g_gridsize : 0; -} - -float GetGridSize() -{ - return g_gridsize; -} - - -void setGridPower(GridPower power); - -class GridMenuItem { -GridPower m_id; - -GridMenuItem(const GridMenuItem &other); // NOT COPYABLE -GridMenuItem &operator=(const GridMenuItem &other); // NOT ASSIGNABLE -public: -ToggleItem m_item; - -GridMenuItem(GridPower id) : m_id(id), m_item(ExportCaller(*this)) -{ -} - -void set() -{ - g_grid_power = m_id; - m_item.update(); - setGridPower(m_id); -} - -typedef MemberCaller SetCaller; - -void active(const Callback &importCallback) -{ - importCallback(g_grid_power == m_id); -} - -typedef MemberCaller &), &GridMenuItem::active> ExportCaller; -}; - -GridMenuItem g_gridMenu0125(GRIDPOWER_0125); -GridMenuItem g_gridMenu025(GRIDPOWER_025); -GridMenuItem g_gridMenu05(GRIDPOWER_05); -GridMenuItem g_gridMenu1(GRIDPOWER_1); -GridMenuItem g_gridMenu2(GRIDPOWER_2); -GridMenuItem g_gridMenu4(GRIDPOWER_4); -GridMenuItem g_gridMenu8(GRIDPOWER_8); -GridMenuItem g_gridMenu16(GRIDPOWER_16); -GridMenuItem g_gridMenu32(GRIDPOWER_32); -GridMenuItem g_gridMenu64(GRIDPOWER_64); -GridMenuItem g_gridMenu128(GRIDPOWER_128); -GridMenuItem g_gridMenu256(GRIDPOWER_256); - -void setGridPower(GridPower power) -{ - g_grid_snap = true; - g_gridsize = GridSize_forGridPower(power); - - g_gridMenu0125.m_item.update(); - g_gridMenu025.m_item.update(); - g_gridMenu05.m_item.update(); - g_gridMenu1.m_item.update(); - g_gridMenu2.m_item.update(); - g_gridMenu4.m_item.update(); - g_gridMenu8.m_item.update(); - g_gridMenu16.m_item.update(); - g_gridMenu32.m_item.update(); - g_gridMenu64.m_item.update(); - g_gridMenu128.m_item.update(); - g_gridMenu256.m_item.update(); - GridChangeNotify(); -} - -void GridPrev() -{ - g_grid_snap = true; - if (g_grid_power > GRIDPOWER_0125) { - setGridPower(static_cast( --g_grid_power )); - } -} - -void GridNext() -{ - g_grid_snap = true; - if (g_grid_power < GRIDPOWER_256) { - setGridPower(static_cast( ++g_grid_power )); - } -} - -void ToggleGridSnap() -{ - g_grid_snap = !g_grid_snap; - GridChangeNotify(); -} - -void Grid_registerCommands() -{ - GlobalCommands_insert("GridDown", makeCallbackF(GridPrev), Accelerator('[')); - GlobalCommands_insert("GridUp", makeCallbackF(GridNext), Accelerator(']')); - - GlobalCommands_insert("ToggleGridSnap", makeCallbackF(ToggleGridSnap)); - - GlobalToggles_insert("SetGrid0.125", GridMenuItem::SetCaller(g_gridMenu0125), - ToggleItem::AddCallbackCaller(g_gridMenu0125.m_item)); - GlobalToggles_insert("SetGrid0.25", GridMenuItem::SetCaller(g_gridMenu025), - ToggleItem::AddCallbackCaller(g_gridMenu025.m_item)); - GlobalToggles_insert("SetGrid0.5", GridMenuItem::SetCaller(g_gridMenu05), - ToggleItem::AddCallbackCaller(g_gridMenu05.m_item)); - GlobalToggles_insert("SetGrid1", GridMenuItem::SetCaller(g_gridMenu1), - ToggleItem::AddCallbackCaller(g_gridMenu1.m_item), Accelerator('1')); - GlobalToggles_insert("SetGrid2", GridMenuItem::SetCaller(g_gridMenu2), - ToggleItem::AddCallbackCaller(g_gridMenu2.m_item), Accelerator('2')); - GlobalToggles_insert("SetGrid4", GridMenuItem::SetCaller(g_gridMenu4), - ToggleItem::AddCallbackCaller(g_gridMenu4.m_item), Accelerator('3')); - GlobalToggles_insert("SetGrid8", GridMenuItem::SetCaller(g_gridMenu8), - ToggleItem::AddCallbackCaller(g_gridMenu8.m_item), Accelerator('4')); - GlobalToggles_insert("SetGrid16", GridMenuItem::SetCaller(g_gridMenu16), - ToggleItem::AddCallbackCaller(g_gridMenu16.m_item), Accelerator('5')); - GlobalToggles_insert("SetGrid32", GridMenuItem::SetCaller(g_gridMenu32), - ToggleItem::AddCallbackCaller(g_gridMenu32.m_item), Accelerator('6')); - GlobalToggles_insert("SetGrid64", GridMenuItem::SetCaller(g_gridMenu64), - ToggleItem::AddCallbackCaller(g_gridMenu64.m_item), Accelerator('7')); - GlobalToggles_insert("SetGrid128", GridMenuItem::SetCaller(g_gridMenu128), - ToggleItem::AddCallbackCaller(g_gridMenu128.m_item), Accelerator('8')); - GlobalToggles_insert("SetGrid256", GridMenuItem::SetCaller(g_gridMenu256), - ToggleItem::AddCallbackCaller(g_gridMenu256.m_item), Accelerator('9')); -} - - -void Grid_constructMenu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "Grid0.125", "SetGrid0.125"); - create_check_menu_item_with_mnemonic(menu, "Grid0.25", "SetGrid0.25"); - create_check_menu_item_with_mnemonic(menu, "Grid0.5", "SetGrid0.5"); - create_check_menu_item_with_mnemonic(menu, "Grid1", "SetGrid1"); - create_check_menu_item_with_mnemonic(menu, "Grid2", "SetGrid2"); - create_check_menu_item_with_mnemonic(menu, "Grid4", "SetGrid4"); - create_check_menu_item_with_mnemonic(menu, "Grid8", "SetGrid8"); - create_check_menu_item_with_mnemonic(menu, "Grid16", "SetGrid16"); - create_check_menu_item_with_mnemonic(menu, "Grid32", "SetGrid32"); - create_check_menu_item_with_mnemonic(menu, "Grid64", "SetGrid64"); - create_check_menu_item_with_mnemonic(menu, "Grid128", "SetGrid128"); - create_check_menu_item_with_mnemonic(menu, "Grid256", "SetGrid256"); -} - -void Grid_registerShortcuts() -{ - command_connect_accelerator("ToggleGrid"); - command_connect_accelerator("GridDown"); - command_connect_accelerator("GridUp"); - command_connect_accelerator("ToggleGridSnap"); -} - -void Grid_constructPreferences(PreferencesPage &page) -{ - page.appendCombo( - "Default grid spacing", - g_grid_default, - ARRAY_RANGE(g_gridnames) - ); -} - -void Grid_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Grid", "Grid Settings")); - Grid_constructPreferences(page); -} - -void Grid_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Grid_constructPage)); -} - -void Grid_construct() -{ - Grid_registerPreferencesPage(); - - g_grid_default = GridDefault_forGridPower(GRIDPOWER_8); - - GlobalPreferenceSystem().registerPreference("GridDefault", make_property_string(g_grid_default)); - - g_grid_power = GridPower_forGridDefault(g_grid_default); - g_gridsize = GridSize_forGridPower(g_grid_power); -} - -void Grid_destroy() -{ -} diff --git a/src/grid.h b/src/grid.h deleted file mode 100644 index 513f4a0..0000000 --- a/src/grid.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GRID_H ) -#define INCLUDED_GRID_H - -#include -#include "signal/signalfwd.h" - -float GetSnapGridSize(); - -float GetGridSize(); - -int Grid_getPower(); - -void AddGridChangeCallback(const SignalHandler &handler); - -void Grid_registerCommands(); - -void Grid_constructMenu(ui::Menu menu); - -void Grid_registerShortcuts(); - -void Grid_construct(); - -void Grid_destroy(); - -#endif diff --git a/src/groupdialog.cpp b/src/groupdialog.cpp deleted file mode 100644 index 318bcb3..0000000 --- a/src/groupdialog.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Floating dialog that contains a notebook with at least Entities and Group tabs -// I merged the 2 MS Windows dialogs in a single class -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "groupdialog.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include -#include - -#include "gtkutil/widget.h" -#include "gtkutil/accelerator.h" -#include "entityinspector.h" -#include "gtkmisc.h" -#include "multimon.h" -#include "console.h" -#include "commands.h" - - -#include "gtkutil/window.h" - -class GroupDlg { -public: -ui::Widget m_pNotebook{ui::null}; -ui::Window m_window{ui::null}; - -GroupDlg(); - -void Create(ui::Window parent); - -void Show() -{ - // workaround for strange gtk behaviour - modifying the contents of a window while it is not visible causes the window position to change without sending a configure_event - m_position_tracker.sync(m_window); - m_window.show(); -} - -void Hide() -{ - m_window.hide(); -} - -WindowPositionTracker m_position_tracker; -}; - -namespace { -GroupDlg g_GroupDlg; - -std::size_t g_current_page; -std::vector &)> > g_pages; -} - -void GroupDialog_updatePageTitle(ui::Window window, std::size_t pageIndex) -{ - if (pageIndex < g_pages.size()) { - g_pages[pageIndex](PointerCaller(window)); - } -} - -static gboolean switch_page(GtkNotebook *notebook, gpointer page, guint page_num, gpointer data) -{ - GroupDialog_updatePageTitle(ui::Window::from(data), page_num); - g_current_page = page_num; - - return FALSE; -} - -GroupDlg::GroupDlg() : m_window(ui::null) -{ - m_position_tracker.setPosition(c_default_window_pos); -} - -void GroupDlg::Create(ui::Window parent) -{ - ASSERT_MESSAGE(!m_window, "dialog already created"); - - auto window = ui::Window(create_persistent_floating_window("Entities", parent)); - gtk_window_set_keep_above(GTK_WINDOW(window), TRUE); - - global_accel_connect_window(window); - - window_connect_focus_in_clear_focus_widget(window); - - m_window = window; - -#if GDEF_OS_WINDOWS - if ( g_multimon_globals.m_bStartOnPrimMon ) { - WindowPosition pos( m_position_tracker.getPosition() ); - PositionWindowOnPrimaryScreen( pos ); - m_position_tracker.setPosition( pos ); - } -#endif - m_position_tracker.connect(window); - - { - ui::Widget notebook = ui::Widget::from(gtk_notebook_new()); - notebook.show(); - window.add(notebook); - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM); - m_pNotebook = notebook; - - notebook.connect("switch_page", G_CALLBACK(switch_page), (gpointer) window); - } -} - - -ui::Widget GroupDialog_addPage(const char *tabLabel, ui::Widget widget, - const Callback &)> &title) -{ - ui::Widget w = ui::Label(tabLabel); - w.show(); - auto page = ui::Widget::from(gtk_notebook_get_nth_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), - gtk_notebook_insert_page( - GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), widget, w, - -1))); - g_pages.push_back(title); - - return page; -} - - -bool GroupDialog_isShown() -{ - return g_GroupDlg.m_window.visible(); -} - -void GroupDialog_setShown(bool shown) -{ - shown ? g_GroupDlg.Show() : g_GroupDlg.Hide(); -} - -void GroupDialog_ToggleShow() -{ - GroupDialog_setShown(!GroupDialog_isShown()); -} - -void GroupDialog_constructWindow(ui::Window main_window) -{ - g_GroupDlg.Create(main_window); -} - -void GroupDialog_destroyWindow() -{ - ASSERT_TRUE(g_GroupDlg.m_window); - destroy_floating_window(g_GroupDlg.m_window); - g_GroupDlg.m_window = ui::Window{ui::null}; -} - - -ui::Window GroupDialog_getWindow() -{ - return ui::Window(g_GroupDlg.m_window); -} - -void GroupDialog_show() -{ - g_GroupDlg.Show(); -} - -ui::Widget GroupDialog_getPage() -{ - return ui::Widget::from(gtk_notebook_get_nth_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), gint(g_current_page))); -} - -void GroupDialog_setPage(ui::Widget page) -{ - g_current_page = gtk_notebook_page_num(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), page); - gtk_notebook_set_current_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), gint(g_current_page)); -} - -void GroupDialog_showPage(ui::Widget page) -{ - if (GroupDialog_getPage() == page) { - GroupDialog_ToggleShow(); - } else { - g_GroupDlg.m_window.show(); - GroupDialog_setPage(page); - } -} - -void GroupDialog_cycle() -{ - g_current_page = (g_current_page + 1) % g_pages.size(); - gtk_notebook_set_current_page(GTK_NOTEBOOK(g_GroupDlg.m_pNotebook), gint(g_current_page)); -} - -void GroupDialog_updatePageTitle(ui::Widget page) -{ - if (GroupDialog_getPage() == page) { - GroupDialog_updatePageTitle(g_GroupDlg.m_window, g_current_page); - } -} - - -#include "preferencesystem.h" - -void GroupDialog_Construct() -{ - GlobalPreferenceSystem().registerPreference("EntityWnd", make_property( - g_GroupDlg.m_position_tracker)); - - GlobalCommands_insert("ViewEntityInfo", makeCallbackF(GroupDialog_ToggleShow), Accelerator('N')); -} - -void GroupDialog_Destroy() -{ -} diff --git a/src/groupdialog.h b/src/groupdialog.h deleted file mode 100644 index bf0026c..0000000 --- a/src/groupdialog.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_GROUPDIALOG_H ) -#define INCLUDED_GROUPDIALOG_H - -#include -#include "property.h" -#include "generic/callback.h" - -void GroupDialog_Construct(); - -void GroupDialog_Destroy(); - -void GroupDialog_constructWindow(ui::Window main_window); - -void GroupDialog_destroyWindow(); - -ui::Window GroupDialog_getWindow(); - -void GroupDialog_show(); - -inline void RawStringExport(const char *string, const Callback &importer) -{ - importer(string); -} - -typedef ConstPointerCaller &), RawStringExport> RawStringExportCaller; - -ui::Widget GroupDialog_addPage(const char *tabLabel, ui::Widget widget, - const Callback &)> &title); - -void GroupDialog_showPage(ui::Widget page); - -void GroupDialog_updatePageTitle(ui::Widget page); - -bool GroupDialog_isShown(); - -ui::Widget GroupDialog_getPage(); - -#endif diff --git a/src/gtkdlgs.cpp b/src/gtkdlgs.cpp deleted file mode 100644 index c6ad9d7..0000000 --- a/src/gtkdlgs.cpp +++ /dev/null @@ -1,1022 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Some small dialogs that don't need much -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "gtkdlgs.h" -#include "globaldefs.h" - -#include - -#include "debugging/debugging.h" - -#include "igl.h" -#include "iscenegraph.h" -#include "iselection.h" - -#include -#include - -#include "os/path.h" -#include "math/aabb.h" -#include "container/array.h" -#include "generic/static.h" -#include "stream/stringstream.h" -#include "convert.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/image.h" - -#include "gtkmisc.h" -#include "brushmanip.h" -#include "build.h" -#include "qe3.h" -#include "texwindow.h" -#include "xywindow.h" -#include "mainframe.h" -#include "preferences.h" -#include "url.h" -#include "cmdlib.h" - - - -// ============================================================================= -// Project settings dialog - -class GameComboConfiguration { -public: -const char *basegame_dir; -const char *basegame; -const char *known_dir; -const char *known; -const char *custom; - -GameComboConfiguration() : - basegame_dir(g_pGameDescription->getRequiredKeyValue("basegame")), - basegame(g_pGameDescription->getRequiredKeyValue("basegamename")), - known_dir(g_pGameDescription->getKeyValue("knowngame")), - known(g_pGameDescription->getKeyValue("knowngamename")), - custom(g_pGameDescription->getRequiredKeyValue("unknowngamename")) -{ -} -}; - -typedef LazyStatic LazyStaticGameComboConfiguration; - -inline GameComboConfiguration &globalGameComboConfiguration() -{ - return LazyStaticGameComboConfiguration::instance(); -} - - -struct gamecombo_t { - gamecombo_t(int _game, const char *_fs_game, bool _sensitive) - : game(_game), fs_game(_fs_game), sensitive(_sensitive) - { - } - - int game; - const char *fs_game; - bool sensitive; -}; - -gamecombo_t gamecombo_for_dir(const char *dir) -{ - if (string_equal(dir, globalGameComboConfiguration().basegame_dir)) { - return gamecombo_t(0, "", false); - } else if (string_equal(dir, globalGameComboConfiguration().known_dir)) { - return gamecombo_t(1, dir, false); - } else { - return gamecombo_t(string_empty(globalGameComboConfiguration().known_dir) ? 1 : 2, dir, true); - } -} - -gamecombo_t gamecombo_for_gamename(const char *gamename) -{ - if ((strlen(gamename) == 0) || !strcmp(gamename, globalGameComboConfiguration().basegame)) { - return gamecombo_t(0, "", false); - } else if (!strcmp(gamename, globalGameComboConfiguration().known)) { - return gamecombo_t(1, globalGameComboConfiguration().known_dir, false); - } else { - return gamecombo_t(string_empty(globalGameComboConfiguration().known_dir) ? 1 : 2, "", true); - } -} - -inline void path_copy_clean(char *destination, const char *source) -{ - char *i = destination; - - while (*source != '\0') { - *i++ = (*source == '\\') ? '/' : *source; - ++source; - } - - if (i != destination && *(i - 1) != '/') { - *(i++) = '/'; - } - - *i = '\0'; -} - - -struct GameCombo { - ui::ComboBoxText game_select{ui::null}; - ui::Entry fsgame_entry{ui::null}; -}; - -gboolean OnSelchangeComboWhatgame(ui::Widget widget, GameCombo *combo) -{ - const char *gamename; - { - GtkTreeIter iter; - gtk_combo_box_get_active_iter(combo->game_select, &iter); - gtk_tree_model_get(gtk_combo_box_get_model(combo->game_select), &iter, 0, (gpointer *) &gamename, -1); - } - - gamecombo_t gamecombo = gamecombo_for_gamename(gamename); - - combo->fsgame_entry.text(gamecombo.fs_game); - gtk_widget_set_sensitive(combo->fsgame_entry, gamecombo.sensitive); - - return FALSE; -} - -class MappingMode { -public: -bool do_mapping_mode; -const char *sp_mapping_mode; -const char *mp_mapping_mode; - -MappingMode() : - do_mapping_mode(!string_empty(g_pGameDescription->getKeyValue("show_gamemode"))), - sp_mapping_mode("Single Player mapping mode"), - mp_mapping_mode("Multiplayer mapping mode") -{ -} -}; - -typedef LazyStatic LazyStaticMappingMode; - -inline MappingMode &globalMappingMode() -{ - return LazyStaticMappingMode::instance(); -} - -class ProjectSettingsDialog { -public: -GameCombo game_combo; -ui::ComboBox gamemode_combo{ui::null}; -}; - -ui::Window ProjectSettingsDialog_construct(ProjectSettingsDialog &dialog, ModalDialog &modal) -{ - auto window = MainFrame_getWindow().create_dialog_window("Project Settings", G_CALLBACK(dialog_delete_callback), - &modal); - - { - auto table1 = create_dialog_table(1, 2, 4, 4, 4); - window.add(table1); - { - auto vbox = create_dialog_vbox(4); - table1.attach(vbox, {1, 2, 0, 1}, {GTK_FILL, GTK_FILL}); - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &modal); - vbox.pack_start(button, FALSE, FALSE, 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &modal); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - { - auto frame = create_dialog_frame("Project settings"); - table1.attach(frame, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, GTK_FILL}); - { - auto table2 = create_dialog_table((globalMappingMode().do_mapping_mode) ? 4 : 3, 2, 4, 4, 4); - frame.add(table2); - - { - auto label = ui::Label("Select mod"); - label.show(); - table2.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - } - { - dialog.game_combo.game_select = ui::ComboBoxText(ui::New); - - gtk_combo_box_text_append_text(dialog.game_combo.game_select, - globalGameComboConfiguration().basegame); - if (globalGameComboConfiguration().known[0] != '\0') { - gtk_combo_box_text_append_text(dialog.game_combo.game_select, - globalGameComboConfiguration().known); - } - gtk_combo_box_text_append_text(dialog.game_combo.game_select, - globalGameComboConfiguration().custom); - - dialog.game_combo.game_select.show(); - table2.attach(dialog.game_combo.game_select, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - dialog.game_combo.game_select.connect("changed", G_CALLBACK(OnSelchangeComboWhatgame), - &dialog.game_combo); - } - - { - auto label = ui::Label("fs_game"); - label.show(); - table2.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table2.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - dialog.game_combo.fsgame_entry = entry; - } - - if (globalMappingMode().do_mapping_mode) { - auto label = ui::Label("Mapping mode"); - label.show(); - table2.attach(label, {0, 1, 3, 4}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - - auto combo = ui::ComboBoxText(ui::New); - gtk_combo_box_text_append_text(combo, globalMappingMode().sp_mapping_mode); - gtk_combo_box_text_append_text(combo, globalMappingMode().mp_mapping_mode); - - combo.show(); - table2.attach(combo, {1, 2, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - - dialog.gamemode_combo = combo; - } - } - } - } - - // initialise the fs_game selection from the project settings into the dialog - const char *dir = gamename_get(); - gamecombo_t gamecombo = gamecombo_for_dir(dir); - - gtk_combo_box_set_active(dialog.game_combo.game_select, gamecombo.game); - dialog.game_combo.fsgame_entry.text(gamecombo.fs_game); - gtk_widget_set_sensitive(dialog.game_combo.fsgame_entry, gamecombo.sensitive); - - if (globalMappingMode().do_mapping_mode) { - const char *gamemode = gamemode_get(); - if (string_empty(gamemode) || string_equal(gamemode, "sp")) { - gtk_combo_box_set_active(dialog.gamemode_combo, 0); - } else { - gtk_combo_box_set_active(dialog.gamemode_combo, 1); - } - } - - return window; -} - -void ProjectSettingsDialog_ok(ProjectSettingsDialog &dialog) -{ - const char *dir = gtk_entry_get_text(dialog.game_combo.fsgame_entry); - - const char *new_gamename = path_equal(dir, globalGameComboConfiguration().basegame_dir) - ? "" - : dir; - - if (!path_equal(new_gamename, gamename_get())) { - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Changing Game Name"); - - EnginePath_Unrealise(); - - gamename_set(new_gamename); - - EnginePath_Realise(); - } - - if (globalMappingMode().do_mapping_mode) { - // read from gamemode_combo - int active = gtk_combo_box_get_active(dialog.gamemode_combo); - if (active == -1 || active == 0) { - gamemode_set("sp"); - } else { - gamemode_set("mp"); - } - } -} - -void DoProjectSettings() -{ - if (ConfirmModified("Edit Project Settings")) { - ModalDialog modal; - ProjectSettingsDialog dialog; - - ui::Window window = ProjectSettingsDialog_construct(dialog, modal); - - if (modal_dialog_show(window, modal) == eIDOK) { - ProjectSettingsDialog_ok(dialog); - } - - window.destroy(); - } -} - -// ============================================================================= -// Arbitrary Sides dialog - -void DoSides(int type, int axis) -{ - ModalDialog dialog; - - auto window = MainFrame_getWindow().create_dialog_window("Arbitrary sides", G_CALLBACK(dialog_delete_callback), - &dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - auto sides_entry = ui::Entry(ui::New); - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto label = ui::Label("Sides:"); - label.show(); - hbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto entry = sides_entry; - entry.show(); - hbox.pack_start(entry, FALSE, FALSE, 0); - gtk_widget_grab_focus(entry); - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - } - } - - if (modal_dialog_show(window, dialog) == eIDOK) { - const char *str = gtk_entry_get_text(sides_entry); - - Scene_BrushConstructPrefab(GlobalSceneGraph(), (EBrushPrefab) type, atoi(str), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - } - - window.destroy(); -} - -// ============================================================================= -// About dialog (no program is complete without one) -void DoAbout() -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - - auto window = MainFrame_getWindow().create_modal_dialog_window("About WorldSpawn", dialog); - - { - auto vbox = create_dialog_vbox(4, 4); - window.add(vbox); - - { - auto hbox = create_dialog_hbox(4); - vbox.pack_start(hbox, FALSE, TRUE, 0); - - { - auto vbox2 = create_dialog_vbox(4); - hbox.pack_start(vbox2, TRUE, FALSE, 0); - { - auto frame = create_dialog_frame(0, ui::Shadow::IN); - vbox2.pack_start(frame, FALSE, FALSE, 0); - { - auto image = new_local_image("logo.xpm"); - image.show(); - frame.add(image); - } - } - } - - { - char const *label_text = "WorldSpawn 1.0\n" - "Build " __DATE__ "\n\n" - "Copyright (c) Vera Visions, LLC.\n\n" - "This product contains software\n" - "technology from id Software, Inc.\n\n" - "id Technology (c) 2000 id Software, Inc."; - - auto label = ui::Label(label_text); - - label.show(); - hbox.pack_start(label, FALSE, FALSE, 0); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - } - - { - auto vbox2 = create_dialog_vbox(4); - hbox.pack_start(vbox2, FALSE, TRUE, 0); - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox2.pack_start(button, FALSE, FALSE, 0); - } - } - } - { - auto frame = create_dialog_frame("OpenGL Properties"); - vbox.pack_start(frame, FALSE, FALSE, 0); - { - auto table = create_dialog_table(3, 2, 4, 4, 4); - frame.add(table); - { - auto label = ui::Label("Vendor:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Version:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Renderer:"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label(reinterpret_cast( glGetString(GL_VENDOR))); - label.show(); - table.attach(label, {1, 2, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label(reinterpret_cast( glGetString(GL_VERSION))); - label.show(); - table.attach(label, {1, 2, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label(reinterpret_cast( glGetString(GL_RENDERER))); - label.show(); - table.attach(label, {1, 2, 2, 3}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - } - { - auto frame = create_dialog_frame("OpenGL Extensions"); - vbox.pack_start(frame, TRUE, TRUE, 0); - { - auto sc_extensions = create_scrolled_window(ui::Policy::AUTOMATIC, ui::Policy::ALWAYS, 4); - frame.add(sc_extensions); - { - auto text_extensions = ui::TextView(ui::New); - gtk_text_view_set_editable(text_extensions, FALSE); - sc_extensions.add(text_extensions); - text_extensions.text(reinterpret_cast(glGetString(GL_EXTENSIONS))); - gtk_text_view_set_wrap_mode(text_extensions, GTK_WRAP_WORD); - text_extensions.show(); - } - } - } - } - } - - modal_dialog_show(window, dialog); - - window.destroy(); -} - -// ============================================================================= -// TextureLayout dialog - -// Last used texture scale values -static float last_used_texture_layout_scale_x = 4.0; -static float last_used_texture_layout_scale_y = 4.0; - -EMessageBoxReturn DoTextureLayout(float *fx, float *fy) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - ui::Entry x{ui::null}; - ui::Entry y{ui::null}; - - auto window = MainFrame_getWindow().create_modal_dialog_window("Patch texture layout", dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto label = ui::Label("Texture will be fit across the patch based\n" - "on the x and y values given. Values of 1x1\n" - "will \"fit\" the texture. 2x2 will repeat\n" - "it twice, etc."); - label.show(); - vbox.pack_start(label, TRUE, TRUE, 0); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - } - { - auto table = create_dialog_table(2, 2, 4, 4); - table.show(); - vbox.pack_start(table, TRUE, TRUE, 0); - { - auto label = ui::Label("Texture x:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Texture y:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - x = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - y = entry; - } - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - } - } - - // Initialize with last used values - char buf[16]; - - sprintf(buf, "%f", last_used_texture_layout_scale_x); - x.text(buf); - - sprintf(buf, "%f", last_used_texture_layout_scale_y); - y.text(buf); - - // Set focus after intializing the values - gtk_widget_grab_focus(x); - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - if (ret == eIDOK) { - *fx = static_cast( atof(gtk_entry_get_text(x))); - *fy = static_cast( atof(gtk_entry_get_text(y))); - - // Remember last used values - last_used_texture_layout_scale_x = *fx; - last_used_texture_layout_scale_y = *fy; - } - - window.destroy(); - - return ret; -} - -// ============================================================================= -// Text Editor dialog - -// master window widget -static ui::Window text_editor{ui::null}; -static ui::Widget text_widget{ui::null}; // slave, text widget from the gtk editor - -static gint editor_delete(ui::Widget widget, gpointer data) -{ - if (ui::alert(widget.window(), "Close the shader editor ?", "V-Editor", ui::alert_type::YESNO, - ui::alert_icon::Question) == ui::alert_response::NO) { - return TRUE; - } - - text_editor.hide(); - - return TRUE; -} - -static void editor_save(ui::Widget widget, gpointer data) -{ - FILE *f = fopen((char *) g_object_get_data(G_OBJECT(data), "filename"), "w"); - gpointer text = g_object_get_data(G_OBJECT(data), "text"); - - if (f == 0) { - ui::alert(ui::Widget::from(data).window(), "Error saving file !"); - return; - } - - char *str = gtk_editable_get_chars(GTK_EDITABLE(text), 0, -1); - fwrite(str, 1, strlen(str), f); - fclose(f); -} - -static void editor_close(ui::Widget widget, gpointer data) -{ - if (ui::alert(text_editor.window(), "Close the shader editor ?", "V-Editor", ui::alert_type::YESNO, - ui::alert_icon::Question) == ui::alert_response::NO) { - return; - } - - text_editor.hide(); -} - -static void CreateGtkTextEditor() -{ - auto dlg = ui::Window(ui::window_type::TOP); - - dlg.connect("delete_event", - G_CALLBACK(editor_delete), 0); - gtk_window_set_default_size(dlg, 600, 300); - - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - dlg.add(vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - - auto scr = ui::ScrolledWindow(ui::New); - scr.show(); - vbox.pack_start(scr, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN); - - auto text = ui::TextView(ui::New); - scr.add(text); - text.show(); - g_object_set_data(G_OBJECT(dlg), "text", (gpointer) text); - gtk_text_view_set_editable(text, TRUE); - - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, FALSE, TRUE, 0); - - auto button = ui::Button("Close"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(editor_close), dlg); - button.dimensions(60, -1); - - button = ui::Button("Save"); - button.show(); - hbox.pack_end(button, FALSE, FALSE, 0); - button.connect("clicked", - G_CALLBACK(editor_save), dlg); - button.dimensions(60, -1); - - text_editor = dlg; - text_widget = text; -} - -static void DoGtkTextEditor(const char *filename, guint cursorpos) -{ - if (!text_editor) { - CreateGtkTextEditor(); // build it the first time we need it - - } - // Load file - FILE *f = fopen(filename, "r"); - - if (f == 0) { - globalOutputStream() << "Unable to load file " << filename << " in shader editor.\n"; - text_editor.hide(); - } else { - fseek(f, 0, SEEK_END); - int len = ftell(f); - void *buf = malloc(len); - void *old_filename; - - rewind(f); - fread(buf, 1, len, f); - - gtk_window_set_title(text_editor, filename); - - auto text_buffer = gtk_text_view_get_buffer(ui::TextView::from(text_widget)); - gtk_text_buffer_set_text(text_buffer, (char *) buf, len); - - old_filename = g_object_get_data(G_OBJECT(text_editor), "filename"); - if (old_filename) { - free(old_filename); - } - g_object_set_data(G_OBJECT(text_editor), "filename", strdup(filename)); - - // trying to show later - text_editor.show(); - -#if GDEF_OS_WINDOWS - ui::process(); -#endif - - // only move the cursor if it's not exceeding the size.. - // NOTE: this is erroneous, cursorpos is the offset in bytes, not in characters - // len is the max size in bytes, not in characters either, but the character count is below that limit.. - // thinking .. the difference between character count and byte count would be only because of CR/LF? - { - GtkTextIter text_iter; - // character offset, not byte offset - gtk_text_buffer_get_iter_at_offset(text_buffer, &text_iter, cursorpos); - gtk_text_buffer_place_cursor(text_buffer, &text_iter); - } - -#if GDEF_OS_WINDOWS - gtk_widget_queue_draw( text_widget ); -#endif - - free(buf); - fclose(f); - } -} - -// ============================================================================= -// Light Intensity dialog - -EMessageBoxReturn DoLightIntensityDlg(int *intensity) -{ - ModalDialog dialog; - ui::Entry intensity_entry{ui::null}; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - - ui::Window window = MainFrame_getWindow().create_modal_dialog_window("Light intensity", dialog, -1, -1); - - auto accel_group = ui::AccelGroup(ui::New); - window.add_accel_group(accel_group); - - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto label = ui::Label("ESC for default, ENTER to validate"); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - vbox.pack_start(entry, TRUE, TRUE, 0); - - gtk_widget_grab_focus(entry); - - intensity_entry = entry; - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Return, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - } - } - - char buf[16]; - sprintf(buf, "%d", *intensity); - intensity_entry.text(buf); - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - if (ret == eIDOK) { - *intensity = atoi(gtk_entry_get_text(intensity_entry)); - } - - window.destroy(); - - return ret; -} - -// ============================================================================= -// Add new shader tag dialog - -EMessageBoxReturn DoShaderTagDlg(CopiedString *tag, const char *title) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - - auto window = MainFrame_getWindow().create_modal_dialog_window(title, dialog, -1, -1); - - auto accel_group = ui::AccelGroup(ui::New); - window.add_accel_group(accel_group); - - auto textentry = ui::Entry(ui::New); - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - //GtkLabel* label = GTK_LABEL(gtk_label_new("Enter one ore more tags separated by spaces")); - auto label = ui::Label("ESC to cancel, ENTER to validate"); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto entry = textentry; - entry.show(); - vbox.pack_start(entry, TRUE, TRUE, 0); - - gtk_widget_grab_focus(entry); - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Return, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - } - } - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - if (ret == eIDOK) { - *tag = gtk_entry_get_text(textentry); - } - - window.destroy(); - - return ret; -} - -EMessageBoxReturn DoShaderInfoDlg(const char *name, const char *filename, const char *title) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - - auto window = MainFrame_getWindow().create_modal_dialog_window(title, dialog, -1, -1); - - auto accel_group = ui::AccelGroup(ui::New); - window.add_accel_group(accel_group); - - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - { - auto label = ui::Label("The selected shader"); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto label = ui::Label(name); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto label = ui::Label("is located in file"); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto label = ui::Label(filename); - label.show(); - vbox.pack_start(label, FALSE, FALSE, 0); - } - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Return, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - } - } - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - - window.destroy(); - - return ret; -} - - -#if GDEF_OS_WINDOWS -#include -#endif - -#if GDEF_OS_WINDOWS -// use the file associations to open files instead of builtin Gtk editor -bool g_TextEditor_useWin32Editor = true; -#else -// custom shader editor -bool g_TextEditor_useCustomEditor = false; -CopiedString g_TextEditor_editorCommand(""); -#endif - -void DoTextEditor(const char *filename, int cursorpos) -{ -#if GDEF_OS_WINDOWS - if ( g_TextEditor_useWin32Editor ) { - globalOutputStream() << "opening file '" << filename << "' (line " << cursorpos << " info ignored)\n"; - ShellExecute( (HWND)GDK_WINDOW_HWND( gtk_widget_get_window( MainFrame_getWindow() ) ), "open", filename, 0, 0, SW_SHOW ); - return; - } -#else - // check if a custom editor is set - if (g_TextEditor_useCustomEditor && !g_TextEditor_editorCommand.empty()) { - StringOutputStream strEditCommand(256); - strEditCommand << g_TextEditor_editorCommand.c_str() << " \"" << filename << "\""; - - globalOutputStream() << "Launching: " << strEditCommand.c_str() << "\n"; - // note: linux does not return false if the command failed so it will assume success - if (Q_Exec(0, const_cast( strEditCommand.c_str()), 0, true, false) == false) { - globalOutputStream() << "Failed to execute " << strEditCommand.c_str() << ", using default\n"; - } else { - // the command (appeared) to run successfully, no need to do anything more - return; - } - } -#endif - - DoGtkTextEditor(filename, cursorpos); -} diff --git a/src/gtkdlgs.h b/src/gtkdlgs.h deleted file mode 100644 index fa8ac88..0000000 --- a/src/gtkdlgs.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_GTKDLGS_H ) -#define INCLUDED_GTKDLGS_H - -#include "globaldefs.h" -#include "qerplugin.h" -#include "string/string.h" - -EMessageBoxReturn DoLightIntensityDlg(int *intensity); - -EMessageBoxReturn DoShaderTagDlg(CopiedString *tag, const char *title); - -EMessageBoxReturn DoShaderInfoDlg(const char *name, const char *filename, const char *title); - -EMessageBoxReturn DoTextureLayout(float *fx, float *fy); - -void DoTextEditor(const char *filename, int cursorpos); - -void DoProjectSettings(); - -void DoFind(); - -void DoSides(int type, int axis); - -void DoAbout(); - - -#if GDEF_OS_WINDOWS -extern bool g_TextEditor_useWin32Editor; -#else - -#include "string/stringfwd.h" - -extern bool g_TextEditor_useCustomEditor; -extern CopiedString g_TextEditor_editorCommand; -#endif - - -#endif diff --git a/src/gtkmisc.cpp b/src/gtkmisc.cpp deleted file mode 100644 index 0e70633..0000000 --- a/src/gtkmisc.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// Small functions to help with GTK -// - -#include -#include "gtkmisc.h" - -#include "uilib/uilib.h" - -#include "math/vector.h" -#include "os/path.h" - -#include "gtkutil/dialog.h" -#include "gtkutil/filechooser.h" -#include "gtkutil/menu.h" -#include "gtkutil/toolbar.h" -#include "commands.h" - - -// ============================================================================= -// Misc stuff - -void command_connect_accelerator(const char *name) -{ - const Command &command = GlobalCommands_find(name); - GlobalShortcuts_register(name, 1); - global_accel_group_connect(command.m_accelerator, command.m_callback); -} - -void command_disconnect_accelerator(const char *name) -{ - const Command &command = GlobalCommands_find(name); - global_accel_group_disconnect(command.m_accelerator, command.m_callback); -} - -void toggle_add_accelerator(const char *name) -{ - const Toggle &toggle = GlobalToggles_find(name); - GlobalShortcuts_register(name, 2); - global_accel_group_connect(toggle.m_command.m_accelerator, toggle.m_command.m_callback); -} - -void toggle_remove_accelerator(const char *name) -{ - const Toggle &toggle = GlobalToggles_find(name); - global_accel_group_disconnect(toggle.m_command.m_accelerator, toggle.m_command.m_callback); -} - -ui::CheckMenuItem create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const char *commandName) -{ - GlobalShortcuts_register(commandName, 2); - const Toggle &toggle = GlobalToggles_find(commandName); - global_accel_group_connect(toggle.m_command.m_accelerator, toggle.m_command.m_callback); - return create_check_menu_item_with_mnemonic(menu, mnemonic, toggle); -} - -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const char *commandName) -{ - GlobalShortcuts_register(commandName, 1); - const Command &command = GlobalCommands_find(commandName); - global_accel_group_connect(command.m_accelerator, command.m_callback); - return create_menu_item_with_mnemonic(menu, mnemonic, command); -} - -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const char *commandName) -{ - return toolbar_append_button(toolbar, description, icon, GlobalCommands_find(commandName)); -} - -ui::ToggleToolButton -toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, const char *commandName) -{ - return toolbar_append_toggle_button(toolbar, description, icon, GlobalToggles_find(commandName)); -} - -// ============================================================================= -// File dialog - -bool color_dialog(ui::Window parent, Vector3 &color, const char *title) -{ - GdkColor clr = {0, guint16(color[0] * 65535), guint16(color[1] * 65535), guint16(color[2] * 65535)}; - ModalDialog dialog; - - auto dlg = ui::Window::from(gtk_color_selection_dialog_new(title)); - gtk_color_selection_set_current_color( - GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg))), &clr); - dlg.connect("delete_event", G_CALLBACK(dialog_delete_callback), &dialog); - GtkWidget *ok_button, *cancel_button; - g_object_get(G_OBJECT(dlg), "ok-button", &ok_button, "cancel-button", &cancel_button, nullptr); - ui::Widget::from(ok_button).connect("clicked", G_CALLBACK(dialog_button_ok), &dialog); - ui::Widget::from(cancel_button).connect("clicked", G_CALLBACK(dialog_button_cancel), &dialog); - - if (parent) { - gtk_window_set_transient_for(dlg, parent); - } - - bool ok = modal_dialog_show(dlg, dialog) == eIDOK; - if (ok) { - gtk_color_selection_get_current_color( - GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg))), - &clr); - color[0] = clr.red / 65535.0f; - color[1] = clr.green / 65535.0f; - color[2] = clr.blue / 65535.0f; - } - - dlg.destroy(); - - return ok; -} - -void button_clicked_entry_browse_file(ui::Widget widget, ui::Entry entry) -{ - const char *filename = widget.file_dialog(TRUE, "Choose File", gtk_entry_get_text(entry)); - - if (filename != 0) { - entry.text(filename); - } -} - -void button_clicked_entry_browse_directory(ui::Widget widget, ui::Entry entry) -{ - const char *text = gtk_entry_get_text(entry); - char *dir = dir_dialog(widget.window(), "Choose Directory", path_is_absolute(text) ? text : ""); - - if (dir != 0) { - gchar *converted = g_filename_to_utf8(dir, -1, 0, 0, 0); - entry.text(converted); - g_free(dir); - g_free(converted); - } -} diff --git a/src/gtkmisc.h b/src/gtkmisc.h deleted file mode 100644 index 0379797..0000000 --- a/src/gtkmisc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_GTKMISC_H ) -#define INCLUDED_GTKMISC_H - -#include - -void command_connect_accelerator(const char *commandName); - -void command_disconnect_accelerator(const char *commandName); - -void toggle_add_accelerator(const char *commandName); - -void toggle_remove_accelerator(const char *name); - -// this also sets up the shortcut using command_connect_accelerator -ui::MenuItem create_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const char *commandName); - -// this also sets up the shortcut using command_connect_accelerator -ui::CheckMenuItem create_check_menu_item_with_mnemonic(ui::Menu menu, const char *mnemonic, const char *commandName); - - -// this DOES NOT set up the shortcut using command_connect_accelerator -ui::ToolButton -toolbar_append_button(ui::Toolbar toolbar, const char *description, const char *icon, const char *commandName); - -// this DOES NOT set up the shortcut using command_connect_accelerator -ui::ToggleToolButton -toolbar_append_toggle_button(ui::Toolbar toolbar, const char *description, const char *icon, const char *commandName); - - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -bool color_dialog(ui::Window parent, Vector3 &color, const char *title = "Choose Color"); - -void button_clicked_entry_browse_file(ui::Widget widget, ui::Entry entry); - -void button_clicked_entry_browse_directory(ui::Widget widget, ui::Entry entry); - -#endif diff --git a/tools/vmap/help.c b/src/help.c similarity index 100% rename from tools/vmap/help.c rename to src/help.c diff --git a/src/help.cpp b/src/help.cpp deleted file mode 100644 index 2578209..0000000 --- a/src/help.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "help.h" - -#include "debugging/debugging.h" - -#include -#include - -#include "libxml/parser.h" -#include "generic/callback.h" -#include "gtkutil/menu.h" -#include "stream/stringstream.h" -#include "os/file.h" - -#include "url.h" -#include "preferences.h" -#include "mainframe.h" - - -/*! - needed for hooking in Gtk+ - */ -void Help_OpenVV(void) -{ - OpenURL("https://www.vera-visions.com/"); -} -void Help_OpenMAT(void) -{ - OpenURL("https://www.vera-visions.com/docs/materials/"); -} - - -void create_game_help_menu(ui::Menu menu) -{ - create_menu_item_with_mnemonic(menu, "Vera Visions", makeCallbackF(Help_OpenVV)); - create_menu_item_with_mnemonic(menu, "Material Manual", makeCallbackF(Help_OpenMAT)); -} diff --git a/src/help.h b/src/help.h deleted file mode 100644 index e16cb8b..0000000 --- a/src/help.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_HELP_H ) -#define INCLUDED_HELP_H - -void create_game_help_menu(ui::Menu menu); - -#endif diff --git a/tools/vmap/image.c b/src/image.c similarity index 100% rename from tools/vmap/image.c rename to src/image.c diff --git a/src/image.cpp b/src/image.cpp deleted file mode 100644 index 099c258..0000000 --- a/src/image.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "image.h" - -#include "modulesystem.h" -#include "iimage.h" -#include "ifilesystem.h" -#include "iarchive.h" - -#include "generic/reference.h" -#include "os/path.h" -#include "stream/stringstream.h" - - -typedef Modules<_QERPlugImageTable> ImageModules; - -ImageModules &Textures_getImageModules(); - -/// \brief Returns a new image for the first file matching \p name in one of the available texture formats, or 0 if no file is found. -Image *QERApp_LoadImage(void *environment, const char *name) -{ - Image *image = 0; - class LoadImageVisitor : public ImageModules::Visitor { - const char *m_name; - Image *&m_image; -public: - LoadImageVisitor(const char *name, Image *&image) - : m_name(name), m_image(image) - { - } - - void visit(const char *name, const _QERPlugImageTable &table) const - { - if (m_image == 0) { - StringOutputStream fullname(256); - fullname << m_name << '.' << name; - ArchiveFile *file = GlobalFileSystem().openFile(fullname.c_str()); - if (file != 0) { - m_image = table.loadImage(*file); - file->release(); - } - } - } - }; - - Textures_getImageModules().foreachModule(LoadImageVisitor(name, image)); - - return image; -} diff --git a/src/image.h b/src/image.h deleted file mode 100644 index b05323b..0000000 --- a/src/image.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_IMAGE_H ) -#define INCLUDED_IMAGE_H - -class Image; - -Image *QERApp_LoadImage(void *environment, const char *name); - -#endif diff --git a/tools/vmap/leakfile.c b/src/leakfile.c similarity index 100% rename from tools/vmap/leakfile.c rename to src/leakfile.c diff --git a/tools/vmap/light.c b/src/light.c similarity index 100% rename from tools/vmap/light.c rename to src/light.c diff --git a/tools/vmap/light_bounce.c b/src/light_bounce.c similarity index 100% rename from tools/vmap/light_bounce.c rename to src/light_bounce.c diff --git a/tools/vmap/light_shadows.c b/src/light_shadows.c similarity index 100% rename from tools/vmap/light_shadows.c rename to src/light_shadows.c diff --git a/tools/vmap/light_trace.c b/src/light_trace.c similarity index 100% rename from tools/vmap/light_trace.c rename to src/light_trace.c diff --git a/tools/vmap/light_ydnar.c b/src/light_ydnar.c similarity index 100% rename from tools/vmap/light_ydnar.c rename to src/light_ydnar.c diff --git a/tools/vmap/lightmaps.c b/src/lightmaps.c similarity index 100% rename from tools/vmap/lightmaps.c rename to src/lightmaps.c diff --git a/tools/vmap/lightmaps_ydnar.c b/src/lightmaps_ydnar.c similarity index 100% rename from tools/vmap/lightmaps_ydnar.c rename to src/lightmaps_ydnar.c diff --git a/tools/vmap/main.c b/src/main.c similarity index 100% rename from tools/vmap/main.c rename to src/main.c diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 4a3dca9..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,621 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/*! \mainpage GtkRadiant Documentation Index - - \section intro_sec Introduction - - This documentation is generated from comments in the source code. - - \section links_sec Useful Links - - \link include/itextstream.h include/itextstream.h \endlink - Global output and error message streams, similar to std::cout and std::cerr. \n - - FileInputStream - similar to std::ifstream (binary mode) \n - FileOutputStream - similar to std::ofstream (binary mode) \n - TextFileInputStream - similar to std::ifstream (text mode) \n - TextFileOutputStream - similar to std::ofstream (text mode) \n - StringOutputStream - similar to std::stringstream \n - - \link string/string.h string/string.h \endlink - C-style string comparison and memory management. \n - \link os/path.h os/path.h \endlink - Path manipulation for radiant's standard path format \n - \link os/file.h os/file.h \endlink - OS file-system access. \n - - ::CopiedString - automatic string memory management \n - Array - automatic array memory management \n - HashTable - generic hashtable, similar to std::hash_map \n - - \link math/vector.h math/vector.h \endlink - Vectors \n - \link math/matrix.h math/matrix.h \endlink - Matrices \n - \link math/quaternion.h math/quaternion.h \endlink - Quaternions \n - \link math/plane.h math/plane.h \endlink - Planes \n - \link math/aabb.h math/aabb.h \endlink - AABBs \n - - Callback MemberCaller0 FunctionCaller - callbacks similar to using boost::function with boost::bind \n - SmartPointer SmartReference - smart-pointer and smart-reference similar to Loki's SmartPtr \n - - \link generic/bitfield.h generic/bitfield.h \endlink - Type-safe bitfield \n - \link generic/enumeration.h generic/enumeration.h \endlink - Type-safe enumeration \n - - DefaultAllocator - Memory allocation using new/delete, compliant with std::allocator interface \n - - \link debugging/debugging.h debugging/debugging.h \endlink - Debugging macros \n - - */ - -#include "main.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include "iundo.h" - -#include "uilib/uilib.h" - -#include "cmdlib.h" -#include "os/file.h" -#include "os/path.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" - -#include "gtkutil/messagebox.h" -#include "gtkutil/image.h" -#include "console.h" -#include "texwindow.h" -#include "map.h" -#include "mainframe.h" -#include "commands.h" -#include "preferences.h" -#include "environment.h" -#include "referencecache.h" -#include "stacktrace.h" - -#if GDEF_OS_WINDOWS -#include -#endif - -void show_splash(); - -void hide_splash(); - -void error_redirect(const gchar *domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) -{ - gboolean in_recursion; - gboolean is_fatal; - char buf[256]; - - in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0; - is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0; - log_level = (GLogLevelFlags) (log_level & G_LOG_LEVEL_MASK); - - if (!message) { - message = "(0) message"; - } - - if (domain) { - strcpy(buf, domain); - } else { - strcpy(buf, "**"); - } - strcat(buf, "-"); - - switch (log_level) { - case G_LOG_LEVEL_ERROR: - if (in_recursion) { - strcat(buf, "ERROR (recursed) **: "); - } else { - strcat(buf, "ERROR **: "); - } - break; - case G_LOG_LEVEL_CRITICAL: - if (in_recursion) { - strcat(buf, "CRITICAL (recursed) **: "); - } else { - strcat(buf, "CRITICAL **: "); - } - break; - case G_LOG_LEVEL_WARNING: - if (in_recursion) { - strcat(buf, "WARNING (recursed) **: "); - } else { - strcat(buf, "WARNING **: "); - } - break; - case G_LOG_LEVEL_MESSAGE: - if (in_recursion) { - strcat(buf, "Message (recursed): "); - } else { - strcat(buf, "Message: "); - } - break; - case G_LOG_LEVEL_INFO: - if (in_recursion) { - strcat(buf, "INFO (recursed): "); - } else { - strcat(buf, "INFO: "); - } - break; - case G_LOG_LEVEL_DEBUG: - if (in_recursion) { - strcat(buf, "DEBUG (recursed): "); - } else { - strcat(buf, "DEBUG: "); - } - break; - default: - /* we are used for a log level that is not defined by GLib itself, - * try to make the best out of it. - */ - if (in_recursion) { - strcat(buf, "LOG (recursed:"); - } else { - strcat(buf, "LOG ("); - } - if (log_level) { - gchar string[] = "0x00): "; - gchar *p = string + 2; - guint i; - - i = g_bit_nth_msf(log_level, -1); - *p = i >> 4; - p++; - *p = '0' + (i & 0xf); - if (*p > '9') { - *p += 'A' - '9' - 1; - } - - strcat(buf, string); - } else { - strcat(buf, "): "); - } - } - - strcat(buf, message); - if (is_fatal) { - strcat(buf, "\naborting...\n"); - } else { - strcat(buf, "\n"); - } - - // spam it... - globalErrorStream() << buf << "\n"; - - if (is_fatal) { - ERROR_MESSAGE("GTK+ error: " << buf); - } -} - -#if GDEF_COMPILER_MSVC && GDEF_DEBUG -#include "crtdbg.h" -#endif - -void crt_init() -{ -#if GDEF_COMPILER_MSVC && GDEF_DEBUG - _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); -#endif -} - -class Lock { -bool m_locked; -public: -Lock() : m_locked(false) -{ -} - -void lock() -{ - m_locked = true; -} - -void unlock() -{ - m_locked = false; -} - -bool locked() const -{ - return m_locked; -} -}; - -class ScopedLock { -Lock &m_lock; -public: -ScopedLock(Lock &lock) : m_lock(lock) -{ - m_lock.lock(); -} - -~ScopedLock() -{ - m_lock.unlock(); -} -}; - -class LineLimitedTextOutputStream : public TextOutputStream { -TextOutputStream &outputStream; -std::size_t count; -public: -LineLimitedTextOutputStream(TextOutputStream &outputStream, std::size_t count) - : outputStream(outputStream), count(count) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - if (count != 0) { - const char *p = buffer; - const char *end = buffer + length; - for (;;) { - p = std::find(p, end, '\n'); - if (p == end) { - break; - } - ++p; - if (--count == 0) { - length = p - buffer; - break; - } - } - outputStream.write(buffer, length); - } - return length; -} -}; - -class PopupDebugMessageHandler : public DebugMessageHandler { -StringOutputStream m_buffer; -Lock m_lock; -public: -TextOutputStream &getOutputStream() -{ - if (!m_lock.locked()) { - return m_buffer; - } - return globalErrorStream(); -} - -bool handleMessage() -{ - getOutputStream() << "----------------\n"; - LineLimitedTextOutputStream outputStream(getOutputStream(), 24); - write_stack_trace(outputStream); - getOutputStream() << "----------------\n"; - globalErrorStream() << m_buffer.c_str(); - if (!m_lock.locked()) { - 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; - 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); - m_buffer.clear(); - } - } - return true; -} -}; - -typedef Static GlobalPopupDebugMessageHandler; - -void streams_init() -{ - GlobalErrorStream::instance().setOutputStream(getSysPrintErrorStream()); - GlobalOutputStream::instance().setOutputStream(getSysPrintOutputStream()); -} - -void paths_init() -{ - //g_strSettingsPath = environment_get_home_path(); - g_strSettingsPath = environment_get_app_path(); - - Q_mkdir(g_strSettingsPath.c_str()); - - g_strAppPath = environment_get_app_path(); - - // radiant is installed in the parent dir of "tools/" - // NOTE: this is not very easy for debugging - // maybe add options to lookup in several places? - // (for now I had to create symlinks) - { - StringOutputStream path(256); - path << g_strAppPath.c_str() << "bitmaps/"; - BitmapsPath_set(path.c_str()); - } - - // we will set this right after the game selection is done - g_strGameToolsPath = g_strAppPath; -} - -void create_global_pid() -{ - /*! - the global prefs loading / game selection dialog might fail for any reason we don't know about - we need to catch when it happens, to cleanup the stateful prefs which might be killing it - and to turn on console logging for lookup of the problem - this is the first part of the two step .pid system - http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297 - */ - StringOutputStream g_pidFile(256); ///< the global .pid file (only for global part of the startup) - - g_pidFile << SettingsPath_get() << "radiant.pid"; - - FILE *pid; - pid = fopen(g_pidFile.c_str(), "r"); - if (pid != 0) { - fclose(pid); - - 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); - } - - // 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" - "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) { - g_GamesDialog.Reset(); - } - - msg.clear(); - msg << "Logging console output to " << SettingsPath_get() - << "radiant.log\nRefer to the log if Radiant fails to start again."; - - ui::alert(ui::root, msg.c_str(), "Radiant - Console Log", ui::alert_type::OK); - } - } - - // create a primary .pid for global init run - pid = fopen(g_pidFile.c_str(), "w"); - if (pid) { - fclose(pid); - } -} - -void remove_global_pid() -{ - StringOutputStream g_pidFile(256); - g_pidFile << SettingsPath_get() << "radiant.pid"; - - // close the primary - 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); - } -} - -/*! - now the secondary game dependant .pid file - http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297 - */ -void create_local_pid() -{ - StringOutputStream g_pidGameFile(256); ///< the game-specific .pid file - g_pidGameFile << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/radiant-game.pid"; - - FILE *pid = fopen(g_pidGameFile.c_str(), "r"); - if (pid != 0) { - fclose(pid); - 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); - } - - // 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" - "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) { - Preferences_Reset(); - } - - msg.clear(); - msg << "Logging console output to " << SettingsPath_get() - << "radiant.log\nRefer to the log if Radiant fails to start again."; - - ui::alert(ui::root, msg.c_str(), "Radiant - Console Log", ui::alert_type::OK); - } - } else { - // create one, will remove right after entering message loop - pid = fopen(g_pidGameFile.c_str(), "w"); - if (pid) { - fclose(pid); - } - } -} - - -/*! - now the secondary game dependant .pid file - http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297 - */ -void remove_local_pid() -{ - StringOutputStream g_pidGameFile(256); - g_pidGameFile << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/radiant-game.pid"; - remove(g_pidGameFile.c_str()); -} - -void user_shortcuts_init() -{ - StringOutputStream shortpath(256); - StringOutputStream path(256); - shortpath << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << '/'; - - LoadCommandMap(shortpath.c_str(), SettingsPath_get()); - SaveCommandMap(shortpath.c_str()); -} - -void user_shortcuts_save() -{ - StringOutputStream path(256); - path << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << '/'; - SaveCommandMap(path.c_str()); -} - -int main(int argc, char *argv[]) -{ - crt_init(); - - streams_init(); - -#if GDEF_OS_WINDOWS - HMODULE lib; - lib = LoadLibrary( "dwmapi.dll" ); - if ( lib != 0 ) { - void ( WINAPI *qDwmEnableComposition )( bool bEnable ) = ( void (WINAPI *) ( bool bEnable ) )GetProcAddress( lib, "DwmEnableComposition" ); - if ( qDwmEnableComposition ) { - qDwmEnableComposition( FALSE ); - } - FreeLibrary( lib ); - } -#endif - - const char *mapname = NULL; - char const *error = NULL; - if (!ui::init(&argc, &argv, "", &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]; - } else { - mapname = g_build_filename(g_get_current_dir(), argv[1], NULL); - } - } else { - g_print("bad file name, will not load: %s\n", argv[1]); - } - } - } else if (argc > 2) { - g_print("%s\n", "too many arguments"); - return -1; - } - - // redirect Gtk warnings to the console - g_log_set_handler("Gdk", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - g_log_set_handler("Gtk", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - g_log_set_handler("GtkGLExt", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - g_log_set_handler("GLib", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - g_log_set_handler(0, (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | - G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0); - - GlobalDebugMessageHandler::instance().setHandler(GlobalPopupDebugMessageHandler::instance()); - - environment_init(argc, (char const **) argv); - - paths_init(); - - create_global_pid(); - - GlobalPreferences_Init(); - - g_GamesDialog.Init(); - - if (g_GamesDialog.m_bGamePrompt == false) { - show_splash(); - } - - g_strGameToolsPath = g_pGameDescription->mGameToolsPath; - - remove_global_pid(); - - g_Preferences.Init(); // must occur before create_local_pid() to allow preferences to be reset - - create_local_pid(); - - Radiant_Initialise(); - - user_shortcuts_init(); - - g_pParentWnd = 0; - g_pParentWnd = new MainFrame(); - - hide_splash(); - - if (mapname != NULL) { - Map_LoadFile(mapname); - } else if (g_bLoadLastMap && !g_strLastMap.empty()) { - Map_LoadFile(g_strLastMap.c_str()); - } else { - Map_New(); - } - - // load up shaders now that we have the map loaded - // eviltypeguy - TextureBrowser_ShowStartupShaders(GlobalTextureBrowser()); - - - remove_local_pid(); - - ui::main(); - - // avoid saving prefs when the app is minimized - if (g_pParentWnd->IsSleeping()) { - globalOutputStream() << "Shutdown while sleeping, not saving prefs\n"; - g_preferences_globals.disable_ini = true; - } - - Map_Free(); - - if (!Map_Unnamed(g_map)) { - g_strLastMap = Map_Name(g_map); - } - - delete g_pParentWnd; - - user_shortcuts_save(); - - Radiant_Shutdown(); - - return EXIT_SUCCESS; -} diff --git a/src/main.h b/src/main.h deleted file mode 100644 index d87b7a8..0000000 --- a/src/main.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MAIN_H ) -#define INCLUDED_MAIN_H - -#endif diff --git a/src/mainframe.cpp b/src/mainframe.cpp deleted file mode 100644 index ef4f2c4..0000000 --- a/src/mainframe.cpp +++ /dev/null @@ -1,3388 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Main Window for Q3Radiant -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "mainframe.h" -#include "globaldefs.h" - -#include - -#include "ifilesystem.h" -#include "iundo.h" -#include "editable.h" -#include "ientity.h" -#include "ishaders.h" -#include "igl.h" -#include "moduleobserver.h" - -#include - -#include - - -#include "cmdlib.h" -#include "stream/stringstream.h" -#include "signal/isignal.h" -#include "os/path.h" -#include "os/file.h" -#include "eclasslib.h" -#include "moduleobservers.h" - -#include "gtkutil/clipboard.h" -#include "gtkutil/frame.h" -#include "gtkutil/glwidget.h" -#include "gtkutil/image.h" -#include "gtkutil/menu.h" -#include "gtkutil/paned.h" - -#include "autosave.h" -#include "build.h" -#include "brushmanip.h" -#include "brushmodule.h" -#include "camwindow.h" -#include "csg.h" -#include "commands.h" -#include "entity.h" -#include "entityinspector.h" -#include "entitylist.h" -#include "filters.h" -#include "findtexturedialog.h" -#include "grid.h" -#include "groupdialog.h" -#include "gtkdlgs.h" -#include "gtkmisc.h" -#include "help.h" -#include "map.h" -#include "mru.h" -#include "multimon.h" -#include "patchdialog.h" -#include "patchmanip.h" -#include "plugin.h" -#include "pluginmanager.h" -#include "pluginmenu.h" -#include "plugintoolbar.h" -#include "preferences.h" -#include "qe3.h" -#include "qgl.h" -#include "select.h" -#include "server.h" -#include "surfacedialog.h" -#include "textures.h" -#include "texwindow.h" -#include "url.h" -#include "xywindow.h" -#include "windowobservers.h" -#include "renderstate.h" -#include "feedback.h" -#include "referencecache.h" -#include "texwindow.h" - - -struct layout_globals_t { - WindowPosition m_position; - - - int nXYHeight; - int nXYWidth; - int nCamWidth; - int nCamHeight; - int nState; - - layout_globals_t() : - m_position(-1, -1, 640, 480), - - nXYHeight(300), - nXYWidth(300), - nCamWidth(200), - nCamHeight(200) - { - } -}; - -layout_globals_t g_layout_globals; -glwindow_globals_t g_glwindow_globals; - - -// VFS - -bool g_vfsInitialized = false; - -void VFS_Init() -{ - if (g_vfsInitialized) { return; } - QE_InitVFS(); - GlobalFileSystem().initialise(); - g_vfsInitialized = true; -} - -void VFS_Shutdown() -{ - if (!g_vfsInitialized) { return; } - GlobalFileSystem().shutdown(); - g_vfsInitialized = false; -} - -void VFS_Refresh() -{ - if (!g_vfsInitialized) { return; } - GlobalFileSystem().clear(); - QE_InitVFS(); - GlobalFileSystem().refresh(); - g_vfsInitialized = true; - // also refresh models - RefreshReferences(); - // also refresh texture browser - TextureBrowser_RefreshShaders(); - // also show textures (all or common) - TextureBrowser_ShowStartupShaders( GlobalTextureBrowser() ); -} - -void VFS_Restart() -{ - VFS_Shutdown(); - VFS_Init(); -} - -class VFSModuleObserver : public ModuleObserver { -public: -void realise() -{ - VFS_Init(); -} - -void unrealise() -{ - VFS_Shutdown(); -} -}; - -VFSModuleObserver g_VFSModuleObserver; - -void VFS_Construct() -{ -} - -void VFS_Destroy() -{ -} - -// Engine Path - -CopiedString g_strEnginePath; -ModuleObservers g_enginePathObservers; -std::size_t g_enginepath_unrealised = 1; - -void Radiant_attachEnginePathObserver(ModuleObserver &observer) -{ - g_enginePathObservers.attach(observer); -} - -void Radiant_detachEnginePathObserver(ModuleObserver &observer) -{ - g_enginePathObservers.detach(observer); -} - - -void EnginePath_Realise() -{ - if (--g_enginepath_unrealised == 0) { - g_enginePathObservers.realise(); - } -} - - -const char *EnginePath_get() -{ - if (g_enginepath_unrealised == 0) { - g_enginePathObservers.realise(); - } - return g_strEnginePath.c_str(); -} - -void EnginePath_Unrealise() -{ - if (++g_enginepath_unrealised == 1) { - g_enginePathObservers.unrealise(); - } -} - -void setEnginePath(const char *path) -{ - StringOutputStream buffer(256); - buffer << DirectoryCleaned(path); - if (!path_equal(buffer.c_str(), g_strEnginePath.c_str())) { -#if 0 - while ( !ConfirmModified( "Paths Changed" ) ) - { - if ( Map_Unnamed( g_map ) ) { - Map_SaveAs(); - } - else - { - Map_Save(); - } - } - Map_RegionOff(); -#endif - - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Changing Nuclide Path"); - - EnginePath_Unrealise(); - - g_strEnginePath = buffer.c_str(); - - EnginePath_Realise(); - } -} - -// App Path - -CopiedString g_strAppPath; //< holds the full path of the executable - -const char *AppPath_get() -{ - return g_strAppPath.c_str(); -} - -/// the path to the local rc-dir -const char *LocalRcPath_get(void) -{ - static CopiedString rc_path; - if (rc_path.empty()) { - StringOutputStream stream(256); - stream << GlobalRadiant().getSettingsPath() << g_pGameDescription->mGameFile.c_str() << "/"; - rc_path = stream.c_str(); - } - return rc_path.c_str(); -} - -/// directory for temp files -/// NOTE: on *nix this is were we check for .pid -CopiedString g_strSettingsPath; - -const char *SettingsPath_get() -{ - return g_strSettingsPath.c_str(); -} - - -/*! - points to the game tools directory, for instance - C:/Program Files/Quake III Arena/GtkRadiant - (or other games) - this is one of the main variables that are configured by the game selection on startup - [GameToolsPath]/plugins - and also q3map, bspc - */ -CopiedString g_strGameToolsPath; ///< this is set by g_GamesDialog - -const char *GameToolsPath_get() -{ - return g_strGameToolsPath.c_str(); -} - -struct EnginePath { - static void Export(const CopiedString &self, const Callback &returnz) - { - returnz(self.c_str()); - } - - static void Import(CopiedString &self, const char *value) - { - setEnginePath(value); - } -}; - -void Paths_constructPreferences(PreferencesPage &page) -{ - page.appendPathEntry("Nuclide Path", true, make_property(g_strEnginePath)); -} - -void Paths_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Paths", "Path Settings")); - Paths_constructPreferences(page); -} - -void Paths_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Paths_constructPage)); -} - - -class PathsDialog : public Dialog { -public: -ui::Window BuildDialog() -{ - 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); - } - - return ui::Window(create_simple_modal_dialog_window("Nuclide Path Not Found", m_modal, frame)); -} -}; - -PathsDialog g_PathsDialog; - -void EnginePath_verify() -{ - if (!file_exists(g_strEnginePath.c_str())) { - g_PathsDialog.Create(); - g_PathsDialog.DoModal(); - g_PathsDialog.Destroy(); - } -} - -namespace { -CopiedString g_gamename; -CopiedString g_gamemode; -ModuleObservers g_gameNameObservers; -ModuleObservers g_gameModeObservers; -} - -void Radiant_attachGameNameObserver(ModuleObserver &observer) -{ - g_gameNameObservers.attach(observer); -} - -void Radiant_detachGameNameObserver(ModuleObserver &observer) -{ - g_gameNameObservers.detach(observer); -} - -const char *basegame_get() -{ - return g_pGameDescription->getRequiredKeyValue("basegame"); -} - -const char *gamename_get() -{ - const char *gamename = g_gamename.c_str(); - if (string_empty(gamename)) { - return basegame_get(); - } - return gamename; -} - -void gamename_set(const char *gamename) -{ - if (!string_equal(gamename, g_gamename.c_str())) { - g_gameNameObservers.unrealise(); - g_gamename = gamename; - g_gameNameObservers.realise(); - } -} - -void Radiant_attachGameModeObserver(ModuleObserver &observer) -{ - g_gameModeObservers.attach(observer); -} - -void Radiant_detachGameModeObserver(ModuleObserver &observer) -{ - g_gameModeObservers.detach(observer); -} - -const char *gamemode_get() -{ - return g_gamemode.c_str(); -} - -void gamemode_set(const char *gamemode) -{ - if (!string_equal(gamemode, g_gamemode.c_str())) { - g_gameModeObservers.unrealise(); - g_gamemode = gamemode; - g_gameModeObservers.realise(); - } -} - - -#include "os/dir.h" - -const char *const c_library_extension = -#if defined( CMAKE_SHARED_MODULE_SUFFIX ) - CMAKE_SHARED_MODULE_SUFFIX -#elif GDEF_OS_WINDOWS - "dll" -#elif GDEF_OS_MACOS - "dylib" -#elif GDEF_OS_LINUX || GDEF_OS_BSD - "so" -#endif -; - -void Radiant_loadModules(const char *path) -{ - Directory_forEach(path, matchFileExtension(c_library_extension, [&](const char *name) { - char fullname[1024]; - ASSERT_MESSAGE(strlen(path) + strlen(name) < 1024, ""); - strcpy(fullname, path); - strcat(fullname, name); - globalOutputStream() << "Found '" << fullname << "'\n"; - GlobalModuleServer_loadModule(fullname); - })); -} - -void Radiant_loadModulesFromRoot(const char *directory) -{ - { - StringOutputStream path(256); - path << directory << g_pluginsDir; - Radiant_loadModules(path.c_str()); - } -} - -//! Make COLOR_BRUSHES override worldspawn eclass colour. -void SetWorldspawnColour(const Vector3 &colour) -{ - EntityClass *worldspawn = GlobalEntityClassManager().findOrInsert("worldspawn", true); - eclass_release_state(worldspawn); - worldspawn->color = colour; - eclass_capture_state(worldspawn); -} - - -class WorldspawnColourEntityClassObserver : public ModuleObserver { -std::size_t m_unrealised; -public: -WorldspawnColourEntityClassObserver() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - SetWorldspawnColour(g_xywindow_globals.color_brushes); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - } -} -}; - -WorldspawnColourEntityClassObserver g_WorldspawnColourEntityClassObserver; - - -ModuleObservers g_gameToolsPathObservers; - -void Radiant_attachGameToolsPathObserver(ModuleObserver &observer) -{ - g_gameToolsPathObservers.attach(observer); -} - -void Radiant_detachGameToolsPathObserver(ModuleObserver &observer) -{ - g_gameToolsPathObservers.detach(observer); -} - -void Radiant_Initialise() -{ - GlobalModuleServer_Initialise(); - - Radiant_loadModulesFromRoot(AppPath_get()); - - Preferences_Load(); - - bool success = Radiant_Construct(GlobalModuleServer_get()); - ASSERT_MESSAGE(success, "module system failed to initialise - see radiant.log for error messages"); - - g_gameToolsPathObservers.realise(); - g_gameModeObservers.realise(); - g_gameNameObservers.realise(); -} - -void Radiant_Shutdown() -{ - g_gameNameObservers.unrealise(); - g_gameModeObservers.unrealise(); - g_gameToolsPathObservers.unrealise(); - - if (!g_preferences_globals.disable_ini) { - Preferences_Save(); - } - - Radiant_Destroy(); - - GlobalModuleServer_Shutdown(); -} - -void Exit() -{ - if (ConfirmModified("Exit WorldSpawn")) { - gtk_main_quit(); - } -} - - -void Undo() -{ - GlobalUndoSystem().undo(); - SceneChangeNotify(); -} - -void Redo() -{ - GlobalUndoSystem().redo(); - SceneChangeNotify(); -} - -void deleteSelection() -{ - UndoableCommand undo("deleteSelected"); - Select_Delete(); -} - -void Map_ExportSelected(TextOutputStream &ostream) -{ - Map_ExportSelected(ostream, Map_getFormat(g_map)); -} - -void Map_ImportSelected(TextInputStream &istream) -{ - Map_ImportSelected(istream, Map_getFormat(g_map)); -} - -void Selection_Copy() -{ - clipboard_copy(Map_ExportSelected); -} - -void Selection_Paste() -{ - clipboard_paste(Map_ImportSelected); -} - -void Copy() -{ - if (SelectedFaces_empty()) { - Selection_Copy(); - } else { - SelectedFaces_copyTexture(); - } -} - - - -enum ENudgeDirection { - eNudgeUp = 1, - eNudgeDown = 3, - eNudgeLeft = 0, - eNudgeRight = 2, -}; - - -void NudgeSelection(ENudgeDirection direction, float fAmount, VIEWTYPE viewtype); - -void Paste() -{ - if (SelectedFaces_empty()) { - UndoableCommand undo("paste"); - - GlobalSelectionSystem().setSelectedAll(false); - Selection_Paste(); - - NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - } else { - SelectedFaces_pasteTexture(); - } -} - -void PasteToCamera() -{ - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - GlobalSelectionSystem().setSelectedAll(false); - - UndoableCommand undo("pasteToCamera"); - - Selection_Paste(); - - // Work out the delta - Vector3 mid; - Select_GetMid(mid); - Vector3 delta = vector3_subtracted(vector3_snapped(Camera_getOrigin(camwnd), GetSnapGridSize()), mid); - - // Move to camera - GlobalSelectionSystem().translateSelected(delta); -} - - -void ColorScheme_WorldSpawn() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.15f, 0.15f, 0.15f)); - - g_camwindow_globals.color_cameraback = Vector3(0.15f, 0.15f, 0.15f); - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(0.0f, 0.0f, 0.0f); - g_xywindow_globals.color_gridminor = Vector3(0.2f, 0.2f, 0.2f); - g_xywindow_globals.color_gridmajor = Vector3(0.45f, 0.45f, 0.45f); - g_xywindow_globals.color_gridblock = Vector3(0.39f, 0.18f, 0.0f); - g_xywindow_globals.color_gridtext = Vector3(1.0f, 1.0f, 1.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); - g_xywindow_globals.color_brushes = Vector3(0.55f, 0.55f, 0.55f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.7f, 0.7f, 0.0f); - XY_UpdateAllWindows(); -} - -void ColorScheme_Original() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f)); - - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(1.0f, 1.0f, 1.0f); - g_xywindow_globals.color_gridminor = Vector3(0.75f, 0.75f, 0.75f); - g_xywindow_globals.color_gridmajor = Vector3(0.5f, 0.5f, 0.5f); - g_xywindow_globals.color_gridminor_alt = Vector3(0.5f, 0.0f, 0.0f); - g_xywindow_globals.color_gridmajor_alt = Vector3(1.0f, 0.0f, 0.0f); - g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f); - 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); - g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f); - XY_UpdateAllWindows(); -} - -void ColorScheme_QER() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f)); - - g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f); - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(1.0f, 1.0f, 1.0f); - g_xywindow_globals.color_gridminor = Vector3(1.0f, 1.0f, 1.0f); - g_xywindow_globals.color_gridmajor = Vector3(0.5f, 0.5f, 0.5f); - g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f); - 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); - g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f); - XY_UpdateAllWindows(); -} - -void ColorScheme_Black() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f)); - - g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f); - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(0.0f, 0.0f, 0.0f); - g_xywindow_globals.color_gridminor = Vector3(0.2f, 0.2f, 0.2f); - g_xywindow_globals.color_gridmajor = Vector3(0.3f, 0.5f, 0.5f); - g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f); - g_xywindow_globals.color_gridtext = Vector3(1.0f, 1.0f, 1.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); - g_xywindow_globals.color_brushes = Vector3(1.0f, 1.0f, 1.0f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.7f, 0.7f, 0.0f); - XY_UpdateAllWindows(); -} - -/* ydnar: to emulate maya/max/lightwave color schemes */ -void ColorScheme_Ydnar() -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f)); - - g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f); - g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - - g_xywindow_globals.color_gridback = Vector3(0.77f, 0.77f, 0.77f); - g_xywindow_globals.color_gridminor = Vector3(0.83f, 0.83f, 0.83f); - g_xywindow_globals.color_gridmajor = Vector3(0.89f, 0.89f, 0.89f); - g_xywindow_globals.color_gridblock = Vector3(1.0f, 1.0f, 1.0f); - 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); - g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f); - SetWorldspawnColour(g_xywindow_globals.color_brushes); - g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f); - XY_UpdateAllWindows(); -} - -typedef Callback GetColourCallback; -typedef Callback SetColourCallback; - -class ChooseColour { -GetColourCallback m_get; -SetColourCallback m_set; -public: -ChooseColour(const GetColourCallback &get, const SetColourCallback &set) - : m_get(get), m_set(set) -{ -} - -void operator()() -{ - Vector3 colour; - m_get(colour); - color_dialog(MainFrame_getWindow(), colour); - m_set(colour); -} -}; - - -void Colour_get(const Vector3 &colour, Vector3 &other) -{ - other = colour; -} - -typedef ConstReferenceCaller ColourGetCaller; - -void Colour_set(Vector3 &colour, const Vector3 &other) -{ - colour = other; - SceneChangeNotify(); -} - -typedef ReferenceCaller ColourSetCaller; - -void BrushColour_set(const Vector3 &other) -{ - g_xywindow_globals.color_brushes = other; - SetWorldspawnColour(g_xywindow_globals.color_brushes); - SceneChangeNotify(); -} - -typedef FreeCaller BrushColourSetCaller; - -void ClipperColour_set(const Vector3 &other) -{ - g_xywindow_globals.color_clipper = other; - Brush_clipperColourChanged(); - SceneChangeNotify(); -} - -typedef FreeCaller ClipperColourSetCaller; - -void TextureBrowserColour_get(Vector3 &other) -{ - other = TextureBrowser_getBackgroundColour(GlobalTextureBrowser()); -} - -typedef FreeCaller TextureBrowserColourGetCaller; - -void TextureBrowserColour_set(const Vector3 &other) -{ - TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), other); -} - -typedef FreeCaller TextureBrowserColourSetCaller; - - -class ColoursMenu { -public: -ChooseColour m_textureback; -ChooseColour m_xyback; -ChooseColour m_gridmajor; -ChooseColour m_gridminor; -ChooseColour m_gridmajor_alt; -ChooseColour m_gridminor_alt; -ChooseColour m_gridtext; -ChooseColour m_gridblock; -ChooseColour m_cameraback; -ChooseColour m_brush; -ChooseColour m_selectedbrush; -ChooseColour m_selectedbrush3d; -ChooseColour m_clipper; -ChooseColour m_viewname; - -ColoursMenu() : - m_textureback(TextureBrowserColourGetCaller(), TextureBrowserColourSetCaller()), - m_xyback(ColourGetCaller(g_xywindow_globals.color_gridback), - ColourSetCaller(g_xywindow_globals.color_gridback)), - m_gridmajor(ColourGetCaller(g_xywindow_globals.color_gridmajor), - ColourSetCaller(g_xywindow_globals.color_gridmajor)), - m_gridminor(ColourGetCaller(g_xywindow_globals.color_gridminor), - ColourSetCaller(g_xywindow_globals.color_gridminor)), - m_gridmajor_alt(ColourGetCaller(g_xywindow_globals.color_gridmajor_alt), - ColourSetCaller(g_xywindow_globals.color_gridmajor_alt)), - m_gridminor_alt(ColourGetCaller(g_xywindow_globals.color_gridminor_alt), - ColourSetCaller(g_xywindow_globals.color_gridminor_alt)), - m_gridtext(ColourGetCaller(g_xywindow_globals.color_gridtext), - ColourSetCaller(g_xywindow_globals.color_gridtext)), - m_gridblock(ColourGetCaller(g_xywindow_globals.color_gridblock), - ColourSetCaller(g_xywindow_globals.color_gridblock)), - m_cameraback(ColourGetCaller(g_camwindow_globals.color_cameraback), - ColourSetCaller(g_camwindow_globals.color_cameraback)), - m_brush(ColourGetCaller(g_xywindow_globals.color_brushes), BrushColourSetCaller()), - m_selectedbrush(ColourGetCaller(g_xywindow_globals.color_selbrushes), - ColourSetCaller(g_xywindow_globals.color_selbrushes)), - m_selectedbrush3d(ColourGetCaller(g_camwindow_globals.color_selbrushes3d), - ColourSetCaller(g_camwindow_globals.color_selbrushes3d)), - m_clipper(ColourGetCaller(g_xywindow_globals.color_clipper), ClipperColourSetCaller()), - m_viewname(ColourGetCaller(g_xywindow_globals.color_viewname), - ColourSetCaller(g_xywindow_globals.color_viewname)) -{ -} -}; - -ColoursMenu g_ColoursMenu; - -ui::MenuItem create_colours_menu() -{ - auto colours_menu_item = new_sub_menu_item_with_mnemonic("Colors"); - auto menu_in_menu = ui::Menu::from(gtk_menu_item_get_submenu(colours_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - - auto menu_3 = create_sub_menu_with_mnemonic(menu_in_menu, "Themes"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_3); - }*/ - - create_menu_item_with_mnemonic(menu_3, "Default", "ColorSchemeWS"); - create_menu_item_with_mnemonic(menu_3, "QE4 Original", "ColorSchemeOriginal"); - 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"); - - menu_separator(menu_in_menu); - - create_menu_item_with_mnemonic(menu_in_menu, "_Texture Background...", "ChooseTextureBackgroundColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Background...", "ChooseGridBackgroundColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Major...", "ChooseGridMajorColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Minor...", "ChooseGridMinorColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Major Small...", "ChooseSmallGridMajorColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Minor Small...", "ChooseSmallGridMinorColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Text...", "ChooseGridTextColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Grid Block...", "ChooseGridBlockColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Default Brush...", "ChooseBrushColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Camera Background...", "ChooseCameraBackgroundColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Selected Brush...", "ChooseSelectedBrushColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Selected Brush (Camera)...", "ChooseCameraSelectedBrushColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Clipper...", "ChooseClipperColor"); - create_menu_item_with_mnemonic(menu_in_menu, "Active View name...", "ChooseOrthoViewNameColor"); - - return colours_menu_item; -} - - -void Restart() -{ - PluginsMenu_clear(); - PluginToolbar_clear(); - - Radiant_Shutdown(); - Radiant_Initialise(); - - PluginsMenu_populate(); - - PluginToolbar_populate(); -} - - -void thunk_OnSleep() -{ - g_pParentWnd->OnSleep(); -} - -void OpenHelpURL() -{ - OpenURL("https://www.vera-visions.com/developer/"); -} - -void OpenBugReportURL() -{ - OpenURL("https://www.vera-visions.com/developer/"); -} - - -ui::Widget g_page_entity{ui::null}; - -void EntityInspector_ToggleShow() -{ - GroupDialog_showPage(g_page_entity); -} - - -void SetClipMode(bool enable); - -void ModeChangeNotify(); - -typedef void ( *ToolMode )(); - -ToolMode g_currentToolMode = 0; -bool g_currentToolModeSupportsComponentEditing = false; -ToolMode g_defaultToolMode = 0; - - -void SelectionSystem_DefaultMode() -{ - GlobalSelectionSystem().SetMode(SelectionSystem::ePrimitive); - GlobalSelectionSystem().SetComponentMode(SelectionSystem::eDefault); - ModeChangeNotify(); -} - - -bool EdgeMode() -{ - return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eEdge; -} - -bool VertexMode() -{ - return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex; -} - -bool FaceMode() -{ - return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace; -} - -template -class BoolFunctionExport { -public: -static void apply(const Callback &importCallback) -{ - importCallback(BoolFunction()); -} -}; - -typedef FreeCaller &), &BoolFunctionExport::apply> EdgeModeApplyCaller; -EdgeModeApplyCaller g_edgeMode_button_caller; -Callback &)> g_edgeMode_button_callback(g_edgeMode_button_caller); -ToggleItem g_edgeMode_button(g_edgeMode_button_callback); - -typedef FreeCaller &), &BoolFunctionExport::apply> VertexModeApplyCaller; -VertexModeApplyCaller g_vertexMode_button_caller; -Callback &)> g_vertexMode_button_callback(g_vertexMode_button_caller); -ToggleItem g_vertexMode_button(g_vertexMode_button_callback); - -typedef FreeCaller &), &BoolFunctionExport::apply> FaceModeApplyCaller; -FaceModeApplyCaller g_faceMode_button_caller; -Callback &)> g_faceMode_button_callback(g_faceMode_button_caller); -ToggleItem g_faceMode_button(g_faceMode_button_callback); - -void ComponentModeChanged() -{ - g_edgeMode_button.update(); - g_vertexMode_button.update(); - g_faceMode_button.update(); -} - -void ComponentMode_SelectionChanged(const Selectable &selectable) -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().countSelected() == 0) { - SelectionSystem_DefaultMode(); - ComponentModeChanged(); - } -} - -void SelectEdgeMode() -{ -#if 0 - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { - GlobalSelectionSystem().Select( false ); - } -#endif - - if (EdgeMode()) { - SelectionSystem_DefaultMode(); - } else if (GlobalSelectionSystem().countSelected() != 0) { - if (!g_currentToolModeSupportsComponentEditing) { - g_defaultToolMode(); - } - - GlobalSelectionSystem().SetMode(SelectionSystem::eComponent); - GlobalSelectionSystem().SetComponentMode(SelectionSystem::eEdge); - } - - ComponentModeChanged(); - - ModeChangeNotify(); -} - -void SelectVertexMode() -{ -#if 0 - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { - GlobalSelectionSystem().Select( false ); - } -#endif - - if (VertexMode()) { - SelectionSystem_DefaultMode(); - } else if (GlobalSelectionSystem().countSelected() != 0) { - if (!g_currentToolModeSupportsComponentEditing) { - g_defaultToolMode(); - } - - GlobalSelectionSystem().SetMode(SelectionSystem::eComponent); - GlobalSelectionSystem().SetComponentMode(SelectionSystem::eVertex); - } - - ComponentModeChanged(); - - ModeChangeNotify(); -} - -void SelectFaceMode() -{ -#if 0 - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { - GlobalSelectionSystem().Select( false ); - } -#endif - - if (FaceMode()) { - SelectionSystem_DefaultMode(); - } else if (GlobalSelectionSystem().countSelected() != 0) { - if (!g_currentToolModeSupportsComponentEditing) { - g_defaultToolMode(); - } - - GlobalSelectionSystem().SetMode(SelectionSystem::eComponent); - GlobalSelectionSystem().SetComponentMode(SelectionSystem::eFace); - } - - ComponentModeChanged(); - - ModeChangeNotify(); -} - - -class CloneSelected : public scene::Graph::Walker { -bool doMakeUnique; -NodeSmartReference worldspawn; -public: -CloneSelected(bool d) : doMakeUnique(d), worldspawn(Map_FindOrInsertWorldspawn(g_map)) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.size() == 1) { - return true; - } - - // ignore worldspawn, but keep checking children - NodeSmartReference me(path.top().get()); - if (me == worldspawn) { - return true; - } - - if (!path.top().get().isRoot()) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - return false; - } - } - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.size() == 1) { - return; - } - - // ignore worldspawn, but keep checking children - NodeSmartReference me(path.top().get()); - if (me == worldspawn) { - return; - } - - if (!path.top().get().isRoot()) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - NodeSmartReference clone(Node_Clone(path.top())); - if (doMakeUnique) { - Map_gatherNamespaced(clone); - } - Node_getTraversable(path.parent().get())->insert(clone); - } - } -} -}; - -void Scene_Clone_Selected(scene::Graph &graph, bool doMakeUnique) -{ - graph.traverse(CloneSelected(doMakeUnique)); - - Map_mergeClonedNames(); -} - -struct AxisBase { - Vector3 x; - Vector3 y; - Vector3 z; - - AxisBase(const Vector3 &x_, const Vector3 &y_, const Vector3 &z_) - : x(x_), y(y_), z(z_) - { - } -}; - -AxisBase AxisBase_forViewType(VIEWTYPE viewtype) -{ - switch (viewtype) { - case XY: - return AxisBase(g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z); - case XZ: - return AxisBase(g_vector3_axis_x, g_vector3_axis_z, g_vector3_axis_y); - case YZ: - return AxisBase(g_vector3_axis_y, g_vector3_axis_z, g_vector3_axis_x); - } - - ERROR_MESSAGE("invalid viewtype"); - return AxisBase(Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(0, 0, 0)); -} - -Vector3 AxisBase_axisForDirection(const AxisBase &axes, ENudgeDirection direction) -{ - switch (direction) { - case eNudgeLeft: - return vector3_negated(axes.x); - case eNudgeUp: - return axes.y; - case eNudgeRight: - return axes.x; - case eNudgeDown: - return vector3_negated(axes.y); - } - - ERROR_MESSAGE("invalid direction"); - return Vector3(0, 0, 0); -} - -void NudgeSelection(ENudgeDirection direction, float fAmount, VIEWTYPE viewtype) -{ - AxisBase axes(AxisBase_forViewType(viewtype)); - Vector3 view_direction(vector3_negated(axes.z)); - Vector3 nudge(vector3_scaled(AxisBase_axisForDirection(axes, direction), fAmount)); - GlobalSelectionSystem().NudgeManipulator(nudge, view_direction); -} - -void Selection_Clone() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - UndoableCommand undo("cloneSelected"); - - Scene_Clone_Selected(GlobalSceneGraph(), false); - - NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - } -} - -void Selection_Clone_MakeUnique() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - UndoableCommand undo("cloneSelectedMakeUnique"); - - Scene_Clone_Selected(GlobalSceneGraph(), true); - - NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - } -} - -// called when the escape key is used (either on the main window or on an inspector) -void Selection_Deselect() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - if (GlobalSelectionSystem().countSelectedComponents() != 0) { - GlobalSelectionSystem().setSelectedAllComponents(false); - } else { - SelectionSystem_DefaultMode(); - ComponentModeChanged(); - } - } else { - if (GlobalSelectionSystem().countSelectedComponents() != 0) { - GlobalSelectionSystem().setSelectedAllComponents(false); - } else { - GlobalSelectionSystem().setSelectedAll(false); - } - } -} - - -void Selection_NudgeUp() -{ - UndoableCommand undo("nudgeSelectedUp"); - NudgeSelection(eNudgeUp, GetGridSize(), GlobalXYWnd_getCurrentViewType()); -} - -void Selection_NudgeDown() -{ - UndoableCommand undo("nudgeSelectedDown"); - NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); -} - -void Selection_NudgeLeft() -{ - UndoableCommand undo("nudgeSelectedLeft"); - NudgeSelection(eNudgeLeft, GetGridSize(), GlobalXYWnd_getCurrentViewType()); -} - -void Selection_NudgeRight() -{ - UndoableCommand undo("nudgeSelectedRight"); - NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); -} - - -void TranslateToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eTranslate); -} - -void RotateToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eRotate); -} - -void ScaleToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eScale); -} - -void DragToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eDrag); -} - -void ClipperToolExport(const Callback &importCallback) -{ - importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip); -} - -FreeCaller &), TranslateToolExport> g_translatemode_button_caller; -Callback &)> g_translatemode_button_callback(g_translatemode_button_caller); -ToggleItem g_translatemode_button(g_translatemode_button_callback); - -FreeCaller &), RotateToolExport> g_rotatemode_button_caller; -Callback &)> g_rotatemode_button_callback(g_rotatemode_button_caller); -ToggleItem g_rotatemode_button(g_rotatemode_button_callback); - -FreeCaller &), ScaleToolExport> g_scalemode_button_caller; -Callback &)> g_scalemode_button_callback(g_scalemode_button_caller); -ToggleItem g_scalemode_button(g_scalemode_button_callback); - -FreeCaller &), DragToolExport> g_dragmode_button_caller; -Callback &)> g_dragmode_button_callback(g_dragmode_button_caller); -ToggleItem g_dragmode_button(g_dragmode_button_callback); - -FreeCaller &), ClipperToolExport> g_clipper_button_caller; -Callback &)> g_clipper_button_callback(g_clipper_button_caller); -ToggleItem g_clipper_button(g_clipper_button_callback); - -void ToolChanged() -{ - g_translatemode_button.update(); - g_rotatemode_button.update(); - g_scalemode_button.update(); - g_dragmode_button.update(); - g_clipper_button.update(); -} -const char *const c_ResizeMode_status = "Drag Tool: move and resize objects"; - -void DragMode() -{ - if (g_currentToolMode == DragMode && g_defaultToolMode != DragMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = DragMode; - g_currentToolModeSupportsComponentEditing = true; - - OnClipMode(false); - - Sys_Status(c_ResizeMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eDrag); - ToolChanged(); - ModeChangeNotify(); - } -} - - -const char *const c_TranslateMode_status = "Translate Tool: translate objects and components"; - -void TranslateMode() -{ - if (g_currentToolMode == TranslateMode && g_defaultToolMode != TranslateMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = TranslateMode; - g_currentToolModeSupportsComponentEditing = true; - - OnClipMode(false); - - Sys_Status(c_TranslateMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eTranslate); - ToolChanged(); - ModeChangeNotify(); - } -} - -const char *const c_RotateMode_status = "Rotate Tool: rotate objects and components"; - -void RotateMode() -{ - if (g_currentToolMode == RotateMode && g_defaultToolMode != RotateMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = RotateMode; - g_currentToolModeSupportsComponentEditing = true; - - OnClipMode(false); - - Sys_Status(c_RotateMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eRotate); - ToolChanged(); - ModeChangeNotify(); - } -} - -const char *const c_ScaleMode_status = "Scale Tool: scale objects and components"; - -void ScaleMode() -{ - if (g_currentToolMode == ScaleMode && g_defaultToolMode != ScaleMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = ScaleMode; - g_currentToolModeSupportsComponentEditing = true; - - OnClipMode(false); - - Sys_Status(c_ScaleMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eScale); - ToolChanged(); - ModeChangeNotify(); - } -} - - -const char *const c_ClipperMode_status = "Clipper Tool: apply clip planes to objects"; - - -void ClipperMode() -{ - if (g_currentToolMode == ClipperMode && g_defaultToolMode != ClipperMode) { - g_defaultToolMode(); - } else { - g_currentToolMode = ClipperMode; - g_currentToolModeSupportsComponentEditing = false; - - SelectionSystem_DefaultMode(); - - OnClipMode(true); - - Sys_Status(c_ClipperMode_status); - GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eClip); - ToolChanged(); - ModeChangeNotify(); - } -} - -static int g_modifier_state; - -void Modifier1Export(const Callback &importCallback) -{ - importCallback(g_modifier_state == 0); -} -void Modifier2Export(const Callback &importCallback) -{ - importCallback(g_modifier_state == 1); -} -void Modifier3Export(const Callback &importCallback) -{ - importCallback(g_modifier_state == 3); -} - -FreeCaller &), Modifier1Export> g_modifier1_button_caller; -Callback &)> g_modifier1_button_callback(g_modifier1_button_caller); -ToggleItem g_modifier1_button(g_modifier1_button_callback); - -FreeCaller &), Modifier2Export> g_modifier2_button_caller; -Callback &)> g_modifier2_button_callback(g_modifier2_button_caller); -ToggleItem g_modifier2_button(g_modifier2_button_callback); - -FreeCaller &), Modifier3Export> g_modifier3_button_caller; -Callback &)> g_modifier3_button_callback(g_modifier3_button_caller); -ToggleItem g_modifier3_button(g_modifier3_button_callback); - -void ModifierChanged() -{ - g_modifier1_button.update(); - g_modifier2_button.update(); - g_modifier3_button.update(); -} - -void Modifier1() -{ - g_modifier_state = 0; - ModifierChanged(); - ModeChangeNotify(); -} -void Modifier2() -{ - g_modifier_state = 1; - ModifierChanged(); - ModeChangeNotify(); -} -void Modifier3() -{ - g_modifier_state = 3; - ModifierChanged(); - ModeChangeNotify(); -} - -int -Get_Modifier_State(void) -{ - return g_modifier_state; -} - - -void Texdef_Rotate(float angle) -{ - StringOutputStream command; - command << "brushRotateTexture -angle " << angle; - UndoableCommand undo(command.c_str()); - Select_RotateTexture(angle); -} - -void Texdef_RotateClockwise() -{ - Texdef_Rotate(static_cast( fabs(g_si_globals.rotate))); -} - -void Texdef_RotateAntiClockwise() -{ - Texdef_Rotate(static_cast( -fabs(g_si_globals.rotate))); -} - -void Texdef_Scale(float x, float y) -{ - StringOutputStream command; - command << "brushScaleTexture -x " << x << " -y " << y; - UndoableCommand undo(command.c_str()); - Select_ScaleTexture(x, y); -} - -void Texdef_ScaleUp() -{ - Texdef_Scale(0, g_si_globals.scale[1]); -} - -void Texdef_ScaleDown() -{ - Texdef_Scale(0, -g_si_globals.scale[1]); -} - -void Texdef_ScaleLeft() -{ - Texdef_Scale(-g_si_globals.scale[0], 0); -} - -void Texdef_ScaleRight() -{ - Texdef_Scale(g_si_globals.scale[0], 0); -} - -void Texdef_Shift(float x, float y) -{ - StringOutputStream command; - command << "brushShiftTexture -x " << x << " -y " << y; - UndoableCommand undo(command.c_str()); - Select_ShiftTexture(x, y); -} - -void Texdef_ShiftLeft() -{ - Texdef_Shift(-g_si_globals.shift[0], 0); -} - -void Texdef_ShiftRight() -{ - Texdef_Shift(g_si_globals.shift[0], 0); -} - -void Texdef_ShiftUp() -{ - Texdef_Shift(0, g_si_globals.shift[1]); -} - -void Texdef_ShiftDown() -{ - Texdef_Shift(0, -g_si_globals.shift[1]); -} - - -class SnappableSnapToGridSelected : public scene::Graph::Walker { -float m_snap; -public: -SnappableSnapToGridSelected(float snap) - : m_snap(snap) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Snappable *snappable = Node_getSnappable(path.top()); - if (snappable != 0 - && Instance_getSelectable(instance)->isSelected()) { - snappable->snapto(m_snap); - } - } - return true; -} -}; - -void Scene_SnapToGrid_Selected(scene::Graph &graph, float snap) -{ - graph.traverse(SnappableSnapToGridSelected(snap)); -} - -class ComponentSnappableSnapToGridSelected : public scene::Graph::Walker { -float m_snap; -public: -ComponentSnappableSnapToGridSelected(float snap) - : m_snap(snap) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - ComponentSnappable *componentSnappable = Instance_getComponentSnappable(instance); - if (componentSnappable != 0 - && Instance_getSelectable(instance)->isSelected()) { - componentSnappable->snapComponents(m_snap); - } - } - return true; -} -}; - -void Scene_SnapToGrid_Component_Selected(scene::Graph &graph, float snap) -{ - graph.traverse(ComponentSnappableSnapToGridSelected(snap)); -} - -void Selection_SnapToGrid() -{ - StringOutputStream command; - command << "snapSelected -grid " << GetGridSize(); - UndoableCommand undo(command.c_str()); - - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - Scene_SnapToGrid_Component_Selected(GlobalSceneGraph(), GetGridSize()); - } else { - Scene_SnapToGrid_Selected(GlobalSceneGraph(), GetGridSize()); - } -} - - -static gint qe_every_second(gpointer data) -{ - GdkModifierType mask; - - gdk_window_get_pointer(0, 0, 0, &mask); - - if ((mask & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0) { - QE_CheckAutoSave(); - } - - return TRUE; -} - -guint s_qe_every_second_id = 0; - -void EverySecondTimer_enable() -{ - if (s_qe_every_second_id == 0) { - s_qe_every_second_id = g_timeout_add(1000, qe_every_second, 0); - } -} - -void EverySecondTimer_disable() -{ - if (s_qe_every_second_id != 0) { - g_source_remove(s_qe_every_second_id); - s_qe_every_second_id = 0; - } -} - -gint window_realize_remove_decoration(ui::Widget widget, gpointer data) -{ - gdk_window_set_decorations(gtk_widget_get_window(widget), - (GdkWMDecoration) (GDK_DECOR_ALL | GDK_DECOR_MENU | GDK_DECOR_MINIMIZE | - GDK_DECOR_MAXIMIZE)); - return FALSE; -} - -class WaitDialog { -public: -ui::Window m_window{ui::null}; -ui::Label m_label{ui::null}; -}; - -WaitDialog create_wait_dialog(const char *title, const char *text) -{ - WaitDialog dialog; - - dialog.m_window = MainFrame_getWindow().create_floating_window(title); - gtk_window_set_resizable(dialog.m_window, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(dialog.m_window), 0); - gtk_window_set_position(dialog.m_window, GTK_WIN_POS_CENTER_ON_PARENT); - - dialog.m_window.connect("realize", G_CALLBACK(window_realize_remove_decoration), 0); - - { - dialog.m_label = ui::Label(text); - gtk_misc_set_alignment(GTK_MISC(dialog.m_label), 0.0, 0.5); - gtk_label_set_justify(dialog.m_label, GTK_JUSTIFY_LEFT); - dialog.m_label.show(); - dialog.m_label.dimensions(200, -1); - - dialog.m_window.add(dialog.m_label); - } - return dialog; -} - -namespace { -clock_t g_lastRedrawTime = 0; -const clock_t c_redrawInterval = clock_t(CLOCKS_PER_SEC / 10); - -bool redrawRequired() -{ - clock_t currentTime = std::clock(); - if (currentTime - g_lastRedrawTime >= c_redrawInterval) { - g_lastRedrawTime = currentTime; - return true; - } - return false; -} -} - -bool MainFrame_isActiveApp() -{ - //globalOutputStream() << "listing\n"; - GList *list = gtk_window_list_toplevels(); - for (GList *i = list; i != 0; i = g_list_next(i)) { - //globalOutputStream() << "toplevel.. "; - if (gtk_window_is_active(ui::Window::from(i->data))) { - //globalOutputStream() << "is active\n"; - return true; - } - //globalOutputStream() << "not active\n"; - } - return false; -} - -typedef std::list StringStack; -StringStack g_wait_stack; -WaitDialog g_wait; - -bool ScreenUpdates_Enabled() -{ - return g_wait_stack.empty(); -} - -void ScreenUpdates_process() -{ - if (redrawRequired() && g_wait.m_window.visible()) { - ui::process(); - } -} - - -void ScreenUpdates_Disable(const char *message, const char *title) -{ - if (g_wait_stack.empty()) { - EverySecondTimer_disable(); - - ui::process(); - - 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(); - ScreenUpdates_process(); - } - } else if (g_wait.m_window.visible()) { - g_wait.m_label.text(message); - ScreenUpdates_process(); - } - g_wait_stack.push_back(message); -} - -void ScreenUpdates_Enable() -{ - ASSERT_MESSAGE(!ScreenUpdates_Enabled(), "screen updates already enabled"); - g_wait_stack.pop_back(); - if (g_wait_stack.empty()) { - EverySecondTimer_enable(); - //gtk_widget_set_sensitive(MainFrame_getWindow(), TRUE); - - gtk_grab_remove(g_wait.m_window); - destroy_floating_window(g_wait.m_window); - g_wait.m_window = ui::Window{ui::null}; - - //gtk_window_present(MainFrame_getWindow()); - } else if (g_wait.m_window.visible()) { - g_wait.m_label.text(g_wait_stack.back().c_str()); - ScreenUpdates_process(); - } -} - - -void GlobalCamera_UpdateWindow() -{ - if (g_pParentWnd != 0) { - CamWnd_Update(*g_pParentWnd->GetCamWnd()); - } -} - -void XY_UpdateWindow(MainFrame &mainframe) -{ - if (mainframe.GetXYWnd() != 0) { - XYWnd_Update(*mainframe.GetXYWnd()); - } -} - -void XZ_UpdateWindow(MainFrame &mainframe) -{ - if (mainframe.GetXZWnd() != 0) { - XYWnd_Update(*mainframe.GetXZWnd()); - } -} - -void YZ_UpdateWindow(MainFrame &mainframe) -{ - if (mainframe.GetYZWnd() != 0) { - XYWnd_Update(*mainframe.GetYZWnd()); - } -} - -void XY_UpdateAllWindows(MainFrame &mainframe) -{ - XY_UpdateWindow(mainframe); - XZ_UpdateWindow(mainframe); - YZ_UpdateWindow(mainframe); -} - -void XY_UpdateAllWindows() -{ - if (g_pParentWnd != 0) { - XY_UpdateAllWindows(*g_pParentWnd); - } -} - -void XYZ_SetOrigin(const Vector3 &origin) -{ - g_pParentWnd->GetXYWnd()->SetOrigin(origin); - g_pParentWnd->GetXZWnd()->SetOrigin(origin); - g_pParentWnd->GetYZWnd()->SetOrigin(origin); -} - -void UpdateAllWindows() -{ - GlobalCamera_UpdateWindow(); - XY_UpdateAllWindows(); -} - - -void ModeChangeNotify() -{ - SceneChangeNotify(); -} - -void ClipperChangeNotify() -{ - GlobalCamera_UpdateWindow(); - XY_UpdateAllWindows(); -} - -LatchedValue g_Layout_enablePluginToolbar(true, "Plugin Toolbar"); - - -ui::MenuItem create_file_menu() -{ - // File menu - auto file_menu_item = new_sub_menu_item_with_mnemonic("_File"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(file_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_menu_item_with_mnemonic(menu, "_New Map", "NewMap"); - menu_separator(menu); - -#if 0 - //++timo temporary experimental stuff for sleep mode.. - create_menu_item_with_mnemonic( menu, "_Sleep", "Sleep" ); - menu_separator( menu ); - // end experimental -#endif - - create_menu_item_with_mnemonic(menu, "_Open...", "OpenMap"); - - create_menu_item_with_mnemonic(menu, "_Import...", "ImportMap"); - create_menu_item_with_mnemonic(menu, "_Save", "SaveMap"); - create_menu_item_with_mnemonic(menu, "Save _as...", "SaveMapAs"); - create_menu_item_with_mnemonic(menu, "_Export selected...", "ExportSelected"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Save re_gion...", "SaveRegion"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "_Refresh assets", "RefreshReferences"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Pro_ject settings...", "ProjectSettings"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "_Pointfile...", "TogglePointfile"); - menu_separator(menu); - MRU_constructMenu(menu); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "E_xit", "Exit"); - - return file_menu_item; -} - -ui::MenuItem undobutton{ui::null}; -void -Undo_SetButtonlabel(const char *title) -{ - StringOutputStream name(128); - name << "Undo ("<< title << ")"; - gtk_menu_item_set_label(undobutton, name.c_str()); - gtk_widget_set_sensitive(undobutton, true); -} -void -Undo_DisableButton(void) -{ - gtk_menu_item_set_label(undobutton, "Undo"); - gtk_widget_set_sensitive(undobutton, false); -} - -ui::MenuItem redobutton{ui::null}; -void -Redo_SetButtonlabel(const char *title) -{ - StringOutputStream name(128); - name << "Redo (" << title << ")"; - gtk_menu_item_set_label(redobutton, name.c_str()); - gtk_widget_set_sensitive(redobutton, true); -} -void -Redo_DisableButton(void) -{ - gtk_menu_item_set_label(redobutton, "Redo"); - gtk_widget_set_sensitive(redobutton, false); -} - -ui::MenuItem create_edit_menu() -{ - // Edit menu - auto edit_menu_item = new_sub_menu_item_with_mnemonic("_Edit"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(edit_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - undobutton = create_menu_item_with_mnemonic(menu, "_Undo", "Undo"); - redobutton = create_menu_item_with_mnemonic(menu, "_Redo", "Redo"); - Undo_DisableButton(); - Redo_DisableButton(); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "_Copy", "Copy"); - create_menu_item_with_mnemonic(menu, "_Paste", "Paste"); - create_menu_item_with_mnemonic(menu, "P_aste To Camera", "PasteToCamera"); - menu_separator(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, "Pa_rent", "ParentSelection"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "C_lear Selection", "UnSelectSelection"); - create_menu_item_with_mnemonic(menu, "_Invert Selection", "InvertSelection"); - create_menu_item_with_mnemonic(menu, "Select i_nside", "SelectInside"); - create_menu_item_with_mnemonic(menu, "Select _touching", "SelectTouching"); - - create_check_menu_item_with_mnemonic(menu, "Auto-Expand Selection", "ToggleExpansion"); - create_check_menu_item_with_mnemonic(menu, "Additive Selection", "ToggleAddSelect"); - - auto convert_menu = create_sub_menu_with_mnemonic(menu, "E_xpand Selection"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(convert_menu); - }*/ - create_menu_item_with_mnemonic(convert_menu, "To Whole _Entities", "ExpandSelectionToEntities"); - - create_menu_item_with_mnemonic(menu, "Select all of model type", "SelectAllOfModel"); - - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Pre_ferences...", "Preferences"); - - return edit_menu_item; -} - -void fill_view_xy_top_menu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "XY (Top) View", "ToggleView"); -} - - -void fill_view_yz_side_menu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "YZ (Side) View", "ToggleSideView"); -} - - -void fill_view_xz_front_menu(ui::Menu menu) -{ - create_check_menu_item_with_mnemonic(menu, "XZ (Front) View", "ToggleFrontView"); -} - - -ui::Widget g_toggle_z_item{ui::null}; -ui::Widget g_toggle_entity_item{ui::null}; -ui::Widget g_toggle_entitylist_item{ui::null}; - -ui::MenuItem create_view_menu() -{ - // View menu - auto view_menu_item = new_sub_menu_item_with_mnemonic("Vie_w"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(view_menu_item)); - - - /*fill_view_camera_menu(menu); - fill_view_xy_top_menu(menu); - fill_view_yz_side_menu(menu); - fill_view_xz_front_menu(menu);*/ - - create_menu_item_with_mnemonic(menu, "Map Info", "MapInfo"); - create_menu_item_with_mnemonic(menu, "Texture Browser", "ToggleTextures"); - create_menu_item_with_mnemonic(menu, "Entity Inspector", "ToggleEntityInspector"); - - - create_menu_item_with_mnemonic(menu, "_Surface Inspector", "SurfaceInspector"); - create_menu_item_with_mnemonic(menu, "Entity List", "EntityList"); - - menu_separator(menu); - menu.add(create_colours_menu()); - { - auto camera_menu = create_sub_menu_with_mnemonic(menu, "Camera"); - - create_menu_item_with_mnemonic(camera_menu, "_Center", "CenterView"); - create_menu_item_with_mnemonic(camera_menu, "_Up Floor", "UpFloor"); - create_menu_item_with_mnemonic(camera_menu, "_Down Floor", "DownFloor"); - menu_separator(camera_menu); - 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, "Next leak spot", "NextLeakSpot"); - create_menu_item_with_mnemonic(camera_menu, "Previous leak spot", "PrevLeakSpot"); - menu_separator(camera_menu); - create_menu_item_with_mnemonic(camera_menu, "Look Through Selected", "LookThroughSelected"); - create_menu_item_with_mnemonic(camera_menu, "Look Through Camera", "LookThroughCamera"); - menu_separator(camera_menu); - create_menu_item_with_mnemonic(camera_menu, "Move to [0,0,0]", "GoToZero"); - } - - { - auto orthographic_menu = create_sub_menu_with_mnemonic(menu, "Orthographic"); - - create_menu_item_with_mnemonic(orthographic_menu, "_Next (XY, YZ, XY)", "NextView"); - create_menu_item_with_mnemonic(orthographic_menu, "XY (Top)", "ViewTop"); - create_menu_item_with_mnemonic(orthographic_menu, "YZ", "ViewSide"); - create_menu_item_with_mnemonic(orthographic_menu, "XZ", "ViewFront"); - menu_separator(orthographic_menu); - - - create_menu_item_with_mnemonic(orthographic_menu, "_XY 100%", "Zoom100"); - create_menu_item_with_mnemonic(orthographic_menu, "XY Zoom _In", "ZoomIn"); - create_menu_item_with_mnemonic(orthographic_menu, "XY Zoom _Out", "ZoomOut"); - } - - menu_separator(menu); - - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Show"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_check_menu_item_with_mnemonic(menu_in_menu, "Show _Angles", "ShowAngles"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show _Names", "ShowNames"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Blocks", "ShowBlocks"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show C_oordinates", "ShowCoordinates"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Window Outline", "ShowWindowOutline"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Axes", "ShowAxes"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Workzone", "ShowWorkzone"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Lighting", "ShowLighting"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Alpha", "ShowAlpha"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Stats", "ShowStats"); - create_check_menu_item_with_mnemonic(menu_in_menu, "Show Patch Balls", "ShowPatchBalls"); - } - - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Filter"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - Filters_constructMenu(menu_in_menu); - } - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Hide/Show"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Hide Selected", "HideSelected"); - create_menu_item_with_mnemonic(menu_in_menu, "Hide Unselected", "HideUnselected"); - create_menu_item_with_mnemonic(menu_in_menu, "Show Hidden", "ShowHidden"); - } - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Region"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "_Off", "RegionOff"); - create_menu_item_with_mnemonic(menu_in_menu, "_Set XY", "RegionSetXY"); - create_menu_item_with_mnemonic(menu_in_menu, "Set _Brush", "RegionSetBrush"); - create_menu_item_with_mnemonic(menu_in_menu, "Set Se_lected Brushes", "RegionSetSelection"); - } - - command_connect_accelerator("CenterXYView"); - - return view_menu_item; -} - -ui::MenuItem create_selection_menu() -{ - // Selection menu - auto selection_menu_item = new_sub_menu_item_with_mnemonic("M_odify"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(selection_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Components"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_check_menu_item_with_mnemonic(menu_in_menu, "_Edges", "DragEdges"); - create_check_menu_item_with_mnemonic(menu_in_menu, "_Vertices", "DragVertices"); - create_check_menu_item_with_mnemonic(menu_in_menu, "_Faces", "DragFaces"); - } - - menu_separator(menu); - - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Nudge"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Nudge Left", "SelectNudgeLeft"); - create_menu_item_with_mnemonic(menu_in_menu, "Nudge Right", "SelectNudgeRight"); - create_menu_item_with_mnemonic(menu_in_menu, "Nudge Up", "SelectNudgeUp"); - create_menu_item_with_mnemonic(menu_in_menu, "Nudge Down", "SelectNudgeDown"); - } - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Rotate"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Rotate X", "RotateSelectionX"); - create_menu_item_with_mnemonic(menu_in_menu, "Rotate Y", "RotateSelectionY"); - create_menu_item_with_mnemonic(menu_in_menu, "Rotate Z", "RotateSelectionZ"); - } - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Flip"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Flip _X", "MirrorSelectionX"); - create_menu_item_with_mnemonic(menu_in_menu, "Flip _Y", "MirrorSelectionY"); - create_menu_item_with_mnemonic(menu_in_menu, "Flip _Z", "MirrorSelectionZ"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Arbitrary move...", "ArbitraryMove"); - create_menu_item_with_mnemonic(menu, "Arbitrary rotation...", "ArbitraryRotation"); - create_menu_item_with_mnemonic(menu, "Arbitrary scale...", "ArbitraryScale"); - create_menu_item_with_mnemonic(menu, "Find brush...", "FindBrush"); - return selection_menu_item; -} - -ui::MenuItem create_bsp_menu() -{ - // BSP menu - auto bsp_menu_item = new_sub_menu_item_with_mnemonic("_Build"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(bsp_menu_item)); - - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_menu_item_with_mnemonic(menu, "Customize...", "BuildMenuCustomize"); - - menu_separator(menu); - - Build_constructMenu(menu); - - g_bsp_menu = menu; - - return bsp_menu_item; -} - -ui::MenuItem create_grid_menu() -{ - // Grid menu - auto grid_menu_item = new_sub_menu_item_with_mnemonic("_Grid"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(grid_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - Grid_constructMenu(menu); - - return grid_menu_item; -} - -ui::MenuItem create_entity_menu() -{ - // Brush menu - auto entity_menu_item = new_sub_menu_item_with_mnemonic("E_ntity"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(entity_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - Entity_constructMenu(menu); - - return entity_menu_item; -} - -ui::MenuItem create_brush_menu() -{ - // Brush menu - auto brush_menu_item = new_sub_menu_item_with_mnemonic("B_rush"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(brush_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - Brush_constructMenu(menu); - - return brush_menu_item; -} - -ui::MenuItem create_patch_menu() -{ - // Curve menu - auto patch_menu_item = new_sub_menu_item_with_mnemonic("_Curve"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(patch_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - Patch_constructMenu(menu); - - return patch_menu_item; -} - -ui::MenuItem create_help_menu() -{ - // Help menu - auto help_menu_item = new_sub_menu_item_with_mnemonic("_Help"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(help_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - // this creates all the per-game drop downs for the game pack helps - // it will take care of hooking the Sys_OpenURL calls etc. - create_game_help_menu(menu); - - create_menu_item_with_mnemonic(menu, "Shortcuts list", makeCallbackF(DoCommandListDlg)); - create_menu_item_with_mnemonic(menu, "_About", makeCallbackF(DoAbout)); - - return help_menu_item; -} - -ui::MenuBar create_main_menu() -{ - auto menu_bar = ui::MenuBar::from(gtk_menu_bar_new()); - menu_bar.show(); - menu_bar.add(create_file_menu()); - menu_bar.add(create_edit_menu()); - menu_bar.add(create_view_menu()); - menu_bar.add(create_selection_menu()); - menu_bar.add(create_bsp_menu()); - menu_bar.add(create_grid_menu()); - menu_bar.add(create_entity_menu()); - menu_bar.add(create_brush_menu()); - menu_bar.add(create_patch_menu()); - menu_bar.add(create_plugins_menu()); - menu_bar.add(create_help_menu()); - return menu_bar; -} - - -void PatchInspector_registerShortcuts() -{ - command_connect_accelerator("PatchInspector"); -} - -void Patch_registerShortcuts() -{ - command_connect_accelerator("InvertCurveTextureX"); - command_connect_accelerator("InvertCurveTextureY"); - command_connect_accelerator("PatchInsertInsertColumn"); - command_connect_accelerator("PatchInsertInsertRow"); - command_connect_accelerator("PatchDeleteLastColumn"); - command_connect_accelerator("PatchDeleteLastRow"); - command_connect_accelerator("NaturalizePatch"); - //command_connect_accelerator("CapCurrentCurve"); -} - -void Manipulators_registerShortcuts() -{ - toggle_add_accelerator("MouseRotate"); - toggle_add_accelerator("MouseTranslate"); - toggle_add_accelerator("MouseScale"); - toggle_add_accelerator("MouseDrag"); - toggle_add_accelerator("ToggleClipper"); -} - -void TexdefNudge_registerShortcuts() -{ - command_connect_accelerator("TexRotateClock"); - command_connect_accelerator("TexRotateCounter"); - command_connect_accelerator("TexScaleUp"); - command_connect_accelerator("TexScaleDown"); - command_connect_accelerator("TexScaleLeft"); - command_connect_accelerator("TexScaleRight"); - command_connect_accelerator("TexShiftUp"); - command_connect_accelerator("TexShiftDown"); - command_connect_accelerator("TexShiftLeft"); - command_connect_accelerator("TexShiftRight"); -} - -void SelectNudge_registerShortcuts() -{ - command_connect_accelerator("MoveSelectionDOWN"); - command_connect_accelerator("MoveSelectionUP"); - //command_connect_accelerator("SelectNudgeLeft"); - //command_connect_accelerator("SelectNudgeRight"); - //command_connect_accelerator("SelectNudgeUp"); - //command_connect_accelerator("SelectNudgeDown"); -} - -void SnapToGrid_registerShortcuts() -{ - command_connect_accelerator("SnapToGrid"); -} - -void SelectByType_registerShortcuts() -{ - command_connect_accelerator("SelectAllOfType"); -} - -void SurfaceInspector_registerShortcuts() -{ - command_connect_accelerator("FitTexture"); -} - - -void register_shortcuts() -{ - PatchInspector_registerShortcuts(); - Patch_registerShortcuts(); - Grid_registerShortcuts(); - XYWnd_registerShortcuts(); - CamWnd_registerShortcuts(); - Manipulators_registerShortcuts(); - SurfaceInspector_registerShortcuts(); - TexdefNudge_registerShortcuts(); - SelectNudge_registerShortcuts(); - SnapToGrid_registerShortcuts(); - SelectByType_registerShortcuts(); -} - -void File_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "New map", "file_new.xpm", "NewMap"); - toolbar_append_button(toolbar, "Open an existing map", "file_open.xpm", "OpenMap"); - toolbar_append_button(toolbar, "Save the active map", "file_save.xpm", "SaveMap"); -} - -void UndoRedo_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "Undo (CTRL + Z)", "undo.xpm", "Undo"); - toolbar_append_button(toolbar, "Redo (CTRL + Y)", "redo.xpm", "Redo"); -} - -void Rotate_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "x-axis Rotate", "brush_rotatex.xpm", "RotateSelectionX"); - toolbar_append_button(toolbar, "y-axis Rotate", "brush_rotatey.xpm", "RotateSelectionZ"); - toolbar_append_button(toolbar, "z-axis Rotate", "brush_rotatez.xpm", "RotateSelectionY"); -} - -void Flip_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "x-axis Flip", "brush_flipx.xpm", "MirrorSelectionX"); - toolbar_append_button(toolbar, "y-axis Flip", "brush_flipy.xpm", "MirrorSelectionY"); - toolbar_append_button(toolbar, "z-axis Flip", "brush_flipz.xpm", "MirrorSelectionZ"); -} - -void Select_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "Select touching", "selection_selecttouching.xpm", "SelectTouching"); - toolbar_append_button(toolbar, "Select inside", "selection_selectinside.xpm", "SelectInside"); -} - -void CSG_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "CSG Subtract", "selection_csgsubtract.xpm", "CSGSubtract"); - toolbar_append_button(toolbar, "CSG Merge", "selection_csgmerge.xpm", "CSGMerge"); - toolbar_append_button(toolbar, "Make Hollow", "selection_makehollow.xpm", "CSGMakeHollow"); - toolbar_append_button(toolbar, "Make Room", "selection_makeroom.xpm", "CSGMakeRoom"); -} - -void ComponentModes_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_toggle_button(toolbar, "Select Vertices", "modify_vertices.xpm", "DragVertices"); - toolbar_append_toggle_button(toolbar, "Select Edges", "modify_edges.xpm", "DragEdges"); - toolbar_append_toggle_button(toolbar, "Select Faces", "modify_faces.xpm", "DragFaces"); -} - -void XYWnd_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "Change views", "view_change.xpm", "NextView"); -} - - -void PluginToolbar_AddToMain(ui::Toolbar toolbar); -ui::Toolbar create_main_toolbar() -{ - auto toolbar = ui::Toolbar::from(gtk_toolbar_new()); - gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL); - gtk_toolbar_set_style(toolbar, GTK_TOOLBAR_ICONS); - - toolbar.show(); - - auto space = [&]() { - auto btn = ui::ToolItem::from(gtk_separator_tool_item_new()); - btn.show(); - toolbar.add(btn); - }; - - File_constructToolbar(toolbar); - space(); - UndoRedo_constructToolbar(toolbar); - space(); - Rotate_constructToolbar(toolbar); - space(); - Flip_constructToolbar(toolbar); - space(); - Select_constructToolbar(toolbar); - space(); - CSG_constructToolbar(toolbar); - space(); - ComponentModes_constructToolbar(toolbar); - space(); - XYWnd_constructToolbar(toolbar); - space(); - CamWnd_constructToolbar(toolbar); - space(); - Patch_constructToolbar(toolbar); - - space(); - toolbar_append_toggle_button(toolbar, "Texture Lock", "texture_lock.xpm", "TogTexLock"); - space(); - toolbar_append_button(toolbar, "Refresh Assets", "refresh_models.xpm", - "RefreshReferences"); - - toolbar_append_toggle_button(toolbar, "Auto-Expand Selection", "select_autoexpand.xpm", - "ToggleExpansion"); - toolbar_append_toggle_button(toolbar, "Additive Selection", "select_additive.xpm", - "ToggleAddSelect"); - - PluginToolbar_AddToMain(toolbar); - - - return toolbar; -} - -ui::Toolbar create_main_sidebar() -{ - auto toolbar = ui::Toolbar::from(gtk_toolbar_new()); - gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_VERTICAL); - gtk_toolbar_set_style(toolbar, GTK_TOOLBAR_ICONS); - toolbar.show(); - - auto space = [&]() { - auto btn = ui::ToolItem::from(gtk_separator_tool_item_new()); - btn.show(); - toolbar.add(btn); - }; - - toolbar_append_toggle_button(toolbar, "Create", "side_select.png", "Modifier1"); - toolbar_append_toggle_button(toolbar, "Select Face", "side_selectface.png", "Modifier3"); - toolbar_append_toggle_button(toolbar, "Select-Whole", "side_selectwhole.png", "Modifier2"); - space(); - toolbar_append_toggle_button(toolbar, "Resize (Q)", "side_resize.png", "MouseDrag"); - toolbar_append_toggle_button(toolbar, "Translate (W)", "side_move.png", "MouseTranslate"); - toolbar_append_toggle_button(toolbar, "Rotate (R)", "side_rotate.png", "MouseRotate"); - toolbar_append_toggle_button(toolbar, "Scale", "side_scale.png", "MouseScale"); - toolbar_append_toggle_button(toolbar, "Clipper", "side_cut.png", "ToggleClipper"); - space(); - toolbar_append_button(toolbar, "Texture Browser", "side_tex.png", "ToggleTextures"); - toolbar_append_button(toolbar, "Entity Inspector", "side_entspec.png", "ToggleEntityInspector"); - toolbar_append_button(toolbar, "Surface Inspector", "side_surfspec.png", "SurfaceInspector"); - toolbar_append_button(toolbar, "Patch Inspector", "side_patchspec.png", "PatchInspector"); - return toolbar; -} - -ui::Widget create_main_statusbar(ui::Widget pStatusLabel[c_count_status]) -{ - auto table = ui::Table(1, c_count_status, FALSE); - table.show(); - - { - auto label = ui::Label("Label"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_misc_set_padding(GTK_MISC(label), 4, 2); - label.show(); - table.attach(label, {0, 1, 0, 1}); - pStatusLabel[c_command_status] = ui::Widget(label); - } - - for (unsigned int i = 1; (int) i < c_count_status; ++i) { - auto frame = ui::Frame(); - frame.show(); - table.attach(frame, {i, i + 1, 0, 1}); - gtk_frame_set_shadow_type(frame, GTK_SHADOW_IN); - - auto label = ui::Label("Label"); - gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_misc_set_padding(GTK_MISC(label), 4, 2); - label.show(); - frame.add(label); - pStatusLabel[i] = ui::Widget(label); - } - - return ui::Widget(table); -} - -#if 0 - - -WidgetFocusPrinter g_mainframeWidgetFocusPrinter( "mainframe" ); - -class WindowFocusPrinter -{ -const char* m_name; - -static gboolean frame_event( ui::Widget widget, GdkEvent* event, WindowFocusPrinter* self ){ - globalOutputStream() << self->m_name << " frame_event\n"; - return FALSE; -} -static gboolean keys_changed( ui::Widget widget, WindowFocusPrinter* self ){ - globalOutputStream() << self->m_name << " keys_changed\n"; - return FALSE; -} -static gboolean notify( ui::Window window, gpointer dummy, WindowFocusPrinter* self ){ - if ( gtk_window_is_active( window ) ) { - globalOutputStream() << self->m_name << " takes toplevel focus\n"; - } - else - { - globalOutputStream() << self->m_name << " loses toplevel focus\n"; - } - return FALSE; -} -public: -WindowFocusPrinter( const char* name ) : m_name( name ){ -} -void connect( ui::Window toplevel_window ){ - toplevel_window.connect( "notify::has_toplevel_focus", G_CALLBACK( notify ), this ); - toplevel_window.connect( "notify::is_active", G_CALLBACK( notify ), this ); - toplevel_window.connect( "keys_changed", G_CALLBACK( keys_changed ), this ); - toplevel_window.connect( "frame_event", G_CALLBACK( frame_event ), this ); -} -}; - -WindowFocusPrinter g_mainframeFocusPrinter( "mainframe" ); - -#endif - -class MainWindowActive { -static gboolean notify(ui::Window window, gpointer dummy, MainWindowActive *self) -{ - if (g_wait.m_window && gtk_window_is_active(window) && !g_wait.m_window.visible()) { - g_wait.m_window.show(); - } - - return FALSE; -} - -public: -void connect(ui::Window toplevel_window) -{ - toplevel_window.connect("notify::is-active", G_CALLBACK(notify), this); -} -}; - -MainWindowActive g_MainWindowActive; - -SignalHandlerId XYWindowDestroyed_connect(const SignalHandler &handler) -{ - return g_pParentWnd->GetXYWnd()->onDestroyed.connectFirst(handler); -} - -void XYWindowDestroyed_disconnect(SignalHandlerId id) -{ - g_pParentWnd->GetXYWnd()->onDestroyed.disconnect(id); -} - -MouseEventHandlerId XYWindowMouseDown_connect(const MouseEventHandler &handler) -{ - return g_pParentWnd->GetXYWnd()->onMouseDown.connectFirst(handler); -} - -void XYWindowMouseDown_disconnect(MouseEventHandlerId id) -{ - g_pParentWnd->GetXYWnd()->onMouseDown.disconnect(id); -} - -// ============================================================================= -// MainFrame class - -MainFrame *g_pParentWnd = 0; - -ui::Window MainFrame_getWindow() -{ - return g_pParentWnd ? g_pParentWnd->m_window : ui::Window{ui::null}; -} - -std::vector g_floating_windows; - -MainFrame::MainFrame() : m_idleRedrawStatusText(RedrawStatusTextCaller(*this)) -{ - m_pXYWnd = 0; - m_pCamWnd = 0; - m_pZWnd = 0; - m_pYZWnd = 0; - m_pXZWnd = 0; - m_pActiveXY = 0; - - for (auto &n : m_pStatusLabel) { - n = NULL; - } - - m_bSleeping = false; - - Create(); -} - -MainFrame::~MainFrame() -{ - SaveWindowInfo(); - - m_window.hide(); - - Shutdown(); - - for (std::vector::iterator i = g_floating_windows.begin(); i != g_floating_windows.end(); ++i) { - i->destroy(); - } - - m_window.destroy(); -} - -void MainFrame::SetActiveXY(XYWnd *p) -{ - if (m_pActiveXY) { - m_pActiveXY->SetActive(false); - } - - m_pActiveXY = p; - - if (m_pActiveXY) { - m_pActiveXY->SetActive(true); - } - -} - -void MainFrame::ReleaseContexts() -{ -#if 0 - if ( m_pXYWnd ) { - m_pXYWnd->DestroyContext(); - } - if ( m_pYZWnd ) { - m_pYZWnd->DestroyContext(); - } - if ( m_pXZWnd ) { - m_pXZWnd->DestroyContext(); - } - if ( m_pCamWnd ) { - m_pCamWnd->DestroyContext(); - } - if ( m_pTexWnd ) { - m_pTexWnd->DestroyContext(); - } - if ( m_pZWnd ) { - m_pZWnd->DestroyContext(); - } -#endif -} - -void MainFrame::CreateContexts() -{ -#if 0 - if ( m_pCamWnd ) { - m_pCamWnd->CreateContext(); - } - if ( m_pXYWnd ) { - m_pXYWnd->CreateContext(); - } - if ( m_pYZWnd ) { - m_pYZWnd->CreateContext(); - } - if ( m_pXZWnd ) { - m_pXZWnd->CreateContext(); - } - if ( m_pTexWnd ) { - m_pTexWnd->CreateContext(); - } - if ( m_pZWnd ) { - m_pZWnd->CreateContext(); - } -#endif -} - -#if GDEF_DEBUG -//#define DBG_SLEEP -#endif - -void MainFrame::OnSleep() -{ -#if 0 - m_bSleeping ^= 1; - if ( m_bSleeping ) { - // useful when trying to debug crashes in the sleep code - globalOutputStream() << "Going into sleep mode..\n"; - - globalOutputStream() << "Dispatching sleep msg..."; - DispatchRadiantMsg( RADIANT_SLEEP ); - globalOutputStream() << "Done.\n"; - - gtk_window_iconify( m_window ); - GlobalSelectionSystem().setSelectedAll( false ); - - GlobalShaderCache().unrealise(); - Shaders_Free(); - GlobalOpenGL_debugAssertNoErrors(); - ScreenUpdates_Disable(); - - // release contexts - globalOutputStream() << "Releasing contexts..."; - ReleaseContexts(); - globalOutputStream() << "Done.\n"; - } - else - { - globalOutputStream() << "Waking up\n"; - - gtk_window_deiconify( m_window ); - - // create contexts - globalOutputStream() << "Creating contexts..."; - CreateContexts(); - globalOutputStream() << "Done.\n"; - - globalOutputStream() << "Making current on camera..."; - m_pCamWnd->MakeCurrent(); - globalOutputStream() << "Done.\n"; - - globalOutputStream() << "Reloading shaders..."; - Shaders_Load(); - GlobalShaderCache().realise(); - globalOutputStream() << "Done.\n"; - - ScreenUpdates_Enable(); - - globalOutputStream() << "Dispatching wake msg..."; - DispatchRadiantMsg( RADIANT_WAKEUP ); - globalOutputStream() << "Done\n"; - } -#endif -} - - -ui::Window create_splash() -{ - auto window = ui::Window(ui::window_type::TOP); - gtk_window_set_decorated(window, false); - gtk_window_set_resizable(window, false); - gtk_window_set_modal(window, true); - gtk_window_set_default_size(window, -1, -1); - gtk_window_set_position(window, GTK_WIN_POS_CENTER); - gtk_container_set_border_width(window, 0); - - auto image = new_local_image("splash.xpm"); - image.show(); - window.add(image); - - window.dimensions(-1, -1); - window.show(); - - return window; -} - -static ui::Window splash_screen{ui::null}; - -void show_splash() -{ - splash_screen = create_splash(); - - ui::process(); -} - -void hide_splash() -{ - splash_screen.destroy(); -} - -WindowPositionTracker g_posCamWnd; -WindowPositionTracker g_posXYWnd; -WindowPositionTracker g_posXZWnd; -WindowPositionTracker g_posYZWnd; - -static gint mainframe_delete(ui::Widget widget, GdkEvent *event, gpointer data) -{ - if (ConfirmModified("Exit WorldSpawn")) { - gtk_main_quit(); - } - - return TRUE; -} - -void MainFrame::Create() -{ - ui::Window window = ui::Window(ui::window_type::TOP); - GlobalWindowObservers_connectTopLevel(window); - gtk_window_set_transient_for(splash_screen, window); - -#if !GDEF_OS_WINDOWS - { - GdkPixbuf *pixbuf = pixbuf_new_from_file_with_mask("bitmaps/icon.xpm"); - if (pixbuf != 0) { - gtk_window_set_icon(window, pixbuf); - g_object_unref(pixbuf); - } - } -#endif - - gtk_widget_add_events(window, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK); - window.connect("delete_event", G_CALLBACK(mainframe_delete), this); - m_position_tracker.connect(window); - -#if 0 - g_mainframeWidgetFocusPrinter.connect( window ); - g_mainframeFocusPrinter.connect( window ); -#endif - - g_MainWindowActive.connect(window); - - GetPlugInMgr().Init(window); - - auto vbox = ui::VBox(FALSE, 0); - auto hbox = ui::HBox(FALSE, 0); - window.add(vbox); - window.add(hbox); - vbox.show(); - hbox.show(); - - global_accel_connect_window(window); - - register_shortcuts(); - - auto main_menu = create_main_menu(); - vbox.pack_start(main_menu, FALSE, FALSE, 0); - - auto main_toolbar = create_main_toolbar(); - vbox.pack_start(main_toolbar, FALSE, FALSE, 0); - - auto main_sidebar = create_main_sidebar(); - hbox.pack_start(main_sidebar, FALSE, FALSE, 0); - - /*if (!g_Layout_enablePluginToolbar.m_value) { - plugin_toolbar.hide(); - }*/ - - ui::Widget main_statusbar = create_main_statusbar(reinterpret_cast(m_pStatusLabel)); - vbox.pack_end(main_statusbar, FALSE, TRUE, 2); - - GroupDialog_constructWindow(window); - g_page_entity = GroupDialog_addPage("Entities", EntityInspector_constructWindow(GroupDialog_getWindow()), - RawStringExportCaller("Entities")); - - m_window = window; - - window.show(); - - 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(); - - auto split = create_split_views(camera, yz, xy, xz); - vbox.pack_start(hbox, TRUE, TRUE, 0); - - hbox.pack_start(split, TRUE, TRUE, 0); - - { - auto frame = create_framed_widget(TextureBrowser_constructWindow(window)); - g_page_textures = GroupDialog_addPage("Textures", frame, TextureBrowserExportTitleCaller()); - } - - #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 ); - } - #endif - -#if 1 - if (g_layout_globals.nState & GDK_WINDOW_STATE_MAXIMIZED) { - WindowPosition default_position(-1, -1, 640, 480); - window_set_position(window, default_position); - gtk_window_maximize(window); - } else { - window_set_position(window, g_layout_globals.m_position); - gtk_window_resize(window, g_layout_globals.m_position.w, g_layout_globals.m_position.h); - } - UpdateAllWindows(); -#else - WindowPosition default_position(-1, -1, 640, 480); - window_set_position(window, default_position); -#endif - - EntityList_constructWindow(window); - PreferencesDialog_constructWindow(window); - FindTextureDialog_constructWindow(window); - SurfaceInspector_constructWindow(window); - PatchInspector_constructWindow(window); - SetActiveXY(m_pXYWnd); - AddGridChangeCallback(SetGridStatusCaller(*this)); - AddGridChangeCallback(ReferenceCaller(*this)); - g_defaultToolMode = DragMode; - g_defaultToolMode(); - SetStatusText(m_command_status, c_TranslateMode_status); - EverySecondTimer_enable(); -} - -void MainFrame::SaveWindowInfo() -{ - /*if (!FloatingGroupDialog()) { - g_layout_globals.nXYHeight = gtk_paned_get_position(GTK_PANED(m_vSplit)); - - if (CurrentStyle() != eRegular) { - g_layout_globals.nCamWidth = gtk_paned_get_position(GTK_PANED(m_hSplit)); - } else { - g_layout_globals.nXYWidth = gtk_paned_get_position(GTK_PANED(m_hSplit)); - } - - g_layout_globals.nCamHeight = gtk_paned_get_position(GTK_PANED(m_vSplit2)); - }*/ - - g_layout_globals.m_position = m_position_tracker.getPosition(); - g_layout_globals.nState = gdk_window_get_state(gtk_widget_get_window(m_window)); -} - -void MainFrame::Shutdown() -{ - EverySecondTimer_disable(); - - EntityList_destroyWindow(); - - delete m_pXYWnd; - m_pXYWnd = 0; - delete m_pYZWnd; - m_pYZWnd = 0; - delete m_pXZWnd; - m_pXZWnd = 0; - - TextureBrowser_destroyWindow(); - - DeleteCamWnd(m_pCamWnd); - m_pCamWnd = 0; - - PreferencesDialog_destroyWindow(); - SurfaceInspector_destroyWindow(); - FindTextureDialog_destroyWindow(); - PatchInspector_destroyWindow(); - - g_DbgDlg.destroyWindow(); - - // destroying group-dialog last because it may contain texture-browser - GroupDialog_destroyWindow(); -} - -void MainFrame::RedrawStatusText() -{ - ui::Label::from(m_pStatusLabel[c_command_status]).text(m_command_status.c_str()); - ui::Label::from(m_pStatusLabel[c_position_status]).text(m_position_status.c_str()); - ui::Label::from(m_pStatusLabel[c_brushcount_status]).text(m_brushcount_status.c_str()); - ui::Label::from(m_pStatusLabel[c_texture_status]).text(m_texture_status.c_str()); - ui::Label::from(m_pStatusLabel[c_grid_status]).text(m_grid_status.c_str()); -} - -void MainFrame::UpdateStatusText() -{ - m_idleRedrawStatusText.queueDraw(); -} - -void MainFrame::SetStatusText(CopiedString &status_text, const char *pText) -{ - status_text = pText; - UpdateStatusText(); -} - -void Sys_Status(const char *status) -{ - if (g_pParentWnd != 0) { - g_pParentWnd->SetStatusText(g_pParentWnd->m_command_status, status); - } -} - -int getRotateIncrement() -{ - return static_cast( g_si_globals.rotate ); -} - -int getFarClipDistance() -{ - return g_camwindow_globals.m_nCubicScale; -} - -float ( *GridStatus_getGridSize )() = GetGridSize; - -int ( *GridStatus_getRotateIncrement )() = getRotateIncrement; - -int ( *GridStatus_getFarClipDistance )() = getFarClipDistance; - -bool ( *GridStatus_getTextureLockEnabled )(); - -void MainFrame::SetGridStatus() -{ - StringOutputStream status(64); - const char *lock = (GridStatus_getTextureLockEnabled()) ? "ON" : "OFF"; - status << (GetSnapGridSize() > 0 ? "G:" : "g:") << GridStatus_getGridSize() - << " R:" << GridStatus_getRotateIncrement() - << " C:" << GridStatus_getFarClipDistance() - << " L:" << lock; - SetStatusText(m_grid_status, status.c_str()); -} - -void GridStatus_onTextureLockEnabledChanged() -{ - if (g_pParentWnd != 0) { - g_pParentWnd->SetGridStatus(); - } -} - -void GlobalGL_sharedContextCreated() -{ - GLFont *g_font = NULL; - - // report OpenGL information -#if 0 - globalOutputStream() << "GL_VENDOR: " << reinterpret_cast( glGetString(GL_VENDOR)) << "\n"; - globalOutputStream() << "GL_RENDERER: " << reinterpret_cast( glGetString(GL_RENDERER)) << "\n"; - globalOutputStream() << "GL_VERSION: " << reinterpret_cast( glGetString(GL_VERSION)) << "\n"; - const auto extensions = reinterpret_cast( glGetString(GL_EXTENSIONS)); - globalOutputStream() << "GL_EXTENSIONS: " << (extensions ? extensions : "") << "\n"; -#endif - - QGL_sharedContextCreated(GlobalOpenGL()); - - ShaderCache_extensionsInitialised(); - - GlobalShaderCache().realise(); - Textures_Realise(); - - g_font = glfont_create("Misc Fixed 12"); - - GlobalOpenGL().m_font = g_font; -} - -void GlobalGL_sharedContextDestroyed() -{ - Textures_Unrealise(); - GlobalShaderCache().unrealise(); - - QGL_sharedContextDestroyed(GlobalOpenGL()); -} - - -void Layout_constructPreferences(PreferencesPage &page) -{ - - page.appendCheckBox( - "", "Plugin Toolbar", - make_property(g_Layout_enablePluginToolbar) - ); -} - -void Layout_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Layout", "Layout Preferences")); - Layout_constructPreferences(page); -} - -void Layout_registerPreferencesPage() -{ - PreferencesDialog_addInterfacePage(makeCallbackF(Layout_constructPage)); -} - -/* eukara: this makes things more sane */ -bool g_expansion_enabled = true; -Callback g_expansion_status_changed; -ConstReferenceCaller &), PropertyImpl::Export> g_expansion_caller( - g_expansion_enabled); -ToggleItem g_expansion_item(g_expansion_caller); - -void Texdef_ToggleExpansion() -{ - g_expansion_enabled = !g_expansion_enabled; - g_expansion_item.update(); - g_expansion_status_changed(); -} - -/* eukara: requested by Xylemon */ -bool g_addselect_enabled = true; -Callback g_addselect_status_changed; -ConstReferenceCaller &), PropertyImpl::Export> g_addselect_caller( - g_addselect_enabled); -ToggleItem g_addselect_item(g_addselect_caller); - -void Texdef_ToggleAddSelect() -{ - g_addselect_enabled = !g_addselect_enabled; - g_addselect_item.update(); - g_addselect_status_changed(); -} - -#include "preferencesystem.h" -#include "stringio.h" - -void MainFrame_Construct() -{ - /*GlobalCommands_insert("Sleep", makeCallbackF(thunk_OnSleep), - Accelerator('P', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK)));*/ - GlobalCommands_insert("NewMap", makeCallbackF(NewMap)); - GlobalCommands_insert("OpenMap", makeCallbackF(OpenMap), Accelerator('O', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("ImportMap", makeCallbackF(ImportMap)); - GlobalCommands_insert("SaveMap", makeCallbackF(SaveMap), Accelerator('S', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("SaveMapAs", makeCallbackF(SaveMapAs)); - GlobalCommands_insert("ExportSelected", makeCallbackF(ExportMap)); - GlobalCommands_insert("SaveRegion", makeCallbackF(SaveRegion)); - GlobalCommands_insert("RefreshReferences", makeCallbackF(VFS_Refresh)); - GlobalCommands_insert("ProjectSettings", makeCallbackF(DoProjectSettings)); - GlobalCommands_insert("Exit", makeCallbackF(Exit)); - - GlobalCommands_insert("Undo", makeCallbackF(Undo), Accelerator('Z', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Redo", makeCallbackF(Redo), Accelerator('Y', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Copy", makeCallbackF(Copy), Accelerator('C', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("Paste", makeCallbackF(Paste), Accelerator('V', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("PasteToCamera", makeCallbackF(PasteToCamera), - Accelerator('V', (GdkModifierType) GDK_MOD1_MASK)); - GlobalCommands_insert("CloneSelection", makeCallbackF(Selection_Clone), Accelerator(GDK_KEY_space)); - GlobalCommands_insert("CloneSelectionAndMakeUnique", makeCallbackF(Selection_Clone_MakeUnique), - Accelerator(GDK_KEY_space, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("DeleteSelection", makeCallbackF(deleteSelection), Accelerator(GDK_KEY_BackSpace)); - GlobalCommands_insert("ParentSelection", makeCallbackF(Scene_parentSelected)); - GlobalCommands_insert("UnSelectSelection", makeCallbackF(Selection_Deselect), Accelerator(GDK_KEY_Escape)); - GlobalCommands_insert("InvertSelection", makeCallbackF(Select_Invert), Accelerator('I')); - GlobalCommands_insert("SelectInside", makeCallbackF(Select_Inside)); - GlobalCommands_insert("SelectTouching", makeCallbackF(Select_Touching)); - GlobalCommands_insert("ExpandSelectionToEntities", makeCallbackF(Scene_ExpandSelectionToEntities), - Accelerator('E', (GdkModifierType) (GDK_MOD1_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("Preferences", makeCallbackF(PreferencesDialog_showDialog)); - - GlobalCommands_insert("ToggleEntityInspector", makeCallbackF(EntityInspector_ToggleShow), Accelerator('N')); - GlobalCommands_insert("EntityList", makeCallbackF(EntityList_toggleShown), Accelerator('L')); - - GlobalCommands_insert("ShowHidden", makeCallbackF(Select_ShowAllHidden), - Accelerator('H', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("HideSelected", makeCallbackF(HideSelected), Accelerator('H')); - GlobalCommands_insert("HideUnselected", makeCallbackF(HideUnselected)); - - GlobalToggles_insert("DragVertices", makeCallbackF(SelectVertexMode), - ToggleItem::AddCallbackCaller(g_vertexMode_button), Accelerator('V')); - GlobalToggles_insert("DragEdges", makeCallbackF(SelectEdgeMode), ToggleItem::AddCallbackCaller(g_edgeMode_button), - Accelerator('E')); - GlobalToggles_insert("DragFaces", makeCallbackF(SelectFaceMode), ToggleItem::AddCallbackCaller(g_faceMode_button), - Accelerator('F')); - - GlobalCommands_insert("MirrorSelectionX", makeCallbackF(Selection_Flipx)); - GlobalCommands_insert("RotateSelectionX", makeCallbackF(Selection_Rotatex)); - GlobalCommands_insert("MirrorSelectionY", makeCallbackF(Selection_Flipy)); - GlobalCommands_insert("RotateSelectionY", makeCallbackF(Selection_Rotatey)); - GlobalCommands_insert("MirrorSelectionZ", makeCallbackF(Selection_Flipz)); - GlobalCommands_insert("RotateSelectionZ", makeCallbackF(Selection_Rotatez)); - - GlobalCommands_insert("ArbitraryMove", makeCallbackF(DoMoveDlg)); - GlobalCommands_insert("ArbitraryRotation", makeCallbackF(DoRotateDlg)); - GlobalCommands_insert("ArbitraryScale", makeCallbackF(DoScaleDlg)); - - GlobalCommands_insert("BuildMenuCustomize", makeCallbackF(DoBuildMenu)); - - GlobalCommands_insert("FindBrush", makeCallbackF(DoFind)); - - GlobalCommands_insert("MapInfo", makeCallbackF(DoMapInfo), Accelerator('M')); - - GlobalToggles_insert("ToggleExpansion", makeCallbackF(Texdef_ToggleExpansion), - ToggleItem::AddCallbackCaller(g_expansion_item)); - - GlobalToggles_insert("ToggleAddSelect", makeCallbackF(Texdef_ToggleAddSelect), - ToggleItem::AddCallbackCaller(g_addselect_item)); - - GlobalToggles_insert("ToggleClipper", makeCallbackF(ClipperMode), ToggleItem::AddCallbackCaller(g_clipper_button), - Accelerator('X')); - - GlobalToggles_insert("MouseTranslate", makeCallbackF(TranslateMode), - ToggleItem::AddCallbackCaller(g_translatemode_button)); - GlobalToggles_insert("MouseRotate", makeCallbackF(RotateMode), ToggleItem::AddCallbackCaller(g_rotatemode_button), - Accelerator('R')); - GlobalToggles_insert("MouseScale", makeCallbackF(ScaleMode), ToggleItem::AddCallbackCaller(g_scalemode_button)); - GlobalToggles_insert("MouseDrag", makeCallbackF(DragMode), ToggleItem::AddCallbackCaller(g_dragmode_button), - Accelerator('Q')); - - - GlobalToggles_insert("Modifier1", makeCallbackF(Modifier1), ToggleItem::AddCallbackCaller(g_modifier1_button)); - GlobalToggles_insert("Modifier2", makeCallbackF(Modifier2), ToggleItem::AddCallbackCaller(g_modifier2_button)); - GlobalToggles_insert("Modifier3", makeCallbackF(Modifier3), ToggleItem::AddCallbackCaller(g_modifier3_button)); - - GlobalCommands_insert("ColorSchemeWS", makeCallbackF(ColorScheme_WorldSpawn)); - GlobalCommands_insert("ColorSchemeOriginal", makeCallbackF(ColorScheme_Original)); - GlobalCommands_insert("ColorSchemeQER", makeCallbackF(ColorScheme_QER)); - GlobalCommands_insert("ColorSchemeBlackAndGreen", makeCallbackF(ColorScheme_Black)); - GlobalCommands_insert("ColorSchemeYdnar", makeCallbackF(ColorScheme_Ydnar)); - 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("ChooseGridMinorColor", makeCallback(g_ColoursMenu.m_gridminor)); - GlobalCommands_insert("ChooseSmallGridMajorColor", makeCallback(g_ColoursMenu.m_gridmajor_alt)); - GlobalCommands_insert("ChooseSmallGridMinorColor", makeCallback(g_ColoursMenu.m_gridminor_alt)); - GlobalCommands_insert("ChooseGridTextColor", makeCallback(g_ColoursMenu.m_gridtext)); - GlobalCommands_insert("ChooseGridBlockColor", makeCallback(g_ColoursMenu.m_gridblock)); - GlobalCommands_insert("ChooseBrushColor", makeCallback(g_ColoursMenu.m_brush)); - GlobalCommands_insert("ChooseCameraBackgroundColor", makeCallback(g_ColoursMenu.m_cameraback)); - GlobalCommands_insert("ChooseSelectedBrushColor", makeCallback(g_ColoursMenu.m_selectedbrush)); - GlobalCommands_insert("ChooseCameraSelectedBrushColor", makeCallback(g_ColoursMenu.m_selectedbrush3d)); - GlobalCommands_insert("ChooseClipperColor", makeCallback(g_ColoursMenu.m_clipper)); - GlobalCommands_insert("ChooseOrthoViewNameColor", makeCallback(g_ColoursMenu.m_viewname)); - - - GlobalCommands_insert("CSGSubtract", makeCallbackF(CSG_Subtract), - Accelerator('U', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("CSGMerge", makeCallbackF(CSG_Merge), Accelerator('U', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("CSGMakeHollow", makeCallbackF(CSG_MakeHollow)); - GlobalCommands_insert("CSGMakeRoom", makeCallbackF(CSG_MakeRoom)); - - Grid_registerCommands(); - - GlobalCommands_insert("SnapToGrid", makeCallbackF(Selection_SnapToGrid), - Accelerator('G', (GdkModifierType) GDK_CONTROL_MASK)); - - GlobalCommands_insert("SelectAllOfType", makeCallbackF(Select_AllOfType), - Accelerator('A', (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalCommands_insert("SelectAllOfModel", makeCallbackF(Select_AllOfModel)); - - GlobalCommands_insert("TexRotateClock", makeCallbackF(Texdef_RotateClockwise), - Accelerator(GDK_KEY_Next, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexRotateCounter", makeCallbackF(Texdef_RotateAntiClockwise), - Accelerator(GDK_KEY_Prior, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexScaleUp", makeCallbackF(Texdef_ScaleUp), - Accelerator(GDK_KEY_Up, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("TexScaleDown", makeCallbackF(Texdef_ScaleDown), - Accelerator(GDK_KEY_Down, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("TexScaleLeft", makeCallbackF(Texdef_ScaleLeft), - Accelerator(GDK_KEY_Left, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("TexScaleRight", makeCallbackF(Texdef_ScaleRight), - Accelerator(GDK_KEY_Right, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("TexShiftUp", makeCallbackF(Texdef_ShiftUp), - Accelerator(GDK_KEY_Up, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexShiftDown", makeCallbackF(Texdef_ShiftDown), - Accelerator(GDK_KEY_Down, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexShiftLeft", makeCallbackF(Texdef_ShiftLeft), - Accelerator(GDK_KEY_Left, (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("TexShiftRight", makeCallbackF(Texdef_ShiftRight), - Accelerator(GDK_KEY_Right, (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalCommands_insert("MoveSelectionDOWN", makeCallbackF(Selection_MoveDown), Accelerator(GDK_KEY_KP_Subtract)); - GlobalCommands_insert("MoveSelectionUP", makeCallbackF(Selection_MoveUp), Accelerator(GDK_KEY_KP_Add)); - - GlobalCommands_insert("SelectNudgeLeft", makeCallbackF(Selection_NudgeLeft), - Accelerator(GDK_KEY_Left, (GdkModifierType) GDK_MOD1_MASK)); - GlobalCommands_insert("SelectNudgeRight", makeCallbackF(Selection_NudgeRight), - Accelerator(GDK_KEY_Right, (GdkModifierType) GDK_MOD1_MASK)); - GlobalCommands_insert("SelectNudgeUp", makeCallbackF(Selection_NudgeUp), - Accelerator(GDK_KEY_Up, (GdkModifierType) GDK_MOD1_MASK)); - GlobalCommands_insert("SelectNudgeDown", makeCallbackF(Selection_NudgeDown), - Accelerator(GDK_KEY_Down, (GdkModifierType) GDK_MOD1_MASK)); - - Patch_registerCommands(); - XYShow_registerCommands(); - - typedef FreeCaller ComponentModeSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(ComponentModeSelectionChangedCaller()); - - GlobalPreferenceSystem().registerPreference("PluginToolBar", - make_property_string(g_Layout_enablePluginToolbar.m_latched)); - GlobalPreferenceSystem().registerPreference("XYHeight", make_property_string(g_layout_globals.nXYHeight)); - GlobalPreferenceSystem().registerPreference("XYWidth", make_property_string(g_layout_globals.nXYWidth)); - GlobalPreferenceSystem().registerPreference("CamWidth", make_property_string(g_layout_globals.nCamWidth)); - GlobalPreferenceSystem().registerPreference("CamHeight", make_property_string(g_layout_globals.nCamHeight)); - - GlobalPreferenceSystem().registerPreference("State", make_property_string(g_layout_globals.nState)); - GlobalPreferenceSystem().registerPreference("PositionX", make_property_string(g_layout_globals.m_position.x)); - GlobalPreferenceSystem().registerPreference("PositionY", make_property_string(g_layout_globals.m_position.y)); - GlobalPreferenceSystem().registerPreference("Width", make_property_string(g_layout_globals.m_position.w)); - GlobalPreferenceSystem().registerPreference("Height", make_property_string(g_layout_globals.m_position.h)); - - GlobalPreferenceSystem().registerPreference("CamWnd", make_property(g_posCamWnd)); - GlobalPreferenceSystem().registerPreference("XYWnd", make_property(g_posXYWnd)); - GlobalPreferenceSystem().registerPreference("YZWnd", make_property(g_posYZWnd)); - GlobalPreferenceSystem().registerPreference("XZWnd", make_property(g_posXZWnd)); - - { - const char *ENGINEPATH_ATTRIBUTE = -#if GDEF_OS_WINDOWS - "enginepath_win32" -#elif GDEF_OS_MACOS - "enginepath_macos" -#elif GDEF_OS_LINUX || GDEF_OS_BSD - "enginepath_linux" -#else -#error "unknown platform" -#endif - ; - StringOutputStream path(256); - path << DirectoryCleaned(g_pGameDescription->getRequiredKeyValue(ENGINEPATH_ATTRIBUTE)); - g_strEnginePath = path.c_str(); - } - - GlobalPreferenceSystem().registerPreference("EnginePath", make_property_string(g_strEnginePath)); - - g_Layout_enablePluginToolbar.useLatched(); - - Layout_registerPreferencesPage(); - Paths_registerPreferencesPage(); - - g_brushCount.setCountChangedCallback(makeCallbackF(QE_brushCountChanged)); - g_entityCount.setCountChangedCallback(makeCallbackF(QE_entityCountChanged)); - GlobalEntityCreator().setCounter(&g_entityCount); - - GLWidget_sharedContextCreated = GlobalGL_sharedContextCreated; - GLWidget_sharedContextDestroyed = GlobalGL_sharedContextDestroyed; - - GlobalEntityClassManager().attach(g_WorldspawnColourEntityClassObserver); -} - -void MainFrame_Destroy() -{ - GlobalEntityClassManager().detach(g_WorldspawnColourEntityClassObserver); - - GlobalEntityCreator().setCounter(0); - g_entityCount.setCountChangedCallback(Callback()); - g_brushCount.setCountChangedCallback(Callback()); -} - - -void GLWindow_Construct() -{ - GlobalPreferenceSystem().registerPreference("MouseButtons", make_property_string(g_glwindow_globals.m_nMouseType)); -} - -void GLWindow_Destroy() -{ -} diff --git a/src/mainframe.h b/src/mainframe.h deleted file mode 100644 index 9954e73..0000000 --- a/src/mainframe.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MAINFRAME_H ) -#define INCLUDED_MAINFRAME_H - -#include -#include "gtkutil/window.h" -#include "gtkutil/idledraw.h" -#include "gtkutil/widget.h" -#include "string/string.h" - -#include "qerplugin.h" - -class IPlugIn; -class IToolbarButton; -class XYWnd; -class CamWnd; -class ZWnd; - - -const int c_command_status = 0; -const int c_position_status = 1; -const int c_brushcount_status = 2; -const int c_texture_status = 3; -const int c_grid_status = 4; -const int c_count_status = 5; - -class MainFrame { -public: -enum EViewStyle { - eRegular = 0, - eFloating = 1, - eSplit = 2, - eRegularLeft = 3, -}; - -MainFrame(); - -~MainFrame(); - -ui::Window m_window{ui::null}; - -CopiedString m_command_status; -CopiedString m_position_status; -CopiedString m_brushcount_status; -CopiedString m_texture_status; -CopiedString m_grid_status; -private: - -void Create(); - -void SaveWindowInfo(); - -void Shutdown(); - -ui::Widget m_vSplit{ui::null}; -ui::Widget m_hSplit{ui::null}; -ui::Widget m_vSplit2{ui::null}; - -XYWnd *m_pXYWnd; -XYWnd *m_pYZWnd; -XYWnd *m_pXZWnd; -CamWnd *m_pCamWnd; -ZWnd *m_pZWnd; -XYWnd *m_pActiveXY; - -bool m_bSleeping; - -void *m_pStatusLabel[c_count_status]; - -WindowPositionTracker m_position_tracker; - -IdleDraw m_idleRedrawStatusText; - -public: - -bool IsSleeping() -{ - return m_bSleeping; -} - -void OnSleep(); - -void SetStatusText(CopiedString &status_text, const char *pText); - -void UpdateStatusText(); - -void RedrawStatusText(); - -typedef MemberCaller RedrawStatusTextCaller; - -void SetGridStatus(); - -typedef MemberCaller SetGridStatusCaller; - -void SetActiveXY(XYWnd *p); - -XYWnd *ActiveXY() -{ - return m_pActiveXY; -}; - -XYWnd *GetXYWnd() -{ - return m_pXYWnd; -} - -XYWnd *GetXZWnd() -{ - return m_pXZWnd; -} - -XYWnd *GetYZWnd() -{ - return m_pYZWnd; -} - -ZWnd *GetZWnd() -{ - return m_pZWnd; -} - -CamWnd *GetCamWnd() -{ - return m_pCamWnd; -} - -void ReleaseContexts(); - -void CreateContexts(); -}; - -extern MainFrame *g_pParentWnd; - -ui::Window MainFrame_getWindow(); - -enum EMouseButtonMode { - ETwoButton = 0, - EThreeButton = 1, -}; - -struct glwindow_globals_t { - int m_nMouseType; - - glwindow_globals_t() : - m_nMouseType(EThreeButton) - { - } -}; - -void GLWindow_Construct(); - -void GLWindow_Destroy(); - -extern glwindow_globals_t g_glwindow_globals; - -template -class LatchedValue; - -extern LatchedValue g_Layout_enableOpenStepUX; - -void deleteSelection(); - - -void Sys_Status(const char *status); - - -void ScreenUpdates_Disable(const char *message, const char *title); - -void ScreenUpdates_Enable(); - -bool ScreenUpdates_Enabled(); - -void ScreenUpdates_process(); - -class ScopeDisableScreenUpdates { -public: -ScopeDisableScreenUpdates(const char *message, const char *title) -{ - ScreenUpdates_Disable(message, title); -} - -~ScopeDisableScreenUpdates() -{ - ScreenUpdates_Enable(); -} -}; - - -void EnginePath_Realise(); - -void EnginePath_Unrealise(); - -class ModuleObserver; - -void Radiant_attachEnginePathObserver(ModuleObserver &observer); - -void Radiant_detachEnginePathObserver(ModuleObserver &observer); - -void Radiant_attachGameToolsPathObserver(ModuleObserver &observer); - -void Radiant_detachGameToolsPathObserver(ModuleObserver &observer); - -extern CopiedString g_strEnginePath; - -void EnginePath_verify(); - -const char *EnginePath_get(); - -const char *QERApp_GetGamePath(); - -extern bool g_disableEnginePath; - -extern CopiedString g_strAppPath; - -const char *AppPath_get(); - -extern CopiedString g_strSettingsPath; - -const char *SettingsPath_get(); - -const char *LocalRcPath_get(void); - -const char *const g_pluginsDir = "plugins/"; ///< name of plugins directory, always sub-directory of toolspath - -extern CopiedString g_strGameToolsPath; - -const char *GameToolsPath_get(); - -void Radiant_Initialise(); - -void Radiant_Shutdown(); - -void SaveMapAs(); - - -void XY_UpdateAllWindows(); - -void UpdateAllWindows(); - - -void ClipperChangeNotify(); - -void DefaultMode(); - -const char *basegame_get(); - -const char *gamename_get(); - -void gamename_set(const char *gamename); - -void Radiant_attachGameNameObserver(ModuleObserver &observer); - -void Radiant_detachGameNameObserver(ModuleObserver &observer); - -const char *gamemode_get(); - -void gamemode_set(const char *gamemode); - -void Radiant_attachGameModeObserver(ModuleObserver &observer); - -void Radiant_detachGameModeObserver(ModuleObserver &observer); - -void VFS_Refresh(); - -void VFS_Restart(); - -void VFS_Construct(); - -void VFS_Destroy(); - - -void MainFrame_Construct(); - -void MainFrame_Destroy(); - - -extern float ( *GridStatus_getGridSize )(); - -extern int ( *GridStatus_getRotateIncrement )(); - -extern int ( *GridStatus_getFarClipDistance )(); - -extern bool ( *GridStatus_getTextureLockEnabled )(); - -void GridStatus_onTextureLockEnabledChanged(); - -SignalHandlerId XYWindowDestroyed_connect(const SignalHandler &handler); - -void XYWindowDestroyed_disconnect(SignalHandlerId id); - -MouseEventHandlerId XYWindowMouseDown_connect(const MouseEventHandler &handler); - -void XYWindowMouseDown_disconnect(MouseEventHandlerId id); - -extern ui::Widget g_page_entity; - -#endif diff --git a/tools/vmap/map.c b/src/map.c similarity index 100% rename from tools/vmap/map.c rename to src/map.c diff --git a/src/map.cpp b/src/map.cpp deleted file mode 100644 index aa0907e..0000000 --- a/src/map.cpp +++ /dev/null @@ -1,2386 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "map.h" - -#include - -#include "debugging/debugging.h" - -#include "imap.h" - -MapModules &ReferenceAPI_getMapModules(); - -#include "iselection.h" -#include "iundo.h" -#include "ibrush.h" -#include "ifilter.h" -#include "ireference.h" -#include "ifiletypes.h" -#include "ieclass.h" -#include "irender.h" -#include "ientity.h" -#include "editable.h" -#include "iarchive.h" -#include "ifilesystem.h" -#include "namespace.h" -#include "moduleobserver.h" - -#include - -#include -#include "uilib/uilib.h" - -#include "scenelib.h" -#include "transformlib.h" -#include "selectionlib.h" -#include "instancelib.h" -#include "traverselib.h" -#include "maplib.h" -#include "eclasslib.h" -#include "cmdlib.h" -#include "stream/textfilestream.h" -#include "os/path.h" -#include "uniquenames.h" -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" -#include "stream/stringstream.h" -#include "signal/signal.h" - -#include "gtkutil/filechooser.h" -#include "timer.h" -#include "select.h" -#include "plugin.h" -#include "filetypes.h" -#include "gtkdlgs.h" -#include "entityinspector.h" -#include "points.h" -#include "qe3.h" -#include "camwindow.h" -#include "xywindow.h" -#include "mainframe.h" -#include "preferences.h" -#include "preferencesystem.h" -#include "referencecache.h" -#include "mru.h" -#include "commands.h" -#include "autosave.h" -#include "brushmodule.h" -#include "brush.h" - -class NameObserver { -UniqueNames &m_names; -CopiedString m_name; - -void construct() -{ - if (!empty()) { - //globalOutputStream() << "construct " << makeQuoted(c_str()) << "\n"; - m_names.insert(name_read(c_str())); - } -} - -void destroy() -{ - if (!empty()) { - //globalOutputStream() << "destroy " << makeQuoted(c_str()) << "\n"; - m_names.erase(name_read(c_str())); - } -} - -NameObserver &operator=(const NameObserver &other); - -public: -NameObserver(UniqueNames &names) : m_names(names) -{ - construct(); -} - -NameObserver(const NameObserver &other) : m_names(other.m_names), m_name(other.m_name) -{ - construct(); -} - -~NameObserver() -{ - destroy(); -} - -bool empty() const -{ - return string_empty(c_str()); -} - -const char *c_str() const -{ - return m_name.c_str(); -} - -void nameChanged(const char *name) -{ - destroy(); - m_name = name; - construct(); -} - -typedef MemberCaller NameChangedCaller; -}; - -class BasicNamespace : public Namespace { -typedef std::map Names; -Names m_names; -UniqueNames m_uniqueNames; -public: -~BasicNamespace() -{ - ASSERT_MESSAGE(m_names.empty(), "namespace: names still registered at shutdown"); -} - -void attach(const NameCallback &setName, const NameCallbackCallback &attachObserver) -{ - std::pair result = m_names.insert(Names::value_type(setName, m_uniqueNames)); - ASSERT_MESSAGE(result.second, "cannot attach name"); - attachObserver(NameObserver::NameChangedCaller((*result.first).second)); - //globalOutputStream() << "attach: " << reinterpret_cast(setName) << "\n"; -} - -void detach(const NameCallback &setName, const NameCallbackCallback &detachObserver) -{ - Names::iterator i = m_names.find(setName); - ASSERT_MESSAGE(i != m_names.end(), "cannot detach name"); - //globalOutputStream() << "detach: " << reinterpret_cast(setName) << "\n"; - detachObserver(NameObserver::NameChangedCaller((*i).second)); - m_names.erase(i); -} - -void makeUnique(const char *name, const NameCallback &setName) const -{ - char buffer[1024]; - name_write(buffer, m_uniqueNames.make_unique(name_read(name))); - setName(buffer); -} - -void mergeNames(const BasicNamespace &other) const -{ - typedef std::list SetNameCallbacks; - typedef std::map NameGroups; - NameGroups groups; - - UniqueNames uniqueNames(other.m_uniqueNames); - - for (Names::const_iterator i = m_names.begin(); i != m_names.end(); ++i) { - groups[(*i).second.c_str()].push_back((*i).first); - } - - for (NameGroups::iterator i = groups.begin(); i != groups.end(); ++i) { - name_t uniqueName(uniqueNames.make_unique(name_read((*i).first.c_str()))); - uniqueNames.insert(uniqueName); - - char buffer[1024]; - name_write(buffer, uniqueName); - - //globalOutputStream() << "renaming " << makeQuoted((*i).first.c_str()) << " to " << makeQuoted(buffer) << "\n"; - - SetNameCallbacks &setNameCallbacks = (*i).second; - - for (SetNameCallbacks::const_iterator j = setNameCallbacks.begin(); j != setNameCallbacks.end(); ++j) { - (*j)(buffer); - } - } -} -}; - -BasicNamespace g_defaultNamespace; -BasicNamespace g_cloneNamespace; - -class NamespaceAPI { -Namespace *m_namespace; -public: -typedef Namespace Type; - -STRING_CONSTANT(Name, "*"); - -NamespaceAPI() -{ - m_namespace = &g_defaultNamespace; -} - -Namespace *getTable() -{ - return m_namespace; -} -}; - -typedef SingletonModule NamespaceModule; -typedef Static StaticNamespaceModule; -StaticRegisterModule staticRegisterDefaultNamespace(StaticNamespaceModule::instance()); - - -std::list g_cloned; - -inline Namespaced *Node_getNamespaced(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -void Node_gatherNamespaced(scene::Node &node) -{ - Namespaced *namespaced = Node_getNamespaced(node); - if (namespaced != 0) { - g_cloned.push_back(namespaced); - } -} - -class GatherNamespaced : public scene::Traversable::Walker { -public: -bool pre(scene::Node &node) const -{ - Node_gatherNamespaced(node); - return true; -} -}; - -void Map_gatherNamespaced(scene::Node &root) -{ - Node_traverseSubgraph(root, GatherNamespaced()); -} - -void Map_mergeClonedNames() -{ - for (std::list::const_iterator i = g_cloned.begin(); i != g_cloned.end(); ++i) { - (*i)->setNamespace(g_cloneNamespace); - } - g_cloneNamespace.mergeNames(g_defaultNamespace); - for (std::list::const_iterator i = g_cloned.begin(); i != g_cloned.end(); ++i) { - (*i)->setNamespace(g_defaultNamespace); - } - - g_cloned.clear(); -} - -class WorldNode { -scene::Node *m_node; -public: -WorldNode() - : m_node(0) -{ -} - -void set(scene::Node *node) -{ - if (m_node != 0) { - m_node->DecRef(); - } - m_node = node; - if (m_node != 0) { - m_node->IncRef(); - } -} - -scene::Node *get() const -{ - return m_node; -} -}; - -class Map; - -void Map_SetValid(Map &map, bool valid); - -void Map_UpdateTitle(const Map &map); - -void Map_SetWorldspawn(Map &map, scene::Node *node); - - -class Map : public ModuleObserver { -public: -CopiedString m_name; -Resource *m_resource; -bool m_valid; - -bool m_modified; - -void ( *m_modified_changed )(const Map &); - -Signal0 m_mapValidCallbacks; - -WorldNode m_world_node; // "classname" "worldspawn" ! - -Map() : m_resource(0), m_valid(false), m_modified_changed(Map_UpdateTitle) -{ -} - -void realise() -{ - if (m_resource != 0) { - if (Map_Unnamed(*this)) { - g_map.m_resource->setNode(NewMapRoot("").get_pointer()); - MapFile *map = Node_getMapFile(*g_map.m_resource->getNode()); - if (map != 0) { - map->save(); - } - } else { - m_resource->load(); - } - - GlobalSceneGraph().insert_root(*m_resource->getNode()); - - AutoSave_clear(); - - Map_SetValid(g_map, true); - } -} - -void unrealise() -{ - if (m_resource != 0) { - Map_SetValid(g_map, false); - Map_SetWorldspawn(g_map, 0); - - - GlobalUndoSystem().clear(); - - GlobalSceneGraph().erase_root(); - } -} -}; - -Map g_map; -Map *g_currentMap = 0; - -void Map_addValidCallback(Map &map, const SignalHandler &handler) -{ - map.m_mapValidCallbacks.connectLast(handler); -} - -bool Map_Valid(const Map &map) -{ - return map.m_valid; -} - -void Map_SetValid(Map &map, bool valid) -{ - map.m_valid = valid; - map.m_mapValidCallbacks(); -} - - -const char *Map_Name(const Map &map) -{ - return map.m_name.c_str(); -} - -bool Map_Unnamed(const Map &map) -{ - return string_equal(Map_Name(map), "unnamed.map"); -} - -inline const MapFormat &MapFormat_forFile(const char *filename) -{ - const char *moduleName = findModuleName(GetFileTypeRegistry(), MapFormat::Name(), path_get_extension(filename)); - MapFormat *format = Radiant_getMapModules().findModule(moduleName); - ASSERT_MESSAGE(format != 0, "map format not found for file " << makeQuoted(filename)); - return *format; -} - -const MapFormat &Map_getFormat(const Map &map) -{ - return MapFormat_forFile(Map_Name(map)); -} - - -bool Map_Modified(const Map &map) -{ - return map.m_modified; -} - -void Map_SetModified(Map &map, bool modified) -{ - if (map.m_modified ^ modified) { - map.m_modified = modified; - - map.m_modified_changed(map); - } -} - -void Map_UpdateTitle(const Map &map) -{ - Sys_SetTitle(map.m_name.c_str(), Map_Modified(map)); -} - - -scene::Node *Map_GetWorldspawn(const Map &map) -{ - return map.m_world_node.get(); -} - -void Map_SetWorldspawn(Map &map, scene::Node *node) -{ - map.m_world_node.set(node); -} - - -// TTimo -// need that in a variable, will have to tweak depending on the game -float g_MaxWorldCoord = 64 * 1024; -float g_MinWorldCoord = -64 * 1024; - -void AddRegionBrushes(void); - -void RemoveRegionBrushes(void); - - -/* - ================ - Map_Free - free all map elements, reinitialize the structures that depend on them - ================ - */ -void Map_Free() -{ - Pointfile_Clear(); - - g_map.m_resource->detach(g_map); - GlobalReferenceCache().release(g_map.m_name.c_str()); - g_map.m_resource = 0; - - FlushReferences(); - - g_currentMap = 0; - Brush_unlatchPreferences(); -} - -class EntityFindByClassname : public scene::Graph::Walker { -const char *m_name; -Entity *&m_entity; -public: -EntityFindByClassname(const char *name, Entity *&entity) : m_name(name), m_entity(entity) -{ - m_entity = 0; -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (m_entity == 0) { - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && string_equal(m_name, entity->getKeyValue("classname"))) { - m_entity = entity; - } - } - return true; -} -}; - -Entity *Scene_FindEntityByClass(const char *name) -{ - Entity *entity; - GlobalSceneGraph().traverse(EntityFindByClassname(name, entity)); - return entity; -} - -#if 0 -// TODO: We probably want to make this game-specific and put it into the game definitions! -Entity *Scene_FindPlayerStart() -{ - typedef const char *StaticString; - StaticString strings[] = { - "info_player_start", - "info_player_deathmatch", - "team_CTF_redplayer", - "team_CTF_blueplayer", - "team_CTF_redspawn", - "team_CTF_bluespawn", - }; - typedef const StaticString *StaticStringIterator; - for (StaticStringIterator i = strings, end = strings + (sizeof(strings) / sizeof(StaticString)); i != end; ++i) { - Entity *entity = Scene_FindEntityByClass(*i); - if (entity != 0) { - return entity; - } - } - return 0; -} -#endif - -void FocusViews(const Vector3 &point, float angle) -{ - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - Camera_setOrigin(camwnd, point); - Vector3 angles(Camera_getAngles(camwnd)); - angles[CAMERA_PITCH] = 0; - angles[CAMERA_YAW] = angle; - Camera_setAngles(camwnd, angles); - - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - xywnd->SetOrigin(point); -} - -#include "stringio.h" - -// -// move the view to a start position -// -void GlobalCamera_GoToZero(); -void Map_StartPosition() -{ - GlobalCamera_GoToZero(); -} - -inline bool node_is_worldspawn(scene::Node &node) -{ - Entity *entity = Node_getEntity(node); - return entity != 0 && string_equal(entity->getKeyValue("classname"), "worldspawn"); -} - - -// use first worldspawn -class entity_updateworldspawn : public scene::Traversable::Walker { -public: -bool pre(scene::Node &node) const -{ - if (node_is_worldspawn(node)) { - if (Map_GetWorldspawn(g_map) == 0) { - Map_SetWorldspawn(g_map, &node); - } - } - return false; -} -}; - -scene::Node *Map_FindWorldspawn(Map &map) -{ - Map_SetWorldspawn(map, 0); - - Node_getTraversable(GlobalSceneGraph().root())->traverse(entity_updateworldspawn()); - - return Map_GetWorldspawn(map); -} - - -class CollectAllWalker : public scene::Traversable::Walker { -scene::Node &m_root; -UnsortedNodeSet &m_nodes; -public: -CollectAllWalker(scene::Node &root, UnsortedNodeSet &nodes) : m_root(root), m_nodes(nodes) -{ -} - -bool pre(scene::Node &node) const -{ - m_nodes.insert(NodeSmartReference(node)); - Node_getTraversable(m_root)->erase(node); - return false; -} -}; - -void Node_insertChildFirst(scene::Node &parent, scene::Node &child) -{ - UnsortedNodeSet nodes; - Node_getTraversable(parent)->traverse(CollectAllWalker(parent, nodes)); - Node_getTraversable(parent)->insert(child); - - for (UnsortedNodeSet::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node_getTraversable(parent)->insert((*i)); - } -} - -scene::Node &createWorldspawn() -{ - NodeSmartReference worldspawn( - GlobalEntityCreator().createEntity(GlobalEntityClassManager().findOrInsert("worldspawn", true))); - Node_insertChildFirst(GlobalSceneGraph().root(), worldspawn); - return worldspawn; -} - -void Map_UpdateWorldspawn(Map &map) -{ - if (Map_FindWorldspawn(map) == 0) { - Map_SetWorldspawn(map, &createWorldspawn()); - } -} - -scene::Node &Map_FindOrInsertWorldspawn(Map &map) -{ - Map_UpdateWorldspawn(map); - return *Map_GetWorldspawn(map); -} - - -class MapMergeAll : public scene::Traversable::Walker { -mutable scene::Path m_path; -public: -MapMergeAll(const scene::Path &root) - : m_path(root) -{ -} - -bool pre(scene::Node &node) const -{ - Node_getTraversable(m_path.top())->insert(node); - m_path.push(makeReference(node)); - selectPath(m_path, true); - return false; -} - -void post(scene::Node &node) const -{ - m_path.pop(); -} -}; - -class MapMergeEntities : public scene::Traversable::Walker { -mutable scene::Path m_path; -public: -MapMergeEntities(const scene::Path &root) - : m_path(root) -{ -} - -bool pre(scene::Node &node) const -{ - if (node_is_worldspawn(node)) { - scene::Node *world_node = Map_FindWorldspawn(g_map); - if (world_node == 0) { - Map_SetWorldspawn(g_map, &node); - Node_getTraversable(m_path.top().get())->insert(node); - m_path.push(makeReference(node)); - Node_getTraversable(node)->traverse(SelectChildren(m_path)); - } else { - m_path.push(makeReference(*world_node)); - Node_getTraversable(node)->traverse(MapMergeAll(m_path)); - } - } else { - Node_getTraversable(m_path.top())->insert(node); - m_path.push(makeReference(node)); - if (node_is_group(node)) { - Node_getTraversable(node)->traverse(SelectChildren(m_path)); - } else { - selectPath(m_path, true); - } - } - return false; -} - -void post(scene::Node &node) const -{ - m_path.pop(); -} -}; - -class BasicContainer : public scene::Node::Symbiot { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeContainedCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - -scene::Node m_node; -TraversableNodeSet m_traverse; -public: - -typedef LazyStatic StaticTypeCasts; - -scene::Traversable &get(NullType) -{ - return m_traverse; -} - -BasicContainer() : m_node(this, this, StaticTypeCasts::instance().get()) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} -}; - -/// Merges the map graph rooted at \p node into the global scene-graph. -void MergeMap(scene::Node &node) -{ - Node_getTraversable(node)->traverse(MapMergeEntities(scene::Path(makeReference(GlobalSceneGraph().root())))); -} - -void Map_ImportSelected(TextInputStream &in, const MapFormat &format) -{ - NodeSmartReference node((new BasicContainer)->node()); - format.readGraph(node, in, GlobalEntityCreator()); - Map_gatherNamespaced(node); - Map_mergeClonedNames(); - MergeMap(node); -} - -inline scene::Cloneable *Node_getCloneable(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -inline scene::Node &node_clone(scene::Node &node) -{ - scene::Cloneable *cloneable = Node_getCloneable(node); - if (cloneable != 0) { - return cloneable->clone(); - } - - return (new scene::NullNode)->node(); -} - -class CloneAll : public scene::Traversable::Walker { -mutable scene::Path m_path; -public: -CloneAll(scene::Node &root) - : m_path(makeReference(root)) -{ -} - -bool pre(scene::Node &node) const -{ - if (node.isRoot()) { - return false; - } - - m_path.push(makeReference(node_clone(node))); - m_path.top().get().IncRef(); - - return true; -} - -void post(scene::Node &node) const -{ - if (node.isRoot()) { - return; - } - - Node_getTraversable(m_path.parent())->insert(m_path.top()); - - m_path.top().get().DecRef(); - m_path.pop(); -} -}; - -scene::Node &Node_Clone(scene::Node &node) -{ - scene::Node &clone = node_clone(node); - scene::Traversable *traversable = Node_getTraversable(node); - if (traversable != 0) { - traversable->traverse(CloneAll(clone)); - } - return clone; -} - - -typedef std::map EntityBreakdown; - -class EntityBreakdownWalker : public scene::Graph::Walker { -EntityBreakdown &m_entitymap; -public: -EntityBreakdownWalker(EntityBreakdown &entitymap) - : m_entitymap(entitymap) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0) { - const EntityClass &eclass = entity->getEntityClass(); - if (m_entitymap.find(eclass.name()) == m_entitymap.end()) { - m_entitymap[eclass.name()] = 1; - } else { ++m_entitymap[eclass.name()]; } - } - return true; -} -}; - -void Scene_EntityBreakdown(EntityBreakdown &entitymap) -{ - GlobalSceneGraph().traverse(EntityBreakdownWalker(entitymap)); -} - - -WindowPosition g_posMapInfoWnd(c_default_window_pos); - -void DoMapInfo() -{ - ModalDialog dialog; - ui::Entry brushes_entry{ui::null}; - ui::Entry entities_entry{ui::null}; - ui::ListStore EntityBreakdownWalker{ui::null}; - - ui::Window window = MainFrame_getWindow().create_dialog_window("Map Info", G_CALLBACK(dialog_delete_callback), - &dialog); - - window_set_position(window, g_posMapInfoWnd); - - { - auto vbox = create_dialog_vbox(4, 4); - window.add(vbox); - - { - auto hbox = create_dialog_hbox(4); - vbox.pack_start(hbox, FALSE, TRUE, 0); - - { - auto table = create_dialog_table(2, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); - - brushes_entry = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); - - entities_entry = entry; - } - { - ui::Widget label = ui::Label("Total Brushes"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - ui::Widget label = ui::Label("Total Entities"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - } - { - auto vbox2 = create_dialog_vbox(4); - hbox.pack_start(vbox2, FALSE, FALSE, 0); - - { - auto button = create_dialog_button("Close", G_CALLBACK(dialog_button_ok), &dialog); - vbox2.pack_start(button, FALSE, FALSE, 0); - } - } - } - { - ui::Widget label = ui::Label("Entity breakdown"); - label.show(); - vbox.pack_start(label, FALSE, TRUE, 0); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto scr = create_scrolled_window(ui::Policy::NEVER, ui::Policy::AUTOMATIC, 4); - vbox.pack_start(scr, TRUE, TRUE, 0); - - { - auto store = ui::ListStore::from(gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_headers_clickable(view, TRUE); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Entity", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_sort_column_id(column, 0); - } - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Count", renderer, {{"text", 1}}); - gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_sort_column_id(column, 1); - } - - view.show(); - - scr.add(view); - - EntityBreakdownWalker = store; - } - } - } - - // Initialize fields - - { - EntityBreakdown entitymap; - Scene_EntityBreakdown(entitymap); - - for (EntityBreakdown::iterator i = entitymap.begin(); i != entitymap.end(); ++i) { - char tmp[16]; - sprintf(tmp, "%u", Unsigned((*i).second)); - EntityBreakdownWalker.append(0, (*i).first.c_str(), 1, tmp); - } - } - - EntityBreakdownWalker.unref(); - - char tmp[16]; - sprintf(tmp, "%u", Unsigned(g_brushCount.get())); - brushes_entry.text(tmp); - sprintf(tmp, "%u", Unsigned(g_entityCount.get())); - entities_entry.text(tmp); - - modal_dialog_show(window, dialog); - - // save before exit - window_get_position(window, g_posMapInfoWnd); - - window.destroy(); -} - - -class ScopeTimer { -Timer m_timer; -const char *m_message; -public: -ScopeTimer(const char *message) - : m_message(message) -{ - m_timer.start(); -} - -~ScopeTimer() -{ - double elapsed_time = m_timer.elapsed_msec() / 1000.f; - globalOutputStream() << m_message << " timer: " << FloatFormat(elapsed_time, 5, 2) << " second(s) elapsed\n"; -} -}; - -CopiedString g_strLastFolder = ""; - -/* - ================ - Map_LoadFile - ================ - */ - -void Map_LoadFile(const char *filename) -{ - globalOutputStream() << "Loading map from " << filename << "\n"; - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map"); - - MRU_AddFile(filename); - g_strLastFolder = g_path_get_dirname(filename); - - { - ScopeTimer timer("map load"); - - const MapFormat *format = NULL; - const char *moduleName = findModuleName(&GlobalFiletypes(), MapFormat::Name(), path_get_extension(filename)); - if (string_not_empty(moduleName)) { - format = ReferenceAPI_getMapModules().findModule(moduleName); - } - - for (int i = 0; i < Brush_toggleFormatCount(); ++i) { - if (i) { - Map_Free(); - } - Brush_toggleFormat(i); - g_map.m_name = filename; - Map_UpdateTitle(g_map); - g_map.m_resource = GlobalReferenceCache().capture(g_map.m_name.c_str()); - if (format) { - format->wrongFormat = false; - } - g_map.m_resource->attach(g_map); - if (format) { - if (!format->wrongFormat) { - break; - } - } - } - - Node_getTraversable(GlobalSceneGraph().root())->traverse(entity_updateworldspawn()); - } - - globalOutputStream() << "--- LoadMapFile ---\n"; - globalOutputStream() << g_map.m_name.c_str() << "\n"; - - globalOutputStream() << Unsigned(g_brushCount.get()) << " primitive\n"; - globalOutputStream() << Unsigned(g_entityCount.get()) << " entities\n"; - - //GlobalEntityCreator().printStatistics(); - - // - // move the view to a start position - // - Map_StartPosition(); - - g_currentMap = &g_map; - - // refresh VFS to apply new pak filtering based on mapname - // needed for daemon DPK VFS - VFS_Refresh(); -} - -class Excluder { -public: -virtual bool excluded(scene::Node &node) const = 0; -}; - -class ExcludeWalker : public scene::Traversable::Walker { -const scene::Traversable::Walker &m_walker; -const Excluder *m_exclude; -mutable bool m_skip; -public: -ExcludeWalker(const scene::Traversable::Walker &walker, const Excluder &exclude) - : m_walker(walker), m_exclude(&exclude), m_skip(false) -{ -} - -bool pre(scene::Node &node) const -{ - if (m_exclude->excluded(node) || node.isRoot()) { - m_skip = true; - return false; - } else { - m_walker.pre(node); - } - return true; -} - -void post(scene::Node &node) const -{ - if (m_skip) { - m_skip = false; - } else { - m_walker.post(node); - } -} -}; - -class AnyInstanceSelected : public scene::Instantiable::Visitor { -bool &m_selected; -public: -AnyInstanceSelected(bool &selected) : m_selected(selected) -{ - m_selected = false; -} - -void visit(scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - m_selected = true; - } -} -}; - -bool Node_instanceSelected(scene::Node &node) -{ - scene::Instantiable *instantiable = Node_getInstantiable(node); - ASSERT_NOTNULL(instantiable); - bool selected; - instantiable->forEachInstance(AnyInstanceSelected(selected)); - return selected; -} - -class SelectedDescendantWalker : public scene::Traversable::Walker { -bool &m_selected; -public: -SelectedDescendantWalker(bool &selected) : m_selected(selected) -{ - m_selected = false; -} - -bool pre(scene::Node &node) const -{ - if (node.isRoot()) { - return false; - } - - if (Node_instanceSelected(node)) { - m_selected = true; - } - - return true; -} -}; - -bool Node_selectedDescendant(scene::Node &node) -{ - bool selected; - Node_traverseSubgraph(node, SelectedDescendantWalker(selected)); - return selected; -} - -class SelectionExcluder : public Excluder { -public: -bool excluded(scene::Node &node) const -{ - return !Node_selectedDescendant(node); -} -}; - -class IncludeSelectedWalker : public scene::Traversable::Walker { -const scene::Traversable::Walker &m_walker; -mutable std::size_t m_selected; -mutable bool m_skip; - -bool selectedParent() const -{ - return m_selected != 0; -} - -public: -IncludeSelectedWalker(const scene::Traversable::Walker &walker) - : m_walker(walker), m_selected(0), m_skip(false) -{ -} - -bool pre(scene::Node &node) const -{ - // include node if: - // node is not a 'root' AND ( node is selected OR any child of node is selected OR any parent of node is selected ) - if (!node.isRoot() && (Node_selectedDescendant(node) || selectedParent())) { - if (Node_instanceSelected(node)) { - ++m_selected; - } - m_walker.pre(node); - return true; - } else { - m_skip = true; - return false; - } -} - -void post(scene::Node &node) const -{ - if (m_skip) { - m_skip = false; - } else { - if (Node_instanceSelected(node)) { - --m_selected; - } - m_walker.post(node); - } -} -}; - -void Map_Traverse_Selected(scene::Node &root, const scene::Traversable::Walker &walker) -{ - scene::Traversable *traversable = Node_getTraversable(root); - if (traversable != 0) { -#if 0 - traversable->traverse( ExcludeWalker( walker, SelectionExcluder() ) ); -#else - traversable->traverse(IncludeSelectedWalker(walker)); -#endif - } -} - -void Map_ExportSelected(TextOutputStream &out, const MapFormat &format) -{ - format.writeGraph(GlobalSceneGraph().root(), Map_Traverse_Selected, out); -} - -void Map_Traverse(scene::Node &root, const scene::Traversable::Walker &walker) -{ - scene::Traversable *traversable = Node_getTraversable(root); - if (traversable != 0) { - traversable->traverse(walker); - } -} - -class RegionExcluder : public Excluder { -public: -bool excluded(scene::Node &node) const -{ - return node.excluded(); -} -}; - -void Map_Traverse_Region(scene::Node &root, const scene::Traversable::Walker &walker) -{ - scene::Traversable *traversable = Node_getTraversable(root); - if (traversable != 0) { - traversable->traverse(ExcludeWalker(walker, RegionExcluder())); - } -} - -bool Map_SaveRegion(const char *filename) -{ - AddRegionBrushes(); - - bool success = MapResource_saveFile(MapFormat_forFile(filename), GlobalSceneGraph().root(), Map_Traverse_Region, - filename); - - RemoveRegionBrushes(); - - return success; -} - - -void Map_RenameAbsolute(const char *absolute) -{ - Resource *resource = GlobalReferenceCache().capture(absolute); - NodeSmartReference clone(NewMapRoot(path_make_relative(absolute, GlobalFileSystem().findRoot(absolute)))); - resource->setNode(clone.get_pointer()); - - { - //ScopeTimer timer("clone subgraph"); - Node_getTraversable(GlobalSceneGraph().root())->traverse(CloneAll(clone)); - } - - g_map.m_resource->detach(g_map); - GlobalReferenceCache().release(g_map.m_name.c_str()); - - g_map.m_resource = resource; - - g_map.m_name = absolute; - Map_UpdateTitle(g_map); - - g_map.m_resource->attach(g_map); - // refresh VFS to apply new pak filtering based on mapname - // needed for daemon DPK VFS - VFS_Refresh(); -} - -void Map_Rename(const char *filename) -{ - if (!string_equal(g_map.m_name.c_str(), filename)) { - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Saving Map"); - - Map_RenameAbsolute(filename); - - SceneChangeNotify(); - } else { - SaveReferences(); - } -} - -bool Map_Save() -{ - Pointfile_Clear(); - - ScopeTimer timer("map save"); - SaveReferences(); - return true; // assume success.. -} - -/* - =========== - Map_New - - =========== - */ -void Map_New() -{ - //globalOutputStream() << "Map_New\n"; - - g_map.m_name = "unnamed.map"; - Map_UpdateTitle(g_map); - - { - g_map.m_resource = GlobalReferenceCache().capture(g_map.m_name.c_str()); -// ASSERT_MESSAGE(g_map.m_resource->getNode() == 0, "bleh"); - g_map.m_resource->attach(g_map); - - SceneChangeNotify(); - } - - FocusViews(g_vector3_identity, 0); - - g_currentMap = &g_map; - - // restart VFS to apply new pak filtering based on mapname - // needed for daemon DPK VFS - VFS_Restart(); -} - -extern void ConstructRegionBrushes(scene::Node *brushes[6], const Vector3 ®ion_mins, const Vector3 ®ion_maxs); - -void ConstructRegionStartpoint(scene::Node *startpoint, const Vector3 ®ion_mins, const Vector3 ®ion_maxs) -{ - /*! - \todo we need to make sure that the player start IS inside the region and bail out if it's not - the compiler will refuse to compile a map with a player_start somewhere in empty space.. - for now, let's just print an error - */ - - Vector3 vOrig(Camera_getOrigin(*g_pParentWnd->GetCamWnd())); - - for (int i = 0; i < 3; i++) { - if (vOrig[i] > region_maxs[i] || vOrig[i] < region_mins[i]) { - globalErrorStream() << "Camera is NOT in the region, it's likely that the region won't compile correctly\n"; - break; - } - } - - // write the info_playerstart - char sTmp[1024]; - sprintf(sTmp, "%d %d %d", (int) vOrig[0], (int) vOrig[1], (int) vOrig[2]); - Node_getEntity(*startpoint)->setKeyValue("origin", sTmp); - sprintf(sTmp, "%d", (int) Camera_getAngles(*g_pParentWnd->GetCamWnd())[CAMERA_YAW]); - Node_getEntity(*startpoint)->setKeyValue("angle", sTmp); -} - -/* - =========================================================== - - REGION - - =========================================================== - */ -bool region_active; -Vector3 region_mins(g_MinWorldCoord, g_MinWorldCoord, g_MinWorldCoord); -Vector3 region_maxs(g_MaxWorldCoord, g_MaxWorldCoord, g_MaxWorldCoord); - -scene::Node *region_sides[6]; -scene::Node *region_startpoint = 0; - -/* - =========== - AddRegionBrushes - a regioned map will have temp walls put up at the region boundary - \todo TODO TTimo old implementation of region brushes - we still add them straight in the worldspawn and take them out after the map is saved - with the new implementation we should be able to append them in a temporary manner to the data we pass to the map module - =========== - */ -void AddRegionBrushes(void) -{ - int i; - - for (i = 0; i < 6; i++) { - region_sides[i] = &GlobalBrushCreator().createBrush(); - Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(NodeSmartReference(*region_sides[i])); - } - - region_startpoint = &GlobalEntityCreator().createEntity( - GlobalEntityClassManager().findOrInsert("info_player_start", false)); - - ConstructRegionBrushes(region_sides, region_mins, region_maxs); - ConstructRegionStartpoint(region_startpoint, region_mins, region_maxs); - - Node_getTraversable(GlobalSceneGraph().root())->insert(NodeSmartReference(*region_startpoint)); -} - -void RemoveRegionBrushes(void) -{ - for (std::size_t i = 0; i < 6; i++) { - Node_getTraversable(*Map_GetWorldspawn(g_map))->erase(*region_sides[i]); - } - Node_getTraversable(GlobalSceneGraph().root())->erase(*region_startpoint); -} - -inline void exclude_node(scene::Node &node, bool exclude) -{ - exclude - ? node.enable(scene::Node::eExcluded) - : node.disable(scene::Node::eExcluded); -} - -class ExcludeAllWalker : public scene::Graph::Walker { -bool m_exclude; -public: -ExcludeAllWalker(bool exclude) - : m_exclude(exclude) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - exclude_node(path.top(), m_exclude); - - return true; -} -}; - -void Scene_Exclude_All(bool exclude) -{ - GlobalSceneGraph().traverse(ExcludeAllWalker(exclude)); -} - -bool Instance_isSelected(const scene::Instance &instance) -{ - const Selectable *selectable = Instance_getSelectable(instance); - return selectable != 0 && selectable->isSelected(); -} - -class ExcludeSelectedWalker : public scene::Graph::Walker { -bool m_exclude; -public: -ExcludeSelectedWalker(bool exclude) - : m_exclude(exclude) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - exclude_node(path.top(), - (instance.isSelected() || instance.childSelected() || instance.parentSelected()) == m_exclude); - return true; -} -}; - -void Scene_Exclude_Selected(bool exclude) -{ - GlobalSceneGraph().traverse(ExcludeSelectedWalker(exclude)); -} - -class ExcludeRegionedWalker : public scene::Graph::Walker { -bool m_exclude; -public: -ExcludeRegionedWalker(bool exclude) - : m_exclude(exclude) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - exclude_node( - path.top(), - !( - ( - aabb_intersects_aabb( - instance.worldAABB(), - aabb_for_minmax(region_mins, region_maxs) - ) != 0 - ) ^ m_exclude - ) - ); - - return true; -} -}; - -void Scene_Exclude_Region(bool exclude) -{ - GlobalSceneGraph().traverse(ExcludeRegionedWalker(exclude)); -} - -/* - =========== - Map_RegionOff - - Other filtering options may still be on - =========== - */ -void Map_RegionOff() -{ - region_active = false; - - region_maxs[0] = g_MaxWorldCoord - 64; - region_mins[0] = g_MinWorldCoord + 64; - region_maxs[1] = g_MaxWorldCoord - 64; - region_mins[1] = g_MinWorldCoord + 64; - region_maxs[2] = g_MaxWorldCoord - 64; - region_mins[2] = g_MinWorldCoord + 64; - - Scene_Exclude_All(false); -} - -void Map_ApplyRegion(void) -{ - region_active = true; - - Scene_Exclude_Region(false); -} - - -/* - ======================== - Map_RegionSelectedBrushes - ======================== - */ -void Map_RegionSelectedBrushes(void) -{ - Map_RegionOff(); - - if (GlobalSelectionSystem().countSelected() != 0 - && GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - region_active = true; - Select_GetBounds(region_mins, region_maxs); - - Scene_Exclude_Selected(false); - - GlobalSelectionSystem().setSelectedAll(false); - } -} - - -/* - =========== - Map_RegionXY - =========== - */ -void Map_RegionXY(float x_min, float y_min, float x_max, float y_max) -{ - Map_RegionOff(); - - region_mins[0] = x_min; - region_maxs[0] = x_max; - region_mins[1] = y_min; - region_maxs[1] = y_max; - region_mins[2] = g_MinWorldCoord + 64; - region_maxs[2] = g_MaxWorldCoord - 64; - - Map_ApplyRegion(); -} - -void Map_RegionBounds(const AABB &bounds) -{ - Map_RegionOff(); - - region_mins = vector3_subtracted(bounds.origin, bounds.extents); - region_maxs = vector3_added(bounds.origin, bounds.extents); - - deleteSelection(); - - Map_ApplyRegion(); -} - -/* - =========== - Map_RegionBrush - =========== - */ -void Map_RegionBrush(void) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - scene::Instance &instance = GlobalSelectionSystem().ultimateSelected(); - Map_RegionBounds(instance.worldAABB()); - } -} - -// -//================ -//Map_ImportFile -//================ -// -bool Map_ImportFile(const char *filename) -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map"); - - g_strLastFolder = g_path_get_dirname(filename); - - bool success = false; - - if (extension_equal(path_get_extension(filename), "bsp")) { - goto tryDecompile; - } - - { - const MapFormat *format = NULL; - const char *moduleName = findModuleName(&GlobalFiletypes(), MapFormat::Name(), path_get_extension(filename)); - if (string_not_empty(moduleName)) { - format = ReferenceAPI_getMapModules().findModule(moduleName); - } - - if (format) { - format->wrongFormat = false; - } - Resource *resource = GlobalReferenceCache().capture(filename); - resource->refresh(); // avoid loading old version if map has changed on disk since last import - if (!resource->load()) { - GlobalReferenceCache().release(filename); - goto tryDecompile; - } - if (format) { - if (format->wrongFormat) { - GlobalReferenceCache().release(filename); - goto tryDecompile; - } - } - NodeSmartReference clone(NewMapRoot("")); - Node_getTraversable(*resource->getNode())->traverse(CloneAll(clone)); - Map_gatherNamespaced(clone); - Map_mergeClonedNames(); - MergeMap(clone); - success = true; - GlobalReferenceCache().release(filename); - } - - SceneChangeNotify(); - - return success; - -tryDecompile: - - 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("vmap"); - 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("\""); - - 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"); - if (extension_equal(path_get_extension(filename), "map")) { - output.push_string(" -readmap "); - } - output.push_string(" \""); - output.push_string(filename); - output.push_string("\""); - - // 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"); - filename = output.c_str(); - - // open - Resource *resource = GlobalReferenceCache().capture(filename); - resource->refresh(); // avoid loading old version if map has changed on disk since last import - if (!resource->load()) { - GlobalReferenceCache().release(filename); - goto tryDecompile; - } - NodeSmartReference clone(NewMapRoot("")); - Node_getTraversable(*resource->getNode())->traverse(CloneAll(clone)); - Map_gatherNamespaced(clone); - Map_mergeClonedNames(); - MergeMap(clone); - success = true; - GlobalReferenceCache().release(filename); - } - - SceneChangeNotify(); - return success; -} - -/* - =========== - Map_SaveFile - =========== - */ -bool Map_SaveFile(const char *filename) -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Saving Map"); - bool success = MapResource_saveFile(MapFormat_forFile(filename), GlobalSceneGraph().root(), Map_Traverse, filename); - if (success) { - // refresh VFS to apply new pak filtering based on mapname - // needed for daemon DPK VFS - VFS_Refresh(); - } - return success; -} - -// -//=========== -//Map_SaveSelected -//=========== -// -// Saves selected world brushes and whole entities with partial/full selections -// -bool Map_SaveSelected(const char *filename) -{ - return MapResource_saveFile(MapFormat_forFile(filename), GlobalSceneGraph().root(), Map_Traverse_Selected, - filename); -} - - -class ParentSelectedBrushesToEntityWalker : public scene::Graph::Walker { -scene::Node &m_parent; -public: -ParentSelectedBrushesToEntityWalker(scene::Node &parent) : m_parent(parent) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get_pointer() != &m_parent - && Node_isPrimitive(path.top())) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected() - && path.size() > 1) { - return false; - } - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get_pointer() != &m_parent - && Node_isPrimitive(path.top())) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected() - && path.size() > 1) { - scene::Node &parent = path.parent(); - if (&parent != &m_parent) { - NodeSmartReference node(path.top().get()); - Node_getTraversable(parent)->erase(node); - Node_getTraversable(m_parent)->insert(node); - } - } - } -} -}; - -void Scene_parentSelectedBrushesToEntity(scene::Graph &graph, scene::Node &parent) -{ - graph.traverse(ParentSelectedBrushesToEntityWalker(parent)); -} - -class CountSelectedBrushes : public scene::Graph::Walker { -std::size_t &m_count; -mutable std::size_t m_depth; -public: -CountSelectedBrushes(std::size_t &count) : m_count(count), m_depth(0) -{ - m_count = 0; -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (++m_depth != 1 && path.top().get().isRoot()) { - return false; - } - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected() - && Node_isPrimitive(path.top())) { - ++m_count; - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - --m_depth; -} -}; - -std::size_t Scene_countSelectedBrushes(scene::Graph &graph) -{ - std::size_t count; - graph.traverse(CountSelectedBrushes(count)); - return count; -} - - - -class CountHiddenBrushes : public scene::Graph::Walker { -std::size_t &m_count; -mutable std::size_t m_depth; -public: -CountHiddenBrushes(std::size_t &count) : m_count(count), m_depth(0) -{ - m_count = 0; -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (++m_depth != 1 && path.top().get().isRoot()) { - return false; - } - - if (Node_isHidden(path.top())) { - ++m_count; - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - --m_depth; -} -}; - -std::size_t Scene_countHiddenBrushes(scene::Graph &graph) -{ - std::size_t count; - graph.traverse(CountHiddenBrushes(count)); - return count; -} - -enum ENodeType { - eNodeUnknown, - eNodeMap, - eNodeEntity, - eNodePrimitive, -}; - -const char *nodetype_get_name(ENodeType type) -{ - if (type == eNodeMap) { - return "map"; - } - if (type == eNodeEntity) { - return "entity"; - } - if (type == eNodePrimitive) { - return "primitive"; - } - return "unknown"; -} - -ENodeType node_get_nodetype(scene::Node &node) -{ - if (Node_isEntity(node)) { - return eNodeEntity; - } - if (Node_isPrimitive(node)) { - return eNodePrimitive; - } - return eNodeUnknown; -} - -bool contains_entity(scene::Node &node) -{ - return Node_getTraversable(node) != 0 && !Node_isBrush(node) && !Node_isPatch(node) && !Node_isEntity(node); -} - -bool contains_primitive(scene::Node &node) -{ - return Node_isEntity(node) && Node_getTraversable(node) != 0 && Node_getEntity(node)->isContainer(); -} - -ENodeType node_get_contains(scene::Node &node) -{ - if (contains_entity(node)) { - return eNodeEntity; - } - if (contains_primitive(node)) { - return eNodePrimitive; - } - return eNodeUnknown; -} - -void Path_parent(const scene::Path &parent, const scene::Path &child) -{ - ENodeType contains = node_get_contains(parent.top()); - ENodeType type = node_get_nodetype(child.top()); - - if (contains != eNodeUnknown && contains == type) { - NodeSmartReference node(child.top().get()); - Path_deleteTop(child); - Node_getTraversable(parent.top())->insert(node); - SceneChangeNotify(); - } else { - globalErrorStream() << "failed - " << nodetype_get_name(type) << " cannot be parented to " - << nodetype_get_name(contains) << " container.\n"; - } -} - -void Scene_parentSelected() -{ - UndoableCommand undo("parentSelected"); - - if (GlobalSelectionSystem().countSelected() > 1) { - class ParentSelectedBrushesToEntityWalker : public SelectionSystem::Visitor { - const scene::Path &m_parent; -public: - ParentSelectedBrushesToEntityWalker(const scene::Path &parent) : m_parent(parent) - { - } - - void visit(scene::Instance &instance) const - { - if (&m_parent != &instance.path()) { - Path_parent(m_parent, instance.path()); - } - } - }; - - ParentSelectedBrushesToEntityWalker visitor(GlobalSelectionSystem().ultimateSelected().path()); - GlobalSelectionSystem().foreachSelected(visitor); - } else { - globalOutputStream() << "failed - did not find two selected nodes.\n"; - } -} - - -void NewMap() -{ - if (ConfirmModified("New Map")) { - Map_RegionOff(); - Map_Free(); - Map_New(); - } -} - -CopiedString g_mapsPath; - -const char *getMapsPath() -{ - return g_mapsPath.c_str(); -} - -const char *getLastFolderPath() -{ - if (g_strLastFolder.empty()) { - GlobalPreferenceSystem().registerPreference("LastFolder", make_property_string(g_strLastFolder)); - if (g_strLastFolder.empty()) { - g_strLastFolder = EnginePath_get(); - } - } - return g_strLastFolder.c_str(); -} - -const char *map_open(const char *title) -{ - return MainFrame_getWindow().file_dialog(TRUE, title, getLastFolderPath(), MapFormat::Name(), true, false, false); -} - -const char *map_import(const char *title) -{ - return MainFrame_getWindow().file_dialog(TRUE, title, getLastFolderPath(), MapFormat::Name(), false, true, false); -} - -const char *map_save(const char *title) -{ - return MainFrame_getWindow().file_dialog(FALSE, title, getLastFolderPath(), MapFormat::Name(), false, false, true); -} - -void OpenMap() -{ - if (!ConfirmModified("Open Map")) { - return; - } - - const char *filename = map_open("Open Map"); - - if (filename != NULL) { - MRU_AddFile(filename); - Map_RegionOff(); - Map_Free(); - Map_LoadFile(filename); - } -} - -void ImportMap() -{ - const char *filename = map_import("Import Map"); - - if (filename != NULL) { - UndoableCommand undo("mapImport"); - Map_ImportFile(filename); - } -} - -bool Map_SaveAs() -{ - const char *filename = map_save("Save Map"); - - if (filename != NULL) { - g_strLastFolder = g_path_get_dirname(filename); - MRU_AddFile(filename); - Map_Rename(filename); - return Map_Save(); - } - return false; -} - -void SaveMapAs() -{ - Map_SaveAs(); -} - -void SaveMap() -{ - if (Map_Unnamed(g_map)) { - SaveMapAs(); - } else /*if (Map_Modified(g_map))*/ { - Map_Save(); - } -} - -void ExportMap() -{ - const char *filename = map_save("Export Selection"); - - if (filename != NULL) { - g_strLastFolder = g_path_get_dirname(filename); - Map_SaveSelected(filename); - } -} - -void SaveRegion() -{ - const char *filename = map_save("Export Region"); - - if (filename != NULL) { - g_strLastFolder = g_path_get_dirname(filename); - Map_SaveRegion(filename); - } -} - - -void RegionOff() -{ - Map_RegionOff(); - SceneChangeNotify(); -} - -void RegionXY() -{ - Map_RegionXY( - g_pParentWnd->GetXYWnd()->GetOrigin()[0] - - 0.5f * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale(), - g_pParentWnd->GetXYWnd()->GetOrigin()[1] - - 0.5f * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale(), - g_pParentWnd->GetXYWnd()->GetOrigin()[0] + - 0.5f * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale(), - g_pParentWnd->GetXYWnd()->GetOrigin()[1] + - 0.5f * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale() - ); - SceneChangeNotify(); -} - -void RegionBrush() -{ - Map_RegionBrush(); - SceneChangeNotify(); -} - -void RegionSelected() -{ - Map_RegionSelectedBrushes(); - SceneChangeNotify(); -} - - -class BrushFindByIndexWalker : public scene::Traversable::Walker { -mutable std::size_t m_index; -scene::Path &m_path; -public: -BrushFindByIndexWalker(std::size_t index, scene::Path &path) - : m_index(index), m_path(path) -{ -} - -bool pre(scene::Node &node) const -{ - if (Node_isPrimitive(node) && m_index-- == 0) { - m_path.push(makeReference(node)); - } - return false; -} -}; - -class EntityFindByIndexWalker : public scene::Traversable::Walker { -mutable std::size_t m_index; -scene::Path &m_path; -public: -EntityFindByIndexWalker(std::size_t index, scene::Path &path) - : m_index(index), m_path(path) -{ -} - -bool pre(scene::Node &node) const -{ - if (Node_isEntity(node) && m_index-- == 0) { - m_path.push(makeReference(node)); - } - return false; -} -}; - -void Scene_FindEntityBrush(std::size_t entity, std::size_t brush, scene::Path &path) -{ - path.push(makeReference(GlobalSceneGraph().root())); - { - Node_getTraversable(path.top())->traverse(EntityFindByIndexWalker(entity, path)); - } - if (path.size() == 2) { - scene::Traversable *traversable = Node_getTraversable(path.top()); - if (traversable != 0) { - traversable->traverse(BrushFindByIndexWalker(brush, path)); - } - } -} - -inline bool Node_hasChildren(scene::Node &node) -{ - scene::Traversable *traversable = Node_getTraversable(node); - return traversable != 0 && !traversable->empty(); -} - -void SelectBrush(int entitynum, int brushnum) -{ - scene::Path path; - Scene_FindEntityBrush(entitynum, brushnum, path); - if (path.size() == 3 || (path.size() == 2 && !Node_hasChildren(path.top()))) { - scene::Instance *instance = GlobalSceneGraph().find(path); - ASSERT_MESSAGE(instance != 0, "SelectBrush: path not found in scenegraph"); - Selectable *selectable = Instance_getSelectable(*instance); - ASSERT_MESSAGE(selectable != 0, "SelectBrush: path not selectable"); - selectable->setSelected(true); - g_pParentWnd->GetXYWnd()->PositionView(instance->worldAABB().origin); - } -} - - -class BrushFindIndexWalker : public scene::Graph::Walker { -mutable const scene::Node *m_node; -std::size_t &m_count; -public: -BrushFindIndexWalker(const scene::Node &node, std::size_t &count) - : m_node(&node), m_count(count) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (Node_isPrimitive(path.top())) { - if (m_node == path.top().get_pointer()) { - m_node = 0; - } - if (m_node) { - ++m_count; - } - } - return true; -} -}; - -class EntityFindIndexWalker : public scene::Graph::Walker { -mutable const scene::Node *m_node; -std::size_t &m_count; -public: -EntityFindIndexWalker(const scene::Node &node, std::size_t &count) - : m_node(&node), m_count(count) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (Node_isEntity(path.top())) { - if (m_node == path.top().get_pointer()) { - m_node = 0; - } - if (m_node) { - ++m_count; - } - } - return true; -} -}; - -static void GetSelectionIndex(int *ent, int *brush) -{ - std::size_t count_brush = 0; - std::size_t count_entity = 0; - if (GlobalSelectionSystem().countSelected() != 0) { - const scene::Path &path = GlobalSelectionSystem().ultimateSelected().path(); - - GlobalSceneGraph().traverse(BrushFindIndexWalker(path.top(), count_brush)); - GlobalSceneGraph().traverse(EntityFindIndexWalker(path.parent(), count_entity)); - } - *brush = int(count_brush); - *ent = int(count_entity); -} - -void DoFind() -{ - ModalDialog dialog; - ui::Entry entity{ui::null}; - ui::Entry brush{ui::null}; - - ui::Window window = MainFrame_getWindow().create_dialog_window("Find Brush", G_CALLBACK(dialog_delete_callback), - &dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - - { - auto vbox = create_dialog_vbox(4, 4); - window.add(vbox); - { - auto table = create_dialog_table(2, 2, 4, 4); - vbox.pack_start(table, TRUE, TRUE, 0); - { - ui::Widget label = ui::Label("Entity number"); - label.show(); - (table).attach(label, {0, 1, 0, 1}, {0, 0}); - } - { - ui::Widget label = ui::Label("Brush number"); - label.show(); - (table).attach(label, {0, 1, 1, 2}, {0, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - gtk_widget_grab_focus(entry); - entity = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - brush = entry; - } - } - { - auto hbox = create_dialog_hbox(4); - vbox.pack_start(hbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("Find", G_CALLBACK(dialog_button_ok), &dialog); - hbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Close", G_CALLBACK(dialog_button_cancel), &dialog); - hbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - } - } - - // Initialize dialog - char buf[16]; - int ent, br; - - GetSelectionIndex(&ent, &br); - sprintf(buf, "%i", ent); - entity.text(buf); - sprintf(buf, "%i", br); - brush.text(buf); - - if (modal_dialog_show(window, dialog) == eIDOK) { - const char *entstr = gtk_entry_get_text(entity); - const char *brushstr = gtk_entry_get_text(brush); - SelectBrush(atoi(entstr), atoi(brushstr)); - } - - window.destroy(); -} - -void Map_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox("", "Load last map on open", g_bLoadLastMap); -} - - -class MapEntityClasses : public ModuleObserver { -std::size_t m_unrealised; -public: -MapEntityClasses() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - if (g_map.m_resource != 0) { - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map"); - g_map.m_resource->realise(); - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - if (g_map.m_resource != 0) { - g_map.m_resource->flush(); - g_map.m_resource->unrealise(); - } - } -} -}; - -MapEntityClasses g_MapEntityClasses; - - -class MapModuleObserver : public ModuleObserver { -std::size_t m_unrealised; -public: -MapModuleObserver() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - ASSERT_MESSAGE(!string_empty(g_qeglobals.m_userGamePath.c_str()), - "maps_directory: user-game-path is empty"); - StringOutputStream buffer(256); - buffer << g_qeglobals.m_userGamePath.c_str() << "maps/"; - Q_mkdir(buffer.c_str()); - g_mapsPath = buffer.c_str(); - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - g_mapsPath = ""; - } -} -}; - -MapModuleObserver g_MapModuleObserver; - -CopiedString g_strLastMap; -bool g_bLoadLastMap = false; - -void Map_Construct() -{ - GlobalCommands_insert("RegionOff", makeCallbackF(RegionOff)); - GlobalCommands_insert("RegionSetXY", makeCallbackF(RegionXY)); - GlobalCommands_insert("RegionSetBrush", makeCallbackF(RegionBrush)); - GlobalCommands_insert("RegionSetSelection", makeCallbackF(RegionSelected), - Accelerator('R', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - - GlobalPreferenceSystem().registerPreference("LastMap", make_property_string(g_strLastMap)); - GlobalPreferenceSystem().registerPreference("LoadLastMap", make_property_string(g_bLoadLastMap)); - GlobalPreferenceSystem().registerPreference("MapInfoDlg", make_property(g_posMapInfoWnd)); - - PreferencesDialog_addSettingsPreferences(makeCallbackF(Map_constructPreferences)); - - GlobalEntityClassManager().attach(g_MapEntityClasses); -} - -void Map_Destroy() -{ - GlobalEntityClassManager().detach(g_MapEntityClasses); -} diff --git a/src/map.h b/src/map.h deleted file mode 100644 index e2b1731..0000000 --- a/src/map.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MAP_H ) -#define INCLUDED_MAP_H - -#include "iscenegraph.h" -#include "generic/callback.h" -#include "signal/signalfwd.h" -#include "string/stringfwd.h" - -class Map; - -extern Map g_map; - -class MapFormat; - -void Map_addValidCallback(Map &map, const SignalHandler &handler); - -bool Map_Valid(const Map &map); - -class DeferredDraw { -Callback m_draw; -bool m_defer; -bool m_deferred; -public: -DeferredDraw(const Callback &draw) : m_draw(draw), m_defer(false), m_deferred(false) -{ -} - -void defer() -{ - m_defer = true; -} - -void draw() -{ - if (m_defer) { - m_deferred = true; - } else { - m_draw(); - } -} - -void flush() -{ - if (m_defer && m_deferred) { - m_draw(); - } - m_deferred = false; - m_defer = false; -} -}; - -inline void DeferredDraw_onMapValidChanged(DeferredDraw &self) -{ - if (Map_Valid(g_map)) { - self.flush(); - } else { - self.defer(); - } -} - -typedef ReferenceCaller DeferredDrawOnMapValidChangedCaller; - - -const char *Map_Name(const Map &map); - -const MapFormat &Map_getFormat(const Map &map); - -bool Map_Unnamed(const Map &map); - - -namespace scene { -class Node; - -class Graph; -} - -scene::Node *Map_GetWorldspawn(const Map &map); - -scene::Node *Map_FindWorldspawn(Map &map); - -scene::Node &Map_FindOrInsertWorldspawn(Map &map); - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -extern Vector3 region_mins, region_maxs; -extern bool region_active; - -// used to be #defines, multiple engine support suggests we should go towards dynamic -extern float g_MaxWorldCoord; -extern float g_MinWorldCoord; - -void Map_LoadFile(const char *filename); - -bool Map_SaveFile(const char *filename); - -void Map_New(); - -void Map_Free(); - -void Map_RegionOff(); - -bool Map_SaveRegion(const char *filename); - -class TextInputStream; - -class TextOutputStream; - -void Map_ImportSelected(TextInputStream &in, const MapFormat &format); - -void Map_ExportSelected(TextOutputStream &out, const MapFormat &format); - -bool Map_Modified(const Map &map); - -void Map_SetModified(Map &map, bool modified); - -bool Map_Save(); - -bool Map_SaveAs(); - -scene::Node &Node_Clone(scene::Node &node); - -void DoMapInfo(); - -void Scene_parentSelectedBrushesToEntity(scene::Graph &graph, scene::Node &parent); - -std::size_t Scene_countSelectedBrushes(scene::Graph &graph); - -void Scene_parentSelected(); - -void OnUndoSizeChanged(); - -void NewMap(); - -void OpenMap(); - -void ImportMap(); - -void SaveMapAs(); - -void SaveMap(); - -void ExportMap(); - -void SaveRegion(); - - -void Map_Traverse(scene::Node &root, const scene::Traversable::Walker &walker); - - -void SelectBrush(int entitynum, int brushnum); - -extern CopiedString g_strLastMap; -extern bool g_bLoadLastMap; - -void Map_Construct(); - -void Map_Destroy(); - - -void Map_gatherNamespaced(scene::Node &root); - -void Map_mergeClonedNames(); - - -const char *getMapsPath(); - -#endif diff --git a/tools/vmap/mesh.c b/src/mesh.c similarity index 100% rename from tools/vmap/mesh.c rename to src/mesh.c diff --git a/tools/vmap/model.c b/src/model.c similarity index 100% rename from tools/vmap/model.c rename to src/model.c diff --git a/src/mru.cpp b/src/mru.cpp deleted file mode 100644 index 20545ed..0000000 --- a/src/mru.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mru.h" - -#include -#include -#include - -#include "os/file.h" -#include "generic/callback.h" -#include "stream/stringstream.h" -#include "convert.h" - -#include "gtkutil/menu.h" -#include "map.h" -#include "qe3.h" - -const int MRU_MAX = 4; -namespace { -GtkMenuItem *MRU_items[MRU_MAX]; -std::size_t MRU_used; -typedef CopiedString MRU_filename_t; -MRU_filename_t MRU_filenames[MRU_MAX]; -typedef const char *MRU_key_t; -MRU_key_t MRU_keys[MRU_MAX] = {"File0", "File1", "File2", "File3"}; -} - -inline const char *MRU_GetText(std::size_t index) -{ - return MRU_filenames[index].c_str(); -} - -class EscapedMnemonic { -StringBuffer m_buffer; -public: -EscapedMnemonic(std::size_t capacity) : m_buffer(capacity) -{ - m_buffer.push_back('_'); -} - -const char *c_str() const -{ - return m_buffer.c_str(); -} - -void push_back(char c) -{ // not escaped - m_buffer.push_back(c); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - for (const char *end = buffer + length; buffer != end; ++buffer) { - if (*buffer == '_') { - m_buffer.push_back('_'); - } - - m_buffer.push_back(*buffer); - } - return length; -} -}; - -template -inline EscapedMnemonic &operator<<(EscapedMnemonic &ostream, const T &t) -{ - return ostream_write(ostream, t); -} - - -void MRU_updateWidget(std::size_t index, const char *filename) -{ - EscapedMnemonic mnemonic(64); - mnemonic << Unsigned(index + 1) << "- " << filename; - gtk_label_set_text_with_mnemonic(GTK_LABEL(gtk_bin_get_child(GTK_BIN(MRU_items[index]))), mnemonic.c_str()); -} - -void MRU_SetText(std::size_t index, const char *filename) -{ - MRU_filenames[index] = filename; - MRU_updateWidget(index, filename); -} - -void MRU_AddFile(const char *str) -{ - std::size_t i; - const char *text; - - // check if file is already in our list - for (i = 0; i < MRU_used; i++) { - text = MRU_GetText(i); - - if (strcmp(text, str) == 0) { - // reorder menu - for (; i > 0; i--) { - MRU_SetText(i, MRU_GetText(i - 1)); - } - - MRU_SetText(0, str); - - return; - } - } - - if (MRU_used < MRU_MAX) { - MRU_used++; - } - - // move items down - for (i = MRU_used - 1; i > 0; i--) { - MRU_SetText(i, MRU_GetText(i - 1)); - } - - MRU_SetText(0, str); - gtk_widget_set_sensitive(ui::MenuItem::from(MRU_items[0]), TRUE); - ui::MenuItem::from(MRU_items[MRU_used - 1]).show(); -} - -void MRU_Init() -{ - if (MRU_used > MRU_MAX) { - MRU_used = MRU_MAX; - } -} - -void MRU_AddWidget(ui::MenuItem widget, std::size_t pos) -{ - if (pos < MRU_MAX) { - MRU_items[pos] = widget; - if (pos < MRU_used) { - MRU_updateWidget(pos, MRU_GetText(pos)); - gtk_widget_set_sensitive(ui::MenuItem::from(MRU_items[0]), TRUE); - ui::MenuItem::from(MRU_items[pos]).show(); - } - } -} - -void MRU_Activate(std::size_t index) -{ - char text[1024]; - strcpy(text, MRU_GetText(index)); - - if (file_readable(text)) { //\todo Test 'map load succeeds' instead of 'file is readable'. - MRU_AddFile(text); - Map_RegionOff(); - Map_Free(); - Map_LoadFile(text); - } else { - MRU_used--; - - for (std::size_t i = index; i < MRU_used; i++) { - MRU_SetText(i, MRU_GetText(i + 1)); - } - - if (MRU_used == 0) { - auto label = ui::Label::from(gtk_bin_get_child(GTK_BIN(MRU_items[0]))); - label.text("Recent Files"); - gtk_widget_set_sensitive(ui::MenuItem::from(MRU_items[0]), FALSE); - } else { - ui::MenuItem::from(MRU_items[MRU_used]).hide(); - } - } -} - - -class LoadMRU { -std::size_t m_number; -public: -LoadMRU(std::size_t number) - : m_number(number) -{ -} - -void load() -{ - if (ConfirmModified("Open Map")) { - MRU_Activate(m_number - 1); - } -} -}; - -typedef MemberCaller LoadMRUCaller; - -LoadMRU g_load_mru1(1); -LoadMRU g_load_mru2(2); -LoadMRU g_load_mru3(3); -LoadMRU g_load_mru4(4); - -void MRU_constructMenu(ui::Menu menu) -{ - { - auto item = create_menu_item_with_mnemonic(menu, "_1", LoadMRUCaller(g_load_mru1)); - gtk_widget_set_sensitive(item, FALSE); - MRU_AddWidget(item, 0); - } - { - auto item = create_menu_item_with_mnemonic(menu, "_2", LoadMRUCaller(g_load_mru2)); - item.hide(); - MRU_AddWidget(item, 1); - } - { - auto item = create_menu_item_with_mnemonic(menu, "_3", LoadMRUCaller(g_load_mru3)); - item.hide(); - MRU_AddWidget(item, 2); - } - { - auto item = create_menu_item_with_mnemonic(menu, "_4", LoadMRUCaller(g_load_mru4)); - item.hide(); - MRU_AddWidget(item, 3); - } -} - -#include "preferencesystem.h" -#include "stringio.h" - -void MRU_Construct() -{ - GlobalPreferenceSystem().registerPreference("Count", make_property_string(MRU_used)); - - for (std::size_t i = 0; i != MRU_MAX; ++i) { - GlobalPreferenceSystem().registerPreference(MRU_keys[i], make_property_string(MRU_filenames[i])); - } - - MRU_Init(); -} - -void MRU_Destroy() -{ -} diff --git a/src/mru.h b/src/mru.h deleted file mode 100644 index 64d2cd3..0000000 --- a/src/mru.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_MRU_H ) -#define INCLUDED_MRU_H - -void MRU_AddFile(const char *str); - -void MRU_constructMenu(ui::Menu menu); - -void MRU_Construct(); - -void MRU_Destroy(); - -#endif diff --git a/src/multimon.cpp b/src/multimon.cpp deleted file mode 100644 index ae9dbe7..0000000 --- a/src/multimon.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if defined(GDEF_OS_WINDOWS) - -#include "multimon.h" -#include "debugging/debugging.h" -#include "gtkutil/window.h" -#include "preferences.h" - -multimon_globals_t g_multimon_globals; - -LatchedValue g_Multimon_enableSysMenuPopups(false, "Floating windows sysmenu icons"); - -void MultiMonitor_constructPreferences(PreferencesPage &page) -{ - ui::CheckButton primary_monitor = page.appendCheckBox("Multi Monitor", "Start on Primary Monitor", - g_multimon_globals.m_bStartOnPrimMon); - ui::CheckButton popup = page.appendCheckBox( - "", "Disable system menu on popup windows", - make_property(g_Multimon_enableSysMenuPopups) - ); - Widget_connectToggleDependency(popup, primary_monitor); -} - -#include "preferencesystem.h" -#include "stringio.h" - -#include - -namespace { -GdkRectangle primaryMonitor; -} - -void PositionWindowOnPrimaryScreen(WindowPosition &position) -{ - if (position.w >= primaryMonitor.width - 12) { - position.w = primaryMonitor.width - 12; - } - if (position.h >= primaryMonitor.height - 24) { - position.h = primaryMonitor.height - 48; - } - if (position.x <= primaryMonitor.x || position.x + position.w >= (primaryMonitor.x + primaryMonitor.width) - 12) { - position.x = primaryMonitor.x + 6; - } - if (position.y <= primaryMonitor.y || position.y + position.h >= (primaryMonitor.y + primaryMonitor.height) - 48) { - position.y = primaryMonitor.y + 24; - } -} - -void MultiMon_Construct() -{ - // detect multiple monitors - - GdkScreen *screen = gdk_display_get_default_screen(gdk_display_get_default()); - gint m = gdk_screen_get_n_monitors(screen); - globalOutputStream() << "default screen has " << m << " monitors\n"; - for (int j = 0; j != m; ++j) { - GdkRectangle geom; - gdk_screen_get_monitor_geometry(screen, j, &geom); - globalOutputStream() << "monitor " << j << " geometry: " << geom.x << ", " << geom.y << ", " << geom.width - << ", " << geom.height << "\n"; - if (j == 0) { - // I am making the assumption that monitor 0 is always the primary monitor on win32. Tested on WinXP with gtk+-2.4. - primaryMonitor = geom; - } - } - - if (m > 1) { - g_multimon_globals.m_bStartOnPrimMon = true; - } - - GlobalPreferenceSystem().registerPreference("StartOnPrimMon", - make_property_string(g_multimon_globals.m_bStartOnPrimMon)); - GlobalPreferenceSystem().registerPreference("NoSysMenuPopups", - make_property_string(g_Multimon_enableSysMenuPopups.m_latched)); - - g_Multimon_enableSysMenuPopups.useLatched(); - - PreferencesDialog_addInterfacePreferences(makeCallbackF(MultiMonitor_constructPreferences)); -} - -void MultiMon_Destroy() -{ -} -#endif diff --git a/src/multimon.h b/src/multimon.h deleted file mode 100644 index 2122690..0000000 --- a/src/multimon.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_MULTIMON_H ) -#define INCLUDED_MULTIMON_H - -#include "globaldefs.h" - -struct WindowPosition; - -void PositionWindowOnPrimaryScreen(WindowPosition &position); - -struct multimon_globals_t { - bool m_bStartOnPrimMon; - - multimon_globals_t() : - m_bStartOnPrimMon(false) - { - } -}; - -extern multimon_globals_t g_multimon_globals; - -#if GDEF_OS_WINDOWS -void MultiMon_Construct(); -void MultiMon_Destroy(); -#else - -inline void MultiMon_Construct() -{ -} - -inline void MultiMon_Destroy() -{ -} - -#endif - -#endif diff --git a/src/nullmodel.cpp b/src/nullmodel.cpp deleted file mode 100644 index e36af95..0000000 --- a/src/nullmodel.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "nullmodel.h" - -#include "debugging/debugging.h" - -#include "iscenegraph.h" -#include "irender.h" -#include "iselection.h" -#include "iundo.h" -#include "ientity.h" -#include "ireference.h" -#include "igl.h" -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" - -#include "math/frustum.h" -#include "scenelib.h" -#include "instancelib.h" -#include "entitylib.h" - -class NullModel : - public Bounded, - public Cullable { -Shader *m_state; -AABB m_aabb_local; -RenderableSolidAABB m_aabb_solid; -RenderableWireframeAABB m_aabb_wire; -public: -NullModel() : m_aabb_local(Vector3(0, 0, 0), Vector3(8, 8, 8)), m_aabb_solid(m_aabb_local), - m_aabb_wire(m_aabb_local) -{ - m_state = GlobalShaderCache().capture(""); -} - -~NullModel() -{ - GlobalShaderCache().release(""); -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - return volume.TestAABB(m_aabb_local, localToWorld); -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state, Renderer::eFullMaterials); - renderer.addRenderable(m_aabb_solid, localToWorld); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.addRenderable(m_aabb_wire, localToWorld); -} - -void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld) -{ - test.BeginMesh(localToWorld); - - SelectionIntersection best; - aabb_testselect(m_aabb_local, test, best); - if (best.valid()) { - selector.addIntersection(best); - } -} -}; - -class NullModelInstance : public scene::Instance, public Renderable, public SelectionTestable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - -NullModel &m_nullmodel; -public: - -typedef LazyStatic StaticTypeCasts; - -Bounded &get(NullType) -{ - return m_nullmodel; -} - -Cullable &get(NullType) -{ - return m_nullmodel; -} - -NullModelInstance(const scene::Path &path, scene::Instance *parent, NullModel &nullmodel) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_nullmodel(nullmodel) -{ -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_nullmodel.renderSolid(renderer, volume, Instance::localToWorld()); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_nullmodel.renderWireframe(renderer, volume, Instance::localToWorld()); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - m_nullmodel.testSelect(selector, test, Instance::localToWorld()); -} -}; - -class NullModelNode : public scene::Node::Symbiot, public scene::Instantiable { -class TypeCasts { -NodeTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); -} - -NodeTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -NullModel m_nullmodel; -public: - -typedef LazyStatic StaticTypeCasts; - -NullModelNode() : m_node(this, this, StaticTypeCasts::instance().get()) -{ - m_node.m_isRoot = true; -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new NullModelInstance(path, parent, m_nullmodel); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - -NodeSmartReference NewNullModel() -{ - return NodeSmartReference((new NullModelNode)->node()); -} - -void NullModel_construct() -{ -} - -void NullModel_destroy() -{ -} diff --git a/src/nullmodel.h b/src/nullmodel.h deleted file mode 100644 index 3fb5daf..0000000 --- a/src/nullmodel.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_NULLMODEL_H ) -#define INCLUDED_NULLMODEL_H - -namespace scene { -class Node; -} - -#include "generic/referencecounted.h" - -typedef SmartReference > NodeSmartReference; - -NodeSmartReference NewNullModel(); - -void NullModel_construct(); - -void NullModel_destroy(); - -#endif diff --git a/src/parse.cpp b/src/parse.cpp deleted file mode 100644 index 9afaa02..0000000 --- a/src/parse.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parse.h" - -#include "script/scripttokeniser.h" -#include "script/scripttokenwriter.h" - -class ScriptLibraryAPI { -_QERScripLibTable m_scriptlibrary; -public: -typedef _QERScripLibTable Type; - -STRING_CONSTANT(Name, "*"); - -ScriptLibraryAPI() -{ - m_scriptlibrary.m_pfnNewScriptTokeniser = &NewScriptTokeniser; - m_scriptlibrary.m_pfnNewSimpleTokeniser = &NewSimpleTokeniser; - m_scriptlibrary.m_pfnNewSimpleTokenWriter = &NewSimpleTokenWriter; -} - -_QERScripLibTable *getTable() -{ - return &m_scriptlibrary; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule ScriptLibraryModule; -typedef Static StaticScriptLibraryModule; -StaticRegisterModule staticRegisterScriptLibrary(StaticScriptLibraryModule::instance()); diff --git a/src/parse.h b/src/parse.h deleted file mode 100644 index bf9f2be..0000000 --- a/src/parse.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PARSE_H ) -#define INCLUDED_PARSE_H - -#endif diff --git a/tools/vmap/patch.c b/src/patch.c similarity index 100% rename from tools/vmap/patch.c rename to src/patch.c diff --git a/src/patch.cpp b/src/patch.cpp deleted file mode 100644 index 28306ac..0000000 --- a/src/patch.cpp +++ /dev/null @@ -1,2960 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define _USE_MATH_DEFINES -#include "patch.h" - -#include -#include "preferences.h" -#include "brush_primit.h" -#include "signal/signal.h" - - -Signal0 g_patchTextureChangedCallbacks; - -void Patch_addTextureChangedCallback(const SignalHandler &handler) -{ - g_patchTextureChangedCallbacks.connectLast(handler); -} - -void Patch_textureChanged() -{ - g_patchTextureChangedCallbacks(); -} - - -Shader *PatchInstance::m_state_selpoint; -Shader *Patch::m_state_ctrl; -Shader *Patch::m_state_lattice; -EPatchType Patch::m_type; - - -std::size_t MAX_PATCH_WIDTH = 0; -std::size_t MAX_PATCH_HEIGHT = 0; - -int g_PatchSubdivideThreshold = 4; - -void BezierCurveTree_Delete(BezierCurveTree *pCurve) -{ - if (pCurve) { - BezierCurveTree_Delete(pCurve->left); - BezierCurveTree_Delete(pCurve->right); - delete pCurve; - } -} - -std::size_t BezierCurveTree_Setup(BezierCurveTree *pCurve, std::size_t index, std::size_t stride) -{ - if (pCurve) { - if (pCurve->left && pCurve->right) { - index = BezierCurveTree_Setup(pCurve->left, index, stride); - pCurve->index = index * stride; - index++; - index = BezierCurveTree_Setup(pCurve->right, index, stride); - } else { - pCurve->index = BEZIERCURVETREE_MAX_INDEX; - } - } - - return index; -} - -bool BezierCurve_IsCurved(BezierCurve *pCurve) -{ - Vector3 vTemp(vector3_subtracted(pCurve->right, pCurve->left)); - Vector3 v1(vector3_subtracted(pCurve->crd, pCurve->left)); - Vector3 v2(vector3_subtracted(pCurve->right, pCurve->crd)); - - if (vector3_equal(v1, g_vector3_identity) || vector3_equal(vTemp, v1)) { // return 0 if 1->2 == 0 or 1->2 == 1->3 - return false; - } - - vector3_normalise(v1); - vector3_normalise(v2); - if (vector3_equal(v1, v2)) { - return false; - } - - Vector3 v3(vTemp); - const double width = vector3_length(v3); - vector3_scale(v3, 1.0 / width); - - if (vector3_equal(v1, v3) && vector3_equal(v2, v3)) { - return false; - } - - const double angle = acos(vector3_dot(v1, v2)) / c_pi; - - const double index = width * angle; - - if (index > static_cast( g_PatchSubdivideThreshold )) { - return true; - } - return false; -} - -void BezierInterpolate(BezierCurve *pCurve) -{ - pCurve->left = vector3_mid(pCurve->left, pCurve->crd); - pCurve->right = vector3_mid(pCurve->crd, pCurve->right); - pCurve->crd = vector3_mid(pCurve->left, pCurve->right); -} - -const std::size_t PATCH_MAX_SUBDIVISION_DEPTH = 16; - -void BezierCurveTree_FromCurveList(BezierCurveTree *pTree, GSList *pCurveList, std::size_t depth = 0) -{ - GSList *pLeftList = 0; - GSList *pRightList = 0; - BezierCurve *pCurve, *pLeftCurve, *pRightCurve; - bool bSplit = false; - - for (GSList *l = pCurveList; l; l = l->next) { - pCurve = (BezierCurve *) (l->data); - if (bSplit || BezierCurve_IsCurved(pCurve)) { - bSplit = true; - pLeftCurve = new BezierCurve; - pRightCurve = new BezierCurve; - pLeftCurve->left = pCurve->left; - pRightCurve->right = pCurve->right; - BezierInterpolate(pCurve); - pLeftCurve->crd = pCurve->left; - pRightCurve->crd = pCurve->right; - pLeftCurve->right = pCurve->crd; - pRightCurve->left = pCurve->crd; - - pLeftList = g_slist_prepend(pLeftList, pLeftCurve); - pRightList = g_slist_prepend(pRightList, pRightCurve); - } - } - - if (pLeftList != 0 && pRightList != 0 && depth != PATCH_MAX_SUBDIVISION_DEPTH) { - pTree->left = new BezierCurveTree; - pTree->right = new BezierCurveTree; - BezierCurveTree_FromCurveList(pTree->left, pLeftList, depth + 1); - BezierCurveTree_FromCurveList(pTree->right, pRightList, depth + 1); - - for (GSList *l = pLeftList; l != 0; l = g_slist_next(l)) { - delete (BezierCurve *) l->data; - } - - for (GSList *l = pRightList; l != 0; l = g_slist_next(l)) { - delete (BezierCurve *) l->data; - } - - g_slist_free(pLeftList); - g_slist_free(pRightList); - } else { - pTree->left = 0; - pTree->right = 0; - } -} - - -int Patch::m_CycleCapIndex = 0; - - -void Patch::setDims(std::size_t w, std::size_t h) -{ - if ((w % 2) == 0) { - w -= 1; - } - ASSERT_MESSAGE(w <= MAX_PATCH_WIDTH, "patch too wide"); - if (w > MAX_PATCH_WIDTH) { - w = MAX_PATCH_WIDTH; - } else if (w < MIN_PATCH_WIDTH) { - w = MIN_PATCH_WIDTH; - } - - if ((h % 2) == 0) { - m_height -= 1; - } - ASSERT_MESSAGE(h <= MAX_PATCH_HEIGHT, "patch too tall"); - if (h > MAX_PATCH_HEIGHT) { - h = MAX_PATCH_HEIGHT; - } else if (h < MIN_PATCH_HEIGHT) { - h = MIN_PATCH_HEIGHT; - } - - m_width = w; - m_height = h; - - if (m_width * m_height != m_ctrl.size()) { - m_ctrl.resize(m_width * m_height); - onAllocate(m_ctrl.size()); - } -} - -inline const Colour4b &colour_for_index(std::size_t i, std::size_t width) -{ - return (i % 2 || (i / width) % 2) ? colour_inside : colour_corner; -} - -inline bool float_valid(float f) -{ - return f == f; -} - -bool Patch::isValid() const -{ - if (!m_width || !m_height) { - return false; - } - - for (const_iterator i = m_ctrl.begin(); i != m_ctrl.end(); ++i) { - if (!float_valid((*i).m_vertex.x()) - || !float_valid((*i).m_vertex.y()) - || !float_valid((*i).m_vertex.z()) - || !float_valid((*i).m_texcoord.x()) - || !float_valid((*i).m_texcoord.y())) { - globalErrorStream() << "patch has invalid control points\n"; - return false; - } - } - return true; -} - -void Patch::UpdateCachedData() -{ - m_ctrl_vertices.clear(); - m_lattice_indices.clear(); - - if (!isValid()) { - m_tess.m_numStrips = 0; - m_tess.m_lenStrips = 0; - m_tess.m_nArrayHeight = 0; - m_tess.m_nArrayWidth = 0; - m_tess.m_curveTreeU.resize(0); - m_tess.m_curveTreeV.resize(0); - m_tess.m_indices.resize(0); - m_tess.m_vertices.resize(0); - m_tess.m_arrayHeight.resize(0); - m_tess.m_arrayWidth.resize(0); - m_aabb_local = AABB(); - return; - } - - BuildTesselationCurves(ROW); - BuildTesselationCurves(COL); - BuildVertexArray(); - AccumulateBBox(); - - IndexBuffer ctrl_indices; - - m_lattice_indices.reserve(((m_width * (m_height - 1)) + (m_height * (m_width - 1))) << 1); - ctrl_indices.reserve(m_ctrlTransformed.size()); - { - UniqueVertexBuffer inserter(m_ctrl_vertices); - for (iterator i = m_ctrlTransformed.begin(); i != m_ctrlTransformed.end(); ++i) { - ctrl_indices.insert(inserter.insert(pointvertex_quantised( - PointVertex(reinterpret_cast((*i).m_vertex ), - colour_for_index(i - m_ctrlTransformed.begin(), m_width))))); - } - } - { - for (IndexBuffer::iterator i = ctrl_indices.begin(); i != ctrl_indices.end(); ++i) { - if (std::size_t(i - ctrl_indices.begin()) % m_width) { - m_lattice_indices.insert(*(i - 1)); - m_lattice_indices.insert(*i); - } - if (std::size_t(i - ctrl_indices.begin()) >= m_width) { - m_lattice_indices.insert(*(i - m_width)); - m_lattice_indices.insert(*i); - } - } - } - -#if 0 - { - Array::iterator first = m_tess.m_indices.begin(); - for ( std::size_t s = 0; s < m_tess.m_numStrips; s++ ) - { - Array::iterator last = first + m_tess.m_lenStrips; - - for ( Array::iterator i( first ); i + 2 != last; i += 2 ) - { - ArbitraryMeshTriangle_sumTangents( m_tess.m_vertices[*( i + 0 )], m_tess.m_vertices[*( i + 1 )], m_tess.m_vertices[*( i + 2 )] ); - ArbitraryMeshTriangle_sumTangents( m_tess.m_vertices[*( i + 2 )], m_tess.m_vertices[*( i + 1 )], m_tess.m_vertices[*( i + 3 )] ); - } - - first = last; - } - - for ( Array::iterator i = m_tess.m_vertices.begin(); i != m_tess.m_vertices.end(); ++i ) - { - vector3_normalise( reinterpret_cast( ( *i ).tangent ) ); - vector3_normalise( reinterpret_cast( ( *i ).bitangent ) ); - } - } -#endif - - SceneChangeNotify(); -} - -void Patch::InvertMatrix() -{ - undoSave(); - - PatchControlArray_invert(m_ctrl, m_width, m_height); - - controlPointsChanged(); -} - -void Patch::TransposeMatrix() -{ - undoSave(); - - { - Array tmp(m_width * m_height); - copy_ctrl(tmp.data(), m_ctrl.data(), m_ctrl.data() + m_width * m_height); - - PatchControlIter from = tmp.data(); - for (std::size_t h = 0; h != m_height; ++h) { - PatchControlIter to = m_ctrl.data() + h; - for (std::size_t w = 0; w != m_width; ++w, ++from, to += m_height) { - *to = *from; - } - } - } - - { - std::size_t tmp = m_width; - m_width = m_height; - m_height = tmp; - } - - controlPointsChanged(); -} - -void Patch::Redisperse(EMatrixMajor mt) -{ - std::size_t w, h, width, height, row_stride, col_stride; - PatchControl *p1, *p2, *p3; - - undoSave(); - - switch (mt) { - case COL: - width = (m_width - 1) >> 1; - height = m_height; - col_stride = 1; - row_stride = m_width; - break; - case ROW: - width = (m_height - 1) >> 1; - height = m_width; - col_stride = m_width; - row_stride = 1; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - for (h = 0; h < height; h++) { - p1 = m_ctrl.data() + (h * row_stride); - for (w = 0; w < width; w++) { - p2 = p1 + col_stride; - p3 = p2 + col_stride; - p2->m_vertex = vector3_mid(p1->m_vertex, p3->m_vertex); - p1 = p3; - } - } - - controlPointsChanged(); -} - -void Patch::Smooth(EMatrixMajor mt) -{ - std::size_t w, h, width, height, row_stride, col_stride; - bool wrap; - PatchControl *p1, *p2, *p3, *p2b; - - undoSave(); - - switch (mt) { - case COL: - width = (m_width - 1) >> 1; - height = m_height; - col_stride = 1; - row_stride = m_width; - break; - case ROW: - width = (m_height - 1) >> 1; - height = m_width; - col_stride = m_width; - row_stride = 1; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - wrap = true; - for (h = 0; h < height; h++) { - p1 = m_ctrl.data() + (h * row_stride); - p2 = p1 + (2 * width) * col_stride; - //globalErrorStream() << "compare " << p1->m_vertex << " and " << p2->m_vertex << "\n"; - if (vector3_length_squared(vector3_subtracted(p1->m_vertex, p2->m_vertex)) > 1.0) { - //globalErrorStream() << "too far\n"; - wrap = false; - break; - } - } - - for (h = 0; h < height; h++) { - p1 = m_ctrl.data() + (h * row_stride) + col_stride; - for (w = 0; w < width - 1; w++) { - p2 = p1 + col_stride; - p3 = p2 + col_stride; - p2->m_vertex = vector3_mid(p1->m_vertex, p3->m_vertex); - p1 = p3; - } - if (wrap) { - p1 = m_ctrl.data() + (h * row_stride) + (2 * width - 1) * col_stride; - p2 = m_ctrl.data() + (h * row_stride); - p2b = m_ctrl.data() + (h * row_stride) + (2 * width) * col_stride; - p3 = m_ctrl.data() + (h * row_stride) + col_stride; - p2->m_vertex = p2b->m_vertex = vector3_mid(p1->m_vertex, p3->m_vertex); - } - } - - controlPointsChanged(); -} - -void Patch::InsertRemove(bool bInsert, bool bColumn, bool bFirst) -{ - undoSave(); - - if (bInsert) { - if (bColumn && (m_width + 2 <= MAX_PATCH_WIDTH)) { - InsertPoints(COL, bFirst); - } else if (m_height + 2 <= MAX_PATCH_HEIGHT) { - InsertPoints(ROW, bFirst); - } - } else { - if (bColumn && (m_width - 2 >= MIN_PATCH_WIDTH)) { - RemovePoints(COL, bFirst); - } else if (m_height - 2 >= MIN_PATCH_HEIGHT) { - RemovePoints(ROW, bFirst); - } - } - - controlPointsChanged(); -} - -Patch *Patch::MakeCap(Patch *patch, EPatchCap eType, EMatrixMajor mt, bool bFirst) -{ - std::size_t i, width, height; - - switch (mt) { - case ROW: - width = m_width; - height = m_height; - break; - case COL: - width = m_height; - height = m_width; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return 0; - } - - Array p(width); - - std::size_t nIndex = (bFirst) ? 0 : height - 1; - if (mt == ROW) { - for (i = 0; i < width; i++) { - p[(bFirst) ? i : (width - 1) - i] = ctrlAt(nIndex, i).m_vertex; - } - } else { - for (i = 0; i < width; i++) { - p[(bFirst) ? i : (width - 1) - i] = ctrlAt(i, nIndex).m_vertex; - } - } - - patch->ConstructSeam(eType, p.data(), width); - return patch; -} - -void Patch::FlipTexture(int nAxis) -{ - undoSave(); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - (*i).m_texcoord[nAxis] = -(*i).m_texcoord[nAxis]; - } - - controlPointsChanged(); -} - -void Patch::TranslateTexture(float s, float t) -{ - undoSave(); - - s = -1 * s / m_state->getTexture().width; - t = t / m_state->getTexture().height; - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - (*i).m_texcoord[0] += s; - (*i).m_texcoord[1] += t; - } - - controlPointsChanged(); -} - -void Patch::ScaleTexture(float s, float t) -{ - undoSave(); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - (*i).m_texcoord[0] *= s; - (*i).m_texcoord[1] *= t; - } - - controlPointsChanged(); -} - -void Patch::RotateTexture(float angle) -{ - undoSave(); - - const float s = static_cast( sin(degrees_to_radians(angle))); - const float c = static_cast( cos(degrees_to_radians(angle))); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - const float x = (*i).m_texcoord[0]; - const float y = (*i).m_texcoord[1]; - (*i).m_texcoord[0] = (x * c) - (y * s); - (*i).m_texcoord[1] = (y * c) + (x * s); - } - - controlPointsChanged(); -} - - -void Patch::SetTextureRepeat(float s, float t) -{ - std::size_t w, h; - float si, ti, sc, tc; - PatchControl *pDest; - - undoSave(); - - si = s / (float) (m_width - 1); - ti = t / (float) (m_height - 1); - - pDest = m_ctrl.data(); - for (h = 0, tc = 0.0f; h < m_height; h++, tc += ti) { - for (w = 0, sc = 0.0f; w < m_width; w++, sc += si) { - pDest->m_texcoord[0] = sc; - pDest->m_texcoord[1] = tc; - pDest++; - } - } - - controlPointsChanged(); -} - -/* - void Patch::SetTextureInfo(texdef_t *pt) - { - if(pt->getShift()[0] || pt->getShift()[1]) - TranslateTexture (pt->getShift()[0], pt->getShift()[1]); - else if(pt->getScale()[0] || pt->getScale()[1]) - { - if(pt->getScale()[0] == 0.0f) pt->setScale(0, 1.0f); - if(pt->getScale()[1] == 0.0f) pt->setScale(1, 1.0f); - ScaleTexture (pt->getScale()[0], pt->getScale()[1]); - } - else if(pt->rotate) - RotateTexture (pt->rotate); - } - */ - -inline int texture_axis(const Vector3 &normal) -{ - // axis dominance order: Z, X, Y - return (normal.x() >= normal.y()) ? (normal.x() > normal.z()) ? 0 : 2 : (normal.y() > normal.z()) ? 1 : 2; -} - -void Patch::CapTexture() -{ - const PatchControl &p1 = m_ctrl[m_width]; - const PatchControl &p2 = m_ctrl[m_width * (m_height - 1)]; - const PatchControl &p3 = m_ctrl[(m_width * m_height) - 1]; - - - Vector3 normal(g_vector3_identity); - - { - Vector3 tmp(vector3_cross( - vector3_subtracted(p2.m_vertex, m_ctrl[0].m_vertex), - vector3_subtracted(p3.m_vertex, m_ctrl[0].m_vertex) - )); - if (!vector3_equal(tmp, g_vector3_identity)) { - vector3_add(normal, tmp); - } - } - { - Vector3 tmp(vector3_cross( - vector3_subtracted(p1.m_vertex, p3.m_vertex), - vector3_subtracted(m_ctrl[0].m_vertex, p3.m_vertex) - )); - if (!vector3_equal(tmp, g_vector3_identity)) { - vector3_add(normal, tmp); - } - } - - ProjectTexture(texture_axis(normal)); -} - -// uses longest parallel chord to calculate texture coords for each row/col -void Patch::NaturalTexture() -{ - undoSave(); - - { - float fSize = (float) m_state->getTexture().width * Texdef_getDefaultTextureScale(); - - double texBest = 0; - double tex = 0; - PatchControl *pWidth = m_ctrl.data(); - for (std::size_t w = 0; w < m_width; w++, pWidth++) { - { - PatchControl *pHeight = pWidth; - for (std::size_t h = 0; h < m_height; h++, pHeight += m_width) { - pHeight->m_texcoord[0] = static_cast( tex ); - } - } - - if (w + 1 == m_width) { - break; - } - - { - PatchControl *pHeight = pWidth; - for (std::size_t h = 0; h < m_height; h++, pHeight += m_width) { - Vector3 v(vector3_subtracted(pHeight->m_vertex, (pHeight + 1)->m_vertex)); - double length = tex + (vector3_length(v) / fSize); - if (fabs(length) > texBest) { - texBest = length; - } - } - } - - tex = texBest; - } - } - - { - float fSize = -(float) m_state->getTexture().height * Texdef_getDefaultTextureScale(); - - double texBest = 0; - double tex = 0; - PatchControl *pHeight = m_ctrl.data(); - for (std::size_t h = 0; h < m_height; h++, pHeight += m_width) { - { - PatchControl *pWidth = pHeight; - for (std::size_t w = 0; w < m_width; w++, pWidth++) { - pWidth->m_texcoord[1] = static_cast( tex ); - } - } - - if (h + 1 == m_height) { - break; - } - - { - PatchControl *pWidth = pHeight; - for (std::size_t w = 0; w < m_width; w++, pWidth++) { - Vector3 v(vector3_subtracted(pWidth->m_vertex, (pWidth + m_width)->m_vertex)); - double length = tex + (vector3_length(v) / fSize); - if (fabs(length) > texBest) { - texBest = length; - } - } - } - - tex = texBest; - } - } - - controlPointsChanged(); -} - -void Patch::IdentityColour() -{ - PatchControl *pCtrl = m_ctrl.data(); - - for (std::size_t h = 0; h < m_height; h++) { - for (std::size_t w = 0; w < m_width; w++, ++pCtrl) { - pCtrl->m_color = Vector4(1,1,1,1); - } - } -} - - -// private: - -void Patch::AccumulateBBox() -{ - m_aabb_local = AABB(); - - for (PatchControlArray::iterator i = m_ctrlTransformed.begin(); i != m_ctrlTransformed.end(); ++i) { - aabb_extend_by_point_safe(m_aabb_local, (*i).m_vertex); - } - - m_boundsChanged(); - m_lightsChanged(); -} - -void Patch::InsertPoints(EMatrixMajor mt, bool bFirst) -{ - std::size_t width, height, row_stride, col_stride; - - switch (mt) { - case ROW: - col_stride = 1; - row_stride = m_width; - width = m_width; - height = m_height; - break; - case COL: - col_stride = m_width; - row_stride = 1; - width = m_height; - height = m_width; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - std::size_t pos = 0; - { - PatchControl *p1 = m_ctrl.data(); - /* - if(GlobalSelectionSystem().countSelected() != 0) - { - scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); - PatchInstance* patch = Instance_getPatch(instance); - patch->m_selectable.isSelected(); - } - */ - for (std::size_t w = 0; w != width; ++w, p1 += col_stride) { - { - PatchControl *p2 = p1; - for (std::size_t h = 1; h < height; h += 2, p2 += 2 * row_stride) { - if (0) { //p2->m_selectable.isSelected()) - pos = h; - break; - } - } - if (pos != 0) { - break; - } - } - - { - PatchControl *p2 = p1; - for (std::size_t h = 0; h < height; h += 2, p2 += 2 * row_stride) { - if (0) { //p2->m_selectable.isSelected()) - pos = h; - break; - } - } - if (pos != 0) { - break; - } - } - } - } - - Array tmp(m_ctrl); - - std::size_t row_stride2, col_stride2; - switch (mt) { - case ROW: - setDims(m_width, m_height + 2); - col_stride2 = 1; - row_stride2 = m_width; - break; - case COL: - setDims(m_width + 2, m_height); - col_stride2 = m_width; - row_stride2 = 1; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - if (bFirst) { - pos = height - 1; - } else { - pos = 2; - } - - if (pos >= height) { - if (bFirst) { - pos = height - 1; - } else { - pos = 2; - } - } else if (pos == 0) { - pos = 2; - } else if (pos % 2) { - ++pos; - } - - - for (std::size_t w = 0; w != width; ++w) { - PatchControl *p1 = tmp.data() + (w * col_stride); - PatchControl *p2 = m_ctrl.data() + (w * col_stride2); - for (std::size_t h = 0; h != height; ++h, p2 += row_stride2, p1 += row_stride) { - if (h == pos) { - p2 += 2 * row_stride2; - } - *p2 = *p1; - } - - p1 = tmp.data() + (w * col_stride + pos * row_stride); - p2 = m_ctrl.data() + (w * col_stride2 + pos * row_stride2); - - PatchControl *r2a = (p2 + row_stride2); - PatchControl *r2b = (p2 - row_stride2); - PatchControl *c2a = (p1 - 2 * row_stride); - PatchControl *c2b = (p1 - row_stride); - - // set two new row points - *(p2 + 2 * row_stride2) = *p1; - *r2a = *c2b; - - for (std::size_t i = 0; i != 3; ++i) { - r2a->m_vertex[i] = float_mid(c2b->m_vertex[i], p1->m_vertex[i]); - - r2b->m_vertex[i] = float_mid(c2a->m_vertex[i], c2b->m_vertex[i]); - - p2->m_vertex[i] = float_mid(r2a->m_vertex[i], r2b->m_vertex[i]); - } - for (std::size_t i = 0; i != 2; ++i) { - r2a->m_texcoord[i] = float_mid(c2b->m_texcoord[i], p1->m_texcoord[i]); - - r2b->m_texcoord[i] = float_mid(c2a->m_texcoord[i], c2b->m_texcoord[i]); - - p2->m_texcoord[i] = float_mid(r2a->m_texcoord[i], r2b->m_texcoord[i]); - } - for (std::size_t i = 0; i != 4; ++i) { - r2a->m_color[i] = float_mid(c2b->m_color[i], p1->m_color[i]); - - r2b->m_color[i] = float_mid(c2a->m_color[i], c2b->m_color[i]); - - p2->m_color[i] = float_mid(r2a->m_color[i], r2b->m_color[i]); - } - } -} - -void Patch::RemovePoints(EMatrixMajor mt, bool bFirst) -{ - std::size_t width, height, row_stride, col_stride; - - switch (mt) { - case ROW: - col_stride = 1; - row_stride = m_width; - width = m_width; - height = m_height; - break; - case COL: - col_stride = m_width; - row_stride = 1; - width = m_height; - height = m_width; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - std::size_t pos = 0; - { - PatchControl *p1 = m_ctrl.data(); - for (std::size_t w = 0; w != width; ++w, p1 += col_stride) { - { - PatchControl *p2 = p1; - for (std::size_t h = 1; h < height; h += 2, p2 += 2 * row_stride) { - if (0) { //p2->m_selectable.isSelected()) - pos = h; - break; - } - } - if (pos != 0) { - break; - } - } - - { - PatchControl *p2 = p1; - for (std::size_t h = 0; h < height; h += 2, p2 += 2 * row_stride) { - if (0) { //p2->m_selectable.isSelected()) - pos = h; - break; - } - } - if (pos != 0) { - break; - } - } - } - } - - Array tmp(m_ctrl); - - std::size_t row_stride2, col_stride2; - switch (mt) { - case ROW: - setDims(m_width, m_height - 2); - col_stride2 = 1; - row_stride2 = m_width; - break; - case COL: - setDims(m_width - 2, m_height); - col_stride2 = m_width; - row_stride2 = 1; - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - if (bFirst) { - pos = height - 3; - } else { - pos = 2; - } - if (pos >= height) { - if (bFirst) { - pos = height - 3; - } else { - pos = 2; - } - } else if (pos == 0) { - pos = 2; - } else if (pos > height - 3) { - pos = height - 3; - } else if (pos % 2) { - ++pos; - } - - for (std::size_t w = 0; w != width; w++) { - PatchControl *p1 = tmp.data() + (w * col_stride); - PatchControl *p2 = m_ctrl.data() + (w * col_stride2); - for (std::size_t h = 0; h != height; ++h, p2 += row_stride2, p1 += row_stride) { - if (h == pos) { - p1 += 2 * row_stride2; - h += 2; - } - *p2 = *p1; - } - - p1 = tmp.data() + (w * col_stride + pos * row_stride); - p2 = m_ctrl.data() + (w * col_stride2 + pos * row_stride2); - - for (std::size_t i = 0; i < 3; i++) { - (p2 - row_stride2)->m_vertex[i] = - ((p1 + 2 * row_stride)->m_vertex[i] + (p1 - 2 * row_stride)->m_vertex[i]) * 0.5f; - - (p2 - row_stride2)->m_vertex[i] = - (p2 - row_stride2)->m_vertex[i] + (2.0f * ((p1)->m_vertex[i] - (p2 - row_stride2)->m_vertex[i])); - } - for (std::size_t i = 0; i < 2; i++) { - (p2 - row_stride2)->m_texcoord[i] = - ((p1 + 2 * row_stride)->m_texcoord[i] + (p1 - 2 * row_stride)->m_texcoord[i]) * 0.5f; - - (p2 - row_stride2)->m_texcoord[i] = (p2 - row_stride2)->m_texcoord[i] + - (2.0f * ((p1)->m_texcoord[i] - (p2 - row_stride2)->m_texcoord[i])); - } - } -} - -void Patch::ConstructSeam(EPatchCap eType, Vector3 *p, std::size_t width) -{ - switch (eType) { - case eCapIBevel: { - setDims(3, 3); - m_ctrl[0].m_vertex = p[0]; - m_ctrl[1].m_vertex = p[1]; - m_ctrl[2].m_vertex = p[1]; - m_ctrl[3].m_vertex = p[1]; - m_ctrl[4].m_vertex = p[1]; - m_ctrl[5].m_vertex = p[1]; - m_ctrl[6].m_vertex = p[2]; - m_ctrl[7].m_vertex = p[1]; - m_ctrl[8].m_vertex = p[1]; - } - break; - case eCapBevel: { - setDims(3, 3); - Vector3 p3(vector3_added(p[2], vector3_subtracted(p[0], p[1]))); - m_ctrl[0].m_vertex = p3; - m_ctrl[1].m_vertex = p3; - m_ctrl[2].m_vertex = p[2]; - m_ctrl[3].m_vertex = p3; - m_ctrl[4].m_vertex = p3; - m_ctrl[5].m_vertex = p[1]; - m_ctrl[6].m_vertex = p3; - m_ctrl[7].m_vertex = p3; - m_ctrl[8].m_vertex = p[0]; - } - break; - case eCapEndCap: { - Vector3 p5(vector3_mid(p[0], p[4])); - - setDims(3, 3); - m_ctrl[0].m_vertex = p[0]; - m_ctrl[1].m_vertex = p5; - m_ctrl[2].m_vertex = p[4]; - m_ctrl[3].m_vertex = p[1]; - m_ctrl[4].m_vertex = p[2]; - m_ctrl[5].m_vertex = p[3]; - m_ctrl[6].m_vertex = p[2]; - m_ctrl[7].m_vertex = p[2]; - m_ctrl[8].m_vertex = p[2]; - } - break; - case eCapIEndCap: { - setDims(5, 3); - m_ctrl[0].m_vertex = p[4]; - m_ctrl[1].m_vertex = p[3]; - m_ctrl[2].m_vertex = p[2]; - m_ctrl[3].m_vertex = p[1]; - m_ctrl[4].m_vertex = p[0]; - m_ctrl[5].m_vertex = p[3]; - m_ctrl[6].m_vertex = p[3]; - m_ctrl[7].m_vertex = p[2]; - m_ctrl[8].m_vertex = p[1]; - m_ctrl[9].m_vertex = p[1]; - m_ctrl[10].m_vertex = p[3]; - m_ctrl[11].m_vertex = p[3]; - m_ctrl[12].m_vertex = p[2]; - m_ctrl[13].m_vertex = p[1]; - m_ctrl[14].m_vertex = p[1]; - } - break; - case eCapCylinder: { - std::size_t mid = (width - 1) >> 1; - - bool degenerate = (mid % 2) != 0; - - std::size_t newHeight = mid + (degenerate ? 2 : 1); - - setDims(3, newHeight); - - if (degenerate) { - ++mid; - for (std::size_t i = width; i != width + 2; ++i) { - p[i] = p[width - 1]; - } - } - - { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t i = 0; i != m_height; ++i, pCtrl += m_width) { - pCtrl->m_vertex = p[i]; - } - } - { - PatchControl *pCtrl = m_ctrl.data() + 2; - std::size_t h = m_height - 1; - for (std::size_t i = 0; i != m_height; ++i, pCtrl += m_width) { - pCtrl->m_vertex = p[h + (h - i)]; - } - } - - Redisperse(COL); - } - break; - default: - ERROR_MESSAGE("invalid patch-cap type"); - return; - } - CapTexture(); - controlPointsChanged(); -} - -void Patch::ProjectTexture(int nAxis) -{ - undoSave(); - - int s, t; - - switch (nAxis) { - case 2: - s = 0; - t = 1; - break; - case 0: - s = 1; - t = 2; - break; - case 1: - s = 0; - t = 2; - break; - default: - ERROR_MESSAGE("invalid axis"); - return; - } - - float fWidth = 1 / (m_state->getTexture().width * Texdef_getDefaultTextureScale()); - float fHeight = 1 / (m_state->getTexture().height * -Texdef_getDefaultTextureScale()); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - (*i).m_texcoord[0] = (*i).m_vertex[s] * fWidth; - (*i).m_texcoord[1] = (*i).m_vertex[t] * fHeight; - } - - controlPointsChanged(); -} - -void Patch::constructPlane(const AABB &aabb, int axis, std::size_t width, std::size_t height) -{ - setDims(width, height); - - int x, y, z; - switch (axis) { - case 2: - x = 0; - y = 1; - z = 2; - break; - case 1: - x = 0; - y = 2; - z = 1; - break; - case 0: - x = 1; - y = 2; - z = 0; - break; - default: - ERROR_MESSAGE("invalid view-type"); - return; - } - - if (m_width < MIN_PATCH_WIDTH || m_width > MAX_PATCH_WIDTH) { - m_width = 3; - } - if (m_height < MIN_PATCH_HEIGHT || m_height > MAX_PATCH_HEIGHT) { - m_height = 3; - } - - Vector3 vStart; - vStart[x] = aabb.origin[x] - aabb.extents[x]; - vStart[y] = aabb.origin[y] - aabb.extents[y]; - vStart[z] = aabb.origin[z]; - - float xAdj = fabsf((vStart[x] - (aabb.origin[x] + aabb.extents[x])) / (float) (m_width - 1)); - float yAdj = fabsf((vStart[y] - (aabb.origin[y] + aabb.extents[y])) / (float) (m_height - 1)); - - Vector3 vTmp; - vTmp[z] = vStart[z]; - PatchControl *pCtrl = m_ctrl.data(); - - vTmp[y] = vStart[y]; - for (std::size_t h = 0; h < m_height; h++) { - vTmp[x] = vStart[x]; - for (std::size_t w = 0; w < m_width; w++, ++pCtrl) { - pCtrl->m_vertex = vTmp; - vTmp[x] += xAdj; - } - vTmp[y] += yAdj; - } - - IdentityColour(); - NaturalTexture(); -} - -void Patch::ConstructPrefab(const AABB &aabb, EPatchPrefab eType, int axis, std::size_t width, std::size_t height) -{ - Vector3 vPos[3]; - - if (eType != ePlane) { - vPos[0] = vector3_subtracted(aabb.origin, aabb.extents); - vPos[1] = aabb.origin; - vPos[2] = vector3_added(aabb.origin, aabb.extents); - } - - if (eType == ePlane) { - constructPlane(aabb, axis, width, height); - } else if (eType == eSqCylinder - || eType == eCylinder - || eType == eDenseCylinder - || eType == eVeryDenseCylinder - || eType == eCone - || eType == eSphere) { - unsigned char *pIndex; - unsigned char pCylIndex[] = - { - 0, 0, - 1, 0, - 2, 0, - 2, 1, - 2, 2, - 1, 2, - 0, 2, - 0, 1, - 0, 0 - }; - - - PatchControl *pStart; - switch (eType) { - case eSqCylinder: - setDims(9, 3); - pStart = m_ctrl.data(); - break; - case eDenseCylinder: - case eVeryDenseCylinder: - case eCylinder: - setDims(9, 3); - pStart = m_ctrl.data() + 1; - break; - case eCone: - setDims(9, 3); - pStart = m_ctrl.data() + 1; - break; - case eSphere: - setDims(9, 5); - pStart = m_ctrl.data() + (9 + 1); - break; - default: - ERROR_MESSAGE("this should be unreachable"); - return; - } - - for (std::size_t h = 0; h < 3; h++, pStart += 9) { - pIndex = pCylIndex; - PatchControl *pCtrl = pStart; - for (std::size_t w = 0; w < 8; w++, pCtrl++) { - pCtrl->m_vertex[0] = vPos[pIndex[0]][0]; - pCtrl->m_vertex[1] = vPos[pIndex[1]][1]; - pCtrl->m_vertex[2] = vPos[h][2]; - pIndex += 2; - } - } - - switch (eType) { - case eSqCylinder: { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 3; h++, pCtrl += 9) { - pCtrl[8].m_vertex = pCtrl[0].m_vertex; - } - } - break; - case eDenseCylinder: - case eVeryDenseCylinder: - case eCylinder: { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 3; h++, pCtrl += 9) { - pCtrl[0].m_vertex = pCtrl[8].m_vertex; - } - } - break; - case eCone: { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 2; h++, pCtrl += 9) { - pCtrl[0].m_vertex = pCtrl[8].m_vertex; - } - } - { - PatchControl *pCtrl = m_ctrl.data() + 9 * 2; - for (std::size_t w = 0; w < 9; w++, pCtrl++) { - pCtrl->m_vertex[0] = vPos[1][0]; - pCtrl->m_vertex[1] = vPos[1][1]; - pCtrl->m_vertex[2] = vPos[2][2]; - } - } - break; - case eSphere: { - PatchControl *pCtrl = m_ctrl.data() + 9; - for (std::size_t h = 0; h < 3; h++, pCtrl += 9) { - pCtrl[0].m_vertex = pCtrl[8].m_vertex; - } - } - { - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t w = 0; w < 9; w++, pCtrl++) { - pCtrl->m_vertex[0] = vPos[1][0]; - pCtrl->m_vertex[1] = vPos[1][1]; - pCtrl->m_vertex[2] = vPos[0][2]; - } - } - { - PatchControl *pCtrl = m_ctrl.data() + (9 * 4); - for (std::size_t w = 0; w < 9; w++, pCtrl++) { - pCtrl->m_vertex[0] = vPos[1][0]; - pCtrl->m_vertex[1] = vPos[1][1]; - pCtrl->m_vertex[2] = vPos[2][2]; - } - } - break; - default: - ERROR_MESSAGE("this should be unreachable"); - return; - } - } else if (eType == eXactCylinder) { - int n = (width - 1) / 2; // n = number of segments - setDims(width, height); - - // vPos[0] = vector3_subtracted(aabb.origin, aabb.extents); - // vPos[1] = aabb.origin; - // vPos[2] = vector3_added(aabb.origin, aabb.extents); - - float f = 1 / cos(M_PI / n); - for (std::size_t i = 0; i < width; ++i) { - float angle = (M_PI * i) / n; // 0 to 2pi - float x = vPos[1][0] + (vPos[2][0] - vPos[1][0]) * cos(angle) * ((i & 1) ? f : 1.0f); - float y = vPos[1][1] + (vPos[2][1] - vPos[1][1]) * sin(angle) * ((i & 1) ? f : 1.0f); - for (std::size_t j = 0; j < height; ++j) { - float z = vPos[0][2] + (vPos[2][2] - vPos[0][2]) * (j / (float) (height - 1)); - PatchControl *v; - v = &m_ctrl.data()[j * width + i]; - v->m_vertex[0] = x; - v->m_vertex[1] = y; - v->m_vertex[2] = z; - } - } - } else if (eType == eXactCone) { - int n = (width - 1) / 2; // n = number of segments - setDims(width, height); - - // vPos[0] = vector3_subtracted(aabb.origin, aabb.extents); - // vPos[1] = aabb.origin; - // vPos[2] = vector3_added(aabb.origin, aabb.extents); - - float f = 1 / cos(M_PI / n); - for (std::size_t i = 0; i < width; ++i) { - float angle = (M_PI * i) / n; - for (std::size_t j = 0; j < height; ++j) { - float x = vPos[1][0] + (1.0f - (j / (float) (height - 1))) * (vPos[2][0] - vPos[1][0]) * cos(angle) * - ((i & 1) ? f : 1.0f); - float y = vPos[1][1] + (1.0f - (j / (float) (height - 1))) * (vPos[2][1] - vPos[1][1]) * sin(angle) * - ((i & 1) ? f : 1.0f); - float z = vPos[0][2] + (vPos[2][2] - vPos[0][2]) * (j / (float) (height - 1)); - PatchControl *v; - v = &m_ctrl.data()[j * width + i]; - v->m_vertex[0] = x; - v->m_vertex[1] = y; - v->m_vertex[2] = z; - } - } - } else if (eType == eXactSphere) { - int n = (width - 1) / 2; // n = number of segments (yaw) - int m = (height - 1) / 2; // m = number of segments (pitch) - setDims(width, height); - - // vPos[0] = vector3_subtracted(aabb.origin, aabb.extents); - // vPos[1] = aabb.origin; - // vPos[2] = vector3_added(aabb.origin, aabb.extents); - - float f = 1 / cos(M_PI / n); - float g = 1 / cos(M_PI / (2 * m)); - for (std::size_t i = 0; i < width; ++i) { - float angle = (M_PI * i) / n; - for (std::size_t j = 0; j < height; ++j) { - float angle2 = (M_PI * j) / (2 * m); - float x = vPos[1][0] + (vPos[2][0] - vPos[1][0]) * sin(angle2) * ((j & 1) ? g : 1.0f) * cos(angle) * - ((i & 1) ? f : 1.0f); - float y = vPos[1][1] + (vPos[2][1] - vPos[1][1]) * sin(angle2) * ((j & 1) ? g : 1.0f) * sin(angle) * - ((i & 1) ? f : 1.0f); - float z = vPos[1][2] + (vPos[2][2] - vPos[1][2]) * -cos(angle2) * ((j & 1) ? g : 1.0f); - PatchControl *v; - v = &m_ctrl.data()[j * width + i]; - v->m_vertex[0] = x; - v->m_vertex[1] = y; - v->m_vertex[2] = z; - } - } - } else if (eType == eBevel) { - unsigned char *pIndex; - unsigned char pBevIndex[] = - { - 0, 0, - 2, 0, - 2, 2, - }; - - setDims(3, 3); - - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 3; h++) { - pIndex = pBevIndex; - for (std::size_t w = 0; w < 3; w++, pIndex += 2, pCtrl++) { - pCtrl->m_vertex[0] = vPos[pIndex[0]][0]; - pCtrl->m_vertex[1] = vPos[pIndex[1]][1]; - pCtrl->m_vertex[2] = vPos[h][2]; - } - } - } else if (eType == eEndCap) { - unsigned char *pIndex; - unsigned char pEndIndex[] = - { - 2, 0, - 2, 2, - 1, 2, - 0, 2, - 0, 0, - }; - - setDims(5, 3); - - PatchControl *pCtrl = m_ctrl.data(); - for (std::size_t h = 0; h < 3; h++) { - pIndex = pEndIndex; - for (std::size_t w = 0; w < 5; w++, pIndex += 2, pCtrl++) { - pCtrl->m_vertex[0] = vPos[pIndex[0]][0]; - pCtrl->m_vertex[1] = vPos[pIndex[1]][1]; - pCtrl->m_vertex[2] = vPos[h][2]; - } - } - } - - if (eType == eDenseCylinder) { - InsertRemove(true, false, true); - } - - if (eType == eVeryDenseCylinder) { - InsertRemove(true, false, false); - InsertRemove(true, false, true); - } - - IdentityColour(); - NaturalTexture(); -} - -void Patch::RenderDebug(RenderStateFlags state) const -{ - for (std::size_t i = 0; i < m_tess.m_numStrips; i++) { - glBegin(GL_QUAD_STRIP); - for (std::size_t j = 0; j < m_tess.m_lenStrips; j++) { - glNormal3fv(normal3f_to_array( - (m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j])->normal)); - glTexCoord2fv(texcoord2f_to_array( - (m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j])->texcoord)); - glVertex3fv(vertex3f_to_array( - (m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j])->vertex)); - } - glEnd(); - } -} - -#include "patchdialog.h" - -bool PatchInspector_IsSelected(int x, int y); -void patch_draw_sphere(const Vector3 origin, float radius, int sides) -{ - if (radius <= 0) { - return; - } - - const double dt = c_2pi / static_cast( sides ); - const double dp = c_pi / static_cast( sides ); - - for (int i = 0; i <= sides - 1; ++i) { - for (int j = 0; j <= sides - 2; ++j) { - const double t = i * dt; - const double p = (j * dp) - (c_pi / 2.0); - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - } - } - - { - const double p = (sides - 1) * dp - (c_pi / 2.0); - for (int i = 0; i <= sides - 1; ++i) { - const double t = i * dt; - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p + dp), radius))); - glVertex3fv(vector3_to_array(v)); - } - - { - Vector3 v(vector3_added(origin, vector3_scaled(vector3_for_spherical(t + dt, p), radius))); - glVertex3fv(vector3_to_array(v)); - } - } - } -} - -bool PatchBalls_Visible(void); -void RenderablePatchFixedSolid::RenderNormals() const -{ - const std::size_t width = m_tess.m_numStrips + 1; - const std::size_t height = m_tess.m_lenStrips >> 1; - - glBegin(GL_TRIANGLES); - for (std::size_t i = 0; i < width; i++) { - for (std::size_t j = 0; j < height; j++) { - Vector3 pos = (m_tess.m_vertices.data() + (j * width + i))->vertex; - Vector4 colour = (m_tess.m_vertices.data() + (j * width + i))->colour; - - /* color the currently selected bit */ - if (PatchBalls_Visible()) { - if (PatchInspector_IsSelected((int)i, (int)j)) { - glColor3f(1,0,0); - patch_draw_sphere(pos, 8, 4); - } else { - glColor3f(1,1,1); - patch_draw_sphere(pos, 2, 4); - } - } - - /*{ - Vector3 vNormal( - vector3_added( - vertex3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->vertex), - vector3_scaled( - normal3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->normal), 8) - ) - ); - glVertex3fv(vertex3f_to_array((m_tess.m_vertices.data() + (j * width + i))->vertex)); - glVertex3fv(&vNormal[0]); - } - { - Vector3 vNormal( - vector3_added( - vertex3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->vertex), - vector3_scaled( - normal3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->tangent), 8) - ) - ); - glVertex3fv(vertex3f_to_array((m_tess.m_vertices.data() + (j * width + i))->vertex)); - glVertex3fv(&vNormal[0]); - } - { - Vector3 vNormal( - vector3_added( - vertex3f_to_vector3(), - vector3_scaled( - normal3f_to_vector3((m_tess.m_vertices.data() + (j * width + i))->bitangent), 8) - ) - ); - glVertex3fv(vertex3f_to_array((m_tess.m_vertices.data() + (j * width + i))->vertex)); - glVertex3fv(&vNormal[0]); - }*/ - } - } - glEnd(); - glColor3f( 1, 1, 1 ); -} - -const int DEGEN_0a = 0x01; -const int DEGEN_1a = 0x02; -const int DEGEN_2a = 0x04; -const int DEGEN_0b = 0x08; -const int DEGEN_1b = 0x10; -const int DEGEN_2b = 0x20; -const int SPLIT = 0x40; -const int AVERAGE = 0x80; - - -unsigned int subarray_get_degen(PatchControlIter subarray, std::size_t strideU, std::size_t strideV) -{ - unsigned int nDegen = 0; - const PatchControl *p1; - const PatchControl *p2; - - p1 = subarray; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_0a; - } - p1 = p2; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_0b; - } - - p1 = subarray + strideV; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_1a; - } - p1 = p2; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_1b; - } - - p1 = subarray + (strideV << 1); - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_2a; - } - p1 = p2; - p2 = p1 + strideU; - if (vector3_equal(p1->m_vertex, p2->m_vertex)) { - nDegen |= DEGEN_2b; - } - - return nDegen; -} - - -inline void -deCasteljau3(const Vector3 &P0, const Vector3 &P1, const Vector3 &P2, Vector3 &P01, Vector3 &P12, Vector3 &P012) -{ - P01 = vector3_mid(P0, P1); - P12 = vector3_mid(P1, P2); - P012 = vector3_mid(P01, P12); -} - -inline void BezierInterpolate4(const Vector4 &start, Vector4 &left, Vector4 &mid, Vector4 &right, const Vector4 &end) -{ - left = vector4_mid(start, mid); - right = vector4_mid(mid, end); - mid = vector4_mid(left, right); -} - -inline void BezierInterpolate3(const Vector3 &start, Vector3 &left, Vector3 &mid, Vector3 &right, const Vector3 &end) -{ - left = vector3_mid(start, mid); - right = vector3_mid(mid, end); - mid = vector3_mid(left, right); -} - -inline void BezierInterpolate2(const Vector2 &start, Vector2 &left, Vector2 &mid, Vector2 &right, const Vector2 &end) -{ - left[0] = float_mid(start[0], mid[0]); - left[1] = float_mid(start[1], mid[1]); - right[0] = float_mid(mid[0], end[0]); - right[1] = float_mid(mid[1], end[1]); - mid[0] = float_mid(left[0], right[0]); - mid[1] = float_mid(left[1], right[1]); -} - - -inline Vector2 &texcoord_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].texcoord ); -} - -inline Vector4 &colour_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].colour ); -} - -inline Vector3 &vertex_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].vertex ); -} - -inline Vector3 &normal_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].normal ); -} - -inline Vector3 &tangent_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].tangent ); -} - -inline Vector3 &bitangent_for_index(Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].bitangent ); -} - -inline const Vector2 &texcoord_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].texcoord ); -} - -inline const Vector4 &colour_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].colour ); -} - -inline const Vector3 &vertex_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].vertex ); -} - -inline const Vector3 &normal_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].normal ); -} - -inline const Vector3 &tangent_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].tangent ); -} - -inline const Vector3 &bitangent_for_index(const Array &vertices, std::size_t index) -{ - return reinterpret_cast( vertices[index].bitangent ); -} - -#include "math/curve.h" - -inline PatchControl QuadraticBezier_evaluate(const PatchControl *firstPoint, double t) -{ - PatchControl result = {Vector3(0, 0, 0), Vector2(0, 0), Vector4(0, 0, 0, 0)}; - double denominator = 0; - - { - double weight = BernsteinPolynomial::apply(t); - vector3_add(result.m_vertex, vector3_scaled(firstPoint[0].m_vertex, weight)); - vector2_add(result.m_texcoord, vector2_scaled(firstPoint[0].m_texcoord, weight)); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply(t); - vector3_add(result.m_vertex, vector3_scaled(firstPoint[1].m_vertex, weight)); - vector2_add(result.m_texcoord, vector2_scaled(firstPoint[1].m_texcoord, weight)); - denominator += weight; - } - { - double weight = BernsteinPolynomial::apply(t); - vector3_add(result.m_vertex, vector3_scaled(firstPoint[2].m_vertex, weight)); - vector2_add(result.m_texcoord, vector2_scaled(firstPoint[2].m_texcoord, weight)); - denominator += weight; - } - - vector3_divide(result.m_vertex, denominator); - vector2_divide(result.m_texcoord, denominator); - return result; -} - -inline Vector3 vector3_linear_interpolated(const Vector3 &a, const Vector3 &b, double t) -{ - return vector3_added(vector3_scaled(a, 1.0 - t), vector3_scaled(b, t)); -} - -inline Vector2 vector2_linear_interpolated(const Vector2 &a, const Vector2 &b, double t) -{ - return vector2_added(vector2_scaled(a, 1.0 - t), vector2_scaled(b, t)); -} - -void normalise_safe(Vector3 &normal) -{ - if (!vector3_equal(normal, g_vector3_identity)) { - vector3_normalise(normal); - } -} - -inline void QuadraticBezier_evaluate(const PatchControl &a, const PatchControl &b, const PatchControl &c, double t, - PatchControl &point, PatchControl &left, PatchControl &right) -{ - left.m_vertex = vector3_linear_interpolated(a.m_vertex, b.m_vertex, t); - left.m_texcoord = vector2_linear_interpolated(a.m_texcoord, b.m_texcoord, t); - right.m_vertex = vector3_linear_interpolated(b.m_vertex, c.m_vertex, t); - right.m_texcoord = vector2_linear_interpolated(b.m_texcoord, c.m_texcoord, t); - point.m_vertex = vector3_linear_interpolated(left.m_vertex, right.m_vertex, t); - point.m_texcoord = vector2_linear_interpolated(left.m_texcoord, right.m_texcoord, t); -} - -void Patch::TesselateSubMatrixFixed(ArbitraryMeshVertex *vertices, std::size_t strideX, std::size_t strideY, - unsigned int nFlagsX, unsigned int nFlagsY, PatchControl *subMatrix[3][3]) -{ - double incrementU = 1.0 / m_subdivisions_x; - double incrementV = 1.0 / m_subdivisions_y; - const std::size_t width = m_subdivisions_x + 1; - const std::size_t height = m_subdivisions_y + 1; - - for (std::size_t i = 0; i != width; ++i) { - double tU = (i + 1 == width) ? 1 : i * incrementU; - PatchControl pointX[3]; - PatchControl leftX[3]; - PatchControl rightX[3]; - QuadraticBezier_evaluate(*subMatrix[0][0], *subMatrix[0][1], *subMatrix[0][2], tU, pointX[0], leftX[0], - rightX[0]); - QuadraticBezier_evaluate(*subMatrix[1][0], *subMatrix[1][1], *subMatrix[1][2], tU, pointX[1], leftX[1], - rightX[1]); - QuadraticBezier_evaluate(*subMatrix[2][0], *subMatrix[2][1], *subMatrix[2][2], tU, pointX[2], leftX[2], - rightX[2]); - - ArbitraryMeshVertex *p = vertices + i * strideX; - for (std::size_t j = 0; j != height; ++j) { - if ((j == 0 || j + 1 == height) && (i == 0 || i + 1 == width)) { - } else { - double tV = (j + 1 == height) ? 1 : j * incrementV; - - PatchControl pointY[3]; - PatchControl leftY[3]; - PatchControl rightY[3]; - QuadraticBezier_evaluate(*subMatrix[0][0], *subMatrix[1][0], *subMatrix[2][0], tV, pointY[0], leftY[0], - rightY[0]); - QuadraticBezier_evaluate(*subMatrix[0][1], *subMatrix[1][1], *subMatrix[2][1], tV, pointY[1], leftY[1], - rightY[1]); - QuadraticBezier_evaluate(*subMatrix[0][2], *subMatrix[1][2], *subMatrix[2][2], tV, pointY[2], leftY[2], - rightY[2]); - - PatchControl point; - PatchControl left; - PatchControl right; - QuadraticBezier_evaluate(pointX[0], pointX[1], pointX[2], tV, point, left, right); - PatchControl up; - PatchControl down; - QuadraticBezier_evaluate(pointY[0], pointY[1], pointY[2], tU, point, up, down); - - vertex3f_to_vector3(p->vertex) = point.m_vertex; - texcoord2f_to_vector2(p->texcoord) = point.m_texcoord; - colour4f_to_vector4(p->colour) = point.m_color; - - ArbitraryMeshVertex a, b, c; - - a.vertex = vertex3f_for_vector3(left.m_vertex); - a.texcoord = texcoord2f_for_vector2(left.m_texcoord); - b.vertex = vertex3f_for_vector3(right.m_vertex); - b.texcoord = texcoord2f_for_vector2(right.m_texcoord); - - if (i != 0) { - c.vertex = vertex3f_for_vector3(up.m_vertex); - c.texcoord = texcoord2f_for_vector2(up.m_texcoord); - } else { - c.vertex = vertex3f_for_vector3(down.m_vertex); - c.texcoord = texcoord2f_for_vector2(down.m_texcoord); - } - - Vector3 normal = vector3_normalised( - vector3_cross(right.m_vertex - left.m_vertex, up.m_vertex - down.m_vertex)); - - Vector3 tangent, bitangent; - ArbitraryMeshTriangle_calcTangents(a, b, c, tangent, bitangent); - vector3_normalise(tangent); - vector3_normalise(bitangent); - - if (((nFlagsX & AVERAGE) != 0 && i == 0) || ((nFlagsY & AVERAGE) != 0 && j == 0)) { - normal3f_to_vector3(p->normal) = vector3_normalised( - vector3_added(normal3f_to_vector3(p->normal), normal)); - normal3f_to_vector3(p->tangent) = vector3_normalised( - vector3_added(normal3f_to_vector3(p->tangent), tangent)); - normal3f_to_vector3(p->bitangent) = vector3_normalised( - vector3_added(normal3f_to_vector3(p->bitangent), bitangent)); - } else { - normal3f_to_vector3(p->normal) = normal; - normal3f_to_vector3(p->tangent) = tangent; - normal3f_to_vector3(p->bitangent) = bitangent; - } - } - - p += strideY; - } - } -} - -void Patch::TesselateSubMatrix(const BezierCurveTree *BX, const BezierCurveTree *BY, - std::size_t offStartX, std::size_t offStartY, - std::size_t offEndX, std::size_t offEndY, - std::size_t nFlagsX, std::size_t nFlagsY, - Vector3 &left, Vector3 &mid, Vector3 &right, - Vector2 &texLeft, Vector2 &texMid, Vector2 &texRight, - Vector4 &colLeft, Vector4 &colMid, Vector4 &colRight, - bool bTranspose) -{ - int newFlagsX, newFlagsY; - - Vector3 tmp; - Vector3 vertex_0_0, vertex_0_1, vertex_1_0, vertex_1_1, vertex_2_0, vertex_2_1; - Vector2 texTmp; - Vector2 texcoord_0_0, texcoord_0_1, texcoord_1_0, texcoord_1_1, texcoord_2_0, texcoord_2_1; - Vector4 colTmp, colour_0_0, colour_0_1, colour_1_0, colour_1_1, colour_2_0, colour_2_1; - - { - // texcoords - - BezierInterpolate2(texcoord_for_index(m_tess.m_vertices, offStartX + offStartY), - texcoord_0_0, - texcoord_for_index(m_tess.m_vertices, BX->index + offStartY), - texcoord_0_1, - texcoord_for_index(m_tess.m_vertices, offEndX + offStartY)); - - - BezierInterpolate2(texcoord_for_index(m_tess.m_vertices, offStartX + offEndY), - texcoord_2_0, - texcoord_for_index(m_tess.m_vertices, BX->index + offEndY), - texcoord_2_1, - texcoord_for_index(m_tess.m_vertices, offEndX + offEndY)); - - texTmp = texMid; - - BezierInterpolate2(texLeft, - texcoord_1_0, - texTmp, - texcoord_1_1, - texRight); - - if (!BezierCurveTree_isLeaf(BY)) { - texcoord_for_index(m_tess.m_vertices, BX->index + BY->index) = texTmp; - } - - - if (!BezierCurveTree_isLeaf(BX->left)) { - texcoord_for_index(m_tess.m_vertices, BX->left->index + offStartY) = texcoord_0_0; - texcoord_for_index(m_tess.m_vertices, BX->left->index + offEndY) = texcoord_2_0; - - if (!BezierCurveTree_isLeaf(BY)) { - texcoord_for_index(m_tess.m_vertices, BX->left->index + BY->index) = texcoord_1_0; - } - } - if (!BezierCurveTree_isLeaf(BX->right)) { - texcoord_for_index(m_tess.m_vertices, BX->right->index + offStartY) = texcoord_0_1; - texcoord_for_index(m_tess.m_vertices, BX->right->index + offEndY) = texcoord_2_1; - - if (!BezierCurveTree_isLeaf(BY)) { - texcoord_for_index(m_tess.m_vertices, BX->right->index + BY->index) = texcoord_1_1; - } - } - - - // colours - - BezierInterpolate4(colour_for_index(m_tess.m_vertices, offStartX + offStartY), - colour_0_0, - colour_for_index(m_tess.m_vertices, BX->index + offStartY), - colour_0_1, - colour_for_index(m_tess.m_vertices, offEndX + offStartY)); - - - BezierInterpolate4(colour_for_index(m_tess.m_vertices, offStartX + offEndY), - colour_2_0, - colour_for_index(m_tess.m_vertices, BX->index + offEndY), - colour_2_1, - colour_for_index(m_tess.m_vertices, offEndX + offEndY)); - - colTmp = colMid; - - BezierInterpolate4(colLeft, - colour_1_0, - colTmp, - colour_1_1, - colRight); - - if (!BezierCurveTree_isLeaf(BY)) { - colour_for_index(m_tess.m_vertices, BX->index + BY->index) = colTmp; - } - - - if (!BezierCurveTree_isLeaf(BX->left)) { - colour_for_index(m_tess.m_vertices, BX->left->index + offStartY) = colour_0_0; - colour_for_index(m_tess.m_vertices, BX->left->index + offEndY) = colour_2_0; - - if (!BezierCurveTree_isLeaf(BY)) { - colour_for_index(m_tess.m_vertices, BX->left->index + BY->index) = colour_1_0; - } - } - if (!BezierCurveTree_isLeaf(BX->right)) { - colour_for_index(m_tess.m_vertices, BX->right->index + offStartY) = colour_0_1; - colour_for_index(m_tess.m_vertices, BX->right->index + offEndY) = colour_2_1; - - if (!BezierCurveTree_isLeaf(BY)) { - colour_for_index(m_tess.m_vertices, BX->right->index + BY->index) = colour_1_1; - } - } - - - // verts - - BezierInterpolate3(vertex_for_index(m_tess.m_vertices, offStartX + offStartY), - vertex_0_0, - vertex_for_index(m_tess.m_vertices, BX->index + offStartY), - vertex_0_1, - vertex_for_index(m_tess.m_vertices, offEndX + offStartY)); - - - BezierInterpolate3(vertex_for_index(m_tess.m_vertices, offStartX + offEndY), - vertex_2_0, - vertex_for_index(m_tess.m_vertices, BX->index + offEndY), - vertex_2_1, - vertex_for_index(m_tess.m_vertices, offEndX + offEndY)); - - - tmp = mid; - - BezierInterpolate3(left, - vertex_1_0, - tmp, - vertex_1_1, - right); - - if (!BezierCurveTree_isLeaf(BY)) { - vertex_for_index(m_tess.m_vertices, BX->index + BY->index) = tmp; - } - - - if (!BezierCurveTree_isLeaf(BX->left)) { - vertex_for_index(m_tess.m_vertices, BX->left->index + offStartY) = vertex_0_0; - vertex_for_index(m_tess.m_vertices, BX->left->index + offEndY) = vertex_2_0; - - if (!BezierCurveTree_isLeaf(BY)) { - vertex_for_index(m_tess.m_vertices, BX->left->index + BY->index) = vertex_1_0; - } - } - if (!BezierCurveTree_isLeaf(BX->right)) { - vertex_for_index(m_tess.m_vertices, BX->right->index + offStartY) = vertex_0_1; - vertex_for_index(m_tess.m_vertices, BX->right->index + offEndY) = vertex_2_1; - - if (!BezierCurveTree_isLeaf(BY)) { - vertex_for_index(m_tess.m_vertices, BX->right->index + BY->index) = vertex_1_1; - } - } - - // normals - - if (nFlagsX & SPLIT) { - ArbitraryMeshVertex a, b, c; - Vector3 tangentU; - - if (!(nFlagsX & DEGEN_0a) || !(nFlagsX & DEGEN_0b)) { - tangentU = vector3_subtracted(vertex_0_1, vertex_0_0); - a.vertex = vertex3f_for_vector3(vertex_0_0); - a.texcoord = texcoord2f_for_vector2(texcoord_0_0); - c.vertex = vertex3f_for_vector3(vertex_0_1); - c.texcoord = texcoord2f_for_vector2(texcoord_0_1); - } else if (!(nFlagsX & DEGEN_1a) || !(nFlagsX & DEGEN_1b)) { - tangentU = vector3_subtracted(vertex_1_1, vertex_1_0); - a.vertex = vertex3f_for_vector3(vertex_1_0); - a.texcoord = texcoord2f_for_vector2(texcoord_1_0); - c.vertex = vertex3f_for_vector3(vertex_1_1); - c.texcoord = texcoord2f_for_vector2(texcoord_1_1); - } else { - tangentU = vector3_subtracted(vertex_2_1, vertex_2_0); - a.vertex = vertex3f_for_vector3(vertex_2_0); - a.texcoord = texcoord2f_for_vector2(texcoord_2_0); - c.vertex = vertex3f_for_vector3(vertex_2_1); - c.texcoord = texcoord2f_for_vector2(texcoord_2_1); - } - - Vector3 tangentV; - - if ((nFlagsY & DEGEN_0a) && (nFlagsY & DEGEN_1a) && (nFlagsY & DEGEN_2a)) { - tangentV = vector3_subtracted(vertex_for_index(m_tess.m_vertices, BX->index + offEndY), tmp); - b.vertex = vertex3f_for_vector3(tmp); //m_tess.m_vertices[BX->index + offEndY].vertex; - b.texcoord = texcoord2f_for_vector2(texTmp); //m_tess.m_vertices[BX->index + offEndY].texcoord; - } else { - tangentV = vector3_subtracted(tmp, vertex_for_index(m_tess.m_vertices, BX->index + offStartY)); - b.vertex = vertex3f_for_vector3(tmp); //m_tess.m_vertices[BX->index + offStartY].vertex; - b.texcoord = texcoord2f_for_vector2(texTmp); //m_tess.m_vertices[BX->index + offStartY].texcoord; - } - - - Vector3 normal, s, t; - ArbitraryMeshVertex &v = m_tess.m_vertices[offStartY + BX->index]; - Vector3 &p = normal3f_to_vector3(v.normal); - Vector3 &ps = normal3f_to_vector3(v.tangent); - Vector3 &pt = normal3f_to_vector3(v.bitangent); - - if (bTranspose) { - normal = vector3_cross(tangentV, tangentU); - } else { - normal = vector3_cross(tangentU, tangentV); - } - normalise_safe(normal); - - ArbitraryMeshTriangle_calcTangents(a, b, c, s, t); - normalise_safe(s); - normalise_safe(t); - - if (nFlagsX & AVERAGE) { - p = vector3_normalised(vector3_added(p, normal)); - ps = vector3_normalised(vector3_added(ps, s)); - pt = vector3_normalised(vector3_added(pt, t)); - } else { - p = normal; - ps = s; - pt = t; - } - } - - { - ArbitraryMeshVertex a, b, c; - Vector3 tangentU; - - if (!(nFlagsX & DEGEN_2a) || !(nFlagsX & DEGEN_2b)) { - tangentU = vector3_subtracted(vertex_2_1, vertex_2_0); - a.vertex = vertex3f_for_vector3(vertex_2_0); - a.texcoord = texcoord2f_for_vector2(texcoord_2_0); - c.vertex = vertex3f_for_vector3(vertex_2_1); - c.texcoord = texcoord2f_for_vector2(texcoord_2_1); - } else if (!(nFlagsX & DEGEN_1a) || !(nFlagsX & DEGEN_1b)) { - tangentU = vector3_subtracted(vertex_1_1, vertex_1_0); - a.vertex = vertex3f_for_vector3(vertex_1_0); - a.texcoord = texcoord2f_for_vector2(texcoord_1_0); - c.vertex = vertex3f_for_vector3(vertex_1_1); - c.texcoord = texcoord2f_for_vector2(texcoord_1_1); - } else { - tangentU = vector3_subtracted(vertex_0_1, vertex_0_0); - a.vertex = vertex3f_for_vector3(vertex_0_0); - a.texcoord = texcoord2f_for_vector2(texcoord_0_0); - c.vertex = vertex3f_for_vector3(vertex_0_1); - c.texcoord = texcoord2f_for_vector2(texcoord_0_1); - } - - Vector3 tangentV; - - if ((nFlagsY & DEGEN_0b) && (nFlagsY & DEGEN_1b) && (nFlagsY & DEGEN_2b)) { - tangentV = vector3_subtracted(tmp, vertex_for_index(m_tess.m_vertices, BX->index + offStartY)); - b.vertex = vertex3f_for_vector3(tmp); //m_tess.m_vertices[BX->index + offStartY].vertex; - b.texcoord = texcoord2f_for_vector2(texTmp); //m_tess.m_vertices[BX->index + offStartY].texcoord; - } else { - tangentV = vector3_subtracted(vertex_for_index(m_tess.m_vertices, BX->index + offEndY), tmp); - b.vertex = vertex3f_for_vector3(tmp); //m_tess.m_vertices[BX->index + offEndY].vertex; - b.texcoord = texcoord2f_for_vector2(texTmp); //m_tess.m_vertices[BX->index + offEndY].texcoord; - } - - ArbitraryMeshVertex &v = m_tess.m_vertices[offEndY + BX->index]; - Vector3 &p = normal3f_to_vector3(v.normal); - Vector3 &ps = normal3f_to_vector3(v.tangent); - Vector3 &pt = normal3f_to_vector3(v.bitangent); - - if (bTranspose) { - p = vector3_cross(tangentV, tangentU); - } else { - p = vector3_cross(tangentU, tangentV); - } - normalise_safe(p); - - ArbitraryMeshTriangle_calcTangents(a, b, c, ps, pt); - normalise_safe(ps); - normalise_safe(pt); - } - } - - - newFlagsX = newFlagsY = 0; - - if ((nFlagsX & DEGEN_0a) && (nFlagsX & DEGEN_0b)) { - newFlagsX |= DEGEN_0a; - newFlagsX |= DEGEN_0b; - } - if ((nFlagsX & DEGEN_1a) && (nFlagsX & DEGEN_1b)) { - newFlagsX |= DEGEN_1a; - newFlagsX |= DEGEN_1b; - } - if ((nFlagsX & DEGEN_2a) && (nFlagsX & DEGEN_2b)) { - newFlagsX |= DEGEN_2a; - newFlagsX |= DEGEN_2b; - } - if ((nFlagsY & DEGEN_0a) && (nFlagsY & DEGEN_1a) && (nFlagsY & DEGEN_2a)) { - newFlagsY |= DEGEN_0a; - newFlagsY |= DEGEN_1a; - newFlagsY |= DEGEN_2a; - } - if ((nFlagsY & DEGEN_0b) && (nFlagsY & DEGEN_1b) && (nFlagsY & DEGEN_2b)) { - newFlagsY |= DEGEN_0b; - newFlagsY |= DEGEN_1b; - newFlagsY |= DEGEN_2b; - } - - - //if((nFlagsX & DEGEN_0a) && (nFlagsX & DEGEN_1a) && (nFlagsX & DEGEN_2a)) { newFlagsX |= DEGEN_0a; newFlagsX |= DEGEN_1a; newFlagsX |= DEGEN_2a; } - //if((nFlagsX & DEGEN_0b) && (nFlagsX & DEGEN_1b) && (nFlagsX & DEGEN_2b)) { newFlagsX |= DEGEN_0b; newFlagsX |= DEGEN_1b; newFlagsX |= DEGEN_2b; } - - newFlagsX |= (nFlagsX & SPLIT); - newFlagsX |= (nFlagsX & AVERAGE); - - if (!BezierCurveTree_isLeaf(BY)) { - { - int nTemp = newFlagsY; - - if ((nFlagsY & DEGEN_0a) && (nFlagsY & DEGEN_0b)) { - newFlagsY |= DEGEN_0a; - newFlagsY |= DEGEN_0b; - } - newFlagsY |= (nFlagsY & SPLIT); - newFlagsY |= (nFlagsY & AVERAGE); - - Vector3 &p = vertex_for_index(m_tess.m_vertices, BX->index + BY->index); - Vector3 vTemp(p); - - Vector2 &p2 = texcoord_for_index(m_tess.m_vertices, BX->index + BY->index); - Vector2 stTemp(p2); - - TesselateSubMatrix(BY, BX->left, - offStartY, offStartX, - offEndY, BX->index, - newFlagsY, newFlagsX, - vertex_0_0, vertex_1_0, vertex_2_0, - texcoord_0_0, texcoord_1_0, texcoord_2_0, - colour_0_0, colour_1_0, colour_2_0, - !bTranspose); - - newFlagsY = nTemp; - p = vTemp; - p2 = stTemp; - } - - if ((nFlagsY & DEGEN_2a) && (nFlagsY & DEGEN_2b)) { - newFlagsY |= DEGEN_2a; - newFlagsY |= DEGEN_2b; - } - - TesselateSubMatrix(BY, BX->right, - offStartY, BX->index, - offEndY, offEndX, - newFlagsY, newFlagsX, - vertex_0_1, vertex_1_1, vertex_2_1, - texcoord_0_1, texcoord_1_1, texcoord_2_1, - colour_0_1, colour_1_1, colour_2_1, - !bTranspose); - } else { - if (!BezierCurveTree_isLeaf(BX->left)) { - TesselateSubMatrix(BX->left, BY, - offStartX, offStartY, - BX->index, offEndY, - newFlagsX, newFlagsY, - left, vertex_1_0, tmp, - texLeft, texcoord_1_0, texTmp, - colLeft, colour_1_0, colTmp, - bTranspose); - } - - if (!BezierCurveTree_isLeaf(BX->right)) { - TesselateSubMatrix(BX->right, BY, - BX->index, offStartY, - offEndX, offEndY, - newFlagsX, newFlagsY, - tmp, vertex_1_1, right, - texTmp, texcoord_1_1, texRight, - colTmp, colour_1_1, colRight, - bTranspose); - } - } - -} - -void Patch::BuildTesselationCurves(EMatrixMajor major) -{ - std::size_t nArrayStride, length, cross, strideU, strideV; - switch (major) { - case ROW: - nArrayStride = 1; - length = (m_width - 1) >> 1; - cross = m_height; - strideU = 1; - strideV = m_width; - - if (!m_patchDef3) { - BezierCurveTreeArray_deleteAll(m_tess.m_curveTreeU); - } - - break; - case COL: - nArrayStride = m_tess.m_nArrayWidth; - length = (m_height - 1) >> 1; - cross = m_width; - strideU = m_width; - strideV = 1; - - if (!m_patchDef3) { - BezierCurveTreeArray_deleteAll(m_tess.m_curveTreeV); - } - - break; - default: - ERROR_MESSAGE("neither row-major nor column-major"); - return; - } - - Array arrayLength(length); - Array pCurveTree(length); - - std::size_t nArrayLength = 1; - - if (m_patchDef3) { - if (!m_subdivisions_x && !m_subdivisions_y) { - for (Array::iterator i = arrayLength.begin(); i != arrayLength.end(); ++i) { - *i = 2; - nArrayLength += *i; - } - } else { - for (Array::iterator i = arrayLength.begin(); i != arrayLength.end(); ++i) { - *i = Array::value_type((major == ROW) ? m_subdivisions_x : m_subdivisions_y); - nArrayLength += *i; - } - } - } else { - // create a list of the horizontal control curves in each column of sub-patches - // adaptively tesselate each horizontal control curve in the list - // create a binary tree representing the combined tesselation of the list - for (std::size_t i = 0; i != length; ++i) { - PatchControl *p1 = m_ctrlTransformed.data() + (i * 2 * strideU); - GSList *pCurveList = 0; - for (std::size_t j = 0; j < cross; j += 2) { - PatchControl *p2 = p1 + strideV; - PatchControl *p3 = p2 + strideV; - - // directly taken from one row of control points - { - BezierCurve *pCurve = new BezierCurve; - pCurve->crd = (p1 + strideU)->m_vertex; - pCurve->left = p1->m_vertex; - pCurve->right = (p1 + (strideU << 1))->m_vertex; - pCurveList = g_slist_prepend(pCurveList, pCurve); - } - - if (j + 2 >= cross) { - break; - } - - // interpolated from three columns of control points - { - BezierCurve *pCurve = new BezierCurve; - pCurve->crd = vector3_mid((p1 + strideU)->m_vertex, (p3 + strideU)->m_vertex); - pCurve->left = vector3_mid(p1->m_vertex, p3->m_vertex); - pCurve->right = vector3_mid((p1 + (strideU << 1))->m_vertex, (p3 + (strideU << 1))->m_vertex); - - pCurve->crd = vector3_mid(pCurve->crd, (p2 + strideU)->m_vertex); - pCurve->left = vector3_mid(pCurve->left, p2->m_vertex); - pCurve->right = vector3_mid(pCurve->right, (p2 + (strideU << 1))->m_vertex); - pCurveList = g_slist_prepend(pCurveList, pCurve); - } - - p1 = p3; - } - - pCurveTree[i] = new BezierCurveTree; - BezierCurveTree_FromCurveList(pCurveTree[i], pCurveList); - for (GSList *l = pCurveList; l != 0; l = g_slist_next(l)) { - delete static_cast((*l).data ); - } - g_slist_free(pCurveList); - - // set up array indices for binary tree - // accumulate subarray width - arrayLength[i] = Array::value_type( - BezierCurveTree_Setup(pCurveTree[i], nArrayLength, nArrayStride) - (nArrayLength - 1)); - // accumulate total array width - nArrayLength += arrayLength[i]; - } - } - - switch (major) { - case ROW: - m_tess.m_nArrayWidth = nArrayLength; - std::swap(m_tess.m_arrayWidth, arrayLength); - - if (!m_patchDef3) { - std::swap(m_tess.m_curveTreeU, pCurveTree); - } - break; - case COL: - m_tess.m_nArrayHeight = nArrayLength; - std::swap(m_tess.m_arrayHeight, arrayLength); - - if (!m_patchDef3) { - std::swap(m_tess.m_curveTreeV, pCurveTree); - } - break; - } -} - -inline void vertex_assign_ctrl(ArbitraryMeshVertex &vertex, const PatchControl &ctrl) -{ - vertex.vertex = vertex3f_for_vector3(ctrl.m_vertex); - vertex.texcoord = texcoord2f_for_vector2(ctrl.m_texcoord); -} - -inline void vertex_clear_normal(ArbitraryMeshVertex &vertex) -{ - vertex.normal = Normal3f(0, 0, 0); - vertex.tangent = Normal3f(0, 0, 0); - vertex.bitangent = Normal3f(0, 0, 0); -} - -inline void tangents_remove_degenerate(Vector3 tangents[6], Vector2 textureTangents[6], unsigned int flags) -{ - if (flags & DEGEN_0a) { - const std::size_t i = - (flags & DEGEN_0b) - ? (flags & DEGEN_1a) - ? (flags & DEGEN_1b) - ? (flags & DEGEN_2a) - ? 5 - : 4 - : 3 - : 2 - : 1; - tangents[0] = tangents[i]; - textureTangents[0] = textureTangents[i]; - } - if (flags & DEGEN_0b) { - const std::size_t i = - (flags & DEGEN_0a) - ? (flags & DEGEN_1b) - ? (flags & DEGEN_1a) - ? (flags & DEGEN_2b) - ? 4 - : 5 - : 2 - : 3 - : 0; - tangents[1] = tangents[i]; - textureTangents[1] = textureTangents[i]; - } - if (flags & DEGEN_2a) { - const std::size_t i = - (flags & DEGEN_2b) - ? (flags & DEGEN_1a) - ? (flags & DEGEN_1b) - ? (flags & DEGEN_0a) - ? 1 - : 0 - : 3 - : 2 - : 5; - tangents[4] = tangents[i]; - textureTangents[4] = textureTangents[i]; - } - if (flags & DEGEN_2b) { - const std::size_t i = - (flags & DEGEN_2a) - ? (flags & DEGEN_1b) - ? (flags & DEGEN_1a) - ? (flags & DEGEN_0b) - ? 0 - : 1 - : 2 - : 3 - : 4; - tangents[5] = tangents[i]; - textureTangents[5] = textureTangents[i]; - } -} - -void bestTangents00(unsigned int degenerateFlags, double dot, double length, std::size_t &index0, std::size_t &index1) -{ - if (fabs(dot + length) < 0.001) { // opposing direction = degenerate - if (!(degenerateFlags & DEGEN_1a)) { // if this tangent is degenerate we cannot use it - index0 = 2; - index1 = 0; - } else if (!(degenerateFlags & DEGEN_0b)) { - index0 = 0; - index1 = 1; - } else { - index0 = 1; - index1 = 0; - } - } else if (fabs(dot - length) < 0.001) { // same direction = degenerate - if (degenerateFlags & DEGEN_0b) { - index0 = 0; - index1 = 1; - } else { - index0 = 1; - index1 = 0; - } - } -} - -void bestTangents01(unsigned int degenerateFlags, double dot, double length, std::size_t &index0, std::size_t &index1) -{ - if (fabs(dot - length) < 0.001) { // same direction = degenerate - if (!(degenerateFlags & DEGEN_1a)) { // if this tangent is degenerate we cannot use it - index0 = 2; - index1 = 1; - } else if (!(degenerateFlags & DEGEN_2b)) { - index0 = 4; - index1 = 0; - } else { - index0 = 5; - index1 = 1; - } - } else if (fabs(dot + length) < 0.001) { // opposing direction = degenerate - if (degenerateFlags & DEGEN_2b) { - index0 = 4; - index1 = 0; - } else { - index0 = 5; - index1 = 1; - } - } -} - -void bestTangents10(unsigned int degenerateFlags, double dot, double length, std::size_t &index0, std::size_t &index1) -{ - if (fabs(dot - length) < 0.001) { // same direction = degenerate - if (!(degenerateFlags & DEGEN_1b)) { // if this tangent is degenerate we cannot use it - index0 = 3; - index1 = 4; - } else if (!(degenerateFlags & DEGEN_0a)) { - index0 = 1; - index1 = 5; - } else { - index0 = 0; - index1 = 4; - } - } else if (fabs(dot + length) < 0.001) { // opposing direction = degenerate - if (degenerateFlags & DEGEN_0a) { - index0 = 1; - index1 = 5; - } else { - index0 = 0; - index1 = 4; - } - } -} - -void bestTangents11(unsigned int degenerateFlags, double dot, double length, std::size_t &index0, std::size_t &index1) -{ - if (fabs(dot + length) < 0.001) { // opposing direction = degenerate - if (!(degenerateFlags & DEGEN_1b)) { // if this tangent is degenerate we cannot use it - index0 = 3; - index1 = 5; - } else if (!(degenerateFlags & DEGEN_2a)) { - index0 = 5; - index1 = 4; - } else { - index0 = 4; - index1 = 5; - } - } else if (fabs(dot - length) < 0.001) { // same direction = degenerate - if (degenerateFlags & DEGEN_2a) { - index0 = 5; - index1 = 4; - } else { - index0 = 4; - index1 = 5; - } - } -} - -void -Patch::accumulateVertexTangentSpace(std::size_t index, Vector3 tangentX[6], Vector3 tangentY[6], Vector2 tangentS[6], - Vector2 tangentT[6], std::size_t index0, std::size_t index1) -{ - { - Vector3 normal(vector3_cross(tangentX[index0], tangentY[index1])); - if (!vector3_equal(normal, g_vector3_identity)) { - vector3_add(normal_for_index(m_tess.m_vertices, index), vector3_normalised(normal)); - } - } - - { - ArbitraryMeshVertex a, b, c; - a.vertex = Vertex3f(0, 0, 0); - a.texcoord = TexCoord2f(0, 0); - b.vertex = vertex3f_for_vector3(tangentX[index0]); - b.texcoord = texcoord2f_for_vector2(tangentS[index0]); - c.vertex = vertex3f_for_vector3(tangentY[index1]); - c.texcoord = texcoord2f_for_vector2(tangentT[index1]); - - Vector3 s, t; - ArbitraryMeshTriangle_calcTangents(a, b, c, s, t); - if (!vector3_equal(s, g_vector3_identity)) { - vector3_add(tangent_for_index(m_tess.m_vertices, index), vector3_normalised(s)); - } - if (!vector3_equal(t, g_vector3_identity)) { - vector3_add(bitangent_for_index(m_tess.m_vertices, index), vector3_normalised(t)); - } - } -} - -const std::size_t PATCH_MAX_VERTEX_ARRAY = 1048576; - -void Patch::BuildVertexArray() -{ - const std::size_t strideU = 1; - const std::size_t strideV = m_width; - - const std::size_t numElems = - m_tess.m_nArrayWidth * m_tess.m_nArrayHeight; // total number of elements in vertex array - - const bool bWidthStrips = (m_tess.m_nArrayWidth >= - m_tess.m_nArrayHeight); // decide if horizontal strips are longer than vertical - - - // allocate vertex, normal, texcoord and primitive-index arrays - m_tess.m_vertices.resize(numElems); - m_tess.m_indices.resize(m_tess.m_nArrayWidth * 2 * (m_tess.m_nArrayHeight - 1)); - - // set up strip indices - if (bWidthStrips) { - m_tess.m_numStrips = m_tess.m_nArrayHeight - 1; - m_tess.m_lenStrips = m_tess.m_nArrayWidth * 2; - - for (std::size_t i = 0; i < m_tess.m_nArrayWidth; i++) { - for (std::size_t j = 0; j < m_tess.m_numStrips; j++) { - m_tess.m_indices[(j * m_tess.m_lenStrips) + i * 2] = RenderIndex(j * m_tess.m_nArrayWidth + i); - m_tess.m_indices[(j * m_tess.m_lenStrips) + i * 2 + 1] = RenderIndex( - (j + 1) * m_tess.m_nArrayWidth + i); - // reverse because radiant uses CULL_FRONT - //m_tess.m_indices[(j*m_tess.m_lenStrips)+i*2+1] = RenderIndex(j*m_tess.m_nArrayWidth+i); - //m_tess.m_indices[(j*m_tess.m_lenStrips)+i*2] = RenderIndex((j+1)*m_tess.m_nArrayWidth+i); - } - } - } else { - m_tess.m_numStrips = m_tess.m_nArrayWidth - 1; - m_tess.m_lenStrips = m_tess.m_nArrayHeight * 2; - - for (std::size_t i = 0; i < m_tess.m_nArrayHeight; i++) { - for (std::size_t j = 0; j < m_tess.m_numStrips; j++) { - m_tess.m_indices[(j * m_tess.m_lenStrips) + i * 2] = RenderIndex( - ((m_tess.m_nArrayHeight - 1) - i) * m_tess.m_nArrayWidth + j); - m_tess.m_indices[(j * m_tess.m_lenStrips) + i * 2 + 1] = RenderIndex( - ((m_tess.m_nArrayHeight - 1) - i) * m_tess.m_nArrayWidth + j + 1); - // reverse because radiant uses CULL_FRONT - //m_tess.m_indices[(j*m_tess.m_lenStrips)+i*2+1] = RenderIndex(((m_tess.m_nArrayHeight-1)-i)*m_tess.m_nArrayWidth+j); - //m_tess.m_indices[(j*m_tess.m_lenStrips)+i*2] = RenderIndex(((m_tess.m_nArrayHeight-1)-i)*m_tess.m_nArrayWidth+j+1); - - } - } - } - - if (m_patchDef3 && !m_subdivisions_x && !m_subdivisions_y) - { - for (std::size_t i = 0; i < m_width*m_height; i++) - { - ArbitraryMeshVertex &p = m_tess.m_vertices[i]; - PatchControl &cp = m_ctrlTransformed[i]; - p.vertex = vertex3f_for_vector3(cp.m_vertex); - p.texcoord = texcoord2f_for_vector2(cp.m_texcoord); - p.colour = colour4f_for_vector4(cp.m_color); - } - } - else - { - PatchControlIter pCtrl = m_ctrlTransformed.data(); - for (std::size_t j = 0, offStartY = 0; j + 1 < m_height; j += 2, pCtrl += (strideU + strideV)) { - // set up array offsets for this sub-patch - const bool leafY = (m_patchDef3) ? false : BezierCurveTree_isLeaf(m_tess.m_curveTreeV[j >> 1]); - const std::size_t offMidY = (m_patchDef3) ? 0 : m_tess.m_curveTreeV[j >> 1]->index; - const std::size_t widthY = m_tess.m_arrayHeight[j >> 1] * m_tess.m_nArrayWidth; - const std::size_t offEndY = offStartY + widthY; - - for (std::size_t i = 0, offStartX = 0; i + 1 < m_width; i += 2, pCtrl += (strideU << 1)) { - const bool leafX = (m_patchDef3) ? false : BezierCurveTree_isLeaf(m_tess.m_curveTreeU[i >> 1]); - const std::size_t offMidX = (m_patchDef3) ? 0 : m_tess.m_curveTreeU[i >> 1]->index; - const std::size_t widthX = m_tess.m_arrayWidth[i >> 1]; - const std::size_t offEndX = offStartX + widthX; - - PatchControl *subMatrix[3][3]; - subMatrix[0][0] = pCtrl; - subMatrix[0][1] = subMatrix[0][0] + strideU; - subMatrix[0][2] = subMatrix[0][1] + strideU; - subMatrix[1][0] = subMatrix[0][0] + strideV; - subMatrix[1][1] = subMatrix[1][0] + strideU; - subMatrix[1][2] = subMatrix[1][1] + strideU; - subMatrix[2][0] = subMatrix[1][0] + strideV; - subMatrix[2][1] = subMatrix[2][0] + strideU; - subMatrix[2][2] = subMatrix[2][1] + strideU; - - // assign on-patch control points to vertex array - if (i == 0 && j == 0) { - vertex_clear_normal(m_tess.m_vertices[offStartX + offStartY]); - } - vertex_assign_ctrl(m_tess.m_vertices[offStartX + offStartY], *subMatrix[0][0]); - if (j == 0) { - vertex_clear_normal(m_tess.m_vertices[offEndX + offStartY]); - } - vertex_assign_ctrl(m_tess.m_vertices[offEndX + offStartY], *subMatrix[0][2]); - if (i == 0) { - vertex_clear_normal(m_tess.m_vertices[offStartX + offEndY]); - } - vertex_assign_ctrl(m_tess.m_vertices[offStartX + offEndY], *subMatrix[2][0]); - - vertex_clear_normal(m_tess.m_vertices[offEndX + offEndY]); - vertex_assign_ctrl(m_tess.m_vertices[offEndX + offEndY], *subMatrix[2][2]); - - if (!m_patchDef3) { - // assign remaining control points to vertex array - if (!leafX) { - vertex_assign_ctrl(m_tess.m_vertices[offMidX + offStartY], *subMatrix[0][1]); - vertex_assign_ctrl(m_tess.m_vertices[offMidX + offEndY], *subMatrix[2][1]); - } - if (!leafY) { - vertex_assign_ctrl(m_tess.m_vertices[offStartX + offMidY], *subMatrix[1][0]); - vertex_assign_ctrl(m_tess.m_vertices[offEndX + offMidY], *subMatrix[1][2]); - - if (!leafX) { - vertex_assign_ctrl(m_tess.m_vertices[offMidX + offMidY], *subMatrix[1][1]); - } - } - } - - // test all 12 edges for degeneracy - unsigned int nFlagsX = subarray_get_degen(pCtrl, strideU, strideV); - unsigned int nFlagsY = subarray_get_degen(pCtrl, strideV, strideU); - Vector3 tangentX[6], tangentY[6]; - Vector2 tangentS[6], tangentT[6]; - - // set up tangents for each of the 12 edges if they were not degenerate - if (!(nFlagsX & DEGEN_0a)) { - tangentX[0] = vector3_subtracted(subMatrix[0][1]->m_vertex, subMatrix[0][0]->m_vertex); - tangentS[0] = vector2_subtracted(subMatrix[0][1]->m_texcoord, subMatrix[0][0]->m_texcoord); - } - if (!(nFlagsX & DEGEN_0b)) { - tangentX[1] = vector3_subtracted(subMatrix[0][2]->m_vertex, subMatrix[0][1]->m_vertex); - tangentS[1] = vector2_subtracted(subMatrix[0][2]->m_texcoord, subMatrix[0][1]->m_texcoord); - } - if (!(nFlagsX & DEGEN_1a)) { - tangentX[2] = vector3_subtracted(subMatrix[1][1]->m_vertex, subMatrix[1][0]->m_vertex); - tangentS[2] = vector2_subtracted(subMatrix[1][1]->m_texcoord, subMatrix[1][0]->m_texcoord); - } - if (!(nFlagsX & DEGEN_1b)) { - tangentX[3] = vector3_subtracted(subMatrix[1][2]->m_vertex, subMatrix[1][1]->m_vertex); - tangentS[3] = vector2_subtracted(subMatrix[1][2]->m_texcoord, subMatrix[1][1]->m_texcoord); - } - if (!(nFlagsX & DEGEN_2a)) { - tangentX[4] = vector3_subtracted(subMatrix[2][1]->m_vertex, subMatrix[2][0]->m_vertex); - tangentS[4] = vector2_subtracted(subMatrix[2][1]->m_texcoord, subMatrix[2][0]->m_texcoord); - } - if (!(nFlagsX & DEGEN_2b)) { - tangentX[5] = vector3_subtracted(subMatrix[2][2]->m_vertex, subMatrix[2][1]->m_vertex); - tangentS[5] = vector2_subtracted(subMatrix[2][2]->m_texcoord, subMatrix[2][1]->m_texcoord); - } - - if (!(nFlagsY & DEGEN_0a)) { - tangentY[0] = vector3_subtracted(subMatrix[1][0]->m_vertex, subMatrix[0][0]->m_vertex); - tangentT[0] = vector2_subtracted(subMatrix[1][0]->m_texcoord, subMatrix[0][0]->m_texcoord); - } - if (!(nFlagsY & DEGEN_0b)) { - tangentY[1] = vector3_subtracted(subMatrix[2][0]->m_vertex, subMatrix[1][0]->m_vertex); - tangentT[1] = vector2_subtracted(subMatrix[2][0]->m_texcoord, subMatrix[1][0]->m_texcoord); - } - if (!(nFlagsY & DEGEN_1a)) { - tangentY[2] = vector3_subtracted(subMatrix[1][1]->m_vertex, subMatrix[0][1]->m_vertex); - tangentT[2] = vector2_subtracted(subMatrix[1][1]->m_texcoord, subMatrix[0][1]->m_texcoord); - } - if (!(nFlagsY & DEGEN_1b)) { - tangentY[3] = vector3_subtracted(subMatrix[2][1]->m_vertex, subMatrix[1][1]->m_vertex); - tangentT[3] = vector2_subtracted(subMatrix[2][1]->m_texcoord, subMatrix[1][1]->m_texcoord); - } - if (!(nFlagsY & DEGEN_2a)) { - tangentY[4] = vector3_subtracted(subMatrix[1][2]->m_vertex, subMatrix[0][2]->m_vertex); - tangentT[4] = vector2_subtracted(subMatrix[1][2]->m_texcoord, subMatrix[0][2]->m_texcoord); - } - if (!(nFlagsY & DEGEN_2b)) { - tangentY[5] = vector3_subtracted(subMatrix[2][2]->m_vertex, subMatrix[1][2]->m_vertex); - tangentT[5] = vector2_subtracted(subMatrix[2][2]->m_texcoord, subMatrix[1][2]->m_texcoord); - } - - // set up remaining edge tangents by borrowing the tangent from the closest parallel non-degenerate edge - tangents_remove_degenerate(tangentX, tangentS, nFlagsX); - tangents_remove_degenerate(tangentY, tangentT, nFlagsY); - - { - // x=0, y=0 - std::size_t index = offStartX + offStartY; - std::size_t index0 = 0; - std::size_t index1 = 0; - - double dot = vector3_dot(tangentX[index0], tangentY[index1]); - double length = vector3_length(tangentX[index0]) * vector3_length(tangentY[index1]); - - bestTangents00(nFlagsX, dot, length, index0, index1); - - accumulateVertexTangentSpace(index, tangentX, tangentY, tangentS, tangentT, index0, index1); - } - - { - // x=1, y=0 - std::size_t index = offEndX + offStartY; - std::size_t index0 = 1; - std::size_t index1 = 4; - - double dot = vector3_dot(tangentX[index0], tangentY[index1]); - double length = vector3_length(tangentX[index0]) * vector3_length(tangentY[index1]); - - bestTangents10(nFlagsX, dot, length, index0, index1); - - accumulateVertexTangentSpace(index, tangentX, tangentY, tangentS, tangentT, index0, index1); - } - - { - // x=0, y=1 - std::size_t index = offStartX + offEndY; - std::size_t index0 = 4; - std::size_t index1 = 1; - - double dot = vector3_dot(tangentX[index0], tangentY[index1]); - double length = vector3_length(tangentX[index1]) * vector3_length(tangentY[index1]); - - bestTangents01(nFlagsX, dot, length, index0, index1); - - accumulateVertexTangentSpace(index, tangentX, tangentY, tangentS, tangentT, index0, index1); - } - - { - // x=1, y=1 - std::size_t index = offEndX + offEndY; - std::size_t index0 = 5; - std::size_t index1 = 5; - - double dot = vector3_dot(tangentX[index0], tangentY[index1]); - double length = vector3_length(tangentX[index0]) * vector3_length(tangentY[index1]); - - bestTangents11(nFlagsX, dot, length, index0, index1); - - accumulateVertexTangentSpace(index, tangentX, tangentY, tangentS, tangentT, index0, index1); - } - - //normalise normals that won't be accumulated again - if (i != 0 || j != 0) { - normalise_safe(normal_for_index(m_tess.m_vertices, offStartX + offStartY)); - normalise_safe(tangent_for_index(m_tess.m_vertices, offStartX + offStartY)); - normalise_safe(bitangent_for_index(m_tess.m_vertices, offStartX + offStartY)); - } - if (i + 3 == m_width) { - normalise_safe(normal_for_index(m_tess.m_vertices, offEndX + offStartY)); - normalise_safe(tangent_for_index(m_tess.m_vertices, offEndX + offStartY)); - normalise_safe(bitangent_for_index(m_tess.m_vertices, offEndX + offStartY)); - } - if (j + 3 == m_height) { - normalise_safe(normal_for_index(m_tess.m_vertices, offStartX + offEndY)); - normalise_safe(tangent_for_index(m_tess.m_vertices, offStartX + offEndY)); - normalise_safe(bitangent_for_index(m_tess.m_vertices, offStartX + offEndY)); - } - if (i + 3 == m_width && j + 3 == m_height) { - normalise_safe(normal_for_index(m_tess.m_vertices, offEndX + offEndY)); - normalise_safe(tangent_for_index(m_tess.m_vertices, offEndX + offEndY)); - normalise_safe(bitangent_for_index(m_tess.m_vertices, offEndX + offEndY)); - } - - // set flags to average normals between shared edges - if (j != 0) { - nFlagsX |= AVERAGE; - } - if (i != 0) { - nFlagsY |= AVERAGE; - } - // set flags to save evaluating shared edges twice - nFlagsX |= SPLIT; - nFlagsY |= SPLIT; - - // if the patch is curved.. tesselate recursively - // use the relevant control curves for this sub-patch - if (m_patchDef3) { - TesselateSubMatrixFixed(m_tess.m_vertices.data() + offStartX + offStartY, 1, m_tess.m_nArrayWidth, - nFlagsX, nFlagsY, subMatrix); - } else { - if (!leafX) { - TesselateSubMatrix(m_tess.m_curveTreeU[i >> 1], m_tess.m_curveTreeV[j >> 1], - offStartX, offStartY, offEndX, offEndY, // array offsets - nFlagsX, nFlagsY, - subMatrix[1][0]->m_vertex, subMatrix[1][1]->m_vertex, - subMatrix[1][2]->m_vertex, - subMatrix[1][0]->m_texcoord, subMatrix[1][1]->m_texcoord, - subMatrix[1][2]->m_texcoord, - subMatrix[1][0]->m_color, subMatrix[1][1]->m_color, - subMatrix[1][2]->m_color, - false); - } else if (!leafY) { - TesselateSubMatrix(m_tess.m_curveTreeV[j >> 1], m_tess.m_curveTreeU[i >> 1], - offStartY, offStartX, offEndY, offEndX, // array offsets - nFlagsY, nFlagsX, - subMatrix[0][1]->m_vertex, subMatrix[1][1]->m_vertex, - subMatrix[2][1]->m_vertex, - subMatrix[0][1]->m_texcoord, subMatrix[1][1]->m_texcoord, - subMatrix[2][1]->m_texcoord, - subMatrix[0][1]->m_color, subMatrix[1][1]->m_color, - subMatrix[2][1]->m_color, - true); - } - } - - offStartX = offEndX; - } - offStartY = offEndY; - } - } -} - - -class PatchFilterWrapper : public Filter { -bool m_active; -bool m_invert; -PatchFilter &m_filter; -public: -PatchFilterWrapper(PatchFilter &filter, bool invert) : m_invert(invert), m_filter(filter) -{ -} - -void setActive(bool active) -{ - m_active = active; -} - -bool active() -{ - return m_active; -} - -bool filter(const Patch &patch) -{ - return m_invert ^ m_filter.filter(patch); -} -}; - - -typedef std::list PatchFilters; -PatchFilters g_patchFilters; - -void add_patch_filter(PatchFilter &filter, int mask, bool invert) -{ - g_patchFilters.push_back(PatchFilterWrapper(filter, invert)); - GlobalFilterSystem().addFilter(g_patchFilters.back(), mask); -} - -bool patch_filtered(Patch &patch) -{ - for (PatchFilters::iterator i = g_patchFilters.begin(); i != g_patchFilters.end(); ++i) { - if ((*i).active() && (*i).filter(patch)) { - return true; - } - } - return false; -} diff --git a/src/patch.h b/src/patch.h deleted file mode 100644 index c0e74aa..0000000 --- a/src/patch.h +++ /dev/null @@ -1,2129 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PATCH_H ) -#define INCLUDED_PATCH_H - -/// \file -/// \brief The patch primitive. -/// -/// A 2-dimensional matrix of vertices that define a quadratic bezier surface. -/// The Boundary-Representation of this primitive is a triangle mesh. -/// The surface is recursively tesselated until the angle between each triangle -/// edge is smaller than a specified tolerance. - -#include "globaldefs.h" -#include "nameable.h" -#include "ifilter.h" -#include "imap.h" -#include "ipatch.h" -#include "cullable.h" -#include "renderable.h" -#include "editable.h" -#include "selectable.h" - -#include "debugging/debugging.h" - -#include -#include - -#include "math/frustum.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "stream/textstream.h" -#include "xml/xmlelement.h" -#include "scenelib.h" -#include "transformlib.h" -#include "instancelib.h" -#include "selectionlib.h" -#include "traverselib.h" -#include "render.h" -#include "stringio.h" -#include "shaderlib.h" -#include "generic/callback.h" -#include "signal/signalfwd.h" -#include "texturelib.h" -#include "xml/ixml.h" -#include "dragplanes.h" - -enum EPatchType { - ePatchTypeQuake3, - ePatchTypeDoom3, -}; - -extern int g_PatchSubdivideThreshold; - - -#define MIN_PATCH_WIDTH 3 -#define MIN_PATCH_HEIGHT 3 - -extern std::size_t MAX_PATCH_WIDTH; -extern std::size_t MAX_PATCH_HEIGHT; - -#define MAX_PATCH_ROWCTRL ( ( ( MAX_PATCH_WIDTH - 1 ) - 1 ) / 2 ) -#define MAX_PATCH_COLCTRL ( ( ( MAX_PATCH_HEIGHT - 1 ) - 1 ) / 2 ) - -enum EPatchCap { - eCapBevel, - eCapEndCap, - eCapIBevel, - eCapIEndCap, - eCapCylinder, -}; - -enum EPatchPrefab { - ePlane, - eBevel, - eEndCap, - eCylinder, - eDenseCylinder, - eVeryDenseCylinder, - eSqCylinder, - eCone, - eSphere, - eXactCylinder, - eXactSphere, - eXactCone, -}; - -enum EMatrixMajor { - ROW, COL, -}; - -struct BezierCurve { - Vector3 crd; - Vector3 left; - Vector3 right; -}; - -const std::size_t BEZIERCURVETREE_MAX_INDEX = std::size_t(1) << (std::numeric_limits::digits - 1); - -struct BezierCurveTree { - std::size_t index; - BezierCurveTree *left; - BezierCurveTree *right; -}; - -inline bool BezierCurveTree_isLeaf(const BezierCurveTree *node) -{ - return node->left == 0 && node->right == 0; -} - -void BezierCurveTree_Delete(BezierCurveTree *pCurve); - - -inline VertexPointer vertexpointer_arbitrarymeshvertex(const ArbitraryMeshVertex *array) -{ - return VertexPointer(VertexPointer::pointer(&array->vertex), sizeof(ArbitraryMeshVertex)); -} - -typedef PatchControl *PatchControlIter; -typedef const PatchControl *PatchControlConstIter; - -inline void copy_ctrl(PatchControlIter ctrl, PatchControlConstIter begin, PatchControlConstIter end) -{ - std::copy(begin, end, ctrl); -} - -const Colour4b colour_corner(0, 255, 0, 255); -const Colour4b colour_inside(255, 0, 255, 255); - -class Patch; - -class PatchFilter { -public: -virtual bool filter(const Patch &patch) const = 0; -}; - -bool patch_filtered(Patch &patch); - -void add_patch_filter(PatchFilter &filter, int mask, bool invert = false); - -void Patch_addTextureChangedCallback(const SignalHandler &handler); - -void Patch_textureChanged(); - -inline void BezierCurveTreeArray_deleteAll(Array &curveTrees) -{ - for (Array::iterator i = curveTrees.begin(); i != curveTrees.end(); ++i) { - BezierCurveTree_Delete(*i); - } -} - -inline void PatchControlArray_invert(Array &ctrl, std::size_t width, std::size_t height) -{ - Array tmp(width); - - PatchControlIter from = ctrl.data() + (width * (height - 1)); - PatchControlIter to = ctrl.data(); - for (std::size_t h = 0; h != ((height - 1) >> 1); ++h, to += width, from -= width) { - copy_ctrl(tmp.data(), to, to + width); - copy_ctrl(to, from, from + width); - copy_ctrl(from, tmp.data(), tmp.data() + width); - } -} - -class PatchTesselation { -public: -PatchTesselation() - : m_numStrips(0), m_lenStrips(0), m_nArrayWidth(0), m_nArrayHeight(0) -{ -} - -Array m_vertices; -Array m_indices; -std::size_t m_numStrips; -std::size_t m_lenStrips; - -Array m_arrayWidth; -std::size_t m_nArrayWidth; -Array m_arrayHeight; -std::size_t m_nArrayHeight; - -Array m_curveTreeU; -Array m_curveTreeV; -}; - -class RenderablePatchWireframe : public OpenGLRenderable { -PatchTesselation &m_tess; -public: -RenderablePatchWireframe(PatchTesselation &tess) : m_tess(tess) -{ -} - -void render(RenderStateFlags state) const -{ - { -#if NV_DRIVER_BUG - glVertexPointer(3, GL_FLOAT, 0, 0); - glDrawArrays(GL_TRIANGLE_FAN, 0, 0); -#endif - - std::size_t n = 0; - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->vertex); - for (std::size_t i = 0; i <= m_tess.m_curveTreeV.size(); ++i) { - glDrawArrays(GL_LINE_STRIP, GLint(n), GLsizei(m_tess.m_nArrayWidth)); - - if (i == m_tess.m_curveTreeV.size()) { - break; - } - - if (!BezierCurveTree_isLeaf(m_tess.m_curveTreeV[i])) { - glDrawArrays(GL_LINE_STRIP, GLint(m_tess.m_curveTreeV[i]->index), GLsizei(m_tess.m_nArrayWidth)); - } - - n += (m_tess.m_arrayHeight[i] * m_tess.m_nArrayWidth); - - } - } - - { - const ArbitraryMeshVertex *p = m_tess.m_vertices.data(); - std::size_t n = m_tess.m_nArrayWidth * sizeof(ArbitraryMeshVertex); - for (std::size_t i = 0; i <= m_tess.m_curveTreeU.size(); ++i) { - glVertexPointer(3, GL_FLOAT, GLsizei(n), &p->vertex); - glDrawArrays(GL_LINE_STRIP, 0, GLsizei(m_tess.m_nArrayHeight)); - - if (i == m_tess.m_curveTreeU.size()) { - break; - } - - if (!BezierCurveTree_isLeaf(m_tess.m_curveTreeU[i])) { - glVertexPointer(3, GL_FLOAT, GLsizei(n), - &(m_tess.m_vertices.data() + (m_tess.m_curveTreeU[i]->index))->vertex); - glDrawArrays(GL_LINE_STRIP, 0, GLsizei(m_tess.m_nArrayHeight)); - } - - p += m_tess.m_arrayWidth[i]; - } - } -} -}; - -class RenderablePatchFixedWireframe : public OpenGLRenderable { -PatchTesselation &m_tess; -public: -RenderablePatchFixedWireframe(PatchTesselation &tess) : m_tess(tess) -{ -} - -void render(RenderStateFlags state) const -{ - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->vertex); - const RenderIndex *strip_indices = m_tess.m_indices.data(); - for (std::size_t i = 0; i < m_tess.m_numStrips; i++, strip_indices += m_tess.m_lenStrips) { - glDrawElements(GL_QUAD_STRIP, GLsizei(m_tess.m_lenStrips), RenderIndexTypeID, strip_indices); - } -} -}; - -class RenderablePatchFixedSolid : public OpenGLRenderable { -PatchTesselation &m_tess; -public: -RenderablePatchFixedSolid(PatchTesselation &tess) : m_tess(tess) -{ -} - -void RenderNormals() const; - -void render(RenderStateFlags state) const -{ - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->normal); - glTexCoordPointer(2, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->texcoord); - glShadeModel(GL_SMOOTH); - glColorPointer(4, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->vertex); - const RenderIndex *strip_indices = m_tess.m_indices.data(); - for (std::size_t i = 0; i < m_tess.m_numStrips; i++, strip_indices += m_tess.m_lenStrips) { - glDrawElements(GL_QUAD_STRIP, GLsizei(m_tess.m_lenStrips), RenderIndexTypeID, strip_indices); - } - glShadeModel(GL_FLAT); - RenderNormals(); -} -}; - -class RenderablePatchSolid : public OpenGLRenderable { -PatchTesselation &m_tess; -public: -RenderablePatchSolid(PatchTesselation &tess) : m_tess(tess) -{ -} - -void RenderNormals() const; - -void render(RenderStateFlags state) const -{ - glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->normal); - glTexCoordPointer(2, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->texcoord); - glShadeModel(GL_SMOOTH); - glColorPointer(4, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_tess.m_vertices.data()->vertex); - const RenderIndex *strip_indices = m_tess.m_indices.data(); - for (std::size_t i = 0; i < m_tess.m_numStrips; i++, strip_indices += m_tess.m_lenStrips) { - glDrawElements(GL_QUAD_STRIP, GLsizei(m_tess.m_lenStrips), RenderIndexTypeID, strip_indices); - } - glShadeModel(GL_FLAT); -} -}; - -// parametric surface defined by quadratic bezier control curves -class Patch : - public XMLImporter, - public XMLExporter, - public TransformNode, - public Bounded, - public Cullable, - public Snappable, - public Undoable, - public Filterable, - public Nameable { -class xml_state_t { -public: -enum EState { - eDefault, - ePatch, - eMatrix, - eShader, -}; - -xml_state_t(EState state) - : m_state(state) -{ -} - -EState state() const -{ - return m_state; -} - -const char *content() const -{ - return m_content.c_str(); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return m_content.write(buffer, length); -} - -private: -EState m_state; -StringOutputStream m_content; -}; - -std::vector m_xml_state; - -typedef Array PatchControlArray; - -class SavedState : public UndoMemento { -public: -SavedState( - std::size_t width, - std::size_t height, - const PatchControlArray &ctrl, - const char *shader, - bool patchDef3, - bool patchDefWS, - std::size_t subdivisions_x, - std::size_t subdivisions_y - ) : - m_width(width), - m_height(height), - m_shader(shader), - m_ctrl(ctrl), - m_patchDef3(patchDef3), - m_patchDefWS(patchDefWS), - m_subdivisions_x(subdivisions_x), - m_subdivisions_y(subdivisions_y) -{ -} - -void release() -{ - delete this; -} - -std::size_t m_width, m_height; -CopiedString m_shader; -PatchControlArray m_ctrl; -bool m_patchDef3; -bool m_patchDefWS; -std::size_t m_subdivisions_x; -std::size_t m_subdivisions_y; -}; - -public: -class Observer { -public: -virtual void allocate(std::size_t size) = 0; -}; - -private: -typedef UniqueSet Observers; -Observers m_observers; - -scene::Node *m_node; - -AABB m_aabb_local; // local bbox - -CopiedString m_shader; -Shader *m_state; - -std::size_t m_width; -std::size_t m_height; -public: -bool m_patchDef3; -bool m_patchDefWS; -std::size_t m_subdivisions_x; -std::size_t m_subdivisions_y; -PatchTesselation m_tess; -private: - -UndoObserver *m_undoable_observer; -MapFile *m_map; - -// dynamically allocated array of control points, size is m_width*m_height -PatchControlArray m_ctrl; -PatchControlArray m_ctrlTransformed; - -RenderablePatchSolid m_render_solid; -RenderablePatchFixedSolid m_render_solid_fixed; -RenderablePatchWireframe m_render_wireframe; -RenderablePatchFixedWireframe m_render_wireframe_fixed; - -static Shader *m_state_ctrl; -static Shader *m_state_lattice; -VertexBuffer m_ctrl_vertices; -RenderableVertexBuffer m_render_ctrl; -IndexBuffer m_lattice_indices; -RenderableIndexBuffer m_render_lattice; - -bool m_bOverlay; - -bool m_transformChanged; -Callback m_evaluateTransform; -Callback m_boundsChanged; - -void construct() -{ - m_bOverlay = false; - m_width = m_height = 0; - - m_patchDef3 = false; - m_patchDefWS = false; - m_subdivisions_x = 0; - m_subdivisions_y = 0; - - check_shader(); - captureShader(); - - m_xml_state.push_back(xml_state_t::eDefault); -} - -public: -Callback m_lightsChanged; - -static int m_CycleCapIndex; // = 0; -static EPatchType m_type; - -STRING_CONSTANT(Name, "Patch"); - -Patch(scene::Node &node, const Callback &evaluateTransform, const Callback &boundsChanged) : - m_node(&node), - m_shader(texdef_name_default()), - m_state(0), - m_undoable_observer(0), - m_map(0), - m_render_solid(m_tess), - m_render_solid_fixed(m_tess), - m_render_wireframe(m_tess), - m_render_wireframe_fixed(m_tess), - m_render_ctrl(GL_POINTS, m_ctrl_vertices), - m_render_lattice(GL_LINES, m_lattice_indices, m_ctrl_vertices), - m_transformChanged(false), - m_evaluateTransform(evaluateTransform), - m_boundsChanged(boundsChanged) -{ - construct(); -} - -Patch(const Patch &other, scene::Node &node, const Callback &evaluateTransform, - const Callback &boundsChanged) : - m_node(&node), - m_shader(texdef_name_default()), - m_state(0), - m_undoable_observer(0), - m_map(0), - m_render_solid(m_tess), - m_render_solid_fixed(m_tess), - m_render_wireframe(m_tess), - m_render_wireframe_fixed(m_tess), - m_render_ctrl(GL_POINTS, m_ctrl_vertices), - m_render_lattice(GL_LINES, m_lattice_indices, m_ctrl_vertices), - m_transformChanged(false), - m_evaluateTransform(evaluateTransform), - m_boundsChanged(boundsChanged) -{ - construct(); - - m_patchDef3 = other.m_patchDef3; - m_patchDefWS = other.m_patchDefWS; - m_subdivisions_x = other.m_subdivisions_x; - m_subdivisions_y = other.m_subdivisions_y; - setDims(other.m_width, other.m_height); - copy_ctrl(m_ctrl.data(), other.m_ctrl.data(), other.m_ctrl.data() + (m_width * m_height)); - SetShader(other.m_shader.c_str()); - controlPointsChanged(); -} - -Patch(const Patch &other) : - XMLImporter(other), - XMLExporter(other), - TransformNode(other), - Bounded(other), - Cullable(other), - Snappable(), - Undoable(other), - Filterable(other), - Nameable(other), - m_state(0), - m_undoable_observer(0), - m_map(0), - m_render_solid(m_tess), - m_render_solid_fixed(m_tess), - m_render_wireframe(m_tess), - m_render_wireframe_fixed(m_tess), - m_render_ctrl(GL_POINTS, m_ctrl_vertices), - m_render_lattice(GL_LINES, m_lattice_indices, m_ctrl_vertices), - m_transformChanged(false), - m_evaluateTransform(other.m_evaluateTransform), - m_boundsChanged(other.m_boundsChanged) -{ - m_bOverlay = false; - - m_patchDef3 = other.m_patchDef3; - m_patchDefWS = other.m_patchDefWS; - m_subdivisions_x = other.m_subdivisions_x; - m_subdivisions_y = other.m_subdivisions_y; - setDims(other.m_width, other.m_height); - copy_ctrl(m_ctrl.data(), other.m_ctrl.data(), other.m_ctrl.data() + (m_width * m_height)); - SetShader(other.m_shader.c_str()); - controlPointsChanged(); -} - -~Patch() -{ - BezierCurveTreeArray_deleteAll(m_tess.m_curveTreeU); - BezierCurveTreeArray_deleteAll(m_tess.m_curveTreeV); - - releaseShader(); - - ASSERT_MESSAGE(m_observers.empty(), "Patch::~Patch: observers still attached"); -} - -InstanceCounter m_instanceCounter; - -void instanceAttach(const scene::Path &path) -{ - if (++m_instanceCounter.m_count == 1) { - m_state->incrementUsed(); - m_map = path_find_mapfile(path.begin(), path.end()); - m_undoable_observer = GlobalUndoSystem().observer(this); - GlobalFilterSystem().registerFilterable(*this); - } else { - ASSERT_MESSAGE(path_find_mapfile(path.begin(), path.end()) == m_map, - "node is instanced across more than one file"); - } -} - -void instanceDetach(const scene::Path &path) -{ - if (--m_instanceCounter.m_count == 0) { - m_map = 0; - m_undoable_observer = 0; - GlobalUndoSystem().release(this); - GlobalFilterSystem().unregisterFilterable(*this); - m_state->decrementUsed(); - } -} - -const char *name() const -{ - return "patch"; -} - -void attach(const NameCallback &callback) -{ -} - -void detach(const NameCallback &callback) -{ -} - -void attach(Observer *observer) -{ - observer->allocate(m_width * m_height); - - m_observers.insert(observer); -} - -void detach(Observer *observer) -{ - m_observers.erase(observer); -} - -void updateFiltered() -{ - if (m_node != 0) { - if (patch_filtered(*this)) { - m_node->enable(scene::Node::eFiltered); - } else { - m_node->disable(scene::Node::eFiltered); - } - } -} - -void onAllocate(std::size_t size) -{ - for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) { - (*i)->allocate(size); - } -} - -const Matrix4 &localToParent() const -{ - return g_matrix4_identity; -} - -const AABB &localAABB() const -{ - return m_aabb_local; -} - -VolumeIntersectionValue intersectVolume(const VolumeTest &test, const Matrix4 &localToWorld) const -{ - return test.TestAABB(m_aabb_local, localToWorld); -} - -void render_solid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state, Renderer::eFullMaterials); - - if (m_patchDef3) { - renderer.addRenderable(m_render_solid_fixed, localToWorld); - } else { - renderer.addRenderable(m_render_solid, localToWorld); - } -} - -void render_wireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state, Renderer::eFullMaterials); - if (m_patchDef3) { - renderer.addRenderable(m_render_wireframe_fixed, localToWorld); - } else { - renderer.addRenderable(m_render_wireframe, localToWorld); - } -} - -void render_component(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld) const -{ - renderer.SetState(m_state_lattice, Renderer::eWireframeOnly); - renderer.SetState(m_state_lattice, Renderer::eFullMaterials); - renderer.addRenderable(m_render_lattice, localToWorld); - - renderer.SetState(m_state_ctrl, Renderer::eWireframeOnly); - renderer.SetState(m_state_ctrl, Renderer::eFullMaterials); - renderer.addRenderable(m_render_ctrl, localToWorld); -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - IndexPointer::index_type *pIndex = m_tess.m_indices.data(); - for (std::size_t s = 0; s < m_tess.m_numStrips; s++) { - test.TestQuadStrip(vertexpointer_arbitrarymeshvertex(m_tess.m_vertices.data()), - IndexPointer(pIndex, m_tess.m_lenStrips), best); - pIndex += m_tess.m_lenStrips; - } - if (best.valid()) { - selector.addIntersection(best); - } -} - -void transform(const Matrix4 &matrix) -{ - for (PatchControlIter i = m_ctrlTransformed.data(); - i != m_ctrlTransformed.data() + m_ctrlTransformed.size(); ++i) { - matrix4_transform_point(matrix, (*i).m_vertex); - } - - if (matrix4_handedness(matrix) == MATRIX4_LEFTHANDED) { - PatchControlArray_invert(m_ctrlTransformed, m_width, m_height); - } - UpdateCachedData(); -} - -void transformChanged() -{ - m_transformChanged = true; - m_lightsChanged(); - SceneChangeNotify(); -} - -typedef MemberCaller TransformChangedCaller; - -void evaluateTransform() -{ - if (m_transformChanged) { - m_transformChanged = false; - revertTransform(); - m_evaluateTransform(); - } -} - -void revertTransform() -{ - m_ctrlTransformed = m_ctrl; -} - -void freezeTransform() -{ - undoSave(); - evaluateTransform(); - ASSERT_MESSAGE(m_ctrlTransformed.size() == m_ctrl.size(), "Patch::freeze: size mismatch"); - std::copy(m_ctrlTransformed.begin(), m_ctrlTransformed.end(), m_ctrl.begin()); -} - -void controlPointsChanged() -{ - transformChanged(); - evaluateTransform(); - UpdateCachedData(); -} - -bool isValid() const; - -void snapto(float snap) -{ - undoSave(); - - for (PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i) { - vector3_snap((*i).m_vertex, snap); - } - - controlPointsChanged(); -} - - -void RenderDebug(RenderStateFlags state) const; - -void RenderNormals(RenderStateFlags state) const; - -void pushElement(const XMLElement &element) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - ASSERT_MESSAGE(string_equal(element.name(), "patch"), "parse error"); - m_xml_state.push_back(xml_state_t::ePatch); - break; - case xml_state_t::ePatch: - if (string_equal(element.name(), "matrix")) { - setDims(atoi(element.attribute("width")), atoi(element.attribute("height"))); - m_xml_state.push_back(xml_state_t::eMatrix); - } else if (string_equal(element.name(), "shader")) { - m_xml_state.push_back(xml_state_t::eShader); - } - break; - default: - ERROR_MESSAGE("parse error"); - } - -} - -void popElement(const char *name) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - ERROR_MESSAGE("parse error"); - break; - case xml_state_t::ePatch: - break; - case xml_state_t::eMatrix: { - StringTokeniser content(m_xml_state.back().content()); - - for (PatchControlIter i = m_ctrl.data(), end = m_ctrl.data() + m_ctrl.size(); i != end; ++i) { - (*i).m_vertex[0] = string_read_float(content.getToken()); - (*i).m_vertex[1] = string_read_float(content.getToken()); - (*i).m_vertex[2] = string_read_float(content.getToken()); - (*i).m_texcoord[0] = string_read_float(content.getToken()); - (*i).m_texcoord[1] = string_read_float(content.getToken()); - } - controlPointsChanged(); - } - break; - case xml_state_t::eShader: { - SetShader(m_xml_state.back().content()); - } - break; - default: - ERROR_MESSAGE("parse error"); - } - - ASSERT_MESSAGE(!m_xml_state.empty(), "popping empty stack"); - m_xml_state.pop_back(); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - switch (m_xml_state.back().state()) { - case xml_state_t::eDefault: - break; - case xml_state_t::ePatch: - break; - case xml_state_t::eMatrix: - case xml_state_t::eShader: - return m_xml_state.back().write(buffer, length); - break; - default: - ERROR_MESSAGE("parse error"); - } - return length; -} - -void exportXML(XMLImporter &importer) -{ - StaticElement patchElement("patch"); - importer.pushElement(patchElement); - - { - const StaticElement element("shader"); - importer.pushElement(element); - importer.write(m_shader.c_str(), strlen(m_shader.c_str())); - importer.popElement(element.name()); - } - - { - char width[16], height[16]; - sprintf(width, "%u", Unsigned(m_width)); - sprintf(height, "%u", Unsigned(m_height)); - StaticElement element("matrix"); - element.insertAttribute("width", width); - element.insertAttribute("height", height); - - importer.pushElement(element); - { - for (PatchControlIter i = m_ctrl.data(), end = m_ctrl.data() + m_ctrl.size(); i != end; ++i) { - importer << (*i).m_vertex[0] - << ' ' << (*i).m_vertex[1] - << ' ' << (*i).m_vertex[2] - << ' ' << (*i).m_texcoord[0] - << ' ' << (*i).m_texcoord[1]; - } - } - importer.popElement(element.name()); - } - - importer.popElement(patchElement.name()); -} - -void UpdateCachedData(); - -const char *GetShader() const -{ - return m_shader.c_str(); -} - -void SetShader(const char *name) -{ - ASSERT_NOTNULL(name); - - if (shader_equal(m_shader.c_str(), name)) { - return; - } - - undoSave(); - - if (m_instanceCounter.m_count != 0) { - m_state->decrementUsed(); - } - releaseShader(); - m_shader = name; - captureShader(); - if (m_instanceCounter.m_count != 0) { - m_state->incrementUsed(); - } - - check_shader(); - Patch_textureChanged(); -} - -int getShaderFlags() const -{ - if (m_state != 0) { - return m_state->getFlags(); - } - return 0; -} - -typedef PatchControl *iterator; -typedef const PatchControl *const_iterator; - -iterator begin() -{ - return m_ctrl.data(); -} - -const_iterator begin() const -{ - return m_ctrl.data(); -} - -iterator end() -{ - return m_ctrl.data() + m_ctrl.size(); -} - -const_iterator end() const -{ - return m_ctrl.data() + m_ctrl.size(); -} - -PatchControlArray &getControlPoints() -{ - return m_ctrl; -} - -PatchControlArray &getControlPointsTransformed() -{ - return m_ctrlTransformed; -} - -void setDims(std::size_t w, std::size_t h); - -std::size_t getWidth() const -{ - return m_width; -} - -std::size_t getHeight() const -{ - return m_height; -} - -PatchControl &ctrlAt(std::size_t row, std::size_t col) -{ - return m_ctrl[row * m_width + col]; -} - -const PatchControl &ctrlAt(std::size_t row, std::size_t col) const -{ - return m_ctrl[row * m_width + col]; -} - -void ConstructPrefab(const AABB &aabb, EPatchPrefab eType, int axis, std::size_t width = 3, std::size_t height = 3); - -void constructPlane(const AABB &aabb, int axis, std::size_t width, std::size_t height); - -void InvertMatrix(); - -void TransposeMatrix(); - -void Redisperse(EMatrixMajor mt); - -void Smooth(EMatrixMajor mt); - -void InsertRemove(bool bInsert, bool bColumn, bool bFirst); - -Patch *MakeCap(Patch *patch, EPatchCap eType, EMatrixMajor mt, bool bFirst); - -void ConstructSeam(EPatchCap eType, Vector3 *p, std::size_t width); - -void FlipTexture(int nAxis); - -void TranslateTexture(float s, float t); - -void ScaleTexture(float s, float t); - -void RotateTexture(float angle); - -void SetTextureRepeat(float s, float t); // call with s=1 t=1 for FIT -void CapTexture(); - -void NaturalTexture(); - -void ProjectTexture(int nAxis); - -void IdentityColour(void); //sets all colours to 1,1,1,1 - -void undoSave() -{ - if (m_map != 0) { - m_map->changed(); - } - if (m_undoable_observer != 0) { - m_undoable_observer->save(this); - } -} - -UndoMemento *exportState() const -{ - return new SavedState(m_width, m_height, m_ctrl, m_shader.c_str(), m_patchDef3, m_patchDefWS, m_subdivisions_x, - m_subdivisions_y); -} - -void importState(const UndoMemento *state) -{ - undoSave(); - - const SavedState &other = *(static_cast( state )); - - // begin duplicate of SavedState copy constructor, needs refactoring - - // copy construct - { - m_width = other.m_width; - m_height = other.m_height; - SetShader(other.m_shader.c_str()); - m_ctrl = other.m_ctrl; - onAllocate(m_ctrl.size()); - m_patchDef3 = other.m_patchDef3; - m_patchDefWS = other.m_patchDefWS; - m_subdivisions_x = other.m_subdivisions_x; - m_subdivisions_y = other.m_subdivisions_y; - } - - // end duplicate code - - Patch_textureChanged(); - - controlPointsChanged(); -} - -static void constructStatic(EPatchType type) -{ - Patch::m_type = type; - Patch::m_state_ctrl = GlobalShaderCache().capture("$POINT"); - Patch::m_state_lattice = GlobalShaderCache().capture("$LATTICE"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$LATTICE"); - GlobalShaderCache().release("$POINT"); -} - -private: -void captureShader() -{ - m_state = GlobalShaderCache().capture(m_shader.c_str()); -} - -void releaseShader() -{ - GlobalShaderCache().release(m_shader.c_str()); -} - -void check_shader() -{ - if (!shader_valid(GetShader())) { - globalErrorStream() << "patch has invalid texture name: '" << GetShader() << "'\n"; - } -} - -void InsertPoints(EMatrixMajor mt, bool bFirst); - -void RemovePoints(EMatrixMajor mt, bool bFirst); - -void AccumulateBBox(); - -void TesselateSubMatrixFixed(ArbitraryMeshVertex *vertices, std::size_t strideX, std::size_t strideY, - unsigned int nFlagsX, unsigned int nFlagsY, PatchControl *subMatrix[3][3]); - -// uses binary trees representing bezier curves to recursively tesselate a bezier sub-patch -void TesselateSubMatrix(const BezierCurveTree *BX, const BezierCurveTree *BY, - std::size_t offStartX, std::size_t offStartY, - std::size_t offEndX, std::size_t offEndY, - std::size_t nFlagsX, std::size_t nFlagsY, - Vector3 &left, Vector3 &mid, Vector3 &right, - Vector2 &texLeft, Vector2 &texMid, Vector2 &texRight, - Vector4 &colLeft, Vector4 &colMid, Vector4 &colRight, - bool bTranspose); - -// tesselates the entire surface -void BuildTesselationCurves(EMatrixMajor major); - -void accumulateVertexTangentSpace(std::size_t index, Vector3 tangentX[6], Vector3 tangentY[6], Vector2 tangentS[6], - Vector2 tangentT[6], std::size_t index0, std::size_t index1); - -void BuildVertexArray(); -}; - -inline bool Patch_importHeader(Patch &patch, Tokeniser &tokeniser) -{ - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "{")); - return true; -} - -inline bool Patch_importShader(Patch &patch, Tokeniser &tokeniser) -{ - // parse shader name - tokeniser.nextLine(); - const char *texture = tokeniser.getToken(); - if (texture == 0) { - Tokeniser_unexpectedError(tokeniser, texture, "#texture-name"); - return false; - } - if (string_equal(texture, "NULL")) { - patch.SetShader(texdef_name_default()); - } else { - StringOutputStream shader(string_length(GlobalTexturePrefix_get()) + string_length(texture)); - shader << GlobalTexturePrefix_get() << texture; - patch.SetShader(shader.c_str()); - } - return true; -} - -inline bool PatchDoom3_importShader(Patch &patch, Tokeniser &tokeniser) -{ - // parse shader name - tokeniser.nextLine(); - const char *shader = tokeniser.getToken(); - if (shader == 0) { - Tokeniser_unexpectedError(tokeniser, shader, "#shader-name"); - return false; - } - if (string_equal(shader, "_emptyname")) { - shader = texdef_name_default(); - } - patch.SetShader(shader); - return true; -} - -inline bool Patch_importParams(Patch &patch, Tokeniser &tokeniser) -{ - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - - // parse matrix dimensions - { - std::size_t c, r; - RETURN_FALSE_IF_FAIL(Tokeniser_getSize(tokeniser, c)); - RETURN_FALSE_IF_FAIL(Tokeniser_getSize(tokeniser, r)); - - patch.setDims(c, r); - } - - if (patch.m_patchDef3) { - RETURN_FALSE_IF_FAIL(Tokeniser_getSize(tokeniser, patch.m_subdivisions_x)); - RETURN_FALSE_IF_FAIL(Tokeniser_getSize(tokeniser, patch.m_subdivisions_y)); - } - - // ignore contents/flags/value - int tmp; - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, tmp)); - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, tmp)); - RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, tmp)); - - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - return true; -} - -inline bool Patch_importMatrix(Patch &patch, Tokeniser &tokeniser) -{ - // parse matrix - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - { - for (std::size_t c = 0; c < patch.getWidth(); c++) { - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - for (std::size_t r = 0; r < patch.getHeight(); r++) { - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_vertex[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_vertex[1])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_vertex[2])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_texcoord[0])); - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_texcoord[1])); - - patch.ctrlAt(r, c).m_color = Vector4(1,1,1,1); //assume opaque white. - - if (patch.m_patchDefWS) { - //Temp Hack, to handle weird format... - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "(")); - //End Temp Hack. - } - - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - continue; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_color[0])); - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - continue; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_color[1])); - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - continue; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_color[2])); - if (Tokeniser_nextTokenMatches(tokeniser, ")")) - continue; - RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, patch.ctrlAt(r, c).m_color[3])); - - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - } - } - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")")); - return true; -} - -inline bool Patch_importFooter(Patch &patch, Tokeniser &tokeniser) -{ - patch.controlPointsChanged(); - - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "}")); - - tokeniser.nextLine(); - RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "}")); - return true; -} - -class PatchTokenImporter : public MapImporter { -Patch &m_patch; -public: -PatchTokenImporter(Patch &patch) : m_patch(patch) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(Patch_importHeader(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importShader(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importParams(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importMatrix(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importFooter(m_patch, tokeniser)); - - return true; -} -}; - -class PatchDoom3TokenImporter : public MapImporter { -Patch &m_patch; -public: -PatchDoom3TokenImporter(Patch &patch) : m_patch(patch) -{ -} - -bool importTokens(Tokeniser &tokeniser) -{ - RETURN_FALSE_IF_FAIL(Patch_importHeader(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(PatchDoom3_importShader(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importParams(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importMatrix(m_patch, tokeniser)); - RETURN_FALSE_IF_FAIL(Patch_importFooter(m_patch, tokeniser)); - - return true; -} -}; - -inline void Patch_exportHeader(const Patch &patch, TokenWriter &writer) -{ - writer.writeToken("{"); - writer.nextLine(); - - //if it has colours, use our postfix on the patchdef type (to prevent incompatible tools giving weird results - our parser doesn't really care for now...) - bool hascolours = false; - for (std::size_t c = 0; c < patch.getWidth() && !hascolours; c++) { - for (std::size_t r = 0; r < patch.getHeight(); r++) { - auto v = patch.ctrlAt(r, c); - if (v.m_color[0] != 1 || v.m_color[1] != 1 || v.m_color[2] != 1 || v.m_color[3] != 1) - { - hascolours = true; - break; - } - } - } - if (hascolours) { - writer.writeToken(patch.m_patchDef3 ? "patchDef3WS" : "patchDef2WS"); - } else { - writer.writeToken(patch.m_patchDef3 ? "patchDef3" : "patchDef2"); - } - writer.nextLine(); - writer.writeToken("{"); - writer.nextLine(); -} - -inline void Patch_exportShader(const Patch &patch, TokenWriter &writer) -{ - // write shader name - if (*(shader_get_textureName(patch.GetShader())) == '\0') { - writer.writeToken("NULL"); - } else { - writer.writeToken(shader_get_textureName(patch.GetShader())); - } - writer.nextLine(); -} - -inline void PatchDoom3_exportShader(const Patch &patch, TokenWriter &writer) -{ - // write shader name - if (*(shader_get_textureName(patch.GetShader())) == '\0') { - writer.writeString("_emptyname"); - } else { - writer.writeString(patch.GetShader()); - } - writer.nextLine(); -} - -inline void Patch_exportParams(const Patch &patch, TokenWriter &writer) -{ - // write matrix dimensions - writer.writeToken("("); - writer.writeUnsigned(patch.getWidth()); - writer.writeUnsigned(patch.getHeight()); - if (patch.m_patchDef3) { - writer.writeUnsigned(patch.m_subdivisions_x); - writer.writeUnsigned(patch.m_subdivisions_y); - } - writer.writeInteger(0); - writer.writeInteger(0); - writer.writeInteger(0); - writer.writeToken(")"); - writer.nextLine(); -} - -inline void Patch_exportMatrix(const Patch &patch, TokenWriter &writer) -{ - // write matrix - writer.writeToken("("); - writer.nextLine(); - for (std::size_t c = 0; c < patch.getWidth(); c++) { - writer.writeToken("("); - for (std::size_t r = 0; r < patch.getHeight(); r++) { - writer.writeToken("("); - auto v = patch.ctrlAt(r, c); - - writer.writeFloat(v.m_vertex[0]); - writer.writeFloat(v.m_vertex[1]); - writer.writeFloat(v.m_vertex[2]); - writer.writeFloat(v.m_texcoord[0]); - writer.writeFloat(v.m_texcoord[1]); - - if (v.m_color[0] != 1 || v.m_color[1] != 1 || v.m_color[2] != 1 || v.m_color[3] != 1) { - writer.writeFloat(v.m_color[0]); - writer.writeFloat(v.m_color[1]); - writer.writeFloat(v.m_color[2]); - writer.writeFloat(v.m_color[3]); - } - - writer.writeToken(")"); - } - writer.writeToken(")"); - writer.nextLine(); - } - writer.writeToken(")"); - writer.nextLine(); -} - -inline void Patch_exportFooter(const Patch &patch, TokenWriter &writer) -{ - writer.writeToken("}"); - writer.nextLine(); - writer.writeToken("}"); - writer.nextLine(); -} - -class PatchTokenExporter : public MapExporter { -const Patch &m_patch; -public: -PatchTokenExporter(Patch &patch) : m_patch(patch) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - Patch_exportHeader(m_patch, writer); - Patch_exportShader(m_patch, writer); - Patch_exportParams(m_patch, writer); - Patch_exportMatrix(m_patch, writer); - Patch_exportFooter(m_patch, writer); -} -}; - -class PatchDoom3TokenExporter : public MapExporter { -const Patch &m_patch; -public: -PatchDoom3TokenExporter(Patch &patch) : m_patch(patch) -{ -} - -void exportTokens(TokenWriter &writer) const -{ - Patch_exportHeader(m_patch, writer); - PatchDoom3_exportShader(m_patch, writer); - Patch_exportParams(m_patch, writer); - Patch_exportMatrix(m_patch, writer); - Patch_exportFooter(m_patch, writer); -} -}; - -class PatchControlInstance { -public: -PatchControl *m_ctrl; -ObservedSelectable m_selectable; - -PatchControlInstance(PatchControl *ctrl, const SelectionChangeCallback &observer) - : m_ctrl(ctrl), m_selectable(observer) -{ -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - SelectionIntersection best; - test.TestPoint(m_ctrl->m_vertex, best); - if (best.valid()) { - Selector_add(selector, m_selectable, best); - } -} - -void snapto(float snap) -{ - vector3_snap(m_ctrl->m_vertex, snap); -} -}; - - -class PatchInstance : - public Patch::Observer, - public scene::Instance, - public Selectable, - public Renderable, - public SelectionTestable, - public ComponentSelectionTestable, - public ComponentEditable, - public ComponentSnappable, - public PlaneSelectable, - public LightCullable { -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - InstanceStaticCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); - InstanceContainedCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - - -Patch &m_patch; -typedef std::vector PatchControlInstances; -PatchControlInstances m_ctrl_instances; - -ObservedSelectable m_selectable; - -DragPlanes m_dragPlanes; - -mutable RenderablePointVector m_render_selected; -mutable AABB m_aabb_component; - -static Shader *m_state_selpoint; - -const LightList *m_lightList; - -TransformModifier m_transform; -public: - -typedef LazyStatic StaticTypeCasts; - -void lightsChanged() -{ - m_lightList->lightsChanged(); -} - -typedef MemberCaller LightsChangedCaller; - -STRING_CONSTANT(Name, "PatchInstance"); - -PatchInstance(const scene::Path &path, scene::Instance *parent, Patch &patch) : - Instance(path, parent, this, StaticTypeCasts::instance().get()), - m_patch(patch), - m_selectable(SelectedChangedCaller(*this)), - m_dragPlanes(SelectedChangedComponentCaller(*this)), - m_render_selected(GL_POINTS), - m_transform(Patch::TransformChangedCaller(m_patch), ApplyTransformCaller(*this)) -{ - m_patch.instanceAttach(Instance::path()); - m_patch.attach(this); - - m_lightList = &GlobalShaderCache().attach(*this); - m_patch.m_lightsChanged = LightsChangedCaller(*this); - - Instance::setTransformChangedCallback(LightsChangedCaller(*this)); -} - -~PatchInstance() -{ - Instance::setTransformChangedCallback(Callback()); - - m_patch.m_lightsChanged = Callback(); - GlobalShaderCache().detach(*this); - - m_patch.detach(this); - m_patch.instanceDetach(Instance::path()); -} - -void selectedChanged(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::ePrimitive)(selectable); - GlobalSelectionSystem().onSelectedChanged(*this, selectable); - - Instance::selectedChanged(); -} - -typedef MemberCaller SelectedChangedCaller; - -void selectedChangedComponent(const Selectable &selectable) -{ - GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); - GlobalSelectionSystem().onComponentSelection(*this, selectable); -} - -typedef MemberCaller SelectedChangedComponentCaller; - -Patch &getPatch() -{ - return m_patch; -} - -Bounded &get(NullType) -{ - return m_patch; -} - -Cullable &get(NullType) -{ - return m_patch; -} - -Transformable &get(NullType) -{ - return m_transform; -} - -static void constructStatic() -{ - m_state_selpoint = GlobalShaderCache().capture("$SELPOINT"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$SELPOINT"); -} - - -void allocate(std::size_t size) -{ - m_ctrl_instances.clear(); - m_ctrl_instances.reserve(size); - for (Patch::iterator i = m_patch.begin(); i != m_patch.end(); ++i) { - m_ctrl_instances.push_back(PatchControlInstance(&(*i), SelectedChangedComponentCaller(*this))); - } -} - -void setSelected(bool select) -{ - m_selectable.setSelected(select); -} - -bool isSelected() const -{ - return m_selectable.isSelected(); -} - - -void update_selected() const -{ - m_render_selected.clear(); - Patch::iterator ctrl = m_patch.getControlPointsTransformed().begin(); - for (PatchControlInstances::const_iterator i = m_ctrl_instances.begin(); - i != m_ctrl_instances.end(); ++i, ++ctrl) { - if ((*i).m_selectable.isSelected()) { - const Colour4b colour_selected(0, 0, 255, 255); - m_render_selected.push_back( - PointVertex(reinterpret_cast((*ctrl).m_vertex ), colour_selected)); - } - } -} - -#if 0 -void render( Renderer& renderer, const VolumeTest& volume ) const { - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && m_selectable.isSelected() ) { - renderer.Highlight( Renderer::eFace, false ); - - m_patch.render( renderer, volume, localToWorld() ); - - if ( GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex ) { - renderer.Highlight( Renderer::ePrimitive, false ); - - m_patch.render_component( renderer, volume, localToWorld() ); - - renderComponentsSelected( renderer, volume ); - } - } - else{ - m_patch.render( renderer, volume, localToWorld() ); - } -} -#endif - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - m_patch.evaluateTransform(); - renderer.setLights(*m_lightList); - m_patch.render_solid(renderer, volume, localToWorld()); - - renderComponentsSelected(renderer, volume); -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - m_patch.evaluateTransform(); - m_patch.render_wireframe(renderer, volume, localToWorld()); - - renderComponentsSelected(renderer, volume); -} - -void renderComponentsSelected(Renderer &renderer, const VolumeTest &volume) const -{ - m_patch.evaluateTransform(); - update_selected(); - if (!m_render_selected.empty()) { - renderer.Highlight(Renderer::ePrimitive, false); - renderer.SetState(m_state_selpoint, Renderer::eWireframeOnly); - renderer.SetState(m_state_selpoint, Renderer::eFullMaterials); - renderer.addRenderable(m_render_selected, localToWorld()); - } -} - -void renderComponents(Renderer &renderer, const VolumeTest &volume) const -{ - m_patch.evaluateTransform(); - if (GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex) { - m_patch.render_component(renderer, volume, localToWorld()); - } -} - -void testSelect(Selector &selector, SelectionTest &test) -{ - test.BeginMesh(localToWorld(), true); - m_patch.testSelect(selector, test); -} - -void selectCtrl(bool select) -{ - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - (*i).m_selectable.setSelected(select); - } -} - -bool isSelectedComponents() const -{ - for (PatchControlInstances::const_iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - if ((*i).m_selectable.isSelected()) { - return true; - } - } - return false; -} - -void setSelectedComponents(bool select, SelectionSystem::EComponentMode mode) -{ - if (mode == SelectionSystem::eVertex) { - selectCtrl(select); - } else if (mode == SelectionSystem::eFace) { - m_dragPlanes.setSelected(select); - } -} - -const AABB &getSelectedComponentsBounds() const -{ - m_aabb_component = AABB(); - - for (PatchControlInstances::const_iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - if ((*i).m_selectable.isSelected()) { - aabb_extend_by_point_safe(m_aabb_component, (*i).m_ctrl->m_vertex); - } - } - - return m_aabb_component; -} - -void testSelectComponents(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) -{ - test.BeginMesh(localToWorld()); - - switch (mode) { - case SelectionSystem::eVertex: { - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - (*i).testSelect(selector, test); - } - } - break; - default: - break; - } -} - -bool selectedVertices() -{ - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - if ((*i).m_selectable.isSelected()) { - return true; - } - } - return false; -} - -void transformComponents(const Matrix4 &matrix) -{ - if (selectedVertices()) { - PatchControlIter ctrl = m_patch.getControlPointsTransformed().begin(); - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); - i != m_ctrl_instances.end(); ++i, ++ctrl) { - if ((*i).m_selectable.isSelected()) { - matrix4_transform_point(matrix, (*ctrl).m_vertex); - } - } - m_patch.UpdateCachedData(); - } - - if (m_dragPlanes.isSelected()) { // this should only be true when the transform is a pure translation. - m_patch.transform(m_dragPlanes.evaluateTransform(vector4_to_vector3(matrix.t()))); - } -} - - -void selectPlanes(Selector &selector, SelectionTest &test, const PlaneCallback &selectedPlaneCallback) -{ - test.BeginMesh(localToWorld()); - - m_dragPlanes.selectPlanes(m_patch.localAABB(), selector, test, selectedPlaneCallback); -} - -void selectReversedPlanes(Selector &selector, const SelectedPlanes &selectedPlanes) -{ - m_dragPlanes.selectReversedPlanes(m_patch.localAABB(), selector, selectedPlanes); -} - - -void snapComponents(float snap) -{ - if (selectedVertices()) { - m_patch.undoSave(); - for (PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i) { - if ((*i).m_selectable.isSelected()) { - (*i).snapto(snap); - } - } - m_patch.controlPointsChanged(); - } -} - -void evaluateTransform() -{ - Matrix4 matrix(m_transform.calculateTransform()); - - if (m_transform.getType() == TRANSFORM_PRIMITIVE) { - m_patch.transform(matrix); - } else { - transformComponents(matrix); - } -} - -void applyTransform() -{ - m_patch.revertTransform(); - evaluateTransform(); - m_patch.freezeTransform(); -} - -typedef MemberCaller ApplyTransformCaller; - - -bool testLight(const RendererLight &light) const -{ - return light.testAABB(worldAABB()); -} -}; - - -template -class PatchNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable { -typedef PatchNode Self; - -class TypeCasts { -InstanceTypeCastTable m_casts; -public: -TypeCasts() -{ - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); -} - -InstanceTypeCastTable &get() -{ - return m_casts; -} -}; - - -scene::Node m_node; -InstanceSet m_instances; -Patch m_patch; -TokenImporter m_importMap; -TokenExporter m_exportMap; - -public: - -typedef LazyStatic StaticTypeCasts; - -Snappable &get(NullType) -{ - return m_patch; -} - -TransformNode &get(NullType) -{ - return m_patch; -} - -Patch &get(NullType) -{ - return m_patch; -} - -XMLImporter &get(NullType) -{ - return m_patch; -} - -XMLExporter &get(NullType) -{ - return m_patch; -} - -MapImporter &get(NullType) -{ - return m_importMap; -} - -MapExporter &get(NullType) -{ - return m_exportMap; -} - -Nameable &get(NullType) -{ - return m_patch; -} - -PatchNode(bool patchDef3, bool patchWS) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_patch(m_node, InstanceSetEvaluateTransform::Caller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances)), - m_importMap(m_patch), - m_exportMap(m_patch) -{ - m_patch.m_patchDef3 = patchDef3; - m_patch.m_patchDefWS = patchWS; -} - -PatchNode(const PatchNode &other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_patch(other.m_patch, m_node, InstanceSetEvaluateTransform::Caller(m_instances), - InstanceSet::BoundsChangedCaller(m_instances)), - m_importMap(m_patch), - m_exportMap(m_patch) -{ -} - -void release() -{ - delete this; -} - -scene::Node &node() -{ - return m_node; -} - -Patch &get() -{ - return m_patch; -} - -const Patch &get() const -{ - return m_patch; -} - -scene::Node &clone() const -{ - return (new PatchNode(*this))->node(); -} - -scene::Instance *create(const scene::Path &path, scene::Instance *parent) -{ - return new PatchInstance(path, parent, m_patch); -} - -void forEachInstance(const scene::Instantiable::Visitor &visitor) -{ - m_instances.forEachInstance(visitor); -} - -void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) -{ - m_instances.insert(observer, path, instance); -} - -scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) -{ - return m_instances.erase(observer, path); -} -}; - - -typedef PatchNode PatchNodeQuake3; -typedef PatchNode PatchNodeDoom3; - -inline Patch *Node_getPatch(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -inline PatchInstance *Instance_getPatch(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -template -class PatchSelectedVisitor : public SelectionSystem::Visitor { -const Functor &m_functor; -public: -PatchSelectedVisitor(const Functor &functor) : m_functor(functor) -{ -} - -void visit(scene::Instance &instance) const -{ - PatchInstance *patch = Instance_getPatch(instance); - if (patch != 0) { - m_functor(*patch); - } -} -}; - -template -inline void Scene_forEachSelectedPatch(const Functor &functor) -{ - GlobalSelectionSystem().foreachSelected(PatchSelectedVisitor(functor)); -} - - -template -class PatchVisibleSelectedVisitor : public SelectionSystem::Visitor { -const Functor &m_functor; -public: -PatchVisibleSelectedVisitor(const Functor &functor) : m_functor(functor) -{ -} - -void visit(scene::Instance &instance) const -{ - PatchInstance *patch = Instance_getPatch(instance); - if (patch != 0 - && instance.path().top().get().visible()) { - m_functor(*patch); - } -} -}; - -template -inline void Scene_forEachVisibleSelectedPatchInstance(const Functor &functor) -{ - GlobalSelectionSystem().foreachSelected(PatchVisibleSelectedVisitor(functor)); -} - -template -class PatchForEachWalker : public scene::Graph::Walker { -const Functor &m_functor; -public: -PatchForEachWalker(const Functor &functor) : m_functor(functor) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Patch *patch = Node_getPatch(path.top()); - if (patch != 0) { - m_functor(*patch); - } - } - return true; -} -}; - -template -inline void Scene_forEachVisiblePatch(const Functor &functor) -{ - GlobalSceneGraph().traverse(PatchForEachWalker(functor)); -} - -template -class PatchForEachSelectedWalker : public scene::Graph::Walker { -const Functor &m_functor; -public: -PatchForEachSelectedWalker(const Functor &functor) : m_functor(functor) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Patch *patch = Node_getPatch(path.top()); - if (patch != 0 - && Instance_getSelectable(instance)->isSelected()) { - m_functor(*patch); - } - } - return true; -} -}; - -template -inline void Scene_forEachVisibleSelectedPatch(const Functor &functor) -{ - GlobalSceneGraph().traverse(PatchForEachSelectedWalker(functor)); -} - -template -class PatchForEachInstanceWalker : public scene::Graph::Walker { -const Functor &m_functor; -public: -PatchForEachInstanceWalker(const Functor &functor) : m_functor(functor) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - PatchInstance *patch = Instance_getPatch(instance); - if (patch != 0) { - m_functor(*patch); - } - } - return true; -} -}; - -template -inline void Scene_forEachVisiblePatchInstance(const Functor &functor) -{ - GlobalSceneGraph().traverse(PatchForEachInstanceWalker(functor)); -} - -#endif diff --git a/src/patchdialog.cpp b/src/patchdialog.cpp deleted file mode 100644 index 1362388..0000000 --- a/src/patchdialog.cpp +++ /dev/null @@ -1,1239 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Patch Dialog -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "patchdialog.h" - -#include - -#include "itexdef.h" - -#include "debugging/debugging.h" - -#include "gtkutil/idledraw.h" -#include "gtkutil/entry.h" -#include "gtkutil/button.h" -#include "gtkutil/nonmodal.h" -#include "dialog.h" -#include "gtkdlgs.h" -#include "mainframe.h" -#include "patchmanip.h" -#include "patch.h" -#include "commands.h" -#include "preferences.h" -#include "signal/isignal.h" - - -#include - -// the increment we are using for the patch inspector (this is saved in the prefs) -struct pi_globals_t { - float shift[2]; - float scale[2]; - float rotate; - - pi_globals_t() - { - shift[0] = 8.0f; - shift[1] = 8.0f; - scale[0] = 0.5f; - scale[1] = 0.5f; - rotate = 45.0f; - } -}; - -pi_globals_t g_pi_globals; - -class PatchFixedSubdivisions { -public: -PatchFixedSubdivisions() : m_enabled(false), m_x(0), m_y(0) -{ -} - -PatchFixedSubdivisions(bool enabled, std::size_t x, std::size_t y) : m_enabled(enabled), m_x(x), m_y(y) -{ -} - -bool m_enabled; -std::size_t m_x; -std::size_t m_y; -}; - -void Patch_getFixedSubdivisions(const Patch &patch, PatchFixedSubdivisions &subdivisions) -{ - subdivisions.m_enabled = patch.m_patchDef3; - subdivisions.m_x = patch.m_subdivisions_x; - subdivisions.m_y = patch.m_subdivisions_y; -} - -const std::size_t MAX_PATCH_SUBDIVISIONS = 32; - -void Patch_setFixedSubdivisions(Patch &patch, const PatchFixedSubdivisions &subdivisions) -{ - patch.undoSave(); - - patch.m_patchDef3 = subdivisions.m_enabled; - patch.m_subdivisions_x = subdivisions.m_x; - patch.m_subdivisions_y = subdivisions.m_y; - - if (patch.m_subdivisions_x || patch.m_subdivisions_y) - { - if (patch.m_subdivisions_x == 0) { - patch.m_subdivisions_x = 4; - } else if (patch.m_subdivisions_x > MAX_PATCH_SUBDIVISIONS) { - patch.m_subdivisions_x = MAX_PATCH_SUBDIVISIONS; - } - if (patch.m_subdivisions_y == 0) { - patch.m_subdivisions_y = 4; - } else if (patch.m_subdivisions_y > MAX_PATCH_SUBDIVISIONS) { - patch.m_subdivisions_y = MAX_PATCH_SUBDIVISIONS; - } - } - - SceneChangeNotify(); - Patch_textureChanged(); - patch.controlPointsChanged(); -} - -class PatchGetFixedSubdivisions { -PatchFixedSubdivisions &m_subdivisions; -public: -PatchGetFixedSubdivisions(PatchFixedSubdivisions &subdivisions) : m_subdivisions(subdivisions) -{ -} - -void operator()(Patch &patch) -{ - Patch_getFixedSubdivisions(patch, m_subdivisions); - SceneChangeNotify(); -} -}; - -void Scene_PatchGetFixedSubdivisions(PatchFixedSubdivisions &subdivisions) -{ -#if 1 - if (GlobalSelectionSystem().countSelected() != 0) { - Patch *patch = Node_getPatch(GlobalSelectionSystem().ultimateSelected().path().top()); - if (patch != 0) { - Patch_getFixedSubdivisions(*patch, subdivisions); - } - } -#else - Scene_forEachVisibleSelectedPatch( PatchGetFixedSubdivisions( subdivisions ) ); -#endif -} - -void Scene_PatchSetFixedSubdivisions(const PatchFixedSubdivisions &subdivisions) -{ - UndoableCommand command("patchSetFixedSubdivisions"); - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - Patch_setFixedSubdivisions(patch, subdivisions); - }); -} - - -class Subdivisions { -public: -gulong m_changeevent; -ui::ComboBoxText m_type; -// ui::CheckButton m_enabled; -ui::Entry m_horizontal; -ui::Entry m_vertical; - -Subdivisions() : m_type(ui::null), m_horizontal(ui::null), m_vertical(ui::null) -{ -} - -void update() -{ - PatchFixedSubdivisions subdivisions; - Scene_PatchGetFixedSubdivisions(subdivisions); - int mode = 0; - if (subdivisions.m_enabled) - { - if (subdivisions.m_x || subdivisions.m_y) - mode = 1; - else - mode = 2; - } - auto combo = GTK_COMBO_BOX_TEXT(m_type); - g_signal_handler_block(combo, m_changeevent); - gtk_combo_box_set_active(GTK_COMBO_BOX(combo), mode); - g_signal_handler_unblock(combo, m_changeevent); - - if (subdivisions.m_enabled && (subdivisions.m_x||subdivisions.m_y)) { - entry_set_int(m_horizontal, static_cast( subdivisions.m_x )); - entry_set_int(m_vertical, static_cast( subdivisions.m_y )); - gtk_widget_set_sensitive(m_horizontal, TRUE); - gtk_widget_set_sensitive(m_vertical, TRUE); - } else { - m_horizontal.text(""); - m_vertical.text(""); - gtk_widget_set_sensitive(m_horizontal, FALSE); - gtk_widget_set_sensitive(m_vertical, FALSE); - } -} - -void cancel() -{ - update(); -} - -typedef MemberCaller CancelCaller; - -void apply() -{ - auto patchtypetext = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(m_type)); - int patchtype; - if (!strcasecmp(patchtypetext, "Explicit")) - patchtype = 2; - else if (!strcasecmp(patchtypetext, "Fixed")) - patchtype = 1; - else - patchtype = 0; - auto horiz = static_cast( entry_get_int(m_horizontal)); - auto vert = static_cast( entry_get_int(m_vertical)); - if (patchtype == 2) - horiz = vert = 0; - else if (!horiz || !vert) - horiz = vert = 4; - - Scene_PatchSetFixedSubdivisions( - PatchFixedSubdivisions( - patchtype != 0, - horiz, - vert - ) - ); - - SceneChangeNotify(); -} - -typedef MemberCaller ApplyCaller; - -static void OnSelchangeComboPatchType(ui::ComboBoxText toggle, Subdivisions *self) -{ - self->apply(); -} -// static void applyGtk(ui::ToggleButton toggle, Subdivisions *self) -// { -// self->apply(); -// } -}; - -class PatchInspector : public Dialog { -ui::Window BuildDialog(); - -Subdivisions m_subdivisions; -NonModalEntry m_horizontalSubdivisionsEntry; -NonModalEntry m_verticalSubdivisionsEntry; -public: -IdleDraw m_idleDraw; -WindowPositionTracker m_position_tracker; - -Patch *m_Patch; - -CopiedString m_strName; -float m_fS; -float m_fT; -float m_fX; -float m_fY; -float m_fZ; -float m_fR; -float m_fG; -float m_fB; -float m_fA; -/* float m_fHScale; - float m_fHShift; - float m_fRotate; - float m_fVScale; - float m_fVShift; */ -int m_nCol; -int m_nRow; -ui::ComboBoxText m_pRowCombo{ui::null}; -ui::ComboBoxText m_pColCombo{ui::null}; -std::size_t m_countRows; -std::size_t m_countCols; - -// turn on/off processing of the "changed" "value_changed" messages -// (need to turn off when we are feeding data in) -// NOTE: much more simple than blocking signals -bool m_bListenChanged; - -PatchInspector() : - m_horizontalSubdivisionsEntry(Subdivisions::ApplyCaller(m_subdivisions), - Subdivisions::CancelCaller(m_subdivisions)), - m_verticalSubdivisionsEntry(Subdivisions::ApplyCaller(m_subdivisions), - Subdivisions::CancelCaller(m_subdivisions)), - m_idleDraw(MemberCaller(*this)) -{ - m_fS = 0.0f; - m_fT = 0.0f; - m_fX = 0.0f; - m_fY = 0.0f; - m_fZ = 0.0f; - m_fR = 1.f; - m_fG = 1.f; - m_fB = 1.f; - m_fA = 1.f; - m_nCol = 0; - m_nRow = 0; - m_countRows = 0; - m_countCols = 0; - m_Patch = 0; - m_bListenChanged = true; - - m_position_tracker.setPosition(c_default_window_pos); -} - -bool visible() -{ - return GetWidget().visible(); -} - -// void UpdateInfo(); -// void SetPatchInfo(); -void GetPatchInfo(); - -void UpdateSpinners(bool bUp, int nID); - -// read the current patch on map and initialize m_fX m_fY accordingly -void UpdateRowColInfo(); - -// sync the dialog our internal data structures -// depending on the flag it will read or write -// we use m_nCol m_nRow m_fX m_fY m_fZ m_fS m_fT m_strName -// (NOTE: this doesn't actually commit stuff to the map or read from it) -void importData(); - -void exportData(); -}; - -PatchInspector g_PatchInspector; - -bool PatchInspector_IsSelected(int x, int y) -{ - if (g_PatchInspector.m_nCol == x && g_PatchInspector.m_nRow == y) { - return true; - } - return false; -} - -void PatchInspector_constructWindow(ui::Window main_window) -{ - g_PatchInspector.m_parent = main_window; - g_PatchInspector.Create(); -} - -void PatchInspector_destroyWindow() -{ - g_PatchInspector.Destroy(); -} - -void PatchInspector_queueDraw() -{ - if (g_PatchInspector.visible()) { - g_PatchInspector.m_idleDraw.queueDraw(); - } -} - -void DoPatchInspector() -{ - g_PatchInspector.GetPatchInfo(); - if (!g_PatchInspector.visible()) { - g_PatchInspector.ShowDlg(); - } -} - -void PatchInspector_toggleShown() -{ - if (g_PatchInspector.visible()) { - g_PatchInspector.m_Patch = 0; - g_PatchInspector.HideDlg(); - } else { - DoPatchInspector(); - } -} - - -// ============================================================================= -// static functions - -// memorize the current state (that is don't try to undo our do before changing something else) -static void OnApply(ui::Widget widget, gpointer data) -{ - g_PatchInspector.exportData(); - if (g_PatchInspector.m_Patch != 0) { - UndoableCommand command("patchSetTexture"); - g_PatchInspector.m_Patch->undoSave(); - - if (!texdef_name_valid(g_PatchInspector.m_strName.c_str())) { - globalErrorStream() << "invalid texture name '" << g_PatchInspector.m_strName.c_str() << "'\n"; - g_PatchInspector.m_strName = texdef_name_default(); - } - g_PatchInspector.m_Patch->SetShader(g_PatchInspector.m_strName.c_str()); - - std::size_t r = g_PatchInspector.m_nRow; - std::size_t c = g_PatchInspector.m_nCol; - if (r < g_PatchInspector.m_Patch->getHeight() - && c < g_PatchInspector.m_Patch->getWidth()) { - PatchControl &p = g_PatchInspector.m_Patch->ctrlAt(r, c); - p.m_vertex[0] = g_PatchInspector.m_fX; - p.m_vertex[1] = g_PatchInspector.m_fY; - p.m_vertex[2] = g_PatchInspector.m_fZ; - p.m_texcoord[0] = g_PatchInspector.m_fS; - p.m_texcoord[1] = g_PatchInspector.m_fT; - p.m_color[0] = g_PatchInspector.m_fR; - p.m_color[1] = g_PatchInspector.m_fG; - p.m_color[2] = g_PatchInspector.m_fB; - p.m_color[3] = g_PatchInspector.m_fA; - g_PatchInspector.m_Patch->controlPointsChanged(); - } - } -} - -static void OnSelchangeComboColRow(ui::Widget widget, gpointer data) -{ - if (!g_PatchInspector.m_bListenChanged) { - return; - } - // retrieve the current m_nRow and m_nCol, other params are not relevant - g_PatchInspector.exportData(); - // read the changed values ourselves - g_PatchInspector.UpdateRowColInfo(); - // now reflect our changes - g_PatchInspector.importData(); - - if (g_PatchInspector.m_Patch) - g_PatchInspector.m_Patch->controlPointsChanged(); -} - -void Scene_PatchTileTexture_Selected(scene::Graph &graph, float s, float t) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.SetTextureRepeat(s, t); - }); - SceneChangeNotify(); -} - -static void OnBtnPatchdetails(ui::Widget widget, gpointer data) -{ - Patch_CapTexture(); -} - -static void OnBtnPatchfit(ui::Widget widget, gpointer data) -{ - Patch_FitTexture(); -} - -static void OnBtnPatchnatural(ui::Widget widget, gpointer data) -{ - Patch_NaturalTexture(); -} - -static void OnBtnPatchreset(ui::Widget widget, gpointer data) -{ - Patch_ResetTexture(); -} - -static void OnBtnPatchFlipX(ui::Widget widget, gpointer data) -{ - Patch_FlipTextureX(); -} - -static void OnBtnPatchFlipY(ui::Widget widget, gpointer data) -{ - Patch_FlipTextureY(); -} - -void Scene_PatchRotateTexture_Selected(scene::Graph &graph, float angle) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.RotateTexture(angle); - }); -} - -float Patch_convertScale(float scale) -{ - if (scale > 0) { - return scale; - } - if (scale < 0) { - return -1 / scale; - } - return 1; -} - -void Scene_PatchScaleTexture_Selected(scene::Graph &graph, float s, float t) -{ - s = Patch_convertScale(s); - t = Patch_convertScale(t); - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.ScaleTexture(s, t); - }); -} - -void Scene_PatchTranslateTexture_Selected(scene::Graph &graph, float s, float t) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.TranslateTexture(s, t); - }); -} - -static void OnBtnPatchAutoCap(ui::Widget widget, gpointer data) -{ - Patch_AutoCapTexture(); -} - -static void OnSpinChanged(ui::Adjustment adj, gpointer data) -{ - texdef_t td; - - td.rotate = 0; - td.scale[0] = td.scale[1] = 0; - td.shift[0] = td.shift[1] = 0; - - if (gtk_adjustment_get_value(adj) == 0) { - return; - } - - if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "hshift_adj")) { - g_pi_globals.shift[0] = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - - if (gtk_adjustment_get_value(adj) > 0) { - td.shift[0] = g_pi_globals.shift[0]; - } else { - td.shift[0] = -g_pi_globals.shift[0]; - } - } else if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "vshift_adj")) { - g_pi_globals.shift[1] = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - - if (gtk_adjustment_get_value(adj) > 0) { - td.shift[1] = g_pi_globals.shift[1]; - } else { - td.shift[1] = -g_pi_globals.shift[1]; - } - } else if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "hscale_adj")) { - g_pi_globals.scale[0] = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - if (g_pi_globals.scale[0] == 0.0f) { - return; - } - if (gtk_adjustment_get_value(adj) > 0) { - td.scale[0] = g_pi_globals.scale[0]; - } else { - td.scale[0] = -g_pi_globals.scale[0]; - } - } else if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "vscale_adj")) { - g_pi_globals.scale[1] = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - if (g_pi_globals.scale[1] == 0.0f) { - return; - } - if (gtk_adjustment_get_value(adj) > 0) { - td.scale[1] = g_pi_globals.scale[1]; - } else { - td.scale[1] = -g_pi_globals.scale[1]; - } - } else if (adj == g_object_get_data(G_OBJECT(g_PatchInspector.GetWidget()), "rotate_adj")) { - g_pi_globals.rotate = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(data)))); - - if (gtk_adjustment_get_value(adj) > 0) { - td.rotate = g_pi_globals.rotate; - } else { - td.rotate = -g_pi_globals.rotate; - } - } - - gtk_adjustment_set_value(adj, 0); - - // will scale shift rotate the patch accordingly - if (td.shift[0] || td.shift[1]) { - UndoableCommand command("patchTranslateTexture"); - Scene_PatchTranslateTexture_Selected(GlobalSceneGraph(), td.shift[0], td.shift[1]); - } else if (td.scale[0] || td.scale[1]) { - UndoableCommand command("patchScaleTexture"); - Scene_PatchScaleTexture_Selected(GlobalSceneGraph(), td.scale[0], td.scale[1]); - } else if (td.rotate) { - UndoableCommand command("patchRotateTexture"); - Scene_PatchRotateTexture_Selected(GlobalSceneGraph(), td.rotate); - } else { - /* we don't want to do this on locked patches - eukara */ - // update the point-by-point view - OnSelchangeComboColRow(ui::root, 0); - } -} - -static gint OnDialogKey(ui::Widget widget, GdkEventKey *event, gpointer data) -{ - if (event->keyval == GDK_KEY_Return) { - OnApply(ui::root, 0); - return TRUE; - } else if (event->keyval == GDK_KEY_Escape) { - g_PatchInspector.GetPatchInfo(); - return TRUE; - } - return FALSE; -} - -// ============================================================================= -// PatchInspector class - -ui::Window PatchInspector::BuildDialog() -{ - ui::Window window = ui::Window(create_floating_window("Patch Properties", m_parent)); - - m_position_tracker.connect(window); - - global_accel_connect_window(window); - - window_connect_focus_in_clear_focus_widget(window); - - - { - auto vbox = ui::VBox(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - vbox.show(); - window.add(vbox); - { - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - vbox.pack_start(hbox, TRUE, TRUE, 0); - { - auto vbox2 = ui::VBox(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 0); - vbox2.show(); - hbox.pack_start(vbox2, TRUE, TRUE, 0); - { - auto frame = ui::Frame("Details"); - frame.show(); - vbox2.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(vbox3), 5); - vbox3.show(); - frame.add(vbox3); - { - auto table = ui::Table(2, 2, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - { - auto label = ui::Label("Row:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - } - { - auto label = ui::Label("Column:"); - label.show(); - table.attach(label, {1, 2, 0, 1}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - } - { - auto combo = ui::ComboBoxText(ui::New); - combo.connect("changed", G_CALLBACK(OnSelchangeComboColRow), this); - AddDialogData(combo, m_nRow); - - combo.show(); - table.attach(combo, {0, 1, 1, 2}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - combo.dimensions(60, -1); - m_pRowCombo = combo; - } - - { - auto combo = ui::ComboBoxText(ui::New); - combo.connect("changed", G_CALLBACK(OnSelchangeComboColRow), this); - AddDialogData(combo, m_nCol); - - combo.show(); - table.attach(combo, {1, 2, 1, 2}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - combo.dimensions(60, -1); - m_pColCombo = combo; - } - } - auto table = ui::Table(5, 2, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - { - auto label = ui::Label("X:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("Y:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("Z:"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("S:"); - label.show(); - table.attach(label, {0, 1, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("T:"); - label.show(); - table.attach(label, {0, 1, 4, 5}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("R:"); - label.show(); - table.attach(label, {0, 1, 5, 6}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("G:"); - label.show(); - table.attach(label, {0, 1, 6, 7}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("B:"); - label.show(); - table.attach(label, {0, 1, 7, 8}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto label = ui::Label("A:"); - label.show(); - table.attach(label, {0, 1, 8, 9}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fX); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fY); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fZ); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fS); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 4, 5}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fT); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 5, 6}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fR); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 6, 7}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fG); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 7, 8}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fB); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 8, 9}, {GTK_EXPAND | GTK_FILL, 0}); - AddDialogData(entry, m_fA); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - } - } - { - auto frame = ui::Frame("Tesselation"); - frame.show(); - vbox2.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(vbox3), 5); - vbox3.show(); - frame.add(vbox3); - { - auto table = ui::Table(3, 2, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - { - auto label = ui::Label("Type"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto combo = ui::ComboBoxText(ui::New); - gtk_combo_box_text_append_text(combo, "Auto"); - gtk_combo_box_text_append_text(combo, "Fixed"); //patchDef3 - gtk_combo_box_text_append_text(combo, "Explicit"); - m_subdivisions.m_changeevent = combo.connect("changed", G_CALLBACK(Subdivisions::OnSelchangeComboPatchType), &m_subdivisions); -// AddDialogData(combo, m_nRow); - - combo.show(); - table.attach(combo, {1, 2, 0, 1}, - {(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0)}, - {0, 0}); - combo.dimensions(60, -1); - m_subdivisions.m_type = combo; - } - - /* - { - auto label = ui::Label("Fixed"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto check = ui::CheckButton::from(gtk_check_button_new()); - check.show(); - table.attach(check, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - m_subdivisions.m_enabled = check; - guint handler_id = check.connect("toggled", G_CALLBACK(&Subdivisions::applyGtk), - &m_subdivisions); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer(handler_id)); - }*/ - { - auto label = ui::Label("Horizontal"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - m_subdivisions.m_horizontal = entry; - m_horizontalSubdivisionsEntry.connect(entry); - } - { - auto label = ui::Label("Vertical"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - m_subdivisions.m_vertical = entry; - m_verticalSubdivisionsEntry.connect(entry); - } - } - } - } - } - { - auto frame = ui::Frame("Texturing"); - frame.show(); - hbox.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox2 = ui::VBox(FALSE, 5); - vbox2.show(); - frame.add(vbox2); - gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); - { - auto label = ui::Label("Name:"); - label.show(); - vbox2.pack_start(label, TRUE, TRUE, 0); - gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto entry = ui::Entry(ui::New); - // gtk_editable_set_editable (GTK_ENTRY (entry), false); - entry.show(); - vbox2.pack_start(entry, TRUE, TRUE, 0); - AddDialogData(entry, m_strName); - - entry.connect("key_press_event", G_CALLBACK(OnDialogKey), 0); - } - { - auto table = ui::Table(5, 4, FALSE); - table.show(); - vbox2.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - { - auto label = ui::Label("Horizontal Shift Step"); - label.show(); - table.attach(label, {2, 4, 0, 1}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Vertical Shift Step"); - label.show(); - table.attach(label, {2, 4, 1, 2}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Horizontal Stretch Step"); - label.show(); - table.attach(label, {2, 3, 2, 3}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto button = ui::Button("Flip"); - button.show(); - table.attach(button, {3, 4, 2, 3}, {GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnBtnPatchFlipX), 0); - button.dimensions(60, -1); - } - { - auto label = ui::Label("Vertical Stretch Step"); - label.show(); - table.attach(label, {2, 3, 3, 4}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto button = ui::Button("Flip"); - button.show(); - table.attach(button, {3, 4, 3, 4}, {GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnBtnPatchFlipY), 0); - button.dimensions(60, -1); - } - { - auto label = ui::Label("Rotate Step"); - label.show(); - table.attach(label, {2, 4, 4, 5}, {GTK_FILL | GTK_EXPAND, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 0, 1}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - g_object_set_data(G_OBJECT(window), "hshift_entry", (void *) entry); - // we fill in this data, if no patch is selected the widgets are unmodified when the inspector is raised - // so we need to have at least one initialisation somewhere - entry_set_float(entry, g_pi_globals.shift[0]); - - auto adj = ui::Adjustment(0, -8192, 8192, 1, 1, 0); - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), (gpointer) entry); - g_object_set_data(G_OBJECT(window), "hshift_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 0, 1}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 1, 2}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - entry_set_float(entry, g_pi_globals.shift[1]); - - auto adj = ui::Adjustment(0, -8192, 8192, 1, 1, 0); - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), entry); - g_object_set_data(G_OBJECT(window), "vshift_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 1, 2}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 2, 3}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - entry_set_float(entry, g_pi_globals.scale[0]); - - auto adj = ui::Adjustment(0, -1000, 1000, 1, 1, 0); - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), entry); - g_object_set_data(G_OBJECT(window), "hscale_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 2, 3}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 3, 4}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - entry_set_float(entry, g_pi_globals.scale[1]); - - auto adj = ui::Adjustment(0, -1000, 1000, 1, 1, 0); - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), entry); - g_object_set_data(G_OBJECT(window), "vscale_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 3, 4}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {0, 1, 4, 5}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - entry_set_float(entry, g_pi_globals.rotate); - - auto adj = ui::Adjustment(0, -1000, 1000, 1, 1, - 0); // NOTE: Arnout - this really should be 360 but can't change it anymore as it could break existing maps - adj.connect("value_changed", G_CALLBACK(OnSpinChanged), entry); - g_object_set_data(G_OBJECT(window), "rotate_adj", (gpointer) adj); - - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 4, 5}, {0, 0}); - spin.dimensions(10, -1); - gtk_widget_set_can_focus(spin, false); - } - } - auto hbox2 = ui::HBox(TRUE, 5); - hbox2.show(); - vbox2.pack_start(hbox2, TRUE, FALSE, 0); - { - auto button = ui::Button("Auto Cap"); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchAutoCap), 0); - button.dimensions(60, -1); - } - { - auto button = ui::Button("CAP"); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchdetails), 0); - button.dimensions(60, -1); - } - { - auto button = ui::Button("Set..."); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchreset), 0); - button.dimensions(60, -1); - } - { - auto button = ui::Button("Natural"); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchnatural), 0); - button.dimensions(60, -1); - } - { - auto button = ui::Button("Fit"); - button.show(); - hbox2.pack_end(button, TRUE, FALSE, 0); - button.connect("clicked", G_CALLBACK(OnBtnPatchfit), 0); - button.dimensions(60, -1); - } - } - } - } - } - - /* make small */ - gtk_window_set_default_size(GTK_WINDOW(window), 8, 8); - return window; -} - -// sync the dialog our internal data structures -void PatchInspector::exportData() -{ - m_bListenChanged = false; - Dialog::exportData(); - m_bListenChanged = true; -} - -void PatchInspector::importData() -{ - m_bListenChanged = false; - Dialog::importData(); - m_bListenChanged = true; -} - -// read the map and feed in the stuff to the dialog box -void PatchInspector::GetPatchInfo() -{ - { - m_subdivisions.update(); - } - - if (GlobalSelectionSystem().countSelected() == 0) { - m_Patch = 0; - } else { - m_Patch = Node_getPatch(GlobalSelectionSystem().ultimateSelected().path().top()); - } - - if (m_Patch != 0) { - m_strName = m_Patch->GetShader(); - - // fill in the numbers for Row / Col selection - m_bListenChanged = false; - - { - gtk_combo_box_set_active(m_pRowCombo, 0); - - for (std::size_t i = 0; i < m_countRows; ++i) { - gtk_combo_box_text_remove(m_pRowCombo, gint(m_countRows - i - 1)); - } - - m_countRows = m_Patch->getHeight(); - for (std::size_t i = 0; i < m_countRows; ++i) { - char buffer[16]; - sprintf(buffer, "%u", Unsigned(i)); - gtk_combo_box_text_append_text(m_pRowCombo, buffer); - } - - gtk_combo_box_set_active(m_pRowCombo, 0); - } - - { - gtk_combo_box_set_active(m_pColCombo, 0); - - for (std::size_t i = 0; i < m_countCols; ++i) { - gtk_combo_box_text_remove(m_pColCombo, gint(m_countCols - i - 1)); - } - - m_countCols = m_Patch->getWidth(); - for (std::size_t i = 0; i < m_countCols; ++i) { - char buffer[16]; - sprintf(buffer, "%u", Unsigned(i)); - gtk_combo_box_text_append_text(m_pColCombo, buffer); - } - - gtk_combo_box_set_active(m_pColCombo, 0); - } - - m_bListenChanged = true; - - } else { - //globalOutputStream() << "WARNING: no patch\n"; - } - // fill in our internal structs - m_nRow = 0; - m_nCol = 0; - UpdateRowColInfo(); - // now update the dialog box - importData(); -} - -// read the current patch on map and initialize m_fX m_fY accordingly -// NOTE: don't call UpdateData in there, it's not meant for -void PatchInspector::UpdateRowColInfo() -{ - m_fX = m_fY = m_fZ = m_fS = m_fT = 0.0; - m_fR = m_fG = m_fB = m_fA = 1; - - if (m_Patch != 0) { - // we rely on whatever active row/column has been set before we get called - std::size_t r = m_nRow; - std::size_t c = m_nCol; - if (r < m_Patch->getHeight() - && c < m_Patch->getWidth()) { - const PatchControl &p = m_Patch->ctrlAt(r, c); - m_fX = p.m_vertex[0]; - m_fY = p.m_vertex[1]; - m_fZ = p.m_vertex[2]; - m_fS = p.m_texcoord[0]; - m_fT = p.m_texcoord[1]; - m_fR = p.m_color[0]; - m_fG = p.m_color[1]; - m_fB = p.m_color[2]; - m_fA = p.m_color[3]; - } - } -} - - -void PatchInspector_SelectionChanged(const Selectable &selectable) -{ - PatchInspector_queueDraw(); -} - - -#include "preferencesystem.h" - - -void PatchInspector_Construct() -{ - GlobalCommands_insert("PatchInspector", makeCallbackF(PatchInspector_toggleShown), - Accelerator('S', (GdkModifierType) GDK_SHIFT_MASK)); - - GlobalPreferenceSystem().registerPreference("PatchWnd", make_property( - g_PatchInspector.m_position_tracker)); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Scale1", make_property_string(g_pi_globals.scale[0])); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Scale2", make_property_string(g_pi_globals.scale[1])); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Shift1", make_property_string(g_pi_globals.shift[0])); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Shift2", make_property_string(g_pi_globals.shift[1])); - GlobalPreferenceSystem().registerPreference("SI_PatchTexdef_Rotate", make_property_string(g_pi_globals.rotate)); - - typedef FreeCaller PatchInspectorSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(PatchInspectorSelectionChangedCaller()); - typedef FreeCaller PatchInspectorQueueDrawCaller; - Patch_addTextureChangedCallback(PatchInspectorQueueDrawCaller()); -} - -void PatchInspector_Destroy() -{ -} diff --git a/src/patchdialog.h b/src/patchdialog.h deleted file mode 100644 index 38f52eb..0000000 --- a/src/patchdialog.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_PATCHDIALOG_H ) -#define INCLUDED_PATCHDIALOG_H - -void PatchInspector_Construct(); - -void PatchInspector_Destroy(); - -void PatchInspector_constructWindow(ui::Window main_window); - -void PatchInspector_destroyWindow(); - -namespace scene { -class Graph; -} - -void Scene_PatchTranslateTexture_Selected(scene::Graph &graph, float s, float t); - -void Scene_PatchRotateTexture_Selected(scene::Graph &graph, float angle); - -void Scene_PatchScaleTexture_Selected(scene::Graph &graph, float s, float t); - - -#endif diff --git a/src/patchmanip.cpp b/src/patchmanip.cpp deleted file mode 100644 index 42c5e39..0000000 --- a/src/patchmanip.cpp +++ /dev/null @@ -1,1137 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "patchmanip.h" - -#include -#include - -#include "debugging/debugging.h" - - -#include "iselection.h" -#include "ipatch.h" - -#include "math/vector.h" -#include "math/aabb.h" -#include "generic/callback.h" - -#include "gtkutil/menu.h" -#include "gtkutil/image.h" -#include "map.h" -#include "mainframe.h" -#include "commands.h" -#include "gtkmisc.h" -#include "gtkdlgs.h" -#include "texwindow.h" -#include "xywindow.h" -#include "select.h" -#include "patch.h" -#include "grid.h" - -PatchCreator *g_patchCreator = 0; - -void Scene_PatchConstructPrefab(scene::Graph &graph, const AABB aabb, const char *shader, EPatchPrefab eType, int axis, - std::size_t width = 3, std::size_t height = 3, int patchtype=0) -{ - Select_Delete(); - GlobalSelectionSystem().setSelectedAll(false); - - NodeSmartReference node(g_patchCreator->createPatch(patchtype!=0, true)); - Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(node); - - Patch *patch = Node_getPatch(node); - patch->SetShader(shader); - - if (patchtype==1) - { - patch->m_subdivisions_x = 4; - patch->m_subdivisions_y = 4; - } - - patch->ConstructPrefab(aabb, eType, axis, width, height); - patch->controlPointsChanged(); - - { - scene::Path patchpath(makeReference(GlobalSceneGraph().root())); - patchpath.push(makeReference(*Map_GetWorldspawn(g_map))); - patchpath.push(makeReference(node.get())); - Instance_getSelectable(*graph.find(patchpath))->setSelected(true); - } -} - -void PatchAutoCapTexture(Patch &patch) -{ - - AABB box = patch.localAABB(); - float x = box.extents.x(); - float y = box.extents.y(); - float z = box.extents.z(); - - int cap_direction = -1; - if (x < y && x < z) { - cap_direction = 0; - } else if (y < x && y < z) { - cap_direction = 1; - } else if (z < x && z < x) { - cap_direction = 2; - } - - if (cap_direction >= 0) { - patch.ProjectTexture(cap_direction); - } else { - patch.NaturalTexture(); - } -} - -void Patch_AutoCapTexture() -{ - UndoableCommand command("patchAutoCapTexture"); - Scene_forEachVisibleSelectedPatch(&PatchAutoCapTexture); - SceneChangeNotify(); -} - -void Patch_makeCaps(Patch &patch, scene::Instance &instance, EPatchCap type, const char *shader) -{ - if ((type == eCapEndCap || type == eCapIEndCap) - && patch.getWidth() != 5) { - globalErrorStream() << "cannot create end-cap - patch width != 5\n"; - return; - } - if ((type == eCapBevel || type == eCapIBevel) - && patch.getWidth() != 3 && patch.getWidth() != 5) { - globalErrorStream() << "cannot create bevel-cap - patch width != 3\n"; - return; - } - if (type == eCapCylinder - && patch.getWidth() != 9) { - globalErrorStream() << "cannot create cylinder-cap - patch width != 9\n"; - return; - } - - { - NodeSmartReference cap(g_patchCreator->createPatch(false, true)); - Node_getTraversable(instance.path().parent())->insert(cap); - - Patch *cap_patch = Node_getPatch(cap); - patch.MakeCap(cap_patch, type, ROW, true); - cap_patch->SetShader(shader); - PatchAutoCapTexture(*cap_patch); - - scene::Path path(instance.path()); - path.pop(); - path.push(makeReference(cap.get())); - selectPath(path, true); - } - - { - NodeSmartReference cap(g_patchCreator->createPatch(false, true)); - Node_getTraversable(instance.path().parent())->insert(cap); - - Patch *cap_patch = Node_getPatch(cap); - patch.MakeCap(cap_patch, type, ROW, false); - cap_patch->SetShader(shader); - PatchAutoCapTexture(*cap_patch); - - scene::Path path(instance.path()); - path.pop(); - path.push(makeReference(cap.get())); - selectPath(path, true); - } -} - -typedef std::vector InstanceVector; - -enum ECapDialog { - PATCHCAP_BEVEL = 0, - PATCHCAP_ENDCAP, - PATCHCAP_INVERTED_BEVEL, - PATCHCAP_INVERTED_ENDCAP, - PATCHCAP_CYLINDER -}; - -EMessageBoxReturn DoCapDlg(ECapDialog *type); - -void Scene_PatchDoCap_Selected(scene::Graph &graph, const char *shader) -{ - ECapDialog nType; - - if (DoCapDlg(&nType) == eIDOK) { - EPatchCap eType; - switch (nType) { - case PATCHCAP_INVERTED_BEVEL: - eType = eCapIBevel; - break; - case PATCHCAP_BEVEL: - eType = eCapBevel; - break; - case PATCHCAP_INVERTED_ENDCAP: - eType = eCapIEndCap; - break; - case PATCHCAP_ENDCAP: - eType = eCapEndCap; - break; - case PATCHCAP_CYLINDER: - eType = eCapCylinder; - break; - default: - ERROR_MESSAGE("invalid patch cap type"); - return; - } - - InstanceVector instances; - Scene_forEachVisibleSelectedPatchInstance([&](PatchInstance &patch) { - instances.push_back(&patch); - }); - for (InstanceVector::const_iterator i = instances.begin(); i != instances.end(); ++i) { - Patch_makeCaps(*Node_getPatch((*i)->path().top()), *(*i), eType, shader); - } - } -} - -Patch *Scene_GetUltimateSelectedVisiblePatch() -{ - if (GlobalSelectionSystem().countSelected() != 0) { - scene::Node &node = GlobalSelectionSystem().ultimateSelected().path().top(); - if (node.visible()) { - return Node_getPatch(node); - } - } - return 0; -} - - -void Scene_PatchCapTexture_Selected(scene::Graph &graph) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.ProjectTexture(Patch::m_CycleCapIndex); - }); - Patch::m_CycleCapIndex = (Patch::m_CycleCapIndex == 0) ? 1 : (Patch::m_CycleCapIndex == 1) ? 2 : 0; - SceneChangeNotify(); -} - -void Scene_PatchFlipTexture_Selected(scene::Graph &graph, int axis) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.FlipTexture(axis); - }); -} - -void Scene_PatchNaturalTexture_Selected(scene::Graph &graph) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.NaturalTexture(); - }); - SceneChangeNotify(); -} - - -void Scene_PatchInsertRemove_Selected(scene::Graph &graph, bool bInsert, bool bColumn, bool bFirst) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.InsertRemove(bInsert, bColumn, bFirst); - }); -} - -void Scene_PatchInvert_Selected(scene::Graph &graph) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.InvertMatrix(); - }); -} - -void Scene_PatchRedisperse_Selected(scene::Graph &graph, EMatrixMajor major) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.Redisperse(major); - }); -} - -void Scene_PatchSmooth_Selected(scene::Graph &graph, EMatrixMajor major) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.Smooth(major); - }); -} - -void Scene_PatchTranspose_Selected(scene::Graph &graph) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.TransposeMatrix(); - }); -} - -void Scene_PatchSetShader_Selected(scene::Graph &graph, const char *name) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - patch.SetShader(name); - }); - SceneChangeNotify(); -} - -void Scene_PatchGetShader_Selected(scene::Graph &graph, CopiedString &name) -{ - Patch *patch = Scene_GetUltimateSelectedVisiblePatch(); - if (patch != 0) { - name = patch->GetShader(); - } -} - -void Scene_PatchSelectByShader(scene::Graph &graph, const char *name) -{ - Scene_forEachVisiblePatchInstance([&](PatchInstance &patch) { - if (shader_equal(patch.getPatch().GetShader(), name)) { - patch.setSelected(true); - } - }); -} - - -void Scene_PatchFindReplaceShader(scene::Graph &graph, const char *find, const char *replace) -{ - Scene_forEachVisiblePatch([&](Patch &patch) { - if (shader_equal(patch.GetShader(), find)) { - patch.SetShader(replace); - } - }); -} - -void Scene_PatchFindReplaceShader_Selected(scene::Graph &graph, const char *find, const char *replace) -{ - Scene_forEachVisibleSelectedPatch([&](Patch &patch) { - if (shader_equal(patch.GetShader(), find)) { - patch.SetShader(replace); - } - }); -} - - -AABB PatchCreator_getBounds() -{ - AABB aabb(aabb_for_minmax(Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max)); - - float gridSize = GetGridSize(); - - if (aabb.extents[0] == 0) { - aabb.extents[0] = gridSize; - } - if (aabb.extents[1] == 0) { - aabb.extents[1] = gridSize; - } - if (aabb.extents[2] == 0) { - aabb.extents[2] = gridSize; - } - - if (aabb_valid(aabb)) { - return aabb; - } - return AABB(Vector3(0, 0, 0), Vector3(64, 64, 64)); -} - -void DoNewPatchDlg(EPatchPrefab prefab, int minrows, int mincols, int defrows, int defcols, int maxrows, int maxcols); - -void Patch_XactCylinder() -{ - UndoableCommand undo("patchCreateXactCylinder"); - - DoNewPatchDlg(eXactCylinder, 3, 7, 3, 13, 0, 0); -} - -void Patch_XactSphere() -{ - UndoableCommand undo("patchCreateXactSphere"); - - DoNewPatchDlg(eXactSphere, 5, 7, 7, 13, 0, 0); -} - -void Patch_XactCone() -{ - UndoableCommand undo("patchCreateXactCone"); - - DoNewPatchDlg(eXactCone, 3, 7, 3, 13, 0, 0); -} - -void Patch_Cylinder() -{ - UndoableCommand undo("patchCreateCylinder"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eCylinder, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_DenseCylinder() -{ - UndoableCommand undo("patchCreateDenseCylinder"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eDenseCylinder, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_VeryDenseCylinder() -{ - UndoableCommand undo("patchCreateVeryDenseCylinder"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eVeryDenseCylinder, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_SquareCylinder() -{ - UndoableCommand undo("patchCreateSquareCylinder"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eSqCylinder, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_Endcap() -{ - UndoableCommand undo("patchCreateCaps"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eEndCap, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_Bevel() -{ - UndoableCommand undo("patchCreateBevel"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eBevel, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_Sphere() -{ - UndoableCommand undo("patchCreateSphere"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eSphere, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_SquareBevel() -{ -} - -void Patch_SquareEndcap() -{ -} - -void Patch_Cone() -{ - UndoableCommand undo("patchCreateCone"); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), eCone, - GlobalXYWnd_getCurrentViewType()); -} - -void Patch_Plane() -{ - UndoableCommand undo("patchCreatePlane"); - - DoNewPatchDlg(ePlane, 3, 3, 3, 3, 0, 0); -} - -void Patch_InsertInsertColumn() -{ - UndoableCommand undo("patchInsertColumns"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), true, true, false); -} - -void Patch_InsertAddColumn() -{ - UndoableCommand undo("patchAddColumns"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), true, true, true); -} - -void Patch_InsertInsertRow() -{ - UndoableCommand undo("patchInsertRows"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), true, false, false); -} - -void Patch_InsertAddRow() -{ - UndoableCommand undo("patchAddRows"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), true, false, true); -} - -void Patch_DeleteFirstColumn() -{ - UndoableCommand undo("patchDeleteFirstColumns"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), false, true, true); -} - -void Patch_DeleteLastColumn() -{ - UndoableCommand undo("patchDeleteLastColumns"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), false, true, false); -} - -void Patch_DeleteFirstRow() -{ - UndoableCommand undo("patchDeleteFirstRows"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), false, false, true); -} - -void Patch_DeleteLastRow() -{ - UndoableCommand undo("patchDeleteLastRows"); - - Scene_PatchInsertRemove_Selected(GlobalSceneGraph(), false, false, false); -} - -void Patch_Invert() -{ - UndoableCommand undo("patchInvert"); - - Scene_PatchInvert_Selected(GlobalSceneGraph()); -} - -void Patch_RedisperseRows() -{ - UndoableCommand undo("patchRedisperseRows"); - - Scene_PatchRedisperse_Selected(GlobalSceneGraph(), ROW); -} - -void Patch_RedisperseCols() -{ - UndoableCommand undo("patchRedisperseColumns"); - - Scene_PatchRedisperse_Selected(GlobalSceneGraph(), COL); -} - -void Patch_SmoothRows() -{ - UndoableCommand undo("patchSmoothRows"); - - Scene_PatchSmooth_Selected(GlobalSceneGraph(), ROW); -} - -void Patch_SmoothCols() -{ - UndoableCommand undo("patchSmoothColumns"); - - Scene_PatchSmooth_Selected(GlobalSceneGraph(), COL); -} - -void Patch_Transpose() -{ - UndoableCommand undo("patchTranspose"); - - Scene_PatchTranspose_Selected(GlobalSceneGraph()); -} - -void Patch_Cap() -{ - // FIXME: add support for patch cap creation - // Patch_CapCurrent(); - UndoableCommand undo("patchCreateCaps"); - - Scene_PatchDoCap_Selected(GlobalSceneGraph(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); -} - -void Patch_CycleProjection() -{ - UndoableCommand undo("patchCycleUVProjectionAxis"); - - Scene_PatchCapTexture_Selected(GlobalSceneGraph()); -} - -///\todo Unfinished. -void Patch_OverlayOn() -{ -} - -///\todo Unfinished. -void Patch_OverlayOff() -{ -} - -void Patch_FlipTextureX() -{ - UndoableCommand undo("patchFlipTextureU"); - - Scene_PatchFlipTexture_Selected(GlobalSceneGraph(), 0); -} - -void Patch_FlipTextureY() -{ - UndoableCommand undo("patchFlipTextureV"); - - Scene_PatchFlipTexture_Selected(GlobalSceneGraph(), 1); -} - -void Patch_NaturalTexture() -{ - UndoableCommand undo("patchNaturalTexture"); - - 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); -} - -#include "ifilter.h" - - -class filter_patch_all : public PatchFilter { -public: -bool filter(const Patch &patch) const -{ - return true; -} -}; - -class filter_patch_shader : public PatchFilter { -const char *m_shader; -public: -filter_patch_shader(const char *shader) : m_shader(shader) -{ -} - -bool filter(const Patch &patch) const -{ - return shader_equal(patch.GetShader(), m_shader); -} -}; - -class filter_patch_flags : public PatchFilter { -int m_flags; -public: -filter_patch_flags(int flags) : m_flags(flags) -{ -} - -bool filter(const Patch &patch) const -{ - return (patch.getShaderFlags() & m_flags) != 0; -} -}; - - -filter_patch_all g_filter_patch_all; -filter_patch_shader g_filter_patch_clip("textures/common/clip"); -filter_patch_shader g_filter_patch_weapclip("textures/common/weapclip"); -filter_patch_flags g_filter_patch_translucent(QER_TRANS); - -void PatchFilters_construct() -{ - add_patch_filter(g_filter_patch_all, EXCLUDE_CURVES); - add_patch_filter(g_filter_patch_clip, EXCLUDE_CLIP); - add_patch_filter(g_filter_patch_weapclip, EXCLUDE_CLIP); - add_patch_filter(g_filter_patch_translucent, EXCLUDE_TRANSLUCENT); -} - - -#include "preferences.h" - -void Patch_constructPreferences(PreferencesPage &page) -{ - page.appendEntry("Patch Subdivide Threshold", g_PatchSubdivideThreshold); -} - -void Patch_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Patches", "Patch Display Preferences")); - Patch_constructPreferences(page); -} - -void Patch_registerPreferencesPage() -{ - PreferencesDialog_addDisplayPage(makeCallbackF(Patch_constructPage)); -} - - -#include "preferencesystem.h" - -void PatchPreferences_construct() -{ - GlobalPreferenceSystem().registerPreference("Subdivisions", make_property_string(g_PatchSubdivideThreshold)); -} - - -#include "generic/callback.h" - -void Patch_registerCommands() -{ - GlobalCommands_insert("InvertCurveTextureX", makeCallbackF(Patch_FlipTextureX), - Accelerator('I', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("InvertCurveTextureY", makeCallbackF(Patch_FlipTextureY), - Accelerator('I', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("NaturalizePatch", makeCallbackF(Patch_NaturalTexture), - Accelerator('N', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("PatchCylinder", makeCallbackF(Patch_Cylinder)); - GlobalCommands_insert("PatchDenseCylinder", makeCallbackF(Patch_DenseCylinder)); - GlobalCommands_insert("PatchVeryDenseCylinder", makeCallbackF(Patch_VeryDenseCylinder)); - GlobalCommands_insert("PatchSquareCylinder", makeCallbackF(Patch_SquareCylinder)); - GlobalCommands_insert("PatchXactCylinder", makeCallbackF(Patch_XactCylinder)); - GlobalCommands_insert("PatchXactSphere", makeCallbackF(Patch_XactSphere)); - GlobalCommands_insert("PatchXactCone", makeCallbackF(Patch_XactCone)); - GlobalCommands_insert("PatchEndCap", makeCallbackF(Patch_Endcap)); - GlobalCommands_insert("PatchBevel", makeCallbackF(Patch_Bevel)); - GlobalCommands_insert("PatchSquareBevel", makeCallbackF(Patch_SquareBevel)); - GlobalCommands_insert("PatchSquareEndcap", makeCallbackF(Patch_SquareEndcap)); - GlobalCommands_insert("PatchCone", makeCallbackF(Patch_Cone)); - GlobalCommands_insert("PatchSphere", makeCallbackF(Patch_Sphere)); - GlobalCommands_insert("SimplePatchMesh", makeCallbackF(Patch_Plane), - Accelerator('P', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("PatchInsertInsertColumn", makeCallbackF(Patch_InsertInsertColumn), - Accelerator(GDK_KEY_KP_Add, (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("PatchInsertAddColumn", makeCallbackF(Patch_InsertAddColumn)); - GlobalCommands_insert("PatchInsertInsertRow", makeCallbackF(Patch_InsertInsertRow), - Accelerator(GDK_KEY_KP_Add, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("PatchInsertAddRow", makeCallbackF(Patch_InsertAddRow)); - GlobalCommands_insert("PatchDeleteFirstColumn", makeCallbackF(Patch_DeleteFirstColumn)); - GlobalCommands_insert("PatchDeleteLastColumn", makeCallbackF(Patch_DeleteLastColumn), - Accelerator(GDK_KEY_KP_Subtract, (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("PatchDeleteFirstRow", makeCallbackF(Patch_DeleteFirstRow), - Accelerator(GDK_KEY_KP_Subtract, (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("PatchDeleteLastRow", makeCallbackF(Patch_DeleteLastRow)); - GlobalCommands_insert("InvertCurve", makeCallbackF(Patch_Invert), - Accelerator('I', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("RedisperseRows", makeCallbackF(Patch_RedisperseRows), - Accelerator('E', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("RedisperseCols", makeCallbackF(Patch_RedisperseCols), - Accelerator('E', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("SmoothRows", makeCallbackF(Patch_SmoothRows), - Accelerator('W', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("SmoothCols", makeCallbackF(Patch_SmoothCols), - Accelerator('W', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("MatrixTranspose", makeCallbackF(Patch_Transpose), - Accelerator('M', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("CapCurrentCurve", makeCallbackF(Patch_Cap), - Accelerator('C', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("CycleCapTexturePatch", makeCallbackF(Patch_CycleProjection), - Accelerator('N', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("MakeOverlayPatch", makeCallbackF(Patch_OverlayOn), Accelerator('Y')); - GlobalCommands_insert("ClearPatchOverlays", makeCallbackF(Patch_OverlayOff), - Accelerator('L', (GdkModifierType) GDK_CONTROL_MASK)); -} - -void Patch_constructToolbar(ui::Toolbar toolbar) -{ - toolbar_append_button(toolbar, "Put caps on the current patch", "cap_curve.xpm", "CapCurrentCurve"); -} - -void Patch_constructMenu(ui::Menu menu) -{ - create_menu_item_with_mnemonic(menu, "Cylinder", "PatchCylinder"); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "More Cylinders"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Dense Cylinder", "PatchDenseCylinder"); - create_menu_item_with_mnemonic(menu_in_menu, "Very Dense Cylinder", "PatchVeryDenseCylinder"); - create_menu_item_with_mnemonic(menu_in_menu, "Square Cylinder", "PatchSquareCylinder"); - create_menu_item_with_mnemonic(menu_in_menu, "Exact Cylinder...", "PatchXactCylinder"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "End cap", "PatchEndCap"); - create_menu_item_with_mnemonic(menu, "Bevel", "PatchBevel"); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "More End caps, Bevels"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Square Endcap", "PatchSquareBevel"); - create_menu_item_with_mnemonic(menu_in_menu, "Square Bevel", "PatchSquareEndcap"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Cone", "PatchCone"); - create_menu_item_with_mnemonic(menu, "Exact Cone...", "PatchXactCone"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Sphere", "PatchSphere"); - create_menu_item_with_mnemonic(menu, "Exact Sphere...", "PatchXactSphere"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Simple Patch Mesh...", "SimplePatchMesh"); - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Insert"); - /*if (g_Layout_enableOpenStepUX.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"); - 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"); - } - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Delete"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "First (2) Columns", "PatchDeleteFirstColumn"); - create_menu_item_with_mnemonic(menu_in_menu, "Last (2) Columns", "PatchDeleteLastColumn"); - menu_separator(menu_in_menu); - create_menu_item_with_mnemonic(menu_in_menu, "First (2) Rows", "PatchDeleteFirstRow"); - create_menu_item_with_mnemonic(menu_in_menu, "Last (2) Rows", "PatchDeleteLastRow"); - } - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Matrix"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Invert", "InvertCurve"); - auto menu_3 = create_sub_menu_with_mnemonic(menu_in_menu, "Re-disperse"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_3); - }*/ - create_menu_item_with_mnemonic(menu_3, "Rows", "RedisperseRows"); - create_menu_item_with_mnemonic(menu_3, "Columns", "RedisperseCols"); - auto menu_4 = create_sub_menu_with_mnemonic(menu_in_menu, "Smooth"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_4); - }*/ - create_menu_item_with_mnemonic(menu_4, "Rows", "SmoothRows"); - create_menu_item_with_mnemonic(menu_4, "Columns", "SmoothCols"); - create_menu_item_with_mnemonic(menu_in_menu, "Transpose", "MatrixTranspose"); - } - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Cap Selection", "CapCurrentCurve"); - create_menu_item_with_mnemonic(menu, "Cycle Cap Texture", "CycleCapTexturePatch"); - menu_separator(menu); - { - auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Overlay"); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu_in_menu); - }*/ - create_menu_item_with_mnemonic(menu_in_menu, "Set", "MakeOverlayPatch"); - create_menu_item_with_mnemonic(menu_in_menu, "Clear", "ClearPatchOverlays"); - } -} - - -#include "gtkutil/dialog.h" -#include "gtkutil/widget.h" - -void DoNewPatchDlg(EPatchPrefab prefab, int minrows, int mincols, int defrows, int defcols, int maxrows, int maxcols) -{ - ModalDialog dialog; - - ui::Window window = MainFrame_getWindow().create_dialog_window("Patch density", G_CALLBACK(dialog_delete_callback), - &dialog); - - auto accel = ui::AccelGroup(ui::New); - window.add_accel_group(accel); - auto width = ui::ComboBoxText(ui::New); - auto height = ui::ComboBoxText(ui::New); - auto type = ui::ComboBoxText(ui::New); - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - { - auto table = create_dialog_table(3, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - { - auto label = ui::Label("Width:"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Height:"); - label.show(); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - auto label = ui::Label("Type:"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_FILL, 0}); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - - { - auto combo = width; -#define D_ITEM(x) if ( x >= mincols && ( !maxcols || x <= maxcols ) ) gtk_combo_box_text_append_text( combo, #x ) - D_ITEM(3); - D_ITEM(5); - D_ITEM(7); - D_ITEM(9); - D_ITEM(11); - D_ITEM(13); - D_ITEM(15); - D_ITEM(17); - D_ITEM(19); - D_ITEM(21); - D_ITEM(23); - D_ITEM(25); - D_ITEM(27); - D_ITEM(29); - D_ITEM(31); // MAX_PATCH_SIZE is 32, so we should be able to do 31... -#undef D_ITEM - combo.show(); - table.attach(combo, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto combo = height; -#define D_ITEM(x) if ( x >= minrows && ( !maxrows || x <= maxrows ) ) gtk_combo_box_text_append_text( combo, #x ) - D_ITEM(3); - D_ITEM(5); - D_ITEM(7); - D_ITEM(9); - D_ITEM(11); - D_ITEM(13); - D_ITEM(15); - D_ITEM(17); - D_ITEM(19); - D_ITEM(21); - D_ITEM(23); - D_ITEM(25); - D_ITEM(27); - D_ITEM(29); - D_ITEM(31); // MAX_PATCH_SIZE is 32, so we should be able to do 31... -#undef D_ITEM - combo.show(); - table.attach(combo, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - } - { - auto combo = type; -#define D_ITEM(x) gtk_combo_box_text_append_text( combo, x ) - D_ITEM("Auto"); - D_ITEM("Fixed"); - D_ITEM("Explicit"); -#undef D_ITEM - combo.show(); - table.attach(combo, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - } - } - - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_grab_focus(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - } - } - - // Initialize dialog - gtk_combo_box_set_active(width, (defcols - mincols) / 2); - gtk_combo_box_set_active(height, (defrows - minrows) / 2); - gtk_combo_box_set_active(type, 0); - - if (modal_dialog_show(window, dialog) == eIDOK) { - int w = gtk_combo_box_get_active(width) * 2 + mincols; - int h = gtk_combo_box_get_active(height) * 2 + minrows; - int t = gtk_combo_box_get_active(type); - - Scene_PatchConstructPrefab(GlobalSceneGraph(), PatchCreator_getBounds(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser()), prefab, - GlobalXYWnd_getCurrentViewType(), w, h, t); - } - - window.destroy(); -} - - -EMessageBoxReturn DoCapDlg(ECapDialog *type) -{ - ModalDialog dialog; - ModalDialogButton ok_button(dialog, eIDOK); - ModalDialogButton cancel_button(dialog, eIDCANCEL); - ui::Widget bevel{ui::null}; - ui::Widget ibevel{ui::null}; - ui::Widget endcap{ui::null}; - ui::Widget iendcap{ui::null}; - ui::Widget cylinder{ui::null}; - - ui::Window window = MainFrame_getWindow().create_modal_dialog_window("Cap", dialog); - - auto accel_group = ui::AccelGroup(ui::New); - window.add_accel_group(accel_group); - - { - auto hbox = create_dialog_hbox(4, 4); - window.add(hbox); - - { - // Gef: Added a vbox to contain the toggle buttons - auto radio_vbox = create_dialog_vbox(4); - hbox.add(radio_vbox); - - { - auto table = ui::Table(5, 2, FALSE); - table.show(); - radio_vbox.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - - { - auto image = new_local_image("cap_bevel.xpm"); - image.show(); - table.attach(image, {0, 1, 0, 1}, {GTK_FILL, 0}); - } - { - auto image = new_local_image("cap_endcap.xpm"); - image.show(); - table.attach(image, {0, 1, 1, 2}, {GTK_FILL, 0}); - } - { - auto image = new_local_image("cap_ibevel.xpm"); - image.show(); - table.attach(image, {0, 1, 2, 3}, {GTK_FILL, 0}); - } - { - auto image = new_local_image("cap_iendcap.xpm"); - image.show(); - table.attach(image, {0, 1, 3, 4}, {GTK_FILL, 0}); - } - { - auto image = new_local_image("cap_cylinder.xpm"); - image.show(); - table.attach(image, {0, 1, 4, 5}, {GTK_FILL, 0}); - } - - GSList *group = 0; - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Bevel")); - button.show(); - table.attach(button, {1, 2, 0, 1}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - bevel = button; - } - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Endcap")); - button.show(); - table.attach(button, {1, 2, 1, 2}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - endcap = button; - } - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Inverted Bevel")); - button.show(); - table.attach(button, {1, 2, 2, 3}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - ibevel = button; - } - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Inverted Endcap")); - button.show(); - table.attach(button, {1, 2, 3, 4}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - iendcap = button; - } - { - ui::Widget button = ui::Widget::from(gtk_radio_button_new_with_label(group, "Cylinder")); - button.show(); - table.attach(button, {1, 2, 4, 5}, {GTK_FILL | GTK_EXPAND, 0}); - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); - - cylinder = button; - } - } - } - - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, FALSE, FALSE, 0); - { - auto button = create_modal_dialog_button("OK", ok_button); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Return, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - { - auto button = create_modal_dialog_button("Cancel", cancel_button); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType) 0, - GTK_ACCEL_VISIBLE); - } - } - } - - // Initialize dialog - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bevel), TRUE); - - EMessageBoxReturn ret = modal_dialog_show(window, dialog); - if (ret == eIDOK) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bevel))) { - *type = PATCHCAP_BEVEL; - } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(endcap))) { - *type = PATCHCAP_ENDCAP; - } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ibevel))) { - *type = PATCHCAP_INVERTED_BEVEL; - } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(iendcap))) { - *type = PATCHCAP_INVERTED_ENDCAP; - } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cylinder))) { - *type = PATCHCAP_CYLINDER; - } - } - - window.destroy(); - - return ret; -} diff --git a/src/patchmanip.h b/src/patchmanip.h deleted file mode 100644 index 151d59c..0000000 --- a/src/patchmanip.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_PATCHMANIP_H ) -#define INCLUDED_PATCHMANIP_H - -#include -#include "string/stringfwd.h" - -void Patch_registerCommands(); - -void Patch_constructToolbar(ui::Toolbar toolbar); - -void Patch_constructMenu(ui::Menu menu); - -namespace scene { -class Graph; -} - -void Scene_PatchSetShader_Selected(scene::Graph &graph, const char *name); - -void Scene_PatchGetShader_Selected(scene::Graph &graph, CopiedString &name); - -void Scene_PatchSelectByShader(scene::Graph &graph, const char *name); - -void Scene_PatchFindReplaceShader(scene::Graph &graph, const char *find, const char *replace); - -void Scene_PatchFindReplaceShader_Selected(scene::Graph &graph, const char *find, const char *replace); - -void Scene_PatchCapTexture_Selected(scene::Graph &graph); - -void Scene_PatchNaturalTexture_Selected(scene::Graph &graph); - -void Scene_PatchTileTexture_Selected(scene::Graph &graph, float s, float t); - -void PatchFilters_construct(); - -void PatchPreferences_construct(); - -void Patch_registerPreferencesPage(); - -void Patch_NaturalTexture(); - -void Patch_CapTexture(); - -void Patch_ResetTexture(); - -void Patch_FitTexture(); - -void Patch_FlipTextureX(); - -void Patch_FlipTextureY(); - -void Patch_AutoCapTexture(); - -class PatchCreator; - -extern PatchCreator *g_patchCreator; - -#endif diff --git a/src/patchmodule.cpp b/src/patchmodule.cpp deleted file mode 100644 index aa9b620..0000000 --- a/src/patchmodule.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "patchmodule.h" - -#include "qerplugin.h" -#include "ipatch.h" - -#include "patch.h" -#include "patchmanip.h" - -namespace { -std::size_t g_patchModuleCount = 0; -} - -void Patch_Construct(EPatchType type) -{ - if (++g_patchModuleCount != 1) { - return; - } - - PatchFilters_construct(); - - PatchPreferences_construct(); - - Patch_registerPreferencesPage(); - - Patch::constructStatic(type); - PatchInstance::constructStatic(); - - if (type == ePatchTypeDoom3) { - MAX_PATCH_WIDTH = MAX_PATCH_HEIGHT = 99; - } else { - MAX_PATCH_WIDTH = MAX_PATCH_HEIGHT = 31; // matching q3map2 - } -} - -void Patch_Destroy() -{ - if (--g_patchModuleCount != 0) { - return; - } - - Patch::destroyStatic(); - PatchInstance::destroyStatic(); -} - -class CommonPatchCreator : public PatchCreator { -public: -void Patch_undoSave(scene::Node &patch) const -{ - Node_getPatch(patch)->undoSave(); -} - -void Patch_resize(scene::Node &patch, std::size_t width, std::size_t height) const -{ - Node_getPatch(patch)->setDims(width, height); -} - -PatchControlMatrix Patch_getControlPoints(scene::Node &node) const -{ - Patch &patch = *Node_getPatch(node); - return PatchControlMatrix(patch.getHeight(), patch.getWidth(), patch.getControlPoints().data()); -} - -void Patch_controlPointsChanged(scene::Node &patch) const -{ - return Node_getPatch(patch)->controlPointsChanged(); -} - -const char *Patch_getShader(scene::Node &patch) const -{ - return Node_getPatch(patch)->GetShader(); -} - -void Patch_setShader(scene::Node &patch, const char *shader) const -{ - Node_getPatch(patch)->SetShader(shader); -} -}; - -class Quake3PatchCreator : public CommonPatchCreator { -public: -scene::Node &createPatch(bool def3, bool ws) -{ - return (new PatchNodeQuake3(def3, ws))->node(); -} -}; - -Quake3PatchCreator g_Quake3PatchCreator; - -PatchCreator &GetQuake3PatchCreator() -{ - return g_Quake3PatchCreator; -} - -class Doom3PatchCreator : public CommonPatchCreator { -public: -scene::Node &createPatch(bool def3, bool ws) -{ //these are ALWAYS def3... - return (new PatchNodeDoom3(true, ws))->node(); -} -}; - -Doom3PatchCreator g_Doom3PatchCreator; - -PatchCreator &GetDoom3PatchCreator() -{ - return g_Doom3PatchCreator; -} - -class Doom3PatchDef2Creator : public CommonPatchCreator { -public: -scene::Node &createPatch(bool def3, bool ws) -{ - return (new PatchNodeDoom3(def3, ws))->node(); -} -}; - -Doom3PatchDef2Creator g_Doom3PatchDef2Creator; - -PatchCreator &GetDoom3PatchDef2Creator() -{ - return g_Doom3PatchDef2Creator; -} - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class PatchDependencies : - public GlobalRadiantModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalSelectionModuleRef, - public GlobalOpenGLModuleRef, - public GlobalUndoModuleRef, - public GlobalFilterModuleRef { -}; - -class PatchQuake3API : public TypeSystemRef { -PatchCreator *m_patchquake3; -public: -typedef PatchCreator Type; - -STRING_CONSTANT(Name, "quake3"); - -PatchQuake3API() -{ - Patch_Construct(ePatchTypeQuake3); - - m_patchquake3 = &GetQuake3PatchCreator(); - g_patchCreator = m_patchquake3; -} - -~PatchQuake3API() -{ - Patch_Destroy(); -} - -PatchCreator *getTable() -{ - return m_patchquake3; -} -}; - -typedef SingletonModule PatchQuake3Module; -typedef Static StaticPatchQuake3Module; -StaticRegisterModule staticRegisterPatchQuake3(StaticPatchQuake3Module::instance()); - - -class PatchDoom3API : public TypeSystemRef { -PatchCreator *m_patchdoom3; -public: -typedef PatchCreator Type; - -STRING_CONSTANT(Name, "doom3"); - -PatchDoom3API() -{ - Patch_Construct(ePatchTypeDoom3); - - m_patchdoom3 = &GetDoom3PatchCreator(); -} - -~PatchDoom3API() -{ - Patch_Destroy(); -} - -PatchCreator *getTable() -{ - return m_patchdoom3; -} -}; - -typedef SingletonModule PatchDoom3Module; -typedef Static StaticPatchDoom3Module; -StaticRegisterModule staticRegisterPatchDoom3(StaticPatchDoom3Module::instance()); - - -class PatchDef2Doom3API : public TypeSystemRef { -PatchCreator *m_patchdef2doom3; -public: -typedef PatchCreator Type; - -STRING_CONSTANT(Name, "def2doom3"); - -PatchDef2Doom3API() -{ - Patch_Construct(ePatchTypeDoom3); - - m_patchdef2doom3 = &GetDoom3PatchDef2Creator(); - g_patchCreator = m_patchdef2doom3; -} - -~PatchDef2Doom3API() -{ - Patch_Destroy(); -} - -PatchCreator *getTable() -{ - return m_patchdef2doom3; -} -}; - -typedef SingletonModule PatchDef2Doom3Module; -typedef Static StaticPatchDef2Doom3Module; -StaticRegisterModule staticRegisterPatchDef2Doom3(StaticPatchDef2Doom3Module::instance()); diff --git a/src/patchmodule.h b/src/patchmodule.h deleted file mode 100644 index c97cb7f..0000000 --- a/src/patchmodule.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PATCHMODULE_H ) -#define INCLUDED_PATCHMODULE_H - -#endif diff --git a/tools/vmap/path_init.c b/src/path_init.c similarity index 100% rename from tools/vmap/path_init.c rename to src/path_init.c diff --git a/src/plugin.cpp b/src/plugin.cpp deleted file mode 100644 index 8de23e7..0000000 --- a/src/plugin.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "plugin.h" - -#include "debugging/debugging.h" - -#include "qerplugin.h" -#include "ifilesystem.h" -#include "ishaders.h" -#include "ientity.h" -#include "ieclass.h" -#include "irender.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "ifilter.h" -#include "iscriplib.h" -#include "igl.h" -#include "iundo.h" -#include "itextures.h" -#include "ireference.h" -#include "ifiletypes.h" -#include "preferencesystem.h" -#include "ibrush.h" -#include "ipatch.h" -#include "iimage.h" -#include "itoolbar.h" -#include "iplugin.h" -#include "imap.h" -#include "namespace.h" - -#include "gtkutil/messagebox.h" -#include "gtkutil/filechooser.h" -#include "maplib.h" - -#include "error.h" -#include "map.h" -#include "qe3.h" -#include "entityinspector.h" -#include "entitylist.h" -#include "points.h" -#include "gtkmisc.h" -#include "texwindow.h" -#include "mainframe.h" -#include "build.h" -#include "mru.h" -#include "multimon.h" -#include "surfacedialog.h" -#include "groupdialog.h" -#include "patchdialog.h" -#include "camwindow.h" -#include "watchbsp.h" -#include "xywindow.h" -#include "entity.h" -#include "select.h" -#include "preferences.h" -#include "autosave.h" -#include "plugintoolbar.h" -#include "findtexturedialog.h" -#include "nullmodel.h" -#include "grid.h" - -#include "modulesystem/modulesmap.h" -#include "modulesystem/singletonmodule.h" - -#include "generic/callback.h" - -const char *GameDescription_getKeyValue(const char *key) -{ - return g_pGameDescription->getKeyValue(key); -} - -const char *GameDescription_getRequiredKeyValue(const char *key) -{ - return g_pGameDescription->getRequiredKeyValue(key); -} - -const char *getMapName() -{ - return Map_Name(g_map); -} - -scene::Node &getMapWorldEntity() -{ - return Map_FindOrInsertWorldspawn(g_map); -} - -VIEWTYPE XYWindow_getViewType() -{ - return g_pParentWnd->GetXYWnd()->GetViewType(); -} - -Vector3 XYWindow_windowToWorld(const WindowVector &position) -{ - Vector3 result(0, 0, 0); - g_pParentWnd->GetXYWnd()->XY_ToPoint(static_cast( position.x()), static_cast( position.y()), result); - return result; -} - -const char *TextureBrowser_getSelectedShader() -{ - return TextureBrowser_GetSelectedShader(GlobalTextureBrowser()); -} - -const char *getGameFile() -{ - return g_GamesDialog.m_sGameFile.c_str(); -} - -class RadiantCoreAPI { -_QERFuncTable_1 m_radiantcore; -public: -typedef _QERFuncTable_1 Type; - -STRING_CONSTANT(Name, "*"); - -RadiantCoreAPI() -{ - m_radiantcore.getEnginePath = &EnginePath_get; - m_radiantcore.getLocalRcPath = &LocalRcPath_get; - m_radiantcore.getAppPath = &AppPath_get; - m_radiantcore.getGameToolsPath = &GameToolsPath_get; - m_radiantcore.getSettingsPath = &SettingsPath_get; - m_radiantcore.getMapsPath = &getMapsPath; - - m_radiantcore.getGameFile = &getGameFile; - m_radiantcore.getGameName = &gamename_get; - m_radiantcore.getGameMode = &gamemode_get; - - m_radiantcore.getMapName = &getMapName; - m_radiantcore.getMapWorldEntity = getMapWorldEntity; - m_radiantcore.getGridSize = GetGridSize; - - m_radiantcore.getGameDescriptionKeyValue = &GameDescription_getKeyValue; - m_radiantcore.getRequiredGameDescriptionKeyValue = &GameDescription_getRequiredKeyValue; - - m_radiantcore.XYWindowDestroyed_connect = XYWindowDestroyed_connect; - m_radiantcore.XYWindowDestroyed_disconnect = XYWindowDestroyed_disconnect; - m_radiantcore.XYWindowMouseDown_connect = XYWindowMouseDown_connect; - m_radiantcore.XYWindowMouseDown_disconnect = XYWindowMouseDown_disconnect; - m_radiantcore.XYWindow_getViewType = XYWindow_getViewType; - m_radiantcore.XYWindow_windowToWorld = XYWindow_windowToWorld; - m_radiantcore.TextureBrowser_getSelectedShader = TextureBrowser_getSelectedShader; - - m_radiantcore.m_pfnMessageBox = >k_MessageBox; - m_radiantcore.m_pfnFileDialog = &file_dialog; - m_radiantcore.m_pfnColorDialog = &color_dialog; - m_radiantcore.m_pfnDirDialog = &dir_dialog; - m_radiantcore.m_pfnNewImage = &new_plugin_image; -} - -_QERFuncTable_1 *getTable() -{ - return &m_radiantcore; -} -}; - -typedef SingletonModule RadiantCoreModule; -typedef Static StaticRadiantCoreModule; -StaticRegisterModule staticRegisterRadiantCore(StaticRadiantCoreModule::instance()); - - -class RadiantDependencies : - public GlobalRadiantModuleRef, - public GlobalFileSystemModuleRef, - public GlobalEntityModuleRef, - public GlobalShadersModuleRef, - public GlobalBrushModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalFiletypesModuleRef, - public GlobalSelectionModuleRef, - public GlobalReferenceModuleRef, - public GlobalOpenGLModuleRef, - public GlobalEntityClassManagerModuleRef, - public GlobalUndoModuleRef, - public GlobalScripLibModuleRef, - public GlobalNamespaceModuleRef { -ImageModulesRef m_image_modules; -MapModulesRef m_map_modules; -ToolbarModulesRef m_toolbar_modules; -PluginModulesRef m_plugin_modules; - -public: -RadiantDependencies() : - GlobalEntityModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entities")), - GlobalShadersModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("shaders")), - GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")), - GlobalEntityClassManagerModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entityclass")), - m_image_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("texturetypes")), - m_map_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("maptypes")), - m_toolbar_modules("*"), - m_plugin_modules("*") -{ -} - -ImageModules &getImageModules() -{ - return m_image_modules.get(); -} - -MapModules &getMapModules() -{ - return m_map_modules.get(); -} - -ToolbarModules &getToolbarModules() -{ - return m_toolbar_modules.get(); -} - -PluginModules &getPluginModules() -{ - return m_plugin_modules.get(); -} -}; - -class Radiant : public TypeSystemRef { -public: -Radiant() -{ - Preferences_Init(); - - GlobalFiletypes().addType("sound", "wav", filetype_t("PCM sound files", "*.wav")); - - Selection_construct(); - VFS_Construct(); - Grid_construct(); - MultiMon_Construct(); - MRU_Construct(); - Pointfile_Construct(); - GLWindow_Construct(); - BuildMenu_Construct(); - Map_Construct(); - EntityList_Construct(); - MainFrame_Construct(); - GroupDialog_Construct(); - SurfaceInspector_Construct(); - PatchInspector_Construct(); - CamWnd_Construct(); - XYWindow_Construct(); - BuildMonitor_Construct(); - TextureBrowser_Construct(); - Entity_Construct(); - Autosave_Construct(); - EntityInspector_construct(); - FindTextureDialog_Construct(); - NullModel_construct(); - MapRoot_construct(); - - EnginePath_verify(); - EnginePath_Realise(); -} - -~Radiant() -{ - EnginePath_Unrealise(); - - MapRoot_destroy(); - NullModel_destroy(); - FindTextureDialog_Destroy(); - EntityInspector_destroy(); - Autosave_Destroy(); - Entity_Destroy(); - TextureBrowser_Destroy(); - BuildMonitor_Destroy(); - XYWindow_Destroy(); - CamWnd_Destroy(); - PatchInspector_Destroy(); - SurfaceInspector_Destroy(); - GroupDialog_Destroy(); - MainFrame_Destroy(); - EntityList_Destroy(); - Map_Destroy(); - BuildMenu_Destroy(); - GLWindow_Destroy(); - Pointfile_Destroy(); - MRU_Destroy(); - MultiMon_Destroy(); - Grid_destroy(); - VFS_Destroy(); - Selection_destroy(); -} -}; - -namespace { -bool g_RadiantInitialised = false; -RadiantDependencies *g_RadiantDependencies; -Radiant *g_Radiant; -} - - -bool Radiant_Construct(ModuleServer &server) -{ - GlobalModuleServer::instance().set(server); - StaticModuleRegistryList().instance().registerModules(); - - g_RadiantDependencies = new RadiantDependencies(); - - g_RadiantInitialised = !server.getError(); - - if (g_RadiantInitialised) { - g_Radiant = new Radiant; - } - - return g_RadiantInitialised; -} - -void Radiant_Destroy() -{ - if (g_RadiantInitialised) { - delete g_Radiant; - } - - delete g_RadiantDependencies; -} - -ImageModules &Radiant_getImageModules() -{ - return g_RadiantDependencies->getImageModules(); -} - -MapModules &Radiant_getMapModules() -{ - return g_RadiantDependencies->getMapModules(); -} - -ToolbarModules &Radiant_getToolbarModules() -{ - return g_RadiantDependencies->getToolbarModules(); -} - -PluginModules &Radiant_getPluginModules() -{ - return g_RadiantDependencies->getPluginModules(); -} diff --git a/src/plugin.h b/src/plugin.h deleted file mode 100644 index 4b0992a..0000000 --- a/src/plugin.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PLUGIN_H ) -#define INCLUDED_PLUGIN_H - -class ModuleServer; - -bool Radiant_Construct(ModuleServer &server); - -void Radiant_Destroy(); - - -template -class Modules; - -struct _QERPlugImageTable; -typedef Modules<_QERPlugImageTable> ImageModules; - -ImageModules &Radiant_getImageModules(); - -class MapFormat; - -typedef Modules MapModules; - -MapModules &Radiant_getMapModules(); - -struct _QERPlugToolbarTable; -typedef Modules<_QERPlugToolbarTable> ToolbarModules; - -ToolbarModules &Radiant_getToolbarModules(); - -struct _QERPluginTable; -typedef Modules<_QERPluginTable> PluginModules; - -PluginModules &Radiant_getPluginModules(); - - -#endif diff --git a/src/pluginapi.cpp b/src/pluginapi.cpp deleted file mode 100644 index aca5a06..0000000 --- a/src/pluginapi.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "pluginapi.h" - -#include "modulesystem.h" -#include "qerplugin.h" - -#include "generic/callback.h" -#include "math/vector.h" - -#include "gtkmisc.h" - -#include "camwindow.h" - -#include "mainframe.h" - - -// camera API -void QERApp_GetCamera(Vector3 &origin, Vector3 &angles) -{ - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - origin = Camera_getOrigin(camwnd); - angles = Camera_getAngles(camwnd); -} - -void QERApp_SetCamera(const Vector3 &origin, const Vector3 &angles) -{ - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - Camera_setOrigin(camwnd, origin); - Camera_setAngles(camwnd, angles); -} - -void QERApp_GetCamWindowExtents(int *x, int *y, int *width, int *height) -{ -#if 0 - CamWnd* camwnd = g_pParentWnd->GetCamWnd(); - - gtk_window_get_position( camwnd->m_window, x, y ); - - *width = camwnd->Camera()->width; - *height = camwnd->Camera()->height; -#endif -} - -#include "icamera.h" - -class CameraAPI { -_QERCameraTable m_camera; -public: -typedef _QERCameraTable Type; - -STRING_CONSTANT(Name, "*"); - -CameraAPI() -{ - m_camera.m_pfnGetCamera = &QERApp_GetCamera; - m_camera.m_pfnSetCamera = &QERApp_SetCamera; - m_camera.m_pfnGetCamWindowExtents = &QERApp_GetCamWindowExtents; -} - -_QERCameraTable *getTable() -{ - return &m_camera; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule CameraModule; -typedef Static StaticCameraModule; -StaticRegisterModule staticRegisterCamera(StaticCameraModule::instance()); diff --git a/src/pluginapi.h b/src/pluginapi.h deleted file mode 100644 index f145c09..0000000 --- a/src/pluginapi.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PLUGINAPI_H ) -#define INCLUDED_PLUGINAPI_H - -template -class BasicVector3; - -typedef BasicVector3 Vector3; - -// camera API -void QERApp_GetCamera(Vector3 &origin, Vector3 &angles); - -void QERApp_SetCamera(const Vector3 &origin, const Vector3 &angles); - -void QERApp_GetCamWindowExtents(int *x, int *y, int *width, int *height); - -#endif diff --git a/src/pluginmanager.cpp b/src/pluginmanager.cpp deleted file mode 100644 index fe9e694..0000000 --- a/src/pluginmanager.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// PlugInManager.cpp: implementation of the CPlugInManager class. -// -////////////////////////////////////////////////////////////////////// - -#include "pluginmanager.h" - -#include "modulesystem.h" -#include "qerplugin.h" -#include "iplugin.h" - -#include "math/vector.h" -#include "string/string.h" - -#include "error.h" -#include "select.h" -#include "plugin.h" - -#include "modulesystem.h" - -#include - -/* plugin manager --------------------------------------- */ -class CPluginSlot : public IPlugIn { -CopiedString m_menu_name; -const _QERPluginTable *mpTable; -std::list m_CommandStrings; -std::list m_CommandTitleStrings; -std::list m_CommandIDs; - -public: -/*! - build directly from a SYN_PROVIDE interface - */ -CPluginSlot(ui::Widget main_window, const char *name, const _QERPluginTable &table); - -/*! - dispatching a command by name to the plugin - */ -void Dispatch(const char *p); - -// IPlugIn ------------------------------------------------------------ -const char *getMenuName(); - -std::size_t getCommandCount(); - -const char *getCommand(std::size_t n); - -const char *getCommandTitle(std::size_t n); - -void addMenuID(std::size_t n); - -bool ownsCommandID(std::size_t n); - -}; - -CPluginSlot::CPluginSlot(ui::Widget main_window, const char *name, const _QERPluginTable &table) -{ - mpTable = &table; - m_menu_name = name; - - const char *commands = mpTable->m_pfnQERPlug_GetCommandList(); - const char *titles = mpTable->m_pfnQERPlug_GetCommandTitleList(); - - StringTokeniser commandTokeniser(commands, ",;"); - StringTokeniser titleTokeniser(titles, ",;"); - - const char *cmdToken = commandTokeniser.getToken(); - const char *titleToken = titleTokeniser.getToken(); - while (!string_empty(cmdToken)) { - if (string_empty(titleToken)) { - m_CommandStrings.push_back(cmdToken); - m_CommandTitleStrings.push_back(cmdToken); - cmdToken = commandTokeniser.getToken(); - titleToken = ""; - } else { - m_CommandStrings.push_back(cmdToken); - m_CommandTitleStrings.push_back(titleToken); - cmdToken = commandTokeniser.getToken(); - titleToken = titleTokeniser.getToken(); - } - } - mpTable->m_pfnQERPlug_Init(0, (void *) main_window); -} - -const char *CPluginSlot::getMenuName() -{ - return m_menu_name.c_str(); -} - -std::size_t CPluginSlot::getCommandCount() -{ - return m_CommandStrings.size(); -} - -const char *CPluginSlot::getCommand(std::size_t n) -{ - std::list::iterator i = m_CommandStrings.begin(); - while (n-- != 0) { - ++i; - } - return (*i).c_str(); -} - -const char *CPluginSlot::getCommandTitle(std::size_t n) -{ - std::list::iterator i = m_CommandTitleStrings.begin(); - while (n-- != 0) { - ++i; - } - return (*i).c_str(); -} - -void CPluginSlot::addMenuID(std::size_t n) -{ - m_CommandIDs.push_back(n); -} - -bool CPluginSlot::ownsCommandID(std::size_t n) -{ - for (std::list::iterator i = m_CommandIDs.begin(); i != m_CommandIDs.end(); ++i) { - if (*i == n) { - return true; - } - } - return false; -} - -void CPluginSlot::Dispatch(const char *p) -{ - Vector3 vMin, vMax; - Select_GetBounds(vMin, vMax); - mpTable->m_pfnQERPlug_Dispatch(p, reinterpret_cast( &vMin ), reinterpret_cast( &vMax ), - true); //QE_SingleBrush(true)); -} - - -class CPluginSlots { -std::list mSlots; -public: -virtual ~CPluginSlots(); - -void AddPluginSlot(ui::Widget main_window, const char *name, const _QERPluginTable &table) -{ - mSlots.push_back(new CPluginSlot(main_window, name, table)); -} - -void PopulateMenu(PluginsVisitor &menu); - -bool Dispatch(std::size_t n, const char *p); -}; - -CPluginSlots::~CPluginSlots() -{ - std::list::iterator iSlot; - for (iSlot = mSlots.begin(); iSlot != mSlots.end(); ++iSlot) { - delete *iSlot; - *iSlot = 0; - } -} - -void CPluginSlots::PopulateMenu(PluginsVisitor &menu) -{ - std::list::iterator iPlug; - for (iPlug = mSlots.begin(); iPlug != mSlots.end(); ++iPlug) { - menu.visit(*(*iPlug)); - } -} - -bool CPluginSlots::Dispatch(std::size_t n, const char *p) -{ - std::list::iterator iPlug; - for (iPlug = mSlots.begin(); iPlug != mSlots.end(); ++iPlug) { - CPluginSlot *pPlug = *iPlug; - if (pPlug->ownsCommandID(n)) { - pPlug->Dispatch(p); - return true; - } - } - return false; -} - -CPluginSlots g_plugin_slots; - - -void FillPluginSlots(CPluginSlots &slots, ui::Widget main_window) -{ - class AddPluginVisitor : public PluginModules::Visitor { - CPluginSlots &m_slots; - ui::Widget m_main_window; -public: - AddPluginVisitor(CPluginSlots &slots, ui::Widget main_window) - : m_slots(slots), m_main_window(main_window) - { - } - - void visit(const char *name, const _QERPluginTable &table) const - { - m_slots.AddPluginSlot(m_main_window, name, table); - } - } visitor(slots, main_window); - - Radiant_getPluginModules().foreachModule(visitor); -} - - -#include "pluginmanager.h" - -CPlugInManager g_PlugInMgr; - -CPlugInManager &GetPlugInMgr() -{ - return g_PlugInMgr; -} - -void CPlugInManager::Dispatch(std::size_t n, const char *p) -{ - g_plugin_slots.Dispatch(n, p); -} - -void CPlugInManager::Init(ui::Widget main_window) -{ - FillPluginSlots(g_plugin_slots, main_window); -} - -void CPlugInManager::constructMenu(PluginsVisitor &menu) -{ - g_plugin_slots.PopulateMenu(menu); -} - -void CPlugInManager::Shutdown() -{ -} diff --git a/src/pluginmanager.h b/src/pluginmanager.h deleted file mode 100644 index af8c096..0000000 --- a/src/pluginmanager.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PLUGINMANAGER_H ) -#define INCLUDED_PLUGINMANAGER_H - -#include -#include - - -/*! - \class IPlugin - pure virtual interface for a plugin - temporary solution for migration from old plugin tech to synapse plugins - */ -class IPlugIn { -public: -IPlugIn() -{ -} - -virtual ~IPlugIn() -{ -} - -virtual const char *getMenuName() = 0; - -virtual std::size_t getCommandCount() = 0; - -virtual const char *getCommand(std::size_t) = 0; - -virtual const char *getCommandTitle(std::size_t) = 0; - -virtual void addMenuID(std::size_t) = 0; - -virtual bool ownsCommandID(std::size_t n) = 0; -}; - -class PluginsVisitor { -public: -virtual void visit(IPlugIn &plugin) = 0; -}; - -class CPlugInManager { -public: -void Dispatch(std::size_t n, const char *p); - -void Init(ui::Widget main_window); - -void constructMenu(PluginsVisitor &menu); - -void Shutdown(); -}; - -CPlugInManager &GetPlugInMgr(); - -#endif diff --git a/src/pluginmenu.cpp b/src/pluginmenu.cpp deleted file mode 100644 index 2db4bf1..0000000 --- a/src/pluginmenu.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "pluginmenu.h" - -#include - -#include "stream/textstream.h" - -#include "gtkutil/pointer.h" -#include "gtkutil/menu.h" - -#include "pluginmanager.h" -#include "mainframe.h" -#include "preferences.h" - - -int m_nNextPlugInID = 0; - -void plugin_activated(ui::Widget widget, gpointer data) -{ - const char *str = (const char *) g_object_get_data(G_OBJECT(widget), "command"); - GetPlugInMgr().Dispatch(gpointer_to_int(data), str); -} - -#include - -void PlugInMenu_Add(ui::Menu plugin_menu, IPlugIn *pPlugIn) -{ - ui::Widget item{ui::null}, parent{ui::null}; - ui::Menu menu{ui::null}, subMenu{ui::null}; - const char *menuText, *menuCommand; - std::stack menuStack; - - parent = ui::MenuItem(pPlugIn->getMenuName()); - parent.show(); - plugin_menu.add(parent); - - std::size_t nCount = pPlugIn->getCommandCount(); - if (nCount > 0) { - menu = ui::Menu(ui::New); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - while (nCount > 0) { - menuText = pPlugIn->getCommandTitle(--nCount); - menuCommand = pPlugIn->getCommand(nCount); - - if (menuText != 0 && strlen(menuText) > 0) { - if (!strcmp(menuText, "-")) { - item = ui::Widget::from(gtk_menu_item_new()); - gtk_widget_set_sensitive(item, FALSE); - } else if (!strcmp(menuText, ">")) { - menuText = pPlugIn->getCommandTitle(--nCount); - menuCommand = pPlugIn->getCommand(nCount); - if (!strcmp(menuText, "-") || !strcmp(menuText, ">") || !strcmp(menuText, "<")) { - globalErrorStream() << pPlugIn->getMenuName() << " Invalid title (" << menuText - << ") for submenu.\n"; - continue; - } - - item = ui::MenuItem(menuText); - item.show(); - menu.add(item); - - subMenu = ui::Menu(ui::New); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), subMenu); - menuStack.push(menu); - menu = subMenu; - continue; - } else if (!strcmp(menuText, "<")) { - if (!menuStack.empty()) { - menu = menuStack.top(); - menuStack.pop(); - } else { - globalErrorStream() << pPlugIn->getMenuName() - << ": Attempt to end non-existent submenu ignored.\n"; - } - continue; - } else { - item = ui::MenuItem(menuText); - g_object_set_data(G_OBJECT(item), "command", - const_cast( static_cast( menuCommand ))); - item.connect("activate", G_CALLBACK(plugin_activated), gint_to_pointer(m_nNextPlugInID)); - } - item.show(); - menu.add(item); - pPlugIn->addMenuID(m_nNextPlugInID++); - } - } - if (!menuStack.empty()) { - std::size_t size = menuStack.size(); - if (size != 0) { - globalErrorStream() << pPlugIn->getMenuName() << " mismatched > <. " << Unsigned(size) - << " submenu(s) not closed.\n"; - } - for (std::size_t i = 0; i < (size - 1); i++) { - menuStack.pop(); - } - menu = menuStack.top(); - menuStack.pop(); - } - gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent), menu); - } -} - -ui::Menu g_plugins_menu{ui::null}; -ui::MenuItem g_plugins_menu_separator{ui::null}; - -void PluginsMenu_populate() -{ - class PluginsMenuConstructor : public PluginsVisitor { - ui::Menu m_menu; -public: - PluginsMenuConstructor(ui::Menu menu) : m_menu(menu) - { - } - - void visit(IPlugIn &plugin) - { - PlugInMenu_Add(m_menu, &plugin); - } - }; - - PluginsMenuConstructor constructor(g_plugins_menu); - GetPlugInMgr().constructMenu(constructor); -} - -void PluginsMenu_clear() -{ - m_nNextPlugInID = 0; - - GList *lst = g_list_find(gtk_container_get_children(GTK_CONTAINER(g_plugins_menu)), - g_plugins_menu_separator._handle); - while (lst->next) { - g_plugins_menu.remove(ui::Widget::from(lst->next->data)); - lst = g_list_find(gtk_container_get_children(GTK_CONTAINER(g_plugins_menu)), g_plugins_menu_separator._handle); - } -} - -ui::MenuItem create_plugins_menu() -{ - // Plugins menu - auto plugins_menu_item = new_sub_menu_item_with_mnemonic("_Plugins"); - auto menu = ui::Menu::from(gtk_menu_item_get_submenu(plugins_menu_item)); - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - g_plugins_menu = menu; - - //TODO: some modules/plugins do not yet support refresh -#if 0 - create_menu_item_with_mnemonic( menu, "Refresh", makeCallbackF(Restart) ); - - // NOTE: the seperator is used when doing a refresh of the list, everything past the seperator is removed - g_plugins_menu_separator = menu_separator( menu ); -#endif - - PluginsMenu_populate(); - - return plugins_menu_item; -} diff --git a/src/pluginmenu.h b/src/pluginmenu.h deleted file mode 100644 index 1d2f8b6..0000000 --- a/src/pluginmenu.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_PLUGINMENU_H ) -#define INCLUDED_PLUGINMENU_H - -ui::MenuItem create_plugins_menu(); - -void PluginsMenu_populate(); - -void PluginsMenu_clear(); - -#endif diff --git a/src/plugintoolbar.cpp b/src/plugintoolbar.cpp deleted file mode 100644 index f0c5b49..0000000 --- a/src/plugintoolbar.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "plugintoolbar.h" - -#include - -#include "itoolbar.h" -#include "modulesystem.h" - -#include "stream/stringstream.h" -#include "gtkutil/image.h" -#include "gtkutil/container.h" - -#include "mainframe.h" -#include "plugin.h" - -ui::Image new_plugin_image(const char *filename) -{ - { - StringOutputStream fullpath(256); - fullpath << GameToolsPath_get() << g_pluginsDir << "bitmaps/" << filename; - if (auto image = image_new_from_file_with_mask(fullpath.c_str())) { return image; } - } - - { - StringOutputStream fullpath(256); - fullpath << AppPath_get() << g_pluginsDir << "bitmaps/" << filename; - if (auto image = image_new_from_file_with_mask(fullpath.c_str())) { return image; } - } - - return image_new_missing(); -} - -void -toolbar_insert(ui::Toolbar toolbar, const char *icon, const char *text, const char *tooltip, IToolbarButton::EType type, - GCallback handler, gpointer data) -{ - if (type == IToolbarButton::eSpace) { - auto it = ui::ToolItem::from(gtk_separator_tool_item_new()); - it.show(); - toolbar.add(it); - return; - } - if (type == IToolbarButton::eButton) { - auto button = ui::ToolButton::from(gtk_tool_button_new(new_plugin_image(icon), text)); - gtk_widget_set_tooltip_text(button, tooltip); - gtk_widget_show_all(button); - button.connect("clicked", G_CALLBACK(handler), data); - toolbar.add(button); - return; - } - if (type == IToolbarButton::eToggleButton) { - auto button = ui::ToolButton::from(gtk_toggle_tool_button_new()); - gtk_tool_button_set_icon_widget(button, new_plugin_image(icon)); - gtk_tool_button_set_label(button, text); - gtk_widget_set_tooltip_text(button, tooltip); - gtk_widget_show_all(button); - button.connect("toggled", G_CALLBACK(handler), data); - toolbar.add(button); - return; - } - ERROR_MESSAGE("invalid toolbar button type"); -} - -void ActivateToolbarButton(ui::ToolButton widget, gpointer data) -{ - (const_cast( reinterpret_cast( data )))->activate(); -} - -void PlugInToolbar_AddButton(ui::Toolbar toolbar, const IToolbarButton *button) -{ - toolbar_insert(toolbar, button->getImage(), button->getText(), button->getTooltip(), button->getType(), - G_CALLBACK(ActivateToolbarButton), - reinterpret_cast( const_cast( button ))); -} - -ui::Toolbar g_plugin_toolbar{ui::null}; - -void PluginToolbar_populate() -{ - class AddToolbarItemVisitor : public ToolbarModules::Visitor { - ui::Toolbar m_toolbar; -public: - AddToolbarItemVisitor(ui::Toolbar toolbar) - : m_toolbar(toolbar) - { - } - - void visit(const char *name, const _QERPlugToolbarTable &table) const - { - const std::size_t count = table.m_pfnToolbarButtonCount(); - for (std::size_t i = 0; i < count; ++i) { - PlugInToolbar_AddButton(m_toolbar, table.m_pfnGetToolbarButton(i)); - } - } - - } visitor(g_plugin_toolbar); - - Radiant_getToolbarModules().foreachModule(visitor); -} - -void PluginToolbar_clear() -{ - container_remove_all(g_plugin_toolbar); -} - -ui::Toolbar create_plugin_toolbar() -{ - - auto toolbar = ui::Toolbar::from(gtk_toolbar_new()); - gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL); - gtk_toolbar_set_style(toolbar, GTK_TOOLBAR_ICONS); - toolbar.show(); - - g_plugin_toolbar = toolbar; - - PluginToolbar_populate(); - - return toolbar; -} - -/* blerugh - eukara */ -void PluginToolbar_AddToMain(ui::Toolbar toolbar) -{ - - g_plugin_toolbar = toolbar; - - PluginToolbar_populate(); -} diff --git a/src/plugintoolbar.h b/src/plugintoolbar.h deleted file mode 100644 index 9445cdf..0000000 --- a/src/plugintoolbar.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_PLUGINTOOLBAR_H ) -#define INCLUDED_PLUGINTOOLBAR_H - -ui::Toolbar create_plugin_toolbar(); - -void PluginToolbar_populate(); - -void PluginToolbar_clear(); - -ui::Image new_plugin_image(const char *filename); // filename is relative to plugin bitmaps path - -#endif diff --git a/src/points.cpp b/src/points.cpp deleted file mode 100644 index 650a1fc..0000000 --- a/src/points.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - The following source code is licensed by Id Software and subject to the terms of - its LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with - GtkRadiant. If you did not receive a LIMITED USE SOFTWARE LICENSE AGREEMENT, - please contact Id Software immediately at info@idsoftware.com. - */ - -#include "points.h" - -#include "debugging/debugging.h" - -#include "irender.h" -#include "igl.h" -#include "renderable.h" - -#include "stream/stringstream.h" -#include "os/path.h" -#include "os/file.h" -#include "cmdlib.h" - -#include "map.h" -#include "qe3.h" -#include "camwindow.h" -#include "xywindow.h" -#include "xmlstuff.h" -#include "mainframe.h" -#include "watchbsp.h" -#include "commands.h" - - -class CPointfile; - -void Pointfile_Parse(CPointfile &pointfile); - - -class CPointfile : public ISAXHandler, public Renderable, public OpenGLRenderable { -enum { - MAX_POINTFILE = 8192, -}; -Vector3 s_pointvecs[MAX_POINTFILE]; -std::size_t s_num_points; -int m_displaylist; -static Shader *m_renderstate; -StringOutputStream m_characters; -public: -CPointfile() -{ -} - -~CPointfile() -{ -} - -void Init(); - -void PushPoint(const Vector3 &v); - -void GenerateDisplayList(); - -// SAX interface -void Release() -{ - // blank because not heap-allocated -} - -void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs); - -void saxEndElement(message_info_t *ctx, const xmlChar *name); - -void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len); - -const char *getName(); - -typedef const Vector3 *const_iterator; - -const_iterator begin() const -{ - return &s_pointvecs[0]; -} - -const_iterator end() const -{ - return &s_pointvecs[s_num_points]; -} - -bool shown() const -{ - return m_displaylist != 0; -} - -void show(bool show) -{ - if (show && !shown()) { - Pointfile_Parse(*this); - GenerateDisplayList(); - SceneChangeNotify(); - } else if (!show && shown()) { - glDeleteLists(m_displaylist, 1); - m_displaylist = 0; - SceneChangeNotify(); - } -} - -void render(RenderStateFlags state) const -{ - glCallList(m_displaylist); -} - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - if (shown()) { - renderer.SetState(m_renderstate, Renderer::eWireframeOnly); - renderer.SetState(m_renderstate, Renderer::eFullMaterials); - renderer.addRenderable(*this, g_matrix4_identity); - } -} - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} - -static void constructStatic() -{ - m_renderstate = GlobalShaderCache().capture("$POINTFILE"); -} - -static void destroyStatic() -{ - GlobalShaderCache().release("$POINTFILE"); -} -}; - -Shader *CPointfile::m_renderstate = 0; - -namespace { -CPointfile s_pointfile; -} - -ISAXHandler &g_pointfile = s_pointfile; - -static CPointfile::const_iterator s_check_point; - -void CPointfile::Init() -{ - s_num_points = 0; - m_displaylist = 0; -} - -void CPointfile::PushPoint(const Vector3 &v) -{ - if (s_num_points < MAX_POINTFILE) { - s_pointvecs[s_num_points] = v; - ++s_num_points; - } -} - -// create the display list at the end -void CPointfile::GenerateDisplayList() -{ - m_displaylist = glGenLists(1); - - glNewList(m_displaylist, GL_COMPILE); - - glBegin(GL_LINE_STRIP); - for (std::size_t i = 0; i < s_num_points; i++) - glVertex3fv(vector3_to_array(s_pointvecs[i])); - glEnd(); - glLineWidth(1); - - glEndList(); -} - -// old (but still relevant) pointfile code ------------------------------------- - -void Pointfile_Delete(void) -{ - const char *mapname = Map_Name(g_map); - StringOutputStream name(256); - name << StringRange(mapname, path_get_filename_base_end(mapname)) << ".lin"; - file_remove(name.c_str()); -} - -// advance camera to next point -void Pointfile_Next(void) -{ - if (!s_pointfile.shown()) { - return; - } - - if (s_check_point + 2 == s_pointfile.end()) { - globalOutputStream() << "End of pointfile\n"; - return; - } - - CPointfile::const_iterator i = ++s_check_point; - - - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - Camera_setOrigin(camwnd, *i); - g_pParentWnd->GetXYWnd()->SetOrigin(*i); - { - Vector3 dir(vector3_normalised(vector3_subtracted(*(++i), Camera_getOrigin(camwnd)))); - Vector3 angles(Camera_getAngles(camwnd)); - angles[CAMERA_YAW] = static_cast( radians_to_degrees(atan2(dir[1], dir[0]))); - angles[CAMERA_PITCH] = static_cast( radians_to_degrees(asin(dir[2]))); - Camera_setAngles(camwnd, angles); - } -} - -// advance camera to previous point -void Pointfile_Prev(void) -{ - if (!s_pointfile.shown()) { - return; - } - - if (s_check_point == s_pointfile.begin()) { - globalOutputStream() << "Start of pointfile\n"; - return; - } - - CPointfile::const_iterator i = --s_check_point; - - CamWnd &camwnd = *g_pParentWnd->GetCamWnd(); - Camera_setOrigin(camwnd, *i); - g_pParentWnd->GetXYWnd()->SetOrigin(*i); - { - Vector3 dir(vector3_normalised(vector3_subtracted(*(++i), Camera_getOrigin(camwnd)))); - Vector3 angles(Camera_getAngles(camwnd)); - angles[CAMERA_YAW] = static_cast( radians_to_degrees(atan2(dir[1], dir[0]))); - angles[CAMERA_PITCH] = static_cast( radians_to_degrees(asin(dir[2]))); - Camera_setAngles(camwnd, angles); - } -} - -int LoadFile(const char *filename, void **bufferptr) -{ - FILE *f; - long len; - - f = fopen(filename, "rb"); - if (f == 0) { - return -1; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - rewind(f); - - *bufferptr = malloc(len + 1); - if (*bufferptr == 0) { - return -1; - } - - fread(*bufferptr, 1, len, f); - fclose(f); - - // we need to end the buffer with a 0 - ((char *) (*bufferptr))[len] = 0; - - return len; -} - -void Pointfile_Parse(CPointfile &pointfile) -{ - int size; - char *data; - char *text; - int line = 1; - - const char *mapname = Map_Name(g_map); - StringOutputStream name(256); - name << StringRange(mapname, path_get_filename_base_end(mapname)) << ".lin"; - - size = LoadFile(name.c_str(), (void **) &data); - if (size == -1) { - globalErrorStream() << "Pointfile " << name.c_str() << " not found\n"; - return; - } - - // store a pointer - text = data; - - globalOutputStream() << "Reading pointfile " << name.c_str() << "\n"; - - pointfile.Init(); - - while (*data) { - Vector3 v; - if (sscanf(data, "%f %f %f", &v[0], &v[1], &v[2]) != 3) { - globalOutputStream() << "Corrupt point file, line " << line << "\n"; - break; - } - - while (*data && *data != '\n') { - if (*(data - 1) == ' ' && *(data) == '-' && *(data + 1) == ' ') { - break; - } - data++; - } - // deal with zhlt style point files. - if (*data == '-') { - if (sscanf(data, "- %f %f %f", &v[0], &v[1], &v[2]) != 3) { - globalOutputStream() << "Corrupt point file, line " << line << "\n"; - break; - } - - while (*data && *data != '\n') { - data++; - } - - } - while (*data == '\n') { - data++; // skip the \n - line++; - } - pointfile.PushPoint(v); - } - - g_free(text); -} - -void Pointfile_Clear() -{ - s_pointfile.show(false); -} - -void Pointfile_Toggle() -{ - s_pointfile.show(!s_pointfile.shown()); - - s_check_point = s_pointfile.begin(); -} - -void Pointfile_Construct() -{ - CPointfile::constructStatic(); - - GlobalShaderCache().attachRenderable(s_pointfile); - - GlobalCommands_insert("TogglePointfile", makeCallbackF(Pointfile_Toggle)); - GlobalCommands_insert("NextLeakSpot", makeCallbackF(Pointfile_Next), - Accelerator('K', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalCommands_insert("PrevLeakSpot", makeCallbackF(Pointfile_Prev), - Accelerator('L', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); -} - -void Pointfile_Destroy() -{ - GlobalShaderCache().detachRenderable(s_pointfile); - - CPointfile::destroyStatic(); -} - - -// CPointfile implementation for SAX-specific stuff ------------------------------- -void CPointfile::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) -{ - if (string_equal(reinterpret_cast( name ), "polyline")) { - Init(); - // there's a prefs setting to avoid stopping on leak - if (!g_WatchBSP_LeakStop) { - ctx->stop_depth = 0; - } - } -} - -void CPointfile::saxEndElement(message_info_t *ctx, const xmlChar *name) -{ - if (string_equal(reinterpret_cast( name ), "polyline")) { - // we are done - GenerateDisplayList(); - SceneChangeNotify(); - s_check_point = begin(); - } else if (string_equal(reinterpret_cast( name ), "point")) { - Vector3 v; - sscanf(m_characters.c_str(), "%f %f %f\n", &v[0], &v[1], &v[2]); - PushPoint(v); - m_characters.clear(); - } -} - -// only "point" is expected to have characters around here -void CPointfile::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) -{ - m_characters.write(reinterpret_cast( ch ), len); -} - -const char *CPointfile::getName() -{ - return "Map leaked"; -} diff --git a/src/points.h b/src/points.h deleted file mode 100644 index 449af54..0000000 --- a/src/points.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//----------------------------------------------------------------------------- -// -// DESCRIPTION: -// header for Pointfile stuff (adding a C++ class to wrap the pointfile thing in the SAX parser) -// - -#if !defined( INCLUDED_POINTS_H ) -#define INCLUDED_POINTS_H - -void Pointfile_Clear(); - -void Pointfile_Delete(void); - -void Pointfile_Construct(); - -void Pointfile_Destroy(); - -class ISAXHandler; - -extern ISAXHandler &g_pointfile; - -#endif diff --git a/tools/vmap/portals.c b/src/portals.c similarity index 100% rename from tools/vmap/portals.c rename to src/portals.c diff --git a/src/preferencedictionary.cpp b/src/preferencedictionary.cpp deleted file mode 100644 index 08ca943..0000000 --- a/src/preferencedictionary.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "preferencedictionary.h" diff --git a/src/preferencedictionary.h b/src/preferencedictionary.h deleted file mode 100644 index be1f69f..0000000 --- a/src/preferencedictionary.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_PREFERENCEDICTIONARY_H ) -#define INCLUDED_PREFERENCEDICTIONARY_H - -#include "preferencesystem.h" -#include "xml/ixml.h" -#include "stream/stringstream.h" -#include "generic/callback.h" -#include "versionlib.h" -#include - -class PreferenceDictionary : public PreferenceSystem { -class PreferenceEntry { -Property m_cb; -public: -PreferenceEntry(const Property &cb) - : m_cb(cb) -{ -} - -void importString(const char *string) -{ - m_cb.set(string); -} - -void exportString(const Callback &importer) -{ - m_cb.get(importer); -} -}; - -typedef std::map PreferenceEntries; -PreferenceEntries m_preferences; - -typedef std::map PreferenceCache; -PreferenceCache m_cache; - -public: -typedef PreferenceEntries::iterator iterator; - -iterator begin() -{ - return m_preferences.begin(); -} - -iterator end() -{ - return m_preferences.end(); -} - -iterator find(const char *name) -{ - return m_preferences.find(name); -} - -void registerPreference(const char *name, const Property &cb) -{ - m_preferences.insert(PreferenceEntries::value_type(name, PreferenceEntry(cb))); - PreferenceCache::iterator i = m_cache.find(name); - if (i != m_cache.end()) { - cb.set(i->second.c_str()); - m_cache.erase(i); - } -} - -void importPref(const char *name, const char *value) -{ - PreferenceEntries::iterator i = m_preferences.find(name); - if (i != m_preferences.end()) { - (*i).second.importString(value); - } else { - m_cache.erase(name); - m_cache.insert(PreferenceCache::value_type(name, value)); - } -} -}; - -inline void XMLPreference_importString(XMLImporter &importer, const char *value) -{ - importer.write(value, string_length(value)); -} - -typedef ReferenceCaller XMLPreferenceImportStringCaller; - -class XMLPreferenceDictionaryExporter : public XMLExporter { -class XMLQPrefElement : public XMLElement { -const char *m_version; -public: -XMLQPrefElement(const char *version) : m_version(version) -{ -} - -const char *name() const -{ - return "qpref"; -} - -const char *attribute(const char *name) const -{ - if (string_equal(name, "version")) { - return m_version; - } - return ""; -} - -void forEachAttribute(XMLAttrVisitor &visitor) const -{ - visitor.visit("version", m_version); -} -}; - -class XMLPreferenceElement : public XMLElement { -const char *m_name; -public: -XMLPreferenceElement(const char *name) - : m_name(name) -{ -} - -const char *name() const -{ - return "epair"; -} - -const char *attribute(const char *name) const -{ - if (string_equal(name, "name")) { - return m_name; - } - return ""; -} - -void forEachAttribute(XMLAttrVisitor &visitor) const -{ - visitor.visit("name", m_name); -} -}; - -typedef PreferenceDictionary PreferenceEntries; -PreferenceEntries &m_preferences; -const char *m_version; -public: -XMLPreferenceDictionaryExporter(PreferenceDictionary &preferences, const char *version) - : m_preferences(preferences), m_version(version) -{ -} - -void exportXML(XMLImporter &importer) -{ - importer.write("\n", 1); - - XMLQPrefElement qpref_element(m_version); - importer.pushElement(qpref_element); - importer.write("\n", 1); - - for (PreferenceEntries::iterator i = m_preferences.begin(); i != m_preferences.end(); ++i) { - XMLPreferenceElement epair_element((*i).first.c_str()); - - importer.pushElement(epair_element); - - (*i).second.exportString(XMLPreferenceImportStringCaller(importer)); - - importer.popElement(epair_element.name()); - importer.write("\n", 1); - } - - importer.popElement(qpref_element.name()); - importer.write("\n", 1); -} -}; - -class XMLPreferenceDictionaryImporter : public XMLImporter { -struct xml_state_t { - enum ETag { - tag_qpref, - tag_qpref_ignore, - tag_epair, - tag_epair_ignore - }; - - xml_state_t(ETag tag) - : m_tag(tag) - { - } - - ETag m_tag; - CopiedString m_name; - StringOutputStream m_ostream; -}; - -typedef std::vector xml_stack_t; -xml_stack_t m_xml_stack; - -typedef PreferenceDictionary PreferenceEntries; -PreferenceEntries &m_preferences; -Version m_version; -public: -XMLPreferenceDictionaryImporter(PreferenceDictionary &preferences, const char *version) - : m_preferences(preferences), m_version(version_parse(version)) -{ -} - -void pushElement(const XMLElement &element) -{ - if (m_xml_stack.empty()) { - if (string_equal(element.name(), "qpref")) { - Version dataVersion(version_parse(element.attribute("version"))); - if (!version_compatible(m_version, dataVersion)) { - globalOutputStream() << "qpref import: data version " << dataVersion - << " is not compatible with code version " << m_version << "\n"; - m_xml_stack.push_back(xml_state_t::tag_qpref_ignore); - } else { - globalOutputStream() << "qpref import: data version " << dataVersion - << " is compatible with code version " << m_version << "\n"; - m_xml_stack.push_back(xml_state_t::tag_qpref); - } - } else { - // not valid - } - } else { - switch (m_xml_stack.back().m_tag) { - case xml_state_t::tag_qpref: - if (string_equal(element.name(), "epair")) { - m_xml_stack.push_back(xml_state_t::tag_epair); - m_xml_stack.back().m_name = element.attribute("name"); - } else { - // not valid - } - break; - case xml_state_t::tag_qpref_ignore: - if (string_equal(element.name(), "epair")) { - m_xml_stack.push_back(xml_state_t::tag_epair_ignore); - } else { - // not valid - } - break; - case xml_state_t::tag_epair: - case xml_state_t::tag_epair_ignore: - // not valid - break; - } - } - -} - -void popElement(const char *name) -{ - if (m_xml_stack.back().m_tag == xml_state_t::tag_epair) { - m_preferences.importPref(m_xml_stack.back().m_name.c_str(), m_xml_stack.back().m_ostream.c_str()); - } - m_xml_stack.pop_back(); -} - -std::size_t write(const char *buffer, std::size_t length) -{ - return m_xml_stack.back().m_ostream.write(buffer, length); -} -}; - -#endif diff --git a/src/preferences.cpp b/src/preferences.cpp deleted file mode 100644 index ee72aa5..0000000 --- a/src/preferences.cpp +++ /dev/null @@ -1,1011 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// User preferences -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "preferences.h" -#include "globaldefs.h" - -#include -#include "gtkutil/image.h" -#include "environment.h" - -#include "debugging/debugging.h" - -#include "generic/callback.h" -#include "math/vector.h" -#include "string/string.h" -#include "stream/stringstream.h" -#include "os/file.h" -#include "os/path.h" -#include "os/dir.h" -#include "gtkutil/filechooser.h" -#include "gtkutil/messagebox.h" -#include "cmdlib.h" - -#include "error.h" -#include "console.h" -#include "xywindow.h" -#include "mainframe.h" -#include "qe3.h" -#include "gtkdlgs.h" - -void Interface_constructPreferences(PreferencesPage &page) -{ -#if GDEF_OS_WINDOWS - page.appendCheckBox( "", "Default Text Editor", g_TextEditor_useWin32Editor ); -#else - { - ui::CheckButton use_custom = page.appendCheckBox("Text Editor", "Custom", g_TextEditor_useCustomEditor); - ui::Widget custom_editor = page.appendPathEntry("Text Editor Command", g_TextEditor_editorCommand, true); - Widget_connectToggleDependency(custom_editor, use_custom); - } -#endif -} - -void Mouse_constructPreferences(PreferencesPage &page) -{ - { - const char *buttons[] = {"2 button", "3 button",}; - page.appendRadio("Mouse Type", g_glwindow_globals.m_nMouseType, STRING_ARRAY_RANGE(buttons)); - } - page.appendCheckBox("Right Button", "Activates Context Menu", g_xywindow_globals.m_bRightClick); -} - -void Mouse_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Mouse", "Mouse Preferences")); - Mouse_constructPreferences(page); -} - -void Mouse_registerPreferencesPage() -{ - PreferencesDialog_addInterfacePage(makeCallbackF(Mouse_constructPage)); -} - - -/*! - ========================================================= - Games selection dialog - ========================================================= - */ - -#include -#include - -inline const char *xmlAttr_getName(xmlAttrPtr attr) -{ - return reinterpret_cast( attr->name ); -} - -inline const char *xmlAttr_getValue(xmlAttrPtr attr) -{ - return reinterpret_cast( attr->children->content ); -} - -CGameDescription::CGameDescription(xmlDocPtr pDoc, const CopiedString &gameFile) -{ - // read the user-friendly game name - xmlNodePtr pNode = pDoc->children; - - while (strcmp((const char *) pNode->name, "game") && pNode != 0) { - pNode = pNode->next; - } - if (!pNode) { - Error("Didn't find 'game' node in the game description file '%s'\n", pDoc->URL); - } - - for (xmlAttrPtr attr = pNode->properties; attr != 0; attr = attr->next) { - m_gameDescription.insert(GameDescription::value_type(xmlAttr_getName(attr), xmlAttr_getValue(attr))); - } - - { - StringOutputStream path(256); - path << AppPath_get() << gameFile.c_str() << "/"; - mGameToolsPath = path.c_str(); - } - - ASSERT_MESSAGE(file_exists(mGameToolsPath.c_str()), - "game directory not found: " << makeQuoted(mGameToolsPath.c_str())); - - mGameFile = gameFile; - - { - GameDescription::iterator i = m_gameDescription.find("type"); - if (i == m_gameDescription.end()) { - globalErrorStream() << "Warning, 'type' attribute not found in '" - << reinterpret_cast( pDoc->URL ) << "'\n"; - // default - mGameType = "q3"; - } else { - mGameType = (*i).second.c_str(); - } - } -} - -void CGameDescription::Dump() -{ - globalOutputStream() << "game description file: " << makeQuoted(mGameFile.c_str()) << "\n"; - for (GameDescription::iterator i = m_gameDescription.begin(); i != m_gameDescription.end(); ++i) { - globalOutputStream() << (*i).first.c_str() << " = " << makeQuoted((*i).second.c_str()) << "\n"; - } -} - -CGameDescription *g_pGameDescription; ///< shortcut to g_GamesDialog.m_pCurrentDescription - - -#include "warnings.h" -#include "stream/textfilestream.h" -#include "container/array.h" -#include "xml/ixml.h" -#include "xml/xmlparser.h" -#include "xml/xmlwriter.h" - -#include "preferencedictionary.h" -#include "stringio.h" - -const char *const PREFERENCES_VERSION = "1.0"; - -bool Preferences_Load(PreferenceDictionary &preferences, const char *filename, const char *cmdline_prefix) -{ - bool ret = false; - TextFileInputStream file(filename); - if (!file.failed()) { - XMLStreamParser parser(file); - XMLPreferenceDictionaryImporter importer(preferences, PREFERENCES_VERSION); - parser.exportXML(importer); - ret = true; - } - - int l = strlen(cmdline_prefix); - for (int i = 1; i < g_argc - 1; ++i) { - if (g_argv[i][0] == '-') { - if (!strncmp(g_argv[i] + 1, cmdline_prefix, l)) { - if (g_argv[i][l + 1] == '-') { - preferences.importPref(g_argv[i] + l + 2, g_argv[i + 1]); - } - } - ++i; - } - } - - return ret; -} - -bool Preferences_Save(PreferenceDictionary &preferences, const char *filename) -{ - TextFileOutputStream file(filename); - if (!file.failed()) { - XMLStreamWriter writer(file); - XMLPreferenceDictionaryExporter exporter(preferences, PREFERENCES_VERSION); - exporter.exportXML(writer); - return true; - } - return false; -} - -bool Preferences_Save_Safe(PreferenceDictionary &preferences, const char *filename) -{ - Array tmpName(filename, filename + strlen(filename) + 1 + 3); - *(tmpName.end() - 4) = 'T'; - *(tmpName.end() - 3) = 'M'; - *(tmpName.end() - 2) = 'P'; - *(tmpName.end() - 1) = '\0'; - - return Preferences_Save(preferences, tmpName.data()) - && (!file_exists(filename) || file_remove(filename)) - && file_move(tmpName.data(), filename); -} - -void RegisterGlobalPreferences(PreferenceSystem &preferences) -{ - preferences.registerPreference("gamefile", make_property_string(g_GamesDialog.m_sGameFile)); - preferences.registerPreference("gamePrompt", make_property_string(g_GamesDialog.m_bGamePrompt)); -} - - -PreferenceDictionary g_global_preferences; - -void GlobalPreferences_Init() -{ - RegisterGlobalPreferences(g_global_preferences); -} - -void CGameDialog::LoadPrefs() -{ - // load global .pref file - StringOutputStream strGlobalPref(256); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; - - globalOutputStream() << "loading global preferences from " << makeQuoted(strGlobalPref.c_str()) << "\n"; - - if (!Preferences_Load(g_global_preferences, strGlobalPref.c_str(), "global")) { - globalOutputStream() << "failed to load global preferences from " << strGlobalPref.c_str() << "\n"; - } -} - -void CGameDialog::SavePrefs() -{ - StringOutputStream strGlobalPref(256); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; - - globalOutputStream() << "saving global preferences to " << strGlobalPref.c_str() << "\n"; - - if (!Preferences_Save_Safe(g_global_preferences, strGlobalPref.c_str())) { - globalOutputStream() << "failed to save global preferences to " << strGlobalPref.c_str() << "\n"; - } -} - -void CGameDialog::DoGameDialog() -{ - // show the UI - DoModal(); - - // we save the prefs file - SavePrefs(); -} - -void CGameDialog::GameFileImport(int value) -{ - m_nComboSelect = value; - // use value to set m_sGameFile - std::list::iterator iGame = mGames.begin(); - int i; - for (i = 0; i < value; i++) { - ++iGame; - } - m_sGameFile = (*iGame)->mGameFile; -} - -void CGameDialog::GameFileExport(const Callback &importCallback) const -{ - // use m_sGameFile to set value - std::list::const_iterator iGame; - int i = 0; - for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame) { - if ((*iGame)->mGameFile == m_sGameFile) { - m_nComboSelect = i; - break; - } - i++; - } - importCallback(m_nComboSelect); -} - -struct CGameDialog_GameFile { - static void Export(const CGameDialog &self, const Callback &returnz) - { - self.GameFileExport(returnz); - } - - static void Import(CGameDialog &self, int value) - { - self.GameFileImport(value); - } -}; - -void CGameDialog::CreateGlobalFrame(PreferencesPage &page) -{ - std::vector games; - games.reserve(mGames.size()); - for (std::list::iterator i = mGames.begin(); i != mGames.end(); ++i) { - games.push_back((*i)->getRequiredKeyValue("name")); - } - page.appendCombo( - "Select the game", - StringArrayRange(&(*games.begin()), &(*games.end())), - make_property(*this) - ); - page.appendCheckBox("Startup", "Show Global Preferences", m_bGamePrompt); -} - -ui::Window CGameDialog::BuildDialog() -{ - - auto frame = create_dialog_frame("Game settings", ui::Shadow::ETCHED_IN); - auto image = new_local_image("splash.xpm"); - image.show(); - auto vbox = ui::VBox(FALSE, 2); - auto vbox2 = create_dialog_vbox(0, 4); - vbox.show(); - vbox.pack_start(image, TRUE, TRUE, 0); - frame.add(vbox2); - vbox.pack_start(frame, FALSE, FALSE, 0); - - PreferencesPage preferencesPage(*this, vbox2); - CreateGlobalFrame(preferencesPage); - - return create_simple_modal_dialog_window("Global Preferences", m_modal, vbox); -} - -void CGameDialog::ScanForGames() -{ - StringOutputStream strGamesPath(256); - strGamesPath << AppPath_get() << "games/"; - const char *path = strGamesPath.c_str(); - - globalOutputStream() << "Scanning for game description files: " << path << '\n'; - - /*! - \todo FIXME LINUX: - do we put game description files below AppPath, or in ~/.radiant - i.e. read only or read/write? - my guess .. readonly cause it's an install - we will probably want to add ~/.radiant//games/ scanning on top of that for developers - (if that's really needed) - */ - - Directory_forEach(path, [&](const char *name) { - if (!extension_equal(path_get_extension(name), "game")) { - return; - } - StringOutputStream strPath(256); - strPath << path << name; - globalOutputStream() << strPath.c_str() << '\n'; - - xmlDocPtr pDoc = xmlParseFile(strPath.c_str()); - if (pDoc) { - mGames.push_front(new CGameDescription(pDoc, name)); - xmlFreeDoc(pDoc); - } else { - globalErrorStream() << "XML parser failed on '" << strPath.c_str() << "'\n"; - } - }); -} - -CGameDescription *CGameDialog::GameDescriptionForComboItem() -{ - std::list::iterator iGame; - int i = 0; - for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame, i++) { - if (i == m_nComboSelect) { - return (*iGame); - } - } - return 0; // not found -} - -void CGameDialog::InitGlobalPrefPath() -{ - g_Preferences.m_global_rc_path = g_string_new(SettingsPath_get()); -} - -void CGameDialog::Reset() -{ - if (!g_Preferences.m_global_rc_path) { - InitGlobalPrefPath(); - } - StringOutputStream strGlobalPref(256); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; - file_remove(strGlobalPref.c_str()); -} - -void CGameDialog::Init() -{ - InitGlobalPrefPath(); - LoadPrefs(); - ScanForGames(); - if (mGames.empty()) { - Error("Didn't find any valid game file descriptions, aborting\n"); - } else { - std::list::iterator iGame, iPrevGame; - for (iGame = mGames.begin(), iPrevGame = mGames.end(); iGame != mGames.end(); iPrevGame = iGame, ++iGame) { - if (iPrevGame != mGames.end()) { - if (strcmp((*iGame)->getRequiredKeyValue("name"), (*iPrevGame)->getRequiredKeyValue("name")) < 0) { - CGameDescription *h = *iGame; - *iGame = *iPrevGame; - *iPrevGame = h; - } - } - } - } - - CGameDescription *currentGameDescription = 0; - - if (!m_bGamePrompt) { - // search by .game name - std::list::iterator iGame; - for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame) { - if ((*iGame)->mGameFile == m_sGameFile) { - currentGameDescription = (*iGame); - break; - } - } - } - if (m_bGamePrompt || !currentGameDescription) { - Create(); - DoGameDialog(); - // use m_nComboSelect to identify the game to run as and set the globals - currentGameDescription = GameDescriptionForComboItem(); - ASSERT_NOTNULL(currentGameDescription); - } - g_pGameDescription = currentGameDescription; - - g_pGameDescription->Dump(); -} - -CGameDialog::~CGameDialog() -{ - // free all the game descriptions - std::list::iterator iGame; - for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame) { - delete (*iGame); - *iGame = 0; - } - if (GetWidget()) { - Destroy(); - } -} - -inline const char *GameDescription_getIdentifier(const CGameDescription &gameDescription) -{ - const char *identifier = gameDescription.getKeyValue("index"); - if (string_empty(identifier)) { - identifier = "1"; - } - return identifier; -} - - -CGameDialog g_GamesDialog; - - -// ============================================================================= -// Widget callbacks for PrefsDlg - -static void OnButtonClean(ui::Widget widget, gpointer data) -{ - // make sure this is what the user wants - if (ui::alert(g_Preferences.GetWidget(), "This will close Radiant and clean the corresponding registry entries.\n" - "Next time you start Radiant it will be good as new. Do you wish to continue?", - "Reset Registry", ui::alert_type::YESNO, ui::alert_icon::Asterisk) == ui::alert_response::YES) { - PrefsDlg *dlg = (PrefsDlg *) data; - dlg->EndModal(eIDCANCEL); - - g_preferences_globals.disable_ini = true; - Preferences_Reset(); - gtk_main_quit(); - } -} - -// ============================================================================= -// PrefsDlg class - -/* - ======== - - very first prefs init deals with selecting the game and the game tools path - then we can load .ini stuff - - using prefs / ini settings: - those are per-game - - look in ~/.radiant//gamename - ======== - */ - -const char *PREFS_LOCAL_FILENAME = "local.pref"; - -void PrefsDlg::Init() -{ - // m_global_rc_path has been set above - // m_rc_path is for game specific preferences - // takes the form: global-pref-path/gamename/prefs-file - - // this is common to win32 and Linux init now - m_rc_path = g_string_new(m_global_rc_path->str); - - // game sub-dir - g_string_append(m_rc_path, g_pGameDescription->mGameFile.c_str()); - g_string_append(m_rc_path, "/"); - Q_mkdir(m_rc_path->str); - - // then the ini file - m_inipath = g_string_new(m_rc_path->str); - g_string_append(m_inipath, PREFS_LOCAL_FILENAME); -} - -void notebook_set_page(ui::Widget notebook, ui::Widget page) -{ - int pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), page); - if (gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)) != pagenum) { - gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), pagenum); - } -} - -void PrefsDlg::showPrefPage(ui::Widget prefpage) -{ - notebook_set_page(m_notebook, prefpage); - return; -} - -static void treeSelection(ui::TreeSelection selection, gpointer data) -{ - PrefsDlg *dlg = (PrefsDlg *) data; - - GtkTreeModel *model; - GtkTreeIter selected; - if (gtk_tree_selection_get_selected(selection, &model, &selected)) { - ui::Widget prefpage{ui::null}; - gtk_tree_model_get(model, &selected, 1, (gpointer *) &prefpage, -1); - dlg->showPrefPage(prefpage); - } -} - -typedef std::list PreferenceGroupCallbacks; - -inline void PreferenceGroupCallbacks_constructGroup(const PreferenceGroupCallbacks &callbacks, PreferenceGroup &group) -{ - for (PreferenceGroupCallbacks::const_iterator i = callbacks.begin(); i != callbacks.end(); ++i) { - (*i)(group); - } -} - - -inline void -PreferenceGroupCallbacks_pushBack(PreferenceGroupCallbacks &callbacks, const PreferenceGroupCallback &callback) -{ - callbacks.push_back(callback); -} - -typedef std::list PreferencesPageCallbacks; - -inline void PreferencesPageCallbacks_constructPage(const PreferencesPageCallbacks &callbacks, PreferencesPage &page) -{ - for (PreferencesPageCallbacks::const_iterator i = callbacks.begin(); i != callbacks.end(); ++i) { - (*i)(page); - } -} - -inline void -PreferencesPageCallbacks_pushBack(PreferencesPageCallbacks &callbacks, const PreferencesPageCallback &callback) -{ - callbacks.push_back(callback); -} - -PreferencesPageCallbacks g_interfacePreferences; - -void PreferencesDialog_addInterfacePreferences(const PreferencesPageCallback &callback) -{ - PreferencesPageCallbacks_pushBack(g_interfacePreferences, callback); -} - -PreferenceGroupCallbacks g_interfaceCallbacks; - -void PreferencesDialog_addInterfacePage(const PreferenceGroupCallback &callback) -{ - PreferenceGroupCallbacks_pushBack(g_interfaceCallbacks, callback); -} - -PreferencesPageCallbacks g_displayPreferences; - -void PreferencesDialog_addDisplayPreferences(const PreferencesPageCallback &callback) -{ - PreferencesPageCallbacks_pushBack(g_displayPreferences, callback); -} - -PreferenceGroupCallbacks g_displayCallbacks; - -void PreferencesDialog_addDisplayPage(const PreferenceGroupCallback &callback) -{ - PreferenceGroupCallbacks_pushBack(g_displayCallbacks, callback); -} - -PreferencesPageCallbacks g_settingsPreferences; - -void PreferencesDialog_addSettingsPreferences(const PreferencesPageCallback &callback) -{ - PreferencesPageCallbacks_pushBack(g_settingsPreferences, callback); -} - -PreferenceGroupCallbacks g_settingsCallbacks; - -void PreferencesDialog_addSettingsPage(const PreferenceGroupCallback &callback) -{ - PreferenceGroupCallbacks_pushBack(g_settingsCallbacks, callback); -} - -void Widget_updateDependency(ui::Widget self, ui::Widget toggleButton) -{ - gtk_widget_set_sensitive(self, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggleButton)) && - gtk_widget_is_sensitive(toggleButton)); -} - -void ToggleButton_toggled_Widget_updateDependency(ui::Widget toggleButton, ui::Widget self) -{ - Widget_updateDependency(self, toggleButton); -} - -void ToggleButton_state_changed_Widget_updateDependency(ui::Widget toggleButton, GtkStateType state, ui::Widget self) -{ - if (state == GTK_STATE_INSENSITIVE) { - Widget_updateDependency(self, toggleButton); - } -} - -void Widget_connectToggleDependency(ui::Widget self, ui::Widget toggleButton) -{ - toggleButton.connect("state_changed", G_CALLBACK(ToggleButton_state_changed_Widget_updateDependency), self); - toggleButton.connect("toggled", G_CALLBACK(ToggleButton_toggled_Widget_updateDependency), self); - Widget_updateDependency(self, toggleButton); -} - - -inline ui::VBox getVBox(ui::Bin page) -{ - return ui::VBox::from(gtk_bin_get_child(page)); -} - -GtkTreeIter PreferenceTree_appendPage(ui::TreeStore store, GtkTreeIter *parent, const char *name, ui::Widget page) -{ - GtkTreeIter group; - gtk_tree_store_append(store, &group, parent); - gtk_tree_store_set(store, &group, 0, name, 1, page, -1); - return group; -} - -ui::Bin PreferencePages_addPage(ui::Widget notebook, const char *name) -{ - ui::Widget preflabel = ui::Label(name); - preflabel.show(); - - auto pageframe = ui::Frame(name); - gtk_container_set_border_width(GTK_CONTAINER(pageframe), 4); - pageframe.show(); - - ui::Widget vbox = ui::VBox(FALSE, 4); - vbox.show(); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 4); - pageframe.add(vbox); - - // Add the page to the notebook - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel); - - return pageframe; -} - -class PreferenceTreeGroup : public PreferenceGroup { -Dialog &m_dialog; -ui::Widget m_notebook; -ui::TreeStore m_store; -GtkTreeIter m_group; -public: -PreferenceTreeGroup(Dialog &dialog, ui::Widget notebook, ui::TreeStore store, GtkTreeIter group) : - m_dialog(dialog), - m_notebook(notebook), - m_store(store), - m_group(group) -{ -} - -PreferencesPage createPage(const char *treeName, const char *frameName) -{ - auto page = PreferencePages_addPage(m_notebook, frameName); - PreferenceTree_appendPage(m_store, &m_group, treeName, page); - return PreferencesPage(m_dialog, getVBox(page)); -} -}; - -ui::Window PrefsDlg::BuildDialog() -{ - PreferencesDialog_addInterfacePreferences(makeCallbackF(Interface_constructPreferences)); - Mouse_registerPreferencesPage(); - - ui::Window dialog = ui::Window(create_floating_window("WorldSpawn Preferences", m_parent)); - - { - auto mainvbox = ui::VBox(FALSE, 5); - dialog.add(mainvbox); - gtk_container_set_border_width(GTK_CONTAINER(mainvbox), 5); - mainvbox.show(); - - { - auto hbox = ui::HBox(FALSE, 5); - hbox.show(); - mainvbox.pack_end(hbox, FALSE, TRUE, 0); - - { - auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &m_modal); - hbox.pack_end(button, FALSE, FALSE, 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &m_modal); - hbox.pack_end(button, FALSE, FALSE, 0); - } - { - auto button = create_dialog_button("Clean", G_CALLBACK(OnButtonClean), this); - hbox.pack_end(button, FALSE, FALSE, 0); - } - } - - { - auto hbox = ui::HBox(FALSE, 5); - mainvbox.pack_start(hbox, TRUE, TRUE, 0); - hbox.show(); - - { - auto sc_win = ui::ScrolledWindow(ui::New); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - hbox.pack_start(sc_win, FALSE, FALSE, 0); - sc_win.show(); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sc_win), GTK_SHADOW_IN); - - // prefs pages notebook - m_notebook = ui::Widget::from(gtk_notebook_new()); - // hide the notebook tabs since its not supposed to look like a notebook - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(m_notebook), FALSE); - hbox.pack_start(m_notebook, TRUE, TRUE, 0); - m_notebook.show(); - - - { - auto store = ui::TreeStore::from(gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER)); - - auto view = ui::TreeView(ui::TreeModel::from(store._handle)); - gtk_tree_view_set_headers_visible(view, FALSE); - - { - auto renderer = ui::CellRendererText(ui::New); - auto column = ui::TreeViewColumn("Preferences", renderer, {{"text", 0}}); - gtk_tree_view_append_column(view, column); - } - - { - auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); - selection.connect("changed", G_CALLBACK(treeSelection), this); - } - - view.show(); - - sc_win.add(view); - - { - /********************************************************************/ - /* Add preference tree options */ - /********************************************************************/ - // Front page... - //GtkWidget* front = - PreferencePages_addPage(m_notebook, "Front Page"); - - { - auto global = PreferencePages_addPage(m_notebook, "Global Preferences"); - { - PreferencesPage preferencesPage(*this, getVBox(global)); - } - auto group = PreferenceTree_appendPage(store, 0, "Global", global); - { - auto game = PreferencePages_addPage(m_notebook, "Game"); - PreferencesPage preferencesPage(*this, getVBox(game)); - g_GamesDialog.CreateGlobalFrame(preferencesPage); - - PreferenceTree_appendPage(store, &group, "Game", game); - } - } - - { - auto interfacePage = PreferencePages_addPage(m_notebook, "Interface Preferences"); - { - PreferencesPage preferencesPage(*this, getVBox(interfacePage)); - PreferencesPageCallbacks_constructPage(g_interfacePreferences, preferencesPage); - } - - auto group = PreferenceTree_appendPage(store, 0, "Interface", interfacePage); - PreferenceTreeGroup preferenceGroup(*this, m_notebook, store, group); - - PreferenceGroupCallbacks_constructGroup(g_interfaceCallbacks, preferenceGroup); - } - - { - auto display = PreferencePages_addPage(m_notebook, "Display Preferences"); - { - PreferencesPage preferencesPage(*this, getVBox(display)); - PreferencesPageCallbacks_constructPage(g_displayPreferences, preferencesPage); - } - auto group = PreferenceTree_appendPage(store, 0, "Display", display); - PreferenceTreeGroup preferenceGroup(*this, m_notebook, store, group); - - PreferenceGroupCallbacks_constructGroup(g_displayCallbacks, preferenceGroup); - } - - { - auto settings = PreferencePages_addPage(m_notebook, "General Settings"); - { - PreferencesPage preferencesPage(*this, getVBox(settings)); - PreferencesPageCallbacks_constructPage(g_settingsPreferences, preferencesPage); - } - - auto group = PreferenceTree_appendPage(store, 0, "Settings", settings); - PreferenceTreeGroup preferenceGroup(*this, m_notebook, store, group); - - PreferenceGroupCallbacks_constructGroup(g_settingsCallbacks, preferenceGroup); - } - } - - gtk_tree_view_expand_all(view); - - g_object_unref(G_OBJECT(store)); - } - } - } - } - - gtk_notebook_set_current_page(GTK_NOTEBOOK(m_notebook), 0); - - return dialog; -} - -preferences_globals_t g_preferences_globals; - -PrefsDlg g_Preferences; // global prefs instance - - -void PreferencesDialog_constructWindow(ui::Window main_window) -{ - g_Preferences.m_parent = main_window; - g_Preferences.Create(); -} - -void PreferencesDialog_destroyWindow() -{ - g_Preferences.Destroy(); -} - - -PreferenceDictionary g_preferences; - -PreferenceSystem &GetPreferenceSystem() -{ - return g_preferences; -} - -class PreferenceSystemAPI { -PreferenceSystem *m_preferencesystem; -public: -typedef PreferenceSystem Type; - -STRING_CONSTANT(Name, "*"); - -PreferenceSystemAPI() -{ - m_preferencesystem = &GetPreferenceSystem(); -} - -PreferenceSystem *getTable() -{ - return m_preferencesystem; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule PreferenceSystemModule; -typedef Static StaticPreferenceSystemModule; -StaticRegisterModule staticRegisterPreferenceSystem(StaticPreferenceSystemModule::instance()); - -void Preferences_Load() -{ - g_GamesDialog.LoadPrefs(); - - globalOutputStream() << "loading local preferences from " << g_Preferences.m_inipath->str << "\n"; - - if (!Preferences_Load(g_preferences, g_Preferences.m_inipath->str, g_GamesDialog.m_sGameFile.c_str())) { - globalOutputStream() << "failed to load local preferences from " << g_Preferences.m_inipath->str << "\n"; - } -} - -void Preferences_Save() -{ - if (g_preferences_globals.disable_ini) { - return; - } - - g_GamesDialog.SavePrefs(); - - globalOutputStream() << "saving local preferences to " << g_Preferences.m_inipath->str << "\n"; - - if (!Preferences_Save_Safe(g_preferences, g_Preferences.m_inipath->str)) { - globalOutputStream() << "failed to save local preferences to " << g_Preferences.m_inipath->str << "\n"; - } -} - -void Preferences_Reset() -{ - file_remove(g_Preferences.m_inipath->str); -} - - -void PrefsDlg::PostModal(EMessageBoxReturn code) -{ - if (code == eIDOK) { - Preferences_Save(); - UpdateAllWindows(); - } -} - -std::vector g_restart_required; - -void PreferencesDialog_restartRequired(const char *staticName) -{ - g_restart_required.push_back(staticName); -} - -void PreferencesDialog_showDialog() -{ - if (ConfirmModified("Edit Preferences") && g_Preferences.DoModal() == eIDOK) { - if (!g_restart_required.empty()) { - StringOutputStream message(256); - message << "Preference changes require a restart:\n"; - for (std::vector::iterator i = g_restart_required.begin(); - i != g_restart_required.end(); ++i) { - message << (*i) << '\n'; - } - ui::alert(MainFrame_getWindow(), message.c_str()); - g_restart_required.clear(); - } - } -} - -struct GameName { - static void Export(const Callback &returnz) - { - returnz(gamename_get()); - } - - static void Import(const char *value) - { - gamename_set(value); - } -}; - -struct GameMode { - static void Export(const Callback &returnz) - { - returnz(gamemode_get()); - } - - static void Import(const char *value) - { - gamemode_set(value); - } -}; - -void RegisterPreferences(PreferenceSystem &preferences) -{ -#if GDEF_OS_WINDOWS - preferences.registerPreference( "UseCustomShaderEditor", make_property_string( g_TextEditor_useWin32Editor ) ); -#else - preferences.registerPreference("UseCustomShaderEditor", make_property_string(g_TextEditor_useCustomEditor)); - preferences.registerPreference("CustomShaderEditorCommand", make_property_string(g_TextEditor_editorCommand)); -#endif - - preferences.registerPreference("GameName", make_property()); - preferences.registerPreference("GameMode", make_property()); -} - -void Preferences_Init() -{ - RegisterPreferences(GetPreferenceSystem()); -} diff --git a/src/preferences.h b/src/preferences.h deleted file mode 100644 index 7ea3ba3..0000000 --- a/src/preferences.h +++ /dev/null @@ -1,461 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - The following source code is licensed by Id Software and subject to the terms of - its LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with - GtkRadiant. If you did not receive a LIMITED USE SOFTWARE LICENSE AGREEMENT, - please contact Id Software immediately at info@idsoftware.com. - */ - -#if !defined( INCLUDED_PREFERENCES_H ) -#define INCLUDED_PREFERENCES_H - -#include "libxml/parser.h" -#include "dialog.h" -#include -#include -#include "property.h" - -void Widget_connectToggleDependency(ui::Widget self, ui::Widget toggleButton); - -class PreferencesPage { -Dialog &m_dialog; -ui::VBox m_vbox; -public: -PreferencesPage(Dialog &dialog, ui::VBox vbox) : m_dialog(dialog), m_vbox(vbox) -{ -} - -ui::CheckButton appendCheckBox(const char *name, const char *flag, bool &data) -{ - return m_dialog.addCheckBox(m_vbox, name, flag, data); -} - -ui::CheckButton appendCheckBox(const char *name, const char *flag, Property const &cb) -{ - return m_dialog.addCheckBox(m_vbox, name, flag, cb); -} - -void appendCombo(const char *name, StringArrayRange values, Property const &cb) -{ - m_dialog.addCombo(m_vbox, name, values, cb); -} - -void appendCombo(const char *name, int &data, StringArrayRange values) -{ - m_dialog.addCombo(m_vbox, name, data, values); -} - -void appendSlider(const char *name, int &data, gboolean draw_value, const char *low, const char *high, double value, - double lower, double upper, double step_increment, double page_increment) -{ - m_dialog.addSlider(m_vbox, name, data, draw_value, low, high, value, lower, upper, step_increment, - page_increment); -} - -void appendRadio(const char *name, StringArrayRange names, Property const &cb) -{ - m_dialog.addRadio(m_vbox, name, names, cb); -} - -void appendRadio(const char *name, int &data, StringArrayRange names) -{ - m_dialog.addRadio(m_vbox, name, data, names); -} - -void appendRadioIcons(const char *name, StringArrayRange icons, Property const &cb) -{ - m_dialog.addRadioIcons(m_vbox, name, icons, cb); -} - -void appendRadioIcons(const char *name, int &data, StringArrayRange icons) -{ - m_dialog.addRadioIcons(m_vbox, name, data, icons); -} - -ui::Widget appendEntry(const char *name, Property const &cb) -{ - return m_dialog.addIntEntry(m_vbox, name, cb); -} - -ui::Widget appendEntry(const char *name, int &data) -{ - return m_dialog.addEntry(m_vbox, name, data); -} - -ui::Widget appendEntry(const char *name, Property const &cb) -{ - return m_dialog.addSizeEntry(m_vbox, name, cb); -} - -ui::Widget appendEntry(const char *name, std::size_t &data) -{ - return m_dialog.addEntry(m_vbox, name, data); -} - -ui::Widget appendEntry(const char *name, Property const &cb) -{ - return m_dialog.addFloatEntry(m_vbox, name, cb); -} - -ui::Widget appendEntry(const char *name, float &data) -{ - return m_dialog.addEntry(m_vbox, name, data); -} - -ui::Widget appendPathEntry(const char *name, bool browse_directory, Property const &cb) -{ - return m_dialog.addPathEntry(m_vbox, name, browse_directory, cb); -} - -ui::Widget appendPathEntry(const char *name, CopiedString &data, bool directory) -{ - return m_dialog.addPathEntry(m_vbox, name, data, directory); -} - -ui::SpinButton appendSpinner(const char *name, int &data, double value, double lower, double upper) -{ - return m_dialog.addSpinner(m_vbox, name, data, value, lower, upper); -} - -ui::SpinButton appendSpinner(const char *name, double value, double lower, double upper, Property const &cb) -{ - return m_dialog.addSpinner(m_vbox, name, value, lower, upper, cb); -} - -ui::SpinButton appendSpinner(const char *name, double value, double lower, double upper, Property const &cb) -{ - return m_dialog.addSpinner(m_vbox, name, value, lower, upper, cb); -} -}; - -typedef Callback PreferencesPageCallback; - -class PreferenceGroup { -public: -virtual PreferencesPage createPage(const char *treeName, const char *frameName) = 0; -}; - -typedef Callback PreferenceGroupCallback; - -void PreferencesDialog_addInterfacePreferences(const PreferencesPageCallback &callback); - -void PreferencesDialog_addInterfacePage(const PreferenceGroupCallback &callback); - -void PreferencesDialog_addDisplayPreferences(const PreferencesPageCallback &callback); - -void PreferencesDialog_addDisplayPage(const PreferenceGroupCallback &callback); - -void PreferencesDialog_addSettingsPreferences(const PreferencesPageCallback &callback); - -void PreferencesDialog_addSettingsPage(const PreferenceGroupCallback &callback); - -void PreferencesDialog_restartRequired(const char *staticName); - -template -class LatchedValue { -public: -Value m_value; -Value m_latched; -const char *m_description; - -LatchedValue(Value value, const char *description) : m_latched(value), m_description(description) -{ -} - -void useLatched() -{ - m_value = m_latched; -} -}; - -template -struct PropertyImpl, T> { - static void Export(const LatchedValue &self, const Callback &returnz) - { - returnz(self.m_latched); - } - - static void Import(LatchedValue &self, T value) - { - self.m_latched = value; - if (value != self.m_value) { - PreferencesDialog_restartRequired(self.m_description); - } - } -}; - -template -Property make_property(LatchedValue &self) -{ - return make_property, T>(self); -} - -/*! - holds information for a given game - I'm a bit unclear on that still - it holds game specific configuration stuff - such as base names, engine names, some game specific features to activate in the various modules - it is not strictly a prefs thing since the user is not supposed to edit that (unless he is hacking - support for a new game) - - what we do now is fully generate the information for this during the setup. We might want to - generate a piece that just says "the game pack is there", but put the rest of the config somwhere - else (i.e. not generated, copied over during setup .. for instance in the game tools directory) - */ -class CGameDescription { -typedef std::map GameDescription; - -public: -CopiedString mGameFile; ///< the .game file that describes this game -GameDescription m_gameDescription; - -CopiedString mGameToolsPath; ///< the explicit path to the game-dependent modules -CopiedString mGameType; ///< the type of the engine - -const char *getKeyValue(const char *key) const -{ - GameDescription::const_iterator i = m_gameDescription.find(key); - if (i != m_gameDescription.end()) { - return (*i).second.c_str(); - } - return ""; -} - -const char *getRequiredKeyValue(const char *key) const -{ - GameDescription::const_iterator i = m_gameDescription.find(key); - if (i != m_gameDescription.end()) { - return (*i).second.c_str(); - } - ERROR_MESSAGE("game attribute " << makeQuoted(key) << " not found in " << makeQuoted(mGameFile.c_str())); - return ""; -} - -CGameDescription(xmlDocPtr pDoc, const CopiedString &GameFile); - -void Dump(); -}; - -extern CGameDescription *g_pGameDescription; - -class PrefsDlg; - -class PreferencesPage; - -class StringOutputStream; - -/*! - standalone dialog for games selection, and more generally global settings - */ -class CGameDialog : public Dialog { -protected: - -mutable int m_nComboSelect; ///< intermediate int value for combo in dialog box - -public: - -/*! - those settings are saved in the global prefs file - I'm too lazy to wrap behind protected access, not sure this needs to be public - NOTE: those are preference settings. if you change them it is likely that you would - have to restart the editor for them to take effect - */ -/*@{*/ -/*! - what game has been selected - this is the name of the .game file - */ -CopiedString m_sGameFile; -/*! - prompt which game to load on startup - */ -bool m_bGamePrompt; -/*@}*/ - -/*! - the list of game descriptions we scanned from the game/ dir - */ -std::list mGames; - -CGameDialog() : - m_sGameFile(""), - m_bGamePrompt(true) -{ -} - -virtual ~CGameDialog(); - -/*! - intialize the game dialog, called at CPrefsDlg::Init - will scan for games, load prefs, and do game selection dialog if needed - */ -void Init(); - -/*! - reset the global settings by removing the file - */ -void Reset(); - -/*! - run the dialog UI for the list of games - */ -void DoGameDialog(); - -/*! - Dialog API - this is only called when the dialog is built at startup for main engine select - */ -ui::Window BuildDialog(); - -void GameFileImport(int value); - -void GameFileExport(const Callback &importCallback) const; - -/*! - construction of the dialog frame - this is the part to be re-used in prefs dialog - for the standalone dialog, we include this in a modal box - for prefs, we hook the frame in the main notebook - build the frame on-demand (only once) - */ -void CreateGlobalFrame(PreferencesPage &page); - -/*! - global preferences subsystem - XML-based this time, hopefully this will generalize to other prefs - LoadPrefs has hardcoded defaults - NOTE: it may not be strictly 'CGameDialog' to put the global prefs here - could have named the class differently I guess - */ -/*@{*/ -void LoadPrefs(); ///< load from file into variables -void SavePrefs(); ///< save pref variables to file -/*@}*/ - -private: -/*! - scan for .game files, load them - */ -void ScanForGames(); - -/*! - inits g_Preferences.m_global_rc_path - */ -void InitGlobalPrefPath(); - -/*! - uses m_nComboItem to find the right mGames - */ -CGameDescription *GameDescriptionForComboItem(); -}; - -/*! - this holds global level preferences - */ -extern CGameDialog g_GamesDialog; - - -class texdef_t; - -class PrefsDlg : public Dialog { -public: -protected: -std::list mGames; - -public: - -ui::Widget m_notebook{ui::null}; - -virtual ~PrefsDlg() -{ - g_string_free(m_rc_path, true); - g_string_free(m_inipath, true); -} - -/*! - path for global settings - win32: AppPath - linux: ~/.radiant/[version]/ - */ -GString *m_global_rc_path; - -/*! - path to per-game settings - used for various game dependant storage - win32: GameToolsPath - linux: ~/.radiant/[version]/[gamename]/ - */ -GString *m_rc_path; - -/*! - holds per-game settings - m_rc_path+"local.pref" - \todo FIXME at some point this should become XML property bag code too - */ -GString *m_inipath; - -// initialize the above paths -void Init(); - -/*! Utility function for swapping notebook pages for tree list selections */ -void showPrefPage(ui::Widget prefpage); - -protected: - -/*! Dialog API */ -ui::Window BuildDialog(); - -void PostModal(EMessageBoxReturn code); -}; - -extern PrefsDlg g_Preferences; - -struct preferences_globals_t { - // disabled all INI / registry read write .. used when shutting down after registry cleanup - bool disable_ini; - - preferences_globals_t() : disable_ini(false) - { - } -}; - -extern preferences_globals_t g_preferences_globals; - -void PreferencesDialog_constructWindow(ui::Window main_window); - -void PreferencesDialog_destroyWindow(); - -void PreferencesDialog_showDialog(); - -void GlobalPreferences_Init(); - -void Preferences_Init(); - -void Preferences_Load(); - -void Preferences_Save(); - -void Preferences_Reset(); - - -#endif diff --git a/tools/vmap/prtfile.c b/src/prtfile.c similarity index 100% rename from tools/vmap/prtfile.c rename to src/prtfile.c diff --git a/src/qe3.cpp b/src/qe3.cpp deleted file mode 100644 index bca2c78..0000000 --- a/src/qe3.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - The following source code is licensed by Id Software and subject to the terms of - its LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with - GtkRadiant. If you did not receive a LIMITED USE SOFTWARE LICENSE AGREEMENT, - please contact Id Software immediately at info@idsoftware.com. - */ - -// -// Linux stuff -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "qe3.h" -#include "globaldefs.h" - -#include - -#include "debugging/debugging.h" - -#include "ifilesystem.h" -//#include "imap.h" - -#include - -#include - -#include "stream/textfilestream.h" -#include "cmdlib.h" -#include "stream/stringstream.h" -#include "os/path.h" -#include "scenelib.h" - -#include "gtkutil/messagebox.h" -#include "error.h" -#include "map.h" -#include "build.h" -#include "points.h" -#include "camwindow.h" -#include "mainframe.h" -#include "preferences.h" -#include "watchbsp.h" -#include "autosave.h" -#include "convert.h" - -QEGlobals_t g_qeglobals; - - -#if GDEF_OS_WINDOWS -#define PATH_MAX 260 -#endif - - -void QE_InitVFS() -{ - // VFS initialization ----------------------- - // we will call GlobalFileSystem().initDirectory, giving the directories to look in (for files in pk3's and for standalone files) - // we need to call in order, the mod ones first, then the base ones .. they will be searched in this order - // *nix systems have a dual filesystem in ~/.q3a, which is searched first .. so we need to add that too - - const char *gamename = gamename_get(); - const char *basegame = basegame_get(); - const char *globalRoot = EnginePath_get(); - - // if we have a mod dir - if (!string_equal(gamename, basegame)) { - // / - StringOutputStream globalGamePath(256); - globalGamePath << globalRoot << gamename << '/'; - GlobalFileSystem().initDirectory(globalGamePath.c_str()); - } - - StringOutputStream globalBasePath(256); - globalBasePath << globalRoot << basegame << '/'; - GlobalFileSystem().initDirectory(globalBasePath.c_str()); -} - -int g_numbrushes = 0; -int g_numentities = 0; -int g_numhidden = 0; - -void QE_UpdateStatusBar() -{ - char buffer[128]; - sprintf(buffer, "Brushes: %d Entities: %d Hidden: %d", g_numbrushes, g_numentities, g_numhidden); - g_pParentWnd->SetStatusText(g_pParentWnd->m_brushcount_status, buffer); -} - -SimpleCounter g_brushCount; - -void QE_brushCountChanged() -{ - g_numbrushes = int(g_brushCount.get()); - QE_UpdateStatusBar(); -} - -SimpleCounter g_entityCount; - -void QE_entityCountChanged() -{ - g_numentities = int(g_entityCount.get()); - QE_UpdateStatusBar(); -} - -std::size_t Scene_countHiddenBrushes(scene::Graph &graph); -void QE_hiddenCountChanged() -{ - g_numhidden = int(Scene_countHiddenBrushes(GlobalSceneGraph())); - QE_UpdateStatusBar(); -} - -bool ConfirmModified(const char *title) -{ - if (!Map_Modified(g_map)) { - return true; - } - - auto result = ui::alert(MainFrame_getWindow(), - "The current map has changed since it was last saved.\nDo you want to save the current map before continuing?", - title, ui::alert_type::YESNOCANCEL, ui::alert_icon::Question); - if (result == ui::alert_response::CANCEL) { - return false; - } - if (result == ui::alert_response::YES) { - if (Map_Unnamed(g_map)) { - return Map_SaveAs(); - } else { - return Map_Save(); - } - } - return true; -} - -void bsp_init() -{ - build_set_variable("RadiantPath", AppPath_get()); - build_set_variable("EnginePath", EnginePath_get()); - build_set_variable("UserEnginePath", g_qeglobals.m_userEnginePath.c_str()); - build_set_variable("MonitorAddress", (g_WatchBSP_Enabled) ? "127.0.0.1:39000" : ""); - build_set_variable("GameName", gamename_get()); - - const char *mapname = Map_Name(g_map); - StringOutputStream name(256); - name << StringRange(mapname, path_get_filename_base_end(mapname)) << ".bsp"; - - build_set_variable("MapFile", mapname); - build_set_variable("BspFile", name.c_str()); -} - -void bsp_shutdown() -{ - build_clear_variables(); -} - -class ArrayCommandListener : public CommandListener { -GPtrArray *m_array; -public: -ArrayCommandListener() -{ - m_array = g_ptr_array_new(); -} - -~ArrayCommandListener() -{ - g_ptr_array_free(m_array, TRUE); -} - -void execute(const char *command) -{ - g_ptr_array_add(m_array, g_strdup(command)); -} - -GPtrArray *array() const -{ - return m_array; -} -}; - -class BatchCommandListener : public CommandListener { -TextOutputStream &m_file; -std::size_t m_commandCount; -const char *m_outputRedirect; -public: -BatchCommandListener(TextOutputStream &file, const char *outputRedirect) : m_file(file), m_commandCount(0), - m_outputRedirect(outputRedirect) -{ -} - -void execute(const char *command) -{ - m_file << command; - if (m_commandCount == 0) { - m_file << " > "; - } else { - m_file << " >> "; - } - m_file << "\"" << m_outputRedirect << "\""; - m_file << "\n"; - ++m_commandCount; -} -}; - -bool Region_cameraValid() -{ - Vector3 vOrig(vector3_snapped(Camera_getOrigin(*g_pParentWnd->GetCamWnd()))); - - for (int i = 0; i < 3; i++) { - if (vOrig[i] > region_maxs[i] || vOrig[i] < region_mins[i]) { - return false; - } - } - return true; -} - - -void RunBSP(const char *name) -{ - // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=503 - // make sure we don't attempt to region compile a map with the camera outside the region - if (region_active && !Region_cameraValid()) { - globalErrorStream() << "The camera must be in the region to start a region compile.\n"; - return; - } - - SaveMap(); - - if (Map_Unnamed(g_map)) { - globalOutputStream() << "build cancelled\n"; - return; - } - - if (g_SnapShots_Enabled && !Map_Unnamed(g_map) && Map_Modified(g_map)) { - Map_Snapshot(); - } - - if (region_active) { - const char *mapname = Map_Name(g_map); - StringOutputStream name(256); - name << StringRange(mapname, path_get_filename_base_end(mapname)) << ".reg"; - Map_SaveRegion(name.c_str()); - } - - Pointfile_Delete(); - - bsp_init(); - - if (g_WatchBSP_Enabled) { - ArrayCommandListener listener; - build_run(name, listener); - // grab the file name for engine running - const char *fullname = Map_Name(g_map); - StringOutputStream bspname(64); - bspname << StringRange(path_get_filename_start(fullname), path_get_filename_base_end(fullname)); - BuildMonitor_Run(listener.array(), bspname.c_str()); - } else { - char junkpath[PATH_MAX]; - strcpy(junkpath, SettingsPath_get()); - strcat(junkpath, "junk.txt"); - - char batpath[PATH_MAX]; -#if GDEF_OS_POSIX - strcpy(batpath, SettingsPath_get()); - strcat(batpath, "qe3bsp.sh"); -#elif GDEF_OS_WINDOWS - strcpy( batpath, SettingsPath_get() ); - strcat( batpath, "qe3bsp.bat" ); -#else -#error "unsupported platform" -#endif - bool written = false; - { - TextFileOutputStream batchFile(batpath); - if (!batchFile.failed()) { -#if GDEF_OS_POSIX - batchFile << "#!/bin/sh \n\n"; -#endif - BatchCommandListener listener(batchFile, junkpath); - build_run(name, listener); - written = true; - } - } - if (written) { -#if GDEF_OS_POSIX - chmod(batpath, 0744); -#endif - globalOutputStream() << "Writing the compile script to '" << batpath << "'\n"; - globalOutputStream() << "The build output will be saved in '" << junkpath << "'\n"; - Q_Exec(batpath, NULL, NULL, true, false); - } - } - - bsp_shutdown(); -} - -// ============================================================================= -// Sys_ functions - -void Sys_SetTitle(const char *text, bool modified) -{ - StringOutputStream title; - title << "WorldSpawn - ["; - title << text; - title << "]"; - - if (modified) { - title << " *"; - } - - gtk_window_set_title(MainFrame_getWindow(), title.c_str()); -} - -bool g_bWaitCursor = false; - -void Sys_BeginWait(void) -{ - ScreenUpdates_Disable("Processing...", "Please Wait"); - GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); - gdk_window_set_cursor(gtk_widget_get_window(MainFrame_getWindow()), cursor); - gdk_cursor_unref(cursor); - g_bWaitCursor = true; -} - -void Sys_EndWait(void) -{ - ScreenUpdates_Enable(); - gdk_window_set_cursor(gtk_widget_get_window(MainFrame_getWindow()), 0); - g_bWaitCursor = false; -} - -void Sys_Beep(void) -{ - gdk_beep(); -} diff --git a/src/qe3.h b/src/qe3.h deleted file mode 100644 index fae88ed..0000000 --- a/src/qe3.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_QE3_H ) -#define INCLUDED_QE3_H - -#include "string/string.h" - -// -// system functions -// -void Sys_SetTitle(const char *text, bool modified); - - -void RunBSP(const char *name); - - -void QE_InitVFS(); - -void QE_brushCountChanged(); - -void QE_entityCountChanged(); - -bool ConfirmModified(const char *title); - - -// most of the QE globals are stored in this structure -typedef struct { - /*! - win32: engine full path. - unix: user home full path + engine dir. - */ - CopiedString m_userEnginePath; - /*! - cache for m_userEnginePath + mod subdirectory. - */ - CopiedString m_userGamePath; - -} QEGlobals_t; - -extern QEGlobals_t g_qeglobals; - -class SimpleCounter; - -extern SimpleCounter g_brushCount; -extern SimpleCounter g_entityCount; - - -#endif diff --git a/src/qgl.cpp b/src/qgl.cpp deleted file mode 100644 index d7dce85..0000000 --- a/src/qgl.cpp +++ /dev/null @@ -1,1515 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "qgl.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#if GDEF_OS_WINDOWS -#define WINGDIAPI __declspec( dllimport ) -#define APIENTRY __stdcall -#endif - -#if GDEF_OS_MACOS && !defined( XWINDOWS ) -#include -#else - -#include - -#endif - -#if GDEF_OS_WINDOWS -#undef WINGDIAPI -#undef APIENTRY -#endif - -#include "igl.h" - - -#if GDEF_OS_WINDOWS - -#include - -PROC ( WINAPI * qwglGetProcAddress )( LPCSTR ); - -#elif defined ( XWINDOWS ) - -#include -#include - -Bool ( *qglXQueryExtension )(Display *dpy, int *errorb, int *event); - -void *( *qglXGetProcAddressARB )(const GLubyte *procName); - -typedef void *( *glXGetProcAddressARBProc )(const GLubyte *procName); - -#elif GDEF_OS_MACOS -#include -#include -#include -#else -#error "unsupported platform" -#endif - - -void QGL_Shutdown(OpenGLBinding &table) -{ - globalOutputStream() << "Shutting down OpenGL module..."; - -#if GDEF_OS_WINDOWS - qwglGetProcAddress = 0; -#elif defined( XWINDOWS ) - qglXQueryExtension = glXQueryExtension; - qglXGetProcAddressARB = 0; -#elif GDEF_OS_MACOS -#else -#error "unsupported platform" -#endif - - globalOutputStream() << "Done.\n"; -} - - -typedef struct glu_error_struct { - GLenum errnum; - const char *errstr; -} GLU_ERROR_STRUCT; - -GLU_ERROR_STRUCT glu_errlist[] = { - {GL_NO_ERROR, "GL_NO_ERROR - no error"}, - {GL_INVALID_ENUM, "GL_INVALID_ENUM - An unacceptable value is specified for an enumerated argument."}, - {GL_INVALID_VALUE, "GL_INVALID_VALUE - A numeric argument is out of range."}, - {GL_INVALID_OPERATION, "GL_INVALID_OPERATION - The specified operation is not allowed in the current state."}, - {GL_STACK_OVERFLOW, "GL_STACK_OVERFLOW - Function would cause a stack overflow."}, - {GL_STACK_UNDERFLOW, "GL_STACK_UNDERFLOW - Function would cause a stack underflow."}, - {GL_OUT_OF_MEMORY, "GL_OUT_OF_MEMORY - There is not enough memory left to execute the function."}, - {0, 0} -}; - -const GLubyte *qgluErrorString(GLenum errCode) -{ - int search = 0; - for (search = 0; glu_errlist[search].errstr; search++) { - if (errCode == glu_errlist[search].errnum) { - return (const GLubyte *) glu_errlist[search].errstr; - } - } //end for - return (const GLubyte *) "Unknown error"; -} - - -void glInvalidFunction() -{ - ERROR_MESSAGE("calling an invalid OpenGL function"); -} - -#define EXTENSIONS_ENABLED 1 - -bool QGL_ExtensionSupported(const char *extension) -{ -#if EXTENSIONS_ENABLED - const GLubyte *extensions = 0; - const GLubyte *start; - GLubyte *where, *terminator; - - // Extension names should not have spaces. - where = (GLubyte *) strchr(extension, ' '); - if (where || *extension == '\0') { - return false; - } - - extensions = GlobalOpenGL().m_glGetString(GL_EXTENSIONS); -#if !GDEF_OS_MACOS - if (!extensions) { - return false; - } -#endif - - // It takes a bit of care to be fool-proof about parsing the - // OpenGL extensions string. Don't be fooled by sub-strings, etc. - for (start = extensions;;) { - where = (GLubyte *) strstr((const char *) start, extension); - if (!where) { - break; - } - - terminator = where + strlen(extension); - if (where == start || *(where - 1) == ' ') { - if (*terminator == ' ' || *terminator == '\0') { - return true; - } - } - - start = terminator; - } -#endif - - return false; -} - -typedef int ( QGL_DLLEXPORT *QGLFunctionPointer )(); - -QGLFunctionPointer QGL_getExtensionFunc(const char *symbol) -{ -#if GDEF_OS_WINDOWS - ASSERT_NOTNULL( qwglGetProcAddress ); - return (QGLFunctionPointer) qwglGetProcAddress( symbol ); -#elif defined( XWINDOWS ) - //ASSERT_NOTNULL(qglXGetProcAddressARB); - if (qglXGetProcAddressARB == 0) { - return reinterpret_cast( glInvalidFunction ); - } else { - return (QGLFunctionPointer) qglXGetProcAddressARB(reinterpret_cast( symbol )); - } -#elif GDEF_OS_MACOS - // Prepend a '_' for the Unix C symbol mangling convention - char *symbolName = (char *) malloc(strlen(symbol) + 2); - strcpy(symbolName + 1, symbol); - symbolName[0] = '_'; - NSSymbol nssymbol = NULL; - if (NSIsSymbolNameDefined(symbolName)) nssymbol = NSLookupAndBindSymbol(symbolName); - free(symbolName); - return nssymbol ? reinterpret_cast(NSAddressOfSymbol(nssymbol)) : reinterpret_cast(glInvalidFunction); -#error "unsupported platform" -#endif -} - - -template -bool QGL_constructExtensionFunc(Func &func, const char *symbol) -{ - func = reinterpret_cast( QGL_getExtensionFunc(symbol)); - return func != 0; -} - -template -void QGL_invalidateExtensionFunc(Func &func) -{ - func = reinterpret_cast( glInvalidFunction ); -} - -void QGL_clear(OpenGLBinding &table) -{ - QGL_invalidateExtensionFunc(table.m_glAccum); - QGL_invalidateExtensionFunc(table.m_glAlphaFunc); - QGL_invalidateExtensionFunc(table.m_glAreTexturesResident); - QGL_invalidateExtensionFunc(table.m_glArrayElement); - QGL_invalidateExtensionFunc(table.m_glBegin); - QGL_invalidateExtensionFunc(table.m_glBindTexture); - QGL_invalidateExtensionFunc(table.m_glBitmap); - QGL_invalidateExtensionFunc(table.m_glBlendFunc); - QGL_invalidateExtensionFunc(table.m_glCallList); - QGL_invalidateExtensionFunc(table.m_glCallLists); - QGL_invalidateExtensionFunc(table.m_glClear); - QGL_invalidateExtensionFunc(table.m_glClearAccum); - QGL_invalidateExtensionFunc(table.m_glClearColor); - QGL_invalidateExtensionFunc(table.m_glClearDepth); - QGL_invalidateExtensionFunc(table.m_glClearIndex); - QGL_invalidateExtensionFunc(table.m_glClearStencil); - QGL_invalidateExtensionFunc(table.m_glClipPlane); - QGL_invalidateExtensionFunc(table.m_glColor3b); - QGL_invalidateExtensionFunc(table.m_glColor3bv); - QGL_invalidateExtensionFunc(table.m_glColor3d); - QGL_invalidateExtensionFunc(table.m_glColor3dv); - QGL_invalidateExtensionFunc(table.m_glColor3f); - QGL_invalidateExtensionFunc(table.m_glColor3fv); - QGL_invalidateExtensionFunc(table.m_glColor3i); - QGL_invalidateExtensionFunc(table.m_glColor3iv); - QGL_invalidateExtensionFunc(table.m_glColor3s); - QGL_invalidateExtensionFunc(table.m_glColor3sv); - QGL_invalidateExtensionFunc(table.m_glColor3ub); - QGL_invalidateExtensionFunc(table.m_glColor3ubv); - QGL_invalidateExtensionFunc(table.m_glColor3ui); - QGL_invalidateExtensionFunc(table.m_glColor3uiv); - QGL_invalidateExtensionFunc(table.m_glColor3us); - QGL_invalidateExtensionFunc(table.m_glColor3usv); - QGL_invalidateExtensionFunc(table.m_glColor4b); - QGL_invalidateExtensionFunc(table.m_glColor4bv); - QGL_invalidateExtensionFunc(table.m_glColor4d); - QGL_invalidateExtensionFunc(table.m_glColor4dv); - QGL_invalidateExtensionFunc(table.m_glColor4f); - QGL_invalidateExtensionFunc(table.m_glColor4fv); - QGL_invalidateExtensionFunc(table.m_glColor4i); - QGL_invalidateExtensionFunc(table.m_glColor4iv); - QGL_invalidateExtensionFunc(table.m_glColor4s); - QGL_invalidateExtensionFunc(table.m_glColor4sv); - QGL_invalidateExtensionFunc(table.m_glColor4ub); - QGL_invalidateExtensionFunc(table.m_glColor4ubv); - QGL_invalidateExtensionFunc(table.m_glColor4ui); - QGL_invalidateExtensionFunc(table.m_glColor4uiv); - QGL_invalidateExtensionFunc(table.m_glColor4us); - QGL_invalidateExtensionFunc(table.m_glColor4usv); - QGL_invalidateExtensionFunc(table.m_glColorMask); - QGL_invalidateExtensionFunc(table.m_glColorMaterial); - QGL_invalidateExtensionFunc(table.m_glColorPointer); - QGL_invalidateExtensionFunc(table.m_glCopyPixels); - QGL_invalidateExtensionFunc(table.m_glCopyTexImage1D); - QGL_invalidateExtensionFunc(table.m_glCopyTexImage2D); - QGL_invalidateExtensionFunc(table.m_glCopyTexSubImage1D); - QGL_invalidateExtensionFunc(table.m_glCopyTexSubImage2D); - QGL_invalidateExtensionFunc(table.m_glCullFace); - QGL_invalidateExtensionFunc(table.m_glDeleteLists); - QGL_invalidateExtensionFunc(table.m_glDeleteTextures); - QGL_invalidateExtensionFunc(table.m_glDepthFunc); - QGL_invalidateExtensionFunc(table.m_glDepthMask); - QGL_invalidateExtensionFunc(table.m_glDepthRange); - QGL_invalidateExtensionFunc(table.m_glDisable); - QGL_invalidateExtensionFunc(table.m_glDisableClientState); - QGL_invalidateExtensionFunc(table.m_glDrawArrays); - QGL_invalidateExtensionFunc(table.m_glDrawBuffer); - QGL_invalidateExtensionFunc(table.m_glDrawElements); - QGL_invalidateExtensionFunc(table.m_glDrawPixels); - QGL_invalidateExtensionFunc(table.m_glEdgeFlag); - QGL_invalidateExtensionFunc(table.m_glEdgeFlagPointer); - QGL_invalidateExtensionFunc(table.m_glEdgeFlagv); - QGL_invalidateExtensionFunc(table.m_glEnable); - QGL_invalidateExtensionFunc(table.m_glEnableClientState); - QGL_invalidateExtensionFunc(table.m_glEnd); - QGL_invalidateExtensionFunc(table.m_glEndList); - QGL_invalidateExtensionFunc(table.m_glEvalCoord1d); - QGL_invalidateExtensionFunc(table.m_glEvalCoord1dv); - QGL_invalidateExtensionFunc(table.m_glEvalCoord1f); - QGL_invalidateExtensionFunc(table.m_glEvalCoord1fv); - QGL_invalidateExtensionFunc(table.m_glEvalCoord2d); - QGL_invalidateExtensionFunc(table.m_glEvalCoord2dv); - QGL_invalidateExtensionFunc(table.m_glEvalCoord2f); - QGL_invalidateExtensionFunc(table.m_glEvalCoord2fv); - QGL_invalidateExtensionFunc(table.m_glEvalMesh1); - QGL_invalidateExtensionFunc(table.m_glEvalMesh2); - QGL_invalidateExtensionFunc(table.m_glEvalPoint1); - QGL_invalidateExtensionFunc(table.m_glEvalPoint2); - QGL_invalidateExtensionFunc(table.m_glFeedbackBuffer); - QGL_invalidateExtensionFunc(table.m_glFinish); - QGL_invalidateExtensionFunc(table.m_glFlush); - QGL_invalidateExtensionFunc(table.m_glFogf); - QGL_invalidateExtensionFunc(table.m_glFogfv); - QGL_invalidateExtensionFunc(table.m_glFogi); - QGL_invalidateExtensionFunc(table.m_glFogiv); - QGL_invalidateExtensionFunc(table.m_glFrontFace); - QGL_invalidateExtensionFunc(table.m_glFrustum); - QGL_invalidateExtensionFunc(table.m_glGenLists); - QGL_invalidateExtensionFunc(table.m_glGenTextures); - QGL_invalidateExtensionFunc(table.m_glGetBooleanv); - QGL_invalidateExtensionFunc(table.m_glGetClipPlane); - QGL_invalidateExtensionFunc(table.m_glGetDoublev); - QGL_invalidateExtensionFunc(table.m_glGetError); - QGL_invalidateExtensionFunc(table.m_glGetFloatv); - QGL_invalidateExtensionFunc(table.m_glGetIntegerv); - QGL_invalidateExtensionFunc(table.m_glGetLightfv); - QGL_invalidateExtensionFunc(table.m_glGetLightiv); - QGL_invalidateExtensionFunc(table.m_glGetMapdv); - QGL_invalidateExtensionFunc(table.m_glGetMapfv); - QGL_invalidateExtensionFunc(table.m_glGetMapiv); - QGL_invalidateExtensionFunc(table.m_glGetMaterialfv); - QGL_invalidateExtensionFunc(table.m_glGetMaterialiv); - QGL_invalidateExtensionFunc(table.m_glGetPixelMapfv); - QGL_invalidateExtensionFunc(table.m_glGetPixelMapuiv); - QGL_invalidateExtensionFunc(table.m_glGetPixelMapusv); - QGL_invalidateExtensionFunc(table.m_glGetPointerv); - QGL_invalidateExtensionFunc(table.m_glGetPolygonStipple); - table.m_glGetString = glGetString; - QGL_invalidateExtensionFunc(table.m_glGetTexEnvfv); - QGL_invalidateExtensionFunc(table.m_glGetTexEnviv); - QGL_invalidateExtensionFunc(table.m_glGetTexGendv); - QGL_invalidateExtensionFunc(table.m_glGetTexGenfv); - QGL_invalidateExtensionFunc(table.m_glGetTexGeniv); - QGL_invalidateExtensionFunc(table.m_glGetTexImage); - QGL_invalidateExtensionFunc(table.m_glGetTexLevelParameterfv); - QGL_invalidateExtensionFunc(table.m_glGetTexLevelParameteriv); - QGL_invalidateExtensionFunc(table.m_glGetTexParameterfv); - QGL_invalidateExtensionFunc(table.m_glGetTexParameteriv); - QGL_invalidateExtensionFunc(table.m_glHint); - QGL_invalidateExtensionFunc(table.m_glIndexMask); - QGL_invalidateExtensionFunc(table.m_glIndexPointer); - QGL_invalidateExtensionFunc(table.m_glIndexd); - QGL_invalidateExtensionFunc(table.m_glIndexdv); - QGL_invalidateExtensionFunc(table.m_glIndexf); - QGL_invalidateExtensionFunc(table.m_glIndexfv); - QGL_invalidateExtensionFunc(table.m_glIndexi); - QGL_invalidateExtensionFunc(table.m_glIndexiv); - QGL_invalidateExtensionFunc(table.m_glIndexs); - QGL_invalidateExtensionFunc(table.m_glIndexsv); - QGL_invalidateExtensionFunc(table.m_glIndexub); - QGL_invalidateExtensionFunc(table.m_glIndexubv); - QGL_invalidateExtensionFunc(table.m_glInitNames); - QGL_invalidateExtensionFunc(table.m_glInterleavedArrays); - QGL_invalidateExtensionFunc(table.m_glIsEnabled); - QGL_invalidateExtensionFunc(table.m_glIsList); - QGL_invalidateExtensionFunc(table.m_glIsTexture); - QGL_invalidateExtensionFunc(table.m_glLightModelf); - QGL_invalidateExtensionFunc(table.m_glLightModelfv); - QGL_invalidateExtensionFunc(table.m_glLightModeli); - QGL_invalidateExtensionFunc(table.m_glLightModeliv); - QGL_invalidateExtensionFunc(table.m_glLightf); - QGL_invalidateExtensionFunc(table.m_glLightfv); - QGL_invalidateExtensionFunc(table.m_glLighti); - QGL_invalidateExtensionFunc(table.m_glLightiv); - QGL_invalidateExtensionFunc(table.m_glLineStipple); - QGL_invalidateExtensionFunc(table.m_glLineWidth); - QGL_invalidateExtensionFunc(table.m_glListBase); - QGL_invalidateExtensionFunc(table.m_glLoadIdentity); - QGL_invalidateExtensionFunc(table.m_glLoadMatrixd); - QGL_invalidateExtensionFunc(table.m_glLoadMatrixf); - QGL_invalidateExtensionFunc(table.m_glLoadName); - QGL_invalidateExtensionFunc(table.m_glLogicOp); - QGL_invalidateExtensionFunc(table.m_glMap1d); - QGL_invalidateExtensionFunc(table.m_glMap1f); - QGL_invalidateExtensionFunc(table.m_glMap2d); - QGL_invalidateExtensionFunc(table.m_glMap2f); - QGL_invalidateExtensionFunc(table.m_glMapGrid1d); - QGL_invalidateExtensionFunc(table.m_glMapGrid1f); - QGL_invalidateExtensionFunc(table.m_glMapGrid2d); - QGL_invalidateExtensionFunc(table.m_glMapGrid2f); - QGL_invalidateExtensionFunc(table.m_glMaterialf); - QGL_invalidateExtensionFunc(table.m_glMaterialfv); - QGL_invalidateExtensionFunc(table.m_glMateriali); - QGL_invalidateExtensionFunc(table.m_glMaterialiv); - QGL_invalidateExtensionFunc(table.m_glMatrixMode); - QGL_invalidateExtensionFunc(table.m_glMultMatrixd); - QGL_invalidateExtensionFunc(table.m_glMultMatrixf); - QGL_invalidateExtensionFunc(table.m_glNewList); - QGL_invalidateExtensionFunc(table.m_glNormal3b); - QGL_invalidateExtensionFunc(table.m_glNormal3bv); - QGL_invalidateExtensionFunc(table.m_glNormal3d); - QGL_invalidateExtensionFunc(table.m_glNormal3dv); - QGL_invalidateExtensionFunc(table.m_glNormal3f); - QGL_invalidateExtensionFunc(table.m_glNormal3fv); - QGL_invalidateExtensionFunc(table.m_glNormal3i); - QGL_invalidateExtensionFunc(table.m_glNormal3iv); - QGL_invalidateExtensionFunc(table.m_glNormal3s); - QGL_invalidateExtensionFunc(table.m_glNormal3sv); - QGL_invalidateExtensionFunc(table.m_glNormalPointer); - QGL_invalidateExtensionFunc(table.m_glOrtho); - QGL_invalidateExtensionFunc(table.m_glPassThrough); - QGL_invalidateExtensionFunc(table.m_glPixelMapfv); - QGL_invalidateExtensionFunc(table.m_glPixelMapuiv); - QGL_invalidateExtensionFunc(table.m_glPixelMapusv); - QGL_invalidateExtensionFunc(table.m_glPixelStoref); - QGL_invalidateExtensionFunc(table.m_glPixelStorei); - QGL_invalidateExtensionFunc(table.m_glPixelTransferf); - QGL_invalidateExtensionFunc(table.m_glPixelTransferi); - QGL_invalidateExtensionFunc(table.m_glPixelZoom); - QGL_invalidateExtensionFunc(table.m_glPointSize); - QGL_invalidateExtensionFunc(table.m_glPolygonMode); - QGL_invalidateExtensionFunc(table.m_glPolygonOffset); - QGL_invalidateExtensionFunc(table.m_glPolygonStipple); - QGL_invalidateExtensionFunc(table.m_glPopAttrib); - QGL_invalidateExtensionFunc(table.m_glPopClientAttrib); - QGL_invalidateExtensionFunc(table.m_glPopMatrix); - QGL_invalidateExtensionFunc(table.m_glPopName); - QGL_invalidateExtensionFunc(table.m_glPrioritizeTextures); - QGL_invalidateExtensionFunc(table.m_glPushAttrib); - QGL_invalidateExtensionFunc(table.m_glPushClientAttrib); - QGL_invalidateExtensionFunc(table.m_glPushMatrix); - QGL_invalidateExtensionFunc(table.m_glPushName); - QGL_invalidateExtensionFunc(table.m_glRasterPos2d); - QGL_invalidateExtensionFunc(table.m_glRasterPos2dv); - QGL_invalidateExtensionFunc(table.m_glRasterPos2f); - QGL_invalidateExtensionFunc(table.m_glRasterPos2fv); - QGL_invalidateExtensionFunc(table.m_glRasterPos2i); - QGL_invalidateExtensionFunc(table.m_glRasterPos2iv); - QGL_invalidateExtensionFunc(table.m_glRasterPos2s); - QGL_invalidateExtensionFunc(table.m_glRasterPos2sv); - QGL_invalidateExtensionFunc(table.m_glRasterPos3d); - QGL_invalidateExtensionFunc(table.m_glRasterPos3dv); - QGL_invalidateExtensionFunc(table.m_glRasterPos3f); - QGL_invalidateExtensionFunc(table.m_glRasterPos3fv); - QGL_invalidateExtensionFunc(table.m_glRasterPos3i); - QGL_invalidateExtensionFunc(table.m_glRasterPos3iv); - QGL_invalidateExtensionFunc(table.m_glRasterPos3s); - QGL_invalidateExtensionFunc(table.m_glRasterPos3sv); - QGL_invalidateExtensionFunc(table.m_glRasterPos4d); - QGL_invalidateExtensionFunc(table.m_glRasterPos4dv); - QGL_invalidateExtensionFunc(table.m_glRasterPos4f); - QGL_invalidateExtensionFunc(table.m_glRasterPos4fv); - QGL_invalidateExtensionFunc(table.m_glRasterPos4i); - QGL_invalidateExtensionFunc(table.m_glRasterPos4iv); - QGL_invalidateExtensionFunc(table.m_glRasterPos4s); - QGL_invalidateExtensionFunc(table.m_glRasterPos4sv); - QGL_invalidateExtensionFunc(table.m_glReadBuffer); - QGL_invalidateExtensionFunc(table.m_glReadPixels); - QGL_invalidateExtensionFunc(table.m_glRectd); - QGL_invalidateExtensionFunc(table.m_glRectdv); - QGL_invalidateExtensionFunc(table.m_glRectf); - QGL_invalidateExtensionFunc(table.m_glRectfv); - QGL_invalidateExtensionFunc(table.m_glRecti); - QGL_invalidateExtensionFunc(table.m_glRectiv); - QGL_invalidateExtensionFunc(table.m_glRects); - QGL_invalidateExtensionFunc(table.m_glRectsv); - QGL_invalidateExtensionFunc(table.m_glRenderMode); - QGL_invalidateExtensionFunc(table.m_glRotated); - QGL_invalidateExtensionFunc(table.m_glRotatef); - QGL_invalidateExtensionFunc(table.m_glScaled); - QGL_invalidateExtensionFunc(table.m_glScalef); - QGL_invalidateExtensionFunc(table.m_glScissor); - QGL_invalidateExtensionFunc(table.m_glSelectBuffer); - QGL_invalidateExtensionFunc(table.m_glShadeModel); - QGL_invalidateExtensionFunc(table.m_glStencilFunc); - QGL_invalidateExtensionFunc(table.m_glStencilMask); - QGL_invalidateExtensionFunc(table.m_glStencilOp); - QGL_invalidateExtensionFunc(table.m_glTexCoord1d); - QGL_invalidateExtensionFunc(table.m_glTexCoord1dv); - QGL_invalidateExtensionFunc(table.m_glTexCoord1f); - QGL_invalidateExtensionFunc(table.m_glTexCoord1fv); - QGL_invalidateExtensionFunc(table.m_glTexCoord1i); - QGL_invalidateExtensionFunc(table.m_glTexCoord1iv); - QGL_invalidateExtensionFunc(table.m_glTexCoord1s); - QGL_invalidateExtensionFunc(table.m_glTexCoord1sv); - QGL_invalidateExtensionFunc(table.m_glTexCoord2d); - QGL_invalidateExtensionFunc(table.m_glTexCoord2dv); - QGL_invalidateExtensionFunc(table.m_glTexCoord2f); - QGL_invalidateExtensionFunc(table.m_glTexCoord2fv); - QGL_invalidateExtensionFunc(table.m_glTexCoord2i); - QGL_invalidateExtensionFunc(table.m_glTexCoord2iv); - QGL_invalidateExtensionFunc(table.m_glTexCoord2s); - QGL_invalidateExtensionFunc(table.m_glTexCoord2sv); - QGL_invalidateExtensionFunc(table.m_glTexCoord3d); - QGL_invalidateExtensionFunc(table.m_glTexCoord3dv); - QGL_invalidateExtensionFunc(table.m_glTexCoord3f); - QGL_invalidateExtensionFunc(table.m_glTexCoord3fv); - QGL_invalidateExtensionFunc(table.m_glTexCoord3i); - QGL_invalidateExtensionFunc(table.m_glTexCoord3iv); - QGL_invalidateExtensionFunc(table.m_glTexCoord3s); - QGL_invalidateExtensionFunc(table.m_glTexCoord3sv); - QGL_invalidateExtensionFunc(table.m_glTexCoord4d); - QGL_invalidateExtensionFunc(table.m_glTexCoord4dv); - QGL_invalidateExtensionFunc(table.m_glTexCoord4f); - QGL_invalidateExtensionFunc(table.m_glTexCoord4fv); - QGL_invalidateExtensionFunc(table.m_glTexCoord4i); - QGL_invalidateExtensionFunc(table.m_glTexCoord4iv); - QGL_invalidateExtensionFunc(table.m_glTexCoord4s); - QGL_invalidateExtensionFunc(table.m_glTexCoord4sv); - QGL_invalidateExtensionFunc(table.m_glTexCoordPointer); - QGL_invalidateExtensionFunc(table.m_glTexEnvf); - QGL_invalidateExtensionFunc(table.m_glTexEnvfv); - QGL_invalidateExtensionFunc(table.m_glTexEnvi); - QGL_invalidateExtensionFunc(table.m_glTexEnviv); - QGL_invalidateExtensionFunc(table.m_glTexGend); - QGL_invalidateExtensionFunc(table.m_glTexGendv); - QGL_invalidateExtensionFunc(table.m_glTexGenf); - QGL_invalidateExtensionFunc(table.m_glTexGenfv); - QGL_invalidateExtensionFunc(table.m_glTexGeni); - QGL_invalidateExtensionFunc(table.m_glTexGeniv); - QGL_invalidateExtensionFunc(table.m_glTexImage1D); - QGL_invalidateExtensionFunc(table.m_glTexImage2D); - QGL_invalidateExtensionFunc(table.m_glTexParameterf); - QGL_invalidateExtensionFunc(table.m_glTexParameterfv); - QGL_invalidateExtensionFunc(table.m_glTexParameteri); - QGL_invalidateExtensionFunc(table.m_glTexParameteriv); - QGL_invalidateExtensionFunc(table.m_glTexSubImage1D); - QGL_invalidateExtensionFunc(table.m_glTexSubImage2D); - QGL_invalidateExtensionFunc(table.m_glTranslated); - QGL_invalidateExtensionFunc(table.m_glTranslatef); - QGL_invalidateExtensionFunc(table.m_glVertex2d); - QGL_invalidateExtensionFunc(table.m_glVertex2dv); - QGL_invalidateExtensionFunc(table.m_glVertex2f); - QGL_invalidateExtensionFunc(table.m_glVertex2fv); - QGL_invalidateExtensionFunc(table.m_glVertex2i); - QGL_invalidateExtensionFunc(table.m_glVertex2iv); - QGL_invalidateExtensionFunc(table.m_glVertex2s); - QGL_invalidateExtensionFunc(table.m_glVertex2sv); - QGL_invalidateExtensionFunc(table.m_glVertex3d); - QGL_invalidateExtensionFunc(table.m_glVertex3dv); - QGL_invalidateExtensionFunc(table.m_glVertex3f); - QGL_invalidateExtensionFunc(table.m_glVertex3fv); - QGL_invalidateExtensionFunc(table.m_glVertex3i); - QGL_invalidateExtensionFunc(table.m_glVertex3iv); - QGL_invalidateExtensionFunc(table.m_glVertex3s); - QGL_invalidateExtensionFunc(table.m_glVertex3sv); - QGL_invalidateExtensionFunc(table.m_glVertex4d); - QGL_invalidateExtensionFunc(table.m_glVertex4dv); - QGL_invalidateExtensionFunc(table.m_glVertex4f); - QGL_invalidateExtensionFunc(table.m_glVertex4fv); - QGL_invalidateExtensionFunc(table.m_glVertex4i); - QGL_invalidateExtensionFunc(table.m_glVertex4iv); - QGL_invalidateExtensionFunc(table.m_glVertex4s); - QGL_invalidateExtensionFunc(table.m_glVertex4sv); - QGL_invalidateExtensionFunc(table.m_glVertexPointer); - QGL_invalidateExtensionFunc(table.m_glViewport); -} - -int QGL_Init(OpenGLBinding &table) -{ - QGL_clear(table); - -#if GDEF_OS_WINDOWS - qwglGetProcAddress = wglGetProcAddress; -#elif defined( XWINDOWS ) - qglXGetProcAddressARB = (glXGetProcAddressARBProc) dlsym(RTLD_DEFAULT, "glXGetProcAddressARB"); - if ((qglXQueryExtension == 0)) { - return 0; - } -#elif GDEF_OS_MACOS -#else -#error "unsupported platform" -#endif - - return 1; -} - -int g_qglMajorVersion = 0; -int g_qglMinorVersion = 0; - -// requires a valid gl context -void QGL_InitVersion() -{ -#if EXTENSIONS_ENABLED - const std::size_t versionSize = 256; - char version[versionSize]; - strncpy(version, reinterpret_cast( GlobalOpenGL().m_glGetString(GL_VERSION)), versionSize - 1); - version[versionSize - 1] = '\0'; - char *firstDot = strchr(version, '.'); - ASSERT_NOTNULL(firstDot); - *firstDot = '\0'; - g_qglMajorVersion = atoi(version); - char *secondDot = strchr(firstDot + 1, '.'); - if (secondDot != 0) { - *secondDot = '\0'; - } - g_qglMinorVersion = atoi(firstDot + 1); -#else - g_qglMajorVersion = 1; - g_qglMinorVersion = 1; -#endif -} - - -inline void extension_not_implemented(const char *extension) -{ - globalErrorStream() << "WARNING: OpenGL driver reports support for " << extension << " but does not implement it\n"; -} - -float g_maxTextureAnisotropy; - -float QGL_maxTextureAnisotropy() -{ - return g_maxTextureAnisotropy; -} - -void QGL_sharedContextCreated(OpenGLBinding &table) -{ - QGL_InitVersion(); - - table.major_version = g_qglMajorVersion; - table.minor_version = g_qglMinorVersion; - - table.m_glAccum = glAccum; - table.m_glAlphaFunc = glAlphaFunc; - table.m_glAreTexturesResident = glAreTexturesResident; - table.m_glArrayElement = glArrayElement; - table.m_glBegin = glBegin; - table.m_glBindTexture = glBindTexture; - table.m_glBitmap = glBitmap; - table.m_glBlendFunc = glBlendFunc; - table.m_glCallList = glCallList; - table.m_glCallLists = glCallLists; - table.m_glClear = glClear; - table.m_glClearAccum = glClearAccum; - table.m_glClearColor = glClearColor; - table.m_glClearDepth = glClearDepth; - table.m_glClearIndex = glClearIndex; - table.m_glClearStencil = glClearStencil; - table.m_glClipPlane = glClipPlane; - table.m_glColor3b = glColor3b; - table.m_glColor3bv = glColor3bv; - table.m_glColor3d = glColor3d; - table.m_glColor3dv = glColor3dv; - table.m_glColor3f = glColor3f; - table.m_glColor3fv = glColor3fv; - table.m_glColor3i = glColor3i; - table.m_glColor3iv = glColor3iv; - table.m_glColor3s = glColor3s; - table.m_glColor3sv = glColor3sv; - table.m_glColor3ub = glColor3ub; - table.m_glColor3ubv = glColor3ubv; - table.m_glColor3ui = glColor3ui; - table.m_glColor3uiv = glColor3uiv; - table.m_glColor3us = glColor3us; - table.m_glColor3usv = glColor3usv; - table.m_glColor4b = glColor4b; - table.m_glColor4bv = glColor4bv; - table.m_glColor4d = glColor4d; - table.m_glColor4dv = glColor4dv; - table.m_glColor4f = glColor4f; - table.m_glColor4fv = glColor4fv; - table.m_glColor4i = glColor4i; - table.m_glColor4iv = glColor4iv; - table.m_glColor4s = glColor4s; - table.m_glColor4sv = glColor4sv; - table.m_glColor4ub = glColor4ub; - table.m_glColor4ubv = glColor4ubv; - table.m_glColor4ui = glColor4ui; - table.m_glColor4uiv = glColor4uiv; - table.m_glColor4us = glColor4us; - table.m_glColor4usv = glColor4usv; - table.m_glColorMask = glColorMask; - table.m_glColorMaterial = glColorMaterial; - table.m_glColorPointer = glColorPointer; - table.m_glCopyPixels = glCopyPixels; - table.m_glCopyTexImage1D = glCopyTexImage1D; - table.m_glCopyTexImage2D = glCopyTexImage2D; - table.m_glCopyTexSubImage1D = glCopyTexSubImage1D; - table.m_glCopyTexSubImage2D = glCopyTexSubImage2D; - table.m_glCullFace = glCullFace; - table.m_glDeleteLists = glDeleteLists; - table.m_glDeleteTextures = glDeleteTextures; - table.m_glDepthFunc = glDepthFunc; - table.m_glDepthMask = glDepthMask; - table.m_glDepthRange = glDepthRange; - table.m_glDisable = glDisable; - table.m_glDisableClientState = glDisableClientState; - table.m_glDrawArrays = glDrawArrays; - table.m_glDrawBuffer = glDrawBuffer; - table.m_glDrawElements = glDrawElements; - table.m_glDrawPixels = glDrawPixels; - table.m_glEdgeFlag = glEdgeFlag; - table.m_glEdgeFlagPointer = glEdgeFlagPointer; - table.m_glEdgeFlagv = glEdgeFlagv; - table.m_glEnable = glEnable; - table.m_glEnableClientState = glEnableClientState; - table.m_glEnd = glEnd; - table.m_glEndList = glEndList; - table.m_glEvalCoord1d = glEvalCoord1d; - table.m_glEvalCoord1dv = glEvalCoord1dv; - table.m_glEvalCoord1f = glEvalCoord1f; - table.m_glEvalCoord1fv = glEvalCoord1fv; - table.m_glEvalCoord2d = glEvalCoord2d; - table.m_glEvalCoord2dv = glEvalCoord2dv; - table.m_glEvalCoord2f = glEvalCoord2f; - table.m_glEvalCoord2fv = glEvalCoord2fv; - table.m_glEvalMesh1 = glEvalMesh1; - table.m_glEvalMesh2 = glEvalMesh2; - table.m_glEvalPoint1 = glEvalPoint1; - table.m_glEvalPoint2 = glEvalPoint2; - table.m_glFeedbackBuffer = glFeedbackBuffer; - table.m_glFinish = glFinish; - table.m_glFlush = glFlush; - table.m_glFogf = glFogf; - table.m_glFogfv = glFogfv; - table.m_glFogi = glFogi; - table.m_glFogiv = glFogiv; - table.m_glFrontFace = glFrontFace; - table.m_glFrustum = glFrustum; - table.m_glGenLists = glGenLists; - table.m_glGenTextures = glGenTextures; - table.m_glGetBooleanv = glGetBooleanv; - table.m_glGetClipPlane = glGetClipPlane; - table.m_glGetDoublev = glGetDoublev; - table.m_glGetError = glGetError; - table.m_glGetFloatv = glGetFloatv; - table.m_glGetIntegerv = glGetIntegerv; - table.m_glGetLightfv = glGetLightfv; - table.m_glGetLightiv = glGetLightiv; - table.m_glGetMapdv = glGetMapdv; - table.m_glGetMapfv = glGetMapfv; - table.m_glGetMapiv = glGetMapiv; - table.m_glGetMaterialfv = glGetMaterialfv; - table.m_glGetMaterialiv = glGetMaterialiv; - table.m_glGetPixelMapfv = glGetPixelMapfv; - table.m_glGetPixelMapuiv = glGetPixelMapuiv; - table.m_glGetPixelMapusv = glGetPixelMapusv; - table.m_glGetPointerv = glGetPointerv; - table.m_glGetPolygonStipple = glGetPolygonStipple; - table.m_glGetString = glGetString; - table.m_glGetTexEnvfv = glGetTexEnvfv; - table.m_glGetTexEnviv = glGetTexEnviv; - table.m_glGetTexGendv = glGetTexGendv; - table.m_glGetTexGenfv = glGetTexGenfv; - table.m_glGetTexGeniv = glGetTexGeniv; - table.m_glGetTexImage = glGetTexImage; - table.m_glGetTexLevelParameterfv = glGetTexLevelParameterfv; - table.m_glGetTexLevelParameteriv = glGetTexLevelParameteriv; - table.m_glGetTexParameterfv = glGetTexParameterfv; - table.m_glGetTexParameteriv = glGetTexParameteriv; - table.m_glHint = glHint; - table.m_glIndexMask = glIndexMask; - table.m_glIndexPointer = glIndexPointer; - table.m_glIndexd = glIndexd; - table.m_glIndexdv = glIndexdv; - table.m_glIndexf = glIndexf; - table.m_glIndexfv = glIndexfv; - table.m_glIndexi = glIndexi; - table.m_glIndexiv = glIndexiv; - table.m_glIndexs = glIndexs; - table.m_glIndexsv = glIndexsv; - table.m_glIndexub = glIndexub; - table.m_glIndexubv = glIndexubv; - table.m_glInitNames = glInitNames; - table.m_glInterleavedArrays = glInterleavedArrays; - table.m_glIsEnabled = glIsEnabled; - table.m_glIsList = glIsList; - table.m_glIsTexture = glIsTexture; - table.m_glLightModelf = glLightModelf; - table.m_glLightModelfv = glLightModelfv; - table.m_glLightModeli = glLightModeli; - table.m_glLightModeliv = glLightModeliv; - table.m_glLightf = glLightf; - table.m_glLightfv = glLightfv; - table.m_glLighti = glLighti; - table.m_glLightiv = glLightiv; - table.m_glLineStipple = glLineStipple; - table.m_glLineWidth = glLineWidth; - table.m_glListBase = glListBase; - table.m_glLoadIdentity = glLoadIdentity; - table.m_glLoadMatrixd = glLoadMatrixd; - table.m_glLoadMatrixf = glLoadMatrixf; - table.m_glLoadName = glLoadName; - table.m_glLogicOp = glLogicOp; - table.m_glMap1d = glMap1d; - table.m_glMap1f = glMap1f; - table.m_glMap2d = glMap2d; - table.m_glMap2f = glMap2f; - table.m_glMapGrid1d = glMapGrid1d; - table.m_glMapGrid1f = glMapGrid1f; - table.m_glMapGrid2d = glMapGrid2d; - table.m_glMapGrid2f = glMapGrid2f; - table.m_glMaterialf = glMaterialf; - table.m_glMaterialfv = glMaterialfv; - table.m_glMateriali = glMateriali; - table.m_glMaterialiv = glMaterialiv; - table.m_glMatrixMode = glMatrixMode; - table.m_glMultMatrixd = glMultMatrixd; - table.m_glMultMatrixf = glMultMatrixf; - table.m_glNewList = glNewList; - table.m_glNormal3b = glNormal3b; - table.m_glNormal3bv = glNormal3bv; - table.m_glNormal3d = glNormal3d; - table.m_glNormal3dv = glNormal3dv; - table.m_glNormal3f = glNormal3f; - table.m_glNormal3fv = glNormal3fv; - table.m_glNormal3i = glNormal3i; - table.m_glNormal3iv = glNormal3iv; - table.m_glNormal3s = glNormal3s; - table.m_glNormal3sv = glNormal3sv; - table.m_glNormalPointer = glNormalPointer; - table.m_glOrtho = glOrtho; - table.m_glPassThrough = glPassThrough; - table.m_glPixelMapfv = glPixelMapfv; - table.m_glPixelMapuiv = glPixelMapuiv; - table.m_glPixelMapusv = glPixelMapusv; - table.m_glPixelStoref = glPixelStoref; - table.m_glPixelStorei = glPixelStorei; - table.m_glPixelTransferf = glPixelTransferf; - table.m_glPixelTransferi = glPixelTransferi; - table.m_glPixelZoom = glPixelZoom; - table.m_glPointSize = glPointSize; - table.m_glPolygonMode = glPolygonMode; - table.m_glPolygonOffset = glPolygonOffset; - table.m_glPolygonStipple = glPolygonStipple; - table.m_glPopAttrib = glPopAttrib; - table.m_glPopClientAttrib = glPopClientAttrib; - table.m_glPopMatrix = glPopMatrix; - table.m_glPopName = glPopName; - table.m_glPrioritizeTextures = glPrioritizeTextures; - table.m_glPushAttrib = glPushAttrib; - table.m_glPushClientAttrib = glPushClientAttrib; - table.m_glPushMatrix = glPushMatrix; - table.m_glPushName = glPushName; - table.m_glRasterPos2d = glRasterPos2d; - table.m_glRasterPos2dv = glRasterPos2dv; - table.m_glRasterPos2f = glRasterPos2f; - table.m_glRasterPos2fv = glRasterPos2fv; - table.m_glRasterPos2i = glRasterPos2i; - table.m_glRasterPos2iv = glRasterPos2iv; - table.m_glRasterPos2s = glRasterPos2s; - table.m_glRasterPos2sv = glRasterPos2sv; - table.m_glRasterPos3d = glRasterPos3d; - table.m_glRasterPos3dv = glRasterPos3dv; - table.m_glRasterPos3f = glRasterPos3f; - table.m_glRasterPos3fv = glRasterPos3fv; - table.m_glRasterPos3i = glRasterPos3i; - table.m_glRasterPos3iv = glRasterPos3iv; - table.m_glRasterPos3s = glRasterPos3s; - table.m_glRasterPos3sv = glRasterPos3sv; - table.m_glRasterPos4d = glRasterPos4d; - table.m_glRasterPos4dv = glRasterPos4dv; - table.m_glRasterPos4f = glRasterPos4f; - table.m_glRasterPos4fv = glRasterPos4fv; - table.m_glRasterPos4i = glRasterPos4i; - table.m_glRasterPos4iv = glRasterPos4iv; - table.m_glRasterPos4s = glRasterPos4s; - table.m_glRasterPos4sv = glRasterPos4sv; - table.m_glReadBuffer = glReadBuffer; - table.m_glReadPixels = glReadPixels; - table.m_glRectd = glRectd; - table.m_glRectdv = glRectdv; - table.m_glRectf = glRectf; - table.m_glRectfv = glRectfv; - table.m_glRecti = glRecti; - table.m_glRectiv = glRectiv; - table.m_glRects = glRects; - table.m_glRectsv = glRectsv; - table.m_glRenderMode = glRenderMode; - table.m_glRotated = glRotated; - table.m_glRotatef = glRotatef; - table.m_glScaled = glScaled; - table.m_glScalef = glScalef; - table.m_glScissor = glScissor; - table.m_glSelectBuffer = glSelectBuffer; - table.m_glShadeModel = glShadeModel; - table.m_glStencilFunc = glStencilFunc; - table.m_glStencilMask = glStencilMask; - table.m_glStencilOp = glStencilOp; - table.m_glTexCoord1d = glTexCoord1d; - table.m_glTexCoord1dv = glTexCoord1dv; - table.m_glTexCoord1f = glTexCoord1f; - table.m_glTexCoord1fv = glTexCoord1fv; - table.m_glTexCoord1i = glTexCoord1i; - table.m_glTexCoord1iv = glTexCoord1iv; - table.m_glTexCoord1s = glTexCoord1s; - table.m_glTexCoord1sv = glTexCoord1sv; - table.m_glTexCoord2d = glTexCoord2d; - table.m_glTexCoord2dv = glTexCoord2dv; - table.m_glTexCoord2f = glTexCoord2f; - table.m_glTexCoord2fv = glTexCoord2fv; - table.m_glTexCoord2i = glTexCoord2i; - table.m_glTexCoord2iv = glTexCoord2iv; - table.m_glTexCoord2s = glTexCoord2s; - table.m_glTexCoord2sv = glTexCoord2sv; - table.m_glTexCoord3d = glTexCoord3d; - table.m_glTexCoord3dv = glTexCoord3dv; - table.m_glTexCoord3f = glTexCoord3f; - table.m_glTexCoord3fv = glTexCoord3fv; - table.m_glTexCoord3i = glTexCoord3i; - table.m_glTexCoord3iv = glTexCoord3iv; - table.m_glTexCoord3s = glTexCoord3s; - table.m_glTexCoord3sv = glTexCoord3sv; - table.m_glTexCoord4d = glTexCoord4d; - table.m_glTexCoord4dv = glTexCoord4dv; - table.m_glTexCoord4f = glTexCoord4f; - table.m_glTexCoord4fv = glTexCoord4fv; - table.m_glTexCoord4i = glTexCoord4i; - table.m_glTexCoord4iv = glTexCoord4iv; - table.m_glTexCoord4s = glTexCoord4s; - table.m_glTexCoord4sv = glTexCoord4sv; - table.m_glTexCoordPointer = glTexCoordPointer; - table.m_glTexEnvf = glTexEnvf; - table.m_glTexEnvfv = glTexEnvfv; - table.m_glTexEnvi = glTexEnvi; - table.m_glTexEnviv = glTexEnviv; - table.m_glTexGend = glTexGend; - table.m_glTexGendv = glTexGendv; - table.m_glTexGenf = glTexGenf; - table.m_glTexGenfv = glTexGenfv; - table.m_glTexGeni = glTexGeni; - table.m_glTexGeniv = glTexGeniv; - table.m_glTexImage1D = glTexImage1D; - table.m_glTexImage2D = glTexImage2D; - table.m_glTexParameterf = glTexParameterf; - table.m_glTexParameterfv = glTexParameterfv; - table.m_glTexParameteri = glTexParameteri; - table.m_glTexParameteriv = glTexParameteriv; - table.m_glTexSubImage1D = glTexSubImage1D; - table.m_glTexSubImage2D = glTexSubImage2D; - table.m_glTranslated = glTranslated; - table.m_glTranslatef = glTranslatef; - table.m_glVertex2d = glVertex2d; - table.m_glVertex2dv = glVertex2dv; - table.m_glVertex2f = glVertex2f; - table.m_glVertex2fv = glVertex2fv; - table.m_glVertex2i = glVertex2i; - table.m_glVertex2iv = glVertex2iv; - table.m_glVertex2s = glVertex2s; - table.m_glVertex2sv = glVertex2sv; - table.m_glVertex3d = glVertex3d; - table.m_glVertex3dv = glVertex3dv; - table.m_glVertex3f = glVertex3f; - table.m_glVertex3fv = glVertex3fv; - table.m_glVertex3i = glVertex3i; - table.m_glVertex3iv = glVertex3iv; - table.m_glVertex3s = glVertex3s; - table.m_glVertex3sv = glVertex3sv; - table.m_glVertex4d = glVertex4d; - table.m_glVertex4dv = glVertex4dv; - table.m_glVertex4f = glVertex4f; - table.m_glVertex4fv = glVertex4fv; - table.m_glVertex4i = glVertex4i; - table.m_glVertex4iv = glVertex4iv; - table.m_glVertex4s = glVertex4s; - table.m_glVertex4sv = glVertex4sv; - table.m_glVertexPointer = glVertexPointer; - table.m_glViewport = glViewport; - - if (QGL_ExtensionSupported("GL_ARB_multitexture")) { - table.support_ARB_multitexture = - QGL_constructExtensionFunc(table.m_glActiveTextureARB, "glActiveTextureARB") - && QGL_constructExtensionFunc(table.m_glClientActiveTextureARB, "glClientActiveTextureARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1dARB, "glMultiTexCoord1dARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1dvARB, "glMultiTexCoord1dvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1fARB, "glMultiTexCoord1fARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1fvARB, "glMultiTexCoord1fvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1iARB, "glMultiTexCoord1iARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1ivARB, "glMultiTexCoord1ivARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1sARB, "glMultiTexCoord1sARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1svARB, "glMultiTexCoord1svARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2dARB, "glMultiTexCoord2dARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2dvARB, "glMultiTexCoord2dvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2fARB, "glMultiTexCoord2fARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2fvARB, "glMultiTexCoord2fvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2iARB, "glMultiTexCoord2iARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2ivARB, "glMultiTexCoord2ivARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2sARB, "glMultiTexCoord2sARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2svARB, "glMultiTexCoord2svARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3dARB, "glMultiTexCoord3dARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3dvARB, "glMultiTexCoord3dvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3fARB, "glMultiTexCoord3fARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3fvARB, "glMultiTexCoord3fvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3iARB, "glMultiTexCoord3iARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3ivARB, "glMultiTexCoord3ivARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3sARB, "glMultiTexCoord3sARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3svARB, "glMultiTexCoord3svARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4dARB, "glMultiTexCoord4dARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4dvARB, "glMultiTexCoord4dvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4fARB, "glMultiTexCoord4fARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4fvARB, "glMultiTexCoord4fvARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4iARB, "glMultiTexCoord4iARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4ivARB, "glMultiTexCoord4ivARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4sARB, "glMultiTexCoord4sARB") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4svARB, "glMultiTexCoord4svARB"); - - if (!table.support_ARB_multitexture) { - extension_not_implemented("GL_ARB_multitexture"); - } - } else { - table.support_ARB_multitexture = false; - } - - if (QGL_ExtensionSupported("GL_ARB_texture_compression")) { - table.support_ARB_texture_compression = - QGL_constructExtensionFunc(table.m_glCompressedTexImage3DARB, "glCompressedTexImage3DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage2DARB, "glCompressedTexImage2DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage1DARB, "glCompressedTexImage1DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage3DARB, "glCompressedTexSubImage3DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage2DARB, "glCompressedTexSubImage2DARB") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage1DARB, "glCompressedTexSubImage1DARB") - && QGL_constructExtensionFunc(table.m_glGetCompressedTexImageARB, "glGetCompressedTexImageARB"); - - if (!table.support_ARB_texture_compression) { - extension_not_implemented("GL_ARB_texture_compression"); - } - } else { - table.support_ARB_texture_compression = false; - } - - table.support_EXT_texture_compression_s3tc = QGL_ExtensionSupported("GL_EXT_texture_compression_s3tc"); - - // GL 1.2 - if (table.major_version > 1 || table.minor_version >= 2) { - table.support_GL_1_2 = - QGL_constructExtensionFunc(table.m_glCopyTexSubImage3D, "glCopyTexSubImage3D") - && QGL_constructExtensionFunc(table.m_glDrawRangeElements, "glDrawRangeElements") - && QGL_constructExtensionFunc(table.m_glTexImage3D, "glTexImage3D") - && QGL_constructExtensionFunc(table.m_glTexSubImage3D, "glTexSubImage3D"); - - if (!table.support_GL_1_2) { - extension_not_implemented("GL_VERSION_1_2"); - } - } else { - table.support_GL_1_2 = false; - } - - // GL 1.3 - if (table.major_version > 1 || table.minor_version >= 3) { - table.support_GL_1_3 = - QGL_constructExtensionFunc(table.m_glActiveTexture, "glActiveTexture") - && QGL_constructExtensionFunc(table.m_glClientActiveTexture, "glClientActiveTexture") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage1D, "glCompressedTexImage1D") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage2D, "glCompressedTexImage2D") - && QGL_constructExtensionFunc(table.m_glCompressedTexImage3D, "glCompressedTexImage3D") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage1D, "glCompressedTexSubImage1D") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage2D, "glCompressedTexSubImage2D") - && QGL_constructExtensionFunc(table.m_glCompressedTexSubImage3D, "glCompressedTexSubImage3D") - && QGL_constructExtensionFunc(table.m_glGetCompressedTexImage, "glGetCompressedTexImage") - && QGL_constructExtensionFunc(table.m_glLoadTransposeMatrixd, "glLoadTransposeMatrixd") - && QGL_constructExtensionFunc(table.m_glLoadTransposeMatrixf, "glLoadTransposeMatrixf") - && QGL_constructExtensionFunc(table.m_glMultTransposeMatrixd, "glMultTransposeMatrixd") - && QGL_constructExtensionFunc(table.m_glMultTransposeMatrixf, "glMultTransposeMatrixf") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1d, "glMultiTexCoord1d") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1dv, "glMultiTexCoord1dv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1f, "glMultiTexCoord1f") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1fv, "glMultiTexCoord1fv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1i, "glMultiTexCoord1i") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1iv, "glMultiTexCoord1iv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1s, "glMultiTexCoord1s") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord1sv, "glMultiTexCoord1sv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2d, "glMultiTexCoord2d") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2dv, "glMultiTexCoord2dv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2f, "glMultiTexCoord2f") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2fv, "glMultiTexCoord2fv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2i, "glMultiTexCoord2i") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2iv, "glMultiTexCoord2iv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2s, "glMultiTexCoord2s") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord2sv, "glMultiTexCoord2sv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3d, "glMultiTexCoord3d") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3dv, "glMultiTexCoord3dv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3f, "glMultiTexCoord3f") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3fv, "glMultiTexCoord3fv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3i, "glMultiTexCoord3i") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3iv, "glMultiTexCoord3iv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3s, "glMultiTexCoord3s") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord3sv, "glMultiTexCoord3sv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4d, "glMultiTexCoord4d") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4dv, "glMultiTexCoord4dv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4f, "glMultiTexCoord4f") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4fv, "glMultiTexCoord4fv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4i, "glMultiTexCoord4i") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4iv, "glMultiTexCoord4iv") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4s, "glMultiTexCoord4s") - && QGL_constructExtensionFunc(table.m_glMultiTexCoord4sv, "glMultiTexCoord4sv") - && QGL_constructExtensionFunc(table.m_glSampleCoverage, "glSampleCoverage"); - - if (!table.support_GL_1_3) { - extension_not_implemented("GL_VERSION_1_3"); - } - } else { - table.support_GL_1_3 = false; - } - - // GL 1.4 - if (table.major_version > 1 || table.minor_version >= 4) { - table.support_GL_1_4 = - QGL_constructExtensionFunc(table.m_glBlendColor, "glBlendColor") - && QGL_constructExtensionFunc(table.m_glBlendEquation, "glBlendEquation") - && QGL_constructExtensionFunc(table.m_glBlendFuncSeparate, "glBlendFuncSeparate") - && QGL_constructExtensionFunc(table.m_glFogCoordPointer, "glFogCoordPointer") - && QGL_constructExtensionFunc(table.m_glFogCoordd, "glFogCoordd") - && QGL_constructExtensionFunc(table.m_glFogCoorddv, "glFogCoorddv") - && QGL_constructExtensionFunc(table.m_glFogCoordf, "glFogCoordf") - && QGL_constructExtensionFunc(table.m_glFogCoordfv, "glFogCoordfv") - && QGL_constructExtensionFunc(table.m_glMultiDrawArrays, "glMultiDrawArrays") - && QGL_constructExtensionFunc(table.m_glMultiDrawElements, "glMultiDrawElements") - && QGL_constructExtensionFunc(table.m_glPointParameterf, "glPointParameterf") - && QGL_constructExtensionFunc(table.m_glPointParameterfv, "glPointParameterfv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3b, "glSecondaryColor3b") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3bv, "glSecondaryColor3bv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3d, "glSecondaryColor3d") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3dv, "glSecondaryColor3dv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3f, "glSecondaryColor3f") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3fv, "glSecondaryColor3fv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3i, "glSecondaryColor3i") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3iv, "glSecondaryColor3iv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3s, "glSecondaryColor3s") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3sv, "glSecondaryColor3sv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3ub, "glSecondaryColor3ub") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3ubv, "glSecondaryColor3ubv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3ui, "glSecondaryColor3ui") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3uiv, "glSecondaryColor3uiv") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3us, "glSecondaryColor3us") - && QGL_constructExtensionFunc(table.m_glSecondaryColor3usv, "glSecondaryColor3usv") - && QGL_constructExtensionFunc(table.m_glSecondaryColorPointer, "glSecondaryColorPointer") - && QGL_constructExtensionFunc(table.m_glWindowPos2d, "glWindowPos2d") - && QGL_constructExtensionFunc(table.m_glWindowPos2dv, "glWindowPos2dv") - && QGL_constructExtensionFunc(table.m_glWindowPos2f, "glWindowPos2f") - && QGL_constructExtensionFunc(table.m_glWindowPos2fv, "glWindowPos2fv") - && QGL_constructExtensionFunc(table.m_glWindowPos2i, "glWindowPos2i") - && QGL_constructExtensionFunc(table.m_glWindowPos2iv, "glWindowPos2iv") - && QGL_constructExtensionFunc(table.m_glWindowPos2s, "glWindowPos2s") - && QGL_constructExtensionFunc(table.m_glWindowPos2sv, "glWindowPos2sv") - && QGL_constructExtensionFunc(table.m_glWindowPos3d, "glWindowPos3d") - && QGL_constructExtensionFunc(table.m_glWindowPos3dv, "glWindowPos3dv") - && QGL_constructExtensionFunc(table.m_glWindowPos3f, "glWindowPos3f") - && QGL_constructExtensionFunc(table.m_glWindowPos3fv, "glWindowPos3fv") - && QGL_constructExtensionFunc(table.m_glWindowPos3i, "glWindowPos3i") - && QGL_constructExtensionFunc(table.m_glWindowPos3iv, "glWindowPos3iv") - && QGL_constructExtensionFunc(table.m_glWindowPos3s, "glWindowPos3s") - && QGL_constructExtensionFunc(table.m_glWindowPos3sv, "glWindowPos3sv"); - - if (!table.support_GL_1_4) { - extension_not_implemented("GL_VERSION_1_4"); - } - } else { - table.support_GL_1_4 = false; - } - - // GL 1.5 - if (table.major_version > 1 || table.minor_version >= 5) { - table.support_GL_1_5 = - QGL_constructExtensionFunc(table.m_glBeginQuery, "glBeginQuery") - && QGL_constructExtensionFunc(table.m_glBindBuffer, "glBindBuffer") - && QGL_constructExtensionFunc(table.m_glBufferData, "glBufferData") - && QGL_constructExtensionFunc(table.m_glBufferSubData, "glBufferSubData") - && QGL_constructExtensionFunc(table.m_glDeleteBuffers, "glDeleteBuffers") - && QGL_constructExtensionFunc(table.m_glDeleteQueries, "glDeleteQueries") - && QGL_constructExtensionFunc(table.m_glEndQuery, "glEndQuery") - && QGL_constructExtensionFunc(table.m_glGenBuffers, "glGenBuffers") - && QGL_constructExtensionFunc(table.m_glGenQueries, "glGenQueries") - && QGL_constructExtensionFunc(table.m_glGetBufferParameteriv, "glGetBufferParameteriv") - && QGL_constructExtensionFunc(table.m_glGetBufferPointerv, "glGetBufferPointerv") - && QGL_constructExtensionFunc(table.m_glGetBufferSubData, "glGetBufferSubData") - && QGL_constructExtensionFunc(table.m_glGetQueryObjectiv, "glGetQueryObjectiv") - && QGL_constructExtensionFunc(table.m_glGetQueryObjectuiv, "glGetQueryObjectuiv") - && QGL_constructExtensionFunc(table.m_glGetQueryiv, "glGetQueryiv") - && QGL_constructExtensionFunc(table.m_glIsBuffer, "glIsBuffer") - && QGL_constructExtensionFunc(table.m_glIsQuery, "glIsQuery") - && QGL_constructExtensionFunc(table.m_glMapBuffer, "glMapBuffer") - && QGL_constructExtensionFunc(table.m_glUnmapBuffer, "glUnmapBuffer"); - - if (!table.support_GL_1_5) { - extension_not_implemented("GL_VERSION_1_5"); - } - } else { - table.support_GL_1_5 = false; - } - - - if (QGL_ExtensionSupported("GL_ARB_vertex_program")) { - table.support_ARB_vertex_program = - QGL_constructExtensionFunc(table.m_glVertexAttrib1sARB, "glVertexAttrib1sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fARB, "glVertexAttrib1fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1dARB, "glVertexAttrib1dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2sARB, "glVertexAttrib2sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fARB, "glVertexAttrib2fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2dARB, "glVertexAttrib2dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3sARB, "glVertexAttrib3sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fARB, "glVertexAttrib3fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3dARB, "glVertexAttrib3dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4sARB, "glVertexAttrib4sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fARB, "glVertexAttrib4fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4dARB, "glVertexAttrib4dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NubARB, "glVertexAttrib4NubARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1svARB, "glVertexAttrib1svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fvARB, "glVertexAttrib1fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1dvARB, "glVertexAttrib1dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2svARB, "glVertexAttrib2svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fvARB, "glVertexAttrib2fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2dvARB, "glVertexAttrib2dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3svARB, "glVertexAttrib3svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fvARB, "glVertexAttrib3fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3dvARB, "glVertexAttrib3dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4bvARB, "glVertexAttrib4bvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4svARB, "glVertexAttrib4svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4ivARB, "glVertexAttrib4ivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4ubvARB, "glVertexAttrib4ubvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4usvARB, "glVertexAttrib4usvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4uivARB, "glVertexAttrib4uivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fvARB, "glVertexAttrib4fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4dvARB, "glVertexAttrib4dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NbvARB, "glVertexAttrib4NbvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NsvARB, "glVertexAttrib4NsvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NivARB, "glVertexAttrib4NivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NubvARB, "glVertexAttrib4NubvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NusvARB, "glVertexAttrib4NusvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NuivARB, "glVertexAttrib4NuivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttribPointerARB, "glVertexAttribPointerARB") - && QGL_constructExtensionFunc(table.m_glEnableVertexAttribArrayARB, "glEnableVertexAttribArrayARB") - && QGL_constructExtensionFunc(table.m_glDisableVertexAttribArrayARB, "glDisableVertexAttribArrayARB") - && QGL_constructExtensionFunc(table.m_glProgramStringARB, "glProgramStringARB") - && QGL_constructExtensionFunc(table.m_glBindProgramARB, "glBindProgramARB") - && QGL_constructExtensionFunc(table.m_glDeleteProgramsARB, "glDeleteProgramsARB") - && QGL_constructExtensionFunc(table.m_glGenProgramsARB, "glGenProgramsARB") - && QGL_constructExtensionFunc(table.m_glProgramEnvParameter4dARB, "glProgramEnvParameter4dARB") - && QGL_constructExtensionFunc(table.m_glProgramEnvParameter4dvARB, "glProgramEnvParameter4dvARB") - && QGL_constructExtensionFunc(table.m_glProgramEnvParameter4fARB, "glProgramEnvParameter4fARB") - && QGL_constructExtensionFunc(table.m_glProgramEnvParameter4fvARB, "glProgramEnvParameter4fvARB") - && QGL_constructExtensionFunc(table.m_glProgramLocalParameter4dARB, "glProgramLocalParameter4dARB") - && QGL_constructExtensionFunc(table.m_glProgramLocalParameter4dvARB, "glProgramLocalParameter4dvARB") - && QGL_constructExtensionFunc(table.m_glProgramLocalParameter4fARB, "glProgramLocalParameter4fARB") - && QGL_constructExtensionFunc(table.m_glProgramLocalParameter4fvARB, "glProgramLocalParameter4fvARB") - && QGL_constructExtensionFunc(table.m_glGetProgramEnvParameterdvARB, "glGetProgramEnvParameterdvARB") - && QGL_constructExtensionFunc(table.m_glGetProgramEnvParameterfvARB, "glGetProgramEnvParameterfvARB") - && - QGL_constructExtensionFunc(table.m_glGetProgramLocalParameterdvARB, "glGetProgramLocalParameterdvARB") - && - QGL_constructExtensionFunc(table.m_glGetProgramLocalParameterfvARB, "glGetProgramLocalParameterfvARB") - && QGL_constructExtensionFunc(table.m_glGetProgramivARB, "glGetProgramivARB") - && QGL_constructExtensionFunc(table.m_glGetProgramStringARB, "glGetProgramStringARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribdvARB, "glGetVertexAttribdvARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribfvARB, "glGetVertexAttribfvARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribivARB, "glGetVertexAttribivARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribPointervARB, "glGetVertexAttribPointervARB") - && QGL_constructExtensionFunc(table.m_glIsProgramARB, "glIsProgramARB"); - - if (!table.support_ARB_vertex_program) { - extension_not_implemented("GL_ARB_vertex_program"); - } - } else { - table.support_ARB_vertex_program = false; - } - - - table.support_ARB_fragment_program = QGL_ExtensionSupported("GL_ARB_fragment_program"); - - if (QGL_ExtensionSupported("GL_ARB_shader_objects")) { - table.support_ARB_shader_objects = - QGL_constructExtensionFunc(table.m_glDeleteObjectARB, "glDeleteObjectARB") - && QGL_constructExtensionFunc(table.m_glGetHandleARB, "glGetHandleARB") - && QGL_constructExtensionFunc(table.m_glDetachObjectARB, "glDetachObjectARB") - && QGL_constructExtensionFunc(table.m_glCreateShaderObjectARB, "glCreateShaderObjectARB") - && QGL_constructExtensionFunc(table.m_glShaderSourceARB, "glShaderSourceARB") - && QGL_constructExtensionFunc(table.m_glCompileShaderARB, "glCompileShaderARB") - && QGL_constructExtensionFunc(table.m_glCreateProgramObjectARB, "glCreateProgramObjectARB") - && QGL_constructExtensionFunc(table.m_glAttachObjectARB, "glAttachObjectARB") - && QGL_constructExtensionFunc(table.m_glLinkProgramARB, "glLinkProgramARB") - && QGL_constructExtensionFunc(table.m_glUseProgramObjectARB, "glUseProgramObjectARB") - && QGL_constructExtensionFunc(table.m_glValidateProgramARB, "glValidateProgramARB") - && QGL_constructExtensionFunc(table.m_glUniform1fARB, "glUniform1fARB") - && QGL_constructExtensionFunc(table.m_glUniform2fARB, "glUniform2fARB") - && QGL_constructExtensionFunc(table.m_glUniform3fARB, "glUniform3fARB") - && QGL_constructExtensionFunc(table.m_glUniform4fARB, "glUniform4fARB") - && QGL_constructExtensionFunc(table.m_glUniform1iARB, "glUniform1iARB") - && QGL_constructExtensionFunc(table.m_glUniform2iARB, "glUniform2iARB") - && QGL_constructExtensionFunc(table.m_glUniform3iARB, "glUniform3iARB") - && QGL_constructExtensionFunc(table.m_glUniform4iARB, "glUniform4iARB") - && QGL_constructExtensionFunc(table.m_glUniform1fvARB, "glUniform1fvARB") - && QGL_constructExtensionFunc(table.m_glUniform2fvARB, "glUniform2fvARB") - && QGL_constructExtensionFunc(table.m_glUniform3fvARB, "glUniform3fvARB") - && QGL_constructExtensionFunc(table.m_glUniform4fvARB, "glUniform4fvARB") - && QGL_constructExtensionFunc(table.m_glUniform1ivARB, "glUniform1ivARB") - && QGL_constructExtensionFunc(table.m_glUniform2ivARB, "glUniform2ivARB") - && QGL_constructExtensionFunc(table.m_glUniform3ivARB, "glUniform3ivARB") - && QGL_constructExtensionFunc(table.m_glUniform4ivARB, "glUniform4ivARB") - && QGL_constructExtensionFunc(table.m_glUniformMatrix2fvARB, "glUniformMatrix2fvARB") - && QGL_constructExtensionFunc(table.m_glUniformMatrix3fvARB, "glUniformMatrix3fvARB") - && QGL_constructExtensionFunc(table.m_glUniformMatrix4fvARB, "glUniformMatrix4fvARB") - && QGL_constructExtensionFunc(table.m_glGetObjectParameterfvARB, "glGetObjectParameterfvARB") - && QGL_constructExtensionFunc(table.m_glGetObjectParameterivARB, "glGetObjectParameterivARB") - && QGL_constructExtensionFunc(table.m_glGetInfoLogARB, "glGetInfoLogARB") - && QGL_constructExtensionFunc(table.m_glGetAttachedObjectsARB, "glGetAttachedObjectsARB") - && QGL_constructExtensionFunc(table.m_glGetUniformLocationARB, "glGetUniformLocationARB") - && QGL_constructExtensionFunc(table.m_glGetActiveUniformARB, "glGetActiveUniformARB") - && QGL_constructExtensionFunc(table.m_glGetUniformfvARB, "glGetUniformfvARB") - && QGL_constructExtensionFunc(table.m_glGetUniformivARB, "glGetUniformivARB") - && QGL_constructExtensionFunc(table.m_glGetShaderSourceARB, "glGetShaderSourceARB"); - - if (!table.support_ARB_shader_objects) { - extension_not_implemented("GL_ARB_shader_objects"); - } - } else { - table.support_ARB_shader_objects = false; - } - - if (QGL_ExtensionSupported("GL_ARB_vertex_shader")) { - table.support_ARB_vertex_shader = - QGL_constructExtensionFunc(table.m_glVertexAttrib1fARB, "glVertexAttrib1fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1sARB, "glVertexAttrib1sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1dARB, "glVertexAttrib1dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fARB, "glVertexAttrib2fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2sARB, "glVertexAttrib2sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2dARB, "glVertexAttrib2dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fARB, "glVertexAttrib3fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3sARB, "glVertexAttrib3sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3dARB, "glVertexAttrib3dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fARB, "glVertexAttrib4fARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4sARB, "glVertexAttrib4sARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4dARB, "glVertexAttrib4dARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NubARB, "glVertexAttrib4NubARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fvARB, "glVertexAttrib1fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1svARB, "glVertexAttrib1svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1dvARB, "glVertexAttrib1dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fvARB, "glVertexAttrib2fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2svARB, "glVertexAttrib2svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2dvARB, "glVertexAttrib2dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fvARB, "glVertexAttrib3fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3svARB, "glVertexAttrib3svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3dvARB, "glVertexAttrib3dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fvARB, "glVertexAttrib4fvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4svARB, "glVertexAttrib4svARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4dvARB, "glVertexAttrib4dvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4ivARB, "glVertexAttrib4ivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4bvARB, "glVertexAttrib4bvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4ubvARB, "glVertexAttrib4ubvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4usvARB, "glVertexAttrib4usvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4uivARB, "glVertexAttrib4uivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NbvARB, "glVertexAttrib4NbvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NsvARB, "glVertexAttrib4NsvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NivARB, "glVertexAttrib4NivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NubvARB, "glVertexAttrib4NubvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NusvARB, "glVertexAttrib4NusvARB") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4NuivARB, "glVertexAttrib4NuivARB") - && QGL_constructExtensionFunc(table.m_glVertexAttribPointerARB, "glVertexAttribPointerARB") - && QGL_constructExtensionFunc(table.m_glEnableVertexAttribArrayARB, "glEnableVertexAttribArrayARB") - && QGL_constructExtensionFunc(table.m_glDisableVertexAttribArrayARB, "glDisableVertexAttribArrayARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribdvARB, "glGetVertexAttribdvARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribfvARB, "glGetVertexAttribfvARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribivARB, "glGetVertexAttribivARB") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribPointervARB, "glGetVertexAttribPointervARB") - && QGL_constructExtensionFunc(table.m_glBindAttribLocationARB, "glBindAttribLocationARB") - && QGL_constructExtensionFunc(table.m_glGetActiveAttribARB, "glGetActiveAttribARB") - && QGL_constructExtensionFunc(table.m_glGetAttribLocationARB, "glGetAttribLocationARB"); - - if (!table.support_ARB_vertex_shader) { - extension_not_implemented("GL_ARB_vertex_shader"); - } - } else { - table.support_ARB_vertex_shader = false; - } - - if (QGL_ExtensionSupported("GL_NV_vertex_program2")) { - table.support_NV_vertex_program2 = - QGL_constructExtensionFunc(table.m_glAreProgramsResidentNV, "glAreProgramsResidentNV") - && QGL_constructExtensionFunc(table.m_glBindProgramNV, "glBindProgramNV") - && QGL_constructExtensionFunc(table.m_glDeleteProgramsNV, "glDeleteProgramsNV") - && QGL_constructExtensionFunc(table.m_glExecuteProgramNV, "glExecuteProgramNV") - && QGL_constructExtensionFunc(table.m_glGenProgramsNV, "glGenProgramsNV") - && QGL_constructExtensionFunc(table.m_glGetProgramParameterdvNV, "glGetProgramParameterdvNV") - && QGL_constructExtensionFunc(table.m_glGetProgramParameterfvNV, "glGetProgramParameterfvNV") - && QGL_constructExtensionFunc(table.m_glGetProgramivNV, "glGetProgramivNV") - && QGL_constructExtensionFunc(table.m_glGetProgramStringNV, "glGetProgramStringNV") - && QGL_constructExtensionFunc(table.m_glGetTrackMatrixivNV, "glGetTrackMatrixivNV") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribdvNV, "glGetVertexAttribdvNV") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribfvNV, "glGetVertexAttribfvNV") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribivNV, "glGetVertexAttribivNV") - && QGL_constructExtensionFunc(table.m_glGetVertexAttribPointervNV, "glGetVertexAttribPointervNV") - && QGL_constructExtensionFunc(table.m_glIsProgramNV, "glIsProgramNV") - && QGL_constructExtensionFunc(table.m_glLoadProgramNV, "glLoadProgramNV") - && QGL_constructExtensionFunc(table.m_glProgramParameter4fNV, "glProgramParameter4fNV") - && QGL_constructExtensionFunc(table.m_glProgramParameter4fvNV, "glProgramParameter4fvNV") - && QGL_constructExtensionFunc(table.m_glProgramParameters4fvNV, "glProgramParameters4fvNV") - && QGL_constructExtensionFunc(table.m_glRequestResidentProgramsNV, "glRequestResidentProgramsNV") - && QGL_constructExtensionFunc(table.m_glTrackMatrixNV, "glTrackMatrixNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribPointerNV, "glVertexAttribPointerNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fNV, "glVertexAttrib1fNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib1fvNV, "glVertexAttrib1fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fNV, "glVertexAttrib2fNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib2fvNV, "glVertexAttrib2fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fNV, "glVertexAttrib3fNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib3fvNV, "glVertexAttrib3fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fNV, "glVertexAttrib4fNV") - && QGL_constructExtensionFunc(table.m_glVertexAttrib4fvNV, "glVertexAttrib4fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribs1fvNV, "glVertexAttribs1fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribs2fvNV, "glVertexAttribs2fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribs3fvNV, "glVertexAttribs3fvNV") - && QGL_constructExtensionFunc(table.m_glVertexAttribs4fvNV, "glVertexAttribs4fvNV"); - - if (!table.support_NV_vertex_program2) { - extension_not_implemented("GL_NV_vertex_program2"); - } - } else { - table.support_NV_vertex_program2 = false; - QGL_invalidateExtensionFunc(table.m_glAreProgramsResidentNV); - QGL_invalidateExtensionFunc(table.m_glBindProgramNV); - QGL_invalidateExtensionFunc(table.m_glDeleteProgramsNV); - QGL_invalidateExtensionFunc(table.m_glExecuteProgramNV); - QGL_invalidateExtensionFunc(table.m_glGenProgramsNV); - QGL_invalidateExtensionFunc(table.m_glGetProgramParameterdvNV); - QGL_invalidateExtensionFunc(table.m_glGetProgramParameterfvNV); - QGL_invalidateExtensionFunc(table.m_glGetProgramivNV); - QGL_invalidateExtensionFunc(table.m_glGetProgramStringNV); - QGL_invalidateExtensionFunc(table.m_glGetTrackMatrixivNV); - QGL_invalidateExtensionFunc(table.m_glGetVertexAttribdvNV); - QGL_invalidateExtensionFunc(table.m_glGetVertexAttribfvNV); - QGL_invalidateExtensionFunc(table.m_glGetVertexAttribivNV); - QGL_invalidateExtensionFunc(table.m_glGetVertexAttribPointervNV); - QGL_invalidateExtensionFunc(table.m_glIsProgramNV); - QGL_invalidateExtensionFunc(table.m_glLoadProgramNV); - QGL_invalidateExtensionFunc(table.m_glProgramParameter4fNV); - QGL_invalidateExtensionFunc(table.m_glProgramParameter4fvNV); - QGL_invalidateExtensionFunc(table.m_glProgramParameters4fvNV); - QGL_invalidateExtensionFunc(table.m_glRequestResidentProgramsNV); - QGL_invalidateExtensionFunc(table.m_glTrackMatrixNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribPointerNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib1fNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib1fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib2fNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib2fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib3fNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib3fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib4fNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttrib4fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribs1fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribs2fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribs3fvNV); - QGL_invalidateExtensionFunc(table.m_glVertexAttribs4fvNV); - } - - if (QGL_ExtensionSupported("GL_NV_fragment_program")) { - table.support_NV_fragment_program = - QGL_constructExtensionFunc(table.m_glProgramNamedParameter4fNV, "glProgramNamedParameter4fNV") - && QGL_constructExtensionFunc(table.m_glProgramNamedParameter4fvNV, "glProgramNamedParameter4fvNV") - && QGL_constructExtensionFunc(table.m_glGetProgramNamedParameterfvNV, "glGetProgramNamedParameterfvNV"); - - if (!table.support_NV_fragment_program) { - extension_not_implemented("GL_NV_fragment_program"); - } - } else { - table.support_NV_fragment_program = false; - } - - table.support_ARB_fragment_shader = QGL_ExtensionSupported("GL_ARB_fragment_shader"); - table.support_ARB_shading_language_100 = QGL_ExtensionSupported("GL_ARB_shading_language_100"); - - if (QGL_ExtensionSupported("GL_EXT_texture_filter_anisotropic")) { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &g_maxTextureAnisotropy); - globalOutputStream() << "Anisotropic filtering possible (max " << g_maxTextureAnisotropy << "x)\n"; - } else { - globalOutputStream() << "No Anisotropic filtering available\n"; - g_maxTextureAnisotropy = 0; - } -} - -void QGL_sharedContextDestroyed(OpenGLBinding &table) -{ - QGL_clear(table); -} - - -void QGL_assertNoErrors(const char *file, int line) -{ - GLenum error = GlobalOpenGL().m_glGetError(); - while (error != GL_NO_ERROR) { - const char *errorString = reinterpret_cast( qgluErrorString(error)); - if (error == GL_OUT_OF_MEMORY) { - ERROR_MESSAGE("OpenGL out of memory error at " << file << ":" << line << ": " << errorString); - } else { - ERROR_MESSAGE("OpenGL error at " << file << ":" << line << ": " << errorString); - } - error = GlobalOpenGL().m_glGetError(); - } -} - - -class QglAPI { -OpenGLBinding m_qgl; -public: -typedef OpenGLBinding Type; - -STRING_CONSTANT(Name, "*"); - -QglAPI() -{ - QGL_Init(m_qgl); - - m_qgl.assertNoErrors = &QGL_assertNoErrors; -} - -~QglAPI() -{ - QGL_Shutdown(m_qgl); -} - -OpenGLBinding *getTable() -{ - return &m_qgl; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule QglModule; -typedef Static StaticQglModule; -StaticRegisterModule staticRegisterQgl(StaticQglModule::instance()); diff --git a/src/qgl.h b/src/qgl.h deleted file mode 100644 index 9d80852..0000000 --- a/src/qgl.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_QGL_H ) -#define INCLUDED_QGL_H - -struct OpenGLBinding; - -void QGL_sharedContextCreated(OpenGLBinding &table); - -void QGL_sharedContextDestroyed(OpenGLBinding &table); - -bool QGL_ExtensionSupported(const char *extension); - -float QGL_maxTextureAnisotropy(); - -#endif diff --git a/src/referencecache.cpp b/src/referencecache.cpp deleted file mode 100644 index d053e70..0000000 --- a/src/referencecache.cpp +++ /dev/null @@ -1,803 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "referencecache.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include "iscenegraph.h" -#include "iselection.h" -#include "iundo.h" -#include "imap.h" - -MapModules &ReferenceAPI_getMapModules(); - -#include "imodel.h" - -ModelModules &ReferenceAPI_getModelModules(); - -#include "ifilesystem.h" -#include "iarchive.h" -#include "ifiletypes.h" -#include "ireference.h" -#include "ientity.h" -#include "qerplugin.h" - -#include - -#include "container/cache.h" -#include "container/hashfunc.h" -#include "os/path.h" -#include "stream/textfilestream.h" -#include "nullmodel.h" -#include "maplib.h" -#include "stream/stringstream.h" -#include "os/file.h" -#include "moduleobserver.h" -#include "moduleobservers.h" - -#include "mainframe.h" -#include "map.h" -#include "filetypes.h" - - -bool References_Saved(); - -void MapChanged() -{ - Map_SetModified(g_map, !References_Saved()); -} - - -EntityCreator *g_entityCreator = 0; - -bool MapResource_loadFile(const MapFormat &format, scene::Node &root, const char *filename) -{ - globalOutputStream() << "Open file " << filename << " for read..."; - TextFileInputStream file(filename); - if (!file.failed()) { - globalOutputStream() << "success\n"; - ScopeDisableScreenUpdates disableScreenUpdates(path_get_filename_start(filename), "Loading Map"); - ASSERT_NOTNULL(g_entityCreator); - format.readGraph(root, file, *g_entityCreator); - return true; - } else { - globalErrorStream() << "failure\n"; - return false; - } -} - -NodeSmartReference MapResource_load(const MapFormat &format, const char *path, const char *name) -{ - NodeSmartReference root(NewMapRoot(name)); - - StringOutputStream fullpath(256); - fullpath << path << name; - - if (path_is_absolute(fullpath.c_str())) { - MapResource_loadFile(format, root, fullpath.c_str()); - } else { - globalErrorStream() << "map path is not fully qualified: " << makeQuoted(fullpath.c_str()) << "\n"; - } - - return root; -} - -bool MapResource_saveFile(const MapFormat &format, scene::Node &root, GraphTraversalFunc traverse, const char *filename) -{ - //ASSERT_MESSAGE(path_is_absolute(filename), "MapResource_saveFile: path is not absolute: " << makeQuoted(filename)); - globalOutputStream() << "Open file " << filename << " for write..."; - TextFileOutputStream file(filename); - if (!file.failed()) { - globalOutputStream() << "success\n"; - ScopeDisableScreenUpdates disableScreenUpdates(path_get_filename_start(filename), "Saving Map"); - format.writeGraph(root, traverse, file); - return true; - } - - globalErrorStream() << "failure\n"; - return false; -} - -bool file_saveBackup(const char *path) -{ - if (file_writeable(path)) { - StringOutputStream backup(256); - backup << StringRange(path, path_get_extension(path)) << "bak"; - - return (!file_exists(backup.c_str()) || file_remove(backup.c_str())) // remove backup - && file_move(path, backup.c_str()); // rename current to backup - } - - globalErrorStream() << "map path is not writeable: " << makeQuoted(path) << "\n"; - return false; -} - -bool MapResource_save(const MapFormat &format, scene::Node &root, const char *path, const char *name) -{ - StringOutputStream fullpath(256); - fullpath << path << name; - - if (path_is_absolute(fullpath.c_str())) { - if (!file_exists(fullpath.c_str()) || file_saveBackup(fullpath.c_str())) { - return MapResource_saveFile(format, root, Map_Traverse, fullpath.c_str()); - } - - globalErrorStream() << "failed to save a backup map file: " << makeQuoted(fullpath.c_str()) << "\n"; - return false; - } - - globalErrorStream() << "map path is not fully qualified: " << makeQuoted(fullpath.c_str()) << "\n"; - return false; -} - -namespace { -NodeSmartReference g_nullNode(NewNullNode()); -NodeSmartReference g_nullModel(g_nullNode); -} - -class NullModelLoader : public ModelLoader { -public: -scene::Node &loadModel(ArchiveFile &file) -{ - return g_nullModel; -} -}; - -namespace { -NullModelLoader g_NullModelLoader; -} - - -/// \brief Returns the model loader for the model \p type or 0 if the model \p type has no loader module -ModelLoader *ModelLoader_forType(const char *type) -{ - const char *moduleName = findModuleName(&GlobalFiletypes(), ModelLoader::Name(), type); - if (string_not_empty(moduleName)) { - ModelLoader *table = ReferenceAPI_getModelModules().findModule(moduleName); - if (table != 0) { - return table; - } else { - globalErrorStream() << "ERROR: Model type incorrectly registered: \"" << moduleName << "\"\n"; - return &g_NullModelLoader; - } - } - return 0; -} - -NodeSmartReference ModelResource_load(ModelLoader *loader, const char *name) -{ - ScopeDisableScreenUpdates disableScreenUpdates(path_get_filename_start(name), "Loading Model"); - - NodeSmartReference model(g_nullModel); - - - ArchiveFile *file = GlobalFileSystem().openFile(name); - - if (file != 0) { - // Only output failures, we don't need to spam the console with successes - //globalOutputStream() << "Loaded Model: \"" << name << "\"\n"; - model = loader->loadModel(*file); - file->release(); - } else { - globalErrorStream() << "Model load failed: \"" << name << "\"\n"; - } - - model.get().m_isRoot = true; - return model; -} - - -inline hash_t path_hash(const char *path, hash_t previous = 0) -{ -#if GDEF_OS_WINDOWS - return string_hash_nocase( path, previous ); -#else // UNIX - return string_hash(path, previous); -#endif -} - -struct PathEqual { - bool operator()(const CopiedString &path, const CopiedString &other) const - { - return path_equal(path.c_str(), other.c_str()); - } -}; - -struct PathHash { - typedef hash_t hash_type; - - hash_type operator()(const CopiedString &path) const - { - return path_hash(path.c_str()); - } -}; - -typedef std::pair ModelKey; - -struct ModelKeyEqual { - bool operator()(const ModelKey &key, const ModelKey &other) const - { - return path_equal(key.first.c_str(), other.first.c_str()) && - path_equal(key.second.c_str(), other.second.c_str()); - } -}; - -struct ModelKeyHash { - typedef hash_t hash_type; - - hash_type operator()(const ModelKey &key) const - { - return hash_combine(path_hash(key.first.c_str()), path_hash(key.second.c_str())); - } -}; - -typedef HashTable ModelCache; -ModelCache g_modelCache; -bool g_modelCache_enabled = true; - -ModelCache::iterator ModelCache_find(const char *path, const char *name) -{ - if (g_modelCache_enabled) { - return g_modelCache.find(ModelKey(path, name)); - } - return g_modelCache.end(); -} - -ModelCache::iterator ModelCache_insert(const char *path, const char *name, scene::Node &node) -{ - if (g_modelCache_enabled) { - return g_modelCache.insert(ModelKey(path, name), NodeSmartReference(node)); - } - return g_modelCache.insert(ModelKey("", ""), g_nullModel); -} - -void ModelCache_flush(const char *path, const char *name) -{ - ModelCache::iterator i = g_modelCache.find(ModelKey(path, name)); - if (i != g_modelCache.end()) { - //ASSERT_MESSAGE((*i).value.getCount() == 0, "resource flushed while still in use: " << (*i).key.first.c_str() << (*i).key.second.c_str()); - g_modelCache.erase(i); - } -} - -void ModelCache_clear() -{ - g_modelCache_enabled = false; - g_modelCache.clear(); - g_modelCache_enabled = true; -} - -NodeSmartReference Model_load(ModelLoader *loader, const char *path, const char *name, const char *type) -{ - if (loader != 0) { - return ModelResource_load(loader, name); - } else { - const char *moduleName = findModuleName(&GlobalFiletypes(), MapFormat::Name(), type); - if (string_not_empty(moduleName)) { - const MapFormat *format = ReferenceAPI_getMapModules().findModule(moduleName); - if (format != 0) { - return MapResource_load(*format, path, name); - } else { - globalErrorStream() << "ERROR: Map type incorrectly registered: \"" << moduleName << "\"\n"; - return g_nullModel; - } - } else { - if (string_not_empty(type)) { - globalErrorStream() << "Model type not supported: \"" << name << "\"\n"; - } - return g_nullModel; - } - } -} - -namespace { -bool g_realised = false; - -// name may be absolute or relative -const char *rootPath(const char *name) -{ - return GlobalFileSystem().findRoot( - path_is_absolute(name) - ? name - : GlobalFileSystem().findFile(name) - ); -} -} - -struct ModelResource : public Resource { - NodeSmartReference m_model; - const CopiedString m_originalName; - CopiedString m_path; - CopiedString m_name; - CopiedString m_type; - ModelLoader *m_loader; - ModuleObservers m_observers; - std::time_t m_modified; - std::size_t m_unrealised; - - ModelResource(const CopiedString &name) : - m_model(g_nullModel), - m_originalName(name), - m_type(path_get_extension(name.c_str())), - m_loader(0), - m_modified(0), - m_unrealised(1) - { - m_loader = ModelLoader_forType(m_type.c_str()); - - if (g_realised) { - realise(); - } - } - - ~ModelResource() - { - if (realised()) { - unrealise(); - } - ASSERT_MESSAGE(!realised(), "ModelResource::~ModelResource: resource reference still realised: " - << makeQuoted(m_name.c_str())); - } - - // NOT COPYABLE - ModelResource(const ModelResource &); - - // NOT ASSIGNABLE - ModelResource &operator=(const ModelResource &); - - void setModel(const NodeSmartReference &model) - { - m_model = model; - } - - void clearModel() - { - m_model = g_nullModel; - } - - void loadCached() - { - if (g_modelCache_enabled) { - // cache lookup - ModelCache::iterator i = ModelCache_find(m_path.c_str(), m_name.c_str()); - if (i == g_modelCache.end()) { - i = ModelCache_insert( - m_path.c_str(), - m_name.c_str(), - Model_load(m_loader, m_path.c_str(), m_name.c_str(), m_type.c_str()) - ); - } - - setModel((*i).value); - } else { - setModel(Model_load(m_loader, m_path.c_str(), m_name.c_str(), m_type.c_str())); - } - } - - void loadModel() - { - loadCached(); - connectMap(); - mapSave(); - } - - bool load() - { - ASSERT_MESSAGE(realised(), "resource not realised"); - if (m_model == g_nullModel) { - loadModel(); - } - - return m_model != g_nullModel; - } - - bool save() - { - if (!mapSaved()) { - const char *moduleName = findModuleName(GetFileTypeRegistry(), MapFormat::Name(), m_type.c_str()); - if (string_not_empty(moduleName)) { - const MapFormat *format = ReferenceAPI_getMapModules().findModule(moduleName); - if (format != 0 && MapResource_save(*format, m_model.get(), m_path.c_str(), m_name.c_str())) { - mapSave(); - return true; - } - } - } - return false; - } - - void flush() - { - if (realised()) { - ModelCache_flush(m_path.c_str(), m_name.c_str()); - } - } - - scene::Node *getNode() - { - //if(m_model != g_nullModel) - { - return m_model.get_pointer(); - } - //return 0; - } - - void setNode(scene::Node *node) - { - ModelCache::iterator i = ModelCache_find(m_path.c_str(), m_name.c_str()); - if (i != g_modelCache.end()) { - (*i).value = NodeSmartReference(*node); - } - setModel(NodeSmartReference(*node)); - - connectMap(); - } - - void attach(ModuleObserver &observer) - { - if (realised()) { - observer.realise(); - } - m_observers.attach(observer); - } - - void detach(ModuleObserver &observer) - { - if (realised()) { - observer.unrealise(); - } - m_observers.detach(observer); - } - - bool realised() - { - return m_unrealised == 0; - } - - void realise() - { - ASSERT_MESSAGE(m_unrealised != 0, "ModelResource::realise: already realised"); - if (--m_unrealised == 0) { - m_path = rootPath(m_originalName.c_str()); - m_name = path_make_relative(m_originalName.c_str(), m_path.c_str()); - - //globalOutputStream() << "ModelResource::realise: " << m_path.c_str() << m_name.c_str() << "\n"; - - m_observers.realise(); - } - } - - void unrealise() - { - if (++m_unrealised == 1) { - m_observers.unrealise(); - - //globalOutputStream() << "ModelResource::unrealise: " << m_path.c_str() << m_name.c_str() << "\n"; - clearModel(); - } - } - - bool isMap() const - { - return Node_getMapFile(m_model) != 0; - } - - void connectMap() - { - MapFile *map = Node_getMapFile(m_model); - if (map != 0) { - map->setChangedCallback(makeCallbackF(MapChanged)); - } - } - - std::time_t modified() const - { - StringOutputStream fullpath(256); - fullpath << m_path.c_str() << m_name.c_str(); - return file_modified(fullpath.c_str()); - } - - void mapSave() - { - m_modified = modified(); - MapFile *map = Node_getMapFile(m_model); - if (map != 0) { - map->save(); - } - } - - bool mapSaved() const - { - MapFile *map = Node_getMapFile(m_model); - if (map != 0) { - return m_modified == modified() && map->saved(); - } - return true; - } - - bool isModified() const - { - return ((!string_empty(m_path.c_str()) // had or has an absolute path - && m_modified != modified()) // AND disk timestamp changed - || !path_equal(rootPath(m_originalName.c_str()), m_path.c_str())); // OR absolute vfs-root changed - } - - void refresh() - { - if (isModified()) { - flush(); - unrealise(); - realise(); - } - } -}; - -class HashtableReferenceCache : public ReferenceCache, public ModuleObserver { -typedef HashedCache ModelReferences; -ModelReferences m_references; -std::size_t m_unrealised; - -class ModelReferencesSnapshot { -ModelReferences &m_references; -typedef std::list Iterators; -Iterators m_iterators; -public: -typedef Iterators::iterator iterator; - -ModelReferencesSnapshot(ModelReferences &references) : m_references(references) -{ - for (ModelReferences::iterator i = m_references.begin(); i != m_references.end(); ++i) { - m_references.capture(i); - m_iterators.push_back(i); - } -} - -~ModelReferencesSnapshot() -{ - for (Iterators::iterator i = m_iterators.begin(); i != m_iterators.end(); ++i) { - m_references.release(*i); - } -} - -iterator begin() -{ - return m_iterators.begin(); -} - -iterator end() -{ - return m_iterators.end(); -} -}; - -public: - -typedef ModelReferences::iterator iterator; - -HashtableReferenceCache() : m_unrealised(1) -{ -} - -iterator begin() -{ - return m_references.begin(); -} - -iterator end() -{ - return m_references.end(); -} - -void clear() -{ - m_references.clear(); -} - -Resource *capture(const char *path) -{ - //globalOutputStream() << "capture: \"" << path << "\"\n"; - return m_references.capture(CopiedString(path)).get(); -} - -void release(const char *path) -{ - m_references.release(CopiedString(path)); - //globalOutputStream() << "release: \"" << path << "\"\n"; -} - -void setEntityCreator(EntityCreator &entityCreator) -{ - g_entityCreator = &entityCreator; -} - -bool realised() const -{ - return m_unrealised == 0; -} - -void realise() -{ - ASSERT_MESSAGE(m_unrealised != 0, "HashtableReferenceCache::realise: already realised"); - if (--m_unrealised == 0) { - g_realised = true; - - { - ModelReferencesSnapshot snapshot(m_references); - for (ModelReferencesSnapshot::iterator i = snapshot.begin(); i != snapshot.end(); ++i) { - ModelReferences::value_type &value = *(*i); - if (value.value.count() != 1) { - value.value.get()->realise(); - } - } - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - g_realised = false; - - { - ModelReferencesSnapshot snapshot(m_references); - for (ModelReferencesSnapshot::iterator i = snapshot.begin(); i != snapshot.end(); ++i) { - ModelReferences::value_type &value = *(*i); - if (value.value.count() != 1) { - value.value.get()->unrealise(); - } - } - } - - ModelCache_clear(); - } -} - -void refresh() -{ - ModelReferencesSnapshot snapshot(m_references); - for (ModelReferencesSnapshot::iterator i = snapshot.begin(); i != snapshot.end(); ++i) { - ModelResource *resource = (*(*i)).value.get(); - if (!resource->isMap()) { - resource->refresh(); - } - } -} -}; - -namespace { -HashtableReferenceCache g_referenceCache; -} - -void SaveReferences() -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Saving Map"); - for (HashtableReferenceCache::iterator i = g_referenceCache.begin(); i != g_referenceCache.end(); ++i) { - (*i).value->save(); - } - MapChanged(); -} - -bool References_Saved() -{ - for (HashtableReferenceCache::iterator i = g_referenceCache.begin(); i != g_referenceCache.end(); ++i) { - scene::Node *node = (*i).value->getNode(); - if (node != 0) { - MapFile *map = Node_getMapFile(*node); - if (map != 0 && !map->saved()) { - return false; - } - } - } - return true; -} - -void RefreshReferences() -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Refreshing Models"); - g_referenceCache.refresh(); -} - - -void FlushReferences() -{ - ModelCache_clear(); - - g_referenceCache.clear(); -} - -ReferenceCache &GetReferenceCache() -{ - return g_referenceCache; -} - - -#include "modulesystem/modulesmap.h" -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class ReferenceDependencies : - public GlobalRadiantModuleRef, - public GlobalFileSystemModuleRef, - public GlobalFiletypesModuleRef { -ModelModulesRef m_model_modules; -MapModulesRef m_map_modules; -public: -ReferenceDependencies() : - m_model_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("modeltypes")), - m_map_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("maptypes")) -{ -} - -ModelModules &getModelModules() -{ - return m_model_modules.get(); -} - -MapModules &getMapModules() -{ - return m_map_modules.get(); -} -}; - -class ReferenceAPI : public TypeSystemRef { -ReferenceCache *m_reference; -public: -typedef ReferenceCache Type; - -STRING_CONSTANT(Name, "*"); - -ReferenceAPI() -{ - g_nullModel = NewNullModel(); - - GlobalFileSystem().attach(g_referenceCache); - - m_reference = &GetReferenceCache(); -} - -~ReferenceAPI() -{ - GlobalFileSystem().detach(g_referenceCache); - - g_nullModel = g_nullNode; -} - -ReferenceCache *getTable() -{ - return m_reference; -} -}; - -typedef SingletonModule ReferenceModule; -typedef Static StaticReferenceModule; -StaticRegisterModule staticRegisterReference(StaticReferenceModule::instance()); - -ModelModules &ReferenceAPI_getModelModules() -{ - return StaticReferenceModule::instance().getDependencies().getModelModules(); -} - -MapModules &ReferenceAPI_getMapModules() -{ - return StaticReferenceModule::instance().getDependencies().getMapModules(); -} diff --git a/src/referencecache.h b/src/referencecache.h deleted file mode 100644 index 1431e3e..0000000 --- a/src/referencecache.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_REFERENCECACHE_H ) -#define INCLUDED_REFERENCECACHE_H - -/// \brief Saves all open resource references if they differ from the version on disk. -void SaveReferences(); - -/// \brief Flushes the cache of resource references. All resource references must be released before calling this. -void FlushReferences(); - -/// \brief Reloads all resource references that differ from the version on disk. -void RefreshReferences(); - -#include "iscenegraph.h" - -namespace scene { -class Node; -} -class MapFormat; - -typedef void ( *GraphTraversalFunc )(scene::Node &root, const scene::Traversable::Walker &walker); - -bool -MapResource_saveFile(const MapFormat &format, scene::Node &root, GraphTraversalFunc traverse, const char *filename); - -#endif diff --git a/src/renderer.cpp b/src/renderer.cpp deleted file mode 100644 index 76e80f4..0000000 --- a/src/renderer.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "renderer.h" diff --git a/src/renderer.h b/src/renderer.h deleted file mode 100644 index 3de3b1b..0000000 --- a/src/renderer.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_RENDERER_H ) -#define INCLUDED_RENDERER_H - -#include "irender.h" -#include "renderable.h" -#include "iselection.h" -#include "cullable.h" -#include "scenelib.h" -#include "math/frustum.h" -#include - -inline Cullable *Instance_getCullable(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -inline Renderable *Instance_getRenderable(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -inline VolumeIntersectionValue -Cullable_testVisible(scene::Instance &instance, const VolumeTest &volume, VolumeIntersectionValue parentVisible) -{ - if (parentVisible == c_volumePartial) { - Cullable *cullable = Instance_getCullable(instance); - if (cullable != 0) { - return cullable->intersectVolume(volume, instance.localToWorld()); - } - } - return parentVisible; -} - -template -class CullingWalker { -const VolumeTest &m_volume; -const _Walker &m_walker; -public: -CullingWalker(const VolumeTest &volume, const _Walker &walker) - : m_volume(volume), m_walker(walker) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance, VolumeIntersectionValue parentVisible) const -{ - VolumeIntersectionValue visible = Cullable_testVisible(instance, m_volume, parentVisible); - if (visible != c_volumeOutside) { - return m_walker.pre(path, instance); - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance, VolumeIntersectionValue parentVisible) const -{ - return m_walker.post(path, instance); -} -}; - -template -class ForEachVisible : public scene::Graph::Walker { -const VolumeTest &m_volume; -const Walker_ &m_walker; -mutable std::vector m_state; -public: -ForEachVisible(const VolumeTest &volume, const Walker_ &walker) - : m_volume(volume), m_walker(walker) -{ - m_state.push_back(c_volumePartial); -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - VolumeIntersectionValue visible = (path.top().get().visible()) ? m_state.back() : c_volumeOutside; - - if (visible == c_volumePartial) { - visible = m_volume.TestAABB(instance.worldAABB()); - } - - m_state.push_back(visible); - - if (visible == c_volumeOutside) { - return false; - } else { - return m_walker.pre(path, instance, m_state.back()); - } -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (m_state.back() != c_volumeOutside) { - m_walker.post(path, instance, m_state.back()); - } - - m_state.pop_back(); -} -}; - -template -inline void Scene_forEachVisible(scene::Graph &graph, const VolumeTest &volume, const Functor &functor) -{ - graph.traverse(ForEachVisible >(volume, CullingWalker(volume, functor))); -} - -class RenderHighlighted { -Renderer &m_renderer; -const VolumeTest &m_volume; -public: -RenderHighlighted(Renderer &renderer, const VolumeTest &volume) - : m_renderer(renderer), m_volume(volume) -{ -} - -void render(const Renderable &renderable) const -{ - switch (m_renderer.getStyle()) { - case Renderer::eFullMaterials: - renderable.renderSolid(m_renderer, m_volume); - break; - case Renderer::eWireframeOnly: - renderable.renderWireframe(m_renderer, m_volume); - break; - } -} - -typedef ConstMemberCaller RenderCaller; - -bool pre(const scene::Path &path, scene::Instance &instance, VolumeIntersectionValue parentVisible) const -{ - m_renderer.PushState(); - - if (Cullable_testVisible(instance, m_volume, parentVisible) != c_volumeOutside) { - Renderable *renderable = Instance_getRenderable(instance); - if (renderable) { - renderable->viewChanged(); - } - - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 && selectable->isSelected()) { - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - m_renderer.Highlight(Renderer::eFace); - } else if (renderable) { - renderable->renderComponents(m_renderer, m_volume); - } - m_renderer.Highlight(Renderer::ePrimitive); - } - - if (renderable) { - render(*renderable); - } - } - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance, VolumeIntersectionValue parentVisible) const -{ - m_renderer.PopState(); -} -}; - -inline void Scene_Render(Renderer &renderer, const VolumeTest &volume) -{ - GlobalSceneGraph().traverse(ForEachVisible(volume, RenderHighlighted(renderer, volume))); - GlobalShaderCache().forEachRenderable(RenderHighlighted::RenderCaller(RenderHighlighted(renderer, volume))); -} - -#endif diff --git a/src/renderstate.cpp b/src/renderstate.cpp deleted file mode 100644 index fde54cb..0000000 --- a/src/renderstate.cpp +++ /dev/null @@ -1,2522 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "renderstate.h" - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "ishaders.h" -#include "irender.h" -#include "itextures.h" -#include "igl.h" -#include "iglrender.h" -#include "renderable.h" -#include "qerplugin.h" - -#include -#include -#include -#include - -#include "math/matrix.h" -#include "math/aabb.h" -#include "generic/callback.h" -#include "texturelib.h" -#include "string/string.h" -#include "container/hashfunc.h" -#include "container/cache.h" -#include "generic/reference.h" -#include "moduleobservers.h" -#include "stream/filestream.h" -#include "stream/stringstream.h" -#include "os/file.h" -#include "preferences.h" - -#include "xywindow.h" - - -#define DEBUG_RENDER 0 - -inline void debug_string(const char *string) -{ -#if (DEBUG_RENDER) - globalOutputStream() << string << "\n"; -#endif -} - -inline void debug_int(const char *comment, int i) -{ -#if (DEBUG_RENDER) - globalOutputStream() << comment << " " << i << "\n"; -#endif -} - -inline void debug_colour(const char *comment) -{ -#if (DEBUG_RENDER) - Vector4 v; - glGetFloatv( GL_CURRENT_COLOR, reinterpret_cast( &v ) ); - globalOutputStream() << comment << " colour: " - << v[0] << " " - << v[1] << " " - << v[2] << " " - << v[3]; - if ( glIsEnabled( GL_COLOR_ARRAY ) ) { - globalOutputStream() << " ARRAY"; - } - if ( glIsEnabled( GL_COLOR_MATERIAL ) ) { - globalOutputStream() << " MATERIAL"; - } - globalOutputStream() << "\n"; -#endif -} - -#include "timer.h" - -StringOutputStream g_renderer_stats; -std::size_t g_count_prims; -std::size_t g_count_states; -std::size_t g_count_transforms; -Timer g_timer; - -inline void count_prim() -{ - ++g_count_prims; -} - -inline void count_state() -{ - ++g_count_states; -} - -inline void count_transform() -{ - ++g_count_transforms; -} - -void Renderer_ResetStats() -{ - g_count_prims = 0; - g_count_states = 0; - g_count_transforms = 0; - g_timer.start(); -} - -const char *Renderer_GetStats() -{ - g_renderer_stats.clear(); - g_renderer_stats << "prims: " << Unsigned(g_count_prims) - << " | states: " << Unsigned(g_count_states) - << " | transforms: " << Unsigned(g_count_transforms) - << " | msec: " << g_timer.elapsed_msec(); - return g_renderer_stats.c_str(); -} - - -void printShaderLog(GLhandleARB object) -{ - GLint log_length = 0; - glGetObjectParameterivARB(object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &log_length); - - Array log(log_length); - glGetInfoLogARB(object, log_length, &log_length, log.data()); - - globalErrorStream() << StringRange(log.begin(), log.begin() + log_length) << "\n"; -} - -void createShader(GLhandleARB program, const char *filename, GLenum type) -{ - GLhandleARB shader = glCreateShaderObjectARB(type); - GlobalOpenGL_debugAssertNoErrors(); - - // load shader - { - std::size_t size = file_size(filename); - FileInputStream file(filename); - ASSERT_MESSAGE(!file.failed(), "failed to open " << makeQuoted(filename)); - Array buffer(size); - size = file.read(reinterpret_cast( buffer.data()), size); - - const GLcharARB *string = buffer.data(); - GLint length = GLint(size); - glShaderSourceARB(shader, 1, &string, &length); - } - - // compile shader - { - glCompileShaderARB(shader); - - GLint compiled = 0; - glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled); - - if (!compiled) { - printShaderLog(shader); - } - - ASSERT_MESSAGE(compiled, "shader compile failed: " << makeQuoted(filename)); - } - - // attach shader - glAttachObjectARB(program, shader); - - glDeleteObjectARB(shader); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void GLSLProgram_link(GLhandleARB program) -{ - glLinkProgramARB(program); - - GLint linked = false; - glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linked); - - if (!linked) { - printShaderLog(program); - } - - ASSERT_MESSAGE(linked, "program link failed"); -} - -void GLSLProgram_validate(GLhandleARB program) -{ - glValidateProgramARB(program); - - GLint validated = false; - glGetObjectParameterivARB(program, GL_OBJECT_VALIDATE_STATUS_ARB, &validated); - - if (!validated) { - printShaderLog(program); - } - - ASSERT_MESSAGE(validated, "program validation failed"); -} - -bool g_bumpGLSLPass_enabled = false; -bool g_depthfillPass_enabled = false; - -class GLSLBumpProgram : public GLProgram { -public: -GLhandleARB m_program; -qtexture_t *m_light_attenuation_xy; -qtexture_t *m_light_attenuation_z; -GLint u_view_origin; -GLint u_light_origin; -GLint u_light_color; -GLint u_bump_scale; -GLint u_specular_exponent; - -GLSLBumpProgram() : m_program(0), m_light_attenuation_xy(0), m_light_attenuation_z(0) -{ -} - -void create() -{ - // create program - m_program = glCreateProgramObjectARB(); - - // create shader - { - StringOutputStream filename(256); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.glsl"; - createShader(m_program, filename.c_str(), GL_VERTEX_SHADER_ARB); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.glsl"; - createShader(m_program, filename.c_str(), GL_FRAGMENT_SHADER_ARB); - } - - GLSLProgram_link(m_program); - GLSLProgram_validate(m_program); - - glUseProgramObjectARB(m_program); - - glBindAttribLocationARB(m_program, c_attr_TexCoord0, "attr_TexCoord0"); - glBindAttribLocationARB(m_program, c_attr_Tangent, "attr_Tangent"); - glBindAttribLocationARB(m_program, c_attr_Binormal, "attr_Binormal"); - - glUniform1iARB(glGetUniformLocationARB(m_program, "u_diffusemap"), 0); - glUniform1iARB(glGetUniformLocationARB(m_program, "u_bumpmap"), 1); - glUniform1iARB(glGetUniformLocationARB(m_program, "u_specularmap"), 2); - glUniform1iARB(glGetUniformLocationARB(m_program, "u_attenuationmap_xy"), 3); - glUniform1iARB(glGetUniformLocationARB(m_program, "u_attenuationmap_z"), 4); - - u_view_origin = glGetUniformLocationARB(m_program, "u_view_origin"); - u_light_origin = glGetUniformLocationARB(m_program, "u_light_origin"); - u_light_color = glGetUniformLocationARB(m_program, "u_light_color"); - u_bump_scale = glGetUniformLocationARB(m_program, "u_bump_scale"); - u_specular_exponent = glGetUniformLocationARB(m_program, "u_specular_exponent"); - - glUseProgramObjectARB(0); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroy() -{ - glDeleteObjectARB(m_program); - m_program = 0; -} - -void enable() -{ - glUseProgramObjectARB(m_program); - - glEnableVertexAttribArrayARB(c_attr_TexCoord0); - glEnableVertexAttribArrayARB(c_attr_Tangent); - glEnableVertexAttribArrayARB(c_attr_Binormal); - - GlobalOpenGL_debugAssertNoErrors(); - - debug_string("enable bump"); - g_bumpGLSLPass_enabled = true; -} - -void disable() -{ - glUseProgramObjectARB(0); - - glDisableVertexAttribArrayARB(c_attr_TexCoord0); - glDisableVertexAttribArrayARB(c_attr_Tangent); - glDisableVertexAttribArrayARB(c_attr_Binormal); - - GlobalOpenGL_debugAssertNoErrors(); - - debug_string("disable bump"); - g_bumpGLSLPass_enabled = false; -} - -void setParameters(const Vector3 &viewer, const Matrix4 &localToWorld, const Vector3 &origin, const Vector3 &colour, - const Matrix4 &world2light) -{ - Matrix4 world2local(localToWorld); - matrix4_affine_invert(world2local); - - Vector3 localLight(origin); - matrix4_transform_point(world2local, localLight); - - Vector3 localViewer(viewer); - matrix4_transform_point(world2local, localViewer); - - Matrix4 local2light(world2light); - matrix4_multiply_by_matrix4(local2light, localToWorld); // local->world->light - - glUniform3fARB(u_view_origin, localViewer.x(), localViewer.y(), localViewer.z()); - glUniform3fARB(u_light_origin, localLight.x(), localLight.y(), localLight.z()); - glUniform3fARB(u_light_color, colour.x(), colour.y(), colour.z()); - glUniform1fARB(u_bump_scale, 1.0); - glUniform1fARB(u_specular_exponent, 32.0); - - glActiveTexture(GL_TEXTURE3); - glClientActiveTexture(GL_TEXTURE3); - - glMatrixMode(GL_TEXTURE); - glLoadMatrixf(reinterpret_cast( &local2light )); - glMatrixMode(GL_MODELVIEW); - - GlobalOpenGL_debugAssertNoErrors(); -} -}; - -GLSLBumpProgram g_bumpGLSL; - - -class GLSLDepthFillProgram : public GLProgram { -public: -GLhandleARB m_program; - -void create() -{ - // create program - m_program = glCreateProgramObjectARB(); - - // create shader - { - StringOutputStream filename(256); - filename << GlobalRadiant().getAppPath() << "gl/zfill_vp.glsl"; - createShader(m_program, filename.c_str(), GL_VERTEX_SHADER_ARB); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/zfill_fp.glsl"; - createShader(m_program, filename.c_str(), GL_FRAGMENT_SHADER_ARB); - } - - GLSLProgram_link(m_program); - GLSLProgram_validate(m_program); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroy() -{ - glDeleteObjectARB(m_program); - m_program = 0; -} - -void enable() -{ - glUseProgramObjectARB(m_program); - GlobalOpenGL_debugAssertNoErrors(); - debug_string("enable depthfill"); - g_depthfillPass_enabled = true; -} - -void disable() -{ - glUseProgramObjectARB(0); - GlobalOpenGL_debugAssertNoErrors(); - debug_string("disable depthfill"); - g_depthfillPass_enabled = false; -} - -void setParameters(const Vector3 &viewer, const Matrix4 &localToWorld, const Vector3 &origin, const Vector3 &colour, - const Matrix4 &world2light) -{ -} -}; - -GLSLDepthFillProgram g_depthFillGLSL; - - -// ARB path - -void createProgram(const char *filename, GLenum type) -{ - std::size_t size = file_size(filename); - FileInputStream file(filename); - ASSERT_MESSAGE(!file.failed(), "failed to open " << makeQuoted(filename)); - Array buffer(size); - size = file.read(reinterpret_cast( buffer.data()), size); - - glProgramStringARB(type, GL_PROGRAM_FORMAT_ASCII_ARB, GLsizei(size), buffer.data()); - - if (GL_INVALID_OPERATION == glGetError()) { - GLint errPos; - glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); - const GLubyte *errString = glGetString(GL_PROGRAM_ERROR_STRING_ARB); - - globalErrorStream() << reinterpret_cast( filename ) << ":" << errPos << "\n" - << reinterpret_cast( errString ); - - ERROR_MESSAGE("error in gl program"); - } -} - -class ARBBumpProgram : public GLProgram { -public: -GLuint m_vertex_program; -GLuint m_fragment_program; - -void create() -{ - glEnable(GL_VERTEX_PROGRAM_ARB); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - - { - glGenProgramsARB(1, &m_vertex_program); - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_vertex_program); - StringOutputStream filename(256); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.glp"; - createProgram(filename.c_str(), GL_VERTEX_PROGRAM_ARB); - - glGenProgramsARB(1, &m_fragment_program); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_fragment_program); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.glp"; - createProgram(filename.c_str(), GL_FRAGMENT_PROGRAM_ARB); - } - - glDisable(GL_VERTEX_PROGRAM_ARB); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroy() -{ - glDeleteProgramsARB(1, &m_vertex_program); - glDeleteProgramsARB(1, &m_fragment_program); - GlobalOpenGL_debugAssertNoErrors(); -} - -void enable() -{ - glEnable(GL_VERTEX_PROGRAM_ARB); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_vertex_program); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_fragment_program); - - glEnableVertexAttribArrayARB(8); - glEnableVertexAttribArrayARB(9); - glEnableVertexAttribArrayARB(10); - glEnableVertexAttribArrayARB(11); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void disable() -{ - glDisable(GL_VERTEX_PROGRAM_ARB); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - - glDisableVertexAttribArrayARB(8); - glDisableVertexAttribArrayARB(9); - glDisableVertexAttribArrayARB(10); - glDisableVertexAttribArrayARB(11); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void setParameters(const Vector3 &viewer, const Matrix4 &localToWorld, const Vector3 &origin, const Vector3 &colour, - const Matrix4 &world2light) -{ - Matrix4 world2local(localToWorld); - matrix4_affine_invert(world2local); - - Vector3 localLight(origin); - matrix4_transform_point(world2local, localLight); - - Vector3 localViewer(viewer); - matrix4_transform_point(world2local, localViewer); - - Matrix4 local2light(world2light); - matrix4_multiply_by_matrix4(local2light, localToWorld); // local->world->light - - // view origin - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 4, localViewer.x(), localViewer.y(), localViewer.z(), 0); - - // light origin - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, localLight.x(), localLight.y(), localLight.z(), 1); - - // light colour - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 3, colour.x(), colour.y(), colour.z(), 0); - - // bump scale - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1, 0, 0, 0); - - // specular exponent - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 5, 32, 0, 0, 0); - - - glActiveTexture(GL_TEXTURE3); - glClientActiveTexture(GL_TEXTURE3); - - glMatrixMode(GL_TEXTURE); - glLoadMatrixf(reinterpret_cast( &local2light )); - glMatrixMode(GL_MODELVIEW); - - GlobalOpenGL_debugAssertNoErrors(); -} -}; - -class ARBDepthFillProgram : public GLProgram { -public: -GLuint m_vertex_program; -GLuint m_fragment_program; - -void create() -{ - glEnable(GL_VERTEX_PROGRAM_ARB); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - - { - glGenProgramsARB(1, &m_vertex_program); - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_vertex_program); - StringOutputStream filename(256); - filename << GlobalRadiant().getAppPath() << "gl/zfill_vp.glp"; - createProgram(filename.c_str(), GL_VERTEX_PROGRAM_ARB); - - glGenProgramsARB(1, &m_fragment_program); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_fragment_program); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/zfill_fp.glp"; - createProgram(filename.c_str(), GL_FRAGMENT_PROGRAM_ARB); - } - - glDisable(GL_VERTEX_PROGRAM_ARB); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroy() -{ - glDeleteProgramsARB(1, &m_vertex_program); - glDeleteProgramsARB(1, &m_fragment_program); - GlobalOpenGL_debugAssertNoErrors(); -} - -void enable() -{ - glEnable(GL_VERTEX_PROGRAM_ARB); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_vertex_program); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_fragment_program); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void disable() -{ - glDisable(GL_VERTEX_PROGRAM_ARB); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void setParameters(const Vector3 &viewer, const Matrix4 &localToWorld, const Vector3 &origin, const Vector3 &colour, - const Matrix4 &world2light) -{ -} -}; - -ARBBumpProgram g_bumpARB; -ARBDepthFillProgram g_depthFillARB; - - -#if 0 -// NV20 path (unfinished) - -void createProgram( GLint program, const char* filename, GLenum type ){ - std::size_t size = file_size( filename ); - FileInputStream file( filename ); - ASSERT_MESSAGE( !file.failed(), "failed to open " << makeQuoted( filename ) ); - Array buffer( size ); - size = file.read( reinterpret_cast( buffer.data() ), size ); - - glLoadProgramNV( type, program, GLsizei( size ), buffer.data() ); - - if ( GL_INVALID_OPERATION == glGetError() ) { - GLint errPos; - glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); - const GLubyte* errString = glGetString( GL_PROGRAM_ERROR_STRING_NV ); - - globalErrorStream() << filename << ":" << errPos << "\n" << errString; - - ERROR_MESSAGE( "error in gl program" ); - } -} - -GLuint m_vertex_program; -GLuint m_fragment_program; -qtexture_t* g_cube = 0; -qtexture_t* g_specular_lookup = 0; -qtexture_t* g_attenuation_xy = 0; -qtexture_t* g_attenuation_z = 0; - -void createVertexProgram(){ - { - glGenProgramsNV( 1, &m_vertex_program ); - glBindProgramNV( GL_VERTEX_PROGRAM_NV, m_vertex_program ); - StringOutputStream filename( 256 ); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.nv30"; - createProgram( m_vertex_program, filename.c_str(), GL_VERTEX_PROGRAM_NV ); - - glGenProgramsNV( 1, &m_fragment_program ); - glBindProgramNV( GL_FRAGMENT_PROGRAM_NV, m_fragment_program ); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.nv30"; - createProgram( m_fragment_program, filename.c_str(), GL_FRAGMENT_PROGRAM_NV ); - } - - g_cube = GlobalTexturesCache().capture( "generated/cube" ); - g_specular_lookup = GlobalTexturesCache().capture( "generated/specular" ); - - g_attenuation_xy = GlobalTexturesCache().capture( "lights/squarelight1" ); - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, g_attenuation_xy->texture_number ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER ); - - g_attenuation_z = GlobalTexturesCache().capture( "lights/squarelight1a" ); - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, g_attenuation_z->texture_number ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroyVertexProgram(){ - glDeleteProgramsNV( 1, &m_vertex_program ); - glDeleteProgramsNV( 1, &m_fragment_program ); - GlobalOpenGL_debugAssertNoErrors(); - - GlobalTexturesCache().release( g_cube ); - GlobalTexturesCache().release( g_specular_lookup ); - GlobalTexturesCache().release( g_attenuation_xy ); - GlobalTexturesCache().release( g_attenuation_z ); -} - -bool g_vertexProgram_enabled = false; - -void enableVertexProgram(){ - //set up the register combiners - //two general combiners - glCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 2 ); - - //combiner 0 does tex0+tex1 -> spare0 - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, - GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, - GL_UNSIGNED_INVERT_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE1_ARB, - GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, - GL_UNSIGNED_INVERT_NV, GL_RGB ); - glCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, - GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); - - //combiner 1 does tex2 dot tex3 -> spare1 - glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE2_ARB, - GL_EXPAND_NORMAL_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, GL_TEXTURE3_ARB, - GL_EXPAND_NORMAL_NV, GL_RGB ); - glCombinerOutputNV( GL_COMBINER1_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV, GL_DISCARD_NV, - GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE ); - - - - //final combiner outputs (1-spare0)*constant color 0*spare1 - //do constant color 0*spare1 in the EF multiplier - glFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - - //now do (1-spare0)*EF - glFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_E_TIMES_F_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - - glEnable( GL_VERTEX_PROGRAM_NV ); - glEnable( GL_REGISTER_COMBINERS_NV ); - glBindProgramNV( GL_VERTEX_PROGRAM_NV, m_vertex_program ); - glBindProgramNV( GL_FRAGMENT_PROGRAM_NV, m_fragment_program ); - - glActiveTexture( GL_TEXTURE0 ); - glEnable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE1 ); - glEnable( GL_TEXTURE_1D ); - glActiveTexture( GL_TEXTURE2 ); - glEnable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE3 ); - glEnable( GL_TEXTURE_2D ); - - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY8_NV ); - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY9_NV ); - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY10_NV ); - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY11_NV ); - - GlobalOpenGL_debugAssertNoErrors(); - g_vertexProgram_enabled = true; -} - -void disableVertexProgram(){ - glDisable( GL_VERTEX_PROGRAM_NV ); - glDisable( GL_REGISTER_COMBINERS_NV ); - - glActiveTexture( GL_TEXTURE0 ); - glDisable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE1 ); - glDisable( GL_TEXTURE_1D ); - glActiveTexture( GL_TEXTURE2 ); - glDisable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE3 ); - glDisable( GL_TEXTURE_2D ); - - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY8_NV ); - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY9_NV ); - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY10_NV ); - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY11_NV ); - - GlobalOpenGL_debugAssertNoErrors(); - g_vertexProgram_enabled = false; -} - -class GLstringNV -{ -public: -const GLubyte* m_string; -const GLint m_length; -GLstringNV( const char* string ) : m_string( reinterpret_cast( string ) ), m_length( GLint( string_length( string ) ) ){ -} -}; - -GLstringNV g_light_origin( "light_origin" ); -GLstringNV g_view_origin( "view_origin" ); -GLstringNV g_light_color( "light_color" ); -GLstringNV g_bumpGLSL_scale( "bump_scale" ); -GLstringNV g_specular_exponent( "specular_exponent" ); - -void setVertexProgramEnvironment( const Vector3& localViewer ){ - Matrix4 local2light( g_matrix4_identity ); - matrix4_translate_by_vec3( local2light, Vector3( 0.5, 0.5, 0.5 ) ); - matrix4_scale_by_vec3( local2light, Vector3( 0.5, 0.5, 0.5 ) ); - matrix4_scale_by_vec3( local2light, Vector3( 1.0 / 512.0, 1.0 / 512.0, 1.0 / 512.0 ) ); - matrix4_translate_by_vec3( local2light, vector3_negated( localViewer ) ); - - glActiveTexture( GL_TEXTURE3 ); - glClientActiveTexture( GL_TEXTURE3 ); - - glMatrixMode( GL_TEXTURE ); - glLoadMatrixf( reinterpret_cast( &local2light ) ); - glMatrixMode( GL_MODELVIEW ); - - glTrackMatrixNV( GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV ); - glTrackMatrixNV( GL_VERTEX_PROGRAM_NV, 4, GL_TEXTURE0_ARB, GL_IDENTITY_NV ); - - // view origin - //qglProgramNamedParameter4fNV(m_fragment_program, g_view_origin.m_length, g_view_origin.m_string, localViewer.x(), localViewer.y(), localViewer.z(), 0); - - // light origin - glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 8, localViewer.x(), localViewer.y(), localViewer.z(), 1.0f ); - - // light colour - glCombinerParameterfNV( GL_CONSTANT_COLOR0_NV, 1, 1, 1, 1 ) - - // bump scale - //qglProgramNamedParameter4fNV(m_fragment_program, g_bumpGLSL_scale.m_length, g_bumpGLSL_scale.m_string, 1, 0, 0, 0); - - // specular exponent - //qglProgramNamedParameter4fNV(m_fragment_program, g_specular_exponent.m_length, g_specular_exponent.m_string, 32, 0, 0, 0); - - GlobalOpenGL_debugAssertNoErrors(); -} - -#endif - - -bool g_vertexArray_enabled = false; -bool g_normalArray_enabled = false; -bool g_texcoordArray_enabled = false; -bool g_colorArray_enabled = false; - -inline bool OpenGLState_less(const OpenGLState &self, const OpenGLState &other) -{ - //! Sort by sort-order override. - if (self.m_sort != other.m_sort) { - return self.m_sort < other.m_sort; - } - //! Sort by texture handle. - if (self.m_texture != other.m_texture) { - return self.m_texture < other.m_texture; - } - if (self.m_texture1 != other.m_texture1) { - return self.m_texture1 < other.m_texture1; - } - if (self.m_texture2 != other.m_texture2) { - return self.m_texture2 < other.m_texture2; - } - if (self.m_texture3 != other.m_texture3) { - return self.m_texture3 < other.m_texture3; - } - if (self.m_texture4 != other.m_texture4) { - return self.m_texture4 < other.m_texture4; - } - if (self.m_texture5 != other.m_texture5) { - return self.m_texture5 < other.m_texture5; - } - if (self.m_texture6 != other.m_texture6) { - return self.m_texture6 < other.m_texture6; - } - if (self.m_texture7 != other.m_texture7) { - return self.m_texture7 < other.m_texture7; - } - //! Sort by state bit-vector. - if (self.m_state != other.m_state) { - return self.m_state < other.m_state; - } - //! Comparing address makes sure states are never equal. - return &self < &other; -} - -void OpenGLState_constructDefault(OpenGLState &state) -{ - state.m_state = RENDER_DEFAULT; - - state.m_texture = 0; - state.m_texture1 = 0; - state.m_texture2 = 0; - state.m_texture3 = 0; - state.m_texture4 = 0; - state.m_texture5 = 0; - state.m_texture6 = 0; - state.m_texture7 = 0; - - state.m_colour[0] = 1; - state.m_colour[1] = 1; - state.m_colour[2] = 1; - state.m_colour[3] = 1; - - state.m_depthfunc = GL_LESS; - - state.m_blend_src = GL_SRC_ALPHA; - state.m_blend_dst = GL_ONE_MINUS_SRC_ALPHA; - - state.m_alphafunc = GL_ALWAYS; - state.m_alpharef = 0; - - state.m_linewidth = 1; - state.m_pointsize = 1; - - state.m_linestipple_factor = 1; - state.m_linestipple_pattern = 0xaaaa; - - state.m_fog = OpenGLFogState(); -} - - -/// \brief A container of Renderable references. -/// May contain the same Renderable multiple times, with different transforms. -class OpenGLStateBucket { -public: -struct RenderTransform { - const Matrix4 *m_transform; - const OpenGLRenderable *m_renderable; - const RendererLight *m_light; - - RenderTransform(const OpenGLRenderable &renderable, const Matrix4 &transform, const RendererLight *light) - : m_transform(&transform), m_renderable(&renderable), m_light(light) - { - } -}; - -typedef std::vector Renderables; - -private: - -OpenGLState m_state; -Renderables m_renderables; - -public: -OpenGLStateBucket() -{ -} - -void addRenderable(const OpenGLRenderable &renderable, const Matrix4 &modelview, const RendererLight *light = 0) -{ - m_renderables.push_back(RenderTransform(renderable, modelview, light)); -} - -OpenGLState &state() -{ - return m_state; -} - -void render(OpenGLState ¤t, unsigned int globalstate, const Vector3 &viewer); -}; - -#define LIGHT_SHADER_DEBUG 0 - -#if LIGHT_SHADER_DEBUG -typedef std::vector LightDebugShaders; -LightDebugShaders g_lightDebugShaders; -#endif - -class OpenGLStateLess { -public: -bool operator()(const OpenGLState &self, const OpenGLState &other) const -{ - return OpenGLState_less(self, other); -} -}; - -typedef ConstReference OpenGLStateReference; -typedef std::map OpenGLStates; -OpenGLStates g_state_sorted; - -class OpenGLStateBucketAdd { -OpenGLStateBucket &m_bucket; -const OpenGLRenderable &m_renderable; -const Matrix4 &m_modelview; -public: -using func = void (const RendererLight &); - -OpenGLStateBucketAdd(OpenGLStateBucket &bucket, const OpenGLRenderable &renderable, const Matrix4 &modelview) : - m_bucket(bucket), m_renderable(renderable), m_modelview(modelview) -{ -} - -void operator()(const RendererLight &light) -{ - m_bucket.addRenderable(m_renderable, m_modelview, &light); -} -}; - -class CountLights { -std::size_t m_count; -public: -using func = void (RendererLight &); - -CountLights() : m_count(0) -{ -} - -void operator()(const RendererLight &light) -{ - ++m_count; -} - -std::size_t count() const -{ - return m_count; -} -}; - -class OpenGLShader : public Shader { -typedef std::list Passes; -Passes m_passes; -IShader *m_shader; -std::size_t m_used; -ModuleObservers m_observers; -public: -OpenGLShader() : m_shader(0), m_used(0) -{ -} - -~OpenGLShader() -{ -} - -void construct(const char *name); - -void destroy() -{ - if (m_shader) { - m_shader->DecRef(); - } - m_shader = 0; - - for (Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i) { - delete *i; - } - m_passes.clear(); -} - -void addRenderable(const OpenGLRenderable &renderable, const Matrix4 &modelview, const LightList *lights) -{ - for (Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i) { -#if LIGHT_SHADER_DEBUG - if ( ( ( *i )->state().m_state & RENDER_BUMP ) != 0 ) { - if ( lights != 0 ) { - CountLights counter; - lights->forEachLight( makeCallback1( counter ) ); - globalOutputStream() << "count = " << counter.count() << "\n"; - for ( std::size_t i = 0; i < counter.count(); ++i ) - { - g_lightDebugShaders[counter.count()]->addRenderable( renderable, modelview ); - } - } - } - else -#else - if (((*i)->state().m_state & RENDER_BUMP) != 0) { - if (lights != 0) { - OpenGLStateBucketAdd add(*(*i), renderable, modelview); - lights->forEachLight(makeCallback(add)); - } - } else -#endif - { - (*i)->addRenderable(renderable, modelview); - } - } -} - -void incrementUsed() -{ - if (++m_used == 1 && m_shader != 0) { - m_shader->SetInUse(true); - } -} - -void decrementUsed() -{ - if (--m_used == 0 && m_shader != 0) { - m_shader->SetInUse(false); - } -} - -bool realised() const -{ - return m_shader != 0; -} - -void attach(ModuleObserver &observer) -{ - if (realised()) { - observer.realise(); - } - m_observers.attach(observer); -} - -void detach(ModuleObserver &observer) -{ - if (realised()) { - observer.unrealise(); - } - m_observers.detach(observer); -} - -void realise(const CopiedString &name) -{ - construct(name.c_str()); - - if (m_used != 0 && m_shader != 0) { - m_shader->SetInUse(true); - } - - for (Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i) { - g_state_sorted.insert(OpenGLStates::value_type(OpenGLStateReference((*i)->state()), *i)); - } - - m_observers.realise(); -} - -void unrealise() -{ - m_observers.unrealise(); - - for (Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i) { - g_state_sorted.erase(OpenGLStateReference((*i)->state())); - } - - destroy(); -} - -qtexture_t &getTexture() const -{ - ASSERT_NOTNULL(m_shader); - return *m_shader->getTexture(); -} - -unsigned int getFlags() const -{ - ASSERT_NOTNULL(m_shader); - return m_shader->getFlags(); -} - -IShader &getShader() const -{ - ASSERT_NOTNULL(m_shader); - return *m_shader; -} - -OpenGLState &appendDefaultPass() -{ - m_passes.push_back(new OpenGLStateBucket); - OpenGLState &state = m_passes.back()->state(); - OpenGLState_constructDefault(state); - return state; -} -}; - - -inline bool lightEnabled(const RendererLight &light, const LightCullable &cullable) -{ - return cullable.testLight(light); -} - -typedef std::set RendererLights; - -#define DEBUG_LIGHT_SYNC 0 - -class LinearLightList : public LightList { -LightCullable &m_cullable; -RendererLights &m_allLights; -Callback m_evaluateChanged; - -typedef std::list Lights; -mutable Lights m_lights; -mutable bool m_lightsChanged; -public: -LinearLightList(LightCullable &cullable, RendererLights &lights, const Callback &evaluateChanged) : - m_cullable(cullable), m_allLights(lights), m_evaluateChanged(evaluateChanged) -{ - m_lightsChanged = true; -} - -void evaluateLights() const -{ - m_evaluateChanged(); - if (m_lightsChanged) { - m_lightsChanged = false; - - m_lights.clear(); - m_cullable.clearLights(); - for (RendererLights::const_iterator i = m_allLights.begin(); i != m_allLights.end(); ++i) { - if (lightEnabled(*(*i), m_cullable)) { - m_lights.push_back(*i); - m_cullable.insertLight(*(*i)); - } - } - } -#if (DEBUG_LIGHT_SYNC) - else - { - Lights lights; - for ( RendererLights::const_iterator i = m_allLights.begin(); i != m_allLights.end(); ++i ) - { - if ( lightEnabled( *( *i ), m_cullable ) ) { - lights.push_back( *i ); - } - } - ASSERT_MESSAGE( - !std::lexicographical_compare( lights.begin(), lights.end(), m_lights.begin(), m_lights.end() ) - && !std::lexicographical_compare( m_lights.begin(), m_lights.end(), lights.begin(), lights.end() ), - "lights out of sync" - ); - } -#endif -} - -void forEachLight(const RendererLightCallback &callback) const -{ - evaluateLights(); - - for (Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i) { - callback(*(*i)); - } -} - -void lightsChanged() const -{ - m_lightsChanged = true; -} -}; - -inline void setFogState(const OpenGLFogState &state) -{ - glFogi(GL_FOG_MODE, state.mode); - glFogf(GL_FOG_DENSITY, state.density); - glFogf(GL_FOG_START, state.start); - glFogf(GL_FOG_END, state.end); - glFogi(GL_FOG_INDEX, state.index); - glFogfv(GL_FOG_COLOR, vector4_to_array(state.colour)); -} - -#define DEBUG_SHADERS 0 - -class OpenGLShaderCache : public ShaderCache, public TexturesCacheObserver, public ModuleObserver { -class CreateOpenGLShader { -OpenGLShaderCache *m_cache; -public: -explicit CreateOpenGLShader(OpenGLShaderCache *cache = 0) - : m_cache(cache) -{ -} - -OpenGLShader *construct(const CopiedString &name) -{ - OpenGLShader *shader = new OpenGLShader; - if (m_cache->realised()) { - shader->realise(name); - } - return shader; -} - -void destroy(OpenGLShader *shader) -{ - if (m_cache->realised()) { - shader->unrealise(); - } - delete shader; -} -}; - -typedef HashedCache, CreateOpenGLShader> Shaders; -Shaders m_shaders; -std::size_t m_unrealised; - -bool m_lightingEnabled; -bool m_lightingSupported; -bool m_useShaderLanguage; - -public: -OpenGLShaderCache() - : m_shaders(CreateOpenGLShader(this)), - m_unrealised( - 3), // wait until shaders, gl-context and textures are realised before creating any render-states - m_lightingEnabled(true), - m_lightingSupported(false), - m_useShaderLanguage(false), - m_lightsChanged(true), - m_traverseRenderablesMutex(false) -{ -} - -~OpenGLShaderCache() -{ - for (Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i) { - globalOutputStream() << "leaked shader: " << makeQuoted((*i).key.c_str()) << "\n"; - } -} - -Shader *capture(const char *name) -{ - ASSERT_MESSAGE(name[0] == '$' - || *name == '[' - || *name == '<' - || *name == '(' - || strchr(name, '\\') == 0, "shader name contains invalid characters: \"" << name << "\""); -#if DEBUG_SHADERS - globalOutputStream() << "shaders capture: " << makeQuoted( name ) << '\n'; -#endif - return m_shaders.capture(name).get(); -} - -void release(const char *name) -{ -#if DEBUG_SHADERS - globalOutputStream() << "shaders release: " << makeQuoted( name ) << '\n'; -#endif - m_shaders.release(name); -} - -void -render(RenderStateFlags globalstate, const Matrix4 &modelview, const Matrix4 &projection, const Vector3 &viewer) -{ - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(reinterpret_cast( &projection )); -#if 0 - //qglGetFloatv(GL_PROJECTION_MATRIX, reinterpret_cast(&projection)); -#endif - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(reinterpret_cast( &modelview )); -#if 0 - //qglGetFloatv(GL_MODELVIEW_MATRIX, reinterpret_cast(&modelview)); -#endif - - ASSERT_MESSAGE(realised(), "render states are not realised"); - - // global settings that are not set in renderstates - glFrontFace(GL_CW); - glCullFace(GL_BACK); - glPolygonOffset(-1, 1); - { - const GLubyte pattern[132] = { - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55 - }; - glPolygonStipple(pattern); - } - glEnableClientState(GL_VERTEX_ARRAY); - g_vertexArray_enabled = true; - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - } - - if (GlobalOpenGL().ARB_shader_objects()) { - glUseProgramObjectARB(0); - glDisableVertexAttribArrayARB(c_attr_TexCoord0); - glDisableVertexAttribArrayARB(c_attr_Tangent); - glDisableVertexAttribArrayARB(c_attr_Binormal); - } - - if (globalstate & RENDER_TEXTURE) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } - - OpenGLState current; - OpenGLState_constructDefault(current); - current.m_sort = OpenGLState::eSortFirst; - - // default renderstate settings - glLineStipple(current.m_linestipple_factor, current.m_linestipple_pattern); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - g_texcoordArray_enabled = false; - glDisableClientState(GL_COLOR_ARRAY); - g_colorArray_enabled = false; - glDisableClientState(GL_NORMAL_ARRAY); - g_normalArray_enabled = false; - glDisable(GL_BLEND); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glShadeModel(GL_FLAT); - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_ALPHA_TEST); - glDisable(GL_LINE_STIPPLE); - glDisable(GL_POLYGON_STIPPLE); - glDisable(GL_POLYGON_OFFSET_LINE); - - glBindTexture(GL_TEXTURE_2D, 0); - glColor4f(1, 1, 1, 1); - glDepthFunc(GL_LESS); - glAlphaFunc(GL_ALWAYS, 0); - glLineWidth(1); - glPointSize(1); - - glHint(GL_FOG_HINT, GL_NICEST); - glDisable(GL_FOG); - setFogState(OpenGLFogState()); - - GlobalOpenGL_debugAssertNoErrors(); - - debug_string("begin rendering"); - for (OpenGLStates::iterator i = g_state_sorted.begin(); i != g_state_sorted.end(); ++i) { - (*i).second->render(current, globalstate, viewer); - } - debug_string("end rendering"); -} - -void realise() -{ - if (--m_unrealised == 0) { - if (lightingSupported() && lightingEnabled()) { - if (useShaderLanguage()) { - g_bumpGLSL.create(); - g_depthFillGLSL.create(); - } else { - g_bumpARB.create(); - g_depthFillARB.create(); - } - } - - for (Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i) { - if (!(*i).value.empty()) { - (*i).value->realise(i->key); - } - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - for (Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i) { - if (!(*i).value.empty()) { - (*i).value->unrealise(); - } - } - if (GlobalOpenGL().contextValid && lightingSupported() && lightingEnabled()) { - if (useShaderLanguage()) { - g_bumpGLSL.destroy(); - g_depthFillGLSL.destroy(); - } else { - g_bumpARB.destroy(); - g_depthFillARB.destroy(); - } - } - } -} - -bool realised() -{ - return m_unrealised == 0; -} - - -bool lightingEnabled() const -{ - return m_lightingEnabled; -} - -bool lightingSupported() const -{ - return m_lightingSupported; -} - -bool useShaderLanguage() const -{ - return m_useShaderLanguage; -} - -void setLighting(bool supported, bool enabled) -{ - bool refresh = (m_lightingSupported && m_lightingEnabled) != (supported && enabled); - - if (refresh) { - unrealise(); - GlobalShaderSystem().setLightingEnabled(supported && enabled); - } - - m_lightingSupported = supported; - m_lightingEnabled = enabled; - - if (refresh) { - realise(); - } -} - -void extensionsInitialised() -{ - setLighting(GlobalOpenGL().GL_1_3() - && GlobalOpenGL().ARB_vertex_program() - && GlobalOpenGL().ARB_fragment_program() - && GlobalOpenGL().ARB_shader_objects() - && GlobalOpenGL().ARB_vertex_shader() - && GlobalOpenGL().ARB_fragment_shader() - && GlobalOpenGL().ARB_shading_language_100(), - m_lightingEnabled - ); - - if (!lightingSupported()) { - globalOutputStream() << "Lighting mode requires OpenGL features not supported by your graphics drivers:\n"; - if (!GlobalOpenGL().GL_1_3()) { - globalOutputStream() << " GL version 1.3 or better\n"; - } - if (!GlobalOpenGL().ARB_vertex_program()) { - globalOutputStream() << " GL_ARB_vertex_program\n"; - } - if (!GlobalOpenGL().ARB_fragment_program()) { - globalOutputStream() << " GL_ARB_fragment_program\n"; - } - if (!GlobalOpenGL().ARB_shader_objects()) { - globalOutputStream() << " GL_ARB_shader_objects\n"; - } - if (!GlobalOpenGL().ARB_vertex_shader()) { - globalOutputStream() << " GL_ARB_vertex_shader\n"; - } - if (!GlobalOpenGL().ARB_fragment_shader()) { - globalOutputStream() << " GL_ARB_fragment_shader\n"; - } - if (!GlobalOpenGL().ARB_shading_language_100()) { - globalOutputStream() << " GL_ARB_shading_language_100\n"; - } - } -} - -void setLightingEnabled(bool enabled) -{ - setLighting(m_lightingSupported, enabled); -} - -// light culling - -RendererLights m_lights; -bool m_lightsChanged; -typedef std::map LightLists; -LightLists m_lightLists; - -const LightList &attach(LightCullable &cullable) -{ - return (*m_lightLists.insert(LightLists::value_type(&cullable, LinearLightList(cullable, m_lights, - EvaluateChangedCaller( - *this)))).first).second; -} - -void detach(LightCullable &cullable) -{ - m_lightLists.erase(&cullable); -} - -void changed(LightCullable &cullable) -{ - LightLists::iterator i = m_lightLists.find(&cullable); - ASSERT_MESSAGE(i != m_lightLists.end(), "cullable not attached"); - (*i).second.lightsChanged(); -} - -void attach(RendererLight &light) -{ - ASSERT_MESSAGE(m_lights.find(&light) == m_lights.end(), "light could not be attached"); - m_lights.insert(&light); - changed(light); -} - -void detach(RendererLight &light) -{ - ASSERT_MESSAGE(m_lights.find(&light) != m_lights.end(), "light could not be detached"); - m_lights.erase(&light); - changed(light); -} - -void changed(RendererLight &light) -{ - m_lightsChanged = true; -} - -void evaluateChanged() -{ - if (m_lightsChanged) { - m_lightsChanged = false; - for (LightLists::iterator i = m_lightLists.begin(); i != m_lightLists.end(); ++i) { - (*i).second.lightsChanged(); - } - } -} - -typedef MemberCaller EvaluateChangedCaller; - -typedef std::set Renderables; -Renderables m_renderables; -mutable bool m_traverseRenderablesMutex; - -// renderables -void attachRenderable(const Renderable &renderable) -{ - ASSERT_MESSAGE(!m_traverseRenderablesMutex, "attaching renderable during traversal"); - ASSERT_MESSAGE(m_renderables.find(&renderable) == m_renderables.end(), "renderable could not be attached"); - m_renderables.insert(&renderable); -} - -void detachRenderable(const Renderable &renderable) -{ - ASSERT_MESSAGE(!m_traverseRenderablesMutex, "detaching renderable during traversal"); - ASSERT_MESSAGE(m_renderables.find(&renderable) != m_renderables.end(), "renderable could not be detached"); - m_renderables.erase(&renderable); -} - -void forEachRenderable(const RenderableCallback &callback) const -{ - ASSERT_MESSAGE(!m_traverseRenderablesMutex, "for-each during traversal"); - m_traverseRenderablesMutex = true; - for (Renderables::const_iterator i = m_renderables.begin(); i != m_renderables.end(); ++i) { - callback(*(*i)); - } - m_traverseRenderablesMutex = false; -} -}; - -static OpenGLShaderCache *g_ShaderCache; - -void ShaderCache_extensionsInitialised() -{ - g_ShaderCache->extensionsInitialised(); -} - -void ShaderCache_setBumpEnabled(bool enabled) -{ - g_ShaderCache->setLightingEnabled(enabled); -} - - -Vector3 g_DebugShaderColours[256]; -Shader *g_defaultPointLight = 0; - -void ShaderCache_Construct() -{ - g_ShaderCache = new OpenGLShaderCache; - GlobalTexturesCache().attach(*g_ShaderCache); - GlobalShaderSystem().attach(*g_ShaderCache); -} - -void ShaderCache_Destroy() -{ - GlobalShaderSystem().detach(*g_ShaderCache); - GlobalTexturesCache().detach(*g_ShaderCache); - delete g_ShaderCache; -} - -ShaderCache *GetShaderCache() -{ - return g_ShaderCache; -} - -inline void setTextureState(GLint ¤t, const GLint &texture, GLenum textureUnit) -{ - if (texture != current) { - glActiveTexture(textureUnit); - glClientActiveTexture(textureUnit); - glBindTexture(GL_TEXTURE_2D, texture); - GlobalOpenGL_debugAssertNoErrors(); - current = texture; - } -} - -inline void setTextureState(GLint ¤t, const GLint &texture) -{ - if (texture != current) { - glBindTexture(GL_TEXTURE_2D, texture); - GlobalOpenGL_debugAssertNoErrors(); - current = texture; - } -} - -inline void setState(unsigned int state, unsigned int delta, unsigned int flag, GLenum glflag) -{ - if (delta & state & flag) { - glEnable(glflag); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & flag) { - glDisable(glflag); - GlobalOpenGL_debugAssertNoErrors(); - } -} - -void OpenGLState_apply(const OpenGLState &self, OpenGLState ¤t, unsigned int globalstate) -{ - debug_int("sort", int(self.m_sort)); - debug_int("texture", self.m_texture); - debug_int("state", self.m_state); - debug_int("address", int(std::size_t(&self))); - - count_state(); - - if (self.m_state & RENDER_OVERRIDE) { - globalstate |= RENDER_FILL | RENDER_DEPTHWRITE; - } - - const unsigned int state = self.m_state & globalstate; - const unsigned int delta = state ^current.m_state; - - GlobalOpenGL_debugAssertNoErrors(); - - GLProgram *program = (state & RENDER_PROGRAM) != 0 ? self.m_program : 0; - - if (program != current.m_program) { - if (current.m_program != 0) { - current.m_program->disable(); - glColor4fv(vector4_to_array(current.m_colour)); - debug_colour("cleaning program"); - } - - current.m_program = program; - - if (current.m_program != 0) { - current.m_program->enable(); - } - } - - if (delta & state & RENDER_FILL) { - //qglPolygonMode (GL_BACK, GL_LINE); - //qglPolygonMode (GL_FRONT, GL_FILL); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_FILL) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_OFFSETLINE, GL_POLYGON_OFFSET_LINE); - - if (delta & state & RENDER_LIGHTING) { - glEnable(GL_LIGHTING); - glEnable(GL_COLOR_MATERIAL); - glEnable(GL_RESCALE_NORMAL); - glEnableClientState(GL_NORMAL_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - g_normalArray_enabled = true; - } else if (delta & ~state & RENDER_LIGHTING) { - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_RESCALE_NORMAL); - glDisableClientState(GL_NORMAL_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - g_normalArray_enabled = false; - } - - if (delta & state & RENDER_TEXTURE) { - GlobalOpenGL_debugAssertNoErrors(); - - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - } - - glEnable(GL_TEXTURE_2D); - - glColor4f(1, 1, 1, self.m_colour[3]); - debug_colour("setting texture"); - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - g_texcoordArray_enabled = true; - } else if (delta & ~state & RENDER_TEXTURE) { - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - } - - glDisable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - g_texcoordArray_enabled = false; - } - - if (delta & state & RENDER_BLEND) { - // FIXME: some .TGA are buggy, have a completely empty alpha channel - // if such brushes are rendered in this loop they would be totally transparent with GL_MODULATE - // so I decided using GL_DECAL instead - // if an empty-alpha-channel or nearly-empty texture is used. It will be blank-transparent. - // this could get better if you can get glTexEnviv (GL_TEXTURE_ENV, to work .. patches are welcome - glEnable(GL_BLEND); - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - } - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_BLEND) { - glDisable(GL_BLEND); - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - } - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_CULLFACE, GL_CULL_FACE); - - if (delta & state & RENDER_SMOOTH) { - glShadeModel(GL_SMOOTH); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_SMOOTH) { - glShadeModel(GL_FLAT); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_SCALED, GL_RESCALE_NORMAL); // not GL_RESCALE_NORMAL - setState(state, delta, RENDER_DEPTHTEST, GL_DEPTH_TEST); - - if (delta & state & RENDER_DEPTHWRITE) { - glDepthMask(GL_TRUE); - - #if DEBUG_RENDER - GLboolean depthEnabled; - glGetBooleanv( GL_DEPTH_WRITEMASK, &depthEnabled ); - ASSERT_MESSAGE( depthEnabled, "failed to set depth buffer mask bit" ); - #endif - debug_string("enabled depth-buffer writing"); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_DEPTHWRITE) { - glDepthMask(GL_FALSE); - - #if DEBUG_RENDER - GLboolean depthEnabled; - glGetBooleanv( GL_DEPTH_WRITEMASK, &depthEnabled ); - ASSERT_MESSAGE( !depthEnabled, "failed to set depth buffer mask bit" ); - #endif - debug_string("disabled depth-buffer writing"); - - GlobalOpenGL_debugAssertNoErrors(); - } - - if (delta & state & RENDER_COLOURWRITE) { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - GlobalOpenGL_debugAssertNoErrors(); - } else if (delta & ~state & RENDER_COLOURWRITE) { - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_ALPHATEST, GL_ALPHA_TEST); - - if (delta & state & RENDER_COLOURARRAY) { - glEnableClientState(GL_COLOR_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - debug_colour("enabling color_array"); - g_colorArray_enabled = true; - } else if (delta & ~state & RENDER_COLOURARRAY) { - glDisableClientState(GL_COLOR_ARRAY); - glColor4fv(vector4_to_array(self.m_colour)); - debug_colour("cleaning color_array"); - GlobalOpenGL_debugAssertNoErrors(); - g_colorArray_enabled = false; - } - - if (delta & ~state & RENDER_COLOURCHANGE) { - glColor4fv(vector4_to_array(self.m_colour)); - GlobalOpenGL_debugAssertNoErrors(); - } - - setState(state, delta, RENDER_LINESTIPPLE, GL_LINE_STIPPLE); - setState(state, delta, RENDER_LINESMOOTH, GL_LINE_SMOOTH); - setState(state, delta, RENDER_POLYGONSTIPPLE, GL_POLYGON_STIPPLE); - setState(state, delta, RENDER_POLYGONSMOOTH, GL_POLYGON_SMOOTH); - setState(state, delta, RENDER_FOG, GL_FOG); - - if ((state & RENDER_FOG) != 0) { - setFogState(self.m_fog); - GlobalOpenGL_debugAssertNoErrors(); - current.m_fog = self.m_fog; - } - - if (state & RENDER_DEPTHTEST && self.m_depthfunc != current.m_depthfunc) { - glDepthFunc(self.m_depthfunc); - GlobalOpenGL_debugAssertNoErrors(); - current.m_depthfunc = self.m_depthfunc; - } - - if (state & RENDER_POLYOFS) { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-0.05, -25 * self.m_polygonoffset); - } else { - glDisable(GL_POLYGON_OFFSET_FILL); - } - - if (state & RENDER_LINESTIPPLE - && (self.m_linestipple_factor != current.m_linestipple_factor - || self.m_linestipple_pattern != current.m_linestipple_pattern)) { - glLineStipple(self.m_linestipple_factor, self.m_linestipple_pattern); - GlobalOpenGL_debugAssertNoErrors(); - current.m_linestipple_factor = self.m_linestipple_factor; - current.m_linestipple_pattern = self.m_linestipple_pattern; - } - - if (state & RENDER_ALPHATEST - && (self.m_alphafunc != current.m_alphafunc - || self.m_alpharef != current.m_alpharef)) { - glAlphaFunc(self.m_alphafunc, self.m_alpharef); - GlobalOpenGL_debugAssertNoErrors(); - current.m_alphafunc = self.m_alphafunc; - current.m_alpharef = self.m_alpharef; - } - - GLint texture0 = 0; - GLint texture1 = 0; - GLint texture2 = 0; - GLint texture3 = 0; - GLint texture4 = 0; - GLint texture5 = 0; - GLint texture6 = 0; - GLint texture7 = 0; - - texture0 = self.m_texture; - texture1 = self.m_texture1; - texture2 = self.m_texture2; - texture3 = self.m_texture3; - texture4 = self.m_texture4; - texture5 = self.m_texture5; - texture6 = self.m_texture6; - texture7 = self.m_texture7; - - if (GlobalOpenGL().GL_1_3()) { - setTextureState(current.m_texture, texture0, GL_TEXTURE0); - setTextureState(current.m_texture1, texture1, GL_TEXTURE1); - setTextureState(current.m_texture2, texture2, GL_TEXTURE2); - setTextureState(current.m_texture3, texture3, GL_TEXTURE3); - setTextureState(current.m_texture4, texture4, GL_TEXTURE4); - setTextureState(current.m_texture5, texture5, GL_TEXTURE5); - setTextureState(current.m_texture6, texture6, GL_TEXTURE6); - setTextureState(current.m_texture7, texture7, GL_TEXTURE7); - } else { - setTextureState(current.m_texture, texture0); - } - - if (state & RENDER_TEXTURE && self.m_colour[3] != current.m_colour[3]) { - debug_colour("setting alpha"); - glColor4f(1, 1, 1, self.m_colour[3]); - GlobalOpenGL_debugAssertNoErrors(); - } - - if (!(state & RENDER_TEXTURE) - && (self.m_colour[0] != current.m_colour[0] - || self.m_colour[1] != current.m_colour[1] - || self.m_colour[2] != current.m_colour[2] - || self.m_colour[3] != current.m_colour[3])) { - glColor4fv(vector4_to_array(self.m_colour)); - debug_colour("setting non-texture"); - GlobalOpenGL_debugAssertNoErrors(); - } - current.m_colour = self.m_colour; - - if (state & RENDER_BLEND - && (self.m_blend_src != current.m_blend_src || self.m_blend_dst != current.m_blend_dst)) { - glBlendFunc(self.m_blend_src, self.m_blend_dst); - GlobalOpenGL_debugAssertNoErrors(); - current.m_blend_src = self.m_blend_src; - current.m_blend_dst = self.m_blend_dst; - } - - if (!(state & RENDER_FILL) - && self.m_linewidth != current.m_linewidth) { - glLineWidth(self.m_linewidth); - GlobalOpenGL_debugAssertNoErrors(); - current.m_linewidth = self.m_linewidth; - } - - if (!(state & RENDER_FILL) - && self.m_pointsize != current.m_pointsize) { - glPointSize(self.m_pointsize); - GlobalOpenGL_debugAssertNoErrors(); - current.m_pointsize = self.m_pointsize; - } - - current.m_state = state; - - GlobalOpenGL_debugAssertNoErrors(); -} - -void Renderables_flush(OpenGLStateBucket::Renderables &renderables, OpenGLState ¤t, unsigned int globalstate, - const Vector3 &viewer) -{ - const Matrix4 *transform = 0; - glPushMatrix(); - for (OpenGLStateBucket::Renderables::const_iterator i = renderables.begin(); i != renderables.end(); ++i) { - //qglLoadMatrixf(i->m_transform); - if (!transform || (transform != (*i).m_transform && !matrix4_affine_equal(*transform, *(*i).m_transform))) { - count_transform(); - transform = (*i).m_transform; - glPopMatrix(); - glPushMatrix(); - glMultMatrixf(reinterpret_cast( transform )); - glFrontFace( - ((current.m_state & RENDER_CULLFACE) != 0 && matrix4_handedness(*transform) == MATRIX4_RIGHTHANDED) - ? GL_CW : GL_CCW); - } - - count_prim(); - - if (current.m_program != 0 && (*i).m_light != 0) { - const IShader &lightShader = static_cast((*i).m_light->getShader())->getShader(); - if (lightShader.firstLayer() != 0) { - GLuint attenuation_xy = lightShader.firstLayer()->texture()->texture_number; - GLuint attenuation_z = lightShader.lightFalloffImage() != 0 - ? lightShader.lightFalloffImage()->texture_number - : static_cast( g_defaultPointLight )->getShader().lightFalloffImage()->texture_number; - - setTextureState(current.m_texture3, attenuation_xy, GL_TEXTURE3); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, attenuation_xy); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - - setTextureState(current.m_texture4, attenuation_z, GL_TEXTURE4); - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, attenuation_z); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - - AABB lightBounds((*i).m_light->aabb()); - - Matrix4 world2light(g_matrix4_identity); - - if ((*i).m_light->isProjected()) { - world2light = (*i).m_light->projection(); - matrix4_multiply_by_matrix4(world2light, matrix4_transposed((*i).m_light->rotation())); - matrix4_translate_by_vec3(world2light, vector3_negated(lightBounds.origin)); // world->lightBounds - } - if (!(*i).m_light->isProjected()) { - matrix4_translate_by_vec3(world2light, Vector3(0.5f, 0.5f, 0.5f)); - matrix4_scale_by_vec3(world2light, Vector3(0.5f, 0.5f, 0.5f)); - matrix4_scale_by_vec3(world2light, - Vector3(1.0f / lightBounds.extents.x(), 1.0f / lightBounds.extents.y(), - 1.0f / lightBounds.extents.z())); - matrix4_multiply_by_matrix4(world2light, matrix4_transposed((*i).m_light->rotation())); - matrix4_translate_by_vec3(world2light, vector3_negated(lightBounds.origin)); // world->lightBounds - } - - current.m_program->setParameters(viewer, *(*i).m_transform, lightBounds.origin + (*i).m_light->offset(), - (*i).m_light->colour(), world2light); - debug_string("set lightBounds parameters"); - } - } - - (*i).m_renderable->render(current.m_state); - } - glPopMatrix(); - renderables.clear(); -} - -void OpenGLStateBucket::render(OpenGLState ¤t, unsigned int globalstate, const Vector3 &viewer) -{ - if ((globalstate & m_state.m_state & RENDER_SCREEN) != 0) { - OpenGLState_apply(m_state, current, globalstate); - debug_colour("screen fill"); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(reinterpret_cast( &g_matrix4_identity )); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(reinterpret_cast( &g_matrix4_identity )); - - glBegin(GL_QUADS); - glVertex3f(-1, -1, 0); - glVertex3f(1, -1, 0); - glVertex3f(1, 1, 0); - glVertex3f(-1, 1, 0); - glEnd(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } else if (!m_renderables.empty()) { - OpenGLState_apply(m_state, current, globalstate); - Renderables_flush(m_renderables, current, globalstate, viewer); - } -} - - -class OpenGLStateMap : public OpenGLStateLibrary { -typedef std::map States; -States m_states; -public: -~OpenGLStateMap() -{ - ASSERT_MESSAGE(m_states.empty(), "OpenGLStateMap::~OpenGLStateMap: not empty"); -} - -typedef States::iterator iterator; - -iterator begin() -{ - return m_states.begin(); -} - -iterator end() -{ - return m_states.end(); -} - -void getDefaultState(OpenGLState &state) const -{ - OpenGLState_constructDefault(state); -} - -void insert(const char *name, const OpenGLState &state) -{ - bool inserted = m_states.insert(States::value_type(name, state)).second; - ASSERT_MESSAGE(inserted, "OpenGLStateMap::insert: " << name << " already exists"); -} - -void erase(const char *name) -{ - std::size_t count = m_states.erase(name); - ASSERT_MESSAGE(count == 1, "OpenGLStateMap::erase: " << name << " does not exist"); -} - -iterator find(const char *name) -{ - return m_states.find(name); -} -}; - -OpenGLStateMap *g_openglStates = 0; - -inline GLenum convertBlendFactor(BlendFactor factor) -{ - switch (factor) { - case BLEND_ZERO: - return GL_ZERO; - case BLEND_ONE: - return GL_ONE; - case BLEND_SRC_COLOUR: - return GL_SRC_COLOR; - case BLEND_ONE_MINUS_SRC_COLOUR: - return GL_ONE_MINUS_SRC_COLOR; - case BLEND_SRC_ALPHA: - return GL_SRC_ALPHA; - case BLEND_ONE_MINUS_SRC_ALPHA: - return GL_ONE_MINUS_SRC_ALPHA; - case BLEND_DST_COLOUR: - return GL_DST_COLOR; - case BLEND_ONE_MINUS_DST_COLOUR: - return GL_ONE_MINUS_DST_COLOR; - case BLEND_DST_ALPHA: - return GL_DST_ALPHA; - case BLEND_ONE_MINUS_DST_ALPHA: - return GL_ONE_MINUS_DST_ALPHA; - case BLEND_SRC_ALPHA_SATURATE: - return GL_SRC_ALPHA_SATURATE; - } - return GL_ZERO; -} - -/// \todo Define special-case shaders in a data file. -void OpenGLShader::construct(const char *name) -{ - OpenGLState &state = appendDefaultPass(); - switch (name[0]) { - case '(': - sscanf(name, "(%g %g %g)", &state.m_colour[0], &state.m_colour[1], &state.m_colour[2]); - state.m_colour[3] = 1.0f; - state.m_state = RENDER_FILL | RENDER_LIGHTING | RENDER_DEPTHTEST | RENDER_CULLFACE | RENDER_COLOURWRITE | - RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - break; - - case '[': - sscanf(name, "[%g %g %g]", &state.m_colour[0], &state.m_colour[1], &state.m_colour[2]); - state.m_colour[3] = 0.5f; - state.m_state = RENDER_FILL | RENDER_LIGHTING | RENDER_DEPTHTEST | RENDER_CULLFACE | RENDER_COLOURWRITE | - RENDER_DEPTHWRITE | RENDER_BLEND; - state.m_sort = OpenGLState::eSortTranslucent; - break; - - case '<': - sscanf(name, "<%g %g %g>", &state.m_colour[0], &state.m_colour[1], &state.m_colour[2]); - state.m_colour[3] = 1; - state.m_state = RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - state.m_depthfunc = GL_LESS; - state.m_linewidth = 1; - state.m_pointsize = 1; - break; - - case '$': { - OpenGLStateMap::iterator i = g_openglStates->find(name); - if (i != g_openglStates->end()) { - state = (*i).second; - break; - } - } - if (string_equal(name + 1, "POINT")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortControlFirst; - state.m_pointsize = 4; - } else if (string_equal(name + 1, "SELPOINT")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortControlFirst + 1; - state.m_pointsize = 4; - } else if (string_equal(name + 1, "BIGPOINT")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortControlFirst; - state.m_pointsize = 6; - } else if (string_equal(name + 1, "PIVOT")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHTEST | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortGUI1; - state.m_linewidth = 2; - state.m_depthfunc = GL_LEQUAL; - - OpenGLState &hiddenLine = appendDefaultPass(); - hiddenLine.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHTEST | RENDER_LINESTIPPLE; - hiddenLine.m_sort = OpenGLState::eSortGUI0; - hiddenLine.m_linewidth = 2; - hiddenLine.m_depthfunc = GL_GREATER; - } else if (string_equal(name + 1, "LATTICE")) { - state.m_colour[0] = 1; - state.m_colour[1] = 0.5; - state.m_colour[2] = 0; - state.m_colour[3] = 1; - state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortControlFirst; - } else if (string_equal(name + 1, "WIREFRAME")) { - state.m_state = RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - } else if (string_equal(name + 1, "CAM_HIGHLIGHT")) { - state.m_colour[0] = 1; - state.m_colour[1] = 0; - state.m_colour[2] = 0; - state.m_colour[3] = 0.5f; - state.m_state = RENDER_FILL | RENDER_DEPTHTEST | RENDER_CULLFACE | RENDER_BLEND | RENDER_COLOURWRITE | - RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortHighlight; - state.m_depthfunc = GL_LEQUAL; - } else if (string_equal(name + 1, "CAM_OVERLAY")) { -#if 0 - state.m_state = RENDER_CULLFACE | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortOverlayFirst; -#else - state.m_state = - RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_OFFSETLINE; - state.m_sort = OpenGLState::eSortOverlayFirst + 1; - state.m_depthfunc = GL_LEQUAL; - - OpenGLState &hiddenLine = appendDefaultPass(); - hiddenLine.m_colour[0] = 0.75; - hiddenLine.m_colour[1] = 0.75; - hiddenLine.m_colour[2] = 0.75; - hiddenLine.m_colour[3] = 1; - hiddenLine.m_state = RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_OFFSETLINE | - RENDER_LINESTIPPLE; - hiddenLine.m_sort = OpenGLState::eSortOverlayFirst; - hiddenLine.m_depthfunc = GL_GREATER; - hiddenLine.m_linestipple_factor = 2; -#endif - } else if (string_equal(name + 1, "XY_OVERLAY")) { - state.m_colour[0] = g_xywindow_globals.color_selbrushes[0]; - state.m_colour[1] = g_xywindow_globals.color_selbrushes[1]; - state.m_colour[2] = g_xywindow_globals.color_selbrushes[2]; - state.m_colour[3] = 1; - state.m_state = RENDER_COLOURWRITE | RENDER_LINESTIPPLE; - state.m_sort = OpenGLState::eSortOverlayFirst; - state.m_linewidth = 2; - state.m_linestipple_factor = 3; - } else if (string_equal(name + 1, "DEBUG_CLIPPED")) { - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortLast; - } else if (string_equal(name + 1, "POINTFILE")) { - state.m_colour[0] = 1; - state.m_colour[1] = 0; - state.m_colour[2] = 0; - state.m_colour[3] = 1; - state.m_state = RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - state.m_linewidth = 4; - } else if (string_equal(name + 1, "LIGHT_SPHERE")) { - state.m_colour[0] = .15f * .95f; - state.m_colour[1] = .15f * .95f; - state.m_colour[2] = .15f * .95f; - state.m_colour[3] = 1; - state.m_state = RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_BLEND | RENDER_FILL | RENDER_COLOURWRITE | - RENDER_DEPTHWRITE; - state.m_blend_src = GL_ONE; - state.m_blend_dst = GL_ONE; - state.m_sort = OpenGLState::eSortTranslucent; - } else if (string_equal(name + 1, "Q3MAP2_LIGHT_SPHERE")) { - state.m_colour[0] = .05f; - state.m_colour[1] = .05f; - state.m_colour[2] = .05f; - state.m_colour[3] = 1; - state.m_state = RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_BLEND | RENDER_FILL; - state.m_blend_src = GL_ONE; - state.m_blend_dst = GL_ONE; - state.m_sort = OpenGLState::eSortTranslucent; - } else if (string_equal(name + 1, "WIRE_OVERLAY")) { -#if 0 - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | RENDER_OVERRIDE; - state.m_sort = OpenGLState::eSortOverlayFirst; -#else - state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | - RENDER_OVERRIDE; - state.m_sort = OpenGLState::eSortGUI1; - state.m_depthfunc = GL_LEQUAL; - - OpenGLState &hiddenLine = appendDefaultPass(); - hiddenLine.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | - RENDER_OVERRIDE | RENDER_LINESTIPPLE; - hiddenLine.m_sort = OpenGLState::eSortGUI0; - hiddenLine.m_depthfunc = GL_GREATER; -#endif - } else if (string_equal(name + 1, "FLATSHADE_OVERLAY")) { - state.m_state = RENDER_CULLFACE | RENDER_LIGHTING | RENDER_SMOOTH | RENDER_SCALED | RENDER_COLOURARRAY | - RENDER_FILL | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | - RENDER_OVERRIDE; - state.m_sort = OpenGLState::eSortGUI1; - state.m_depthfunc = GL_LEQUAL; - - OpenGLState &hiddenLine = appendDefaultPass(); - hiddenLine.m_state = - RENDER_CULLFACE | RENDER_LIGHTING | RENDER_SMOOTH | RENDER_SCALED | RENDER_COLOURARRAY | - RENDER_FILL | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | RENDER_OVERRIDE | - RENDER_POLYGONSTIPPLE; - hiddenLine.m_sort = OpenGLState::eSortGUI0; - hiddenLine.m_depthfunc = GL_GREATER; - } else if (string_equal(name + 1, "CLIPPER_OVERLAY")) { - state.m_colour[0] = g_xywindow_globals.color_clipper[0]; - state.m_colour[1] = g_xywindow_globals.color_clipper[1]; - state.m_colour[2] = g_xywindow_globals.color_clipper[2]; - state.m_colour[3] = 1; - state.m_state = - RENDER_CULLFACE | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_FILL | RENDER_POLYGONSTIPPLE; - state.m_sort = OpenGLState::eSortOverlayFirst; - } else if (string_equal(name + 1, "OVERBRIGHT")) { - const float lightScale = 2; - state.m_colour[0] = lightScale * 0.5f; - state.m_colour[1] = lightScale * 0.5f; - state.m_colour[2] = lightScale * 0.5f; - state.m_colour[3] = 0.5; - state.m_state = RENDER_FILL | RENDER_BLEND | RENDER_COLOURWRITE | RENDER_SCREEN; - state.m_sort = OpenGLState::eSortOverbrighten; - state.m_blend_src = GL_DST_COLOR; - state.m_blend_dst = GL_SRC_COLOR; - } else { - // default to something recognisable.. =) - ERROR_MESSAGE("hardcoded renderstate not found"); - state.m_colour[0] = 1; - state.m_colour[1] = 0; - state.m_colour[2] = 1; - state.m_colour[3] = 1; - state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFirst; - } - break; - default: - // construction from IShader - m_shader = QERApp_Shader_ForName(name); - - if (g_ShaderCache->lightingSupported() && g_ShaderCache->lightingEnabled() && m_shader->getBump() != 0 && - m_shader->getBump()->texture_number != 0) { // is a bump shader - state.m_state = RENDER_FILL | RENDER_CULLFACE | RENDER_TEXTURE | RENDER_DEPTHTEST | RENDER_DEPTHWRITE | - RENDER_COLOURWRITE | RENDER_PROGRAM; - state.m_colour[0] = 0; - state.m_colour[1] = 0; - state.m_colour[2] = 0; - state.m_colour[3] = 1; - state.m_sort = OpenGLState::eSortOpaque; - - if (g_ShaderCache->useShaderLanguage()) { - state.m_program = &g_depthFillGLSL; - } else { - state.m_program = &g_depthFillARB; - } - - OpenGLState &bumpPass = appendDefaultPass(); - bumpPass.m_texture = m_shader->getDiffuse()->texture_number; - bumpPass.m_texture1 = m_shader->getBump()->texture_number; - bumpPass.m_texture2 = m_shader->getSpecular()->texture_number; - - bumpPass.m_state = - RENDER_BLEND | RENDER_FILL | RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | - RENDER_SMOOTH | RENDER_BUMP | RENDER_PROGRAM; - - if (g_ShaderCache->useShaderLanguage()) { - bumpPass.m_state |= RENDER_LIGHTING; - bumpPass.m_program = &g_bumpGLSL; - } else { - bumpPass.m_program = &g_bumpARB; - } - - bumpPass.m_depthfunc = GL_LEQUAL; - bumpPass.m_sort = OpenGLState::eSortMultiFirst; - bumpPass.m_blend_src = GL_ONE; - bumpPass.m_blend_dst = GL_ONE; - } else { - state.m_texture = m_shader->getTexture()->texture_number; - - state.m_state = RENDER_FILL | RENDER_TEXTURE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_LIGHTING | - RENDER_SMOOTH; - if ((m_shader->getFlags() & QER_CULL) != 0) { - if (m_shader->getCull() == IShader::eCullBack) { - state.m_state |= RENDER_CULLFACE; - } - } else { - state.m_state |= RENDER_CULLFACE; - } - - if ((m_shader->getFlags() & QER_POLYOFS) != 0) { - state.m_polygonoffset = m_shader->getPolygonOffset(); - state.m_state |= RENDER_POLYOFS; - } - - if ((m_shader->getFlags() & QER_ALPHATEST) != 0) { - state.m_state |= RENDER_ALPHATEST; - IShader::EAlphaFunc alphafunc; - m_shader->getAlphaFunc(&alphafunc, &state.m_alpharef); - switch (alphafunc) { - case IShader::eAlways: - state.m_alphafunc = GL_ALWAYS; - break; - case IShader::eEqual: - state.m_alphafunc = GL_EQUAL; - break; - case IShader::eLess: - state.m_alphafunc = GL_LESS; - break; - case IShader::eGreater: - state.m_alphafunc = GL_GREATER; - break; - case IShader::eLEqual: - state.m_alphafunc = GL_LEQUAL; - break; - case IShader::eGEqual: - state.m_alphafunc = GL_GEQUAL; - break; - } - } - reinterpret_cast( state.m_colour ) = m_shader->getTexture()->color; - state.m_colour[3] = 1.0f; - - if ((m_shader->getFlags() & QER_TRANS) != 0) { - state.m_state |= RENDER_BLEND; - state.m_colour[3] = m_shader->getTrans(); - state.m_sort = OpenGLState::eSortTranslucent; - BlendFunc blendFunc = m_shader->getBlendFunc(); - state.m_blend_src = convertBlendFactor(blendFunc.m_src); - state.m_blend_dst = convertBlendFactor(blendFunc.m_dst); - if (state.m_blend_src == GL_SRC_ALPHA || state.m_blend_dst == GL_SRC_ALPHA) { - state.m_state |= RENDER_DEPTHWRITE; - } - } else { - state.m_state |= RENDER_DEPTHWRITE; - state.m_sort = OpenGLState::eSortFullbright; - } - } - } -} - - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class OpenGLStateLibraryAPI { -OpenGLStateMap m_stateMap; -public: -typedef OpenGLStateLibrary Type; - -STRING_CONSTANT(Name, "*"); - -OpenGLStateLibraryAPI() -{ - g_openglStates = &m_stateMap; -} - -~OpenGLStateLibraryAPI() -{ - g_openglStates = 0; -} - -OpenGLStateLibrary *getTable() -{ - return &m_stateMap; -} -}; - -typedef SingletonModule OpenGLStateLibraryModule; -typedef Static StaticOpenGLStateLibraryModule; -StaticRegisterModule staticRegisterOpenGLStateLibrary(StaticOpenGLStateLibraryModule::instance()); - -class ShaderCacheDependencies - : public GlobalShadersModuleRef, public GlobalTexturesModuleRef, public GlobalOpenGLStateLibraryModuleRef { -public: -ShaderCacheDependencies() : - GlobalShadersModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("shaders")) -{ -} -}; - -class ShaderCacheAPI { -ShaderCache *m_shaderCache; -public: -typedef ShaderCache Type; - -STRING_CONSTANT(Name, "*"); - -ShaderCacheAPI() -{ - ShaderCache_Construct(); - - m_shaderCache = GetShaderCache(); -} - -~ShaderCacheAPI() -{ - ShaderCache_Destroy(); -} - -ShaderCache *getTable() -{ - return m_shaderCache; -} -}; - -typedef SingletonModule ShaderCacheModule; -typedef Static StaticShaderCacheModule; -StaticRegisterModule staticRegisterShaderCache(StaticShaderCacheModule::instance()); diff --git a/src/renderstate.h b/src/renderstate.h deleted file mode 100644 index f4ba496..0000000 --- a/src/renderstate.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_RENDERSTATE_H ) -#define INCLUDED_RENDERSTATE_H - -void ShaderCache_setBumpEnabled(bool enabled); - -void ShaderCache_extensionsInitialised(); - -#endif diff --git a/src/resource.h b/src/resource.h deleted file mode 100644 index 506ba8a..0000000 --- a/src/resource.h +++ /dev/null @@ -1,18 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by worldspawn.rc -// -#define IDI_WORLDSPAWN 101 -#define IDR_MENU1 102 -#define IDD_DIALOG1 103 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 104 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/scenegraph.cpp b/src/scenegraph.cpp deleted file mode 100644 index 851f091..0000000 --- a/src/scenegraph.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "scenegraph.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#include "string/string.h" -#include "signal/signal.h" -#include "scenelib.h" -#include "instancelib.h" -#include "treemodel.h" - -template -class TypeIdMap { -typedef const char *TypeName; -typedef TypeName TypeNames[SIZE]; -TypeNames m_typeNames; -TypeName *m_typeNamesEnd; - -public: -TypeIdMap() : m_typeNamesEnd(m_typeNames) -{ -} - -TypeId getTypeId(const char *name) -{ - TypeName *i = std::find_if(m_typeNames, m_typeNamesEnd, [&](const char *other) { - return string_equal(name, other); - }); - if (i == m_typeNamesEnd) { - ASSERT_MESSAGE(m_typeNamesEnd != m_typeNames + SIZE, - "reached maximum number of type names supported (" << Unsigned(SIZE) << ")"); - *m_typeNamesEnd++ = name; - } - return i - m_typeNames; -} -}; - -class CompiledGraph : public scene::Graph, public scene::Instantiable::Observer { -typedef std::map InstanceMap; - -InstanceMap m_instances; -scene::Instantiable::Observer *m_observer; -Signal0 m_boundsChanged; -scene::Path m_rootpath; -Signal0 m_sceneChangedCallbacks; - -TypeIdMap m_nodeTypeIds; -TypeIdMap m_instanceTypeIds; - -public: - -CompiledGraph(scene::Instantiable::Observer *observer) - : m_observer(observer) -{ -} - -void addSceneChangedCallback(const SignalHandler &handler) -{ - m_sceneChangedCallbacks.connectLast(handler); -} - -void sceneChanged() -{ - m_sceneChangedCallbacks(); -} - -scene::Node &root() -{ - ASSERT_MESSAGE(!m_rootpath.empty(), "scenegraph root does not exist"); - return m_rootpath.top(); -} - -void insert_root(scene::Node &root) -{ - //globalOutputStream() << "insert_root\n"; - - ASSERT_MESSAGE(m_rootpath.empty(), "scenegraph root already exists"); - - root.IncRef(); - - Node_traverseSubgraph(root, InstanceSubgraphWalker(this, scene::Path(), 0)); - - m_rootpath.push(makeReference(root)); -} - -void erase_root() -{ - //globalOutputStream() << "erase_root\n"; - - ASSERT_MESSAGE(!m_rootpath.empty(), "scenegraph root does not exist"); - - scene::Node &root = m_rootpath.top(); - - m_rootpath.pop(); - - Node_traverseSubgraph(root, UninstanceSubgraphWalker(this, scene::Path())); - - root.DecRef(); -} - -void boundsChanged() -{ - m_boundsChanged(); -} - -void traverse(const Walker &walker) -{ - traverse_subgraph(walker, m_instances.begin()); -} - -void traverse_subgraph(const Walker &walker, const scene::Path &start) -{ - if (!m_instances.empty()) { - traverse_subgraph(walker, m_instances.find(PathConstReference(start))); - } -} - -scene::Instance *find(const scene::Path &path) -{ - InstanceMap::iterator i = m_instances.find(PathConstReference(path)); - if (i == m_instances.end()) { - return 0; - } - return (*i).second; -} - -void insert(scene::Instance *instance) -{ - m_instances.insert(InstanceMap::value_type(PathConstReference(instance->path()), instance)); - - m_observer->insert(instance); -} - -void erase(scene::Instance *instance) -{ - m_observer->erase(instance); - - m_instances.erase(PathConstReference(instance->path())); -} - -SignalHandlerId addBoundsChangedCallback(const SignalHandler &boundsChanged) -{ - return m_boundsChanged.connectLast(boundsChanged); -} - -void removeBoundsChangedCallback(SignalHandlerId id) -{ - m_boundsChanged.disconnect(id); -} - -TypeId getNodeTypeId(const char *name) -{ - return m_nodeTypeIds.getTypeId(name); -} - -TypeId getInstanceTypeId(const char *name) -{ - return m_instanceTypeIds.getTypeId(name); -} - -private: - -bool pre(const Walker &walker, const InstanceMap::iterator &i) -{ - return walker.pre(i->first, *i->second); -} - -void post(const Walker &walker, const InstanceMap::iterator &i) -{ - walker.post(i->first, *i->second); -} - -void traverse_subgraph(const Walker &walker, InstanceMap::iterator i) -{ - Stack stack; - if (i != m_instances.end()) { - const std::size_t startSize = (*i).first.get().size(); - do { - if (i != m_instances.end() - && stack.size() < ((*i).first.get().size() - startSize + 1)) { - stack.push(i); - ++i; - if (!pre(walker, stack.top())) { - // skip subgraph - while (i != m_instances.end() - && stack.size() < ((*i).first.get().size() - startSize + 1)) { - ++i; - } - } - } else { - post(walker, stack.top()); - stack.pop(); - } - } while (!stack.empty()); - } -} -}; - -namespace { -CompiledGraph *g_sceneGraph; -GraphTreeModel *g_tree_model; -} - -GraphTreeModel *scene_graph_get_tree_model() -{ - return g_tree_model; -} - - -class SceneGraphObserver : public scene::Instantiable::Observer { -public: -void insert(scene::Instance *instance) -{ - g_sceneGraph->sceneChanged(); - graph_tree_model_insert(g_tree_model, *instance); -} - -void erase(scene::Instance *instance) -{ - g_sceneGraph->sceneChanged(); - graph_tree_model_erase(g_tree_model, *instance); -} -}; - -SceneGraphObserver g_SceneGraphObserver; - -void SceneGraph_Construct() -{ - g_tree_model = graph_tree_model_new(); - - g_sceneGraph = new CompiledGraph(&g_SceneGraphObserver); -} - -void SceneGraph_Destroy() -{ - delete g_sceneGraph; - - graph_tree_model_delete(g_tree_model); -} - - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class SceneGraphAPI { -scene::Graph *m_scenegraph; -public: -typedef scene::Graph Type; - -STRING_CONSTANT(Name, "*"); - -SceneGraphAPI() -{ - SceneGraph_Construct(); - - m_scenegraph = g_sceneGraph; -} - -~SceneGraphAPI() -{ - SceneGraph_Destroy(); -} - -scene::Graph *getTable() -{ - return m_scenegraph; -} -}; - -typedef SingletonModule SceneGraphModule; -typedef Static StaticSceneGraphModule; -StaticRegisterModule staticRegisterSceneGraph(StaticSceneGraphModule::instance()); diff --git a/src/scenegraph.h b/src/scenegraph.h deleted file mode 100644 index 48fb08b..0000000 --- a/src/scenegraph.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDEDE_SCENEGRAPH_H ) -#define INCLUDED_SCENEGRAPH_H - -#endif diff --git a/src/select.cpp b/src/select.cpp deleted file mode 100644 index ddeb791..0000000 --- a/src/select.cpp +++ /dev/null @@ -1,1421 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "select.h" - -#include - -#include "debugging/debugging.h" - -#include "ientity.h" -#include "eclasslib.h" -#include "iselection.h" -#include "iundo.h" - -#include - -#include "stream/stringstream.h" -#include "signal/isignal.h" -#include "shaderlib.h" -#include "scenelib.h" - -#include "gtkutil/idledraw.h" -#include "gtkutil/dialog.h" -#include "gtkutil/widget.h" -#include "brushmanip.h" -#include "brush.h" -#include "patchmanip.h" -#include "patchdialog.h" -#include "selection.h" -#include "texwindow.h" -#include "gtkmisc.h" -#include "mainframe.h" -#include "grid.h" -#include "map.h" -#include "entityinspector.h" - - -select_workzone_t g_select_workzone; - - -/** - Loops over all selected brushes and stores their - world AABBs in the specified array. - */ -class CollectSelectedBrushesBounds : public SelectionSystem::Visitor { -AABB *m_bounds; // array of AABBs -Unsigned m_max; // max AABB-elements in array -Unsigned &m_count; // count of valid AABBs stored in array - -public: -CollectSelectedBrushesBounds(AABB *bounds, Unsigned max, Unsigned &count) - : m_bounds(bounds), - m_max(max), - m_count(count) -{ - m_count = 0; -} - -void visit(scene::Instance &instance) const -{ - ASSERT_MESSAGE(m_count <= m_max, "Invalid m_count in CollectSelectedBrushesBounds"); - - // stop if the array is already full - if (m_count == m_max) { - return; - } - - Selectable *selectable = Instance_getSelectable(instance); - if ((selectable != 0) - && instance.isSelected()) { - // brushes only - if (Instance_getBrush(instance) != 0) { - m_bounds[m_count] = instance.worldAABB(); - ++m_count; - } - } -} -}; - -/** - Selects all objects that intersect one of the bounding AABBs. - The exact intersection-method is specified through TSelectionPolicy - */ -template -class SelectByBounds : public scene::Graph::Walker { -AABB *m_aabbs; // selection aabbs -Unsigned m_count; // number of aabbs in m_aabbs -TSelectionPolicy policy; // type that contains a custom intersection method aabb<->aabb - -public: -SelectByBounds(AABB *aabbs, Unsigned count) - : m_aabbs(aabbs), - m_count(count) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - - // ignore worldspawn - Entity *entity = Node_getEntity(path.top()); - if (entity) { - if (string_equal(entity->getKeyValue("classname"), "worldspawn")) { - return true; - } - } - - if ((path.size() > 1) && - (!path.top().get().isRoot()) && - (selectable != 0) - ) { - for (Unsigned i = 0; i < m_count; ++i) { - if (policy.Evaluate(m_aabbs[i], instance)) { - selectable->setSelected(true); - } - } - } - - return true; -} - -/** - Performs selection operation on the global scenegraph. - If delete_bounds_src is true, then the objects which were - used as source for the selection aabbs will be deleted. - */ -static void DoSelection(bool delete_bounds_src = true) -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - // we may not need all AABBs since not all selected objects have to be brushes - const Unsigned max = (Unsigned) GlobalSelectionSystem().countSelected(); - AABB *aabbs = new AABB[max]; - - Unsigned count; - CollectSelectedBrushesBounds collector(aabbs, max, count); - GlobalSelectionSystem().foreachSelected(collector); - - // nothing usable in selection - if (!count) { - delete[] aabbs; - return; - } - - // delete selected objects - if (delete_bounds_src) { // see deleteSelection - UndoableCommand undo("deleteSelected"); - Select_Delete(); - } - - // select objects with bounds - GlobalSceneGraph().traverse(SelectByBounds(aabbs, count)); - - SceneChangeNotify(); - delete[] aabbs; - } -} -}; - -/** - SelectionPolicy for SelectByBounds - Returns true if box and the AABB of instance intersect - */ -class SelectionPolicy_Touching { -public: -bool Evaluate(const AABB &box, scene::Instance &instance) const -{ - const AABB &other(instance.worldAABB()); - for (Unsigned i = 0; i < 3; ++i) { - if (fabsf(box.origin[i] - other.origin[i]) > (box.extents[i] + other.extents[i])) { - return false; - } - } - return true; -} -}; - -/** - SelectionPolicy for SelectByBounds - Returns true if the AABB of instance is inside box - */ -class SelectionPolicy_Inside { -public: -bool Evaluate(const AABB &box, scene::Instance &instance) const -{ - const AABB &other(instance.worldAABB()); - for (Unsigned i = 0; i < 3; ++i) { - if (fabsf(box.origin[i] - other.origin[i]) > (box.extents[i] - other.extents[i])) { - return false; - } - } - return true; -} -}; - -class DeleteSelected : public scene::Graph::Walker { -mutable bool m_remove; -mutable bool m_removedChild; -public: -DeleteSelected() - : m_remove(false), m_removedChild(false) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - m_removedChild = false; - - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected() - && path.size() > 1 - && !path.top().get().isRoot()) { - m_remove = true; - - return false; // dont traverse into child elements - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - - if (m_removedChild) { - m_removedChild = false; - - // delete empty entities - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && path.top().get_pointer() != Map_FindWorldspawn(g_map) - && Node_getTraversable(path.top())->empty()) { - Path_deleteTop(path); - } - } - - // node should be removed - if (m_remove) { - if (Node_isEntity(path.parent()) != 0) { - m_removedChild = true; - } - - m_remove = false; - Path_deleteTop(path); - } -} -}; - - - -class DeleteEmpty : public scene::Graph::Walker { -mutable bool m_remove; -public: -DeleteEmpty() - : m_remove(false) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - /* skip point ents, crash otherwise */ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 && entity->getEntityClass().fixedsize) { - return; - } - - // delete empty entities - if (entity != 0 - && path.top().get_pointer() != Map_FindWorldspawn(g_map) - && Node_getTraversable(path.top())->empty()) - { - Path_deleteTop(path); - } - /*}*/ - - /*// node should be removed - if (m_remove) { - if (Node_isEntity(path.parent()) != 0) { - m_removedChild = true; - } - - m_remove = false; - Path_deleteTop(path); - }*/ -} -}; - - -void Scene_DeleteEmpty() -{ - GlobalSceneGraph().traverse(DeleteEmpty()); - SceneChangeNotify(); -} - -void Scene_DeleteSelected(scene::Graph &graph) -{ - graph.traverse(DeleteSelected()); - SceneChangeNotify(); -} - -void Select_Delete(void) -{ - Scene_DeleteSelected(GlobalSceneGraph()); -} - -class InvertSelectionWalker : public scene::Graph::Walker { -SelectionSystem::EMode m_mode; -mutable Selectable *m_selectable; -public: -InvertSelectionWalker(SelectionSystem::EMode mode) - : m_mode(mode), m_selectable(0) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable) { - switch (m_mode) { - case SelectionSystem::eEntity: - if (Node_isEntity(path.top()) != 0) { - m_selectable = path.top().get().visible() ? selectable : 0; - } - break; - case SelectionSystem::ePrimitive: - m_selectable = path.top().get().visible() ? selectable : 0; - break; - case SelectionSystem::eComponent: - break; - } - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - if (m_selectable != 0) { - m_selectable->setSelected(!m_selectable->isSelected()); - m_selectable = 0; - } -} -}; - -void Scene_Invert_Selection(scene::Graph &graph) -{ - graph.traverse(InvertSelectionWalker(GlobalSelectionSystem().Mode())); -} - -void Select_Invert() -{ - Scene_Invert_Selection(GlobalSceneGraph()); -} - -class ExpandSelectionToEntitiesWalker : public scene::Graph::Walker { -mutable std::size_t m_depth; -NodeSmartReference worldspawn; -public: -ExpandSelectionToEntitiesWalker() : m_depth(0), worldspawn(Map_FindOrInsertWorldspawn(g_map)) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - ++m_depth; - - // ignore worldspawn - NodeSmartReference me(path.top().get()); - if (me == worldspawn) { - return false; - } - - if (m_depth == 2) { // entity depth - // traverse and select children if any one is selected - if (instance.childSelected()) { - Instance_setSelected(instance, true); - } - return Node_getEntity(path.top())->isContainer() && instance.isSelected(); - } else if (m_depth == 3) { // primitive depth - Instance_setSelected(instance, true); - return false; - } - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - --m_depth; -} -}; - -void Scene_ExpandSelectionToEntities() -{ - GlobalSceneGraph().traverse(ExpandSelectionToEntitiesWalker()); -} - - -namespace { -void Selection_UpdateWorkzone() -{ - if (GlobalSelectionSystem().countSelected() != 0) { - Select_GetBounds(g_select_workzone.d_work_min, g_select_workzone.d_work_max); - } -} - -typedef FreeCaller SelectionUpdateWorkzoneCaller; - -IdleDraw g_idleWorkzone = IdleDraw(SelectionUpdateWorkzoneCaller()); -} - -const select_workzone_t &Select_getWorkZone() -{ - g_idleWorkzone.flush(); - return g_select_workzone; -} - -void UpdateWorkzone_ForSelection() -{ - g_idleWorkzone.queueDraw(); -} - -// update the workzone to the current selection -void UpdateWorkzone_ForSelectionChanged(const Selectable &selectable) -{ - if (selectable.isSelected()) { - UpdateWorkzone_ForSelection(); - } -} - -void Select_SetShader(const char *shader) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushSetShader_Selected(GlobalSceneGraph(), shader); - Scene_PatchSetShader_Selected(GlobalSceneGraph(), shader); - } - Scene_BrushSetShader_Component_Selected(GlobalSceneGraph(), shader); -} - -void Select_SetTexdef(const TextureProjection &projection, bool ignorebasis) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushSetTexdef_Selected(GlobalSceneGraph(), projection, ignorebasis); - } - Scene_BrushSetTexdef_Component_Selected(GlobalSceneGraph(), projection, ignorebasis); -} - -void Select_SetFlags(const ContentsFlagsValue &flags) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushSetFlags_Selected(GlobalSceneGraph(), flags); - } - Scene_BrushSetFlags_Component_Selected(GlobalSceneGraph(), flags); -} - -void Select_GetBounds(Vector3 &mins, Vector3 &maxs) -{ - AABB bounds; - Scene_BoundsSelected(GlobalSceneGraph(), bounds); - maxs = vector3_added(bounds.origin, bounds.extents); - mins = vector3_subtracted(bounds.origin, bounds.extents); -} - -void Select_GetMid(Vector3 &mid) -{ - AABB bounds; - Scene_BoundsSelected(GlobalSceneGraph(), bounds); - mid = vector3_snapped(bounds.origin); -} - - -void Select_FlipAxis(int axis) -{ - Vector3 flip(1, 1, 1); - flip[axis] = -1; - GlobalSelectionSystem().scaleSelected(flip); -} - - -void Select_Scale(float x, float y, float z) -{ - GlobalSelectionSystem().scaleSelected(Vector3(x, y, z)); -} - -enum axis_t { - eAxisX = 0, - eAxisY = 1, - eAxisZ = 2, -}; - -enum sign_t { - eSignPositive = 1, - eSignNegative = -1, -}; - -inline Matrix4 matrix4_rotation_for_axis90(axis_t axis, sign_t sign) -{ - switch (axis) { - case eAxisX: - if (sign == eSignPositive) { - return matrix4_rotation_for_sincos_x(1, 0); - } else { - return matrix4_rotation_for_sincos_x(-1, 0); - } - case eAxisY: - if (sign == eSignPositive) { - return matrix4_rotation_for_sincos_y(1, 0); - } else { - return matrix4_rotation_for_sincos_y(-1, 0); - } - default: //case eAxisZ: - if (sign == eSignPositive) { - return matrix4_rotation_for_sincos_z(1, 0); - } else { - return matrix4_rotation_for_sincos_z(-1, 0); - } - } -} - -inline void matrix4_rotate_by_axis90(Matrix4 &matrix, axis_t axis, sign_t sign) -{ - matrix4_multiply_by_matrix4(matrix, matrix4_rotation_for_axis90(axis, sign)); -} - -inline void matrix4_pivoted_rotate_by_axis90(Matrix4 &matrix, axis_t axis, sign_t sign, const Vector3 &pivotpoint) -{ - matrix4_translate_by_vec3(matrix, pivotpoint); - matrix4_rotate_by_axis90(matrix, axis, sign); - matrix4_translate_by_vec3(matrix, vector3_negated(pivotpoint)); -} - -inline Quaternion quaternion_for_axis90(axis_t axis, sign_t sign) -{ -#if 1 - switch (axis) { - case eAxisX: - if (sign == eSignPositive) { - return Quaternion(c_half_sqrt2f, 0, 0, c_half_sqrt2f); - } else { - return Quaternion(-c_half_sqrt2f, 0, 0, -c_half_sqrt2f); - } - case eAxisY: - if (sign == eSignPositive) { - return Quaternion(0, c_half_sqrt2f, 0, c_half_sqrt2f); - } else { - return Quaternion(0, -c_half_sqrt2f, 0, -c_half_sqrt2f); - } - default: //case eAxisZ: - if (sign == eSignPositive) { - return Quaternion(0, 0, c_half_sqrt2f, c_half_sqrt2f); - } else { - return Quaternion(0, 0, -c_half_sqrt2f, -c_half_sqrt2f); - } - } -#else - quaternion_for_matrix4_rotation( matrix4_rotation_for_axis90( (axis_t)axis, ( deg > 0 ) ? eSignPositive : eSignNegative ) ); -#endif -} - -void Select_RotateAxis(int axis, float deg) -{ - if (fabs(deg) == 90.f) { - GlobalSelectionSystem().rotateSelected( - quaternion_for_axis90((axis_t) axis, (deg > 0) ? eSignPositive : eSignNegative)); - } else { - switch (axis) { - case 0: - GlobalSelectionSystem().rotateSelected( - quaternion_for_matrix4_rotation(matrix4_rotation_for_x_degrees(deg))); - break; - case 1: - GlobalSelectionSystem().rotateSelected( - quaternion_for_matrix4_rotation(matrix4_rotation_for_y_degrees(deg))); - break; - case 2: - GlobalSelectionSystem().rotateSelected( - quaternion_for_matrix4_rotation(matrix4_rotation_for_z_degrees(deg))); - break; - } - } -} - - -void Select_ShiftTexture(float x, float y) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushShiftTexdef_Selected(GlobalSceneGraph(), x, y); - Scene_PatchTranslateTexture_Selected(GlobalSceneGraph(), x, y); - } - //globalOutputStream() << "shift selected face textures: s=" << x << " t=" << y << '\n'; - Scene_BrushShiftTexdef_Component_Selected(GlobalSceneGraph(), x, y); -} - -void Select_ScaleTexture(float x, float y) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushScaleTexdef_Selected(GlobalSceneGraph(), x, y); - Scene_PatchScaleTexture_Selected(GlobalSceneGraph(), x, y); - } - Scene_BrushScaleTexdef_Component_Selected(GlobalSceneGraph(), x, y); -} - -void Select_RotateTexture(float amt) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushRotateTexdef_Selected(GlobalSceneGraph(), amt); - Scene_PatchRotateTexture_Selected(GlobalSceneGraph(), amt); - } - Scene_BrushRotateTexdef_Component_Selected(GlobalSceneGraph(), amt); -} - -// TTimo modified to handle shader architecture: -// expects shader names at input, comparison relies on shader names .. texture names no longer relevant -void FindReplaceTextures(const char *pFind, const char *pReplace, bool bSelected) -{ - if (!texdef_name_valid(pFind)) { - globalErrorStream() << "FindReplaceTextures: invalid texture name: '" << pFind << "', aborted\n"; - return; - } - if (!texdef_name_valid(pReplace)) { - globalErrorStream() << "FindReplaceTextures: invalid texture name: '" << pReplace << "', aborted\n"; - return; - } - - StringOutputStream command; - command << "textureFindReplace -find " << pFind << " -replace " << pReplace; - UndoableCommand undo(command.c_str()); - - if (bSelected) { - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushFindReplaceShader_Selected(GlobalSceneGraph(), pFind, pReplace); - Scene_PatchFindReplaceShader_Selected(GlobalSceneGraph(), pFind, pReplace); - } - Scene_BrushFindReplaceShader_Component_Selected(GlobalSceneGraph(), pFind, pReplace); - } else { - Scene_BrushFindReplaceShader(GlobalSceneGraph(), pFind, pReplace); - Scene_PatchFindReplaceShader(GlobalSceneGraph(), pFind, pReplace); - } -} - -typedef std::vector PropertyValues; - -bool propertyvalues_contain(const PropertyValues &propertyvalues, const char *str) -{ - for (PropertyValues::const_iterator i = propertyvalues.begin(); i != propertyvalues.end(); ++i) { - if (string_equal(str, *i)) { - return true; - } - } - return false; -} - -class EntityFindByPropertyValueWalker : public scene::Graph::Walker { -const PropertyValues &m_propertyvalues; -const char *m_prop; -public: -EntityFindByPropertyValueWalker(const char *prop, const PropertyValues &propertyvalues) - : m_propertyvalues(propertyvalues), m_prop(prop) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Entity *entity = Node_getEntity(path.top()); - if (entity != 0 - && propertyvalues_contain(m_propertyvalues, entity->getKeyValue(m_prop))) { - Instance_getSelectable(instance)->setSelected(true); - } - return true; -} -}; - -void Scene_EntitySelectByPropertyValues(scene::Graph &graph, const char *prop, const PropertyValues &propertyvalues) -{ - graph.traverse(EntityFindByPropertyValueWalker(prop, propertyvalues)); -} - -class EntityGetSelectedPropertyValuesWalker : public scene::Graph::Walker { -PropertyValues &m_propertyvalues; -const char *m_prop; -public: -EntityGetSelectedPropertyValuesWalker(const char *prop, PropertyValues &propertyvalues) - : m_propertyvalues(propertyvalues), m_prop(prop) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - Entity *entity = Node_getEntity(path.top()); - if (entity != 0) { - if (!propertyvalues_contain(m_propertyvalues, entity->getKeyValue(m_prop))) { - m_propertyvalues.push_back(entity->getKeyValue(m_prop)); - } - } - } - return true; -} -}; - -void Scene_EntityGetPropertyValues(scene::Graph &graph, const char *prop, PropertyValues &propertyvalues) -{ - graph.traverse(EntityGetSelectedPropertyValuesWalker(prop, propertyvalues)); -} - -void Select_AllOfType() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - if (GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace) { - GlobalSelectionSystem().setSelectedAllComponents(false); - Scene_BrushSelectByShader_Component(GlobalSceneGraph(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - } - } else { - PropertyValues propertyvalues; - const char *prop = EntityInspector_getCurrentKey(); - if (!prop || !*prop) { - prop = "classname"; - } - Scene_EntityGetPropertyValues(GlobalSceneGraph(), prop, propertyvalues); - GlobalSelectionSystem().setSelectedAll(false); - if (!propertyvalues.empty()) { - Scene_EntitySelectByPropertyValues(GlobalSceneGraph(), prop, propertyvalues); - } else { - Scene_BrushSelectByShader(GlobalSceneGraph(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - Scene_PatchSelectByShader(GlobalSceneGraph(), TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - } - } -} - -void Select_AllOfModel() -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - if (GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace) { - GlobalSelectionSystem().setSelectedAllComponents(false); - Scene_BrushSelectByShader_Component(GlobalSceneGraph(), - TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - } - } else { - PropertyValues propertyvalues; - const char *prop = EntityInspector_getCurrentKey(); - if (!prop || !*prop) { - prop = "model"; - } - Scene_EntityGetPropertyValues(GlobalSceneGraph(), prop, propertyvalues); - GlobalSelectionSystem().setSelectedAll(false); - if (!propertyvalues.empty()) { - Scene_EntitySelectByPropertyValues(GlobalSceneGraph(), prop, propertyvalues); - } - } -} - -void Select_Inside(void) -{ - SelectByBounds::DoSelection(); -} - -void Select_Touching(void) -{ - SelectByBounds::DoSelection(false); -} - -void Select_FitTexture(float horizontal, float vertical) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushFitTexture_Selected(GlobalSceneGraph(), horizontal, vertical); - } - Scene_BrushFitTexture_Component_Selected(GlobalSceneGraph(), horizontal, vertical); - - SceneChangeNotify(); -} - - -void Select_AlignTexture(int alignment) -{ - if (GlobalSelectionSystem().Mode() != SelectionSystem::eComponent) { - Scene_BrushAlignTexture_Selected(GlobalSceneGraph(), alignment); - } - Scene_BrushAlignTexture_Component_Selected(GlobalSceneGraph(), alignment); - - SceneChangeNotify(); -} - -inline void hide_node(scene::Node &node, bool hide) -{ - hide - ? node.enable(scene::Node::eHidden) - : node.disable(scene::Node::eHidden); -} - -class HideSelectedWalker : public scene::Graph::Walker { -bool m_hide; -public: -HideSelectedWalker(bool hide) - : m_hide(hide) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - hide_node(path.top(), m_hide); - } - return true; -} -}; - -void Scene_Hide_Selected(bool hide) -{ - GlobalSceneGraph().traverse(HideSelectedWalker(hide)); -} - -void Select_Hide() -{ - Scene_Hide_Selected(true); - SceneChangeNotify(); -} - -void QE_hiddenCountChanged(); -void HideSelected() -{ - Select_Hide(); - GlobalSelectionSystem().setSelectedAll(false); - QE_hiddenCountChanged(); -} - -void HideUnselected() -{ - Select_Invert(); - Select_Hide(); - GlobalSelectionSystem().setSelectedAll(false); - QE_hiddenCountChanged(); -} - - -class HideAllWalker : public scene::Graph::Walker { -bool m_hide; -public: -HideAllWalker(bool hide) - : m_hide(hide) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - hide_node(path.top(), m_hide); - return true; -} -}; - -void Scene_Hide_All(bool hide) -{ - GlobalSceneGraph().traverse(HideAllWalker(hide)); -} - -void Select_ShowAllHidden() -{ - Scene_Hide_All(false); - SceneChangeNotify(); - QE_hiddenCountChanged(); -} - - -void Selection_Flipx() -{ - UndoableCommand undo("mirrorSelected -axis x"); - Select_FlipAxis(0); -} - -void Selection_Flipy() -{ - UndoableCommand undo("mirrorSelected -axis y"); - Select_FlipAxis(1); -} - -void Selection_Flipz() -{ - UndoableCommand undo("mirrorSelected -axis z"); - Select_FlipAxis(2); -} - -void Selection_Rotatex() -{ - UndoableCommand undo("rotateSelected -axis x -angle -90"); - Select_RotateAxis(0, -90); -} - -void Selection_Rotatey() -{ - UndoableCommand undo("rotateSelected -axis y -angle 90"); - Select_RotateAxis(1, 90); -} - -void Selection_Rotatez() -{ - UndoableCommand undo("rotateSelected -axis z -angle -90"); - Select_RotateAxis(2, -90); -} - - -void Nudge(int nDim, float fNudge) -{ - Vector3 translate(0, 0, 0); - translate[nDim] = fNudge; - - GlobalSelectionSystem().translateSelected(translate); -} - -void Selection_NudgeZ(float amount) -{ - StringOutputStream command; - command << "nudgeSelected -axis z -amount " << amount; - UndoableCommand undo(command.c_str()); - - Nudge(2, amount); -} - -void Selection_MoveDown() -{ - Selection_NudgeZ(-GetGridSize()); -} - -void Selection_MoveUp() -{ - Selection_NudgeZ(GetGridSize()); -} - -void SceneSelectionChange(const Selectable &selectable) -{ - SceneChangeNotify(); -} - -SignalHandlerId Selection_boundsChanged; - -void Selection_construct() -{ - typedef FreeCaller SceneSelectionChangeCaller; - GlobalSelectionSystem().addSelectionChangeCallback(SceneSelectionChangeCaller()); - typedef FreeCaller UpdateWorkzoneForSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(UpdateWorkzoneForSelectionChangedCaller()); - typedef FreeCaller UpdateWorkzoneForSelectionCaller; - Selection_boundsChanged = GlobalSceneGraph().addBoundsChangedCallback(UpdateWorkzoneForSelectionCaller()); -} - -void Selection_destroy() -{ - GlobalSceneGraph().removeBoundsChangedCallback(Selection_boundsChanged); -} - - -#include "gtkdlgs.h" -#include - - -inline Quaternion quaternion_for_euler_xyz_degrees(const Vector3 &eulerXYZ) -{ -#if 0 - return quaternion_for_matrix4_rotation( matrix4_rotation_for_euler_xyz_degrees( eulerXYZ ) ); -#elif 0 - return quaternion_multiplied_by_quaternion( - quaternion_multiplied_by_quaternion( - quaternion_for_z( degrees_to_radians( eulerXYZ[2] ) ), - quaternion_for_y( degrees_to_radians( eulerXYZ[1] ) ) - ), - quaternion_for_x( degrees_to_radians( eulerXYZ[0] ) ) - ); -#elif 1 - double cx = cos(degrees_to_radians(eulerXYZ[0] * 0.5)); - double sx = sin(degrees_to_radians(eulerXYZ[0] * 0.5)); - double cy = cos(degrees_to_radians(eulerXYZ[1] * 0.5)); - double sy = sin(degrees_to_radians(eulerXYZ[1] * 0.5)); - double cz = cos(degrees_to_radians(eulerXYZ[2] * 0.5)); - double sz = sin(degrees_to_radians(eulerXYZ[2] * 0.5)); - - return Quaternion( - cz * cy * sx - sz * sy * cx, - cz * sy * cx + sz * cy * sx, - sz * cy * cx - cz * sy * sx, - cz * cy * cx + sz * sy * sx - ); -#endif -} - -struct RotateDialog { - ui::SpinButton x{ui::null}; - ui::SpinButton y{ui::null}; - ui::SpinButton z{ui::null}; - ui::Window window{ui::null}; -}; - -static gboolean rotatedlg_apply(ui::Widget widget, RotateDialog *rotateDialog) -{ - Vector3 eulerXYZ; - - eulerXYZ[0] = static_cast( gtk_spin_button_get_value(rotateDialog->x)); - eulerXYZ[1] = static_cast( gtk_spin_button_get_value(rotateDialog->y)); - eulerXYZ[2] = static_cast( gtk_spin_button_get_value(rotateDialog->z)); - - StringOutputStream command; - command << "rotateSelectedEulerXYZ -x " << eulerXYZ[0] << " -y " << eulerXYZ[1] << " -z " << eulerXYZ[2]; - UndoableCommand undo(command.c_str()); - - GlobalSelectionSystem().rotateSelected(quaternion_for_euler_xyz_degrees(eulerXYZ)); - return TRUE; -} - -static gboolean rotatedlg_cancel(ui::Widget widget, RotateDialog *rotateDialog) -{ - rotateDialog->window.hide(); - - gtk_spin_button_set_value(rotateDialog->x, 0.0f); // reset to 0 on close - gtk_spin_button_set_value(rotateDialog->y, 0.0f); - gtk_spin_button_set_value(rotateDialog->z, 0.0f); - - return TRUE; -} - -static gboolean rotatedlg_ok(ui::Widget widget, RotateDialog *rotateDialog) -{ - rotatedlg_apply(widget, rotateDialog); - rotateDialog->window.hide(); - return TRUE; -} - -static gboolean rotatedlg_delete(ui::Widget widget, GdkEventAny *event, RotateDialog *rotateDialog) -{ - rotatedlg_cancel(widget, rotateDialog); - return TRUE; -} - -RotateDialog g_rotate_dialog; - -void DoRotateDlg() -{ - if (!g_rotate_dialog.window) { - g_rotate_dialog.window = MainFrame_getWindow().create_dialog_window("Arbitrary rotation", - G_CALLBACK(rotatedlg_delete), - &g_rotate_dialog); - - auto accel = ui::AccelGroup(ui::New); - g_rotate_dialog.window.add_accel_group(accel); - - { - auto hbox = create_dialog_hbox(4, 4); - g_rotate_dialog.window.add(hbox); - { - auto table = create_dialog_table(3, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - { - ui::Widget label = ui::Label(" X "); - label.show(); - table.attach(label, {0, 1, 0, 1}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Y "); - label.show(); - table.attach(label, {0, 1, 1, 2}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Z "); - label.show(); - table.attach(label, {0, 1, 2, 3}, {0, 0}); - } - { - auto adj = ui::Adjustment(0, -359, 359, 1, 10, 0); - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(64, -1); - gtk_spin_button_set_wrap(spin, TRUE); - - gtk_widget_grab_focus(spin); - - g_rotate_dialog.x = spin; - } - { - auto adj = ui::Adjustment(0, -359, 359, 1, 10, 0); - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(64, -1); - gtk_spin_button_set_wrap(spin, TRUE); - - g_rotate_dialog.y = spin; - } - { - auto adj = ui::Adjustment(0, -359, 359, 1, 10, 0); - auto spin = ui::SpinButton(adj, 1, 0); - spin.show(); - table.attach(spin, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(64, -1); - gtk_spin_button_set_wrap(spin, TRUE); - - g_rotate_dialog.z = spin; - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(rotatedlg_ok), &g_rotate_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(rotatedlg_cancel), &g_rotate_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Apply", G_CALLBACK(rotatedlg_apply), &g_rotate_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - } - } - - g_rotate_dialog.window.show(); -} - - -struct ScaleDialog { - ui::Entry x{ui::null}; - ui::Entry y{ui::null}; - ui::Entry z{ui::null}; - ui::Window window{ui::null}; -}; - -static gboolean scaledlg_apply(ui::Widget widget, ScaleDialog *scaleDialog) -{ - float sx, sy, sz; - - sx = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(scaleDialog->x)))); - sy = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(scaleDialog->y)))); - sz = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(scaleDialog->z)))); - - StringOutputStream command; - command << "scaleSelected -x " << sx << " -y " << sy << " -z " << sz; - UndoableCommand undo(command.c_str()); - - Select_Scale(sx, sy, sz); - - return TRUE; -} - -static gboolean scaledlg_cancel(ui::Widget widget, ScaleDialog *scaleDialog) -{ - scaleDialog->window.hide(); - - scaleDialog->x.text("1.0"); - scaleDialog->y.text("1.0"); - scaleDialog->z.text("1.0"); - - return TRUE; -} - -static gboolean scaledlg_ok(ui::Widget widget, ScaleDialog *scaleDialog) -{ - scaledlg_apply(widget, scaleDialog); - scaleDialog->window.hide(); - return TRUE; -} - -static gboolean scaledlg_delete(ui::Widget widget, GdkEventAny *event, ScaleDialog *scaleDialog) -{ - scaledlg_cancel(widget, scaleDialog); - return TRUE; -} - -ScaleDialog g_scale_dialog; - -void DoScaleDlg() -{ - if (!g_scale_dialog.window) { - g_scale_dialog.window = MainFrame_getWindow().create_dialog_window("Arbitrary scale", - G_CALLBACK(scaledlg_delete), - &g_scale_dialog); - - auto accel = ui::AccelGroup(ui::New); - g_scale_dialog.window.add_accel_group(accel); - - { - auto hbox = create_dialog_hbox(4, 4); - g_scale_dialog.window.add(hbox); - { - auto table = create_dialog_table(3, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - { - ui::Widget label = ui::Label(" X "); - label.show(); - table.attach(label, {0, 1, 0, 1}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Y "); - label.show(); - table.attach(label, {0, 1, 1, 2}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Z "); - label.show(); - table.attach(label, {0, 1, 2, 3}, {0, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.text("1.0"); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - g_scale_dialog.x = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.text("1.0"); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - g_scale_dialog.y = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.text("1.0"); - entry.show(); - table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - - g_scale_dialog.z = entry; - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(scaledlg_ok), &g_scale_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(scaledlg_cancel), &g_scale_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Apply", G_CALLBACK(scaledlg_apply), &g_scale_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - } - } - - g_scale_dialog.window.show(); -} - -/* NEW: Artbirary Move */ - -struct MoveDialog { - ui::Entry x{ui::null}; - ui::Entry y{ui::null}; - ui::Entry z{ui::null}; - ui::Window window{ui::null}; -}; - -static gboolean movedlg_apply(ui::Widget widget, MoveDialog *moveDialog) -{ - float sx, sy, sz; - - sx = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(moveDialog->x)))); - sy = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(moveDialog->y)))); - sz = static_cast( atof(gtk_entry_get_text(GTK_ENTRY(moveDialog->z)))); - - StringOutputStream command; - command << "nudgeSelected -axis x " << sx; - command << "nudgeSelected -axis y " << sy; - command << "nudgeSelected -axis z " << sz; - UndoableCommand undo(command.c_str()); - - Nudge(0, sx); - Nudge(1, sy); - Nudge(2, sz); - return TRUE; -} - -static gboolean movedlg_cancel(ui::Widget widget, MoveDialog *moveDialog) -{ - moveDialog->window.hide(); - - moveDialog->x.text("0.0"); - moveDialog->y.text("0.0"); - moveDialog->z.text("0.0"); - - return TRUE; -} - -static gboolean movedlg_ok(ui::Widget widget, MoveDialog *moveDialog) -{ - movedlg_apply(widget, moveDialog); - moveDialog->window.hide(); - return TRUE; -} - -static gboolean movedlg_delete(ui::Widget widget, GdkEventAny *event, MoveDialog *moveDialog) -{ - movedlg_cancel(widget, moveDialog); - return TRUE; -} - -MoveDialog g_move_dialog; - -void DoMoveDlg() -{ - if (!g_move_dialog.window) { - g_move_dialog.window = MainFrame_getWindow().create_dialog_window("Arbitrary scale", - G_CALLBACK(movedlg_delete), - &g_move_dialog); - - auto accel = ui::AccelGroup(ui::New); - g_move_dialog.window.add_accel_group(accel); - - { - auto hbox = create_dialog_hbox(4, 4); - g_move_dialog.window.add(hbox); - { - auto table = create_dialog_table(3, 2, 4, 4); - hbox.pack_start(table, TRUE, TRUE, 0); - { - ui::Widget label = ui::Label(" X "); - label.show(); - table.attach(label, {0, 1, 0, 1}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Y "); - label.show(); - table.attach(label, {0, 1, 1, 2}, {0, 0}); - } - { - ui::Widget label = ui::Label(" Z "); - label.show(); - table.attach(label, {0, 1, 2, 3}, {0, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.text("0.0"); - entry.show(); - table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - - g_move_dialog.x = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.text("0.0"); - entry.show(); - table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - - g_move_dialog.y = entry; - } - { - auto entry = ui::Entry(ui::New); - entry.text("0.0"); - entry.show(); - table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - - g_move_dialog.z = entry; - } - } - { - auto vbox = create_dialog_vbox(4); - hbox.pack_start(vbox, TRUE, TRUE, 0); - { - auto button = create_dialog_button("OK", G_CALLBACK(movedlg_ok), &g_move_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - widget_make_default(button); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Cancel", G_CALLBACK(movedlg_cancel), &g_move_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, - (GtkAccelFlags) 0); - } - { - auto button = create_dialog_button("Apply", G_CALLBACK(movedlg_apply), &g_move_dialog); - vbox.pack_start(button, FALSE, FALSE, 0); - } - } - } - } - - g_move_dialog.window.show(); -} - diff --git a/src/select.h b/src/select.h deleted file mode 100644 index 6a4e3f2..0000000 --- a/src/select.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SELECT_H ) -#define INCLUDED_SELECT_H - -#include "math/vector.h" - -void Select_GetBounds(Vector3 &mins, Vector3 &maxs); - -void Select_GetMid(Vector3 &mid); - -void Select_Delete(); - -void Select_Invert(); - -void Select_Inside(); - -void Select_Touching(); - -void Scene_ExpandSelectionToEntities(); - -void Selection_Flipx(); - -void Selection_Flipy(); - -void Selection_Flipz(); - -void Selection_Rotatex(); - -void Selection_Rotatey(); - -void Selection_Rotatez(); - - -void Selection_MoveDown(); - -void Selection_MoveUp(); - -void Select_AllOfType(); - -void Select_AllOfModel(); - -void DoRotateDlg(); - -void DoScaleDlg(); - -void DoMoveDlg(); - -void Select_SetShader(const char *shader); - -class TextureProjection; - -void Select_SetTexdef(const TextureProjection &projection, bool ignorebasis); - -class ContentsFlagsValue; - -void Select_SetFlags(const ContentsFlagsValue &flags); - -void Select_RotateTexture(float amt); - -void Select_ScaleTexture(float x, float y); - -void Select_ShiftTexture(float x, float y); - -void Select_FitTexture(float horizontal = 1, float vertical = 1); - -void Select_AlignTexture(int alignment); - -void FindReplaceTextures(const char *pFind, const char *pReplace, bool bSelected); - -void HideSelected(); -void HideUnselected(); - -void Select_ShowAllHidden(); - -// updating workzone to a given brush (depends on current view) - -void Selection_construct(); - -void Selection_destroy(); - - -struct select_workzone_t { - // defines the boundaries of the current work area - // is used to guess brushes and drop points third coordinate when creating from 2D view - Vector3 d_work_min, d_work_max; - - select_workzone_t() : - d_work_min(-64.0f, -64.0f, -64.0f), - d_work_max(64.0f, 64.0f, 64.0f) - { - } -}; - -const select_workzone_t &Select_getWorkZone(); - -#endif diff --git a/src/selection.cpp b/src/selection.cpp deleted file mode 100644 index eeaca18..0000000 --- a/src/selection.cpp +++ /dev/null @@ -1,4098 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "selection.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#include "windowobserver.h" -#include "iundo.h" -#include "ientity.h" -#include "cullable.h" -#include "renderable.h" -#include "selectable.h" -#include "editable.h" - -#include "math/frustum.h" -#include "signal/signal.h" -#include "generic/object.h" -#include "selectionlib.h" -#include "render.h" -#include "view.h" -#include "renderer.h" -#include "stream/stringstream.h" -#include "eclasslib.h" -#include "generic/bitfield.h" -#include "generic/static.h" -#include "pivot.h" -#include "stringio.h" -#include "container/container.h" - -#include "grid.h" - -void Selection_Deselect(void); - -TextOutputStream &ostream_write(TextOutputStream &t, const Vector4 &v) -{ - return t << "[ " << v.x() << " " << v.y() << " " << v.z() << " " << v.w() << " ]"; -} - -TextOutputStream &ostream_write(TextOutputStream &t, const Matrix4 &m) -{ - return t << "[ " << m.x() << " " << m.y() << " " << m.z() << " " << m.t() << " ]"; -} - -struct Pivot2World { - Matrix4 m_worldSpace; - Matrix4 m_viewpointSpace; - Matrix4 m_viewplaneSpace; - Vector3 m_axis_screen; - - void - update(const Matrix4 &pivot2world, const Matrix4 &modelview, const Matrix4 &projection, const Matrix4 &viewport) - { - Pivot2World_worldSpace(m_worldSpace, pivot2world, modelview, projection, viewport); - Pivot2World_viewpointSpace(m_viewpointSpace, m_axis_screen, pivot2world, modelview, projection, viewport); - Pivot2World_viewplaneSpace(m_viewplaneSpace, pivot2world, modelview, projection, viewport); - } -}; - - -void point_for_device_point(Vector3 &point, const Matrix4 &device2object, const float x, const float y, const float z) -{ - // transform from normalised device coords to object coords - point = vector4_projected(matrix4_transformed_vector4(device2object, Vector4(x, y, z, 1))); -} - -void ray_for_device_point(Ray &ray, const Matrix4 &device2object, const float x, const float y) -{ - // point at x, y, zNear - point_for_device_point(ray.origin, device2object, x, y, -1); - - // point at x, y, zFar - point_for_device_point(ray.direction, device2object, x, y, 1); - - // construct ray - vector3_subtract(ray.direction, ray.origin); - vector3_normalise(ray.direction); -} - -bool sphere_intersect_ray(const Vector3 &origin, float radius, const Ray &ray, Vector3 &intersection) -{ - intersection = vector3_subtracted(origin, ray.origin); - const double a = vector3_dot(intersection, ray.direction); - const double d = radius * radius - (vector3_dot(intersection, intersection) - a * a); - - if (d > 0) { - intersection = vector3_added(ray.origin, vector3_scaled(ray.direction, a - sqrt(d))); - return true; - } else { - intersection = vector3_added(ray.origin, vector3_scaled(ray.direction, a)); - return false; - } -} - -void ray_intersect_ray(const Ray &ray, const Ray &other, Vector3 &intersection) -{ - intersection = vector3_subtracted(ray.origin, other.origin); - //float a = 1;//vector3_dot(ray.direction, ray.direction); // always >= 0 - double dot = vector3_dot(ray.direction, other.direction); - //float c = 1;//vector3_dot(other.direction, other.direction); // always >= 0 - double d = vector3_dot(ray.direction, intersection); - double e = vector3_dot(other.direction, intersection); - double D = 1 - dot * dot; //a*c - dot*dot; // always >= 0 - - if (D < 0.000001) { - // the lines are almost parallel - intersection = vector3_added(other.origin, vector3_scaled(other.direction, e)); - } else { - intersection = vector3_added(other.origin, vector3_scaled(other.direction, (e - dot * d) / D)); - } -} - -const Vector3 g_origin(0, 0, 0); -const float g_radius = 64; - -void point_on_sphere(Vector3 &point, const Matrix4 &device2object, const float x, const float y) -{ - Ray ray; - ray_for_device_point(ray, device2object, x, y); - sphere_intersect_ray(g_origin, g_radius, ray, point); -} - -void point_on_axis(Vector3 &point, const Vector3 &axis, const Matrix4 &device2object, const float x, const float y) -{ - Ray ray; - ray_for_device_point(ray, device2object, x, y); - ray_intersect_ray(ray, Ray(Vector3(0, 0, 0), axis), point); -} - -void point_on_plane(Vector3 &point, const Matrix4 &device2object, const float x, const float y) -{ - Matrix4 object2device(matrix4_full_inverse(device2object)); - point = vector4_projected( - matrix4_transformed_vector4(device2object, Vector4(x, y, object2device[14] / object2device[15], 1))); -} - -//! a and b are unit vectors .. returns angle in radians -inline float angle_between(const Vector3 &a, const Vector3 &b) -{ - return static_cast( 2.0 * atan2( - vector3_length(vector3_subtracted(a, b)), - vector3_length(vector3_added(a, b)) - )); -} - - -#if GDEF_DEBUG - -class test_quat { -public: -test_quat(const Vector3 &from, const Vector3 &to) -{ - Vector4 quaternion(quaternion_for_unit_vectors(from, to)); - Matrix4 matrix(matrix4_rotation_for_quaternion( - quaternion_multiplied_by_quaternion(quaternion, c_quaternion_identity))); -} - -private: -}; - -static test_quat bleh(g_vector3_axis_x, g_vector3_axis_y); -#endif - -//! axis is a unit vector -inline void constrain_to_axis(Vector3 &vec, const Vector3 &axis) -{ - vec = vector3_normalised(vector3_added(vec, vector3_scaled(axis, -vector3_dot(vec, axis)))); -} - -//! a and b are unit vectors .. a and b must be orthogonal to axis .. returns angle in radians -float angle_for_axis(const Vector3 &a, const Vector3 &b, const Vector3 &axis) -{ - if (vector3_dot(axis, vector3_cross(a, b)) > 0.0) { - return angle_between(a, b); - } else { - return -angle_between(a, b); - } -} - -float distance_for_axis(const Vector3 &a, const Vector3 &b, const Vector3 &axis) -{ - return static_cast( vector3_dot(b, axis) - vector3_dot(a, axis)); -} - -class Manipulatable { -public: -virtual void Construct(const Matrix4 &device2manip, const float x, const float y) = 0; - -virtual void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) = 0; -}; - -void transform_local2object(Matrix4 &object, const Matrix4 &local, const Matrix4 &local2object) -{ - object = matrix4_multiplied_by_matrix4( - matrix4_multiplied_by_matrix4(local2object, local), - matrix4_full_inverse(local2object) - ); -} - -class Rotatable { -public: -virtual ~Rotatable() = default; - -virtual void rotate(const Quaternion &rotation) = 0; -}; - -class RotateFree : public Manipulatable { -Vector3 m_start; -Rotatable &m_rotatable; -public: -RotateFree(Rotatable &rotatable) - : m_rotatable(rotatable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_sphere(m_start, device2manip, x, y); - vector3_normalise(m_start); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - - point_on_sphere(current, device2manip, x, y); - vector3_normalise(current); - - m_rotatable.rotate(quaternion_for_unit_vectors(m_start, current)); -} -}; - -class RotateAxis : public Manipulatable { -Vector3 m_axis; -Vector3 m_start; -Rotatable &m_rotatable; -public: -RotateAxis(Rotatable &rotatable) - : m_rotatable(rotatable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_sphere(m_start, device2manip, x, y); - constrain_to_axis(m_start, m_axis); -} - -/// \brief Converts current position to a normalised vector orthogonal to axis. -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_sphere(current, device2manip, x, y); - constrain_to_axis(current, m_axis); - - m_rotatable.rotate(quaternion_for_axisangle(m_axis, angle_for_axis(m_start, current, m_axis))); -} - -void SetAxis(const Vector3 &axis) -{ - m_axis = axis; -} -}; - -void translation_local2object(Vector3 &object, const Vector3 &local, const Matrix4 &local2object) -{ - object = matrix4_get_translation_vec3( - matrix4_multiplied_by_matrix4( - matrix4_translated_by_vec3(local2object, local), - matrix4_full_inverse(local2object) - ) - ); -} - -class Translatable { -public: -virtual ~Translatable() = default; - -virtual void translate(const Vector3 &translation) = 0; -}; - -class TranslateAxis : public Manipulatable { -Vector3 m_start; -Vector3 m_axis; -Translatable &m_translatable; -public: -TranslateAxis(Translatable &translatable) - : m_translatable(translatable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_axis(m_start, m_axis, device2manip, x, y); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_axis(current, m_axis, device2manip, x, y); - current = vector3_scaled(m_axis, distance_for_axis(m_start, current, m_axis)); - - translation_local2object(current, current, manip2object); - vector3_snap(current, GetSnapGridSize()); - - m_translatable.translate(current); -} - -void SetAxis(const Vector3 &axis) -{ - m_axis = axis; -} -}; - -class TranslateFree : public Manipulatable { -private: -Vector3 m_start; -Translatable &m_translatable; -public: -TranslateFree(Translatable &translatable) - : m_translatable(translatable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_plane(m_start, device2manip, x, y); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_plane(current, device2manip, x, y); - current = vector3_subtracted(current, m_start); - - translation_local2object(current, current, manip2object); - vector3_snap(current, GetSnapGridSize()); - - m_translatable.translate(current); -} -}; - - -class Scalable { -public: -virtual ~Scalable() = default; - -virtual void scale(const Vector3 &scaling) = 0; -}; - - -class ScaleAxis : public Manipulatable { -private: -Vector3 m_start; -Vector3 m_axis; -Scalable &m_scalable; -public: -ScaleAxis(Scalable &scalable) - : m_scalable(scalable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_axis(m_start, m_axis, device2manip, x, y); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_axis(current, m_axis, device2manip, x, y); - Vector3 delta = vector3_subtracted(current, m_start); - - translation_local2object(delta, delta, manip2object); - vector3_snap(delta, GetSnapGridSize()); - - Vector3 start(vector3_snapped(m_start, GetSnapGridSize())); - Vector3 scale( - start[0] == 0 ? 1 : 1 + delta[0] / start[0], - start[1] == 0 ? 1 : 1 + delta[1] / start[1], - start[2] == 0 ? 1 : 1 + delta[2] / start[2] - ); - m_scalable.scale(scale); -} - -void SetAxis(const Vector3 &axis) -{ - m_axis = axis; -} -}; - -class ScaleFree : public Manipulatable { -private: -Vector3 m_start; -Scalable &m_scalable; -public: -ScaleFree(Scalable &scalable) - : m_scalable(scalable) -{ -} - -void Construct(const Matrix4 &device2manip, const float x, const float y) -{ - point_on_plane(m_start, device2manip, x, y); -} - -void Transform(const Matrix4 &manip2object, const Matrix4 &device2manip, const float x, const float y) -{ - Vector3 current; - point_on_plane(current, device2manip, x, y); - Vector3 delta = vector3_subtracted(current, m_start); - - translation_local2object(delta, delta, manip2object); - vector3_snap(delta, GetSnapGridSize()); - - Vector3 start(vector3_snapped(m_start, GetSnapGridSize())); - Vector3 scale( - start[0] == 0 ? 1 : 1 + delta[0] / start[0], - start[1] == 0 ? 1 : 1 + delta[1] / start[1], - start[2] == 0 ? 1 : 1 + delta[2] / start[2] - ); - m_scalable.scale(scale); -} -}; - - -class RenderableClippedPrimitive : public OpenGLRenderable { -struct primitive_t { - PointVertex m_points[9]; - std::size_t m_count; -}; -Matrix4 m_inverse; -std::vector m_primitives; -public: -Matrix4 m_world; - -void render(RenderStateFlags state) const -{ - for (std::size_t i = 0; i < m_primitives.size(); ++i) { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_primitives[i].m_points[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_primitives[i].m_points[0].vertex); - switch (m_primitives[i].m_count) { - case 1: - break; - case 2: - glDrawArrays(GL_LINES, 0, GLsizei(m_primitives[i].m_count)); - break; - default: - glDrawArrays(GL_POLYGON, 0, GLsizei(m_primitives[i].m_count)); - break; - } - } -} - -void construct(const Matrix4 &world2device) -{ - m_inverse = matrix4_full_inverse(world2device); - m_world = g_matrix4_identity; -} - -void insert(const Vector4 clipped[9], std::size_t count) -{ - add_one(); - - m_primitives.back().m_count = count; - for (std::size_t i = 0; i < count; ++i) { - Vector3 world_point(vector4_projected(matrix4_transformed_vector4(m_inverse, clipped[i]))); - m_primitives.back().m_points[i].vertex = vertex3f_for_vector3(world_point); - } -} - -void destroy() -{ - m_primitives.clear(); -} - -private: -void add_one() -{ - m_primitives.push_back(primitive_t()); - - const Colour4b colour_clipped(255, 127, 0, 255); - - for (std::size_t i = 0; i < 9; ++i) { - m_primitives.back().m_points[i].colour = colour_clipped; - } -} -}; - -#if GDEF_DEBUG -//#define DEBUG_SELECTION -#endif - -#if defined( DEBUG_SELECTION ) -Shader *g_state_clipped; -RenderableClippedPrimitive g_render_clipped; -#endif - - -#if 0 -// dist_Point_to_Line(): get the distance of a point to a line. -// Input: a Point P and a Line L (in any dimension) -// Return: the shortest distance from P to L -float -dist_Point_to_Line( Point P, Line L ){ - Vector v = L.P1 - L.P0; - Vector w = P - L.P0; - - double c1 = dot( w,v ); - double c2 = dot( v,v ); - double b = c1 / c2; - - Point Pb = L.P0 + b * v; - return d( P, Pb ); -} -#endif - -class Segment3D { -typedef Vector3 point_type; -public: -Segment3D(const point_type &_p0, const point_type &_p1) - : p0(_p0), p1(_p1) -{ -} - -point_type p0, p1; -}; - -typedef Vector3 Point3D; - -inline double vector3_distance_squared(const Point3D &a, const Point3D &b) -{ - return vector3_length_squared(b - a); -} - -// get the distance of a point to a segment. -Point3D segment_closest_point_to_point(const Segment3D &segment, const Point3D &point) -{ - Vector3 v = segment.p1 - segment.p0; - Vector3 w = point - segment.p0; - - double c1 = vector3_dot(w, v); - if (c1 <= 0) { - return segment.p0; - } - - double c2 = vector3_dot(v, v); - if (c2 <= c1) { - return segment.p1; - } - - return Point3D(segment.p0 + v * (c1 / c2)); -} - -double segment_dist_to_point_3d(const Segment3D &segment, const Point3D &point) -{ - return vector3_distance_squared(point, segment_closest_point_to_point(segment, point)); -} - -typedef Vector3 point_t; -typedef const Vector3 *point_iterator_t; - -// crossing number test for a point in a polygon -// This code is patterned after [Franklin, 2000] -bool point_test_polygon_2d(const point_t &P, point_iterator_t start, point_iterator_t finish) -{ - std::size_t crossings = 0; - - // loop through all edges of the polygon - for (point_iterator_t prev = finish - 1, cur = start; - cur != finish; prev = cur, ++cur) { // edge from (*prev) to (*cur) - if ((((*prev)[1] <= P[1]) && ((*cur)[1] > P[1])) // an upward crossing - || (((*prev)[1] > P[1]) && ((*cur)[1] <= P[1]))) { // a downward crossing - // compute the actual edge-ray intersect x-coordinate - float vt = (float) (P[1] - (*prev)[1]) / ((*cur)[1] - (*prev)[1]); - if (P[0] < (*prev)[0] + vt * ((*cur)[0] - (*prev)[0])) { // P[0] < intersect - ++crossings; // a valid crossing of y=P[1] right of P[0] - } - } - } - return (crossings & 0x1) != 0; // 0 if even (out), and 1 if odd (in) -} - -inline double triangle_signed_area_XY(const Vector3 &p0, const Vector3 &p1, const Vector3 &p2) -{ - return ((p1[0] - p0[0]) * (p2[1] - p0[1])) - ((p2[0] - p0[0]) * (p1[1] - p0[1])); -} - -enum clipcull_t { - eClipCullNone, - eClipCullCW, - eClipCullCCW, -}; - - -inline SelectionIntersection select_point_from_clipped(Vector4 &clipped) -{ - return SelectionIntersection(clipped[2] / clipped[3], static_cast( vector3_length_squared( - Vector3(clipped[0] / clipped[3], clipped[1] / clipped[3], 0)))); -} - -void BestPoint(std::size_t count, Vector4 clipped[9], SelectionIntersection &best, clipcull_t cull) -{ - Vector3 normalised[9]; - - { - for (std::size_t i = 0; i < count; ++i) { - normalised[i][0] = clipped[i][0] / clipped[i][3]; - normalised[i][1] = clipped[i][1] / clipped[i][3]; - normalised[i][2] = clipped[i][2] / clipped[i][3]; - } - } - - if (cull != eClipCullNone && count > 2) { - double signed_area = triangle_signed_area_XY(normalised[0], normalised[1], normalised[2]); - - if ((cull == eClipCullCW && signed_area > 0) - || (cull == eClipCullCCW && signed_area < 0)) { - return; - } - } - - if (count == 2) { - Segment3D segment(normalised[0], normalised[1]); - Point3D point = segment_closest_point_to_point(segment, Vector3(0, 0, 0)); - assign_if_closer(best, SelectionIntersection(point.z(), 0)); - } else if (count > 2 && !point_test_polygon_2d(Vector3(0, 0, 0), normalised, normalised + count)) { - point_iterator_t end = normalised + count; - for (point_iterator_t previous = end - 1, current = normalised; current != end; previous = current, ++current) { - Segment3D segment(*previous, *current); - Point3D point = segment_closest_point_to_point(segment, Vector3(0, 0, 0)); - float depth = point.z(); - point.z() = 0; - float distance = static_cast( vector3_length_squared(point)); - - assign_if_closer(best, SelectionIntersection(depth, distance)); - } - } else if (count > 2) { - assign_if_closer( - best, - SelectionIntersection( - static_cast( ray_distance_to_plane( - Ray(Vector3(0, 0, 0), Vector3(0, 0, 1)), - plane3_for_points(normalised[0], normalised[1], normalised[2]) - )), - 0 - ) - ); - } - -#if defined( DEBUG_SELECTION ) - if (count >= 2) { - g_render_clipped.insert(clipped, count); - } -#endif -} - -void LineStrip_BestPoint(const Matrix4 &local2view, const PointVertex *vertices, const std::size_t size, - SelectionIntersection &best) -{ - Vector4 clipped[2]; - for (std::size_t i = 0; (i + 1) < size; ++i) { - const std::size_t count = matrix4_clip_line(local2view, vertex3f_to_vector3(vertices[i].vertex), - vertex3f_to_vector3(vertices[i + 1].vertex), clipped); - BestPoint(count, clipped, best, eClipCullNone); - } -} - -void LineLoop_BestPoint(const Matrix4 &local2view, const PointVertex *vertices, const std::size_t size, - SelectionIntersection &best) -{ - Vector4 clipped[2]; - for (std::size_t i = 0; i < size; ++i) { - const std::size_t count = matrix4_clip_line(local2view, vertex3f_to_vector3(vertices[i].vertex), - vertex3f_to_vector3(vertices[(i + 1) % size].vertex), clipped); - BestPoint(count, clipped, best, eClipCullNone); - } -} - -void Line_BestPoint(const Matrix4 &local2view, const PointVertex vertices[2], SelectionIntersection &best) -{ - Vector4 clipped[2]; - const std::size_t count = matrix4_clip_line(local2view, vertex3f_to_vector3(vertices[0].vertex), - vertex3f_to_vector3(vertices[1].vertex), clipped); - BestPoint(count, clipped, best, eClipCullNone); -} - -void Circle_BestPoint(const Matrix4 &local2view, clipcull_t cull, const PointVertex *vertices, const std::size_t size, - SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (std::size_t i = 0; i < size; ++i) { - const std::size_t count = matrix4_clip_triangle(local2view, g_vector3_identity, - vertex3f_to_vector3(vertices[i].vertex), - vertex3f_to_vector3(vertices[(i + 1) % size].vertex), clipped); - BestPoint(count, clipped, best, cull); - } -} - -void -Quad_BestPoint(const Matrix4 &local2view, clipcull_t cull, const PointVertex *vertices, SelectionIntersection &best) -{ - Vector4 clipped[9]; - { - const std::size_t count = matrix4_clip_triangle(local2view, vertex3f_to_vector3(vertices[0].vertex), - vertex3f_to_vector3(vertices[1].vertex), - vertex3f_to_vector3(vertices[3].vertex), clipped); - BestPoint(count, clipped, best, cull); - } - { - const std::size_t count = matrix4_clip_triangle(local2view, vertex3f_to_vector3(vertices[1].vertex), - vertex3f_to_vector3(vertices[2].vertex), - vertex3f_to_vector3(vertices[3].vertex), clipped); - BestPoint(count, clipped, best, cull); - } -} - -struct FlatShadedVertex { - Vertex3f vertex; - Colour4b colour; - Normal3f normal; - - FlatShadedVertex() - { - } -}; - - -typedef FlatShadedVertex *FlatShadedVertexIterator; - -void Triangles_BestPoint(const Matrix4 &local2view, clipcull_t cull, FlatShadedVertexIterator first, - FlatShadedVertexIterator last, SelectionIntersection &best) -{ - for (FlatShadedVertexIterator x(first), y(first + 1), z(first + 2); x != last; x += 3, y += 3, z += 3) { - Vector4 clipped[9]; - BestPoint( - matrix4_clip_triangle( - local2view, - reinterpret_cast((*x).vertex ), - reinterpret_cast((*y).vertex ), - reinterpret_cast((*z).vertex ), - clipped - ), - clipped, - best, - cull - ); - } -} - - -typedef std::multimap SelectableSortedSet; - -class SelectionPool : public Selector { -SelectableSortedSet m_pool; -SelectionIntersection m_intersection; -Selectable *m_selectable; - -public: -void pushSelectable(Selectable &selectable) -{ - m_intersection = SelectionIntersection(); - m_selectable = &selectable; -} - -void popSelectable() -{ - addSelectable(m_intersection, m_selectable); - m_intersection = SelectionIntersection(); -} - -void addIntersection(const SelectionIntersection &intersection) -{ - assign_if_closer(m_intersection, intersection); -} - -void addSelectable(const SelectionIntersection &intersection, Selectable *selectable) -{ - if (intersection.valid()) { - m_pool.insert(SelectableSortedSet::value_type(intersection, selectable)); - } -} - -typedef SelectableSortedSet::iterator iterator; - -iterator begin() -{ - return m_pool.begin(); -} - -iterator end() -{ - return m_pool.end(); -} - -bool failed() -{ - return m_pool.empty(); -} -}; - - -const Colour4b g_colour_sphere(0, 0, 0, 255); -const Colour4b g_colour_screen(0, 255, 255, 255); -const Colour4b g_colour_selected(255, 255, 0, 255); - -inline const Colour4b &colourSelected(const Colour4b &colour, bool selected) -{ - return (selected) ? g_colour_selected : colour; -} - -template -inline void draw_semicircle(const std::size_t segments, const float radius, PointVertex *vertices, remap_policy remap) -{ - const double increment = c_pi / double(segments << 2); - - std::size_t count = 0; - float x = radius; - float y = 0; - remap_policy::set(vertices[segments << 2].vertex, -radius, 0, 0); - while (count < segments) { - PointVertex *i = vertices + count; - PointVertex *j = vertices + ((segments << 1) - (count + 1)); - - PointVertex *k = i + (segments << 1); - PointVertex *l = j + (segments << 1); - -#if 0 - PointVertex* m = i + ( segments << 2 ); - PointVertex* n = j + ( segments << 2 ); - PointVertex* o = k + ( segments << 2 ); - PointVertex* p = l + ( segments << 2 ); -#endif - - remap_policy::set(i->vertex, x, -y, 0); - remap_policy::set(k->vertex, -y, -x, 0); -#if 0 - remap_policy::set( m->vertex,-x, y, 0 ); - remap_policy::set( o->vertex, y, x, 0 ); -#endif - - ++count; - - { - const double theta = increment * count; - x = static_cast( radius * cos(theta)); - y = static_cast( radius * sin(theta)); - } - - remap_policy::set(j->vertex, y, -x, 0); - remap_policy::set(l->vertex, -x, -y, 0); -#if 0 - remap_policy::set( n->vertex,-y, x, 0 ); - remap_policy::set( p->vertex, x, y, 0 ); -#endif - } -} - -class Manipulator { -public: -virtual Manipulatable *GetManipulatable() = 0; - -virtual void testSelect(const View &view, const Matrix4 &pivot2world) -{ -} - -virtual void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &pivot2world) -{ -} - -virtual void setSelected(bool select) = 0; - -virtual bool isSelected() const = 0; -}; - - -inline Vector3 normalised_safe(const Vector3 &self) -{ - if (vector3_equal(self, g_vector3_identity)) { - return g_vector3_identity; - } - return vector3_normalised(self); -} - - -class RotateManipulator : public Manipulator { -struct RenderableCircle : public OpenGLRenderable { - Array m_vertices; - - RenderableCircle(std::size_t size) : m_vertices(size) - { - } - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_vertices.data()->vertex); - glDrawArrays(GL_LINE_LOOP, 0, GLsizei(m_vertices.size())); - } - - void setColour(const Colour4b &colour) - { - for (Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - (*i).colour = colour; - } - } -}; - -struct RenderableSemiCircle : public OpenGLRenderable { - Array m_vertices; - - RenderableSemiCircle(std::size_t size) : m_vertices(size) - { - } - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_vertices.data()->vertex); - glDrawArrays(GL_LINE_STRIP, 0, GLsizei(m_vertices.size())); - } - - void setColour(const Colour4b &colour) - { - for (Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - (*i).colour = colour; - } - } -}; - -RotateFree m_free; -RotateAxis m_axis; -Vector3 m_axis_screen; -RenderableSemiCircle m_circle_x; -RenderableSemiCircle m_circle_y; -RenderableSemiCircle m_circle_z; -RenderableCircle m_circle_screen; -RenderableCircle m_circle_sphere; -SelectableBool m_selectable_x; -SelectableBool m_selectable_y; -SelectableBool m_selectable_z; -SelectableBool m_selectable_screen; -SelectableBool m_selectable_sphere; -Pivot2World m_pivot; -Matrix4 m_local2world_x; -Matrix4 m_local2world_y; -Matrix4 m_local2world_z; -bool m_circle_x_visible; -bool m_circle_y_visible; -bool m_circle_z_visible; -public: -static Shader *m_state_outer; - -RotateManipulator(Rotatable &rotatable, std::size_t segments, float radius) : - m_free(rotatable), - m_axis(rotatable), - m_circle_x((segments << 2) + 1), - m_circle_y((segments << 2) + 1), - m_circle_z((segments << 2) + 1), - m_circle_screen(segments << 3), - m_circle_sphere(segments << 3) -{ - draw_semicircle(segments, radius, m_circle_x.m_vertices.data(), RemapYZX()); - draw_semicircle(segments, radius, m_circle_y.m_vertices.data(), RemapZXY()); - draw_semicircle(segments, radius, m_circle_z.m_vertices.data(), RemapXYZ()); - - draw_circle(segments, radius * 1.15f, m_circle_screen.m_vertices.data(), RemapXYZ()); - draw_circle(segments, radius, m_circle_sphere.m_vertices.data(), RemapXYZ()); -} - - -void UpdateColours() -{ - m_circle_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected())); - m_circle_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected())); - m_circle_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected())); - m_circle_screen.setColour(colourSelected(g_colour_screen, m_selectable_screen.isSelected())); - m_circle_sphere.setColour(colourSelected(g_colour_sphere, false)); -} - -void updateCircleTransforms() -{ - Vector3 localViewpoint(matrix4_transformed_direction(matrix4_transposed(m_pivot.m_worldSpace), - vector4_to_vector3(m_pivot.m_viewpointSpace.z()))); - - m_circle_x_visible = !vector3_equal_epsilon(g_vector3_axis_x, localViewpoint, 1e-6f); - if (m_circle_x_visible) { - m_local2world_x = g_matrix4_identity; - vector4_to_vector3(m_local2world_x.y()) = normalised_safe( - vector3_cross(g_vector3_axis_x, localViewpoint) - ); - vector4_to_vector3(m_local2world_x.z()) = normalised_safe( - vector3_cross(vector4_to_vector3(m_local2world_x.x()), vector4_to_vector3(m_local2world_x.y())) - ); - matrix4_premultiply_by_matrix4(m_local2world_x, m_pivot.m_worldSpace); - } - - m_circle_y_visible = !vector3_equal_epsilon(g_vector3_axis_y, localViewpoint, 1e-6f); - if (m_circle_y_visible) { - m_local2world_y = g_matrix4_identity; - vector4_to_vector3(m_local2world_y.z()) = normalised_safe( - vector3_cross(g_vector3_axis_y, localViewpoint) - ); - vector4_to_vector3(m_local2world_y.x()) = normalised_safe( - vector3_cross(vector4_to_vector3(m_local2world_y.y()), vector4_to_vector3(m_local2world_y.z())) - ); - matrix4_premultiply_by_matrix4(m_local2world_y, m_pivot.m_worldSpace); - } - - m_circle_z_visible = !vector3_equal_epsilon(g_vector3_axis_z, localViewpoint, 1e-6f); - if (m_circle_z_visible) { - m_local2world_z = g_matrix4_identity; - vector4_to_vector3(m_local2world_z.x()) = normalised_safe( - vector3_cross(g_vector3_axis_z, localViewpoint) - ); - vector4_to_vector3(m_local2world_z.y()) = normalised_safe( - vector3_cross(vector4_to_vector3(m_local2world_z.z()), vector4_to_vector3(m_local2world_z.x())) - ); - matrix4_premultiply_by_matrix4(m_local2world_z, m_pivot.m_worldSpace); - } -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport()); - updateCircleTransforms(); - - // temp hack - UpdateColours(); - - renderer.SetState(m_state_outer, Renderer::eWireframeOnly); - renderer.SetState(m_state_outer, Renderer::eFullMaterials); - - renderer.addRenderable(m_circle_screen, m_pivot.m_viewpointSpace); - renderer.addRenderable(m_circle_sphere, m_pivot.m_viewpointSpace); - - if (m_circle_x_visible) { - renderer.addRenderable(m_circle_x, m_local2world_x); - } - if (m_circle_y_visible) { - renderer.addRenderable(m_circle_y, m_local2world_y); - } - if (m_circle_z_visible) { - renderer.addRenderable(m_circle_z, m_local2world_z); - } -} - -void testSelect(const View &view, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport()); - updateCircleTransforms(); - - SelectionPool selector; - - { - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_x)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - SelectionIntersection best; - LineStrip_BestPoint(local2view, m_circle_x.m_vertices.data(), m_circle_x.m_vertices.size(), best); - selector.addSelectable(best, &m_selectable_x); - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_y)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - SelectionIntersection best; - LineStrip_BestPoint(local2view, m_circle_y.m_vertices.data(), m_circle_y.m_vertices.size(), best); - selector.addSelectable(best, &m_selectable_y); - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_z)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - SelectionIntersection best; - LineStrip_BestPoint(local2view, m_circle_z.m_vertices.data(), m_circle_z.m_vertices.size(), best); - selector.addSelectable(best, &m_selectable_z); - } - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace)); - - { - SelectionIntersection best; - LineLoop_BestPoint(local2view, m_circle_screen.m_vertices.data(), m_circle_screen.m_vertices.size(), - best); - selector.addSelectable(best, &m_selectable_screen); - } - - { - SelectionIntersection best; - Circle_BestPoint(local2view, eClipCullCW, m_circle_sphere.m_vertices.data(), - m_circle_sphere.m_vertices.size(), best); - selector.addSelectable(best, &m_selectable_sphere); - } - } - - m_axis_screen = m_pivot.m_axis_screen; - - if (!selector.failed()) { - (*selector.begin()).second->setSelected(true); - } -} - -Manipulatable *GetManipulatable() -{ - if (m_selectable_x.isSelected()) { - m_axis.SetAxis(g_vector3_axis_x); - return &m_axis; - } else if (m_selectable_y.isSelected()) { - m_axis.SetAxis(g_vector3_axis_y); - return &m_axis; - } else if (m_selectable_z.isSelected()) { - m_axis.SetAxis(g_vector3_axis_z); - return &m_axis; - } else if (m_selectable_screen.isSelected()) { - m_axis.SetAxis(m_axis_screen); - return &m_axis; - } else { - return &m_free; - } -} - -void setSelected(bool select) -{ - m_selectable_x.setSelected(select); - m_selectable_y.setSelected(select); - m_selectable_z.setSelected(select); - m_selectable_screen.setSelected(select); -} - -bool isSelected() const -{ - return m_selectable_x.isSelected() - | m_selectable_y.isSelected() - | m_selectable_z.isSelected() - | m_selectable_screen.isSelected() - | m_selectable_sphere.isSelected(); -} -}; - -Shader *RotateManipulator::m_state_outer; - - -const float arrowhead_length = 16; -const float arrowhead_radius = 4; - -inline void draw_arrowline(const float length, PointVertex *line, const std::size_t axis) -{ - (*line++).vertex = vertex3f_identity; - (*line).vertex = vertex3f_identity; - vertex3f_to_array((*line).vertex)[axis] = length - arrowhead_length; -} - -template -inline void -draw_arrowhead(const std::size_t segments, const float length, FlatShadedVertex *vertices, VertexRemap, NormalRemap) -{ - std::size_t head_tris = (segments << 3); - const double head_segment = c_2pi / head_tris; - for (std::size_t i = 0; i < head_tris; ++i) { - { - FlatShadedVertex &point = vertices[i * 6 + 0]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = arrowhead_radius * static_cast( cos(i * head_segment)); - VertexRemap::z(point.vertex) = arrowhead_radius * static_cast( sin(i * head_segment)); - NormalRemap::x(point.normal) = arrowhead_radius / arrowhead_length; - NormalRemap::y(point.normal) = static_cast( cos(i * head_segment)); - NormalRemap::z(point.normal) = static_cast( sin(i * head_segment)); - } - { - FlatShadedVertex &point = vertices[i * 6 + 1]; - VertexRemap::x(point.vertex) = length; - VertexRemap::y(point.vertex) = 0; - VertexRemap::z(point.vertex) = 0; - NormalRemap::x(point.normal) = arrowhead_radius / arrowhead_length; - NormalRemap::y(point.normal) = static_cast( cos((i + 0.5) * head_segment)); - NormalRemap::z(point.normal) = static_cast( sin((i + 0.5) * head_segment)); - } - { - FlatShadedVertex &point = vertices[i * 6 + 2]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = arrowhead_radius * static_cast( cos((i + 1) * head_segment)); - VertexRemap::z(point.vertex) = arrowhead_radius * static_cast( sin((i + 1) * head_segment)); - NormalRemap::x(point.normal) = arrowhead_radius / arrowhead_length; - NormalRemap::y(point.normal) = static_cast( cos((i + 1) * head_segment)); - NormalRemap::z(point.normal) = static_cast( sin((i + 1) * head_segment)); - } - - { - FlatShadedVertex &point = vertices[i * 6 + 3]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = 0; - VertexRemap::z(point.vertex) = 0; - NormalRemap::x(point.normal) = -1; - NormalRemap::y(point.normal) = 0; - NormalRemap::z(point.normal) = 0; - } - { - FlatShadedVertex &point = vertices[i * 6 + 4]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = arrowhead_radius * static_cast( cos(i * head_segment)); - VertexRemap::z(point.vertex) = arrowhead_radius * static_cast( sin(i * head_segment)); - NormalRemap::x(point.normal) = -1; - NormalRemap::y(point.normal) = 0; - NormalRemap::z(point.normal) = 0; - } - { - FlatShadedVertex &point = vertices[i * 6 + 5]; - VertexRemap::x(point.vertex) = length - arrowhead_length; - VertexRemap::y(point.vertex) = arrowhead_radius * static_cast( cos((i + 1) * head_segment)); - VertexRemap::z(point.vertex) = arrowhead_radius * static_cast( sin((i + 1) * head_segment)); - NormalRemap::x(point.normal) = -1; - NormalRemap::y(point.normal) = 0; - NormalRemap::z(point.normal) = 0; - } - } -} - -template -class TripleRemapXYZ { -public: -static float &x(Triple &triple) -{ - return triple.x(); -} - -static float &y(Triple &triple) -{ - return triple.y(); -} - -static float &z(Triple &triple) -{ - return triple.z(); -} -}; - -template -class TripleRemapYZX { -public: -static float &x(Triple &triple) -{ - return triple.y(); -} - -static float &y(Triple &triple) -{ - return triple.z(); -} - -static float &z(Triple &triple) -{ - return triple.x(); -} -}; - -template -class TripleRemapZXY { -public: -static float &x(Triple &triple) -{ - return triple.z(); -} - -static float &y(Triple &triple) -{ - return triple.x(); -} - -static float &z(Triple &triple) -{ - return triple.y(); -} -}; - -void vector3_print(const Vector3 &v) -{ - globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )"; -} - -class TranslateManipulator : public Manipulator { -struct RenderableArrowLine : public OpenGLRenderable { - PointVertex m_line[2]; - - RenderableArrowLine() - { - } - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_line[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_line[0].vertex); - glDrawArrays(GL_LINES, 0, 2); - } - - void setColour(const Colour4b &colour) - { - m_line[0].colour = colour; - m_line[1].colour = colour; - } -}; - -struct RenderableArrowHead : public OpenGLRenderable { - Array m_vertices; - - RenderableArrowHead(std::size_t size) - : m_vertices(size) - { - } - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FlatShadedVertex), &m_vertices.data()->colour); - glVertexPointer(3, GL_FLOAT, sizeof(FlatShadedVertex), &m_vertices.data()->vertex); - glNormalPointer(GL_FLOAT, sizeof(FlatShadedVertex), &m_vertices.data()->normal); - glDrawArrays(GL_TRIANGLES, 0, GLsizei(m_vertices.size())); - } - - void setColour(const Colour4b &colour) - { - for (Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) { - (*i).colour = colour; - } - } -}; - -struct RenderableQuad : public OpenGLRenderable { - PointVertex m_quad[4]; - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_quad[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_quad[0].vertex); - glDrawArrays(GL_LINE_LOOP, 0, 4); - } - - void setColour(const Colour4b &colour) - { - m_quad[0].colour = colour; - m_quad[1].colour = colour; - m_quad[2].colour = colour; - m_quad[3].colour = colour; - } -}; - -TranslateFree m_free; -TranslateAxis m_axis; -RenderableArrowLine m_arrow_x; -RenderableArrowLine m_arrow_y; -RenderableArrowLine m_arrow_z; -RenderableArrowHead m_arrow_head_x; -RenderableArrowHead m_arrow_head_y; -RenderableArrowHead m_arrow_head_z; -RenderableQuad m_quad_screen; -SelectableBool m_selectable_x; -SelectableBool m_selectable_y; -SelectableBool m_selectable_z; -SelectableBool m_selectable_screen; -Pivot2World m_pivot; -public: -static Shader *m_state_wire; -static Shader *m_state_fill; - -TranslateManipulator(Translatable &translatable, std::size_t segments, float length) : - m_free(translatable), - m_axis(translatable), - m_arrow_head_x(3 * 2 * (segments << 3)), - m_arrow_head_y(3 * 2 * (segments << 3)), - m_arrow_head_z(3 * 2 * (segments << 3)) -{ - draw_arrowline(length, m_arrow_x.m_line, 0); - draw_arrowhead(segments, length, m_arrow_head_x.m_vertices.data(), TripleRemapXYZ(), - TripleRemapXYZ()); - draw_arrowline(length, m_arrow_y.m_line, 1); - draw_arrowhead(segments, length, m_arrow_head_y.m_vertices.data(), TripleRemapYZX(), - TripleRemapYZX()); - draw_arrowline(length, m_arrow_z.m_line, 2); - draw_arrowhead(segments, length, m_arrow_head_z.m_vertices.data(), TripleRemapZXY(), - TripleRemapZXY()); - - draw_quad(16, m_quad_screen.m_quad); -} - -void UpdateColours() -{ - m_arrow_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected())); - m_arrow_head_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected())); - m_arrow_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected())); - m_arrow_head_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected())); - m_arrow_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected())); - m_arrow_head_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected())); - m_quad_screen.setColour(colourSelected(g_colour_screen, m_selectable_screen.isSelected())); -} - -bool manipulator_show_axis(const Pivot2World &pivot, const Vector3 &axis) -{ - return fabs(vector3_dot(pivot.m_axis_screen, axis)) < 0.95; -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport()); - - // temp hack - UpdateColours(); - - Vector3 x = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.x())); - bool show_x = manipulator_show_axis(m_pivot, x); - - Vector3 y = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.y())); - bool show_y = manipulator_show_axis(m_pivot, y); - - Vector3 z = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.z())); - bool show_z = manipulator_show_axis(m_pivot, z); - - renderer.SetState(m_state_wire, Renderer::eWireframeOnly); - renderer.SetState(m_state_wire, Renderer::eFullMaterials); - - if (show_x) { - renderer.addRenderable(m_arrow_x, m_pivot.m_worldSpace); - } - if (show_y) { - renderer.addRenderable(m_arrow_y, m_pivot.m_worldSpace); - } - if (show_z) { - renderer.addRenderable(m_arrow_z, m_pivot.m_worldSpace); - } - - renderer.addRenderable(m_quad_screen, m_pivot.m_viewplaneSpace); - - renderer.SetState(m_state_fill, Renderer::eWireframeOnly); - renderer.SetState(m_state_fill, Renderer::eFullMaterials); - - if (show_x) { - renderer.addRenderable(m_arrow_head_x, m_pivot.m_worldSpace); - } - if (show_y) { - renderer.addRenderable(m_arrow_head_y, m_pivot.m_worldSpace); - } - if (show_z) { - renderer.addRenderable(m_arrow_head_z, m_pivot.m_worldSpace); - } -} - -void testSelect(const View &view, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport()); - - SelectionPool selector; - - Vector3 x = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.x())); - bool show_x = manipulator_show_axis(m_pivot, x); - - Vector3 y = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.y())); - bool show_y = manipulator_show_axis(m_pivot, y); - - Vector3 z = vector3_normalised(vector4_to_vector3(m_pivot.m_worldSpace.z())); - bool show_z = manipulator_show_axis(m_pivot, z); - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace)); - - { - SelectionIntersection best; - Quad_BestPoint(local2view, eClipCullCW, m_quad_screen.m_quad, best); - if (best.valid()) { - best = SelectionIntersection(0, 0); - selector.addSelectable(best, &m_selectable_screen); - } - } - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_worldSpace)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - if (show_x) { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_x.m_line, best); - Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_x.m_vertices.begin(), - m_arrow_head_x.m_vertices.end(), best); - selector.addSelectable(best, &m_selectable_x); - } - - if (show_y) { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_y.m_line, best); - Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_y.m_vertices.begin(), - m_arrow_head_y.m_vertices.end(), best); - selector.addSelectable(best, &m_selectable_y); - } - - if (show_z) { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_z.m_line, best); - Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_z.m_vertices.begin(), - m_arrow_head_z.m_vertices.end(), best); - selector.addSelectable(best, &m_selectable_z); - } - } - - if (!selector.failed()) { - (*selector.begin()).second->setSelected(true); - } -} - -Manipulatable *GetManipulatable() -{ - if (m_selectable_x.isSelected()) { - m_axis.SetAxis(g_vector3_axis_x); - return &m_axis; - } else if (m_selectable_y.isSelected()) { - m_axis.SetAxis(g_vector3_axis_y); - return &m_axis; - } else if (m_selectable_z.isSelected()) { - m_axis.SetAxis(g_vector3_axis_z); - return &m_axis; - } else { - return &m_free; - } -} - -void setSelected(bool select) -{ - m_selectable_x.setSelected(select); - m_selectable_y.setSelected(select); - m_selectable_z.setSelected(select); - m_selectable_screen.setSelected(select); -} - -bool isSelected() const -{ - return m_selectable_x.isSelected() - | m_selectable_y.isSelected() - | m_selectable_z.isSelected() - | m_selectable_screen.isSelected(); -} -}; - -Shader *TranslateManipulator::m_state_wire; -Shader *TranslateManipulator::m_state_fill; - -class ScaleManipulator : public Manipulator { -struct RenderableArrow : public OpenGLRenderable { - PointVertex m_line[2]; - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_line[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_line[0].vertex); - glDrawArrays(GL_LINES, 0, 2); - } - - void setColour(const Colour4b &colour) - { - m_line[0].colour = colour; - m_line[1].colour = colour; - } -}; - -struct RenderableQuad : public OpenGLRenderable { - PointVertex m_quad[4]; - - void render(RenderStateFlags state) const - { - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_quad[0].colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_quad[0].vertex); - glDrawArrays(GL_QUADS, 0, 4); - } - - void setColour(const Colour4b &colour) - { - m_quad[0].colour = colour; - m_quad[1].colour = colour; - m_quad[2].colour = colour; - m_quad[3].colour = colour; - } -}; - -ScaleFree m_free; -ScaleAxis m_axis; -RenderableArrow m_arrow_x; -RenderableArrow m_arrow_y; -RenderableArrow m_arrow_z; -RenderableQuad m_quad_screen; -SelectableBool m_selectable_x; -SelectableBool m_selectable_y; -SelectableBool m_selectable_z; -SelectableBool m_selectable_screen; -Pivot2World m_pivot; -public: -ScaleManipulator(Scalable &scalable, std::size_t segments, float length) : - m_free(scalable), - m_axis(scalable) -{ - draw_arrowline(length, m_arrow_x.m_line, 0); - draw_arrowline(length, m_arrow_y.m_line, 1); - draw_arrowline(length, m_arrow_z.m_line, 2); - - draw_quad(16, m_quad_screen.m_quad); -} - -Pivot2World &getPivot() -{ - return m_pivot; -} - -void UpdateColours() -{ - m_arrow_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected())); - m_arrow_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected())); - m_arrow_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected())); - m_quad_screen.setColour(colourSelected(g_colour_screen, m_selectable_screen.isSelected())); -} - -void render(Renderer &renderer, const VolumeTest &volume, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport()); - - // temp hack - UpdateColours(); - - renderer.addRenderable(m_arrow_x, m_pivot.m_worldSpace); - renderer.addRenderable(m_arrow_y, m_pivot.m_worldSpace); - renderer.addRenderable(m_arrow_z, m_pivot.m_worldSpace); - - renderer.addRenderable(m_quad_screen, m_pivot.m_viewpointSpace); -} - -void testSelect(const View &view, const Matrix4 &pivot2world) -{ - m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport()); - - SelectionPool selector; - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_worldSpace)); - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(view.GetViewMatrix()); -#endif - - { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_x.m_line, best); - selector.addSelectable(best, &m_selectable_x); - } - - { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_y.m_line, best); - selector.addSelectable(best, &m_selectable_y); - } - - { - SelectionIntersection best; - Line_BestPoint(local2view, m_arrow_z.m_line, best); - selector.addSelectable(best, &m_selectable_z); - } - } - - { - Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace)); - - { - SelectionIntersection best; - Quad_BestPoint(local2view, eClipCullCW, m_quad_screen.m_quad, best); - selector.addSelectable(best, &m_selectable_screen); - } - } - - if (!selector.failed()) { - (*selector.begin()).second->setSelected(true); - } -} - -Manipulatable *GetManipulatable() -{ - if (m_selectable_x.isSelected()) { - m_axis.SetAxis(g_vector3_axis_x); - return &m_axis; - } else if (m_selectable_y.isSelected()) { - m_axis.SetAxis(g_vector3_axis_y); - return &m_axis; - } else if (m_selectable_z.isSelected()) { - m_axis.SetAxis(g_vector3_axis_z); - return &m_axis; - } else { - return &m_free; - } -} - -void setSelected(bool select) -{ - m_selectable_x.setSelected(select); - m_selectable_y.setSelected(select); - m_selectable_z.setSelected(select); - m_selectable_screen.setSelected(select); -} - -bool isSelected() const -{ - return m_selectable_x.isSelected() - | m_selectable_y.isSelected() - | m_selectable_z.isSelected() - | m_selectable_screen.isSelected(); -} -}; - - -inline PlaneSelectable *Instance_getPlaneSelectable(scene::Instance &instance) -{ - return InstanceTypeCast::cast(instance); -} - -class PlaneSelectableSelectPlanes : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -PlaneCallback m_selectedPlaneCallback; -public: -PlaneSelectableSelectPlanes(Selector &selector, SelectionTest &test, const PlaneCallback &selectedPlaneCallback) - : m_selector(selector), m_test(test), m_selectedPlaneCallback(selectedPlaneCallback) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 && selectable->isSelected()) { - PlaneSelectable *planeSelectable = Instance_getPlaneSelectable(instance); - if (planeSelectable != 0) { - planeSelectable->selectPlanes(m_selector, m_test, m_selectedPlaneCallback); - } - } - } - return true; -} -}; - -class PlaneSelectableSelectReversedPlanes : public scene::Graph::Walker { -Selector &m_selector; -const SelectedPlanes &m_selectedPlanes; -public: -PlaneSelectableSelectReversedPlanes(Selector &selector, const SelectedPlanes &selectedPlanes) - : m_selector(selector), m_selectedPlanes(selectedPlanes) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 && selectable->isSelected()) { - PlaneSelectable *planeSelectable = Instance_getPlaneSelectable(instance); - if (planeSelectable != 0) { - planeSelectable->selectReversedPlanes(m_selector, m_selectedPlanes); - } - } - } - return true; -} -}; - -void Scene_forEachPlaneSelectable_selectPlanes(scene::Graph &graph, Selector &selector, SelectionTest &test, - const PlaneCallback &selectedPlaneCallback) -{ - graph.traverse(PlaneSelectableSelectPlanes(selector, test, selectedPlaneCallback)); -} - -void Scene_forEachPlaneSelectable_selectReversedPlanes(scene::Graph &graph, Selector &selector, - const SelectedPlanes &selectedPlanes) -{ - graph.traverse(PlaneSelectableSelectReversedPlanes(selector, selectedPlanes)); -} - - -class PlaneLess { -public: -bool operator()(const Plane3 &plane, const Plane3 &other) const -{ - if (plane.a < other.a) { - return true; - } - if (other.a < plane.a) { - return false; - } - - if (plane.b < other.b) { - return true; - } - if (other.b < plane.b) { - return false; - } - - if (plane.c < other.c) { - return true; - } - if (other.c < plane.c) { - return false; - } - - if (plane.d < other.d) { - return true; - } - if (other.d < plane.d) { - return false; - } - - return false; -} -}; - -typedef std::set PlaneSet; - -inline void PlaneSet_insert(PlaneSet &self, const Plane3 &plane) -{ - self.insert(plane); -} - -inline bool PlaneSet_contains(const PlaneSet &self, const Plane3 &plane) -{ - return self.find(plane) != self.end(); -} - - -class SelectedPlaneSet : public SelectedPlanes { -PlaneSet m_selectedPlanes; -public: -bool empty() const -{ - return m_selectedPlanes.empty(); -} - -void insert(const Plane3 &plane) -{ - PlaneSet_insert(m_selectedPlanes, plane); -} - -bool contains(const Plane3 &plane) const -{ - return PlaneSet_contains(m_selectedPlanes, plane); -} - -typedef MemberCaller InsertCaller; -}; - - -bool Scene_forEachPlaneSelectable_selectPlanes(scene::Graph &graph, Selector &selector, SelectionTest &test) -{ - SelectedPlaneSet selectedPlanes; - - Scene_forEachPlaneSelectable_selectPlanes(graph, selector, test, SelectedPlaneSet::InsertCaller(selectedPlanes)); - Scene_forEachPlaneSelectable_selectReversedPlanes(graph, selector, selectedPlanes); - - return !selectedPlanes.empty(); -} - -void Scene_Translate_Component_Selected(scene::Graph &graph, const Vector3 &translation); - -void Scene_Translate_Selected(scene::Graph &graph, const Vector3 &translation); - -void Scene_TestSelect_Primitive(Selector &selector, SelectionTest &test, const VolumeTest &volume); - -void Scene_TestSelect_Component(Selector &selector, SelectionTest &test, const VolumeTest &volume, - SelectionSystem::EComponentMode componentMode); - -void Scene_TestSelect_Component_Selected(Selector &selector, SelectionTest &test, const VolumeTest &volume, - SelectionSystem::EComponentMode componentMode); - -void Scene_SelectAll_Component(bool select, SelectionSystem::EComponentMode componentMode); - -class ResizeTranslatable : public Translatable { -void translate(const Vector3 &translation) -{ - Scene_Translate_Component_Selected(GlobalSceneGraph(), translation); -} -}; - -class DragTranslatable : public Translatable { -void translate(const Vector3 &translation) -{ - if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { - Scene_Translate_Component_Selected(GlobalSceneGraph(), translation); - } else { - Scene_Translate_Selected(GlobalSceneGraph(), translation); - } -} -}; - -class SelectionVolume : public SelectionTest { -Matrix4 m_local2view; -const View &m_view; -clipcull_t m_cull; -Vector3 m_near; -Vector3 m_far; -public: -SelectionVolume(const View &view) - : m_view(view) -{ -} - -const VolumeTest &getVolume() const -{ - return m_view; -} - -const Vector3 &getNear() const -{ - return m_near; -} - -const Vector3 &getFar() const -{ - return m_far; -} - -void BeginMesh(const Matrix4 &localToWorld, bool twoSided) -{ - m_local2view = matrix4_multiplied_by_matrix4(m_view.GetViewMatrix(), localToWorld); - - // Cull back-facing polygons based on winding being clockwise or counter-clockwise. - // Don't cull if the view is wireframe and the polygons are two-sided. - m_cull = twoSided && !m_view.fill() ? eClipCullNone : (matrix4_handedness(localToWorld) == MATRIX4_RIGHTHANDED) - ? eClipCullCW : eClipCullCCW; - - { - Matrix4 screen2world(matrix4_full_inverse(m_local2view)); - - m_near = vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(0, 0, -1, 1) - ) - ); - - m_far = vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(0, 0, 1, 1) - ) - ); - } - -#if defined( DEBUG_SELECTION ) - g_render_clipped.construct(m_view.GetViewMatrix()); -#endif -} - -void TestPoint(const Vector3 &point, SelectionIntersection &best) -{ - Vector4 clipped; - if (matrix4_clip_point(m_local2view, point, clipped) == c_CLIP_PASS) { - best = select_point_from_clipped(clipped); - } -} - -void TestPolygon(const VertexPointer &vertices, std::size_t count, SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (std::size_t i = 0; i + 2 < count; ++i) { - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[0] ), - reinterpret_cast( vertices[i + 1] ), - reinterpret_cast( vertices[i + 2] ), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestLineLoop(const VertexPointer &vertices, std::size_t count, SelectionIntersection &best) -{ - if (count == 0) { - return; - } - Vector4 clipped[9]; - for (VertexPointer::iterator i = vertices.begin(), end = i + count, prev = i + (count - 1); - i != end; prev = i, ++i) { - BestPoint( - matrix4_clip_line( - m_local2view, - reinterpret_cast((*prev)), - reinterpret_cast((*i)), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestLineStrip(const VertexPointer &vertices, std::size_t count, SelectionIntersection &best) -{ - if (count == 0) { - return; - } - Vector4 clipped[9]; - for (VertexPointer::iterator i = vertices.begin(), end = i + count, next = i + 1; - next != end; i = next, ++next) { - BestPoint( - matrix4_clip_line( - m_local2view, - reinterpret_cast((*i)), - reinterpret_cast((*next)), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestLines(const VertexPointer &vertices, std::size_t count, SelectionIntersection &best) -{ - if (count == 0) { - return; - } - Vector4 clipped[9]; - for (VertexPointer::iterator i = vertices.begin(), end = i + count; i != end; i += 2) { - BestPoint( - matrix4_clip_line( - m_local2view, - reinterpret_cast((*i)), - reinterpret_cast((*(i + 1))), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestTriangles(const VertexPointer &vertices, const IndexPointer &indices, SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (IndexPointer::iterator i(indices.begin()); i != indices.end(); i += 3) { - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*i] ), - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 2)] ), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestQuads(const VertexPointer &vertices, const IndexPointer &indices, SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (IndexPointer::iterator i(indices.begin()); i != indices.end(); i += 4) { - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*i] ), - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 3)] ), - clipped - ), - clipped, - best, - m_cull - ); - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 2)] ), - reinterpret_cast( vertices[*(i + 3)] ), - clipped - ), - clipped, - best, - m_cull - ); - } -} - -void TestQuadStrip(const VertexPointer &vertices, const IndexPointer &indices, SelectionIntersection &best) -{ - Vector4 clipped[9]; - for (IndexPointer::iterator i(indices.begin()); i + 2 != indices.end(); i += 2) { - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*i] ), - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 2)] ), - clipped - ), - clipped, - best, - m_cull - ); - BestPoint( - matrix4_clip_triangle( - m_local2view, - reinterpret_cast( vertices[*(i + 2)] ), - reinterpret_cast( vertices[*(i + 1)] ), - reinterpret_cast( vertices[*(i + 3)] ), - clipped - ), - clipped, - best, - m_cull - ); - } -} -}; - -class SelectionCounter { -public: -using func = void (const Selectable &); - -SelectionCounter(const SelectionChangeCallback &onchanged) - : m_count(0), m_onchanged(onchanged) -{ -} - -void operator()(const Selectable &selectable) -{ - if (selectable.isSelected()) { - ++m_count; - } else { - ASSERT_MESSAGE(m_count != 0, "selection counter underflow"); - --m_count; - } - - m_onchanged(selectable); -} - -bool empty() const -{ - return m_count == 0; -} - -std::size_t size() const -{ - return m_count; -} - -private: -std::size_t m_count; -SelectionChangeCallback m_onchanged; -}; - -inline void ConstructSelectionTest(View &view, const rect_t selection_box) -{ - view.EnableScissor(selection_box.min[0], selection_box.max[0], selection_box.min[1], selection_box.max[1]); -} - -inline const rect_t SelectionBoxForPoint(const float device_point[2], const float device_epsilon[2]) -{ - rect_t selection_box; - selection_box.min[0] = device_point[0] - device_epsilon[0]; - selection_box.min[1] = device_point[1] - device_epsilon[1]; - selection_box.max[0] = device_point[0] + device_epsilon[0]; - selection_box.max[1] = device_point[1] + device_epsilon[1]; - return selection_box; -} - -inline const rect_t SelectionBoxForArea(const float device_point[2], const float device_delta[2]) -{ - rect_t selection_box; - selection_box.min[0] = (device_delta[0] < 0) ? (device_point[0] + device_delta[0]) : (device_point[0]); - selection_box.min[1] = (device_delta[1] < 0) ? (device_point[1] + device_delta[1]) : (device_point[1]); - selection_box.max[0] = (device_delta[0] > 0) ? (device_point[0] + device_delta[0]) : (device_point[0]); - selection_box.max[1] = (device_delta[1] > 0) ? (device_point[1] + device_delta[1]) : (device_point[1]); - return selection_box; -} - -Quaternion construct_local_rotation(const Quaternion &world, const Quaternion &localToWorld) -{ - return quaternion_normalised(quaternion_multiplied_by_quaternion( - quaternion_normalised(quaternion_multiplied_by_quaternion( - quaternion_inverse(localToWorld), - world - )), - localToWorld - )); -} - -inline void matrix4_assign_rotation(Matrix4 &matrix, const Matrix4 &other) -{ - matrix[0] = other[0]; - matrix[1] = other[1]; - matrix[2] = other[2]; - matrix[4] = other[4]; - matrix[5] = other[5]; - matrix[6] = other[6]; - matrix[8] = other[8]; - matrix[9] = other[9]; - matrix[10] = other[10]; -} - -void matrix4_assign_rotation_for_pivot(Matrix4 &matrix, scene::Instance &instance) -{ - Editable *editable = Node_getEditable(instance.path().top()); - if (editable != 0) { - matrix4_assign_rotation(matrix, - matrix4_multiplied_by_matrix4(instance.localToWorld(), editable->getLocalPivot())); - } else { - matrix4_assign_rotation(matrix, instance.localToWorld()); - } -} - -inline bool Instance_isSelectedComponents(scene::Instance &instance) -{ - ComponentSelectionTestable *componentSelectionTestable = Instance_getComponentSelectionTestable(instance); - return componentSelectionTestable != 0 - && componentSelectionTestable->isSelectedComponents(); -} - -class TranslateSelected : public SelectionSystem::Visitor { -const Vector3 &m_translate; -public: -TranslateSelected(const Vector3 &translate) - : m_translate(translate) -{ -} - -void visit(scene::Instance &instance) const -{ - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->setType(TRANSFORM_PRIMITIVE); - transform->setTranslation(m_translate); - } -} -}; - -void Scene_Translate_Selected(scene::Graph &graph, const Vector3 &translation) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - GlobalSelectionSystem().foreachSelected(TranslateSelected(translation)); - } -} - -Vector3 get_local_pivot(const Vector3 &world_pivot, const Matrix4 &localToWorld) -{ - return Vector3( - matrix4_transformed_point( - matrix4_full_inverse(localToWorld), - world_pivot - ) - ); -} - -void translation_for_pivoted_matrix_transform(Vector3 &parent_translation, const Matrix4 &local_transform, - const Vector3 &world_pivot, const Matrix4 &localToWorld, - const Matrix4 &localToParent) -{ - // we need a translation inside the parent system to move the origin of this object to the right place - - // mathematically, it must fulfill: - // - // local_translation local_transform local_pivot = local_pivot - // local_translation = local_pivot - local_transform local_pivot - // - // or maybe? - // local_transform local_translation local_pivot = local_pivot - // local_translation local_pivot = local_transform^-1 local_pivot - // local_translation + local_pivot = local_transform^-1 local_pivot - // local_translation = local_transform^-1 local_pivot - local_pivot - - Vector3 local_pivot(get_local_pivot(world_pivot, localToWorld)); - - Vector3 local_translation( - vector3_subtracted( - local_pivot, - matrix4_transformed_point( - local_transform, - local_pivot - ) - /* - matrix4_transformed_point( - matrix4_full_inverse(local_transform), - local_pivot - ), - local_pivot - */ - ) - ); - - translation_local2object(parent_translation, local_translation, localToParent); - - /* - // verify it! - globalOutputStream() << "World pivot is at " << world_pivot << "\n"; - globalOutputStream() << "Local pivot is at " << local_pivot << "\n"; - globalOutputStream() << "Transformation " << local_transform << " moves it to: " << matrix4_transformed_point(local_transform, local_pivot) << "\n"; - globalOutputStream() << "Must move by " << local_translation << " in the local system" << "\n"; - globalOutputStream() << "Must move by " << parent_translation << " in the parent system" << "\n"; - */ -} - -void translation_for_pivoted_rotation(Vector3 &parent_translation, const Quaternion &local_rotation, - const Vector3 &world_pivot, const Matrix4 &localToWorld, - const Matrix4 &localToParent) -{ - translation_for_pivoted_matrix_transform(parent_translation, - matrix4_rotation_for_quaternion_quantised(local_rotation), world_pivot, - localToWorld, localToParent); -} - -void translation_for_pivoted_scale(Vector3 &parent_translation, const Vector3 &world_scale, const Vector3 &world_pivot, - const Matrix4 &localToWorld, const Matrix4 &localToParent) -{ - Matrix4 local_transform( - matrix4_multiplied_by_matrix4( - matrix4_full_inverse(localToWorld), - matrix4_multiplied_by_matrix4( - matrix4_scale_for_vec3(world_scale), - localToWorld - ) - ) - ); - local_transform.tx() = local_transform.ty() = local_transform.tz() = 0; // cancel translation parts - translation_for_pivoted_matrix_transform(parent_translation, local_transform, world_pivot, localToWorld, - localToParent); -} - -class rotate_selected : public SelectionSystem::Visitor { -const Quaternion &m_rotate; -const Vector3 &m_world_pivot; -public: -rotate_selected(const Quaternion &rotation, const Vector3 &world_pivot) - : m_rotate(rotation), m_world_pivot(world_pivot) -{ -} - -void visit(scene::Instance &instance) const -{ - TransformNode *transformNode = Node_getTransformNode(instance.path().top()); - if (transformNode != 0) { - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->setType(TRANSFORM_PRIMITIVE); - transform->setScale(c_scale_identity); - transform->setTranslation(c_translation_identity); - - transform->setType(TRANSFORM_PRIMITIVE); - transform->setRotation(m_rotate); - - { - Editable *editable = Node_getEditable(instance.path().top()); - const Matrix4 &localPivot = editable != 0 ? editable->getLocalPivot() : g_matrix4_identity; - - Vector3 parent_translation; - translation_for_pivoted_rotation( - parent_translation, - m_rotate, - m_world_pivot, - matrix4_multiplied_by_matrix4(instance.localToWorld(), localPivot), - matrix4_multiplied_by_matrix4(transformNode->localToParent(), localPivot) - ); - - transform->setTranslation(parent_translation); - } - } - } -} -}; - -void Scene_Rotate_Selected(scene::Graph &graph, const Quaternion &rotation, const Vector3 &world_pivot) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - GlobalSelectionSystem().foreachSelected(rotate_selected(rotation, world_pivot)); - } -} - -class scale_selected : public SelectionSystem::Visitor { -const Vector3 &m_scale; -const Vector3 &m_world_pivot; -public: -scale_selected(const Vector3 &scaling, const Vector3 &world_pivot) - : m_scale(scaling), m_world_pivot(world_pivot) -{ -} - -void visit(scene::Instance &instance) const -{ - TransformNode *transformNode = Node_getTransformNode(instance.path().top()); - if (transformNode != 0) { - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->setType(TRANSFORM_PRIMITIVE); - transform->setScale(c_scale_identity); - transform->setTranslation(c_translation_identity); - - transform->setType(TRANSFORM_PRIMITIVE); - transform->setScale(m_scale); - { - Editable *editable = Node_getEditable(instance.path().top()); - const Matrix4 &localPivot = editable != 0 ? editable->getLocalPivot() : g_matrix4_identity; - - Vector3 parent_translation; - translation_for_pivoted_scale( - parent_translation, - m_scale, - m_world_pivot, - matrix4_multiplied_by_matrix4(instance.localToWorld(), localPivot), - matrix4_multiplied_by_matrix4(transformNode->localToParent(), localPivot) - ); - - transform->setTranslation(parent_translation); - } - } - } -} -}; - -void Scene_Scale_Selected(scene::Graph &graph, const Vector3 &scaling, const Vector3 &world_pivot) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - GlobalSelectionSystem().foreachSelected(scale_selected(scaling, world_pivot)); - } -} - - -class translate_component_selected : public SelectionSystem::Visitor { -const Vector3 &m_translate; -public: -translate_component_selected(const Vector3 &translate) - : m_translate(translate) -{ -} - -void visit(scene::Instance &instance) const -{ - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->setType(TRANSFORM_COMPONENT); - transform->setTranslation(m_translate); - } -} -}; - -void Scene_Translate_Component_Selected(scene::Graph &graph, const Vector3 &translation) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - GlobalSelectionSystem().foreachSelectedComponent(translate_component_selected(translation)); - } -} - -class rotate_component_selected : public SelectionSystem::Visitor { -const Quaternion &m_rotate; -const Vector3 &m_world_pivot; -public: -rotate_component_selected(const Quaternion &rotation, const Vector3 &world_pivot) - : m_rotate(rotation), m_world_pivot(world_pivot) -{ -} - -void visit(scene::Instance &instance) const -{ - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - Vector3 parent_translation; - translation_for_pivoted_rotation(parent_translation, m_rotate, m_world_pivot, instance.localToWorld(), - Node_getTransformNode(instance.path().top())->localToParent()); - - transform->setType(TRANSFORM_COMPONENT); - transform->setRotation(m_rotate); - transform->setTranslation(parent_translation); - } -} -}; - -void Scene_Rotate_Component_Selected(scene::Graph &graph, const Quaternion &rotation, const Vector3 &world_pivot) -{ - if (GlobalSelectionSystem().countSelectedComponents() != 0) { - GlobalSelectionSystem().foreachSelectedComponent(rotate_component_selected(rotation, world_pivot)); - } -} - -class scale_component_selected : public SelectionSystem::Visitor { -const Vector3 &m_scale; -const Vector3 &m_world_pivot; -public: -scale_component_selected(const Vector3 &scaling, const Vector3 &world_pivot) - : m_scale(scaling), m_world_pivot(world_pivot) -{ -} - -void visit(scene::Instance &instance) const -{ - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - Vector3 parent_translation; - translation_for_pivoted_scale(parent_translation, m_scale, m_world_pivot, instance.localToWorld(), - Node_getTransformNode(instance.path().top())->localToParent()); - - transform->setType(TRANSFORM_COMPONENT); - transform->setScale(m_scale); - transform->setTranslation(parent_translation); - } -} -}; - -void Scene_Scale_Component_Selected(scene::Graph &graph, const Vector3 &scaling, const Vector3 &world_pivot) -{ - if (GlobalSelectionSystem().countSelectedComponents() != 0) { - GlobalSelectionSystem().foreachSelectedComponent(scale_component_selected(scaling, world_pivot)); - } -} - - -class BooleanSelector : public Selector { -bool m_selected; -SelectionIntersection m_intersection; -Selectable *m_selectable; -public: -BooleanSelector() : m_selected(false) -{ -} - -void pushSelectable(Selectable &selectable) -{ - m_intersection = SelectionIntersection(); - m_selectable = &selectable; -} - -void popSelectable() -{ - if (m_intersection.valid()) { - m_selected = true; - } - m_intersection = SelectionIntersection(); -} - -void addIntersection(const SelectionIntersection &intersection) -{ - if (m_selectable->isSelected()) { - assign_if_closer(m_intersection, intersection); - } -} - -bool isSelected() -{ - return m_selected; -} -}; - -class BestSelector : public Selector { -SelectionIntersection m_intersection; -Selectable *m_selectable; -SelectionIntersection m_bestIntersection; -std::list m_bestSelectable; -public: -BestSelector() : m_bestIntersection(SelectionIntersection()), m_bestSelectable(0) -{ -} - -void pushSelectable(Selectable &selectable) -{ - m_intersection = SelectionIntersection(); - m_selectable = &selectable; -} - -void popSelectable() -{ - if (m_intersection.equalEpsilon(m_bestIntersection, 0.25f, 0.001f)) { - m_bestSelectable.push_back(m_selectable); - m_bestIntersection = m_intersection; - } else if (m_intersection < m_bestIntersection) { - m_bestSelectable.clear(); - m_bestSelectable.push_back(m_selectable); - m_bestIntersection = m_intersection; - } - m_intersection = SelectionIntersection(); -} - -void addIntersection(const SelectionIntersection &intersection) -{ - assign_if_closer(m_intersection, intersection); -} - -std::list &best() -{ - return m_bestSelectable; -} -}; - -class DragManipulator : public Manipulator { -TranslateFree m_freeResize; -TranslateFree m_freeDrag; -ResizeTranslatable m_resize; -DragTranslatable m_drag; -SelectableBool m_dragSelectable; -public: - -bool m_selected; - -DragManipulator() : m_freeResize(m_resize), m_freeDrag(m_drag), m_selected(false) -{ -} - -Manipulatable *GetManipulatable() -{ - return m_dragSelectable.isSelected() ? &m_freeDrag : &m_freeResize; -} - -void testSelect(const View &view, const Matrix4 &pivot2world) -{ - SelectionPool selector; - - SelectionVolume test(view); - - if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) { - BooleanSelector booleanSelector; - - Scene_TestSelect_Primitive(booleanSelector, test, view); - - if (booleanSelector.isSelected()) { - selector.addSelectable(SelectionIntersection(0, 0), &m_dragSelectable); - m_selected = false; - } else { - m_selected = Scene_forEachPlaneSelectable_selectPlanes(GlobalSceneGraph(), selector, test); - } - } else { - BestSelector bestSelector; - Scene_TestSelect_Component_Selected(bestSelector, test, view, GlobalSelectionSystem().ComponentMode()); - for (std::list::iterator i = bestSelector.best().begin(); - i != bestSelector.best().end(); ++i) { - if (!(*i)->isSelected()) { - GlobalSelectionSystem().setSelectedAllComponents(false); - } - m_selected = false; - selector.addSelectable(SelectionIntersection(0, 0), (*i)); - m_dragSelectable.setSelected(true); - } - } - - for (SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i) { - (*i).second->setSelected(true); - } -} - -void setSelected(bool select) -{ - m_selected = select; - m_dragSelectable.setSelected(select); -} - -bool isSelected() const -{ - return m_selected || m_dragSelectable.isSelected(); -} -}; - -class ClipManipulator : public Manipulator { -public: - -Manipulatable *GetManipulatable() -{ - ERROR_MESSAGE("clipper is not manipulatable"); - return 0; -} - -void setSelected(bool select) -{ -} - -bool isSelected() const -{ - return false; -} -}; - -class select_all : public scene::Graph::Walker { -bool m_select; -public: -select_all(bool select) - : m_select(select) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0) { - selectable->setSelected(m_select); - } - return true; -} -}; - -class select_all_component : public scene::Graph::Walker { -bool m_select; -SelectionSystem::EComponentMode m_mode; -public: -select_all_component(bool select, SelectionSystem::EComponentMode mode) - : m_select(select), m_mode(mode) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - ComponentSelectionTestable *componentSelectionTestable = Instance_getComponentSelectionTestable(instance); - if (componentSelectionTestable) { - componentSelectionTestable->setSelectedComponents(m_select, m_mode); - } - return true; -} -}; - -void Scene_SelectAll_Component(bool select, SelectionSystem::EComponentMode componentMode) -{ - GlobalSceneGraph().traverse(select_all_component(select, componentMode)); -} -extern bool g_expansion_enabled; -extern bool g_addselect_enabled; - -void Scene_ExpandSelectionToEntities(); - -// RadiantSelectionSystem -class RadiantSelectionSystem : - public SelectionSystem, - public Translatable, - public Rotatable, - public Scalable, - public Renderable { -mutable Matrix4 m_pivot2world; -Matrix4 m_pivot2world_start; -Matrix4 m_manip2pivot_start; -Translation m_translation; -Rotation m_rotation; -Scale m_scale; -public: -static Shader *m_state; -private: -EManipulatorMode m_manipulator_mode; -Manipulator *m_manipulator; - -// state -bool m_undo_begun; -EMode m_mode; -EComponentMode m_componentmode; - -SelectionCounter m_count_primitive; -SelectionCounter m_count_component; - -TranslateManipulator m_translate_manipulator; -RotateManipulator m_rotate_manipulator; -ScaleManipulator m_scale_manipulator; -DragManipulator m_drag_manipulator; -ClipManipulator m_clip_manipulator; - -typedef SelectionList selection_t; -selection_t m_selection; -selection_t m_component_selection; - -Signal1 m_selectionChanged_callbacks; - -void ConstructPivot() const; - -mutable bool m_pivotChanged; -bool m_pivot_moving; - -void Scene_TestSelect(Selector &selector, SelectionTest &test, const View &view, SelectionSystem::EMode mode, - SelectionSystem::EComponentMode componentMode); - -bool nothingSelected() const -{ - return (Mode() == eComponent && m_count_component.empty()) - || (Mode() == ePrimitive && m_count_primitive.empty()); -} - - -public: -enum EModifier { - eManipulator, - eToggle, - eReplace, - eCycle, -}; - -RadiantSelectionSystem() : - m_undo_begun(false), - m_mode(ePrimitive), - m_componentmode(eDefault), - m_count_primitive(SelectionChangedCaller(*this)), - m_count_component(SelectionChangedCaller(*this)), - m_translate_manipulator(*this, 2, 64), - m_rotate_manipulator(*this, 8, 64), - m_scale_manipulator(*this, 0, 64), - m_pivotChanged(false), - m_pivot_moving(false) -{ - SetManipulatorMode(eTranslate); - pivotChanged(); - addSelectionChangeCallback(PivotChangedSelectionCaller(*this)); - AddGridChangeCallback(PivotChangedCaller(*this)); -} - -void pivotChanged() const -{ - m_pivotChanged = true; - SceneChangeNotify(); -} - -typedef ConstMemberCaller PivotChangedCaller; - -void pivotChangedSelection(const Selectable &selectable) -{ - pivotChanged(); -} - -typedef MemberCaller PivotChangedSelectionCaller; - -void SetMode(EMode mode) -{ - if (m_mode != mode) { - m_mode = mode; - pivotChanged(); - } -} - -EMode Mode() const -{ - return m_mode; -} - -void SetComponentMode(EComponentMode mode) -{ - m_componentmode = mode; -} - -EComponentMode ComponentMode() const -{ - return m_componentmode; -} - -void SetManipulatorMode(EManipulatorMode mode) -{ - m_manipulator_mode = mode; - switch (m_manipulator_mode) { - case eTranslate: - m_manipulator = &m_translate_manipulator; - break; - case eRotate: - m_manipulator = &m_rotate_manipulator; - break; - case eScale: - m_manipulator = &m_scale_manipulator; - break; - case eDrag: - m_manipulator = &m_drag_manipulator; - break; - case eClip: - m_manipulator = &m_clip_manipulator; - break; - } - pivotChanged(); -} - -EManipulatorMode ManipulatorMode() const -{ - return m_manipulator_mode; -} - -SelectionChangeCallback getObserver(EMode mode) -{ - if (mode == ePrimitive) { - return makeCallback(m_count_primitive); - } else { - return makeCallback(m_count_component); - } -} - -std::size_t countSelected() const -{ - return m_count_primitive.size(); -} - -std::size_t countSelectedComponents() const -{ - return m_count_component.size(); -} - -void onSelectedChanged(scene::Instance &instance, const Selectable &selectable) -{ - if (selectable.isSelected()) { - m_selection.append(instance); - } else { - m_selection.erase(instance); - } - - ASSERT_MESSAGE(m_selection.size() == m_count_primitive.size(), "selection-tracking error"); -} - -void onComponentSelection(scene::Instance &instance, const Selectable &selectable) -{ - if (selectable.isSelected()) { - m_component_selection.append(instance); - } else { - m_component_selection.erase(instance); - } - - ASSERT_MESSAGE(m_component_selection.size() == m_count_component.size(), "selection-tracking error"); -} - -scene::Instance &ultimateSelected() const -{ - ASSERT_MESSAGE(m_selection.size() > 0, "no instance selected"); - return m_selection.back(); -} - -scene::Instance &penultimateSelected() const -{ - ASSERT_MESSAGE(m_selection.size() > 1, "only one instance selected"); - return *(*(--(--m_selection.end()))); -} - -void setSelectedAll(bool selected) -{ - GlobalSceneGraph().traverse(select_all(selected)); - - m_manipulator->setSelected(selected); -} - -void setSelectedAllComponents(bool selected) -{ - Scene_SelectAll_Component(selected, SelectionSystem::eVertex); - Scene_SelectAll_Component(selected, SelectionSystem::eEdge); - Scene_SelectAll_Component(selected, SelectionSystem::eFace); - - m_manipulator->setSelected(selected); -} - -void foreachSelected(const Visitor &visitor) const -{ - selection_t::const_iterator i = m_selection.begin(); - while (i != m_selection.end()) { - visitor.visit(*(*(i++))); - } -} - -void foreachSelectedComponent(const Visitor &visitor) const -{ - selection_t::const_iterator i = m_component_selection.begin(); - while (i != m_component_selection.end()) { - visitor.visit(*(*(i++))); - } -} - -void addSelectionChangeCallback(const SelectionChangeHandler &handler) -{ - m_selectionChanged_callbacks.connectLast(handler); -} - -void selectionChanged(const Selectable &selectable) -{ - m_selectionChanged_callbacks(selectable); -} - -typedef MemberCaller SelectionChangedCaller; - - -void startMove() -{ - m_pivot2world_start = GetPivot2World(); -} - -bool SelectManipulator(const View &view, const float device_point[2], const float device_epsilon[2]) -{ - if (!nothingSelected() || (ManipulatorMode() == eDrag && Mode() == eComponent)) { -#if defined ( DEBUG_SELECTION ) - g_render_clipped.destroy(); -#endif - - m_manipulator->setSelected(false); - - if (!nothingSelected() || (ManipulatorMode() == eDrag && Mode() == eComponent)) { - View scissored(view); - ConstructSelectionTest(scissored, SelectionBoxForPoint(device_point, device_epsilon)); - m_manipulator->testSelect(scissored, GetPivot2World()); - } - - startMove(); - - m_pivot_moving = m_manipulator->isSelected(); - - if (m_pivot_moving) { - Pivot2World pivot; - pivot.update(GetPivot2World(), view.GetModelview(), view.GetProjection(), view.GetViewport()); - - m_manip2pivot_start = matrix4_multiplied_by_matrix4(matrix4_full_inverse(m_pivot2world_start), - pivot.m_worldSpace); - - Matrix4 device2manip; - ConstructDevice2Manip(device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), - view.GetViewport()); - m_manipulator->GetManipulatable()->Construct(device2manip, device_point[0], device_point[1]); - - m_undo_begun = false; - } - - SceneChangeNotify(); - } - - return m_pivot_moving; -} - -void deselectAll() -{ - if (Mode() == eComponent) { - setSelectedAllComponents(false); - } else { - setSelectedAll(false); - } -} - -void SelectPoint(const View &view, const float device_point[2], const float device_epsilon[2], - RadiantSelectionSystem::EModifier modifier, bool face) -{ - ASSERT_MESSAGE(fabs(device_point[0]) <= 1.0f && fabs(device_point[1]) <= 1.0f, "point-selection error"); - if (modifier == eReplace) { - if (face) { - setSelectedAllComponents(false); - } else { - deselectAll(); - } - } - -#if defined ( DEBUG_SELECTION ) - g_render_clipped.destroy(); -#endif - - { - View scissored(view); - ConstructSelectionTest(scissored, SelectionBoxForPoint(device_point, device_epsilon)); - - SelectionVolume volume(scissored); - SelectionPool selector; - if (face) { - Scene_TestSelect_Component(selector, volume, scissored, eFace); - } else { - Scene_TestSelect(selector, volume, scissored, Mode(), ComponentMode()); - } - - if (!selector.failed()) { - switch (modifier) { - case RadiantSelectionSystem::eToggle: { - if (g_addselect_enabled == false) - Selection_Deselect(); - - SelectableSortedSet::iterator best = selector.begin(); - // toggle selection of the object with least depth - if ((*best).second->isSelected()) { - (*best).second->setSelected(false); - } else { - (*best).second->setSelected(true); - - if (modifier == eToggle && g_expansion_enabled == true) { /* eukara: hack? */ - Scene_ExpandSelectionToEntities(); - } - } - } - break; - // if cycle mode not enabled, enable it - case RadiantSelectionSystem::eReplace: { - // select closest - (*selector.begin()).second->setSelected(true); - } - break; - // select the next object in the list from the one already selected - case RadiantSelectionSystem::eCycle: { - SelectionPool::iterator i = selector.begin(); - while (i != selector.end()) { - if ((*i).second->isSelected()) { - (*i).second->setSelected(false); - ++i; - if (i != selector.end()) { - i->second->setSelected(true); - } else { - selector.begin()->second->setSelected(true); - } - break; - } - ++i; - } - } - break; - default: - break; - } - } - } -} - -void SelectArea(const View &view, const float device_point[2], const float device_delta[2], - RadiantSelectionSystem::EModifier modifier, bool face) -{ - if (modifier == eReplace) { - if (face) { - setSelectedAllComponents(false); - } else { - deselectAll(); - } - } - -#if defined ( DEBUG_SELECTION ) - g_render_clipped.destroy(); -#endif - - { - View scissored(view); - ConstructSelectionTest(scissored, SelectionBoxForArea(device_point, device_delta)); - - SelectionVolume volume(scissored); - SelectionPool pool; - if (face) { - Scene_TestSelect_Component(pool, volume, scissored, eFace); - } else { - Scene_TestSelect(pool, volume, scissored, Mode(), ComponentMode()); - } - - for (SelectionPool::iterator i = pool.begin(); i != pool.end(); ++i) { - (*i).second->setSelected(!(modifier == RadiantSelectionSystem::eToggle && (*i).second->isSelected())); - } - } -} - - -void translate(const Vector3 &translation) -{ - if (!nothingSelected()) { - //ASSERT_MESSAGE(!m_pivotChanged, "pivot is invalid"); - - m_translation = translation; - - m_pivot2world = m_pivot2world_start; - matrix4_translate_by_vec3(m_pivot2world, translation); - - if (Mode() == eComponent) { - Scene_Translate_Component_Selected(GlobalSceneGraph(), m_translation); - } else { - Scene_Translate_Selected(GlobalSceneGraph(), m_translation); - } - - SceneChangeNotify(); - } -} - -void outputTranslation(TextOutputStream &ostream) -{ - ostream << " -xyz " << m_translation.x() << " " << m_translation.y() << " " << m_translation.z(); -} - -void rotate(const Quaternion &rotation) -{ - if (!nothingSelected()) { - //ASSERT_MESSAGE(!m_pivotChanged, "pivot is invalid"); - - m_rotation = rotation; - - if (Mode() == eComponent) { - Scene_Rotate_Component_Selected(GlobalSceneGraph(), m_rotation, vector4_to_vector3(m_pivot2world.t())); - - matrix4_assign_rotation_for_pivot(m_pivot2world, m_component_selection.back()); - } else { - Scene_Rotate_Selected(GlobalSceneGraph(), m_rotation, vector4_to_vector3(m_pivot2world.t())); - - matrix4_assign_rotation_for_pivot(m_pivot2world, m_selection.back()); - } - - SceneChangeNotify(); - } -} - -void outputRotation(TextOutputStream &ostream) -{ - ostream << " -eulerXYZ " << m_rotation.x() << " " << m_rotation.y() << " " << m_rotation.z(); -} - -void scale(const Vector3 &scaling) -{ - if (!nothingSelected()) { - m_scale = scaling; - - if (Mode() == eComponent) { - Scene_Scale_Component_Selected(GlobalSceneGraph(), m_scale, vector4_to_vector3(m_pivot2world.t())); - } else { - Scene_Scale_Selected(GlobalSceneGraph(), m_scale, vector4_to_vector3(m_pivot2world.t())); - } - - SceneChangeNotify(); - } -} - -void outputScale(TextOutputStream &ostream) -{ - ostream << " -scale " << m_scale.x() << " " << m_scale.y() << " " << m_scale.z(); -} - -void rotateSelected(const Quaternion &rotation) -{ - startMove(); - rotate(rotation); - freezeTransforms(); -} - -void translateSelected(const Vector3 &translation) -{ - startMove(); - translate(translation); - freezeTransforms(); -} - -void scaleSelected(const Vector3 &scaling) -{ - startMove(); - scale(scaling); - freezeTransforms(); -} - -void MoveSelected(const View &view, const float device_point[2]) -{ - if (m_manipulator->isSelected()) { - if (!m_undo_begun) { - m_undo_begun = true; - GlobalUndoSystem().start(); - } - - Matrix4 device2manip; - ConstructDevice2Manip(device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), - view.GetViewport()); - m_manipulator->GetManipulatable()->Transform(m_manip2pivot_start, device2manip, device_point[0], - device_point[1]); - } -} - -/// \todo Support view-dependent nudge. -void NudgeManipulator(const Vector3 &nudge, const Vector3 &view) -{ - if (ManipulatorMode() == eTranslate || ManipulatorMode() == eDrag) { - translateSelected(nudge); - } -} - -void endMove(); - -void freezeTransforms(); - -void renderSolid(Renderer &renderer, const VolumeTest &volume) const; - -void renderWireframe(Renderer &renderer, const VolumeTest &volume) const -{ - renderSolid(renderer, volume); -} - -const Matrix4 &GetPivot2World() const -{ - ConstructPivot(); - return m_pivot2world; -} - -static void constructStatic() -{ - m_state = GlobalShaderCache().capture("$POINT"); -#if defined( DEBUG_SELECTION ) - g_state_clipped = GlobalShaderCache().capture("$DEBUG_CLIPPED"); -#endif - TranslateManipulator::m_state_wire = GlobalShaderCache().capture("$WIRE_OVERLAY"); - TranslateManipulator::m_state_fill = GlobalShaderCache().capture("$FLATSHADE_OVERLAY"); - RotateManipulator::m_state_outer = GlobalShaderCache().capture("$WIRE_OVERLAY"); -} - -static void destroyStatic() -{ -#if defined( DEBUG_SELECTION ) - GlobalShaderCache().release("$DEBUG_CLIPPED"); -#endif - GlobalShaderCache().release("$WIRE_OVERLAY"); - GlobalShaderCache().release("$FLATSHADE_OVERLAY"); - GlobalShaderCache().release("$WIRE_OVERLAY"); - GlobalShaderCache().release("$POINT"); -} -}; - -Shader *RadiantSelectionSystem::m_state = 0; - - -namespace { -RadiantSelectionSystem *g_RadiantSelectionSystem; - -inline RadiantSelectionSystem &getSelectionSystem() -{ - return *g_RadiantSelectionSystem; -} -} - - -class testselect_entity_visible : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -public: -testselect_entity_visible(Selector &selector, SelectionTest &test) - : m_selector(selector), m_test(test) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && Node_isEntity(path.top())) { - m_selector.pushSelectable(*selectable); - } - - SelectionTestable *selectionTestable = Instance_getSelectionTestable(instance); - if (selectionTestable) { - selectionTestable->testSelect(m_selector, m_test); - } - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && Node_isEntity(path.top())) { - m_selector.popSelectable(); - } -} -}; - -class testselect_primitive_visible : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -public: -testselect_primitive_visible(Selector &selector, SelectionTest &test) - : m_selector(selector), m_test(test) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0) { - m_selector.pushSelectable(*selectable); - } - - SelectionTestable *selectionTestable = Instance_getSelectionTestable(instance); - if (selectionTestable) { - selectionTestable->testSelect(m_selector, m_test); - } - - return true; -} - -void post(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0) { - m_selector.popSelectable(); - } -} -}; - -class testselect_component_visible : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -SelectionSystem::EComponentMode m_mode; -public: -testselect_component_visible(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) - : m_selector(selector), m_test(test), m_mode(mode) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - ComponentSelectionTestable *componentSelectionTestable = Instance_getComponentSelectionTestable(instance); - if (componentSelectionTestable) { - componentSelectionTestable->testSelectComponents(m_selector, m_test, m_mode); - } - - return true; -} -}; - - -class testselect_component_visible_selected : public scene::Graph::Walker { -Selector &m_selector; -SelectionTest &m_test; -SelectionSystem::EComponentMode m_mode; -public: -testselect_component_visible_selected(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) - : m_selector(selector), m_test(test), m_mode(mode) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 && selectable->isSelected()) { - ComponentSelectionTestable *componentSelectionTestable = Instance_getComponentSelectionTestable(instance); - if (componentSelectionTestable) { - componentSelectionTestable->testSelectComponents(m_selector, m_test, m_mode); - } - } - - return true; -} -}; - -void Scene_TestSelect_Primitive(Selector &selector, SelectionTest &test, const VolumeTest &volume) -{ - Scene_forEachVisible(GlobalSceneGraph(), volume, testselect_primitive_visible(selector, test)); -} - -void Scene_TestSelect_Component_Selected(Selector &selector, SelectionTest &test, const VolumeTest &volume, - SelectionSystem::EComponentMode componentMode) -{ - Scene_forEachVisible(GlobalSceneGraph(), volume, - testselect_component_visible_selected(selector, test, componentMode)); -} - -void Scene_TestSelect_Component(Selector &selector, SelectionTest &test, const VolumeTest &volume, - SelectionSystem::EComponentMode componentMode) -{ - Scene_forEachVisible(GlobalSceneGraph(), volume, testselect_component_visible(selector, test, componentMode)); -} - -void RadiantSelectionSystem::Scene_TestSelect(Selector &selector, SelectionTest &test, const View &view, - SelectionSystem::EMode mode, - SelectionSystem::EComponentMode componentMode) -{ - switch (mode) { - case eEntity: { - Scene_forEachVisible(GlobalSceneGraph(), view, testselect_entity_visible(selector, test)); - } - break; - case ePrimitive: - Scene_TestSelect_Primitive(selector, test, view); - break; - case eComponent: - Scene_TestSelect_Component_Selected(selector, test, view, componentMode); - break; - } -} - -class FreezeTransforms : public scene::Graph::Walker { -public: -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - TransformNode *transformNode = Node_getTransformNode(path.top()); - if (transformNode != 0) { - Transformable *transform = Instance_getTransformable(instance); - if (transform != 0) { - transform->freezeTransform(); - } - } - return true; -} -}; - -void RadiantSelectionSystem::freezeTransforms() -{ - GlobalSceneGraph().traverse(FreezeTransforms()); -} - - -void RadiantSelectionSystem::endMove() -{ - freezeTransforms(); - - if (Mode() == ePrimitive) { - if (ManipulatorMode() == eDrag) { - Scene_SelectAll_Component(false, SelectionSystem::eFace); - } - } - - m_pivot_moving = false; - pivotChanged(); - - SceneChangeNotify(); - - if (m_undo_begun) { - StringOutputStream command; - - if (ManipulatorMode() == eTranslate) { - command << "translateTool"; - outputTranslation(command); - } else if (ManipulatorMode() == eRotate) { - command << "rotateTool"; - outputRotation(command); - } else if (ManipulatorMode() == eScale) { - command << "scaleTool"; - outputScale(command); - } else if (ManipulatorMode() == eDrag) { - command << "dragTool"; - } - - GlobalUndoSystem().finish(command.c_str()); - } - -} - -inline AABB Instance_getPivotBounds(scene::Instance &instance) -{ - Entity *entity = Node_getEntity(instance.path().top()); - if (entity != 0 - && (entity->getEntityClass().fixedsize - || !node_is_group(instance.path().top()))) { - Editable *editable = Node_getEditable(instance.path().top()); - if (editable != 0) { - return AABB(vector4_to_vector3( - matrix4_multiplied_by_matrix4(instance.localToWorld(), editable->getLocalPivot()).t()), - Vector3(0, 0, 0)); - } else { - return AABB(vector4_to_vector3(instance.localToWorld().t()), Vector3(0, 0, 0)); - } - } - - return instance.worldAABB(); -} - -class bounds_selected : public scene::Graph::Walker { -AABB &m_bounds; -public: -bounds_selected(AABB &bounds) - : m_bounds(bounds) -{ - m_bounds = AABB(); -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - aabb_extend_by_aabb_safe(m_bounds, Instance_getPivotBounds(instance)); - } - return true; -} -}; - -class bounds_selected_component : public scene::Graph::Walker { -AABB &m_bounds; -public: -bounds_selected_component(AABB &bounds) - : m_bounds(bounds) -{ - m_bounds = AABB(); -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - Selectable *selectable = Instance_getSelectable(instance); - if (selectable != 0 - && selectable->isSelected()) { - ComponentEditable *componentEditable = Instance_getComponentEditable(instance); - if (componentEditable) { - aabb_extend_by_aabb_safe(m_bounds, - aabb_for_oriented_aabb_safe(componentEditable->getSelectedComponentsBounds(), - instance.localToWorld())); - } - } - return true; -} -}; - -void Scene_BoundsSelected(scene::Graph &graph, AABB &bounds) -{ - graph.traverse(bounds_selected(bounds)); -} - -void Scene_BoundsSelectedComponent(scene::Graph &graph, AABB &bounds) -{ - graph.traverse(bounds_selected_component(bounds)); -} - -#if 0 -inline void pivot_for_node( Matrix4& pivot, scene::Node& node, scene::Instance& instance ){ - ComponentEditable* componentEditable = Instance_getComponentEditable( instance ); - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && componentEditable != 0 ) { - pivot = matrix4_translation_for_vec3( componentEditable->getSelectedComponentsBounds().origin ); - } - else - { - Bounded* bounded = Instance_getBounded( instance ); - if ( bounded != 0 ) { - pivot = matrix4_translation_for_vec3( bounded->localAABB().origin ); - } - else - { - pivot = g_matrix4_identity; - } - } -} -#endif - -void RadiantSelectionSystem::ConstructPivot() const -{ - if (!m_pivotChanged || m_pivot_moving) { - return; - } - m_pivotChanged = false; - - Vector3 m_object_pivot; - - if (!nothingSelected()) { - { - AABB bounds; - if (Mode() == eComponent) { - Scene_BoundsSelectedComponent(GlobalSceneGraph(), bounds); - } else { - Scene_BoundsSelected(GlobalSceneGraph(), bounds); - } - m_object_pivot = bounds.origin; - } - - vector3_snap(m_object_pivot, GetSnapGridSize()); - m_pivot2world = matrix4_translation_for_vec3(m_object_pivot); - - switch (m_manipulator_mode) { - case eTranslate: - break; - case eRotate: - if (Mode() == eComponent) { - matrix4_assign_rotation_for_pivot(m_pivot2world, m_component_selection.back()); - } else { - matrix4_assign_rotation_for_pivot(m_pivot2world, m_selection.back()); - } - break; - case eScale: - if (Mode() == eComponent) { - matrix4_assign_rotation_for_pivot(m_pivot2world, m_component_selection.back()); - } else { - matrix4_assign_rotation_for_pivot(m_pivot2world, m_selection.back()); - } - break; - default: - break; - } - } -} - -void RadiantSelectionSystem::renderSolid(Renderer &renderer, const VolumeTest &volume) const -{ - //if(view->TestPoint(m_object_pivot)) - if (!nothingSelected()) { - renderer.Highlight(Renderer::ePrimitive, false); - renderer.Highlight(Renderer::eFace, false); - - renderer.SetState(m_state, Renderer::eWireframeOnly); - renderer.SetState(m_state, Renderer::eFullMaterials); - - m_manipulator->render(renderer, volume, GetPivot2World()); - } - -#if defined( DEBUG_SELECTION ) - renderer.SetState(g_state_clipped, Renderer::eWireframeOnly); - renderer.SetState(g_state_clipped, Renderer::eFullMaterials); - renderer.addRenderable(g_render_clipped, g_render_clipped.m_world); -#endif -} - - -void SelectionSystem_OnBoundsChanged() -{ - getSelectionSystem().pivotChanged(); -} - - -SignalHandlerId SelectionSystem_boundsChanged; - -void SelectionSystem_Construct() -{ - RadiantSelectionSystem::constructStatic(); - - g_RadiantSelectionSystem = new RadiantSelectionSystem; - - SelectionSystem_boundsChanged = GlobalSceneGraph().addBoundsChangedCallback( - FreeCaller()); - - GlobalShaderCache().attachRenderable(getSelectionSystem()); -} - -void SelectionSystem_Destroy() -{ - GlobalShaderCache().detachRenderable(getSelectionSystem()); - - GlobalSceneGraph().removeBoundsChangedCallback(SelectionSystem_boundsChanged); - - delete g_RadiantSelectionSystem; - - RadiantSelectionSystem::destroyStatic(); -} - - -inline float screen_normalised(float pos, std::size_t size) -{ - return ((2.0f * pos) / size) - 1.0f; -} - -typedef Vector2 DeviceVector; - -inline DeviceVector window_to_normalised_device(WindowVector window, std::size_t width, std::size_t height) -{ - return DeviceVector(screen_normalised(window.x(), width), screen_normalised(height - 1 - window.y(), height)); -} - -inline float device_constrained(float pos) -{ - return std::min(1.0f, std::max(-1.0f, pos)); -} - -inline DeviceVector device_constrained(DeviceVector device) -{ - return DeviceVector(device_constrained(device.x()), device_constrained(device.y())); -} - -inline float window_constrained(float pos, std::size_t origin, std::size_t size) -{ - return std::min(static_cast( origin + size ), std::max(static_cast( origin ), pos)); -} - -inline WindowVector -window_constrained(WindowVector window, std::size_t x, std::size_t y, std::size_t width, std::size_t height) -{ - return WindowVector(window_constrained(window.x(), x, width), window_constrained(window.y(), y, height)); -} - -typedef Callback MouseEventCallback; - -Single g_mouseMovedCallback; -Single g_mouseUpCallback; - - -const ButtonIdentifier c_button_select = c_buttonLeft; -const ButtonIdentifier c_button_texture = c_buttonMiddle; -const ModifierFlags c_modifier_manipulator = c_modifierNone; -const ModifierFlags c_modifier_toggle = c_modifierShift; -const ModifierFlags c_modifier_toggle_face = c_modifierShift | c_modifierControl; -const ModifierFlags c_modifier_face = c_modifierControl; -const ModifierFlags c_modifier_replace = c_modifierShift | c_modifierAlt; -const ModifierFlags c_modifier_replace_face = c_modifier_replace | c_modifier_face; -const ModifierFlags c_modifier_apply_texture1 = c_modifierControl | c_modifierShift; -const ModifierFlags c_modifier_apply_texture2 = c_modifierControl; -const ModifierFlags c_modifier_apply_texture3 = c_modifierShift; -const ModifierFlags c_modifier_copy_texture = c_modifierNone; - -class Selector_ { -RadiantSelectionSystem::EModifier modifier_for_state(ModifierFlags state) -{ - if (state == c_modifier_toggle || state == c_modifier_toggle_face) { - return RadiantSelectionSystem::eToggle; - } - if (state == c_modifier_replace || state == c_modifier_replace_face) { - return RadiantSelectionSystem::eReplace; - } - return RadiantSelectionSystem::eManipulator; -} - -rect_t getDeviceArea() const -{ - DeviceVector delta(m_current - m_start); - if (selecting() && fabs(delta.x()) > m_epsilon.x() && fabs(delta.y()) > m_epsilon.y()) { - return SelectionBoxForArea(&m_start[0], &delta[0]); - } else { - rect_t default_area = {{0, 0,}, - {0, 0,},}; - return default_area; - } -} - -public: -DeviceVector m_start; -DeviceVector m_current; -DeviceVector m_epsilon; -std::size_t m_unmoved_replaces; -ModifierFlags m_state; -const View *m_view; -RectangleCallback m_window_update; - -Selector_() : m_start(0.0f, 0.0f), m_current(0.0f, 0.0f), m_unmoved_replaces(0), m_state(c_modifierNone) -{ -} - -void draw_area() -{ - m_window_update(getDeviceArea()); -} - -void testSelect(DeviceVector position) -{ - RadiantSelectionSystem::EModifier modifier = modifier_for_state(m_state); - if (modifier != RadiantSelectionSystem::eManipulator) { - DeviceVector delta(position - m_start); - if (fabs(delta.x()) > m_epsilon.x() && fabs(delta.y()) > m_epsilon.y()) { - DeviceVector delta(position - m_start); - getSelectionSystem().SelectArea(*m_view, &m_start[0], &delta[0], modifier, - (m_state & c_modifier_face) != c_modifierNone); - } else { - if (modifier == RadiantSelectionSystem::eReplace && m_unmoved_replaces++ > 0) { - modifier = RadiantSelectionSystem::eCycle; - } - getSelectionSystem().SelectPoint(*m_view, &position[0], &m_epsilon[0], modifier, - (m_state & c_modifier_face) != c_modifierNone); - } - } - - m_start = m_current = DeviceVector(0.0f, 0.0f); - draw_area(); -} - -bool selecting() const -{ - return m_state != c_modifier_manipulator; -} - -void setState(ModifierFlags state) -{ - bool was_selecting = selecting(); - m_state = state; - if (was_selecting ^ selecting()) { - draw_area(); - } -} - -ModifierFlags getState() const -{ - return m_state; -} - -void modifierEnable(ModifierFlags type) -{ - setState(bitfield_enable(getState(), type)); -} - -void modifierDisable(ModifierFlags type) -{ - setState(bitfield_disable(getState(), type)); -} - -void mouseDown(DeviceVector position) -{ - m_start = m_current = device_constrained(position); -} - -void mouseMoved(DeviceVector position) -{ - m_current = device_constrained(position); - draw_area(); -} - -typedef MemberCaller MouseMovedCaller; - -void mouseUp(DeviceVector position) -{ - testSelect(device_constrained(position)); - - g_mouseMovedCallback.clear(); - g_mouseUpCallback.clear(); -} - -typedef MemberCaller MouseUpCaller; -}; - - -class Manipulator_ { -public: -DeviceVector m_epsilon; -const View *m_view; - -bool mouseDown(DeviceVector position) -{ - return getSelectionSystem().SelectManipulator(*m_view, &position[0], &m_epsilon[0]); -} - -void mouseMoved(DeviceVector position) -{ - getSelectionSystem().MoveSelected(*m_view, &position[0]); -} - -typedef MemberCaller MouseMovedCaller; - -void mouseUp(DeviceVector position) -{ - getSelectionSystem().endMove(); - g_mouseMovedCallback.clear(); - g_mouseUpCallback.clear(); -} - -typedef MemberCaller MouseUpCaller; -}; - -void Scene_copyClosestTexture(SelectionTest &test); - -void Scene_applyClosestTexture(SelectionTest &test); - -class RadiantWindowObserver : public SelectionSystemWindowObserver { -enum { - SELECT_EPSILON = 8, -}; - -int m_width; -int m_height; - -bool m_mouse_down; - -public: -Selector_ m_selector; -Manipulator_ m_manipulator; - -RadiantWindowObserver() : m_mouse_down(false) -{ -} - -void release() -{ - delete this; -} - -void setView(const View &view) -{ - m_selector.m_view = &view; - m_manipulator.m_view = &view; -} - -void setRectangleDrawCallback(const RectangleCallback &callback) -{ - m_selector.m_window_update = callback; -} - -void onSizeChanged(int width, int height) -{ - m_width = width; - m_height = height; - DeviceVector epsilon(SELECT_EPSILON / static_cast( m_width ), - SELECT_EPSILON / static_cast( m_height )); - m_selector.m_epsilon = m_manipulator.m_epsilon = epsilon; -} - -void onMouseDown(const WindowVector &position, ButtonIdentifier button, ModifierFlags modifiers) -{ - if (button == c_button_select) { - m_mouse_down = true; - - DeviceVector devicePosition(window_to_normalised_device(position, m_width, m_height)); - if (modifiers == c_modifier_manipulator && m_manipulator.mouseDown(devicePosition)) { - g_mouseMovedCallback.insert(MouseEventCallback(Manipulator_::MouseMovedCaller(m_manipulator))); - g_mouseUpCallback.insert(MouseEventCallback(Manipulator_::MouseUpCaller(m_manipulator))); - } else { - m_selector.mouseDown(devicePosition); - g_mouseMovedCallback.insert(MouseEventCallback(Selector_::MouseMovedCaller(m_selector))); - g_mouseUpCallback.insert(MouseEventCallback(Selector_::MouseUpCaller(m_selector))); - } - } else if (button == c_button_texture) { - DeviceVector devicePosition(device_constrained(window_to_normalised_device(position, m_width, m_height))); - - View scissored(*m_selector.m_view); - ConstructSelectionTest(scissored, SelectionBoxForPoint(&devicePosition[0], &m_selector.m_epsilon[0])); - SelectionVolume volume(scissored); - - if (modifiers == c_modifier_apply_texture1 || modifiers == c_modifier_apply_texture2 || - modifiers == c_modifier_apply_texture3) { - Scene_applyClosestTexture(volume); - } else if (modifiers == c_modifier_copy_texture) { - Scene_copyClosestTexture(volume); - } - } -} - -void onMouseMotion(const WindowVector &position, ModifierFlags modifiers) -{ - m_selector.m_unmoved_replaces = 0; - - if (m_mouse_down && !g_mouseMovedCallback.empty()) { - g_mouseMovedCallback.get()(window_to_normalised_device(position, m_width, m_height)); - } -} - -void onMouseUp(const WindowVector &position, ButtonIdentifier button, ModifierFlags modifiers) -{ - if (button == c_button_select && !g_mouseUpCallback.empty()) { - m_mouse_down = false; - - g_mouseUpCallback.get()(window_to_normalised_device(position, m_width, m_height)); - } -} - -void onModifierDown(ModifierFlags type) -{ - m_selector.modifierEnable(type); -} - -void onModifierUp(ModifierFlags type) -{ - m_selector.modifierDisable(type); -} -}; - - -SelectionSystemWindowObserver *NewWindowObserver() -{ - return new RadiantWindowObserver; -} - - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class SelectionDependencies : - public GlobalSceneGraphModuleRef, - public GlobalShaderCacheModuleRef, - public GlobalOpenGLModuleRef { -}; - -class SelectionAPI : public TypeSystemRef { -SelectionSystem *m_selection; -public: -typedef SelectionSystem Type; - -STRING_CONSTANT(Name, "*"); - -SelectionAPI() -{ - SelectionSystem_Construct(); - - m_selection = &getSelectionSystem(); -} - -~SelectionAPI() -{ - SelectionSystem_Destroy(); -} - -SelectionSystem *getTable() -{ - return m_selection; -} -}; - -typedef SingletonModule SelectionModule; -typedef Static StaticSelectionModule; -StaticRegisterModule staticRegisterSelection(StaticSelectionModule::instance()); diff --git a/src/selection.h b/src/selection.h deleted file mode 100644 index b28ae30..0000000 --- a/src/selection.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SELECTION_H ) -#define INCLUDED_SELECTION_H - -#include "windowobserver.h" -#include "generic/callback.h" - -struct rect_t { - float min[2]; - float max[2]; -}; - -typedef Callback RectangleCallback; - -class View; - -class SelectionSystemWindowObserver : public WindowObserver { -public: -virtual ~SelectionSystemWindowObserver() = default; - -virtual void setView(const View &view) = 0; - -virtual void setRectangleDrawCallback(const RectangleCallback &callback) = 0; -}; - -SelectionSystemWindowObserver *NewWindowObserver(); - -class AABB; -namespace scene { -class Graph; -} - -void Scene_BoundsSelected(scene::Graph &graph, AABB &bounds); - -#endif diff --git a/src/server.cpp b/src/server.cpp deleted file mode 100644 index 84d1650..0000000 --- a/src/server.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "server.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" -#include "warnings.h" - -#include -#include -#include "os/path.h" - -#include "modulesystem.h" - -class RadiantModuleServer : public ModuleServer { -typedef std::pair ModuleType; -typedef std::pair ModuleKey; -typedef std::map Modules_; -Modules_ m_modules; -bool m_error; - -public: -RadiantModuleServer() : m_error(false) -{ -} - -void setError(bool error) -{ - m_error = error; -} - -bool getError() const -{ - return m_error; -} - -TextOutputStream &getOutputStream() -{ - return globalOutputStream(); -} - -TextOutputStream &getErrorStream() -{ - return globalErrorStream(); -} - -DebugMessageHandler &getDebugMessageHandler() -{ - return globalDebugMessageHandler(); -} - -void registerModule(const char *type, int version, const char *name, Module &module) -{ - if (!m_modules.insert(Modules_::value_type(ModuleKey(ModuleType(type, version), name), &module)).second) { - globalErrorStream() << "module already registered: type=" << makeQuoted(type) << " name=" - << makeQuoted(name) << "\n"; - } else { - globalOutputStream() << "Module Registered: type=" << makeQuoted(type) << " version=" << makeQuoted(version) - << " name=" << makeQuoted(name) << "\n"; - } -} - -Module *findModule(const char *type, int version, const char *name) const -{ - Modules_::const_iterator i = m_modules.find(ModuleKey(ModuleType(type, version), name)); - if (i != m_modules.end()) { - return (*i).second; - } - return 0; -} - -void foreachModule(const char *type, int version, const Visitor &visitor) -{ - for (Modules_::const_iterator i = m_modules.begin(); i != m_modules.end(); ++i) { - if (string_equal((*i).first.first.first.c_str(), type)) { - visitor.visit((*i).first.second.c_str(), *(*i).second); - } - } -} -}; - - -#if GDEF_OS_WINDOWS - -#include - -const int FORMAT_BUFSIZE = 2048; -const char* FormatGetLastError(){ - static char buf[FORMAT_BUFSIZE]; - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language - buf, - FORMAT_BUFSIZE, - NULL - ); - return buf; -} - -class DynamicLibrary -{ -HMODULE m_library; -public: -typedef int ( __stdcall * FunctionPointer )(); - -DynamicLibrary( const char* filename ){ - m_library = LoadLibrary( filename ); - if ( m_library == 0 ) { - globalErrorStream() << "LoadLibrary failed: '" << filename << "'\n"; - globalErrorStream() << "GetLastError: " << FormatGetLastError(); - } -} -~DynamicLibrary(){ - if ( !failed() ) { - FreeLibrary( m_library ); - } -} -bool failed(){ - return m_library == 0; -} -FunctionPointer findSymbol( const char* symbol ){ - FunctionPointer address = (FunctionPointer) GetProcAddress( m_library, symbol ); - if ( address == 0 ) { - globalErrorStream() << "GetProcAddress failed: '" << symbol << "'\n"; - globalErrorStream() << "GetLastError: " << FormatGetLastError(); - } - return address; -} -}; - -#elif GDEF_OS_POSIX - -#include - -class DynamicLibrary { -void *m_library; -public: -typedef int ( *FunctionPointer )(); - -DynamicLibrary(const char *filename) -{ - m_library = dlopen(filename, RTLD_NOW); -} - -~DynamicLibrary() -{ - if (!failed()) { - dlclose(m_library); - } -} - -bool failed() -{ - return m_library == 0; -} - -FunctionPointer findSymbol(const char *symbol) -{ - FunctionPointer p = (FunctionPointer) dlsym(m_library, symbol); - if (p == 0) { - const char *error = reinterpret_cast( dlerror()); - if (error != 0) { - globalErrorStream() << error; - } - } - return p; -} -}; - -#else -#error "unsupported platform" -#endif - -class DynamicLibraryModule { -typedef void ( RADIANT_DLLIMPORT *RegisterModulesFunc )(ModuleServer &server); - -DynamicLibrary m_library; -RegisterModulesFunc m_registerModule; -public: -DynamicLibraryModule(const char *filename) - : m_library(filename), m_registerModule(0) -{ - if (!m_library.failed()) { - m_registerModule = reinterpret_cast( m_library.findSymbol("Radiant_RegisterModules")); -#if 0 - if ( !m_registerModule ) { - m_registerModule = reinterpret_cast( m_library.findSymbol( "Radiant_RegisterModules@4" ) ); - } -#endif - } -} - -bool failed() -{ - return m_registerModule == 0; -} - -void registerModules(ModuleServer &server) -{ - m_registerModule(server); -} -}; - - -class Libraries { -typedef std::vector libraries_t; -libraries_t m_libraries; - -public: -~Libraries() -{ - release(); -} - -void registerLibrary(const char *filename, ModuleServer &server) -{ - DynamicLibraryModule *library = new DynamicLibraryModule(filename); - - if (library->failed()) { - delete library; - } else { - m_libraries.push_back(library); - library->registerModules(server); - } -} - -void release() -{ - for (libraries_t::iterator i = m_libraries.begin(); i != m_libraries.end(); ++i) { - delete *i; - } -} - -void clear() -{ - m_libraries.clear(); -} -}; - - -Libraries g_libraries; -RadiantModuleServer g_server; - -ModuleServer &GlobalModuleServer_get() -{ - return g_server; -} - -void GlobalModuleServer_loadModule(const char *filename) -{ - g_libraries.registerLibrary(filename, g_server); -} - -void GlobalModuleServer_Initialise() -{ -} - -void GlobalModuleServer_Shutdown() -{ -} diff --git a/src/server.h b/src/server.h deleted file mode 100644 index c54b9d2..0000000 --- a/src/server.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SERVER_H ) -#define INCLUDED_SERVER_H - -class ModuleServer; - -ModuleServer &GlobalModuleServer_get(); - -void GlobalModuleServer_loadModule(const char *filename); - -void GlobalModuleServer_Initialise(); - -void GlobalModuleServer_Shutdown(); - -#endif diff --git a/tools/vmap/shaders.c b/src/shaders.c similarity index 100% rename from tools/vmap/shaders.c rename to src/shaders.c diff --git a/src/shaders.cpp b/src/shaders.cpp deleted file mode 100644 index 0a71b30..0000000 --- a/src/shaders.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "shaders.h" - -#include "ifilesystem.h" - -#include "stream/stringstream.h" - -#include "gtkdlgs.h" - -void ViewShader(const char *pFile, const char *pName) -{ - char *pBuff = 0; - //int nSize = - vfsLoadFile(pFile, reinterpret_cast( &pBuff )); - if (pBuff == 0) { - globalErrorStream() << "Failed to load shader file " << pFile << "\n"; - return; - } - // look for the shader declaration - StringOutputStream strFind(string_length(pName)); - strFind << LowerCase(pName); - StringOutputStream strLook(string_length(pBuff)); - strFind << LowerCase(pBuff); - // offset used when jumping over commented out definitions - std::size_t nOffset = 0; - while (true) { - const char *substr = strstr(strFind.c_str() + nOffset, strFind.c_str()); - if (substr == 0) { - break; - } - std::size_t nStart = substr - strLook.c_str(); - // we have found something, maybe it's a commented out shader name? - char *strCheck = new char[string_length(strLook.c_str()) + 1]; - strcpy(strCheck, strLook.c_str()); - strCheck[nStart] = 0; - char *pCheck = strrchr(strCheck, '\n'); - // if there's a commentary sign in-between we'll continue - if (pCheck && strstr(pCheck, "//")) { - delete[] strCheck; - nOffset = nStart + 1; - continue; - } - delete[] strCheck; - nOffset = nStart; - break; - } - // now close the file - vfsFreeFile(pBuff); - - DoTextEditor(pFile, static_cast( nOffset )); -} diff --git a/src/shaders.h b/src/shaders.h deleted file mode 100644 index 7c6bd2b..0000000 --- a/src/shaders.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_SHADERS_H ) -#define INCLUDED_SHADERS_H - -void ViewShader(const char *file, const char *shader); - -#endif diff --git a/src/sockets.cpp b/src/sockets.cpp deleted file mode 100644 index 8cba164..0000000 --- a/src/sockets.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "sockets.h" -#include "globaldefs.h" - -#if GDEF_OS_WINDOWS -#include -#elif GDEF_OS_POSIX - -#include - -const int SOCKET_ERROR = -1; -#else -#error "unsupported platform" -#endif - -#if GDEF_OS_MACOS -#include -#endif - -int Net_Wait(socket_t *sock, long sec, long usec) -{ -// used for select() -#if GDEF_OS_WINDOWS - TIMEVAL tout = { sec, usec }; -#endif -#if GDEF_OS_POSIX - timeval tout; - tout.tv_sec = sec; - tout.tv_usec = usec; -#endif - - // select() will identify if the socket needs an update - // if the socket is identified that means there's either a message or the connection has been closed/reset/terminated - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(((unsigned int) sock->socket), &readfds); - // from select man page: - // n is the highest-numbered descriptor in any of the three sets, plus 1 - // (no use on windows) - switch (select(sock->socket + 1, &readfds, 0, 0, &tout)) { - case SOCKET_ERROR: - return -1; - case 0: - return 0; - default: - return 1; - } -} diff --git a/src/sockets.h b/src/sockets.h deleted file mode 100644 index 2ab6264..0000000 --- a/src/sockets.h +++ /dev/null @@ -1,14 +0,0 @@ - -#if !defined( INCLUDED_SOCKETS_H ) -#define INCLUDED_SOCKETS_H - -#include "l_net/l_net.h" - -// waits for a socket to become ready -// returns -// -1: error -// 0: timeout -// 1: ready -int Net_Wait(socket_t *sock, long sec, long usec); - -#endif diff --git a/src/stacktrace.cpp b/src/stacktrace.cpp deleted file mode 100644 index 60d5b1e..0000000 --- a/src/stacktrace.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "stacktrace.h" -#include "globaldefs.h" - -#include "stream/textstream.h" - -#include "environment.h" - -#if GDEF_OS_LINUX - -#include - -void write_stack_trace(TextOutputStream &outputStream) -{ - const unsigned int MAX_SYMBOLS = 256; - void *symbols[MAX_SYMBOLS]; - - // get return addresses - int symbol_count = backtrace(symbols, MAX_SYMBOLS); - - if (!symbol_count) { - return; - } - - // resolve and print names - char **symbol_names = backtrace_symbols(symbols, symbol_count); - if (symbol_names) { - for (int i = 0; (i < symbol_count); ++i) { - outputStream << symbol_names[i] << "\n"; - } - - // not a memleak, see www.gnu.org/software/libc/manual (Debugging Support, Backtraces) - free(symbol_names); - } -} - -#elif GDEF_COMPILER_MSVC - -#include "windows.h" -#include "winnt.h" -#include "dbghelp.h" - -class Address -{ -public: -void* m_value; -Address( void* value ) : m_value( value ){ -} -}; - -/// \brief Writes an address \p p to \p ostream in hexadecimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Address& p ){ - const std::size_t bufferSize = ( sizeof( void* ) * 2 ) + 1; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%0p", p.m_value ) ); - return ostream; -} - -class Offset -{ -public: -void* m_value; -Offset( void* value ) : m_value( value ){ -} -}; - -/// \brief Writes an address \p p to \p ostream in hexadecimal form. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Offset& p ){ - const std::size_t bufferSize = ( sizeof( void* ) * 2 ) + 1; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%X", p.m_value ) ); - return ostream; -} - -/// \brief Writes a WCHAR string \p s to \p ostream. -template -inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const WCHAR* s ){ - const std::size_t bufferSize = 1024; - char buf[bufferSize]; - ostream.write( buf, snprintf( buf, bufferSize, "%ls", s ) ); - return ostream; -} - -struct EnumerateSymbolsContext -{ - STACKFRAME64& sf; - TextOutputStream& outputStream; - std::size_t count; - EnumerateSymbolsContext( STACKFRAME64& sf, TextOutputStream& outputStream ) : sf( sf ), outputStream( outputStream ), count( 0 ){ - } -}; - -void write_symbol( PSYMBOL_INFO pSym, STACKFRAME64& sf, TextOutputStream& outputStream, std::size_t& count ){ -#if 0 - if ( pSym->Flags & SYMFLAG_PARAMETER ) { - - DWORD basicType; - if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex, - TI_GET_BASETYPE, &basicType ) ) { - int bleh = 0; - } - else - { - DWORD typeId; - if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex, - TI_GET_TYPEID, &typeId ) ) { - if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex, - TI_GET_BASETYPE, &basicType ) ) { - int bleh = 0; - } - else - { - const char* FormatGetLastError(); - const char* error = FormatGetLastError(); - int bleh = 0; - - WCHAR* name; - if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, typeId, - TI_GET_SYMNAME, &name ) ) { - outputStream << name << " "; - LocalFree( name ); - int bleh = 0; - } - else - { - const char* FormatGetLastError(); - const char* error = FormatGetLastError(); - int bleh = 0; - } - } - } - else - { - const char* FormatGetLastError(); - const char* error = FormatGetLastError(); - int bleh = 0; - } - } - if ( count != 0 ) { - outputStream << ", "; - } - outputStream << pSym->Name; - ++count; - } -#endif -} - -BOOL CALLBACK -EnumerateSymbolsCallback( - PSYMBOL_INFO pSymInfo, - ULONG SymbolSize, - PVOID UserContext ){ - write_symbol( pSymInfo, ( (EnumerateSymbolsContext*)UserContext )->sf, ( (EnumerateSymbolsContext*)UserContext )->outputStream, ( (EnumerateSymbolsContext*)UserContext )->count ); - - - return TRUE; -} - -void write_stack_trace( PCONTEXT pContext, TextOutputStream& outputStream ){ - HANDLE m_hProcess = GetCurrentProcess(); - DWORD dwMachineType = 0; - - CONTEXT context = *pContext; - - // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag - if ( !SymInitialize( m_hProcess, (PSTR)environment_get_app_path(), TRUE ) ) { - return; - } - - STACKFRAME64 sf; - memset( &sf, 0, sizeof( sf ) ); - sf.AddrPC.Mode = AddrModeFlat; - sf.AddrStack.Mode = AddrModeFlat; - sf.AddrFrame.Mode = AddrModeFlat; - -#ifdef _M_IX86 - // Initialize the STACKFRAME structure for the first call. This is only - // necessary for Intel CPUs, and isn't mentioned in the documentation. - sf.AddrPC.Offset = context.Eip; - sf.AddrStack.Offset = context.Esp; - sf.AddrFrame.Offset = context.Ebp; - - dwMachineType = IMAGE_FILE_MACHINE_I386; -#elif _M_X64 - sf.AddrPC.Offset = context.Rip; - sf.AddrStack.Offset = context.Rsp; - - // MSDN: x64: The frame pointer is RBP or RDI. This value is not always used. - // very funny, we'll try Rdi for now - sf.AddrFrame.Offset = context.Rdi; - - dwMachineType = IMAGE_FILE_MACHINE_AMD64; -#endif - - const unsigned int max_sym_name = 1024; // should be enough - - while ( 1 ) - { - // Get the next stack frame - if ( !StackWalk64( dwMachineType, - m_hProcess, - GetCurrentThread(), - &sf, - &context, - 0, - SymFunctionTableAccess64, - SymGetModuleBase64, - 0 ) ) { - break; - } - - if ( 0 == sf.AddrFrame.Offset ) { // Basic sanity check to make sure - break; // the frame is OK. Bail if not. - - } - // Get the name of the function for this stack frame entry - BYTE symbolBuffer[ sizeof( SYMBOL_INFO ) + max_sym_name ]; - PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer; - pSymbol->SizeOfStruct = sizeof( SYMBOL_INFO ); - pSymbol->MaxNameLen = max_sym_name; - - DWORD64 symDisplacement = 0; // Displacement of the input address, - // relative to the start of the symbol - - IMAGEHLP_MODULE64 module = { sizeof( IMAGEHLP_MODULE64 ) }; - if ( SymGetModuleInfo64( m_hProcess, sf.AddrPC.Offset, &module ) ) { - outputStream << module.ModuleName << "!"; - - if ( SymFromAddr( m_hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol ) ) { - char undecoratedName[max_sym_name]; - UnDecorateSymbolName( pSymbol->Name, undecoratedName, max_sym_name, UNDNAME_COMPLETE ); - - outputStream << undecoratedName; - - outputStream << "("; - // Use SymSetContext to get just the locals/params for this frame - IMAGEHLP_STACK_FRAME imagehlpStackFrame; - imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset; - SymSetContext( m_hProcess, &imagehlpStackFrame, 0 ); - - // Enumerate the locals/parameters - EnumerateSymbolsContext context( sf, outputStream ); - SymEnumSymbols( m_hProcess, 0, 0, EnumerateSymbolsCallback, &context ); - outputStream << ")"; - - outputStream << " + " << Offset( reinterpret_cast( symDisplacement ) ); - - // Get the source line for this stack frame entry - IMAGEHLP_LINE64 lineInfo = { sizeof( IMAGEHLP_LINE64 ) }; - DWORD dwLineDisplacement; - if ( SymGetLineFromAddr64( m_hProcess, sf.AddrPC.Offset, - &dwLineDisplacement, &lineInfo ) ) { - outputStream << " " << lineInfo.FileName << " line " << Unsigned( lineInfo.LineNumber ); - } - } - else - { - outputStream << Address( reinterpret_cast( sf.AddrPC.Offset ) ); - } - } - - outputStream << "\n"; - } - - SymCleanup( m_hProcess ); - - return; -} - -void write_stack_trace( TextOutputStream& outputStream ){ - __try { RaiseException( 0,0,0,0 ); } __except( write_stack_trace( ( GetExceptionInformation() )->ContextRecord, outputStream ), EXCEPTION_CONTINUE_EXECUTION ) { - } -} - -#elif GDEF_OS_WINDOWS -void write_stack_trace( TextOutputStream& outputStream ){ - outputStream << "\nStacktrace is disabled on this compiler\n"; -} -#else -void write_stack_trace( TextOutputStream& outputStream ){ - outputStream << "\nStacktrace is disabled on this platform\n"; -} -#endif diff --git a/src/stacktrace.h b/src/stacktrace.h deleted file mode 100644 index 8475ceb..0000000 --- a/src/stacktrace.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_STACKTRACE_H ) -#define INCLUDED_STACKTRACE_H - -class TextOutputStream; - -void write_stack_trace(TextOutputStream &outputStream); - -#endif diff --git a/tools/vmap/surface.c b/src/surface.c similarity index 100% rename from tools/vmap/surface.c rename to src/surface.c diff --git a/tools/vmap/surface_extra.c b/src/surface_extra.c similarity index 100% rename from tools/vmap/surface_extra.c rename to src/surface_extra.c diff --git a/tools/vmap/surface_foliage.c b/src/surface_foliage.c similarity index 100% rename from tools/vmap/surface_foliage.c rename to src/surface_foliage.c diff --git a/tools/vmap/surface_fur.c b/src/surface_fur.c similarity index 100% rename from tools/vmap/surface_fur.c rename to src/surface_fur.c diff --git a/tools/vmap/surface_meta.c b/src/surface_meta.c similarity index 100% rename from tools/vmap/surface_meta.c rename to src/surface_meta.c diff --git a/src/surfacedialog.cpp b/src/surfacedialog.cpp deleted file mode 100644 index 04978d0..0000000 --- a/src/surfacedialog.cpp +++ /dev/null @@ -1,2506 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Surface Dialog -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "surfacedialog.h" - -#include - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "iscenegraph.h" -#include "itexdef.h" -#include "iundo.h" -#include "iselection.h" - -#include - -#include "signal/isignal.h" -#include "generic/object.h" -#include "math/vector.h" -#include "texturelib.h" -#include "shaderlib.h" -#include "stringio.h" - -#include "gtkutil/idledraw.h" -#include "gtkutil/dialog.h" -#include "gtkutil/entry.h" -#include "gtkutil/nonmodal.h" -#include "gtkutil/pointer.h" -#include "gtkutil/glwidget.h" //Shamus: For Textool -#include "gtkutil/button.h" -#include "map.h" -#include "select.h" -#include "patchmanip.h" -#include "brushmanip.h" -#include "patchdialog.h" -#include "preferences.h" -#include "brush_primit.h" -#include "xywindow.h" -#include "mainframe.h" -#include "gtkdlgs.h" -#include "dialog.h" -#include "brush.h" //Shamus: for Textool -#include "patch.h" -#include "commands.h" -#include "stream/stringstream.h" -#include "grid.h" -#include "textureentry.h" - -//NOTE: Proper functioning of Textool currently requires that the "#if 1" lines in -// brush_primit.h be changed to "#if 0". add/removeScale screws this up ATM. :-) -// Plus, Radiant seems to work just fine without that stuff. ;-) - -#define TEXTOOL_ENABLED 0 - -#if TEXTOOL_ENABLED - -namespace TexTool -{ - -//Shamus: Textool function prototypes -gboolean size_allocate( ui::Widget, GtkAllocation *, gpointer ); -gboolean expose( ui::Widget, GdkEventExpose *, gpointer ); -gboolean button_press( ui::Widget, GdkEventButton *, gpointer ); -gboolean button_release( ui::Widget, GdkEventButton *, gpointer ); -gboolean motion( ui::Widget, GdkEventMotion *, gpointer ); -void flipX( ui::ToggleButton, gpointer ); -void flipY( ui::ToggleButton, gpointer ); - -//End Textool function prototypes - -//Shamus: Textool globals -ui::Widget g_textoolWin; -//End Textool globals - -void queueDraw(){ - gtk_widget_queue_draw( g_textoolWin ); -} - -} - -#endif - -inline void spin_button_set_step(ui::SpinButton spin, gfloat step) -{ -#if 1 - gtk_adjustment_set_step_increment(gtk_spin_button_get_adjustment(spin), step); -#else - GValue gvalue = GValue_default(); - g_value_init( &gvalue, G_TYPE_DOUBLE ); - g_value_set_double( &gvalue, step ); - g_object_set( G_OBJECT( gtk_spin_button_get_adjustment( spin ) ), "step-increment", &gvalue, NULL ); -#endif -} - -class Increment { -float &m_f; -public: -ui::SpinButton m_spin; -ui::Entry m_entry; - -Increment(float &f) : m_f(f), m_spin(ui::null), m_entry(ui::null) -{ -} - -void cancel() -{ - entry_set_float(m_entry, m_f); -} - -typedef MemberCaller CancelCaller; - -void apply() -{ - m_f = static_cast( entry_get_float(m_entry)); - spin_button_set_step(m_spin, m_f); -} - -typedef MemberCaller ApplyCaller; -}; - -void SurfaceInspector_GridChange(); - -class SurfaceInspector : public Dialog { -ui::Window BuildDialog(); - -NonModalEntry m_textureEntry; -NonModalSpinner m_hshiftSpinner; -NonModalEntry m_hshiftEntry; -NonModalSpinner m_vshiftSpinner; -NonModalEntry m_vshiftEntry; -NonModalSpinner m_hscaleSpinner; -NonModalEntry m_hscaleEntry; -NonModalSpinner m_vscaleSpinner; -NonModalEntry m_vscaleEntry; -NonModalSpinner m_rotateSpinner; -NonModalEntry m_rotateEntry; - -IdleDraw m_idleDraw; - -GtkCheckButton *m_surfaceFlags[32]; -GtkCheckButton *m_contentFlags[32]; - -NonModalEntry m_valueEntry; -ui::Entry m_valueEntryWidget{ui::null}; -public: -WindowPositionTracker m_positionTracker; - -// Dialog Data -float m_fitHorizontal; -float m_fitVertical; - -Increment m_hshiftIncrement; -Increment m_vshiftIncrement; -Increment m_hscaleIncrement; -Increment m_vscaleIncrement; -Increment m_rotateIncrement; -ui::Entry m_texture{ui::null}; - -SurfaceInspector() : - m_textureEntry(ApplyShaderCaller(*this), UpdateCaller(*this)), - m_hshiftSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_hshiftEntry(Increment::ApplyCaller(m_hshiftIncrement), Increment::CancelCaller(m_hshiftIncrement)), - m_vshiftSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_vshiftEntry(Increment::ApplyCaller(m_vshiftIncrement), Increment::CancelCaller(m_vshiftIncrement)), - m_hscaleSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_hscaleEntry(Increment::ApplyCaller(m_hscaleIncrement), Increment::CancelCaller(m_hscaleIncrement)), - m_vscaleSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_vscaleEntry(Increment::ApplyCaller(m_vscaleIncrement), Increment::CancelCaller(m_vscaleIncrement)), - m_rotateSpinner(ApplyTexdefCaller(*this), UpdateCaller(*this)), - m_rotateEntry(Increment::ApplyCaller(m_rotateIncrement), Increment::CancelCaller(m_rotateIncrement)), - m_idleDraw(UpdateCaller(*this)), - m_valueEntry(ApplyFlagsCaller(*this), UpdateCaller(*this)), - m_hshiftIncrement(g_si_globals.shift[0]), - m_vshiftIncrement(g_si_globals.shift[1]), - m_hscaleIncrement(g_si_globals.scale[0]), - m_vscaleIncrement(g_si_globals.scale[1]), - m_rotateIncrement(g_si_globals.rotate) -{ - m_fitVertical = 1; - m_fitHorizontal = 1; - m_positionTracker.setPosition(c_default_window_pos); -} - -void constructWindow(ui::Window main_window) -{ - m_parent = main_window; - Create(); - AddGridChangeCallback(FreeCaller()); -} - -void destroyWindow() -{ - Destroy(); -} - -bool visible() -{ - return GetWidget().visible(); -} - -void queueDraw() -{ - if (visible()) { - m_idleDraw.queueDraw(); - } -} - -void Update(); - -typedef MemberCaller UpdateCaller; - -void ApplyShader(); - -typedef MemberCaller ApplyShaderCaller; - -void ApplyTexdef(); - -typedef MemberCaller ApplyTexdefCaller; - -void ApplyFlags(); - -typedef MemberCaller ApplyFlagsCaller; -}; - -namespace { -SurfaceInspector *g_SurfaceInspector; - -inline SurfaceInspector &getSurfaceInspector() -{ - ASSERT_NOTNULL(g_SurfaceInspector); - return *g_SurfaceInspector; -} -} - -void SurfaceInspector_constructWindow(ui::Window main_window) -{ - getSurfaceInspector().constructWindow(main_window); -} - -void SurfaceInspector_destroyWindow() -{ - getSurfaceInspector().destroyWindow(); -} - -void SurfaceInspector_queueDraw() -{ - getSurfaceInspector().queueDraw(); -} - -namespace { -CopiedString g_selectedShader; -TextureProjection g_selectedTexdef; -ContentsFlagsValue g_selectedFlags; -size_t g_selectedShaderSize[2]; -} - -void SurfaceInspector_SetSelectedShader(const char *shader) -{ - g_selectedShader = shader; - SurfaceInspector_queueDraw(); -} - -void SurfaceInspector_SetSelectedTexdef(const TextureProjection &projection) -{ - g_selectedTexdef = projection; - SurfaceInspector_queueDraw(); -} - -void SurfaceInspector_SetSelectedFlags(const ContentsFlagsValue &flags) -{ - g_selectedFlags = flags; - SurfaceInspector_queueDraw(); -} - -static bool s_texture_selection_dirty = false; - -void SurfaceInspector_updateSelection() -{ - s_texture_selection_dirty = true; - SurfaceInspector_queueDraw(); - -#if TEXTOOL_ENABLED - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { - TexTool::queueDraw(); - //globalOutputStream() << "textool texture changed..\n"; - } -#endif -} - -void SurfaceInspector_SelectionChanged(const Selectable &selectable) -{ - SurfaceInspector_updateSelection(); -} - -void SurfaceInspector_SetCurrent_FromSelected() -{ - if (s_texture_selection_dirty == true) { - s_texture_selection_dirty = false; - if (!g_SelectedFaceInstances.empty()) { - TextureProjection projection; -//This *may* be the point before it fucks up... Let's see! -//Yep, there was a call to removeScale in there... - Scene_BrushGetTexdef_Component_Selected(GlobalSceneGraph(), projection); - - SurfaceInspector_SetSelectedTexdef(projection); - - Scene_BrushGetShaderSize_Component_Selected(GlobalSceneGraph(), g_selectedShaderSize[0], - g_selectedShaderSize[1]); - g_selectedTexdef.m_brushprimit_texdef.coords[0][2] = float_mod( - g_selectedTexdef.m_brushprimit_texdef.coords[0][2], (float) g_selectedShaderSize[0]); - g_selectedTexdef.m_brushprimit_texdef.coords[1][2] = float_mod( - g_selectedTexdef.m_brushprimit_texdef.coords[1][2], (float) g_selectedShaderSize[1]); - - CopiedString name; - Scene_BrushGetShader_Component_Selected(GlobalSceneGraph(), name); - if (string_not_empty(name.c_str())) { - SurfaceInspector_SetSelectedShader(name.c_str()); - } - - ContentsFlagsValue flags; - Scene_BrushGetFlags_Component_Selected(GlobalSceneGraph(), flags); - SurfaceInspector_SetSelectedFlags(flags); - } else { - TextureProjection projection; - Scene_BrushGetTexdef_Selected(GlobalSceneGraph(), projection); - SurfaceInspector_SetSelectedTexdef(projection); - - CopiedString name; - Scene_BrushGetShader_Selected(GlobalSceneGraph(), name); - if (string_empty(name.c_str())) { - Scene_PatchGetShader_Selected(GlobalSceneGraph(), name); - } - if (string_not_empty(name.c_str())) { - SurfaceInspector_SetSelectedShader(name.c_str()); - } - - ContentsFlagsValue flags(0, 0, 0, false); - Scene_BrushGetFlags_Selected(GlobalSceneGraph(), flags); - SurfaceInspector_SetSelectedFlags(flags); - } - } -} - -const char *SurfaceInspector_GetSelectedShader() -{ - SurfaceInspector_SetCurrent_FromSelected(); - return g_selectedShader.c_str(); -} - -const TextureProjection &SurfaceInspector_GetSelectedTexdef() -{ - SurfaceInspector_SetCurrent_FromSelected(); - return g_selectedTexdef; -} - -const ContentsFlagsValue &SurfaceInspector_GetSelectedFlags() -{ - SurfaceInspector_SetCurrent_FromSelected(); - return g_selectedFlags; -} - - -/* - =================================================== - - SURFACE INSPECTOR - - =================================================== - */ - -si_globals_t g_si_globals; - - -// make the shift increments match the grid settings -// the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size -// this depends on a scale value if you have selected a particular texture on which you want it to work: -// we move the textures in pixels, not world units. (i.e. increment values are in pixel) -// depending on the texture scale it doesn't take the same amount of pixels to move of GetGridSize() -// increment * scale = gridsize -// hscale and vscale are optional parameters, if they are zero they will be set to the default scale -// NOTE: the default scale depends if you are using BP mode or regular. -// For regular it's 0.5f (128 pixels cover 64 world units), for BP it's simply 1.0f -// see fenris #2810 -void DoSnapTToGrid(float hscale, float vscale) -{ - g_si_globals.shift[0] = static_cast( float_to_integer(static_cast( GetGridSize()) / hscale)); - g_si_globals.shift[1] = static_cast( float_to_integer(static_cast( GetGridSize()) / vscale)); - getSurfaceInspector().queueDraw(); -} - -void SurfaceInspector_GridChange() -{ - if (g_si_globals.m_bSnapTToGrid) { - DoSnapTToGrid(Texdef_getDefaultTextureScale(), Texdef_getDefaultTextureScale()); - } -} - -// make the shift increments match the grid settings -// the objective being that the shift+arrows shortcuts move the texture by the corresponding grid size -// this depends on the current texture scale used? -// we move the textures in pixels, not world units. (i.e. increment values are in pixel) -// depending on the texture scale it doesn't take the same amount of pixels to move of GetGridSize() -// increment * scale = gridsize -static void OnBtnMatchGrid(ui::Widget widget, gpointer data) -{ - float hscale, vscale; - hscale = static_cast( gtk_spin_button_get_value(getSurfaceInspector().m_hscaleIncrement.m_spin)); - vscale = static_cast( gtk_spin_button_get_value(getSurfaceInspector().m_vscaleIncrement.m_spin)); - - if (hscale == 0.0f || vscale == 0.0f) { - globalOutputStream() << "ERROR: unexpected scale == 0.0f\n"; - return; - } - - DoSnapTToGrid(hscale, vscale); -} - -// DoSurface will always try to show the surface inspector -// or update it because something new has been selected -// Shamus: It does get called when the SI is hidden, but not when you select something new. ;-) -void DoSurface(void) -{ - if (!getSurfaceInspector().GetWidget()) { - getSurfaceInspector().Create(); - - } - getSurfaceInspector().Update(); - getSurfaceInspector().importData(); - getSurfaceInspector().ShowDlg(); -} - -void SurfaceInspector_toggleShown() -{ - if (getSurfaceInspector().visible()) { - getSurfaceInspector().HideDlg(); - } else { - DoSurface(); - } -} - -void SurfaceInspector_FitTexture() -{ - UndoableCommand undo("textureAutoFit"); - Select_FitTexture(getSurfaceInspector().m_fitHorizontal, getSurfaceInspector().m_fitVertical); -} - -void SurfaceInspector_AlignTopLeft() -{ - Select_AlignTexture(0); -} -void SurfaceInspector_AlignTop() -{ - Select_AlignTexture(1); -} -void SurfaceInspector_AlignTopRight() -{ - Select_AlignTexture(2); -} -void SurfaceInspector_AlignLeft() -{ - Select_AlignTexture(3); -} -void SurfaceInspector_AlignCenter() -{ - Select_AlignTexture(4); -} -void SurfaceInspector_AlignRight() -{ - Select_AlignTexture(5); -} -void SurfaceInspector_AlignBottomLeft() -{ - Select_AlignTexture(6); -} -void SurfaceInspector_AlignBottom() -{ - Select_AlignTexture(7); -} -void SurfaceInspector_AlignBottomRight() -{ - Select_AlignTexture(8); -} - -static void OnBtnPatchdetails(ui::Widget widget, gpointer data) -{ - Patch_CapTexture(); -} - -static void OnBtnPatchnatural(ui::Widget widget, gpointer data) -{ - Patch_NaturalTexture(); -} - -static void OnBtnPatchreset(ui::Widget widget, gpointer data) -{ - Patch_ResetTexture(); -} - -static void OnBtnPatchFit(ui::Widget widget, gpointer data) -{ - Patch_FitTexture(); -} - -static void OnBtnAxial(ui::Widget widget, gpointer data) -{ -//globalOutputStream() << "--> [OnBtnAxial]...\n"; - UndoableCommand undo("textureDefault"); - TextureProjection projection; -//globalOutputStream() << " TexDef_Construct_Default()...\n"; - TexDef_Construct_Default(projection); -//globalOutputStream() << " Select_SetTexdef()...\n"; - -#if TEXTOOL_ENABLED - - //Shamus: - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { - // Scale up texture width/height if in BP mode... -//NOTE: This may not be correct any more! :-P - if ( !g_SelectedFaceInstances.empty() ) { - Face & face = g_SelectedFaceInstances.last().getFace(); - float x = face.getShader().m_state->getTexture().width; - float y = face.getShader().m_state->getTexture().height; - projection.m_brushprimit_texdef.coords[0][0] /= x; - projection.m_brushprimit_texdef.coords[0][1] /= y; - projection.m_brushprimit_texdef.coords[1][0] /= x; - projection.m_brushprimit_texdef.coords[1][1] /= y; - } - } -#endif - - Select_SetTexdef(projection, true); -} - -static void OnBtnFaceFit(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_FitTexture(); -} - - -static void OnBtnTopLeft(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignTopLeft(); -} -static void OnBtnTopCenter(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignTop(); -} -static void OnBtnTopRight(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignTopRight(); -} - - -static void OnBtnMiddleLeft(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignLeft(); -} -static void OnBtnMiddleCenter(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignCenter(); -} -static void OnBtnMiddleRight(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignRight(); -} - - -static void OnBtnBottomLeft(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignBottomLeft(); -} -static void OnBtnBottomCenter(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignBottom(); -} -static void OnBtnBottomRight(ui::Widget widget, gpointer data) -{ - getSurfaceInspector().exportData(); - SurfaceInspector_AlignBottomRight(); -} - -typedef const char *FlagName; - -const FlagName surfaceflagNamesDefault[32] = { - "surf1", - "surf2", - "surf3", - "surf4", - "surf5", - "surf6", - "surf7", - "surf8", - "surf9", - "surf10", - "surf11", - "surf12", - "surf13", - "surf14", - "surf15", - "surf16", - "surf17", - "surf18", - "surf19", - "surf20", - "surf21", - "surf22", - "surf23", - "surf24", - "surf25", - "surf26", - "surf27", - "surf28", - "surf29", - "surf30", - "surf31", - "surf32" -}; - -const FlagName contentflagNamesDefault[32] = { - "cont1", - "cont2", - "cont3", - "cont4", - "cont5", - "cont6", - "cont7", - "cont8", - "cont9", - "cont10", - "cont11", - "cont12", - "cont13", - "cont14", - "cont15", - "cont16", - "cont17", - "cont18", - "cont19", - "cont20", - "cont21", - "cont22", - "cont23", - "cont24", - "cont25", - "cont26", - "cont27", - "cont28", - "cont29", - "cont30", - "cont31", - "cont32" -}; - -const char *getSurfaceFlagName(std::size_t bit) -{ - const char *value = g_pGameDescription->getKeyValue(surfaceflagNamesDefault[bit]); - if (string_empty(value)) { - return surfaceflagNamesDefault[bit]; - } - return value; -} - -const char *getContentFlagName(std::size_t bit) -{ - const char *value = g_pGameDescription->getKeyValue(contentflagNamesDefault[bit]); - if (string_empty(value)) { - return contentflagNamesDefault[bit]; - } - return value; -} - - -// ============================================================================= -// SurfaceInspector class - -guint togglebutton_connect_toggled(ui::ToggleButton button, const Callback &callback) -{ - return g_signal_connect_swapped(G_OBJECT(button), "toggled", G_CALLBACK(callback.getThunk()), - callback.getEnvironment()); -} - -ui::Window SurfaceInspector::BuildDialog() -{ - ui::Window window = ui::Window(create_floating_window("Surface Inspector", m_parent)); - - m_positionTracker.connect(window); - - global_accel_connect_window(window); - - window_connect_focus_in_clear_focus_widget(window); - - - { - // replaced by only the vbox: - auto vbox = ui::VBox(FALSE, 5); - vbox.show(); - window.add(vbox); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - - { - auto hbox2 = ui::HBox(FALSE, 5); - hbox2.show(); - vbox.pack_start(hbox2, FALSE, FALSE, 0); - - { - ui::Widget label = ui::Label("Texture"); - label.show(); - hbox2.pack_start(label, FALSE, TRUE, 0); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - hbox2.pack_start(entry, TRUE, TRUE, 0); - m_texture = entry; - m_textureEntry.connect(entry); - GlobalTextureEntryCompletion::instance().connect(entry); - } - } - - - { - auto table = ui::Table(6, 4, FALSE); - table.show(); - vbox.pack_start(table, FALSE, FALSE, 0); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - { - ui::Widget label = ui::Label("Horizontal shift"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 2); - m_hshiftIncrement.m_spin = spin; - m_hshiftSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(60, -1); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 0, 1}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - entry.dimensions(50, -1); - m_hshiftIncrement.m_entry = entry; - m_hshiftEntry.connect(entry); - } - { - ui::Widget label = ui::Label("Vertical shift"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 2); - m_vshiftIncrement.m_spin = spin; - m_vshiftSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 1, 2}, {GTK_FILL, 0}); - spin.dimensions(60, -1); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 1, 2}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 1, 2}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - m_vshiftIncrement.m_entry = entry; - m_vshiftEntry.connect(entry); - } - { - ui::Widget label = ui::Label("Horizontal stretch"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 2, 3}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 5); - m_hscaleIncrement.m_spin = spin; - m_hscaleSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 2, 3}, {GTK_FILL, 0}); - spin.dimensions(60, -1); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 2, 3}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 2, 3}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - m_hscaleIncrement.m_entry = entry; - m_hscaleEntry.connect(entry); - } - { - ui::Widget label = ui::Label("Vertical stretch"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 3, 4}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 5); - m_vscaleIncrement.m_spin = spin; - m_vscaleSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 3, 4}, {GTK_FILL, 0}); - spin.dimensions(60, -1); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 3, 4}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 3, 4}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - m_vscaleIncrement.m_entry = entry; - m_vscaleEntry.connect(entry); - } - { - ui::Widget label = ui::Label("Rotate"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {0, 1, 4, 5}, {GTK_FILL, 0}); - } - { - auto spin = ui::SpinButton(ui::Adjustment(0, -8192, 8192, 2, 8, 0), 0, 2); - m_rotateIncrement.m_spin = spin; - m_rotateSpinner.connect(spin); - spin.show(); - table.attach(spin, {1, 2, 4, 5}, {GTK_FILL, 0}); - spin.dimensions(60, -1); - gtk_spin_button_set_wrap(spin, TRUE); - } - { - ui::Widget label = ui::Label("Step"); - label.show(); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - table.attach(label, {2, 3, 4, 5}, {GTK_FILL, 0}); - } - { - auto entry = ui::Entry(ui::New); - entry.show(); - table.attach(entry, {3, 4, 4, 5}, {GTK_FILL, 0}); - entry.dimensions(50, -1); - m_rotateIncrement.m_entry = entry; - m_rotateEntry.connect(entry); - } - { - // match grid button - ui::Widget button = ui::Button("Match Grid"); - button.show(); - table.attach(button, {2, 4, 5, 6}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", G_CALLBACK(OnBtnMatchGrid), 0); - } - } - - { - auto frame = ui::Frame("Texturing"); - frame.show(); - vbox.pack_start(frame, FALSE, FALSE, 0); - { - auto table = ui::Table(4, 4, FALSE); - table.show(); - frame.add(table); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - gtk_container_set_border_width(GTK_CONTAINER(table), 5); - { - ui::Widget label = ui::Label("Brush"); - label.show(); - table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); - } - { - ui::Widget label = ui::Label("Patch"); - label.show(); - table.attach(label, {0, 1, 2, 3}, {GTK_FILL, 0}); - } - { - ui::Widget label = ui::Label("Width"); - label.show(); - table.attach(label, {2, 3, 0, 1}, {GTK_FILL, 0}); - } - { - ui::Widget label = ui::Label("Height"); - label.show(); - table.attach(label, {3, 4, 0, 1}, {GTK_FILL, 0}); - } - { - ui::Widget button = ui::Button("Axial"); - button.show(); - table.attach(button, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnAxial), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Fit"); - button.show(); - table.attach(button, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnFaceFit), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("CAP"); - button.show(); - table.attach(button, {0, 1, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnPatchdetails), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Set..."); - button.show(); - table.attach(button, {1, 2, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnPatchreset), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Natural"); - button.show(); - table.attach(button, {2, 3, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnPatchnatural), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Fit"); - button.show(); - table.attach(button, {3, 4, 3, 4}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnPatchFit), 0); - button.dimensions(60, -1); - } - { - auto spin = ui::SpinButton(ui::Adjustment(1, 0, 1 << 16, 1, 10, 0), 0, 6); - spin.show(); - table.attach(spin, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(60, -1); - AddDialogData(spin, m_fitHorizontal); - } - { - auto spin = ui::SpinButton(ui::Adjustment(1, 0, 1 << 16, 1, 10, 0), 0, 6); - spin.show(); - table.attach(spin, {3, 4, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - spin.dimensions(60, -1); - AddDialogData(spin, m_fitVertical); - } - } - } - { - auto frame = ui::Frame("Alignment"); - frame.show(); - vbox.pack_start(frame, FALSE, FALSE, 0); - { - auto table = ui::Table(3, 3, FALSE); - table.show(); - frame.add(table); - gtk_table_set_row_spacings(table, 5); - gtk_table_set_col_spacings(table, 5); - gtk_container_set_border_width(GTK_CONTAINER(table), 5); - { - ui::Widget button = ui::Button("Top-Left"); - button.show(); - table.attach(button, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnTopLeft), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Top"); - button.show(); - table.attach(button, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnTopCenter), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Top-Right"); - button.show(); - table.attach(button, {2, 3, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnTopRight), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Left"); - button.show(); - table.attach(button, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnMiddleLeft), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Center"); - button.show(); - table.attach(button, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnMiddleCenter), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Right"); - button.show(); - table.attach(button, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnMiddleRight), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Bottom-Left"); - button.show(); - table.attach(button, {0, 1, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnBottomLeft), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Bottom"); - button.show(); - table.attach(button, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnBottomCenter), 0); - button.dimensions(60, -1); - } - { - ui::Widget button = ui::Button("Bottom-Right"); - button.show(); - table.attach(button, {2, 3, 2, 3}, {GTK_EXPAND | GTK_FILL, 0}); - button.connect("clicked", - G_CALLBACK(OnBtnBottomRight), 0); - button.dimensions(60, -1); - } - } - } - - if (!string_empty(g_pGameDescription->getKeyValue("si_flags"))) { - { - auto frame = ui::Frame("Surface Flags"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 4); - //gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4); - vbox3.show(); - frame.add(vbox3); - { - auto table = ui::Table(8, 4, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 0); - gtk_table_set_col_spacings(table, 0); - - GtkCheckButton **p = m_surfaceFlags; - - for (unsigned int c = 0; c != 4; ++c) { - for (unsigned int r = 0; r != 8; ++r) { - auto check = ui::CheckButton(getSurfaceFlagName(c * 8 + r)); - check.show(); - table.attach(check, {c, c + 1, r, r + 1}, {GTK_EXPAND | GTK_FILL, 0}); - *p++ = check; - guint handler_id = togglebutton_connect_toggled(check, ApplyFlagsCaller(*this)); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer(handler_id)); - } - } - } - } - } - { - auto frame = ui::Frame("Content Flags"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 4); - //gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4); - vbox3.show(); - frame.add(vbox3); - { - - auto table = ui::Table(8, 4, FALSE); - table.show(); - vbox3.pack_start(table, TRUE, TRUE, 0); - gtk_table_set_row_spacings(table, 0); - gtk_table_set_col_spacings(table, 0); - - GtkCheckButton **p = m_contentFlags; - - for (unsigned int c = 0; c != 4; ++c) { - for (unsigned int r = 0; r != 8; ++r) { - auto check = ui::CheckButton(getContentFlagName(c * 8 + r)); - check.show(); - table.attach(check, {c, c + 1, r, r + 1}, {GTK_EXPAND | GTK_FILL, 0}); - *p++ = check; - guint handler_id = togglebutton_connect_toggled(check, ApplyFlagsCaller(*this)); - g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer(handler_id)); - } - } - - // not allowed to modify detail flag using Surface Inspector - gtk_widget_set_sensitive(ui::CheckButton::from(m_contentFlags[BRUSH_DETAIL_FLAG]), FALSE); - } - } - } - { - auto frame = ui::Frame("Value"); - frame.show(); - vbox.pack_start(frame, TRUE, TRUE, 0); - { - auto vbox3 = ui::VBox(FALSE, 4); - gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4); - vbox3.show(); - frame.add(vbox3); - - { - auto entry = ui::Entry(ui::New); - entry.show(); - vbox3.pack_start(entry, TRUE, TRUE, 0); - m_valueEntryWidget = entry; - m_valueEntry.connect(entry); - } - } - } - } - -#if TEXTOOL_ENABLED - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { -// Shamus: Textool goodies... - ui::Widget frame = ui::Frame( "Textool" ); - frame.show(); - vbox.pack_start( frame, FALSE, FALSE, 0 ); - { - //Prolly should make this a member or global var, so the SI can draw on it... - TexTool::g_textoolWin = glwidget_new( FALSE ); - // --> Dunno, but this stuff may be necessary... (Looks like it!) - g_object_ref( TexTool::g_textoolWin ); - gtk_widget_set_events( TexTool::g_textoolWin, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK ); - gtk_widget_set_can_focus( TexTool::g_textoolWin, true ); - // <-- end stuff... - TexTool::g_textoolWin.show(); - TexTool::g_textoolWin.dimensions( -1, 240 ); //Yeah! - frame.add(TexTool::g_textoolWin); - - TexTool::g_textoolWin.connect( "size_allocate", G_CALLBACK( TexTool::size_allocate ), NULL ); - TexTool::g_textoolWin.connect( "expose_event", G_CALLBACK( TexTool::expose ), NULL ); - TexTool::g_textoolWin.connect( "button_press_event", G_CALLBACK( TexTool::button_press ), NULL ); - TexTool::g_textoolWin.connect( "button_release_event", G_CALLBACK( TexTool::button_release ), NULL ); - TexTool::g_textoolWin.connect( "motion_notify_event", G_CALLBACK( TexTool::motion ), NULL ); - } - { - ui::Widget hbox = ui::HBox( FALSE, 5 ); - hbox.show(); - vbox.pack_start( hbox, FALSE, FALSE, 0 ); - // Checkboxes go here... (Flip X/Y) - ui::Widget flipX = ui::CheckButton( "Flip X axis" ); - ui::Widget flipY = ui::CheckButton( "Flip Y axis" ); - flipX.show(); - flipY.show(); - hbox.pack_start( flipX, FALSE, FALSE, 0 ); - hbox.pack_start( flipY, FALSE, FALSE, 0 ); - -//Instead of this, we probably need to create a vbox to put into the frame, then the -//window, then the hbox. !!! FIX !!! -// frame.add(hbox); - -//Hmm. Do we really need g_object_set_data? Mebbe not... And we don't! :-) -// g_object_set_data(G_OBJECT(flipX), "handler", gint_to_pointer(flipX.connect("toggled", G_CALLBACK(TexTool::flipX), 0))); -// g_object_set_data(G_OBJECT(flipY), "handler", gint_to_pointer(flipY.connect("toggled", G_CALLBACK(TexTool::flipY), 0))); -//Instead, just do: - flipX.connect( "toggled", G_CALLBACK( TexTool::flipX ), NULL ); - flipY.connect( "toggled", G_CALLBACK( TexTool::flipY ), NULL ); - } - } -#endif - } - - /* make small */ - gtk_window_set_default_size(GTK_WINDOW(window), 8, 8); - return window; -} - -/* - ============== - Update - - Set the fields to the current texdef (i.e. map/texdef -> dialog widgets) - if faces selected (instead of brushes) -> will read this face texdef, else current texdef - if only patches selected, will read the patch texdef - =============== - */ - -void spin_button_set_value_no_signal(ui::SpinButton spin, gdouble value) -{ - guint handler_id = gpointer_to_int(g_object_get_data(G_OBJECT(spin), "handler")); - g_signal_handler_block(G_OBJECT(gtk_spin_button_get_adjustment(spin)), handler_id); - gtk_spin_button_set_value(spin, value); - g_signal_handler_unblock(G_OBJECT(gtk_spin_button_get_adjustment(spin)), handler_id); -} - -void spin_button_set_step_increment(ui::SpinButton spin, gdouble value) -{ - auto adjust = gtk_spin_button_get_adjustment(spin); - gtk_adjustment_set_step_increment(adjust, value); -} - -void SurfaceInspector::Update() -{ - const char *name = SurfaceInspector_GetSelectedShader(); - - if (shader_is_texture(name)) { - m_texture.text(shader_get_textureName(name)); - } else { - m_texture.text(""); - } - - texdef_t shiftScaleRotate; -//Shamus: This is where we get into trouble--the BP code tries to convert to a "faked" -//shift, rotate & scale values from the brush face, which seems to screw up for some reason. -//!!! FIX !!! -/*globalOutputStream() << "--> SI::Update. About to do ShiftScaleRotate_fromFace()...\n"; - SurfaceInspector_GetSelectedBPTexdef(); - globalOutputStream() << "BP: (" << g_selectedBrushPrimitTexdef.coords[0][0] << ", " << g_selectedBrushPrimitTexdef.coords[0][1] << ")(" - << g_selectedBrushPrimitTexdef.coords[1][0] << ", " << g_selectedBrushPrimitTexdef.coords[1][1] << ")(" - << g_selectedBrushPrimitTexdef.coords[0][2] << ", " << g_selectedBrushPrimitTexdef.coords[1][2] << ") SurfaceInspector::Update\n";//*/ -//Ok, it's screwed up *before* we get here... - ShiftScaleRotate_fromFace(shiftScaleRotate, SurfaceInspector_GetSelectedTexdef()); - - // normalize again to hide the ridiculously high scale values that get created when using texlock - shiftScaleRotate.shift[0] = float_mod(shiftScaleRotate.shift[0], (float) g_selectedShaderSize[0]); - shiftScaleRotate.shift[1] = float_mod(shiftScaleRotate.shift[1], (float) g_selectedShaderSize[1]); - - { - spin_button_set_value_no_signal(m_hshiftIncrement.m_spin, shiftScaleRotate.shift[0]); - spin_button_set_step_increment(m_hshiftIncrement.m_spin, g_si_globals.shift[0]); - entry_set_float(m_hshiftIncrement.m_entry, g_si_globals.shift[0]); - } - - { - spin_button_set_value_no_signal(m_vshiftIncrement.m_spin, shiftScaleRotate.shift[1]); - spin_button_set_step_increment(m_vshiftIncrement.m_spin, g_si_globals.shift[1]); - entry_set_float(m_vshiftIncrement.m_entry, g_si_globals.shift[1]); - } - - { - spin_button_set_value_no_signal(m_hscaleIncrement.m_spin, shiftScaleRotate.scale[0]); - spin_button_set_step_increment(m_hscaleIncrement.m_spin, g_si_globals.scale[0]); - entry_set_float(m_hscaleIncrement.m_entry, g_si_globals.scale[0]); - } - - { - spin_button_set_value_no_signal(m_vscaleIncrement.m_spin, shiftScaleRotate.scale[1]); - spin_button_set_step_increment(m_vscaleIncrement.m_spin, g_si_globals.scale[1]); - entry_set_float(m_vscaleIncrement.m_entry, g_si_globals.scale[1]); - } - - { - spin_button_set_value_no_signal(m_rotateIncrement.m_spin, shiftScaleRotate.rotate); - spin_button_set_step_increment(m_rotateIncrement.m_spin, g_si_globals.rotate); - entry_set_float(m_rotateIncrement.m_entry, g_si_globals.rotate); - } - - if (!string_empty(g_pGameDescription->getKeyValue("si_flags"))) { - ContentsFlagsValue flags(SurfaceInspector_GetSelectedFlags()); - - entry_set_int(m_valueEntryWidget, flags.m_value); - - for (GtkCheckButton **p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p) { - toggle_button_set_active_no_signal(ui::CheckButton::from(*p), - flags.m_surfaceFlags & (1 << (p - m_surfaceFlags))); - } - - for (GtkCheckButton **p = m_contentFlags; p != m_contentFlags + 32; ++p) { - toggle_button_set_active_no_signal(ui::CheckButton::from(*p), - flags.m_contentFlags & (1 << (p - m_contentFlags))); - } - } -} - -/* - ============== - Apply - - Reads the fields to get the current texdef (i.e. widgets -> MAP) - in brush primitive mode, grab the fake shift scale rot and compute a new texture matrix - =============== - */ -void SurfaceInspector::ApplyShader() -{ - StringOutputStream name(256); - name << GlobalTexturePrefix_get() << gtk_entry_get_text(m_texture); - - // TTimo: detect and refuse invalid texture names (at least the ones with spaces) - if (!texdef_name_valid(name.c_str())) { - globalErrorStream() << "invalid texture name '" << name.c_str() << "'\n"; - SurfaceInspector_queueDraw(); - return; - } - - UndoableCommand undo("textureNameSetSelected"); - Select_SetShader(name.c_str()); -} - -void SurfaceInspector::ApplyTexdef() -{ - texdef_t shiftScaleRotate; - - shiftScaleRotate.shift[0] = static_cast( gtk_spin_button_get_value(m_hshiftIncrement.m_spin)); - shiftScaleRotate.shift[1] = static_cast( gtk_spin_button_get_value(m_vshiftIncrement.m_spin)); - shiftScaleRotate.scale[0] = static_cast( gtk_spin_button_get_value(m_hscaleIncrement.m_spin)); - shiftScaleRotate.scale[1] = static_cast( gtk_spin_button_get_value(m_vscaleIncrement.m_spin)); - shiftScaleRotate.rotate = static_cast( gtk_spin_button_get_value(m_rotateIncrement.m_spin)); - - TextureProjection projection; -//Shamus: This is the other place that screws up, it seems, since it doesn't seem to do the -//conversion from the face (I think) and so bogus values end up in the thing... !!! FIX !!! -//This is actually OK. :-P - ShiftScaleRotate_toFace(shiftScaleRotate, projection); - - UndoableCommand undo("textureProjectionSetSelected"); - Select_SetTexdef(projection, true); -} - -void SurfaceInspector::ApplyFlags() -{ - unsigned int surfaceflags = 0; - for (GtkCheckButton **p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*p))) { - surfaceflags |= (1 << (p - m_surfaceFlags)); - } - } - - unsigned int contentflags = 0; - for (GtkCheckButton **p = m_contentFlags; p != m_contentFlags + 32; ++p) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*p))) { - contentflags |= (1 << (p - m_contentFlags)); - } - } - - int value = entry_get_int(m_valueEntryWidget); - - UndoableCommand undo("flagsSetSelected"); - Select_SetFlags(ContentsFlagsValue(surfaceflags, contentflags, value, true)); -} - - -void Face_getTexture(Face &face, CopiedString &shader, TextureProjection &projection, ContentsFlagsValue &flags) -{ - shader = face.GetShader(); - face.GetTexdef(projection); - flags = face.getShader().m_flags; -} - -typedef Function FaceGetTexture; - -void -Face_setTexture(Face &face, const char *shader, const TextureProjection &projection, const ContentsFlagsValue &flags) -{ - face.SetShader(shader); - face.SetTexdef(projection, false); - face.SetFlags(flags); -} - -typedef Function FaceSetTexture; - - -void Patch_getTexture(Patch &patch, CopiedString &shader, TextureProjection &projection, ContentsFlagsValue &flags) -{ - shader = patch.GetShader(); - projection = TextureProjection(texdef_t(), brushprimit_texdef_t(), Vector3(0, 0, 0), Vector3(0, 0, 0)); - flags = ContentsFlagsValue(0, 0, 0, false); -} - -typedef Function PatchGetTexture; - -void -Patch_setTexture(Patch &patch, const char *shader, const TextureProjection &projection, const ContentsFlagsValue &flags) -{ - patch.SetShader(shader); -} - -typedef Function PatchSetTexture; - - -typedef Callback GetTextureCallback; -typedef Callback SetTextureCallback; - -struct Texturable { - GetTextureCallback getTexture; - SetTextureCallback setTexture; -}; - - -void Face_getClosest(Face &face, SelectionTest &test, SelectionIntersection &bestIntersection, Texturable &texturable) -{ - SelectionIntersection intersection; - face.testSelect(test, intersection); - if (intersection.valid() - && SelectionIntersection_closer(intersection, bestIntersection)) { - bestIntersection = intersection; - texturable.setTexture = makeCallback(FaceSetTexture(), face); - texturable.getTexture = makeCallback(FaceGetTexture(), face); - } -} - - -class OccludeSelector : public Selector { -SelectionIntersection &m_bestIntersection; -bool &m_occluded; -public: -OccludeSelector(SelectionIntersection &bestIntersection, bool &occluded) : m_bestIntersection(bestIntersection), - m_occluded(occluded) -{ - m_occluded = false; -} - -void pushSelectable(Selectable &selectable) -{ -} - -void popSelectable() -{ -} - -void addIntersection(const SelectionIntersection &intersection) -{ - if (SelectionIntersection_closer(intersection, m_bestIntersection)) { - m_bestIntersection = intersection; - m_occluded = true; - } -} -}; - -class BrushGetClosestFaceVisibleWalker : public scene::Graph::Walker { -SelectionTest &m_test; -Texturable &m_texturable; -mutable SelectionIntersection m_bestIntersection; -public: -BrushGetClosestFaceVisibleWalker(SelectionTest &test, Texturable &texturable) : m_test(test), - m_texturable(texturable) -{ -} - -bool pre(const scene::Path &path, scene::Instance &instance) const -{ - if (path.top().get().visible()) { - BrushInstance *brush = Instance_getBrush(instance); - if (brush != 0) { - m_test.BeginMesh(brush->localToWorld()); - - for (Brush::const_iterator i = brush->getBrush().begin(); i != brush->getBrush().end(); ++i) { - Face_getClosest(*(*i), m_test, m_bestIntersection, m_texturable); - } - } else { - SelectionTestable *selectionTestable = Instance_getSelectionTestable(instance); - if (selectionTestable) { - bool occluded; - OccludeSelector selector(m_bestIntersection, occluded); - selectionTestable->testSelect(selector, m_test); - if (occluded) { - Patch *patch = Node_getPatch(path.top()); - if (patch != 0) { - m_texturable.setTexture = makeCallback(PatchSetTexture(), *patch); - m_texturable.getTexture = makeCallback(PatchGetTexture(), *patch); - } else { - m_texturable = Texturable(); - } - } - } - } - } - return true; -} -}; - -Texturable Scene_getClosestTexturable(scene::Graph &graph, SelectionTest &test) -{ - Texturable texturable; - graph.traverse(BrushGetClosestFaceVisibleWalker(test, texturable)); - return texturable; -} - -bool -Scene_getClosestTexture(scene::Graph &graph, SelectionTest &test, CopiedString &shader, TextureProjection &projection, - ContentsFlagsValue &flags) -{ - Texturable texturable = Scene_getClosestTexturable(graph, test); - if (texturable.getTexture != GetTextureCallback()) { - texturable.getTexture(shader, projection, flags); - return true; - } - return false; -} - -void Scene_setClosestTexture(scene::Graph &graph, SelectionTest &test, const char *shader, - const TextureProjection &projection, const ContentsFlagsValue &flags) -{ - Texturable texturable = Scene_getClosestTexturable(graph, test); - if (texturable.setTexture != SetTextureCallback()) { - texturable.setTexture(shader, projection, flags); - } -} - - -class FaceTexture { -public: -TextureProjection m_projection; -ContentsFlagsValue m_flags; -}; - -FaceTexture g_faceTextureClipboard; - -void FaceTextureClipboard_setDefault() -{ - g_faceTextureClipboard.m_flags = ContentsFlagsValue(0, 0, 0, false); - TexDef_Construct_Default(g_faceTextureClipboard.m_projection); -} - -void TextureClipboard_textureSelected(const char *shader) -{ - FaceTextureClipboard_setDefault(); -} - -class TextureBrowser; - -extern TextureBrowser g_TextureBrowser; - -void TextureBrowser_SetSelectedShader(TextureBrowser &textureBrowser, const char *shader); - -const char *TextureBrowser_GetSelectedShader(TextureBrowser &textureBrowser); - -void Scene_copyClosestTexture(SelectionTest &test) -{ - CopiedString shader; - if (Scene_getClosestTexture(GlobalSceneGraph(), test, shader, g_faceTextureClipboard.m_projection, - g_faceTextureClipboard.m_flags)) { - TextureBrowser_SetSelectedShader(g_TextureBrowser, shader.c_str()); - } -} - -void Scene_applyClosestTexture(SelectionTest &test) -{ - UndoableCommand command("facePaintTexture"); - - Scene_setClosestTexture(GlobalSceneGraph(), test, TextureBrowser_GetSelectedShader(g_TextureBrowser), - g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags); - - SceneChangeNotify(); -} - - -void SelectedFaces_copyTexture() -{ - if (!g_SelectedFaceInstances.empty()) { - Face &face = g_SelectedFaceInstances.last().getFace(); - face.GetTexdef(g_faceTextureClipboard.m_projection); - g_faceTextureClipboard.m_flags = face.getShader().m_flags; - - TextureBrowser_SetSelectedShader(g_TextureBrowser, face.getShader().getShader()); - } -} - -void FaceInstance_pasteTexture(FaceInstance &faceInstance) -{ - faceInstance.getFace().SetTexdef(g_faceTextureClipboard.m_projection, false); - faceInstance.getFace().SetShader(TextureBrowser_GetSelectedShader(g_TextureBrowser)); - faceInstance.getFace().SetFlags(g_faceTextureClipboard.m_flags); - SceneChangeNotify(); -} - -bool SelectedFaces_empty() -{ - return g_SelectedFaceInstances.empty(); -} - -void SelectedFaces_pasteTexture() -{ - UndoableCommand command("facePasteTexture"); - g_SelectedFaceInstances.foreach(FaceInstance_pasteTexture); -} - - -void SurfaceInspector_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox("", "Surface Inspector Increments Match Grid", g_si_globals.m_bSnapTToGrid); -} - -void SurfaceInspector_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Surface Inspector", "Surface Inspector Preferences")); - SurfaceInspector_constructPreferences(page); -} - -void SurfaceInspector_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(SurfaceInspector_constructPage)); -} - -void SurfaceInspector_registerCommands() -{ - GlobalCommands_insert("FitTexture", makeCallbackF(SurfaceInspector_FitTexture), - Accelerator('B', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("SurfaceInspector", makeCallbackF(SurfaceInspector_toggleShown), Accelerator('S')); - - GlobalCommands_insert("FaceCopyTexture", makeCallbackF(SelectedFaces_copyTexture)); - GlobalCommands_insert("FacePasteTexture", makeCallbackF(SelectedFaces_pasteTexture)); -} - - -#include "preferencesystem.h" - - -void SurfaceInspector_Construct() -{ - g_SurfaceInspector = new SurfaceInspector; - - SurfaceInspector_registerCommands(); - - FaceTextureClipboard_setDefault(); - - GlobalPreferenceSystem().registerPreference("SurfaceWnd", make_property( - getSurfaceInspector().m_positionTracker)); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Scale1", make_property_string(g_si_globals.scale[0])); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Scale2", make_property_string(g_si_globals.scale[1])); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Shift1", make_property_string(g_si_globals.shift[0])); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Shift2", make_property_string(g_si_globals.shift[1])); - GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Rotate", make_property_string(g_si_globals.rotate)); - GlobalPreferenceSystem().registerPreference("SnapTToGrid", make_property_string(g_si_globals.m_bSnapTToGrid)); - - typedef FreeCaller SurfaceInspectorSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback(SurfaceInspectorSelectionChangedCaller()); - typedef FreeCaller SurfaceInspectorUpdateSelectionCaller; - Brush_addTextureChangedCallback(SurfaceInspectorUpdateSelectionCaller()); - Patch_addTextureChangedCallback(SurfaceInspectorUpdateSelectionCaller()); - - SurfaceInspector_registerPreferencesPage(); -} - -void SurfaceInspector_Destroy() -{ - delete g_SurfaceInspector; -} - - -#if TEXTOOL_ENABLED - -namespace TexTool { // namespace hides these symbols from other object-files -// -//Shamus: Textool functions, including GTK+ callbacks -// - -//NOTE: Black screen when TT first comes up is caused by an uninitialized Extent... !!! FIX !!! -// But... You can see down below that it *is* initialized! WTF? -struct Extent -{ - float minX, minY, maxX, maxY; - float width( void ) { - return fabs( maxX - minX ); - } - float height( void ) { - return fabs( maxY - minY ); - } -}; - -//This seems to control the texture scale... (Yep! ;-) -Extent extents = { -2.0f, -2.0f, +2.0f, +2.0f }; -brushprimit_texdef_t tm; // Texture transform matrix -Vector2 pts[c_brush_maxFaces]; -Vector2 center; -int numPts; -int textureNum; -Vector2 textureSize; -Vector2 windowSize; -#define VP_PADDING 1.2 -#define PI 3.14159265358979 -bool lButtonDown = false; -bool rButtonDown = false; -//int dragPoint; -//int anchorPoint; -bool haveAnchor = false; -brushprimit_texdef_t currentBP; -brushprimit_texdef_t origBP; // Original brush primitive (before we muck it up) -float controlRadius = 5.0f; -float rotationAngle = 0.0f; -float rotationAngle2 = 0.0f; -float oldRotationAngle; -Vector2 rotationPoint; -bool translatingX = false; // Widget state variables -bool translatingY = false; -bool scalingX = false; -bool scalingY = false; -bool rotating = false; -bool resizingX = false; // Not sure what this means... :-/ -bool resizingY = false; -float origAngle, origScaleX, origScaleY; -Vector2 oldCenter; - - -// Function prototypes (move up to top later...) - -void DrawCircularArc( Vector2 ctr, float startAngle, float endAngle, float radius ); - - -void CopyPointsFromSelectedFace( void ){ - // Make sure that there's a face and winding to get! - - if ( g_SelectedFaceInstances.empty() ) { - numPts = 0; - return; - } - - Face & face = g_SelectedFaceInstances.last().getFace(); - textureNum = face.getShader().m_state->getTexture().texture_number; - textureSize.x() = face.getShader().m_state->getTexture().width; - textureSize.y() = face.getShader().m_state->getTexture().height; -//globalOutputStream() << "--> Texture #" << textureNum << ": " << textureSize.x() << " x " << textureSize.y() << "...\n"; - - currentBP = SurfaceInspector_GetSelectedTexdef().m_brushprimit_texdef; - - face.EmitTextureCoordinates(); - Winding & w = face.getWinding(); - int count = 0; - - for ( Winding::const_iterator i = w.begin(); i != w.end(); i++ ) - { - //globalOutputStream() << (*i).texcoord.x() << " " << (*i).texcoord.y() << ", "; - pts[count].x() = ( *i ).texcoord.x(); - pts[count].y() = ( *i ).texcoord.y(); - count++; - } - - numPts = count; - - //globalOutputStream() << " ..copied points\n"; -} - -brushprimit_texdef_t bp; -//This approach is probably wrongheaded and just not right anyway. So, !!! FIX !!! [DONE] -void CommitChanges( void ){ - texdef_t t; // Throwaway, since this is BP only - - bp.coords[0][0] = tm.coords[0][0] * origBP.coords[0][0] + tm.coords[0][1] * origBP.coords[1][0]; - bp.coords[0][1] = tm.coords[0][0] * origBP.coords[0][1] + tm.coords[0][1] * origBP.coords[1][1]; - bp.coords[0][2] = tm.coords[0][0] * origBP.coords[0][2] + tm.coords[0][1] * origBP.coords[1][2] + tm.coords[0][2]; -//Ok, this works for translation... -// bp.coords[0][2] = tm.coords[0][0] * origBP.coords[0][2] + tm.coords[0][1] * origBP.coords[1][2] + tm.coords[0][2] * textureSize.x(); - bp.coords[1][0] = tm.coords[1][0] * origBP.coords[0][0] + tm.coords[1][1] * origBP.coords[1][0]; - bp.coords[1][1] = tm.coords[1][0] * origBP.coords[0][1] + tm.coords[1][1] * origBP.coords[1][1]; - bp.coords[1][2] = tm.coords[1][0] * origBP.coords[0][2] + tm.coords[1][1] * origBP.coords[1][2] + tm.coords[1][2]; -// bp.coords[1][2] = tm.coords[1][0] * origBP.coords[0][2] + tm.coords[1][1] * origBP.coords[1][2] + tm.coords[1][2] * textureSize.y(); - -//This doesn't work: g_brush_texture_changed(); -// Let's try this: -//Note: We should only set an undo *after* the button has been released... !!! FIX !!! -//Definitely *should* have an undo, though! -// UndoableCommand undo("textureProjectionSetSelected"); - Select_SetTexdef( TextureProjection( t, bp, Vector3( 0, 0, 0 ), Vector3( 0, 0, 0 ) ) ); -//This is working, but for some reason the translate is causing the rest of the SI -//widgets to yield bad readings... !!! FIX !!! -//I.e., click on textool window, translate face wireframe, then controls go crazy. Dunno why. -//It's because there were some uncommented out add/removeScale functions in brush.h and a -//removeScale in brushmanip.cpp... :-/ -//Translate isn't working at all now... :-( -//It's because we need to multiply in some scaling factor (prolly the texture width/height) -//Yep. :-P -} - -void UpdateControlPoints( void ){ - CommitChanges(); - - // Init texture transform matrix - - tm.coords[0][0] = 1.0f; tm.coords[0][1] = 0.0f; tm.coords[0][2] = 0.0f; - tm.coords[1][0] = 0.0f; tm.coords[1][1] = 1.0f; tm.coords[1][2] = 0.0f; -} - - -/* - For shifting we have: - */ -/* - The code that should provide reasonable defaults, but doesn't for some reason: - It's scaling the BP by 128 for some reason, between the time it's created and the - time we get back to the SI widgets: - - static void OnBtnAxial(GtkWidget *widget, gpointer data) - { - UndoableCommand undo("textureDefault"); - TextureProjection projection; - TexDef_Construct_Default(projection); - Select_SetTexdef(projection); - } - - Select_SetTexdef() calls Scene_BrushSetTexdef_Component_Selected(GlobalSceneGraph(), projection) - which is in brushmanip.h: This eventually calls - Texdef_Assign(m_texdef, texdef, m_brushprimit_texdef, brushprimit_texdef) in class Face... - which just copies from brushpr to m_brushpr... - */ - -//Small problem with this thing: It's scaled to the texture which is all screwed up... !!! FIX !!! [DONE] -//Prolly should separate out the grid drawing so that we can draw it behind the polygon. -const float gridWidth = 1.3f; // Let's try an absolute height... WORKS!!! -// NOTE that 2.0 is the height of the viewport. Dunno why... Should make collision -// detection easier... -const float gridRadius = gridWidth * 0.5f; - -typedef const float WidgetColor[3]; -const WidgetColor widgetColor[10] = { - { 1.0000f, 0.2000f, 0.0000f }, // Red - { 0.9137f, 0.9765f, 0.4980f }, // Yellow - { 0.0000f, 0.6000f, 0.3216f }, // Green - { 0.6157f, 0.7726f, 0.8196f }, // Cyan - { 0.4980f, 0.5000f, 0.4716f }, // Grey - - // Highlight colors - { 1.0000f, 0.6000f, 0.4000f }, // Light Red - { 1.0000f, 1.0000f, 0.8980f }, // Light Yellow - { 0.4000f, 1.0000f, 0.7216f }, // Light Green - { 1.0000f, 1.0000f, 1.0000f }, // Light Cyan - { 0.8980f, 0.9000f, 0.8716f } // Light Grey -}; - -#define COLOR_RED 0 -#define COLOR_YELLOW 1 -#define COLOR_GREEN 2 -#define COLOR_CYAN 3 -#define COLOR_GREY 4 -#define COLOR_LT_RED 5 -#define COLOR_LT_YELLOW 6 -#define COLOR_LT_GREEN 7 -#define COLOR_LT_CYAN 8 -#define COLOR_LT_GREY 9 - -void DrawControlWidgets( void ){ -//Note that the grid should go *behind* the face outline... !!! FIX !!! - // Grid - float xStart = center.x() - ( gridWidth / 2.0f ); - float yStart = center.y() - ( gridWidth / 2.0f ); - float xScale = ( extents.height() / extents.width() ) * ( textureSize.y() / textureSize.x() ); - - glPushMatrix(); -//Small problem with this approach: Changing the center point in the TX code doesn't seem to -//change anything here--prolly because we load a new identity matrix. A couple of ways to fix -//this would be to get rid of that code, or change the center to a new point by taking into -//account the transforms that we toss with the new identity matrix. Dunno which is better. - glLoadIdentity(); - glScalef( xScale, 1.0, 1.0 ); // Will that square it up? Yup. - glRotatef( static_cast( radians_to_degrees( atan2( -currentBP.coords[0][1], currentBP.coords[0][0] ) ) ), 0.0, 0.0, -1.0 ); - glTranslatef( -center.x(), -center.y(), 0.0 ); - - // Circle - glColor3fv( translatingX && translatingY ? widgetColor[COLOR_LT_YELLOW] : widgetColor[COLOR_YELLOW] ); - glBegin( GL_LINE_LOOP ); - DrawCircularArc( center, 0, 2.0f * PI, gridRadius * 0.16 ); - - glEnd(); - - // Axes - glBegin( GL_LINES ); - glColor3fv( translatingY && !translatingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN] ); - glVertex2f( center.x(), center.y() + ( gridRadius * 0.16 ) ); - glVertex2f( center.x(), center.y() + ( gridRadius * 1.00 ) ); - glColor3fv( translatingX && !translatingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED] ); - glVertex2f( center.x() + ( gridRadius * 0.16 ), center.y() ); - glVertex2f( center.x() + ( gridRadius * 1.00 ), center.y() ); - glEnd(); - - // Arrowheads - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glBegin( GL_TRIANGLES ); - glColor3fv( translatingY && !translatingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN] ); - glVertex2f( center.x(), center.y() + ( gridRadius * 1.10 ) ); - glVertex2f( center.x() + ( gridRadius * 0.06 ), center.y() + ( gridRadius * 0.94 ) ); - glVertex2f( center.x() - ( gridRadius * 0.06 ), center.y() + ( gridRadius * 0.94 ) ); - glColor3fv( translatingX && !translatingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED] ); - glVertex2f( center.x() + ( gridRadius * 1.10 ), center.y() ); - glVertex2f( center.x() + ( gridRadius * 0.94 ), center.y() + ( gridRadius * 0.06 ) ); - glVertex2f( center.x() + ( gridRadius * 0.94 ), center.y() - ( gridRadius * 0.06 ) ); - glEnd(); - - // Arc - glBegin( GL_LINE_STRIP ); - glColor3fv( rotating ? widgetColor[COLOR_LT_CYAN] : widgetColor[COLOR_CYAN] ); - DrawCircularArc( center, 0.03f * PI, 0.47f * PI, gridRadius * 0.90 ); - glEnd(); - - // Boxes - glColor3fv( scalingY && !scalingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN] ); - glBegin( GL_LINES ); - glVertex2f( center.x() + ( gridRadius * 0.20 ), center.y() + ( gridRadius * 1.50 ) ); - glVertex2f( center.x() - ( gridRadius * 0.20 ), center.y() + ( gridRadius * 1.50 ) ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( center.x() + ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.40 ) ); - glVertex2f( center.x() - ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.40 ) ); - glVertex2f( center.x() - ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.20 ) ); - glVertex2f( center.x() + ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.20 ) ); - glEnd(); - - glColor3fv( scalingX && !scalingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED] ); - glBegin( GL_LINES ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() + ( gridRadius * 0.20 ) ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() - ( gridRadius * 0.20 ) ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() + ( gridRadius * 0.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() - ( gridRadius * 0.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() - ( gridRadius * 0.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() + ( gridRadius * 0.10 ) ); - glEnd(); - - glColor3fv( scalingX && scalingY ? widgetColor[COLOR_LT_CYAN] : widgetColor[COLOR_CYAN] ); - glBegin( GL_LINE_STRIP ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() + ( gridRadius * 1.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() + ( gridRadius * 1.50 ) ); - glVertex2f( center.x() + ( gridRadius * 1.10 ), center.y() + ( gridRadius * 1.50 ) ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() + ( gridRadius * 1.40 ) ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() + ( gridRadius * 1.20 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() + ( gridRadius * 1.20 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() + ( gridRadius * 1.40 ) ); - glEnd(); - - glPopMatrix(); -} - -void DrawControlPoints( void ){ - glColor3f( 1, 1, 1 ); - glBegin( GL_LINE_LOOP ); - - for ( int i = 0; i < numPts; i++ ) - glVertex2f( pts[i].x(), pts[i].y() ); - - glEnd(); -} - -// Note: Setup and all that jazz must be done by the caller! - -void DrawCircularArc( Vector2 ctr, float startAngle, float endAngle, float radius ){ - float stepSize = ( 2.0f * PI ) / 200.0f; - - for ( float angle = startAngle; angle <= endAngle; angle += stepSize ) - glVertex2f( ctr.x() + radius * cos( angle ), ctr.y() + radius * sin( angle ) ); -} - - -void focus(){ - if ( numPts == 0 ) { - return; - } - - // Find selected texture's extents... - - extents.minX = extents.maxX = pts[0].x(), - extents.minY = extents.maxY = pts[0].y(); - - for ( int i = 1; i < numPts; i++ ) - { - if ( pts[i].x() < extents.minX ) { - extents.minX = pts[i].x(); - } - if ( pts[i].x() > extents.maxX ) { - extents.maxX = pts[i].x(); - } - if ( pts[i].y() < extents.minY ) { - extents.minY = pts[i].y(); - } - if ( pts[i].y() > extents.maxY ) { - extents.maxY = pts[i].y(); - } - } - - // Do some viewport fitting stuff... - -//globalOutputStream() << "--> Center: " << center.x() << ", " << center.y() << "\n"; -//globalOutputStream() << "--> Extents (stage 1): " << extents.minX << ", " -// << extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n"; - // TTimo: Apply a ratio to get the area we'll draw. - center.x() = 0.5f * ( extents.minX + extents.maxX ), - center.y() = 0.5f * ( extents.minY + extents.maxY ); - extents.minX = center.x() + VP_PADDING * ( extents.minX - center.x() ), - extents.minY = center.y() + VP_PADDING * ( extents.minY - center.y() ), - extents.maxX = center.x() + VP_PADDING * ( extents.maxX - center.x() ), - extents.maxY = center.y() + VP_PADDING * ( extents.maxY - center.y() ); -//globalOutputStream() << "--> Extents (stage 2): " << extents.minX << ", " -// << extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n"; - - // TTimo: We want a texture with the same X / Y ratio. - // TTimo: Compute XY space / window size ratio. - float SSize = extents.width(), TSize = extents.height(); - float ratioX = textureSize.x() * extents.width() / windowSize.x(), - ratioY = textureSize.y() * extents.height() / windowSize.y(); -//globalOutputStream() << "--> Texture size: " << textureSize.x() << ", " << textureSize.y() << "\n"; -//globalOutputStream() << "--> Window size: " << windowSize.x() << ", " << windowSize.y() << "\n"; - - if ( ratioX > ratioY ) { - TSize = ( windowSize.y() * ratioX ) / textureSize.y(); -// TSize = extents.width() * (windowSize.y() / windowSize.x()) * (textureSize.x() / textureSize.y()); - } - else - { - SSize = ( windowSize.x() * ratioY ) / textureSize.x(); -// SSize = extents.height() * (windowSize.x() / windowSize.y()) * (textureSize.y() / textureSize.x()); - } - - extents.minX = center.x() - 0.5f * SSize, extents.maxX = center.x() + 0.5f * SSize, - extents.minY = center.y() - 0.5f * TSize, extents.maxY = center.y() + 0.5f * TSize; -//globalOutputStream() << "--> Extents (stage 3): " << extents.minX << ", " -// << extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n"; -} - -gboolean size_allocate( ui::Widget win, GtkAllocation * a, gpointer ){ - windowSize.x() = a->width; - windowSize.y() = a->height; - queueDraw(); - return false; -} - -gboolean expose( ui::Widget win, GdkEventExpose * e, gpointer ){ -// globalOutputStream() << "--> Textool Window was exposed!\n"; -// globalOutputStream() << " (window width/height: " << cc << "/" << e->area.height << ")\n"; - -// windowSize.x() = e->area.width, windowSize.y() = e->area.height; -//This needs to go elsewhere... -// InitTextool(); - - if ( glwidget_make_current( win ) == FALSE ) { - globalOutputStream() << " FAILED to make current! Oh, the agony! :-(\n"; - return true; - } - - CopyPointsFromSelectedFace(); - - if ( !lButtonDown ) { - focus(); - } - - // Probably should init button/anchor states here as well... -// rotationAngle = 0.0f; - glClearColor( 0, 0, 0, 0 ); - glViewport( 0, 0, e->area.width, e->area.height ); - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - -//??? - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_BLEND ); - - glOrtho( extents.minX, extents.maxX, extents.maxY, extents.minY, -1, 1 ); - - glColor3f( 1, 1, 1 ); - // draw the texture background - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glBindTexture( GL_TEXTURE_2D, textureNum ); - - glEnable( GL_TEXTURE_2D ); - glBegin( GL_QUADS ); - glTexCoord2f( extents.minX, extents.minY ); - glVertex2f( extents.minX, extents.minY ); - glTexCoord2f( extents.maxX, extents.minY ); - glVertex2f( extents.maxX, extents.minY ); - glTexCoord2f( extents.maxX, extents.maxY ); - glVertex2f( extents.maxX, extents.maxY ); - glTexCoord2f( extents.minX, extents.maxY ); - glVertex2f( extents.minX, extents.maxY ); - glEnd(); - glDisable( GL_TEXTURE_2D ); - - // draw the texture-space grid - glColor3fv( widgetColor[COLOR_GREY] ); - glBegin( GL_LINES ); - - const int gridSubdivisions = 8; - const float gridExtents = 4.0f; - - for ( int i = 0; i < gridSubdivisions + 1; ++i ) - { - float y = i * ( gridExtents / float(gridSubdivisions) ); - float x = i * ( gridExtents / float(gridSubdivisions) ); - glVertex2f( 0, y ); - glVertex2f( gridExtents, y ); - glVertex2f( x, 0 ); - glVertex2f( x, gridExtents ); - } - - glEnd(); - - DrawControlPoints(); - DrawControlWidgets(); -//??? - // reset the current texture -// glBindTexture(GL_TEXTURE_2D, 0); -// glFinish(); - glwidget_swap_buffers( win ); - - return false; -} - -/*int FindSelectedPoint(int x, int y) - { - for(int i=0; i Textool button press...\n"; - - if ( e->button == 1 ) { - lButtonDown = true; - GlobalUndoSystem().start(); - - origBP = currentBP; - - //globalOutputStream() << "--> Original BP: [" << origBP.coords[0][0] << "][" << origBP.coords[0][1] << "][" << origBP.coords[0][2] << "]\n"; - //globalOutputStream() << " [" << origBP.coords[1][0] << "][" << origBP.coords[1][1] << "][" << origBP.coords[1][2] << "]\n"; - //float angle = atan2(origBP.coords[0][1], origBP.coords[0][0]) * 180.0f / 3.141592653589f; - origAngle = ( origBP.coords[0][1] > 0 ? PI : -PI ); // Could also be -PI... !!! FIX !!! [DONE] - - if ( origBP.coords[0][0] != 0.0f ) { - origAngle = atan( origBP.coords[0][1] / origBP.coords[0][0] ); - } - - origScaleX = origBP.coords[0][0] / cos( origAngle ); - origScaleY = origBP.coords[1][1] / cos( origAngle ); - rotationAngle = origAngle; - oldCenter[0] = oldCenter[1] = 0; - - //globalOutputStream() << "--> BP stats: ang=" << origAngle * RAD_TO_DEG << ", scale=" << origScaleX << "/" << origScaleY << "\n"; - //Should also set the Flip X/Y checkboxes here as well... !!! FIX !!! - //Also: should reverse texture left/right up/down instead of flipping the points... - -//disnowok -//float nx = windowSize.x() * (e->x - extents.minX) / (extents.maxX - extents.minX); -//float ny = windowSize.y() * (e->y - extents.minY) / (extents.maxY - extents.minY); -//disdoes... -//But I want it to scroll the texture window, not the points... !!! FIX !!! -//Actually, should scroll the texture window only when mouse is down on no widgets... - float nx = e->x / windowSize.x() * extents.width() + extents.minX; - float ny = e->y / windowSize.y() * extents.height() + extents.minY; - trans.x() = -tm.coords[0][0] * nx - tm.coords[0][1] * ny; - trans.y() = -tm.coords[1][0] * nx - tm.coords[1][1] * ny; - - dragPoint.x() = e->x, dragPoint.y() = e->y; - trans2.x() = nx, trans2.y() = ny; - oldRotationAngle = rotationAngle; -// oldTrans.x() = tm.coords[0][2] - nx * textureSize.x(); -// oldTrans.y() = tm.coords[1][2] - ny * textureSize.y(); - oldTrans.x() = tm.coords[0][2]; - oldTrans.y() = tm.coords[1][2]; - oldCenter.x() = center.x(); - oldCenter.y() = center.y(); - - queueDraw(); - - return true; - } -/* else if (e->button == 3) - { - rButtonDown = true; - }//*/ - -//globalOutputStream() << "(" << (haveAnchor ? "anchor" : "released") << ")\n"; - - return false; -} - -gboolean button_release( ui::Widget win, GdkEventButton * e, gpointer ){ -// globalOutputStream() << "--> Textool button release...\n"; - - if ( e->button == 1 ) { -/* float ptx = e->x / windowSize.x() * extents.width() + extents.minX; - float pty = e->y / windowSize.y() * extents.height() + extents.minY; - - //This prolly should go into the mouse move code... - //Doesn't work correctly anyway... - if (translatingX || translatingY) - center.x() = ptx, center.y() = pty;//*/ - - lButtonDown = false; - - if ( translatingX || translatingY ) { - GlobalUndoSystem().finish( "translateTexture" ); - } - else if ( rotating ) { - GlobalUndoSystem().finish( "rotateTexture" ); - } - else if ( scalingX || scalingY ) { - GlobalUndoSystem().finish( "scaleTexture" ); - } - else if ( resizingX || resizingY ) { - GlobalUndoSystem().finish( "resizeTexture" ); - } - else - { - GlobalUndoSystem().finish( "textoolUnknown" ); - } - - rotating = translatingX = translatingY = scalingX = scalingY - = resizingX = resizingY = false; - - queueDraw(); - } - else if ( e->button == 3 ) { - rButtonDown = false; - } - - return true; -} - -/* - void C2DView::GridForWindow( float c[2], int x, int y) - { - SpaceForWindow( c, x, y ); - if ( !m_bDoGrid ) - return; - c[0] /= m_GridStep[0]; - c[1] /= m_GridStep[1]; - c[0] = (float)floor( c[0] + 0.5f ); - c[1] = (float)floor( c[1] + 0.5f ); - c[0] *= m_GridStep[0]; - c[1] *= m_GridStep[1]; - } - void C2DView::SpaceForWindow( float c[2], int x, int y) - { - c[0] = ((float)(x))/((float)(m_rect.right-m_rect.left))*(m_Maxs[0]-m_Mins[0])+m_Mins[0]; - c[1] = ((float)(y))/((float)(m_rect.bottom-m_rect.top))*(m_Maxs[1]-m_Mins[1])+m_Mins[1]; - } - */ -gboolean motion( ui::Widget win, GdkEventMotion * e, gpointer ){ -// globalOutputStream() << "--> Textool motion...\n"; - - if ( lButtonDown ) { - if ( translatingX || translatingY ) { - float ptx = e->x / windowSize.x() * extents.width() + extents.minX; - float pty = e->y / windowSize.y() * extents.height() + extents.minY; - -//Need to fix this to take the rotation angle into account, so that it moves along -//the rotated X/Y axis... - if ( translatingX ) { -// tm.coords[0][2] = (trans.x() + ptx) * textureSize.x(); -//This works, but only when the angle is zero. !!! FIX !!! [DONE] -// tm.coords[0][2] = oldCenter.x() + (ptx * textureSize.x()); - tm.coords[0][2] = oldTrans.x() + ( ptx - trans2.x() ) * textureSize.x(); -// center.x() = oldCenter.x() + (ptx - trans2.x()); - } - - if ( translatingY ) { -// tm.coords[1][2] = (trans.y() + pty) * textureSize.y(); -// tm.coords[1][2] = oldCenter.y() + (pty * textureSize.y()); - tm.coords[1][2] = oldTrans.y() + ( pty - trans2.y() ) * textureSize.y(); -// center.y() = oldCenter.y() + (pty - trans2.y()); - } - -//Need to update center.x/y() so that the widget translates as well. Also, oldCenter -//is badly named... Should be oldTrans or something like that... !!! FIX !!! -//Changing center.x/y() here doesn't seem to change anything... :-/ - UpdateControlPoints(); - } - else if ( rotating ) { - // Shamus: New rotate code - int cx = (int)( windowSize.x() * ( center.x() - extents.minX ) / extents.width() ); - int cy = (int)( windowSize.y() * ( center.y() - extents.minY ) / extents.height() ); - Vector3 v1( dragPoint.x() - cx, dragPoint.y() - cy, 0 ), v2( e->x - cx, e->y - cy, 0 ); - - vector3_normalise( v1 ); - vector3_normalise( v2 ); - float c = vector3_dot( v1, v2 ); - Vector3 cross = vector3_cross( v1, v2 ); - float s = vector3_length( cross ); - - if ( cross[2] > 0 ) { - s = -s; - } - -// Problem with this: arcsin/cos seems to only return -90 to 90 and 0 to 180... -// Can't derive angle from that! - -//rotationAngle = asin(s);// * 180.0f / 3.141592653589f; - rotationAngle = acos( c ); -//rotationAngle2 = asin(s); - if ( cross[2] < 0 ) { - rotationAngle = -rotationAngle; - } - -//NO! DOESN'T WORK! rotationAngle -= 45.0f * DEG_TO_RAD; -//Let's try this: -//No wok. -/*c = cos(rotationAngle - oldRotationAngle); - s = sin(rotationAngle - oldRotationAngle); - rotationAngle += oldRotationAngle; - //c += cos(oldRotationAngle); - //s += sin(oldRotationAngle); - //rotationAngle += oldRotationAngle; - //c %= 2.0 * PI; - //s %= 2.0 * PI; - //rotationAngle %= 2.0 * PI;//*/ - -//This is wrong... Hmm... -//It seems to shear the texture instead of rotating it... !!! FIX !!! -// Now it rotates correctly. Seems TTimo was overcomplicating things here... ;-) - -// Seems like what needs to happen here is multiplying these rotations by tm... !!! FIX !!! - -// See brush_primit.cpp line 244 (Texdef_EmitTextureCoordinates()) for where texcoords come from... - - tm.coords[0][0] = c; - tm.coords[0][1] = s; - tm.coords[1][0] = -s; - tm.coords[1][1] = c; -//It doesn't work anymore... Dunno why... -//tm.coords[0][2] = -trans.x(); // This works!!! Yeah!!! -//tm.coords[1][2] = -trans.y(); -//nope. -//tm.coords[0][2] = rotationPoint.x(); // This works, but strangely... -//tm.coords[1][2] = rotationPoint.y(); -//tm.coords[0][2] = 0;// center.x() / 2.0f; -//tm.coords[1][2] = 0;// center.y() / 2.0f; -//No. -//tm.coords[0][2] = -(center.x() * textureSize.x()); -//tm.coords[1][2] = -(center.y() * textureSize.y()); -//Eh? No, but seems to be getting closer... -/*float ptx = e->x / windowSize.x() * extents.width() + extents.minX; - float pty = e->y / windowSize.y() * extents.height() + extents.minY; - tm.coords[0][2] = -c * center.x() - s * center.y() + ptx; - tm.coords[1][2] = s * center.x() - c * center.x() + pty;//*/ -//Kinda works, but center drifts around on non-square textures... -/*tm.coords[0][2] = (-c * center.x() - s * center.y()) * textureSize.x(); - tm.coords[1][2] = ( s * center.x() - c * center.y()) * textureSize.y();//*/ -//Rotates correctly, but not around the actual center of the face's points... -/*tm.coords[0][2] = -c * center.x() * textureSize.x() - s * center.y() * textureSize.y(); - tm.coords[1][2] = s * center.x() * textureSize.x() - c * center.y() * textureSize.y();//*/ -//Yes!!! - tm.coords[0][2] = ( -c * center.x() * textureSize.x() - s * center.y() * textureSize.y() ) + center.x() * textureSize.x(); - tm.coords[1][2] = ( s * center.x() * textureSize.x() - c * center.y() * textureSize.y() ) + center.y() * textureSize.y(); //*/ -//This doesn't work... -//And this is the wrong place for this anyway (I'm pretty sure). -/*tm.coords[0][2] += oldCenter.x(); - tm.coords[1][2] += oldCenter.y();//*/ - UpdateControlPoints(); // will cause a redraw - } - - return true; - } - else // Check for widget mouseovers - { - Vector2 tran; - float nx = e->x / windowSize.x() * extents.width() + extents.minX; - float ny = e->y / windowSize.y() * extents.height() + extents.minY; - // Translate nx/y to the "center" point... - nx -= center.x(); - ny -= center.y(); - ny = -ny; // Flip Y-axis so that increasing numbers move up - - tran.x() = tm.coords[0][0] * nx + tm.coords[0][1] * ny; - tran.y() = tm.coords[1][0] * nx + tm.coords[1][1] * ny; -//This doesn't seem to generate a valid distance from the center--for some reason it -//calculates a fixed number every time -//Look at nx/y above: they're getting fixed there! !!! FIX !!! [DONE] - float dist = sqrt( ( nx * nx ) + ( ny * ny ) ); - // Normalize to the 2.0 = height standard (for now) -//globalOutputStream() << "--> Distance before: " << dist; - dist = dist * 2.0f / extents.height(); -//globalOutputStream() << ". After: " << dist; - tran.x() = tran.x() * 2.0f / extents.height(); - tran.y() = tran.y() * 2.0f / extents.height(); -//globalOutputStream() << ". Trans: " << tran.x() << ", " << tran.y() << "\n"; - -//Let's try this instead... -//Interesting! It seems that e->x/y are rotated -//(no, they're not--the TM above is what's doing it...) - nx = ( ( e->x / windowSize.y() ) * 2.0f ) - ( windowSize.x() / windowSize.y() ); - ny = ( ( e->y / windowSize.y() ) * 2.0f ) - ( windowSize.y() / windowSize.y() ); - ny = -ny; -//Cool! It works! Now just need to do rotation... - - rotating = translatingX = translatingY = scalingX = scalingY - = resizingX = resizingY = false; - - if ( dist < ( gridRadius * 0.16f ) ) { - translatingX = translatingY = true; - } - else if ( dist > ( gridRadius * 0.16f ) && dist < ( gridRadius * 1.10f ) - && fabs( ny ) < ( gridRadius * 0.05f ) && nx > 0 ) { - translatingX = true; - } - else if ( dist > ( gridRadius * 0.16f ) && dist < ( gridRadius * 1.10f ) - && fabs( nx ) < ( gridRadius * 0.05f ) && ny > 0 ) { - translatingY = true; - } - // Should tighten up the angle on this, or put this test after the axis tests... - else if ( tran.x() > 0 && tran.y() > 0 - && ( dist > ( gridRadius * 0.82f ) && dist < ( gridRadius * 0.98f ) ) ) { - rotating = true; - } - - queueDraw(); - - return true; - } - - return false; -} - -//It seems the fake tex coords conversion is screwing this stuff up... !!! FIX !!! -//This is still wrong... Prolly need to do something with the oldScaleX/Y stuff... -void flipX( ui::ToggleButton, gpointer ){ -// globalOutputStream() << "--> Flip X...\n"; - //Shamus: -// SurfaceInspector_GetSelectedBPTexdef(); // Refresh g_selectedBrushPrimitTexdef... -// tm.coords[0][0] = -tm.coords[0][0]; -// tm.coords[1][0] = -tm.coords[1][0]; -// tm.coords[0][0] = -tm.coords[0][0]; // This should be correct now...Nope. -// tm.coords[1][1] = -tm.coords[1][1]; - tm.coords[0][0] = -tm.coords[0][0]; // This should be correct now... - tm.coords[1][0] = -tm.coords[1][0]; -// tm.coords[2][0] = -tm.coords[2][0];//wil wok? no. - UpdateControlPoints(); -} - -void flipY( ui::ToggleButton, gpointer ){ -// globalOutputStream() << "--> Flip Y...\n"; -// tm.coords[0][1] = -tm.coords[0][1]; -// tm.coords[1][1] = -tm.coords[1][1]; -// tm.coords[0][1] = -tm.coords[0][1]; // This should be correct now...Nope. -// tm.coords[1][0] = -tm.coords[1][0]; - tm.coords[0][1] = -tm.coords[0][1]; // This should be correct now... - tm.coords[1][1] = -tm.coords[1][1]; -// tm.coords[2][1] = -tm.coords[2][1];//wil wok? no. - UpdateControlPoints(); -} - -} // end namespace TexTool - -#endif diff --git a/src/surfacedialog.h b/src/surfacedialog.h deleted file mode 100644 index ae8e9c0..0000000 --- a/src/surfacedialog.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#if !defined( INCLUDED_SURFACEDIALOG_H ) -#define INCLUDED_SURFACEDIALOG_H - - -void SurfaceInspector_Construct(); - -void SurfaceInspector_Destroy(); - -void SurfaceInspector_constructWindow(ui::Window widget); - -void SurfaceInspector_destroyWindow(); - -bool SelectedFaces_empty(); - -void SelectedFaces_copyTexture(); - -void SelectedFaces_pasteTexture(); - -void FaceTextureClipboard_setDefault(); - - -// the increment we are using for the surface inspector (this is saved in the prefs) -struct si_globals_t { - float shift[2]; - float scale[2]; - float rotate; - - bool m_bSnapTToGrid; - - si_globals_t() : m_bSnapTToGrid(false) - { - shift[0] = 8.0f; - shift[1] = 8.0f; - scale[0] = 0.5f; - scale[1] = 0.5f; - rotate = 45.0f; - } -}; - -extern si_globals_t g_si_globals; - -#endif diff --git a/src/texmanip.cpp b/src/texmanip.cpp deleted file mode 100644 index 9ccc1ef..0000000 --- a/src/texmanip.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - Copyright (c) 2002 Forest "LordHavoc" Hale - - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Forest Hale nor the names of other contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "texmanip.h" - -#include -#include "stream/textstream.h" - -static byte *row1 = NULL, *row2 = NULL; -static int rowsize = 0; - -void R_ResampleTextureLerpLine(const byte *in, byte *out, int inwidth, int outwidth, int bytesperpixel) -{ - int j, xi, oldx = 0, f, fstep, endx, lerp; -#define LERPBYTE(i) out[i] = (byte) ( ( ( ( row2[i] - row1[i] ) * lerp ) >> 16 ) + row1[i] ) - - fstep = (int) (inwidth * 65536.0f / outwidth); - endx = (inwidth - 1); - if (bytesperpixel == 4) { - for (j = 0, f = 0; j < outwidth; j++, f += fstep) { - xi = f >> 16; - if (xi != oldx) { - in += (xi - oldx) * 4; - oldx = xi; - } - - if (xi < endx) { - lerp = f & 0xFFFF; - *out++ = (byte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]); - *out++ = (byte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]); - *out++ = (byte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]); - *out++ = (byte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]); - } else // last pixel of the line has no pixel to lerp to - { - *out++ = in[0]; - *out++ = in[1]; - *out++ = in[2]; - *out++ = in[3]; - } - } - } else if (bytesperpixel == 3) { - for (j = 0, f = 0; j < outwidth; j++, f += fstep) { - xi = f >> 16; - if (xi != oldx) { - in += (xi - oldx) * 3; - oldx = xi; - } - - if (xi < endx) { - lerp = f & 0xFFFF; - *out++ = (byte) ((((in[3] - in[0]) * lerp) >> 16) + in[0]); - *out++ = (byte) ((((in[4] - in[1]) * lerp) >> 16) + in[1]); - *out++ = (byte) ((((in[5] - in[2]) * lerp) >> 16) + in[2]); - } else // last pixel of the line has no pixel to lerp to - { - *out++ = in[0]; - *out++ = in[1]; - *out++ = in[2]; - } - } - } else { - globalOutputStream() << "R_ResampleTextureLerpLine: unsupported bytesperpixel " << bytesperpixel << "\n"; - } -} - -/* - ================ - R_ResampleTexture - ================ - */ -void R_ResampleTexture(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight, - int bytesperpixel) -{ - if (rowsize < outwidth * bytesperpixel) { - if (row1) { - free(row1); - } - if (row2) { - free(row2); - } - - rowsize = outwidth * bytesperpixel; - row1 = (byte *) malloc(rowsize); - row2 = (byte *) malloc(rowsize); - } - - if (bytesperpixel == 4) { - int i, j, yi, oldy, f, fstep, lerp, endy = (inheight - 1), inwidth4 = inwidth * 4, outwidth4 = outwidth * 4; - byte *inrow, *out; - out = (byte *) outdata; - fstep = (int) (inheight * 65536.0f / outheight); -#define LERPBYTE(i) out[i] = (byte) ( ( ( ( row2[i] - row1[i] ) * lerp ) >> 16 ) + row1[i] ) - - inrow = (byte *) indata; - oldy = 0; - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - R_ResampleTextureLerpLine(inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel); - - for (i = 0, f = 0; i < outheight; i++, f += fstep) { - yi = f >> 16; - if (yi < endy) { - lerp = f & 0xFFFF; - if (yi != oldy) { - inrow = (byte *) indata + inwidth4 * yi; - if (yi == oldy + 1) { - memcpy(row1, row2, outwidth4); - } else { - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - } - - R_ResampleTextureLerpLine(inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel); - oldy = yi; - } - j = outwidth - 4; - while (j >= 0) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - LERPBYTE(4); - LERPBYTE(5); - LERPBYTE(6); - LERPBYTE(7); - LERPBYTE(8); - LERPBYTE(9); - LERPBYTE(10); - LERPBYTE(11); - LERPBYTE(12); - LERPBYTE(13); - LERPBYTE(14); - LERPBYTE(15); - out += 16; - row1 += 16; - row2 += 16; - j -= 4; - } - if (j & 2) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - LERPBYTE(4); - LERPBYTE(5); - LERPBYTE(6); - LERPBYTE(7); - out += 8; - row1 += 8; - row2 += 8; - } - if (j & 1) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - out += 4; - row1 += 4; - row2 += 4; - } - row1 -= outwidth4; - row2 -= outwidth4; - } else { - if (yi != oldy) { - inrow = (byte *) indata + inwidth4 * yi; - if (yi == oldy + 1) { - memcpy(row1, row2, outwidth4); - } else { - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - } - - oldy = yi; - } - memcpy(out, row1, outwidth4); - } - } - } else if (bytesperpixel == 3) { - int i, j, yi, oldy, f, fstep, lerp, endy = (inheight - 1), inwidth3 = inwidth * 3, outwidth3 = outwidth * 3; - byte *inrow, *out; - out = (byte *) outdata; - fstep = (int) (inheight * 65536.0f / outheight); -#define LERPBYTE(i) out[i] = (byte) ( ( ( ( row2[i] - row1[i] ) * lerp ) >> 16 ) + row1[i] ) - - inrow = (byte *) indata; - oldy = 0; - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - R_ResampleTextureLerpLine(inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel); - for (i = 0, f = 0; i < outheight; i++, f += fstep) { - yi = f >> 16; - if (yi < endy) { - lerp = f & 0xFFFF; - if (yi != oldy) { - inrow = (byte *) indata + inwidth3 * yi; - if (yi == oldy + 1) { - memcpy(row1, row2, outwidth3); - } else { - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - } - - R_ResampleTextureLerpLine(inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel); - oldy = yi; - } - j = outwidth - 4; - while (j >= 0) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - LERPBYTE(4); - LERPBYTE(5); - LERPBYTE(6); - LERPBYTE(7); - LERPBYTE(8); - LERPBYTE(9); - LERPBYTE(10); - LERPBYTE(11); - out += 12; - row1 += 12; - row2 += 12; - j -= 4; - } - if (j & 2) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - LERPBYTE(3); - LERPBYTE(4); - LERPBYTE(5); - out += 6; - row1 += 6; - row2 += 6; - } - if (j & 1) { - LERPBYTE(0); - LERPBYTE(1); - LERPBYTE(2); - out += 3; - row1 += 3; - row2 += 3; - } - row1 -= outwidth3; - row2 -= outwidth3; - } else { - if (yi != oldy) { - inrow = (byte *) indata + inwidth3 * yi; - if (yi == oldy + 1) { - memcpy(row1, row2, outwidth3); - } else { - R_ResampleTextureLerpLine(inrow, row1, inwidth, outwidth, bytesperpixel); - } - - oldy = yi; - } - memcpy(out, row1, outwidth3); - } - } - } else { - globalOutputStream() << "R_ResampleTexture: unsupported bytesperpixel " << bytesperpixel << "\n"; - } -} - -// in can be the same as out -void GL_MipReduce(byte *in, byte *out, int width, int height, int destwidth, int destheight) -{ - int x, y, width2, height2, nextrow; - if (width > destwidth) { - if (height > destheight) { - // reduce both - width2 = width >> 1; - height2 = height >> 1; - nextrow = width << 2; - for (y = 0; y < height2; y++) { - for (x = 0; x < width2; x++) { - out[0] = (byte) ((in[0] + in[4] + in[nextrow] + in[nextrow + 4]) >> 2); - out[1] = (byte) ((in[1] + in[5] + in[nextrow + 1] + in[nextrow + 5]) >> 2); - out[2] = (byte) ((in[2] + in[6] + in[nextrow + 2] + in[nextrow + 6]) >> 2); - out[3] = (byte) ((in[3] + in[7] + in[nextrow + 3] + in[nextrow + 7]) >> 2); - out += 4; - in += 8; - } - in += nextrow; // skip a line - } - } else { - // reduce width - width2 = width >> 1; - for (y = 0; y < height; y++) { - for (x = 0; x < width2; x++) { - out[0] = (byte) ((in[0] + in[4]) >> 1); - out[1] = (byte) ((in[1] + in[5]) >> 1); - out[2] = (byte) ((in[2] + in[6]) >> 1); - out[3] = (byte) ((in[3] + in[7]) >> 1); - out += 4; - in += 8; - } - } - } - } else { - if (height > destheight) { - // reduce height - height2 = height >> 1; - nextrow = width << 2; - for (y = 0; y < height2; y++) { - for (x = 0; x < width; x++) { - out[0] = (byte) ((in[0] + in[nextrow]) >> 1); - out[1] = (byte) ((in[1] + in[nextrow + 1]) >> 1); - out[2] = (byte) ((in[2] + in[nextrow + 2]) >> 1); - out[3] = (byte) ((in[3] + in[nextrow + 3]) >> 1); - out += 4; - in += 4; - } - in += nextrow; // skip a line - } - } else { - globalOutputStream() << "GL_MipReduce: desired size already achieved\n"; - } - } -} diff --git a/src/texmanip.h b/src/texmanip.h deleted file mode 100644 index cd01ab0..0000000 --- a/src/texmanip.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) 2002 Forest "LordHavoc" Hale - - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Forest Hale nor the names of other contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_TEXMANIP_H ) -#define INCLUDED_TEXMANIP_H - -typedef unsigned char byte; - -void R_ResampleTexture(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight, - int bytesperpixel); - -void GL_MipReduce(byte *in, byte *out, int width, int height, int destwidth, int destheight); - -#endif diff --git a/src/textureentry.cpp b/src/textureentry.cpp deleted file mode 100644 index fcfe8be..0000000 --- a/src/textureentry.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "textureentry.h" - -#include - -template -void EntryCompletion::connect(ui::Entry entry) -{ - if (!m_store) { - m_store = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING)); - - fill(); - - StringList().connect(IdleDraw::QueueDrawCaller(m_idleUpdate)); - } - - auto completion = ui::EntryCompletion::from(gtk_entry_completion_new()); - gtk_entry_set_completion(entry, completion); - gtk_entry_completion_set_model(completion, m_store); - gtk_entry_completion_set_text_column(completion, 0); -} - -template -void EntryCompletion::append(const char *string) -{ - m_store.append(0, string); -} - -template -void EntryCompletion::fill() -{ - StringList().forEach(AppendCaller(*this)); -} - -template -void EntryCompletion::clear() -{ - m_store.clear(); -} - -template -void EntryCompletion::update() -{ - clear(); - fill(); -} - -template -class EntryCompletion; - -template -class EntryCompletion; diff --git a/src/textureentry.h b/src/textureentry.h deleted file mode 100644 index d7731ee..0000000 --- a/src/textureentry.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TEXTUREENTRY_H ) -#define INCLUDED_TEXTUREENTRY_H - -#include "gtkutil/idledraw.h" - -#include "generic/static.h" -#include "signal/isignal.h" -#include "shaderlib.h" - -#include "texwindow.h" - -template -class EntryCompletion { -ui::ListStore m_store; -IdleDraw m_idleUpdate; -public: -EntryCompletion() : m_store(ui::null), m_idleUpdate(UpdateCaller(*this)) -{ -} - -void connect(ui::Entry entry); - -void append(const char *string); - -using AppendCaller = MemberCaller; - -void fill(); - -void clear(); - -void update(); - -using UpdateCaller = MemberCaller; -}; - -class TextureNameList { -public: -void forEach(const ShaderNameCallback &callback) const -{ - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (shader_equal_prefix(shader->getName(), "textures/")) { - callback(shader->getName() + 9); - } - } -} - -void connect(const SignalHandler &update) const -{ - TextureBrowser_addActiveShadersChangedCallback(update); -} -}; - -typedef Static > GlobalTextureEntryCompletion; - - -class ShaderList { -public: -void forEach(const ShaderNameCallback &callback) const -{ - GlobalShaderSystem().foreachShaderName(callback); -} - -void connect(const SignalHandler &update) const -{ - TextureBrowser_addShadersRealiseCallback(update); -} -}; - -typedef Static > GlobalShaderEntryCompletion; - - -#endif diff --git a/src/textures.cpp b/src/textures.cpp deleted file mode 100644 index ab7672b..0000000 --- a/src/textures.cpp +++ /dev/null @@ -1,902 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "textures.h" - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "itextures.h" -#include "igl.h" -#include "preferencesystem.h" -#include "qgl.h" - -#include "texturelib.h" -#include "container/hashfunc.h" -#include "container/cache.h" -#include "generic/callback.h" -#include "stringio.h" - -#include "image.h" -#include "texmanip.h" -#include "preferences.h" - - -enum ETexturesMode { - eTextures_NEAREST = 0, - eTextures_NEAREST_MIPMAP_NEAREST = 1, - eTextures_NEAREST_MIPMAP_LINEAR = 2, - eTextures_LINEAR = 3, - eTextures_LINEAR_MIPMAP_NEAREST = 4, - eTextures_LINEAR_MIPMAP_LINEAR = 5, - eTextures_MAX_ANISOTROPY = 6, -}; - -enum TextureCompressionFormat { - TEXTURECOMPRESSION_NONE = 0, - TEXTURECOMPRESSION_RGBA = 1, - TEXTURECOMPRESSION_RGBA_S3TC_DXT1 = 2, - TEXTURECOMPRESSION_RGBA_S3TC_DXT3 = 3, - TEXTURECOMPRESSION_RGBA_S3TC_DXT5 = 4, -}; - -struct texture_globals_t { - // RIANT - // texture compression format - TextureCompressionFormat m_nTextureCompressionFormat; - - float fGamma; - - bool bTextureCompressionSupported; // is texture compression supported by hardware? - GLint texture_components; - - // temporary values that should be initialised only once at run-time - bool m_bOpenGLCompressionSupported; - bool m_bS3CompressionSupported; - - texture_globals_t(GLint components) : - m_nTextureCompressionFormat(TEXTURECOMPRESSION_NONE), - fGamma(1.0f), - bTextureCompressionSupported(false), - texture_components(components), - m_bOpenGLCompressionSupported(false), - m_bS3CompressionSupported(false) - { - } -}; - -texture_globals_t g_texture_globals(GL_RGBA); - -void SetTexParameters(ETexturesMode mode) -{ - float maxAniso = QGL_maxTextureAnisotropy(); - if (maxAniso > 1) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); - } else if (mode == eTextures_MAX_ANISOTROPY) { - mode = eTextures_LINEAR_MIPMAP_LINEAR; - } - - switch (mode) { - case eTextures_NEAREST: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - case eTextures_NEAREST_MIPMAP_NEAREST: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - case eTextures_NEAREST_MIPMAP_LINEAR: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - case eTextures_LINEAR: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - case eTextures_LINEAR_MIPMAP_NEAREST: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - case eTextures_LINEAR_MIPMAP_LINEAR: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - case eTextures_MAX_ANISOTROPY: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso); - break; - default: - globalOutputStream() << "invalid texture mode\n"; - } -} - -ETexturesMode g_texture_mode = eTextures_NEAREST_MIPMAP_NEAREST; - - -byte g_gammatable[256]; - -void ResampleGamma(float fGamma) -{ - int i, inf; - if (fGamma == 1.0) { - for (i = 0; i < 256; i++) { - g_gammatable[i] = i; - } - } else { - for (i = 0; i < 256; i++) { - inf = (int) (255 * pow(static_cast((i + 0.5) / 255.5 ), static_cast( fGamma )) + 0.5); - if (inf < 0) { - inf = 0; - } - if (inf > 255) { - inf = 255; - } - g_gammatable[i] = inf; - } - } -} - -inline const int &min_int(const int &left, const int &right) -{ - return std::min(left, right); -} - -int max_tex_size = 0; -const int max_texture_quality = 3; -LatchedValue g_Textures_textureQuality(3, "Texture Quality"); - -/// \brief This function does the actual processing of raw RGBA data into a GL texture. -/// It will also resample to power-of-two dimensions, generate the mipmaps and adjust gamma. -void LoadTextureRGBA(qtexture_t *q, unsigned char *pPixels, int nWidth, int nHeight) -{ - static float fGamma = -1; - float total[3]; - byte *outpixels = 0; - int nCount = nWidth * nHeight; - - if (fGamma != g_texture_globals.fGamma) { - fGamma = g_texture_globals.fGamma; - ResampleGamma(fGamma); - } - - q->width = nWidth; - q->height = nHeight; - - total[0] = total[1] = total[2] = 0.0f; - - // resample texture gamma according to user settings - for (int i = 0; i < (nCount * 4); i += 4) { - for (int j = 0; j < 3; j++) { - total[j] += (pPixels + i)[j]; - byte b = (pPixels + i)[j]; - (pPixels + i)[j] = g_gammatable[b]; - } - } - - q->color[0] = total[0] / (nCount * 255); - q->color[1] = total[1] / (nCount * 255); - q->color[2] = total[2] / (nCount * 255); - - glGenTextures(1, &q->texture_number); - - glBindTexture(GL_TEXTURE_2D, q->texture_number); - - SetTexParameters(g_texture_mode); - - int gl_width = 1; - while (gl_width < nWidth) { - gl_width <<= 1; - } - - int gl_height = 1; - while (gl_height < nHeight) { - gl_height <<= 1; - } - - bool resampled = false; - if (!(gl_width == nWidth && gl_height == nHeight)) { - resampled = true; - outpixels = (byte *) malloc(gl_width * gl_height * 4); - R_ResampleTexture(pPixels, nWidth, nHeight, outpixels, gl_width, gl_height, 4); - } else { - outpixels = pPixels; - } - - int quality_reduction = max_texture_quality - g_Textures_textureQuality.m_value; - int target_width = min_int(gl_width >> quality_reduction, max_tex_size); - int target_height = min_int(gl_height >> quality_reduction, max_tex_size); - - while (gl_width > target_width || gl_height > target_height) { - GL_MipReduce(outpixels, outpixels, gl_width, gl_height, target_width, target_height); - - if (gl_width > target_width) { - gl_width >>= 1; - } - if (gl_height > target_height) { - gl_height >>= 1; - } - } - - int mip = 0; - glTexImage2D(GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, outpixels); - while (gl_width > 1 || gl_height > 1) { - GL_MipReduce(outpixels, outpixels, gl_width, gl_height, 1, 1); - - if (gl_width > 1) { - gl_width >>= 1; - } - if (gl_height > 1) { - gl_height >>= 1; - } - - glTexImage2D(GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, outpixels); - } - - glBindTexture(GL_TEXTURE_2D, 0); - if (resampled) { - free(outpixels); - } -} - -#if 0 -/* - ============== - Texture_InitPalette - ============== - */ -void Texture_InitPalette( byte *pal ){ - int r,g,b; - int i; - int inf; - byte gammatable[256]; - float gamma; - - gamma = g_texture_globals.fGamma; - - if ( gamma == 1.0 ) { - for ( i = 0; i < 256; i++ ) - gammatable[i] = i; - } - else - { - for ( i = 0; i < 256; i++ ) - { - inf = (int)( 255 * pow( ( i + 0.5 ) / 255.5, gamma ) + 0.5 ); - if ( inf < 0 ) { - inf = 0; - } - if ( inf > 255 ) { - inf = 255; - } - gammatable[i] = inf; - } - } - - for ( i = 0; i < 256; i++ ) - { - r = gammatable[pal[0]]; - g = gammatable[pal[1]]; - b = gammatable[pal[2]]; - pal += 3; - - //v = (r<<24) + (g<<16) + (b<<8) + 255; - //v = BigLong (v); - - //tex_palette[i] = v; - tex_palette[i * 3 + 0] = r; - tex_palette[i * 3 + 1] = g; - tex_palette[i * 3 + 2] = b; - } -} -#endif - -#if 0 -class TestHashtable -{ -public: -TestHashtable(){ - HashTable strings; - strings["Monkey"] = "bleh"; - strings["MonkeY"] = "blah"; -} -}; - -const TestHashtable g_testhashtable; - -#endif - -typedef std::pair TextureKey; - -void qtexture_realise(qtexture_t &texture, const TextureKey &key) -{ - texture.texture_number = 0; - if (!string_empty(key.second.c_str())) { - Image *image = key.first.loadImage(key.second.c_str()); - if (image != 0) { - LoadTextureRGBA(&texture, image->getRGBAPixels(), image->getWidth(), image->getHeight()); - texture.surfaceFlags = image->getSurfaceFlags(); - texture.contentFlags = image->getContentFlags(); - texture.value = image->getValue(); - image->release(); - // We only want to report when errors happen - //globalOutputStream() << "Loaded Texture: \"" << key.second.c_str() << "\"\n"; - GlobalOpenGL_debugAssertNoErrors(); - } else { - globalErrorStream() << "Texture load failed: \"" << key.second.c_str() << "\"\n"; - } - } -} - -void qtexture_unrealise(qtexture_t &texture) -{ - if (GlobalOpenGL().contextValid && texture.texture_number != 0) { - glDeleteTextures(1, &texture.texture_number); - GlobalOpenGL_debugAssertNoErrors(); - } -} - -class TextureKeyEqualNoCase { -public: -bool operator()(const TextureKey &key, const TextureKey &other) const -{ - return key.first == other.first && string_equal_nocase(key.second.c_str(), other.second.c_str()); -} -}; - -class TextureKeyHashNoCase { -public: -typedef hash_t hash_type; - -hash_t operator()(const TextureKey &key) const -{ - return hash_combine(string_hash_nocase(key.second.c_str()), pod_hash(key.first)); -} -}; - -#define DEBUG_TEXTURES 0 - -class TexturesMap : public TexturesCache { -class TextureConstructor { -TexturesMap *m_cache; -public: -explicit TextureConstructor(TexturesMap *cache) - : m_cache(cache) -{ -} - -qtexture_t *construct(const TextureKey &key) -{ - qtexture_t *texture = new qtexture_t(key.first, key.second.c_str()); - if (m_cache->realised()) { - qtexture_realise(*texture, key); - } - return texture; -} - -void destroy(qtexture_t *texture) -{ - if (m_cache->realised()) { - qtexture_unrealise(*texture); - } - delete texture; -} -}; - -typedef HashedCache qtextures_t; -qtextures_t m_qtextures; -TexturesCacheObserver *m_observer; -std::size_t m_unrealised; - -public: -virtual ~TexturesMap() = default; - -TexturesMap() : m_qtextures(TextureConstructor(this)), m_observer(0), m_unrealised(1) -{ -} - -typedef qtextures_t::iterator iterator; - -iterator begin() -{ - return m_qtextures.begin(); -} - -iterator end() -{ - return m_qtextures.end(); -} - -LoadImageCallback defaultLoader() const -{ - return LoadImageCallback(0, QERApp_LoadImage); -} - -Image *loadImage(const char *name) -{ - return defaultLoader().loadImage(name); -} - -qtexture_t *capture(const char *name) -{ - return capture(defaultLoader(), name); -} - -qtexture_t *capture(const LoadImageCallback &loader, const char *name) -{ -#if DEBUG_TEXTURES - globalOutputStream() << "textures capture: " << makeQuoted( name ) << '\n'; -#endif - return m_qtextures.capture(TextureKey(loader, name)).get(); -} - -void release(qtexture_t *texture) -{ -#if DEBUG_TEXTURES - globalOutputStream() << "textures release: " << makeQuoted( texture->name ) << '\n'; -#endif - m_qtextures.release(TextureKey(texture->load, texture->name)); -} - -void attach(TexturesCacheObserver &observer) -{ - ASSERT_MESSAGE(m_observer == 0, "TexturesMap::attach: cannot attach observer"); - m_observer = &observer; -} - -void detach(TexturesCacheObserver &observer) -{ - ASSERT_MESSAGE(m_observer == &observer, "TexturesMap::detach: cannot detach observer"); - m_observer = 0; -} - -void realise() -{ - if (--m_unrealised == 0) { - g_texture_globals.bTextureCompressionSupported = false; - - if (GlobalOpenGL().ARB_texture_compression()) { - g_texture_globals.bTextureCompressionSupported = true; - g_texture_globals.m_bOpenGLCompressionSupported = true; - } - - if (GlobalOpenGL().EXT_texture_compression_s3tc()) { - g_texture_globals.bTextureCompressionSupported = true; - g_texture_globals.m_bS3CompressionSupported = true; - } - - switch (g_texture_globals.texture_components) { - case GL_RGBA: - break; - case GL_COMPRESSED_RGBA_ARB: - if (!g_texture_globals.m_bOpenGLCompressionSupported) { - globalOutputStream() - << "OpenGL extension GL_ARB_texture_compression not supported by current graphics drivers\n"; - g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE; - g_texture_globals.texture_components = GL_RGBA; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - if (!g_texture_globals.m_bS3CompressionSupported) { - globalOutputStream() - << "OpenGL extension GL_EXT_texture_compression_s3tc not supported by current graphics drivers\n"; - if (g_texture_globals.m_bOpenGLCompressionSupported) { - g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_RGBA; - g_texture_globals.texture_components = GL_COMPRESSED_RGBA_ARB; - } else { - g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE; - g_texture_globals.texture_components = GL_RGBA; - } - } - break; - default: - globalOutputStream() << "Unknown texture compression selected, reverting\n"; - g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE; - g_texture_globals.texture_components = GL_RGBA; - break; - } - - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size); - if (max_tex_size == 0) { - max_tex_size = 1024; - } - - for (qtextures_t::iterator i = m_qtextures.begin(); i != m_qtextures.end(); ++i) { - if (!(*i).value.empty()) { - qtexture_realise(*(*i).value, (*i).key); - } - } - if (m_observer != 0) { - m_observer->realise(); - } - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - if (m_observer != 0) { - m_observer->unrealise(); - } - for (qtextures_t::iterator i = m_qtextures.begin(); i != m_qtextures.end(); ++i) { - if (!(*i).value.empty()) { - qtexture_unrealise(*(*i).value); - } - } - } -} - -bool realised() -{ - return m_unrealised == 0; -} -}; - -TexturesMap *g_texturesmap; - -TexturesCache &GetTexturesCache() -{ - return *g_texturesmap; -} - - -void Textures_Realise() -{ - g_texturesmap->realise(); -} - -void Textures_Unrealise() -{ - g_texturesmap->unrealise(); -} - - -Callback g_texturesModeChangedNotify; - -void Textures_setModeChangedNotify(const Callback ¬ify) -{ - g_texturesModeChangedNotify = notify; -} - -void Textures_ModeChanged() -{ - if (g_texturesmap->realised()) { - SetTexParameters(g_texture_mode); - - for (TexturesMap::iterator i = g_texturesmap->begin(); i != g_texturesmap->end(); ++i) { - glBindTexture(GL_TEXTURE_2D, (*i).value->texture_number); - SetTexParameters(g_texture_mode); - } - - glBindTexture(GL_TEXTURE_2D, 0); - } - g_texturesModeChangedNotify(); -} - -void Textures_SetMode(ETexturesMode mode) -{ - if (g_texture_mode != mode) { - g_texture_mode = mode; - - Textures_ModeChanged(); - } -} - -void Textures_setTextureComponents(GLint texture_components) -{ - if (g_texture_globals.texture_components != texture_components) { - Textures_Unrealise(); - g_texture_globals.texture_components = texture_components; - Textures_Realise(); - } -} - -void Textures_UpdateTextureCompressionFormat() -{ - GLint texture_components = GL_RGBA; - - switch (g_texture_globals.m_nTextureCompressionFormat) { - case (TEXTURECOMPRESSION_NONE): { - texture_components = GL_RGBA; - break; - } - case (TEXTURECOMPRESSION_RGBA): { - texture_components = GL_COMPRESSED_RGBA_ARB; - break; - } - case (TEXTURECOMPRESSION_RGBA_S3TC_DXT1): { - texture_components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - break; - } - case (TEXTURECOMPRESSION_RGBA_S3TC_DXT3): { - texture_components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - break; - } - case (TEXTURECOMPRESSION_RGBA_S3TC_DXT5): { - texture_components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - break; - } - } - - Textures_setTextureComponents(texture_components); -} - -struct TextureCompression { - static void Export(const TextureCompressionFormat &self, const Callback &returnz) - { - returnz(self); - } - - static void Import(TextureCompressionFormat &self, int value) - { - if (!g_texture_globals.m_bOpenGLCompressionSupported - && g_texture_globals.m_bS3CompressionSupported - && value >= 1) { - ++value; - } - switch (value) { - case 0: - self = TEXTURECOMPRESSION_NONE; - break; - case 1: - self = TEXTURECOMPRESSION_RGBA; - break; - case 2: - self = TEXTURECOMPRESSION_RGBA_S3TC_DXT1; - break; - case 3: - self = TEXTURECOMPRESSION_RGBA_S3TC_DXT3; - break; - case 4: - self = TEXTURECOMPRESSION_RGBA_S3TC_DXT5; - break; - } - Textures_UpdateTextureCompressionFormat(); - } -}; - -struct TextureGamma { - static void Export(const float &self, const Callback &returnz) - { - returnz(self); - } - - static void Import(float &self, float value) - { - if (value != self) { - Textures_Unrealise(); - self = value; - Textures_Realise(); - } - } -}; - -struct TextureMode { - static void Export(const ETexturesMode &self, const Callback &returnz) - { - switch (self) { - case eTextures_NEAREST: - returnz(0); - break; - case eTextures_NEAREST_MIPMAP_NEAREST: - returnz(1); - break; - case eTextures_LINEAR: - returnz(2); - break; - case eTextures_NEAREST_MIPMAP_LINEAR: - returnz(3); - break; - case eTextures_LINEAR_MIPMAP_NEAREST: - returnz(4); - break; - case eTextures_LINEAR_MIPMAP_LINEAR: - returnz(5); - break; - case eTextures_MAX_ANISOTROPY: - returnz(6); - break; - default: - returnz(4); - } - } - - static void Import(ETexturesMode &self, int value) - { - switch (value) { - case 0: - Textures_SetMode(eTextures_NEAREST); - break; - case 1: - Textures_SetMode(eTextures_NEAREST_MIPMAP_NEAREST); - break; - case 2: - Textures_SetMode(eTextures_LINEAR); - break; - case 3: - Textures_SetMode(eTextures_NEAREST_MIPMAP_LINEAR); - break; - case 4: - Textures_SetMode(eTextures_LINEAR_MIPMAP_NEAREST); - break; - case 5: - Textures_SetMode(eTextures_LINEAR_MIPMAP_LINEAR); - break; - case 6: - Textures_SetMode(eTextures_MAX_ANISOTROPY); - } - } -}; - -void Textures_constructPreferences(PreferencesPage &page) -{ - { - const char *percentages[] = {"12.5%", "25%", "50%", "100%",}; - page.appendRadio( - "Texture Quality", - STRING_ARRAY_RANGE(percentages), - make_property(g_Textures_textureQuality) - ); - } - page.appendSpinner( - "Texture Gamma", - 1.0, - 0.0, - 1.0, - make_property(g_texture_globals.fGamma) - ); - { - const char *texture_mode[] = {"Nearest", "Nearest Mipmap", "Linear", "Bilinear", "Bilinear Mipmap", "Trilinear", - "Anisotropy"}; - page.appendCombo( - "Texture Render Mode", - STRING_ARRAY_RANGE(texture_mode), - make_property(g_texture_mode) - ); - } - { - const char *compression_none[] = {"None"}; - const char *compression_opengl[] = {"None", "OpenGL ARB"}; - const char *compression_s3tc[] = {"None", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5"}; - const char *compression_opengl_s3tc[] = {"None", "OpenGL ARB", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5"}; - StringArrayRange compression( - (g_texture_globals.m_bOpenGLCompressionSupported) - ? (g_texture_globals.m_bS3CompressionSupported) - ? STRING_ARRAY_RANGE(compression_opengl_s3tc) - : STRING_ARRAY_RANGE(compression_opengl) - : (g_texture_globals.m_bS3CompressionSupported) - ? STRING_ARRAY_RANGE(compression_s3tc) - : STRING_ARRAY_RANGE(compression_none) - ); - page.appendCombo( - "Hardware Texture Compression", - compression, - make_property(g_texture_globals.m_nTextureCompressionFormat) - ); - } -} - -void Textures_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Textures", "Texture Settings")); - Textures_constructPreferences(page); -} - -void Textures_registerPreferencesPage() -{ - PreferencesDialog_addDisplayPage(makeCallbackF(Textures_constructPage)); -} - -struct TextureCompressionPreference { - static void Export(const Callback &returnz) - { - returnz(g_texture_globals.m_nTextureCompressionFormat); - } - - static void Import(int value) - { - g_texture_globals.m_nTextureCompressionFormat = static_cast( value ); - Textures_UpdateTextureCompressionFormat(); - } -}; - -void Textures_Construct() -{ - g_texturesmap = new TexturesMap; - - GlobalPreferenceSystem().registerPreference("TextureCompressionFormat", - make_property_string()); - GlobalPreferenceSystem().registerPreference("TextureFiltering", - make_property_string(reinterpret_cast( g_texture_mode ))); - GlobalPreferenceSystem().registerPreference("TextureQuality", - make_property_string(g_Textures_textureQuality.m_latched)); - GlobalPreferenceSystem().registerPreference("SI_Gamma", make_property_string(g_texture_globals.fGamma)); - - g_Textures_textureQuality.useLatched(); - - Textures_registerPreferencesPage(); - - Textures_ModeChanged(); -} - -void Textures_Destroy() -{ - delete g_texturesmap; -} - - -#include "modulesystem/modulesmap.h" -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -class TexturesDependencies : - public GlobalRadiantModuleRef, - public GlobalOpenGLModuleRef, - public GlobalPreferenceSystemModuleRef { -ImageModulesRef m_image_modules; -public: -TexturesDependencies() : - m_image_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("texturetypes")) -{ -} - -ImageModules &getImageModules() -{ - return m_image_modules.get(); -} -}; - -class TexturesAPI { -TexturesCache *m_textures; -public: -typedef TexturesCache Type; - -STRING_CONSTANT(Name, "*"); - -TexturesAPI() -{ - Textures_Construct(); - - m_textures = &GetTexturesCache(); -} - -~TexturesAPI() -{ - Textures_Destroy(); -} - -TexturesCache *getTable() -{ - return m_textures; -} -}; - -typedef SingletonModule TexturesModule; -typedef Static StaticTexturesModule; -StaticRegisterModule staticRegisterTextures(StaticTexturesModule::instance()); - -ImageModules &Textures_getImageModules() -{ - return StaticTexturesModule::instance().getDependencies().getImageModules(); -} diff --git a/src/textures.h b/src/textures.h deleted file mode 100644 index 35f22f3..0000000 --- a/src/textures.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TEXTURES_H ) -#define INCLUDED_TEXTURES_H - -#include "generic/callback.h" - -void Textures_Realise(); - -void Textures_Unrealise(); - -void Textures_sharedContextDestroyed(); - -void Textures_setModeChangedNotify(const Callback ¬ify); - -#endif diff --git a/src/texwindow.cpp b/src/texwindow.cpp deleted file mode 100644 index af0f16a..0000000 --- a/src/texwindow.cpp +++ /dev/null @@ -1,2975 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// Texture Window -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "texwindow.h" - -#include - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "ifilesystem.h" -#include "iundo.h" -#include "igl.h" -#include "iarchive.h" -#include "moduleobserver.h" - -#include -#include -#include - -#include - -#include "signal/signal.h" -#include "math/vector.h" -#include "texturelib.h" -#include "string/string.h" -#include "shaderlib.h" -#include "os/file.h" -#include "os/path.h" -#include "stream/memstream.h" -#include "stream/textfilestream.h" -#include "stream/stringstream.h" -#include "cmdlib.h" -#include "texmanip.h" -#include "textures.h" -#include "convert.h" - -#include "gtkutil/menu.h" -#include "gtkutil/nonmodal.h" -#include "gtkutil/cursor.h" -#include "gtkutil/widget.h" -#include "gtkutil/glwidget.h" -#include "gtkutil/messagebox.h" - -#include "error.h" -#include "map.h" -#include "qgl.h" -#include "select.h" -#include "brush_primit.h" -#include "brushmanip.h" -#include "patchmanip.h" -#include "plugin.h" -#include "qe3.h" -#include "gtkdlgs.h" -#include "gtkmisc.h" -#include "mainframe.h" -#include "findtexturedialog.h" -#include "surfacedialog.h" -#include "patchdialog.h" -#include "groupdialog.h" -#include "preferences.h" -#include "shaders.h" -#include "commands.h" - -#define NOTEX_BASENAME "notex" -#define SHADERNOTEX_BASENAME "shadernotex" - -bool TextureBrowser_showWads() -{ - return !string_empty(g_pGameDescription->getKeyValue("show_wads")); -} - -void TextureBrowser_queueDraw(TextureBrowser &textureBrowser); - -bool string_equal_start(const char *string, StringRange start) -{ - return string_equal_n(string, start.first, start.last - start.first); -} - -typedef std::set TextureGroups; - -void TextureGroups_addWad(TextureGroups &groups, const char *archive) -{ - if (extension_equal(path_get_extension(archive), "wad")) { -#if 1 - groups.insert(archive); -#else - CopiedString archiveBaseName( path_get_filename_start( archive ), path_get_filename_base_end( archive ) ); - groups.insert( archiveBaseName ); -#endif - } -} - -typedef ReferenceCaller TextureGroupsAddWadCaller; - -namespace { -bool g_TextureBrowser_shaderlistOnly = false; -bool g_TextureBrowser_fixedSize = true; -bool g_TextureBrowser_filterMissing = false; -bool g_TextureBrowser_filterFallback = true; -bool g_TextureBrowser_enableAlpha = true; -} - -CopiedString g_notex; -CopiedString g_shadernotex; - -bool isMissing(const char *name); - -bool isNotex(const char *name); - -bool isMissing(const char *name) -{ - if (string_equal(g_notex.c_str(), name)) { - return true; - } - if (string_equal(g_shadernotex.c_str(), name)) { - return true; - } - return false; -} - -bool isNotex(const char *name) -{ - if (string_equal_suffix(name, "/" NOTEX_BASENAME)) { - return true; - } - if (string_equal_suffix(name, "/" SHADERNOTEX_BASENAME)) { - return true; - } - return false; -} - -void TextureGroups_addShader(TextureGroups &groups, const char *shaderName) -{ - const char *texture = path_make_relative(shaderName, "textures/"); - - // hide notex / shadernotex images - if (g_TextureBrowser_filterFallback) { - if (isNotex(shaderName)) { - return; - } - if (isNotex(texture)) { - return; - } - } - - if (texture != shaderName) { - const char *last = path_remove_directory(texture); - if (!string_empty(last)) { - groups.insert(CopiedString(StringRange(texture, --last))); - } - } -} - -typedef ReferenceCaller TextureGroupsAddShaderCaller; - -void TextureGroups_addDirectory(TextureGroups &groups, const char *directory) -{ - groups.insert(directory); -} - -typedef ReferenceCaller TextureGroupsAddDirectoryCaller; - -class DeferredAdjustment { -gdouble m_value; -guint m_handler; - -typedef void ( *ValueChangedFunction )(void *data, gdouble value); - -ValueChangedFunction m_function; -void *m_data; - -static gboolean deferred_value_changed(gpointer data) -{ - reinterpret_cast( data )->m_function( - reinterpret_cast( data )->m_data, - reinterpret_cast( data )->m_value - ); - reinterpret_cast( data )->m_handler = 0; - reinterpret_cast( data )->m_value = 0; - return FALSE; -} - -public: -DeferredAdjustment(ValueChangedFunction function, void *data) : m_value(0), m_handler(0), m_function(function), - m_data(data) -{ -} - -void flush() -{ - if (m_handler != 0) { - g_source_remove(m_handler); - deferred_value_changed(this); - } -} - -void value_changed(gdouble value) -{ - m_value = value; - if (m_handler == 0) { - m_handler = g_idle_add(deferred_value_changed, this); - } -} - -static void adjustment_value_changed(ui::Adjustment adjustment, DeferredAdjustment *self) -{ - self->value_changed(gtk_adjustment_get_value(adjustment)); -} -}; - - -class TextureBrowser; - -typedef ReferenceCaller TextureBrowserQueueDrawCaller; - -void TextureBrowser_scrollChanged(void *data, gdouble value); - - -enum StartupShaders { - STARTUPSHADERS_NONE = 0, - STARTUPSHADERS_COMMON, -}; - -void TextureBrowser_hideUnusedExport(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_hideUnusedExport> TextureBrowserHideUnusedExport; - -void TextureBrowser_showShadersExport(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_showShadersExport> TextureBrowserShowShadersExport; - -void TextureBrowser_showShaderlistOnly(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_showShaderlistOnly> TextureBrowserShowShaderlistOnlyExport; - -void TextureBrowser_fixedSize(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_fixedSize> TextureBrowserFixedSizeExport; - -void TextureBrowser_filterMissing(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_filterMissing> TextureBrowserFilterMissingExport; - -void TextureBrowser_filterFallback(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_filterFallback> TextureBrowserFilterFallbackExport; - -void TextureBrowser_enableAlpha(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_enableAlpha> TextureBrowserEnableAlphaExport; - -class TextureBrowser { -public: -int width, height; -int originy; -int m_nTotalHeight; - -CopiedString shader; - -ui::Window m_parent{ui::null}; -ui::GLArea m_gl_widget{ui::null}; -ui::Widget m_texture_scroll{ui::null}; -ui::TreeView m_treeViewTree{ui::New}; -ui::TreeView m_treeViewTags{ui::null}; -ui::Frame m_tag_frame{ui::null}; -ui::ListStore m_assigned_store{ui::null}; -ui::ListStore m_available_store{ui::null}; -ui::TreeView m_assigned_tree{ui::null}; -ui::TreeView m_available_tree{ui::null}; -ui::Widget m_scr_win_tree{ui::null}; -ui::Widget m_scr_win_tags{ui::null}; -ui::Widget m_tag_notebook{ui::null}; -ui::Button m_search_button{ui::null}; -ui::Widget m_shader_info_item{ui::null}; - -std::set m_all_tags; -ui::ListStore m_all_tags_list{ui::null}; -std::vector m_copied_tags; -std::set m_found_shaders; - -ToggleItem m_hideunused_item; -ToggleItem m_hidenotex_item; -ToggleItem m_showshaders_item; -ToggleItem m_showshaderlistonly_item; -ToggleItem m_fixedsize_item; -ToggleItem m_filternotex_item; -ToggleItem m_enablealpha_item; - -guint m_sizeHandler; -guint m_exposeHandler; - -bool m_heightChanged; -bool m_originInvalid; - -DeferredAdjustment m_scrollAdjustment; -FreezePointer m_freezePointer; - -Vector3 color_textureback; -// the increment step we use against the wheel mouse -std::size_t m_mouseWheelScrollIncrement; -std::size_t m_textureScale; -// make the texture increments match the grid changes -bool m_showShaders; -bool m_showTextureScrollbar; -StartupShaders m_startupShaders; -// if true, the texture window will only display in-use shaders -// if false, all the shaders in memory are displayed -bool m_hideUnused; -bool m_rmbSelected; -bool m_searchedTags; -bool m_tags; -// The uniform size (in pixels) that textures are resized to when m_resizeTextures is true. -int m_uniformTextureSize; - -// Return the display width of a texture in the texture browser -int getTextureWidth(qtexture_t *tex) -{ - int width; - if (!g_TextureBrowser_fixedSize) { - // Don't use uniform size - width = (int) (tex->width * ((float) m_textureScale / 100)); - } else if - (tex->width >= tex->height) { - // Texture is square, or wider than it is tall - width = m_uniformTextureSize; - } else { - // Otherwise, preserve the texture's aspect ratio - width = (int) (m_uniformTextureSize * ((float) tex->width / tex->height)); - } - return width; -} - -// Return the display height of a texture in the texture browser -int getTextureHeight(qtexture_t *tex) -{ - int height; - if (!g_TextureBrowser_fixedSize) { - // Don't use uniform size - height = (int) (tex->height * ((float) m_textureScale / 100)); - } else if (tex->height >= tex->width) { - // Texture is square, or taller than it is wide - height = m_uniformTextureSize; - } else { - // Otherwise, preserve the texture's aspect ratio - height = (int) (m_uniformTextureSize * ((float) tex->height / tex->width)); - } - return height; -} - -TextureBrowser() : - m_texture_scroll(ui::null), - m_hideunused_item(TextureBrowserHideUnusedExport()), - m_hidenotex_item(TextureBrowserFilterFallbackExport()), - m_showshaders_item(TextureBrowserShowShadersExport()), - m_showshaderlistonly_item(TextureBrowserShowShaderlistOnlyExport()), - m_fixedsize_item(TextureBrowserFixedSizeExport()), - m_filternotex_item(TextureBrowserFilterMissingExport()), - m_enablealpha_item(TextureBrowserEnableAlphaExport()), - m_heightChanged(true), - m_originInvalid(true), - m_scrollAdjustment(TextureBrowser_scrollChanged, this), - color_textureback(0.25f, 0.25f, 0.25f), - m_mouseWheelScrollIncrement(64), - m_textureScale(50), - m_showShaders(true), - m_showTextureScrollbar(true), - m_startupShaders(STARTUPSHADERS_NONE), - m_hideUnused(false), - m_rmbSelected(false), - m_searchedTags(false), - m_tags(false), - m_uniformTextureSize(96) -{ -} -}; - -void ( *TextureBrowser_textureSelected )(const char *shader); - - -void TextureBrowser_updateScroll(TextureBrowser &textureBrowser); - - -const char *TextureBrowser_getComonShadersName() -{ - const char *value = g_pGameDescription->getKeyValue("common_shaders_name"); - if (!string_empty(value)) { - return value; - } - return "Common"; -} - -const char *TextureBrowser_getComonShadersDir() -{ - const char *value = g_pGameDescription->getKeyValue("common_shaders_dir"); - if (!string_empty(value)) { - return value; - } - return "common/"; -} - -inline int TextureBrowser_fontHeight(TextureBrowser &textureBrowser) -{ - return GlobalOpenGL().m_font->getPixelHeight(); -} - -const char *TextureBrowser_GetSelectedShader(TextureBrowser &textureBrowser) -{ - return textureBrowser.shader.c_str(); -} - -void TextureBrowser_SetStatus(TextureBrowser &textureBrowser, const char *name) -{ - IShader *shader = QERApp_Shader_ForName(name); - qtexture_t *q = shader->getTexture(); - StringOutputStream strTex(256); - strTex << name << " W: " << Unsigned(q->width) << " H: " << Unsigned(q->height); - shader->DecRef(); - g_pParentWnd->SetStatusText(g_pParentWnd->m_texture_status, strTex.c_str()); -} - -void TextureBrowser_Focus(TextureBrowser &textureBrowser, const char *name); - -void TextureBrowser_SetSelectedShader(TextureBrowser &textureBrowser, const char *shader) -{ - textureBrowser.shader = shader; - TextureBrowser_SetStatus(textureBrowser, shader); - TextureBrowser_Focus(textureBrowser, shader); - - if (FindTextureDialog_isOpen()) { - FindTextureDialog_selectTexture(shader); - } - - // disable the menu item "shader info" if no shader was selected - IShader *ishader = QERApp_Shader_ForName(shader); - CopiedString filename = ishader->getShaderFileName(); - - if (filename.empty()) { - if (textureBrowser.m_shader_info_item != NULL) { - gtk_widget_set_sensitive(textureBrowser.m_shader_info_item, FALSE); - } - } else { - gtk_widget_set_sensitive(textureBrowser.m_shader_info_item, TRUE); - } - - ishader->DecRef(); -} - - -CopiedString g_TextureBrowser_currentDirectory; - -/* - ============================================================================ - - TEXTURE LAYOUT - - TTimo: now based on a rundown through all the shaders - NOTE: we expect the Active shaders count doesn't change during a Texture_StartPos .. Texture_NextPos cycle - otherwise we may need to rely on a list instead of an array storage - ============================================================================ - */ - -class TextureLayout { -public: -// texture layout functions -// TTimo: now based on shaders -int current_x, current_y, current_row; -}; - -void Texture_StartPos(TextureLayout &layout) -{ - layout.current_x = 8; - layout.current_y = -8; - layout.current_row = 0; -} - -void Texture_NextPos(TextureBrowser &textureBrowser, TextureLayout &layout, qtexture_t *current_texture, int *x, int *y) -{ - qtexture_t *q = current_texture; - - int nWidth = textureBrowser.getTextureWidth(q); - int nHeight = textureBrowser.getTextureHeight(q); - 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_row = 0; - } - - *x = layout.current_x; - *y = layout.current_y; - - // Is our texture larger than the row? If so, grow the - // row height to match it - - if (layout.current_row < nHeight) { - layout.current_row = nHeight; - } - - // never go less than 96, or the names get all crunched up - layout.current_x += nWidth < 96 ? 96 : nWidth; - layout.current_x += 8; -} - -bool TextureSearch_IsShown(const char *name) -{ - std::set::iterator iter; - - iter = GlobalTextureBrowser().m_found_shaders.find(name); - - if (iter == GlobalTextureBrowser().m_found_shaders.end()) { - return false; - } else { - return true; - } -} - -// if texture_showinuse jump over non in-use textures -bool Texture_IsShown(IShader *shader, bool show_shaders, bool hideUnused) -{ - // filter missing shaders - // ugly: filter on built-in fallback name after substitution - if (g_TextureBrowser_filterMissing) { - if (isMissing(shader->getTexture()->name)) { - return false; - } - } - // filter the fallback (notex/shadernotex) for missing shaders or editor image - if (g_TextureBrowser_filterFallback) { - if (isNotex(shader->getName())) { - return false; - } - if (isNotex(shader->getTexture()->name)) { - return false; - } - } - - if (g_TextureBrowser_currentDirectory == "Untagged") { - std::set::iterator iter; - - iter = GlobalTextureBrowser().m_found_shaders.find(shader->getName()); - - if (iter == GlobalTextureBrowser().m_found_shaders.end()) { - return false; - } else { - return true; - } - } - - if (!shader_equal_prefix(shader->getName(), "textures/")) { - return false; - } - - if (!show_shaders && !shader->IsDefault()) { - return false; - } - - if (hideUnused && !shader->IsInUse()) { - return false; - } - - if (GlobalTextureBrowser().m_searchedTags) { - if (!TextureSearch_IsShown(shader->getName())) { - return false; - } else { - return true; - } - } else { - if (!shader_equal_prefix(shader_get_textureName(shader->getName()), - g_TextureBrowser_currentDirectory.c_str())) { - return false; - } - } - - return true; -} - -void TextureBrowser_heightChanged(TextureBrowser &textureBrowser) -{ - textureBrowser.m_heightChanged = true; - - TextureBrowser_updateScroll(textureBrowser); - TextureBrowser_queueDraw(textureBrowser); -} - -void TextureBrowser_evaluateHeight(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_heightChanged) { - textureBrowser.m_heightChanged = false; - - textureBrowser.m_nTotalHeight = 0; - - TextureLayout layout; - Texture_StartPos(layout); - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (!Texture_IsShown(shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused)) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - textureBrowser.m_nTotalHeight = std::max(textureBrowser.m_nTotalHeight, - abs(layout.current_y) + TextureBrowser_fontHeight(textureBrowser) + - textureBrowser.getTextureHeight(shader->getTexture()) + 4); - } - } -} - -int TextureBrowser_TotalHeight(TextureBrowser &textureBrowser) -{ - TextureBrowser_evaluateHeight(textureBrowser); - return textureBrowser.m_nTotalHeight; -} - -inline const int &min_int(const int &left, const int &right) -{ - return std::min(left, right); -} - -void TextureBrowser_clampOriginY(TextureBrowser &textureBrowser) -{ - if (textureBrowser.originy > 0) { - textureBrowser.originy = 0; - } - int lower = min_int(textureBrowser.height - TextureBrowser_TotalHeight(textureBrowser), 0); - if (textureBrowser.originy < lower) { - textureBrowser.originy = lower; - } -} - -int TextureBrowser_getOriginY(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_originInvalid) { - textureBrowser.m_originInvalid = false; - TextureBrowser_clampOriginY(textureBrowser); - TextureBrowser_updateScroll(textureBrowser); - } - return textureBrowser.originy; -} - -void TextureBrowser_setOriginY(TextureBrowser &textureBrowser, int originy) -{ - textureBrowser.originy = originy; - TextureBrowser_clampOriginY(textureBrowser); - TextureBrowser_updateScroll(textureBrowser); - TextureBrowser_queueDraw(textureBrowser); -} - - -Signal0 g_activeShadersChangedCallbacks; - -void TextureBrowser_addActiveShadersChangedCallback(const SignalHandler &handler) -{ - g_activeShadersChangedCallbacks.connectLast(handler); -} - -void TextureBrowser_constructTreeStore(); - -class ShadersObserver : public ModuleObserver { -Signal0 m_realiseCallbacks; -public: -void realise() -{ - m_realiseCallbacks(); - TextureBrowser_constructTreeStore(); -} - -void unrealise() -{ -} - -void insert(const SignalHandler &handler) -{ - m_realiseCallbacks.connectLast(handler); -} -}; - -namespace { -ShadersObserver g_ShadersObserver; -} - -void TextureBrowser_addShadersRealiseCallback(const SignalHandler &handler) -{ - g_ShadersObserver.insert(handler); -} - -void TextureBrowser_activeShadersChanged(TextureBrowser &textureBrowser) -{ - TextureBrowser_heightChanged(textureBrowser); - textureBrowser.m_originInvalid = true; - - g_activeShadersChangedCallbacks(); -} - -struct TextureBrowser_ShowScrollbar { - static void Export(const TextureBrowser &self, const Callback &returnz) - { - returnz(self.m_showTextureScrollbar); - } - - static void Import(TextureBrowser &self, bool value) - { - self.m_showTextureScrollbar = value; - if (self.m_texture_scroll) { - self.m_texture_scroll.visible(self.m_showTextureScrollbar); - TextureBrowser_updateScroll(self); - } - } -}; - - -/* - ============== - TextureBrowser_ShowDirectory - relies on texture_directory global for the directory to use - 1) Load the shaders for the given directory - 2) Scan the remaining texture, load them and assign them a default shader (the "noshader" shader) - NOTE: when writing a texture plugin, or some texture extensions, this function may need to be overriden, and made - available through the IShaders interface - NOTE: for texture window layout: - all shaders are stored with alphabetical order after load - previously loaded and displayed stuff is hidden, only in-use and newly loaded is shown - ( the GL textures are not flushed though) - ============== - */ - -bool endswith(const char *haystack, const char *needle) -{ - size_t lh = strlen(haystack); - size_t ln = strlen(needle); - if (lh < ln) { - return false; - } - return !memcmp(haystack + (lh - ln), needle, ln); -} - -bool texture_name_ignore(const char *name) -{ - StringOutputStream strTemp(string_length(name)); - strTemp << LowerCase(name); - - return - endswith(strTemp.c_str(), ".specular") || - endswith(strTemp.c_str(), ".glow") || - endswith(strTemp.c_str(), ".bump") || - endswith(strTemp.c_str(), ".diffuse") || - endswith(strTemp.c_str(), ".blend") || - endswith(strTemp.c_str(), ".alpha") || - endswith(strTemp.c_str(), "_alpha") || - /* Quetoo */ - endswith(strTemp.c_str(), "_h") || - endswith(strTemp.c_str(), "_local") || - endswith(strTemp.c_str(), "_nm") || - endswith(strTemp.c_str(), "_s") || - /* DarkPlaces */ - endswith(strTemp.c_str(), "_bump") || - endswith(strTemp.c_str(), "_glow") || - endswith(strTemp.c_str(), "_gloss") || - endswith(strTemp.c_str(), "_luma") || - endswith(strTemp.c_str(), "_norm") || - endswith(strTemp.c_str(), "_pants") || - endswith(strTemp.c_str(), "_shirt") || - endswith(strTemp.c_str(), "_reflect") || - /* Unvanquished */ - endswith(strTemp.c_str(), "_d") || - endswith(strTemp.c_str(), "_n") || - endswith(strTemp.c_str(), "_p") || - endswith(strTemp.c_str(), "_g") || - endswith(strTemp.c_str(), "_a") || - 0; -} - -class LoadShaderVisitor : public Archive::Visitor { -public: -void visit(const char *name) -{ - IShader *shader = QERApp_Shader_ForName( - CopiedString(StringRange(name, path_get_filename_base_end(name))).c_str()); - shader->DecRef(); -} -}; - -void TextureBrowser_SetHideUnused(TextureBrowser &textureBrowser, bool hideUnused); - -ui::Widget g_page_textures{ui::null}; - -void TextureBrowser_toggleShow() -{ - GroupDialog_showPage(g_page_textures); -} - - -void TextureBrowser_updateTitle() -{ - GroupDialog_updatePageTitle(g_page_textures); -} - - -class TextureCategoryLoadShader { -const char *m_directory; -std::size_t &m_count; -public: -using func = void (const char *); - -TextureCategoryLoadShader(const char *directory, std::size_t &count) - : m_directory(directory), m_count(count) -{ - m_count = 0; -} - -void operator()(const char *name) const -{ - if (shader_equal_prefix(name, "textures/") - && shader_equal_prefix(name + string_length("textures/"), m_directory)) { - ++m_count; - // request the shader, this will load the texture if needed - // this Shader_ForName call is a kind of hack - IShader *pFoo = QERApp_Shader_ForName(name); - pFoo->DecRef(); - } -} -}; - -void TextureDirectory_loadTexture(const char *directory, const char *texture) -{ - StringOutputStream name(256); - name << directory << StringRange(texture, path_get_filename_base_end(texture)); - - if (texture_name_ignore(name.c_str())) { - return; - } - - if (!shader_valid(name.c_str())) { - globalOutputStream() << "Skipping invalid texture name: [" << name.c_str() << "]\n"; - return; - } - - // if a texture is already in use to represent a shader, ignore it - IShader *shader = QERApp_Shader_ForName(name.c_str()); - shader->DecRef(); -} - -typedef ConstPointerCaller TextureDirectoryLoadTextureCaller; - -class LoadTexturesByTypeVisitor : public ImageModules::Visitor { -const char *m_dirstring; -public: -LoadTexturesByTypeVisitor(const char *dirstring) - : m_dirstring(dirstring) -{ -} - -void visit(const char *minor, const _QERPlugImageTable &table) const -{ - GlobalFileSystem().forEachFile(m_dirstring, minor, TextureDirectoryLoadTextureCaller(m_dirstring)); -} -}; - -void TextureBrowser_ShowDirectory(TextureBrowser &textureBrowser, const char *directory) -{ - if (TextureBrowser_showWads()) { - Archive *archive = GlobalFileSystem().getArchive(directory); - ASSERT_NOTNULL(archive); - LoadShaderVisitor visitor; - archive->forEachFile(Archive::VisitorFunc(visitor, Archive::eFiles, 0), "textures/"); - } else { - g_TextureBrowser_currentDirectory = directory; - TextureBrowser_heightChanged(textureBrowser); - - std::size_t shaders_count; - GlobalShaderSystem().foreachShaderName(makeCallback(TextureCategoryLoadShader(directory, shaders_count))); - globalOutputStream() << "Showing " << Unsigned(shaders_count) << " shaders.\n"; - - if (g_pGameDescription->mGameType != "doom3") { - // load remaining texture files - - StringOutputStream dirstring(64); - dirstring << "textures/" << directory; - - Radiant_getImageModules().foreachModule(LoadTexturesByTypeVisitor(dirstring.c_str())); - } - } - - // we'll display the newly loaded textures + all the ones already in use - TextureBrowser_SetHideUnused(textureBrowser, false); - - TextureBrowser_updateTitle(); -} - -void TextureBrowser_ShowTagSearchResult(TextureBrowser &textureBrowser, const char *directory) -{ - g_TextureBrowser_currentDirectory = directory; - TextureBrowser_heightChanged(textureBrowser); - - std::size_t shaders_count; - GlobalShaderSystem().foreachShaderName(makeCallback(TextureCategoryLoadShader(directory, shaders_count))); - globalOutputStream() << "Showing " << Unsigned(shaders_count) << " shaders.\n"; - - if (g_pGameDescription->mGameType != "doom3") { - // load remaining texture files - StringOutputStream dirstring(64); - dirstring << "textures/" << directory; - - { - LoadTexturesByTypeVisitor visitor(dirstring.c_str()); - Radiant_getImageModules().foreachModule(visitor); - } - } - - // we'll display the newly loaded textures + all the ones already in use - TextureBrowser_SetHideUnused(textureBrowser, false); -} - - -bool TextureBrowser_hideUnused(); - -void TextureBrowser_hideUnusedExport(const Callback &importer) -{ - importer(TextureBrowser_hideUnused()); -} - -typedef FreeCaller &), TextureBrowser_hideUnusedExport> TextureBrowserHideUnusedExport; - -void TextureBrowser_showShadersExport(const Callback &importer) -{ - importer(GlobalTextureBrowser().m_showShaders); -} - -typedef FreeCaller &), TextureBrowser_showShadersExport> TextureBrowserShowShadersExport; - -void TextureBrowser_showShaderlistOnly(const Callback &importer) -{ - importer(g_TextureBrowser_shaderlistOnly); -} - -typedef FreeCaller &), TextureBrowser_showShaderlistOnly> TextureBrowserShowShaderlistOnlyExport; - -void TextureBrowser_fixedSize(const Callback &importer) -{ - importer(g_TextureBrowser_fixedSize); -} - -typedef FreeCaller &), TextureBrowser_fixedSize> TextureBrowser_FixedSizeExport; - -void TextureBrowser_filterMissing(const Callback &importer) -{ - importer(g_TextureBrowser_filterMissing); -} - -typedef FreeCaller &), TextureBrowser_filterMissing> TextureBrowser_filterMissingExport; - -void TextureBrowser_filterFallback(const Callback &importer) -{ - importer(g_TextureBrowser_filterFallback); -} - -typedef FreeCaller &), TextureBrowser_filterFallback> TextureBrowser_filterFallbackExport; - -void TextureBrowser_enableAlpha(const Callback &importer) -{ - importer(g_TextureBrowser_enableAlpha); -} - -typedef FreeCaller &), TextureBrowser_enableAlpha> TextureBrowser_enableAlphaExport; - -void TextureBrowser_SetHideUnused(TextureBrowser &textureBrowser, bool hideUnused) -{ - if (hideUnused) { - textureBrowser.m_hideUnused = true; - } else { - textureBrowser.m_hideUnused = false; - } - - textureBrowser.m_hideunused_item.update(); - - TextureBrowser_heightChanged(textureBrowser); - textureBrowser.m_originInvalid = true; -} - -void TextureBrowser_ShowStartupShaders(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_startupShaders == STARTUPSHADERS_COMMON) { - TextureBrowser_ShowDirectory(textureBrowser, TextureBrowser_getComonShadersDir()); - } -} - - -//++timo NOTE: this is a mix of Shader module stuff and texture explorer -// it might need to be split in parts or moved out .. dunno -// scroll origin so the specified texture is completely on screen -// if current texture is not displayed, nothing is changed -void TextureBrowser_Focus(TextureBrowser &textureBrowser, const char *name) -{ - TextureLayout layout; - // scroll origin so the texture is completely on screen - Texture_StartPos(layout); - - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (!Texture_IsShown(shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused)) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - qtexture_t *q = shader->getTexture(); - if (!q) { - break; - } - - // 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 originy = TextureBrowser_getOriginY(textureBrowser); - if (y > originy) { - originy = y; - } - - if (y - textureHeight < originy - textureBrowser.height) { - originy = (y - textureHeight) + textureBrowser.height; - } - - TextureBrowser_setOriginY(textureBrowser, originy); - return; - } - } -} - -IShader *Texture_At(TextureBrowser &textureBrowser, int mx, int my) -{ - my += TextureBrowser_getOriginY(textureBrowser) - textureBrowser.height; - - TextureLayout layout; - Texture_StartPos(layout); - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (!Texture_IsShown(shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused)) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - qtexture_t *q = shader->getTexture(); - if (!q) { - break; - } - - int nWidth = textureBrowser.getTextureWidth(q); - int nHeight = textureBrowser.getTextureHeight(q); - if (mx > x && mx - x < nWidth - && my < y && y - my < nHeight + TextureBrowser_fontHeight(textureBrowser)) { - return shader; - } - } - - return 0; -} - -/* - ============== - SelectTexture - - By mouse click - ============== - */ -void SelectTexture(TextureBrowser &textureBrowser, int mx, int my, bool bShift) -{ - IShader *shader = Texture_At(textureBrowser, mx, my); - if (shader != 0) { - if (bShift) { - if (shader->IsDefault()) { - globalOutputStream() << "ERROR: " << shader->getName() << " is not a shader, it's a texture.\n"; - } else { - ViewShader(shader->getShaderFileName(), shader->getName()); - } - } else { - TextureBrowser_SetSelectedShader(textureBrowser, shader->getName()); - TextureBrowser_textureSelected(shader->getName()); - - if (!FindTextureDialog_isOpen() && !textureBrowser.m_rmbSelected) { - UndoableCommand undo("textureNameSetSelected"); - Select_SetShader(shader->getName()); - } - } - } -} - -/* - ============================================================================ - - MOUSE ACTIONS - - ============================================================================ - */ - -void TextureBrowser_trackingDelta(int x, int y, unsigned int state, void *data) -{ - TextureBrowser &textureBrowser = *reinterpret_cast( data ); - if (y != 0) { - int scale = 1; - - if (state & GDK_SHIFT_MASK) { - scale = 4; - } - - int originy = TextureBrowser_getOriginY(textureBrowser); - originy += y * scale; - TextureBrowser_setOriginY(textureBrowser, originy); - } -} - -void TextureBrowser_Tracking_MouseDown(TextureBrowser &textureBrowser) -{ - textureBrowser.m_freezePointer.freeze_pointer(textureBrowser.m_parent, TextureBrowser_trackingDelta, - &textureBrowser); -} - -void TextureBrowser_Tracking_MouseUp(TextureBrowser &textureBrowser) -{ - textureBrowser.m_freezePointer.unfreeze_pointer(textureBrowser.m_parent); -} - -void TextureBrowser_Selection_MouseDown(TextureBrowser &textureBrowser, guint32 flags, int pointx, int pointy) -{ - SelectTexture(textureBrowser, pointx, textureBrowser.height - 1 - pointy, (flags & GDK_SHIFT_MASK) != 0); -} - -/* - ============================================================================ - - DRAWING - - ============================================================================ - */ - -/* - ============ - Texture_Draw - TTimo: relying on the shaders list to display the textures - we must query all qtexture_t* to manage and display through the IShaders interface - this allows a plugin to completely override the texture system - ============ - */ -void Texture_Draw(TextureBrowser &textureBrowser) -{ - int originy = TextureBrowser_getOriginY(textureBrowser); - - glClearColor(textureBrowser.color_textureback[0], - textureBrowser.color_textureback[1], - textureBrowser.color_textureback[2], - 0); - glViewport(0, 0, textureBrowser.width, textureBrowser.height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); - if (g_TextureBrowser_enableAlpha) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } else { - glDisable(GL_BLEND); - } - glOrtho(0, textureBrowser.width, originy - textureBrowser.height, originy, -100, 100); - glEnable(GL_TEXTURE_2D); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - int last_y = 0, last_height = 0; - - TextureLayout layout; - Texture_StartPos(layout); - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - if (!Texture_IsShown(shader, textureBrowser.m_showShaders, textureBrowser.m_hideUnused)) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - qtexture_t *q = shader->getTexture(); - if (!q) { - break; - } - - int nWidth = textureBrowser.getTextureWidth(q); - int nHeight = textureBrowser.getTextureHeight(q); - - if (y != last_y) { - last_y = y; - last_height = 0; - } - last_height = std::max(nHeight, last_height); - - // Is this texture visible? - if ((y - nHeight - TextureBrowser_fontHeight(textureBrowser) < originy) - && (y > originy - textureBrowser.height)) { - // borders rules: - // if it's the current texture, draw a thick red line, else: - // shaders have a white border, simple textures don't - // if !texture_showinuse: (some textures displayed may not be in use) - // draw an additional square around with 0.5 1 0.5 color - if (shader_equal(TextureBrowser_GetSelectedShader(textureBrowser), shader->getName())) { - glLineWidth(3); - if (textureBrowser.m_rmbSelected) { - glColor3f(0, 0, 1); - } else { - glColor3f(1, 0, 0); - } - 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); - glEnd(); - - glEnable(GL_TEXTURE_2D); - glLineWidth(1); - } else { - glLineWidth(1); - // shader border: - if (!shader->IsDefault()) { - glColor3f(1, 1, 1); - glDisable(GL_TEXTURE_2D); - - glBegin(GL_LINE_LOOP); - glVertex2i(x - 1, y + 1 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x - 1, y - nHeight - 1 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x + 1 + nWidth, y - nHeight - 1 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x + 1 + nWidth, y + 1 - TextureBrowser_fontHeight(textureBrowser)); - glEnd(); - glEnable(GL_TEXTURE_2D); - } - - // highlight in-use textures - if (!textureBrowser.m_hideUnused && shader->IsInUse()) { - glColor3f(0.5, 1, 0.5); - glDisable(GL_TEXTURE_2D); - glBegin(GL_LINE_LOOP); - glVertex2i(x - 3, y + 3 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x - 3, y - nHeight - 3 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x + 3 + nWidth, y - nHeight - 3 - TextureBrowser_fontHeight(textureBrowser)); - glVertex2i(x + 3 + nWidth, y + 3 - TextureBrowser_fontHeight(textureBrowser)); - glEnd(); - glEnable(GL_TEXTURE_2D); - } - } - - // draw checkerboard for transparent textures - if (g_TextureBrowser_enableAlpha) { - glDisable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - int font_height = TextureBrowser_fontHeight(textureBrowser); - for (int i = 0; i < nHeight; i += 8) { - for (int j = 0; j < nWidth; j += 8) { - unsigned char color = (i + j) / 8 % 2 ? 0x66 : 0x99; - glColor3ub(color, color, color); - int left = j; - int right = std::min(j + 8, nWidth); - int top = i; - int bottom = std::min(i + 8, nHeight); - glVertex2i(x + right, y - nHeight - font_height + top); - glVertex2i(x + left, y - nHeight - font_height + top); - glVertex2i(x + left, y - nHeight - font_height + bottom); - glVertex2i(x + right, y - nHeight - font_height + bottom); - } - } - glEnd(); - glEnable(GL_TEXTURE_2D); - } - - // Draw the texture - glBindTexture(GL_TEXTURE_2D, q->texture_number); - GlobalOpenGL_debugAssertNoErrors(); - glColor3f(1, 1, 1); - glBegin(GL_QUADS); - glTexCoord2i(0, 0); - glVertex2i(x, y - TextureBrowser_fontHeight(textureBrowser)); - glTexCoord2i(1, 0); - glVertex2i(x + nWidth, y - TextureBrowser_fontHeight(textureBrowser)); - glTexCoord2i(1, 1); - glVertex2i(x + nWidth, y - TextureBrowser_fontHeight(textureBrowser) - nHeight); - glTexCoord2i(0, 1); - glVertex2i(x, y - TextureBrowser_fontHeight(textureBrowser) - nHeight); - glEnd(); - - // draw the texture name - glDisable(GL_TEXTURE_2D); - glColor3f(1, 1, 1); - - glRasterPos2i(x, y - TextureBrowser_fontHeight(textureBrowser) + 5); - - // don't draw the directory name - const char *name = shader->getName(); - name += strlen(name); - while (name != shader->getName() && *(name - 1) != '/' && *(name - 1) != '\\') { - name--; - } - - GlobalOpenGL().drawString(name); - glEnable(GL_TEXTURE_2D); - } - - //int totalHeight = abs(y) + last_height + TextureBrowser_fontHeight(textureBrowser) + 4; - } - - - // reset the current texture - glBindTexture(GL_TEXTURE_2D, 0); - //qglFinish(); -} - - -void Texture_DrawSingle(TextureBrowser &textureBrowser) -{ - int originy = TextureBrowser_getOriginY(textureBrowser); - - glClearColor(textureBrowser.color_textureback[0], - textureBrowser.color_textureback[1], - textureBrowser.color_textureback[2], - 0); - glViewport(0, 0, textureBrowser.width, textureBrowser.height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); - if (g_TextureBrowser_enableAlpha) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } else { - glDisable(GL_BLEND); - } - glOrtho(0, textureBrowser.width, originy - textureBrowser.height, originy, -100, 100); - glEnable(GL_TEXTURE_2D); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - int last_y = 0, last_height = 0; - - TextureLayout layout; - Texture_StartPos(layout); - for (QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement()) { - IShader *shader = QERApp_ActiveShaders_IteratorCurrent(); - - - if (!shader_equal(TextureBrowser_GetSelectedShader(textureBrowser), shader->getName())) { - continue; - } - - int x, y; - Texture_NextPos(textureBrowser, layout, shader->getTexture(), &x, &y); - qtexture_t *q = shader->getTexture(); - if (!q) { - break; - } - - int nWidth = textureBrowser.getTextureWidth(q); - int nHeight = textureBrowser.getTextureHeight(q); - - if (y != last_y) { - last_y = y; - last_height = 0; - } - last_height = std::max(nHeight, last_height); - - // Is this texture visible? - if ((y - nHeight - TextureBrowser_fontHeight(textureBrowser) < originy) - && (y > originy - textureBrowser.height)) { - // borders rules: - // if it's the current texture, draw a thick red line, else: - // shaders have a white border, simple textures don't - // if !texture_showinuse: (some textures displayed may not be in use) - // draw an additional square around with 0.5 1 0.5 color - - glLineWidth(3); - if (textureBrowser.m_rmbSelected) { - glColor3f(0, 0, 1); - } else { - glColor3f(1, 0, 0); - } - 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); - glEnd(); - - glEnable(GL_TEXTURE_2D); - glLineWidth(1); - - // draw checkerboard for transparent textures - if (g_TextureBrowser_enableAlpha) { - glDisable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - int font_height = TextureBrowser_fontHeight(textureBrowser); - for (int i = 0; i < nHeight; i += 8) { - for (int j = 0; j < nWidth; j += 8) { - unsigned char color = (i + j) / 8 % 2 ? 0x66 : 0x99; - glColor3ub(color, color, color); - int left = j; - int right = std::min(j + 8, nWidth); - int top = i; - int bottom = std::min(i + 8, nHeight); - glVertex2i(x + right, y - nHeight - font_height + top); - glVertex2i(x + left, y - nHeight - font_height + top); - glVertex2i(x + left, y - nHeight - font_height + bottom); - glVertex2i(x + right, y - nHeight - font_height + bottom); - } - } - glEnd(); - glEnable(GL_TEXTURE_2D); - } - - // Draw the texture - glBindTexture(GL_TEXTURE_2D, q->texture_number); - GlobalOpenGL_debugAssertNoErrors(); - glColor3f(1, 1, 1); - glBegin(GL_QUADS); - glTexCoord2i(0, 0); - glVertex2i(x, y - TextureBrowser_fontHeight(textureBrowser)); - glTexCoord2i(1, 0); - glVertex2i(x + nWidth, y - TextureBrowser_fontHeight(textureBrowser)); - glTexCoord2i(1, 1); - glVertex2i(x + nWidth, y - TextureBrowser_fontHeight(textureBrowser) - nHeight); - glTexCoord2i(0, 1); - glVertex2i(x, y - TextureBrowser_fontHeight(textureBrowser) - nHeight); - glEnd(); - - // draw the texture name - glDisable(GL_TEXTURE_2D); - glColor3f(1, 1, 1); - - glRasterPos2i(x, y - TextureBrowser_fontHeight(textureBrowser) + 5); - - // don't draw the directory name - const char *name = shader->getName(); - name += strlen(name); - while (name != shader->getName() && *(name - 1) != '/' && *(name - 1) != '\\') { - name--; - } - - GlobalOpenGL().drawString(name); - glEnable(GL_TEXTURE_2D); - } - - //int totalHeight = abs(y) + last_height + TextureBrowser_fontHeight(textureBrowser) + 4; - } - - - // reset the current texture - glBindTexture(GL_TEXTURE_2D, 0); - //qglFinish(); -} - -void TextureBrowser_queueDraw(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_gl_widget) { - gtk_widget_queue_draw(textureBrowser.m_gl_widget); - } -} - - -void TextureBrowser_setScale(TextureBrowser &textureBrowser, std::size_t scale) -{ - textureBrowser.m_textureScale = scale; - - TextureBrowser_queueDraw(textureBrowser); -} - -void TextureBrowser_setUniformSize(TextureBrowser &textureBrowser, std::size_t scale) -{ - textureBrowser.m_uniformTextureSize = scale; - - TextureBrowser_queueDraw(textureBrowser); -} - - -void TextureBrowser_MouseWheel(TextureBrowser &textureBrowser, bool bUp) -{ - int originy = TextureBrowser_getOriginY(textureBrowser); - - if (bUp) { - originy += int(textureBrowser.m_mouseWheelScrollIncrement); - } else { - originy -= int(textureBrowser.m_mouseWheelScrollIncrement); - } - - TextureBrowser_setOriginY(textureBrowser, originy); -} - -XmlTagBuilder TagBuilder; - -enum { - TAG_COLUMN, - N_COLUMNS -}; - -void BuildStoreAssignedTags(ui::ListStore store, const char *shader, TextureBrowser *textureBrowser) -{ - GtkTreeIter iter; - - store.clear(); - - std::vector assigned_tags; - TagBuilder.GetShaderTags(shader, assigned_tags); - - for (size_t i = 0; i < assigned_tags.size(); i++) { - store.append(TAG_COLUMN, assigned_tags[i].c_str()); - } -} - -void BuildStoreAvailableTags(ui::ListStore storeAvailable, - ui::ListStore storeAssigned, - const std::set &allTags, - TextureBrowser *textureBrowser) -{ - GtkTreeIter iterAssigned; - GtkTreeIter iterAvailable; - std::set::const_iterator iterAll; - gchar *tag_assigned; - - storeAvailable.clear(); - - bool row = gtk_tree_model_get_iter_first(storeAssigned, &iterAssigned) != 0; - - if (!row) { // does the shader have tags assigned? - for (iterAll = allTags.begin(); iterAll != allTags.end(); ++iterAll) { - storeAvailable.append(TAG_COLUMN, (*iterAll).c_str()); - } - } else { - while (row) // available tags = all tags - assigned tags - { - gtk_tree_model_get(storeAssigned, &iterAssigned, TAG_COLUMN, &tag_assigned, -1); - - for (iterAll = allTags.begin(); iterAll != allTags.end(); ++iterAll) { - if (strcmp((char *) tag_assigned, (*iterAll).c_str()) != 0) { - storeAvailable.append(TAG_COLUMN, (*iterAll).c_str()); - } else { - row = gtk_tree_model_iter_next(storeAssigned, &iterAssigned) != 0; - - if (row) { - gtk_tree_model_get(storeAssigned, &iterAssigned, TAG_COLUMN, &tag_assigned, -1); - } - } - } - } - } -} - -gboolean TextureBrowser_button_press(ui::Widget widget, GdkEventButton *event, TextureBrowser *textureBrowser) -{ - if (event->type == GDK_BUTTON_PRESS) { - if (event->button == 3) { - if (GlobalTextureBrowser().m_tags) { - textureBrowser->m_rmbSelected = true; - TextureBrowser_Selection_MouseDown(*textureBrowser, event->state, static_cast( event->x ), - static_cast( event->y )); - - BuildStoreAssignedTags(textureBrowser->m_assigned_store, textureBrowser->shader.c_str(), - textureBrowser); - BuildStoreAvailableTags(textureBrowser->m_available_store, textureBrowser->m_assigned_store, - textureBrowser->m_all_tags, textureBrowser); - textureBrowser->m_heightChanged = true; - textureBrowser->m_tag_frame.show(); - - ui::process(); - - TextureBrowser_Focus(*textureBrowser, textureBrowser->shader.c_str()); - } else { - TextureBrowser_Tracking_MouseDown(*textureBrowser); - } - } else if (event->button == 1) { - TextureBrowser_Selection_MouseDown(*textureBrowser, event->state, static_cast( event->x ), - static_cast( event->y )); - - if (GlobalTextureBrowser().m_tags) { - textureBrowser->m_rmbSelected = false; - textureBrowser->m_tag_frame.hide(); - } - } - } - return FALSE; -} - -gboolean TextureBrowser_button_release(ui::Widget widget, GdkEventButton *event, TextureBrowser *textureBrowser) -{ - if (event->type == GDK_BUTTON_RELEASE) { - if (event->button == 3) { - if (!GlobalTextureBrowser().m_tags) { - TextureBrowser_Tracking_MouseUp(*textureBrowser); - } - } - } - return FALSE; -} - -gboolean TextureBrowser_motion(ui::Widget widget, GdkEventMotion *event, TextureBrowser *textureBrowser) -{ - return FALSE; -} - -gboolean TextureBrowser_scroll(ui::Widget widget, GdkEventScroll *event, TextureBrowser *textureBrowser) -{ - if (event->direction == GDK_SCROLL_UP) { - TextureBrowser_MouseWheel(*textureBrowser, true); - } else if (event->direction == GDK_SCROLL_DOWN) { - TextureBrowser_MouseWheel(*textureBrowser, false); - } - return FALSE; -} - -void TextureBrowser_scrollChanged(void *data, gdouble value) -{ - //globalOutputStream() << "vertical scroll\n"; - TextureBrowser_setOriginY(*reinterpret_cast( data ), -(int) value); -} - -static void TextureBrowser_verticalScroll(ui::Adjustment adjustment, TextureBrowser *textureBrowser) -{ - textureBrowser->m_scrollAdjustment.value_changed(gtk_adjustment_get_value(adjustment)); -} - -void TextureBrowser_updateScroll(TextureBrowser &textureBrowser) -{ - if (textureBrowser.m_showTextureScrollbar) { - int totalHeight = TextureBrowser_TotalHeight(textureBrowser); - - totalHeight = std::max(totalHeight, textureBrowser.height); - - auto vadjustment = gtk_range_get_adjustment(GTK_RANGE(textureBrowser.m_texture_scroll)); - - gtk_adjustment_set_value(vadjustment, -TextureBrowser_getOriginY(textureBrowser)); - gtk_adjustment_set_page_size(vadjustment, textureBrowser.height); - gtk_adjustment_set_page_increment(vadjustment, textureBrowser.height / 2); - gtk_adjustment_set_step_increment(vadjustment, 20); - gtk_adjustment_set_lower(vadjustment, 0); - gtk_adjustment_set_upper(vadjustment, totalHeight); - - g_signal_emit_by_name(G_OBJECT(vadjustment), "changed"); - } -} - -gboolean TextureBrowser_size_allocate(ui::Widget widget, GtkAllocation *allocation, TextureBrowser *textureBrowser) -{ - textureBrowser->width = allocation->width; - textureBrowser->height = allocation->height; - TextureBrowser_heightChanged(*textureBrowser); - textureBrowser->m_originInvalid = true; - TextureBrowser_queueDraw(*textureBrowser); - return FALSE; -} - -gboolean TextureBrowser_expose(ui::Widget widget, GdkEventExpose *event, TextureBrowser *textureBrowser) -{ - if (glwidget_make_current(textureBrowser->m_gl_widget) != FALSE) { - GlobalOpenGL_debugAssertNoErrors(); - TextureBrowser_evaluateHeight(*textureBrowser); - Texture_Draw(*textureBrowser); - GlobalOpenGL_debugAssertNoErrors(); - glwidget_swap_buffers(textureBrowser->m_gl_widget); - } - return FALSE; -} - - -TextureBrowser g_TextureBrowser; - -TextureBrowser &GlobalTextureBrowser() -{ - return g_TextureBrowser; -} - -bool TextureBrowser_hideUnused() -{ - return g_TextureBrowser.m_hideUnused; -} - -void TextureBrowser_ToggleHideUnused() -{ - if (g_TextureBrowser.m_hideUnused) { - TextureBrowser_SetHideUnused(g_TextureBrowser, false); - } else { - TextureBrowser_SetHideUnused(g_TextureBrowser, true); - } -} - -void TextureGroups_constructTreeModel(TextureGroups groups, ui::TreeStore store) -{ - // put the information from the old textures menu into a treeview - GtkTreeIter iter, child; - - TextureGroups::const_iterator i = groups.begin(); - while (i != groups.end()) { - const char *dirName = (*i).c_str(); - const char *firstUnderscore = strchr(dirName, '_'); - StringRange dirRoot(dirName, (firstUnderscore == 0) ? dirName : firstUnderscore + 1); - - TextureGroups::const_iterator next = i; - ++next; - if (firstUnderscore != 0 - && next != groups.end() - && string_equal_start((*next).c_str(), dirRoot)) { - gtk_tree_store_append(store, &iter, NULL); - gtk_tree_store_set(store, &iter, 0, CopiedString(StringRange(dirName, firstUnderscore)).c_str(), -1); - - // keep going... - while (i != groups.end() && string_equal_start((*i).c_str(), dirRoot)) { - gtk_tree_store_append(store, &child, &iter); - gtk_tree_store_set(store, &child, 0, (*i).c_str(), -1); - ++i; - } - } else { - gtk_tree_store_append(store, &iter, NULL); - gtk_tree_store_set(store, &iter, 0, dirName, -1); - ++i; - } - } -} - -TextureGroups TextureGroups_constructTreeView() -{ - TextureGroups groups; - - if (TextureBrowser_showWads()) { - GlobalFileSystem().forEachArchive(TextureGroupsAddWadCaller(groups)); - } else { - // scan texture dirs and pak files only if not restricting to shaderlist - if (g_pGameDescription->mGameType != "doom3" && !g_TextureBrowser_shaderlistOnly) { - GlobalFileSystem().forEachDirectory("textures/", TextureGroupsAddDirectoryCaller(groups)); - } - - GlobalShaderSystem().foreachShaderName(TextureGroupsAddShaderCaller(groups)); - } - - return groups; -} - -void TextureBrowser_constructTreeStore() -{ - TextureGroups groups = TextureGroups_constructTreeView(); - auto store = ui::TreeStore::from(gtk_tree_store_new(1, G_TYPE_STRING)); - TextureGroups_constructTreeModel(groups, store); - - gtk_tree_view_set_model(g_TextureBrowser.m_treeViewTree, store); - - g_object_unref(G_OBJECT(store)); -} - -void TextureBrowser_constructTreeStoreTags() -{ - TextureGroups groups; - auto store = ui::TreeStore::from(gtk_tree_store_new(1, G_TYPE_STRING)); - auto model = g_TextureBrowser.m_all_tags_list; - - gtk_tree_view_set_model(g_TextureBrowser.m_treeViewTags, model); - - g_object_unref(G_OBJECT(store)); -} - -void TreeView_onRowActivated(ui::TreeView treeview, ui::TreePath path, ui::TreeViewColumn col, gpointer userdata) -{ - GtkTreeIter iter; - - auto model = gtk_tree_view_get_model(treeview); - - if (gtk_tree_model_get_iter(model, &iter, path)) { - gchar dirName[1024]; - - gchar *buffer; - gtk_tree_model_get(model, &iter, 0, &buffer, -1); - strcpy(dirName, buffer); - g_free(buffer); - - g_TextureBrowser.m_searchedTags = false; - - if (!TextureBrowser_showWads()) { - strcat(dirName, "/"); - } - - ScopeDisableScreenUpdates disableScreenUpdates(dirName, "Loading Textures"); - TextureBrowser_ShowDirectory(GlobalTextureBrowser(), dirName); - TextureBrowser_queueDraw(GlobalTextureBrowser()); - } -} - -void TextureBrowser_createTreeViewTree() -{ - gtk_tree_view_set_enable_search(g_TextureBrowser.m_treeViewTree, FALSE); - - gtk_tree_view_set_headers_visible(g_TextureBrowser.m_treeViewTree, FALSE); - g_TextureBrowser.m_treeViewTree.connect("row-activated", (GCallback) TreeView_onRowActivated, NULL); - - auto renderer = ui::CellRendererText(ui::New); - gtk_tree_view_insert_column_with_attributes(g_TextureBrowser.m_treeViewTree, -1, "", renderer, "text", 0, NULL); - - TextureBrowser_constructTreeStore(); -} - -void TextureBrowser_addTag(); - -void TextureBrowser_renameTag(); - -void TextureBrowser_deleteTag(); - -void TextureBrowser_createContextMenu(ui::Widget treeview, GdkEventButton *event) -{ - ui::Widget menu = ui::Menu(ui::New); - - ui::Widget menuitem = ui::MenuItem("Add tag"); - menuitem.connect("activate", (GCallback) TextureBrowser_addTag, treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - menuitem = ui::MenuItem("Rename tag"); - menuitem.connect("activate", (GCallback) TextureBrowser_renameTag, treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - menuitem = ui::MenuItem("Delete tag"); - menuitem.connect("activate", (GCallback) TextureBrowser_deleteTag, treeview); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - gtk_widget_show_all(menu); - - gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, - (event != NULL) ? event->button : 0, - gdk_event_get_time((GdkEvent *) event)); -} - -gboolean TreeViewTags_onButtonPressed(ui::TreeView treeview, GdkEventButton *event) -{ - if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - GtkTreePath *path; - auto selection = gtk_tree_view_get_selection(treeview); - - if (gtk_tree_view_get_path_at_pos(treeview, event->x, event->y, &path, NULL, NULL, NULL)) { - gtk_tree_selection_unselect_all(selection); - gtk_tree_selection_select_path(selection, path); - gtk_tree_path_free(path); - } - - TextureBrowser_createContextMenu(treeview, event); - return TRUE; - } - return FALSE; -} - -void TextureBrowser_createTreeViewTags() -{ - g_TextureBrowser.m_treeViewTags = ui::TreeView(ui::New); - gtk_tree_view_set_enable_search(g_TextureBrowser.m_treeViewTags, FALSE); - - g_TextureBrowser.m_treeViewTags.connect("button-press-event", (GCallback) TreeViewTags_onButtonPressed, NULL); - - gtk_tree_view_set_headers_visible(g_TextureBrowser.m_treeViewTags, FALSE); - - auto renderer = ui::CellRendererText(ui::New); - gtk_tree_view_insert_column_with_attributes(g_TextureBrowser.m_treeViewTags, -1, "", renderer, "text", 0, NULL); - - TextureBrowser_constructTreeStoreTags(); -} - -ui::MenuItem TextureBrowser_constructViewMenu(ui::Menu menu) -{ - ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic("_View")); - - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_check_menu_item_with_mnemonic(menu, "Hide _Unused", "ShowInUse"); - if (string_empty(g_pGameDescription->getKeyValue("show_wads"))) { - create_check_menu_item_with_mnemonic(menu, "Hide Image Missing", "FilterMissing"); - } - - // hide notex and shadernotex on texture browser: no one wants to apply them - create_check_menu_item_with_mnemonic(menu, "Hide Fallback", "FilterFallback"); - - menu_separator(menu); - - create_menu_item_with_mnemonic(menu, "Show All", "ShowAllTextures"); - - // we always want to show shaders but don't want a "Show Shaders" menu for doom3 and .wad file games - if (!string_empty(g_pGameDescription->getKeyValue("show_wads"))) { - g_TextureBrowser.m_showShaders = true; - } else { - create_check_menu_item_with_mnemonic(menu, "Show shaders", "ToggleShowShaders"); - } - - if (string_empty(g_pGameDescription->getKeyValue("show_wads"))) { - create_check_menu_item_with_mnemonic(menu, "Shaders Only", "ToggleShowShaderlistOnly"); - } - if (g_TextureBrowser.m_tags) { - create_menu_item_with_mnemonic(menu, "Show Untagged", "ShowUntagged"); - } - - menu_separator(menu); - create_check_menu_item_with_mnemonic(menu, "Fixed Size", "FixedSize"); - create_check_menu_item_with_mnemonic(menu, "Transparency", "EnableAlpha"); - - if (string_empty(g_pGameDescription->getKeyValue("show_wads"))) { - menu_separator(menu); - g_TextureBrowser.m_shader_info_item = ui::Widget( - create_menu_item_with_mnemonic(menu, "Shader Info", "ShaderInfo")); - gtk_widget_set_sensitive(g_TextureBrowser.m_shader_info_item, FALSE); - } - - - return textures_menu_item; -} - -ui::MenuItem TextureBrowser_constructToolsMenu(ui::Menu menu) -{ - ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic("_Tools")); - - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_menu_item_with_mnemonic(menu, "Flush & Reload Shaders", "RefreshShaders"); - create_menu_item_with_mnemonic(menu, "Find / Replace...", "FindReplaceTextures"); - - return textures_menu_item; -} - -ui::MenuItem TextureBrowser_constructTagsMenu(ui::Menu menu) -{ - ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic("T_ags")); - - /*if (g_Layout_enableOpenStepUX.m_value) { - menu_tearoff(menu); - }*/ - - create_menu_item_with_mnemonic(menu, "Add tag", "AddTag"); - create_menu_item_with_mnemonic(menu, "Rename tag", "RenameTag"); - create_menu_item_with_mnemonic(menu, "Delete tag", "DeleteTag"); - menu_separator(menu); - create_menu_item_with_mnemonic(menu, "Copy tags from selected", "CopyTag"); - create_menu_item_with_mnemonic(menu, "Paste tags to selected", "PasteTag"); - - return textures_menu_item; -} - -gboolean TextureBrowser_tagMoveHelper(ui::TreeModel model, ui::TreePath path, GtkTreeIter iter, GSList **selected) -{ - g_assert(selected != NULL); - - auto rowref = gtk_tree_row_reference_new(model, path); - - if (rowref != NULL) - *selected = g_slist_append(*selected, rowref); - - return FALSE; -} - -void TextureBrowser_assignTags() -{ - GSList *selected = NULL; - GSList *node; - gchar *tag_assigned; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree); - - gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) TextureBrowser_tagMoveHelper, - &selected); - - if (selected != NULL) { - for (node = selected; node != NULL; node = node->next) { - auto path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) node->data); - - if (path) { - GtkTreeIter iter; - - if (gtk_tree_model_get_iter(g_TextureBrowser.m_available_store, &iter, path)) { - gtk_tree_model_get(g_TextureBrowser.m_available_store, &iter, TAG_COLUMN, &tag_assigned, -1); - if (!TagBuilder.CheckShaderTag(g_TextureBrowser.shader.c_str())) { - // create a custom shader/texture entry - IShader *ishader = QERApp_Shader_ForName(g_TextureBrowser.shader.c_str()); - CopiedString filename = ishader->getShaderFileName(); - - if (filename.empty()) { - // it's a texture - TagBuilder.AddShaderNode(g_TextureBrowser.shader.c_str(), CUSTOM, TEXTURE); - } else { - // it's a shader - TagBuilder.AddShaderNode(g_TextureBrowser.shader.c_str(), CUSTOM, SHADER); - } - ishader->DecRef(); - } - TagBuilder.AddShaderTag(g_TextureBrowser.shader.c_str(), (char *) tag_assigned, TAG); - - gtk_list_store_remove(g_TextureBrowser.m_available_store, &iter); - g_TextureBrowser.m_assigned_store.append(TAG_COLUMN, tag_assigned); - } - } - } - - g_slist_foreach(selected, (GFunc) gtk_tree_row_reference_free, NULL); - - // Save changes - TagBuilder.SaveXmlDoc(); - } - g_slist_free(selected); -} - -void TextureBrowser_removeTags() -{ - GSList *selected = NULL; - GSList *node; - gchar *tag; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_assigned_tree); - - gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) TextureBrowser_tagMoveHelper, - &selected); - - if (selected != NULL) { - for (node = selected; node != NULL; node = node->next) { - auto path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) node->data); - - if (path) { - GtkTreeIter iter; - - if (gtk_tree_model_get_iter(g_TextureBrowser.m_assigned_store, &iter, path)) { - gtk_tree_model_get(g_TextureBrowser.m_assigned_store, &iter, TAG_COLUMN, &tag, -1); - TagBuilder.DeleteShaderTag(g_TextureBrowser.shader.c_str(), tag); - gtk_list_store_remove(g_TextureBrowser.m_assigned_store, &iter); - } - } - } - - g_slist_foreach(selected, (GFunc) gtk_tree_row_reference_free, NULL); - - // Update the "available tags list" - BuildStoreAvailableTags(g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, - g_TextureBrowser.m_all_tags, &g_TextureBrowser); - - // Save changes - TagBuilder.SaveXmlDoc(); - } - g_slist_free(selected); -} - -void TextureBrowser_buildTagList() -{ - g_TextureBrowser.m_all_tags_list.clear(); - - std::set::iterator iter; - - for (iter = g_TextureBrowser.m_all_tags.begin(); iter != g_TextureBrowser.m_all_tags.end(); ++iter) { - g_TextureBrowser.m_all_tags_list.append(TAG_COLUMN, (*iter).c_str()); - } -} - -void TextureBrowser_searchTags() -{ - GSList *selected = NULL; - GSList *node; - gchar *tag; - char buffer[256]; - char tags_searched[256]; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags); - - gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) TextureBrowser_tagMoveHelper, - &selected); - - if (selected != NULL) { - strcpy(buffer, "/root/*/*[tag='"); - strcpy(tags_searched, "[TAGS] "); - - for (node = selected; node != NULL; node = node->next) { - auto path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) node->data); - - if (path) { - GtkTreeIter iter; - - if (gtk_tree_model_get_iter(g_TextureBrowser.m_all_tags_list, &iter, path)) { - gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iter, TAG_COLUMN, &tag, -1); - - strcat(buffer, tag); - strcat(tags_searched, tag); - if (node != g_slist_last(node)) { - strcat(buffer, "' and tag='"); - strcat(tags_searched, ", "); - } - } - } - } - - strcat(buffer, "']"); - - g_slist_foreach(selected, (GFunc) gtk_tree_row_reference_free, NULL); - - g_TextureBrowser.m_found_shaders.clear(); // delete old list - TagBuilder.TagSearch(buffer, g_TextureBrowser.m_found_shaders); - - if (!g_TextureBrowser.m_found_shaders.empty()) { // found something - size_t shaders_found = g_TextureBrowser.m_found_shaders.size(); - - globalOutputStream() << "Found " << (unsigned int) shaders_found << " textures and shaders with " - << tags_searched << "\n"; - ScopeDisableScreenUpdates disableScreenUpdates("Searching...", "Loading Textures"); - - std::set::iterator iter; - - for (iter = g_TextureBrowser.m_found_shaders.begin(); - iter != g_TextureBrowser.m_found_shaders.end(); iter++) { - std::string path = (*iter).c_str(); - size_t pos = path.find_last_of("/", path.size()); - std::string name = path.substr(pos + 1, path.size()); - path = path.substr(0, pos + 1); - TextureDirectory_loadTexture(path.c_str(), name.c_str()); - } - } - g_TextureBrowser.m_searchedTags = true; - g_TextureBrowser_currentDirectory = tags_searched; - - g_TextureBrowser.m_nTotalHeight = 0; - TextureBrowser_setOriginY(g_TextureBrowser, 0); - TextureBrowser_heightChanged(g_TextureBrowser); - TextureBrowser_updateTitle(); - } - g_slist_free(selected); -} - -void TextureBrowser_toggleSearchButton() -{ - gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(g_TextureBrowser.m_tag_notebook)); - - if (page == 0) { // tag page - gtk_widget_show_all(g_TextureBrowser.m_search_button); - } else { - g_TextureBrowser.m_search_button.hide(); - } -} - -void TextureBrowser_constructTagNotebook() -{ - g_TextureBrowser.m_tag_notebook = ui::Widget::from(gtk_notebook_new()); - ui::Widget labelTags = ui::Label("Tags"); - ui::Widget labelTextures = ui::Label("Textures"); - - gtk_notebook_append_page(GTK_NOTEBOOK(g_TextureBrowser.m_tag_notebook), g_TextureBrowser.m_scr_win_tree, - labelTextures); - gtk_notebook_append_page(GTK_NOTEBOOK(g_TextureBrowser.m_tag_notebook), g_TextureBrowser.m_scr_win_tags, labelTags); - - g_TextureBrowser.m_tag_notebook.connect("switch-page", G_CALLBACK(TextureBrowser_toggleSearchButton), NULL); - - gtk_widget_show_all(g_TextureBrowser.m_tag_notebook); -} - -void TextureBrowser_constructSearchButton() -{ - auto image = ui::Widget::from(gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_SMALL_TOOLBAR)); - g_TextureBrowser.m_search_button = ui::Button(ui::New); - g_TextureBrowser.m_search_button.connect("clicked", G_CALLBACK(TextureBrowser_searchTags), NULL); - gtk_widget_set_tooltip_text(g_TextureBrowser.m_search_button, "Search with selected tags"); - g_TextureBrowser.m_search_button.add(image); -} - -void TextureBrowser_checkTagFile() -{ - const char SHADERTAG_FILE[] = "shadertags.xml"; - CopiedString default_filename, rc_filename; - StringOutputStream stream(256); - - stream << LocalRcPath_get(); - stream << SHADERTAG_FILE; - rc_filename = stream.c_str(); - - if (file_exists(rc_filename.c_str())) { - g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc(rc_filename.c_str()); - - if (g_TextureBrowser.m_tags) { - globalOutputStream() << "Loading tag file " << rc_filename.c_str() << ".\n"; - } - } else { - // load default tagfile - stream.clear(); - stream << g_pGameDescription->mGameToolsPath.c_str(); - stream << SHADERTAG_FILE; - default_filename = stream.c_str(); - - if (file_exists(default_filename.c_str())) { - g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc(default_filename.c_str(), rc_filename.c_str()); - - if (g_TextureBrowser.m_tags) { - globalOutputStream() << "Loading default tag file " << default_filename.c_str() << ".\n"; - } - } else { - globalErrorStream() << "Unable to find default tag file " << default_filename.c_str() - << ". No tag support.\n"; - } - } -} - -void TextureBrowser_SetNotex() -{ - StringOutputStream name(256); - name << GlobalRadiant().getAppPath() << "bitmaps/" NOTEX_BASENAME ".xpm"; - g_notex = name.c_str(); - - name = StringOutputStream(256); - name << GlobalRadiant().getAppPath() << "bitmaps/" SHADERNOTEX_BASENAME " .xpm"; - g_shadernotex = name.c_str(); -} - -ui::Widget TextureBrowser_constructWindow(ui::Window toplevel) -{ - // The gl_widget and the tag assignment frame should be packed into a GtkVPaned with the slider - // position stored in local.pref. gtk_paned_get_position() and gtk_paned_set_position() don't - // seem to work in gtk 2.4 and the arrow buttons don't handle GTK_FILL, so here's another thing - // for the "once-the-gtk-libs-are-updated-TODO-list" :x - - TextureBrowser_checkTagFile(); - TextureBrowser_SetNotex(); - - GlobalShaderSystem().setActiveShadersChangedNotify( - ReferenceCaller(g_TextureBrowser)); - - g_TextureBrowser.m_parent = toplevel; - - auto table = ui::Table(3, 3, FALSE); - auto vbox = ui::VBox(FALSE, 0); - table.attach(vbox, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL}); - vbox.show(); - - ui::Widget menu_bar{ui::null}; - - { // menu bar - menu_bar = ui::Widget::from(gtk_menu_bar_new()); - auto menu_view = ui::Menu(ui::New); - auto view_item = TextureBrowser_constructViewMenu(menu_view); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_item), menu_view); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), view_item); - - auto menu_tools = ui::Menu(ui::New); - auto tools_item = TextureBrowser_constructToolsMenu(menu_tools); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(tools_item), menu_tools); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), tools_item); - - table.attach(menu_bar, {0, 3, 0, 1}, {GTK_FILL, GTK_SHRINK}); - menu_bar.show(); - } - { // Texture TreeView - g_TextureBrowser.m_scr_win_tree = ui::ScrolledWindow(ui::New); - gtk_container_set_border_width(GTK_CONTAINER(g_TextureBrowser.m_scr_win_tree), 0); - - // vertical only scrolling for treeview - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tree), GTK_POLICY_NEVER, - GTK_POLICY_ALWAYS); - - g_TextureBrowser.m_scr_win_tree.show(); - - TextureBrowser_createTreeViewTree(); - - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tree), - g_TextureBrowser.m_treeViewTree); - g_TextureBrowser.m_treeViewTree.show(); - } - { // gl_widget scrollbar - auto w = ui::Widget::from(gtk_vscrollbar_new(ui::Adjustment(0, 0, 0, 1, 1, 0))); - table.attach(w, {2, 3, 1, 2}, {GTK_SHRINK, GTK_FILL}); - w.show(); - g_TextureBrowser.m_texture_scroll = w; - - auto vadjustment = ui::Adjustment::from(gtk_range_get_adjustment(GTK_RANGE(g_TextureBrowser.m_texture_scroll))); - vadjustment.connect("value_changed", G_CALLBACK(TextureBrowser_verticalScroll), &g_TextureBrowser); - - g_TextureBrowser.m_texture_scroll.visible(g_TextureBrowser.m_showTextureScrollbar); - } - { // gl_widget - g_TextureBrowser.m_gl_widget = glwidget_new(FALSE); - g_object_ref(g_TextureBrowser.m_gl_widget._handle); - - gtk_widget_set_events(g_TextureBrowser.m_gl_widget, - GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK); - gtk_widget_set_can_focus(g_TextureBrowser.m_gl_widget, true); - - table.attach(g_TextureBrowser.m_gl_widget, {1, 2, 1, 2}); - g_TextureBrowser.m_gl_widget.show(); - - g_TextureBrowser.m_sizeHandler = g_TextureBrowser.m_gl_widget.connect("size_allocate", - G_CALLBACK(TextureBrowser_size_allocate), - &g_TextureBrowser); - g_TextureBrowser.m_exposeHandler = g_TextureBrowser.m_gl_widget.on_render(G_CALLBACK(TextureBrowser_expose), - &g_TextureBrowser); - - g_TextureBrowser.m_gl_widget.connect("button_press_event", G_CALLBACK(TextureBrowser_button_press), - &g_TextureBrowser); - g_TextureBrowser.m_gl_widget.connect("button_release_event", G_CALLBACK(TextureBrowser_button_release), - &g_TextureBrowser); - g_TextureBrowser.m_gl_widget.connect("motion_notify_event", G_CALLBACK(TextureBrowser_motion), - &g_TextureBrowser); - g_TextureBrowser.m_gl_widget.connect("scroll_event", G_CALLBACK(TextureBrowser_scroll), &g_TextureBrowser); - } - - // tag stuff - if (g_TextureBrowser.m_tags) { - { // fill tag GtkListStore - g_TextureBrowser.m_all_tags_list = ui::ListStore::from(gtk_list_store_new(N_COLUMNS, G_TYPE_STRING)); - auto sortable = GTK_TREE_SORTABLE(g_TextureBrowser.m_all_tags_list); - gtk_tree_sortable_set_sort_column_id(sortable, TAG_COLUMN, GTK_SORT_ASCENDING); - - TagBuilder.GetAllTags(g_TextureBrowser.m_all_tags); - TextureBrowser_buildTagList(); - } - { // tag menu bar - auto menu_tags = ui::Menu(ui::New); - auto tags_item = TextureBrowser_constructTagsMenu(menu_tags); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(tags_item), menu_tags); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), tags_item); - } - { // Tag TreeView - g_TextureBrowser.m_scr_win_tags = ui::ScrolledWindow(ui::New); - gtk_container_set_border_width(GTK_CONTAINER(g_TextureBrowser.m_scr_win_tags), 0); - - // vertical only scrolling for treeview - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tags), GTK_POLICY_NEVER, - GTK_POLICY_ALWAYS); - - TextureBrowser_createTreeViewTags(); - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(g_TextureBrowser.m_scr_win_tags), - g_TextureBrowser.m_treeViewTags); - g_TextureBrowser.m_treeViewTags.show(); - } - { // Texture/Tag notebook - TextureBrowser_constructTagNotebook(); - vbox.pack_start(g_TextureBrowser.m_tag_notebook, TRUE, TRUE, 0); - } - { // Tag search button - TextureBrowser_constructSearchButton(); - vbox.pack_end(g_TextureBrowser.m_search_button, FALSE, FALSE, 0); - } - auto frame_table = ui::Table(3, 3, FALSE); - { // Tag frame - - g_TextureBrowser.m_tag_frame = ui::Frame("Tag assignment"); - gtk_frame_set_label_align(GTK_FRAME(g_TextureBrowser.m_tag_frame), 0.5, 0.5); - gtk_frame_set_shadow_type(GTK_FRAME(g_TextureBrowser.m_tag_frame), GTK_SHADOW_NONE); - - table.attach(g_TextureBrowser.m_tag_frame, {1, 3, 2, 3}, {GTK_FILL, GTK_SHRINK}); - - frame_table.show(); - - g_TextureBrowser.m_tag_frame.add(frame_table); - } - { // assigned tag list - ui::Widget scrolled_win = ui::ScrolledWindow(ui::New); - gtk_container_set_border_width(GTK_CONTAINER(scrolled_win), 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - - g_TextureBrowser.m_assigned_store = ui::ListStore::from(gtk_list_store_new(N_COLUMNS, G_TYPE_STRING)); - - auto sortable = GTK_TREE_SORTABLE(g_TextureBrowser.m_assigned_store); - gtk_tree_sortable_set_sort_column_id(sortable, TAG_COLUMN, GTK_SORT_ASCENDING); - - auto renderer = ui::CellRendererText(ui::New); - - g_TextureBrowser.m_assigned_tree = ui::TreeView( - ui::TreeModel::from(g_TextureBrowser.m_assigned_store._handle)); - g_TextureBrowser.m_assigned_store.unref(); - g_TextureBrowser.m_assigned_tree.connect("row-activated", (GCallback) TextureBrowser_removeTags, NULL); - gtk_tree_view_set_headers_visible(g_TextureBrowser.m_assigned_tree, FALSE); - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_assigned_tree); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - - auto column = ui::TreeViewColumn("", renderer, {{"text", TAG_COLUMN}}); - gtk_tree_view_append_column(g_TextureBrowser.m_assigned_tree, column); - g_TextureBrowser.m_assigned_tree.show(); - - scrolled_win.show(); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), g_TextureBrowser.m_assigned_tree); - - frame_table.attach(scrolled_win, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL}); - } - { // available tag list - ui::Widget scrolled_win = ui::ScrolledWindow(ui::New); - gtk_container_set_border_width(GTK_CONTAINER(scrolled_win), 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - - g_TextureBrowser.m_available_store = ui::ListStore::from(gtk_list_store_new(N_COLUMNS, G_TYPE_STRING)); - auto sortable = GTK_TREE_SORTABLE(g_TextureBrowser.m_available_store); - gtk_tree_sortable_set_sort_column_id(sortable, TAG_COLUMN, GTK_SORT_ASCENDING); - - auto renderer = ui::CellRendererText(ui::New); - - g_TextureBrowser.m_available_tree = ui::TreeView( - ui::TreeModel::from(g_TextureBrowser.m_available_store._handle)); - g_TextureBrowser.m_available_store.unref(); - g_TextureBrowser.m_available_tree.connect("row-activated", (GCallback) TextureBrowser_assignTags, NULL); - gtk_tree_view_set_headers_visible(g_TextureBrowser.m_available_tree, FALSE); - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - - auto column = ui::TreeViewColumn("", renderer, {{"text", TAG_COLUMN}}); - gtk_tree_view_append_column(g_TextureBrowser.m_available_tree, column); - g_TextureBrowser.m_available_tree.show(); - - scrolled_win.show(); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), g_TextureBrowser.m_available_tree); - - frame_table.attach(scrolled_win, {2, 3, 1, 3}, {GTK_FILL, GTK_FILL}); - } - { // tag arrow buttons - auto m_btn_left = ui::Button(ui::New); - auto m_btn_right = ui::Button(ui::New); - auto m_arrow_left = ui::Widget::from(gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_OUT)); - auto m_arrow_right = ui::Widget::from(gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT)); - m_btn_left.add(m_arrow_left); - m_btn_right.add(m_arrow_right); - - // workaround. the size of the tag frame depends of the requested size of the arrow buttons. - m_arrow_left.dimensions(-1, 68); - m_arrow_right.dimensions(-1, 68); - - frame_table.attach(m_btn_left, {1, 2, 1, 2}, {GTK_SHRINK, GTK_EXPAND}); - frame_table.attach(m_btn_right, {1, 2, 2, 3}, {GTK_SHRINK, GTK_EXPAND}); - - m_btn_left.connect("clicked", G_CALLBACK(TextureBrowser_assignTags), NULL); - m_btn_right.connect("clicked", G_CALLBACK(TextureBrowser_removeTags), NULL); - - m_btn_left.show(); - m_btn_right.show(); - m_arrow_left.show(); - m_arrow_right.show(); - } - { // tag fram labels - ui::Widget m_lbl_assigned = ui::Label("Assigned"); - ui::Widget m_lbl_unassigned = ui::Label("Available"); - - frame_table.attach(m_lbl_assigned, {0, 1, 0, 1}, {GTK_EXPAND, GTK_SHRINK}); - frame_table.attach(m_lbl_unassigned, {2, 3, 0, 1}, {GTK_EXPAND, GTK_SHRINK}); - - m_lbl_assigned.show(); - m_lbl_unassigned.show(); - } - } else { // no tag support, show the texture tree only - vbox.pack_start(g_TextureBrowser.m_scr_win_tree, TRUE, TRUE, 0); - } - - // TODO do we need this? - //gtk_container_set_focus_chain(GTK_CONTAINER(hbox_table), NULL); - - return table; -} - -void TextureBrowser_destroyWindow() -{ - GlobalShaderSystem().setActiveShadersChangedNotify(Callback()); - - g_signal_handler_disconnect(G_OBJECT(g_TextureBrowser.m_gl_widget), g_TextureBrowser.m_sizeHandler); - g_signal_handler_disconnect(G_OBJECT(g_TextureBrowser.m_gl_widget), g_TextureBrowser.m_exposeHandler); - - g_TextureBrowser.m_gl_widget.unref(); -} - -const Vector3 &TextureBrowser_getBackgroundColour(TextureBrowser &textureBrowser) -{ - return textureBrowser.color_textureback; -} - -void TextureBrowser_setBackgroundColour(TextureBrowser &textureBrowser, const Vector3 &colour) -{ - textureBrowser.color_textureback = colour; - TextureBrowser_queueDraw(textureBrowser); -} - -void TextureBrowser_selectionHelper(ui::TreeModel model, ui::TreePath path, GtkTreeIter *iter, GSList **selected) -{ - g_assert(selected != NULL); - - gchar *name; - gtk_tree_model_get(model, iter, TAG_COLUMN, &name, -1); - *selected = g_slist_append(*selected, name); -} - -void TextureBrowser_shaderInfo() -{ - const char *name = TextureBrowser_GetSelectedShader(g_TextureBrowser); - IShader *shader = QERApp_Shader_ForName(name); - - DoShaderInfoDlg(name, shader->getShaderFileName(), "Shader Info"); - - shader->DecRef(); -} - -void TextureBrowser_addTag() -{ - CopiedString tag; - - EMessageBoxReturn result = DoShaderTagDlg(&tag, "Add shader tag"); - - if (result == eIDOK && !tag.empty()) { - GtkTreeIter iter; - g_TextureBrowser.m_all_tags.insert(tag.c_str()); - gtk_list_store_append(g_TextureBrowser.m_available_store, &iter); - gtk_list_store_set(g_TextureBrowser.m_available_store, &iter, TAG_COLUMN, tag.c_str(), -1); - - // Select the currently added tag in the available list - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree); - gtk_tree_selection_select_iter(selection, &iter); - - g_TextureBrowser.m_all_tags_list.append(TAG_COLUMN, tag.c_str()); - } -} - -void TextureBrowser_renameTag() -{ - /* WORKAROUND: The tag treeview is set to GTK_SELECTION_MULTIPLE. Because - gtk_tree_selection_get_selected() doesn't work with GTK_SELECTION_MULTIPLE, - we need to count the number of selected rows first and use - gtk_tree_selection_selected_foreach() then to go through the list of selected - rows (which always containins a single row). - */ - - GSList *selected = NULL; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags); - gtk_tree_selection_selected_foreach(selection, GtkTreeSelectionForeachFunc(TextureBrowser_selectionHelper), - &selected); - - if (g_slist_length(selected) == 1) { // we only rename a single tag - CopiedString newTag; - EMessageBoxReturn result = DoShaderTagDlg(&newTag, "Rename shader tag"); - - if (result == eIDOK && !newTag.empty()) { - GtkTreeIter iterList; - gchar *rowTag; - gchar *oldTag = (char *) selected->data; - - bool row = gtk_tree_model_get_iter_first(g_TextureBrowser.m_all_tags_list, &iterList) != 0; - - while (row) { - gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, &rowTag, -1); - - if (strcmp(rowTag, oldTag) == 0) { - gtk_list_store_set(g_TextureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, newTag.c_str(), -1); - } - row = gtk_tree_model_iter_next(g_TextureBrowser.m_all_tags_list, &iterList) != 0; - } - - TagBuilder.RenameShaderTag(oldTag, newTag.c_str()); - - g_TextureBrowser.m_all_tags.erase((CopiedString) oldTag); - g_TextureBrowser.m_all_tags.insert(newTag); - - BuildStoreAssignedTags(g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), - &g_TextureBrowser); - BuildStoreAvailableTags(g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, - g_TextureBrowser.m_all_tags, &g_TextureBrowser); - } - } else { - ui::alert(g_TextureBrowser.m_parent, "Select a single tag for renaming."); - } -} - -void TextureBrowser_deleteTag() -{ - GSList *selected = NULL; - - auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags); - gtk_tree_selection_selected_foreach(selection, GtkTreeSelectionForeachFunc(TextureBrowser_selectionHelper), - &selected); - - if (g_slist_length(selected) == 1) { // we only delete a single tag - auto result = ui::alert(g_TextureBrowser.m_parent, "Are you sure you want to delete the selected tag?", - "Delete Tag", ui::alert_type::YESNO, ui::alert_icon::Question); - - if (result == ui::alert_response::YES) { - GtkTreeIter iterSelected; - gchar *rowTag; - - gchar *tagSelected = (char *) selected->data; - - bool row = gtk_tree_model_get_iter_first(g_TextureBrowser.m_all_tags_list, &iterSelected) != 0; - - while (row) { - gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iterSelected, TAG_COLUMN, &rowTag, -1); - - if (strcmp(rowTag, tagSelected) == 0) { - gtk_list_store_remove(g_TextureBrowser.m_all_tags_list, &iterSelected); - break; - } - row = gtk_tree_model_iter_next(g_TextureBrowser.m_all_tags_list, &iterSelected) != 0; - } - - TagBuilder.DeleteTag(tagSelected); - g_TextureBrowser.m_all_tags.erase((CopiedString) tagSelected); - - BuildStoreAssignedTags(g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), - &g_TextureBrowser); - BuildStoreAvailableTags(g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, - g_TextureBrowser.m_all_tags, &g_TextureBrowser); - } - } else { - ui::alert(g_TextureBrowser.m_parent, "Select a single tag for deletion."); - } -} - -void TextureBrowser_copyTag() -{ - g_TextureBrowser.m_copied_tags.clear(); - TagBuilder.GetShaderTags(g_TextureBrowser.shader.c_str(), g_TextureBrowser.m_copied_tags); -} - -void TextureBrowser_pasteTag() -{ - IShader *ishader = QERApp_Shader_ForName(g_TextureBrowser.shader.c_str()); - CopiedString shader = g_TextureBrowser.shader.c_str(); - - if (!TagBuilder.CheckShaderTag(shader.c_str())) { - CopiedString shaderFile = ishader->getShaderFileName(); - if (shaderFile.empty()) { - // it's a texture - TagBuilder.AddShaderNode(shader.c_str(), CUSTOM, TEXTURE); - } else { - // it's a shader - TagBuilder.AddShaderNode(shader.c_str(), CUSTOM, SHADER); - } - - for (size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i) { - TagBuilder.AddShaderTag(shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG); - } - } else { - for (size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i) { - if (!TagBuilder.CheckShaderTag(shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str())) { - // the tag doesn't exist - let's add it - TagBuilder.AddShaderTag(shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG); - } - } - } - - ishader->DecRef(); - - TagBuilder.SaveXmlDoc(); - BuildStoreAssignedTags(g_TextureBrowser.m_assigned_store, shader.c_str(), &g_TextureBrowser); - BuildStoreAvailableTags(g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, - g_TextureBrowser.m_all_tags, &g_TextureBrowser); -} - -void TextureBrowser_RefreshShaders() -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Shaders"); - GlobalShaderSystem().refresh(); - UpdateAllWindows(); - auto selection = gtk_tree_view_get_selection(GlobalTextureBrowser().m_treeViewTree); - GtkTreeModel *model = NULL; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - gchar dirName[1024]; - - gchar *buffer; - gtk_tree_model_get(model, &iter, 0, &buffer, -1); - strcpy(dirName, buffer); - g_free(buffer); - if (!TextureBrowser_showWads()) { - strcat(dirName, "/"); - } - TextureBrowser_ShowDirectory(GlobalTextureBrowser(), dirName); - TextureBrowser_queueDraw(GlobalTextureBrowser()); - } -} - -void TextureBrowser_ToggleShowShaders() -{ - g_TextureBrowser.m_showShaders ^= 1; - g_TextureBrowser.m_showshaders_item.update(); - TextureBrowser_queueDraw(g_TextureBrowser); -} - -void TextureBrowser_ToggleShowShaderListOnly() -{ - g_TextureBrowser_shaderlistOnly ^= 1; - g_TextureBrowser.m_showshaderlistonly_item.update(); - - TextureBrowser_constructTreeStore(); -} - -void TextureBrowser_showAll() -{ - g_TextureBrowser_currentDirectory = ""; - g_TextureBrowser.m_searchedTags = false; - TextureBrowser_heightChanged(g_TextureBrowser); - TextureBrowser_updateTitle(); -} - -void TextureBrowser_showUntagged() -{ - auto result = ui::alert(g_TextureBrowser.m_parent, - "WARNING! This function might need a lot of memory and time. Are you sure you want to use it?", - "Show Untagged", ui::alert_type::YESNO, ui::alert_icon::Warning); - - if (result == ui::alert_response::YES) { - g_TextureBrowser.m_found_shaders.clear(); - TagBuilder.GetUntagged(g_TextureBrowser.m_found_shaders); - std::set::iterator iter; - - ScopeDisableScreenUpdates disableScreenUpdates("Searching untagged textures...", "Loading Textures"); - - for (iter = g_TextureBrowser.m_found_shaders.begin(); iter != g_TextureBrowser.m_found_shaders.end(); iter++) { - std::string path = (*iter).c_str(); - size_t pos = path.find_last_of("/", path.size()); - std::string name = path.substr(pos + 1, path.size()); - path = path.substr(0, pos + 1); - TextureDirectory_loadTexture(path.c_str(), name.c_str()); - globalErrorStream() << path.c_str() << name.c_str() << "\n"; - } - - g_TextureBrowser_currentDirectory = "Untagged"; - TextureBrowser_queueDraw(GlobalTextureBrowser()); - TextureBrowser_heightChanged(g_TextureBrowser); - TextureBrowser_updateTitle(); - } -} - -void TextureBrowser_FixedSize() -{ - g_TextureBrowser_fixedSize ^= 1; - GlobalTextureBrowser().m_fixedsize_item.update(); - TextureBrowser_activeShadersChanged(GlobalTextureBrowser()); -} - -void TextureBrowser_FilterMissing() -{ - g_TextureBrowser_filterMissing ^= 1; - GlobalTextureBrowser().m_filternotex_item.update(); - TextureBrowser_activeShadersChanged(GlobalTextureBrowser()); - TextureBrowser_RefreshShaders(); -} - -void TextureBrowser_FilterFallback() -{ - g_TextureBrowser_filterFallback ^= 1; - GlobalTextureBrowser().m_hidenotex_item.update(); - TextureBrowser_activeShadersChanged(GlobalTextureBrowser()); - TextureBrowser_RefreshShaders(); -} - -void TextureBrowser_EnableAlpha() -{ - g_TextureBrowser_enableAlpha ^= 1; - GlobalTextureBrowser().m_enablealpha_item.update(); - TextureBrowser_activeShadersChanged(GlobalTextureBrowser()); -} - -void TextureBrowser_exportTitle(const Callback &importer) -{ - StringOutputStream buffer(64); - buffer << "Textures: "; - if (!string_empty(g_TextureBrowser_currentDirectory.c_str())) { - buffer << g_TextureBrowser_currentDirectory.c_str(); - } else { - buffer << "all"; - } - importer(buffer.c_str()); -} - -struct TextureScale { - static void Export(const TextureBrowser &self, const Callback &returnz) - { - switch (self.m_textureScale) { - case 10: - returnz(0); - break; - case 25: - returnz(1); - break; - case 50: - returnz(2); - break; - case 100: - returnz(3); - break; - case 200: - returnz(4); - break; - } - } - - static void Import(TextureBrowser &self, int value) - { - switch (value) { - case 0: - TextureBrowser_setScale(self, 10); - break; - case 1: - TextureBrowser_setScale(self, 25); - break; - case 2: - TextureBrowser_setScale(self, 50); - break; - case 3: - TextureBrowser_setScale(self, 100); - break; - case 4: - TextureBrowser_setScale(self, 200); - break; - } - } -}; - -struct UniformTextureSize { - static void Export(const TextureBrowser &self, const Callback &returnz) - { - returnz(g_TextureBrowser.m_uniformTextureSize); - } - - static void Import(TextureBrowser &self, int value) - { - if (value > 16) { - TextureBrowser_setUniformSize(self, value); - } - } -}; - -void TextureBrowser_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox( - "", "Texture scrollbar", - make_property(GlobalTextureBrowser()) - ); - { - const char *texture_scale[] = {"10%", "25%", "50%", "100%", "200%"}; - page.appendCombo( - "Texture Thumbnail Scale", - STRING_ARRAY_RANGE(texture_scale), - make_property(GlobalTextureBrowser()) - ); - } - page.appendSpinner( - "Texture Thumbnail Size", - GlobalTextureBrowser().m_uniformTextureSize, - GlobalTextureBrowser().m_uniformTextureSize, - 16, 8192 - ); - page.appendEntry("Mousewheel Increment", GlobalTextureBrowser().m_mouseWheelScrollIncrement); - { - const char *startup_shaders[] = {"None", TextureBrowser_getComonShadersName()}; - page.appendCombo("Load Shaders at Startup", reinterpret_cast( GlobalTextureBrowser().m_startupShaders ), - STRING_ARRAY_RANGE(startup_shaders)); - } -} - -void TextureBrowser_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Texture Browser", "Texture Browser Preferences")); - TextureBrowser_constructPreferences(page); -} - -void TextureBrowser_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(TextureBrowser_constructPage)); -} - - -#include "preferencesystem.h" -#include "stringio.h" - - -void TextureClipboard_textureSelected(const char *shader); - -void TextureBrowser_Construct() -{ - GlobalCommands_insert("ShaderInfo", makeCallbackF(TextureBrowser_shaderInfo)); - GlobalCommands_insert("ShowUntagged", makeCallbackF(TextureBrowser_showUntagged)); - GlobalCommands_insert("AddTag", makeCallbackF(TextureBrowser_addTag)); - GlobalCommands_insert("RenameTag", makeCallbackF(TextureBrowser_renameTag)); - GlobalCommands_insert("DeleteTag", makeCallbackF(TextureBrowser_deleteTag)); - GlobalCommands_insert("CopyTag", makeCallbackF(TextureBrowser_copyTag)); - GlobalCommands_insert("PasteTag", makeCallbackF(TextureBrowser_pasteTag)); - GlobalCommands_insert("RefreshShaders", makeCallbackF(VFS_Refresh)); - GlobalToggles_insert("ShowInUse", makeCallbackF(TextureBrowser_ToggleHideUnused), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_hideunused_item), Accelerator('U')); - GlobalCommands_insert("ShowAllTextures", makeCallbackF(TextureBrowser_showAll), - Accelerator('A', (GdkModifierType) GDK_CONTROL_MASK)); - GlobalCommands_insert("ToggleTextures", makeCallbackF(TextureBrowser_toggleShow), Accelerator('T')); - GlobalToggles_insert("ToggleShowShaders", makeCallbackF(TextureBrowser_ToggleShowShaders), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_showshaders_item)); - GlobalToggles_insert("ToggleShowShaderlistOnly", makeCallbackF(TextureBrowser_ToggleShowShaderListOnly), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_showshaderlistonly_item)); - GlobalToggles_insert("FixedSize", makeCallbackF(TextureBrowser_FixedSize), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_fixedsize_item)); - GlobalToggles_insert("FilterMissing", makeCallbackF(TextureBrowser_FilterMissing), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_filternotex_item)); - GlobalToggles_insert("FilterFallback", makeCallbackF(TextureBrowser_FilterFallback), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_hidenotex_item)); - GlobalToggles_insert("EnableAlpha", makeCallbackF(TextureBrowser_EnableAlpha), - ToggleItem::AddCallbackCaller(g_TextureBrowser.m_enablealpha_item)); - - GlobalPreferenceSystem().registerPreference("TextureScale", make_property_string(g_TextureBrowser)); - GlobalPreferenceSystem().registerPreference("UniformTextureSize", - make_property_string(g_TextureBrowser)); - GlobalPreferenceSystem().registerPreference("TextureScrollbar", make_property_string( - GlobalTextureBrowser())); - GlobalPreferenceSystem().registerPreference("ShowShaders", - make_property_string(GlobalTextureBrowser().m_showShaders)); - GlobalPreferenceSystem().registerPreference("ShowShaderlistOnly", - make_property_string(g_TextureBrowser_shaderlistOnly)); - GlobalPreferenceSystem().registerPreference("FixedSize", make_property_string(g_TextureBrowser_fixedSize)); - GlobalPreferenceSystem().registerPreference("FilterMissing", make_property_string(g_TextureBrowser_filterMissing)); - GlobalPreferenceSystem().registerPreference("EnableAlpha", make_property_string(g_TextureBrowser_enableAlpha)); - GlobalPreferenceSystem().registerPreference("LoadShaders", make_property_string( - reinterpret_cast( GlobalTextureBrowser().m_startupShaders ))); - GlobalPreferenceSystem().registerPreference("WheelMouseInc", make_property_string( - GlobalTextureBrowser().m_mouseWheelScrollIncrement)); - GlobalPreferenceSystem().registerPreference("SI_Colors0", - make_property_string(GlobalTextureBrowser().color_textureback)); - - g_TextureBrowser.shader = texdef_name_default(); - - Textures_setModeChangedNotify(ReferenceCaller(g_TextureBrowser)); - - TextureBrowser_registerPreferencesPage(); - - GlobalShaderSystem().attach(g_ShadersObserver); - - TextureBrowser_textureSelected = TextureClipboard_textureSelected; -} - -void TextureBrowser_Destroy() -{ - GlobalShaderSystem().detach(g_ShadersObserver); - - Textures_setModeChangedNotify(Callback()); -} diff --git a/src/texwindow.h b/src/texwindow.h deleted file mode 100644 index 64decd7..0000000 --- a/src/texwindow.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TEXWINDOW_H ) -#define INCLUDED_TEXWINDOW_H - -#include -#include "property.h" -#include "math/vector.h" -#include "generic/callback.h" -#include "signal/signalfwd.h" -#include "xml/xmltextags.h" - -class TextureBrowser; - -TextureBrowser &GlobalTextureBrowser(); - -ui::Widget TextureBrowser_constructWindow(ui::Window toplevel); - -void TextureBrowser_destroyWindow(); - - -void TextureBrowser_ShowDirectory(TextureBrowser &textureBrowser, const char *name); - -void TextureBrowser_ShowStartupShaders(TextureBrowser &textureBrowser); - -const char *TextureBrowser_GetSelectedShader(TextureBrowser &textureBrower); - -void TextureBrowser_Construct(); - -void TextureBrowser_Destroy(); - -extern ui::Widget g_page_textures; - -void TextureBrowser_exportTitle(const Callback &importer); - -typedef FreeCaller &), TextureBrowser_exportTitle> TextureBrowserExportTitleCaller; - -const Vector3 &TextureBrowser_getBackgroundColour(TextureBrowser &textureBrowser); - -void TextureBrowser_setBackgroundColour(TextureBrowser &textureBrowser, const Vector3 &colour); - -void TextureBrowser_addActiveShadersChangedCallback(const SignalHandler &handler); - -void TextureBrowser_addShadersRealiseCallback(const SignalHandler &handler); - -void TextureBrowser_RefreshShaders(); - -#endif diff --git a/src/timer.cpp b/src/timer.cpp deleted file mode 100644 index 3971ec6..0000000 --- a/src/timer.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "timer.h" -#include "globaldefs.h" - - -#if GDEF_OS_WINDOWS - -#include - -MillisecondTime MillisecondTime::current(){ - static class Cached - { - LONGLONG m_frequency; - LONGLONG m_base; -public: - Cached(){ - QueryPerformanceFrequency( (LARGE_INTEGER *) &m_frequency ); - QueryPerformanceCounter( (LARGE_INTEGER *) &m_base ); - } - LONGLONG frequency(){ - return m_frequency; - } - LONGLONG base(){ - return m_base; - } - } cached; - - if ( cached.frequency() > 0 ) { - LONGLONG count; - QueryPerformanceCounter( (LARGE_INTEGER *) &count ); - return time_from_ticks( count - cached.base(), cached.frequency() ); - } - else - { -#if 1 - return MillisecondTime(); -#else - return time_from_ticks( timeGetTime(), 1000 ); -#endif - } -} - - - - -#elif GDEF_OS_POSIX - -#include -#include "sys/time.h" - -MillisecondTime MillisecondTime::current() -{ - static class Cached { - time_t m_base; -public: - Cached() - { - time(&m_base); - } - - time_t base() - { - return m_base; - } - } cached; - - timeval time; - gettimeofday(&time, 0); - return MillisecondTime((time.tv_sec - cached.base()) * 1000 + time.tv_usec / 1000); -} - - -#else - -#include - -MillisecondTime MillisecondTime::current(){ - return time_from_ticks( std::clock(), CLOCKS_PER_SEC ); -} - - - -#endif diff --git a/src/timer.h b/src/timer.h deleted file mode 100644 index 3b31405..0000000 --- a/src/timer.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined ( INCLUDED_TIMER_H ) -#define INCLUDED_TIMER_H - -#if 1 - -const int msec_per_sec = 1000; - -class MillisecondTime { -unsigned int m_milliseconds; -public: -MillisecondTime(unsigned int milliseconds) - : m_milliseconds(milliseconds) -{ -} - -MillisecondTime() -{ -} - -static MillisecondTime current(); - -unsigned int milliseconds_since(const MillisecondTime &other) const -{ - return m_milliseconds - other.m_milliseconds; -} -}; - -template -inline MillisecondTime time_from_ticks(tick_type tick_count, tick_type ticks_per_sec) -{ - return MillisecondTime( - static_cast( tick_count / static_cast( ticks_per_sec / msec_per_sec ))); -} - -#else - -const unsigned int usec_per_sec = 1000000; - -class MillisecondTime -{ -unsigned int m_sec; -unsigned int m_usec; -public: -MillisecondTime( unsigned int sec, unsigned int usec ) - : m_sec( sec ), m_usec( usec ){ -} -MillisecondTime(){ -} -staticMillisecondTime current(); - -unsigned int milliseconds_since( const MillisecondTime& other ) const { - return static_cast( ( m_sec * static_cast( usec_per_sec ) + m_usec ) - - ( other.m_sec * static_cast( usec_per_sec ) + other.m_usec ) ) / 1000; -} -}; - -template -inline MillisecondTime time_from_ticks( tick_type tick_count, tick_type ticks_per_sec ){ - return MillisecondTime( static_cast( tick_count / ticks_per_sec ), - static_cast( ( tick_count % ticks_per_sec ) * ( usec_per_sec / static_cast( ticks_per_sec ) ) ) ); -} - -#endif - -class Timer { -MillisecondTime m_start; - -public: -void start() -{ - m_start = MillisecondTime::current(); -} - -unsigned int elapsed_msec() -{ - return MillisecondTime::current().milliseconds_since(m_start); -} -}; - -#endif diff --git a/tools/vmap/tjunction.c b/src/tjunction.c similarity index 100% rename from tools/vmap/tjunction.c rename to src/tjunction.c diff --git a/tools/vmap/tree.c b/src/tree.c similarity index 100% rename from tools/vmap/tree.c rename to src/tree.c diff --git a/src/treemodel.cpp b/src/treemodel.cpp deleted file mode 100644 index 414a201..0000000 --- a/src/treemodel.cpp +++ /dev/null @@ -1,1488 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "treemodel.h" -#include "globaldefs.h" - -#include "debugging/debugging.h" - -#include -#include -#include - -#include "iscenegraph.h" -#include "nameable.h" - -#include "generic/callback.h" -#include "scenelib.h" -#include "string/string.h" -#include "generic/reference.h" - -inline Nameable *Node_getNameable(scene::Node &node) -{ - return NodeTypeCast::cast(node); -} - -#if 0 - -#include "gtkutil/gtktreestore.h" - -template -inline void gtk_tree_model_get_pointer( ui::TreeModel model, GtkTreeIter* iter, gint column, value_type** pointer ){ - GValue value = GValue_default(); - gtk_tree_model_get_value( model, iter, column, &value ); - *pointer = (value_type*)g_value_get_pointer( &value ); -} - - -typedef GtkTreeStore GraphTreeModel; - -ui::TreeStore graph_tree_model_new( graph_type* graph ){ - return gtk_tree_store_new( 2, G_TYPE_POINTER, G_TYPE_POINTER ); -} - -void graph_tree_model_delete( GraphTreeModel* model ){ - g_object_unref( G_OBJECT( model ) ); -} - - -bool graph_tree_model_subtree_find_node( GraphTreeModel* model, GtkTreeIter* parent, const scene::Node& node, GtkTreeIter* iter ){ - for ( gboolean success = gtk_tree_model_iter_children( model, iter, parent ); - success != FALSE; - success = gtk_tree_model_iter_next( model, iter ) ) - { - scene::Node* current; - gtk_tree_model_get_pointer( model, iter, 0, ¤t ); - if ( current == node ) { - return true; - } - } - return false; -} - -typedef GtkTreeIter DoubleGtkTreeIter[2]; - -bool graph_tree_model_find_top( GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter ){ - int swap = 0; - GtkTreeIter* parent_pointer = NULL; - GtkTreeIter parent; - for ( scene::Path::const_iterator i = path.begin(); i != path.end(); ++i ) - { - if ( !graph_tree_model_subtree_find_node( model, parent_pointer, *i, &iter ) ) { - return false; - } - parent = iter; - parent_pointer = &parent; - } - return true; -} - -bool graph_tree_model_find_parent( GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter ){ - int swap = 0; - GtkTreeIter* parent_pointer = NULL; - ASSERT_MESSAGE( path.size() > 1, "path too short" ); - for ( scene::Path::const_iterator i = path.begin(); i != path.end() - 1; ++i ) - { - GtkTreeIter child; - if ( !graph_tree_model_subtree_find_node( model, parent_pointer, *i, &child ) ) { - return false; - } - iter = child; - parent_pointer = &iter; - } - return true; -} - -void node_attach_name_changed_callback( scene::Node& node, const Callback& callback ){ - if ( node != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->attach( callback ); - } - } -} -void node_detach_name_changed_callback( scene::Node& node, const Callback& callback ){ - if ( node != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->detach( callback ); - } - } -} - -GraphTreeModel* scene_graph_get_tree_model(); // temp hack - -void graph_tree_model_row_changed( const scene::Instance& instance ){ - GraphTreeModel* model = scene_graph_get_tree_model(); - - GtkTreeIter child; - ASSERT_MESSAGE( graph_tree_model_find_top( model, instance.path(), child ), "RUNTIME ERROR" ); - - gtk_tree_store_set( GTK_TREE_STORE( model ), &child, 0, instance.path().top(), -1 ); -} - -void graph_tree_model_row_inserted( GraphTreeModel* model, const scene::Instance& instance ){ - GtkTreeIter parent; - GtkTreeIter* parent_pointer = NULL; - if ( instance.path().size() != 1 ) { - ASSERT_MESSAGE( graph_tree_model_find_parent( model, instance.path(), parent ), "RUNTIME ERROR" ); - parent_pointer = &parent; - } - - gpointer node = instance.path().top(); - gconstpointer selectable = Instance_getSelectable( instance ); - - GtkTreeIter child; - gtk_tree_store_append( GTK_TREE_STORE( model ), &child, parent_pointer ); - gtk_tree_store_set( GTK_TREE_STORE( model ), &child, 0, node, 1, selectable, -1 ); - - node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); -} - -void graph_tree_model_row_deleted( GraphTreeModel* model, const scene::Instance& instance ){ - GtkTreeIter child; - ASSERT_MESSAGE( graph_tree_model_find_top( model, instance.path(), child ), "RUNTIME ERROR" ); - - node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); - - gtk_tree_store_remove( GTK_TREE_STORE( model ), &child ); -} - -#elif 0 - -const char* node_get_name( scene::Node& node ); - -typedef scene::Node* NodePointer; - -class NodeNameLess -{ -public: -bool operator()( const NodePointer& self, const NodePointer& other ) const { - if ( self == 0 ) { - return true; - } - if ( other == 0 ) { - return false; - } - int result = string_compare( node_get_name( self ), node_get_name( other ) ); - if ( result == 0 ) { - return self < other; - } - return result < 0; -} -}; - -class PathNameLess -{ -public: -bool operator()( const PathConstReference& self, const PathConstReference& other ) const { - return std::lexicographical_compare( self.get().begin(), self.get().end(), other.get().begin(), other.get().end(), NodeNameLess() ); -} -}; - -typedef std::map graph_type; - -struct GraphTreeModel -{ - GObject parent; - - graph_type* graph; -}; - -struct GraphTreeModelClass -{ - GObjectClass parent_class; -}; - -#define GRAPH_TREE_MODEL( p ) ( reinterpret_cast( p ) ) - -static GtkTreeModelFlags graph_tree_model_get_flags( GtkTreeModel* tree_model ){ - return GTK_TREE_MODEL_ITERS_PERSIST; -} - -static gint graph_tree_model_get_n_columns( ui::TreeModel tree_model ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model; - - return 2; -} - -static const gint c_stamp = 0xabcdef; - -inline graph_type::iterator graph_iterator_read_tree_iter( GtkTreeIter* iter ){ - ASSERT_MESSAGE( iter != 0, "tree model error" ); - ASSERT_MESSAGE( iter->user_data != 0, "tree model error" ); - ASSERT_MESSAGE( iter->stamp == c_stamp, "tree model error" ); - return *reinterpret_cast( &iter->user_data ); -} - -inline void graph_iterator_write_tree_iter( graph_type::iterator i, GtkTreeIter* iter ){ - ASSERT_MESSAGE( iter != 0, "tree model error" ); - iter->stamp = c_stamp; - *reinterpret_cast( &iter->user_data ) = i; - ASSERT_MESSAGE( iter->user_data != 0, "tree model error" ); -} - -static GType graph_tree_model_get_column_type( ui::TreeModel tree_model, gint index ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model; - - return G_TYPE_POINTER; -} - -static gboolean graph_tree_model_get_iter( ui::TreeModel tree_model, GtkTreeIter* iter, ui::TreePath path ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - gint* indices = gtk_tree_path_get_indices( path ); - gint depth = gtk_tree_path_get_depth( path ); - - g_return_val_if_fail( depth > 0, FALSE ); - - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - - if ( graph.empty() ) { - return FALSE; - } - - GtkTreeIter tmp; - GtkTreeIter* parent = 0; - - for ( gint i = 0; i < depth; i++ ) - { - if ( !gtk_tree_model_iter_nth_child( tree_model, iter, parent, indices[i] ) ) { - return FALSE; - } - tmp = *iter; - parent = &tmp; - } - - return TRUE; -} - -static ui::TreePath graph_tree_model_get_path( ui::TreeModel tree_model, GtkTreeIter* iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - - auto path = ui::TreePath(); - - for ( std::size_t depth = ( *i ).first.get().size(); depth != 0; --depth ) - { - std::size_t index = 0; - - while ( i != graph.begin() && ( *i ).first.get().size() >= depth ) - { - --i; - if ( ( *i ).first.get().size() == depth ) { - ++index; - } - } - - gtk_tree_path_prepend_index( path, index ); - } - - return path; -} - - -static void graph_tree_model_get_value( ui::TreeModel tree_model, GtkTreeIter *iter, gint column, GValue *value ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - ASSERT_MESSAGE( column == 0 || column == 1, "tree model error" ); - - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - - g_value_init( value, G_TYPE_POINTER ); - - if ( column == 0 ) { - g_value_set_pointer( value, reinterpret_cast( ( *i ).first.get().top() ) ); - } - else{ - g_value_set_pointer( value, reinterpret_cast( Instance_getSelectable( *( *i ).second ) ) ); - } -} - -static gboolean graph_tree_model_iter_next( ui::TreeModel tree_model, GtkTreeIter *iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - std::size_t depth = ( *i ).first.get().size(); - - ++i; - - while ( i != graph.end() && ( *i ).first.get().size() > depth ) - { - ++i; - } - - if ( i == graph.end() || ( *i ).first.get().size() != depth ) { - return FALSE; - } - - graph_iterator_write_tree_iter( i, iter ); - - return TRUE; -} - -static gboolean graph_tree_model_iter_children( ui::TreeModel tree_model, GtkTreeIter *iter, GtkTreeIter *parent ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent ); - std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1; - - if ( parent != 0 ) { - ++i; - } - - if ( i != graph.end() && ( *i ).first.get().size() == depth ) { - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_has_child( ui::TreeModel tree_model, GtkTreeIter *iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - std::size_t depth = ( *i ).first.get().size() + 1; - - return ++i != graph.end() && ( *i ).first.get().size() == depth; -} - -static gint graph_tree_model_iter_n_children( ui::TreeModel tree_model, GtkTreeIter *parent ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent ); - std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1; - - if ( parent != 0 ) { - ++i; - } - - gint count = 0; - while ( i != graph.end() && ( *i ).first.get().size() >= depth ) - { - ++count; - ++i; - } - - return count; -} - -static gboolean graph_tree_model_iter_nth_child( ui::TreeModel tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent ); - std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1; - - if ( parent != 0 ) { - ++i; - } - - while ( i != graph.end() && ( *i ).first.get().size() >= depth ) - { - if ( ( *i ).first.get().size() == depth && n-- == 0 ) { - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } - ++i; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_parent( ui::TreeModel tree_model, GtkTreeIter *iter, GtkTreeIter *child ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( child ); - std::size_t depth = ( *i ).first.get().size(); - if ( depth == 1 ) { - return FALSE; - } - else - { - do - { - --i; - } - while ( ( *i ).first.get().size() >= depth ); - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } -} - -static GObjectClass *g_parent_class = 0; - -static void graph_tree_model_init( GraphTreeModel *graph_tree_model ){ - graph_tree_model->graph = 0; -} - -static void graph_tree_model_finalize( GObject* object ){ - GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( object ); - - /* must chain up */ - ( *g_parent_class->finalize )( object ); -} - -static void graph_tree_model_class_init( GraphTreeModelClass *class_ ){ - GObjectClass *object_class; - - g_parent_class = (GObjectClass*)g_type_class_peek_parent( class_ ); - object_class = (GObjectClass *) class_; - - object_class->finalize = graph_tree_model_finalize; -} - -static void graph_tree_model_tree_model_init( GtkTreeModelIface *iface ){ - iface->get_flags = graph_tree_model_get_flags; - iface->get_n_columns = graph_tree_model_get_n_columns; - iface->get_column_type = graph_tree_model_get_column_type; - iface->get_iter = graph_tree_model_get_iter; - iface->get_path = graph_tree_model_get_path; - iface->get_value = graph_tree_model_get_value; - iface->iter_next = graph_tree_model_iter_next; - iface->iter_children = graph_tree_model_iter_children; - iface->iter_has_child = graph_tree_model_iter_has_child; - iface->iter_n_children = graph_tree_model_iter_n_children; - iface->iter_nth_child = graph_tree_model_iter_nth_child; - iface->iter_parent = graph_tree_model_iter_parent; -} - -static gboolean graph_tree_model_row_draggable( GtkTreeDragSource *drag_source, ui::TreePath path ){ -#if GDEF_DEBUG - gint depth = gtk_tree_path_get_depth( path ); -#endif - return gtk_tree_path_get_depth( path ) > 1; -} - -static gboolean graph_tree_model_drag_data_delete( GtkTreeDragSource *drag_source, ui::TreePath path ){ - GtkTreeIter iter; - - if ( gtk_tree_model_get_iter( drag_source, &iter, path ) ) { - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - Path_deleteTop( ( *i ).first ); - return TRUE; - } - else - { - return FALSE; - } -} - -static gboolean graph_tree_model_drag_data_get( GtkTreeDragSource *drag_source, ui::TreePath path, GtkSelectionData *selection_data ){ - if ( gtk_tree_set_row_drag_data( selection_data, drag_source, path ) ) { - return TRUE; - } - else - { - /* FIXME handle text targets at least. */ - } - - return FALSE; -} - -static void graph_tree_model_drag_source_init( GtkTreeDragSourceIface *iface ){ - iface->row_draggable = graph_tree_model_row_draggable; - iface->drag_data_delete = graph_tree_model_drag_data_delete; - iface->drag_data_get = graph_tree_model_drag_data_get; -} - -static gboolean graph_tree_model_drag_data_received( GtkTreeDragDest *drag_dest, ui::TreePath dest, GtkSelectionData *selection_data ){ - auto tree_model = drag_dest; - - GtkTreeModel *src_model = 0; - GtkTreePath *src_path = 0; - if ( gtk_tree_get_row_drag_data( selection_data, &src_model, &src_path ) - && src_model == tree_model ) { - /* Copy the given row to a new position */ - GtkTreeIter iter; - - if ( gtk_tree_model_get_iter( src_model, &iter, src_path ) ) { - int bleh = 0; - } - } - else - { - /* FIXME maybe add some data targets eventually, or handle text - * targets in the simple case. - */ - } - - return FALSE; -} - -static gboolean graph_tree_model_row_drop_possible( GtkTreeDragDest *drag_dest, ui::TreePath dest_path, GtkSelectionData *selection_data ){ - gboolean retval = FALSE; - - GtkTreeModel *src_model = 0; - GtkTreePath *src_path = 0; - if ( gtk_tree_get_row_drag_data( selection_data, &src_model, &src_path ) != FALSE ) { - /* can only drag to ourselves */ - if ( src_model == drag_dest ) { - /* Can't drop into ourself. */ - if ( !gtk_tree_path_is_ancestor( src_path, dest_path ) ) { - /* Can't drop if dest_path's parent doesn't exist */ - if ( gtk_tree_path_get_depth( dest_path ) > 1 ) { - auto tmp = gtk_tree_path_copy( dest_path ); - gtk_tree_path_up( tmp ); - - GtkTreeIter iter; - retval = gtk_tree_model_get_iter( drag_dest, &iter, tmp ); - - gtk_tree_path_free( tmp ); - } - } - } - - gtk_tree_path_free( src_path ); - } - - return retval; -} - -static void graph_tree_model_drag_dest_init( GtkTreeDragDestIface *iface ){ - iface->drag_data_received = graph_tree_model_drag_data_received; - iface->row_drop_possible = graph_tree_model_row_drop_possible; -} - -GType graph_tree_model_get_type( void ){ - static GType graph_tree_model_type = 0; - - if ( !graph_tree_model_type ) { - static const GTypeInfo graph_tree_model_info = - { - sizeof( GraphTreeModelClass ), - 0, /* base_init */ - 0, /* base_finalize */ - (GClassInitFunc) graph_tree_model_class_init, - 0, /* class_finalize */ - 0, /* class_data */ - sizeof( GraphTreeModel ), - 0, /* n_preallocs */ - (GInstanceInitFunc) graph_tree_model_init - }; - - static const GInterfaceInfo tree_model_info = - { - (GInterfaceInitFunc) graph_tree_model_tree_model_init, - 0, - 0 - }; - - static const GInterfaceInfo drag_source_info = - { - (GInterfaceInitFunc) graph_tree_model_drag_source_init, - 0, - 0 - }; - - static const GInterfaceInfo drag_dest_info = - { - (GInterfaceInitFunc) graph_tree_model_drag_dest_init, - 0, - 0 - }; - - graph_tree_model_type = g_type_register_static( G_TYPE_OBJECT, "GraphTreeModel", - &graph_tree_model_info, (GTypeFlags)0 ); - - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info ); - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_DRAG_SOURCE, - &drag_source_info ); - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_DRAG_DEST, - &drag_dest_info ); - } - - return graph_tree_model_type; -} - -GraphTreeModel* graph_tree_model_new(){ - GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( g_object_new( graph_tree_model_get_type(), 0 ) ); - - graph_tree_model->graph = new graph_type; - - return graph_tree_model; -} - -void graph_tree_model_delete( GraphTreeModel* model ){ - delete model->graph; - g_object_unref( G_OBJECT( model ) ); -} - - -class TempNameable : public Nameable -{ -const char* m_name; -public: -TempNameable( const char* name ) : m_name( name ){ -} -const char* name() const { - return m_name; -} -void attach( const NameCallback& callback ){ -} -void detach( const NameCallback& callback ){ -} -}; - -void node_attach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - // 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 ); - } - } -} -void node_detach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - 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 ); - } - } -} - -GraphTreeModel* scene_graph_get_tree_model(); // temp hack - -void graph_tree_model_row_inserted( GraphTreeModel* model, graph_type::iterator i ){ - GtkTreeIter iter; - graph_iterator_write_tree_iter( i, &iter ); - - auto tree_path = graph_tree_model_get_path( model, &iter ); - - gint depth = gtk_tree_path_get_depth( tree_path ); - gint* indices = gtk_tree_path_get_indices( tree_path ); - - gtk_tree_model_row_inserted( model, tree_path, &iter ); - - gtk_tree_path_free( tree_path ); -} - -void graph_tree_model_row_deleted( GraphTreeModel* model, graph_type::iterator i ){ - GtkTreeIter iter; - graph_iterator_write_tree_iter( i, &iter ); - - auto tree_path = graph_tree_model_get_path( model, &iter ); - - gtk_tree_model_row_deleted( model, tree_path ); - - gtk_tree_path_free( tree_path ); -} - -#include "generic/referencecounted.h" - -void graph_tree_model_set_name( const scene::Instance& instance, const char* name ){ - GraphTreeModel* model = scene_graph_get_tree_model(); - - if ( string_empty( name ) ) { // hack! - graph_type::iterator i = model->graph->find( PathConstReference( instance.path() ) ); - ASSERT_MESSAGE( i != model->graph->end(), "ERROR" ); - - graph_tree_model_row_deleted( model, i ); - - model->graph->erase( i ); - } - else - { - graph_type::iterator i = model->graph->insert( graph_type::value_type( PathConstReference( instance.path() ), &const_cast( instance ) ) ).first; - - graph_tree_model_row_inserted( model, i ); - } -} - -void graph_tree_model_insert( GraphTreeModel* model, const scene::Instance& instance ){ - graph_type::iterator i = model->graph->insert( graph_type::value_type( PathConstReference( instance.path() ), &const_cast( instance ) ) ).first; - - graph_tree_model_row_inserted( model, i ); - - node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); -} - -void graph_tree_model_erase( GraphTreeModel* model, const scene::Instance& instance ){ - node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); - - graph_type::iterator i = model->graph->find( PathConstReference( instance.path() ) ); - ASSERT_MESSAGE( i != model->graph->end(), "ERROR" ); - - graph_tree_model_row_deleted( model, i ); - - model->graph->erase( i ); -} - -#elif 1 - -class GraphTreeNode; - -void graph_tree_model_row_changed(GraphTreeNode &node); - -class GraphTreeNode { -typedef std::map, GraphTreeNode *> ChildNodes; -ChildNodes m_childnodes; -public: -Reference m_instance; -GraphTreeNode *m_parent; - -typedef ChildNodes::iterator iterator; -typedef ChildNodes::key_type key_type; -typedef ChildNodes::value_type value_type; -typedef ChildNodes::size_type size_type; - -GraphTreeNode(scene::Instance &instance) : m_instance(instance), m_parent(0) -{ - m_instance.get().setChildSelectedChangedCallback(RowChangedCaller(*this)); -} - -~GraphTreeNode() -{ - m_instance.get().setChildSelectedChangedCallback(Callback()); - ASSERT_MESSAGE(empty(), "GraphTreeNode::~GraphTreeNode: memory leak"); -} - -iterator begin() -{ - return m_childnodes.begin(); -} - -iterator end() -{ - return m_childnodes.end(); -} - -size_type size() const -{ - return m_childnodes.size(); -} - -bool empty() const -{ - return m_childnodes.empty(); -} - -iterator insert(const value_type &value) -{ - iterator i = m_childnodes.insert(value).first; - (*i).second->m_parent = this; - return i; -} - -void erase(iterator i) -{ - m_childnodes.erase(i); -} - -iterator find(const key_type &key) -{ - return m_childnodes.find(key); -} - -void swap(GraphTreeNode &other) -{ - std::swap(m_parent, other.m_parent); - std::swap(m_childnodes, other.m_childnodes); - std::swap(m_instance, other.m_instance); -} - -void rowChanged() -{ - graph_tree_model_row_changed(*this); -} - -typedef MemberCaller RowChangedCaller; -}; - -struct GraphTreeModel { - GObject parent; - - GraphTreeNode *m_graph; -}; - -struct GraphTreeModelClass { - GObjectClass parent_class; -}; - -static GtkTreeModelFlags graph_tree_model_get_flags(ui::TreeModel tree_model) -{ - return GTK_TREE_MODEL_ITERS_PERSIST; -} - -static gint graph_tree_model_get_n_columns(ui::TreeModel tree_model) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - //GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model; - - return 2; -} - -static const gint c_stamp = 0xabcdef; - -inline GraphTreeNode::iterator graph_iterator_read_tree_iter(GtkTreeIter *iter) -{ - ASSERT_MESSAGE(iter != 0, "tree model error"); - ASSERT_MESSAGE(iter->user_data != 0, "tree model error"); - ASSERT_MESSAGE(iter->stamp == c_stamp, "tree model error"); - return *reinterpret_cast( &iter->user_data ); -} - -inline void graph_iterator_write_tree_iter(GraphTreeNode::iterator i, GtkTreeIter *iter) -{ - ASSERT_MESSAGE(iter != 0, "tree model error"); - iter->stamp = c_stamp; - *reinterpret_cast( &iter->user_data ) = i; - ASSERT_MESSAGE(iter->user_data != 0, "tree model error"); -} - -static GType graph_tree_model_get_column_type(ui::TreeModel tree_model, gint index) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - //GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model; - - return G_TYPE_POINTER; -} - -static gboolean graph_tree_model_get_iter(GraphTreeModel *tree_model, GtkTreeIter *iter, ui::TreePath path) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - gint *indices = gtk_tree_path_get_indices(path); - gint depth = gtk_tree_path_get_depth(path); - - g_return_val_if_fail(depth > 0, FALSE); - - GraphTreeNode *graph = tree_model->m_graph; - - if (graph->empty()) { - return FALSE; - } - - GtkTreeIter tmp; - GtkTreeIter *parent = 0; - - for (gint i = 0; i < depth; i++) { - if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(tree_model), iter, parent, indices[i])) { - return FALSE; - } - tmp = *iter; - parent = &tmp; - } - - return TRUE; -} - -static ui::TreePath graph_tree_model_get_path(GraphTreeModel *tree_model, GtkTreeIter *iter) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - GraphTreeNode *graph = tree_model->m_graph; - - auto path = ui::TreePath(ui::New); - - for (GraphTreeNode *node = (*graph_iterator_read_tree_iter(iter)).second; node != graph; node = node->m_parent) { - std::size_t index = 0; - for (GraphTreeNode::iterator i = node->m_parent->begin(); i != node->m_parent->end(); ++i, ++index) { - if ((*i).second == node) { - gtk_tree_path_prepend_index(path, gint(index)); - break; - } - } - ASSERT_MESSAGE(index != node->m_parent->size(), "error resolving tree path"); - } - - return path; -} - - -static void graph_tree_model_get_value(ui::TreeModel tree_model, GtkTreeIter *iter, gint column, GValue *value) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - ASSERT_MESSAGE(column == 0 || column == 1, "tree model error"); - - GraphTreeNode::iterator i = graph_iterator_read_tree_iter(iter); - - g_value_init(value, G_TYPE_POINTER); - - if (column == 0) { - g_value_set_pointer(value, reinterpret_cast((*i).first.second )); - } else { - g_value_set_pointer(value, reinterpret_cast( &(*i).second->m_instance.get())); - } -} - -static gboolean graph_tree_model_iter_next(ui::TreeModel tree_model, GtkTreeIter *iter) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - GraphTreeNode::iterator i = graph_iterator_read_tree_iter(iter); - GraphTreeNode &parent = *(*i).second->m_parent; - - ASSERT_MESSAGE(i != parent.end(), "RUNTIME ERROR"); - - if (++i == parent.end()) { - return FALSE; - } - - graph_iterator_write_tree_iter(i, iter); - - return TRUE; -} - -static gboolean graph_tree_model_iter_children(GraphTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - GraphTreeNode &node = (parent == 0) ? *tree_model->m_graph : *(*graph_iterator_read_tree_iter(parent)).second; - if (!node.empty()) { - graph_iterator_write_tree_iter(node.begin(), iter); - return TRUE; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_has_child(ui::TreeModel tree_model, GtkTreeIter *iter) -{ - ASSERT_MESSAGE(tree_model, "RUNTIME ERROR"); - GraphTreeNode &node = *(*graph_iterator_read_tree_iter(iter)).second; - return !node.empty(); -} - -static gint graph_tree_model_iter_n_children(GraphTreeModel *tree_model, GtkTreeIter *parent) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - GraphTreeNode &node = (parent == 0) ? *tree_model->m_graph : *(*graph_iterator_read_tree_iter(parent)).second; - return static_cast( node.size()); -} - -static gboolean -graph_tree_model_iter_nth_child(GraphTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - GraphTreeNode &node = (parent == 0) ? *tree_model->m_graph : *(*graph_iterator_read_tree_iter(parent)).second; - if (static_cast( n ) < node.size()) { - GraphTreeNode::iterator i = node.begin(); - std::advance(i, n); - graph_iterator_write_tree_iter(i, iter); - return TRUE; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_parent(GraphTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child) -{ - ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR"); - GraphTreeNode &node = *(*graph_iterator_read_tree_iter(child)).second; - if (node.m_parent != tree_model->m_graph) { - GraphTreeNode &parentParent = *node.m_parent->m_parent; - for (GraphTreeNode::iterator i = parentParent.begin(); i != parentParent.end(); ++i) { - if ((*i).second == node.m_parent) { - graph_iterator_write_tree_iter(i, iter); - return TRUE; - } - } - } - return FALSE; -} - -static GObjectClass *g_parent_class = 0; - -namespace { -scene::Node *g_null_node = 0; -} - -class NullInstance : public scene::Instance { -public: -NullInstance() : scene::Instance(scene::Path(makeReference(*g_null_node)), 0, 0, - Static::instance()) -{ -} -}; - -namespace { -NullInstance g_null_instance; -} - -static void graph_tree_model_init(GraphTreeModel *graph_tree_model) -{ - graph_tree_model->m_graph = new GraphTreeNode(g_null_instance); -} - -static void graph_tree_model_finalize(GObject *object) -{ - auto graph_tree_model = reinterpret_cast(object); - - delete graph_tree_model->m_graph; - - /* must chain up */ - (*g_parent_class->finalize)(object); -} - -static void graph_tree_model_class_init(GraphTreeModelClass *class_) -{ - GObjectClass *object_class; - - g_parent_class = (GObjectClass *) g_type_class_peek_parent(class_); - object_class = (GObjectClass *) class_; - - object_class->finalize = graph_tree_model_finalize; -} - -static void graph_tree_model_tree_model_init(GtkTreeModelIface *iface) -{ - iface->get_flags = reinterpret_cast(graph_tree_model_get_flags); - iface->get_n_columns = reinterpret_cast(graph_tree_model_get_n_columns); - iface->get_column_type = reinterpret_cast(graph_tree_model_get_column_type); - iface->get_iter = reinterpret_cast(graph_tree_model_get_iter); - iface->get_path = reinterpret_cast(graph_tree_model_get_path); - iface->get_value = reinterpret_cast(graph_tree_model_get_value); - iface->iter_next = reinterpret_cast(graph_tree_model_iter_next); - iface->iter_children = reinterpret_cast(graph_tree_model_iter_children); - iface->iter_has_child = reinterpret_cast(graph_tree_model_iter_has_child); - iface->iter_n_children = reinterpret_cast(graph_tree_model_iter_n_children); - iface->iter_nth_child = reinterpret_cast(graph_tree_model_iter_nth_child); - iface->iter_parent = reinterpret_cast(graph_tree_model_iter_parent); -} - -GType graph_tree_model_get_type(void) -{ - static GType graph_tree_model_type = 0; - - if (!graph_tree_model_type) { - static const GTypeInfo graph_tree_model_info = - { - sizeof(GraphTreeModelClass), - 0, /* base_init */ - 0, /* base_finalize */ - (GClassInitFunc) graph_tree_model_class_init, - 0, /* class_finalize */ - 0, /* class_data */ - sizeof(GraphTreeModel), - 0, /* n_preallocs */ - (GInstanceInitFunc) graph_tree_model_init, - 0 - }; - - static const GInterfaceInfo tree_model_info = - { - (GInterfaceInitFunc) graph_tree_model_tree_model_init, - 0, - 0 - }; - - graph_tree_model_type = g_type_register_static(G_TYPE_OBJECT, "GraphTreeModel", - &graph_tree_model_info, (GTypeFlags) 0); - - g_type_add_interface_static(graph_tree_model_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info); - } - - return graph_tree_model_type; -} - -GraphTreeModel *graph_tree_model_new() -{ - auto graph_tree_model = reinterpret_cast(g_object_new(graph_tree_model_get_type(), 0)); - - return graph_tree_model; -} - -void graph_tree_model_delete(GraphTreeModel *model) -{ - g_object_unref(G_OBJECT(model)); -} - -void graph_tree_model_row_changed(GraphTreeModel *model, GraphTreeNode::iterator i) -{ - GtkTreeIter iter; - graph_iterator_write_tree_iter(i, &iter); - - auto tree_path = graph_tree_model_get_path(model, &iter); - - gtk_tree_model_row_changed(GTK_TREE_MODEL(model), tree_path, &iter); - - gtk_tree_path_free(tree_path); -} - -void graph_tree_model_row_inserted(GraphTreeModel *model, GraphTreeNode::iterator i) -{ - GtkTreeIter iter; - graph_iterator_write_tree_iter(i, &iter); - - auto tree_path = graph_tree_model_get_path(model, &iter); - - gtk_tree_model_row_inserted(GTK_TREE_MODEL(model), tree_path, &iter); - - gtk_tree_path_free(tree_path); -} - -void graph_tree_model_row_deleted(GraphTreeModel *model, GraphTreeNode::iterator i) -{ - GtkTreeIter iter; - graph_iterator_write_tree_iter(i, &iter); - - auto tree_path = graph_tree_model_get_path(model, &iter); - - gtk_tree_model_row_deleted(GTK_TREE_MODEL(model), tree_path); - - gtk_tree_path_free(tree_path); -} - -void graph_tree_model_row_inserted(GraphTreeModel &model, GraphTreeNode::iterator i) -{ - graph_tree_model_row_inserted(&model, i); -} - -void graph_tree_model_row_deleted(GraphTreeModel &model, GraphTreeNode::iterator i) -{ - graph_tree_model_row_deleted(&model, i); -} - -const char *node_get_name(scene::Node &node); - -const char *node_get_name_safe(scene::Node &node) -{ - volatile intptr_t n = (intptr_t) &node; // see the comment on line 650 - if (n == 0) { - return ""; - } - return node_get_name(node); -} - -GraphTreeNode *graph_tree_model_find_parent(GraphTreeModel *model, const scene::Path &path) -{ - GraphTreeNode *parent = model->m_graph; - for (scene::Path::const_iterator i = path.begin(); i != path.end() - 1; ++i) { - GraphTreeNode::iterator child = parent->find( - GraphTreeNode::key_type(node_get_name_safe((*i).get()), (*i).get_pointer())); - ASSERT_MESSAGE(child != parent->end(), "ERROR"); - parent = (*child).second; - } - return parent; -} - -void node_attach_name_changed_callback(scene::Node &node, const NameCallback &callback) -{ - 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); - } - } -} - -void node_detach_name_changed_callback(scene::Node &node, const NameCallback &callback) -{ - 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); - } - } -} - -GraphTreeModel *scene_graph_get_tree_model(); // temp hack - -void graph_tree_node_foreach_pre(GraphTreeNode::iterator root, const Callback &callback) -{ - callback(root); - for (GraphTreeNode::iterator i = (*root).second->begin(); i != (*root).second->end(); ++i) { - graph_tree_node_foreach_pre(i, callback); - } -} - -void graph_tree_node_foreach_post(GraphTreeNode::iterator root, const Callback &callback) -{ - for (GraphTreeNode::iterator i = (*root).second->begin(); i != (*root).second->end(); ++i) { - graph_tree_node_foreach_post(i, callback); - } - callback(root); -} - -void graph_tree_model_row_changed(GraphTreeNode &node) -{ - GraphTreeModel *model = scene_graph_get_tree_model(); - const scene::Instance &instance = node.m_instance.get(); - - GraphTreeNode::iterator i = node.m_parent->find( - GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), - instance.path().top().get_pointer())); - - graph_tree_model_row_changed(model, i); -} - -void graph_tree_model_set_name(const scene::Instance &instance, const char *name) -{ - GraphTreeModel *model = scene_graph_get_tree_model(); - GraphTreeNode *parent = graph_tree_model_find_parent(model, instance.path()); - - GraphTreeNode::iterator oldNode = parent->find( - GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), - instance.path().top().get_pointer())); - graph_tree_node_foreach_post(oldNode, ReferenceCaller(*model)); - GraphTreeNode *node((*oldNode).second); - parent->erase(oldNode); - - GraphTreeNode::iterator newNode = parent->insert( - GraphTreeNode::value_type(GraphTreeNode::key_type(name, &instance.path().top().get()), node)); - graph_tree_node_foreach_pre(newNode, ReferenceCaller(*model)); -} - -void graph_tree_model_insert(GraphTreeModel *model, const scene::Instance &instance) -{ - GraphTreeNode *parent = graph_tree_model_find_parent(model, instance.path()); - - GraphTreeNode::iterator i = parent->insert(GraphTreeNode::value_type( - GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), - instance.path().top().get_pointer()), - new GraphTreeNode(const_cast( instance )))); - - graph_tree_model_row_inserted(model, i); - - node_attach_name_changed_callback(instance.path().top(), ConstReferenceCaller(instance)); -} - -void graph_tree_model_erase(GraphTreeModel *model, const scene::Instance &instance) -{ - node_detach_name_changed_callback(instance.path().top(), ConstReferenceCaller(instance)); - - GraphTreeNode *parent = graph_tree_model_find_parent(model, instance.path()); - - GraphTreeNode::iterator i = parent->find(GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), - instance.path().top().get_pointer())); - - graph_tree_model_row_deleted(model, i); - - GraphTreeNode *node((*i).second); - parent->erase(i); - delete node; -} - - -#endif - - -#if 0 -class TestGraphTreeModel -{ -public: -TestGraphTreeModel(){ - gtk_init( 0, 0 ); - - graph_type graph; - - scene::Node* root = *(scene::Node*)0xa0000000; - scene::Node* node1 = (scene::Node*)0xa0000001; - scene::Node* node2 = (scene::Node*)0xa0000002; - scene::Node* node3 = (scene::Node*)0xa0000003; - scene::Node* node4 = (scene::Node*)0xa0000004; - scene::Instance* instance = (scene::Instance*)0xaaaaaaaa; - - scene::Path rootpath( root ); - - graph.insert( graph_type::value_type( rootpath, instance ) ); - - rootpath.push( node1 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.pop(); - - rootpath.push( node2 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.push( node3 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.pop(); - rootpath.push( node4 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.pop(); - rootpath.pop(); - - auto model = graph_tree_model_new( &graph ); - - { - gint n_columns = gtk_tree_model_get_n_columns( model ); - ASSERT_MESSAGE( n_columns == 2, "test failed!" ); - } - - { - GType type = gtk_tree_model_get_column_type( model, 0 ); - ASSERT_MESSAGE( type == G_TYPE_POINTER, "test failed!" ); - } - - { - GType type = gtk_tree_model_get_column_type( model, 1 ); - ASSERT_MESSAGE( type == G_TYPE_POINTER, "test failed!" ); - } - - - { - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node1, "test failed!" ); - } - - { - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - ASSERT_MESSAGE( gtk_tree_model_iter_has_child( model, &iter ) == FALSE, "test failed!" ); - - ASSERT_MESSAGE( gtk_tree_model_iter_n_children( model, &iter ) == 0, "test failed!" ); - - gtk_tree_model_iter_next( model, &iter ); - - ASSERT_MESSAGE( gtk_tree_model_iter_has_child( model, &iter ) != FALSE, "test failed!" ); - - ASSERT_MESSAGE( gtk_tree_model_iter_n_children( model, &iter ) == 2, "test failed!" ); - - { - GtkTreeIter child; - gtk_tree_model_iter_nth_child( model, &child, &iter, 0 ); - - scene::Node* test; - gtk_tree_model_get_value( model, &child, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node3, "test failed!" ); - - { - GtkTreeIter parent; - gtk_tree_model_iter_parent( model, &parent, &child ); - - scene::Node* test; - gtk_tree_model_get_value( model, &parent, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node2, "test failed!" ); - } - } - - { - GtkTreeIter child; - gtk_tree_model_iter_nth_child( model, &child, &iter, 1 ); - - scene::Node* test; - gtk_tree_model_get_value( model, &child, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node4, "test failed!" ); - } - } - - { - GtkTreeIter iter; - std::size_t count = 0; - for ( gboolean good = gtk_tree_model_get_iter_first( model, &iter ); good; good = gtk_tree_model_iter_next( model, &iter ) ) - { - scene::Node* test; - gtk_tree_model_get_value( model, &iter, 0, (GValue*)&test ); - - ASSERT_MESSAGE( ( count == 0 && test == node1 ) || ( count == 1 && test == node2 ), "test failed!" ); - ++count; - } - - ASSERT_MESSAGE( count == 2, "test failed!" ); - - } - - { - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - scene::Node* test; - gtk_tree_model_get_value( model, &iter, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node1, "test failed!" ); - } - - { - GtkTreeIter iter; - auto path = ui::TreePath( "0" ); - gtk_tree_model_get_iter( model, &iter, path ); - gtk_tree_path_free( path ); - - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node1, "test failed!" ); - } - - { - GtkTreeIter iter; - auto path = ui::TreePath( "1" ); - gtk_tree_model_get_iter( model, &iter, path ); - gtk_tree_path_free( path ); - - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node2, "test failed!" ); - } - - { - GtkTreeIter iter; - graph_type::iterator i = graph.begin(); - ++i; - graph_iterator_write_tree_iter( i, &iter ); - - auto path = gtk_tree_model_get_path( model, &iter ); - - gint depth = gtk_tree_path_get_depth( path ); - gint* indices = gtk_tree_path_get_indices( path ); - - ASSERT_MESSAGE( depth == 1 && indices[0] == 0, "test failed!" ); - - gtk_tree_path_free( path ); - } - - { - GtkTreeIter iter; - graph_type::iterator i = graph.begin(); - ++i; - ++i; - graph_iterator_write_tree_iter( i, &iter ); - - auto path = gtk_tree_model_get_path( model, &iter ); - - gint depth = gtk_tree_path_get_depth( path ); - gint* indices = gtk_tree_path_get_indices( path ); - - ASSERT_MESSAGE( depth == 1 && indices[0] == 1, "test failed!" ); - - gtk_tree_path_free( path ); - } -} -}; - - -TestGraphTreeModel g_TestGraphTreeModel; - -#endif diff --git a/src/treemodel.h b/src/treemodel.h deleted file mode 100644 index 80fe224..0000000 --- a/src/treemodel.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_TREEMODEL_H ) -#define INCLUDED_TREEMODEL_H - -struct GraphTreeModel; - -GraphTreeModel *graph_tree_model_new(); - -void graph_tree_model_delete(GraphTreeModel *model); - -namespace scene { -class Instance; -} - -void graph_tree_model_insert(GraphTreeModel *model, const scene::Instance &instance); - -void graph_tree_model_erase(GraphTreeModel *model, const scene::Instance &instance); - -#endif diff --git a/src/undo.cpp b/src/undo.cpp deleted file mode 100644 index 364edd2..0000000 --- a/src/undo.cpp +++ /dev/null @@ -1,624 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "undo.h" - -#include "debugging/debugging.h" -#include "warnings.h" - -#include "iundo.h" -#include "preferencesystem.h" -#include "string/string.h" -#include "generic/callback.h" -#include "preferences.h" -#include "stringio.h" - -#include -#include -#include - -#include "timer.h" - -void Undo_SetButtonlabel(const char *title); -void Undo_DisableButton(void); - -void Redo_SetButtonlabel(const char *title); -void Redo_DisableButton(void); - -class DebugScopeTimer { -Timer m_timer; -const char *m_operation; -public: -DebugScopeTimer(const char *operation) - : m_operation(operation) -{ - m_timer.start(); -} - -~DebugScopeTimer() -{ - unsigned int elapsed = m_timer.elapsed_msec(); - if (elapsed > 0) { - globalOutputStream() << m_operation << ": " << elapsed << " msec\n"; - } -} -}; - - -class RadiantUndoSystem : public UndoSystem { -UINT_CONSTANT(MAX_UNDO_LEVELS, 1024); - -class Snapshot { -class StateApplicator { -public: -Undoable *m_undoable; -private: -UndoMemento *m_data; -public: - -StateApplicator(Undoable *undoable, UndoMemento *data) - : m_undoable(undoable), m_data(data) -{ -} - -void restore() -{ - m_undoable->importState(m_data); -} - -void release() -{ - m_data->release(); -} -}; - -typedef std::list states_t; -states_t m_states; - -public: -bool empty() const -{ - return m_states.empty(); -} - -std::size_t size() const -{ - return m_states.size(); -} - -void save(Undoable *undoable) -{ - m_states.push_front(StateApplicator(undoable, undoable->exportState())); -} - -void restore() -{ - for (states_t::iterator i = m_states.begin(); i != m_states.end(); ++i) { - (*i).restore(); - } -} - -void release() -{ - for (states_t::iterator i = m_states.begin(); i != m_states.end(); ++i) { - (*i).release(); - } -} -}; - -struct Operation { - Snapshot m_snapshot; - CopiedString m_command; - - Operation(const char *command) - : m_command(command) - { - } - - ~Operation() - { - m_snapshot.release(); - } -}; - - -class UndoStack { -//! Note: using std::list instead of vector/deque, to avoid copying of undos -typedef std::list Operations; - -Operations m_stack; -Operation *m_pending; - -public: -UndoStack() : m_pending(0) -{ -} - -~UndoStack() -{ - clear(); -} - -bool empty() const -{ - return m_stack.empty(); -} - -std::size_t size() const -{ - return m_stack.size(); -} - -Operation *back() -{ - return m_stack.back(); -} - -const Operation *back() const -{ - return m_stack.back(); -} - -Operation *front() -{ - return m_stack.front(); -} - -const Operation *front() const -{ - return m_stack.front(); -} - -void pop_front() -{ - delete m_stack.front(); - m_stack.pop_front(); -} - -void pop_back() -{ - delete m_stack.back(); - m_stack.pop_back(); -} - -void clear() -{ - if (!m_stack.empty()) { - for (Operations::iterator i = m_stack.begin(); i != m_stack.end(); ++i) { - delete *i; - } - m_stack.clear(); - } -} - -void start(const char *command) -{ - if (m_pending != 0) { - delete m_pending; - } - m_pending = new Operation(command); -} - -bool finish(const char *command) -{ - if (m_pending != 0) { - delete m_pending; - m_pending = 0; - return false; - } else { - ASSERT_MESSAGE(!m_stack.empty(), "undo stack empty"); - m_stack.back()->m_command = command; - return true; - } -} - -void save(Undoable *undoable) -{ - if (m_pending != 0) { - m_stack.push_back(m_pending); - m_pending = 0; - } - back()->m_snapshot.save(undoable); -} -}; - -UndoStack m_undo_stack; -UndoStack m_redo_stack; - -class UndoStackFiller : public UndoObserver { -UndoStack *m_stack; -public: - -UndoStackFiller() - : m_stack(0) -{ -} - -void save(Undoable *undoable) -{ - ASSERT_NOTNULL(undoable); - - if (m_stack != 0) { - m_stack->save(undoable); - m_stack = 0; - } -} - -void setStack(UndoStack *stack) -{ - m_stack = stack; -} -}; - -typedef std::map undoables_t; -undoables_t m_undoables; - -void mark_undoables(UndoStack *stack) -{ - for (undoables_t::iterator i = m_undoables.begin(); i != m_undoables.end(); ++i) { - (*i).second.setStack(stack); - } -} - -std::size_t m_undo_levels; - -typedef std::set Trackers; -Trackers m_trackers; -public: -RadiantUndoSystem() - : m_undo_levels(64) -{ -} - -~RadiantUndoSystem() -{ - clear(); -} - -UndoObserver *observer(Undoable *undoable) -{ - ASSERT_NOTNULL(undoable); - - return &m_undoables[undoable]; -} - -void release(Undoable *undoable) -{ - ASSERT_NOTNULL(undoable); - - m_undoables.erase(undoable); -} - -void setLevels(std::size_t levels) -{ - if (levels > MAX_UNDO_LEVELS()) { - levels = MAX_UNDO_LEVELS(); - } - - while (m_undo_stack.size() > levels) { - m_undo_stack.pop_front(); - } - m_undo_levels = levels; -} - -std::size_t getLevels() const -{ - return m_undo_levels; -} - -std::size_t size() const -{ - return m_undo_stack.size(); -} - -void startUndo() -{ - m_undo_stack.start("unnamedCommand"); - mark_undoables(&m_undo_stack); -} - -bool finishUndo(const char *command) -{ - bool changed = m_undo_stack.finish(command); - mark_undoables(0); - return changed; -} - -void startRedo() -{ - m_redo_stack.start("unnamedCommand"); - mark_undoables(&m_redo_stack); -} - -bool finishRedo(const char *command) -{ - bool changed = m_redo_stack.finish(command); - mark_undoables(0); - return changed; -} - -void start() -{ - m_redo_stack.clear(); - if (m_undo_stack.size() == m_undo_levels) { - m_undo_stack.pop_front(); - } - startUndo(); - trackersBegin(); -} - -void finish(const char *command) -{ - if (finishUndo(command)) { - globalOutputStream() << command << '\n'; - Undo_SetButtonlabel(command); - Redo_DisableButton(); - } -} - -void undo() -{ - if (m_undo_stack.empty()) { - globalOutputStream() << "Undo: no undo available\n"; - } else { - Operation *operation = m_undo_stack.back(); - globalOutputStream() << "Undo: " << operation->m_command.c_str() << "\n"; - Redo_SetButtonlabel(operation->m_command.c_str()); - - startRedo(); - trackersUndo(); - operation->m_snapshot.restore(); - finishRedo(operation->m_command.c_str()); - m_undo_stack.pop_back(); - - Operation *operation2 = m_undo_stack.back(); - if (operation2) { - Undo_SetButtonlabel(operation2->m_command.c_str()); - } else - Undo_DisableButton(); - } -} - -void redo() -{ - if (m_redo_stack.empty()) { - globalOutputStream() << "Redo: no redo available\n"; - } else { - Operation *operation = m_redo_stack.back(); - globalOutputStream() << "Redo: " << operation->m_command.c_str() << "\n"; - - startUndo(); - trackersRedo(); - operation->m_snapshot.restore(); - finishUndo(operation->m_command.c_str()); - m_redo_stack.pop_back(); - Operation *operationu = m_undo_stack.back(); - Undo_SetButtonlabel(operationu->m_command.c_str()); - - Operation *next = m_redo_stack.back(); - if (!next) - Redo_DisableButton(); - else - Redo_SetButtonlabel(next->m_command.c_str()); - } -} - -void clear() -{ - mark_undoables(0); - m_undo_stack.clear(); - m_redo_stack.clear(); - trackersClear(); -} - -void trackerAttach(UndoTracker &tracker) -{ - ASSERT_MESSAGE(m_trackers.find(&tracker) == m_trackers.end(), "undo tracker already attached"); - m_trackers.insert(&tracker); -} - -void trackerDetach(UndoTracker &tracker) -{ - ASSERT_MESSAGE(m_trackers.find(&tracker) != m_trackers.end(), "undo tracker cannot be detached"); - m_trackers.erase(&tracker); -} - -void trackersClear() const -{ - for (Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i) { - (*i)->clear(); - } -} - -void trackersBegin() const -{ - for (Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i) { - (*i)->begin(); - } -} - -void trackersUndo() const -{ - for (Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i) { - (*i)->undo(); - } -} - -void trackersRedo() const -{ - for (Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i) { - (*i)->redo(); - } -} -}; - - -void UndoLevels_importString(RadiantUndoSystem &undo, const char *value) -{ - int levels; - PropertyImpl::Import(levels, value); - undo.setLevels(levels); -} - -typedef ReferenceCaller UndoLevelsImportStringCaller; - -void UndoLevels_exportString(const RadiantUndoSystem &undo, const Callback &importer) -{ - PropertyImpl::Export(static_cast( undo.getLevels()), importer); -} - -typedef ConstReferenceCaller &), UndoLevels_exportString> UndoLevelsExportStringCaller; - -#include "generic/callback.h" - -struct UndoLevels { - static void Export(const RadiantUndoSystem &self, const Callback &returnz) - { - returnz(static_cast(self.getLevels())); - } - - static void Import(RadiantUndoSystem &self, int value) - { - self.setLevels(value); - } -}; - -void Undo_constructPreferences(RadiantUndoSystem &undo, PreferencesPage &page) -{ - page.appendSpinner("Undo Queue Size", 64, 0, 1024, make_property(undo)); -} - -void Undo_constructPage(RadiantUndoSystem &undo, PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Undo", "Undo Queue Settings")); - Undo_constructPreferences(undo, page); -} - -void Undo_registerPreferencesPage(RadiantUndoSystem &undo) -{ - PreferencesDialog_addSettingsPage( - ReferenceCaller(undo)); -} - -class UndoSystemDependencies : public GlobalPreferenceSystemModuleRef { -}; - -class UndoSystemAPI { -RadiantUndoSystem m_undosystem; -public: -typedef UndoSystem Type; - -STRING_CONSTANT(Name, "*"); - -UndoSystemAPI() -{ - GlobalPreferenceSystem().registerPreference("UndoLevels", make_property_string(m_undosystem)); - - Undo_registerPreferencesPage(m_undosystem); -} - -UndoSystem *getTable() -{ - return &m_undosystem; -} -}; - -#include "modulesystem/singletonmodule.h" -#include "modulesystem/moduleregistry.h" - -typedef SingletonModule UndoSystemModule; -typedef Static StaticUndoSystemModule; -StaticRegisterModule staticRegisterUndoSystem(StaticUndoSystemModule::instance()); - - -class undoable_test : public Undoable { -struct state_type : public UndoMemento { - state_type() : test_data(0) - { - } - - state_type(const state_type &other) : UndoMemento(other), test_data(other.test_data) - { - } - - void release() - { - delete this; - } - - int test_data; -}; - -state_type m_state; -UndoObserver *m_observer; -public: -undoable_test() - : m_observer(GlobalUndoSystem().observer(this)) -{ -} - -~undoable_test() -{ - GlobalUndoSystem().release(this); -} - -UndoMemento *exportState() const -{ - return new state_type(m_state); -} - -void importState(const UndoMemento *state) -{ - ASSERT_NOTNULL(state); - - m_observer->save(this); - m_state = *(static_cast( state )); -} - -void mutate(unsigned int data) -{ - m_observer->save(this); - m_state.test_data = data; -} -}; - -#if 0 - -class TestUndo -{ -public: -TestUndo(){ - undoable_test test; - GlobalUndoSystem().begin( "bleh" ); - test.mutate( 3 ); - GlobalUndoSystem().begin( "blah" ); - test.mutate( 4 ); - GlobalUndoSystem().undo(); - GlobalUndoSystem().undo(); - GlobalUndoSystem().redo(); - GlobalUndoSystem().redo(); -} -}; - -TestUndo g_TestUndo; - -#endif diff --git a/src/undo.h b/src/undo.h deleted file mode 100644 index 89e6337..0000000 --- a/src/undo.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_UNDO_H ) -#define INCLUDED_UNDO_H - -#endif diff --git a/src/url.cpp b/src/url.cpp deleted file mode 100644 index ca90d04..0000000 --- a/src/url.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "url.h" -#include "globaldefs.h" - -#include "mainframe.h" -#include "gtkutil/messagebox.h" - -#if GDEF_OS_WINDOWS -#include -#include -#include -bool open_url( const char* url ){ - return ShellExecute( (HWND)GDK_WINDOW_HWND( gtk_widget_get_window( MainFrame_getWindow() ) ), "open", url, 0, 0, SW_SHOW ) > (HINSTANCE)32; -} -#endif - -#if GDEF_OS_LINUX || GDEF_OS_BSD - -#include - -bool open_url(const char *url) -{ - char command[2 * PATH_MAX]; - snprintf(command, sizeof(command), - "xdg-open \"%s\" &", url); - return system(command) == 0; -} - -#endif - -#if GDEF_OS_MACOS -#include -bool open_url( const char* url ){ - char command[2 * PATH_MAX]; - snprintf( command, sizeof( command ), "open \"%s\" &", url ); - return system( command ) == 0; -} -#endif - -void OpenURL(const char *url) -{ - // let's put a little comment - globalOutputStream() << "OpenURL: " << url << "\n"; - if (!open_url(url)) { - ui::alert(MainFrame_getWindow(), "Failed to launch browser!"); - } -} diff --git a/src/url.h b/src/url.h deleted file mode 100644 index 829b039..0000000 --- a/src/url.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_URL_H ) -#define INCLUDED_URL_H - -void OpenURL(const char *url); - -#endif diff --git a/src/view.cpp b/src/view.cpp deleted file mode 100644 index 8c3c18f..0000000 --- a/src/view.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "view.h" - -#if defined( DEBUG_CULLING ) - -#include - -char g_cull_stats[1024]; -int g_count_dots; -int g_count_planes; -int g_count_oriented_planes; -int g_count_bboxs; -int g_count_oriented_bboxs; - -#endif - -void Cull_ResetStats() -{ -#if defined( DEBUG_CULLING ) - g_count_dots = 0; - g_count_planes = 0; - g_count_oriented_planes = 0; - g_count_bboxs = 0; - g_count_oriented_bboxs = 0; -#endif -} - - -const char *Cull_GetStats() -{ -#if defined( DEBUG_CULLING ) - sprintf(g_cull_stats, "dots: %d | planes %d + %d | bboxs %d + %d", g_count_dots, g_count_planes, - g_count_oriented_planes, g_count_bboxs, g_count_oriented_bboxs); - return g_cull_stats; -#else - return ""; -#endif -} diff --git a/src/view.h b/src/view.h deleted file mode 100644 index fa64b31..0000000 --- a/src/view.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_VIEW_H ) -#define INCLUDED_VIEW_H - -#include "globaldefs.h" -#include "cullable.h" -#include "math/frustum.h" - - -#if GDEF_DEBUG -#define DEBUG_CULLING -#endif - - -#if defined( DEBUG_CULLING ) - -extern int g_count_dots; -extern int g_count_planes; -extern int g_count_oriented_planes; -extern int g_count_bboxs; -extern int g_count_oriented_bboxs; - -#endif - -inline void debug_count_dot() -{ -#if defined( DEBUG_CULLING ) - ++g_count_dots; -#endif -} - -inline void debug_count_plane() -{ -#if defined( DEBUG_CULLING ) - ++g_count_planes; -#endif -} - -inline void debug_count_oriented_plane() -{ -#if defined( DEBUG_CULLING ) - ++g_count_oriented_planes; -#endif -} - -inline void debug_count_bbox() -{ -#if defined( DEBUG_CULLING ) - ++g_count_bboxs; -#endif -} - -inline void debug_count_oriented_bbox() -{ -#if defined( DEBUG_CULLING ) - ++g_count_oriented_bboxs; -#endif -} - - -/// \brief View-volume culling and transformations. -class View : public VolumeTest { -/// modelview matrix -Matrix4 m_modelview; -/// projection matrix -Matrix4 m_projection; -/// device-to-screen transform -Matrix4 m_viewport; - -Matrix4 m_scissor; - -/// combined modelview and projection matrix -Matrix4 m_viewproj; -/// camera position in world space -Vector4 m_viewer; -/// view frustum in world space -Frustum m_frustum; - -bool m_fill; - -void construct() -{ - m_viewproj = matrix4_multiplied_by_matrix4(matrix4_multiplied_by_matrix4(m_scissor, m_projection), m_modelview); - - m_frustum = frustum_from_viewproj(m_viewproj); - m_viewer = viewer_from_viewproj(m_viewproj); -} - -public: -View(bool fill = false) : - m_modelview(g_matrix4_identity), - m_projection(g_matrix4_identity), - m_scissor(g_matrix4_identity), - m_fill(fill) -{ -} - -void Construct(const Matrix4 &projection, const Matrix4 &modelview, std::size_t width, std::size_t height) -{ - // modelview - m_modelview = modelview; - - // projection - m_projection = projection; - - // viewport - m_viewport = g_matrix4_identity; - m_viewport[0] = float(width / 2); - m_viewport[5] = float(height / 2); - if (fabs(m_projection[11]) > 0.0000001) { - m_viewport[10] = m_projection[0] * m_viewport[0]; - } else { - m_viewport[10] = 1 / m_projection[10]; - } - - construct(); -} - -void EnableScissor(float min_x, float max_x, float min_y, float max_y) -{ - m_scissor = g_matrix4_identity; - m_scissor[0] = static_cast((max_x - min_x) * 0.5 ); - m_scissor[5] = static_cast((max_y - min_y) * 0.5 ); - m_scissor[12] = static_cast((min_x + max_x) * 0.5 ); - m_scissor[13] = static_cast((min_y + max_y) * 0.5 ); - matrix4_full_invert(m_scissor); - - construct(); -} - -void DisableScissor() -{ - m_scissor = g_matrix4_identity; - - construct(); -} - -bool TestPoint(const Vector3 &point) const -{ - return viewproj_test_point(m_viewproj, point); -} - -bool TestLine(const Segment &segment) const -{ - return frustum_test_line(m_frustum, segment); -} - -bool TestPlane(const Plane3 &plane) const -{ - debug_count_plane(); - return viewer_test_plane(m_viewer, plane); -} - -bool TestPlane(const Plane3 &plane, const Matrix4 &localToWorld) const -{ - debug_count_oriented_plane(); - return viewer_test_transformed_plane(m_viewer, plane, localToWorld); -} - -VolumeIntersectionValue TestAABB(const AABB &aabb) const -{ - debug_count_bbox(); - return frustum_test_aabb(m_frustum, aabb); -} - -VolumeIntersectionValue TestAABB(const AABB &aabb, const Matrix4 &localToWorld) const -{ - debug_count_oriented_bbox(); - return frustum_intersects_transformed_aabb(m_frustum, aabb, localToWorld); -} - -const Matrix4 &GetViewMatrix() const -{ - return m_viewproj; -} - -const Matrix4 &GetViewport() const -{ - return m_viewport; -}; - -const Matrix4 &GetModelview() const -{ - return m_modelview; -} - -const Matrix4 &GetProjection() const -{ - return m_projection; -} - -bool fill() const -{ - return m_fill; -} - -const Vector3 &getViewer() const -{ - return vector4_to_vector3(m_viewer); -} -}; - -#endif diff --git a/tools/vmap/vis.c b/src/vis.c similarity index 100% rename from tools/vmap/vis.c rename to src/vis.c diff --git a/tools/vmap/visflow.c b/src/visflow.c similarity index 100% rename from tools/vmap/visflow.c rename to src/visflow.c diff --git a/tools/vmap/vmap.h b/src/vmap.h similarity index 100% rename from tools/vmap/vmap.h rename to src/vmap.h diff --git a/src/watchbsp.cpp b/src/watchbsp.cpp deleted file mode 100644 index a965c58..0000000 --- a/src/watchbsp.cpp +++ /dev/null @@ -1,821 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//----------------------------------------------------------------------------- -// -// DESCRIPTION: -// monitoring window for running BSP processes (and possibly various other stuff) - -#include "watchbsp.h" -#include "globaldefs.h" - -#include - -#include "cmdlib.h" -#include "convert.h" -#include "string/string.h" -#include "stream/stringstream.h" - -#include "gtkutil/messagebox.h" -#include "xmlstuff.h" -#include "console.h" -#include "preferences.h" -#include "points.h" -#include "feedback.h" -#include "mainframe.h" -#include "sockets.h" - -void message_flush(message_info_t *self) -{ - Sys_Print(self->msg_level, self->m_buffer, self->m_length); - self->m_length = 0; -} - -void message_print(message_info_t *self, const char *characters, std::size_t length) -{ - const char *end = characters + length; - while (characters != end) { - std::size_t space = message_info_t::bufsize - 1 - self->m_length; - if (space == 0) { - message_flush(self); - } else { - std::size_t size = std::min(space, std::size_t(end - characters)); - memcpy(self->m_buffer + self->m_length, characters, size); - self->m_length += size; - characters += size; - } - } -} - - -#include -#include -#include "xmlstuff.h" - -class CWatchBSP { -private: -// a flag we have set to true when using an external BSP plugin -// the resulting code with that is a bit dirty, cleaner solution would be to seperate the succession of commands from the listening loop -// (in two seperate classes probably) -bool m_bBSPPlugin; - -// EIdle: we are not listening -// DoMonitoringLoop will change state to EBeginStep -// EBeginStep: the socket is up for listening, we are expecting incoming connection -// incoming connection will change state to EWatching -// EWatching: we have a connection, monitor it -// connection closed will see if we start a new step (EBeginStep) or launch Quake3 and end (EIdle) -enum EWatchBSPState { EIdle, EBeginStep, EWatching } m_eState; -socket_t *m_pListenSocket; -socket_t *m_pInSocket; -netmessage_t msg; -GPtrArray *m_pCmd; -// used to timeout EBeginStep -GTimer *m_pTimer; -std::size_t m_iCurrentStep; -// name of the map so we can run the engine -char *m_sBSPName; -// buffer we use in push mode to receive data directly from the network -xmlParserInputBufferPtr m_xmlInputBuffer; -xmlParserInputPtr m_xmlInput; -xmlParserCtxtPtr m_xmlParserCtxt; - -// call this to switch the set listening mode -bool SetupListening(); - -// start a new EBeginStep -void DoEBeginStep(); - -// the xml and sax parser state -char m_xmlBuf[MAX_NETMESSAGE]; -bool m_bNeedCtxtInit; -message_info_t m_message_info; - -public: -CWatchBSP() -{ - m_pCmd = 0; - m_bBSPPlugin = false; - m_pListenSocket = NULL; - m_pInSocket = NULL; - m_eState = EIdle; - m_pTimer = g_timer_new(); - m_sBSPName = NULL; - m_xmlInputBuffer = NULL; - m_bNeedCtxtInit = true; -} - -virtual ~CWatchBSP() -{ - EndMonitoringLoop(); - Net_Shutdown(); - - g_timer_destroy(m_pTimer); -} - -bool HasBSPPlugin() const -{ - return m_bBSPPlugin; -} - -// called regularly to keep listening -void RoutineProcessing(); - -// start a monitoring loop with the following steps -void DoMonitoringLoop(GPtrArray *pCmd, const char *sBSPName); - -void EndMonitoringLoop() -{ - Reset(); - if (m_sBSPName) { - string_release(m_sBSPName, string_length(m_sBSPName)); - m_sBSPName = 0; - } - if (m_pCmd) { - g_ptr_array_free(m_pCmd, TRUE); - m_pCmd = 0; - } -} - -// close everything - may be called from the outside to abort the process -void Reset(); - -// start a listening loop for an external process, possibly a BSP plugin -void ExternalListen(); -}; - -CWatchBSP *g_pWatchBSP; - -// watch the BSP process through network connections -// true: trigger the BSP steps one by one and monitor them through the network -// false: create a BAT / .sh file and execute it. don't bother monitoring it. -bool g_WatchBSP_Enabled = true; -// do we stop the compilation process if we come accross a leak? -bool g_WatchBSP_LeakStop = true; -bool g_WatchBSP_RunQuake = false; -// store prefs setting for automatic sleep mode activation -bool g_WatchBSP_DoSleep = true; -// timeout when beginning a step (in seconds) -// if we don't get a connection quick enough we assume something failed and go back to idling -int g_WatchBSP_Timeout = 10; - - -void Build_constructPreferences(PreferencesPage &page) -{ - ui::CheckButton monitorbsp = page.appendCheckBox("", "Enable Build Process Monitoring", g_WatchBSP_Enabled); - ui::CheckButton leakstop = page.appendCheckBox("", "Stop Compilation on Leak", g_WatchBSP_LeakStop); - ui::CheckButton runengine = page.appendCheckBox("", "Run Engine After Compile", g_WatchBSP_RunQuake); - ui::CheckButton sleep = page.appendCheckBox("", "Sleep When Running the Engine", g_WatchBSP_DoSleep); - Widget_connectToggleDependency(leakstop, monitorbsp); - Widget_connectToggleDependency(runengine, monitorbsp); - Widget_connectToggleDependency(sleep, runengine); -} - -void Build_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Build", "Build Preferences")); - Build_constructPreferences(page); -} - -void Build_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Build_constructPage)); -} - -#include "preferencesystem.h" -#include "stringio.h" - -void BuildMonitor_Construct() -{ - g_pWatchBSP = new CWatchBSP(); - - g_WatchBSP_Enabled = !string_equal(g_pGameDescription->getKeyValue("no_bsp_monitor"), "1"); - - GlobalPreferenceSystem().registerPreference("WatchBSP", make_property_string(g_WatchBSP_Enabled)); - GlobalPreferenceSystem().registerPreference("RunQuake2Run", make_property_string(g_WatchBSP_RunQuake)); - GlobalPreferenceSystem().registerPreference("LeakStop", make_property_string(g_WatchBSP_LeakStop)); - GlobalPreferenceSystem().registerPreference("SleepMode", make_property_string(g_WatchBSP_DoSleep)); - - Build_registerPreferencesPage(); -} - -void BuildMonitor_Destroy() -{ - delete g_pWatchBSP; -} - -CWatchBSP *GetWatchBSP() -{ - return g_pWatchBSP; -} - -void BuildMonitor_Run(GPtrArray *commands, const char *mapName) -{ - GetWatchBSP()->DoMonitoringLoop(commands, mapName); -} - - -// Static functions for the SAX callbacks ------------------------------------------------------- - -// utility for saxStartElement below -static void abortStream(message_info_t *data) -{ - GetWatchBSP()->EndMonitoringLoop(); - // tell there has been an error -#if 0 - if ( GetWatchBSP()->HasBSPPlugin() ) { - g_BSPFrontendTable.m_pfnEndListen( 2 ); - } -#endif - // yeah this doesn't look good.. but it's needed so that everything will be ignored until the stream goes out - data->ignore_depth = -1; - data->recurse++; -} - -#include "stream_version.h" - -static void saxStartElement(message_info_t *data, const xmlChar *name, const xmlChar **attrs) -{ -#if 0 - globalOutputStream() << "<" << name; - if ( attrs != 0 ) { - for ( const xmlChar** p = attrs; *p != 0; p += 2 ) - { - globalOutputStream() << " " << p[0] << "=" << makeQuoted( p[1] ); - } - } - globalOutputStream() << ">\n"; -#endif - - if (data->ignore_depth == 0) { - if (data->pGeometry != 0) { - // we have a handler - data->pGeometry->saxStartElement(data, name, attrs); - } else { - if (strcmp(reinterpret_cast( name ), "q3map_feedback") == 0) { - // check the correct version - // old q3map don't send a version attribute - // the ones we support .. send Q3MAP_STREAM_VERSION - if (!attrs[0] || !attrs[1] || (strcmp(reinterpret_cast( attrs[0] ), "version") != 0)) { - message_flush(data); - globalErrorStream() - << "No stream version given in the feedback stream, this is an old q3map version.\n" - "Please turn off monitored compiling if you still wish to use this q3map executable\n"; - abortStream(data); - return; - } else if (strcmp(reinterpret_cast( attrs[1] ), Q3MAP_STREAM_VERSION) != 0) { - message_flush(data); - globalErrorStream() << - "This version of Radiant reads version " Q3MAP_STREAM_VERSION " debug streams, I got an incoming connection with version " - << reinterpret_cast( attrs[1] ) << "\n" - "Please make sure your versions of Radiant and q3map are matching.\n"; - abortStream(data); - return; - } - } - // we don't treat locally - else if (strcmp(reinterpret_cast( name ), "message") == 0) { - int msg_level = atoi(reinterpret_cast( attrs[1] )); - if (msg_level != data->msg_level) { - message_flush(data); - data->msg_level = msg_level; - } - } else if (strcmp(reinterpret_cast( name ), "polyline") == 0) { - // polyline has a particular status .. right now we only use it for leakfile .. - data->geometry_depth = data->recurse; - data->pGeometry = &g_pointfile; - data->pGeometry->saxStartElement(data, name, attrs); - } else if (strcmp(reinterpret_cast( name ), "select") == 0) { - CSelectMsg *pSelect = new CSelectMsg(); - data->geometry_depth = data->recurse; - data->pGeometry = pSelect; - data->pGeometry->saxStartElement(data, name, attrs); - } else if (strcmp(reinterpret_cast( name ), "pointmsg") == 0) { - CPointMsg *pPoint = new CPointMsg(); - data->geometry_depth = data->recurse; - data->pGeometry = pPoint; - data->pGeometry->saxStartElement(data, name, attrs); - } else if (strcmp(reinterpret_cast( name ), "windingmsg") == 0) { - CWindingMsg *pWinding = new CWindingMsg(); - data->geometry_depth = data->recurse; - data->pGeometry = pWinding; - data->pGeometry->saxStartElement(data, name, attrs); - } else { - globalErrorStream() << "Warning: ignoring unrecognized node in XML stream (" - << reinterpret_cast( name ) << ")\n"; - // we don't recognize this node, jump over it - // (NOTE: the ignore mechanism is a bit screwed, only works when starting an ignore at the highest level) - data->ignore_depth = data->recurse; - } - } - } - data->recurse++; -} - -static void saxEndElement(message_info_t *data, const xmlChar *name) -{ -#if 0 - globalOutputStream() << "<" << name << "/>\n"; -#endif - - data->recurse--; - // we are out of an ignored chunk - if (data->recurse == data->ignore_depth) { - data->ignore_depth = 0; - return; - } - if (data->pGeometry != 0) { - data->pGeometry->saxEndElement(data, name); - // we add the object to the debug window - if (data->geometry_depth == data->recurse) { - g_DbgDlg.Push(data->pGeometry); - data->pGeometry = 0; - } - } - if (data->recurse == data->stop_depth) { - message_flush(data); -#if GDEF_DEBUG - globalOutputStream() << "Received error msg .. shutting down..\n"; -#endif - GetWatchBSP()->EndMonitoringLoop(); - // tell there has been an error -#if 0 - if ( GetWatchBSP()->HasBSPPlugin() ) { - g_BSPFrontendTable.m_pfnEndListen( 2 ); - } -#endif - return; - } -} - -class MessageOutputStream : public TextOutputStream { -message_info_t *m_data; -public: -MessageOutputStream(message_info_t *data) : m_data(data) -{ -} - -std::size_t write(const char *buffer, std::size_t length) -{ - if (m_data->pGeometry != 0) { - m_data->pGeometry->saxCharacters(m_data, reinterpret_cast( buffer ), int(length)); - } else { - if (m_data->ignore_depth == 0) { - // output the message using the level - message_print(m_data, buffer, length); - // if this message has error level flag, we mark the depth to stop the compilation when we get out - // we don't set the msg level if we don't stop on leak - if (m_data->msg_level == 3) { - m_data->stop_depth = m_data->recurse - 1; - } - } - } - - return length; -} -}; - -template -inline MessageOutputStream &operator<<(MessageOutputStream &ostream, const T &t) -{ - return ostream_write(ostream, t); -} - -static void saxCharacters(message_info_t *data, const xmlChar *ch, int len) -{ - MessageOutputStream ostream(data); - ostream << StringRange(reinterpret_cast( ch ), reinterpret_cast( ch + len )); -} - -static void saxComment(void *ctx, const xmlChar *msg) -{ - globalOutputStream() << "XML comment: " << reinterpret_cast( msg ) << "\n"; -} - -static void saxWarning(void *ctx, const char *msg, ...) -{ - char saxMsgBuffer[4096]; - va_list args; - - va_start(args, msg); - vsprintf(saxMsgBuffer, msg, args); - va_end(args); - globalOutputStream() << "XML warning: " << saxMsgBuffer << "\n"; -} - -static void saxError(void *ctx, const char *msg, ...) -{ - char saxMsgBuffer[4096]; - va_list args; - - va_start(args, msg); - vsprintf(saxMsgBuffer, msg, args); - va_end(args); - globalErrorStream() << "XML error: " << saxMsgBuffer << "\n"; -} - -static void saxFatal(void *ctx, const char *msg, ...) -{ - char buffer[4096]; - - va_list args; - - va_start(args, msg); - vsprintf(buffer, msg, args); - va_end(args); - globalErrorStream() << "XML fatal error: " << buffer << "\n"; -} - -static xmlSAXHandler saxParser = { - 0, /* internalSubset */ - 0, /* isStandalone */ - 0, /* hasInternalSubset */ - 0, /* hasExternalSubset */ - 0, /* resolveEntity */ - 0, /* getEntity */ - 0, /* entityDecl */ - 0, /* notationDecl */ - 0, /* attributeDecl */ - 0, /* elementDecl */ - 0, /* unparsedEntityDecl */ - 0, /* setDocumentLocator */ - 0, /* startDocument */ - 0, /* endDocument */ - (startElementSAXFunc) saxStartElement, /* startElement */ - (endElementSAXFunc) saxEndElement, /* endElement */ - 0, /* reference */ - (charactersSAXFunc) saxCharacters, /* characters */ - 0, /* ignorableWhitespace */ - 0, /* processingInstruction */ - (commentSAXFunc) saxComment, /* comment */ - (warningSAXFunc) saxWarning, /* warning */ - (errorSAXFunc) saxError, /* error */ - (fatalErrorSAXFunc) saxFatal, /* fatalError */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - -// ------------------------------------------------------------------------------------------------ - - -guint s_routine_id; - -static gint watchbsp_routine(gpointer data) -{ - reinterpret_cast( data )->RoutineProcessing(); - return TRUE; -} - -void CWatchBSP::Reset() -{ - if (m_pInSocket) { - Net_Disconnect(m_pInSocket); - m_pInSocket = NULL; - } - if (m_pListenSocket) { - Net_Disconnect(m_pListenSocket); - m_pListenSocket = NULL; - } - if (m_xmlInputBuffer) { - xmlFreeParserInputBuffer(m_xmlInputBuffer); - m_xmlInputBuffer = NULL; - } - m_eState = EIdle; - if (s_routine_id) { - g_source_remove(s_routine_id); - } -} - -bool CWatchBSP::SetupListening() -{ -#if GDEF_DEBUG - if (m_pListenSocket) { - globalOutputStream() << "ERROR: m_pListenSocket != NULL in CWatchBSP::SetupListening\n"; - return false; - } -#endif - globalOutputStream() << "Setting up\n"; - Net_Setup(); - m_pListenSocket = Net_ListenSocket(39000); - if (m_pListenSocket == NULL) { - return false; - } - globalOutputStream() << "Listening...\n"; - return true; -} - -void CWatchBSP::DoEBeginStep() -{ - Reset(); - if (SetupListening() == false) { - const char *msg = "Failed to get a listening socket on port 39000.\nTry running with Build monitoring disabled if you can't fix this.\n"; - globalOutputStream() << msg; - ui::alert(MainFrame_getWindow(), msg, "Build monitoring", ui::alert_type::OK, ui::alert_icon::Error); - return; - } - // set the timer for timeouts and step cancellation - g_timer_reset(m_pTimer); - g_timer_start(m_pTimer); - - if (!m_bBSPPlugin) { - globalOutputStream() << "=== running build command ===\n" - << static_cast(g_ptr_array_index(m_pCmd, m_iCurrentStep) ) << "\n"; - - if (!Q_Exec(NULL, (char *) g_ptr_array_index(m_pCmd, m_iCurrentStep), NULL, true, false)) { - StringOutputStream msg(256); - msg << "Failed to execute the following command: "; - msg << reinterpret_cast(g_ptr_array_index(m_pCmd, m_iCurrentStep) ); - msg << "\nCheck that the file exists and that you don't run out of system resources.\n"; - globalOutputStream() << msg.c_str(); - ui::alert(MainFrame_getWindow(), msg.c_str(), "Build monitoring", ui::alert_type::OK, - ui::alert_icon::Error); - return; - } - // re-initialise the debug window - if (m_iCurrentStep == 0) { - g_DbgDlg.Init(); - } - } - m_eState = EBeginStep; - s_routine_id = g_timeout_add(25, watchbsp_routine, this); -} - - -#if GDEF_OS_WINDOWS -const char *ENGINE_ATTRIBUTE = "engine_win32"; -const char *MP_ENGINE_ATTRIBUTE = "mp_engine_win32"; -#elif GDEF_OS_LINUX || GDEF_OS_BSD -const char *ENGINE_ATTRIBUTE = "engine_linux"; -const char *MP_ENGINE_ATTRIBUTE = "mp_engine_linux"; -#elif GDEF_OS_MACOS -const char *ENGINE_ATTRIBUTE = "engine_macos"; -const char *MP_ENGINE_ATTRIBUTE = "mp_engine_macos"; -#else -#error "unsupported platform" -#endif - -class RunEngineConfiguration { -public: -const char *executable; -const char *mp_executable; -bool do_sp_mp; - -RunEngineConfiguration() : - executable(g_pGameDescription->getRequiredKeyValue(ENGINE_ATTRIBUTE)), - mp_executable(g_pGameDescription->getKeyValue(MP_ENGINE_ATTRIBUTE)) -{ - do_sp_mp = !string_empty(mp_executable); -} -}; - -inline void GlobalGameDescription_string_write_mapparameter(StringOutputStream &string, const char *mapname) -{ - if (g_pGameDescription->mGameType == "q2" - || g_pGameDescription->mGameType == "heretic2") { - string << ". +exec radiant.cfg +map " << mapname; - } else { - string << "+set sv_pure 0 "; - // TTimo: a check for vm_* but that's all fine - //cmdline = "+set sv_pure 0 +set vm_ui 0 +set vm_cgame 0 +set vm_game 0 "; - const char *fs_game = gamename_get(); - if (!string_equal(fs_game, basegame_get())) { - string << "+set fs_game " << fs_game << " "; - } - if (g_pGameDescription->mGameType == "wolf") { - //|| g_pGameDescription->mGameType == "et") - if (string_equal(gamemode_get(), "mp")) { - // MP - string << "+devmap " << mapname; - } else { - // SP - string << "+set nextmap \"spdevmap " << mapname << "\""; - } - } else { - string << "+devmap " << mapname; - } - } -} - - -void CWatchBSP::RoutineProcessing() -{ - switch (m_eState) { - case EBeginStep: - // timeout: if we don't get an incoming connection fast enough, go back to idle - if (g_timer_elapsed(m_pTimer, NULL) > g_WatchBSP_Timeout) { - ui::alert(MainFrame_getWindow(), - "The connection timed out, assuming the build process failed\nMake sure you are using a networked version of Q3Map?\nOtherwise you need to disable BSP Monitoring in prefs.", - "BSP process monitoring", ui::alert_type::OK); - EndMonitoringLoop(); -#if 0 - if ( m_bBSPPlugin ) { - // status == 1 : didn't get the connection - g_BSPFrontendTable.m_pfnEndListen( 1 ); - } -#endif - return; - } -#if GDEF_DEBUG - // some debug checks - if (!m_pListenSocket) { - globalErrorStream() - << "ERROR: m_pListenSocket == NULL in CWatchBSP::RoutineProcessing EBeginStep state\n"; - return; - } -#endif - // we are not connected yet, accept any incoming connection - m_pInSocket = Net_Accept(m_pListenSocket); - if (m_pInSocket) { - globalOutputStream() << "Connected.\n"; - // prepare the message info struct for diving in - memset(&m_message_info, 0, sizeof(message_info_t)); - // a dumb flag to make sure we init the push parser context when first getting a msg - m_bNeedCtxtInit = true; - m_eState = EWatching; - } - break; - case EWatching: { -#if GDEF_DEBUG - // some debug checks - if (!m_pInSocket) { - globalErrorStream() << "ERROR: m_pInSocket == NULL in CWatchBSP::RoutineProcessing EWatching state\n"; - return; - } -#endif - - int ret = Net_Wait(m_pInSocket, 0, 0); - if (ret == -1) { - globalOutputStream() << "WARNING: SOCKET_ERROR in CWatchBSP::RoutineProcessing\n"; - globalOutputStream() << "Terminating the connection.\n"; - EndMonitoringLoop(); - return; - } - - if (ret == 1) { - // the socket has been identified, there's something (message or disconnection) - // see if there's anything in input - ret = Net_Receive(m_pInSocket, &msg); - if (ret > 0) { - // unsigned int size = msg.size; //++timo just a check - strcpy(m_xmlBuf, NMSG_ReadString(&msg)); - if (m_bNeedCtxtInit) { - m_xmlParserCtxt = NULL; - m_xmlParserCtxt = xmlCreatePushParserCtxt(&saxParser, &m_message_info, m_xmlBuf, - static_cast( strlen(m_xmlBuf)), NULL); - - if (m_xmlParserCtxt == NULL) { - globalErrorStream() << "Failed to create the XML parser (incoming stream began with: " - << m_xmlBuf << ")\n"; - EndMonitoringLoop(); - } - m_bNeedCtxtInit = false; - } else { - xmlParseChunk(m_xmlParserCtxt, m_xmlBuf, static_cast( strlen(m_xmlBuf)), 0); - } - } else { - message_flush(&m_message_info); - // error or connection closed/reset - // NOTE: if we get an error down the XML stream we don't reach here - Net_Disconnect(m_pInSocket); - m_pInSocket = NULL; - globalOutputStream() << "Connection closed.\n"; -#if 0 - if ( m_bBSPPlugin ) { - EndMonitoringLoop(); - // let the BSP plugin know that the job is done - g_BSPFrontendTable.m_pfnEndListen( 0 ); - return; - } -#endif - // move to next step or finish - m_iCurrentStep++; - if (m_iCurrentStep < m_pCmd->len) { - DoEBeginStep(); - } else { - // launch the engine .. OMG - if (g_WatchBSP_RunQuake) { -#if 0 - // do we enter sleep mode before? - if ( g_WatchBSP_DoSleep ) { - globalOutputStream() << "Going into sleep mode..\n"; - g_pParentWnd->OnSleep(); - } -#endif - globalOutputStream() << "Running engine...\n"; - StringOutputStream cmd(256); - // build the command line - cmd << EnginePath_get(); - // this is game dependant - - RunEngineConfiguration engineConfig; - - if (engineConfig.do_sp_mp) { - if (string_equal(gamemode_get(), "mp")) { - cmd << engineConfig.mp_executable; - } else { - cmd << engineConfig.executable; - } - } else { - cmd << engineConfig.executable; - } - - StringOutputStream cmdline; - - GlobalGameDescription_string_write_mapparameter(cmdline, m_sBSPName); - - globalOutputStream() << cmd.c_str() << " " << cmdline.c_str() << "\n"; - - // execute now - if (!Q_Exec(cmd.c_str(), (char *) cmdline.c_str(), EnginePath_get(), false, false)) { - StringOutputStream msg; - msg << "Failed to execute the following command: " << cmd.c_str() << cmdline.c_str(); - globalOutputStream() << msg.c_str(); - ui::alert(MainFrame_getWindow(), msg.c_str(), "Build monitoring", ui::alert_type::OK, - ui::alert_icon::Error); - } - } - EndMonitoringLoop(); - } - } - } - } - break; - default: - break; - } -} - -GPtrArray *str_ptr_array_clone(GPtrArray *array) -{ - GPtrArray *cloned = g_ptr_array_sized_new(array->len); - for (guint i = 0; i < array->len; ++i) { - g_ptr_array_add(cloned, g_strdup((char *) g_ptr_array_index(array, i))); - } - return cloned; -} - -void CWatchBSP::DoMonitoringLoop(GPtrArray *pCmd, const char *sBSPName) -{ - m_sBSPName = string_clone(sBSPName); - if (m_eState != EIdle) { - globalOutputStream() << "WatchBSP got a monitoring request while not idling...\n"; - // prompt the user, should we cancel the current process and go ahead? - if (ui::alert(MainFrame_getWindow(), - "I am already monitoring a Build process.\nDo you want me to override and start a new compilation?", - "Build process monitoring", ui::alert_type::YESNO) == ui::alert_response::YES) { - // disconnect and set EIdle state - Reset(); - } - } - m_pCmd = str_ptr_array_clone(pCmd); - m_iCurrentStep = 0; - DoEBeginStep(); -} - -void CWatchBSP::ExternalListen() -{ - m_bBSPPlugin = true; - DoEBeginStep(); -} - -// the part of the watchbsp interface we export to plugins -// NOTE: in the long run, the whole watchbsp.cpp interface needs to go out and be handled at the BSP plugin level -// for now we provide something really basic and limited, the essential is to have something that works fine and fast (for 1.1 final) -void QERApp_Listen() -{ - // open the listening socket - GetWatchBSP()->ExternalListen(); -} diff --git a/src/watchbsp.h b/src/watchbsp.h deleted file mode 100644 index b8f4345..0000000 --- a/src/watchbsp.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined( INCLUDED_WATCHBSP_H ) -#define INCLUDED_WATCHBSP_H - -void BuildMonitor_Construct(); - -void BuildMonitor_Destroy(); - -typedef struct _GPtrArray GPtrArray; - -void BuildMonitor_Run(GPtrArray *commands, const char *mapName); - -extern bool g_WatchBSP_Enabled; -extern bool g_WatchBSP_LeakStop; - -#endif diff --git a/src/winding.cpp b/src/winding.cpp deleted file mode 100644 index c443e47..0000000 --- a/src/winding.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "winding.h" - -#include - -#include "math/line.h" - - -inline double plane3_distance_to_point(const Plane3 &plane, const DoubleVector3 &point) -{ - return vector3_dot(point, plane.normal()) - plane.dist(); -} - -inline double plane3_distance_to_point(const Plane3 &plane, const Vector3 &point) -{ - return vector3_dot(point, plane.normal()) - plane.dist(); -} - -/// \brief Returns the point at which \p line intersects \p plane, or an undefined value if there is no intersection. -inline DoubleVector3 line_intersect_plane(const DoubleLine &line, const Plane3 &plane) -{ - return line.origin + vector3_scaled( - line.direction, - -plane3_distance_to_point(plane, line.origin) - / vector3_dot(line.direction, plane.normal()) - ); -} - -inline bool float_is_largest_absolute(double axis, double other) -{ - return fabs(axis) > fabs(other); -} - -/// \brief Returns the index of the component of \p v that has the largest absolute value. -inline int vector3_largest_absolute_component_index(const DoubleVector3 &v) -{ - return (float_is_largest_absolute(v[1], v[0])) - ? (float_is_largest_absolute(v[1], v[2])) - ? 1 - : 2 - : (float_is_largest_absolute(v[0], v[2])) - ? 0 - : 2; -} - -/// \brief Returns the infinite line that is the intersection of \p plane and \p other. -inline DoubleLine plane3_intersect_plane3(const Plane3 &plane, const Plane3 &other) -{ - DoubleLine line; - line.direction = vector3_cross(plane.normal(), other.normal()); - switch (vector3_largest_absolute_component_index(line.direction)) { - case 0: - line.origin.x() = 0; - line.origin.y() = - (-other.dist() * plane.normal().z() - -plane.dist() * other.normal().z()) / line.direction.x(); - line.origin.z() = - (-plane.dist() * other.normal().y() - -other.dist() * plane.normal().y()) / line.direction.x(); - break; - case 1: - line.origin.x() = - (-plane.dist() * other.normal().z() - -other.dist() * plane.normal().z()) / line.direction.y(); - line.origin.y() = 0; - line.origin.z() = - (-other.dist() * plane.normal().x() - -plane.dist() * other.normal().x()) / line.direction.y(); - break; - case 2: - line.origin.x() = - (-other.dist() * plane.normal().y() - -plane.dist() * other.normal().y()) / line.direction.z(); - line.origin.y() = - (-plane.dist() * other.normal().x() - -other.dist() * plane.normal().x()) / line.direction.z(); - line.origin.z() = 0; - break; - default: - break; - } - - return line; -} - - -/// \brief Keep the value of \p infinity as small as possible to improve precision in Winding_Clip. -void Winding_createInfinite(FixedWinding &winding, const Plane3 &plane, double infinity) -{ - double max = -infinity; - int x = -1; - for (int i = 0; i < 3; i++) { - double d = fabs(plane.normal()[i]); - if (d > max) { - x = i; - max = d; - } - } - if (x == -1) { - globalErrorStream() << "invalid plane\n"; - return; - } - - DoubleVector3 vup = g_vector3_identity; - switch (x) { - case 0: - case 1: - vup[2] = 1; - break; - case 2: - vup[0] = 1; - break; - } - - - vector3_add(vup, vector3_scaled(plane.normal(), -vector3_dot(vup, plane.normal()))); - vector3_normalise(vup); - - DoubleVector3 org = vector3_scaled(plane.normal(), plane.dist()); - - DoubleVector3 vright = vector3_cross(vup, plane.normal()); - - vector3_scale(vup, infinity); - vector3_scale(vright, infinity); - - // project a really big axis aligned box onto the plane - - DoubleLine r1, r2, r3, r4; - r1.origin = vector3_added(vector3_subtracted(org, vright), vup); - r1.direction = vector3_normalised(vright); - winding.push_back(FixedWindingVertex(r1.origin, r1, c_brush_maxFaces)); - r2.origin = vector3_added(vector3_added(org, vright), vup); - r2.direction = vector3_normalised(vector3_negated(vup)); - winding.push_back(FixedWindingVertex(r2.origin, r2, c_brush_maxFaces)); - r3.origin = vector3_subtracted(vector3_added(org, vright), vup); - r3.direction = vector3_normalised(vector3_negated(vright)); - winding.push_back(FixedWindingVertex(r3.origin, r3, c_brush_maxFaces)); - r4.origin = vector3_subtracted(vector3_subtracted(org, vright), vup); - r4.direction = vector3_normalised(vup); - winding.push_back(FixedWindingVertex(r4.origin, r4, c_brush_maxFaces)); -} - - -inline PlaneClassification Winding_ClassifyDistance(const double distance, const double epsilon) -{ - if (distance > epsilon) { - return ePlaneFront; - } - if (distance < -epsilon) { - return ePlaneBack; - } - return ePlaneOn; -} - -/// \brief Returns true if -/// !flipped && winding is completely BACK or ON -/// or flipped && winding is completely FRONT or ON -bool Winding_TestPlane(const Winding &winding, const Plane3 &plane, bool flipped) -{ - const int test = (flipped) ? ePlaneBack : ePlaneFront; - for (Winding::const_iterator i = winding.begin(); i != winding.end(); ++i) { - if (test == Winding_ClassifyDistance(plane3_distance_to_point(plane, (*i).vertex), ON_EPSILON)) { - return false; - } - } - return true; -} - -/// \brief Returns true if any point in \p w1 is in front of plane2, or any point in \p w2 is in front of plane1 -bool Winding_PlanesConcave(const Winding &w1, const Winding &w2, const Plane3 &plane1, const Plane3 &plane2) -{ - return !Winding_TestPlane(w1, plane2, false) || !Winding_TestPlane(w2, plane1, false); -} - -brushsplit_t Winding_ClassifyPlane(const Winding &winding, const Plane3 &plane) -{ - brushsplit_t split; - for (Winding::const_iterator i = winding.begin(); i != winding.end(); ++i) { - ++split.counts[Winding_ClassifyDistance(plane3_distance_to_point(plane, (*i).vertex), ON_EPSILON)]; - } - return split; -} - - -#define DEBUG_EPSILON ON_EPSILON -const double DEBUG_EPSILON_SQUARED = DEBUG_EPSILON * DEBUG_EPSILON; - -#define WINDING_DEBUG 0 - -/// \brief Clip \p winding which lies on \p plane by \p clipPlane, resulting in \p clipped. -/// If \p winding is completely in front of the plane, \p clipped will be identical to \p winding. -/// If \p winding is completely in back of the plane, \p clipped will be empty. -/// If \p winding intersects the plane, the edge of \p clipped which lies on \p clipPlane will store the value of \p adjacent. -void Winding_Clip(const FixedWinding &winding, const Plane3 &plane, const Plane3 &clipPlane, std::size_t adjacent, - FixedWinding &clipped) -{ - PlaneClassification classification = Winding_ClassifyDistance( - plane3_distance_to_point(clipPlane, winding.back().vertex), ON_EPSILON); - PlaneClassification nextClassification; - // for each edge - for (std::size_t next = 0, i = winding.size() - 1; - next != winding.size(); i = next, ++next, classification = nextClassification) { - nextClassification = Winding_ClassifyDistance(plane3_distance_to_point(clipPlane, winding[next].vertex), - ON_EPSILON); - const FixedWindingVertex &vertex = winding[i]; - - // if first vertex of edge is ON - if (classification == ePlaneOn) { - // append first vertex to output winding - if (nextClassification == ePlaneBack) { - // this edge lies on the clip plane - clipped.push_back( - FixedWindingVertex(vertex.vertex, plane3_intersect_plane3(plane, clipPlane), adjacent)); - } else { - clipped.push_back(vertex); - } - continue; - } - - // if first vertex of edge is FRONT - if (classification == ePlaneFront) { - // add first vertex to output winding - clipped.push_back(vertex); - } - // if second vertex of edge is ON - if (nextClassification == ePlaneOn) { - continue; - } - // else if second vertex of edge is same as first - else if (nextClassification == classification) { - continue; - } - // else if first vertex of edge is FRONT and there are only two edges - else if (classification == ePlaneFront && winding.size() == 2) { - continue; - } - // else first vertex is FRONT and second is BACK or vice versa - else { - // append intersection point of line and plane to output winding - DoubleVector3 mid(line_intersect_plane(vertex.edge, clipPlane)); - - if (classification == ePlaneFront) { - // this edge lies on the clip plane - clipped.push_back(FixedWindingVertex(mid, plane3_intersect_plane3(plane, clipPlane), adjacent)); - } else { - clipped.push_back(FixedWindingVertex(mid, vertex.edge, vertex.adjacent)); - } - } - } -} - -std::size_t Winding_FindAdjacent(const Winding &winding, std::size_t face) -{ - for (std::size_t i = 0; i < winding.numpoints; ++i) { - ASSERT_MESSAGE(winding[i].adjacent != c_brush_maxFaces, "edge connectivity data is invalid"); - if (winding[i].adjacent == face) { - return i; - } - } - return c_brush_maxFaces; -} - -std::size_t Winding_Opposite(const Winding &winding, const std::size_t index, const std::size_t other) -{ - ASSERT_MESSAGE(index < winding.numpoints && other < winding.numpoints, "Winding_Opposite: index out of range"); - - double dist_best = 0; - std::size_t index_best = c_brush_maxFaces; - - Ray edge(ray_for_points(winding[index].vertex, winding[other].vertex)); - - for (std::size_t i = 0; i < winding.numpoints; ++i) { - if (i == index || i == other) { - continue; - } - - double dist_squared = ray_squared_distance_to_point(edge, winding[i].vertex); - - if (dist_squared > dist_best) { - dist_best = dist_squared; - index_best = i; - } - } - return index_best; -} - -std::size_t Winding_Opposite(const Winding &winding, const std::size_t index) -{ - return Winding_Opposite(winding, index, Winding_next(winding, index)); -} - -/// \brief Calculate the \p centroid of the polygon defined by \p winding which lies on plane \p plane. -void Winding_Centroid(const Winding &winding, const Plane3 &plane, Vector3 ¢roid) -{ - double area2 = 0, x_sum = 0, y_sum = 0; - const ProjectionAxis axis = projectionaxis_for_normal(plane.normal()); - const indexremap_t remap = indexremap_for_projectionaxis(axis); - for (std::size_t i = winding.numpoints - 1, j = 0; j < winding.numpoints; i = j, ++j) { - const double ai = winding[i].vertex[remap.x] * winding[j].vertex[remap.y] - - winding[j].vertex[remap.x] * winding[i].vertex[remap.y]; - area2 += ai; - x_sum += (winding[j].vertex[remap.x] + winding[i].vertex[remap.x]) * ai; - y_sum += (winding[j].vertex[remap.y] + winding[i].vertex[remap.y]) * ai; - } - - centroid[remap.x] = static_cast( x_sum / (3 * area2)); - centroid[remap.y] = static_cast( y_sum / (3 * area2)); - { - Ray ray(Vector3(0, 0, 0), Vector3(0, 0, 0)); - ray.origin[remap.x] = centroid[remap.x]; - ray.origin[remap.y] = centroid[remap.y]; - ray.direction[remap.z] = 1; - centroid[remap.z] = static_cast( ray_distance_to_plane(ray, plane)); - } -} diff --git a/src/winding.h b/src/winding.h deleted file mode 100644 index 8ac6f32..0000000 --- a/src/winding.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_WINDING_H ) -#define INCLUDED_WINDING_H - -#include "debugging/debugging.h" - -#include - -#include "math/vector.h" -#include "container/array.h" - -enum ProjectionAxis { - eProjectionAxisX = 0, - eProjectionAxisY = 1, - eProjectionAxisZ = 2, -}; - -const float ProjectionAxisEpsilon = static_cast( 0.0001 ); - -inline bool projectionaxis_better(float axis, float other) -{ - return fabs(axis) > fabs(other) + ProjectionAxisEpsilon; -} - -/// \brief Texture axis precedence: Z > X > Y -inline ProjectionAxis projectionaxis_for_normal(const Vector3 &normal) -{ - return (projectionaxis_better(normal[eProjectionAxisY], normal[eProjectionAxisX])) - ? (projectionaxis_better(normal[eProjectionAxisY], normal[eProjectionAxisZ])) - ? eProjectionAxisY - : eProjectionAxisZ - : (projectionaxis_better(normal[eProjectionAxisX], normal[eProjectionAxisZ])) - ? eProjectionAxisX - : eProjectionAxisZ; -} - - -struct indexremap_t { - indexremap_t(std::size_t _x, std::size_t _y, std::size_t _z) - : x(_x), y(_y), z(_z) - { - } - - std::size_t x, y, z; -}; - -inline indexremap_t indexremap_for_projectionaxis(const ProjectionAxis axis) -{ - switch (axis) { - case eProjectionAxisX: - return indexremap_t(1, 2, 0); - case eProjectionAxisY: - return indexremap_t(2, 0, 1); - default: - return indexremap_t(0, 1, 2); - } -} - -enum PlaneClassification { - ePlaneFront = 0, - ePlaneBack = 1, - ePlaneOn = 2, -}; - -#define MAX_POINTS_ON_WINDING 64 -const std::size_t c_brush_maxFaces = 1024; - - -class WindingVertex { -public: -Vector3 vertex; -Vector2 texcoord; -Vector3 tangent; -Vector3 bitangent; -std::size_t adjacent; -}; - - -struct Winding { - typedef Array container_type; - - std::size_t numpoints; - container_type points; - - typedef container_type::iterator iterator; - typedef container_type::const_iterator const_iterator; - - Winding() : numpoints(0) - { - } - - Winding(std::size_t size) : numpoints(0), points(size) - { - } - - void resize(std::size_t size) - { - points.resize(size); - numpoints = 0; - } - - iterator begin() - { - return points.begin(); - } - - const_iterator begin() const - { - return points.begin(); - } - - iterator end() - { - return points.begin() + numpoints; - } - - const_iterator end() const - { - return points.begin() + numpoints; - } - - WindingVertex &operator[](std::size_t index) - { - ASSERT_MESSAGE(index < points.size(), "winding: index out of bounds"); - return points[index]; - } - - const WindingVertex &operator[](std::size_t index) const - { - ASSERT_MESSAGE(index < points.size(), "winding: index out of bounds"); - return points[index]; - } - - void push_back(const WindingVertex &point) - { - points[numpoints] = point; - ++numpoints; - } - - void erase(iterator point) - { - for (iterator i = point + 1; i != end(); point = i, ++i) { - *point = *i; - } - --numpoints; - } -}; - -typedef BasicVector3 DoubleVector3; - -class DoubleLine { -public: -DoubleVector3 origin; -DoubleVector3 direction; -}; - -class FixedWindingVertex { -public: -DoubleVector3 vertex; -DoubleLine edge; -std::size_t adjacent; - -FixedWindingVertex(const DoubleVector3 &vertex_, const DoubleLine &edge_, std::size_t adjacent_) - : vertex(vertex_), edge(edge_), adjacent(adjacent_) -{ -} -}; - -struct FixedWinding { - typedef std::vector Points; - Points points; - - FixedWinding() - { - points.reserve(MAX_POINTS_ON_WINDING); - } - - FixedWindingVertex &front() - { - return points.front(); - } - - const FixedWindingVertex &front() const - { - return points.front(); - } - - FixedWindingVertex &back() - { - return points.back(); - } - - const FixedWindingVertex &back() const - { - return points.back(); - } - - void clear() - { - points.clear(); - } - - void push_back(const FixedWindingVertex &point) - { - points.push_back(point); - } - - std::size_t size() const - { - return points.size(); - } - - FixedWindingVertex &operator[](std::size_t index) - { - //ASSERT_MESSAGE(index < MAX_POINTS_ON_WINDING, "winding: index out of bounds"); - return points[index]; - } - - const FixedWindingVertex &operator[](std::size_t index) const - { - //ASSERT_MESSAGE(index < MAX_POINTS_ON_WINDING, "winding: index out of bounds"); - return points[index]; - } - -}; - - -inline void Winding_forFixedWinding(Winding &winding, const FixedWinding &fixed) -{ - winding.resize(fixed.size()); - winding.numpoints = fixed.size(); - for (std::size_t i = 0; i < fixed.size(); ++i) { - winding[i].vertex[0] = static_cast( fixed[i].vertex[0] ); - winding[i].vertex[1] = static_cast( fixed[i].vertex[1] ); - winding[i].vertex[2] = static_cast( fixed[i].vertex[2] ); - winding[i].adjacent = fixed[i].adjacent; - } -} - -inline std::size_t Winding_wrap(const Winding &winding, std::size_t i) -{ - ASSERT_MESSAGE(winding.numpoints != 0, "Winding_wrap: empty winding"); - return i % winding.numpoints; -} - -inline std::size_t Winding_next(const Winding &winding, std::size_t i) -{ - return Winding_wrap(winding, ++i); -} - - -class Plane3; - -void Winding_createInfinite(FixedWinding &w, const Plane3 &plane, double infinity); - -const double ON_EPSILON = 1.0 / (1 << 8); - -/// \brief Returns true if edge (\p x, \p y) is smaller than the epsilon used to classify winding points against a plane. -inline bool Edge_isDegenerate(const Vector3 &x, const Vector3 &y) -{ - return vector3_length_squared(y - x) < (ON_EPSILON * ON_EPSILON); -} - -void Winding_Clip(const FixedWinding &winding, const Plane3 &plane, const Plane3 &clipPlane, std::size_t adjacent, - FixedWinding &clipped); - -struct brushsplit_t { - brushsplit_t() - { - counts[0] = 0; - counts[1] = 0; - counts[2] = 0; - } - - brushsplit_t &operator+=(const brushsplit_t &other) - { - counts[0] += other.counts[0]; - counts[1] += other.counts[1]; - counts[2] += other.counts[2]; - return *this; - } - - std::size_t counts[3]; -}; - -brushsplit_t Winding_ClassifyPlane(const Winding &w, const Plane3 &plane); - -bool Winding_PlanesConcave(const Winding &w1, const Winding &w2, const Plane3 &plane1, const Plane3 &plane2); - -bool Winding_TestPlane(const Winding &w, const Plane3 &plane, bool flipped); - -std::size_t Winding_FindAdjacent(const Winding &w, std::size_t face); - -std::size_t Winding_Opposite(const Winding &w, const std::size_t index, const std::size_t other); - -std::size_t Winding_Opposite(const Winding &w, std::size_t index); - -void Winding_Centroid(const Winding &w, const Plane3 &plane, Vector3 ¢roid); - - -inline void Winding_printConnectivity(Winding &winding) -{ - for (Winding::iterator i = winding.begin(); i != winding.end(); ++i) { - std::size_t vertexIndex = std::distance(winding.begin(), i); - globalOutputStream() << "vertex: " << Unsigned(vertexIndex) << " adjacent: " << Unsigned((*i).adjacent) << "\n"; - } -} - -#endif diff --git a/src/windowobservers.cpp b/src/windowobservers.cpp deleted file mode 100644 index 49b92bf..0000000 --- a/src/windowobservers.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "windowobservers.h" - -#include -#include -#include "generic/bitfield.h" - -namespace { -ModifierFlags g_modifier_state = c_modifierNone; -} - -typedef std::vector WindowObservers; - -inline void WindowObservers_OnModifierDown(WindowObservers &observers, ModifierFlags type) -{ - g_modifier_state = bitfield_enable(g_modifier_state, type); - for (WindowObservers::iterator i = observers.begin(); i != observers.end(); ++i) { - (*i)->onModifierDown(type); - } -} - -inline void WindowObservers_OnModifierUp(WindowObservers &observers, ModifierFlags type) -{ - g_modifier_state = bitfield_disable(g_modifier_state, type); - for (WindowObservers::iterator i = observers.begin(); i != observers.end(); ++i) { - (*i)->onModifierUp(type); - } -} - -#include - -gboolean selection_modifier_key_press(ui::Widget widget, GdkEventKey *event, WindowObservers &observers) -{ - switch (event->keyval) { - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - //globalOutputStream() << "Alt PRESSED\n"; - WindowObservers_OnModifierDown(observers, c_modifierAlt); - break; - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - //globalOutputStream() << "Shift PRESSED\n"; - WindowObservers_OnModifierDown(observers, c_modifierShift); - break; - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - //globalOutputStream() << "Control PRESSED\n"; - WindowObservers_OnModifierDown(observers, c_modifierControl); - break; - } - return FALSE; -} - -gboolean selection_modifier_key_release(ui::Widget widget, GdkEventKey *event, WindowObservers &observers) -{ - switch (event->keyval) { - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - //globalOutputStream() << "Alt RELEASED\n"; - WindowObservers_OnModifierUp(observers, c_modifierAlt); - break; - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - //globalOutputStream() << "Shift RELEASED\n"; - WindowObservers_OnModifierUp(observers, c_modifierShift); - break; - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - //globalOutputStream() << "Control RELEASED\n"; - WindowObservers_OnModifierUp(observers, c_modifierControl); - break; - } - return FALSE; -} - -void WindowObservers_UpdateModifier(WindowObservers &observers, ModifierFlags modifiers, ModifierFlags modifier) -{ - if (!bitfield_enabled(g_modifier_state, modifier) && bitfield_enabled(modifiers, modifier)) { - WindowObservers_OnModifierDown(observers, modifier); - } - if (bitfield_enabled(g_modifier_state, modifier) && !bitfield_enabled(modifiers, modifier)) { - WindowObservers_OnModifierUp(observers, modifier); - } -} - -void WindowObservers_UpdateModifiers(WindowObservers &observers, ModifierFlags modifiers) -{ - WindowObservers_UpdateModifier(observers, modifiers, c_modifierAlt); - WindowObservers_UpdateModifier(observers, modifiers, c_modifierShift); - WindowObservers_UpdateModifier(observers, modifiers, c_modifierControl); -} - -gboolean modifiers_button_press(ui::Widget widget, GdkEventButton *event, WindowObservers *observers) -{ - if (event->type == GDK_BUTTON_PRESS) { - WindowObservers_UpdateModifiers(*observers, modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean modifiers_button_release(ui::Widget widget, GdkEventButton *event, WindowObservers *observers) -{ - if (event->type == GDK_BUTTON_RELEASE) { - WindowObservers_UpdateModifiers(*observers, modifiers_for_state(event->state)); - } - return FALSE; -} - -gboolean modifiers_motion(ui::Widget widget, GdkEventMotion *event, WindowObservers *observers) -{ - WindowObservers_UpdateModifiers(*observers, modifiers_for_state(event->state)); - return FALSE; -} - - -WindowObservers g_window_observers; - -void GlobalWindowObservers_updateModifiers(ModifierFlags modifiers) -{ - WindowObservers_UpdateModifiers(g_window_observers, modifiers); -} - -void GlobalWindowObservers_add(WindowObserver *observer) -{ - g_window_observers.push_back(observer); -} - -void GlobalWindowObservers_connectTopLevel(ui::Window window) -{ - window.connect("key_press_event", G_CALLBACK(selection_modifier_key_press), &g_window_observers); - window.connect("key_release_event", G_CALLBACK(selection_modifier_key_release), &g_window_observers); -} - -void GlobalWindowObservers_connectWidget(ui::Widget widget) -{ - widget.connect("button_press_event", G_CALLBACK(modifiers_button_press), &g_window_observers); - widget.connect("button_release_event", G_CALLBACK(modifiers_button_release), &g_window_observers); - widget.connect("motion_notify_event", G_CALLBACK(modifiers_motion), &g_window_observers); -} - -int Get_Modifier_State(void); -ModifierFlags modifiers_for_state(unsigned int state) -{ - ModifierFlags modifiers = c_modifierNone; - if (Get_Modifier_State() & 1) { - modifiers |= c_modifierShift; - } - if (Get_Modifier_State() & 2) { - modifiers |= c_modifierControl; - } - if (Get_Modifier_State() & 4) { - modifiers |= c_modifierAlt; - } - return modifiers; -} - -ModifierFlags modifiers_for_key(unsigned int state) -{ - ModifierFlags modifiers = c_modifierNone; - if (state & GDK_CONTROL_MASK) { - modifiers |= c_modifierShift; - } - if (state & GDK_SHIFT_MASK) { - modifiers |= c_modifierControl; - } - if (state & GDK_MOD1_MASK) { - modifiers |= c_modifierAlt; - } - return modifiers; -} diff --git a/src/windowobservers.h b/src/windowobservers.h deleted file mode 100644 index 7daadc2..0000000 --- a/src/windowobservers.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_WINDOWOBSERVERS_H ) -#define INCLUDED_WINDOWOBSERVERS_H - -#include "windowobserver.h" - -#include - -#include "math/vector.h" - -class WindowObserver; - -void GlobalWindowObservers_add(WindowObserver *observer); - -void GlobalWindowObservers_connectWidget(ui::Widget widget); - -void GlobalWindowObservers_connectTopLevel(ui::Window window); - -inline ButtonIdentifier button_for_button(unsigned int button) -{ - switch (button) { - case 1: - return c_buttonLeft; - case 2: - return c_buttonMiddle; - case 3: - return c_buttonRight; - } - return c_buttonInvalid; -} - -ModifierFlags modifiers_for_state(unsigned int state); -ModifierFlags modifiers_for_state_cam(unsigned int state); - -inline WindowVector WindowVector_forDouble(double x, double y) -{ - return WindowVector(static_cast( x ), static_cast( y )); -} - -#endif diff --git a/src/worldspawn.ico b/src/worldspawn.ico deleted file mode 100644 index 592a184..0000000 Binary files a/src/worldspawn.ico and /dev/null differ diff --git a/tools/vmap/writebsp.c b/src/writebsp.c similarity index 100% rename from tools/vmap/writebsp.c rename to src/writebsp.c diff --git a/src/xmlstuff.cpp b/src/xmlstuff.cpp deleted file mode 100644 index fbb4b85..0000000 --- a/src/xmlstuff.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "xmlstuff.h" diff --git a/src/xmlstuff.h b/src/xmlstuff.h deleted file mode 100644 index 8a05c18..0000000 --- a/src/xmlstuff.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (c) 2001, Loki software, inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of Loki software nor the names of its contributors may be used - to endorse or promote products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//----------------------------------------------------------------------------- -// -// DESCRIPTION: -// header for xml stuff used in radiant -// - -#ifndef __XMLSTUFF__ -#define __XMLSTUFF__ - -#include "libxml/parser.h" - -#include - -class ISAXHandler; - -// a 'user data' structure we pass along in the SAX callbacks to represent the current state -// the recurse value tracks the current depth in the tree -// message_info also stores information to exit the stream listening cleanly with an error: -// if msg_level == SYS_ERR, then we will reset the listening at the end of the current node -// the level for stopping the feed is stored in stop_depth -// unkown nodes are ignored, we use ignore_depth to track the level we start ignoring from -struct message_info_t { - int msg_level; // current message level (SYS_MSG, SYS_WRN, SYS_ERR) - int recurse; // current recursion depth (used to track various things) - int ignore_depth; // the ignore depth limit when we are jumping over unknown nodes (0 means we are not ignoring) - int stop_depth; // the depth we need to stop at the end - int geometry_depth; // are we parsing some geometry information (i.e. do we forward the SAX calls?) - ISAXHandler *pGeometry; // the handler - - enum unnamed0 { bufsize = 1024 }; - char m_buffer[bufsize]; - std::size_t m_length; -}; - -class IGL2DWindow; - -class ISAXHandler { -public: -virtual ~ISAXHandler() = default; - -virtual void Release() -{ -} - -virtual void saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs) = 0; - -virtual void saxEndElement(message_info_t *ctx, const xmlChar *name) = 0; - -virtual void saxCharacters(message_info_t *ctx, const xmlChar *ch, int len) = 0; - -virtual const char *getName() -{ - return NULL; -} - -virtual IGL2DWindow *Highlight() -{ - return 0; -} - -virtual void DropHighlight() -{ -} -}; - -#endif diff --git a/src/xywindow.cpp b/src/xywindow.cpp deleted file mode 100644 index ba2d7c5..0000000 --- a/src/xywindow.cpp +++ /dev/null @@ -1,2998 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// XY Window -// -// Leonardo Zide (leo@lokigames.com) -// - -#include "xywindow.h" - -#include - -#include "debugging/debugging.h" - -#include "ientity.h" -#include "igl.h" -#include "ibrush.h" -#include "iundo.h" -#include "iimage.h" -#include "ifilesystem.h" -#include "os/path.h" -#include "image.h" -#include "gtkutil/messagebox.h" - -#include -#include - -#include "generic/callback.h" -#include "string/string.h" -#include "stream/stringstream.h" - -#include "scenelib.h" -#include "eclasslib.h" -#include "renderer.h" -#include "moduleobserver.h" - -#include "gtkutil/menu.h" -#include "gtkutil/container.h" -#include "gtkutil/widget.h" -#include "gtkutil/glwidget.h" -#include "gtkutil/filechooser.h" -#include "gtkmisc.h" -#include "select.h" -#include "csg.h" -#include "brushmanip.h" -#include "selection.h" -#include "entity.h" -#include "camwindow.h" -#include "texwindow.h" -#include "mainframe.h" -#include "preferences.h" -#include "commands.h" -#include "feedback.h" -#include "grid.h" -#include "windowobservers.h" - -void LoadTextureRGBA(qtexture_t *q, unsigned char *pPixels, int nWidth, int nHeight); - -// d1223m -extern bool g_brush_always_caulk; - -//!\todo Rewrite. -class ClipPoint { -public: -Vector3 m_ptClip; // the 3d point -bool m_bSet; - -ClipPoint() -{ - Reset(); -}; - -void Reset() -{ - m_ptClip[0] = m_ptClip[1] = m_ptClip[2] = 0.0; - m_bSet = false; -} - -bool Set() -{ - return m_bSet; -} - -void Set(bool b) -{ - m_bSet = b; -} - -operator Vector3 &() -{ - return m_ptClip; -}; - -/*! Draw clip/path point with rasterized number label */ -void Draw(int num, float scale); - -/*! Draw clip/path point with rasterized string label */ -void Draw(const char *label, float scale); -}; - -VIEWTYPE g_clip_viewtype; -bool g_bSwitch = true; -bool g_clip_useCaulk = true; -ClipPoint g_Clip1; -ClipPoint g_Clip2; -ClipPoint g_Clip3; -ClipPoint *g_pMovingClip = 0; - -/* Drawing clip points */ -void ClipPoint::Draw(int num, float scale) -{ - StringOutputStream label(4); - label << num; - Draw(label.c_str(), scale); -} - -void ClipPoint::Draw(const char *label, float scale) -{ - // draw point - glPointSize(4); - glColor3fv(vector3_to_array(g_xywindow_globals.color_clipper)); - glBegin(GL_POINTS); - glVertex3fv(vector3_to_array(m_ptClip)); - glEnd(); - glPointSize(1); - - float offset = 2.0f / scale; - - // draw label - glRasterPos3f(m_ptClip[0] + offset, m_ptClip[1] + offset, m_ptClip[2] + offset); - glCallLists(GLsizei(strlen(label)), GL_UNSIGNED_BYTE, label); -} - -float fDiff(float f1, float f2) -{ - if (f1 > f2) { - return f1 - f2; - } else { - return f2 - f1; - } -} - -inline double ClipPoint_Intersect(const ClipPoint &clip, const Vector3 &point, VIEWTYPE viewtype, float scale) -{ - int nDim1 = (viewtype == YZ) ? 1 : 0; - int nDim2 = (viewtype == XY) ? 1 : 2; - double screenDistanceSquared(vector2_length_squared(Vector2(fDiff(clip.m_ptClip[nDim1], point[nDim1]) * scale, - fDiff(clip.m_ptClip[nDim2], point[nDim2]) * scale))); - if (screenDistanceSquared < 8 * 8) { - return screenDistanceSquared; - } - return FLT_MAX; -} - -inline void -ClipPoint_testSelect(ClipPoint &clip, const Vector3 &point, VIEWTYPE viewtype, float scale, double &bestDistance, - ClipPoint *&bestClip) -{ - if (clip.Set()) { - double distance = ClipPoint_Intersect(clip, point, viewtype, scale); - if (distance < bestDistance) { - bestDistance = distance; - bestClip = &clip; - } - } -} - -inline ClipPoint *GlobalClipPoints_Find(const Vector3 &point, VIEWTYPE viewtype, float scale) -{ - double bestDistance = FLT_MAX; - ClipPoint *bestClip = 0; - ClipPoint_testSelect(g_Clip1, point, viewtype, scale, bestDistance, bestClip); - ClipPoint_testSelect(g_Clip2, point, viewtype, scale, bestDistance, bestClip); - ClipPoint_testSelect(g_Clip3, point, viewtype, scale, bestDistance, bestClip); - return bestClip; -} - -inline void GlobalClipPoints_Draw(float scale) -{ - // Draw clip points - if (g_Clip1.Set()) { - g_Clip1.Draw(1, scale); - } - if (g_Clip2.Set()) { - g_Clip2.Draw(2, scale); - } - if (g_Clip3.Set()) { - g_Clip3.Draw(3, scale); - } -} - -inline bool GlobalClipPoints_valid() -{ - return g_Clip1.Set() && g_Clip2.Set(); -} - -void PlanePointsFromClipPoints(Vector3 planepts[3], const AABB &bounds, int viewtype) -{ - ASSERT_MESSAGE(GlobalClipPoints_valid(), "clipper points not initialised"); - planepts[0] = g_Clip1.m_ptClip; - planepts[1] = g_Clip2.m_ptClip; - planepts[2] = g_Clip3.m_ptClip; - Vector3 maxs(vector3_added(bounds.origin, bounds.extents)); - Vector3 mins(vector3_subtracted(bounds.origin, bounds.extents)); - if (!g_Clip3.Set()) { - int n = (viewtype == XY) ? 2 : (viewtype == YZ) ? 0 : 1; - int x = (n == 0) ? 1 : 0; - int y = (n == 2) ? 1 : 2; - - if (n == 1) { // on viewtype XZ, flip clip points - planepts[0][n] = maxs[n]; - planepts[1][n] = maxs[n]; - planepts[2][x] = g_Clip1.m_ptClip[x]; - planepts[2][y] = g_Clip1.m_ptClip[y]; - planepts[2][n] = mins[n]; - } else { - planepts[0][n] = mins[n]; - planepts[1][n] = mins[n]; - planepts[2][x] = g_Clip1.m_ptClip[x]; - planepts[2][y] = g_Clip1.m_ptClip[y]; - planepts[2][n] = maxs[n]; - } - } -} - -void Clip_Update() -{ - Vector3 planepts[3]; - if (!GlobalClipPoints_valid()) { - planepts[0] = Vector3(0, 0, 0); - planepts[1] = Vector3(0, 0, 0); - planepts[2] = Vector3(0, 0, 0); - Scene_BrushSetClipPlane(GlobalSceneGraph(), Plane3(0, 0, 0, 0)); - } else { - AABB bounds(Vector3(0, 0, 0), Vector3(64, 64, 64)); - PlanePointsFromClipPoints(planepts, bounds, g_clip_viewtype); - if (g_bSwitch) { - std::swap(planepts[0], planepts[1]); - } - Scene_BrushSetClipPlane(GlobalSceneGraph(), plane3_for_points(planepts[0], planepts[1], planepts[2])); - } - ClipperChangeNotify(); -} - -const char *Clip_getShader() -{ - return g_clip_useCaulk ? "textures/common/caulk" : TextureBrowser_GetSelectedShader(GlobalTextureBrowser()); -} - -void Clip() -{ - if (ClipMode() && GlobalClipPoints_valid()) { - Vector3 planepts[3]; - AABB bounds(Vector3(0, 0, 0), Vector3(64, 64, 64)); - PlanePointsFromClipPoints(planepts, bounds, g_clip_viewtype); - Scene_BrushSplitByPlane(GlobalSceneGraph(), planepts[0], planepts[1], planepts[2], Clip_getShader(), - (!g_bSwitch) ? eFront : eBack); - g_Clip1.Reset(); - g_Clip2.Reset(); - g_Clip3.Reset(); - Clip_Update(); - ClipperChangeNotify(); - } -} - -void SplitClip() -{ - if (ClipMode() && GlobalClipPoints_valid()) { - Vector3 planepts[3]; - AABB bounds(Vector3(0, 0, 0), Vector3(64, 64, 64)); - PlanePointsFromClipPoints(planepts, bounds, g_clip_viewtype); - Scene_BrushSplitByPlane(GlobalSceneGraph(), planepts[0], planepts[1], planepts[2], Clip_getShader(), - eFrontAndBack); - g_Clip1.Reset(); - g_Clip2.Reset(); - g_Clip3.Reset(); - Clip_Update(); - ClipperChangeNotify(); - } -} - -void FlipClip() -{ - g_bSwitch = !g_bSwitch; - Clip_Update(); - ClipperChangeNotify(); -} - -void OnClipMode(bool enabled) -{ - g_Clip1.Reset(); - g_Clip2.Reset(); - g_Clip3.Reset(); - - if (!enabled && g_pMovingClip) { - g_pMovingClip = 0; - } - - Clip_Update(); - ClipperChangeNotify(); -} - -bool ClipMode() -{ - return GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip; -} - -void NewClipPoint(const Vector3 &point) -{ - if (g_Clip1.Set() == false) { - g_Clip1.m_ptClip = point; - g_Clip1.Set(true); - } else if (g_Clip2.Set() == false) { - g_Clip2.m_ptClip = point; - g_Clip2.Set(true); - } else if (g_Clip3.Set() == false) { - g_Clip3.m_ptClip = point; - g_Clip3.Set(true); - } else { - g_Clip1.Reset(); - g_Clip2.Reset(); - g_Clip3.Reset(); - g_Clip1.m_ptClip = point; - g_Clip1.Set(true); - } - - Clip_Update(); - ClipperChangeNotify(); -} - - -struct xywindow_globals_private_t { - bool d_showgrid; - - // these are in the View > Show menu with Show coordinates - bool show_names; - bool show_coordinates; - bool show_angles; - bool show_outline; - bool show_axis; - - bool d_show_work; - - bool show_blocks; - int blockSize; - - bool m_bCamXYUpdate; - bool m_bChaseMouse; - bool m_bSizePaint; - - xywindow_globals_private_t() : - d_showgrid(true), - /* all very performance intensive */ - show_names(false), - show_coordinates(false), - show_angles(false), - show_outline(false), - show_axis(false), - d_show_work(false), - - show_blocks(true), - - m_bCamXYUpdate(true), - m_bChaseMouse(true), - m_bSizePaint(true) - { - } -}; - -xywindow_globals_t g_xywindow_globals; -xywindow_globals_private_t g_xywindow_globals_private; - -const unsigned int RAD_NONE = 0x00; -const unsigned int RAD_SHIFT = 0x01; -const unsigned int RAD_ALT = 0x02; -const unsigned int RAD_CONTROL = 0x04; -const unsigned int RAD_PRESS = 0x08; -const unsigned int RAD_LBUTTON = 0x10; -const unsigned int RAD_MBUTTON = 0x20; -const unsigned int RAD_RBUTTON = 0x40; - -inline ButtonIdentifier button_for_flags(unsigned int flags) -{ - if (flags & RAD_LBUTTON) { - return c_buttonLeft; - } - if (flags & RAD_RBUTTON) { - return c_buttonRight; - } - if (flags & RAD_MBUTTON) { - return c_buttonMiddle; - } - return c_buttonInvalid; -} - -inline ModifierFlags modifiers_for_flags(unsigned int flags) -{ - ModifierFlags modifiers = c_modifierNone; - if (flags & RAD_SHIFT) { - modifiers |= c_modifierShift; - } - if (flags & RAD_CONTROL) { - modifiers |= c_modifierControl; - } - if (flags & RAD_ALT) { - modifiers |= c_modifierAlt; - } - return modifiers; -} - -inline unsigned int buttons_for_button_and_modifiers(ButtonIdentifier button, ModifierFlags flags) -{ - unsigned int buttons = 0; - - switch (button.get()) { - case ButtonEnumeration::INVALID: - break; - case ButtonEnumeration::LEFT: - buttons |= RAD_LBUTTON; - break; - case ButtonEnumeration::MIDDLE: - buttons |= RAD_MBUTTON; - break; - case ButtonEnumeration::RIGHT: - buttons |= RAD_RBUTTON; - break; - } - - if (bitfield_enabled(flags, c_modifierControl)) { - buttons |= RAD_CONTROL; - } - - if (bitfield_enabled(flags, c_modifierShift)) { - buttons |= RAD_SHIFT; - } - - if (bitfield_enabled(flags, c_modifierAlt)) { - buttons |= RAD_ALT; - } - - return buttons; -} - -inline unsigned int buttons_for_event_button(GdkEventButton *event) -{ - unsigned int flags = 0; - - switch (event->button) { - case 1: - flags |= RAD_LBUTTON; - break; - case 2: - flags |= RAD_MBUTTON; - break; - case 3: - flags |= RAD_RBUTTON; - break; - } - - if ((event->state & GDK_CONTROL_MASK) != 0) { - flags |= RAD_CONTROL; - } - - if ((event->state & GDK_SHIFT_MASK) != 0) { - flags |= RAD_SHIFT; - } - - if ((event->state & GDK_MOD1_MASK) != 0) { - flags |= RAD_ALT; - } - - return flags; -} - -inline unsigned int buttons_for_state(guint state) -{ - unsigned int flags = 0; - - if ((state & GDK_BUTTON1_MASK) != 0) { - flags |= RAD_LBUTTON; - } - - if ((state & GDK_BUTTON2_MASK) != 0) { - flags |= RAD_MBUTTON; - } - - if ((state & GDK_BUTTON3_MASK) != 0) { - flags |= RAD_RBUTTON; - } - - if ((state & GDK_CONTROL_MASK) != 0) { - flags |= RAD_CONTROL; - } - - if ((state & GDK_SHIFT_MASK) != 0) { - flags |= RAD_SHIFT; - } - - if ((state & GDK_MOD1_MASK) != 0) { - flags |= RAD_ALT; - } - - return flags; -} - - -void XYWnd::SetScale(float f) -{ - m_fScale = f; - updateProjection(); - updateModelview(); - XYWnd_Update(*this); -} - -void XYWnd_ZoomIn(XYWnd *xy) -{ - float max_scale = 64; - float scale = xy->Scale() * 5.0f / 4.0f; - if (scale > max_scale) { - if (xy->Scale() != max_scale) { - xy->SetScale(max_scale); - } - } else { - xy->SetScale(scale); - } -} - - -// NOTE: the zoom out factor is 4/5, we could think about customizing it -// we don't go below a zoom factor corresponding to 10% of the max world size -// (this has to be computed against the window size) -void XYWnd_ZoomOut(XYWnd *xy) -{ - float min_scale = MIN(xy->Width(), xy->Height()) / (1.1f * (g_MaxWorldCoord - g_MinWorldCoord)); - float scale = xy->Scale() * 4.0f / 5.0f; - if (scale < min_scale) { - if (xy->Scale() != min_scale) { - xy->SetScale(min_scale); - } - } else { - xy->SetScale(scale); - } -} - -VIEWTYPE GlobalXYWnd_getCurrentViewType() -{ - ASSERT_NOTNULL(g_pParentWnd); - ASSERT_NOTNULL(g_pParentWnd->ActiveXY()); - return g_pParentWnd->ActiveXY()->GetViewType(); -} - -// ============================================================================= -// variables - -bool g_bCrossHairs = false; - -ui::Menu XYWnd::m_mnuDrop(ui::null); -ui::Menu XYWnd::m_mnuDropSingle(ui::null); -ui::Menu XYWnd::m_mnuDropMultiple(ui::null); - -// this is disabled, and broken -// http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=394 -#if 0 -void WXY_Print(){ - long width, height; - width = g_pParentWnd->ActiveXY()->Width(); - height = g_pParentWnd->ActiveXY()->Height(); - unsigned char* img; - const char* filename; - - filename = ui::file_dialog( MainFrame_getWindow( ), FALSE, "Save Image", 0, FILTER_BMP ); - if ( !filename ) { - return; - } - - g_pParentWnd->ActiveXY()->MakeCurrent(); - img = (unsigned char*)malloc( width * height * 3 ); - glReadPixels( 0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,img ); - - FILE *fp; - fp = fopen( filename, "wb" ); - if ( fp ) { - unsigned short bits; - unsigned long cmap, bfSize; - - bits = 24; - cmap = 0; - bfSize = 54 + width * height * 3; - - long byteswritten = 0; - long pixoff = 54 + cmap * 4; - short res = 0; - char m1 = 'B', m2 = 'M'; - fwrite( &m1, 1, 1, fp ); byteswritten++; // B - fwrite( &m2, 1, 1, fp ); byteswritten++; // M - fwrite( &bfSize, 4, 1, fp ); byteswritten += 4; // bfSize - fwrite( &res, 2, 1, fp ); byteswritten += 2; // bfReserved1 - fwrite( &res, 2, 1, fp ); byteswritten += 2; // bfReserved2 - fwrite( &pixoff, 4, 1, fp ); byteswritten += 4; // bfOffBits - - unsigned long biSize = 40, compress = 0, size = 0; - long pixels = 0; - unsigned short planes = 1; - fwrite( &biSize, 4, 1, fp ); byteswritten += 4; // biSize - fwrite( &width, 4, 1, fp ); byteswritten += 4; // biWidth - fwrite( &height, 4, 1, fp ); byteswritten += 4; // biHeight - fwrite( &planes, 2, 1, fp ); byteswritten += 2; // biPlanes - fwrite( &bits, 2, 1, fp ); byteswritten += 2; // biBitCount - fwrite( &compress, 4, 1, fp ); byteswritten += 4; // biCompression - fwrite( &size, 4, 1, fp ); byteswritten += 4; // biSizeImage - fwrite( &pixels, 4, 1, fp ); byteswritten += 4; // biXPelsPerMeter - fwrite( &pixels, 4, 1, fp ); byteswritten += 4; // biYPelsPerMeter - fwrite( &cmap, 4, 1, fp ); byteswritten += 4; // biClrUsed - fwrite( &cmap, 4, 1, fp ); byteswritten += 4; // biClrImportant - - unsigned long widthDW = ( ( ( width * 24 ) + 31 ) / 32 * 4 ); - long row, row_size = width * 3; - for ( row = 0; row < height; row++ ) - { - unsigned char* buf = img + row * row_size; - - // write a row - int col; - for ( col = 0; col < row_size; col += 3 ) - { - putc( buf[col + 2], fp ); - putc( buf[col + 1], fp ); - putc( buf[col], fp ); - } - byteswritten += row_size; - - unsigned long count; - for ( count = row_size; count < widthDW; count++ ) - { - putc( 0, fp ); // dummy - byteswritten++; - } - } - - fclose( fp ); - } - - free( img ); -} -#endif - - -#include "timer.h" - -Timer g_chasemouse_timer; - -void XYWnd::ChaseMouse() -{ - float multiplier = g_chasemouse_timer.elapsed_msec() / 10.0f; - Scroll(float_to_integer(multiplier * m_chasemouse_delta_x), float_to_integer(multiplier * -m_chasemouse_delta_y)); - - //globalOutputStream() << "chasemouse: multiplier=" << multiplier << " x=" << m_chasemouse_delta_x << " y=" << m_chasemouse_delta_y << '\n'; - - XY_MouseMoved(m_chasemouse_current_x, m_chasemouse_current_y, getButtonState()); - g_chasemouse_timer.start(); -} - -gboolean xywnd_chasemouse(gpointer data) -{ - reinterpret_cast( data )->ChaseMouse(); - return TRUE; -} - -inline const int &min_int(const int &left, const int &right) -{ - return std::min(left, right); -} - -bool XYWnd::chaseMouseMotion(int pointx, int pointy) -{ - m_chasemouse_delta_x = 0; - m_chasemouse_delta_y = 0; - - if (g_xywindow_globals_private.m_bChaseMouse && getButtonState() == RAD_LBUTTON) { - const int epsilon = 16; - - if (pointx < epsilon) { - m_chasemouse_delta_x = std::max(pointx, 0) - epsilon; - } else if ((pointx - m_nWidth) > -epsilon) { - m_chasemouse_delta_x = min_int((pointx - m_nWidth), 0) + epsilon; - } - - if (pointy < epsilon) { - m_chasemouse_delta_y = std::max(pointy, 0) - epsilon; - } else if ((pointy - m_nHeight) > -epsilon) { - m_chasemouse_delta_y = min_int((pointy - m_nHeight), 0) + epsilon; - } - - if (m_chasemouse_delta_y != 0 || m_chasemouse_delta_x != 0) { - //globalOutputStream() << "chasemouse motion: x=" << pointx << " y=" << pointy << "... "; - m_chasemouse_current_x = pointx; - m_chasemouse_current_y = pointy; - if (m_chasemouse_handler == 0) { - //globalOutputStream() << "chasemouse timer start... "; - g_chasemouse_timer.start(); - m_chasemouse_handler = g_idle_add(xywnd_chasemouse, this); - } - return true; - } else { - if (m_chasemouse_handler != 0) { - //globalOutputStream() << "chasemouse cancel\n"; - g_source_remove(m_chasemouse_handler); - m_chasemouse_handler = 0; - } - } - } else { - if (m_chasemouse_handler != 0) { - //globalOutputStream() << "chasemouse cancel\n"; - g_source_remove(m_chasemouse_handler); - m_chasemouse_handler = 0; - } - } - return false; -} - -// ============================================================================= -// XYWnd class -Shader *XYWnd::m_state_selected = 0; -ModifierFlags modifiers_for_key(unsigned int state); -void xy_update_xor_rectangle(XYWnd &self, rect_t area) -{ - if (self.GetWidget().visible()) { - self.m_XORRectangle.set(rectangle_from_area(area.min, area.max, self.Width(), self.Height())); - } -} - -gboolean xywnd_button_press(ui::Widget widget, GdkEventButton *event, XYWnd *xywnd) -{ - if (event->type == GDK_BUTTON_PRESS) { - g_pParentWnd->SetActiveXY(xywnd); - - xywnd->ButtonState_onMouseDown(buttons_for_event_button(event)); - - xywnd->onMouseDown(WindowVector(event->x, event->y), button_for_button(event->button), - modifiers_for_key(event->state)); - } - return FALSE; -} - -gboolean xywnd_button_release(ui::Widget widget, GdkEventButton *event, XYWnd *xywnd) -{ - if (event->type == GDK_BUTTON_RELEASE) { - xywnd->XY_MouseUp(static_cast( event->x ), static_cast( event->y ), buttons_for_event_button(event)); - - xywnd->ButtonState_onMouseUp(buttons_for_event_button(event)); - } - return FALSE; -} - -gboolean xywnd_focus_in(ui::Widget widget, GdkEventFocus *event, XYWnd *xywnd) -{ - if (event->type == GDK_FOCUS_CHANGE) { - if (event->in) { - g_pParentWnd->SetActiveXY(xywnd); - } - } - return FALSE; -} - -void xywnd_motion(gdouble x, gdouble y, guint state, void *data) -{ - if (reinterpret_cast( data )->chaseMouseMotion(static_cast( x ), static_cast( y ))) { - return; - } - reinterpret_cast( data )->XY_MouseMoved(static_cast( x ), static_cast( y ), - buttons_for_state(state)); -} - -gboolean xywnd_wheel_scroll(ui::Widget widget, GdkEventScroll *event, XYWnd *xywnd) -{ - if (event->direction == GDK_SCROLL_UP) { - XYWnd_ZoomIn(xywnd); - } else if (event->direction == GDK_SCROLL_DOWN) { - XYWnd_ZoomOut(xywnd); - } - return FALSE; -} - -gboolean xywnd_size_allocate(ui::Widget widget, GtkAllocation *allocation, XYWnd *xywnd) -{ - xywnd->m_nWidth = allocation->width; - xywnd->m_nHeight = allocation->height; - xywnd->updateProjection(); - xywnd->m_window_observer->onSizeChanged(xywnd->Width(), xywnd->Height()); - return FALSE; -} - -gboolean xywnd_expose(ui::Widget widget, GdkEventExpose *event, XYWnd *xywnd) -{ - if (glwidget_make_current(xywnd->GetWidget()) != FALSE) { - if (Map_Valid(g_map) && ScreenUpdates_Enabled()) { - GlobalOpenGL_debugAssertNoErrors(); - xywnd->XY_Draw(); - GlobalOpenGL_debugAssertNoErrors(); - - xywnd->m_XORRectangle.set(rectangle_t()); - } - glwidget_swap_buffers(xywnd->GetWidget()); - } - return FALSE; -} - - -void XYWnd_CameraMoved(XYWnd &xywnd) -{ - if (g_xywindow_globals_private.m_bCamXYUpdate) { - XYWnd_Update(xywnd); - } -} - -XYWnd::XYWnd() : - m_gl_widget(glwidget_new(FALSE)), - m_deferredDraw(WidgetQueueDrawCaller(m_gl_widget)), - m_deferred_motion(xywnd_motion, this), - m_parent(ui::null), - m_window_observer(NewWindowObserver()), - m_XORRectangle(m_gl_widget), - m_chasemouse_handler(0) -{ - m_bActive = false; - m_buttonstate = 0; - - m_bNewBrushDrag = false; - m_move_started = false; - m_zoom_started = false; - - m_nWidth = 0; - m_nHeight = 0; - - m_vOrigin[0] = 0; - m_vOrigin[1] = 20; - m_vOrigin[2] = 46; - m_fScale = 1; - m_viewType = XY; - - m_backgroundActivated = false; - m_alpha = 1.0f; - m_xmin = 0.0f; - m_ymin = 0.0f; - m_xmax = 0.0f; - m_ymax = 0.0f; - - m_entityCreate = false; - - m_mnuDrop = ui::Menu(ui::null); - m_mnuDropSingle = ui::Menu(ui::null); - m_mnuDropMultiple = ui::Menu(ui::null); - - GlobalWindowObservers_add(m_window_observer); - GlobalWindowObservers_connectWidget(m_gl_widget); - - m_window_observer->setRectangleDrawCallback(ReferenceCaller(*this)); - m_window_observer->setView(m_view); - - g_object_ref(m_gl_widget._handle); - - gtk_widget_set_events(m_gl_widget, - GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK); - gtk_widget_set_can_focus(m_gl_widget, true); - - m_sizeHandler = m_gl_widget.connect("size_allocate", G_CALLBACK(xywnd_size_allocate), this); - m_exposeHandler = m_gl_widget.on_render(G_CALLBACK(xywnd_expose), this); - - m_gl_widget.connect("button_press_event", G_CALLBACK(xywnd_button_press), this); - m_gl_widget.connect("button_release_event", G_CALLBACK(xywnd_button_release), this); - m_gl_widget.connect("focus_in_event", G_CALLBACK(xywnd_focus_in), this); - m_gl_widget.connect("motion_notify_event", G_CALLBACK(DeferredMotion::gtk_motion), &m_deferred_motion); - - m_gl_widget.connect("scroll_event", G_CALLBACK(xywnd_wheel_scroll), this); - - Map_addValidCallback(g_map, DeferredDrawOnMapValidChangedCaller(m_deferredDraw)); - - updateProjection(); - updateModelview(); - - AddSceneChangeCallback(ReferenceCaller(*this)); - AddCameraMovedCallback(ReferenceCaller(*this)); - - PressedButtons_connect(g_pressedButtons, m_gl_widget); - - onMouseDown.connectLast(makeSignalHandler3(MouseDownCaller(), *this)); -} - -XYWnd::~XYWnd() -{ - onDestroyed(); - - if (m_mnuDrop) { - m_mnuDrop.destroy(); - m_mnuDrop = ui::Menu(ui::null); - } - - if (m_mnuDropSingle) { - m_mnuDropSingle.destroy(); - m_mnuDropSingle = ui::Menu(ui::null); - } - - if (m_mnuDropMultiple) { - m_mnuDropMultiple.destroy(); - m_mnuDropMultiple = ui::Menu(ui::null); - } - - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_sizeHandler); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_exposeHandler); - - m_gl_widget.unref(); - - m_window_observer->release(); -} - -void XYWnd::captureStates() -{ - m_state_selected = GlobalShaderCache().capture("$XY_OVERLAY"); -} - -void XYWnd::releaseStates() -{ - GlobalShaderCache().release("$XY_OVERLAY"); -} - -const Vector3 &XYWnd::GetOrigin() -{ - return m_vOrigin; -} - -void XYWnd::SetOrigin(const Vector3 &origin) -{ - m_vOrigin = origin; - updateModelview(); -} - -void XYWnd::Scroll(int x, int y) -{ - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - m_vOrigin[nDim1] += x / m_fScale; - m_vOrigin[nDim2] += y / m_fScale; - updateModelview(); - queueDraw(); -} - -unsigned int Clipper_buttons() -{ - return RAD_LBUTTON; -} - -void XYWnd::DropClipPoint(int pointx, int pointy) -{ - Vector3 point; - - XY_ToPoint(pointx, pointy, point); - - Vector3 mid; - Select_GetMid(mid); - g_clip_viewtype = static_cast( GetViewType()); - const int nDim = (g_clip_viewtype == YZ) ? 0 : ((g_clip_viewtype == XZ) ? 1 : 2); - point[nDim] = mid[nDim]; - vector3_snap(point, GetSnapGridSize()); - NewClipPoint(point); -} - -void XYWnd::Clipper_OnLButtonDown(int x, int y) -{ - Vector3 mousePosition; - XY_ToPoint(x, y, mousePosition); - g_pMovingClip = GlobalClipPoints_Find(mousePosition, (VIEWTYPE) m_viewType, m_fScale); - if (!g_pMovingClip) { - DropClipPoint(x, y); - } -} - -void XYWnd::Clipper_OnLButtonUp(int x, int y) -{ - if (g_pMovingClip) { - g_pMovingClip = 0; - } -} - -void XYWnd::Clipper_OnMouseMoved(int x, int y) -{ - if (g_pMovingClip) { - XY_ToPoint(x, y, g_pMovingClip->m_ptClip); - XY_SnapToGrid(g_pMovingClip->m_ptClip); - Clip_Update(); - ClipperChangeNotify(); - } -} - -void XYWnd::Clipper_Crosshair_OnMouseMoved(int x, int y) -{ - Vector3 mousePosition; - XY_ToPoint(x, y, mousePosition); - if (ClipMode() && GlobalClipPoints_Find(mousePosition, (VIEWTYPE) m_viewType, m_fScale) != 0) { - GdkCursor *cursor; - cursor = gdk_cursor_new(GDK_CROSSHAIR); - gdk_window_set_cursor(gtk_widget_get_window(m_gl_widget), cursor); - gdk_cursor_unref(cursor); - } else { - gdk_window_set_cursor(gtk_widget_get_window(m_gl_widget), 0); - } -} - -unsigned int MoveCamera_buttons() -{ - return RAD_CONTROL | (g_glwindow_globals.m_nMouseType == ETwoButton ? RAD_RBUTTON : RAD_MBUTTON); -} - -void XYWnd_PositionCamera(XYWnd *xywnd, int x, int y, CamWnd &camwnd) -{ - Vector3 origin(Camera_getOrigin(camwnd)); - xywnd->XY_ToPoint(x, y, origin); - xywnd->XY_SnapToGrid(origin); - Camera_setOrigin(camwnd, origin); -} - -unsigned int OrientCamera_buttons() -{ - if (g_glwindow_globals.m_nMouseType == ETwoButton) { - return RAD_RBUTTON | RAD_SHIFT | RAD_CONTROL; - } - return RAD_MBUTTON; -} - -void XYWnd_OrientCamera(XYWnd *xywnd, int x, int y, CamWnd &camwnd) -{ - Vector3 point = g_vector3_identity; - xywnd->XY_ToPoint(x, y, point); - xywnd->XY_SnapToGrid(point); - vector3_subtract(point, Camera_getOrigin(camwnd)); - - int n1 = (xywnd->GetViewType() == XY) ? 1 : 2; - int n2 = (xywnd->GetViewType() == YZ) ? 1 : 0; - int nAngle = (xywnd->GetViewType() == XY) ? CAMERA_YAW : CAMERA_PITCH; - if (point[n1] || point[n2]) { - Vector3 angles(Camera_getAngles(camwnd)); - angles[nAngle] = static_cast( radians_to_degrees(atan2(point[n1], point[n2]))); - Camera_setAngles(camwnd, angles); - } -} - -/* - ============== - NewBrushDrag - ============== - */ -unsigned int NewBrushDrag_buttons() -{ - return RAD_LBUTTON; -} - -void XYWnd::NewBrushDrag_Begin(int x, int y) -{ - m_NewBrushDrag = 0; - m_nNewBrushPressx = x; - m_nNewBrushPressy = y; - - m_bNewBrushDrag = true; - GlobalUndoSystem().start(); -} - -void XYWnd::NewBrushDrag_End(int x, int y) -{ - if (m_NewBrushDrag != 0) { - GlobalUndoSystem().finish("brushDragNew"); - } -} - -void XYWnd::NewBrushDrag(int x, int y) -{ - Vector3 mins, maxs; - XY_ToPoint(m_nNewBrushPressx, m_nNewBrushPressy, mins); - XY_SnapToGrid(mins); - XY_ToPoint(x, y, maxs); - XY_SnapToGrid(maxs); - - int nDim = (m_viewType == XY) ? 2 : (m_viewType == YZ) ? 0 : 1; - - mins[nDim] = float_snapped(Select_getWorkZone().d_work_min[nDim], GetSnapGridSize()); - maxs[nDim] = float_snapped(Select_getWorkZone().d_work_max[nDim], GetSnapGridSize()); - - if (maxs[nDim] <= mins[nDim]) { - maxs[nDim] = mins[nDim] + GetGridSize(); - } - - for (int i = 0; i < 3; i++) { - if (mins[i] == maxs[i]) { - return; // don't create a degenerate brush - } - if (mins[i] > maxs[i]) { - float temp = mins[i]; - mins[i] = maxs[i]; - maxs[i] = temp; - } - } - - if (m_NewBrushDrag == 0) { - NodeSmartReference node(GlobalBrushCreator().createBrush()); - Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(node); - - scene::Path brushpath(makeReference(GlobalSceneGraph().root())); - brushpath.push(makeReference(*Map_GetWorldspawn(g_map))); - brushpath.push(makeReference(node.get())); - selectPath(brushpath, true); - - m_NewBrushDrag = node.get_pointer(); - } - - // d1223m - //Scene_BrushResize_Selected(GlobalSceneGraph(), aabb_for_minmax(mins, maxs), TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); - Scene_BrushResize_Selected(GlobalSceneGraph(), aabb_for_minmax(mins, maxs), - g_brush_always_caulk ? - "textures/common/caulk" : TextureBrowser_GetSelectedShader(GlobalTextureBrowser())); -} - -void entitycreate_activated(ui::Widget item) -{ - scene::Node *world_node = Map_FindWorldspawn(g_map); - const char *entity_name = gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(item)))); - - if (!(world_node && string_equal(entity_name, "worldspawn"))) { - g_pParentWnd->ActiveXY()->OnEntityCreate(entity_name); - } else { - GlobalRadiant().m_pfnMessageBox(MainFrame_getWindow(), "There's already a worldspawn in your map!" - "", - "Info", - eMB_OK, - eMB_ICONDEFAULT); - } -} - -void EntityClassMenu_addItem(ui::Menu menu, const char *name) -{ - auto item = ui::MenuItem(name); - item.connect("activate", G_CALLBACK(entitycreate_activated), item); - item.show(); - menu_add_item(menu, item); -} - -class EntityClassMenuInserter : public EntityClassVisitor { -typedef std::pair MenuPair; -typedef std::vector MenuStack; -MenuStack m_stack; -CopiedString m_previous; -public: -EntityClassMenuInserter(ui::Menu menu) -{ - m_stack.reserve(2); - m_stack.push_back(MenuPair(menu, "")); -} - -~EntityClassMenuInserter() -{ - if (!string_empty(m_previous.c_str())) { - addItem(m_previous.c_str(), ""); - } -} - -void visit(EntityClass *e) -{ - ASSERT_MESSAGE(!string_empty(e->name()), "entity-class has no name"); - if (!string_empty(m_previous.c_str())) { - addItem(m_previous.c_str(), e->name()); - } - m_previous = e->name(); -} - -void pushMenu(const CopiedString &name) -{ - auto item = ui::MenuItem(name.c_str()); - item.show(); - m_stack.back().first.add(item); - - auto submenu = ui::Menu(ui::New); - gtk_menu_item_set_submenu(item, submenu); - - m_stack.push_back(MenuPair(submenu, name)); -} - -void popMenu() -{ - m_stack.pop_back(); -} - -void addItem(const char *name, const char *next) -{ - const char *underscore = strchr(name, '_'); - - if (underscore != 0 && underscore != name) { - bool nextEqual = string_equal_n(name, next, (underscore + 1) - name); - const char *parent = m_stack.back().second.c_str(); - - if (!string_empty(parent) - && string_length(parent) == std::size_t(underscore - name) - && string_equal_n(name, parent, underscore - name)) { // this is a child - } else if (nextEqual) { - if (m_stack.size() == 2) { - popMenu(); - } - pushMenu(CopiedString(StringRange(name, underscore))); - } else if (m_stack.size() == 2) { - popMenu(); - } - } else if (m_stack.size() == 2) { - popMenu(); - } - - EntityClassMenu_addItem(m_stack.back().first, name); -} -}; - -void XYWnd::OnContextMenu() -{ - if (g_xywindow_globals.m_bRightClick == false) { - return; - } - - /* first time, init */ - if (!m_mnuDrop) { - auto menu1 = m_mnuDrop = ui::Menu(ui::New); - EntityClassMenuInserter inserter(menu1); - GlobalEntityClassManager().forEachPoint(inserter); - } - if (!m_mnuDropSingle) { - auto menu2 = m_mnuDropSingle = ui::Menu(ui::New); - create_menu_item_with_mnemonic(menu2, "Make detail", "MakeDetail"); - create_menu_item_with_mnemonic(menu2, "Make structural", "MakeStructural"); - create_menu_item_with_mnemonic(menu2, "Snap selection to _grid", "SnapToGrid"); - menu_separator(menu2); - create_menu_item_with_mnemonic(menu2, "Arbitrary rotation...", "ArbitraryRotation"); - create_menu_item_with_mnemonic(menu2, "Arbitrary scale...", "ArbitraryScale"); - menu_separator(menu2); - create_menu_item_with_mnemonic(menu2, "_To Worldspawn", "UngroupSelection"); - - } - if (!m_mnuDropMultiple) { - auto menu3 = m_mnuDropMultiple = ui::Menu(ui::New); - create_menu_item_with_mnemonic(menu3, "Make detail", "MakeDetail"); - create_menu_item_with_mnemonic(menu3, "Make structural", "MakeStructural"); - create_menu_item_with_mnemonic(menu3, "Snap selection to _grid", "SnapToGrid"); - menu_separator(menu3); - create_menu_item_with_mnemonic(menu3, "Arbitrary rotation...", "ArbitraryRotation"); - create_menu_item_with_mnemonic(menu3, "Arbitrary scale...", "ArbitraryScale"); - menu_separator(menu3); - create_menu_item_with_mnemonic(menu3, "_To Worldspawn", "UngroupSelection"); - create_menu_item_with_mnemonic(menu3, "_Group Structural", "CreateFuncGroup"); - create_menu_item_with_mnemonic(menu3, "_Combine Entities", "GroupSelection"); - create_menu_item_with_mnemonic(menu3, "_Connect", "ConnectSelection"); - create_menu_item_with_mnemonic(menu3, "_KillConnect", "KillConnectSelection"); - create_menu_item_with_mnemonic(menu3, "_Select Color...", "EntityColor"); - create_menu_item_with_mnemonic(menu3, "_Normalize Color...", "NormalizeColor"); - } - - if (GlobalSelectionSystem().countSelected() == 0) { - gtk_menu_popup(m_mnuDrop, 0, 0, 0, 0, 1, GDK_CURRENT_TIME); - } else if (GlobalSelectionSystem().countSelected() == 1) { - gtk_menu_popup(m_mnuDropSingle, 0, 0, 0, 0, 1, GDK_CURRENT_TIME); - } else { - gtk_menu_popup(m_mnuDropMultiple, 0, 0, 0, 0, 1, GDK_CURRENT_TIME); - } -} - -FreezePointer g_xywnd_freezePointer; - -unsigned int Move_buttons() -{ - return RAD_RBUTTON; -} - -void XYWnd_moveDelta(int x, int y, unsigned int state, void *data) -{ - reinterpret_cast( data )->EntityCreate_MouseMove(x, y); - reinterpret_cast( data )->Scroll(-x, y); -} - -gboolean XYWnd_Move_focusOut(ui::Widget widget, GdkEventFocus *event, XYWnd *xywnd) -{ - xywnd->Move_End(); - return FALSE; -} - -void XYWnd::Move_Begin() -{ - if (m_move_started) { - Move_End(); - } - m_move_started = true; - g_xywnd_freezePointer.freeze_pointer(m_parent ? m_parent : MainFrame_getWindow(), XYWnd_moveDelta, this); - m_move_focusOut = m_gl_widget.connect("focus_out_event", G_CALLBACK(XYWnd_Move_focusOut), this); -} - -void XYWnd::Move_End() -{ - m_move_started = false; - g_xywnd_freezePointer.unfreeze_pointer(m_parent ? m_parent : MainFrame_getWindow()); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_move_focusOut); -} - -unsigned int Zoom_buttons() -{ - return RAD_RBUTTON | RAD_SHIFT; -} - -int g_dragZoom = 0; - -void XYWnd_zoomDelta(int x, int y, unsigned int state, void *data) -{ - if (y != 0) { - g_dragZoom += y; - - while (abs(g_dragZoom) > 8) { - if (g_dragZoom > 0) { - XYWnd_ZoomOut(reinterpret_cast( data )); - g_dragZoom -= 8; - } else { - XYWnd_ZoomIn(reinterpret_cast( data )); - g_dragZoom += 8; - } - } - } -} - -gboolean XYWnd_Zoom_focusOut(ui::Widget widget, GdkEventFocus *event, XYWnd *xywnd) -{ - xywnd->Zoom_End(); - return FALSE; -} - -void XYWnd::Zoom_Begin() -{ - if (m_zoom_started) { - Zoom_End(); - } - m_zoom_started = true; - g_dragZoom = 0; - g_xywnd_freezePointer.freeze_pointer(m_parent ? m_parent : MainFrame_getWindow(), XYWnd_zoomDelta, this); - m_zoom_focusOut = m_gl_widget.connect("focus_out_event", G_CALLBACK(XYWnd_Zoom_focusOut), this); -} - -void XYWnd::Zoom_End() -{ - m_zoom_started = false; - g_xywnd_freezePointer.unfreeze_pointer(m_parent ? m_parent : MainFrame_getWindow()); - g_signal_handler_disconnect(G_OBJECT(m_gl_widget), m_zoom_focusOut); -} - -// makes sure the selected brush or camera is in view -void XYWnd::PositionView(const Vector3 &position) -{ - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - - m_vOrigin[nDim1] = position[nDim1]; - m_vOrigin[nDim2] = position[nDim2]; - - updateModelview(); - - XYWnd_Update(*this); -} - -void XYWnd::SetViewType(VIEWTYPE viewType) -{ - m_viewType = viewType; - updateModelview(); - - if (m_parent) { - gtk_window_set_title(m_parent, ViewType_getTitle(m_viewType)); - } -} - - -inline WindowVector WindowVector_forInteger(int x, int y) -{ - return WindowVector(static_cast( x ), static_cast( y )); -} - -void XYWnd::mouseDown(const WindowVector &position, ButtonIdentifier button, ModifierFlags modifiers) -{ - XY_MouseDown(static_cast( position.x()), static_cast( position.y()), - buttons_for_button_and_modifiers(button, modifiers)); -} - -void CamWnd_DisableMovement(); - -void XYWnd::XY_MouseDown(int x, int y, unsigned int buttons) -{ - if (buttons == Move_buttons()) { - Move_Begin(); - EntityCreate_MouseDown(x, y); - } else if (buttons == Zoom_buttons()) { - Zoom_Begin(); - } else if (ClipMode() && buttons == Clipper_buttons()) { - Clipper_OnLButtonDown(x, y); - } else if (buttons == NewBrushDrag_buttons() && GlobalSelectionSystem().countSelected() == 0) { - NewBrushDrag_Begin(x, y); - } - // control mbutton = move camera - else if (buttons == MoveCamera_buttons()) { - XYWnd_PositionCamera(this, x, y, *g_pParentWnd->GetCamWnd()); - } - // mbutton = angle camera - else if (buttons == OrientCamera_buttons()) { - XYWnd_OrientCamera(this, x, y, *g_pParentWnd->GetCamWnd()); - } else { - m_window_observer->onMouseDown(WindowVector_forInteger(x, y), button_for_flags(buttons), - modifiers_for_flags(buttons)); - } - CamWnd_DisableMovement(); -} - -void XYWnd::XY_MouseUp(int x, int y, unsigned int buttons) -{ - if (m_move_started) { - Move_End(); - EntityCreate_MouseUp(x, y); - } else if (m_zoom_started) { - Zoom_End(); - } else if (ClipMode() && buttons == Clipper_buttons()) { - Clipper_OnLButtonUp(x, y); - } else if (m_bNewBrushDrag) { - m_bNewBrushDrag = false; - NewBrushDrag_End(x, y); - } else { - m_window_observer->onMouseUp(WindowVector_forInteger(x, y), button_for_flags(buttons), - modifiers_for_flags(buttons)); - } -} - -void XYWnd::XY_MouseMoved(int x, int y, unsigned int buttons) -{ - // rbutton = drag xy origin - if (m_move_started) { - } - // zoom in/out - else if (m_zoom_started) { - } else if (ClipMode() && g_pMovingClip != 0) { - Clipper_OnMouseMoved(x, y); - } - // lbutton without selection = drag new brush - else if (m_bNewBrushDrag) { - NewBrushDrag(x, y); - } - - // control mbutton = move camera - else if (getButtonState() == MoveCamera_buttons()) { - XYWnd_PositionCamera(this, x, y, *g_pParentWnd->GetCamWnd()); - } - - // mbutton = angle camera - else if (getButtonState() == OrientCamera_buttons()) { - XYWnd_OrientCamera(this, x, y, *g_pParentWnd->GetCamWnd()); - } else { - m_window_observer->onMouseMotion(WindowVector_forInteger(x, y), modifiers_for_flags(buttons)); - - m_mousePosition[0] = m_mousePosition[1] = m_mousePosition[2] = 0.0; - XY_ToPoint(x, y, m_mousePosition); - XY_SnapToGrid(m_mousePosition); - - StringOutputStream status(64); - status << "x:: " << FloatFormat(m_mousePosition[0], 6, 1) - << " y:: " << FloatFormat(m_mousePosition[1], 6, 1) - << " z:: " << FloatFormat(m_mousePosition[2], 6, 1); - g_pParentWnd->SetStatusText(g_pParentWnd->m_position_status, status.c_str()); - - if (g_bCrossHairs) { - XYWnd_Update(*this); - } - - Clipper_Crosshair_OnMouseMoved(x, y); - } -} - -void XYWnd::EntityCreate_MouseDown(int x, int y) -{ - m_entityCreate = true; - m_entityCreate_x = x; - m_entityCreate_y = y; -} - -void XYWnd::EntityCreate_MouseMove(int x, int y) -{ - if (m_entityCreate && (m_entityCreate_x != x || m_entityCreate_y != y)) { - m_entityCreate = false; - } -} - -void XYWnd::EntityCreate_MouseUp(int x, int y) -{ - if (m_entityCreate) { - m_entityCreate = false; - OnContextMenu(); - } -} - -inline float screen_normalised(int pos, unsigned int size) -{ - return ((2.0f * pos) / size) - 1.0f; -} - -inline float normalised_to_world(float normalised, float world_origin, float normalised2world_scale) -{ - return world_origin + normalised * normalised2world_scale; -} - - -// TTimo: watch it, this doesn't init one of the 3 coords -void XYWnd::XY_ToPoint(int x, int y, Vector3 &point) -{ - float normalised2world_scale_x = m_nWidth / 2 / m_fScale; - float normalised2world_scale_y = m_nHeight / 2 / m_fScale; - if (m_viewType == XY) { - point[0] = normalised_to_world(screen_normalised(x, m_nWidth), m_vOrigin[0], normalised2world_scale_x); - point[1] = normalised_to_world(-screen_normalised(y, m_nHeight), m_vOrigin[1], normalised2world_scale_y); - } else if (m_viewType == YZ) { - point[1] = normalised_to_world(screen_normalised(x, m_nWidth), m_vOrigin[1], normalised2world_scale_x); - point[2] = normalised_to_world(-screen_normalised(y, m_nHeight), m_vOrigin[2], normalised2world_scale_y); - } else { - point[0] = normalised_to_world(screen_normalised(x, m_nWidth), m_vOrigin[0], normalised2world_scale_x); - point[2] = normalised_to_world(-screen_normalised(y, m_nHeight), m_vOrigin[2], normalised2world_scale_y); - } -} - -void XYWnd::XY_SnapToGrid(Vector3 &point) -{ - if (m_viewType == XY) { - point[0] = float_snapped(point[0], GetSnapGridSize()); - point[1] = float_snapped(point[1], GetSnapGridSize()); - } else if (m_viewType == YZ) { - point[1] = float_snapped(point[1], GetSnapGridSize()); - point[2] = float_snapped(point[2], GetSnapGridSize()); - } else { - point[0] = float_snapped(point[0], GetSnapGridSize()); - point[2] = float_snapped(point[2], GetSnapGridSize()); - } -} - -void XYWnd::XY_LoadBackgroundImage(const char *name) -{ - const char *relative = path_make_relative(name, GlobalFileSystem().findRoot(name)); - if (relative == name) { - globalOutputStream() << "WARNING: could not extract the relative path, using full path instead\n"; - } - - char fileNameWithoutExt[512]; - strncpy(fileNameWithoutExt, relative, sizeof(fileNameWithoutExt) - 1); - fileNameWithoutExt[512 - 1] = '\0'; - fileNameWithoutExt[strlen(fileNameWithoutExt) - 4] = '\0'; - - Image *image = QERApp_LoadImage(0, fileNameWithoutExt); - if (!image) { - globalOutputStream() << "Could not load texture " << fileNameWithoutExt << "\n"; - return; - } - g_pParentWnd->ActiveXY()->m_tex = (qtexture_t *) malloc(sizeof(qtexture_t)); - LoadTextureRGBA(g_pParentWnd->ActiveXY()->XYWnd::m_tex, image->getRGBAPixels(), image->getWidth(), - image->getHeight()); - globalOutputStream() << "Loaded background texture " << relative << "\n"; - g_pParentWnd->ActiveXY()->m_backgroundActivated = true; - - int m_ix, m_iy; - switch (g_pParentWnd->ActiveXY()->m_viewType) { - case XY: - m_ix = 0; - m_iy = 1; - break; - case XZ: - m_ix = 0; - m_iy = 2; - break; - case YZ: - m_ix = 1; - m_iy = 2; - break; - } - - Vector3 min, max; - Select_GetBounds(min, max); - g_pParentWnd->ActiveXY()->m_xmin = min[m_ix]; - g_pParentWnd->ActiveXY()->m_ymin = min[m_iy]; - g_pParentWnd->ActiveXY()->m_xmax = max[m_ix]; - g_pParentWnd->ActiveXY()->m_ymax = max[m_iy]; -} - -void XYWnd::XY_DisableBackground(void) -{ - g_pParentWnd->ActiveXY()->m_backgroundActivated = false; - if (g_pParentWnd->ActiveXY()->m_tex) { - free(g_pParentWnd->ActiveXY()->m_tex); - } - g_pParentWnd->ActiveXY()->m_tex = NULL; -} - -void WXY_BackgroundSelect(void) -{ - bool brushesSelected = Scene_countSelectedBrushes(GlobalSceneGraph()) != 0; - if (!brushesSelected) { - ui::alert(ui::root, "You have to select some brushes to get the bounding box for.\n", - "No selection", ui::alert_type::OK, ui::alert_icon::Error); - return; - } - - const char *filename = MainFrame_getWindow().file_dialog(TRUE, "Background Image", NULL, NULL); - g_pParentWnd->ActiveXY()->XY_DisableBackground(); - if (filename) { - g_pParentWnd->ActiveXY()->XY_LoadBackgroundImage(filename); - } -} - -/* - ============================================================================ - - DRAWING - - ============================================================================ - */ - -/* - ============== - XY_DrawGrid - ============== - */ - -double two_to_the_power(int power) -{ - return pow(2.0f, power); -} - -void XYWnd::XY_DrawAxis(void) -{ - if (g_xywindow_globals_private.show_axis) { - const char g_AxisName[3] = {'X', 'Y', 'Z'}; - const int nDim1 = (m_viewType == YZ) ? 1 : 0; - const int nDim2 = (m_viewType == XY) ? 1 : 2; - const int w = (m_nWidth / 2 / m_fScale); - const int h = (m_nHeight / 2 / m_fScale); - - const Vector3 &colourX = (m_viewType == YZ) ? g_xywindow_globals.AxisColorY : g_xywindow_globals.AxisColorX; - const Vector3 &colourY = (m_viewType == XY) ? g_xywindow_globals.AxisColorY : g_xywindow_globals.AxisColorZ; - - // draw two lines with corresponding axis colors to highlight current view - // horizontal line: nDim1 color - glLineWidth(2); - glBegin(GL_LINES); - glColor3fv(vector3_to_array(colourX)); - glVertex2f(m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale); - glVertex2f(m_vOrigin[nDim1] - w + 65 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale); - glVertex2f(0, 0); - glVertex2f(32 / m_fScale, 0); - glColor3fv(vector3_to_array(colourY)); - glVertex2f(m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale); - glVertex2f(m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale); - glVertex2f(0, 0); - glVertex2f(0, 32 / m_fScale); - glEnd(); - glLineWidth(1); - // now print axis symbols - glColor3fv(vector3_to_array(colourX)); - glRasterPos2f(m_vOrigin[nDim1] - w + 55 / m_fScale, m_vOrigin[nDim2] + h - 55 / m_fScale); - GlobalOpenGL().drawChar(g_AxisName[nDim1]); - glRasterPos2f(28 / m_fScale, -10 / m_fScale); - GlobalOpenGL().drawChar(g_AxisName[nDim1]); - glColor3fv(vector3_to_array(colourY)); - glRasterPos2f(m_vOrigin[nDim1] - w + 25 / m_fScale, m_vOrigin[nDim2] + h - 30 / m_fScale); - GlobalOpenGL().drawChar(g_AxisName[nDim2]); - glRasterPos2f(-10 / m_fScale, 28 / m_fScale); - GlobalOpenGL().drawChar(g_AxisName[nDim2]); - } -} - -void XYWnd::XY_DrawBackground(void) -{ - glPushAttrib(GL_ALL_ATTRIB_BITS); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - glPolygonMode(GL_FRONT, GL_FILL); - - glBindTexture(GL_TEXTURE_2D, m_tex->texture_number); - glBegin(GL_QUADS); - - glColor4f(1.0, 1.0, 1.0, m_alpha); - glTexCoord2f(0.0, 1.0); - glVertex2f(m_xmin, m_ymin); - - glTexCoord2f(1.0, 1.0); - glVertex2f(m_xmax, m_ymin); - - glTexCoord2f(1.0, 0.0); - glVertex2f(m_xmax, m_ymax); - - glTexCoord2f(0.0, 0.0); - glVertex2f(m_xmin, m_ymax); - - glEnd(); - glBindTexture(GL_TEXTURE_2D, 0); - - glPopAttrib(); -} - -void XYWnd::XY_DrawGrid(void) -{ - float x, y, xb, xe, yb, ye; - float w, h, a; - char text[32]; - float step, minor_step, stepx, stepy; - step = minor_step = stepx = stepy = GetGridSize(); - - int minor_power = Grid_getPower(); - int mask; - - while ((minor_step * m_fScale) <= 4.0f) { // make sure minor grid spacing is at least 4 pixels on the screen - ++minor_power; - minor_step *= 2; - } - int power = minor_power; - while ((power % 3) != 0 || - (step * m_fScale) <= 32.0f) { // make sure major grid spacing is at least 32 pixels on the screen - ++power; - step = float(two_to_the_power(power)); - } - mask = (1 << (power - minor_power)) - 1; - while ((stepx * m_fScale) <= 32.0f) { // text step x must be at least 32 - stepx *= 2; - } - while ((stepy * m_fScale) <= 32.0f) { // text step y must be at least 32 - stepy *= 2; - } - - a = ((GetSnapGridSize() > 0.0f) ? 1.0f : 0.3f); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_1D); - glDisable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - glLineWidth(1); - - w = (m_nWidth / 2 / m_fScale); - h = (m_nHeight / 2 / m_fScale); - - const int nDim1 = (m_viewType == YZ) ? 1 : 0; - const int nDim2 = (m_viewType == XY) ? 1 : 2; - - xb = m_vOrigin[nDim1] - w; - if (xb < region_mins[nDim1]) { - xb = region_mins[nDim1]; - } - xb = step * floor(xb / step); - - xe = m_vOrigin[nDim1] + w; - if (xe > region_maxs[nDim1]) { - xe = region_maxs[nDim1]; - } - xe = step * ceil(xe / step); - - yb = m_vOrigin[nDim2] - h; - if (yb < region_mins[nDim2]) { - yb = region_mins[nDim2]; - } - yb = step * floor(yb / step); - - ye = m_vOrigin[nDim2] + h; - if (ye > region_maxs[nDim2]) { - ye = region_maxs[nDim2]; - } - ye = step * ceil(ye / step); - - #define COLORS_DIFFER(a, b) \ - ( ( a )[0] != ( b )[0] || \ - ( a )[1] != ( b )[1] || \ - ( a )[2] != ( b )[2] ) - - // djbob - // draw minor blocks - if (g_xywindow_globals_private.d_showgrid || a < 1.0f) { - if (a < 1.0f) { - glEnable(GL_BLEND); - } - - if (COLORS_DIFFER(g_xywindow_globals.color_gridminor, g_xywindow_globals.color_gridback)) { - glColor4fv(vector4_to_array(Vector4(g_xywindow_globals.color_gridminor, a))); - - glBegin(GL_LINES); - int i = 0; - for (x = xb; x < xe; x += minor_step, ++i) { - if ((i & mask) != 0) { - glVertex2f(x, yb); - glVertex2f(x, ye); - } - } - i = 0; - for (y = yb; y < ye; y += minor_step, ++i) { - if ((i & mask) != 0) { - glVertex2f(xb, y); - glVertex2f(xe, y); - } - } - glEnd(); - } - - // draw major blocks - if (COLORS_DIFFER(g_xywindow_globals.color_gridmajor, g_xywindow_globals.color_gridminor)) { - glColor4fv(vector4_to_array(Vector4(g_xywindow_globals.color_gridmajor, a))); - - glBegin(GL_LINES); - for (x = xb; x <= xe; x += step) { - glVertex2f(x, yb); - glVertex2f(x, ye); - } - for (y = yb; y <= ye; y += step) { - glVertex2f(xb, y); - glVertex2f(xe, y); - } - glEnd(); - } - - if (a < 1.0f) { - glDisable(GL_BLEND); - } - } - - // draw coordinate text if needed - if (g_xywindow_globals_private.show_coordinates) { - glColor4fv(vector4_to_array(Vector4(g_xywindow_globals.color_gridtext, 1.0f))); - float offx = m_vOrigin[nDim2] + h - (4 + GlobalOpenGL().m_font->getPixelAscent()) / m_fScale; - float offy = m_vOrigin[nDim1] - w + 4 / m_fScale; - for (x = xb - fmod(xb, stepx); x <= xe; x += stepx) { - glRasterPos2f(x, offx); - sprintf(text, "%g", x); - GlobalOpenGL().drawString(text); - } - for (y = yb - fmod(yb, stepy); y <= ye; y += stepy) { - glRasterPos2f(offy, y); - sprintf(text, "%g", y); - GlobalOpenGL().drawString(text); - } - - if (Active()) { - glColor3fv(vector3_to_array(g_xywindow_globals.color_viewname)); - } - - // we do this part (the old way) only if show_axis is disabled - if (!g_xywindow_globals_private.show_axis) { - glRasterPos2f(m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale); - - GlobalOpenGL().drawString(ViewType_getTitle(m_viewType)); - } - } - - XYWnd::XY_DrawAxis(); - - // show current work zone? - // the work zone is used to place dropped points and brushes - if (g_xywindow_globals_private.d_show_work) { - glColor4f(1.0f, 0.0f, 0.0f, 1.0f); - glBegin(GL_LINES); - glVertex2f(xb, Select_getWorkZone().d_work_min[nDim2]); - glVertex2f(xe, Select_getWorkZone().d_work_min[nDim2]); - glVertex2f(xb, Select_getWorkZone().d_work_max[nDim2]); - glVertex2f(xe, Select_getWorkZone().d_work_max[nDim2]); - glVertex2f(Select_getWorkZone().d_work_min[nDim1], yb); - glVertex2f(Select_getWorkZone().d_work_min[nDim1], ye); - glVertex2f(Select_getWorkZone().d_work_max[nDim1], yb); - glVertex2f(Select_getWorkZone().d_work_max[nDim1], ye); - glEnd(); - } -} - -/* - ============== - XY_DrawBlockGrid - ============== - */ -void XYWnd::XY_DrawBlockGrid() -{ - if (Map_FindWorldspawn(g_map) == 0) { - return; - } - const char *value = Node_getEntity(*Map_GetWorldspawn(g_map))->getKeyValue("_blocksize"); - if (strlen(value)) { - sscanf(value, "%i", &g_xywindow_globals_private.blockSize); - } - - if (!g_xywindow_globals_private.blockSize || g_xywindow_globals_private.blockSize > 65536 || - g_xywindow_globals_private.blockSize < 1024) { - // don't use custom blocksize if it is less than the default, or greater than the maximum world coordinate - g_xywindow_globals_private.blockSize = 1024; - } - - float x, y, xb, xe, yb, ye; - float w, h; - char text[32]; - - glDisable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_1D); - glDisable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - - w = (m_nWidth / 2 / m_fScale); - h = (m_nHeight / 2 / m_fScale); - - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - - xb = m_vOrigin[nDim1] - w; - if (xb < region_mins[nDim1]) { - xb = region_mins[nDim1]; - } - xb = static_cast( g_xywindow_globals_private.blockSize * floor(xb / g_xywindow_globals_private.blockSize)); - - xe = m_vOrigin[nDim1] + w; - if (xe > region_maxs[nDim1]) { - xe = region_maxs[nDim1]; - } - xe = static_cast( g_xywindow_globals_private.blockSize * ceil(xe / g_xywindow_globals_private.blockSize)); - - yb = m_vOrigin[nDim2] - h; - if (yb < region_mins[nDim2]) { - yb = region_mins[nDim2]; - } - yb = static_cast( g_xywindow_globals_private.blockSize * floor(yb / g_xywindow_globals_private.blockSize)); - - ye = m_vOrigin[nDim2] + h; - if (ye > region_maxs[nDim2]) { - ye = region_maxs[nDim2]; - } - ye = static_cast( g_xywindow_globals_private.blockSize * ceil(ye / g_xywindow_globals_private.blockSize)); - - // draw major blocks - - glColor3fv(vector3_to_array(g_xywindow_globals.color_gridblock)); - glLineWidth(2); - - glBegin(GL_LINES); - - for (x = xb; x <= xe; x += g_xywindow_globals_private.blockSize) { - glVertex2f(x, yb); - glVertex2f(x, ye); - } - - if (m_viewType == XY) { - for (y = yb; y <= ye; y += g_xywindow_globals_private.blockSize) { - glVertex2f(xb, y); - glVertex2f(xe, y); - } - } - - glEnd(); - glLineWidth(1); - - // draw coordinate text if needed - - if (m_viewType == XY && m_fScale > .1) { - for (x = xb; x < xe; x += g_xywindow_globals_private.blockSize) { - for (y = yb; y < ye; y += g_xywindow_globals_private.blockSize) { - glRasterPos2f(x + (g_xywindow_globals_private.blockSize / 2), - y + (g_xywindow_globals_private.blockSize / 2)); - sprintf(text, "%i,%i", (int) floor(x / g_xywindow_globals_private.blockSize), - (int) floor(y / g_xywindow_globals_private.blockSize)); - GlobalOpenGL().drawString(text); - } - } - } - - glColor4f(0, 0, 0, 0); -} - -void XYWnd::DrawCameraIcon(const Vector3 &origin, const Vector3 &angles) -{ - float x, y, fov, box; - double a; - - fov = 48 / m_fScale; - box = 16 / m_fScale; - - if (m_viewType == XY) { - x = origin[0]; - y = origin[1]; - a = degrees_to_radians(angles[CAMERA_YAW]); - } else if (m_viewType == YZ) { - x = origin[1]; - y = origin[2]; - a = degrees_to_radians(angles[CAMERA_PITCH]); - } else { - x = origin[0]; - y = origin[2]; - a = degrees_to_radians(angles[CAMERA_PITCH]); - } - - glColor3f(0.0, 0.0, 1.0); - glBegin(GL_LINE_STRIP); - glVertex3f(x - box, y, 0); - glVertex3f(x, y + (box / 2), 0); - glVertex3f(x + box, y, 0); - glVertex3f(x, y - (box / 2), 0); - glVertex3f(x - box, y, 0); - glVertex3f(x + box, y, 0); - glEnd(); - - glBegin(GL_LINE_STRIP); - glVertex3f(x + static_cast( fov * cos(a + c_pi / 4)), y + static_cast( fov * sin(a + c_pi / 4)), 0); - glVertex3f(x, y, 0); - glVertex3f(x + static_cast( fov * cos(a - c_pi / 4)), y + static_cast( fov * sin(a - c_pi / 4)), 0); - glEnd(); - -} - - -float Betwixt(float f1, float f2) -{ - if (f1 > f2) { - return f2 + ((f1 - f2) / 2); - } else { - return f1 + ((f2 - f1) / 2); - } -} - - -// can be greatly simplified but per usual i am in a hurry -// which is not an excuse, just a fact -void XYWnd::PaintSizeInfo(int nDim1, int nDim2, Vector3 &vMinBounds, Vector3 &vMaxBounds) -{ - if (vector3_equal(vMinBounds, vMaxBounds)) { - return; - } - const char *g_pDimStrings[] = {"x:", "y:", "z:"}; - typedef const char *OrgStrings[2]; - const OrgStrings g_pOrgStrings[] = {{"x:", "y:",}, - {"x:", "z:",}, - {"y:", "z:",}}; - - Vector3 vSize(vector3_subtracted(vMaxBounds, vMinBounds)); - - glColor3f(g_xywindow_globals.color_selbrushes[0] * .65f, - g_xywindow_globals.color_selbrushes[1] * .65f, - g_xywindow_globals.color_selbrushes[2] * .65f); - - StringOutputStream dimensions(16); - - if (m_viewType == XY) { - glBegin(GL_LINES); - glVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); - glVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); - glVertex3f(vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); - glVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); - glVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale, 0.0f); - glVertex3f(vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale, 0.0f); - glVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2], 0.0f); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2], 0.0f); - glEnd(); - - glRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0f / m_fScale, 0.0f); - dimensions << g_pDimStrings[nDim1] << vSize[nDim1]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(vMaxBounds[nDim1] + 16.0f / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2]), 0.0f); - dimensions << g_pDimStrings[nDim2] << vSize[nDim2]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(vMinBounds[nDim1] + 4, vMaxBounds[nDim2] + 8 / m_fScale, 0.0f); - dimensions << "(" << g_pOrgStrings[0][0] << vMinBounds[nDim1] << " " << g_pOrgStrings[0][1] - << vMaxBounds[nDim2] << ")"; - GlobalOpenGL().drawString(dimensions.c_str()); - } else if (m_viewType == XZ) { - glBegin(GL_LINES); - glVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); - glVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(vMinBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 6.0f / m_fScale); - glVertex3f(vMaxBounds[nDim1], 0, vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMinBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMinBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 6.0f / m_fScale, 0, vMaxBounds[nDim2]); - glVertex3f(vMaxBounds[nDim1] + 10.0f / m_fScale, 0, vMaxBounds[nDim2]); - glEnd(); - - glRasterPos3f(Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), 0, vMinBounds[nDim2] - 20.0f / m_fScale); - dimensions << g_pDimStrings[nDim1] << vSize[nDim1]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(vMaxBounds[nDim1] + 16.0f / m_fScale, 0, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); - dimensions << g_pDimStrings[nDim2] << vSize[nDim2]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(vMinBounds[nDim1] + 4, 0, vMaxBounds[nDim2] + 8 / m_fScale); - dimensions << "(" << g_pOrgStrings[1][0] << vMinBounds[nDim1] << " " << g_pOrgStrings[1][1] - << vMaxBounds[nDim2] << ")"; - GlobalOpenGL().drawString(dimensions.c_str()); - } else { - glBegin(GL_LINES); - glVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); - glVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(0, vMinBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 6.0f / m_fScale); - glVertex3f(0, vMaxBounds[nDim1], vMinBounds[nDim2] - 10.0f / m_fScale); - glVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMinBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMinBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 6.0f / m_fScale, vMaxBounds[nDim2]); - glVertex3f(0, vMaxBounds[nDim1] + 10.0f / m_fScale, vMaxBounds[nDim2]); - glEnd(); - - glRasterPos3f(0, Betwixt(vMinBounds[nDim1], vMaxBounds[nDim1]), vMinBounds[nDim2] - 20.0f / m_fScale); - dimensions << g_pDimStrings[nDim1] << vSize[nDim1]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(0, vMaxBounds[nDim1] + 16.0f / m_fScale, Betwixt(vMinBounds[nDim2], vMaxBounds[nDim2])); - dimensions << g_pDimStrings[nDim2] << vSize[nDim2]; - GlobalOpenGL().drawString(dimensions.c_str()); - dimensions.clear(); - - glRasterPos3f(0, vMinBounds[nDim1] + 4.0f, vMaxBounds[nDim2] + 8 / m_fScale); - dimensions << "(" << g_pOrgStrings[2][0] << vMinBounds[nDim1] << " " << g_pOrgStrings[2][1] - << vMaxBounds[nDim2] << ")"; - GlobalOpenGL().drawString(dimensions.c_str()); - } -} - -class XYRenderer : public Renderer { -struct state_type { - state_type() : - m_highlight(0), - m_state(0) - { - } - - unsigned int m_highlight; - Shader *m_state; -}; - -public: -XYRenderer(RenderStateFlags globalstate, Shader *selected) : - m_globalstate(globalstate), - m_state_selected(selected) -{ - ASSERT_NOTNULL(selected); - m_state_stack.push_back(state_type()); -} - -void SetState(Shader *state, EStyle style) -{ - ASSERT_NOTNULL(state); - if (style == eWireframeOnly) { - m_state_stack.back().m_state = state; - } -} - -EStyle getStyle() const -{ - return eWireframeOnly; -} - -void PushState() -{ - m_state_stack.push_back(m_state_stack.back()); -} - -void PopState() -{ - ASSERT_MESSAGE(!m_state_stack.empty(), "popping empty stack"); - m_state_stack.pop_back(); -} - -void Highlight(EHighlightMode mode, bool bEnable = true) -{ - (bEnable) - ? m_state_stack.back().m_highlight |= mode - : m_state_stack.back().m_highlight &= ~mode; -} - -void addRenderable(const OpenGLRenderable &renderable, const Matrix4 &localToWorld) -{ - if (m_state_stack.back().m_highlight & ePrimitive) { - m_state_selected->addRenderable(renderable, localToWorld); - } else { - m_state_stack.back().m_state->addRenderable(renderable, localToWorld); - } -} - -void render(const Matrix4 &modelview, const Matrix4 &projection) -{ - GlobalShaderCache().render(m_globalstate, modelview, projection); -} - -private: -std::vector m_state_stack; -RenderStateFlags m_globalstate; -Shader *m_state_selected; -}; - -void XYWnd::updateProjection() -{ - m_projection[0] = 1.0f / static_cast( m_nWidth / 2 ); - m_projection[5] = 1.0f / static_cast( m_nHeight / 2 ); - m_projection[10] = 1.0f / (g_MaxWorldCoord * m_fScale); - - m_projection[12] = 0.0f; - m_projection[13] = 0.0f; - m_projection[14] = -1.0f; - - m_projection[1] = - m_projection[2] = - m_projection[3] = - - m_projection[4] = - m_projection[6] = - m_projection[7] = - - m_projection[8] = - m_projection[9] = - m_projection[11] = 0.0f; - - m_projection[15] = 1.0f; - - m_view.Construct(m_projection, m_modelview, m_nWidth, m_nHeight); -} - -// note: modelview matrix must have a uniform scale, otherwise strange things happen when rendering the rotation manipulator. -void XYWnd::updateModelview() -{ - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - - // translation - m_modelview[12] = -m_vOrigin[nDim1] * m_fScale; - m_modelview[13] = -m_vOrigin[nDim2] * m_fScale; - m_modelview[14] = g_MaxWorldCoord * m_fScale; - - // axis base - switch (m_viewType) { - case XY: - m_modelview[0] = m_fScale; - m_modelview[1] = 0; - m_modelview[2] = 0; - - m_modelview[4] = 0; - m_modelview[5] = m_fScale; - m_modelview[6] = 0; - - m_modelview[8] = 0; - m_modelview[9] = 0; - m_modelview[10] = -m_fScale; - break; - case XZ: - m_modelview[0] = m_fScale; - m_modelview[1] = 0; - m_modelview[2] = 0; - - m_modelview[4] = 0; - m_modelview[5] = 0; - m_modelview[6] = m_fScale; - - m_modelview[8] = 0; - m_modelview[9] = m_fScale; - m_modelview[10] = 0; - break; - case YZ: - m_modelview[0] = 0; - m_modelview[1] = 0; - m_modelview[2] = -m_fScale; - - m_modelview[4] = m_fScale; - m_modelview[5] = 0; - m_modelview[6] = 0; - - m_modelview[8] = 0; - m_modelview[9] = m_fScale; - m_modelview[10] = 0; - break; - } - - m_modelview[3] = m_modelview[7] = m_modelview[11] = 0; - m_modelview[15] = 1; - - m_view.Construct(m_projection, m_modelview, m_nWidth, m_nHeight); -} - -/* - ============== - XY_Draw - ============== - */ - -//#define DBG_SCENEDUMP - -void XYWnd::XY_Draw() -{ - // - // clear - // - glViewport(0, 0, m_nWidth, m_nHeight); - glClearColor(g_xywindow_globals.color_gridback[0], - g_xywindow_globals.color_gridback[1], - g_xywindow_globals.color_gridback[2], 0); - - glClear(GL_COLOR_BUFFER_BIT); - - // - // set up viewpoint - // - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(reinterpret_cast( &m_projection )); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glScalef(m_fScale, m_fScale, 1); - int nDim1 = (m_viewType == YZ) ? 1 : 0; - int nDim2 = (m_viewType == XY) ? 1 : 2; - glTranslatef(-m_vOrigin[nDim1], -m_vOrigin[nDim2], 0); - - glDisable(GL_LINE_STIPPLE); - glLineWidth(1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_DEPTH_TEST); - - if (m_backgroundActivated) { - XY_DrawBackground(); - } - XY_DrawGrid(); - - if (g_xywindow_globals_private.show_blocks) { - XY_DrawBlockGrid(); - } - - glLoadMatrixf(reinterpret_cast( &m_modelview )); - - unsigned int globalstate = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_POLYGONSMOOTH | RENDER_LINESMOOTH; - if (!g_xywindow_globals.m_bNoStipple) { - globalstate |= RENDER_LINESTIPPLE; - } - - { - XYRenderer renderer(globalstate, m_state_selected); - Scene_Render(renderer, m_view); - GlobalOpenGL_debugAssertNoErrors(); - renderer.render(m_modelview, m_projection); - GlobalOpenGL_debugAssertNoErrors(); - } - - glDepthMask(GL_FALSE); - GlobalOpenGL_debugAssertNoErrors(); - glLoadMatrixf(reinterpret_cast( &m_modelview )); - - GlobalOpenGL_debugAssertNoErrors(); - glDisable(GL_LINE_STIPPLE); - GlobalOpenGL_debugAssertNoErrors(); - glLineWidth(1); - GlobalOpenGL_debugAssertNoErrors(); - if (GlobalOpenGL().GL_1_3()) { - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - glDisableClientState(GL_NORMAL_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - glDisableClientState(GL_COLOR_ARRAY); - GlobalOpenGL_debugAssertNoErrors(); - glDisable(GL_TEXTURE_2D); - GlobalOpenGL_debugAssertNoErrors(); - glDisable(GL_LIGHTING); - GlobalOpenGL_debugAssertNoErrors(); - glDisable(GL_COLOR_MATERIAL); - GlobalOpenGL_debugAssertNoErrors(); - GlobalOpenGL_debugAssertNoErrors(); - - - // size info - if (g_xywindow_globals_private.m_bSizePaint && GlobalSelectionSystem().countSelected() != 0) { - Vector3 min, max; - Select_GetBounds(min, max); - PaintSizeInfo(nDim1, nDim2, min, max); - } - - if (g_bCrossHairs) { - glColor4f(0.2f, 0.9f, 0.2f, 0.8f); - glBegin(GL_LINES); - if (m_viewType == XY) { - glVertex2f(2.0f * g_MinWorldCoord, m_mousePosition[1]); - glVertex2f(2.0f * g_MaxWorldCoord, m_mousePosition[1]); - glVertex2f(m_mousePosition[0], 2.0f * g_MinWorldCoord); - glVertex2f(m_mousePosition[0], 2.0f * g_MaxWorldCoord); - } else if (m_viewType == YZ) { - glVertex3f(m_mousePosition[0], 2.0f * g_MinWorldCoord, m_mousePosition[2]); - glVertex3f(m_mousePosition[0], 2.0f * g_MaxWorldCoord, m_mousePosition[2]); - glVertex3f(m_mousePosition[0], m_mousePosition[1], 2.0f * g_MinWorldCoord); - glVertex3f(m_mousePosition[0], m_mousePosition[1], 2.0f * g_MaxWorldCoord); - } else { - glVertex3f(2.0f * g_MinWorldCoord, m_mousePosition[1], m_mousePosition[2]); - glVertex3f(2.0f * g_MaxWorldCoord, m_mousePosition[1], m_mousePosition[2]); - glVertex3f(m_mousePosition[0], m_mousePosition[1], 2.0f * g_MinWorldCoord); - glVertex3f(m_mousePosition[0], m_mousePosition[1], 2.0f * g_MaxWorldCoord); - } - glEnd(); - } - - if (ClipMode()) { - GlobalClipPoints_Draw(m_fScale); - } - - GlobalOpenGL_debugAssertNoErrors(); - - // reset modelview - glLoadIdentity(); - glScalef(m_fScale, m_fScale, 1); - glTranslatef(-m_vOrigin[nDim1], -m_vOrigin[nDim2], 0); - DrawCameraIcon(Camera_getOrigin(*g_pParentWnd->GetCamWnd()), Camera_getAngles(*g_pParentWnd->GetCamWnd())); - Feedback_draw2D(m_viewType); - - if (g_xywindow_globals_private.show_outline) { - if (Active()) { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, m_nWidth, 0, m_nHeight, 0, 1); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - switch (m_viewType) { - case YZ: - glColor3fv(vector3_to_array(g_xywindow_globals.AxisColorX)); - break; - case XZ: - glColor3fv(vector3_to_array(g_xywindow_globals.AxisColorY)); - break; - case XY: - glColor3fv(vector3_to_array(g_xywindow_globals.AxisColorZ)); - break; - } - - glBegin(GL_LINE_LOOP); - glVertex2f(0.5, 0.5); - glVertex2f(m_nWidth - 0.5, 1); - glVertex2f(m_nWidth - 0.5, m_nHeight - 0.5); - glVertex2f(0.5, m_nHeight - 0.5); - glEnd(); - } - } - - GlobalOpenGL_debugAssertNoErrors(); - glFinish(); -} - -void XYWnd_MouseToPoint(XYWnd *xywnd, int x, int y, Vector3 &point) -{ - xywnd->XY_ToPoint(x, y, point); - xywnd->XY_SnapToGrid(point); - - int nDim = (xywnd->GetViewType() == XY) ? 2 : (xywnd->GetViewType() == YZ) ? 0 : 1; - float fWorkMid = float_mid(Select_getWorkZone().d_work_min[nDim], Select_getWorkZone().d_work_max[nDim]); - point[nDim] = float_snapped(fWorkMid, GetGridSize()); -} - -void XYWnd::OnEntityCreate(const char *item) -{ - StringOutputStream command; - command << "entityCreate -class " << item; - UndoableCommand undo(command.c_str()); - Vector3 point; - XYWnd_MouseToPoint(this, m_entityCreate_x, m_entityCreate_y, point); - Entity_createFromSelection(item, point); -} - - -void GetFocusPosition(Vector3 &position) -{ - if (GlobalSelectionSystem().countSelected() != 0) { - Select_GetMid(position); - } else { - position = Camera_getOrigin(*g_pParentWnd->GetCamWnd()); - } -} - -void XYWnd_Focus(XYWnd *xywnd) -{ - Vector3 position; - GetFocusPosition(position); - xywnd->PositionView(position); -} - -void XY_Split_Focus() -{ - Vector3 position; - GetFocusPosition(position); - if (g_pParentWnd->GetXYWnd()) { - g_pParentWnd->GetXYWnd()->PositionView(position); - } - if (g_pParentWnd->GetXZWnd()) { - g_pParentWnd->GetXZWnd()->PositionView(position); - } - if (g_pParentWnd->GetYZWnd()) { - g_pParentWnd->GetYZWnd()->PositionView(position); - } -} - -void XY_Focus() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - XYWnd_Focus(xywnd); -#endif -} - -void XY_Top() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - xywnd->SetViewType(XY); - XYWnd_Focus(xywnd); -#endif -} - -void XY_Side() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - xywnd->SetViewType(XZ); - XYWnd_Focus(xywnd); -#endif -} - -void XY_Front() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - xywnd->SetViewType(YZ); - XYWnd_Focus(xywnd); -#endif -} - -void XY_Next() -{ -#if 1 - // cannot do this in a split window - // do something else that the user may want here - XY_Split_Focus(); - return; -#else - XYWnd *xywnd = g_pParentWnd->GetXYWnd(); - if (xywnd->GetViewType() == XY) { - xywnd->SetViewType(XZ); - } else if (xywnd->GetViewType() == XZ) { - xywnd->SetViewType(YZ); - } else { - xywnd->SetViewType(XY); - } - XYWnd_Focus(xywnd); -#endif -} - -void XY_Zoom100() -{ - if (g_pParentWnd->GetXYWnd()) { - g_pParentWnd->GetXYWnd()->SetScale(1); - } - if (g_pParentWnd->GetXZWnd()) { - g_pParentWnd->GetXZWnd()->SetScale(1); - } - if (g_pParentWnd->GetYZWnd()) { - g_pParentWnd->GetYZWnd()->SetScale(1); - } -} - -void XY_ZoomIn() -{ - XYWnd_ZoomIn(g_pParentWnd->ActiveXY()); -} - -// NOTE: the zoom out factor is 4/5, we could think about customizing it -// we don't go below a zoom factor corresponding to 10% of the max world size -// (this has to be computed against the window size) -void XY_ZoomOut() -{ - XYWnd_ZoomOut(g_pParentWnd->ActiveXY()); -} - - -void ToggleShowCrosshair() -{ - g_bCrossHairs ^= 1; - XY_UpdateAllWindows(); -} - -void ToggleShowSizeInfo() -{ - g_xywindow_globals_private.m_bSizePaint = !g_xywindow_globals_private.m_bSizePaint; - XY_UpdateAllWindows(); -} - -void ToggleShowGrid() -{ - g_xywindow_globals_private.d_showgrid = !g_xywindow_globals_private.d_showgrid; - XY_UpdateAllWindows(); -} - -ToggleShown g_xy_top_shown(true); - -void XY_Top_Shown_Construct(ui::Window parent) -{ - g_xy_top_shown.connect(parent); -} - -ToggleShown g_yz_side_shown(false); - -void YZ_Side_Shown_Construct(ui::Window parent) -{ - g_yz_side_shown.connect(parent); -} - -ToggleShown g_xz_front_shown(false); - -void XZ_Front_Shown_Construct(ui::Window parent) -{ - g_xz_front_shown.connect(parent); -} - - -class EntityClassMenu : public ModuleObserver { -std::size_t m_unrealised; -public: -EntityClassMenu() : m_unrealised(1) -{ -} - -void realise() -{ - if (--m_unrealised == 0) { - } -} - -void unrealise() -{ - if (++m_unrealised == 1) { - if (XYWnd::m_mnuDrop) { - XYWnd::m_mnuDrop.destroy(); - XYWnd::m_mnuDrop = ui::Menu(ui::null); - } - if (XYWnd::m_mnuDropSingle) { - XYWnd::m_mnuDropSingle.destroy(); - XYWnd::m_mnuDropSingle = ui::Menu(ui::null); - } - if (XYWnd::m_mnuDropMultiple) { - XYWnd::m_mnuDropMultiple.destroy(); - XYWnd::m_mnuDropMultiple = ui::Menu(ui::null); - } - } -} -}; - -EntityClassMenu g_EntityClassMenu; - - -void ShowNamesToggle() -{ - GlobalEntityCreator().setShowNames(!GlobalEntityCreator().getShowNames()); - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowNamesToggleCaller; - -void ShowNamesExport(const Callback &importer) -{ - importer(GlobalEntityCreator().getShowNames()); -} - -typedef FreeCaller &), ShowNamesExport> ShowNamesExportCaller; - -void ShowAnglesToggle() -{ - GlobalEntityCreator().setShowAngles(!GlobalEntityCreator().getShowAngles()); - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowAnglesToggleCaller; - -void ShowAnglesExport(const Callback &importer) -{ - importer(GlobalEntityCreator().getShowAngles()); -} - -typedef FreeCaller &), ShowAnglesExport> ShowAnglesExportCaller; - -void ShowBlocksToggle() -{ - g_xywindow_globals_private.show_blocks ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowBlocksToggleCaller; - -void ShowBlocksExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.show_blocks); -} - -typedef FreeCaller &), ShowBlocksExport> ShowBlocksExportCaller; - -void ShowCoordinatesToggle() -{ - g_xywindow_globals_private.show_coordinates ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowCoordinatesToggleCaller; - -void ShowCoordinatesExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.show_coordinates); -} - -typedef FreeCaller &), ShowCoordinatesExport> ShowCoordinatesExportCaller; - -void ShowOutlineToggle() -{ - g_xywindow_globals_private.show_outline ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowOutlineToggleCaller; - -void ShowOutlineExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.show_outline); -} - -typedef FreeCaller &), ShowOutlineExport> ShowOutlineExportCaller; - -void ShowAxesToggle() -{ - g_xywindow_globals_private.show_axis ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowAxesToggleCaller; - -void ShowAxesExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.show_axis); -} - -typedef FreeCaller &), ShowAxesExport> ShowAxesExportCaller; - -void ShowWorkzoneToggle() -{ - g_xywindow_globals_private.d_show_work ^= 1; - XY_UpdateAllWindows(); -} - -typedef FreeCaller ShowWorkzoneToggleCaller; - -void ShowWorkzoneExport(const Callback &importer) -{ - importer(g_xywindow_globals_private.d_show_work); -} - -typedef FreeCaller &), ShowWorkzoneExport> ShowWorkzoneExportCaller; - -ShowNamesExportCaller g_show_names_caller; -Callback &)> g_show_names_callback(g_show_names_caller); -ToggleItem g_show_names(g_show_names_callback); - -ShowAnglesExportCaller g_show_angles_caller; -Callback &)> g_show_angles_callback(g_show_angles_caller); -ToggleItem g_show_angles(g_show_angles_callback); - -ShowBlocksExportCaller g_show_blocks_caller; -Callback &)> g_show_blocks_callback(g_show_blocks_caller); -ToggleItem g_show_blocks(g_show_blocks_callback); - -ShowCoordinatesExportCaller g_show_coordinates_caller; -Callback &)> g_show_coordinates_callback(g_show_coordinates_caller); -ToggleItem g_show_coordinates(g_show_coordinates_callback); - -ShowOutlineExportCaller g_show_outline_caller; -Callback &)> g_show_outline_callback(g_show_outline_caller); -ToggleItem g_show_outline(g_show_outline_callback); - -ShowAxesExportCaller g_show_axes_caller; -Callback &)> g_show_axes_callback(g_show_axes_caller); -ToggleItem g_show_axes(g_show_axes_callback); - -ShowWorkzoneExportCaller g_show_workzone_caller; -Callback &)> g_show_workzone_callback(g_show_workzone_caller); -ToggleItem g_show_workzone(g_show_workzone_callback); - -void XYShow_registerCommands() -{ - GlobalToggles_insert("ShowAngles", ShowAnglesToggleCaller(), ToggleItem::AddCallbackCaller(g_show_angles)); - GlobalToggles_insert("ShowNames", ShowNamesToggleCaller(), ToggleItem::AddCallbackCaller(g_show_names)); - GlobalToggles_insert("ShowBlocks", ShowBlocksToggleCaller(), ToggleItem::AddCallbackCaller(g_show_blocks)); - GlobalToggles_insert("ShowCoordinates", ShowCoordinatesToggleCaller(), - ToggleItem::AddCallbackCaller(g_show_coordinates)); - GlobalToggles_insert("ShowWindowOutline", ShowOutlineToggleCaller(), ToggleItem::AddCallbackCaller(g_show_outline)); - GlobalToggles_insert("ShowAxes", ShowAxesToggleCaller(), ToggleItem::AddCallbackCaller(g_show_axes)); - GlobalToggles_insert("ShowWorkzone", ShowWorkzoneToggleCaller(), ToggleItem::AddCallbackCaller(g_show_workzone)); -} - -void XYWnd_registerShortcuts() -{ - command_connect_accelerator("ToggleCrosshairs"); - command_connect_accelerator("ToggleSizePaint"); -} - - -void Orthographic_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox("", "Solid selection boxes", g_xywindow_globals.m_bNoStipple); - page.appendCheckBox("", "Display size info", g_xywindow_globals_private.m_bSizePaint); - page.appendCheckBox("", "Chase mouse during drags", g_xywindow_globals_private.m_bChaseMouse); - page.appendCheckBox("", "Update views on camera move", g_xywindow_globals_private.m_bCamXYUpdate); -} - -void Orthographic_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Orthographic", "Orthographic View Preferences")); - Orthographic_constructPreferences(page); -} - -void Orthographic_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Orthographic_constructPage)); -} - -void Clipper_constructPreferences(PreferencesPage &page) -{ - page.appendCheckBox("", "Clipper tool uses caulk", g_clip_useCaulk); -} - -void Clipper_constructPage(PreferenceGroup &group) -{ - PreferencesPage page(group.createPage("Clipper", "Clipper Tool Settings")); - Clipper_constructPreferences(page); -} - -void Clipper_registerPreferencesPage() -{ - PreferencesDialog_addSettingsPage(makeCallbackF(Clipper_constructPage)); -} - - -#include "preferencesystem.h" -#include "stringio.h" - - -struct ToggleShown_Bool { - static void Export(const ToggleShown &self, const Callback &returnz) - { - returnz(self.active()); - } - - static void Import(ToggleShown &self, bool value) - { - self.set(value); - } -}; - - -void XYWindow_Construct() -{ - GlobalCommands_insert("ToggleCrosshairs", makeCallbackF(ToggleShowCrosshair), - Accelerator('X', (GdkModifierType) GDK_SHIFT_MASK)); - GlobalCommands_insert("ToggleSizePaint", makeCallbackF(ToggleShowSizeInfo), Accelerator('J')); - GlobalCommands_insert("ToggleGrid", makeCallbackF(ToggleShowGrid), Accelerator('0')); - - GlobalToggles_insert("ToggleView", ToggleShown::ToggleCaller(g_xy_top_shown), - ToggleItem::AddCallbackCaller(g_xy_top_shown.m_item), - Accelerator('V', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - GlobalToggles_insert("ToggleSideView", ToggleShown::ToggleCaller(g_yz_side_shown), - ToggleItem::AddCallbackCaller(g_yz_side_shown.m_item)); - GlobalToggles_insert("ToggleFrontView", ToggleShown::ToggleCaller(g_xz_front_shown), - ToggleItem::AddCallbackCaller(g_xz_front_shown.m_item)); - GlobalCommands_insert("NextView", makeCallbackF(XY_Next), Accelerator(GDK_KEY_Tab, - (GdkModifierType) GDK_CONTROL_MASK)); // fixme: doesn't show its shortcut - GlobalCommands_insert("ZoomIn", makeCallbackF(XY_ZoomIn), Accelerator(GDK_KEY_Delete)); - GlobalCommands_insert("ZoomOut", makeCallbackF(XY_ZoomOut), Accelerator(GDK_KEY_Insert)); - GlobalCommands_insert("ViewTop", makeCallbackF(XY_Top), Accelerator(GDK_KEY_KP_Home)); - GlobalCommands_insert("ViewSide", makeCallbackF(XY_Side), Accelerator(GDK_KEY_KP_Page_Down)); - GlobalCommands_insert("ViewFront", makeCallbackF(XY_Front), Accelerator(GDK_KEY_KP_End)); - GlobalCommands_insert("Zoom100", makeCallbackF(XY_Zoom100)); - GlobalCommands_insert("CenterXYView", makeCallbackF(XY_Focus), - Accelerator(GDK_KEY_Tab, (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK))); - - GlobalPreferenceSystem().registerPreference("ClipCaulk", make_property_string(g_clip_useCaulk)); - - GlobalPreferenceSystem().registerPreference("NewRightClick", - make_property_string(g_xywindow_globals.m_bRightClick)); - GlobalPreferenceSystem().registerPreference("ChaseMouse", - make_property_string(g_xywindow_globals_private.m_bChaseMouse)); - GlobalPreferenceSystem().registerPreference("SizePainting", - make_property_string(g_xywindow_globals_private.m_bSizePaint)); - GlobalPreferenceSystem().registerPreference("NoStipple", make_property_string(g_xywindow_globals.m_bNoStipple)); - GlobalPreferenceSystem().registerPreference("SI_ShowCoords", - make_property_string(g_xywindow_globals_private.show_coordinates)); - GlobalPreferenceSystem().registerPreference("SI_ShowOutlines", - make_property_string(g_xywindow_globals_private.show_outline)); - GlobalPreferenceSystem().registerPreference("SI_ShowAxis", - make_property_string(g_xywindow_globals_private.show_axis)); - GlobalPreferenceSystem().registerPreference("CamXYUpdate", - make_property_string(g_xywindow_globals_private.m_bCamXYUpdate)); - GlobalPreferenceSystem().registerPreference("ShowWorkzone", - make_property_string(g_xywindow_globals_private.d_show_work)); - - GlobalPreferenceSystem().registerPreference("SI_AxisColors0", make_property_string(g_xywindow_globals.AxisColorX)); - GlobalPreferenceSystem().registerPreference("SI_AxisColors1", make_property_string(g_xywindow_globals.AxisColorY)); - GlobalPreferenceSystem().registerPreference("SI_AxisColors2", make_property_string(g_xywindow_globals.AxisColorZ)); - GlobalPreferenceSystem().registerPreference("SI_Colors1", make_property_string(g_xywindow_globals.color_gridback)); - GlobalPreferenceSystem().registerPreference("SI_Colors2", make_property_string(g_xywindow_globals.color_gridminor)); - GlobalPreferenceSystem().registerPreference("SI_Colors3", make_property_string(g_xywindow_globals.color_gridmajor)); - GlobalPreferenceSystem().registerPreference("SI_Colors6", make_property_string(g_xywindow_globals.color_gridblock)); - GlobalPreferenceSystem().registerPreference("SI_Colors7", make_property_string(g_xywindow_globals.color_gridtext)); - GlobalPreferenceSystem().registerPreference("SI_Colors8", make_property_string(g_xywindow_globals.color_brushes)); - GlobalPreferenceSystem().registerPreference("SI_Colors14", - make_property_string(g_xywindow_globals.color_gridmajor_alt)); - - - GlobalPreferenceSystem().registerPreference("XZVIS", make_property_string(g_xz_front_shown)); - GlobalPreferenceSystem().registerPreference("YZVIS", make_property_string(g_yz_side_shown)); - - Orthographic_registerPreferencesPage(); - Clipper_registerPreferencesPage(); - - XYWnd::captureStates(); - GlobalEntityClassManager().attach(g_EntityClassMenu); -} - -void XYWindow_Destroy() -{ - GlobalEntityClassManager().detach(g_EntityClassMenu); - XYWnd::releaseStates(); -} diff --git a/src/xywindow.h b/src/xywindow.h deleted file mode 100644 index 3878148..0000000 --- a/src/xywindow.h +++ /dev/null @@ -1,366 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined( INCLUDED_XYWINDOW_H ) -#define INCLUDED_XYWINDOW_H - -#include "math/matrix.h" -#include "signal/signal.h" - -#include "gtkutil/cursor.h" -#include "gtkutil/window.h" -#include "gtkutil/xorrectangle.h" -#include "view.h" -#include "map.h" -#include "texturelib.h" - -#include "qerplugin.h" - -class Shader; - -class SelectionSystemWindowObserver; -namespace scene { -class Node; -} - - -void FlipClip(); - -void SplitClip(); - -void Clip(); - -void OnClipMode(bool enabled); - -bool ClipMode(); - -inline const char *ViewType_getTitle(VIEWTYPE viewtype) -{ - if (viewtype == XY) { - return "XY Top"; - } - if (viewtype == XZ) { - return "XZ Front"; - } - if (viewtype == YZ) { - return "YZ Side"; - } - return ""; -} - -class XYWnd { -ui::GLArea m_gl_widget; -guint m_sizeHandler; -guint m_exposeHandler; - -DeferredDraw m_deferredDraw; -DeferredMotion m_deferred_motion; -public: -ui::Window m_parent; - -XYWnd(); - -~XYWnd(); - -void queueDraw() -{ - m_deferredDraw.draw(); -} - -ui::GLArea GetWidget() -{ - return m_gl_widget; -} - -public: -SelectionSystemWindowObserver *m_window_observer; -XORRectangle m_XORRectangle; -WindowPositionTracker m_positionTracker; - -static void captureStates(); - -static void releaseStates(); - -void PositionView(const Vector3 &position); - -const Vector3 &GetOrigin(); - -void SetOrigin(const Vector3 &origin); - -void Scroll(int x, int y); - -void XY_Draw(); - -void DrawCameraIcon(const Vector3 &origin, const Vector3 &angles); - -void XY_DrawBlockGrid(); - -void XY_DrawAxis(); - -void XY_DrawGrid(); - -void XY_DrawBackground(); - -void XY_LoadBackgroundImage(const char *name); - -void XY_DisableBackground(); - -void XY_MouseUp(int x, int y, unsigned int buttons); - -void XY_MouseDown(int x, int y, unsigned int buttons); - -void XY_MouseMoved(int x, int y, unsigned int buttons); - -void NewBrushDrag_Begin(int x, int y); - -void NewBrushDrag(int x, int y); - -void NewBrushDrag_End(int x, int y); - -void XY_ToPoint(int x, int y, Vector3 &point); - -void XY_SnapToGrid(Vector3 &point); - -void Move_Begin(); - -void Move_End(); - -bool m_move_started; -guint m_move_focusOut; - -void Zoom_Begin(); - -void Zoom_End(); - -bool m_zoom_started; -guint m_zoom_focusOut; - -void SetActive(bool b) -{ - m_bActive = b; -}; - -bool Active() -{ - return m_bActive; -}; - -void Clipper_OnLButtonDown(int x, int y); - -void Clipper_OnLButtonUp(int x, int y); - -void Clipper_OnMouseMoved(int x, int y); - -void Clipper_Crosshair_OnMouseMoved(int x, int y); - -void DropClipPoint(int pointx, int pointy); - -void SetViewType(VIEWTYPE n); - -bool m_bActive; - -static ui::Menu m_mnuDrop; -static ui::Menu m_mnuDropSingle; -static ui::Menu m_mnuDropMultiple; - -int m_chasemouse_current_x, m_chasemouse_current_y; -int m_chasemouse_delta_x, m_chasemouse_delta_y; - - -guint m_chasemouse_handler; - -void ChaseMouse(); - -bool chaseMouseMotion(int pointx, int pointy); - -void updateModelview(); - -void updateProjection(); - -Matrix4 m_projection; -Matrix4 m_modelview; - -int m_nWidth; -int m_nHeight; -// background image stuff -qtexture_t *m_tex; -bool m_backgroundActivated; -float m_alpha; // vertex alpha -float m_xmin, m_ymin, m_xmax, m_ymax; -private: -float m_fScale; -Vector3 m_vOrigin; - - -View m_view; -static Shader *m_state_selected; - -int m_ptCursorX, m_ptCursorY; - -unsigned int m_buttonstate; - -int m_nNewBrushPressx; -int m_nNewBrushPressy; -scene::Node *m_NewBrushDrag; -bool m_bNewBrushDrag; - -Vector3 m_mousePosition; - -VIEWTYPE m_viewType; - -void OriginalButtonUp(guint32 nFlags, int point, int pointy); - -void OriginalButtonDown(guint32 nFlags, int point, int pointy); - -void OnContextMenu(); - -void PaintSizeInfo(int nDim1, int nDim2, Vector3 &vMinBounds, Vector3 &vMaxBounds); - -int m_entityCreate_x, m_entityCreate_y; -bool m_entityCreate; - -public: -void ButtonState_onMouseDown(unsigned int buttons) -{ - m_buttonstate |= buttons; -} - -void ButtonState_onMouseUp(unsigned int buttons) -{ - m_buttonstate &= ~buttons; -} - -unsigned int getButtonState() const -{ - return m_buttonstate; -} - -void EntityCreate_MouseDown(int x, int y); - -void EntityCreate_MouseMove(int x, int y); - -void EntityCreate_MouseUp(int x, int y); - -void OnEntityCreate(const char *item); - -VIEWTYPE GetViewType() -{ - return m_viewType; -} - -void SetScale(float f); - -float Scale() -{ - return m_fScale; -} - -int Width() -{ - return m_nWidth; -} - -int Height() -{ - return m_nHeight; -} - -Signal0 onDestroyed; -Signal3 onMouseDown; - -void mouseDown(const WindowVector &position, ButtonIdentifier button, ModifierFlags modifiers); - -typedef Member MouseDownCaller; -}; - -inline void XYWnd_Update(XYWnd &xywnd) -{ - xywnd.queueDraw(); -} - - -struct xywindow_globals_t { - Vector3 color_gridback; - Vector3 color_gridminor; - Vector3 color_gridmajor; - Vector3 color_gridblock; - Vector3 color_gridtext; - Vector3 color_brushes; - Vector3 color_selbrushes; - Vector3 color_clipper; - Vector3 color_viewname; - Vector3 color_gridminor_alt; - Vector3 color_gridmajor_alt; - Vector3 AxisColorX; - Vector3 AxisColorY; - Vector3 AxisColorZ; - - bool m_bRightClick; - bool m_bNoStipple; - - xywindow_globals_t() : - color_gridback(0.0f, 0.0f, 0.0f), - color_gridmajor(0.45f, 0.45f, 0.45f), - color_gridminor(0.2f, 0.2f, 0.2f), - color_gridblock(0.39f, 0.18f, 0.0f), - color_gridtext(0.0f, 0.0f, 0.0f), - color_brushes(0.55f, 0.55f, 0.55f), - color_selbrushes(1.0f, 0.0f, 0.0f), - color_clipper(0.0f, 0.0f, 1.0f), - color_viewname(0.7f, 0.7f, 0.0f), - color_gridminor_alt(0.f, 0.f, 0.f), - color_gridmajor_alt(0.f, 0.f, 0.f), - - AxisColorX(1.f, 0.f, 0.f), - AxisColorY(0.f, 1.f, 0.f), - AxisColorZ(0.f, 0.f, 1.f), - m_bRightClick(true), - m_bNoStipple(false) - { - } - -}; - -extern xywindow_globals_t g_xywindow_globals; - - -VIEWTYPE GlobalXYWnd_getCurrentViewType(); - -void XY_Top_Shown_Construct(ui::Window parent); - -void YZ_Side_Shown_Construct(ui::Window parent); - -void XZ_Front_Shown_Construct(ui::Window parent); - -void XYWindow_Construct(); - -void XYWindow_Destroy(); - -void WXY_Print(); - -void WXY_BackgroundSelect(); - -void XYShow_registerCommands(); - -void XYWnd_registerShortcuts(); - -#endif diff --git a/tools/Makefile b/tools/Makefile deleted file mode 100644 index 70fa52b..0000000 --- a/tools/Makefile +++ /dev/null @@ -1,157 +0,0 @@ -# vmap Makefile - -# ws libs vmap uses -LIBOBJS=../libs/libddslib.a \ - ../libs/libetclib.a \ - ../libs/libfilematch.a \ - ../libs/libl_net.a \ - ../libs/libmathlib.a \ - ../libs/libpicomodel.a - -GLIB_CFLAGS=$(shell pkg-config --cflags glib-2.0) -GLIB_LDFLAGS=$(shell pkg-config --libs glib-2.0) - -XML_CFLAGS=$(shell pkg-config --cflags libxml-2.0) -XML_LDFLAGS=$(shell pkg-config --libs libxml-2.0) - -MINIZIP_CFLAGS=$(shell pkg-config --cflags minizip) -MINIZIP_LDFLAGS=$(shell pkg-config --libs minizip) - -JPEG_CFLAGS=$(shell pkg-config --cflags libjpeg) -JPEG_LDFLAGS=$(shell pkg-config --libs libjpeg) - -PNG_CFLAGS=$(shell pkg-config --cflags libpng) -PNG_LDFLAGS=$(shell pkg-config --libs libpng) - -VMAP_CFLAGS=$(CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS) $(MINIZIP_CFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) -I../include -I./common -I../libs -VMAP_LDFLAGS=$(LDFLAGS) -lm -lpthread -L../lib $(GLIB_LDFLAGS) $(XML_LDFLAGS) $(MINIZIP_LDFLAGS) $(JPEG_LDFLAGS) $(PNG_LDFLAGS) - -DO_CC=$(CC) $(VMAP_CFLAGS) -o $@ -c $< - -.c.o: - $(DO_CC) - -VMAP_OBJS = \ - common/cmdlib.o \ - common/imagelib.o \ - common/inout.o \ - common/jpeg.o \ - common/md4.o \ - common/mutex.o \ - common/polylib.o \ - common/scriplib.o \ - common/matlib.o \ - common/threads.o \ - common/vfs.o \ - vmap/brush.o \ - vmap/brush_primit.o \ - vmap/bsp.o \ - vmap/bsp_analyze.o \ - vmap/bsp_info.o \ - vmap/bsp_scale.o \ - vmap/bspfile_abstract.o \ - vmap/bspfile_ibsp.o \ - vmap/bspfile_rbsp.o \ - vmap/convert_ase.o \ - vmap/convert_bsp.o \ - vmap/convert_map.o \ - vmap/convert_obj.o \ - vmap/decals.o \ - vmap/exportents.o \ - vmap/facebsp.o \ - vmap/fixaas.o \ - vmap/fog.o \ - vmap/help.o \ - vmap/image.o \ - vmap/leakfile.o \ - vmap/light.o \ - vmap/light_bounce.o \ - vmap/light_trace.o \ - vmap/light_ydnar.o \ - vmap/lightmaps_ydnar.o \ - vmap/main.o \ - vmap/map.o \ - vmap/mesh.o \ - vmap/model.o \ - vmap/patch.o \ - vmap/path_init.o \ - vmap/portals.o \ - vmap/prtfile.o \ - vmap/shaders.o \ - vmap/surface.o \ - vmap/surface_extra.o \ - vmap/surface_foliage.o \ - vmap/surface_fur.o \ - vmap/surface_meta.o \ - vmap/tjunction.o \ - vmap/tree.o \ - vmap/vis.o \ - vmap/visflow.o \ - vmap/writebsp.o - -# binary target -../build/vmap: $(VMAP_OBJS) - $(CXX) -o $@ $(VMAP_OBJS) $(LIBOBJS) $(VMAP_LDFLAGS) - -clean: - -rm -f ./common/*.o - -rm -f ./vmap/*.o - -rm -f ../build/vmap - -# object files -common/cmdlib.o: common/cmdlib.c common/cmdlib.h -common/imagelib.o: common/imagelib.c common/imagelib.h -common/inout.o: common/inout.c common/inout.h -common/jpeg.o: common/jpeg.c -common/md4.o: common/md4.c common/md4.h -common/mutex.o: common/mutex.c common/mutex.h -common/polylib.o: common/polylib.c common/polylib.h -common/scriplib.o: common/scriplib.c common/scriplib.h -common/matlib.o: common/matlib.c common/matlib.h -common/threads.o: common/threads.c -common/vfs.o: common/vfs.c common/vfs.h -vmap/brush.o: vmap/brush.c -vmap/brush_primit.o: vmap/brush_primit.c -vmap/bsp.o: vmap/bsp.c -vmap/bsp_analyze.o: vmap/bsp_analyze.c -vmap/bsp_info.o: vmap/bsp_info.c -vmap/bsp_scale.o: vmap/bsp_scale.c -vmap/bspfile_abstract.o: vmap/bspfile_abstract.c -vmap/bspfile_ibsp.o: vmap/bspfile_ibsp.c -vmap/bspfile_rbsp.o: vmap/bspfile_rbsp.c -vmap/convert_ase.o: vmap/convert_ase.c -vmap/convert_bsp.o: vmap/convert_bsp.c -vmap/convert_map.o: vmap/convert_map.c -vmap/convert_obj.o: vmap/convert_obj.c -vmap/decals.o: vmap/decals.c -vmap/exportents.o: vmap/exportents.c -vmap/facebsp.o: vmap/facebsp.c -vmap/fixaas.o: vmap/fixaas.c -vmap/fog.o: vmap/fog.c -vmap/help.o: vmap/help.c -vmap/image.o: vmap/image.c -vmap/leakfile.o: vmap/leakfile.c -vmap/light.o: vmap/light.c -vmap/light_bounce.o: vmap/light_bounce.c -vmap/light_trace.o: vmap/light_trace.c -vmap/light_ydnar.o: vmap/light_ydnar.c -vmap/lightmaps_ydnar.o: vmap/lightmaps_ydnar.c -vmap/main.o: vmap/main.c -vmap/map.o: vmap/map.c -vmap/mesh.o: vmap/mesh.c -vmap/model.o: vmap/model.c -vmap/patch.o: vmap/patch.c -vmap/path_init.o: vmap/path_init.c -vmap/portals.o: vmap/portals.c -vmap/prtfile.o: vmap/prtfile.c -vmap/shaders.o: vmap/shaders.c -vmap/surface.o: vmap/surface.c -vmap/surface_extra.o: vmap/surface_extra.c -vmap/surface_foliage.o: vmap/surface_foliage.c -vmap/surface_fur.o: vmap/surface_fur.c -vmap/surface_meta.o: vmap/surface_meta.c -vmap/tjunction.o: vmap/tjunction.c -vmap/tree.o: vmap/tree.c -vmap/vis.o: vmap/vis.c -vmap/visflow.o: vmap/visflow.c -vmap/writebsp.o: vmap/writebsp.c diff --git a/worldspawn.desktop b/worldspawn.desktop deleted file mode 100755 index f272035..0000000 --- a/worldspawn.desktop +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -Name=WorldSpawn -Comment=idTech BSP Level Editor -Exec=worldspawn %f -Icon=worldspawn -Terminal=true -Type=Application -Categories=Development;

q c #281F22", -",q c #1B1417", -"'q c #405A50", -")q c #E1F1E8", -"!q c #E1CEEB", -"~q c #CFBCD9", -"{q c #E8E5E8", -"]q c #A9A474", -"^q c #614A4C", -"/q c #96757E", -"(q c #AC8F9D", -"_q c #C3A5AE", -":q c #AD97A9", -"r c #5F5F70", -",r c #4F4D72", -"'r c #353754", -")r c #2F3353", -"!r c #3B4064", -"~r c #91C5B6", -"{r c #D3C1DD", -"]r c #EDE9C9", -"^r c #2F303D", -"/r c #2C2F52", -"(r c #3B416B", -"_r c #434976", -":r c #B8E8D5", -"s c #C8A4D5", -",s c #AF94C6", -"'s c #B599C9", -")s c #C5A4C7", -"!s c #B095B5", -"~s c #9B7F9B", -"{s c #88708E", -"]s c #867085", -"^s c #7E6771", -"/s c #735A62", -"(s c #634D52", -"_s c #514044", -":s c #413236", -"t c #2B2C4D", -",t c #272744", -"'t c #292B4A", -")t c #333559", -"!t c #444771", -"~t c #474C79", -"{t c #444672", -"]t c #3F436C", -"^t c #424576", -"/t c #434879", -"(t c #646396", -"_t c #C4EEDD", -":t c #736F89", -"u c #E1DCAF", -",u c #0B0C16", -"'u c #201D2E", -")u c #544965", -"!u c #9379A1", -"~u c #C49ECE", -"{u c #C9EDE2", -"]u c #FBF5D0", -"^u c #CFA9DF", -"/u c #C19FD5", -"(u c #C4A0C9", -"_u c #C7A1D1", -":u c #DAAEDB", -"v c #E8E5B2", -",v c #4A4C6C", -"'v c #393B55", -")v c #2A2D46", -"!v c #24263E", -"~v c #97CFBB", -"{v c #F6F2F7", -"]v c #CCC891", -"^v c #12131D", -"/v c #24253C", -"(v c #363756", -"_v c #BAE9D6", -":v c #FEFCEA", -"w c #D6C6DE", -",w c #C8B0D5", -"'w c #D0B9DC", -")w c #F7F3E4", -"!w c #2D2D1B", -"~w c #AED9CA", -"{w c #F7F4F0", -"]w c #131510", -"^w c #0C0711", -"/w c #9BD0BA", -"(w c #D4C2DE", -"_w c #E7E2DE", -":w c #676448", -"x c #302E32", -",x c #584E58", -"'x c #716B72", -")x c #837D8B", -"!x c #A090B1", -"~x c #AAA0C1", -"{x c #A99FC0", -"]x c #9F94AE", -"^x c #A59ABC", -"/x c #A79BBF", -"(x c #B6E0D6", -"_x c #E0CEEA", -":x c #101218", -"y c #706E46", -",y c #3C3C3B", -"'y c #6A6967", -")y c #62615E", -"!y c #6A6A65", -"~y c #85837C", -"{y c #908C86", -"]y c #878684", -"^y c #83837D", -"/y c #CBB0D8", -"(y c #DAC1E7", -"_y c #F0EBC7", -":y c #222221", -"z c #DDC3E8", -",z c #D6B9E3", -"'z c #E6E0E2", -")z c #6E6C4D", -"!z c #262427", -"~z c #444141", -"{z c #8E849F", -"]z c #968B9F", -"^z c #AA98BB", -"/z c #A797BA", -"(z c #B2A2CA", -"_z c #A69CBD", -":z c #9BA5B3", -"A c #CBC88F", -",A c #191A19", -"'A c #3D3D3C", -")A c #636060", -"!A c #6B6866", -"~A c #868682", -"{A c #94928E", -"]A c #787872", -"^A c #80807C", -"/A c #4D534D", -"(A c #E1ECE6", -"_A c #C09BD1", -":A c #C19BD4", -"B c #F9FDF8", -",B c #E5DEB5", -"'B c #85768B", -")B c #74677B", -"!B c #63566A", -"~B c #605466", -"{B c #64586C", -"]B c #675D71", -"^B c #6D6277", -"/B c #6D6378", -"(B c #675D73", -"_B c #98C4B8", -":B c #F2ECF5", -"C c #555352", -",C c #393935", -"'C c #282725", -")C c #373633", -"!C c #97CFB8", -"~C c #B486CB", -"{C c #B086C1", -"]C c #F3F0F4", -"^C c #B6B37A", -"/C c #575552", -"(C c #827F7B", -"_C c #7D7A74", -":C c #8F8C87", -"D c #241E1D", -",D c #4B3F41", -"'D c #63595D", -")D c #6F6469", -"!D c #7B6F76", -"~D c #9A817F", -"{D c #957979", -"]D c #917C7F", -"^D c #977B81", -"/D c #8F7C7E", -"(D c #927D83", -"_D c #918083", -":D c #958184", -"E c #505050", -",E c #232644", -"'E c #1F2542", -")E c #2C3358", -"!E c #37406C", -"~E c #404977", -"{E c #545986", -"]E c #8580AE", -"^E c #6D6D93", -"/E c #908AC0", -"(E c #616961", -"_E c #E8EFED", -":E c #B583CD", -"F c #F6BBBC", -",F c #FBC2C2", -"'F c #FDC3C1", -")F c #F9C5BE", -"!F c #F2BBBE", -"~F c #E9B5BB", -"{F c #CDE6DC", -"]F c #BF94D4", -"^F c #F0E8F4", -"/F c #CBC48E", -"(F c #2D2224", -"_F c #2A1F1F", -":F c #514041", -"G c #5B5C86", -",G c #616194", -"'G c #51557D", -")G c #4A4D79", -"!G c #464673", -"~G c #60608F", -"{G c #545762", -"]G c #272943", -"^G c #303149", -"/G c #3B3C5C", -"(G c #42456A", -"_G c #3F426D", -":G c #414570", -"H c #1D1621", -",H c #2D232D", -"'H c #564857", -")H c #8C7787", -"!H c #BA99B8", -"~H c #C6A7C1", -"{H c #CFE8E0", -"]H c #BE9BD0", -"^H c #E3DAB5", -"/H c #6D5D64", -"(H c #7D6A77", -"_H c #A18597", -":H c #B699AC", -"I c #B080C8", -",I c #BE8DD3", -"'I c #F3EDD7", -")I c #27262A", -"!I c #262740", -"~I c #2D2D43", -"{I c #3D3C5B", -"]I c #424261", -"^I c #57577C", -"/I c #7870AF", -"(I c #7A7AB1", -"_I c #7E77AF", -":I c #737199", -"J c #B080C9", -",J c #F3EEF1", -"'J c #525132", -")J c #2E3229", -"!J c #31352C", -"~J c #2C3028", -"{J c #20211E", -"]J c #110E14", -"^J c #7DB09C", -"/J c #FBFAFA", -"(J c #A8A56E", -"_J c #09040D", -":J c #0A040F", -"K c #505261", -",K c #464C55", -"'K c #5B5E6D", -")K c #DCEBE5", -"!K c #AE7FC7", -"~K c #E8E1E1", -"{K c #5D5B43", -"]K c #353136", -"^K c #665D6B", -"/K c #7F7788", -"(K c #A89ABB", -"_K c #D4C8EA", -":K c #C5B9DD", -"L c #EEF0F1", -",L c #AF7DC8", -"'L c #F4EEE4", -")L c #35341E", -"!L c #757473", -"~L c #928F8C", -"{L c #918B88", -"]L c #A19F9B", -"^L c #AFACA6", -"/L c #8C8987", -"(L c #908C87", -"_L c #928E8A", -":L c #8F8B8A", -"M c #C7A6C8", -",M c #C4A6CD", -"'M c #B17FCA", -")M c #B27ACD", -"!M c #B589CB", -"~M c #E7DAED", -"{M c #F4EFCE", -"]M c #8D8073", -"^M c #8C768E", -"/M c #AE92AE", -"(M c #C4A5B4", -"_M c #DDAEAE", -":M c #EEB6B6", -"N c #C2A49E", -",N c #BDA19A", -"'N c #C0E3D6", -")N c #B17FCB", -"!N c #F2ECEE", -"~N c #64613E", -"{N c #06060E", -"]N c #10101D", -"^N c #2A293E", -"/N c #363852", -"(N c #494B6B", -"_N c #6A698F", -":N c #8280A7", -"O c #A97BC2", -",O c #A16EBD", -"'O c #B188C7", -")O c #DDD4C9", -"!O c #BEB3A8", -"~O c #A780B5", -"{O c #827864", -"]O c #395950", -"^O c #E4E8EA", -"/O c #BB8CD2", -"(O c #AD7DC6", -"_O c #E4DDE8", -":O c #C3BF88", -"P c #7F7686", -",P c #7D7484", -"'P c #7C7384", -")P c #787485", -"!P c #706E7E", -"~P c #6D6C7F", -"{P c #716E80", -"]P c #716D7D", -"^P c #77717F", -"/P c #85A09E", -"(P c #C8C8BF", -"_P c #C0A3D0", -":P c #AC80C4", -"