X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=radiant%2Fpoints.cpp;h=c4a56492ee86ed73f0c2093d7f73ecfb08e91442;hb=32dc1da26645b97a5823ff22175000542225c6dd;hp=9a84f6c524ab1c2ca813766e262687b71fbb1314;hpb=830125fad042fad35dc029b6eb57c8156ad7e176;p=xonotic%2Fnetradiant.git diff --git a/radiant/points.cpp b/radiant/points.cpp index 9a84f6c5..c4a56492 100644 --- a/radiant/points.cpp +++ b/radiant/points.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 1999-2007 id Software, Inc. and contributors. + 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. @@ -19,135 +19,270 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "stdafx.h" +/* + 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 ); +} -#define MAX_POINTFILE 8192 -static vec3_t s_pointvecs[MAX_POINTFILE]; -static int s_num_points, s_check_point; +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 ); +} -CPointfile g_pointfile; +static void constructStatic(){ + m_renderstate = GlobalShaderCache().capture( "$POINTFILE" ); +} -// CPointfile routine used by the standard code --------------------------------- +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( vec3_t v ){ +void CPointfile::PushPoint( const Vector3& v ){ if ( s_num_points < MAX_POINTFILE ) { - VectorCopy( v, s_pointvecs[s_num_points] ); - s_num_points++; + s_pointvecs[s_num_points] = v; + ++s_num_points; } } // create the display list at the end void CPointfile::GenerateDisplayList(){ - int i; - - if ( !g_qeglobals.d_pointfile_display_list ) { - g_qeglobals.d_pointfile_display_list = qglGenLists( 1 ); - } + m_displaylist = glGenLists( 1 ); - qglNewList( g_qeglobals.d_pointfile_display_list, GL_COMPILE ); - - qglColor3f( 1, 0, 0 ); - qglDisable( GL_TEXTURE_2D ); - qglDisable( GL_TEXTURE_1D ); - qglLineWidth( 4 ); - qglBegin( GL_LINE_STRIP ); - for ( i = 0; i < s_num_points; i++ ) - { - if ( s_num_points < MAX_POINTFILE ) { - qglVertex3fv( s_pointvecs[i] ); - } - } - qglEnd(); - qglLineWidth( 1 ); + glNewList( m_displaylist, GL_COMPILE ); - qglEndList(); + 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 ); - s_check_point = 0; + glEndList(); } // old (but still relevant) pointfile code ------------------------------------- void Pointfile_Delete( void ){ - char name[1024]; - - strcpy( name, currentmap ); - StripExtension( name ); - strcat( name, ".lin" ); - - remove( name ); + 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 ){ - vec3_t dir; + if ( !s_pointfile.shown() ) { + return; + } - if ( s_check_point >= s_num_points - 2 ) { - Sys_Status( "End of pointfile", 0 ); + if ( s_check_point + 2 == s_pointfile.end() ) { + globalOutputStream() << "End of pointfile\n"; return; } - s_check_point++; - VectorCopy( s_pointvecs[s_check_point], g_pParentWnd->GetCamWnd()->Camera()->origin ); - VectorCopy( s_pointvecs[s_check_point], g_pParentWnd->GetXYWnd()->GetOrigin() ); - VectorSubtract( s_pointvecs[s_check_point + 1], g_pParentWnd->GetCamWnd()->Camera()->origin, dir ); - VectorNormalize( dir, dir ); - g_pParentWnd->GetCamWnd()->Camera()->angles[1] = atan2( dir[1], dir[0] ) * 180 / 3.14159; - g_pParentWnd->GetCamWnd()->Camera()->angles[0] = asin( dir[2] ) * 180 / 3.14159; - Sys_UpdateWindows( W_ALL ); + 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 ){ - vec3_t dir; + if ( !s_pointfile.shown() ) { + return; + } - if ( s_check_point == 0 ) { - Sys_Status( "Start of pointfile", 0 ); + if ( s_check_point == s_pointfile.begin() ) { + globalOutputStream() << "Start of pointfile\n"; return; } - s_check_point--; - VectorCopy( s_pointvecs[s_check_point], g_pParentWnd->GetCamWnd()->Camera()->origin ); - VectorCopy( s_pointvecs[s_check_point], g_pParentWnd->GetXYWnd()->GetOrigin() ); - VectorSubtract( s_pointvecs[s_check_point + 1], g_pParentWnd->GetCamWnd()->Camera()->origin, dir ); - VectorNormalize( dir, dir ); - g_pParentWnd->GetCamWnd()->Camera()->angles[1] = atan2( dir[1], dir[0] ) * 180 / 3.14159; - g_pParentWnd->GetCamWnd()->Camera()->angles[0] = asin( dir[2] ) * 180 / 3.14159; - Sys_UpdateWindows( W_ALL ); + 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 WINAPI Pointfile_Check( void ){ - char name[1024]; +void Pointfile_Parse( CPointfile& pointfile ){ int size; char *data; char *text; int line = 1; - vec3_t v; - strcpy( name, currentmap ); - StripExtension( name ); - strcat( name, ".lin" ); + const char* mapname = Map_Name( g_map ); + StringOutputStream name( 256 ); + name << StringRange( mapname, path_get_filename_base_end( mapname ) ) << ".lin"; - size = vfsLoadFullPathFile( name, (void**)&data ); - if ( size <= 0 ) { - Sys_FPrintf( SYS_ERR, "Pointfile %s not found\n", name ); + size = LoadFile( name.c_str(), (void**)&data ); + if ( size == -1 ) { + globalErrorStream() << "Pointfile " << name.c_str() << " not found\n"; return; } // store a pointer text = data; - Sys_Printf( "Reading pointfile %s\n", name ); + globalOutputStream() << "Reading pointfile " << name.c_str() << "\n"; - g_pointfile.Init(); + pointfile.Init(); while ( *data ) { + Vector3 v; if ( sscanf( data,"%f %f %f", &v[0], &v[1], &v[2] ) != 3 ) { - Sys_Printf( "Corrupt point file, line %d\n",line ); + globalOutputStream() << "Corrupt point file, line " << line << "\n"; break; } @@ -161,7 +296,7 @@ void WINAPI Pointfile_Check( void ){ // deal with zhlt style point files. if ( *data == '-' ) { if ( sscanf( data,"- %f %f %f", &v[0], &v[1], &v[2] ) != 3 ) { - Sys_Printf( "Corrupt point file, line %d\n",line ); + globalOutputStream() << "Corrupt point file, line " << line << "\n"; break; } @@ -174,57 +309,71 @@ void WINAPI Pointfile_Check( void ){ data++; // skip the \n line++; } - g_pointfile.PushPoint( v ); + pointfile.PushPoint( v ); } g_free( text ); +} + +void Pointfile_Clear(){ + s_pointfile.show( false ); +} - g_pointfile.GenerateDisplayList(); +void Pointfile_Toggle(){ + s_pointfile.show( !s_pointfile.shown() ); - Sys_UpdateWindows( W_ALL ); + s_check_point = s_pointfile.begin(); } -void Pointfile_Draw( void ){ - qglCallList( g_qeglobals.d_pointfile_display_list ); +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_Clear( void ){ - if ( !g_qeglobals.d_pointfile_display_list ) { - return; - } +void Pointfile_Destroy(){ + GlobalShaderCache().detachRenderable( s_pointfile ); - qglDeleteLists( g_qeglobals.d_pointfile_display_list, 1 ); - g_qeglobals.d_pointfile_display_list = 0; - Sys_UpdateWindows( W_ALL ); + CPointfile::destroyStatic(); } -// CPointfile implementation for SAX speicific stuff ------------------------------- + + +// CPointfile implementation for SAX-specific stuff ------------------------------- void CPointfile::saxStartElement( message_info_t *ctx, const xmlChar *name, const xmlChar **attrs ){ - if ( strcmp( (char *)name, "polyline" ) == 0 ) { + if ( string_equal( reinterpret_cast( name ), "polyline" ) ) { Init(); // there's a prefs setting to avoid stopping on leak - if ( !g_PrefsDlg.m_bLeakStop ) { + if ( !g_WatchBSP_LeakStop ) { ctx->stop_depth = 0; } } } void CPointfile::saxEndElement( message_info_t *ctx, const xmlChar *name ){ - if ( strcmp( (char *)name, "polyline" ) == 0 ) { + if ( string_equal( reinterpret_cast( name ), "polyline" ) ) { // we are done GenerateDisplayList(); - ctx->bGeometry = false; + 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 ){ - vec3_t v; - - sscanf( (char *)ch, "%f %f %f\n", &v[0], &v[1], &v[2] ); - PushPoint( v ); + m_characters.write( reinterpret_cast( ch ), len ); } -char * CPointfile::getName(){ - return "Map is leaked"; +const char* CPointfile::getName(){ + return "Map leaked"; }