Launcher, based on PickleLauncher
[mupen64plus-pandora.git] / source / mupen64launcher / src / cbase.cpp
CommitLineData
8b5037a6 1/**
2 * @section LICENSE
3 *
4 * PickleLauncher
5 * Copyright (C) 2010-2011 Scott Smith
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * @section LOCATION
21 */
22
23#include "cbase.h"
24
25CBase::CBase()
26{
27}
28
29CBase::~CBase()
30{
31}
32
33void CBase::Log( const char* output, ... )
34{
35 va_list fmtargs;
36 char buffer[1024];
37
38 va_start( fmtargs, output );
39 vsnprintf( buffer, sizeof(buffer)-1, output, fmtargs );
40 va_end( fmtargs );
41
42 fprintf( stdout, "%s", buffer );
43
44#if defined(DEBUG)
45 FILE* fout = fopen( "log.txt", "a" );
46 if (!fout)
47 {
48 printf( "Failed to open logfile\n" );
49 return;
50 }
51 fputs(buffer, fout);
52 fclose(fout);
53#endif
54}
55
56uint32_t CBase::CheckRange( int32_t value, int32_t size )
57{
58 if (value >= 0 && value < size)
59 {
60 return 1;
61 }
62 else
63 {
64 return 0;
65 }
66}
67
68uint32_t CBase::rgb_to_int( SDL_Color color )
69{
70 return SDL_MapRGB(SDL_GetVideoSurface()->format, color.r, color.g, color.b);
71}
72
73int32_t CBase::a_to_i( const string& line )
74{
75 int32_t number;
76
77 stringstream ss( line.c_str() );
78 ss >> number; // Convert string to integer
79 return number;
80}
81
82string CBase::i_to_a( const int16_t num )
83{
84 string str;
85 stringstream ss;
86
87 ss << num;
88 ss >> str; // Convert string to integer
89 return str;
90}
91
92string CBase::lowercase( string text )
93{
94 transform( text.begin(), text.end(), text.begin(), (int (*)(int))tolower );
95 return text;
96}
97
98SDL_Surface* CBase::LoadImage( const string& filename )
99{
100 SDL_Surface* loaded_image = NULL; // The mpImage that's loaded
101 SDL_Surface* optimized_image = NULL; // The optimized surface that will be used
102
103 loaded_image = IMG_Load( filename.c_str() ); //Load the mpImage
104
105 // If the mpImage loaded
106 if (NULL != loaded_image)
107 {
108 optimized_image = SDL_DisplayFormatAlpha( loaded_image ); // Create an optimized surface
109 SDL_FreeSurface(loaded_image); // Free the old surface
110 loaded_image = NULL;
111
112 // If the surface was optimized
113 if (NULL != optimized_image)
114 {
115 // Color key surface
116 SDL_SetColorKey( optimized_image, SDL_RLEACCEL | SDL_SRCCOLORKEY, SDL_MapRGB( optimized_image->format, 0xFF, 0, 0xFF ) );
117 }
118 }
119 else
120 {
121 //Log( "LoadImage -> Could not load image: %s at path='%s'\n", IMG_GetError(), filename.c_str() );
122 return NULL;
123 }
124
125 //Return the optimized surface
126 return optimized_image;
127}
128
129void CBase::ApplyImage( int16_t x, int16_t y, SDL_Surface* src, SDL_Surface* dst, SDL_Rect* clip )
130{
131 // Holds offsets
132 SDL_Rect offset;
133
134 // Get offsets
135 offset.x = x;
136 offset.y = y;
137
138 // Blit
139 SDL_BlitSurface( src, clip, dst, &offset );
140}
141
142bool CBase::CheckRectCollision( SDL_Rect* boxA, SDL_Rect* boxB )
143{
144 // The sides of the SDL_Rects
145 int16_t leftA, leftB;
146 int16_t rightA, rightB;
147 int16_t topA, topB;
148 int16_t bottomA, bottomB;
149
150 // Calculate the sides of rec mCollisionbox
151 leftA = boxB->x;
152 rightA = boxB->x + boxB->w;
153 topA = boxB->y;
154 bottomA = boxB->y + boxB->h;
155
156 // Calculate the sides of rec box
157 leftB = boxA->x;
158 rightB = boxA->x + boxA->w;
159 topB = boxA->y;
160 bottomB = boxA->y + boxA->h;
161
162 // If any of the sides from mCollisionbox are outside of box
163 if (bottomA <= topB) return false;
164 if (topA >= bottomB) return false;
165 if (rightA <= leftB) return false;
166 if (leftA >= rightB) return false;
167 // If none of the sides from mCollisionbox are outside box
168 return true; // Collision has occured
169}
170
171void CBase::SplitString( const std::string& delimiter, const std::string& text, vector<string>& array )
172{
173 string::size_type pos1, pos2;
174 string value;
175
176 array.clear();
177
178 pos1 = text.find( delimiter, 0 );
179 if (pos1 == string::npos)
180 {
181 pos1 = text.length();
182 }
183 value = text.substr( 0, pos1 );
184 array.push_back(value);
185
186 pos2 = pos1;
187
188 do {
189 pos1 = text.find( delimiter, pos2 );
190
191 if (pos1 != string::npos)
192 {
193 pos2 = text.find( delimiter, pos1+1 );
194 if (pos2 == string::npos)
195 {
196 pos2 = text.length();
197 }
198
199 value = text.substr( pos1+1, pos2-pos1-1 );
200 array.push_back(value);
201 }
202 } while (pos1 != string::npos);
203}
204
205bool CBase::UnprefixString( string& result, const string& line, const string& prefix )
206{
207 string::size_type pos;
208
209 pos = line.find(prefix, 0);
210 if (pos == 0)
211 {
212 // Remove the prefix
213 pos = line.find("=", 0) + 1;
214 result = line.substr(pos, line.length()-pos);
215 // Remove any comments
216 pos = result.find("#", 0);
217 result = result.substr(0, pos);
218 // Trim left and right white spaces
219 result.erase( result.begin(), std::find_if(result.begin(), result.end(), std::not1(std::ptr_fun<int, int>(std::isspace))) );
220 result.erase( std::find_if(result.rbegin(), result.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), result.end() );
221
222 return true;
223 }
224 return false;
225}
226
227int16_t CBase::CheckExtension( const string& filename, const string& ext )
228{
229 int16_t result;
230 string::size_type pos;
231
232 pos = filename.length() - ext.length();
233 result = lowercase(filename).find( lowercase(ext), pos);
234
235 return result;
236}
237
238void CBase::CheckPath( string& path )
239{
240 if (path.length()>1)
241 {
242 if (path.at(path.length()-1) != '/')
243 {
244 path += '/';
245 }
246 }
247 else
248 {
249 Log( "Warning: CheckPath path too short\n" );
250 }
251}
252
253string CBase::cmdclean( string& cmdline )
254{
255 string spchars = "\\`$();|{}&'\"*?<>[]!^~-#\n\r ";
256 for (uint i=0; i<spchars.length(); i++)
257 {
258 string curchar = spchars.substr(i,1);
259 cmdline = strreplace(cmdline, curchar, "\\"+curchar);
260 }
261 return cmdline;
262}
263
264string CBase::strreplace( string& orig, const string& search, const string& replace )
265{
266 string::size_type pos = orig.find( search, 0 );
267 while (pos != string::npos)
268 {
269 orig.replace(pos,search.length(),replace);
270 pos = orig.find( search, pos+replace.length() );
271 }
272 return orig;
273}
274
275SDL_Surface* CBase::ScaleSurface( SDL_Surface *surface, uint16_t width, uint16_t height )
276{
277 if(!surface || !width || !height)
278 return 0;
279
280 SDL_Surface *_ret = SDL_CreateRGBSurface(surface->flags, width, height, surface->format->BitsPerPixel,
281 surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
282
283 double _stretch_factor_x = ( static_cast<double>(width) / static_cast<double>(surface->w) ),
284 _stretch_factor_y = ( static_cast<double>(height) / static_cast<double>(surface->h) );
285
286 for (int32_t y = 0; y < surface->h; y++)
287 for (int32_t x = 0; x < surface->w; x++)
288 for (int32_t o_y = 0; o_y < _stretch_factor_y; ++o_y)
289 for (int32_t o_x = 0; o_x < _stretch_factor_x; ++o_x)
290 putpixel( _ret, static_cast<int32_t>(_stretch_factor_x * x) + o_x,
291 static_cast<int32_t>(_stretch_factor_y * y) + o_y, getpixel(surface, x, y) );
292
293 return _ret;
294}
295
296uint32_t CBase::getpixel( SDL_Surface *surface, int16_t x, int16_t y )
297{
298 int16_t bpp = surface->format->BytesPerPixel;
299 /* Here p is the address to the pixel we want to retrieve */
300 uint8_t *p = (uint8_t *)surface->pixels + y * surface->pitch + x * bpp;
301
302 switch (bpp) {
303 case 1:
304 return *p;
305 break;
306
307 case 2:
308 return *(uint16_t *)p;
309 break;
310
311 case 3:
312 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
313 return p[0] << 16 | p[1] << 8 | p[2];
314 else
315 return p[0] | p[1] << 8 | p[2] << 16;
316 break;
317
318 case 4:
319 return *(uint32_t *)p;
320 break;
321
322 default:
323 return 0; /* shouldn't happen, but avoids warnings */
324 }
325}
326
327void CBase::putpixel( SDL_Surface *surface, int16_t x, int16_t y, uint32_t pixel )
328{
329 int16_t bpp = surface->format->BytesPerPixel;
330 /* Here p is the address to the pixel we want to set */
331 uint8_t *p = (uint8_t *)surface->pixels + y * surface->pitch + x * bpp;
332
333 switch (bpp) {
334 case 1:
335 *p = pixel;
336 break;
337
338 case 2:
339 *(uint16_t *)p = pixel;
340 break;
341
342 case 3:
343 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
344 p[0] = (pixel >> 16) & 0xff;
345 p[1] = (pixel >> 8) & 0xff;
346 p[2] = pixel & 0xff;
347 } else {
348 p[0] = pixel & 0xff;
349 p[1] = (pixel >> 8) & 0xff;
350 p[2] = (pixel >> 16) & 0xff;
351 }
352 break;
353
354 case 4:
355 default:
356 *(uint32_t *)p = pixel;
357 break;
358 }
359}