diff options
31 files changed, 2519 insertions, 111 deletions
diff --git a/SConstruct b/SConstruct index 05c53a15fc..46edf06a42 100644 --- a/SConstruct +++ b/SConstruct @@ -84,6 +84,9 @@ env_base.__class__.disable_module = methods.disable_module env_base.__class__.add_source_files = methods.add_source_files +env_base["x86_opt_gcc"]=False +env_base["x86_opt_vc"]=False + customs = ['custom.py'] profile = ARGUMENTS.get("profile", False) @@ -106,7 +109,7 @@ opts.Add('opus','Build Opus Audio Format Support: (yes/no)','yes') opts.Add('minizip','Build Minizip Archive Support: (yes/no)','yes') opts.Add('squish','Squish BC Texture Compression in editor (yes/no)','yes') opts.Add('theora','Theora Video (yes/no)','yes') -opts.Add('use_theoraplayer_binary', "Use precompiled binaries from libtheoraplayer for ogg/theora/vorbis (yes/no)", "no") +opts.Add('theoralib','Theora Video (yes/no)','no') opts.Add('freetype','Freetype support in editor','yes') opts.Add('speex','Speex Audio (yes/no)','yes') opts.Add('xml','XML Save/Load support (yes/no)','yes') @@ -304,8 +307,12 @@ if selected_platform in platform_list: if (env['opus']=='yes'): env.Append(CPPFLAGS=['-DOPUS_ENABLED']); + if (env['theora']=='yes'): - env.Append(CPPFLAGS=['-DTHEORA_ENABLED']); + env['theoralib']='yes' + env.Append(CPPFLAGS=['-DTHEORA_ENABLED']); + if (env['theoralib']=='yes'): + env.Append(CPPFLAGS=['-DTHEORALIB_ENABLED']); if (env['png']=='yes'): env.Append(CPPFLAGS=['-DPNG_ENABLED']); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 51d683f1fe..48c38f05f9 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -1291,8 +1291,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(STRING,STRING,String,pad_decimals,INT,"digits",varray()); ADDFUNC1(STRING,STRING,String,pad_zeros,INT,"digits",varray()); - ADDFUNC0(STRING,STRING,String,to_ascii,varray()); - ADDFUNC0(STRING,STRING,String,to_utf8,varray()); + ADDFUNC0(STRING,RAW_ARRAY,String,to_ascii,varray()); + ADDFUNC0(STRING,RAW_ARRAY,String,to_utf8,varray()); ADDFUNC0(VECTOR2,VECTOR2,Vector2,normalized,varray()); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index eabd647837..1bcfa7d2ae 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -2818,9 +2818,9 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { } break; case MATRIX32: { - p_list->push_back( PropertyInfo(Variant::REAL,"x")); - p_list->push_back( PropertyInfo(Variant::REAL,"y")); - p_list->push_back( PropertyInfo(Variant::REAL,"o")); + p_list->push_back( PropertyInfo(Variant::VECTOR2,"x")); + p_list->push_back( PropertyInfo(Variant::VECTOR2,"y")); + p_list->push_back( PropertyInfo(Variant::VECTOR2,"o")); } break; case PLANE: { diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp new file mode 100644 index 0000000000..2bf9fd7f32 --- /dev/null +++ b/core/variant_parser.cpp @@ -0,0 +1,1398 @@ +#include "variant_parser.h" +#include "io/resource_loader.h" +#include "os/keyboard.h" + + + +CharType VariantParser::StreamFile::get_char() { + + return f->get_8(); +} + +bool VariantParser::StreamFile::is_utf8() const { + + return true; +} +bool VariantParser::StreamFile::is_eof() const { + + return f->eof_reached(); +} + + + + +///////////////////////////////////////////////////////////////////////////////////////////////// + + + +const char * VariantParser::tk_name[TK_MAX] = { + "'{'", + "'}'", + "'['", + "']'", + "'('", + "')'", + "identifier", + "string", + "number", + "':'", + "','", + "'='", + "EOF", + "ERROR" +}; + + + +Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, String &r_err_str) { + + while (true) { + + CharType cchar; + if (p_stream->saved) { + cchar=p_stream->saved; + p_stream->saved=0; + } else { + cchar=p_stream->get_char(); + } + + switch(cchar) { + + case '\n': { + + line++; + break; + }; + case 0: { + r_token.type=TK_EOF; + return OK; + } break; + case '{': { + + r_token.type=TK_CURLY_BRACKET_OPEN; + return OK; + }; + case '}': { + + r_token.type=TK_CURLY_BRACKET_CLOSE; + return OK; + }; + case '[': { + + r_token.type=TK_BRACKET_OPEN; + return OK; + }; + case ']': { + + r_token.type=TK_BRACKET_CLOSE; + return OK; + }; + case '(': { + + r_token.type=TK_PARENTHESIS_OPEN; + return OK; + }; + case ')': { + + r_token.type=TK_PARENTHESIS_CLOSE; + return OK; + }; + case ':': { + + r_token.type=TK_COLON; + return OK; + }; + case ',': { + + r_token.type=TK_COMMA; + return OK; + }; + case '=': { + + r_token.type=TK_EQUAL; + return OK; + }; + case '"': { + + + String str; + while(true) { + + CharType ch=p_stream->get_char(); + + if (ch==0) { + r_err_str="Unterminated String"; + r_token.type=TK_ERROR; + return ERR_PARSE_ERROR; + } else if (ch=='"') { + break; + } else if (ch=='\\') { + //escaped characters... + CharType next = p_stream->get_char(); + if (next==0) { + r_err_str="Unterminated String"; + r_token.type=TK_ERROR; + return ERR_PARSE_ERROR; + } + CharType res=0; + + switch(next) { + + case 'b': res=8; break; + case 't': res=9; break; + case 'n': res=10; break; + case 'f': res=12; break; + case 'r': res=13; break; + case 'u': { + //hexnumbarh - oct is deprecated + + + for(int j=0;j<4;j++) { + CharType c = p_stream->get_char(); + if (c==0) { + r_err_str="Unterminated String"; + r_token.type=TK_ERROR; + return ERR_PARSE_ERROR; + } + if (!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))) { + + r_err_str="Malformed hex constant in string"; + r_token.type=TK_ERROR; + return ERR_PARSE_ERROR; + } + CharType v; + if (c>='0' && c<='9') { + v=c-'0'; + } else if (c>='a' && c<='f') { + v=c-'a'; + v+=10; + } else if (c>='A' && c<='F') { + v=c-'A'; + v+=10; + } else { + ERR_PRINT("BUG"); + v=0; + } + + res<<=4; + res|=v; + + + } + + + + } break; + //case '\"': res='\"'; break; + //case '\\': res='\\'; break; + //case '/': res='/'; break; + default: { + res = next; + //r_err_str="Invalid escape sequence"; + //return ERR_PARSE_ERROR; + } break; + } + + str+=res; + + } else { + if (ch=='\n') + line++; + str+=ch; + } + } + + r_token.type=TK_STRING; + r_token.value=str; + return OK; + + } break; + default: { + + if (cchar<=32) { + break; + } + + if (cchar=='-' || (cchar>='0' && cchar<='9')) { + //a number + print_line("a numbar"); + + String num; +#define READING_SIGN 0 +#define READING_INT 1 +#define READING_DEC 2 +#define READING_EXP 3 +#define READING_DONE 4 + int reading=READING_INT; + + if (cchar=='-') { + num+='-'; + cchar=p_stream->get_char(); + print_line("isnegative"); + + } + + + + CharType c = cchar; + bool exp_sign=false; + bool exp_beg=false; + bool is_float=false; + + while(true) { + + switch(reading) { + case READING_INT: { + + if (c>='0' && c<='9') { + //pass + print_line("num: regular"); + } else if (c=='.') { + reading=READING_DEC; + print_line("num: decimal"); + is_float=true; + } else if (c=='e') { + reading=READING_EXP; + print_line("num: exp"); + } else { + reading=READING_DONE; + } + + } break; + case READING_DEC: { + + if (c>='0' && c<='9') { + print_line("dec: exp"); + + } else if (c=='e') { + reading=READING_EXP; + print_line("dec: expe"); + } else { + reading=READING_DONE; + } + + } break; + case READING_EXP: { + + if (c>='0' && c<='9') { + exp_beg=true; + print_line("exp: num"); + } else if ((c=='-' || c=='+') && !exp_sign && !exp_beg) { + exp_sign=true; + print_line("exp: sgn"); + } else { + reading=READING_DONE; + } + } break; + } + + if (reading==READING_DONE) + break; + num+=String::chr(c); + c = p_stream->get_char(); + print_line("add to c"); + + } + + p_stream->saved=c; + + print_line("num was: "+num); + r_token.type=TK_NUMBER; + if (is_float) + r_token.value=num.to_double(); + else + r_token.value=num.to_int(); + return OK; + + } else if ((cchar>='A' && cchar<='Z') || (cchar>='a' && cchar<='z') || cchar=='_') { + + String id; + + while((cchar>='A' && cchar<='Z') || (cchar>='a' && cchar<='z') || cchar=='_') { + + id+=String::chr(cchar); + cchar=p_stream->get_char(); + } + + p_stream->saved=cchar; + + r_token.type=TK_IDENTIFIER; + r_token.value=id; + return OK; + } else { + r_err_str="Unexpected character."; + r_token.type=TK_ERROR; + return ERR_PARSE_ERROR; + } + } + } + } + + r_token.type=TK_ERROR; + return ERR_PARSE_ERROR; +} + + +Error VariantParser::_parse_construct(Stream *p_stream,Vector<float>& r_construct,int &line,String &r_err_str) { + + + Token token; + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_OPEN) { + r_err_str="Expected '('"; + return ERR_PARSE_ERROR; + } + + + bool first=true; + while(true) { + + if (!first) { + get_token(p_stream,token,line,r_err_str); + if (token.type==TK_COMMA) { + //do none + } else if (token.type!=TK_PARENTHESIS_CLOSE) { + break; + } else { + r_err_str="Expected ',' or ')'"; + return ERR_PARSE_ERROR; + + } + } + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_NUMBER) { + r_err_str="Expected float"; + return ERR_PARSE_ERROR; + } + + r_construct.push_back(token.value); + } + + return OK; + +} + +Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,int &line,String &r_err_str,ResourceParser *p_res_parser) { + + + +/* { + Error err = get_token(p_stream,token,line,r_err_str); + if (err) + return err; + }*/ + + + if (token.type==TK_CURLY_BRACKET_OPEN) { + + Dictionary d; + Error err = _parse_dictionary(d,p_stream,line,r_err_str,p_res_parser); + if (err) + return err; + value=d; + return OK; + } else if (token.type==TK_BRACKET_OPEN) { + + Array a; + Error err = _parse_array(a,p_stream,line,r_err_str,p_res_parser); + if (err) + return err; + value=a; + return OK; + + } else if (token.type==TK_IDENTIFIER) { +/* + VECTOR2, // 5 + RECT2, + VECTOR3, + MATRIX32, + PLANE, + QUAT, // 10 + _AABB, //sorry naming convention fail :( not like it's used often + MATRIX3, + TRANSFORM, + + // misc types + COLOR, + IMAGE, // 15 + NODE_PATH, + _RID, + OBJECT, + INPUT_EVENT, + DICTIONARY, // 20 + ARRAY, + + // arrays + RAW_ARRAY, + INT_ARRAY, + REAL_ARRAY, + STRING_ARRAY, // 25 + VECTOR2_ARRAY, + VECTOR3_ARRAY, + COLOR_ARRAY, + + VARIANT_MAX + +*/ + String id = token.value; + if (id=="true") + value=true; + else if (id=="false") + value=false; + else if (id=="null") + value=Variant(); + else if (id=="Vector2"){ + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + if (args.size()!=2) { + r_err_str="Expected 2 arguments for constructor"; + } + + value=Vector2(args[0],args[1]); + return OK; + } else if (id=="Vector3"){ + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + if (args.size()!=3) { + r_err_str="Expected 3 arguments for constructor"; + } + + value=Vector3(args[0],args[1],args[2]); + return OK; + } else if (id=="Matrix32"){ + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + if (args.size()!=6) { + r_err_str="Expected 6 arguments for constructor"; + } + Matrix32 m; + m[0]=Vector2(args[0],args[1]); + m[1]=Vector2(args[2],args[3]); + m[2]=Vector2(args[4],args[5]); + value=m; + return OK; + } else if (id=="Plane") { + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + if (args.size()!=4) { + r_err_str="Expected 4 arguments for constructor"; + } + + value=Plane(args[0],args[1],args[2],args[3]); + return OK; + } else if (id=="Quat") { + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + if (args.size()!=4) { + r_err_str="Expected 4 arguments for constructor"; + } + + value=Quat(args[0],args[1],args[2],args[3]); + return OK; + + } else if (id=="AABB"){ + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + if (args.size()!=6) { + r_err_str="Expected 6 arguments for constructor"; + } + + value=AABB(Vector3(args[0],args[1],args[2]),Vector3(args[3],args[4],args[5])); + return OK; + + } else if (id=="Matrix3"){ + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + if (args.size()!=9) { + r_err_str="Expected 9 arguments for constructor"; + } + + value=Matrix3(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]); + return OK; + } else if (id=="Transform"){ + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + if (args.size()!=12) { + r_err_str="Expected 12 arguments for constructor"; + } + + value=Transform(Matrix3(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]),Vector3(args[9],args[10],args[11])); + return OK; + + } else if (id=="Color") { + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + if (args.size()!=4) { + r_err_str="Expected 4 arguments for constructor"; + } + + value=Color(args[0],args[1],args[2],args[3]); + return OK; + + } else if (id=="Image") { + + //:| + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_OPEN) { + r_err_str="Expected '('"; + return ERR_PARSE_ERROR; + } + + + get_token(p_stream,token,line,r_err_str); + if (token.type==TK_PARENTHESIS_CLOSE) { + value=Image(); // just an Image() + return OK; + } else if (token.type!=TK_NUMBER) { + r_err_str="Expected number (width)"; + return ERR_PARSE_ERROR; + } + + get_token(p_stream,token,line,r_err_str); + + int width=token.value; + if (token.type!=TK_COMMA) { + r_err_str="Expected ','"; + return ERR_PARSE_ERROR; + } + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_NUMBER) { + r_err_str="Expected number (height)"; + return ERR_PARSE_ERROR; + } + + int height=token.value; + if (token.type!=TK_COMMA) { + r_err_str="Expected ','"; + return ERR_PARSE_ERROR; + } + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_NUMBER) { + r_err_str="Expected number (mipmaps)"; + return ERR_PARSE_ERROR; + } + + int mipmaps=token.value; + if (token.type!=TK_COMMA) { + r_err_str="Expected ','"; + return ERR_PARSE_ERROR; + } + + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_IDENTIFIER) { + r_err_str="Expected identifier (format)"; + return ERR_PARSE_ERROR; + } + + String sformat=token.value; + + Image::Format format; + + if (sformat=="GRAYSCALE") format=Image::FORMAT_GRAYSCALE; + else if (sformat=="INTENSITY") format=Image::FORMAT_INTENSITY; + else if (sformat=="GRAYSCALE_ALPHA") format=Image::FORMAT_GRAYSCALE_ALPHA; + else if (sformat=="RGB") format=Image::FORMAT_RGB; + else if (sformat=="RGBA") format=Image::FORMAT_RGBA; + else if (sformat=="INDEXED") format=Image::FORMAT_INDEXED; + else if (sformat=="INDEXED_ALPHA") format=Image::FORMAT_INDEXED_ALPHA; + else if (sformat=="BC1") format=Image::FORMAT_BC1; + else if (sformat=="BC2") format=Image::FORMAT_BC2; + else if (sformat=="BC3") format=Image::FORMAT_BC3; + else if (sformat=="BC4") format=Image::FORMAT_BC4; + else if (sformat=="BC5") format=Image::FORMAT_BC5; + else if (sformat=="PVRTC2") format=Image::FORMAT_PVRTC2; + else if (sformat=="PVRTC2_ALPHA") format=Image::FORMAT_PVRTC2_ALPHA; + else if (sformat=="PVRTC4") format=Image::FORMAT_PVRTC4; + else if (sformat=="PVRTC4_ALPHA") format=Image::FORMAT_PVRTC4_ALPHA; + else if (sformat=="ATC") format=Image::FORMAT_ATC; + else if (sformat=="ATC_ALPHA_EXPLICIT") format=Image::FORMAT_ATC_ALPHA_EXPLICIT; + else if (sformat=="ATC_ALPHA_INTERPOLATED") format=Image::FORMAT_ATC_ALPHA_INTERPOLATED; + else if (sformat=="CUSTOM") format=Image::FORMAT_CUSTOM; + else { + r_err_str="Invalid image format: '"+sformat+"'"; + return ERR_PARSE_ERROR; + }; + + int len = Image::get_image_data_size(width,height,format,mipmaps); + + DVector<uint8_t> buffer; + buffer.resize(len); + + if (buffer.size()!=len) { + r_err_str="Couldn't allocate image buffer of size: "+itos(len); + } + + { + DVector<uint8_t>::Write w=buffer.write(); + + for(int i=0;i<len;i++) { + + if (token.type!=TK_COMMA) { + r_err_str="Expected ','"; + return ERR_PARSE_ERROR; + } + + if (token.type!=TK_NUMBER) { + r_err_str="Expected number"; + return ERR_PARSE_ERROR; + } + + w[i]=int(token.value); + + } + } + + + Image img(width,height,mipmaps,format,buffer); + + value=img; + + return OK; + + + } else if (id=="NodePath") { + + + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_OPEN) { + r_err_str="Expected '('"; + return ERR_PARSE_ERROR; + } + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_STRING) { + r_err_str="Expected string as argument"; + return ERR_PARSE_ERROR; + } + + value=NodePath(String(token.value)); + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_CLOSE) { + r_err_str="Expected ')'"; + return ERR_PARSE_ERROR; + } + + } else if (id=="RID") { + + + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_OPEN) { + r_err_str="Expected '('"; + return ERR_PARSE_ERROR; + } + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_NUMBER) { + r_err_str="Expected number as argument"; + return ERR_PARSE_ERROR; + } + + value=token.value; + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_CLOSE) { + r_err_str="Expected ')'"; + return ERR_PARSE_ERROR; + } + + + return OK; + + } else if (id=="Resource") { + + + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_OPEN) { + r_err_str="Expected '('"; + return ERR_PARSE_ERROR; + } + + get_token(p_stream,token,line,r_err_str); + if (token.type==TK_STRING) { + String path=token.value; + RES res = ResourceLoader::load(path); + if (res.is_null()) { + r_err_str="Can't load resource at path: '"+path+"'."; + return ERR_PARSE_ERROR; + } + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_CLOSE) { + r_err_str="Expected ')'"; + return ERR_PARSE_ERROR; + } + + value=res; + return OK; + + } else if (p_res_parser && p_res_parser->func){ + + RES res; + Error err = p_res_parser->func(p_res_parser->userdata,p_stream,res,line,r_err_str); + if (err) + return err; + + value=res; + + return OK; + } else { + + r_err_str="Expected string as argument."; + return ERR_PARSE_ERROR; + } + + return OK; + + } else if (id=="InputEvent") { + + + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_OPEN) { + r_err_str="Expected '('"; + return ERR_PARSE_ERROR; + } + + get_token(p_stream,token,line,r_err_str); + + if (token.type!=TK_IDENTIFIER) { + r_err_str="Expected identifier"; + return ERR_PARSE_ERROR; + } + + + String id = token.value; + + InputEvent ie; + + if (id=="KEY") { + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_COMMA) { + r_err_str="Expected ','"; + return ERR_PARSE_ERROR; + } + + ie.type=InputEvent::KEY; + + + get_token(p_stream,token,line,r_err_str); + if (token.type==TK_IDENTIFIER) { + String name=token.value; + ie.key.scancode=find_keycode(name); + } else if (token.type==TK_NUMBER) { + + ie.key.scancode=token.value; + } else { + + r_err_str="Expected string or integer for keycode"; + return ERR_PARSE_ERROR; + } + + get_token(p_stream,token,line,r_err_str); + + if (token.type==TK_COMMA) { + + get_token(p_stream,token,line,r_err_str); + + if (token.type!=TK_IDENTIFIER) { + r_err_str="Expected identifier with modifier flas"; + return ERR_PARSE_ERROR; + } + + String mods=token.value; + + if (mods.findn("C")!=-1) + ie.key.mod.control=true; + if (mods.findn("A")!=-1) + ie.key.mod.alt=true; + if (mods.findn("S")!=-1) + ie.key.mod.shift=true; + if (mods.findn("M")!=-1) + ie.key.mod.meta=true; + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_CLOSE) { + r_err_str="Expected ')'"; + return ERR_PARSE_ERROR; + } + + } else if (token.type!=TK_PARENTHESIS_CLOSE) { + + r_err_str="Expected ')' or modifier flags."; + return ERR_PARSE_ERROR; + } + + + } else if (id=="MBUTTON") { + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_COMMA) { + r_err_str="Expected ','"; + return ERR_PARSE_ERROR; + } + + ie.type=InputEvent::MOUSE_BUTTON; + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_NUMBER) { + r_err_str="Expected button index"; + return ERR_PARSE_ERROR; + } + + ie.mouse_button.button_index = token.value; + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_CLOSE) { + r_err_str="Expected ')'"; + return ERR_PARSE_ERROR; + } + + } else if (id=="JBUTTON") { + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_COMMA) { + r_err_str="Expected ','"; + return ERR_PARSE_ERROR; + } + + ie.type=InputEvent::JOYSTICK_BUTTON; + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_NUMBER) { + r_err_str="Expected button index"; + return ERR_PARSE_ERROR; + } + + ie.joy_button.button_index = token.value; + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_CLOSE) { + r_err_str="Expected ')'"; + return ERR_PARSE_ERROR; + } + + } else if (id=="JAXIS") { + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_COMMA) { + r_err_str="Expected ','"; + return ERR_PARSE_ERROR; + } + + ie.type=InputEvent::JOYSTICK_MOTION; + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_NUMBER) { + r_err_str="Expected axis index"; + return ERR_PARSE_ERROR; + } + + ie.joy_motion.axis = token.value; + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_CLOSE) { + r_err_str="Expected ')'"; + return ERR_PARSE_ERROR; + } + + } else { + + r_err_str="Invalid input event type."; + return ERR_PARSE_ERROR; + } + + value=ie; + + return OK; + + } else if (id=="ByteArray") { + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + DVector<uint8_t> arr; + { + int len=args.size(); + arr.resize(len); + DVector<uint8_t>::Write w = arr.write(); + for(int i=0;i<len;i++) { + w[i]=args[i]; + } + } + + value=arr; + + return OK; + + } else if (id=="IntArray") { + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + DVector<int32_t> arr; + { + int len=args.size(); + arr.resize(len); + DVector<int32_t>::Write w = arr.write(); + for(int i=0;i<len;i++) { + w[i]=Math::fast_ftoi(args[i]); + } + } + + value=arr; + + return OK; + + } else if (id=="FloatArray") { + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + DVector<float> arr; + { + int len=args.size(); + arr.resize(len); + DVector<float>::Write w = arr.write(); + for(int i=0;i<len;i++) { + w[i]=args[i]; + } + } + + value=arr; + + return OK; + } else if (id=="StringArray") { + + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_OPEN) { + r_err_str="Expected '('"; + return ERR_PARSE_ERROR; + } + + Vector<String> cs; + + bool first=true; + while(true) { + + if (!first) { + get_token(p_stream,token,line,r_err_str); + if (token.type==TK_COMMA) { + //do none + } else if (token.type!=TK_PARENTHESIS_CLOSE) { + break; + } else { + r_err_str="Expected ',' or ')'"; + return ERR_PARSE_ERROR; + + } + } + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_STRING) { + r_err_str="Expected string"; + return ERR_PARSE_ERROR; + } + + cs.push_back(token.value); + } + + + DVector<String> arr; + { + int len=cs.size(); + arr.resize(len); + DVector<String>::Write w = arr.write(); + for(int i=0;i<len;i++) { + w[i]=cs[i]; + } + } + + value=arr; + + return OK; + + + } else if (id=="Vector2Array") { + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + DVector<Vector2> arr; + { + int len=args.size()/2; + arr.resize(len); + DVector<Vector2>::Write w = arr.write(); + for(int i=0;i<len;i++) { + w[i]=Vector2(args[i*2+0],args[i*2+1]); + } + } + + value=arr; + + return OK; + + } else if (id=="Vector3Array") { + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + DVector<Vector3> arr; + { + int len=args.size()/3; + arr.resize(len); + DVector<Vector3>::Write w = arr.write(); + for(int i=0;i<len;i++) { + w[i]=Vector3(args[i*3+0],args[i*3+1],args[i*3+2]); + } + } + + value=arr; + + return OK; + + } else if (id=="ColorArray") { + + Vector<float> args; + Error err = _parse_construct(p_stream,args,line,r_err_str); + if (err) + return err; + + DVector<Color> arr; + { + int len=args.size()/4; + arr.resize(len); + DVector<Color>::Write w = arr.write(); + for(int i=0;i<len;i++) { + w[i]=Color(args[i*3+0],args[i*3+1],args[i*3+2],args[i*3+3]); + } + } + + value=arr; + + return OK; + + } else { + r_err_str="Unexpected identifier: '"+id+"'."; + return ERR_PARSE_ERROR; + } + + + /* + VECTOR2, // 5 + RECT2, + VECTOR3, + MATRIX32, + PLANE, + QUAT, // 10 + _AABB, //sorry naming convention fail :( not like it's used often + MATRIX3, + TRANSFORM, + + // misc types + COLOR, + IMAGE, // 15 + NODE_PATH, + _RID, + OBJECT, + INPUT_EVENT, + DICTIONARY, // 20 + ARRAY, + + // arrays + RAW_ARRAY, + INT_ARRAY, + REAL_ARRAY, + STRING_ARRAY, // 25 + VECTOR2_ARRAY, + VECTOR3_ARRAY, + COLOR_ARRAY, + + VARIANT_MAX + + */ + + return OK; + + } else if (token.type==TK_NUMBER) { + + value=token.value; + return OK; + } else if (token.type==TK_STRING) { + + value=token.value; + return OK; + } else { + r_err_str="Expected value, got "+String(tk_name[token.type])+"."; + return ERR_PARSE_ERROR; + } + + return ERR_PARSE_ERROR; +} + + +Error VariantParser::_parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) { + + Token token; + bool need_comma=false; + + + while(!p_stream->is_eof()) { + + Error err = get_token(p_stream,token,line,r_err_str); + if (err!=OK) + return err; + + if (token.type==TK_BRACKET_CLOSE) { + + return OK; + } + + if (need_comma) { + + if (token.type!=TK_COMMA) { + + r_err_str="Expected ','"; + return ERR_PARSE_ERROR; + } else { + need_comma=false; + continue; + } + } + + Variant v; + err = parse_value(token,v,p_stream,line,r_err_str,p_res_parser); + if (err) + return err; + + array.push_back(v); + need_comma=true; + + } + + return OK; + +} + +Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) { + + bool at_key=true; + Variant key; + Token token; + bool need_comma=false; + + + while(!p_stream->is_eof()) { + + + if (at_key) { + + Error err = get_token(p_stream,token,line,r_err_str); + if (err!=OK) + return err; + + if (token.type==TK_CURLY_BRACKET_CLOSE) { + + return OK; + } + + if (need_comma) { + + if (token.type!=TK_COMMA) { + + r_err_str="Expected '}' or ','"; + return ERR_PARSE_ERROR; + } else { + need_comma=false; + continue; + } + } + + + + + err = parse_value(token,key,p_stream,line,r_err_str,p_res_parser); + + if (err) + return err; + + err = get_token(p_stream,token,line,r_err_str); + + if (err!=OK) + return err; + if (token.type!=TK_COLON) { + + r_err_str="Expected ':'"; + return ERR_PARSE_ERROR; + } + at_key=false; + } else { + + + Error err = get_token(p_stream,token,line,r_err_str); + if (err!=OK) + return err; + + Variant v; + err = parse_value(token,v,p_stream,line,r_err_str,p_res_parser); + if (err) + return err; + object[key]=v; + need_comma=true; + at_key=true; + } + } + + return OK; +} + + +Error VariantParser::_parse_tag(Token& token,Stream *p_stream, int &line, String &r_err_str,Tag& r_tag) { + + r_tag.fields.clear(); + + if (token.type!=TK_BRACKET_OPEN) { + r_err_str="Expected '['"; + return ERR_PARSE_ERROR; + } + + + get_token(p_stream,token,line,r_err_str); + + + if (token.type!=TK_IDENTIFIER) { + r_err_str="Expected identifier (tag name)"; + return ERR_PARSE_ERROR; + } + + r_tag.name=token.value; + + print_line("tag name: "+r_tag.name); + + while(true) { + + get_token(p_stream,token,line,r_err_str); + if (token.type==TK_BRACKET_CLOSE) + break; + + if (token.type!=TK_IDENTIFIER) { + r_err_str="Expected Identifier"; + return ERR_PARSE_ERROR; + } + + String id=token.value; + + print_line("got ID: "+id); + + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_EQUAL) { + r_err_str="Expected '='"; + return ERR_PARSE_ERROR; + } + + print_line("got tk: "+String(tk_name[token.type])); + + get_token(p_stream,token,line,r_err_str); + Variant value; + Error err = parse_value(token,value,p_stream,line,r_err_str); + if (err) + return err; + + print_line("id: "+id+" value: "+String(value)); + + r_tag.fields[id]=value; + + } + + + return OK; + +} + +Error VariantParser::parse_tag(Stream *p_stream, int &line, String &r_err_str,Tag& r_tag) { + + Token token; + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_BRACKET_OPEN) { + r_err_str="Expected '['"; + return ERR_PARSE_ERROR; + } + + return _parse_tag(token,p_stream,line,r_err_str,r_tag); + +} + +Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r_err_str,Tag& r_tag,String &r_assign) { + + r_tag.name.clear(); + r_assign=String(); + + return OK; +} + +Error VariantParser::parse(Stream *p_stream, Variant& r_ret, String &r_err_str, int &r_err_line, ResourceParser *p_res_parser) { + + + Token token; + Error err = get_token(p_stream,token,r_err_line,r_err_str); + if (err) + return err; + return parse_value(token,r_ret,p_stream,r_err_line,r_err_str,p_res_parser); + +} + + diff --git a/core/variant_parser.h b/core/variant_parser.h new file mode 100644 index 0000000000..d4ec6c6cf5 --- /dev/null +++ b/core/variant_parser.h @@ -0,0 +1,100 @@ +#ifndef VARIANT_PARSER_H +#define VARIANT_PARSER_H + +#include "variant.h" +#include "os/file_access.h" +#include "resource.h" + +class VariantParser { +public: + + struct Stream { + + virtual CharType get_char()=0; + virtual bool is_utf8() const=0; + virtual bool is_eof() const=0; + + CharType saved; + + Stream() { saved=0; } + virtual ~Stream() {} + }; + + struct StreamFile : public Stream { + + FileAccess *f; + + virtual CharType get_char(); + virtual bool is_utf8() const; + virtual bool is_eof() const; + + StreamFile() { f=NULL; } + + }; + + typedef Error (*ParseResourceFunc)(void* p_self, Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str); + + struct ResourceParser { + + void *userdata; + ParseResourceFunc func; + + }; + + enum TokenType { + TK_CURLY_BRACKET_OPEN, + TK_CURLY_BRACKET_CLOSE, + TK_BRACKET_OPEN, + TK_BRACKET_CLOSE, + TK_PARENTHESIS_OPEN, + TK_PARENTHESIS_CLOSE, + TK_IDENTIFIER, + TK_STRING, + TK_NUMBER, + TK_COLON, + TK_COMMA, + TK_EQUAL, + TK_EOF, + TK_ERROR, + TK_MAX + }; + + enum Expecting { + + EXPECT_OBJECT, + EXPECT_OBJECT_KEY, + EXPECT_COLON, + EXPECT_OBJECT_VALUE, + }; + + struct Token { + + TokenType type; + Variant value; + }; + + struct Tag { + + String name; + Map<String,Variant> fields; + }; + +private: + static const char * tk_name[TK_MAX]; + + static Error _parse_construct(Stream *p_stream, Vector<float>& r_construct, int &line, String &r_err_str); + static Error _parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str,ResourceParser *p_res_parser=NULL); + static Error _parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str,ResourceParser *p_res_parser=NULL); + static Error _parse_tag(Token& token,Stream *p_stream, int &line, String &r_err_str,Tag& r_tag); + +public: + + static Error parse_tag(Stream *p_stream, int &line, String &r_err_str,Tag& r_tag); + static Error parse_tag_assign_eof(Stream *p_stream, int &line, String &r_err_str,Tag& r_tag,String &r_assign); + + static Error parse_value(Token& token,Variant &value, Stream *p_stream, int &line, String &r_err_str,ResourceParser *p_res_parser=NULL); + static Error get_token(Stream *p_stream,Token& r_token,int &line,String &r_err_str); + static Error parse(Stream *p_stream, Variant &r_ret, String &r_err_str, int &r_err_line,ResourceParser *p_res_parser=NULL); +}; + +#endif // VARIANT_PARSER_H diff --git a/doc/base/classes.xml b/doc/base/classes.xml index a26458a14f..12f9062888 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -12551,7 +12551,7 @@ This approximation makes straight segments between each point, then subdivides t <description> Connect to a host. This needs to be done before any requests are sent. The host should not have http:// prepended but will strip the protocol identifier if provided. - + verify_host will check the SSL identity of the host if set to true. </description> </method> @@ -12576,9 +12576,9 @@ verify_host will check the SSL identity of the host if set to true. Sends a request to the connected host. The url is the what is normally behind the hostname, i.e: http://somehost.com/index.php url would be "index.php" - + Headers are HTTP request headers - + To create a POST request with query strings to push to the server, do: var fields = {"username" : "user", "password" : "pass"} @@ -12693,10 +12693,10 @@ var result = httpClient.request(httpClient.METHOD_POST, "index.php", headers, qu </argument> <description> Generates a GET/POST application/x-www-form-urlencoded style query string from a provided dictionary. - + var fields = {"username": "user", "password": "pass"} String queryString = httpClient.query_string_from_dict(fields) - + returns:= "username=user&password=pass" </description> </method> @@ -16735,11 +16735,11 @@ returns:= "username=user&password=pass" </method> </methods> <members> - <member name="x" type="float"> + <member name="x" type="Vector2"> </member> - <member name="y" type="float"> + <member name="y" type="Vector2"> </member> - <member name="o" type="float"> + <member name="o" type="Vector2"> </member> </members> <constants> @@ -26372,12 +26372,14 @@ This method controls whether the position between two cached points is interpola <return type="String"> </return> <description> + Returns a copy of the array's contents formatted as String. Fast alternative to get_string_from_utf8(), assuming the content is ASCII-only (unlike the UTF-8 function, this function maps every byte to a character in the string, so any multibyte sequence will be torn apart). </description> </method> <method name="get_string_from_utf8"> <return type="String"> </return> <description> + Returns a copy of the array's contents formatted as String, assuming the array is formatted as UTF-8. Slower than get_string_from_ascii(), but works for UTF-8. Usually you should prefer this function over get_string_from_ascii() to support international input. </description> </method> <method name="push_back"> @@ -33134,9 +33136,10 @@ This method controls whether the position between two cached points is interpola </description> </method> <method name="to_ascii"> - <return type="String"> + <return type="RawArray"> </return> <description> + Convert the String (which is a character array) to RawArray (which is an array of bytes). The conversion is speeded up in comparison to to_utf8() with the assumption that all the characters the String contains are only ASCII characters. </description> </method> <method name="to_float"> @@ -33168,9 +33171,10 @@ This method controls whether the position between two cached points is interpola </description> </method> <method name="to_utf8"> - <return type="String"> + <return type="RawArray"> </return> <description> + Convert the String (which is an array of characters) to RawArray (which is an array of bytes). The conversion is a bit slower than to_ascii(), but supports all UTF-8 characters. Therefore, you should prefer this function over to_ascii(). </description> </method> <method name="xml_escape"> diff --git a/drivers/SCsub b/drivers/SCsub index b94309013a..8e241830f8 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -31,7 +31,7 @@ SConscript("rtaudio/SCsub"); SConscript("nedmalloc/SCsub"); SConscript("nrex/SCsub"); SConscript("chibi/SCsub"); -if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes" or env["opus"]=="yes"): +if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theoralib"]=="yes" or env["opus"]=="yes"): SConscript("ogg/SCsub"); if (env["vorbis"]=="yes"): SConscript("vorbis/SCsub"); @@ -40,9 +40,7 @@ if (env["opus"]=="yes"): if (env["tools"]=="yes"): SConscript("convex_decomp/SCsub"); -#if env["theora"]=="yes": -# SConscript("theoraplayer/SCsub") -if (env["theora"]=="yes"): +if (env["theoralib"]=="yes"): SConscript("theora/SCsub"); if (env['speex']=='yes'): SConscript("speex/SCsub"); diff --git a/drivers/ogg/SCsub b/drivers/ogg/SCsub index c85d4404f3..3ee1bb6408 100644 --- a/drivers/ogg/SCsub +++ b/drivers/ogg/SCsub @@ -6,5 +6,4 @@ ogg_sources = [ "ogg/framing.c", ] -if env['theora'] != "yes" or env['use_theoraplayer_binary'] != "yes": - env.drivers_sources+=ogg_sources +env.drivers_sources+=ogg_sources diff --git a/drivers/register_driver_types.cpp b/drivers/register_driver_types.cpp index c4ab54d102..11c4e7dd29 100644 --- a/drivers/register_driver_types.cpp +++ b/drivers/register_driver_types.cpp @@ -54,10 +54,6 @@ #include "theora/video_stream_theora.h" #endif -#ifdef THEORAPLAYER_ENABLED -#include "theoraplayer/video_stream_theoraplayer.h" -#endif - #include "drivers/nrex/regex.h" @@ -108,10 +104,6 @@ static ResourceFormatLoaderAudioStreamSpeex *speex_stream_loader=NULL; static ResourceFormatLoaderVideoStreamTheora* theora_stream_loader = NULL; #endif -#ifdef THEORAPLAYER_ENABLED -static ResourceFormatLoaderVideoStreamTheoraplayer* theoraplayer_stream_loader = NULL; -#endif - #ifdef MUSEPACK_ENABLED static ResourceFormatLoaderAudioStreamMPC * mpc_stream_loader=NULL; #endif @@ -233,12 +225,6 @@ void register_driver_types() { ObjectTypeDB::register_type<VideoStreamTheora>(); #endif -#ifdef THEORAPLAYER_ENABLED - theoraplayer_stream_loader = memnew( ResourceFormatLoaderVideoStreamTheoraplayer ); - ResourceLoader::add_resource_format_loader(theoraplayer_stream_loader); - ObjectTypeDB::register_type<VideoStreamTheoraplayer>(); -#endif - #ifdef TOOLS_ENABLED #ifdef SQUISH_ENABLED @@ -277,9 +263,6 @@ void unregister_driver_types() { memdelete (theora_stream_loader); #endif -#ifdef THEORAPLAYER_ENABLED - memdelete (theoraplayer_stream_loader); -#endif #ifdef MUSEPACK_ENABLED diff --git a/drivers/theora/SCsub b/drivers/theora/SCsub index faa1ede6a7..fa85b49804 100644 --- a/drivers/theora/SCsub +++ b/drivers/theora/SCsub @@ -31,5 +31,37 @@ sources = [ "theora/video_stream_theora.cpp", ] -if env['use_theoraplayer_binary'] != "yes": - env.drivers_sources += sources +sources_x86 = [ + "theora/x86/mmxencfrag.c", + "theora/x86/mmxfdct.c", + "theora/x86/mmxfrag.c", + "theora/x86/mmxidct.c", + "theora/x86/mmxstate.c", + "theora/x86/sse2fdct.c", + "theora/x86/x86enc.c", + "theora/x86/x86state.c", +] + +sources_x86_vc = [ + "theora/x86_vc/mmxencfrag.c", + "theora/x86_vc/mmxfdct.c", + "theora/x86_vc/mmxfrag.c", + "theora/x86_vc/mmxidct.c", + "theora/x86_vc/mmxstate.c", + "theora/x86_vc/x86enc.c", + "theora/x86_vc/x86state.c", +] + +env.drivers_sources += sources + +if (env["x86_opt_gcc"]): + env.Append(CCFLAGS=["-DOC_X86_ASM"]) + env.drivers_sources += sources_x86 + +if (env["x86_opt_vc"]): + env.Append(CCFLAGS=["-DOC_X86_ASM"]) + env.drivers_sources += sources_x86_vc + + + + diff --git a/drivers/theora/encint.h b/drivers/theora/encint.h index 97897d5a04..82338256dc 100644 --- a/drivers/theora/encint.h +++ b/drivers/theora/encint.h @@ -14,6 +14,7 @@ last mod: $Id: encint.h 16503 2009-08-22 18:14:02Z giles $ ********************************************************************/ + #if !defined(_encint_H) # define _encint_H (1) # if defined(HAVE_CONFIG_H) diff --git a/drivers/theora/video_stream_theora.cpp b/drivers/theora/video_stream_theora.cpp index ed2565177a..f301bd7515 100644 --- a/drivers/theora/video_stream_theora.cpp +++ b/drivers/theora/video_stream_theora.cpp @@ -441,8 +441,10 @@ void VideoStreamPlaybackTheora::update(float p_delta) { //print_line("play "+rtos(p_delta)); time+=p_delta; - if (videobuf_time>get_time()) + if (videobuf_time>get_time()) { + return; //no new frames need to be produced + } bool frame_done=false; bool audio_done=false; @@ -541,7 +543,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) { if(ogg_stream_packetout(&to,&op)>0){ - if(pp_inc){ + if(false && pp_inc){ pp_level+=pp_inc; th_decode_ctl(td,TH_DECCTL_SET_PPLEVEL,&pp_level, sizeof(pp_level)); @@ -569,16 +571,20 @@ void VideoStreamPlaybackTheora::update(float p_delta) { keyframing. Soon enough libtheora will be able to deal with non-keyframe seeks. */ - if(videobuf_time>=get_time()) + if(videobuf_time>=get_time()) { frame_done=true; - else{ + print_line("frame!"); + } else{ /*If we are too slow, reduce the pp level.*/ pp_inc=pp_level>0?-1:0; + print_line("skip!"); } } - } else + } else { + print_line("no packet.."); break; + } } if (file && /*!videobuf_ready && */ file->eof_reached()) { diff --git a/drivers/vorbis/SCsub b/drivers/vorbis/SCsub index 4a16e80dfc..87805cc2d8 100644 --- a/drivers/vorbis/SCsub +++ b/drivers/vorbis/SCsub @@ -33,6 +33,4 @@ sources_lib = [ ] env.drivers_sources += sources - -if env['theora'] != "yes" or env['use_theoraplayer_binary'] != "yes": - env.drivers_sources += sources_lib +env.drivers_sources += sources_lib diff --git a/main/main.cpp b/main/main.cpp index b6bc10cee7..80a7cbc5fc 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -432,7 +432,6 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas } else if (I->get()=="-e" || I->get()=="-editor") { // fonud editor editor=true; - init_maximized=true; } else if (I->get()=="-nowindow") { // fullscreen OS::get_singleton()->set_no_window_mode(true); @@ -649,6 +648,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas if (editor) { main_args.push_back("-editor"); + init_maximized=true; use_custom_res=false; } @@ -870,21 +870,14 @@ Error Main::setup2() { String boot_logo_path=GLOBAL_DEF("application/boot_splash",String()); bool boot_logo_scale=GLOBAL_DEF("application/boot_splash_fullsize",true); Globals::get_singleton()->set_custom_property_info("application/boot_splash",PropertyInfo(Variant::STRING,"application/boot_splash",PROPERTY_HINT_FILE,"*.png")); - print_line("BOOT SPLASH: "+boot_logo_path); Image boot_logo; boot_logo_path = boot_logo_path.strip_edges(); - print_line("BOOT SPLASH IS : "+boot_logo_path); if (boot_logo_path!=String() /*&& FileAccess::exists(boot_logo_path)*/) { + print_line("Boot splash path: "+boot_logo_path); Error err = boot_logo.load(boot_logo_path); - if (err!=OK) { - print_line("ËRROR LOADING BOOT LOGO SPLASH :"+boot_logo_path); - } else { - print_line("BOOT SPLASH OK!"); - - } } if (!boot_logo.empty()) { @@ -901,7 +894,7 @@ Error Main::setup2() { } else { #ifndef NO_DEFAULT_BOOT_LOGO - MAIN_PRINT("Main: Create botsplash"); + MAIN_PRINT("Main: Create bootsplash"); Image splash(boot_splash_png); MAIN_PRINT("Main: ClearColor"); @@ -944,10 +937,10 @@ Error Main::setup2() { if (String(Globals::get_singleton()->get("display/custom_mouse_cursor"))!=String()) { - print_line("use custom cursor"); + //print_line("use custom cursor"); Ref<Texture> cursor=ResourceLoader::load(Globals::get_singleton()->get("display/custom_mouse_cursor")); if (cursor.is_valid()) { - print_line("loaded ok"); + // print_line("loaded ok"); Vector2 hotspot = Globals::get_singleton()->get("display/custom_mouse_cursor_hotspot"); Input::get_singleton()->set_custom_mouse_cursor(cursor,hotspot); } @@ -1093,7 +1086,7 @@ bool Main::start() { #endif - if(script=="" && game_path=="" && !editor && String(GLOBAL_DEF("application/main_scene",""))!="") { + if(script=="" && game_path=="" && String(GLOBAL_DEF("application/main_scene",""))!="") { game_path=GLOBAL_DEF("application/main_scene",""); } diff --git a/platform/android/detect.py b/platform/android/detect.py index 9db5d02b48..fe83798c56 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -98,6 +98,7 @@ def configure(env): if env['android_arch']=='x86': env['NDK_TARGET']=env['NDK_TARGET_X86'] + env["x86_opt_gcc"]=True if env['PLATFORM'] == 'win32': import methods diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 22cee0527e..f7cf5111f5 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -116,4 +116,4 @@ def configure(env): env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) #env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } ) - + env["x86_opt_gcc"]=True diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 1fa793e2de..f98c1b01ff 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -11,11 +11,11 @@ common_win=[ "stream_peer_winsock.cpp", ] -env.RES('godot_res.rc') -if env["is_mingw"]: - common_win.append("godot_res.o") -else: - common_win.append("godot_res.res") +restarget="godot_res"+env["OBJSUFFIX"] + +obj = env.RES(restarget,'godot_res.rc') + +common_win.append(obj) env.Program('#bin/godot',['godot_win.cpp']+common_win,PROGSUFFIX=env["PROGSUFFIX"]) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index fcde14030f..4ec4b054db 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -263,6 +263,7 @@ def configure(env): env.Append(CCFLAGS=["/I"+DIRECTX_PATH+"/Include"]) env.Append(LIBPATH=[DIRECTX_PATH+"/Lib/x86"]) env['ENV'] = os.environ; + env["x86_opt_vc"]=True else: # Workaround for MinGW. See: @@ -361,6 +362,7 @@ def configure(env): env['AR'] = mingw_prefix+"ar" env['RANLIB'] = mingw_prefix+"ranlib" env['LD'] = mingw_prefix+"g++" + env["x86_opt_gcc"]=True #env['CC'] = "winegcc" #env['CXX'] = "wineg++" diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 9a52a7c92b..a37005738a 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -180,3 +180,5 @@ def configure(env): env.Append(CPPFLAGS=['-DNEW_WM_API']) env.ParseConfig('pkg-config xinerama --cflags --libs') + env["x86_opt_gcc"]=True + diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index 9b9c797ed9..d99da5e906 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "video_player.h" - +#include "os/os.h" int VideoPlayer::InternalStream::get_channel_count() const { @@ -130,7 +130,7 @@ void VideoPlayer::_notification(int p_notification) { if (!playback->is_playing()) return; - double audio_time = AudioServer::get_singleton()->get_mix_time(); + double audio_time = OS::get_singleton()->get_ticks_usec()/1000000.0; //AudioServer::get_singleton()->get_mix_time(); double delta = last_audio_time==0?0:audio_time-last_audio_time; last_audio_time=audio_time; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index fe6b192d78..b3a9ab922e 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -231,6 +231,7 @@ static ResourceFormatLoaderTheme *resource_loader_theme=NULL; static ResourceFormatLoaderShader *resource_loader_shader=NULL; static ResourceFormatSaverText *resource_saver_text=NULL; +static ResourceFormatLoaderText *resource_loader_text=NULL; //static SceneStringNames *string_names; @@ -619,6 +620,9 @@ void register_scene_types() { resource_saver_text = memnew( ResourceFormatSaverText ); ResourceSaver::add_resource_format_saver(resource_saver_text); + resource_loader_text = memnew( ResourceFormatLoaderText ); + ResourceLoader::add_resource_format_loader(resource_loader_text); + } void unregister_scene_types() { @@ -640,5 +644,8 @@ void unregister_scene_types() { if (resource_saver_text) { memdelete(resource_saver_text); } + if (resource_loader_text) { + memdelete(resource_loader_text); + } SceneStringNames::free(); } diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index 8403c06ad1..4fc3ece758 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -6,6 +6,770 @@ #define FORMAT_VERSION 1 +#include "version.h" +#include "os/dir_access.h" + + +Error ResourceInteractiveLoaderText::parse_property(Variant& r_v, String &r_name) { + + return OK; +} + + + + +/// + +void ResourceInteractiveLoaderText::set_local_path(const String& p_local_path) { + + res_path=p_local_path; +} + +Ref<Resource> ResourceInteractiveLoaderText::get_resource() { + + return resource; +} +Error ResourceInteractiveLoaderText::poll() { + +#if 0 + if (error!=OK) + return error; + + bool exit; + Tag *tag = parse_tag(&exit); + + + if (!tag) { + error=ERR_FILE_CORRUPT; + if (!exit) // shouldn't have exited + ERR_FAIL_V(error); + error=ERR_FILE_EOF; + return error; + } + + RES res; + //Object *obj=NULL; + + bool main; + + if (tag->name=="ext_resource") { + + error=ERR_FILE_CORRUPT; + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field."); + ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT); + + String type="Resource"; + if (tag->args.has("type")) + type=tag->args["type"]; + + String path = tag->args["path"]; + + + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> can't use a local path, this is a bug?."); + ERR_FAIL_COND_V(path.begins_with("local://"),ERR_FILE_CORRUPT); + + if (path.find("://")==-1 && path.is_rel_path()) { + // path is relative to file being loaded, so convert to a resource path + path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path)); + } + + if (remaps.has(path)) { + path=remaps[path]; + } + + RES res = ResourceLoader::load(path,type); + + if (res.is_null()) { + + if (ResourceLoader::get_abort_on_missing_resources()) { + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> referenced nonexistent resource at: "+path); + ERR_FAIL_V(error); + } else { + ResourceLoader::notify_dependency_error(local_path,path,type); + } + } else { + + resource_cache.push_back(res); + } + + if (tag->args.has("index")) { + ExtResource er; + er.path=path; + er.type=type; + ext_resources[tag->args["index"].to_int()]=er; + } + + + Error err = close_tag("ext_resource"); + if (err) + return error; + + + error=OK; + resource_current++; + return error; + + } else if (tag->name=="resource") { + + main=false; + } else if (tag->name=="main_resource") { + main=true; + } else { + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": unexpected main tag: "+tag->name); + error=ERR_FILE_CORRUPT; + ERR_FAIL_V(error); + } + + + String type; + String path; + int subres=0; + + if (!main) { + //loading resource + + error=ERR_FILE_CORRUPT; + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <resource> missing 'len' field."); + ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT); + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <resource> missing 'type' field."); + ERR_FAIL_COND_V(!tag->args.has("type"),ERR_FILE_CORRUPT); + path=tag->args["path"]; + + error=OK; + + if (path.begins_with("local://")) { + //built-in resource (but really external) + + path=path.replace("local://",""); + subres=path.to_int(); + path=local_path+"::"+path; + } + + + if (ResourceCache::has(path)) { + Error err = close_tag(tag->name); + if (err) { + error=ERR_FILE_CORRUPT; + } + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Unable to close <resource> tag."); + ERR_FAIL_COND_V( err, err ); + resource_current++; + error=OK; + return OK; + } + + type = tag->args["type"]; + } else { + type=resource_type; + } + + Object *obj = ObjectTypeDB::instance(type); + if (!obj) { + error=ERR_FILE_CORRUPT; + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Object of unrecognized type in file: "+type); + } + ERR_FAIL_COND_V(!obj,ERR_FILE_CORRUPT); + + Resource *r = obj->cast_to<Resource>(); + if (!r) { + error=ERR_FILE_CORRUPT; + memdelete(obj); //bye + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Object type in resource field not a resource, type is: "+obj->get_type()); + ERR_FAIL_COND_V(!r,ERR_FILE_CORRUPT); + } + + res = RES( r ); + if (path!="") + r->set_path(path); + r->set_subindex(subres); + + //load properties + + while(true) { + + String name; + Variant v; + Error err; + err = parse_property(v,name); + if (err==ERR_FILE_EOF) //tag closed + break; + if (err!=OK) { + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Text Parsing aborted."); + ERR_FAIL_COND_V(err!=OK,ERR_FILE_CORRUPT); + } + + obj->set(name,v); + } +#ifdef TOOLS_ENABLED + res->set_edited(false); +#endif + resource_cache.push_back(res); //keep it in mem until finished loading + resource_current++; + if (main) { + f->close(); + resource=res; + resource->set_path(res_path); + error=ERR_FILE_EOF; + return error; + + } + error=OK; +#endif + return OK; +} + +int ResourceInteractiveLoaderText::get_stage() const { + + return resource_current; +} +int ResourceInteractiveLoaderText::get_stage_count() const { + + return resources_total;//+ext_resources; +} + +ResourceInteractiveLoaderText::~ResourceInteractiveLoaderText() { + + memdelete(f); +} + +void ResourceInteractiveLoaderText::get_dependencies(FileAccess *f,List<String> *p_dependencies,bool p_add_types) { + +#if 0 + open(f); + ERR_FAIL_COND(error!=OK); + + while(true) { + bool exit; + Tag *tag = parse_tag(&exit); + + + if (!tag) { + error=ERR_FILE_CORRUPT; + ERR_FAIL_COND(!exit); + error=ERR_FILE_EOF; + return; + } + + if (tag->name!="ext_resource") { + + return; + } + + error=ERR_FILE_CORRUPT; + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field."); + ERR_FAIL_COND(!tag->args.has("path")); + + String path = tag->args["path"]; + + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> can't use a local path, this is a bug?."); + ERR_FAIL_COND(path.begins_with("local://")); + + if (path.find("://")==-1 && path.is_rel_path()) { + // path is relative to file being loaded, so convert to a resource path + path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path)); + } + + if (path.ends_with("*")) { + ERR_FAIL_COND(!tag->args.has("type")); + String type = tag->args["type"]; + path = ResourceLoader::guess_full_filename(path,type); + } + + if (p_add_types && tag->args.has("type")) { + path+="::"+tag->args["type"]; + } + + p_dependencies->push_back(path); + + Error err = close_tag("ext_resource"); + if (err) + return; + + error=OK; + } +#endif +} + +Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) { + + + + if (next_tag.name=="ext_resource") { + + Error err; + + if (!next_tag.fields.has("path")) { + err=ERR_FILE_CORRUPT; + error_text="Missing 'path' in external resource tag"; + _printerr(); + return err; + } + + if (!next_tag.fields.has("type")) { + err=ERR_FILE_CORRUPT; + error_text="Missing 'type' in external resource tag"; + _printerr(); + return err; + } + + if (!next_tag.fields.has("index")) { + err=ERR_FILE_CORRUPT; + error_text="Missing 'index' in external resource tag"; + _printerr(); + return err; + } + + String path=next_tag.fields["path"]; + String type=next_tag.fields["type"]; + int index=next_tag.fields["index"]; + + + if (path.find("://")==-1 && path.is_rel_path()) { + // path is relative to file being loaded, so convert to a resource path + path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path)); + } + + if (remaps.has(path)) { + path=remaps[path]; + } + + RES res = ResourceLoader::load(path,type); + + if (res.is_null()) { + + if (ResourceLoader::get_abort_on_missing_resources()) { + error=ERR_FILE_CORRUPT; + error_text="[ext_resource] referenced nonexistent resource at: "+path; + _printerr(); + return error; + } else { + ResourceLoader::notify_dependency_error(local_path,path,type); + } + } else { + + resource_cache.push_back(res); + } + + ExtResource er; + er.path=path; + er.type=type; + ext_resources[index]=er; + + err = VariantParser::parse_tag(&stream,lines,error_text,next_tag); + + if (err) { + error_text="Unexpected end of file"; + _printerr(); + error=ERR_FILE_CORRUPT; + return error; + } + + return OK; + + + } + +#if 0 + open(p_f); + ERR_FAIL_COND_V(error!=OK,error); + + //FileAccess + + bool old_format=false; + + FileAccess *fw = NULL; + + String base_path=local_path.get_base_dir(); + + while(true) { + bool exit; + List<String> order; + + Tag *tag = parse_tag(&exit,true,&order); + + bool done=false; + + if (!tag) { + if (fw) { + memdelete(fw); + } + error=ERR_FILE_CORRUPT; + ERR_FAIL_COND_V(!exit,error); + error=ERR_FILE_EOF; + + return error; + } + + if (tag->name=="ext_resource") { + + if (!tag->args.has("index") || !tag->args.has("path") || !tag->args.has("type")) { + old_format=true; + break; + } + + if (!fw) { + + fw=FileAccess::open(p_path+".depren",FileAccess::WRITE); + fw->store_line("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); //no escape + fw->store_line("<resource_file type=\""+resource_type+"\" subresource_count=\""+itos(resources_total)+"\" version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\">"); + + } + + String path = tag->args["path"]; + String index = tag->args["index"]; + String type = tag->args["type"]; + + + bool relative=false; + if (!path.begins_with("res://")) { + path=base_path.plus_file(path).simplify_path(); + relative=true; + } + + + if (p_map.has(path)) { + String np=p_map[path]; + path=np; + } + + if (relative) { + //restore relative + path=base_path.path_to_file(path); + } + + tag->args["path"]=path; + tag->args["index"]=index; + tag->args["type"]=type; + + } else { + + done=true; + } + + String tagt="\t<"; + if (exit) + tagt+="/"; + tagt+=tag->name; + + for(List<String>::Element *E=order.front();E;E=E->next()) { + tagt+=" "+E->get()+"=\""+tag->args[E->get()]+"\""; + } + tagt+=">"; + fw->store_line(tagt); + if (done) + break; + close_tag("ext_resource"); + fw->store_line("\t</ext_resource>"); + + } + + + if (old_format) { + if (fw) + memdelete(fw); + + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->remove(p_path+".depren"); + memdelete(da); + //fuck it, use the old approach; + + WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: "+p_path).utf8().get_data()); + + Error err; + FileAccess *f2 = FileAccess::open(p_path,FileAccess::READ,&err); + if (err!=OK) { + ERR_FAIL_COND_V(err!=OK,ERR_FILE_CANT_OPEN); + } + + Ref<ResourceInteractiveLoaderText> ria = memnew( ResourceInteractiveLoaderText ); + ria->local_path=Globals::get_singleton()->localize_path(p_path); + ria->res_path=ria->local_path; + ria->remaps=p_map; + // ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); + ria->open(f2); + + err = ria->poll(); + + while(err==OK) { + err=ria->poll(); + } + + ERR_FAIL_COND_V(err!=ERR_FILE_EOF,ERR_FILE_CORRUPT); + RES res = ria->get_resource(); + ERR_FAIL_COND_V(!res.is_valid(),ERR_FILE_CORRUPT); + + return ResourceFormatSaverText::singleton->save(p_path,res); + } + + if (!fw) { + + return OK; //nothing to rename, do nothing + } + + uint8_t c=f->get_8(); + while(!f->eof_reached()) { + fw->store_8(c); + c=f->get_8(); + } + + bool all_ok = fw->get_error()==OK; + + memdelete(fw); + + if (!all_ok) { + return ERR_CANT_CREATE; + } + + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + da->remove(p_path); + da->rename(p_path+".depren",p_path); + memdelete(da); +#endif + return OK; + +} + + +void ResourceInteractiveLoaderText::open(FileAccess *p_f) { + + error=OK; + + lines=1; + f=p_f; + + + stream.f=f; + is_scene=false; + + + VariantParser::Tag tag; + Error err = VariantParser::parse_tag(&stream,lines,error_text,tag); + + if (err) { + + error=err; + _printerr(); + return; + } + + if (tag.fields.has("format")) { + int fmt = tag.fields["format"]; + if (fmt>FORMAT_VERSION) { + error_text="Saved with newer format version"; + _printerr(); + error=ERR_PARSE_ERROR; + return; + } + } + + print_line("TAG NAME: "+tag.name); + + if (tag.name=="gd_scene") { + is_scene=true; + } else if (tag.name=="gd_resource") { + if (!tag.fields.has("type")) { + error_text="Missing 'type' field in 'gd_resource' tag"; + _printerr(); + error=ERR_PARSE_ERROR; + return; + } + + res_type=tag.fields["type"]; + + } else { + error_text="Unrecognized file type: "+tag.name; + _printerr(); + error=ERR_PARSE_ERROR; + return; + + } + + + + if (tag.fields.has("load_steps")) { + resources_total=tag.fields["load_steps"]; + } else { + resources_total=0; + } + + + err = VariantParser::parse_tag(&stream,lines,error_text,next_tag); + + if (err) { + error_text="Unexpected end of file"; + _printerr(); + error=ERR_FILE_CORRUPT; + } + +} + +void ResourceInteractiveLoaderText::_printerr() { + + ERR_PRINT(String(res_path+":"+itos(lines)+" - Parse Error: "+error_text).utf8().get_data()); +} + + +String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) { + + error=OK; + + lines=1; + f=p_f; + + stream.f=f; + + + VariantParser::Tag tag; + Error err = VariantParser::parse_tag(&stream,lines,error_text,tag); + + if (err) { + _printerr(); + return ""; + } + + if (tag.fields.has("format")) { + int fmt = tag.fields["format"]; + if (fmt>FORMAT_VERSION) { + error_text="Saved with newer format version"; + _printerr(); + return ""; + } + } + + if (tag.name=="gd_scene") + return "PackedScene"; + + if (tag.name!="gd_resource") + return ""; + + + + if (!tag.fields.has("type")) { + error_text="Missing 'type' field in 'gd_resource' tag"; + _printerr(); + return ""; + } + + return tag.fields["type"]; + + +} + +///////////////////// + +Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const String &p_path, Error *r_error) { + + if (r_error) + *r_error=ERR_CANT_OPEN; + + Error err; + FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err); + + + if (err!=OK) { + + ERR_FAIL_COND_V(err!=OK,Ref<ResourceInteractiveLoader>()); + } + + Ref<ResourceInteractiveLoaderText> ria = memnew( ResourceInteractiveLoaderText ); + ria->local_path=Globals::get_singleton()->localize_path(p_path); + ria->res_path=ria->local_path; +// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); + ria->open(f); + + return ria; +} + +void ResourceFormatLoaderText::get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const { + + + if (p_type=="PackedScene") + p_extensions->push_back("tscn"); + else + p_extensions->push_back("tres"); + +} + +void ResourceFormatLoaderText::get_recognized_extensions(List<String> *p_extensions) const{ + + p_extensions->push_back("tscn"); + p_extensions->push_back("tres"); +} + +bool ResourceFormatLoaderText::handles_type(const String& p_type) const{ + + return true; +} +String ResourceFormatLoaderText::get_resource_type(const String &p_path) const{ + + + + String ext=p_path.extension().to_lower(); + if (ext=="tscn") + return "PackedScene"; + + //for anyhting else must test.. + + FileAccess *f = FileAccess::open(p_path,FileAccess::READ); + if (!f) { + + return ""; //could not rwead + } + + Ref<ResourceInteractiveLoaderText> ria = memnew( ResourceInteractiveLoaderText ); + ria->local_path=Globals::get_singleton()->localize_path(p_path); + ria->res_path=ria->local_path; +// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); + String r = ria->recognize(f); + return r; +} + + +void ResourceFormatLoaderText::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) { + + FileAccess *f = FileAccess::open(p_path,FileAccess::READ); + if (!f) { + + ERR_FAIL(); + } + + Ref<ResourceInteractiveLoaderText> ria = memnew( ResourceInteractiveLoaderText ); + ria->local_path=Globals::get_singleton()->localize_path(p_path); + ria->res_path=ria->local_path; +// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); + ria->get_dependencies(f,p_dependencies,p_add_types); + + +} + +Error ResourceFormatLoaderText::rename_dependencies(const String &p_path,const Map<String,String>& p_map) { + + FileAccess *f = FileAccess::open(p_path,FileAccess::READ); + if (!f) { + + ERR_FAIL_V(ERR_CANT_OPEN); + } + + Ref<ResourceInteractiveLoaderText> ria = memnew( ResourceInteractiveLoaderText ); + ria->local_path=Globals::get_singleton()->localize_path(p_path); + ria->res_path=ria->local_path; +// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); + return ria->rename_dependencies(f,p_path,p_map); +} + + +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + + void ResourceFormatSaverTextInstance::write_property(const String& p_name,const Variant& p_property,bool *r_ok) { if (r_ok) @@ -137,11 +901,11 @@ void ResourceFormatSaverTextInstance::write_property(const String& p_name,const Image img=p_property; if (img.empty()) { - f->store_string("RawImage()"); + f->store_string("Image()"); break; } - String imgstr="RawImage( "; + String imgstr="Image( "; imgstr+=itos(img.get_width()); imgstr+=", "+itos(img.get_height()); imgstr+=", "+itos(img.get_mipmaps()); @@ -182,10 +946,9 @@ void ResourceFormatSaverTextInstance::write_property(const String& p_name,const const uint8_t *ptr=r.ptr();; for (int i=0;i<len;i++) { - uint8_t byte = ptr[i]; - const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - char str[3]={ hex[byte>>4], hex[byte&0xF], 0}; - s+=str; + if (i>0) + s+=", "; + s+=itos(ptr[i]); } imgstr+=", "; @@ -215,7 +978,7 @@ void ResourceFormatSaverTextInstance::write_property(const String& p_name,const if (external_resources.has(res)) { - f->store_string("ExtResource( "+itos(external_resources[res]+1)+" )"); + f->store_string("Resource( "+itos(external_resources[res]+1)+" )"); } else { if (internal_resources.has(res)) { @@ -287,7 +1050,7 @@ void ResourceFormatSaverTextInstance::write_property(const String& p_name,const case Variant::RAW_ARRAY: { - f->store_string("RawArray( "); + f->store_string("ByteArray( "); String s; DVector<uint8_t> data = p_property; int len = data.size(); @@ -297,10 +1060,8 @@ void ResourceFormatSaverTextInstance::write_property(const String& p_name,const if (i>0) f->store_string(", "); - uint8_t byte = ptr[i]; - const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - char str[3]={ hex[byte>>4], hex[byte&0xF], 0}; - f->store_string(str); + + f->store_string(itos(ptr[i])); } diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h index 576a78d183..16260835f8 100644 --- a/scene/resources/scene_format_text.h +++ b/scene/resources/scene_format_text.h @@ -5,6 +5,88 @@ #include "io/resource_saver.h" #include "os/file_access.h" #include "scene/resources/packed_scene.h" +#include "variant_parser.h" + + + +class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { + + String local_path; + String res_path; + String error_text; + + FileAccess *f; + + VariantParser::StreamFile stream; + + struct ExtResource { + String path; + String type; + }; + + + bool is_scene; + String res_type; + + + +// Map<String,String> remaps; + + Map<int,ExtResource> ext_resources; + + int resources_total; + int resource_current; + String resource_type; + + VariantParser::Tag next_tag; + + mutable int lines; + + Map<String,String> remaps; + void _printerr(); + +friend class ResourceFormatLoaderText; + + List<RES> resource_cache; + Error parse_property(Variant& r_v, String &r_name); + Error error; + + RES resource; + +public: + + virtual void set_local_path(const String& p_local_path); + virtual Ref<Resource> get_resource(); + virtual Error poll(); + virtual int get_stage() const; + virtual int get_stage_count() const; + + void open(FileAccess *p_f); + String recognize(FileAccess *p_f); + void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types); + Error rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map); + + + ~ResourceInteractiveLoaderText(); + +}; + + + +class ResourceFormatLoaderText : public ResourceFormatLoader { +public: + + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL); + virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const; + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual bool handles_type(const String& p_type) const; + virtual String get_resource_type(const String &p_path) const; + virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false); + virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map); + + +}; + class ResourceFormatSaverTextInstance { diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp index 321ac76240..1a009214ac 100644 --- a/tools/editor/editor_help.cpp +++ b/tools/editor/editor_help.cpp @@ -36,6 +36,14 @@ #include "os/keyboard.h" +void EditorHelpSearch::popup() { + popup_centered_ratio(0.6); + if (search_box->get_text()!="") { + search_box->select_all(); + _update_search(); + } + search_box->grab_focus(); +} void EditorHelpSearch::popup(const String& p_term) { @@ -263,7 +271,7 @@ void EditorHelpSearch::_confirmed() { String mdata=ti->get_metadata(0); emit_signal("go_to_help",mdata); - editor->call("_editor_select",3); // in case EditorHelpSearch beeen invoked on top of other editor window + editor->call("_editor_select",EditorNode::EDITOR_SCRIPT); // in case EditorHelpSearch beeen invoked on top of other editor window // go to that hide(); } @@ -1049,7 +1057,7 @@ Error EditorHelp::_goto_desc(const String& p_class,int p_vscr) { void EditorHelp::_request_help(const String& p_string) { Error err = _goto_desc(p_string); if (err==OK) { - editor->call("_editor_select",3); + editor->call("_editor_select",EditorNode::EDITOR_SCRIPT); } //100 palabras } @@ -1350,7 +1358,6 @@ void EditorHelp::_notification(int p_what) { // forward->set_icon(get_icon("Forward","EditorIcons")); // back->set_icon(get_icon("Back","EditorIcons")); _update_doc(); - editor->connect("request_help",this,"_request_help"); } break; } @@ -1408,7 +1415,6 @@ void EditorHelp::_bind_methods() { ObjectTypeDB::bind_method("_unhandled_key_input",&EditorHelp::_unhandled_key_input); ObjectTypeDB::bind_method("_search",&EditorHelp::_search); ObjectTypeDB::bind_method("_search_cbk",&EditorHelp::_search_cbk); - ObjectTypeDB::bind_method("_help_callback",&EditorHelp::_help_callback); ADD_SIGNAL(MethodInfo("go_to_help")); diff --git a/tools/editor/editor_help.h b/tools/editor/editor_help.h index b5ee6eca6c..04ac4d35ff 100644 --- a/tools/editor/editor_help.h +++ b/tools/editor/editor_help.h @@ -68,7 +68,8 @@ protected: static void _bind_methods(); public: - void popup(const String& p_term=""); + void popup(); + void popup(const String& p_term); EditorHelpSearch(); }; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 4e22592880..2db099d9bf 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -167,11 +167,20 @@ void EditorNode::_unhandled_input(const InputEvent& p_event) { /*case KEY_F1: if (!p_event.key.mod.shift && !p_event.key.mod.command) - _editor_select(3); + _editor_select(EDITOR_SCRIPT); break;*/ - case KEY_F1: _editor_select(0); break; - case KEY_F2: _editor_select(1); break; - case KEY_F3: _editor_select(2); break; + case KEY_F1: + if (!p_event.key.mod.shift && !p_event.key.mod.command) + _editor_select(EDITOR_2D); + break; + case KEY_F2: + if (!p_event.key.mod.shift && !p_event.key.mod.command) + _editor_select(EDITOR_3D); + break; + case KEY_F3: + if (!p_event.key.mod.shift && !p_event.key.mod.command) + _editor_select(EDITOR_SCRIPT); + break; case KEY_F5: _menu_option_confirm((p_event.key.mod.control&&p_event.key.mod.shift)?RUN_PLAY_CUSTOM_SCENE:RUN_PLAY,true); break; case KEY_F6: _menu_option_confirm(RUN_PLAY_SCENE,true); break; case KEY_F7: _menu_option_confirm(RUN_PAUSE,true); break; @@ -289,7 +298,7 @@ void EditorNode::_notification(int p_what) { VisualServer::get_singleton()->viewport_set_hide_canvas(get_scene_root()->get_viewport(),true); VisualServer::get_singleton()->viewport_set_disable_environment(get_viewport()->get_viewport_rid(),true); - _editor_select(1); + _editor_select(EDITOR_3D); if (defer_load_scene!="") { @@ -879,7 +888,7 @@ void EditorNode::_save_scene_with_preview(String p_file) { } } - _editor_select(is2d?0:1); + _editor_select(is2d?EDITOR_2D:EDITOR_3D); VS::get_singleton()->viewport_queue_screen_capture(viewport); save.step("Creating Thumbnail",2); @@ -2519,7 +2528,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { case OBJECT_REQUEST_HELP: { if (current) { - _editor_select(3); + _editor_select(EDITOR_SCRIPT); emit_signal("request_help",current->get_type()); } @@ -3296,9 +3305,9 @@ void EditorNode::_set_main_scene_state(Dictionary p_state) { int n2d=0,n3d=0; _find_node_types(get_edited_scene(),n2d,n3d); if (n2d>n3d) { - _editor_select(0); + _editor_select(EDITOR_2D); } else if (n3d>n2d) { - _editor_select(1); + _editor_select(EDITOR_3D); } } @@ -3857,7 +3866,8 @@ bool EditorNode::_find_editing_changed_scene(Node *p_from) { void EditorNode::add_io_error(const String& p_error) { - + CharString err_ut = p_error.utf8(); + ERR_PRINT(err_ut.get_data()); _load_error_notify(singleton,p_error); } diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 7d8b97688e..2b91929b94 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -529,6 +529,12 @@ protected: static void _bind_methods(); public: + enum EditorTable { + EDITOR_2D = 0, + EDITOR_3D, + EDITOR_SCRIPT + }; + static EditorNode* get_singleton() { return singleton; } diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 65ed420a51..e01cf72149 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -881,18 +881,17 @@ void ScriptEditor::_menu_option(int p_option) { } break; case SEARCH_HELP: { - help_search_dialog->popup("current"); + help_search_dialog->popup(); } break; case SEARCH_CLASSES: { - if (tab_container->get_tab_count()==0) - break; - String current; - EditorHelp *eh = tab_container->get_child( tab_container->get_current_tab() )->cast_to<EditorHelp>(); - if (eh) { - current=eh->get_class_name(); + if (tab_container->get_tab_count()>0) { + EditorHelp *eh = tab_container->get_child( tab_container->get_current_tab() )->cast_to<EditorHelp>(); + if (eh) { + current=eh->get_class_name(); + } } help_index->popup_centered_ratio(0.6); @@ -1388,6 +1387,7 @@ void ScriptEditor::_notification(int p_what) { if (p_what==NOTIFICATION_READY) { get_tree()->connect("tree_changed",this,"_tree_changed"); + editor->connect("request_help",this,"_request_help"); } if (p_what==NOTIFICATION_EXIT_TREE) { @@ -2205,6 +2205,7 @@ void ScriptEditor::_bind_methods() { ObjectTypeDB::bind_method("_script_split_dragged",&ScriptEditor::_script_split_dragged); ObjectTypeDB::bind_method("_help_class_open",&ScriptEditor::_help_class_open); ObjectTypeDB::bind_method("_help_class_goto",&ScriptEditor::_help_class_goto); + ObjectTypeDB::bind_method("_request_help",&ScriptEditor::_help_class_open); ObjectTypeDB::bind_method("_history_forward",&ScriptEditor::_history_forward); ObjectTypeDB::bind_method("_history_back",&ScriptEditor::_history_back); } diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp index cd6dc06f75..3464b3c9bb 100644 --- a/tools/editor/project_export.cpp +++ b/tools/editor/project_export.cpp @@ -491,6 +491,18 @@ Error ProjectExportDialog::export_platform(const String& p_platform, const Strin Ref<EditorExportPlatform> exporter = EditorImportExport::get_singleton()->get_export_platform(p_platform); if (exporter.is_null()) { ERR_PRINT("Invalid platform for export"); + + List<StringName> platforms; + EditorImportExport::get_singleton()->get_export_platforms(&platforms); + print_line("Valid export plaftorms are:"); + for (List<StringName>::Element *E=platforms.front();E;E=E->next()) + print_line(" \""+E->get()+"\""); + + if (p_quit_after) { + OS::get_singleton()->set_exit_code(255); + get_tree()->quit(); + } + return ERR_INVALID_PARAMETER; } Error err = exporter->export_project(p_path,p_debug); diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 893df04709..04705017d2 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -624,11 +624,6 @@ void ProjectManager::_open_project_confirm() { args.push_back("-editor"); - const String &selected_main = E->get(); - if (selected_main!="") { - args.push_back(selected_main); - } - String exec = OS::get_singleton()->get_executable_path(); OS::ProcessID pid=0; diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 0cafe7459b..8b5bf8c1e1 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -1264,7 +1264,10 @@ void SceneTreeDock::import_subscene() { void SceneTreeDock::_import_subscene() { Node* parent = scene_tree->get_selected(); - ERR_FAIL_COND(!parent); + if (!parent) { + parent = editor_data->get_edited_scene_root(); + ERR_FAIL_COND(!parent); + } import_subscene_dialog->move(parent,edited_scene); editor_data->get_undo_redo().clear_history(); //no undo for now.. |