From 567b4e8c6afc394050c0e002c4cc2d2b0fac1389 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Mon, 24 Jul 2006 09:05:14 +0000 Subject: [PATCH] fix AV when using material that didn't load because texture doesn't exist --- stepmania/src/Model.cpp | 44 ++++++++++++++++++++++++------------ stepmania/src/Model.h | 12 +++++----- stepmania/src/ModelTypes.cpp | 12 +++++++++- stepmania/src/ModelTypes.h | 3 ++- 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/stepmania/src/Model.cpp b/stepmania/src/Model.cpp index 0365fe760b..4807b2d8d8 100644 --- a/stepmania/src/Model.cpp +++ b/stepmania/src/Model.cpp @@ -53,7 +53,7 @@ void Model::Clear() DISPLAY->DeleteCompiledGeometry( m_pTempGeometry ); } -void Model::Load( RString sFile ) +void Model::Load( const RString &sFile ) { if( sFile == "" ) return; @@ -65,12 +65,12 @@ void Model::Load( RString sFile ) #define THROW RageException::Throw( "Parse error in \"%s\" at line %d: '%s'", sPath.c_str(), iLineNum, sLine.c_str() ) -void Model::LoadMilkshapeAscii( RString sPath ) +void Model::LoadMilkshapeAscii( const RString &sPath ) { LoadPieces( sPath, sPath, sPath ); } -void Model::LoadPieces( RString sMeshesPath, RString sMaterialsPath, RString sBonesPath ) +void Model::LoadPieces( const RString &sMeshesPath, const RString &sMaterialsPath, const RString &sBonesPath ) { Clear(); @@ -134,8 +134,10 @@ void Model::LoadFromNode( const RString& sDir, const XNode* pNode ) } -void Model::LoadMaterialsFromMilkshapeAscii( RString sPath ) +void Model::LoadMaterialsFromMilkshapeAscii( const RString &_sPath ) { + RString sPath = _sPath; + FixSlashesInPlace(sPath); const RString sDir = Dirname( sPath ); @@ -174,6 +176,7 @@ void Model::LoadMaterialsFromMilkshapeAscii( RString sPath ) { m_Materials.resize( nNumMaterials ); + // XXX: handle buffer overflow char szName[256]; for( int i = 0; i < nNumMaterials; i++ ) @@ -183,6 +186,7 @@ void Model::LoadMaterialsFromMilkshapeAscii( RString sPath ) // name if( f.GetLine( sLine ) <= 0 ) THROW; + // XXX: handle buffer overflow if( sscanf(sLine, "\"%[^\"]\"", szName) != 1 ) THROW; Material.sName = szName; @@ -242,13 +246,19 @@ void Model::LoadMaterialsFromMilkshapeAscii( RString sPath ) sscanf( sLine, "\"%[^\"]\"", szName ); RString sDiffuseTexture = szName; - if( sDiffuseTexture != "" ) + if( sDiffuseTexture == "" ) + { + Material.diffuse.LoadBlank(); + } + else { RString sTexturePath = sDir + sDiffuseTexture; FixSlashesInPlace( sTexturePath ); CollapsePath( sTexturePath ); if( IsAFile(sTexturePath) ) + { Material.diffuse.Load( sTexturePath ); + } else { RString sError = ssprintf( "'%s' references a texture '%s' that does not exist", sPath.c_str(), sTexturePath.c_str() ); @@ -263,13 +273,19 @@ void Model::LoadMaterialsFromMilkshapeAscii( RString sPath ) sscanf( sLine, "\"%[^\"]\"", szName ); RString sAlphaTexture = szName; - if( sAlphaTexture != "" ) + if( sAlphaTexture == "" ) + { + Material.alpha.LoadBlank(); + } + else { RString sTexturePath = sDir + sAlphaTexture; FixSlashesInPlace( sTexturePath ); CollapsePath( sTexturePath ); if( IsAFile(sTexturePath) ) + { Material.alpha.Load( sTexturePath ); + } else { RString sError = ssprintf( "'%s' references a texture '%s' that does not exist", sPath.c_str(), sTexturePath.c_str() ); @@ -283,7 +299,7 @@ void Model::LoadMaterialsFromMilkshapeAscii( RString sPath ) f.Close(); } -bool Model::LoadMilkshapeAsciiBones( RString sAniName, RString sPath ) +bool Model::LoadMilkshapeAsciiBones( const RString &sAniName, const RString &sPath ) { m_mapNameToAnimation[sAniName] = msAnimation(); msAnimation &Animation = m_mapNameToAnimation[sAniName]; @@ -367,14 +383,14 @@ void Model::DrawPrimitives() if( bUseMultitexture ) { // render the diffuse texture with texture unit 1 - DISPLAY->SetTexture( TextureUnit_1, mat.diffuse.GetCurrentTexture()->GetTexHandle() ); + DISPLAY->SetTexture( TextureUnit_1, mat.diffuse.GetCurrentTexture() ? mat.diffuse.GetCurrentTexture()->GetTexHandle() : 0 ); Actor::SetTextureRenderStates(); // set Actor-specified render states DISPLAY->SetSphereEnvironmentMapping( mat.diffuse.m_bSphereMapped ); // render the additive texture with texture unit 2 if( mat.alpha.GetCurrentTexture() ) { - DISPLAY->SetTexture( TextureUnit_2, mat.alpha.GetCurrentTexture()->GetTexHandle() ); + DISPLAY->SetTexture( TextureUnit_2, mat.alpha.GetCurrentTexture() ? mat.alpha.GetCurrentTexture()->GetTexHandle() : 0 ); Actor::SetTextureRenderStates(); // set Actor-specified render states DISPLAY->SetSphereEnvironmentMapping( mat.alpha.m_bSphereMapped ); DISPLAY->SetTextureModeAdd(); @@ -386,7 +402,7 @@ void Model::DrawPrimitives() // set current texture back to 0 or else texture transform applied above // isn't used. Why?!? - DISPLAY->SetTexture( TextureUnit_1, mat.diffuse.GetCurrentTexture()->GetTexHandle() ); + DISPLAY->SetTexture( TextureUnit_1, mat.diffuse.GetCurrentTexture() ? mat.diffuse.GetCurrentTexture()->GetTexHandle() : 0 ); } /* go */ @@ -399,7 +415,7 @@ void Model::DrawPrimitives() else { // render the diffuse texture - DISPLAY->SetTexture( TextureUnit_1, mat.diffuse.GetCurrentTexture()->GetTexHandle() ); + DISPLAY->SetTexture( TextureUnit_1, mat.diffuse.GetCurrentTexture() ? mat.diffuse.GetCurrentTexture()->GetTexHandle() : 0 ); Actor::SetTextureRenderStates(); // set Actor-specified render states DISPLAY->SetSphereEnvironmentMapping( mat.diffuse.m_bSphereMapped ); DrawMesh( i ); @@ -407,7 +423,7 @@ void Model::DrawPrimitives() // render the additive texture if( mat.alpha.GetCurrentTexture() ) { - DISPLAY->SetTexture( TextureUnit_1, mat.alpha.GetCurrentTexture()->GetTexHandle() ); + DISPLAY->SetTexture( TextureUnit_1, mat.alpha.GetCurrentTexture() ? mat.alpha.GetCurrentTexture()->GetTexHandle() : 0 ); Actor::SetTextureRenderStates(); // set Actor-specified render states DISPLAY->SetSphereEnvironmentMapping( mat.alpha.m_bSphereMapped ); @@ -463,7 +479,7 @@ void Model::DrawPrimitives() if( pMesh->nMaterialIndex != -1 ) { msMaterial& mat = m_Materials[ pMesh->nMaterialIndex ]; - DISPLAY->SetTexture( TextureUnit_1, mat.diffuse.GetCurrentTexture()->GetTexHandle() ); + DISPLAY->SetTexture( TextureUnit_1, mat.diffuse.GetCurrentTexture() ? mat.diffuse.GetCurrentTexture()->GetTexHandle() : 0 ); Actor::SetTextureRenderStates(); // set Actor-specified render states } else @@ -502,7 +518,7 @@ void Model::SetDefaultAnimation( RString sAnimation, float fPlayRate ) m_fDefaultAnimationRate = fPlayRate; } -void Model::PlayAnimation( RString sAniName, float fPlayRate ) +void Model::PlayAnimation( const RString &sAniName, float fPlayRate ) { if( m_mapNameToAnimation.find(sAniName) == m_mapNameToAnimation.end() ) return; diff --git a/stepmania/src/Model.h b/stepmania/src/Model.h index 1f612cb73e..ac2557daf0 100644 --- a/stepmania/src/Model.h +++ b/stepmania/src/Model.h @@ -20,16 +20,16 @@ public: virtual Actor *Copy() const; void Clear(); - void Load( RString sFile ); + void Load( const RString &sFile ); - void LoadPieces( RString sMeshesPath, RString sMaterialsPath, RString sBomesPath ); - void LoadMilkshapeAscii( RString sFile ); - void LoadMaterialsFromMilkshapeAscii( RString sPath ); - bool LoadMilkshapeAsciiBones( RString sAniName, RString sPath ); + void LoadPieces( const RString &sMeshesPath, const RString &sMaterialsPath, const RString &sBomesPath ); + void LoadMilkshapeAscii( const RString &sFile ); + void LoadMaterialsFromMilkshapeAscii( const RString &sPath ); + bool LoadMilkshapeAsciiBones( const RString &sAniName, const RString &sPath ); void LoadFromNode( const RString& sDir, const XNode* pNode ); - void PlayAnimation( RString sAniName, float fPlayRate = 1 ); + void PlayAnimation( const RString &sAniName, float fPlayRate = 1 ); virtual void Update( float fDelta ); virtual bool EarlyAbortDraw() const; diff --git a/stepmania/src/ModelTypes.cpp b/stepmania/src/ModelTypes.cpp index 8e73eb012a..6c5bb7aad3 100644 --- a/stepmania/src/ModelTypes.cpp +++ b/stepmania/src/ModelTypes.cpp @@ -27,7 +27,17 @@ AnimatedTexture::~AnimatedTexture() Unload(); } -void AnimatedTexture::Load( RString sTexOrIniPath ) +void AnimatedTexture::LoadBlank() +{ + AnimatedTextureState state( + NULL, + 1, + RageVector2(0,0) + ); + vFrames.push_back( state ); +} + +void AnimatedTexture::Load( const RString &sTexOrIniPath ) { ASSERT( vFrames.empty() ); // don't load more than once diff --git a/stepmania/src/ModelTypes.h b/stepmania/src/ModelTypes.h index ace2a8dbda..fb87ec263b 100644 --- a/stepmania/src/ModelTypes.h +++ b/stepmania/src/ModelTypes.h @@ -38,7 +38,8 @@ public: AnimatedTexture(); ~AnimatedTexture(); - void Load( RString sTexOrIniFile ); + void LoadBlank(); + void Load( const RString &sTexOrIniFile ); void Unload(); void Update( float fDelta );