1 #include <iostream>
2 #include <algorithm>
3 #include <string>
4 #include "graphics.hpp"
5
6 #include <boost/regex.hpp>
7 #include <boost/lexical_cast.hpp>
8
9 #include "controls.hpp"
10 #include "difficulty.hpp"
11 #include "filesystem.hpp"
12 #include "formatter.hpp"
13 #include "formula_callable.hpp"
14 #include "game_registry.hpp"
15 #include "json_parser.hpp"
16 #include "module.hpp"
17 #include "preferences.hpp"
18 #include "sound.hpp"
19 #include "sys.hpp"
20 #include "variant_utils.hpp"
21
22 #include <time.h>
23
24 #define SAVE_FILENAME "save.cfg"
25 #define AUTOSAVE_FILENAME "autosave.cfg"
26
27 #ifdef _WINDOWS
28 #define WIN32_LEAN_AND_MEAN
29 #include <windows.h>
30 #include <shlobj.h>
31 #include <shlwapi.h>
32
33 class WindowsPrefs
34 {
35 public:
GetPreferencePath()36 std::string GetPreferencePath() { if (State* i = Instance()) return i->GetPreferencePath(); }
GetSaveFilePath()37 std::string GetSaveFilePath() { if (State* i = Instance()) return i->GetSaveFilePath(); }
GetAutoSaveFilePath()38 std::string GetAutoSaveFilePath() { if (State* i = Instance()) return i->GetAutoSaveFilePath(); }
39
40 private:
41 struct State
42 {
43 private:
44 std::string preferences_path;
45 std::string save_file_path;
46 std::string auto_save_file_path;
47 public:
State()48 State::State()
49 {
50 this->preferences_path = GetAppDataPath() + "/" + module::get_module_name() + "/";
51 this->save_file_path = this->preferences_path + SAVE_FILENAME;
52 this->auto_save_file_path = this->preferences_path + AUTOSAVE_FILENAME;
53 }
GetPreferencePathWindowsPrefs::State54 std::string GetPreferencePath()
55 {
56 return this->preferences_path;
57 };
58
GetSaveFilePathWindowsPrefs::State59 std::string GetSaveFilePath()
60 {
61 return this->save_file_path;
62 }
63
GetAutoSaveFilePathWindowsPrefs::State64 std::string GetAutoSaveFilePath()
65 {
66 return this->auto_save_file_path;
67 }
68 };
69
70 static State* Instance();
71 static void CleanUp();
72
73 static bool MDestroyed;
74 static State* MInstance;
75 };
76
GetAppDataPath()77 std::string GetAppDataPath() {
78 char szPath[ MAX_PATH ];
79 if(SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, szPath)))
80 {
81 return std::string(szPath);
82 }
83 return std::string();
84 }
85
86 bool WindowsPrefs::MDestroyed = false;
87 WindowsPrefs::State* WindowsPrefs::MInstance = 0;
88
Instance()89 WindowsPrefs::State* WindowsPrefs::Instance()
90 {
91 if( !MDestroyed && !MInstance ) {
92 MInstance = new State();
93 atexit( &CleanUp );
94 }
95 return MInstance;
96 }
97
CleanUp()98 void WindowsPrefs::CleanUp()
99 {
100 delete MInstance;
101 MInstance = 0;
102 MDestroyed = true;
103 }
104
105 WindowsPrefs winPrefs;
106 #endif // _WINDOWS
107
108
109 namespace preferences {
version()110 const std::string& version() {
111 static const std::string Version = "1.3";
112 return Version;
113 }
114
version_decimal()115 const variant& version_decimal() {
116 static const variant versiond = variant(decimal::from_string(version()));
117 return versiond;
118 }
119
120 namespace {
121 int unique_user_id = 0;
122
123 int screen_editor_mode = 0;
124
125 bool no_sound_ = false;
126 bool no_music_ = false;
127 bool show_debug_hitboxes_ = false;
128 bool show_iphone_controls_ = false;
129 bool use_pretty_scaling_ = false;
130 bool fullscreen_ = false;
131 bool resizable_ = false;
132 bool proportional_resize_ = false;
133 bool debug_ = true;
134 bool reverse_ab_ = false;
135 bool show_fps_ = false;
136 int frame_time_millis_ = 20;
137 bool no_iphone_controls_ = false;
138 bool allow_autopause_ = false;
139
140 std::string level_path_ = "data/level/";
141 bool level_path_set_ = false;
142
143 bool relay_through_server_ = false;
144
145 std::string control_scheme_ = "iphone_2d";
146
147 bool record_history_ = false;
148
149 bool edit_on_start_ = false;
150
151 variant external_code_editor_;
152
153 int force_difficulty_ = INT_MIN;
154
155 uri::uri tbs_uri_ = uri::uri::parse("http://localhost:23456");
156
157 std::string username_;
158 std::string password_;
159
160 #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
161
162 #ifndef PREFERENCES_PATH
163 #define PREFERENCES_PATH "../Documents/"
164 #endif
165 bool send_stats_ = false;
166
167 bool sim_iphone_ = true;
168
169 int virtual_screen_width_ = 960;
170 int virtual_screen_height_ = 640;
171
172 int actual_screen_width_ = 320;
173 int actual_screen_height_ = 480;
174
175 bool screen_rotated_ = true;
176
177 bool use_joystick_ = false;
178
179 bool load_compiled_ = true;
180
181 bool use_16bpp_textures_ = false;
182 #elif defined(TARGET_OS_HARMATTAN)
183
184 bool send_stats_ = false;
185
186 bool sim_iphone_ = false;
187
188 #ifndef PREFERENCES_PATH
189 #define PREFERENCES_PATH "~/.frogatto/"
190 #endif
191 int virtual_screen_width_ = 854;
192 int virtual_screen_height_ = 480;
193
194 int actual_screen_width_ = 854;
195 int actual_screen_height_ = 480;
196
197 bool screen_rotated_ = false;
198
199 bool use_joystick_ = true;
200
201 bool load_compiled_ = true;
202
203 bool use_fbo_ = true;
204 bool use_bequ_ = true;
205
206 bool use_16bpp_textures_ = true;
207 #elif defined(__ANDROID__)
208
209 #ifndef PREFERENCES_PATH
210 #define PREFERENCES_PATH ".frogatto/"
211 #endif
212
213 bool send_stats_ = false;
214 bool sim_iphone_ = false;
215 int virtual_screen_width_ = 800;
216 int virtual_screen_height_ = 480;
217
218 int actual_screen_width_ = 800;
219 int actual_screen_height_ = 480;
220
221 bool screen_rotated_ = false;
222
223 bool use_joystick_ = true;
224
225 bool load_compiled_ = true;
226
227 bool use_fbo_ = true;
228 bool use_bequ_ = true;
229
230 bool use_16bpp_textures_ = true;
231 #elif defined(TARGET_BLACKBERRY)
232
233 #ifndef PREFERENCES_PATH
234 #define PREFERENCES_PATH "~/.frogatto/"
235 #endif
236 bool send_stats_ = true;
237 bool sim_iphone_ = false;
238 bool use_joystick_ = true;
239 bool screen_rotated_ = false;
240 int virtual_screen_width_ = 1024;
241 int virtual_screen_height_ = 600;
242 int actual_screen_width_ = 1024;
243 int actual_screen_height_ = 600;
244 bool load_compiled_ = true;
245 bool use_fbo_ = true;
246 bool use_bequ_ = true;
247 bool use_16bpp_textures_ = false;
248
249 #else
250
251 #if defined(_WINDOWS)
252 #define PREFERENCES_PATH ""
253 #endif // _WINDOWS
254
255 #ifndef NO_UPLOAD_STATS
256 bool send_stats_ = true;
257 #else
258 bool send_stats_ = false;
259 #endif
260
261 bool sim_iphone_ = false;
262
263 #ifndef PREFERENCES_PATH
264 #define PREFERENCES_PATH "~/.frogatto/"
265 #endif
266 bool screen_rotated_ = false;
267
268 bool use_joystick_ = true;
269
270 #if defined(TARGET_TEGRA)
271 int virtual_screen_width_ = 1024;
272 int virtual_screen_height_ = 600;
273
274 int actual_screen_width_ = 1024;
275 int actual_screen_height_ = 600;
276
277 bool load_compiled_ = true;
278 bool use_fbo_ = true;
279 bool use_bequ_ = true;
280 #else
281 int virtual_screen_width_ = 800;
282 int virtual_screen_height_ = 600;
283
284 int actual_screen_width_ = 800;
285 int actual_screen_height_ = 600;
286
287 bool load_compiled_ = false;
288 #endif
289
290 #if defined(TARGET_PANDORA)
291 bool use_fbo_ = true;
292 bool use_bequ_ = true;
293 #endif
294
295 bool use_16bpp_textures_ = false;
296 #endif
297
298 std::string preferences_path_ = PREFERENCES_PATH;
299 std::string save_file_path_ = PREFERENCES_PATH SAVE_FILENAME;
300 std::string auto_save_file_path_ = PREFERENCES_PATH AUTOSAVE_FILENAME;
301
302 #ifdef __APPLE__
303 #include "TargetConditionals.h"
304 #if TARGET_OS_MAC
305 bool editor_save_to_user_preferences_ = true;
306 #endif
307 #else
308 bool editor_save_to_user_preferences_ = false;
309 #endif
310
311 bool force_no_npot_textures_ = false;
312
313 bool run_failing_unit_tests_ = false;
314 bool serialize_bad_objects_ = false;
315 }
316
get_unique_user_id()317 int get_unique_user_id() {
318 if(unique_user_id == 0) {
319 time_t t1;
320 time(&t1);
321 int tm = t1;
322 unique_user_id = tm^rand();
323 }
324
325 return unique_user_id;
326 }
327
328 int xypos_draw_mask = actual_screen_width_ < virtual_screen_width_ ? ~1 : ~0;
double_scale()329 bool double_scale() {
330 return xypos_draw_mask&1;
331 }
332 bool compiling_tiles = false;
333
334 namespace {
recalculate_draw_mask()335 void recalculate_draw_mask() {
336 xypos_draw_mask = actual_screen_width_ < virtual_screen_width_ ? ~1 : ~0;
337 }
338 }
339
no_sound()340 bool no_sound() {
341 return no_sound_;
342 }
343
no_music()344 bool no_music() {
345 return no_music_;
346 }
347
setup_preferences_dir()348 bool setup_preferences_dir()
349 {
350 return !sys::get_dir(user_data_path()).empty();
351 }
352
set_preferences_path_from_module(const std::string & name)353 void set_preferences_path_from_module( const std::string& name)
354 {
355 #ifdef _WINDOWS
356 preferences::set_preferences_path(GetAppDataPath() + "/" + name + "/");
357 #elif defined(__ANDROID__)
358 preferences::set_preferences_path("." + name + "/");
359 #elif __APPLE__
360 #include "TargetConditionals.h"
361 #if TARGET_OS_MAC
362 preferences::set_preferences_path("~/Library/Application Support/" + name + "/");
363 //preferences::set_preferences_path(std::string(getenv("HOME")) + "/Library/Application Support/" + name + "/");
364 #endif
365 #else
366 preferences::set_preferences_path("~/." + name + "/");
367 #endif
368 save_file_path_ = preferences_path_ + SAVE_FILENAME;
369 auto_save_file_path_ = preferences_path_ + AUTOSAVE_FILENAME;
370 }
371
set_preferences_path(const std::string & path)372 void set_preferences_path(const std::string& path)
373 {
374 std::cerr << "SET PREFERENCES PATH: " << path << "\n";
375 preferences_path_ = path;
376 if(preferences_path_[preferences_path_.length()-1] != '/') {
377 preferences_path_ += '/';
378 }
379
380 save_file_path_ = preferences_path_ + SAVE_FILENAME;
381 auto_save_file_path_ = preferences_path_ + AUTOSAVE_FILENAME;
382 }
383
level_path()384 const std::string& level_path() {
385 return level_path_;
386 }
387
is_level_path_set()388 bool is_level_path_set() {
389 return level_path_set_;
390 }
391
save_file_path()392 const char *save_file_path() {
393 std::cerr << "GET SAVE FILE PATH: " << save_file_path_ << std::endl;
394 return save_file_path_.c_str();
395 }
396
auto_save_file_path()397 const char *auto_save_file_path() {
398 std::cerr << "GET AUTOSAVE FILE PATH: " << auto_save_file_path_ << std::endl;
399 return auto_save_file_path_.c_str();
400 }
401
user_data_path()402 const char *user_data_path() {
403 return preferences_path_.c_str();
404 }
405
editor_save_to_user_preferences()406 bool editor_save_to_user_preferences() {
407 return editor_save_to_user_preferences_;
408 }
409
410 namespace {
expand_path(std::string & str)411 void expand_path(std::string& str) {
412 if(!str.empty() && str[0] == '~') {
413 #if defined(TARGET_PANDORA)
414 str = std::string(getenv("PWD")) + std::string(str.begin()+1, str.end());
415 #else
416 str = std::string(getenv("HOME")) + std::string(str.begin()+1, str.end());
417 #endif
418 }
419 }
420 }
421
dlc_path()422 std::string dlc_path() {
423 std::string result(std::string(PREFERENCES_PATH) + "/dlc");
424 expand_path(result);
425 return result;
426 }
427
expand_data_paths()428 void expand_data_paths() {
429 expand_path(level_path_);
430 expand_path(save_file_path_);
431 expand_path(auto_save_file_path_);
432 expand_path(preferences_path_);
433 std::cerr << "EXPAND DATA PATHS\n";
434 }
435
set_save_slot(const std::string & fname)436 void set_save_slot(const std::string& fname) {
437 save_file_path_ = std::string(user_data_path()) + fname;
438 std::cerr << "SET SAVE FILE PATH TO " << save_file_path_ << "\n";
439 }
440
show_debug_hitboxes()441 bool show_debug_hitboxes() {
442 return show_debug_hitboxes_;
443 }
444
toogle_debug_hitboxes()445 bool toogle_debug_hitboxes() {
446 bool shown = show_debug_hitboxes_;
447 show_debug_hitboxes_ = !show_debug_hitboxes_;
448 return shown;
449 }
450
show_iphone_controls()451 bool show_iphone_controls() {
452 return show_iphone_controls_;
453 }
454
use_pretty_scaling()455 bool use_pretty_scaling() {
456 return use_pretty_scaling_;
457 }
458
set_use_pretty_scaling(bool value)459 void set_use_pretty_scaling(bool value) {
460 use_pretty_scaling_ = value;
461 }
462
fullscreen()463 bool fullscreen() {
464 return fullscreen_;
465 }
466
set_fullscreen(bool value)467 void set_fullscreen(bool value) {
468 fullscreen_ = value;
469 }
470
resizable()471 bool resizable() {
472 return resizable_;
473 }
474
no_iphone_controls()475 bool no_iphone_controls() {
476 return no_iphone_controls_;
477 }
478
proportional_resize()479 bool proportional_resize() {
480 return proportional_resize_;
481 }
482
reverse_ab()483 bool reverse_ab() {
484 return reverse_ab_;
485 }
486
set_reverse_ab(bool value)487 void set_reverse_ab(bool value) {
488 reverse_ab_ = value;
489 }
490
control_scheme()491 const std::string& control_scheme()
492 {
493 return control_scheme_;
494 }
495
set_control_scheme(const std::string & scheme)496 void set_control_scheme(const std::string& scheme)
497 {
498 control_scheme_ = scheme;
499 }
500
set_widescreen()501 void set_widescreen()
502 {
503 virtual_screen_width_ = (virtual_screen_height_*16)/9;
504 actual_screen_width_ = (actual_screen_height_*16)/9;
505 recalculate_draw_mask();
506 }
507
virtual_screen_width()508 int virtual_screen_width()
509 {
510 return virtual_screen_width_;
511 }
512
virtual_screen_height()513 int virtual_screen_height()
514 {
515 return virtual_screen_height_;
516 }
517
set_virtual_screen_width(int width)518 void set_virtual_screen_width (int width)
519 {
520 virtual_screen_width_ = width;
521 recalculate_draw_mask();
522 }
523
set_virtual_screen_height(int height)524 void set_virtual_screen_height (int height)
525 {
526 virtual_screen_height_ = height;
527 }
528
actual_screen_width()529 int actual_screen_width()
530 {
531 return actual_screen_width_;
532 }
533
actual_screen_height()534 int actual_screen_height()
535 {
536 return actual_screen_height_;
537 }
538
set_actual_screen_width(int width)539 void set_actual_screen_width(int width)
540 {
541 actual_screen_width_ = width;
542 if(screen_editor_mode) {
543 virtual_screen_width_ = actual_screen_width_;
544 }
545 recalculate_draw_mask();
546 }
547
set_actual_screen_height(int height)548 void set_actual_screen_height(int height)
549 {
550 actual_screen_height_ = height;
551 if(screen_editor_mode) {
552 virtual_screen_height_ = actual_screen_height_;
553 }
554 }
555
load_compiled()556 bool load_compiled()
557 {
558 return load_compiled_;
559 }
560
set_load_compiled(bool value)561 void set_load_compiled(bool value)
562 {
563 load_compiled_ = value;
564 }
565
allow_autopause()566 bool allow_autopause()
567 {
568 return allow_autopause_;
569 }
570
edit_on_start()571 bool edit_on_start()
572 {
573 return edit_on_start_;
574 }
575
set_edit_on_start(bool value)576 void set_edit_on_start(bool value)
577 {
578 edit_on_start_ = value;
579 }
580
get_tbs_uri()581 uri::uri get_tbs_uri()
582 {
583 return tbs_uri_;
584 }
585
get_username()586 std::string get_username()
587 {
588 return username_;
589 }
590
get_password()591 std::string get_password()
592 {
593 return password_;
594 }
595
596 #if defined(TARGET_OS_HARMATTAN) || defined(TARGET_PANDORA) || defined(TARGET_TEGRA) || defined(TARGET_BLACKBERRY)
use_fbo()597 bool use_fbo()
598 {
599 return use_fbo_;
600 }
601
use_bequ()602 bool use_bequ()
603 {
604 return use_bequ_;
605 }
606
set_fbo(bool value)607 void set_fbo( bool value )
608 {
609 use_fbo_ = value;
610 }
611
set_bequ(bool value)612 void set_bequ( bool value )
613 {
614 use_bequ_ = value;
615 }
616 #endif
617
force_no_npot_textures()618 bool force_no_npot_textures()
619 {
620 return force_no_npot_textures_;
621 }
622
screen_rotated()623 bool screen_rotated()
624 {
625 return screen_rotated_;
626 }
627
debug()628 bool debug()
629 {
630 return debug_;
631 }
632
show_fps()633 bool show_fps()
634 {
635 return show_fps_;
636 }
637
frame_time_millis()638 int frame_time_millis()
639 {
640 return frame_time_millis_;
641 }
642
use_joystick()643 bool use_joystick()
644 {
645 return use_joystick_;
646 }
647
registry()648 game_logic::formula_callable* registry()
649 {
650 return &game_registry::instance();
651 }
652
load_preferences()653 void load_preferences()
654 {
655 std::string path;
656 if(preferences_path_.empty()) {
657 #if defined( _WINDOWS )
658 preferences_path_ = winPrefs.GetPreferencePath();
659 save_file_path_ = winPrefs.GetSaveFilePath();
660 auto_save_file_path_ = winPrefs.GetAutoSaveFilePath();
661 path = preferences_path_;
662 #else
663 path = PREFERENCES_PATH;
664 #endif // defined( _WINDOWS )
665 } else {
666 path = preferences_path_;
667 }
668 expand_path(path);
669 if(!sys::file_exists(path + "preferences.cfg")) {
670 return;
671 }
672
673 variant node;
674
675 try {
676 node = json::parse_from_file(path + "preferences.cfg");
677 } catch(json::parse_error&) {
678 return;
679 }
680
681 unique_user_id = node["user_id"].as_int(0);
682
683 use_joystick_ = node["joystick"].as_bool(use_joystick_);
684 variant show_control_rects = node["show_iphone_controls"];
685 if(show_control_rects.is_null() == false) {
686 show_iphone_controls_ = show_control_rects.as_bool(show_iphone_controls_);
687 }
688
689 no_sound_ = node["no_sound"].as_bool(no_sound_);
690 no_music_ = node["no_music"].as_bool(no_music_);
691 reverse_ab_ = node["reverse_ab"].as_bool(reverse_ab_);
692 allow_autopause_ = node["allow_autopause"].as_bool(allow_autopause_);
693
694 sound::set_music_volume(node["music_volume"].as_int(1000)/1000.0);
695 sound::set_sound_volume(node["sound_volume"].as_int(1000)/1000.0);
696
697 const variant registry_node = node["registry"];
698 if(registry_node.is_null() == false) {
699 game_registry::instance().set_contents(registry_node);
700 }
701
702 if(node["code_editor"].is_map()) {
703 external_code_editor_ = node["code_editor"];
704 }
705
706 #if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
707 controls::set_sdlkey(controls::CONTROL_UP, static_cast<SDLKey>(node["key_up"].as_int(SDLK_UP)));
708 controls::set_sdlkey(controls::CONTROL_DOWN, static_cast<SDLKey>(node["key_down"].as_int(SDLK_DOWN)));
709 controls::set_sdlkey(controls::CONTROL_LEFT, static_cast<SDLKey>(node["key_left"].as_int(SDLK_LEFT)));
710 controls::set_sdlkey(controls::CONTROL_RIGHT, static_cast<SDLKey>(node["key_right"].as_int(SDLK_RIGHT)));
711 controls::set_sdlkey(controls::CONTROL_ATTACK, static_cast<SDLKey>(node["key_attack"].as_int(SDLK_d)));
712 controls::set_sdlkey(controls::CONTROL_JUMP, static_cast<SDLKey>(node["key_jump"].as_int(SDLK_a)));
713 controls::set_sdlkey(controls::CONTROL_TONGUE, static_cast<SDLKey>(node["key_tongue"].as_int(SDLK_s)));
714 #endif
715 }
716
save_preferences()717 void save_preferences()
718 {
719 variant_builder node;
720 node.add("user_id", get_unique_user_id());
721 node.add("no_sound", variant::from_bool(no_sound_));
722 node.add("no_music", variant::from_bool(no_music_));
723 node.add("allow_autopause", variant::from_bool(allow_autopause_));
724 node.add("reverse_ab", variant::from_bool(reverse_ab_));
725 node.add("joystick", variant::from_bool(use_joystick_));
726 node.add("sound_volume", static_cast<int>(sound::get_sound_volume()*1000));
727 node.add("music_volume", static_cast<int>(sound::get_music_volume()*1000));
728 node.add("key_up", controls::get_sdlkey(controls::CONTROL_UP));
729 node.add("key_down", controls::get_sdlkey(controls::CONTROL_DOWN));
730 node.add("key_left", controls::get_sdlkey(controls::CONTROL_LEFT));
731 node.add("key_right", controls::get_sdlkey(controls::CONTROL_RIGHT));
732 node.add("key_attack", controls::get_sdlkey(controls::CONTROL_ATTACK));
733 node.add("key_jump", controls::get_sdlkey(controls::CONTROL_JUMP));
734 node.add("key_tongue", controls::get_sdlkey(controls::CONTROL_TONGUE));
735 node.add("show_iphone_controls", variant::from_bool(show_iphone_controls_));
736
737 if(external_code_editor_.is_null() == false) {
738 node.add("code_editor", external_code_editor_);
739 }
740
741 node.add("registry", game_registry::instance().write_contents());
742
743 std::cerr << "WRITE PREFS: " << (preferences_path_ + "preferences.cfg") << std::endl;
744 sys::write_file(preferences_path_ + "preferences.cfg", node.build().write_json());
745 }
746
editor_screen_size_scope()747 editor_screen_size_scope::editor_screen_size_scope() : width_(virtual_screen_width_), height_(virtual_screen_height_) {
748 ++screen_editor_mode;
749 virtual_screen_width_ = actual_screen_width_;
750 virtual_screen_height_ = actual_screen_height_;
751 }
752
~editor_screen_size_scope()753 editor_screen_size_scope::~editor_screen_size_scope() {
754 virtual_screen_width_ = width_;
755 virtual_screen_height_ = height_;
756 --screen_editor_mode;
757 }
758
parse_arg(const char * arg)759 bool parse_arg(const char* arg) {
760 const std::string s(arg);
761
762 std::string arg_name, arg_value;
763 std::string::const_iterator equal = std::find(s.begin(), s.end(), '=');
764 if(equal != s.end()) {
765 arg_name = std::string(s.begin(), equal);
766 arg_value = std::string(equal+1, s.end());
767 }
768
769 if(arg_name == "--level-path") {
770 level_path_ = arg_value + "/";
771 level_path_set_ = true;
772 } else if(s == "--editor_save_to_user_preferences") {
773 editor_save_to_user_preferences_ = true;
774 } else if(s == "--show-hitboxes") {
775 show_debug_hitboxes_ = true;
776 } else if(s == "--show-controls") {
777 show_iphone_controls_ = true;
778 } else if(s == "--scale") {
779 set_use_pretty_scaling(true);
780 } else if(s == "--no-sound") {
781 no_sound_ = true;
782 } else if(s == "--no-music") {
783 no_music_ = true;
784 } else if(s == "--sound") {
785 no_sound_ = false;
786 } else if(s == "--music") {
787 no_music_ = false;
788 } else if(s == "--fullscreen") {
789 fullscreen_ = true;
790 } else if(s == "--windowed") {
791 fullscreen_ = false;
792 } else if(s == "--proportional-resize") {
793 resizable_ = true;
794 proportional_resize_ = true;
795 } else if(s == "--resizable") {
796 resizable_ = true;
797 } else if(s == "--no-resizable") {
798 resizable_ = false;
799 } else if(s == "--widescreen") {
800 set_widescreen();
801 } else if(s == "--bigscreen") {
802 virtual_screen_width_ = actual_screen_width_;
803 virtual_screen_height_ = actual_screen_height_;
804 } else if(s == "--potonly") {
805 force_no_npot_textures_ = true;
806 } else if(s == "--textures16") {
807 use_16bpp_textures_ = true;
808 } else if(s == "--textures32") {
809 use_16bpp_textures_ = false;
810 } else if(arg_name == "--textures32_if_kb_memory_at_least") {
811 const int memory_required = atoi(arg_value.c_str());
812 sys::available_memory_info mem_info;
813 const bool result = sys::get_available_memory(&mem_info);
814 if(result) {
815 use_16bpp_textures_ = mem_info.mem_total_kb < memory_required;
816 std::cerr << "USING " << (use_16bpp_textures_ ? 16 : 32) << "bpp TEXTURES BECAUSE SYSTEM HAS " << mem_info.mem_total_kb << "KB AND " << memory_required << "KB REQUIRED FOR 32bpp TEXTURES\n";
817 } else {
818 use_16bpp_textures_ = true;
819 std::cerr << "USING 16bpp TEXTURES BECAUSE WE COULD NOT DISCOVER HOW MUCH MEMORY THE SYSTEM HAS\n";
820 }
821 } else if(s == "--debug") {
822 debug_ = true;
823 } else if(s == "--no-debug") {
824 debug_ = false;
825 } else if(s == "--simiphone") {
826 sim_iphone_ = true;
827
828 virtual_screen_width_ = 960;
829 virtual_screen_height_ = 640;
830
831 actual_screen_width_ = 480;
832 actual_screen_height_ = 320;
833 use_16bpp_textures_ = true;
834
835 recalculate_draw_mask();
836 } else if(s == "--simipad") {
837 sim_iphone_ = true;
838 control_scheme_ = "ipad_2d";
839
840 virtual_screen_width_ = 1024;
841 virtual_screen_height_ = 768;
842
843 actual_screen_width_ = 1024;
844 actual_screen_height_ = 768;
845
846 recalculate_draw_mask();
847 } else if(s == "--no-iphone-controls") {
848 no_iphone_controls_ = true;
849 } else if(s == "--wvga") {
850 virtual_screen_width_ = 800;
851 virtual_screen_height_ = 480;
852
853 actual_screen_width_ = 800;
854 actual_screen_height_ = 480;
855
856 recalculate_draw_mask();
857 } else if(s == "--native") {
858 virtual_screen_width_ = (actual_screen_width_) * 2;
859 virtual_screen_height_ = (actual_screen_height_) * 2;
860 recalculate_draw_mask();
861 } else if(s == "--fps") {
862 show_fps_ = true;
863 } else if(s == "--no-fps") {
864 show_fps_ = false;
865 } else if(arg_name == "--set-fps" && !arg_value.empty()) {
866 frame_time_millis_ = 1000/boost::lexical_cast<int, std::string>(arg_value);
867 std::cerr << "FPS: " << arg_value << " = " << frame_time_millis_ << "ms/frame\n";
868 } else if(arg_name == "--config-path" && !arg_value.empty()) {
869 set_preferences_path(arg_value);
870 } else if(s == "--send-stats") {
871 send_stats_ = true;
872 } else if(s == "--no-send-stats") {
873 send_stats_ = false;
874 } else if(s == "--time-travel") {
875 record_history_ = true;
876 } else if(s == "--joystick") {
877 use_joystick_ = true;
878 } else if(s == "--no-joystick") {
879 use_joystick_ = false;
880 } else if(arg_name == "--server") {
881 tbs_uri_ = uri::uri::parse(arg_value);
882 } else if(arg_name == "--user") {
883 username_ = arg_value;
884 } else if(arg_name == "--pass") {
885 password_ = arg_value;
886 } else if(s == "--relay") {
887 relay_through_server_ = true;
888 } else if(s == "--failing-tests") {
889 run_failing_unit_tests_ = true;
890 } else if(s == "--serialize-bad-objects") {
891 serialize_bad_objects_ = true;
892 } else if(s == "--no-autopause") {
893 allow_autopause_ = false;
894 } else if(s == "--autopause") {
895 allow_autopause_ = true;
896 } else if(arg_name == "--difficulty" && !arg_value.empty()) {
897 if(boost::regex_match(arg_value, boost::regex("-?[0-9]+"))) {
898 force_difficulty_ = boost::lexical_cast<int>(arg_value);
899 } else {
900 force_difficulty_ = difficulty::from_string(arg_value);
901 }
902 } else {
903 return false;
904 }
905
906 return true;
907 }
908
use_16bpp_textures()909 bool use_16bpp_textures() {
910 return use_16bpp_textures_;
911 }
912
sim_iphone()913 bool sim_iphone() {
914 return sim_iphone_;
915 }
916
send_stats()917 bool send_stats() {
918 return send_stats_;
919 }
920
force_difficulty()921 int force_difficulty() {
922 return force_difficulty_;
923 }
924
record_history()925 bool record_history() {
926 return record_history_;
927 }
928
set_record_history(bool value)929 void set_record_history(bool value) {
930 record_history_ = value;
931 }
932
relay_through_server()933 bool relay_through_server() {
934 return relay_through_server_;
935 }
936
external_code_editor()937 variant external_code_editor() {
938 return external_code_editor_;
939 }
940
set_relay_through_server(bool value)941 void set_relay_through_server(bool value) {
942 relay_through_server_ = value;
943 }
944
run_failing_unit_tests()945 bool run_failing_unit_tests() {
946 return run_failing_unit_tests_;
947 }
948
serialize_bad_objects()949 bool serialize_bad_objects() {
950 return serialize_bad_objects_;
951 }
952
953 #if defined(TARGET_OS_HARMATTAN) || defined(TARGET_PANDORA) || defined(TARGET_TEGRA) || defined(TARGET_BLACKBERRY)
954 PFNGLBLENDEQUATIONOESPROC glBlendEquationOES;
955 PFNGLGENFRAMEBUFFERSOESPROC glGenFramebuffersOES;
956 PFNGLBINDFRAMEBUFFEROESPROC glBindFramebufferOES;
957 PFNGLFRAMEBUFFERTEXTURE2DOESPROC glFramebufferTexture2DOES;
958 PFNGLCHECKFRAMEBUFFERSTATUSOESPROC glCheckFramebufferStatusOES;
959
init_oes(void)960 void init_oes( void )
961 {
962 int retry;
963 const GLubyte* pszGLExtensions = NULL;
964
965 glBlendEquationOES = NULL;
966 glGenFramebuffersOES = NULL;
967 glBindFramebufferOES = NULL;
968 glFramebufferTexture2DOES = NULL;
969 glCheckFramebufferStatusOES = NULL;
970
971 /* Retrieve GL extension string */
972 pszGLExtensions = glGetString(GL_EXTENSIONS);
973
974 // Blend subtract Functions
975 if(preferences::use_bequ())
976 {
977 /* GL_OES_framebuffer_object */
978 if (strstr((char *)pszGLExtensions, "GL_OES_blend_subtract"))
979 {
980 for (retry=1; retry<4; retry++)
981 {
982 glBlendEquationOES = (PFNGLBLENDEQUATIONOESPROC)eglGetProcAddress("glBlendEquationOES");
983 if (glBlendEquationOES!=NULL) {
984 std::cerr << "glBlendEquationOES was set correctly\n";
985 break;
986 }
987 else
988 {
989 std::cerr << "glBlendEquationOES was set to NULL by eglGetProcAddress retry #" << retry << "\n";
990 }
991 }
992 }
993 else
994 {
995 glBlendEquationOES = NULL;
996 }
997 }
998 else
999 {
1000 glBlendEquationOES = NULL;
1001 }
1002
1003 // FBO Functions
1004 if(preferences::use_fbo())
1005 {
1006 /* GL_OES_framebuffer_object */
1007 if (strstr((char *)pszGLExtensions, "GL_OES_framebuffer_object"))
1008 {
1009 for (retry=1; retry<4; retry++)
1010 {
1011 glGenFramebuffersOES = (PFNGLGENFRAMEBUFFERSOESPROC)eglGetProcAddress("glGenFramebuffersOES");
1012 if (glGenFramebuffersOES!=NULL) {
1013 std::cerr << "glGenFramebuffersOES was set correctly\n";
1014 break;
1015 }
1016 else
1017 {
1018 std::cerr << "glGenFramebuffersOES was set to NULL by eglGetProcAddress retry #" << retry << "\n";
1019 }
1020 }
1021 for (retry=1; retry<4; retry++)
1022 {
1023 glBindFramebufferOES = (PFNGLBINDFRAMEBUFFEROESPROC)eglGetProcAddress("glBindFramebufferOES");
1024 if (glBindFramebufferOES!=NULL) {
1025 std::cerr << "glBindFramebufferOES was set correctly\n";
1026 break;
1027 }
1028 else
1029 {
1030 std::cerr << "glBindFramebufferOES was set to NULL by eglGetProcAddress retry #" << retry << "\n";
1031 }
1032 }
1033 for (retry=1; retry<4; retry++)
1034 {
1035 glFramebufferTexture2DOES = (PFNGLFRAMEBUFFERTEXTURE2DOESPROC)eglGetProcAddress("glFramebufferTexture2DOES");
1036 if (glFramebufferTexture2DOES!=NULL) {
1037 std::cerr << "glFramebufferTexture2DOES was set correctly\n";
1038 break;
1039 }
1040 else
1041 {
1042 std::cerr << "glFramebufferTexture2DOES was set to NULL by eglGetProcAddress retry #" << retry << "\n";
1043 }
1044 }
1045 for (retry=1; retry<4; retry++)
1046 {
1047 glCheckFramebufferStatusOES = (PFNGLCHECKFRAMEBUFFERSTATUSOESPROC)eglGetProcAddress("glCheckFramebufferStatusOES");
1048 if (glCheckFramebufferStatusOES!=NULL) {
1049 std::cerr << "glCheckFramebufferStatusOES was set correctly\n";
1050 break;
1051 }
1052 else
1053 {
1054 std::cerr << "glCheckFramebufferStatusOES was set to NULL by eglGetProcAddress retry #" << retry << "\n";
1055 }
1056 }
1057 }
1058 else
1059 {
1060 glGenFramebuffersOES = NULL;
1061 glBindFramebufferOES = NULL;
1062 glFramebufferTexture2DOES = NULL;
1063 glCheckFramebufferStatusOES = NULL;
1064 }
1065 }
1066 else
1067 {
1068 glGenFramebuffersOES = NULL;
1069 glBindFramebufferOES = NULL;
1070 glFramebufferTexture2DOES = NULL;
1071 glCheckFramebufferStatusOES = NULL;
1072 }
1073 }
1074 #endif
1075 }
1076