From c312251580d073826f94c5fca449448fa76f5afd Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Fri, 4 Oct 2019 23:50:33 +0200 Subject: [PATCH] build 191004. static model multiple replacable skins support, retarder state exposed to python scripts, sound source fix --- AnimModel.cpp | 23 +-------- DynObj.cpp | 128 +++++++++++++++++++++++++------------------------- DynObj.h | 3 ++ Train.cpp | 4 +- sound.cpp | 29 ++++++++---- version.h | 2 +- 6 files changed, 91 insertions(+), 98 deletions(-) diff --git a/AnimModel.cpp b/AnimModel.cpp index 71900216..4798b472 100644 --- a/AnimModel.cpp +++ b/AnimModel.cpp @@ -422,28 +422,7 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable asText = asReplacableTexture.substr( 1, asReplacableTexture.length() - 1 ); // zapamiętanie tekstu } else if( asReplacableTexture != "none" ) { -/* - auto const texturepath { substr_path( asReplacableTexture ) }; - if( false == texturepath.empty() ) { - Global.asCurrentTexturePath = texturepath; - } -*/ - m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( asReplacableTexture ); -/* - if( false == texturepath.empty() ) { - // z powrotem defaultowa sciezka do tekstur - Global.asCurrentTexturePath = std::string( szTexturePath ); - } -*/ - } - if( ( m_materialdata.replacable_skins[ 1 ] != null_handle ) - && ( GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) ) { - // tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych - m_materialdata.textures_alpha = 0x31310031; - } - else{ - // tekstura nieprzezroczysta - nie renderować w cyklu przezroczystych - m_materialdata.textures_alpha = 0x30300030; + m_materialdata.assign( asReplacableTexture ); } // TODO: redo the random timer initialization diff --git a/DynObj.cpp b/DynObj.cpp index 05a9f09b..3cfd20c4 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -162,6 +162,65 @@ void TAnim::Parovoz(){ */ +// assigns specified texture or a group of textures to replacable texture slots +void +material_data::assign( std::string const &Replacableskin ) { + + // check for the pipe method first + if( Replacableskin.find( '|' ) != std::string::npos ) { + cParser nameparser( Replacableskin ); + nameparser.getTokens( 4, true, "|" ); + int skinindex = 0; + std::string texturename; nameparser >> texturename; + while( ( texturename != "" ) && ( skinindex < 4 ) ) { + replacable_skins[ skinindex + 1 ] = GfxRenderer.Fetch_Material( texturename ); + ++skinindex; + texturename = ""; nameparser >> texturename; + } + multi_textures = skinindex; + } + else { + // otherwise try the basic approach + int skinindex = 0; + do { + // test quietly for file existence so we don't generate tons of false errors in the log + // NOTE: this means actual missing files won't get reported which is hardly ideal, but still somewhat better + auto const material { TextureTest( ToLower( Replacableskin + "," + std::to_string( skinindex + 1 ) ) ) }; + if( true == material.empty() ) { break; } + + replacable_skins[ skinindex + 1 ] = GfxRenderer.Fetch_Material( material ); + ++skinindex; + } while( skinindex < 4 ); + multi_textures = skinindex; + if( multi_textures == 0 ) { + // zestaw nie zadziałał, próbujemy normanie + replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( Replacableskin ); + } + } + if( replacable_skins[ 1 ] == null_handle ) { + // last ditch attempt, check for single replacable skin texture + replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( Replacableskin ); + } + + textures_alpha = ( + GfxRenderer.Material( replacable_skins[ 1 ] ).has_alpha ? + 0x31310031 : // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych + 0x30300030 ); // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych + if( GfxRenderer.Material( replacable_skins[ 2 ] ).has_alpha ) { + // tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych + textures_alpha |= 0x02020002; + } + if( GfxRenderer.Material( replacable_skins[ 3 ] ).has_alpha ) { + // tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych + textures_alpha |= 0x04040004; + } + if( GfxRenderer.Material( replacable_skins[ 4 ] ).has_alpha ) { + // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych + textures_alpha |= 0x08080008; + } +} + + void TDynamicObject::destination_data::deserialize( cParser &Input ) { while( true == deserialize_mapping( Input ) ) { @@ -4323,6 +4382,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co if( asModel[ 0 ] == '/' ) { asModel.erase( 0, 1 ); } + /* + // never really used, may as well get rid of it std::size_t i = asModel.find( ',' ); if ( i != std::string::npos ) { // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur? @@ -4331,76 +4392,15 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co } m_materialdata.multi_textures = clamp( m_materialdata.multi_textures, 0, 1 ); // na razie ustawiamy na 1 } + */ asModel = asBaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje modele w dynamics/basedir Global.asCurrentTexturePath = asBaseDir; // biezaca sciezka do tekstur to dynamic/... mdModel = TModelsManager::GetModel(asModel, true); - if (ReplacableSkin != "none") - { - if (m_materialdata.multi_textures > 0) { - // jeśli model ma 4 tekstury - // check for the pipe method first - if( ReplacableSkin.find( '|' ) != std::string::npos ) { - cParser nameparser( ReplacableSkin ); - nameparser.getTokens( 4, true, "|" ); - int skinindex = 0; - std::string texturename; nameparser >> texturename; - while( ( texturename != "" ) && ( skinindex < 4 ) ) { - m_materialdata.replacable_skins[ skinindex + 1 ] = GfxRenderer.Fetch_Material( texturename ); - ++skinindex; - texturename = ""; nameparser >> texturename; - } - m_materialdata.multi_textures = skinindex; - } - else { - // otherwise try the basic approach - int skinindex = 0; - do { - material_handle material = GfxRenderer.Fetch_Material( ReplacableSkin + "," + std::to_string( skinindex + 1 ), true ); - if( material == null_handle ) { - break; - } - m_materialdata.replacable_skins[ skinindex + 1 ] = material; - ++skinindex; - } while( skinindex < 4 ); - m_materialdata.multi_textures = skinindex; - if( m_materialdata.multi_textures == 0 ) { - // zestaw nie zadziałał, próbujemy normanie - m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( ReplacableSkin ); - } - } - } - else { - m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( ReplacableSkin ); - } - + if (ReplacableSkin != "none") { + m_materialdata.assign( ReplacableSkin ); // potentially set blank destination texture DestinationSign.destination_off = DestinationFind( "nowhere" ); // DestinationSet( {}, {} ); - - if( GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) { - // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych - m_materialdata.textures_alpha = 0x31310031; - } - else { - // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych - m_materialdata.textures_alpha = 0x30300030; - } - - if( ( m_materialdata.replacable_skins[ 2 ] ) - && ( GfxRenderer.Material( m_materialdata.replacable_skins[ 2 ] ).has_alpha ) ) { - // tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych - m_materialdata.textures_alpha |= 0x02020002; - } - if( ( m_materialdata.replacable_skins[ 3 ] ) - && ( GfxRenderer.Material( m_materialdata.replacable_skins[ 3 ] ).has_alpha ) ) { - // tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych - m_materialdata.textures_alpha |= 0x04040004; - } - if( ( m_materialdata.replacable_skins[ 4 ] ) - && ( GfxRenderer.Material( m_materialdata.replacable_skins[ 4 ] ).has_alpha ) ) { - // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych - m_materialdata.textures_alpha |= 0x08080008; - } } Global.asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur do { diff --git a/DynObj.h b/DynObj.h index b6c72a0d..55a4ba15 100644 --- a/DynObj.h +++ b/DynObj.h @@ -154,6 +154,9 @@ struct material_data { int textures_alpha{ 0x30300030 }; // maska przezroczystości tekstur. default: tekstury wymienne nie mają przezroczystości material_handle replacable_skins[ 5 ] = { null_handle, null_handle, null_handle, null_handle, null_handle }; // McZapkie:zmienialne nadwozie int multi_textures{ 0 }; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna + + // assigns specified texture or a group of textures to replacable texture slots + void assign( std::string const &Replacableskin ); }; class TDynamicObject { // klasa pojazdu diff --git a/Train.cpp b/Train.cpp index 59b96f11..c33a0d46 100644 --- a/Train.cpp +++ b/Train.cpp @@ -524,7 +524,7 @@ dictionary_source *TTrain::GetTrainState() { // induction motor state data char const *TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" }; char const *TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" }; - char const *TXTD[ 10 ] = { "enrot", "nrot", "fill_des", "fill_real", "clutch_des", "clutch_real", "water_temp", "oil_press", "engine_temp", "res1" }; + char const *TXTD[ 10 ] = { "enrot", "nrot", "fill_des", "fill_real", "clutch_des", "clutch_real", "water_temp", "oil_press", "engine_temp", "retarder_fill" }; char const *TXTP[ 3 ] = { "bc", "bp", "sp" }; char const *TXTB[ 2 ] = { "spring_active", "spring_shutoff" }; for( int j = 0; j < 10; ++j ) @@ -5638,7 +5638,7 @@ bool TTrain::Update( double const Deltatime ) fDieselParams[1 + in][6] = p->MoverParameters->dizel_heat.Twy; fDieselParams[1 + in][7] = p->MoverParameters->OilPump.pressure; fDieselParams[1 + in][8] = p->MoverParameters->dizel_heat.Ts; - //fDieselParams[1 + in][9] = p->MoverParameters-> + fDieselParams[1 + in][9] = p->MoverParameters->hydro_R_Fill; bMains[in] = p->MoverParameters->Mains; fCntVol[in] = p->MoverParameters->BatteryVoltage; bFuse[in] = p->MoverParameters->FuseFlag; diff --git a/sound.cpp b/sound.cpp index b8d6ef5a..c3da5ed7 100644 --- a/sound.cpp +++ b/sound.cpp @@ -507,11 +507,14 @@ sound_source::update_basic( audio::openal_source &Source ) { // detect the moment when the sound moves from startup sample to the main if( true == Source.sound_change ) { // when it happens update active sample counters, and potentially activate the looping - update_counter( sound_id::begin, -1 ); - update_counter( soundhandle, 1 ); if( soundhandle == sound_id::main ) { - Source.loop( TestFlag( m_flags, sound_flags::looping ) ); + update_counter( sound_id::begin, -1 ); } + update_counter( soundhandle, 1 ); + Source.loop( ( + soundhandle == sound_id::main ? + TestFlag( m_flags, sound_flags::looping ) : + false ) ); } } @@ -552,10 +555,11 @@ sound_source::update_basic( audio::openal_source &Source ) { // the emitter wasn't yet started auto const soundhandle { Source.sounds[ Source.sound_index ] }; // emitter initialization - if( soundhandle == sound_id::main ) { - // main sample can be optionally set to loop - Source.loop( TestFlag( m_flags, sound_flags::looping ) ); - } + // main sample can be optionally set to loop + Source.loop( ( + soundhandle == sound_id::main ? + TestFlag( m_flags, sound_flags::looping ) : + false ) ); Source.range( m_range ); Source.pitch( m_pitchvariation ); update_location(); @@ -576,12 +580,19 @@ sound_source::update_basic( audio::openal_source &Source ) { } else { // the emitter is either all done or was terminated early + if( true == Source.sound_change ) { + // HACK: sound change flag means when the emitter was stopped our state counters were tracking previous sound in the sequence + // the id of that sound is no longer available, but for basic sounds we can make presumption about it + update_counter( Source.sounds[ Source.sound_index - 1 ] - 1, -1 ); + } + else { + update_counter( Source.sounds[ Source.sound_index - 1 ], -1 ); + } /* - update_counter( Source.sounds[ Source.sound_index - 1 ], -1 ); - */ for( auto &soundchunk : m_soundchunks ) { soundchunk.first.playing = 0; } + */ } } } diff --git a/version.h b/version.h index f70838da..f0b0dee8 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 19 -#define VERSION_MINOR 929 +#define VERSION_MINOR 1004 #define VERSION_REVISION 0