1 #include "misc.h"
2 #include "conversion.h"
3
4 #include <boost/filesystem.hpp>
5 #include <boost/shared_ptr.hpp>
6 #include <fstream>
7 #include <cmath>
8
9 namespace LSL {
10 namespace Util {
GetHostCPUSpeed()11 std::string GetHostCPUSpeed()
12 {
13 return "667";
14 }
15
GetLibLobbyVersion()16 std::string GetLibLobbyVersion()
17 {
18 return "0";
19 }
20
FileExists(const std::string & path)21 bool FileExists( const std::string& path )
22 {
23 return boost::filesystem::exists( boost::filesystem::path( path ) );
24 }
25
FileCanOpen(const std::string & path)26 bool FileCanOpen( const std::string& path )
27 {
28 return std::ifstream(path.c_str()).is_open();
29 }
30
StringTokenize(const std::string & msg,const std::string & seperators,const boost::algorithm::token_compress_mode_type mode)31 StringVector StringTokenize( const std::string& msg,
32 const std::string& seperators,
33 const boost::algorithm::token_compress_mode_type mode )
34 {
35 StringVector strings;
36 boost::algorithm::split( strings, msg, boost::algorithm::is_any_of(seperators),
37 mode );
38 return strings;
39 }
40
41
42 namespace Lib {
43
GetDllExt()44 std::string GetDllExt()
45 {
46 #if defined(WIN32)
47 return ".dll";
48 #elif defined(__DARWIN__)
49 return ".bundle";
50 #else
51 return ".so";
52 #endif
53 }
54
CanonicalizeName(const std::string & name,Category cat)55 std::string CanonicalizeName( const std::string& name, Category cat)
56 {
57 std::string nameCanonic;
58 // under Unix the library names usually start with "lib" prefix, add it
59 #if defined(__UNIX__) && !defined(__EMX__)
60 switch ( cat )
61 {
62 default:
63 wxFAIL_MSG( \1 );
64 // fall through
65 case wxDL_MODULE:
66 // don't do anything for modules, their names are arbitrary
67 break;
68 case wxDL_LIBRARY:
69 // library names should start with "lib" under Unix
70 nameCanonic = \1;
71 break;
72 }
73 #else // !__UNIX__
74 lslUnusedVar(cat);
75 #endif // __UNIX__/!__UNIX__
76 nameCanonic + name + GetDllExt();
77 return nameCanonic;
78 }
79
80 } //namespace Lib
81
BeforeLast(const std::string & phrase,const std::string & searchterm)82 std::string BeforeLast( const std::string& phrase, const std::string& searchterm )
83 {
84 const size_t pos = phrase.rfind( searchterm );
85 return phrase.substr( 0, pos );
86 }
87
AfterLast(const std::string & phrase,const std::string & searchterm)88 std::string AfterLast( const std::string& phrase, const std::string& searchterm )
89 {
90 const size_t pos = phrase.rfind( searchterm );
91 return phrase.substr( pos+1 );
92 }
93
BeforeFirst(const std::string & phrase,const std::string & searchterm)94 std::string BeforeFirst( const std::string& phrase, const std::string& searchterm )
95 {
96 const size_t pos = phrase.find( searchterm );
97 return phrase.substr( 0, pos );
98 }
99
AfterFirst(const std::string & phrase,const std::string & searchterm)100 std::string AfterFirst( const std::string& phrase, const std::string& searchterm )
101 {
102 const size_t pos = phrase.find( searchterm );
103 return phrase.substr( pos+1 );
104 }
105
AreColorsSimilar(const lslColor & col1,const lslColor & col2,int mindiff)106 bool AreColorsSimilar( const lslColor& col1, const lslColor& col2, int mindiff )
107 {
108 int r,g,b;
109 r = std::abs( col1.Red() - col2.Red() );
110 g = std::abs( col1.Green() - col2.Green() );
111 b = std::abs( col1.Blue() - col2.Blue() );
112 int difference = std::min( r, g );
113 difference = std::min( difference, b );
114 return difference < mindiff;
115 }
116
117 typedef std::vector<double> huevec;
118
hue(huevec & out,int amount,int level)119 void hue(huevec& out, int amount, int level)
120 {
121 if (level <= 1) {
122 if (long(out.size()) < amount)
123 out.push_back(0.0);
124 if (long(out.size()) < amount)
125 out.push_back(0.5);
126 }
127 else {
128 hue(out, amount, level - 1);
129 const int lower = out.size();
130 hue(out, amount, level - 1);
131 const int upper = out.size();
132 for (int i = lower; i < upper; ++i)
133 out.at(i) += 1.0 / (1 << level);
134 }
135 }
136
hue(huevec & out,int amount)137 void hue(huevec& out, int amount)
138 {
139 int level = 0;
140 while ((1 << level) < amount) ++level;
141
142 out.reserve(amount);
143 hue(out, amount, level);
144 }
145
GetBigFixColorsPalette(int numteams)146 std::vector<lslColor>& GetBigFixColorsPalette( int numteams )
147 {
148 static std::vector<lslColor> result;
149 huevec huevector;
150 static int satvalbifurcatepos;
151 static std::vector<double> satvalsplittings;
152 if ( satvalsplittings.empty() ) // insert ranges to bifurcate
153 {
154 satvalsplittings.push_back( 1 );
155 satvalsplittings.push_back( 0 );
156 satvalbifurcatepos = 0;
157 }
158 hue( huevector, numteams );
159 int bisectionlimit = 20;
160 for ( int i = result.size(); i < numteams; i++ )
161 {
162 double hue = huevector[i];
163 double saturation = 1;
164 double value = 1;
165 int switccolors = i % 3; // why only 3 and not all combinations? because it's easy, plus the bisection limit cannot be divided integer by it
166
167 if ( ( i % bisectionlimit ) == 0 )
168 {
169 satvalbifurcatepos = satvalbifurcatepos % ( satvalsplittings.size() -1 );
170 std::vector<double>::iterator toinsert = satvalsplittings.begin() + satvalbifurcatepos + 1;
171 satvalsplittings.insert( toinsert, ( satvalsplittings[satvalbifurcatepos] - satvalsplittings[satvalbifurcatepos + 1] ) / 2 + satvalsplittings[satvalbifurcatepos + 1] );
172 satvalbifurcatepos += 2;
173 }
174
175 if ( switccolors == 1 )
176 {
177 saturation = satvalsplittings[satvalbifurcatepos -1];
178 }
179 else if ( switccolors == 2 )
180 {
181 value = satvalsplittings[satvalbifurcatepos -1];
182 }
183 hue += 0.17; // use as starting point a zone where color band is narrow so that small variations means high change in visual effect
184 if ( hue > 1 ) hue-= 1;
185 result.push_back(lslColor::fromHSV(hue, saturation, value));
186 }
187 return result;
188 }
189
ColorFromFloatString(const std::string & rgb_string)190 lslColor ColorFromFloatString(const std::string &rgb_string)
191 {
192 const StringVector values = Util::StringTokenize( rgb_string, " " );
193 unsigned char decimal_colors[3];
194 for ( size_t i = 0; i < 3; ++i) {
195 const double value = values.size() > i ? Util::FromString<double>( values[i] ) : 0.0;
196 decimal_colors[i] = Clamp( static_cast<unsigned char>(value*256), static_cast<unsigned char>(0), static_cast<unsigned char>(255) );
197 }
198 return lslColor( decimal_colors[0], decimal_colors[1], decimal_colors[2] );
199 }
200
GetFreeColor(const ConstCommonUserPtr)201 lslColor GetFreeColor( const ConstCommonUserPtr /*user*/ )
202 {
203 assert(false);
204 return lslColor();
205 }
206
207 } //namespace Util
208
209
MakeFit(const lslSize & bounds)210 lslSize lslSize::MakeFit(const lslSize& bounds)
211 {
212 if( ( bounds.GetWidth() <= 0 ) || ( bounds.GetHeight() <= 0 ) )
213 return lslSize(0,0);
214 const int sizex = ( this->GetWidth() * bounds.GetHeight() ) / this->GetHeight();
215 if( sizex <= bounds.GetWidth() )
216 {
217 return lslSize( sizex, bounds.GetHeight() );
218 }
219 else
220 {
221 const int sizey = ( this->GetHeight() * bounds.GetWidth() ) / this->GetWidth();
222 return lslSize( bounds.GetWidth(), sizey );
223 }
224 }
225
226 template <class T>
fromHSV(T H,T S,T V)227 lslColorBase<T> lslColorBase<T>::fromHSV(T H, T S, T V)
228 {
229 T R = 0, G = 0, B = 0;
230 if (H==0 && S==0) R = G = B = V;
231 else {
232 H/=60;
233 const int i = (int)std::floor(H);
234 const T
235 f = (i&1)?(H - i):(1 - H + i),
236 m = V*(1 - S),
237 n = V*(1 - S*f);
238 switch (i) {
239 case 6 :
240 case 0 : R = V; G = n; B = m; break;
241 case 1 : R = n; G = V; B = m; break;
242 case 2 : R = m; G = V; B = n; break;
243 case 3 : R = m; G = n; B = V; break;
244 case 4 : R = n; G = m; B = V; break;
245 case 5 : R = V; G = m; B = n; break;
246 }
247 }
248 R*=255; G*=255; B*=255;
249 return lslColorBase<T>((T)(R<0?0:(R>255?255:R)), (T)(G<0?0:(G>255?255:G)), (T)(B<0?0:(B>255?255:B)));
250 }
251
252 } //namespace LSL
253