extern "C" int main(int argcount, char* argvec[]) #endif { { std::vector<std::string> args; for(int i = 0; i != argcount; ++i) { args.push_back(argvec[i]); } preferences::set_argv(args); } #if defined(__native_client__) std::cerr << "Running game_main" << std::endl; chdir("/frogatto"); { char buf[256]; const char* const res = getcwd(buf,sizeof(buf)); std::cerr << "Current working directory: " << res << std::endl; } #endif #ifdef _MSC_VER freopen("CON", "w", stderr); freopen("CON", "w", stdout); #endif #if defined(__APPLE__) && TARGET_OS_MAC chdir([[[NSBundle mainBundle] resourcePath] fileSystemRepresentation]); #endif #ifdef NO_STDERR std::freopen("/dev/null", "w", stderr); std::cerr.sync_with_stdio(true); #endif std::cerr << "Frogatto engine version " << preferences::version() << "\n"; LOG( "After print engine version" ); #if defined(TARGET_BLACKBERRY) chdir("app/native"); std::cout<< "Changed working directory to: " << getcwd(0, 0) << std::endl; #endif game_logic::init_callable_definitions(); std::string level_cfg = "titlescreen.cfg"; bool unit_tests_only = false, skip_tests = false; bool run_benchmarks = false; std::vector<std::string> benchmarks_list; std::string utility_program; std::vector<std::string> util_args; std::string server = "wesnoth.org"; #if defined(UTILITY_IN_PROC) bool create_utility_in_new_process = false; std::string utility_name; #endif bool is_child_utility = false; const char* profile_output = NULL; std::string profile_output_buf; #if defined(__ANDROID__) //monstartup("libapplication.so"); #endif std::string orig_level_cfg = level_cfg; std::string override_level_cfg = ""; int modules_loaded = 0; std::vector<std::string> argv; for(int n = 1; n < argcount; ++n) { #if defined(UTILITY_IN_PROC) std::string sarg(argvec[n]); if(sarg.compare(0, 15, "--utility-proc=") == 0) { create_utility_in_new_process = true; utility_name = "--utility-child=" + sarg.substr(15); } else { argv.push_back(argvec[n]); } #else argv.push_back(argvec[n]); #endif if(argv.size() >= 2 && argv[argv.size()-2] == "-NSDocumentRevisionsDebugMode" && argv.back() == "YES") { //XCode passes these arguments by default when debugging -- make sure they are ignored. argv.resize(argv.size()-2); } } std::cerr << "Build Options:"; for(auto bo : preferences::get_build_options()) { std::cerr << " " << bo; } std::cerr << std::endl; #if defined(UTILITY_IN_PROC) if(create_utility_in_new_process) { argv.push_back(utility_name); #if defined(_MSC_VER) // app name is ignored for windows, we get windows to tell us. is_child_utility = create_utility_process("", argv); #else is_child_utility = create_utility_process(argvec[0], argv); #endif if(!is_child_utility) { argv.pop_back(); } #if defined(_MSC_VER) atexit(terminate_utility_process); #endif } #endif if(sys::file_exists("./master-config.cfg")) { std::cerr << "LOADING CONFIGURATION FROM master-config.cfg" << std::endl; variant cfg = json::parse_from_file("./master-config.cfg"); if(cfg.is_map()) { if( cfg["id"].is_null() == false) { std::cerr << "SETTING MODULE PATH FROM master-config.cfg: " << cfg["id"].as_string() << std::endl; preferences::set_preferences_path_from_module(cfg["id"].as_string()); //XXX module::set_module_name(cfg["id"].as_string(), cfg["id"].as_string()); } if(cfg["arguments"].is_null() == false) { std::vector<std::string> additional_args = cfg["arguments"].as_list_string(); argv.insert(argv.begin(), additional_args.begin(), additional_args.end()); std::cerr << "ADDING ARGUMENTS FROM master-config.cfg:"; for(size_t n = 0; n < cfg["arguments"].num_elements(); ++n) { std::cerr << " " << cfg["arguments"][n].as_string(); } std::cerr << std::endl; } } } stats::record_program_args(argv); for(size_t n = 0; n < argv.size(); ++n) { const int argc = argv.size(); const std::string arg(argv[n]); std::string arg_name, arg_value; std::string::const_iterator equal = std::find(arg.begin(), arg.end(), '='); if(equal != arg.end()) { arg_name = std::string(arg.begin(), equal); arg_value = std::string(equal+1, arg.end()); } if(arg_name == "--module") { if(load_module(arg_value, &argv) != 0) { std::cerr << "FAILED TO LOAD MODULE: " << arg_value << "\n"; return -1; } ++modules_loaded; } else if(arg == "--tests") { unit_tests_only = true; } } if(modules_loaded == 0 && !unit_tests_only) { if(load_module(DEFAULT_MODULE, &argv) != 0) { std::cerr << "FAILED TO LOAD MODULE: " << DEFAULT_MODULE << "\n"; return -1; } } preferences::load_preferences(); LOG( "After load_preferences()" ); // load difficulty settings after module, before rest of args. difficulty::manager(); for(size_t n = 0; n < argv.size(); ++n) { const size_t argc = argv.size(); const std::string arg(argv[n]); std::string arg_name, arg_value; std::string::const_iterator equal = std::find(arg.begin(), arg.end(), '='); if(equal != arg.end()) { arg_name = std::string(arg.begin(), equal); arg_value = std::string(equal+1, arg.end()); } std::cerr << "ARGS: " << arg << std::endl; if(arg.substr(0,4) == "-psn") { // ignore. } else if(arg_name == "--module") { // ignore already processed. } else if(arg_name == "--profile" || arg == "--profile") { profile_output_buf = arg_value; profile_output = profile_output_buf.c_str(); } else if(arg_name == "--utility" || arg_name == "--utility-child") { if(arg_name == "--utility-child") { is_child_utility = true; } utility_program = arg_value; for(++n; n < argc; ++n) { const std::string arg(argv[n]); util_args.push_back(arg); } break; } else if(arg == "--benchmarks") { run_benchmarks = true; } else if(arg_name == "--benchmarks") { run_benchmarks = true; benchmarks_list = util::split(arg_value); } else if(arg == "--tests") { // ignore as already processed. } else if(arg == "--no-tests") { skip_tests = true; } else if(arg_name == "--width") { std::string w(arg_value); preferences::set_actual_screen_width(boost::lexical_cast<int>(w)); } else if(arg == "--width" && n+1 < argc) { std::string w(argv[++n]); preferences::set_actual_screen_width(boost::lexical_cast<int>(w)); } else if(arg_name == "--height") { std::string h(arg_value); preferences::set_actual_screen_height(boost::lexical_cast<int>(h)); } else if(arg == "--height" && n+1 < argc) { std::string h(argv[++n]); preferences::set_actual_screen_height(boost::lexical_cast<int>(h)); } else if(arg_name == "--level") { override_level_cfg = arg_value; } else if(arg == "--level" && n+1 < argc) { override_level_cfg = argv[++n]; } else if(arg_name == "--host") { server = arg_value; } else if(arg == "--host" && n+1 < argc) { server = argv[++n]; } else if(arg == "--compiled") { preferences::set_load_compiled(true); #ifndef NO_EDITOR } else if(arg == "--edit") { preferences::set_edit_on_start(true); #endif } else if(arg == "--no-compiled") { preferences::set_load_compiled(false); #if defined(TARGET_PANDORA) } else if(arg == "--no-fbo") { preferences::set_fbo(false); } else if(arg == "--no-bequ") { preferences::set_bequ(false); #endif } else if(arg == "--help" || arg == "-h") { print_help(std::string(argvec[0])); return 0; } else { const bool res = preferences::parse_arg(argv[n].c_str()); if(!res) { std::cerr << "unrecognized arg: '" << arg << "'\n"; return -1; } } } preferences::expand_data_paths(); if(g_auto_update_anura != "" && anura_exe_name != "" && sys::file_exists("manifest.cfg")) { std::string exe_name = argvec[0]; if(exe_name.size() >= anura_exe_name.size() && std::equal(exe_name.end()-anura_exe_name.size(), exe_name.end(), anura_exe_name.begin())) { variant manifest = json::parse(sys::read_file("manifest.cfg")); if(manifest.is_map()) { variant anura_entry = manifest[anura_exe_name]; if(anura_entry.is_map()) { std::string expected_md5 = anura_entry["md5"].as_string(); std::string match; if(expected_md5 != md5::sum(sys::read_file(exe_name))) { for(auto fname : alternative_anura_exe_names()) { if(sys::file_exists(fname) && md5::sum(sys::read_file(fname)) == expected_md5) { match = fname; break; } } ASSERT_LOG(match != "", "anura.exe does not match md5 in manifest and no alternative anura.exe found"); try { sys::move_file(exe_name, "anura.exe.tmp"); sys::move_file(match, exe_name); match = exe_name; } catch(...) { } std::vector<char*> args; for(char** a = argvec; *a; ++a) { args.push_back(*a); } args.push_back(NULL); exe_name.resize(exe_name.size() - anura_exe_name.size()); exe_name += match; args[0] = const_cast<char*>(exe_name.c_str()); fprintf(stderr, "ZZZ: CALLING EXEC...\n"); execv(args[0], &args[0]); fprintf(stderr, "Could not exec()\n"); } } } } } background_task_pool::manager bg_task_pool_manager; LOG( "After expand_data_paths()" ); std::cerr << "Preferences dir: " << preferences::user_data_path() << '\n'; //make sure that the user data path exists. if(!preferences::setup_preferences_dir()) { std::cerr << "cannot create preferences dir!\n"; } std::cerr << "\n"; variant_builder update_info; if(g_auto_update_module || g_auto_update_anura != "") { //remove any .tmp files that may have been left from previous runs. std::vector<std::string> tmp_files; sys::get_files_in_dir(".", &tmp_files, NULL); for(auto f : tmp_files) { if(f.size() > 4 && std::equal(f.end()-4,f.end(),".tmp")) { try { sys::remove_file(f); } catch(...) { } } } boost::intrusive_ptr<module::client> cl, anura_cl; if(g_auto_update_module) { cl.reset(new module::client); cl->install_module(module::get_module_name(), g_force_auto_update); update_info.add("attempt_module", true); } if(g_auto_update_anura != "") { anura_cl.reset(new module::client); anura_cl->set_install_image(true); anura_cl->install_module(g_auto_update_anura, g_force_auto_update); update_info.add("attempt_anura", true); } SDL_Window* update_window = NULL; int nbytes_transferred = 0, nbytes_anura_transferred = 0; int start_time = SDL_GetTicks(); int original_start_time = SDL_GetTicks(); bool timeout = false; bool require_restart = false; fprintf(stderr, "Requesting update to module from server...\n"); while(cl || anura_cl) { if(update_window == NULL && SDL_GetTicks() - original_start_time > 2000) { update_window = SDL_CreateWindow("Updating Anura...", 0, 0, 800, 600, SDL_WINDOW_SHOWN); } int nbytes_obtained = 0; int nbytes_needed = 0; if(cl) { const int transferred = cl->nbytes_transferred(); nbytes_obtained += transferred; nbytes_needed += cl->nbytes_total(); if(transferred != nbytes_transferred) { fprintf(stderr, "Transferred %d/%dKB\n", transferred/1024, cl->nbytes_total()/1024); start_time = SDL_GetTicks(); nbytes_transferred = transferred; } } if(anura_cl) { const int transferred = anura_cl->nbytes_transferred(); nbytes_obtained += transferred; nbytes_needed += anura_cl->nbytes_total(); if(transferred != nbytes_anura_transferred) { fprintf(stderr, "Transferred (anura) %d/%dKB\n", transferred/1024, anura_cl->nbytes_total()/1024); start_time = SDL_GetTicks(); nbytes_anura_transferred = transferred; } } const int time_taken = SDL_GetTicks() - start_time; if(time_taken > g_auto_update_timeout) { fprintf(stderr, "Timed out updating module. Canceling. %dms vs %dms\n", time_taken, g_auto_update_timeout); break; } if(update_window) { SDL_Surface* fb= SDL_GetWindowSurface(update_window); SDL_Rect area = {300, 290, 200, 20}; SDL_FillRect(fb, &area, 0xFFFFFFFF); SDL_Rect inner_area = {303, 292, 194, 16}; SDL_FillRect(fb, &inner_area, 0xFF000000); if(nbytes_needed != 0) { const float ratio = float(nbytes_obtained)/float(nbytes_needed); SDL_Rect area = {303, 292, int(194.0*ratio), 16}; SDL_FillRect(fb, &area, 0xFFFFFFFF); } SDL_UpdateWindowSurface(update_window); } SDL_Event event; while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) { cl.reset(); anura_cl.reset(); break; } } SDL_Delay(20); if(cl && !cl->process()) { if(cl->error().empty() == false) { fprintf(stderr, "Error while updating module: %s\n", cl->error().c_str()); update_info.add("module_error", variant(cl->error())); } else { update_info.add("complete_module", true); } cl.reset(); } if(anura_cl && !anura_cl->process()) { if(anura_cl->error().empty() == false) { fprintf(stderr, "Error while updating anura: %s\n", anura_cl->error().c_str()); update_info.add("anura_error", variant(anura_cl->error())); } else { update_info.add("complete_anura", true); require_restart = anura_cl->nfiles_written() != 0; } anura_cl.reset(); } } if(update_window) { SDL_DestroyWindow(update_window); } if(require_restart) { std::vector<char*> args; for(char** a = argvec; *a; ++a) { std::string arg(*a); if(arg != "--force-auto-update" && arg != "--force_auto_update") { args.push_back(*a); } } args.push_back(NULL); fprintf(stderr, "ZZZ: CALLING EXEC...\n"); execv(args[0], &args[0]); fprintf(stderr, "Could not exec()\n"); } } g_auto_update_info = update_info.build(); checksum::manager checksum_manager; #ifndef NO_EDITOR sys::filesystem_manager fs_manager; #endif // NO_EDITOR const tbs::internal_server_manager internal_server_manager_scope(preferences::internal_tbs_server()); if(utility_program.empty() == false && test::utility_needs_video(utility_program) == false) { #if defined(UTILITY_IN_PROC) if(is_child_utility) { ASSERT_LOG(ipc::semaphore::create(shared_sem_name, 1) != false, "Unable to create shared semaphore: " << errno); std::cerr.sync_with_stdio(true); } #endif test::run_utility(utility_program, util_args); return 0; } #if defined(TARGET_PANDORA) EGL_Open(); #endif #if defined(__ANDROID__) std::freopen("stdout.txt","w",stdout); std::freopen("stderr.txt","w",stderr); std::cerr.sync_with_stdio(true); #endif LOG( "Start of main" ); if(!skip_tests && !test::run_tests()) { return -1; } if(unit_tests_only) { return 0; } // Create the main window. // Initalise SDL and Open GL. main_window = graphics::window_manager_ptr(new graphics::window_manager()); main_window->create_window(preferences::actual_screen_width(), preferences::actual_screen_height()); #ifdef TARGET_OS_HARMATTAN g_type_init(); #endif i18n::init (); LOG( "After i18n::init()" ); #if TARGET_OS_IPHONE || defined(TARGET_BLACKBERRY) || defined(__ANDROID__) //on the iPhone and PlayBook, try to restore the auto-save if it exists if(sys::file_exists(preferences::auto_save_file_path()) && sys::read_file(std::string(preferences::auto_save_file_path()) + ".stat") == "1") { level_cfg = "autosave.cfg"; sys::write_file(std::string(preferences::auto_save_file_path()) + ".stat", "0"); } #endif if(override_level_cfg.empty() != true) { level_cfg = override_level_cfg; orig_level_cfg = level_cfg; } const stats::manager stats_manager; #ifndef NO_EDITOR const external_text_editor::manager editor_manager; #endif // NO_EDITOR #if defined(USE_BOX2D) box2d::manager b2d_manager; #endif const load_level_manager load_manager; { //manager scope const font::manager font_manager; const sound::manager sound_manager; #if !defined(__native_client__) const joystick::manager joystick_manager; #endif graphics::texture::manager texture_manager; #ifndef NO_EDITOR editor::manager editor_manager; #endif variant preloads; loading_screen loader; try { variant gui_node = json::parse_from_file(preferences::load_compiled() ? "data/compiled/gui.cfg" : "data/gui.cfg"); gui_section::init(gui_node); loader.draw_and_increment(_("Initializing GUI")); framed_gui_element::init(gui_node); sound::init_music(json::parse_from_file("data/music.cfg")); graphical_font::init_for_locale(i18n::get_locale()); preloads = json::parse_from_file("data/preload.cfg"); int preload_items = preloads["preload"].num_elements(); loader.set_number_of_items(preload_items+7); // 7 is the number of items that will be loaded below custom_object::init(); loader.draw_and_increment(_("Initializing custom object functions")); loader.draw_and_increment(_("Initializing textures")); loader.load(preloads); loader.draw_and_increment(_("Initializing tiles")); tile_map::init(json::parse_from_file("data/tiles.cfg")); game_logic::formula_object::load_all_classes(); } catch(const json::parse_error& e) { std::cerr << "ERROR PARSING: " << e.error_message() << "\n"; return 0; } loader.draw(_("Loading level")); #if defined(__native_client__) while(1) { } #endif #if defined(__APPLE__) && !(TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE) && !defined(USE_SHADERS) GLint swapInterval = 1; CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &swapInterval); #endif loader.finish_loading(); //look to see if we got any quit events while loading. { SDL_Event event; while(input::sdl_poll_event(&event)) { if(event.type == SDL_QUIT) { return 0; } } } formula_profiler::manager profiler(profile_output); #ifdef USE_SHADERS texture_frame_buffer::init(preferences::actual_screen_width(), preferences::actual_screen_height()); #else texture_frame_buffer::init(); #endif if(run_benchmarks) { if(benchmarks_list.empty() == false) { test::run_benchmarks(&benchmarks_list); } else { test::run_benchmarks(); } return 0; } else if(utility_program.empty() == false && test::utility_needs_video(utility_program) == true) { test::run_utility(utility_program, util_args); return 0; } bool quit = false; while(!quit && !show_title_screen(level_cfg)) { boost::intrusive_ptr<level> lvl(load_level(level_cfg)); #if !defined(__native_client__) //see if we're loading a multiplayer level, in which case we //connect to the server. multiplayer::manager mp_manager(lvl->is_multiplayer()); if(lvl->is_multiplayer()) { multiplayer::setup_networked_game(server); } if(lvl->is_multiplayer()) { last_draw_position() = screen_position(); std::string level_cfg = "waiting-room.cfg"; boost::intrusive_ptr<level> wait_lvl(load_level(level_cfg)); wait_lvl->finish_loading(); wait_lvl->set_multiplayer_slot(0); if(wait_lvl->player()) { wait_lvl->player()->set_current_level(level_cfg); } wait_lvl->set_as_current_level(); level_runner runner(wait_lvl, level_cfg, orig_level_cfg); multiplayer::sync_start_time(*lvl, boost::bind(&level_runner::play_cycle, &runner)); lvl->set_multiplayer_slot(multiplayer::slot()); } #endif last_draw_position() = screen_position(); assert(lvl.get()); if(!lvl->music().empty()) { sound::play_music(lvl->music()); } if(lvl->player() && level_cfg != "autosave.cfg") { lvl->player()->set_current_level(level_cfg); lvl->player()->get_entity().save_game(); } set_scene_title(lvl->title()); try { quit = level_runner(lvl, level_cfg, orig_level_cfg).play_level(); level_cfg = orig_level_cfg; } catch(multiplayer_exception&) { } } level::clear_current_level(); } //end manager scope, make managers destruct before calling SDL_Quit // controls::debug_dump_controls(); #if defined(TARGET_PANDORA) || defined(TARGET_TEGRA) EGL_Destroy(); #endif preferences::save_preferences(); #if !defined(_MSC_VER) && defined(UTILITY_IN_PROC) if(create_utility_in_new_process) { terminate_utility_process(); } #endif std::set<variant*> loading; swap_variants_loading(loading); if(loading.empty() == false) { fprintf(stderr, "Illegal object: %p\n", (void*)(*loading.begin())->as_callable_loading()); ASSERT_LOG(false, "Unresolved unserialized objects: " << loading.size()); } //#ifdef _MSC_VER // ExitProcess(0); //#endif return 0; }
void timage::draw(surface& canvas , const game_logic::map_formula_callable& variables) { DBG_GUI_D << "Image: draw.\n"; /** * @todo formulas are now recalculated every draw cycle which is a bit * silly unless there has been a resize. So to optimize we should use an * extra flag or do the calculation in a separate routine. */ const std::string& name = image_name_(variables); if(name.empty()) { DBG_GUI_D << "Image: formula returned no value, will not be drawn.\n"; return; } /* * The locator might return a different surface for every call so we can't * cache the output, also not if no formula is used. */ surface tmp(image::get_image(image::locator(name))); if(!tmp) { ERR_GUI_D << "Image: '" << name << "' not found and won't be drawn.\n"; return; } image_.assign(make_neutral_surface(tmp)); assert(image_); src_clip_ = ::create_rect(0, 0, image_->w, image_->h); game_logic::map_formula_callable local_variables(variables); local_variables.add("image_original_width", variant(image_->w)); local_variables.add("image_original_height", variant(image_->h)); unsigned w = w_(local_variables); VALIDATE_WITH_DEV_MESSAGE( static_cast<int>(w) >= 0 , _("Image doesn't fit on canvas.") , (formatter() << "Image '" << name << "', w = " << static_cast<int>(w) << ".").str()); unsigned h = h_(local_variables); VALIDATE_WITH_DEV_MESSAGE( static_cast<int>(h) >= 0 , _("Image doesn't fit on canvas.") , (formatter() << "Image '" << name << "', h = " << static_cast<int>(h) << ".").str()); local_variables.add("image_width", variant(w ? w : image_->w)); local_variables.add("image_height", variant(h ? h : image_->h)); const unsigned x = x_(local_variables); VALIDATE_WITH_DEV_MESSAGE( static_cast<int>(x) >= 0 , _("Image doesn't fit on canvas.") , (formatter() << "Image '" << name << "', x = " << static_cast<int>(x) << ".").str()); const unsigned y = y_(local_variables); VALIDATE_WITH_DEV_MESSAGE( static_cast<int>(y) >= 0 , _("Image doesn't fit on canvas.") , (formatter() << "Image '" << name << "', y = " << static_cast<int>(y) << ".").str()); // Copy the data to local variables to avoid overwriting the originals. SDL_Rect src_clip = src_clip_; SDL_Rect dst_clip = ::create_rect(x, y, 0, 0); surface surf; // Test whether we need to scale and do the scaling if needed. if(w || h) { bool done = false; bool stretch_image = (resize_mode_ == stretch) && (!!w ^ !!h); if(!w) { if(stretch_image) { DBG_GUI_D << "Image: vertical stretch from " << image_->w << ',' << image_->h << " to a height of " << h << ".\n"; surf = stretch_surface_vertical(image_, h, false); done = true; } w = image_->w; } if(!h) { if(stretch_image) { DBG_GUI_D << "Image: horizontal stretch from " << image_->w << ',' << image_->h << " to a width of " << w << ".\n"; surf = stretch_surface_horizontal(image_, w, false); done = true; } h = image_->h; } if(!done) { if(resize_mode_ == tile) { DBG_GUI_D << "Image: tiling from " << image_->w << ',' << image_->h << " to " << w << ',' << h << ".\n"; const int columns = (w + image_->w - 1) / image_->w; const int rows = (h + image_->h - 1) / image_->h; surf = create_neutral_surface(w, h); for(int x = 0; x < columns; ++x) { for(int y = 0; y < rows; ++y) { const SDL_Rect dest = ::create_rect( x * image_->w , y * image_->h , 0 , 0); blit_surface(image_, NULL, surf, &dest); } } } else { if(resize_mode_ == stretch) { ERR_GUI_D << "Image: failed to stretch image, " "fall back to scaling.\n"; } DBG_GUI_D << "Image: scaling from " << image_->w << ',' << image_->h << " to " << w << ',' << h << ".\n"; surf = scale_surface(image_, w, h, false); } } src_clip.w = w; src_clip.h = h; } else { surf = image_; } if(vertical_mirror_(local_variables)) { surf = flip_surface(surf, false); } blit_surface(surf, &src_clip, canvas, &dst_clip); }
void add( mutable_variant_object& vo, const char* name, const optional<M>& v )const { if( v.valid() ) vo(name, variant( *v, _max_depth )); }
static QVariant getVariantFromDBusMessage(DBusMessageIter *iter) { dbus_bool_t bool_data; dbus_int32_t int32_data; dbus_uint32_t uint32_data; dbus_int64_t int64_data; dbus_uint64_t uint64_data; char *str_data; char char_data; int argtype = dbus_message_iter_get_arg_type(iter); switch (argtype) { case DBUS_TYPE_BOOLEAN: { dbus_message_iter_get_basic(iter, &bool_data); QVariant variant((bool)bool_data); return variant; } case DBUS_TYPE_ARRAY: { // Handle all arrays here int elem_type = dbus_message_iter_get_element_type(iter); DBusMessageIter array_iter; dbus_message_iter_recurse(iter, &array_iter); if (elem_type == DBUS_TYPE_BYTE) { QByteArray byte_array; do { dbus_message_iter_get_basic(&array_iter, &char_data); byte_array.append(char_data); } while (dbus_message_iter_next(&array_iter)); QVariant variant(byte_array); return variant; } else if (elem_type == DBUS_TYPE_STRING) { QStringList str_list; do { dbus_message_iter_get_basic(&array_iter, &str_data); str_list.append(str_data); } while (dbus_message_iter_next(&array_iter)); QVariant variant(str_list); return variant; } else { QVariantList variantList; do { variantList << getVariantFromDBusMessage(&array_iter); } while (dbus_message_iter_next(&array_iter)); QVariant variant(variantList); return variant; } break; } case DBUS_TYPE_BYTE: { dbus_message_iter_get_basic(iter, &char_data); QChar ch(char_data); QVariant variant(ch); return variant; } case DBUS_TYPE_INT32: { dbus_message_iter_get_basic(iter, &int32_data); QVariant variant((int)int32_data); return variant; } case DBUS_TYPE_UINT32: { dbus_message_iter_get_basic(iter, &uint32_data); QVariant variant((uint)uint32_data); return variant; } case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_STRING: { dbus_message_iter_get_basic(iter, &str_data); QString str(str_data); QVariant variant(str); return variant; } case DBUS_TYPE_INT64: { dbus_message_iter_get_basic(iter, &int64_data); QVariant variant((qlonglong)int64_data); return variant; } case DBUS_TYPE_UINT64: { dbus_message_iter_get_basic(iter, &uint64_data); QVariant variant((qulonglong)uint64_data); return variant; } case DBUS_TYPE_DICT_ENTRY: case DBUS_TYPE_STRUCT: { // Handle all structs here DBusMessageIter struct_iter; dbus_message_iter_recurse(iter, &struct_iter); QVariantList variantList; do { variantList << getVariantFromDBusMessage(&struct_iter); } while (dbus_message_iter_next(&struct_iter)); QVariant variant(variantList); return variant; } case DBUS_TYPE_VARIANT: { DBusMessageIter variant_iter; dbus_message_iter_recurse(iter, &variant_iter); return getVariantFromDBusMessage(&variant_iter); } case DBUS_TYPE_UNIX_FD: { dbus_message_iter_get_basic(iter, &uint32_data); QVariant variant((uint)uint32_data); return variant; } default: qWarning("Unsupported DBUS type: %d\n", argtype); } return QVariant(); }
std::set<std::string> already_known; game_logic::formula_object::visit_variants(obj, boost::bind(add_object_to_set, _1, &objects, &already_known)); std::vector<variant> results_list; foreach(wml_serializable_formula_callable* item, objects) { char addr_buf[256]; sprintf(addr_buf, "%p", item); std::string key(addr_buf); if(already_known.count(key)) { continue; } results_list.push_back(item->write_to_wml()); } res[variant("character")] = variant(&results_list); return variant(&res); } namespace { std::map<intptr_t, wml_serializable_formula_callable_ptr> registered_objects; } void wml_formula_callable_read_scope::register_serialized_object(intptr_t addr, wml_serializable_formula_callable_ptr ptr) { //fprintf(stderr, "REGISTER SERIALIZED: 0x%x\n", (int)addr); registered_objects[addr] = ptr; } wml_serializable_formula_callable_ptr wml_formula_callable_read_scope::get_serialized_object(intptr_t addr)
custom_object_callable::custom_object_callable(bool is_singleton) { if(is_singleton) { instance_ptr = this; set_type_name("custom_obj"); } //make sure 'library' is initialized as a valid type. game_logic::get_library_definition(); static const Property CustomObjectProperties[] = { { "value", "any" }, { "_data", "any" }, { "arg", "object" }, { "consts", "any" }, { "type", "string" }, { "active", "any" }, { "lib", "library" }, { "time_in_animation", "int" }, { "time_in_animation_delta", "int" }, { "frame_in_animation", "int" }, { "level", "any" }, { "animation", "string/string|map" }, { "available_animations", "[string]" }, { "hitpoints", "int" }, { "max_hitpoints", "int" }, { "mass", "int" }, { "label", "string" }, { "x", "int/int|decimal" }, { "y", "int/int|decimal" }, { "xy", "[int]" }, { "z", "int" }, { "relative_x", "int/int|decimal" }, { "relative_y", "int/int|decimal" }, { "spawned_by", "null|custom_obj" }, { "spawned_children", "[custom_obj]" }, { "parent", "null|custom_obj" }, { "pivot", "string" }, { "zorder", "int" }, { "zsub_order", "int" }, { "previous_y", "int" }, { "x1", "int/int|decimal" }, { "x2", "int/int|decimal" }, { "y1", "int/int|decimal" }, { "y2", "int/int|decimal" }, { "w", "int" }, { "h", "int" }, { "mid_x", "int/int|decimal" }, { "mid_y", "int/int|decimal" }, { "mid_xy", "[int]" }, { "midpoint_x", "int/int|decimal" }, { "midpoint_y", "int/int|decimal" }, { "midpoint_xy", "[int]" }, { "is_solid", "bool" }, { "solid_rect", "rect_obj" }, { "solid_mid_x", "int" }, { "solid_mid_y", "int" }, { "solid_mid_xy", "[int]" }, { "img_mid_x", "int" }, { "img_mid_y", "int" }, { "img_mid_xy", "int" }, { "img_w", "int" }, { "img_h", "int" }, { "img_wh", "int" }, { "front", "int" }, { "back", "int" }, { "cycle", "int" }, { "facing", "int" }, { "upside_down", "int" }, { "up", "int" }, { "down", "int" }, { "velocity_x", "int/int|decimal" }, { "velocity_y", "int/int|decimal" }, { "velocity_xy", "[int]" }, { "velocity_magnitude", "decimal" }, { "velocity_angle", "decimal" }, { "accel_x", "int/int|decimal" }, { "accel_y", "int/int|decimal" }, { "accel_xy", "[int]" }, { "gravity_shift", "int" }, { "platform_motion_x", "int" }, { "registry", "object" }, { "globals", "object" }, { "vars", "object" }, { "tmp", "object" }, { "group", "int" }, { "rotate", "decimal" }, { "rotate_x", "decimal" }, { "rotate_y", "decimal" }, { "rotate_z", "decimal" }, { "me", "any" }, { "self", "any" }, { "red", "int" }, { "green", "int" }, { "blue", "int" }, { "alpha", "int" }, { "text_alpha", "int" }, { "damage", "int" }, { "hit_by", "null|custom_obj" }, { "distortion", "null|object" }, { "is_standing", "bool" }, { "standing_info", "null|object" }, { "near_cliff_edge", "bool" }, { "distance_to_cliff", "int" }, { "slope_standing_on", "int" }, { "underwater", "bool" }, { "previous_water_bounds", "[int]" }, { "water_bounds", "null|[int]" }, { "water_object", "null|custom_obj" }, { "driver", "null|custom_obj" }, { "is_human", "bool" }, { "invincible", "int" }, { "sound_volume", "int" }, { "destroyed", "bool" }, { "is_standing_on_platform", "null|bool|custom_obj" }, { "standing_on", "null|custom_obj" }, { "shader", "null|shader_program" }, { "effects", "[shader_program]" }, { "variations", "[string]" }, { "attached_objects", "[custom_obj]" }, { "call_stack", "[string]" }, { "lights", "[object]" }, { "solid_dimensions_in", "[string]" }, { "solid_dimensions_not_in", "[string]" }, { "collide_dimensions_in", "[string]" }, { "collide_dimensions_not_in", "[string]" }, { "brightness", "int" }, { "current_generator", "object" }, { "tags", "object" }, { "draw_area", "any" }, { "scale", "decimal" }, { "activation_area", "null|[int|decimal]" }, { "clip_area", "null|[int]" }, { "always_active", "bool" }, { "activation_border", "int/int|decimal" }, { "fall_through_platforms", "any" }, { "has_feet", "bool" }, { "x_schedule", "any" }, { "y_schedule", "any" }, { "rotation_schedule", "any" }, { "schedule_speed", "any" }, { "schedule_expires", "any" }, { "platform_area", "null|[int]" }, { "platform_offsets", "[int]" }, { "custom_draw", "list" }, { "uv_array", "[decimal]" }, { "xy_array", "[decimal]" }, { "uv_segments", "[int]" }, { "draw_primitives", "[object]/[object|map]|map" }, { "event_handlers", "object" }, { "use_absolute_screen_coordinates", "bool" }, { "widgets", "object/[object|map]|object|map" }, { "widget_list", "[widget]" }, { "textv", "any" }, { "body", "any" }, { "paused", "bool" }, { "mouseover_delay", "int" }, { "mouseover_area", "[int]" }, { "particle_systems", "{string -> object}" }, { "truez", "bool" }, { "tx", "decimal" }, { "ty", "decimal" }, { "tz", "decimal" }, { "animated_movements", "[string]" }, { "ctrl_user_output", "any" }, { "ctrl_up", "bool" }, { "ctrl_down", "bool" }, { "ctrl_left", "bool" }, { "ctrl_right", "bool" }, { "ctrl_attack", "bool" }, { "ctrl_jump", "bool" }, { "ctrl_tongue", "bool" }, { "ctrl_user", "any" }, //player-specific { "difficulty", "int" }, { "can_interact", "bool" }, { "underwater_controls", "bool" }, { "ctrl_mod_key", "int" }, { "ctrl_keys", "[string]" }, { "ctrl_mice", "[[int|string]]" }, { "ctrl_tilt", "int" }, { "ctrl_x", "int" }, { "ctrl_y", "int" }, { "ctrl_reverse_ab", "bool" }, { "control_scheme", "string" }, { "vertical_look", "int" }, { "control_lock", "null|[string]" }, }; ASSERT_EQ(NUM_CUSTOM_OBJECT_PROPERTIES, sizeof(CustomObjectProperties)/sizeof(*CustomObjectProperties)); if(global_entries().empty()) { for(int n = 0; n != sizeof(CustomObjectProperties)/sizeof(*CustomObjectProperties); ++n) { global_entries().push_back(entry(CustomObjectProperties[n].id)); const std::string& type = CustomObjectProperties[n].type; std::string::const_iterator itor = std::find(type.begin(), type.end(), '/'); std::string read_type(type.begin(), itor); global_entries().back().set_variant_type(parse_variant_type(variant(read_type))); if(itor != type.end()) { global_entries().back().write_type = parse_variant_type(variant(std::string(itor+1, type.end()))); } } for(int n = 0; n != global_entries().size(); ++n) { keys_to_slots()[global_entries()[n].id] = n; } global_entries()[CUSTOM_OBJECT_ME].set_variant_type(variant_type::get_custom_object()); global_entries()[CUSTOM_OBJECT_SELF].set_variant_type(variant_type::get_custom_object()); const variant_type_ptr builtin = variant_type::get_builtin("level"); global_entries()[CUSTOM_OBJECT_LEVEL].set_variant_type(builtin); } global_entries()[CUSTOM_OBJECT_PARENT].type_definition = is_singleton ? this : &instance(); global_entries()[CUSTOM_OBJECT_LIB].type_definition = game_logic::get_library_definition().get(); entries_ = global_entries(); }
void tgame_save_oos::pre_show(CVideo& /*video*/, twindow& window) { window.set_canvas_variable("border", variant("default-border")); }
variant execute(const game_logic::formula_callable& variables) const { const std::string key = args()[0]->evaluate(variables).as_string(); return variant(hex_object::get_hex_tile(key).get()); }
widget_settings_dialog* widget::settings_dialog(int x, int y, int w, int h) { return new widget_settings_dialog(x,y,w,h,this); } dialog_ptr widget::get_settings_dialog(int x, int y, int w, int h) { return settings_dialog(x,y,w,h); } BEGIN_DEFINE_CALLABLE_NOBASE(widget) DEFINE_FIELD(draw_area, "[int]") std::vector<variant> v; v.push_back(variant(obj.x_)); v.push_back(variant(obj.y_)); v.push_back(variant(obj.w_)); v.push_back(variant(obj.h_)); return variant(&v); DEFINE_SET_FIELD std::vector<int> r = value.as_list_int(); ASSERT_LOG(r.size() == 4, "Four values must be supplied to the draw_area attribute"); obj.set_loc(r[0], r[1]); obj.set_dim(r[2], r[3]); DEFINE_FIELD(rect, "[int]") std::vector<variant> v; v.push_back(variant(obj.x_)); v.push_back(variant(obj.y_)); v.push_back(variant(obj.w_));
void SmoothNode::onContextFrame( qint64 pTimeStamp ) { if( pTimeStamp < mLastTime ) { mLastTime = pTimeStamp; } const qreal IncVal = variant( mPinIncSpeed ).toReal(); const qreal DecVal = variant( mPinDecSpeed ).toReal(); for( fugio::NodeInterface::UuidPair UP : mNode->pairedPins() ) { QSharedPointer<fugio::PinInterface> SrcPin = mNode->findPinByLocalId( UP.first ); QSharedPointer<fugio::PinInterface> DstPin = mNode->findPinByLocalId( UP.second ); if( !SrcPin || !DstPin || !DstPin->hasControl() ) { continue; } fugio::VariantInterface *DstVar = qobject_cast<fugio::VariantInterface *>( DstPin->control()->qobject() ); qreal CurVal = variant( SrcPin ).toReal(); qreal OutVal = DstVar->variant().toReal(); if( CurVal == OutVal ) { continue; } qreal AddVal = 0; AddVal = qreal( pTimeStamp - mLastTime ) / 1000.0; if( CurVal > OutVal ) { AddVal *= IncVal; if( OutVal + AddVal > CurVal ) { AddVal = CurVal - OutVal; } } else { AddVal *= -DecVal; if( OutVal + AddVal < CurVal ) { AddVal = CurVal - OutVal; } } qreal NewVal = OutVal + AddVal; if( DstVar->variant().toReal() != NewVal ) { DstVar->setVariant( OutVal + AddVal ); pinUpdated( DstPin ); } } mLastTime = pTimeStamp; }
Variant Object::o_set(CStrRef propName, RefResult val, CStrRef context /* = null_string */) { return o_setRef(propName, variant(val), context); }
variant query_value(const std::string& key) const { if(has_self_ && key == "self") { return variant(this); } return get_value(key); }
static void save_to_file( const T& v, const std::string& p, bool pretty = true, output_formatting format = stringify_large_ints_and_doubles, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH ) { save_to_file( variant(v, max_depth), fc::path(p), pretty, format, max_depth ); }
static string to_pretty_string( const T& v, output_formatting format = stringify_large_ints_and_doubles, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH ) { return to_pretty_string( variant(v, max_depth), format, max_depth ); }
variant number_from_stream( T& in ) { fc::stringstream ss; bool dot = false; bool neg = false; if( in.peek() == '-') { neg = true; ss.put( in.get() ); } bool done = false; try { char c; while((c = in.peek()) && !done) { switch( c ) { case '.': if (dot) FC_THROW_EXCEPTION(parse_error_exception, "Can't parse a number with two decimal places"); dot = true; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ss.put( in.get() ); break; default: if( isalnum( c ) ) { return ss.str() + stringFromToken( in ); } done = true; break; } } } catch (fc::eof_exception&) { } catch (const std::ios_base::failure&) { } fc::string str = ss.str(); if (str == "-." || str == ".") // check the obviously wrong things we could have encountered FC_THROW_EXCEPTION(parse_error_exception, "Can't parse token \"${token}\" as a JSON numeric constant", ("token", str)); if( dot ) return parser_type == json::legacy_parser_with_string_doubles ? variant(str) : variant(to_double(str)); if( neg ) return to_int64(str); return to_uint64(str); }
variant wallet_db::get_property( property_enum property_id )const { auto property_itr = properties.find( property_id ); if( property_itr != properties.end() ) return property_itr->second.value; return variant(); }
variant token_from_stream( T& in ) { std::stringstream ss; ss.exceptions( std::ifstream::badbit ); bool received_eof = false; bool done = false; try { char c; while((c = in.peek()) && !done) { switch( c ) { case 'n': case 'u': case 'l': case 't': case 'r': case 'e': case 'f': case 'a': case 's': ss.put( in.get() ); break; default: done = true; break; } } } catch (fc::eof_exception&) { received_eof = true; } catch (const std::ios_base::failure&) { received_eof = true; } // we can get here either by processing a delimiter as in "null," // an EOF like "null<EOF>", or an invalid token like "nullZ" fc::string str = ss.str(); if( str == "null" ) return variant(); if( str == "true" ) return true; if( str == "false" ) return false; else { if (received_eof) { if (str.empty()) FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF" ); else return str; } else { // if we've reached this point, we've either seen a partial // token ("tru<EOF>") or something our simple parser couldn't // make out ("falfe") // A strict JSON parser would signal this as an error, but we // will just treat the malformed token as an un-quoted string. return str + stringFromToken(in);; } } }
FOREACH(AUTO & tmp, canvas()) { tmp.set_variable("positioner_offset", variant(positioner_offset_)); tmp.set_variable("positioner_length", variant(positioner_length_)); }
CallLinkStatus CallLinkStatus::computeFromCallLinkInfo( const ConcurrentJITLocker&, CallLinkInfo& callLinkInfo) { if (callLinkInfo.clearedByGC()) return takesSlowPath(); // Note that despite requiring that the locker is held, this code is racy with respect // to the CallLinkInfo: it may get cleared while this code runs! This is because // CallLinkInfo::unlink() may be called from a different CodeBlock than the one that owns // the CallLinkInfo and currently we save space by not having CallLinkInfos know who owns // them. So, there is no way for either the caller of CallLinkInfo::unlock() or unlock() // itself to figure out which lock to lock. // // Fortunately, that doesn't matter. The only things we ask of CallLinkInfo - the slow // path count, the stub, and the target - can all be asked racily. Stubs and targets can // only be deleted at next GC, so if we load a non-null one, then it must contain data // that is still marginally valid (i.e. the pointers ain't stale). This kind of raciness // is probably OK for now. // PolymorphicCallStubRoutine is a GCAwareJITStubRoutine, so if non-null, it will stay alive // until next GC even if the CallLinkInfo is concurrently cleared. Also, the variants list is // never mutated after the PolymorphicCallStubRoutine is instantiated. We have some conservative // fencing in place to make sure that we see the variants list after construction. if (PolymorphicCallStubRoutine* stub = callLinkInfo.stub()) { WTF::loadLoadFence(); CallEdgeList edges = stub->edges(); // Now that we've loaded the edges list, there are no further concurrency concerns. We will // just manipulate and prune this list to our liking - mostly removing entries that are too // infrequent and ensuring that it's sorted in descending order of frequency. RELEASE_ASSERT(edges.size()); std::sort( edges.begin(), edges.end(), [] (CallEdge a, CallEdge b) { return a.count() > b.count(); }); RELEASE_ASSERT(edges.first().count() >= edges.last().count()); double totalCallsToKnown = 0; double totalCallsToUnknown = callLinkInfo.slowPathCount(); CallVariantList variants; for (size_t i = 0; i < edges.size(); ++i) { CallEdge edge = edges[i]; // If the call is at the tail of the distribution, then we don't optimize it and we // treat it as if it was a call to something unknown. We define the tail as being either // a call that doesn't belong to the N most frequent callees (N = // maxPolymorphicCallVariantsForInlining) or that has a total call count that is too // small. if (i >= Options::maxPolymorphicCallVariantsForInlining() || edge.count() < Options::frequentCallThreshold()) totalCallsToUnknown += edge.count(); else { totalCallsToKnown += edge.count(); variants.append(edge.callee()); } } // Bail if we didn't find any calls that qualified. RELEASE_ASSERT(!!totalCallsToKnown == !!variants.size()); if (variants.isEmpty()) return takesSlowPath(); // We require that the distribution of callees is skewed towards a handful of common ones. if (totalCallsToKnown / totalCallsToUnknown < Options::minimumCallToKnownRate()) return takesSlowPath(); RELEASE_ASSERT(totalCallsToKnown); RELEASE_ASSERT(variants.size()); CallLinkStatus result; result.m_variants = variants; result.m_couldTakeSlowPath = !!totalCallsToUnknown; return result; } CallLinkStatus result; if (JSFunction* target = callLinkInfo.lastSeenCallee()) { CallVariant variant(target); if (callLinkInfo.hasSeenClosure()) variant = variant.despecifiedClosure(); result.m_variants.append(variant); } result.m_couldTakeSlowPath = !!callLinkInfo.slowPathCount(); return result; }
void chain_interface::set_accumulated_fees( share_type fees ) { set_property( accumulated_fees, variant(fees) ); }
variant texture_object::get_value(const std::string& key) const { return variant(); }
void chain_interface::set_fee_rate( share_type fees ) { set_property( current_fee_rate, variant(fees) ); }
GetByIdStatus GetByIdStatus::computeForStubInfo( const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, StringImpl* uid, CallLinkStatus::ExitSiteData callExitSiteData) { if (!stubInfo || !stubInfo->seen) return GetByIdStatus(NoInformation); PolymorphicGetByIdList* list = 0; State slowPathState = TakesSlowPath; if (stubInfo->accessType == access_get_by_id_list) { list = stubInfo->u.getByIdList.list; for (unsigned i = 0; i < list->size(); ++i) { const GetByIdAccess& access = list->at(i); if (access.doesCalls()) slowPathState = MakesCalls; } } // Finally figure out if we can derive an access strategy. GetByIdStatus result; result.m_state = Simple; result.m_wasSeenInJIT = true; // This is interesting for bytecode dumping only. switch (stubInfo->accessType) { case access_unset: return GetByIdStatus(NoInformation); case access_get_by_id_self: { Structure* structure = stubInfo->u.getByIdSelf.baseObjectStructure.get(); if (structure->takesSlowPathInDFGForImpureProperty()) return GetByIdStatus(slowPathState, true); unsigned attributesIgnored; GetByIdVariant variant; variant.m_offset = structure->getConcurrently(uid, attributesIgnored); if (!isValidOffset(variant.m_offset)) return GetByIdStatus(slowPathState, true); variant.m_structureSet.add(structure); bool didAppend = result.appendVariant(variant); ASSERT_UNUSED(didAppend, didAppend); return result; } case access_get_by_id_list: { for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) { Structure* structure = list->at(listIndex).structure(); ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor( profiledBlock, structure, list->at(listIndex).chain(), list->at(listIndex).chainCount(), uid); switch (complexGetStatus.kind()) { case ComplexGetStatus::ShouldSkip: continue; case ComplexGetStatus::TakesSlowPath: return GetByIdStatus(slowPathState, true); case ComplexGetStatus::Inlineable: { std::unique_ptr<CallLinkStatus> callLinkStatus; switch (list->at(listIndex).type()) { case GetByIdAccess::SimpleInline: case GetByIdAccess::SimpleStub: { break; } case GetByIdAccess::Getter: { AccessorCallJITStubRoutine* stub = static_cast<AccessorCallJITStubRoutine*>( list->at(listIndex).stubRoutine()); callLinkStatus = std::make_unique<CallLinkStatus>( CallLinkStatus::computeFor( locker, profiledBlock, *stub->m_callLinkInfo, callExitSiteData)); break; } case GetByIdAccess::CustomGetter: case GetByIdAccess::WatchedStub:{ // FIXME: It would be totally sweet to support this at some point in the future. // https://bugs.webkit.org/show_bug.cgi?id=133052 return GetByIdStatus(slowPathState, true); } default: RELEASE_ASSERT_NOT_REACHED(); } GetByIdVariant variant( StructureSet(structure), complexGetStatus.offset(), complexGetStatus.chain(), WTF::move(callLinkStatus)); if (!result.appendVariant(variant)) return GetByIdStatus(slowPathState, true); break; } } } return result; } default: return GetByIdStatus(slowPathState, true); } RELEASE_ASSERT_NOT_REACHED(); return GetByIdStatus(); }
void tduel::reset_turn(twindow& window) { std::stringstream str; str.str(""); str << "misc/digit-big.png~CROP(" << 30 * (turn_ + 1) << ", 0, 30, 45)"; find_widget<tcontrol>(&window, "turn", false, false)->set_label(str.str()); // set up card for (int index = 0; index < 2; index ++) { setting* t = setting_ + index; t->cards_.clear(); if (!t->deadfight_) { t->deadfight_ = (rand() % 16) < t->skill_; } if (!t->fightback_) { t->fightback_ = (rand() % 64) < t->skill_; } char c = index? 'r': 'l'; for (int index2 = 4; index2 >= 0; index2 --) { str.str(""); str << c << "card" << index2; ttoggle_button* toggle = find_widget<ttoggle_button>(&window, str.str(), false, false); if (t->count_ <= index2) { toggle->set_visible(twidget::INVISIBLE); continue; } if (index == 1) { toggle->set_active(false); } int type = rand() % nb_items; int point = t->min_point_ + rand() % (t->max_point_ - t->min_point_ + 1); t->cards_.insert(std::pair<int, int>(type, point)); } int index2 = 0; for (std::multimap<int, int>::const_iterator c_itor = t->cards_.begin(); c_itor != t->cards_.end(); ++ c_itor, index2 ++) { str.str(""); str << c << "card" << index2; ttoggle_button* toggle = find_widget<ttoggle_button>(&window, str.str(), false, false); if (index == 0) { connect_signal_mouse_left_click( *toggle , boost::bind( &tduel::on_card , this , boost::ref(window) , index2)); } for (int i = 0; i < 6; i ++) { toggle->canvas()[i].set_variable("foreground", variant(menu_items[c_itor->first])); } str.str(""); str << c_itor->second; toggle->set_label(str.str()); // reset lcard/rcard. toggle->set_value(false); toggle->set_dirty(); } // total card str.str(""); str << c << "total"; ttoggle_button* toggle = find_widget<ttoggle_button>(&window, str.str(), false, false); for (int i = 0; i < 6; i ++) { toggle->canvas()[i].set_variable("foreground", variant("")); } toggle->set_label("0"); toggle->set_active(false); // skill str.str(""); str << c << "skill"; find_widget<tcontrol>(&window, str.str(), false, false)->set_label(""); // deadfight str.str(""); str << c << "skill0"; toggle = find_widget<ttoggle_button>(&window, str.str(), false, false); toggle->set_value(false); for (int i = 0; i < 6; i ++) { if (t->deadfight_) { toggle->canvas()[i].set_variable("image", variant("misc/deadfight.png")); } else { toggle->canvas()[i].set_variable("image", variant("")); } } if (index == 0) { toggle->set_active(t->deadfight_); } else { toggle->set_active(false); } // fightback str.str(""); str << c << "skill1"; toggle = find_widget<ttoggle_button>(&window, str.str(), false, false); toggle->set_value(false); for (int i = 0; i < 6; i ++) { if (t->fightback_) { toggle->canvas()[i].set_variable("image", variant("misc/fightback.png")); } else { toggle->canvas()[i].set_variable("image", variant("")); } } if (index == 0) { toggle->set_active(t->fightback_); } else { toggle->set_active(false); } } endturn_->set_active(false); }
void to_variant( const mutable_variant_object& var, variant& vo ) { vo = variant(var); }
void tduel::pre_show(CVideo& /*video*/, twindow& window) { // Override the user value, to make sure it's set properly. window.set_click_dismiss(false); // ***** ***** ***** ***** Set up the widgets ***** ***** ***** ***** window.canvas(1).set_variable("left_image", variant(left_.image(true))); window.canvas(1).set_variable("right_image", variant(right_.image(true))); window.canvas(1).set_variable("center_image", variant("")); window.canvas(1).set_variable("hp_left", variant("misc/hp-blue.png")); window.canvas(1).set_variable("hp_right", variant("misc/hp-red.png")); window.canvas(1).set_variable("percentage", variant((hp_ * 100) / TOTAL_HP)); std::stringstream str; tbutton* b = find_widget<tbutton>(&window, "endturn", false, false); for (int i = 0; i < 4; i ++) { b->canvas()[i].set_variable("image", variant("misc/ok.png")); } find_widget<tcontrol>(&window, "lname", false, false)->set_label(left_.name()); find_widget<tcontrol>(&window, "rname", false, false)->set_label(right_.name()); tcontrol* control = find_widget<tcontrol>(&window, "lforce", false, false); str.str(""); str << setting_[0].force_ << "(" << hero::adaptability_str2(left_.skill_[hero_skill_hero]).c_str() << ")"; control->set_label(str.str()); control = find_widget<tcontrol>(&window, "rforce", false, false); str.str(""); str << setting_[1].force_ << "(" << hero::adaptability_str2(right_.skill_[hero_skill_hero]).c_str() << ")";; control->set_label(str.str()); endturn_ = find_widget<tbutton>(&window, "endturn", false, false); connect_signal_mouse_left_click( *endturn_ , boost::bind( &tduel::end_turn , this , boost::ref(window))); endturn_->set_sound_button_click("hatchet.wav"); lskill0_ = find_widget<ttoggle_button>(&window, "lskill0", false, false); connect_signal_mouse_left_click( *lskill0_ , boost::bind( &tduel::on_deadfight , this , boost::ref(window))); lskill1_ = find_widget<ttoggle_button>(&window, "lskill1", false, false); connect_signal_mouse_left_click( *lskill1_ , boost::bind( &tduel::on_fightback , this , boost::ref(window))); find_widget<ttoggle_button>(&window, "lturn0", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "lturn0_skill", false, false)->set_visible(twidget::INVISIBLE); find_widget<tlabel>(&window, "turn0", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn0", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn0_skill", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "lturn1", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "lturn1_skill", false, false)->set_visible(twidget::INVISIBLE); find_widget<tlabel>(&window, "turn1", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn1", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn1_skill", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "lturn2", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "lturn2_skill", false, false)->set_visible(twidget::INVISIBLE); find_widget<tlabel>(&window, "turn2", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn2", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn2_skill", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "lturn3", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "lturn3_skill", false, false)->set_visible(twidget::INVISIBLE); find_widget<tlabel>(&window, "turn3", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn3", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn3_skill", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "lturn4", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "lturn4_skill", false, false)->set_visible(twidget::INVISIBLE); find_widget<tlabel>(&window, "turn4", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn4", false, false)->set_visible(twidget::INVISIBLE); find_widget<ttoggle_button>(&window, "rturn4_skill", false, false)->set_visible(twidget::INVISIBLE); reset_turn(window); }
void ttext::draw(surface& canvas , const game_logic::map_formula_callable& variables) { assert(variables.has_key("text")); // We first need to determine the size of the text which need the rendered // text. So resolve and render the text first and then start to resolve // the other formulas. const t_string text = text_(variables); // Björn: Add text to canvas labels here if(text.empty()) { DBG_GUI_D << "Text: no text to render, leave.\n"; return; } static font::ttext text_renderer; text_renderer.set_text(text, text_markup_(variables)); text_renderer.set_font_size(font_size_) .set_font_style(font_style_) .set_alignment(text_alignment_(variables)) .set_foreground_color(color_) .set_maximum_width(maximum_width_(variables)) .set_maximum_height(maximum_height_(variables)) .set_ellipse_mode(variables.has_key("text_wrap_mode") ? static_cast<PangoEllipsizeMode> (variables.query_value("text_wrap_mode").as_int()) : PANGO_ELLIPSIZE_END); surface surf = text_renderer.render(); if(surf->w == 0) { DBG_GUI_D << "Text: Rendering '" << text << "' resulted in an empty canvas, leave.\n"; return; } game_logic::map_formula_callable local_variables(variables); local_variables.add("text_width", variant(surf->w)); local_variables.add("text_height", variant(surf->h)); /* std::cerr << "Text: drawing text '" << text << " maximum width " << maximum_width_(variables) << " maximum height " << maximum_height_(variables) << " text width " << surf->w << " text height " << surf->h; */ ///@todo formulas are now recalculated every draw cycle which is a // bit silly unless there has been a resize. So to optimize we should // use an extra flag or do the calculation in a separate routine. const unsigned x = x_(local_variables); const unsigned y = y_(local_variables); const unsigned w = w_(local_variables); const unsigned h = h_(local_variables); DBG_GUI_D << "Text: drawing text '" << text << "' drawn from " << x << ',' << y << " width " << w << " height " << h << " canvas size " << canvas->w << ',' << canvas->h << ".\n"; VALIDATE(static_cast<int>(x) < canvas->w && static_cast<int>(y) < canvas->h , _("Text doesn't start on canvas.")); // A text might be to long and will be clipped. if(surf->w > static_cast<int>(w)) { WRN_GUI_D << "Text: text is too wide for the " "canvas and will be clipped.\n"; } if(surf->h > static_cast<int>(h)) { WRN_GUI_D << "Text: text is too high for the " "canvas and will be clipped.\n"; } SDL_Rect dst = ::create_rect(x, y, canvas->w, canvas->h); blit_surface(surf, 0, canvas, &dst); }
void OculusRiftNode::render( qint64 pTimeStamp, QUuid pSourcePinId ) { Q_UNUSED( pSourcePinId ) #if !defined( OCULUS_PLUGIN_SUPPORTED ) Q_UNUSED( pTimeStamp ) #else fugio::Performance Perf( mNode, "drawGeometry", pTimeStamp ); if( !mNode->isInitialised() ) { return; } if( !mOculusRift->hmd() ) { return; } // We need to keep a reference to ourselves here as ovr_SubmitFrame can // call the main app event loop, which can close the context and delete us! QSharedPointer<fugio::NodeControlInterface> C = mNode->control(); mOculusRift->drawStart(); const float NearPlane = variant( mPinNearPlane ).toFloat(); const float FarPlane = variant( mPinFarPlane ).toFloat(); // float Yaw(3.141592f); // Vector3f Pos2(0.0f,1.6f,-5.0f); // Pos2.y = ovrHmd_GetFloat(mHMD, OVR_KEY_EYE_HEIGHT, Pos2.y); QMatrix4x4 MatEye = variant( mPinViewMatrix ).value<QMatrix4x4>(); QVector3D TrnEye = MatEye.column( 3 ).toVector3D(); MatEye.setColumn( 3, QVector4D( 0, 0, 0, 1 ) ); const Vector3f Pos2( TrnEye.x(), TrnEye.y(), TrnEye.z() ); Matrix4f tempRollPitchYaw; memcpy( tempRollPitchYaw.M, MatEye.constData(), sizeof( float ) * 16 ); const Matrix4f rollPitchYaw = tempRollPitchYaw; // Render Scene to Eye Buffers for (int eye = 0; eye < 2; eye++) { mOculusRift->drawEyeStart( eye ); // Get view and projection matrices //Matrix4f rollPitchYaw = Matrix4f( MatEye.transposed().data() ); Matrix4f finalRollPitchYaw = rollPitchYaw * Matrix4f( mOculusRift->eyeRenderPos( eye ).Orientation); Vector3f finalUp = finalRollPitchYaw.Transform(Vector3f(0, 1, 0)); Vector3f finalForward = finalRollPitchYaw.Transform(Vector3f(0, 0, -1)); Vector3f shiftedEyePos = Pos2 + rollPitchYaw.Transform( mOculusRift->eyeRenderPos( eye ).Position ); Matrix4f view = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + finalForward, finalUp); Matrix4f proj = ovrMatrix4f_Projection( mOculusRift->defaultEyeFOV( eye ), NearPlane, FarPlane, ovrProjection_None ); mProjection->setVariant( QMatrix4x4( &proj.M[ 0 ][ 0 ], 4, 4 ).transposed() ); mView->setVariant( QMatrix4x4( &view.M[ 0 ][ 0 ], 4, 4 ).transposed() ); fugio::OpenGLStateInterface *CurrentState = 0; for( QSharedPointer<fugio::PinInterface> P : mNode->enumInputPins() ) { if( !P->isConnected() ) { continue; } if( P->connectedPin().isNull() ) { continue; } if( P->connectedPin()->control().isNull() ) { continue; } QObject *O = P->connectedPin()->control()->qobject(); if( !O ) { continue; } if( true ) { fugio::RenderInterface *Geometry = qobject_cast<fugio::RenderInterface *>( O ); if( Geometry ) { Geometry->render( pTimeStamp ); continue; } } if( true ) { fugio::OpenGLStateInterface *NextState = qobject_cast<fugio::OpenGLStateInterface *>( O ); if( NextState != 0 ) { if( CurrentState != 0 ) { CurrentState->stateEnd(); } CurrentState = NextState; CurrentState->stateBegin(); continue; } } } if( CurrentState != 0 ) { CurrentState->stateEnd(); } mOculusRift->drawEyeEnd( eye ); } mOculusRift->drawEnd(); pinUpdated( mPinProjection ); pinUpdated( mPinView ); #endif }
void add( mutable_variant_object& vo, const char* name, const M& v )const { vo(name, variant( v, _max_depth )); }
bool basic_unit_filter_impl::internal_matches_filter(const unit & u, const map_location& loc, const unit* u2) const { if (!vcfg["name"].blank() && vcfg["name"].t_str() != u.name()) { return false; } if (!vcfg["id"].empty()) { std::vector<std::string> id_list = utils::split(vcfg["id"]); if (std::find(id_list.begin(), id_list.end(), u.id()) == id_list.end()) { return false; } } // Allow 'speaker' as an alternative to id, since people use it so often if (!vcfg["speaker"].blank() && vcfg["speaker"].str() != u.id()) { return false; } if (vcfg.has_child("filter_location")) { if (vcfg.count_children("filter_location") > 1) { FAIL("Encountered multiple [filter_location] children of a standard unit filter. " "This is not currently supported and in all versions of wesnoth would have " "resulted in the later children being ignored. You must use [and] or similar " "to achieve the desired result."); } terrain_filter filt(vcfg.child("filter_location"), &fc_, use_flat_tod_); if (!filt.match(loc)) { return false; } } if(vcfg.has_child("filter_side")) { if (vcfg.count_children("filter_side") > 1) { FAIL("Encountered multiple [filter_side] children of a standard unit filter. " "This is not currently supported and in all versions of wesnoth would have " "resulted in the later children being ignored. You must use [and] or similar " "to achieve the desired result."); } side_filter filt(vcfg.child("filter_side"), &fc_); if(!filt.match(u.side())) return false; } // Also allow filtering on location ranges outside of the location filter if (!vcfg["x"].blank() || !vcfg["y"].blank()){ if(vcfg["x"] == "recall" && vcfg["y"] == "recall") { //locations on the map are considered to not be on a recall list if (fc_.get_disp_context().map().on_board(loc)) { return false; } } else if(vcfg["x"].empty() && vcfg["y"].empty()) { return false; } else if(!loc.matches_range(vcfg["x"], vcfg["y"])) { return false; } } // The type could be a comma separated list of types if (!vcfg["type"].empty()) { std::vector<std::string> types = utils::split(vcfg["type"]); if (std::find(types.begin(), types.end(), u.type_id()) == types.end()) { return false; } } // Shorthand for all advancements of a given type if (!vcfg["type_tree"].empty()) { std::set<std::string> types; for(const std::string type : utils::split(vcfg["type_tree"])) { if(types.count(type)) { continue; } if(const unit_type* ut = unit_types.find(type)) { const auto& tree = ut->advancement_tree(); types.insert(tree.begin(), tree.end()); types.insert(type); } } if(types.find(u.type_id()) == types.end()) { return false; } } // The variation_type could be a comma separated list of types if (!vcfg["variation"].empty()) { std::vector<std::string> types = utils::split(vcfg["variation"]); if (std::find(types.begin(), types.end(), u.variation()) == types.end()) { return false; } } // The has_variation_type could be a comma separated list of types if (!vcfg["has_variation"].empty()) { bool match = false; // If this unit is a variation itself then search in the base unit's variations. const unit_type* const type = u.variation().empty() ? &u.type() : unit_types.find(u.type().base_id()); assert(type); for (const std::string& variation_id : utils::split(vcfg["has_variation"])) { if (type->has_variation(variation_id)) { match = true; break; } } if (!match) return false; } if (!vcfg["ability"].empty()) { bool match = false; for (const std::string& ability_id : utils::split(vcfg["ability"])) { if (u.has_ability_by_id(ability_id)) { match = true; break; } } if (!match) return false; } if (!vcfg["race"].empty()) { std::vector<std::string> races = utils::split(vcfg["race"]); if (std::find(races.begin(), races.end(), u.race()->id()) == races.end()) { return false; } } if (!vcfg["gender"].blank() && string_gender(vcfg["gender"]) != u.gender()) { return false; } if (!vcfg["side"].empty() && vcfg["side"].to_int(-999) != u.side()) { std::vector<std::string> sides = utils::split(vcfg["side"]); const std::string u_side = std::to_string(u.side()); if (std::find(sides.begin(), sides.end(), u_side) == sides.end()) { return false; } } // handle statuses list if (!vcfg["status"].empty()) { bool status_found = false; for (const std::string status : utils::split(vcfg["status"])) { if(u.get_state(status)) { status_found = true; break; } } if(!status_found) { return false; } } if (vcfg.has_child("has_attack")) { const vconfig& weap_filter = vcfg.child("has_attack"); bool has_weapon = false; for(const attack_type& a : u.attacks()) { if(a.matches_filter(weap_filter.get_parsed_config())) { has_weapon = true; break; } } if(!has_weapon) { return false; } } else if (!vcfg["has_weapon"].blank()) { std::string weapon = vcfg["has_weapon"]; bool has_weapon = false; for(const attack_type& a : u.attacks()) { if(a.id() == weapon) { has_weapon = true; break; } } if(!has_weapon) { return false; } } if (!vcfg["role"].blank() && vcfg["role"].str() != u.get_role()) { return false; } if (!vcfg["ai_special"].blank() && ((vcfg["ai_special"].str() == "guardian") != u.get_state(unit::STATE_GUARDIAN))) { return false; } if (!vcfg["canrecruit"].blank() && vcfg["canrecruit"].to_bool() != u.can_recruit()) { return false; } if (!vcfg["recall_cost"].blank() && vcfg["recall_cost"].to_int(-1) != u.recall_cost()) { return false; } if (!vcfg["level"].blank() && vcfg["level"].to_int(-1) != u.level()) { return false; } if (!vcfg["defense"].blank() && vcfg["defense"].to_int(-1) != u.defense_modifier(fc_.get_disp_context().map().get_terrain(loc))) { return false; } if (!vcfg["movement_cost"].blank() && vcfg["movement_cost"].to_int(-1) != u.movement_cost(fc_.get_disp_context().map().get_terrain(loc))) { return false; } // Now start with the new WML based comparison. // If a key is in the unit and in the filter, they should match // filter only => not for us // unit only => not filtered config unit_cfg; // No point in serializing the unit once for each [filter_wml]! for (const vconfig& wmlcfg : vcfg.get_children("filter_wml")) { config fwml = wmlcfg.get_parsed_config(); /* Check if the filter only cares about variables. If so, no need to serialize the whole unit. */ config::all_children_itors ci = fwml.all_children_range(); if (fwml.all_children_count() == 1 && fwml.attribute_count() == 1 && ci.front().key == "variables") { if (!u.variables().matches(ci.front().cfg)) return false; } else { if (unit_cfg.empty()) u.write(unit_cfg); if (!unit_cfg.matches(fwml)) return false; } } for (const vconfig& vision : vcfg.get_children("filter_vision")) { std::set<int> viewers; // Use standard side filter side_filter ssf(vision, &fc_); std::vector<int> sides = ssf.get_teams(); viewers.insert(sides.begin(), sides.end()); bool found = false; for (const int viewer : viewers) { bool fogged = fc_.get_disp_context().teams()[viewer - 1].fogged(loc); bool hiding = u.invisible(loc, fc_.get_disp_context()) && fc_.get_disp_context().teams()[viewer - 1].is_enemy(u.side()); bool unit_hidden = fogged || hiding; if (vision["visible"].to_bool(true) != unit_hidden) { found = true; break; } } if (!found) {return false;} } if (vcfg.has_child("filter_adjacent")) { const unit_map& units = fc_.get_disp_context().units(); map_location adjacent[6]; get_adjacent_tiles(loc, adjacent); for (const vconfig& adj_cfg : vcfg.get_children("filter_adjacent")) { int match_count=0; unit_filter filt(adj_cfg, &fc_, use_flat_tod_); config::attribute_value i_adjacent = adj_cfg["adjacent"]; std::vector<map_location::DIRECTION> dirs; if (i_adjacent.blank()) { dirs = map_location::default_dirs(); } else { dirs = map_location::parse_directions(i_adjacent); } std::vector<map_location::DIRECTION>::const_iterator j, j_end = dirs.end(); for (j = dirs.begin(); j != j_end; ++j) { unit_map::const_iterator unit_itor = units.find(adjacent[*j]); if (unit_itor == units.end() || !filt(*unit_itor, u)) { continue; } boost::optional<bool> is_enemy; if (!adj_cfg["is_enemy"].blank()) { is_enemy = adj_cfg["is_enemy"].to_bool(); } if (!is_enemy || *is_enemy == fc_.get_disp_context().teams()[u.side() - 1].is_enemy(unit_itor->side())) { ++match_count; } } static std::vector<std::pair<int,int> > default_counts = utils::parse_ranges("1-6"); config::attribute_value i_count = adj_cfg["count"]; if(!in_ranges(match_count, !i_count.blank() ? utils::parse_ranges(i_count) : default_counts)) { return false; } } } if (!vcfg["find_in"].blank()) { // Allow filtering by searching a stored variable of units if (const game_data * gd = fc_.get_game_data()) { try { variable_access_const vi = gd->get_variable_access_read(vcfg["find_in"]); bool found_id = false; for (const config& c : vi.as_array()) { if(c["id"] == u.id()) found_id = true; } if(!found_id) { return false; } } catch(const invalid_variablename_exception&) { return false; } } } if (!vcfg["formula"].blank()) { try { const unit_callable main(loc,u); game_logic::map_formula_callable callable(&main); if (u2) { std::shared_ptr<unit_callable> secondary(new unit_callable(*u2)); callable.add("other", variant(secondary.get())); // It's not destroyed upon scope exit because the variant holds a reference } const game_logic::formula form(vcfg["formula"]); if(!form.evaluate(callable).as_bool()) { return false; } return true; } catch(game_logic::formula_error& e) { lg::wml_error() << "Formula error in unit filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; // Formulae with syntax errors match nothing return false; } } if (!vcfg["lua_function"].blank()) { if (game_lua_kernel * lk = fc_.get_lua_kernel()) { bool b = lk->run_filter(vcfg["lua_function"].str().c_str(), u); if (!b) return false; } } return true; }