* "BrushAlwaysCaulk" option is saveable for brush types other than q3
* brush format is preference for [maptypes, brushtypes]: [mapq1, quake], [mapq2, quake2], [mapq3, quake3]: preferences->Brush->Brush type: Axial projection, Brush primitives, Valve 220 * autodetect brush type on map opening * brush face surfaceflags are optional on loading for flexibility * 'Snap planes to integer grid' option is always off by default
This commit is contained in:
parent
4e4b8e1407
commit
0b3f42ffbc
|
|
@ -27,6 +27,20 @@
|
|||
#include "generic/vector.h"
|
||||
#include "itexdef.h"
|
||||
|
||||
enum EBrushType
|
||||
{
|
||||
eBrushTypeUNKNOWN = 0,
|
||||
eBrushTypeQuake,
|
||||
eBrushTypeQuake2,
|
||||
eBrushTypeQuake3,
|
||||
eBrushTypeQuake3BP,
|
||||
eBrushTypeQuake3Valve220,
|
||||
eBrushTypeDoom3,
|
||||
eBrushTypeQuake4,
|
||||
eBrushTypeValve220,
|
||||
};
|
||||
|
||||
|
||||
namespace scene
|
||||
{
|
||||
class Node;
|
||||
|
|
@ -103,7 +117,7 @@ public:
|
|||
INTEGER_CONSTANT( Version, 1 );
|
||||
STRING_CONSTANT( Name, "brush" );
|
||||
virtual scene::Node& createBrush() = 0;
|
||||
virtual bool useAlternativeTextureProjection() const = 0;
|
||||
virtual EBrushType getCurrentFormat() const = 0;
|
||||
virtual void Brush_forEachFace( scene::Node& brush, const BrushFaceDataCallback& callback ) = 0;
|
||||
virtual bool Brush_addFace( scene::Node& brush, const _QERFaceData& faceData ) = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ virtual void exportTokens( TokenWriter& writer ) const = 0;
|
|||
};
|
||||
|
||||
#include "iscenegraph.h"
|
||||
#include "ibrush.h"
|
||||
|
||||
class EntityCreator;
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ class MapFormat
|
|||
public:
|
||||
INTEGER_CONSTANT( Version, 2 );
|
||||
STRING_CONSTANT( Name, "map" );
|
||||
mutable bool wrongFormat;
|
||||
mutable EBrushType m_detectedFormat;
|
||||
|
||||
/// \brief Read a map graph into \p root from \p outputStream, using \p entityTable to create entities.
|
||||
virtual void readGraph( scene::Node& root, TextInputStream& inputStream, EntityCreator& entityTable ) const = 0;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ virtual const char* getToken() = 0;
|
|||
virtual void ungetToken() = 0;
|
||||
virtual std::size_t getLine() const = 0;
|
||||
virtual std::size_t getColumn() const = 0;
|
||||
virtual bool bufferContains( const char* str ) = 0;
|
||||
};
|
||||
|
||||
class TextInputStream;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ typedef bool ( ScriptTokeniser::*Tokenise )( char c );
|
|||
|
||||
Tokenise m_stack[3];
|
||||
Tokenise* m_state;
|
||||
SingleCharacterInputStream<TextInputStream> m_istream;
|
||||
SingleCharacterInputStreamDoubleBuffered<TextInputStream> m_istream;
|
||||
std::size_t m_scriptline;
|
||||
std::size_t m_scriptcolumn;
|
||||
|
||||
|
|
@ -329,6 +329,9 @@ std::size_t getLine() const {
|
|||
std::size_t getColumn() const {
|
||||
return m_scriptcolumn;
|
||||
}
|
||||
bool bufferContains( const char* str ){
|
||||
return m_istream.bufferContains( str );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -355,6 +355,47 @@ bool readChar( char& c ){
|
|||
}
|
||||
};
|
||||
|
||||
/// doublefuffered to be able to read forward for map format (valve220) detection
|
||||
template<typename TextInputStreamType, int SIZE = 1024>
|
||||
class SingleCharacterInputStreamDoubleBuffered
|
||||
{
|
||||
TextInputStreamType& m_inputStream;
|
||||
char m_bu[SIZE];
|
||||
char* m_buffer;
|
||||
char* m_cur;
|
||||
char* m_end;
|
||||
|
||||
char m_bu2[SIZE];
|
||||
char* m_buffer2;
|
||||
char* m_end2;
|
||||
|
||||
bool fillBuffer(){
|
||||
std::swap( m_buffer, m_buffer2 );
|
||||
m_cur = m_buffer;
|
||||
m_end = m_end2;
|
||||
m_end2 = m_buffer2 + m_inputStream.read( m_buffer2, SIZE );
|
||||
return m_cur != m_end;
|
||||
}
|
||||
public:
|
||||
|
||||
SingleCharacterInputStreamDoubleBuffered( TextInputStreamType& inputStream ) : m_inputStream( inputStream ), m_buffer( m_bu ), m_cur( m_buffer ), m_end( m_buffer ), m_buffer2( m_bu2 ){
|
||||
m_end2 = m_buffer2 + m_inputStream.read( m_buffer2, SIZE );
|
||||
}
|
||||
bool readChar( char& c ){
|
||||
if ( m_cur == m_end && !fillBuffer() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
c = *m_cur++;
|
||||
return true;
|
||||
}
|
||||
bool bufferContains( const char* str ) const{
|
||||
return ( std::search( m_cur, m_end, str, str + strlen( str ) ) != m_end ) ||
|
||||
( std::search( m_buffer2, m_end2, str, str + strlen( str ) ) != m_end2 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief A wrapper for a TextOutputStream, optimised for writing a single character at a time.
|
||||
class SingleCharacterOutputStream : public TextOutputStream
|
||||
{
|
||||
|
|
|
|||
|
|
@ -228,7 +228,6 @@ MapDependencies() :
|
|||
|
||||
class MapQ3API : public TypeSystemRef, public MapFormat, public PrimitiveParser
|
||||
{
|
||||
mutable bool detectedFormat;
|
||||
public:
|
||||
typedef MapFormat Type;
|
||||
STRING_CONSTANT( Name, "mapq3" );
|
||||
|
|
@ -248,31 +247,38 @@ scene::Node& parsePrimitive( Tokeniser& tokeniser ) const {
|
|||
if ( string_equal( primitive, "patchDef2" ) ) {
|
||||
return GlobalPatchModule::getTable().createPatch();
|
||||
}
|
||||
if ( GlobalBrushModule::getTable().useAlternativeTextureProjection() ) {
|
||||
if( !m_detectedFormat ){
|
||||
if ( string_equal( primitive, "brushDef" ) ) {
|
||||
detectedFormat = true;
|
||||
return GlobalBrushModule::getTable().createBrush();
|
||||
m_detectedFormat = eBrushTypeQuake3BP;
|
||||
globalErrorStream() << "m_detectedFormat = eBrushTypeQuake3BP\n";
|
||||
}
|
||||
else if ( !detectedFormat && string_equal( primitive, "(" ) ) {
|
||||
detectedFormat = true;
|
||||
wrongFormat = true;
|
||||
Tokeniser_unexpectedError( tokeniser, primitive, "#quake3-switch-to-texdef" );
|
||||
else if ( string_equal( primitive, "(" ) && tokeniser.bufferContains( " [ " ) && tokeniser.bufferContains( " ] " ) ) {
|
||||
m_detectedFormat = eBrushTypeQuake3Valve220;
|
||||
globalErrorStream() << "m_detectedFormat = eBrushTypeQuake3Valve220\n";
|
||||
}
|
||||
else if ( string_equal( primitive, "(" ) ) {
|
||||
m_detectedFormat = eBrushTypeQuake3;
|
||||
globalErrorStream() << "m_detectedFormat = eBrushTypeQuake3\n";
|
||||
}
|
||||
else{
|
||||
globalErrorStream() << "Format is not detected\n";
|
||||
}
|
||||
|
||||
if( m_detectedFormat != GlobalBrushModule::getTable().getCurrentFormat() ){
|
||||
Tokeniser_unexpectedError( tokeniser, primitive, "#different-brush-format" );
|
||||
return g_nullNode;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
switch ( GlobalBrushModule::getTable().getCurrentFormat() )
|
||||
{
|
||||
if ( string_equal( primitive, "(" ) ) {
|
||||
detectedFormat = true;
|
||||
tokeniser.ungetToken(); // (
|
||||
return GlobalBrushModule::getTable().createBrush();
|
||||
}
|
||||
else if ( !detectedFormat && string_equal( primitive, "brushDef" ) ) {
|
||||
detectedFormat = true;
|
||||
wrongFormat = true;
|
||||
Tokeniser_unexpectedError( tokeniser, primitive, "#quake3-switch-to-brush-primitives" );
|
||||
return g_nullNode;
|
||||
}
|
||||
case eBrushTypeQuake3:
|
||||
case eBrushTypeQuake3Valve220:
|
||||
tokeniser.ungetToken(); // (
|
||||
case eBrushTypeQuake3BP:
|
||||
return GlobalBrushModule::getTable().createBrush();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -281,8 +287,6 @@ scene::Node& parsePrimitive( Tokeniser& tokeniser ) const {
|
|||
}
|
||||
|
||||
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();
|
||||
|
|
@ -316,9 +320,38 @@ MapFormat* getTable(){
|
|||
scene::Node& parsePrimitive( Tokeniser& tokeniser ) const {
|
||||
const char* primitive = tokeniser.getToken();
|
||||
if ( primitive != 0 ) {
|
||||
if ( string_equal( primitive, "(" ) ) {
|
||||
if( !m_detectedFormat ){
|
||||
if ( string_equal( primitive, "brushDef" ) ) {
|
||||
m_detectedFormat = eBrushTypeQuake3BP;
|
||||
globalErrorStream() << "m_detectedFormat = eBrushTypeQuake3BP\n";
|
||||
}
|
||||
else if ( string_equal( primitive, "(" ) && tokeniser.bufferContains( " [ " ) && tokeniser.bufferContains( " ] " ) ) {
|
||||
m_detectedFormat = eBrushTypeValve220;
|
||||
globalErrorStream() << "m_detectedFormat = eBrushTypeValve220\n";
|
||||
}
|
||||
else if ( string_equal( primitive, "(" ) ) {
|
||||
m_detectedFormat = eBrushTypeQuake;
|
||||
globalErrorStream() << "m_detectedFormat = eBrushTypeQuake\n";
|
||||
}
|
||||
else{
|
||||
globalErrorStream() << "Format is not detected\n";
|
||||
}
|
||||
|
||||
if( m_detectedFormat != GlobalBrushModule::getTable().getCurrentFormat() ){
|
||||
Tokeniser_unexpectedError( tokeniser, primitive, "#different-brush-format" );
|
||||
return g_nullNode;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( GlobalBrushModule::getTable().getCurrentFormat() )
|
||||
{
|
||||
case eBrushTypeQuake:
|
||||
case eBrushTypeValve220:
|
||||
tokeniser.ungetToken(); // (
|
||||
case eBrushTypeQuake3BP:
|
||||
return GlobalBrushModule::getTable().createBrush();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -401,9 +434,38 @@ MapFormat* getTable(){
|
|||
scene::Node& parsePrimitive( Tokeniser& tokeniser ) const {
|
||||
const char* primitive = tokeniser.getToken();
|
||||
if ( primitive != 0 ) {
|
||||
if ( string_equal( primitive, "(" ) ) {
|
||||
if( !m_detectedFormat ){
|
||||
if ( string_equal( primitive, "brushDef" ) ) {
|
||||
m_detectedFormat = eBrushTypeQuake3BP;
|
||||
globalErrorStream() << "m_detectedFormat = eBrushTypeQuake3BP\n";
|
||||
}
|
||||
else if ( string_equal( primitive, "(" ) && tokeniser.bufferContains( " [ " ) && tokeniser.bufferContains( " ] " ) ) {
|
||||
m_detectedFormat = eBrushTypeQuake3Valve220;
|
||||
globalErrorStream() << "m_detectedFormat = eBrushTypeQuake3Valve220\n";
|
||||
}
|
||||
else if ( string_equal( primitive, "(" ) ) {
|
||||
m_detectedFormat = eBrushTypeQuake2;
|
||||
globalErrorStream() << "m_detectedFormat = eBrushTypeQuake2\n";
|
||||
}
|
||||
else{
|
||||
globalErrorStream() << "Format is not detected\n";
|
||||
}
|
||||
|
||||
if( m_detectedFormat != GlobalBrushModule::getTable().getCurrentFormat() ){
|
||||
Tokeniser_unexpectedError( tokeniser, primitive, "#different-brush-format" );
|
||||
return g_nullNode;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( GlobalBrushModule::getTable().getCurrentFormat() )
|
||||
{
|
||||
case eBrushTypeQuake2:
|
||||
case eBrushTypeQuake3Valve220:
|
||||
tokeniser.ungetToken(); // (
|
||||
case eBrushTypeQuake3BP:
|
||||
return GlobalBrushModule::getTable().createBrush();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,17 +68,6 @@
|
|||
const unsigned int BRUSH_DETAIL_FLAG = 27;
|
||||
const unsigned int BRUSH_DETAIL_MASK = ( 1 << BRUSH_DETAIL_FLAG );
|
||||
|
||||
enum EBrushType
|
||||
{
|
||||
eBrushTypeQuake,
|
||||
eBrushTypeQuake2,
|
||||
eBrushTypeQuake3,
|
||||
eBrushTypeQuake3BP,
|
||||
eBrushTypeDoom3,
|
||||
eBrushTypeQuake4,
|
||||
eBrushTypeHalfLife,
|
||||
};
|
||||
|
||||
|
||||
#define BRUSH_CONNECTIVITY_DEBUG 0
|
||||
#define BRUSH_DEGENERATE_DEBUG 0
|
||||
|
|
@ -1934,15 +1923,11 @@ static void constructStatic( EBrushType 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 ) {
|
||||
else if ( m_type == eBrushTypeValve220 || m_type == eBrushTypeQuake3Valve220 ) {
|
||||
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(){
|
||||
|
|
|
|||
|
|
@ -128,9 +128,6 @@ enum TexdefTypeId
|
|||
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,36 @@
|
|||
#include "preferences.h"
|
||||
|
||||
LatchedBool g_useAlternativeTextureProjection( false, "Use alternative texture-projection (\"brush primitives\")" );
|
||||
bool g_showAlternativeTextureProjectionOption = false;
|
||||
bool g_multipleBrushTypes = false;
|
||||
EBrushType g_brushTypes[3];
|
||||
int g_brushType;
|
||||
bool g_brush_always_caulk;
|
||||
|
||||
bool getTextureLockEnabled(){
|
||||
return g_brush_texturelock_enabled;
|
||||
}
|
||||
|
||||
const char* BrushType_getName( EBrushType type ){
|
||||
switch ( type )
|
||||
{
|
||||
case eBrushTypeQuake:
|
||||
case eBrushTypeQuake2:
|
||||
case eBrushTypeQuake3:
|
||||
return "Axial Projection";
|
||||
case eBrushTypeQuake3BP:
|
||||
return "Brush Primitives";
|
||||
case eBrushTypeQuake3Valve220:
|
||||
case eBrushTypeValve220:
|
||||
return "Valve 220";
|
||||
case eBrushTypeDoom3:
|
||||
return "Doom3";
|
||||
case eBrushTypeQuake4:
|
||||
return "Quake4";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void Face_importSnapPlanes( bool value ){
|
||||
Face::m_quantise = value ? quantiseInteger : quantiseFloating;
|
||||
}
|
||||
|
|
@ -62,11 +85,12 @@ void Brush_constructPreferences( PreferencesPage& page ){
|
|||
"Default texture scale",
|
||||
g_texdef_default_scale
|
||||
);
|
||||
if ( g_showAlternativeTextureProjectionOption ) {
|
||||
page.appendCheckBox(
|
||||
"", "Use alternative texture-projection (\"brush primitives\")",
|
||||
LatchedBoolImportCaller( g_useAlternativeTextureProjection ),
|
||||
BoolExportCaller( g_useAlternativeTextureProjection.m_latched )
|
||||
if ( g_multipleBrushTypes ) {
|
||||
const char* names[] = { BrushType_getName( g_brushTypes[0] ), BrushType_getName( g_brushTypes[1] ), BrushType_getName( g_brushTypes[2] ) };
|
||||
page.appendCombo(
|
||||
"Brush Type",
|
||||
g_brushType,
|
||||
STRING_ARRAY_RANGE( names )
|
||||
);
|
||||
}
|
||||
// d1223m
|
||||
|
|
@ -83,51 +107,38 @@ void Brush_registerPreferencesPage(){
|
|||
PreferencesDialog_addSettingsPage( FreeCaller1<PreferenceGroup&, Brush_constructPage>() );
|
||||
}
|
||||
|
||||
void Brush_unlatchPreferences(){
|
||||
Brush_toggleFormat( 0 );
|
||||
}
|
||||
|
||||
void Brush_toggleFormat( int i ){
|
||||
if ( g_showAlternativeTextureProjectionOption ) {
|
||||
g_useAlternativeTextureProjection.m_value = g_useAlternativeTextureProjection.m_latched ^ i;
|
||||
void Brush_toggleFormat( EBrushType type ){
|
||||
if( g_multipleBrushTypes ){
|
||||
Brush::destroyStatic();
|
||||
Brush::constructStatic( g_useAlternativeTextureProjection.m_value ? eBrushTypeQuake3BP : eBrushTypeQuake3 );
|
||||
Brush::constructStatic( type );
|
||||
}
|
||||
}
|
||||
|
||||
int Brush_toggleFormatCount(){
|
||||
if ( g_showAlternativeTextureProjectionOption ) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
void Brush_unlatchPreferences(){
|
||||
if( g_multipleBrushTypes )
|
||||
Brush_toggleFormat( g_brushTypes[g_brushType] );
|
||||
}
|
||||
|
||||
void Brush_Construct( EBrushType type ){
|
||||
if ( type == eBrushTypeQuake3 ) {
|
||||
g_showAlternativeTextureProjectionOption = true;
|
||||
|
||||
const char *value = g_pGameDescription->getKeyValue( "brush_primit" );
|
||||
if ( !string_empty( value ) ) {
|
||||
g_useAlternativeTextureProjection.m_latched = atoi( value );
|
||||
if ( g_multipleBrushTypes ) {
|
||||
for ( int i = 0; i < 3; ++i ){
|
||||
if( g_brushTypes[i] == type ){
|
||||
g_brushType = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalPreferenceSystem().registerPreference(
|
||||
"AlternativeTextureProjection",
|
||||
BoolImportStringCaller( g_useAlternativeTextureProjection.m_latched ),
|
||||
BoolExportStringCaller( g_useAlternativeTextureProjection.m_latched )
|
||||
"BrushType",
|
||||
IntImportStringCaller( g_brushType ),
|
||||
IntExportStringCaller( g_brushType )
|
||||
);
|
||||
g_useAlternativeTextureProjection.useLatched();
|
||||
|
||||
if ( g_useAlternativeTextureProjection.m_value ) {
|
||||
type = eBrushTypeQuake3BP;
|
||||
}
|
||||
|
||||
// d1223m
|
||||
GlobalPreferenceSystem().registerPreference(
|
||||
"BrushAlwaysCaulk",
|
||||
BoolImportStringCaller( g_brush_always_caulk ),
|
||||
BoolExportStringCaller( g_brush_always_caulk ) );
|
||||
type = g_brushTypes[g_brushType];
|
||||
}
|
||||
// d1223m
|
||||
GlobalPreferenceSystem().registerPreference(
|
||||
"BrushAlwaysCaulk",
|
||||
BoolImportStringCaller( g_brush_always_caulk ),
|
||||
BoolExportStringCaller( g_brush_always_caulk ) );
|
||||
|
||||
Brush_registerCommands();
|
||||
Brush_registerPreferencesPage();
|
||||
|
|
@ -137,6 +148,7 @@ void Brush_Construct( EBrushType type ){
|
|||
BrushClipPlane::constructStatic();
|
||||
BrushInstance::constructStatic();
|
||||
Brush::constructStatic( type );
|
||||
Face::m_quantise = quantiseFloating;
|
||||
|
||||
Brush::m_maxWorldCoord = g_MaxWorldCoord;
|
||||
BrushInstance::m_counter = &g_brushCount;
|
||||
|
|
@ -197,8 +209,8 @@ public:
|
|||
scene::Node& createBrush(){
|
||||
return ( new BrushNode )->node();
|
||||
}
|
||||
bool useAlternativeTextureProjection() const {
|
||||
return g_useAlternativeTextureProjection.m_value;
|
||||
EBrushType getCurrentFormat() const {
|
||||
return Brush::m_type;
|
||||
}
|
||||
void Brush_forEachFace( scene::Node& brush, const BrushFaceDataCallback& callback ){
|
||||
::Brush_forEachFace( *Node_getBrush( brush ), FaceCallback( BrushFaceDataFromFaceCaller( callback ) ) );
|
||||
|
|
@ -288,7 +300,12 @@ typedef BrushCreator Type;
|
|||
STRING_CONSTANT( Name, "quake3" );
|
||||
|
||||
BrushQuake3API(){
|
||||
Brush_Construct( eBrushTypeQuake3 );
|
||||
g_multipleBrushTypes = true;
|
||||
g_brushTypes[0] = eBrushTypeQuake3;
|
||||
g_brushTypes[1] = eBrushTypeQuake3BP;
|
||||
g_brushTypes[2] = eBrushTypeQuake3Valve220;
|
||||
|
||||
Brush_Construct( eBrushTypeQuake3BP );
|
||||
|
||||
m_brushquake3 = &GetBrushCreator();
|
||||
}
|
||||
|
|
@ -313,6 +330,11 @@ typedef BrushCreator Type;
|
|||
STRING_CONSTANT( Name, "quake2" );
|
||||
|
||||
BrushQuake2API(){
|
||||
g_multipleBrushTypes = true;
|
||||
g_brushTypes[0] = eBrushTypeQuake2;
|
||||
g_brushTypes[1] = eBrushTypeQuake3BP;
|
||||
g_brushTypes[2] = eBrushTypeQuake3Valve220;
|
||||
|
||||
Brush_Construct( eBrushTypeQuake2 );
|
||||
|
||||
m_brushquake2 = &GetBrushCreator();
|
||||
|
|
@ -338,6 +360,11 @@ typedef BrushCreator Type;
|
|||
STRING_CONSTANT( Name, "quake" );
|
||||
|
||||
BrushQuake1API(){
|
||||
g_multipleBrushTypes = true;
|
||||
g_brushTypes[0] = eBrushTypeQuake;
|
||||
g_brushTypes[1] = eBrushTypeQuake3BP;
|
||||
g_brushTypes[2] = eBrushTypeValve220;
|
||||
|
||||
Brush_Construct( eBrushTypeQuake );
|
||||
|
||||
m_brushquake1 = &GetBrushCreator();
|
||||
|
|
@ -363,7 +390,7 @@ typedef BrushCreator Type;
|
|||
STRING_CONSTANT( Name, "halflife" );
|
||||
|
||||
BrushHalfLifeAPI(){
|
||||
Brush_Construct( eBrushTypeHalfLife );
|
||||
Brush_Construct( eBrushTypeValve220 );
|
||||
|
||||
m_brushhalflife = &GetBrushCreator();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@
|
|||
#if !defined( INCLUDED_BRUSHMODULE_H )
|
||||
#define INCLUDED_BRUSHMODULE_H
|
||||
|
||||
#include "ibrush.h"
|
||||
|
||||
void Brush_clipperColourChanged();
|
||||
void Brush_unlatchPreferences();
|
||||
int Brush_toggleFormatCount();
|
||||
void Brush_toggleFormat( int i );
|
||||
void Brush_toggleFormat( EBrushType type );
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ inline bool FaceTexdef_BP_importTokens( FaceTexdef& texdef, Tokeniser& tokeniser
|
|||
return true;
|
||||
}
|
||||
|
||||
inline bool FaceTexdef_HalfLife_importTokens( FaceTexdef& texdef, Tokeniser& tokeniser ){
|
||||
inline bool FaceTexdef_Valve220_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() ) );
|
||||
|
|
@ -221,7 +221,9 @@ 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 ) );
|
||||
if ( Tokeniser_nextTokenIsDigit( tokeniser ) ) { ///optional for more flexibility
|
||||
RETURN_FALSE_IF_FAIL( FaceShader_importContentsFlagsValue( m_face.getShader(), tokeniser ) );
|
||||
}
|
||||
m_face.getTexdef().m_scaleApplied = true;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -237,7 +239,9 @@ 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 ) );
|
||||
if ( Tokeniser_nextTokenIsDigit( tokeniser ) ) { ///optional for more flexibility
|
||||
RETURN_FALSE_IF_FAIL( FaceShader_importContentsFlagsValue( m_face.getShader(), tokeniser ) );
|
||||
}
|
||||
|
||||
m_face.getTexdef().m_projectionInitialised = true;
|
||||
m_face.getTexdef().m_scaleApplied = true;
|
||||
|
|
@ -256,21 +260,45 @@ 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 ) ) { ///try to load for more flexibility
|
||||
RETURN_FALSE_IF_FAIL( FaceShader_importContentsFlagsValue( m_face.getShader(), tokeniser ) );
|
||||
}
|
||||
m_face.getTexdef().m_scaleApplied = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class HalfLifeFaceTokenImporter
|
||||
class Valve220FaceTokenImporter
|
||||
{
|
||||
Face& m_face;
|
||||
public:
|
||||
HalfLifeFaceTokenImporter( Face& face ) : m_face( face ){
|
||||
Valve220FaceTokenImporter( 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( FaceTexdef_Valve220_importTokens( m_face.getTexdef(), tokeniser ) );
|
||||
if ( Tokeniser_nextTokenIsDigit( tokeniser ) ) { ///try to load for more flexibility
|
||||
RETURN_FALSE_IF_FAIL( FaceShader_importContentsFlagsValue( m_face.getShader(), tokeniser ) );
|
||||
}
|
||||
m_face.getTexdef().m_scaleApplied = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class Quake3Valve220FaceTokenImporter
|
||||
{
|
||||
Face& m_face;
|
||||
public:
|
||||
Quake3Valve220FaceTokenImporter( 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_Valve220_importTokens( m_face.getTexdef(), tokeniser ) );
|
||||
if ( Tokeniser_nextTokenIsDigit( tokeniser ) ) { ///optional for more flexibility
|
||||
RETURN_FALSE_IF_FAIL( FaceShader_importContentsFlagsValue( m_face.getShader(), tokeniser ) );
|
||||
}
|
||||
m_face.getTexdef().m_scaleApplied = true;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -471,11 +499,11 @@ void exportTokens( TokenWriter& writer ) const {
|
|||
}
|
||||
};
|
||||
|
||||
class HalfLifeFaceTokenExporter
|
||||
class Valve220FaceTokenExporter
|
||||
{
|
||||
const Face& m_face;
|
||||
public:
|
||||
HalfLifeFaceTokenExporter( const Face& face ) : m_face( face ){
|
||||
Valve220FaceTokenExporter( const Face& face ) : m_face( face ){
|
||||
}
|
||||
void exportTokens( TokenWriter& writer ) const {
|
||||
FacePlane_exportTokens( m_face.getPlane(), writer );
|
||||
|
|
@ -485,6 +513,21 @@ void exportTokens( TokenWriter& writer ) const {
|
|||
}
|
||||
};
|
||||
|
||||
class Quake3Valve220FaceTokenExporter
|
||||
{
|
||||
const Face& m_face;
|
||||
public:
|
||||
Quake3Valve220FaceTokenExporter( 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 BrushTokenImporter : public MapImporter
|
||||
{
|
||||
|
|
@ -554,9 +597,15 @@ bool importTokens( Tokeniser& tokeniser ){
|
|||
RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
|
||||
}
|
||||
break;
|
||||
case eBrushTypeHalfLife:
|
||||
case eBrushTypeValve220:
|
||||
{
|
||||
HalfLifeFaceTokenImporter importer( face );
|
||||
Valve220FaceTokenImporter importer( face );
|
||||
RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
|
||||
}
|
||||
break;
|
||||
case eBrushTypeQuake3Valve220:
|
||||
{
|
||||
Quake3Valve220FaceTokenImporter importer( face );
|
||||
RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
|
||||
}
|
||||
break;
|
||||
|
|
@ -650,9 +699,15 @@ void exportTokens( TokenWriter& writer ) const {
|
|||
exporter.exportTokens( writer );
|
||||
}
|
||||
break;
|
||||
case eBrushTypeHalfLife:
|
||||
case eBrushTypeValve220:
|
||||
{
|
||||
HalfLifeFaceTokenExporter exporter( face );
|
||||
Valve220FaceTokenExporter exporter( face );
|
||||
exporter.exportTokens( writer );
|
||||
}
|
||||
break;
|
||||
case eBrushTypeQuake3Valve220:
|
||||
{
|
||||
Quake3Valve220FaceTokenExporter exporter( face );
|
||||
exporter.exportTokens( writer );
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1119,27 +1119,20 @@ void Map_LoadFile( const char *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;
|
||||
}
|
||||
}
|
||||
if ( format ) {
|
||||
format->m_detectedFormat = eBrushTypeUNKNOWN;
|
||||
}
|
||||
|
||||
g_map.m_name = filename;
|
||||
Map_UpdateTitle( g_map );
|
||||
g_map.m_resource = GlobalReferenceCache().capture( g_map.m_name.c_str() );
|
||||
g_map.m_resource->attach( g_map );
|
||||
if ( format && format->m_detectedFormat && format->m_detectedFormat != GlobalBrushModule::getTable().getCurrentFormat() ) {
|
||||
Map_Free();
|
||||
Brush_toggleFormat( format->m_detectedFormat );
|
||||
g_map.m_resource = GlobalReferenceCache().capture( g_map.m_name.c_str() );
|
||||
g_map.m_resource->attach( g_map );
|
||||
}
|
||||
Node_getTraversable( GlobalSceneGraph().root() )->traverse( entity_updateworldspawn() );
|
||||
}
|
||||
|
||||
|
|
@ -1675,21 +1668,19 @@ bool Map_ImportFile( const char* filename ){
|
|||
if ( string_not_empty( moduleName ) ) {
|
||||
format = ReferenceAPI_getMapModules().findModule( moduleName );
|
||||
}
|
||||
|
||||
if ( format ) {
|
||||
format->wrongFormat = false;
|
||||
format->m_detectedFormat = eBrushTypeUNKNOWN;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if ( format && /*format->m_detectedFormat &&*/ format->m_detectedFormat != GlobalBrushModule::getTable().getCurrentFormat() ) {
|
||||
GlobalReferenceCache().release( filename );
|
||||
goto tryDecompile;
|
||||
}
|
||||
NodeSmartReference clone( NewMapRoot( "" ) );
|
||||
Node_getTraversable( *resource->getNode() )->traverse( CloneAll( clone ) );
|
||||
|
|
@ -1744,7 +1735,7 @@ tryDecompile:
|
|||
resource->refresh(); // avoid loading old version if map has changed on disk since last import
|
||||
if ( !resource->load() ) {
|
||||
GlobalReferenceCache().release( filename );
|
||||
goto tryDecompile;
|
||||
return success;
|
||||
}
|
||||
NodeSmartReference clone( NewMapRoot( "" ) );
|
||||
Node_getTraversable( *resource->getNode() )->traverse( CloneAll( clone ) );
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user