-
Notifications
You must be signed in to change notification settings - Fork 51
/
Button.cpp
166 lines (135 loc) · 4.48 KB
/
Button.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#include "stdafx.h"
#include "Button.h"
#include "parser.h"
#include "Model3d.h"
#include "DynObj.h"
#include "Console.h"
#include "Logs.h"
#include "renderer.h"
void TButton::Clear(int i)
{
*this = TButton();
if( i >= 0 ) {
FeedbackBitSet( i );
}
Update(); // kasowanie bitu Feedback, o ile jakiś ustawiony
};
bool TButton::Init( std::string const &asName, TModel3d const *pModel, bool bNewOn ) {
if( pModel == nullptr ) { return false; }
pModelOn = pModel->GetFromName( asName + "_on" );
pModelOff = pModel->GetFromName( asName + "_off" );
m_state = bNewOn;
Update();
return( ( pModelOn != nullptr ) || ( pModelOff != nullptr ) );
};
void TButton::Load( cParser &Parser, TDynamicObject const *Owner ) {
std::string submodelname;
Parser.getTokens();
if( Parser.peek() != "{" ) {
// old fixed size config
Parser >> submodelname;
}
else {
// new, block type config
// TODO: rework the base part into yaml-compatible flow style mapping
submodelname = Parser.getToken<std::string>( false );
while( true == Load_mapping( Parser ) ) {
; // all work done by while()
}
}
// bind defined sounds with the button owner
m_soundfxincrease.owner( Owner );
m_soundfxdecrease.owner( Owner );
std::array<TModel3d *, 3> sources { Owner->mdKabina, Owner->mdLowPolyInt, Owner->mdModel };
for( auto const *source : sources ) {
if( true == Init( submodelname, source, false ) ) {
// got what we wanted, don't need to search further
break;
}
}
if( ( pModelOn == nullptr )
&& ( pModelOff == nullptr ) ) {
// if we failed to locate even one state submodel, cry
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model(s) of \"" + Owner->name() + "\"", logtype::model );
}
// pass submodel location to defined sounds
auto const nulloffset { glm::vec3{} };
auto const offset { model_offset() };
if( m_soundfxincrease.offset() == nulloffset ) {
m_soundfxincrease.offset( offset );
}
if( m_soundfxdecrease.offset() == nulloffset ) {
m_soundfxdecrease.offset( offset );
}
}
bool
TButton::Load_mapping( cParser &Input ) {
// token can be a key or block end
std::string const key { Input.getToken<std::string>( true, "\n\r\t ,;" ) };
if( ( true == key.empty() ) || ( key == "}" ) ) { return false; }
// if not block end then the key is followed by assigned value or sub-block
if( key == "soundinc:" ) { m_soundfxincrease.deserialize( Input, sound_type::single ); }
else if( key == "sounddec:" ) { m_soundfxdecrease.deserialize( Input, sound_type::single ); }
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
}
// returns offset of submodel associated with the button from the model centre
glm::vec3
TButton::model_offset() const {
auto const
submodel { (
pModelOn ? pModelOn :
pModelOff ? pModelOff :
nullptr ) };
return (
submodel != nullptr ?
submodel->offset( std::numeric_limits<float>::max() ) :
glm::vec3() );
}
void
TButton::Turn( bool const State ) {
if( State != m_state ) {
m_state = State;
play();
Update();
}
}
void TButton::Update( bool const Power ) {
// TODO: remove passing manually power state when LD is in place
auto const state { Power && ( bData ? *bData : m_state ) };
if( state != m_state ) {
m_state = state;
play();
}
if( pModelOn != nullptr ) { pModelOn->iVisible = m_state; }
if( pModelOff != nullptr ) { pModelOff->iVisible = (!m_state); }
#ifdef _WIN32
if (iFeedbackBit) {
// jeżeli generuje informację zwrotną
if (m_state) // zapalenie
Console::BitsSet(iFeedbackBit);
else
Console::BitsClear(iFeedbackBit);
}
#endif
};
void TButton::AssignBool(bool const *bValue) {
bData = bValue;
}
void
TButton::play() {
if( m_state == true ) { m_soundfxincrease.play(); }
else { m_soundfxdecrease.play(); }
}
void
TButton::gain(float new_volume) {
m_soundfxincrease.gain(new_volume);
m_soundfxdecrease.gain(new_volume);
}