void ScriptEditorDebugger::_parse_message(const String& p_msg,const Array& p_data) { if (p_msg=="debug_enter") { Array msg; msg.push_back("get_stack_dump"); ppeer->put_var(msg); ERR_FAIL_COND(p_data.size()!=2); bool can_continue=p_data[0]; String error = p_data[1]; step->set_disabled(!can_continue); next->set_disabled(!can_continue); reason->set_text(error); reason->set_tooltip(error); breaked=true; dobreak->set_disabled(true); docontinue->set_disabled(false); emit_signal("breaked",true,can_continue); OS::get_singleton()->move_window_to_foreground(); tabs->set_current_tab(0); } else if (p_msg=="debug_exit") { breaked=false; step->set_disabled(true); next->set_disabled(true); reason->set_text(""); reason->set_tooltip(""); back->set_disabled(true); forward->set_disabled(true); dobreak->set_disabled(false); docontinue->set_disabled(true); emit_signal("breaked",false,false); //tabs->set_current_tab(0); } else if (p_msg=="message:click_ctrl") { clicked_ctrl->set_text(p_data[0]); clicked_ctrl_type->set_text(p_data[1]); } else if (p_msg=="message:scene_tree") { scene_tree->clear(); Map<int,TreeItem*> lv; for(int i=0;i<p_data.size();i+=3) { TreeItem *p; int level = p_data[i]; if (level==0) { p = NULL; } else { ERR_CONTINUE(!lv.has(level-1)); p=lv[level-1]; } TreeItem *it = scene_tree->create_item(p); it->set_text(0,p_data[i+1]); if (has_icon(p_data[i+2],"EditorIcons")) it->set_icon(0,get_icon(p_data[i+2],"EditorIcons")); lv[level]=it; } le_clear->set_disabled(false); le_set->set_disabled(false); } else if (p_msg=="message:video_mem") { vmem_tree->clear(); TreeItem* root=vmem_tree->create_item(); int total=0; for(int i=0;i<p_data.size();i+=4) { TreeItem *it = vmem_tree->create_item(root); String type=p_data[i+1]; int bytes=p_data[i+3].operator int(); it->set_text(0,p_data[i+0]); //path it->set_text(1,type); //type it->set_text(2,p_data[i+2]); //type it->set_text(3,String::humanize_size(bytes)); //type total+=bytes; if (has_icon(type,"EditorIcons")) it->set_icon(0,get_icon(type,"EditorIcons")); } vmem_total->set_tooltip("Bytes: "+itos(total)); vmem_total->set_text(String::humanize_size(total)); } else if (p_msg=="stack_dump") { stack_dump->clear(); TreeItem *r = stack_dump->create_item(); for(int i=0;i<p_data.size();i++) { Dictionary d = p_data[i]; ERR_CONTINUE(!d.has("function")); ERR_CONTINUE(!d.has("file")); ERR_CONTINUE(!d.has("line")); ERR_CONTINUE(!d.has("id")); TreeItem *s = stack_dump->create_item(r); d["frame"]=i; s->set_metadata(0,d); // String line = itos(i)+" - "+String(d["file"])+":"+itos(d["line"])+" - at func: "+d["function"]; String line = itos(i)+" - "+String(d["file"])+":"+itos(d["line"]); s->set_text(0,line); if (i==0) s->select(0); } } else if (p_msg=="stack_frame_vars") { variables->clear(); int ofs =0; int mcount = p_data[ofs]; ofs++; for(int i=0;i<mcount;i++) { String n = p_data[ofs+i*2+0]; Variant v = p_data[ofs+i*2+1]; if (n.begins_with("*")) { n=n.substr(1,n.length()); } variables->add_property("members/"+n,v); } ofs+=mcount*2; mcount = p_data[ofs]; ofs++; for(int i=0;i<mcount;i++) { String n = p_data[ofs+i*2+0]; Variant v = p_data[ofs+i*2+1]; if (n.begins_with("*")) { n=n.substr(1,n.length()); } variables->add_property("locals/"+n,v); } variables->update(); inspector->edit(variables); } else if (p_msg=="output") { //OUT for(int i=0;i<p_data.size();i++) { String t = p_data[i]; //LOG if (EditorNode::get_log()->is_hidden()) { log_forced_visible=true; EditorNode::get_log()->show(); } EditorNode::get_log()->add_message(t); } } else if (p_msg=="performance") { Array arr = p_data[0]; Vector<float> p; p.resize(arr.size()); for(int i=0;i<arr.size();i++) { p[i]=arr[i]; if (i<perf_items.size()) { perf_items[i]->set_text(1,rtos(p[i])); if (p[i]>perf_max[i]) perf_max[i]=p[i]; } } perf_history.push_front(p); perf_draw->update(); } else if (p_msg=="error") { Array err = p_data[0]; Array vals; vals.push_back(err[0]); vals.push_back(err[1]); vals.push_back(err[2]); vals.push_back(err[3]); bool warning = err[9]; bool e; String time = String("%d:%02d:%02d:%04d").sprintf(vals,&e); String txt=time+" - "+String(err[8]); String tooltip="Type:"+String(warning?"Warning":"Error"); tooltip+="\nDescription: "+String(err[8]); tooltip+="\nTime: "+time; tooltip+="\nC Error: "+String(err[7]); tooltip+="\nC Source: "+String(err[5])+":"+String(err[6]); tooltip+="\nC Function: "+String(err[4]); error_list->add_item(txt,EditorNode::get_singleton()->get_gui_base()->get_icon(warning?"Warning":"Error","EditorIcons")); error_list->set_item_tooltip( error_list->get_item_count() -1,tooltip ); int scc = p_data[1]; Array stack; stack.resize(scc); for(int i=0;i<scc;i++) { stack[i]=p_data[2+i]; } error_list->set_item_metadata( error_list->get_item_count() -1,stack ); error_count++; /* int count = p_data[1]; Array cstack; OutputError oe = errors.front()->get(); packet_peer_stream->put_var(oe.hr); packet_peer_stream->put_var(oe.min); packet_peer_stream->put_var(oe.sec); packet_peer_stream->put_var(oe.msec); packet_peer_stream->put_var(oe.source_func); packet_peer_stream->put_var(oe.source_file); packet_peer_stream->put_var(oe.source_line); packet_peer_stream->put_var(oe.error); packet_peer_stream->put_var(oe.error_descr); packet_peer_stream->put_var(oe.warning); packet_peer_stream->put_var(oe.callstack); */ } else if (p_msg=="kill_me") { editor->call_deferred("stop_child_process"); } }
MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type) { switch (p_type.type_encoding) { case MONO_TYPE_BOOLEAN: { MonoBoolean val = p_var->operator bool(); return BOX_BOOLEAN(val); } case MONO_TYPE_I1: { char val = p_var->operator signed char(); return BOX_INT8(val); } case MONO_TYPE_I2: { short val = p_var->operator signed short(); return BOX_INT16(val); } case MONO_TYPE_I4: { int val = p_var->operator signed int(); return BOX_INT32(val); } case MONO_TYPE_I8: { int64_t val = p_var->operator int64_t(); return BOX_INT64(val); } case MONO_TYPE_U1: { char val = p_var->operator unsigned char(); return BOX_UINT8(val); } case MONO_TYPE_U2: { short val = p_var->operator unsigned short(); return BOX_UINT16(val); } case MONO_TYPE_U4: { int val = p_var->operator unsigned int(); return BOX_UINT32(val); } case MONO_TYPE_U8: { uint64_t val = p_var->operator uint64_t(); return BOX_UINT64(val); } case MONO_TYPE_R4: { float val = p_var->operator float(); return BOX_FLOAT(val); } case MONO_TYPE_R8: { double val = p_var->operator double(); return BOX_DOUBLE(val); } case MONO_TYPE_STRING: { return (MonoObject *)mono_string_from_godot(p_var->operator String()); } break; case MONO_TYPE_VALUETYPE: { GDMonoClass *tclass = p_type.type_class; if (tclass == CACHED_CLASS(Vector2)) RETURN_BOXED_STRUCT(Vector2, p_var); if (tclass == CACHED_CLASS(Rect2)) RETURN_BOXED_STRUCT(Rect2, p_var); if (tclass == CACHED_CLASS(Transform2D)) RETURN_BOXED_STRUCT(Transform2D, p_var); if (tclass == CACHED_CLASS(Vector3)) RETURN_BOXED_STRUCT(Vector3, p_var); if (tclass == CACHED_CLASS(Basis)) RETURN_BOXED_STRUCT(Basis, p_var); if (tclass == CACHED_CLASS(Quat)) RETURN_BOXED_STRUCT(Quat, p_var); if (tclass == CACHED_CLASS(Transform)) RETURN_BOXED_STRUCT(Transform, p_var); if (tclass == CACHED_CLASS(Rect3)) RETURN_BOXED_STRUCT(Rect3, p_var); if (tclass == CACHED_CLASS(Color)) RETURN_BOXED_STRUCT(Color, p_var); if (tclass == CACHED_CLASS(Plane)) RETURN_BOXED_STRUCT(Plane, p_var); } break; case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(GDMonoClass::get_raw_type(p_type.type_class)); if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) return (MonoObject *)Array_to_mono_array(p_var->operator Array()); if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray()); if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray()); if (array_type->eklass == REAL_T_MONOCLASS) return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray()); if (array_type->eklass == CACHED_CLASS_RAW(String)) return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray()); if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array()); if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array()); if (array_type->eklass == CACHED_CLASS_RAW(Color)) return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray()); ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type."); ERR_FAIL_V(NULL); } break; case MONO_TYPE_CLASS: { GDMonoClass *type_class = p_type.type_class; // GodotObject if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); } if (CACHED_CLASS(NodePath) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator NodePath()); } if (CACHED_CLASS(RID) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator RID()); } } break; case MONO_TYPE_OBJECT: { // Variant switch (p_var->get_type()) { case Variant::BOOL: { MonoBoolean val = p_var->operator bool(); return BOX_BOOLEAN(val); } case Variant::INT: { int val = p_var->operator signed int(); return BOX_INT32(val); } case Variant::REAL: { #ifdef REAL_T_IS_DOUBLE double val = p_var->operator double(); return BOX_DOUBLE(val); #else float val = p_var->operator float(); return BOX_FLOAT(val); #endif } case Variant::STRING: return (MonoObject *)mono_string_from_godot(p_var->operator String()); case Variant::VECTOR2: RETURN_BOXED_STRUCT(Vector2, p_var); case Variant::RECT2: RETURN_BOXED_STRUCT(Rect2, p_var); case Variant::VECTOR3: RETURN_BOXED_STRUCT(Vector3, p_var); case Variant::TRANSFORM2D: RETURN_BOXED_STRUCT(Transform2D, p_var); case Variant::PLANE: RETURN_BOXED_STRUCT(Plane, p_var); case Variant::QUAT: RETURN_BOXED_STRUCT(Quat, p_var); case Variant::RECT3: RETURN_BOXED_STRUCT(Rect3, p_var); case Variant::BASIS: RETURN_BOXED_STRUCT(Basis, p_var); case Variant::TRANSFORM: RETURN_BOXED_STRUCT(Transform, p_var); case Variant::COLOR: RETURN_BOXED_STRUCT(Color, p_var); case Variant::NODE_PATH: return GDMonoUtils::create_managed_from(p_var->operator NodePath()); case Variant::_RID: return GDMonoUtils::create_managed_from(p_var->operator RID()); case Variant::OBJECT: { return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); } case Variant::DICTIONARY: return Dictionary_to_mono_object(p_var->operator Dictionary()); case Variant::ARRAY: return (MonoObject *)Array_to_mono_array(p_var->operator Array()); case Variant::POOL_BYTE_ARRAY: return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray()); case Variant::POOL_INT_ARRAY: return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray()); case Variant::POOL_REAL_ARRAY: return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray()); case Variant::POOL_STRING_ARRAY: return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray()); case Variant::POOL_VECTOR2_ARRAY: return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array()); case Variant::POOL_VECTOR3_ARRAY: return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array()); case Variant::POOL_COLOR_ARRAY: return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray()); default: return NULL; } break; case MONO_TYPE_GENERICINST: { if (CACHED_RAW_MONO_CLASS(Dictionary) == p_type.type_class->get_raw()) { return Dictionary_to_mono_object(p_var->operator Dictionary()); } } break; } break; } ERR_EXPLAIN(String() + "Attempted to convert Variant to an unmarshallable managed type. Name: \'" + p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding)); ERR_FAIL_V(NULL); }
Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) { switch (p_type.type_encoding) { case MONO_TYPE_BOOLEAN: return (bool)unbox<MonoBoolean>(p_obj); case MONO_TYPE_I1: return unbox<int8_t>(p_obj); case MONO_TYPE_I2: return unbox<int16_t>(p_obj); case MONO_TYPE_I4: return unbox<int32_t>(p_obj); case MONO_TYPE_I8: return unbox<int64_t>(p_obj); case MONO_TYPE_U1: return unbox<uint8_t>(p_obj); case MONO_TYPE_U2: return unbox<uint16_t>(p_obj); case MONO_TYPE_U4: return unbox<uint32_t>(p_obj); case MONO_TYPE_U8: return unbox<uint64_t>(p_obj); case MONO_TYPE_R4: return unbox<float>(p_obj); case MONO_TYPE_R8: return unbox<double>(p_obj); case MONO_TYPE_STRING: { String str = mono_string_to_godot((MonoString *)p_obj); return str; } break; case MONO_TYPE_VALUETYPE: { GDMonoClass *tclass = p_type.type_class; if (tclass == CACHED_CLASS(Vector2)) RETURN_UNBOXED_STRUCT(Vector2, p_obj); if (tclass == CACHED_CLASS(Rect2)) RETURN_UNBOXED_STRUCT(Rect2, p_obj); if (tclass == CACHED_CLASS(Transform2D)) RETURN_UNBOXED_STRUCT(Transform2D, p_obj); if (tclass == CACHED_CLASS(Vector3)) RETURN_UNBOXED_STRUCT(Vector3, p_obj); if (tclass == CACHED_CLASS(Basis)) RETURN_UNBOXED_STRUCT(Basis, p_obj); if (tclass == CACHED_CLASS(Quat)) RETURN_UNBOXED_STRUCT(Quat, p_obj); if (tclass == CACHED_CLASS(Transform)) RETURN_UNBOXED_STRUCT(Transform, p_obj); if (tclass == CACHED_CLASS(Rect3)) RETURN_UNBOXED_STRUCT(Rect3, p_obj); if (tclass == CACHED_CLASS(Color)) RETURN_UNBOXED_STRUCT(Color, p_obj); if (tclass == CACHED_CLASS(Plane)) RETURN_UNBOXED_STRUCT(Plane, p_obj); } break; case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(GDMonoClass::get_raw_type(p_type.type_class)); if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) return mono_array_to_Array((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) return mono_array_to_PoolByteArray((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) return mono_array_to_PoolIntArray((MonoArray *)p_obj); if (array_type->eklass == REAL_T_MONOCLASS) return mono_array_to_PoolRealArray((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(String)) return mono_array_to_PoolStringArray((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) return mono_array_to_PoolVector2Array((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) return mono_array_to_PoolVector3Array((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(Color)) return mono_array_to_PoolColorArray((MonoArray *)p_obj); ERR_EXPLAIN(String() + "Attempted to convert a managed array of unmarshallable element type to Variant."); ERR_FAIL_V(Variant()); } break; case MONO_TYPE_CLASS: { GDMonoClass *type_class = p_type.type_class; // GodotObject if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { Object *ptr = unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj)); return ptr ? Variant(ptr) : Variant(); } if (CACHED_CLASS(NodePath) == type_class) { NodePath *ptr = unbox<NodePath *>(CACHED_FIELD(NodePath, ptr)->get_value(p_obj)); return ptr ? Variant(*ptr) : Variant(); } if (CACHED_CLASS(RID) == type_class) { RID *ptr = unbox<RID *>(CACHED_FIELD(RID, ptr)->get_value(p_obj)); return ptr ? Variant(*ptr) : Variant(); } } break; case MONO_TYPE_GENERICINST: { if (CACHED_RAW_MONO_CLASS(Dictionary) == p_type.type_class->get_raw()) { return mono_object_to_Dictionary(p_obj); } } break; } ERR_EXPLAIN(String() + "Attempted to convert an unmarshallable managed type to Variant. Name: \'" + p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding)); ERR_FAIL_V(Variant()); }
bool Settings::setU16(const std::string &name, u16 value) { return set(name, itos(value)); }
bool Settings::setS32(const std::string &name, s32 value) { return set(name, itos(value)); }
void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int p_code, const PoolStringArray &headers, const PoolByteArray &p_data) { String error_text; print_line("COMPLETED: " + itos(p_status) + " code: " + itos(p_code) + " data size: " + itos(p_data.size())); switch (p_status) { case HTTPRequest::RESULT_CANT_RESOLVE: { error_text = TTR("Can't resolve hostname:") + " " + host; status->set_text(TTR("Can't resolve.")); } break; case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED: case HTTPRequest::RESULT_CONNECTION_ERROR: case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: { error_text = TTR("Connection error, please try again."); status->set_text(TTR("Can't connect.")); } break; case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR: case HTTPRequest::RESULT_CANT_CONNECT: { error_text = TTR("Can't connect to host:") + " " + host; status->set_text(TTR("Can't connect.")); } break; case HTTPRequest::RESULT_NO_RESPONSE: { error_text = TTR("No response from host:") + " " + host; status->set_text(TTR("No response.")); } break; case HTTPRequest::RESULT_REQUEST_FAILED: { error_text = TTR("Request failed, return code:") + " " + itos(p_code); status->set_text(TTR("Req. Failed.")); } break; case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: { error_text = TTR("Request failed, too many redirects"); status->set_text(TTR("Redirect Loop.")); } break; default: { if (p_code != 200) { error_text = TTR("Request failed, return code:") + " " + itos(p_code); status->set_text(TTR("Failed:") + " " + itos(p_code)); } else if (sha256 != "") { String download_sha256 = FileAccess::get_sha256(download->get_download_file()); if (sha256 != download_sha256) { error_text = TTR("Bad download hash, assuming file has been tampered with.") + "\n"; error_text += TTR("Expected:") + " " + sha256 + "\n" + TTR("Got:") + " " + download_sha256; status->set_text(TTR("Failed sha256 hash check")); } } } break; } if (error_text != String()) { download_error->set_text(TTR("Asset Download Error:") + "\n" + error_text); download_error->popup_centered_minsize(); return; } progress->set_max(download->get_body_size()); progress->set_value(download->get_downloaded_bytes()); print_line("max: " + itos(download->get_body_size()) + " bytes: " + itos(download->get_downloaded_bytes())); install->set_disabled(false); progress->set_value(download->get_downloaded_bytes()); status->set_text(TTR("Success!") + " (" + String::humanize_size(download->get_downloaded_bytes()) + ")"); set_process(false); }
bool ClientLauncher::launch_game(std::string &error_message, bool reconnect_requested, GameParams &game_params, const Settings &cmd_args) { // Initialize menu data MainMenuData menudata; menudata.address = address; menudata.name = playername; menudata.port = itos(game_params.socket_port); menudata.script_data.errormessage = error_message; menudata.script_data.reconnect_requested = reconnect_requested; error_message.clear(); if (cmd_args.exists("password")) menudata.password = cmd_args.get("password"); menudata.enable_public = g_settings->getBool("server_announce"); // If a world was commanded, append and select it if (game_params.world_path != "") { worldspec.gameid = getWorldGameId(game_params.world_path, true); worldspec.name = _("[--world parameter]"); if (worldspec.gameid == "") { // Create new worldspec.gameid = g_settings->get("default_game"); worldspec.name += " [new]"; } worldspec.path = game_params.world_path; } /* Show the GUI menu */ if (!skip_main_menu) { main_menu(&menudata); // Skip further loading if there was an exit signal. if (*porting::signal_handler_killstatus()) return false; address = menudata.address; int newport = stoi(menudata.port); if (newport != 0) game_params.socket_port = newport; simple_singleplayer_mode = menudata.simple_singleplayer_mode; std::vector<WorldSpec> worldspecs = getAvailableWorlds(); if (menudata.selected_world >= 0 && menudata.selected_world < (int)worldspecs.size()) { g_settings->set("selected_world_path", worldspecs[menudata.selected_world].path); worldspec = worldspecs[menudata.selected_world]; } } if (!menudata.script_data.errormessage.empty()) { /* The calling function will pass this back into this function upon the * next iteration (if any) causing it to be displayed by the GUI */ error_message = menudata.script_data.errormessage; return false; } if (menudata.name == "") menudata.name = std::string("Guest") + itos(myrand_range(1000, 9999)); else playername = menudata.name; password = menudata.password; g_settings->set("name", playername); current_playername = playername; current_password = password; current_address = address; current_port = game_params.socket_port; // If using simple singleplayer mode, override if (simple_singleplayer_mode) { assert(skip_main_menu == false); current_playername = "singleplayer"; current_password = ""; current_address = ""; current_port = myrand_range(49152, 65535); } else if (address != "") { ServerListSpec server; server["name"] = menudata.servername; server["address"] = menudata.address; server["port"] = menudata.port; server["description"] = menudata.serverdescription; ServerList::insert(server); } infostream << "Selected world: " << worldspec.name << " [" << worldspec.path << "]" << std::endl; if (current_address == "") { // If local game if (worldspec.path == "") { error_message = gettext("No world selected and no address " "provided. Nothing to do."); errorstream << error_message << std::endl; return false; } if (!fs::PathExists(worldspec.path)) { error_message = gettext("Provided world path doesn't exist: ") + worldspec.path; errorstream << error_message << std::endl; return false; } // Load gamespec for required game gamespec = findWorldSubgame(worldspec.path); if (!gamespec.isValid() && !game_params.game_spec.isValid()) { error_message = gettext("Could not find or load game \"") + worldspec.gameid + "\""; errorstream << error_message << std::endl; return false; } if (porting::signal_handler_killstatus()) return true; if (game_params.game_spec.isValid() && game_params.game_spec.id != worldspec.gameid) { warningstream << "Overriding gamespec from \"" << worldspec.gameid << "\" to \"" << game_params.game_spec.id << "\"" << std::endl; gamespec = game_params.game_spec; } if (!gamespec.isValid()) { error_message = gettext("Invalid gamespec."); error_message += " (world.gameid=" + worldspec.gameid + ")"; errorstream << error_message << std::endl; return false; } } return true; }
Error AudioDriverCoreAudio::init() { mutex = Mutex::create(); AudioComponentDescription desc; zeromem(&desc, sizeof(desc)); desc.componentType = kAudioUnitType_Output; #ifdef OSX_ENABLED desc.componentSubType = kAudioUnitSubType_HALOutput; #else desc.componentSubType = kAudioUnitSubType_RemoteIO; #endif desc.componentManufacturer = kAudioUnitManufacturer_Apple; AudioComponent comp = AudioComponentFindNext(NULL, &desc); ERR_FAIL_COND_V(comp == NULL, FAILED); OSStatus result = AudioComponentInstanceNew(comp, &audio_unit); ERR_FAIL_COND_V(result != noErr, FAILED); #ifdef OSX_ENABLED AudioObjectPropertyAddress prop; prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice; prop.mScope = kAudioObjectPropertyScopeGlobal; prop.mElement = kAudioObjectPropertyElementMaster; result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this); ERR_FAIL_COND_V(result != noErr, FAILED); #endif AudioStreamBasicDescription strdesc; zeromem(&strdesc, sizeof(strdesc)); UInt32 size = sizeof(strdesc); result = AudioUnitGetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kOutputBus, &strdesc, &size); ERR_FAIL_COND_V(result != noErr, FAILED); switch (strdesc.mChannelsPerFrame) { case 2: // Stereo case 4: // Surround 3.1 case 6: // Surround 5.1 case 8: // Surround 7.1 channels = strdesc.mChannelsPerFrame; break; default: // Unknown number of channels, default to stereo channels = 2; break; } mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE); zeromem(&strdesc, sizeof(strdesc)); strdesc.mFormatID = kAudioFormatLinearPCM; strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; strdesc.mChannelsPerFrame = channels; strdesc.mSampleRate = mix_rate; strdesc.mFramesPerPacket = 1; strdesc.mBitsPerChannel = 16; strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8; strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket; result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc)); ERR_FAIL_COND_V(result != noErr, FAILED); int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY); // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels) buffer_frames = closest_power_of_2(latency * mix_rate / 1000); #ifdef OSX_ENABLED result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32)); ERR_FAIL_COND_V(result != noErr, FAILED); #endif unsigned int buffer_size = buffer_frames * channels; samples_in.resize(buffer_size); input_buf.resize(buffer_size); input_buffer.resize(buffer_size * 8); input_position = 0; input_size = 0; print_verbose("CoreAudio: detected " + itos(channels) + " channels"); print_verbose("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); AURenderCallbackStruct callback; zeromem(&callback, sizeof(AURenderCallbackStruct)); callback.inputProc = &AudioDriverCoreAudio::output_callback; callback.inputProcRefCon = this; result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback)); ERR_FAIL_COND_V(result != noErr, FAILED); result = AudioUnitInitialize(audio_unit); ERR_FAIL_COND_V(result != noErr, FAILED); return capture_init(); }
String VisualScriptSequence::get_output_sequence_port_text(int p_port) const { return itos(p_port+1); }
void kf::ksavecon(int li){ if (!init) {du("update setup set data=? where id="+itos(1),li);} }
void AudioDriverCoreAudio::_set_device(const String &device, bool capture) { AudioDeviceID deviceId; bool found = false; if (device != "Default") { AudioObjectPropertyAddress prop; prop.mSelector = kAudioHardwarePropertyDevices; prop.mScope = kAudioObjectPropertyScopeGlobal; prop.mElement = kAudioObjectPropertyElementMaster; UInt32 size = 0; AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &prop, 0, NULL, &size); AudioDeviceID *audioDevices = (AudioDeviceID *)malloc(size); AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop, 0, NULL, &size, audioDevices); UInt32 deviceCount = size / sizeof(AudioDeviceID); for (UInt32 i = 0; i < deviceCount && !found; i++) { prop.mScope = capture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; prop.mSelector = kAudioDevicePropertyStreamConfiguration; AudioObjectGetPropertyDataSize(audioDevices[i], &prop, 0, NULL, &size); AudioBufferList *bufferList = (AudioBufferList *)malloc(size); AudioObjectGetPropertyData(audioDevices[i], &prop, 0, NULL, &size, bufferList); UInt32 channelCount = 0; for (UInt32 j = 0; j < bufferList->mNumberBuffers; j++) channelCount += bufferList->mBuffers[j].mNumberChannels; free(bufferList); if (channelCount >= 1) { CFStringRef cfname; size = sizeof(CFStringRef); prop.mSelector = kAudioObjectPropertyName; AudioObjectGetPropertyData(audioDevices[i], &prop, 0, NULL, &size, &cfname); CFIndex length = CFStringGetLength(cfname); CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; char *buffer = (char *)malloc(maxSize); if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) { String name = String(buffer) + " (" + itos(audioDevices[i]) + ")"; if (name == device) { deviceId = audioDevices[i]; found = true; } } free(buffer); } } free(audioDevices); } if (!found) { // If we haven't found the desired device get the system default one UInt32 size = sizeof(AudioDeviceID); UInt32 elem = capture ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice; AudioObjectPropertyAddress property = { elem, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, NULL, &size, &deviceId); ERR_FAIL_COND(result != noErr); found = true; } if (found) { OSStatus result = AudioUnitSetProperty(capture ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID)); ERR_FAIL_COND(result != noErr); if (capture) { // Reset audio input to keep synchronisation. input_position = 0; input_size = 0; } } }
int main(int argc, char *argv[]) { /* Initialization */ log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION); log_add_output_all_levs(&main_dstream_no_stderr_log_out); log_register_thread("main"); // This enables internatonal characters input if( setlocale(LC_ALL, "") == NULL ) { fprintf( stderr, "%s: warning: could not set default locale\n", argv[0] ); } // Set locale. This is for forcing '.' as the decimal point. std::locale::global(std::locale(std::locale(""), "C", std::locale::numeric)); setlocale(LC_NUMERIC, "C"); /* Parse command line */ // List all allowed options core::map<std::string, ValueSpec> allowed_options; allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG, "Run server directly")); allowed_options.insert("config", ValueSpec(VALUETYPE_STRING, "Load configuration from specified file")); allowed_options.insert("port", ValueSpec(VALUETYPE_STRING)); allowed_options.insert("address", ValueSpec(VALUETYPE_STRING)); allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING)); #ifdef _WIN32 allowed_options.insert("dstream-on-stderr", ValueSpec(VALUETYPE_FLAG)); #endif allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG)); allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG)); Settings cmd_args; bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options); if(ret == false || cmd_args.getFlag("help")) { dstream<<"Allowed options:"<<std::endl; for(core::map<std::string, ValueSpec>::Iterator i = allowed_options.getIterator(); i.atEnd() == false; i++) { dstream<<" --"<<i.getNode()->getKey(); if(i.getNode()->getValue().type == VALUETYPE_FLAG) { } else { dstream<<" <value>"; } dstream<<std::endl; if(i.getNode()->getValue().help != NULL) { dstream<<" "<<i.getNode()->getValue().help <<std::endl; } } return cmd_args.getFlag("help") ? 0 : 1; } /* Low-level initialization */ bool disable_stderr = false; #ifdef _WIN32 if(cmd_args.getFlag("dstream-on-stderr") == false) disable_stderr = true; #endif if(cmd_args.getFlag("info-on-stderr")) log_add_output(&main_stderr_log_out, LMT_INFO); porting::signal_handler_init(); bool &kill = *porting::signal_handler_killstatus(); // Initialize porting::path_data and porting::path_userdata porting::initializePaths(); // Create user data directory fs::CreateDir(porting::path_userdata); init_gettext((porting::path_data+DIR_DELIM+".."+DIR_DELIM+"locale").c_str()); // Initialize debug streams #ifdef RUN_IN_PLACE std::string debugfile = DEBUGFILE; #else std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE; #endif debugstreams_init(disable_stderr, debugfile.c_str()); // Initialize debug stacks debug_stacks_init(); DSTACK(__FUNCTION_NAME); // Init material properties table //initializeMaterialProperties(); // Debug handler BEGIN_DEBUG_EXCEPTION_HANDLER // Print startup message actionstream<<PROJECT_NAME<< " with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST <<", "<<BUILD_INFO <<std::endl; /* Basic initialization */ // Initialize default settings set_default_settings(g_settings); // Initialize sockets sockets_init(); atexit(sockets_cleanup); /* Read config file */ // Path of configuration file in use std::string configpath = ""; if(cmd_args.exists("config")) { bool r = g_settings->readConfigFile(cmd_args.get("config").c_str()); if(r == false) { errorstream<<"Could not read configuration from \"" <<cmd_args.get("config")<<"\""<<std::endl; return 1; } configpath = cmd_args.get("config"); } else { core::array<std::string> filenames; filenames.push_back(porting::path_userdata + DIR_DELIM + "minetest.conf"); #ifdef RUN_IN_PLACE filenames.push_back(porting::path_userdata + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf"); #endif for(u32 i=0; i<filenames.size(); i++) { bool r = g_settings->readConfigFile(filenames[i].c_str()); if(r) { configpath = filenames[i]; break; } } // If no path found, use the first one (menu creates the file) if(configpath == "") configpath = filenames[0]; } // Initialize random seed srand(time(0)); mysrand(time(0)); /* Pre-initialize some stuff with a dummy irrlicht wrapper. These are needed for unit tests at least. */ // Initial call with g_texturesource not set. init_mapnode(); // Must be called before g_texturesource is created // (for texture atlas making) init_mineral(); /* Run unit tests */ if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false) || cmd_args.getFlag("enable-unittests") == true) { run_tests(); } /*for(s16 y=-100; y<100; y++) for(s16 x=-100; x<100; x++) { std::cout<<noise2d_gradient((double)x/10,(double)y/10, 32415)<<std::endl; } return 0;*/ /* Game parameters */ // Port u16 port = 30000; if(cmd_args.exists("port")) port = cmd_args.getU16("port"); else if(g_settings->exists("port")) port = g_settings->getU16("port"); if(port == 0) port = 30000; // Map directory std::string map_dir = porting::path_userdata+DIR_DELIM+"world"; if(cmd_args.exists("map-dir")) map_dir = cmd_args.get("map-dir"); else if(g_settings->exists("map-dir")) map_dir = g_settings->get("map-dir"); // Run dedicated server if asked to if(cmd_args.getFlag("server")) { DSTACK("Dedicated server branch"); // Create time getter g_timegetter = new SimpleTimeGetter(); // Create server Server server(map_dir.c_str(), configpath); server.start(port); // Run server dedicated_server_loop(server, kill); return 0; } /* More parameters */ // Address to connect to std::string address = ""; if(cmd_args.exists("address")) { address = cmd_args.get("address"); } else { address = g_settings->get("address"); } std::string playername = g_settings->get("name"); /* Device initialization */ // Resolution selection bool fullscreen = false; u16 screenW = g_settings->getU16("screenW"); u16 screenH = g_settings->getU16("screenH"); // Determine driver video::E_DRIVER_TYPE driverType; std::string driverstring = g_settings->get("video_driver"); if(driverstring == "null") driverType = video::EDT_NULL; else if(driverstring == "software") driverType = video::EDT_SOFTWARE; else if(driverstring == "burningsvideo") driverType = video::EDT_BURNINGSVIDEO; else if(driverstring == "direct3d8") driverType = video::EDT_DIRECT3D8; else if(driverstring == "direct3d9") driverType = video::EDT_DIRECT3D9; else if(driverstring == "opengl") driverType = video::EDT_OPENGL; else { errorstream<<"WARNING: Invalid video_driver specified; defaulting " "to opengl"<<std::endl; driverType = video::EDT_OPENGL; } /* Create device and exit if creation failed */ MyEventReceiver receiver; IrrlichtDevice *device; device = createDevice(driverType, core::dimension2d<u32>(screenW, screenH), 16, fullscreen, false, false, &receiver); if (device == 0) return 1; // could not create selected driver. /* Continue initialization */ video::IVideoDriver* driver = device->getVideoDriver(); // Disable mipmaps (because some of them look ugly) driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); /* This changes the minimum allowed number of vertices in a VBO. Default is 500. */ //driver->setMinHardwareBufferVertexCount(50); // Set the window caption device->setWindowCaption(L"Minetest [Main Menu]"); // Create time getter g_timegetter = new IrrlichtTimeGetter(device); // Create game callback for menus g_gamecallback = new MainGameCallback(device); // Create texture source g_texturesource = new TextureSource(device); /* Speed tests (done after irrlicht is loaded to get timer) */ if(cmd_args.getFlag("speedtests")) { dstream<<"Running speed tests"<<std::endl; SpeedTests(); return 0; } device->setResizable(true); bool random_input = g_settings->getBool("random_input") || cmd_args.getFlag("random-input"); InputHandler *input = NULL; if(random_input) input = new RandomInputHandler(); else input = new RealInputHandler(device, &receiver); scene::ISceneManager* smgr = device->getSceneManager(); guienv = device->getGUIEnvironment(); gui::IGUISkin* skin = guienv->getSkin(); std::string font_path = porting::getDataPath("font.ttf"); gui::IGUIFont *font = gui::CGUITTFont::createTTFont(guienv, font_path.c_str(), 13); if(font) { skin->setFont(font); } else { errorstream << "WARNING: Font file was not found. Using default font." << std::endl; font = guienv->getFont(getTexturePath("fontlucida.png").c_str()); } // If font was not found, this will get us one font = skin->getFont(); assert(font); u32 text_height = font->getDimension(L"Hello, world!").Height; infostream<<"text_height="<<text_height<<std::endl; //skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,0,0,0)); skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255)); //skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0)); //skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0)); skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255,0,0,0)); skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0)); /* Preload some textures and stuff */ init_mapnode(); // Second call with g_texturesource set /* GUI stuff */ /* If an error occurs, this is set to something and the menu-game loop is restarted. It is then displayed before the menu. */ std::wstring error_message = L""; // The password entered during the menu screen, std::string password; /* Menu-game loop */ while(device->run() && kill == false) { // This is used for catching disconnects try { /* Clear everything from the GUIEnvironment */ guienv->clear(); /* We need some kind of a root node to be able to add custom gui elements directly on the screen. Otherwise they won't be automatically drawn. */ guiroot = guienv->addStaticText(L"", core::rect<s32>(0, 0, 10000, 10000)); /* Out-of-game menu loop. Loop quits when menu returns proper parameters. */ while(kill == false) { // Cursor can be non-visible when coming from the game device->getCursorControl()->setVisible(true); // Some stuff are left to scene manager when coming from the game // (map at least?) smgr->clear(); // Reset or hide the debug gui texts /*guitext->setText(L"Minetest-c55"); guitext2->setVisible(false); guitext_info->setVisible(false); guitext_chat->setVisible(false);*/ // Initialize menu data MainMenuData menudata; menudata.address = narrow_to_wide(address); menudata.name = narrow_to_wide(playername); menudata.port = narrow_to_wide(itos(port)); menudata.fancy_trees = g_settings->getBool("new_style_leaves"); menudata.smooth_lighting = g_settings->getBool("smooth_lighting"); menudata.clouds_3d = g_settings->getBool("enable_3d_clouds"); menudata.opaque_water = g_settings->getBool("opaque_water"); menudata.creative_mode = g_settings->getBool("creative_mode"); menudata.enable_damage = g_settings->getBool("enable_damage"); GUIMainMenu *menu = new GUIMainMenu(guienv, guiroot, -1, &g_menumgr, &menudata, g_gamecallback); menu->allowFocusRemoval(true); if(error_message != L"") { errorstream<<"error_message = " <<wide_to_narrow(error_message)<<std::endl; GUIMessageMenu *menu2 = new GUIMessageMenu(guienv, guiroot, -1, &g_menumgr, error_message.c_str()); menu2->drop(); error_message = L""; } video::IVideoDriver* driver = device->getVideoDriver(); infostream<<"Created main menu"<<std::endl; while(device->run() && kill == false) { if(menu->getStatus() == true) break; //driver->beginScene(true, true, video::SColor(255,0,0,0)); driver->beginScene(true, true, video::SColor(255,128,128,128)); drawMenuBackground(driver); guienv->drawAll(); driver->endScene(); // On some computers framerate doesn't seem to be // automatically limited sleep_ms(25); } // Break out of menu-game loop to shut down cleanly if(device->run() == false || kill == true) break; infostream<<"Dropping main menu"<<std::endl; menu->drop(); // Delete map if requested if(menudata.delete_map) { bool r = fs::RecursiveDeleteContent(map_dir); if(r == false) error_message = L"Delete failed"; continue; } playername = wide_to_narrow(menudata.name); password = translatePassword(playername, menudata.password); //infostream<<"Main: password hash: '"<<password<<"'"<<std::endl; address = wide_to_narrow(menudata.address); int newport = stoi(wide_to_narrow(menudata.port)); if(newport != 0) port = newport; g_settings->set("new_style_leaves", itos(menudata.fancy_trees)); g_settings->set("smooth_lighting", itos(menudata.smooth_lighting)); g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d)); g_settings->set("opaque_water", itos(menudata.opaque_water)); g_settings->set("creative_mode", itos(menudata.creative_mode)); g_settings->set("enable_damage", itos(menudata.enable_damage)); // NOTE: These are now checked server side; no need to do it // here, so let's not do it here. /*// Check for valid parameters, restart menu if invalid. if(playername == "") { error_message = L"Name required."; continue; } // Check that name has only valid chars if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS)==false) { error_message = L"Characters allowed: " +narrow_to_wide(PLAYERNAME_ALLOWED_CHARS); continue; }*/ // Save settings g_settings->set("name", playername); g_settings->set("address", address); g_settings->set("port", itos(port)); // Update configuration file if(configpath != "") g_settings->updateConfigFile(configpath.c_str()); // Continue to game break; } // Break out of menu-game loop to shut down cleanly if(device->run() == false) break; // Initialize mapnode again to enable changed graphics settings init_mapnode(); /* Run game */ the_game( kill, random_input, input, device, font, map_dir, playername, password, address, port, error_message, configpath ); } //try catch(con::PeerNotFoundException &e) { errorstream<<"Connection error (timed out?)"<<std::endl; error_message = L"Connection error (timed out?)"; } catch(SocketException &e) { errorstream<<"Socket error (port already in use?)"<<std::endl; error_message = L"Socket error (port already in use?)"; } #ifdef NDEBUG catch(std::exception &e) { std::string narrow_message = "Some exception, what()=\""; narrow_message += e.what(); narrow_message += "\""; errorstream<<narrow_message<<std::endl; error_message = narrow_to_wide(narrow_message); } #endif } // Menu-game loop delete input; /* In the end, delete the Irrlicht device. */ device->drop(); END_DEBUG_EXCEPTION_HANDLER(errorstream) debugstreams_deinit(); return 0; }
static String get_cache_key(String p_hostname, IP::Type p_type) { return itos(p_type) + p_hostname; }
int tmpfil(void) { itos(serial++); movstr(numbuf, tempfile); return create(tmpout); }
void ScriptEditorDebugger::_notification(int p_what) { switch(p_what) { case NOTIFICATION_ENTER_TREE: { step->set_icon( get_icon("DebugStep","EditorIcons")); next->set_icon( get_icon("DebugNext","EditorIcons")); back->set_icon( get_icon("Back","EditorIcons")); forward->set_icon( get_icon("Forward","EditorIcons")); dobreak->set_icon( get_icon("Pause","EditorIcons")); docontinue->set_icon( get_icon("DebugContinue","EditorIcons")); tb->set_normal_texture( get_icon("Close","EditorIcons")); tb->set_hover_texture( get_icon("CloseHover","EditorIcons")); tb->set_pressed_texture( get_icon("Close","EditorIcons")); scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons")); le_set->connect("pressed",this,"_live_edit_set"); le_clear->connect("pressed",this,"_live_edit_clear"); error_list->connect("item_selected",this,"_error_selected"); error_stack->connect("item_selected",this,"_error_stack_selected"); vmem_refresh->set_icon( get_icon("Reload","EditorIcons")); } break; case NOTIFICATION_PROCESS: { if (error_count!=last_error_count) { if (error_count==0) { error_split->set_name("Errors"); } else { error_split->set_name("Errors ("+itos(error_count)+")"); } last_error_count=error_count; } if (connection.is_null()) { if (server->is_connection_available()) { connection = server->take_connection(); if (connection.is_null()) break; EditorNode::get_log()->add_message("** Debug Process Started **"); log_forced_visible=false; ppeer->set_stream_peer(connection); show(); dobreak->set_disabled(false); tabs->set_current_tab(0); emit_signal("show_debugger",true); reason->set_text("Child Process Connected"); reason->set_tooltip("Child Process Connected"); scene_tree->clear(); le_set->set_disabled(true); le_clear->set_disabled(false); error_list->clear(); error_stack->clear(); error_count=0; //live_edit_root->set_text("/root"); update_live_edit_root(); } else { break; } }; if (!connection->is_connected()) { stop(); editor->notify_child_process_exited(); //somehow, exited break; }; if (ppeer->get_available_packet_count() <= 0) { break; }; while(ppeer->get_available_packet_count() > 0) { if (pending_in_queue) { int todo = MIN( ppeer->get_available_packet_count(), pending_in_queue ); for(int i=0;i<todo;i++) { Variant cmd; Error ret = ppeer->get_var(cmd); if (ret!=OK) { stop(); ERR_FAIL_COND(ret!=OK); } message.push_back(cmd); pending_in_queue--; } if (pending_in_queue==0) { _parse_message(message_type,message); message.clear(); } } else { if (ppeer->get_available_packet_count()>=2) { Variant cmd; Error ret = ppeer->get_var(cmd); if (ret!=OK) { stop(); ERR_FAIL_COND(ret!=OK); } if (cmd.get_type()!=Variant::STRING) { stop(); ERR_FAIL_COND(cmd.get_type()!=Variant::STRING); } message_type=cmd; ret = ppeer->get_var(cmd); if (ret!=OK) { stop(); ERR_FAIL_COND(ret!=OK); } if (cmd.get_type()!=Variant::INT) { stop(); ERR_FAIL_COND(cmd.get_type()!=Variant::INT); } pending_in_queue=cmd; if (pending_in_queue==0) { _parse_message(message_type,Array()); message.clear(); } } else { break; } } } } break; } }
String VisualScriptInputFilter::get_output_sequence_port_text(int p_port) const { String text; switch(filters[p_port].type) { case InputEvent::NONE: { text="None"; } break; case InputEvent::KEY: { InputEventKey k = filters[p_port].key; if (k.scancode==0 && k.unicode==0) { text="No Key"; } else { if (k.scancode!=0) { text="KeyCode: "+keycode_get_string(k.scancode); } else if (k.unicode!=0) { text="Uniode: "+String::chr(k.unicode); } if (k.pressed) text+=", Pressed"; else text+=", Released"; if (k.echo) text+=", Echo"; if (k.mod.alt) text="Alt+"+text; if (k.mod.shift) text="Shift+"+text; if (k.mod.control) text="Ctrl+"+text; if (k.mod.meta) text="Meta+"+text; } } break; case InputEvent::MOUSE_MOTION: { InputEventMouseMotion mm = filters[p_port].mouse_motion; text="Mouse Motion"; String b = "Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight"; for(int i=0;i<7;i++) { if (mm.button_mask&(1<<i)) { text=b.get_slice(",",i)+"+"+text; } } if (mm.mod.alt) text="Alt+"+text; if (mm.mod.shift) text="Shift+"+text; if (mm.mod.control) text="Ctrl+"+text; if (mm.mod.meta) text="Meta+"+text; } break; case InputEvent::MOUSE_BUTTON: { InputEventMouseButton mb = filters[p_port].mouse_button; String b = "Any,Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight"; text=b.get_slice(",",mb.button_index)+" Mouse Button"; if (mb.pressed) text+=", Pressed"; else text+=", Released"; if (mb.doubleclick) text+=", DblClick"; if (mb.mod.alt) text="Alt+"+text; if (mb.mod.shift) text="Shift+"+text; if (mb.mod.control) text="Ctrl+"+text; if (mb.mod.meta) text="Meta+"+text; } break; case InputEvent::JOYSTICK_MOTION: { InputEventJoystickMotion jm = filters[p_port].joy_motion; text="JoyMotion Axis "+itos(jm.axis>>1); if (jm.axis&1) text+=" > "+rtos(jm.axis_value); else text+=" < "+rtos(-jm.axis_value); } break; case InputEvent::JOYSTICK_BUTTON: { InputEventJoystickButton jb = filters[p_port].joy_button; text="JoyButton "+itos(jb.button_index); if (jb.pressed) text+=", Pressed"; else text+=", Released"; } break; case InputEvent::SCREEN_TOUCH: { InputEventScreenTouch sd = filters[p_port].screen_touch; text="Touch Finger "+itos(sd.index); if (sd.pressed) text+=", Pressed"; else text+=", Released"; } break; case InputEvent::SCREEN_DRAG: { InputEventScreenDrag sd = filters[p_port].screen_drag; text="Drag Finger "+itos(sd.index); } break; case InputEvent::ACTION: { List<PropertyInfo> pinfo; Globals::get_singleton()->get_property_list(&pinfo); int index=1; text="No Action"; for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) { const PropertyInfo &pi=E->get(); if (!pi.name.begins_with("input/")) continue; if (filters[p_port].action.action==index) { text="Action "+pi.name.substr(pi.name.find("/")+1,pi.name.length()); break; } index++; } if (filters[p_port].action.pressed) text+=", Pressed"; else text+=", Released"; } break; } return text+" - "+itos(p_port); }
void fm_set_default_settings(Settings *settings) { // Screen #if __ANDROID__ || __ARM_ARCH settings->setDefault("enable_shaders", "0"); #if defined(_IRR_COMPILE_WITH_OGLES1_) settings->setDefault("video_driver", "ogles1"); #elif defined(_IRR_COMPILE_WITH_OGLES2_) settings->setDefault("video_driver", "ogles2"); #else settings->setDefault("video_driver", "opengl"); #endif #else settings->setDefault("video_driver", "opengl"); settings->setDefault("enable_shaders", "1"); #endif // settings->setDefault("chat_buffer_size", "6"); // todo re-enable settings->setDefault("timelapse", "0"); // Paths settings->setDefault("screenshot_path", "screenshots"); // "." settings->setDefault("serverlist_file", "favoriteservers.json"); // "favoriteservers.txt" settings->setDefault("serverlist_cache", porting::path_user + DIR_DELIM + "client" + DIR_DELIM + "servers_public.json"); settings->setDefault("serverlist_lan", "1"); // Main menu settings->setDefault("main_menu_tab", "multiplayer"); settings->setDefault("public_serverlist", "1"); settings->setDefault("password_save", "1"); // Game Speed settings->setDefault("pause_fps_max", "10"); // "20" // Debugging stuff settings->setDefault("show_debug", debug ? "true" : "false"); // "true" settings->setDefault("deprecated_lua_api_handling", debug ? "log" : "legacy"); // "log" settings->setDefault("profiler_print_interval", debug ? "10" : "0"); // "0" settings->setDefault("time_taker_enabled", debug ? "5" : "0"); // Keymaps settings->setDefault("keymap_zoom", "KEY_KEY_Z"); settings->setDefault("keymap_msg", "@"); settings->setDefault("keymap_toggle_update_camera", debug ? "KEY_F4" : ""); settings->setDefault("keymap_toggle_block_boundaries", "KEY_F4"); settings->setDefault("keymap_playerlist", "KEY_TAB"); #if IRRLICHT_VERSION_10000 >= 10703 settings->setDefault("keymap_console", "KEY_OEM_3"); #else settings->setDefault("keymap_console", "KEY_F10"); #endif // Fonts settings->setDefault("freetype", "true"); // "false" settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "liberationsans.ttf")); // porting::getDataPath("fonts" DIR_DELIM "lucida_sans") settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "liberationmono.ttf")); // porting::getDataPath("fonts" DIR_DELIM "mono_dejavu_sans") settings->setDefault("reconnects", win ? "1" : "10"); // TODO: wix windows // Map generation settings->setDefault("mg_name", "indev"); // "v6" settings->setDefault("mg_flags", "trees, caves, dungeons"); // "dungeons" settings->setDefault("mgv6_spflags", "jungles, biome_blend, snowbiomes"); // "jungles, snowbiomes" settings->setDefault("mg_math", ""); // configuration in json struct settings->setDefault("mg_params", ""); // configuration in json struct // Filters settings->setDefault("anisotropic_filter", "true"); // "false" // Waving settings->setDefault("enable_waving_leaves", "true"); // "false" settings->setDefault("enable_waving_plants", "true"); // "false" settings->setDefault("enable_waving_water", "true"); // "false" // Shaders //settings->setDefault("enable_bumpmapping", "true"); // "false" settings->setDefault("enable_parallax_occlusion", "true"); // "false" settings->setDefault("disable_wieldlight", "false"); settings->setDefault("mip_map", "true"); // "false" // Clouds, water, glass, leaves, fog settings->setDefault("cloud_height", "300"); // "120" settings->setDefault("enable_zoom_cinematic", "true"); settings->setDefault("wanted_fps", android ? "25" : "30"); settings->setDefault("viewing_range_max", (win32 || android) ? "300" : "10000" /*itos(MAX_MAP_GENERATION_LIMIT)*/); // "240" settings->setDefault("shadows", "0"); settings->setDefault("zoom_fov", "15"); settings->setDefault("farmesh", android ? "2" : "0"); settings->setDefault("farmesh_step", android ? "2" : "3"); settings->setDefault("farmesh_wanted", android ? "100" :"500"); settings->setDefault("headless_optimize", "false"); //settings->setDefault("node_highlighting", "halo"); //settings->setDefault("enable_vbo", win ? "false" : "true"); // Liquid settings->setDefault("liquid_real", "true"); settings->setDefault("liquid_send", android ? "3.0" : "1.0"); settings->setDefault("liquid_relax", android ? "1" : "2"); settings->setDefault("liquid_fast_flood", "-200"); // Weather settings->setDefault("weather", threads ? "true" : "false"); settings->setDefault("weather_biome", "false"); settings->setDefault("weather_heat_season", "30"); settings->setDefault("weather_heat_daily", "8"); settings->setDefault("weather_heat_width", "3000"); settings->setDefault("weather_hot_core", "1000"); settings->setDefault("weather_heat_height", "-333"); settings->setDefault("year_days", "30"); settings->setDefault("weather_humidity_season", "30"); settings->setDefault("weather_humidity_daily", "-12"); settings->setDefault("weather_humidity_width", "300"); settings->setDefault("weather_humidity_days", "2"); settings->setDefault("respawn_auto", "false"); settings->setDefault("autojump", android ? "1" : "0"); settings->setDefault("hotbar_cycling", "false"); // TODO: refactor and resolve client/server dependencies #ifndef SERVER // Only on client settings->setDefault("minimap_default_mode", itos(MINIMAP_MODE_SURFACEx1)); #endif #if !MINETEST_PROTO settings->setDefault("serverlist_url", "servers.freeminer.org"); settings->setDefault("server_proto", "fm_enet"); #else settings->setDefault("server_proto", "mt"); #endif settings->setDefault("timeout_mul", android ? "5" : "1"); settings->setDefault("default_game", "default"); // "minetest" settings->setDefault("max_users", "100"); // "15" settings->setDefault("enable_any_name", "0"); // WARNING! SETTING TO "1" COULD CAUSE SECURITY RISKS WITH MODULES WITH PLAYER DATA IN FILES CONTAINS PLAYER NAME IN FILENAME settings->setDefault("default_privs_creative", "interact, shout, fly, fast"); settings->setDefault("vertical_spawn_range", "50"); // "16" settings->setDefault("cache_block_before_spawn", "true"); settings->setDefault("abm_random", android ? "false" : "true"); settings->setDefault("active_block_range", android ? "1" : threads ? "4" : "2"); settings->setDefault("abm_neighbors_range_max", (threads && !win32 && !android) ? "16" : "1"); settings->setDefault("enable_force_load", "true"); settings->setDefault("max_simultaneous_block_sends_per_client", "50"); // "10" settings->setDefault("max_block_send_distance", "30"); // "9" settings->setDefault("server_unload_unused_data_timeout", "65"); // "29" settings->setDefault("max_objects_per_block", "100"); // "49" settings->setDefault("server_occlusion", "true"); settings->setDefault("ignore_world_load_errors", "true"); // "false" settings->setDefault("emergequeue_limit_diskonly", ""); // autodetect from number of cpus settings->setDefault("emergequeue_limit_generate", ""); // autodetect from number of cpus settings->setDefault("emergequeue_limit_total", ""); // autodetect from number of cpus settings->setDefault("num_emerge_threads", ""); // "1" settings->setDefault("server_map_save_interval", "300"); // "5.3" settings->setDefault("sqlite_synchronous", "1"); // "2" settings->setDefault("save_generated_block", "true"); settings->setDefault("block_delete_time", threads && arm ? "60" : threads ? "30" : "10"); #if (ENET_IPV6 || MINETEST_PROTO) //settings->setDefault("enable_ipv6", "true"); #else settings->setDefault("enable_ipv6", "false"); #endif #if !USE_IPV4_DEFAULT && (ENET_IPV6 || MINETEST_PROTO) settings->setDefault("ipv6_server", "true"); // problems on all windows versions (unable to play in local game) #else //settings->setDefault("ipv6_server", "false"); #endif settings->setDefault("movement_fov", "true"); settings->setDefault("movement_acceleration_default", "4"); // "3" settings->setDefault("movement_acceleration_air", "4"); // "2" settings->setDefault("movement_speed_walk", "6"); // "4" settings->setDefault("movement_speed_crouch", "2"); // "1.35" settings->setDefault("movement_speed_fast", "20.5"); // "20" settings->setDefault("movement_fall_aerodynamics", "110"); /* settings->setDefault("animation_default_start", "0"); settings->setDefault("animation_default_stop", "79"); settings->setDefault("animation_walk_start", "168"); settings->setDefault("animation_walk_stop", "187"); settings->setDefault("animation_dig_start", "189"); settings->setDefault("animation_dig_stop", "198"); settings->setDefault("animation_wd_start", "200"); settings->setDefault("animation_wd_stop", "219"); */ settings->setDefault("more_threads", "true"); settings->setDefault("console_enabled", debug ? "true" : "false"); if (win32) { settings->setDefault("client_unload_unused_data_timeout", "30"); settings->setDefault("server_unload_unused_data_timeout", "45"); } settings->setDefault("minimap_shape_round", "false"); settings->setDefault("mainmenu_last_selected_world", "1"); #ifdef __ANDROID__ settings->setDefault("TMPFolder", porting::path_user + "/tmp/"); //check for device with small screen float x_inches = porting::getDisplaySize().X / porting::get_dpi(); settings->setDefault("smooth_lighting", "false"); //settings->setDefault("enable_3d_clouds", "false"); settings->setDefault("fps_max", "30"); settings->setDefault("mouse_sensitivity", "0.1"); settings->setDefault("sound_volume", "1"); settings->setDefault("doubletap_jump", "1"); /* settings->setDefault("max_simultaneous_block_sends_per_client", "3"); settings->setDefault("emergequeue_limit_diskonly", "8"); settings->setDefault("emergequeue_limit_generate", "8"); */ //settings->setDefault("viewing_range", "25"); settings->setDefault("num_emerge_threads", "1"); // too unstable when > 1 settings->setDefault("inventory_image_hack", "false"); if (x_inches < 7) { settings->setDefault("enable_minimap", "false"); } if (x_inches < 3.5) { settings->setDefault("hud_scaling", "0.6"); } else if (x_inches < 4.5) { settings->setDefault("hud_scaling", "0.7"); } settings->setDefault("curl_verify_cert", "false"); settings->setDefault("chunksize", "3"); settings->setDefault("server_map_save_interval", "60"); settings->setDefault("server_unload_unused_data_timeout", "65"); settings->setDefault("client_unload_unused_data_timeout", "60"); //settings->setDefault("max_objects_per_block", "20"); settings->setDefault("leaves_style", "opaque"); //settings->setDefault("mg_name", "v7"); char lang[3] = {}; AConfiguration_getLanguage(porting::app_global->config, lang); settings->setDefault("language", lang); settings->setDefault("android_keyboard", "0"); settings->setDefault("texture_min_size", "16"); settings->setDefault("cloud_radius", "6"); { std::stringstream fontsize; auto density = porting::getDisplayDensity(); if (density > 1.6 && porting::getDisplaySize().X > 1024) density = 1.6; float font_size = 10 * density; fontsize << (int)font_size; settings->setDefault("font_size", fontsize.str()); settings->setDefault("mono_font_size", fontsize.str()); settings->setDefault("fallback_font_size", fontsize.str()); actionstream << "Autoconfig: "" displayX=" << porting::getDisplaySize().X << " density=" << porting::getDisplayDensity() << " dpi=" << porting::get_dpi() //<< " densityDpi=" << porting::get_densityDpi() << " x_inches=" << x_inches << " font=" << font_size << " lang=" << lang <<std::endl; } #endif #ifdef HAVE_TOUCHSCREENGUI settings->setDefault("touchscreen", android ? "true" : "false"); settings->setDefault("touchtarget", "true"); settings->setDefault("touchscreen_threshold","20"); #endif }
RES TranslationLoaderPO::load(const String &p_path, const String& p_original_path, Error *r_error) { if (r_error) *r_error=ERR_CANT_OPEN; FileAccess *f=FileAccess::open(p_path,FileAccess::READ); ERR_FAIL_COND_V(!f,RES()); String l = f->get_line(); enum Status { STATUS_NONE, STATUS_READING_ID, STATUS_READING_STRING, }; Status status=STATUS_NONE; String msg_id; String msg_str; String config; if (r_error) *r_error=ERR_FILE_CORRUPT; Ref<Translation> translation = Ref<Translation>( memnew( Translation )); int line = 1; while(true) { String l = f->get_line(); if (f->eof_reached()) { if ( status == STATUS_READING_STRING) { if (msg_id!="") translation->add_message(msg_id,msg_str); else if (config=="") config=msg_str; break; } else if ( status==STATUS_NONE) break; memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+" Unexpected EOF while reading 'msgid' at file: "); ERR_FAIL_V(RES()); } l=l.strip_edges(); if (l.begins_with("msgid")) { if (status==STATUS_READING_ID) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+" nexpected 'msgid', was expecting 'msgstr' while parsing: "); ERR_FAIL_V(RES()); } if (msg_id!="") translation->add_message(msg_id,msg_str); else if (config=="") config=msg_str; l=l.substr(5,l.length()).strip_edges(); status=STATUS_READING_ID; msg_id=""; msg_str=""; } if (l.begins_with("msgstr")) { if (status!=STATUS_READING_ID) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+" Unexpected 'msgstr', was expecting 'msgid' while parsing: "); ERR_FAIL_V(RES()); } l=l.substr(6,l.length()).strip_edges(); status=STATUS_READING_STRING; } if (l=="" || l.begins_with("#")) { line++; continue; //nothing to read or comment } if (!l.begins_with("\"") || status==STATUS_NONE) { //not a string? failure! ERR_EXPLAIN(p_path+":"+itos(line)+" Invalid line '"+l+"' while parsing: "); ERR_FAIL_V(RES()); } l=l.substr(1,l.length()); //find final quote int end_pos=-1; for(int i=0;i<l.length();i++) { if (l[i]=='"' && (i==0 || l[i-1]!='\\')) { end_pos=i; break; } } if (end_pos==-1) { ERR_EXPLAIN(p_path+":"+itos(line)+" Expected '\"' at end of message while parsing file: "); ERR_FAIL_V(RES()); } l=l.substr(0,end_pos); l=l.c_unescape(); if (status==STATUS_READING_ID) msg_id+=l; else msg_str+=l; line++; } f->close(); memdelete(f); if (config=="") { ERR_EXPLAIN("No config found in file: "+p_path); ERR_FAIL_V(RES()); } Vector<String> configs = config.split("\n"); for(int i=0;i<configs.size();i++) { String c = configs[i].strip_edges(); int p = c.find(":"); if (p==-1) continue; String prop = c.substr(0,p).strip_edges(); String value = c.substr(p+1,c.length()).strip_edges(); if (prop=="X-Language") { translation->set_locale(value); } } if (r_error) *r_error=OK; return translation; }
void EditorAssetLibraryItemDownload::_make_request() { download->cancel_request(); download->set_download_file(EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("tmp_asset_" + itos(asset_id)) + ".zip"); Error err = download->request(host); if (err != OK) { status->set_text(TTR("Error making request")); } else { set_process(true); } }
void Camera2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_FIXED_PROCESS: { _update_scroll(); } break; case NOTIFICATION_TRANSFORM_CHANGED: { if (!is_fixed_processing()) _update_scroll(); } break; case NOTIFICATION_ENTER_TREE: { if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) { viewport = custom_viewport; } else { viewport = get_viewport(); } canvas = get_canvas(); RID vp = viewport->get_viewport_rid(); group_name = "__cameras_" + itos(vp.get_id()); canvas_group_name = "__cameras_c" + itos(canvas.get_id()); add_to_group(group_name); add_to_group(canvas_group_name); if (Engine::get_singleton()->is_editor_hint()) { set_fixed_process(false); } _update_scroll(); first = true; } break; case NOTIFICATION_EXIT_TREE: { if (is_current()) { if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { viewport->set_canvas_transform(Transform2D()); } } remove_from_group(group_name); remove_from_group(canvas_group_name); viewport = NULL; } break; case NOTIFICATION_DRAW: { if (!is_inside_tree() || !Engine::get_singleton()->is_editor_hint()) break; if (screen_drawing_enabled) { Color area_axis_color(0.5, 0.42, 0.87, 0.63); float area_axis_width = 1; if (is_current()) { area_axis_width = 3; area_axis_color.a = 0.83; } Transform2D inv_camera_transform = get_camera_transform().affine_inverse(); Size2 screen_size = get_viewport_rect().size; Vector2 screen_endpoints[4] = { inv_camera_transform.xform(Vector2(0, 0)), inv_camera_transform.xform(Vector2(screen_size.width, 0)), inv_camera_transform.xform(Vector2(screen_size.width, screen_size.height)), inv_camera_transform.xform(Vector2(0, screen_size.height)) }; Transform2D inv_transform = get_global_transform().affine_inverse(); // undo global space for (int i = 0; i < 4; i++) { draw_line(inv_transform.xform(screen_endpoints[i]), inv_transform.xform(screen_endpoints[(i + 1) % 4]), area_axis_color, area_axis_width); } } if (limit_drawing_enabled) { Color limit_drawing_color(1, 1, 0, 0.63); float limit_drawing_width = 1; if (is_current()) { limit_drawing_color.a = 0.83; limit_drawing_width = 3; } Vector2 camera_origin = get_global_transform().get_origin(); Vector2 camera_scale = get_global_transform().get_scale().abs(); Vector2 limit_points[4] = { (Vector2(limit[MARGIN_LEFT], limit[MARGIN_TOP]) - camera_origin) / camera_scale, (Vector2(limit[MARGIN_RIGHT], limit[MARGIN_TOP]) - camera_origin) / camera_scale, (Vector2(limit[MARGIN_RIGHT], limit[MARGIN_BOTTOM]) - camera_origin) / camera_scale, (Vector2(limit[MARGIN_LEFT], limit[MARGIN_BOTTOM]) - camera_origin) / camera_scale }; for (int i = 0; i < 4; i++) { draw_line(limit_points[i], limit_points[(i + 1) % 4], limit_drawing_color, limit_drawing_width); } } if (margin_drawing_enabled) { Color margin_drawing_color(0, 1, 1, 0.63); float margin_drawing_width = 1; if (is_current()) { margin_drawing_width = 3; margin_drawing_color.a = 0.83; } Transform2D inv_camera_transform = get_camera_transform().affine_inverse(); Size2 screen_size = get_viewport_rect().size; Vector2 margin_endpoints[4] = { inv_camera_transform.xform(Vector2((screen_size.width / 2) - ((screen_size.width / 2) * drag_margin[MARGIN_LEFT]), (screen_size.height / 2) - ((screen_size.height / 2) * drag_margin[MARGIN_TOP]))), inv_camera_transform.xform(Vector2((screen_size.width / 2) + ((screen_size.width / 2) * drag_margin[MARGIN_RIGHT]), (screen_size.height / 2) - ((screen_size.height / 2) * drag_margin[MARGIN_TOP]))), inv_camera_transform.xform(Vector2((screen_size.width / 2) + ((screen_size.width / 2) * drag_margin[MARGIN_RIGHT]), (screen_size.height / 2) + ((screen_size.height / 2) * drag_margin[MARGIN_BOTTOM]))), inv_camera_transform.xform(Vector2((screen_size.width / 2) - ((screen_size.width / 2) * drag_margin[MARGIN_LEFT]), (screen_size.height / 2) + ((screen_size.height / 2) * drag_margin[MARGIN_BOTTOM]))) }; Transform2D inv_transform = get_global_transform().affine_inverse(); // undo global space for (int i = 0; i < 4; i++) { draw_line(inv_transform.xform(margin_endpoints[i]), inv_transform.xform(margin_endpoints[(i + 1) % 4]), margin_drawing_color, margin_drawing_width); } } } break; } }