mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 04:19:19 +02:00
build 180202. tga texture origin bit recognition, audio file load failure crash fix, cab controls positioning fix,
This commit is contained in:
@@ -105,7 +105,7 @@ TButton::model_offset() const {
|
||||
|
||||
return (
|
||||
submodel != nullptr ?
|
||||
submodel->offset( 2.5f ) :
|
||||
submodel->offset( std::numeric_limits<float>::max() ) :
|
||||
glm::vec3() );
|
||||
}
|
||||
|
||||
|
||||
18
DynObj.cpp
18
DynObj.cpp
@@ -5875,16 +5875,14 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
||||
}
|
||||
}
|
||||
|
||||
if( Vehicle.TrainType == dt_ET40 ) {
|
||||
if( Vehicle.Vel > 0.1 ) {
|
||||
transmission
|
||||
.pitch( transmission.m_frequencyoffset + transmission.m_frequencyfactor * Vehicle.Vel )
|
||||
.gain( transmission.m_amplitudeoffset + transmission.m_amplitudefactor * Vehicle.Vel )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else {
|
||||
transmission.stop();
|
||||
}
|
||||
if( Vehicle.Vel > 0.1 ) {
|
||||
transmission
|
||||
.pitch( transmission.m_frequencyoffset + transmission.m_frequencyfactor * Vehicle.Vel )
|
||||
.gain( transmission.m_amplitudeoffset + transmission.m_amplitudefactor * Vehicle.Vel )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else {
|
||||
transmission.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ struct global_settings {
|
||||
GLfloat FogColor[ 3 ] = { 0.6f, 0.7f, 0.8f };
|
||||
double fFogStart{ 1700 };
|
||||
double fFogEnd{ 2000 };
|
||||
std::string Season; // season of the year, based on simulation date
|
||||
std::string Weather{ "clear:" }; // current weather
|
||||
std::string Season{}; // season of the year, based on simulation date
|
||||
std::string Weather{ "cloudy:" }; // current weather
|
||||
bool FullPhysics{ true }; // full calculations performed for each simulation step
|
||||
bool bnewAirCouplers{ true };
|
||||
double fMoveLight{ -1 }; // numer dnia w roku albo -1
|
||||
|
||||
@@ -1187,7 +1187,8 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const {
|
||||
|
||||
if( true == TestFlag( iFlags, 0x0200 ) ) {
|
||||
// flip coordinates for t3d file which wasn't yet initialized
|
||||
if( std::abs( offset.y ) > offset.z ) {
|
||||
if( ( false == Global.pWorld->InitPerformed() )
|
||||
|| ( false == Vertices.empty() ) ) {
|
||||
// NOTE, HACK: results require flipping if the model wasn't yet initialized, so we're using crude method to detect possible cases
|
||||
// TODO: sort out this mess, either unify offset lookups to take place before (or after) initialization,
|
||||
// or provide way to determine on submodel level whether the initialization took place
|
||||
|
||||
21
Texture.cpp
21
Texture.cpp
@@ -484,6 +484,12 @@ opengl_texture::load_TGA() {
|
||||
return;
|
||||
}
|
||||
|
||||
if( ( tgaheader[ 17 ] & 0x20 ) != 0 ) {
|
||||
// normally origin is bottom-left
|
||||
// if byte 17 bit 5 is set, it is top-left and needs flip
|
||||
flip_vertical();
|
||||
}
|
||||
|
||||
downsize( GL_BGRA );
|
||||
if( ( data_width > Global.iMaxTextureSize ) || ( data_height > Global.iMaxTextureSize ) ) {
|
||||
// for non-square textures there's currently possibility the scaling routine will have to abort
|
||||
@@ -702,6 +708,21 @@ opengl_texture::downsize( GLuint const Format ) {
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
opengl_texture::flip_vertical() {
|
||||
|
||||
auto const swapsize { data_width * 4 };
|
||||
auto destination { data.begin() + ( data_height - 1 ) * swapsize };
|
||||
auto sampler { data.begin() };
|
||||
|
||||
for( auto row = 0; row < data_height / 2; ++row ) {
|
||||
|
||||
std::swap_ranges( sampler, sampler + swapsize, destination );
|
||||
sampler += swapsize;
|
||||
destination -= swapsize;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
texture_manager::assign_units( GLint const Helper, GLint const Shadows, GLint const Normals, GLint const Diffuse ) {
|
||||
|
||||
|
||||
@@ -55,9 +55,10 @@ private:
|
||||
void load_TGA();
|
||||
void set_filtering() const;
|
||||
void downsize( GLuint const Format );
|
||||
void flip_vertical();
|
||||
|
||||
// members
|
||||
std::vector<char> data; // texture data
|
||||
std::vector<char> data; // texture data (stored GL-style, bottom-left origin)
|
||||
resource_state data_state{ resource_state::none }; // current state of texture data
|
||||
int data_width{ 0 },
|
||||
data_height{ 0 },
|
||||
|
||||
77
Train.cpp
77
Train.cpp
@@ -46,42 +46,6 @@ control_mapper::find( TSubModel const *Control ) const {
|
||||
}
|
||||
}
|
||||
|
||||
TCab::TCab()
|
||||
{
|
||||
CabPos1.x = -1.0;
|
||||
CabPos1.y = 1.0;
|
||||
CabPos1.z = 1.0;
|
||||
CabPos2.x = 1.0;
|
||||
CabPos2.y = 1.0;
|
||||
CabPos2.z = -1.0;
|
||||
bEnabled = false;
|
||||
bOccupied = true;
|
||||
dimm_r = dimm_g = dimm_b = 1;
|
||||
intlit_r = intlit_g = intlit_b = 0;
|
||||
intlitlow_r = intlitlow_g = intlitlow_b = 0;
|
||||
/*
|
||||
iGaugesMax = 100; // 95 - trzeba pobierać to z pliku konfiguracyjnego
|
||||
ggList = new TGauge[iGaugesMax];
|
||||
iGauges = 0; // na razie nie są dodane
|
||||
iButtonsMax = 60; // 55 - trzeba pobierać to z pliku konfiguracyjnego
|
||||
btList = new TButton[iButtonsMax];
|
||||
iButtons = 0;
|
||||
*/
|
||||
}
|
||||
/*
|
||||
void TCab::Init(double Initx1, double Inity1, double Initz1, double Initx2, double Inity2,
|
||||
double Initz2, bool InitEnabled, bool InitOccupied)
|
||||
{
|
||||
CabPos1.x = Initx1;
|
||||
CabPos1.y = Inity1;
|
||||
CabPos1.z = Initz1;
|
||||
CabPos2.x = Initx2;
|
||||
CabPos2.y = Inity2;
|
||||
CabPos2.z = Initz2;
|
||||
bEnabled = InitEnabled;
|
||||
bOccupied = InitOccupied;
|
||||
}
|
||||
*/
|
||||
void TCab::Load(cParser &Parser)
|
||||
{
|
||||
// NOTE: clearing control tables here is bit of a crutch, imposed by current scheme of loading compartments anew on each cab change
|
||||
@@ -95,15 +59,15 @@ void TCab::Load(cParser &Parser)
|
||||
{
|
||||
Parser.getTokens( 9, false );
|
||||
Parser
|
||||
>> dimm_r
|
||||
>> dimm_g
|
||||
>> dimm_b
|
||||
>> intlit_r
|
||||
>> intlit_g
|
||||
>> intlit_b
|
||||
>> intlitlow_r
|
||||
>> intlitlow_g
|
||||
>> intlitlow_b;
|
||||
>> dimm.r
|
||||
>> dimm.g
|
||||
>> dimm.b
|
||||
>> intlit.r
|
||||
>> intlit.g
|
||||
>> intlit.b
|
||||
>> intlitlow.r
|
||||
>> intlitlow.g
|
||||
>> intlitlow.b;
|
||||
Parser.getTokens(); Parser >> token;
|
||||
}
|
||||
CabPos1.x = std::stod( token );
|
||||
@@ -119,14 +83,6 @@ void TCab::Load(cParser &Parser)
|
||||
bOccupied = true;
|
||||
}
|
||||
|
||||
TCab::~TCab()
|
||||
{
|
||||
/*
|
||||
delete[] ggList;
|
||||
delete[] btList;
|
||||
*/
|
||||
};
|
||||
|
||||
TGauge &TCab::Gauge(int n)
|
||||
{ // pobranie adresu obiektu aniomowanego ruchem
|
||||
/*
|
||||
@@ -427,12 +383,13 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d)
|
||||
}
|
||||
|
||||
PyObject *TTrain::GetTrainState() {
|
||||
PyObject *dict = PyDict_New();
|
||||
if( dict == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto const &mover = DynamicObject->MoverParameters;
|
||||
auto *dict = PyDict_New();
|
||||
if( ( dict == nullptr )
|
||||
|| ( mover == nullptr ) ) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyDict_SetItemString( dict, "cab", PyGetInt( mover->ActiveCab ) );
|
||||
// basic systems state data
|
||||
@@ -3110,7 +3067,8 @@ void TTrain::OnCommand_radiochanneldecrease( TTrain *Train, command_data const &
|
||||
void TTrain::OnCommand_radiostopsend( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
if( true == Train->mvOccupied->Radio ) {
|
||||
if( ( true == Train->mvOccupied->Radio )
|
||||
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) {
|
||||
simulation::Region->RadioStop( Train->Dynamic()->GetPosition() );
|
||||
}
|
||||
// visual feedback
|
||||
@@ -3125,7 +3083,8 @@ void TTrain::OnCommand_radiostopsend( TTrain *Train, command_data const &Command
|
||||
void TTrain::OnCommand_radiostoptest( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
if( Train->RadioChannel() == 10 ) {
|
||||
if( ( Train->RadioChannel() == 10 )
|
||||
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) {
|
||||
Train->Dynamic()->RadioStop();
|
||||
}
|
||||
// visual feedback
|
||||
|
||||
50
Train.h
50
Train.h
@@ -28,35 +28,27 @@ const float fConverterPrzekaznik = 1.5f; // hunter-261211: do przekaznika nadmia
|
||||
// const double fBuzzerTime= 5.0f;
|
||||
const float fHaslerTime = 1.2f;
|
||||
|
||||
class TCab
|
||||
{
|
||||
public:
|
||||
TCab();
|
||||
~TCab();
|
||||
/*
|
||||
void Init(double Initx1, double Inity1, double Initz1, double Initx2, double Inity2, double Initz2, bool InitEnabled, bool InitOccupied);
|
||||
*/
|
||||
class TCab {
|
||||
|
||||
public:
|
||||
// methods
|
||||
void Load(cParser &Parser);
|
||||
Math3D::vector3 CabPos1;
|
||||
Math3D::vector3 CabPos2;
|
||||
bool bEnabled;
|
||||
bool bOccupied;
|
||||
double dimm_r, dimm_g, dimm_b; // McZapkie-120503: tlumienie swiatla
|
||||
double intlit_r, intlit_g, intlit_b; // McZapkie-120503: oswietlenie kabiny
|
||||
double intlitlow_r, intlitlow_g, intlitlow_b; // McZapkie-120503: przyciemnione oswietlenie kabiny
|
||||
private:
|
||||
/*
|
||||
TGauge *ggList; // Ra 2014-08: lista animacji macierzowych (gałek) w kabinie
|
||||
int iGaugesMax, iGauges; // ile miejsca w tablicy i ile jest w użyciu
|
||||
TButton *btList; // Ra 2014-08: lista animacji dwustanowych (lampek) w kabinie
|
||||
int iButtonsMax, iButtons; // ile miejsca w tablicy i ile jest w użyciu
|
||||
*/
|
||||
std::vector<TGauge> ggList;
|
||||
std::vector<TButton> btList;
|
||||
public:
|
||||
TGauge &Gauge(int n = -1); // pobranie adresu obiektu
|
||||
TButton &Button(int n = -1); // pobranie adresu obiektu
|
||||
void Update();
|
||||
// members
|
||||
Math3D::vector3 CabPos1 { 0, 1, 1 };
|
||||
Math3D::vector3 CabPos2 { 0, 1, -1 };
|
||||
bool bEnabled { false };
|
||||
bool bOccupied { true };
|
||||
glm::vec3 dimm; // McZapkie-120503: tlumienie swiatla
|
||||
glm::vec3 intlit; // McZapkie-120503: oswietlenie kabiny
|
||||
glm::vec3 intlitlow; // McZapkie-120503: przyciemnione oswietlenie kabiny
|
||||
TGauge &Gauge( int n = -1 ); // pobranie adresu obiektu
|
||||
TButton &Button( int n = -1 ); // pobranie adresu obiektu
|
||||
|
||||
private:
|
||||
// members
|
||||
std::vector<TGauge> ggList;
|
||||
std::vector<TButton> btList;
|
||||
};
|
||||
|
||||
class control_mapper {
|
||||
@@ -449,13 +441,13 @@ public: // reszta może by?publiczna
|
||||
sound_source rsHissE { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // nagle
|
||||
sound_source rsHissX { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // fala
|
||||
sound_source rsHissT { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // czasowy
|
||||
sound_source rsSBHiss { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // local
|
||||
sound_source rsSBHiss { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // local
|
||||
sound_source rsSBHissU { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // local, engage brakes
|
||||
float m_lastlocalbrakepressure { -1.f }; // helper, cached level of pressure in local brake cylinder
|
||||
float m_localbrakepressurechange { 0.f }; // recent change of pressure in local brake cylinder
|
||||
|
||||
sound_source rsFadeSound { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
||||
sound_source rsRunningNoise{ sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
||||
sound_source rsRunningNoise{ sound_placement::internal, EU07_SOUND_GLOBALRANGE };
|
||||
|
||||
sound_source dsbHasler { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
||||
sound_source dsbBuzzer { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
||||
|
||||
65
audio.cpp
65
audio.cpp
@@ -30,16 +30,21 @@ openal_buffer::openal_buffer( std::string const &Filename ) :
|
||||
if( Filename.substr( Filename.rfind( '.' ) ) == ".wav" ) {
|
||||
// .wav file
|
||||
auto *file { drwav_open_file( Filename.c_str() ) };
|
||||
rate = file->sampleRate;
|
||||
auto const samplecount { static_cast<std::size_t>( file->totalSampleCount ) };
|
||||
data.resize( samplecount );
|
||||
drwav_read_s16(
|
||||
file,
|
||||
samplecount,
|
||||
&data[ 0 ] );
|
||||
if( file->channels > 1 ) {
|
||||
narrow_to_mono( file->channels );
|
||||
data.resize( samplecount / file->channels );
|
||||
if( file != nullptr ) {
|
||||
rate = file->sampleRate;
|
||||
auto const samplecount{ static_cast<std::size_t>( file->totalSampleCount ) };
|
||||
data.resize( samplecount );
|
||||
drwav_read_s16(
|
||||
file,
|
||||
samplecount,
|
||||
&data[ 0 ] );
|
||||
if( file->channels > 1 ) {
|
||||
narrow_to_mono( file->channels );
|
||||
data.resize( samplecount / file->channels );
|
||||
}
|
||||
}
|
||||
else {
|
||||
ErrorLog( "Bad file: failed do load audio file \"" + Filename + "\"", logtype::file );
|
||||
}
|
||||
// we're done with the disk data
|
||||
drwav_close( file );
|
||||
@@ -47,26 +52,32 @@ openal_buffer::openal_buffer( std::string const &Filename ) :
|
||||
else {
|
||||
// .flac or .ogg file
|
||||
auto *file { drflac_open_file( Filename.c_str() ) };
|
||||
rate = file->sampleRate;
|
||||
auto const samplecount{ static_cast<std::size_t>( file->totalSampleCount ) };
|
||||
data.resize( samplecount );
|
||||
drflac_read_s16(
|
||||
file,
|
||||
samplecount,
|
||||
&data[ 0 ] );
|
||||
if( file->channels > 1 ) {
|
||||
narrow_to_mono( file->channels );
|
||||
data.resize( samplecount / file->channels );
|
||||
if( file != nullptr ) {
|
||||
rate = file->sampleRate;
|
||||
auto const samplecount{ static_cast<std::size_t>( file->totalSampleCount ) };
|
||||
data.resize( samplecount );
|
||||
drflac_read_s16(
|
||||
file,
|
||||
samplecount,
|
||||
&data[ 0 ] );
|
||||
if( file->channels > 1 ) {
|
||||
narrow_to_mono( file->channels );
|
||||
data.resize( samplecount / file->channels );
|
||||
}
|
||||
}
|
||||
else {
|
||||
ErrorLog( "Bad file: failed do load audio file \"" + Filename + "\"", logtype::file );
|
||||
}
|
||||
// we're done with the disk data
|
||||
drflac_close( file );
|
||||
}
|
||||
// send the data to openal side
|
||||
::alBufferData( id, AL_FORMAT_MONO16, data.data(), data.size() * sizeof( std::int16_t ), rate );
|
||||
// and get rid of the source, we shouldn't need it anymore
|
||||
// TBD, TODO: delay data fetching and transfers until the buffer is actually used?
|
||||
std::vector<std::int16_t>().swap( data );
|
||||
|
||||
if( false == data.empty() ) {
|
||||
// send the data to openal side
|
||||
::alBufferData( id, AL_FORMAT_MONO16, data.data(), data.size() * sizeof( std::int16_t ), rate );
|
||||
// and get rid of the source, we shouldn't need it anymore
|
||||
// TBD, TODO: delay data fetching and transfers until the buffer is actually used?
|
||||
std::vector<std::int16_t>().swap( data );
|
||||
}
|
||||
fetch_caption();
|
||||
}
|
||||
|
||||
@@ -166,7 +177,7 @@ buffer_manager::create( std::string const &Filename ) {
|
||||
return emplace( filelookup );
|
||||
}
|
||||
// if we still didn't find anything, give up
|
||||
ErrorLog( "Bad file: failed do locate audio file \"" + Filename + "\"" );
|
||||
ErrorLog( "Bad file: failed do locate audio file \"" + Filename + "\"", logtype::file );
|
||||
return null_handle;
|
||||
}
|
||||
|
||||
|
||||
1
sound.h
1
sound.h
@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "classes.h"
|
||||
#include "names.h"
|
||||
|
||||
float const EU07_SOUND_GLOBALRANGE { -1.f };
|
||||
float const EU07_SOUND_CABCONTROLSCUTOFFRANGE { 7.5f };
|
||||
float const EU07_SOUND_BRAKINGCUTOFFRANGE { 100.f };
|
||||
float const EU07_SOUND_RUNNINGNOISECUTOFFRANGE { 200.f };
|
||||
|
||||
Reference in New Issue
Block a user