-Added google play services (needed for some stuff)
-Added new screen resizing options, stretch_2d is removed, new much more flexible ones. -Fixed bug in viewport (can create more instances in 3d-in-2d demo now) -Can set android permissions and screen sizes manually in the export settings -Changed export templates extension to .tpz (too many people unzipped the manually..) -File dialog now ensures that the proper extension is used (will not allow to save without it) -Fixed bug that made collision exceptions not work in 2D
This commit is contained in:
parent
162d2ebe4f
commit
ec4ef2d2e7
33 changed files with 1594 additions and 262 deletions
|
@ -4,6 +4,7 @@
|
|||
#include "io/marshalls.h"
|
||||
#include "io/base64.h"
|
||||
#include "core/globals.h"
|
||||
#include "io/file_access_encrypted.h"
|
||||
|
||||
_ResourceLoader *_ResourceLoader::singleton=NULL;
|
||||
|
||||
|
@ -812,6 +813,44 @@ _Geometry::_Geometry() {
|
|||
///////////////////////// FILE
|
||||
|
||||
|
||||
|
||||
Error _File::open_encrypted(const String& p_path, int p_mode_flags,const Vector<uint8_t>& p_key) {
|
||||
|
||||
Error err = open(p_path,p_mode_flags);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
FileAccessEncrypted *fae = memnew( FileAccessEncrypted );
|
||||
err = fae->open_and_parse(f,p_key,(p_mode_flags==WRITE)?FileAccessEncrypted::MODE_WRITE_AES256:FileAccessEncrypted::MODE_READ);
|
||||
if (err) {
|
||||
memdelete(fae);
|
||||
close();
|
||||
return err;
|
||||
}
|
||||
f=fae;
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error _File::open_encrypted_pass(const String& p_path, int p_mode_flags,const String& p_pass) {
|
||||
|
||||
Error err = open(p_path,p_mode_flags);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
FileAccessEncrypted *fae = memnew( FileAccessEncrypted );
|
||||
err = fae->open_and_parse_password(f,p_pass,(p_mode_flags==WRITE)?FileAccessEncrypted::MODE_WRITE_AES256:FileAccessEncrypted::MODE_READ);
|
||||
if (err) {
|
||||
memdelete(fae);
|
||||
close();
|
||||
return err;
|
||||
}
|
||||
|
||||
f=fae;
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Error _File::open(const String& p_path, int p_mode_flags) {
|
||||
|
||||
close();
|
||||
|
@ -1113,6 +1152,10 @@ Variant _File::get_var() const {
|
|||
|
||||
void _File::_bind_methods() {
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("open_encrypted","path","mode_flags","key"),&_File::open_encrypted);
|
||||
ObjectTypeDB::bind_method(_MD("open_encrypted_with_pass","path","mode_flags","pass"),&_File::open_encrypted_pass);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("open","path","flags"),&_File::open);
|
||||
ObjectTypeDB::bind_method(_MD("close"),&_File::close);
|
||||
ObjectTypeDB::bind_method(_MD("is_open"),&_File::is_open);
|
||||
|
|
|
@ -243,6 +243,10 @@ public:
|
|||
READ_WRITE=3,
|
||||
};
|
||||
|
||||
Error open_encrypted(const String& p_path, int p_mode_flags,const Vector<uint8_t>& p_key);
|
||||
Error open_encrypted_pass(const String& p_path, int p_mode_flags,const String& p_pass);
|
||||
|
||||
|
||||
Error open(const String& p_path, int p_mode_flags); ///< open a file
|
||||
void close(); ///< close a file
|
||||
bool is_open() const; ///< true when file is open
|
||||
|
|
|
@ -10,6 +10,8 @@ name_es="Plataformero"
|
|||
width=800
|
||||
height=480
|
||||
stretch_2d=true
|
||||
stretch_mode="viewport"
|
||||
stretch_aspect="keep"
|
||||
|
||||
[input]
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4602,6 +4602,12 @@ void RasterizerGLES1::canvas_begin() {
|
|||
|
||||
|
||||
}
|
||||
|
||||
void RasterizerGLES1::canvas_disable_blending() {
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void RasterizerGLES1::canvas_set_opacity(float p_opacity) {
|
||||
|
||||
canvas_opacity = p_opacity;
|
||||
|
|
|
@ -1126,6 +1126,7 @@ public:
|
|||
/* CANVAS API */
|
||||
|
||||
virtual void canvas_begin();
|
||||
virtual void canvas_disable_blending();
|
||||
virtual void canvas_set_opacity(float p_opacity);
|
||||
virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode);
|
||||
virtual void canvas_begin_rect(const Matrix32& p_transform);
|
||||
|
|
|
@ -6302,6 +6302,12 @@ void RasterizerGLES2::canvas_begin() {
|
|||
|
||||
|
||||
}
|
||||
|
||||
void RasterizerGLES2::canvas_disable_blending() {
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void RasterizerGLES2::canvas_set_opacity(float p_opacity) {
|
||||
|
||||
canvas_opacity = p_opacity;
|
||||
|
|
|
@ -1373,6 +1373,8 @@ public:
|
|||
/* CANVAS API */
|
||||
|
||||
virtual void canvas_begin();
|
||||
virtual void canvas_disable_blending();
|
||||
|
||||
virtual void canvas_set_opacity(float p_opacity);
|
||||
virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode);
|
||||
virtual void canvas_begin_rect(const Matrix32& p_transform);
|
||||
|
|
|
@ -1,111 +1,97 @@
|
|||
#include "stream_peer_ssl.h"
|
||||
|
||||
|
||||
int StreamPeerSSL::bio_create( BIO *b ) {
|
||||
b->init = 1;
|
||||
b->num = 0;
|
||||
b->ptr = NULL;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
Error StreamPeerSSL::connect(const String &p_host,int p_port,int p_flags) {
|
||||
|
||||
// Set up a SSL_CTX object, which will tell our BIO object how to do its work
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
// Create our BIO object for SSL connections.
|
||||
BIO* bio = BIO_new_ssl_connect(ctx);
|
||||
// Failure?
|
||||
if (bio == NULL) {
|
||||
|
||||
// We need to free up the SSL_CTX before we leave.
|
||||
ERR_FAIL_COND_V(bio==NULL,ERR_CANT_CREATE);
|
||||
}
|
||||
// Makes ssl point to bio's SSL object.
|
||||
BIO_get_ssl(bio, &ssl);
|
||||
// Set the SSL to automatically retry on failure.
|
||||
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
// We're connection to google.com on port 443.
|
||||
BIO_set_conn_hostname(bio, (p_host+":"+itos(p_port)).utf8().get_data());
|
||||
|
||||
// Same as before, try to connect.
|
||||
if (BIO_do_connect(bio) <= 0) {
|
||||
|
||||
ERR_EXPLAIN("Failed to connect to '"+p_host+"'' port "+itos(p_port));
|
||||
BIO_free_all(bio);
|
||||
SSL_CTX_free(ctx);
|
||||
ERR_FAIL_V(ERR_CANT_CONNECT);
|
||||
}
|
||||
|
||||
int StreamPeerSSL::bio_destroy( BIO *b ) {
|
||||
|
||||
if ( b == NULL ) return 0;
|
||||
b->ptr = NULL; /* sb_tls_remove() will free it */
|
||||
b->init = 0;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
// Now we need to do the SSL handshake, so we can communicate.
|
||||
if (BIO_do_handshake(bio) <= 0) {
|
||||
ERR_EXPLAIN("Failed to handshake to '"+p_host+"'' port "+itos(p_port));
|
||||
BIO_free_all(bio);
|
||||
SSL_CTX_free(ctx);
|
||||
ERR_FAIL_V(ERR_CANT_CONNECT);
|
||||
}
|
||||
|
||||
int StreamPeerSSL::bio_read( BIO *b, char *buf, int len ) {
|
||||
|
||||
if ( buf == NULL || len <= 0 ) return 0;
|
||||
|
||||
StreamPeerSSL * sp = (StreamPeerSSL*)b->ptr;
|
||||
|
||||
if (sp->base.is_null())
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
BIO_clear_retry_flags( b );
|
||||
|
||||
Error err;
|
||||
int ret=0;
|
||||
if (sp->block) {
|
||||
err = sp->base->get_data((const uint8_t*)buf,len);
|
||||
if (err==OK)
|
||||
ret=len;
|
||||
} else {
|
||||
|
||||
err = sp->base->get_partial_data((const uint8_t*)buf,len,ret);
|
||||
if (err==OK && ret!=len) {
|
||||
BIO_set_retry_write( b );
|
||||
// Create a buffer for grabbing information from the page.
|
||||
char buf[1024];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
// Create a buffer for the reqest we'll send to the server
|
||||
char send[1024];
|
||||
memset(send, 0, sizeof(send));
|
||||
// Create our GET request.
|
||||
strcat(send, "GET / HTTP/1.1\nHost:google.com\nUser Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\nConnection: Close\n\n");
|
||||
// BIO_puts sends a null-terminated string to the server. In this case it's our GET request.
|
||||
BIO_puts(bio, send);
|
||||
// Loop while there's information to be read.
|
||||
while (1) {
|
||||
// BIO_read() reads data from the server into a buffer. It returns the number of characters read in.
|
||||
int x = BIO_read(bio, buf, sizeof(buf) - 1);
|
||||
// If we haven't read in anything, assume there's nothing more to be sent since we used Connection: Close.
|
||||
if (x == 0) {
|
||||
break;
|
||||
}
|
||||
// If BIO_read() returns a negative number, there was an error
|
||||
else if (x < 0) {
|
||||
// BIO_should_retry lets us know if we should keep trying to read data or not.
|
||||
if (!BIO_should_retry(bio)) {
|
||||
printf("\nRead Failed!\n");
|
||||
BIO_free_all(bio);
|
||||
SSL_CTX_free(ctx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// We actually got some data, without errors!
|
||||
else {
|
||||
// Null-terminate our buffer, just in case
|
||||
buf[x] = 0;
|
||||
// Echo what the server sent to the screen
|
||||
printf("%s", buf);
|
||||
}
|
||||
}
|
||||
// Free up that BIO object we created.
|
||||
BIO_free_all(bio);
|
||||
// Remember, we also need to free up that SSL_CTX object!
|
||||
SSL_CTX_free(ctx);
|
||||
// Return.
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
void StreamPeerSSL::initialize_ssl() {
|
||||
|
||||
CRYPTO_malloc_init(); // Initialize malloc, free, etc for OpenSSL's use
|
||||
SSL_library_init(); // Initialize OpenSSL's SSL libraries
|
||||
SSL_load_error_strings(); // Load SSL error strings
|
||||
ERR_load_BIO_strings(); // Load BIO error strings
|
||||
OpenSSL_add_all_algorithms(); // Load all available encryption algorithms
|
||||
}
|
||||
|
||||
int StreamPeerSSL::bio_write( BIO *b, const char *buf, int len ) {
|
||||
void StreamPeerSSL::finalize_ssl(){
|
||||
|
||||
if ( buf == NULL || len <= 0 ) return 0;
|
||||
|
||||
StreamPeerSSL * sp = (StreamPeerSSL*)b->ptr;
|
||||
|
||||
if (sp->base.is_null())
|
||||
return 0;
|
||||
|
||||
BIO_clear_retry_flags( b );
|
||||
|
||||
Error err;
|
||||
int wrote=0;
|
||||
if (sp->block) {
|
||||
err = sp->base->put_data((const uint8_t*)buf,len);
|
||||
if (err==OK)
|
||||
wrote=len;
|
||||
} else {
|
||||
|
||||
err = sp->base->put_partial_data((const uint8_t*)buf,len,wrote);
|
||||
if (err==OK && wrote!=len) {
|
||||
BIO_set_retry_write( b );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return wrote;
|
||||
}
|
||||
|
||||
long StreamPeerSSL::bio_ctrl( BIO *b, int cmd, long num, void *ptr ) {
|
||||
if ( cmd == BIO_CTRL_FLUSH ) {
|
||||
/* The OpenSSL library needs this */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int StreamPeerSSL::bio_gets( BIO *b, char *buf, int len ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int StreamPeerSSL::bio_puts( BIO *b, const char *str ) {
|
||||
return StreamPeerSSL::bio_write( b, str, strlen( str ) );
|
||||
}
|
||||
|
||||
BIO_METHOD StreamPeerSSL::bio_methods =
|
||||
{
|
||||
( 100 | 0x400 ), /* it's a source/sink BIO */
|
||||
"sockbuf glue",
|
||||
StreamPeerSSL::bio_write,
|
||||
StreamPeerSSL::bio_read,
|
||||
StreamPeerSSL::bio_puts,
|
||||
StreamPeerSSL::bio_gets,
|
||||
StreamPeerSSL::bio_ctrl,
|
||||
StreamPeerSSL::bio_create,
|
||||
StreamPeerSSL::bio_destroy
|
||||
};
|
||||
|
||||
StreamPeerSSL::StreamPeerSSL() {
|
||||
}
|
||||
|
|
|
@ -1,26 +1,43 @@
|
|||
#ifndef STREAM_PEER_SSL_H
|
||||
#define STREAM_PEER_SSL_H
|
||||
|
||||
#include "io/stream_peer.h"
|
||||
#ifdef OPENSSL_ENABLED
|
||||
|
||||
#include "io/stream_peer.h"
|
||||
#include <openssl/applink.c> // To prevent crashing (see the OpenSSL FAQ)
|
||||
#include <openssl/bio.h> // BIO objects for I/O
|
||||
#include <openssl/ssl.h> // SSL and SSL_CTX for SSL connections
|
||||
#include <openssl/err.h> // Error reporting
|
||||
|
||||
#include <stdio.h> // If you don't know what this is for stop reading now.
|
||||
class StreamPeerSSL : public StreamPeer {
|
||||
|
||||
OBJ_TYPE(StreamPeerSSL,StreamPeer);
|
||||
public:
|
||||
|
||||
Ref<StreamPeer> base;
|
||||
bool block;
|
||||
static BIO_METHOD bio_methods;
|
||||
enum ConnectFlags {
|
||||
|
||||
CONNECT_FLAG_BUG_WORKAROUNDS=1,
|
||||
CONNECT_FLAG_NO_SSLV2=2,
|
||||
CONNECT_FLAG_NO_SSLV3=4,
|
||||
CONNECT_FLAG_NO_TLSV1=8,
|
||||
CONNECT_FLAG_NO_COMPRESSION=16,
|
||||
};
|
||||
|
||||
SSL_CTX* ctx;
|
||||
SSL* ssl;
|
||||
BIO* bio;
|
||||
|
||||
static int bio_create( BIO *b );
|
||||
static int bio_destroy( BIO *b );
|
||||
static int bio_read( BIO *b, char *buf, int len );
|
||||
static int bio_write( BIO *b, const char *buf, int len );
|
||||
static long bio_ctrl( BIO *b, int cmd, long num, void *ptr );
|
||||
static int bio_gets( BIO *b, char *buf, int len );
|
||||
static int bio_puts( BIO *b, const char *str );
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Error connect(const String &p_host,int p_port);
|
||||
static void initialize_ssl();
|
||||
static void finalize_ssl();
|
||||
|
||||
StreamPeerSSL();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // STREAM_PEER_SSL_H
|
||||
|
|
|
@ -1008,11 +1008,25 @@ bool Main::start() {
|
|||
if (!editor) {
|
||||
//standard helpers that can be changed from main config
|
||||
|
||||
if (GLOBAL_DEF("display/stretch_2d",false).operator bool()) {
|
||||
String stretch_mode = GLOBAL_DEF("display/stretch_mode","disabled");
|
||||
String stretch_aspect = GLOBAL_DEF("display/stretch_aspect","ignore");
|
||||
Size2i stretch_size = Size2(GLOBAL_DEF("display/width",0),GLOBAL_DEF("display/height",0));
|
||||
|
||||
sml->get_root()->set_size_override(true,Size2(Globals::get_singleton()->get("display/width"),Globals::get_singleton()->get("display/height")));
|
||||
sml->get_root()->set_size_override_stretch(true);
|
||||
}
|
||||
SceneMainLoop::StretchMode sml_sm=SceneMainLoop::STRETCH_MODE_DISABLED;
|
||||
if (stretch_mode=="2d")
|
||||
sml_sm=SceneMainLoop::STRETCH_MODE_2D;
|
||||
else if (stretch_mode=="viewport")
|
||||
sml_sm=SceneMainLoop::STRETCH_MODE_VIEWPORT;
|
||||
|
||||
SceneMainLoop::StretchAspect sml_aspect=SceneMainLoop::STRETCH_ASPECT_IGNORE;
|
||||
if (stretch_aspect=="keep")
|
||||
sml_aspect=SceneMainLoop::STRETCH_ASPECT_KEEP;
|
||||
else if (stretch_aspect=="keep_width")
|
||||
sml_aspect=SceneMainLoop::STRETCH_ASPECT_KEEP_WIDTH;
|
||||
else if (stretch_aspect=="keep_height")
|
||||
sml_aspect=SceneMainLoop::STRETCH_ASPECT_KEEP_HEIGHT;
|
||||
|
||||
sml->set_screen_stretch(sml_sm,sml_aspect,stretch_size);
|
||||
|
||||
sml->set_auto_accept_quit(GLOBAL_DEF("application/auto_accept_quit",true));
|
||||
String appname = Globals::get_singleton()->get("application/name");
|
||||
|
@ -1021,7 +1035,10 @@ bool Main::start() {
|
|||
|
||||
|
||||
} else {
|
||||
GLOBAL_DEF("display/stretch_2d",false);
|
||||
GLOBAL_DEF("display/stretch_mode","disabled");
|
||||
Globals::get_singleton()->set_custom_property_info("display/stretch_mode",PropertyInfo(Variant::STRING,"display/stretch_mode",PROPERTY_HINT_ENUM,"disabled,2d,viewport"));
|
||||
GLOBAL_DEF("display/stretch_aspect","ignore");
|
||||
Globals::get_singleton()->set_custom_property_info("display/stretch_aspect",PropertyInfo(Variant::STRING,"display/stretch_aspect",PROPERTY_HINT_ENUM,"ignore,keep,keep_width,keep_height"));
|
||||
sml->set_auto_accept_quit(GLOBAL_DEF("application/auto_accept_quit",true));
|
||||
|
||||
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
android:versionName="1.0"
|
||||
android:installLocation="preferExternal"
|
||||
>
|
||||
<supports-screens android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:largeScreens="true"
|
||||
android:xlargeScreens="true"/>
|
||||
|
||||
<application android:label="@string/godot_project_name_string" android:icon="@drawable/icon">
|
||||
<activity android:name="com.android.godot.Godot"
|
||||
android:label="@string/godot_project_name_string"
|
||||
|
@ -26,14 +31,172 @@ $$ADD_APPLICATION_CHUNKS$$
|
|||
|
||||
</application>
|
||||
<uses-feature android:glEsVersion="0x00020000"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<uses-permission android:name="godot.ACCESS_CHECKIN_PROPERTIES"/>
|
||||
<uses-permission android:name="godot.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="godot.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="godot.ACCESS_LOCATION_EXTRA_COMMANDS"/>
|
||||
<uses-permission android:name="godot.ACCESS_MOCK_LOCATION"/>
|
||||
<uses-permission android:name="godot.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="godot.ACCESS_SURFACE_FLINGER"/>
|
||||
<uses-permission android:name="godot.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="godot.ACCOUNT_MANAGER"/>
|
||||
<uses-permission android:name="godot.ADD_VOICEMAIL"/>
|
||||
<uses-permission android:name="godot.AUTHENTICATE_ACCOUNTS"/>
|
||||
<uses-permission android:name="godot.BATTERY_STATS"/>
|
||||
<uses-permission android:name="godot.BIND_ACCESSIBILITY_SERVICE"/>
|
||||
<uses-permission android:name="godot.BIND_APPWIDGET"/>
|
||||
<uses-permission android:name="godot.BIND_DEVICE_ADMIN"/>
|
||||
<uses-permission android:name="godot.BIND_INPUT_METHOD"/>
|
||||
<uses-permission android:name="godot.BIND_NFC_SERVICE"/>
|
||||
<uses-permission android:name="godot.BIND_NOTIFICATION_LISTENER_SERVICE"/>
|
||||
<uses-permission android:name="godot.BIND_PRINT_SERVICE"/>
|
||||
<uses-permission android:name="godot.BIND_REMOTEVIEWS"/>
|
||||
<uses-permission android:name="godot.BIND_TEXT_SERVICE"/>
|
||||
<uses-permission android:name="godot.BIND_VPN_SERVICE"/>
|
||||
<uses-permission android:name="godot.BIND_WALLPAPER"/>
|
||||
<uses-permission android:name="godot.BLUETOOTH"/>
|
||||
<uses-permission android:name="godot.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="godot.BLUETOOTH_PRIVILEGED"/>
|
||||
<uses-permission android:name="godot.BRICK"/>
|
||||
<uses-permission android:name="godot.BROADCAST_PACKAGE_REMOVED"/>
|
||||
<uses-permission android:name="godot.BROADCAST_SMS"/>
|
||||
<uses-permission android:name="godot.BROADCAST_STICKY"/>
|
||||
<uses-permission android:name="godot.BROADCAST_WAP_PUSH"/>
|
||||
<uses-permission android:name="godot.CALL_PHONE"/>
|
||||
<uses-permission android:name="godot.CALL_PRIVILEGED"/>
|
||||
<uses-permission android:name="godot.CAMERA"/>
|
||||
<uses-permission android:name="godot.CAPTURE_AUDIO_OUTPUT"/>
|
||||
<uses-permission android:name="godot.CAPTURE_SECURE_VIDEO_OUTPUT"/>
|
||||
<uses-permission android:name="godot.CAPTURE_VIDEO_OUTPUT"/>
|
||||
<uses-permission android:name="godot.CHANGE_COMPONENT_ENABLED_STATE"/>
|
||||
<uses-permission android:name="godot.CHANGE_CONFIGURATION"/>
|
||||
<uses-permission android:name="godot.CHANGE_NETWORK_STATE"/>
|
||||
<uses-permission android:name="godot.CHANGE_WIFI_MULTICAST_STATE"/>
|
||||
<uses-permission android:name="godot.CHANGE_WIFI_STATE"/>
|
||||
<uses-permission android:name="godot.CLEAR_APP_CACHE"/>
|
||||
<uses-permission android:name="godot.CLEAR_APP_USER_DATA"/>
|
||||
<uses-permission android:name="godot.CONTROL_LOCATION_UPDATES"/>
|
||||
<uses-permission android:name="godot.DELETE_CACHE_FILES"/>
|
||||
<uses-permission android:name="godot.DELETE_PACKAGES"/>
|
||||
<uses-permission android:name="godot.DEVICE_POWER"/>
|
||||
<uses-permission android:name="godot.DIAGNOSTIC"/>
|
||||
<uses-permission android:name="godot.DISABLE_KEYGUARD"/>
|
||||
<uses-permission android:name="godot.DUMP"/>
|
||||
<uses-permission android:name="godot.EXPAND_STATUS_BAR"/>
|
||||
<uses-permission android:name="godot.FACTORY_TEST"/>
|
||||
<uses-permission android:name="godot.FLASHLIGHT"/>
|
||||
<uses-permission android:name="godot.FORCE_BACK"/>
|
||||
<uses-permission android:name="godot.GET_ACCOUNTS"/>
|
||||
<uses-permission android:name="godot.GET_PACKAGE_SIZE"/>
|
||||
<uses-permission android:name="godot.GET_TASKS"/>
|
||||
<uses-permission android:name="godot.GET_TOP_ACTIVITY_INFO"/>
|
||||
<uses-permission android:name="godot.GLOBAL_SEARCH"/>
|
||||
<uses-permission android:name="godot.HARDWARE_TEST"/>
|
||||
<uses-permission android:name="godot.INJECT_EVENTS"/>
|
||||
<uses-permission android:name="godot.INSTALL_LOCATION_PROVIDER"/>
|
||||
<uses-permission android:name="godot.INSTALL_PACKAGES"/>
|
||||
<uses-permission android:name="godot.INSTALL_SHORTCUT"/>
|
||||
<uses-permission android:name="godot.INTERNAL_SYSTEM_WINDOW"/>
|
||||
<uses-permission android:name="godot.INTERNET"/>
|
||||
<uses-permission android:name="godot.KILL_BACKGROUND_PROCESSES"/>
|
||||
<uses-permission android:name="godot.LOCATION_HARDWARE"/>
|
||||
<uses-permission android:name="godot.MANAGE_ACCOUNTS"/>
|
||||
<uses-permission android:name="godot.MANAGE_APP_TOKENS"/>
|
||||
<uses-permission android:name="godot.MANAGE_DOCUMENTS"/>
|
||||
<uses-permission android:name="godot.MASTER_CLEAR"/>
|
||||
<uses-permission android:name="godot.MEDIA_CONTENT_CONTROL"/>
|
||||
<uses-permission android:name="godot.MODIFY_AUDIO_SETTINGS"/>
|
||||
<uses-permission android:name="godot.MODIFY_PHONE_STATE"/>
|
||||
<uses-permission android:name="godot.MOUNT_FORMAT_FILESYSTEMS"/>
|
||||
<uses-permission android:name="godot.MOUNT_UNMOUNT_FILESYSTEMS"/>
|
||||
<uses-permission android:name="godot.NFC"/>
|
||||
<uses-permission android:name="godot.PERSISTENT_ACTIVITY"/>
|
||||
<uses-permission android:name="godot.PROCESS_OUTGOING_CALLS"/>
|
||||
<uses-permission android:name="godot.READ_CALENDAR"/>
|
||||
<uses-permission android:name="godot.READ_CALL_LOG"/>
|
||||
<uses-permission android:name="godot.READ_CONTACTS"/>
|
||||
<uses-permission android:name="godot.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="godot.READ_FRAME_BUFFER"/>
|
||||
<uses-permission android:name="godot.READ_HISTORY_BOOKMARKS"/>
|
||||
<uses-permission android:name="godot.READ_INPUT_STATE"/>
|
||||
<uses-permission android:name="godot.READ_LOGS"/>
|
||||
<uses-permission android:name="godot.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="godot.READ_PROFILE"/>
|
||||
<uses-permission android:name="godot.READ_SMS"/>
|
||||
<uses-permission android:name="godot.READ_SOCIAL_STREAM"/>
|
||||
<uses-permission android:name="godot.READ_SYNC_SETTINGS"/>
|
||||
<uses-permission android:name="godot.READ_SYNC_STATS"/>
|
||||
<uses-permission android:name="godot.READ_USER_DICTIONARY"/>
|
||||
<uses-permission android:name="godot.REBOOT"/>
|
||||
<uses-permission android:name="godot.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission android:name="godot.RECEIVE_MMS"/>
|
||||
<uses-permission android:name="godot.RECEIVE_SMS"/>
|
||||
<uses-permission android:name="godot.RECEIVE_WAP_PUSH"/>
|
||||
<uses-permission android:name="godot.RECORD_AUDIO"/>
|
||||
<uses-permission android:name="godot.REORDER_TASKS"/>
|
||||
<uses-permission android:name="godot.RESTART_PACKAGES"/>
|
||||
<uses-permission android:name="godot.SEND_RESPOND_VIA_MESSAGE"/>
|
||||
<uses-permission android:name="godot.SEND_SMS"/>
|
||||
<uses-permission android:name="godot.SET_ACTIVITY_WATCHER"/>
|
||||
<uses-permission android:name="godot.SET_ALARM"/>
|
||||
<uses-permission android:name="godot.SET_ALWAYS_FINISH"/>
|
||||
<uses-permission android:name="godot.SET_ANIMATION_SCALE"/>
|
||||
<uses-permission android:name="godot.SET_DEBUG_APP"/>
|
||||
<uses-permission android:name="godot.SET_ORIENTATION"/>
|
||||
<uses-permission android:name="godot.SET_POINTER_SPEED"/>
|
||||
<uses-permission android:name="godot.SET_PREFERRED_APPLICATIONS"/>
|
||||
<uses-permission android:name="godot.SET_PROCESS_LIMIT"/>
|
||||
<uses-permission android:name="godot.SET_TIME"/>
|
||||
<uses-permission android:name="godot.SET_TIME_ZONE"/>
|
||||
<uses-permission android:name="godot.SET_WALLPAPER"/>
|
||||
<uses-permission android:name="godot.SET_WALLPAPER_HINTS"/>
|
||||
<uses-permission android:name="godot.SIGNAL_PERSISTENT_PROCESSES"/>
|
||||
<uses-permission android:name="godot.STATUS_BAR"/>
|
||||
<uses-permission android:name="godot.SUBSCRIBED_FEEDS_READ"/>
|
||||
<uses-permission android:name="godot.SUBSCRIBED_FEEDS_WRITE"/>
|
||||
<uses-permission android:name="godot.SYSTEM_ALERT_WINDOW"/>
|
||||
<uses-permission android:name="godot.TRANSMIT_IR"/>
|
||||
<uses-permission android:name="godot.UNINSTALL_SHORTCUT"/>
|
||||
<uses-permission android:name="godot.UPDATE_DEVICE_STATS"/>
|
||||
<uses-permission android:name="godot.USE_CREDENTIALS"/>
|
||||
<uses-permission android:name="godot.USE_SIP"/>
|
||||
<uses-permission android:name="godot.VIBRATE"/>
|
||||
<uses-permission android:name="godot.WAKE_LOCK"/>
|
||||
<uses-permission android:name="godot.WRITE_APN_SETTINGS"/>
|
||||
<uses-permission android:name="godot.WRITE_CALENDAR"/>
|
||||
<uses-permission android:name="godot.WRITE_CALL_LOG"/>
|
||||
<uses-permission android:name="godot.WRITE_CONTACTS"/>
|
||||
<uses-permission android:name="godot.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="godot.WRITE_GSERVICES"/>
|
||||
<uses-permission android:name="godot.WRITE_HISTORY_BOOKMARKS"/>
|
||||
<uses-permission android:name="godot.WRITE_PROFILE"/>
|
||||
<uses-permission android:name="godot.WRITE_SECURE_SETTINGS"/>
|
||||
<uses-permission android:name="godot.WRITE_SETTINGS"/>
|
||||
<uses-permission android:name="godot.WRITE_SMS"/>
|
||||
<uses-permission android:name="godot.WRITE_SOCIAL_STREAM"/>
|
||||
<uses-permission android:name="godot.WRITE_SYNC_SETTINGS"/>
|
||||
<uses-permission android:name="godot.WRITE_USER_DICTIONARY"/>
|
||||
<uses-permission android:name="godot.custom.0"/>
|
||||
<uses-permission android:name="godot.custom.1"/>
|
||||
<uses-permission android:name="godot.custom.2"/>
|
||||
<uses-permission android:name="godot.custom.3"/>
|
||||
<uses-permission android:name="godot.custom.4"/>
|
||||
<uses-permission android:name="godot.custom.5"/>
|
||||
<uses-permission android:name="godot.custom.6"/>
|
||||
<uses-permission android:name="godot.custom.7"/>
|
||||
<uses-permission android:name="godot.custom.8"/>
|
||||
<uses-permission android:name="godot.custom.9"/>
|
||||
<uses-permission android:name="godot.custom.0"/>
|
||||
<uses-permission android:name="godot.custom.11"/>
|
||||
<uses-permission android:name="godot.custom.12"/>
|
||||
<uses-permission android:name="godot.custom.13"/>
|
||||
<uses-permission android:name="godot.custom.14"/>
|
||||
<uses-permission android:name="godot.custom.15"/>
|
||||
<uses-permission android:name="godot.custom.16"/>
|
||||
<uses-permission android:name="godot.custom.17"/>
|
||||
<uses-permission android:name="godot.custom.18"/>
|
||||
<uses-permission android:name="godot.custom.19"/>
|
||||
|
||||
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="15"/>
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ def configure(env):
|
|||
env['SPAWN'] = methods.win32_spawn
|
||||
|
||||
env.android_source_modules.append("../libs/apk_expansion")
|
||||
env.android_source_modules.append("../libs/google_play_services")
|
||||
ndk_platform=""
|
||||
|
||||
ndk_platform="android-15"
|
||||
|
|
|
@ -10,10 +10,169 @@
|
|||
#include "os/os.h"
|
||||
#include "platform/android/logo.h"
|
||||
|
||||
|
||||
static const char* android_perms[]={
|
||||
"ACCESS_CHECKIN_PROPERTIES",
|
||||
"ACCESS_COARSE_LOCATION",
|
||||
"ACCESS_FINE_LOCATION",
|
||||
"ACCESS_LOCATION_EXTRA_COMMANDS",
|
||||
"ACCESS_MOCK_LOCATION",
|
||||
"ACCESS_NETWORK_STATE",
|
||||
"ACCESS_SURFACE_FLINGER",
|
||||
"ACCESS_WIFI_STATE",
|
||||
"ACCOUNT_MANAGER",
|
||||
"ADD_VOICEMAIL",
|
||||
"AUTHENTICATE_ACCOUNTS",
|
||||
"BATTERY_STATS",
|
||||
"BIND_ACCESSIBILITY_SERVICE",
|
||||
"BIND_APPWIDGET",
|
||||
"BIND_DEVICE_ADMIN",
|
||||
"BIND_INPUT_METHOD",
|
||||
"BIND_NFC_SERVICE",
|
||||
"BIND_NOTIFICATION_LISTENER_SERVICE",
|
||||
"BIND_PRINT_SERVICE",
|
||||
"BIND_REMOTEVIEWS",
|
||||
"BIND_TEXT_SERVICE",
|
||||
"BIND_VPN_SERVICE",
|
||||
"BIND_WALLPAPER",
|
||||
"BLUETOOTH",
|
||||
"BLUETOOTH_ADMIN",
|
||||
"BLUETOOTH_PRIVILEGED",
|
||||
"BRICK",
|
||||
"BROADCAST_PACKAGE_REMOVED",
|
||||
"BROADCAST_SMS",
|
||||
"BROADCAST_STICKY",
|
||||
"BROADCAST_WAP_PUSH",
|
||||
"CALL_PHONE",
|
||||
"CALL_PRIVILEGED",
|
||||
"CAMERA",
|
||||
"CAPTURE_AUDIO_OUTPUT",
|
||||
"CAPTURE_SECURE_VIDEO_OUTPUT",
|
||||
"CAPTURE_VIDEO_OUTPUT",
|
||||
"CHANGE_COMPONENT_ENABLED_STATE",
|
||||
"CHANGE_CONFIGURATION",
|
||||
"CHANGE_NETWORK_STATE",
|
||||
"CHANGE_WIFI_MULTICAST_STATE",
|
||||
"CHANGE_WIFI_STATE",
|
||||
"CLEAR_APP_CACHE",
|
||||
"CLEAR_APP_USER_DATA",
|
||||
"CONTROL_LOCATION_UPDATES",
|
||||
"DELETE_CACHE_FILES",
|
||||
"DELETE_PACKAGES",
|
||||
"DEVICE_POWER",
|
||||
"DIAGNOSTIC",
|
||||
"DISABLE_KEYGUARD",
|
||||
"DUMP",
|
||||
"EXPAND_STATUS_BAR",
|
||||
"FACTORY_TEST",
|
||||
"FLASHLIGHT",
|
||||
"FORCE_BACK",
|
||||
"GET_ACCOUNTS",
|
||||
"GET_PACKAGE_SIZE",
|
||||
"GET_TASKS",
|
||||
"GET_TOP_ACTIVITY_INFO",
|
||||
"GLOBAL_SEARCH",
|
||||
"HARDWARE_TEST",
|
||||
"INJECT_EVENTS",
|
||||
"INSTALL_LOCATION_PROVIDER",
|
||||
"INSTALL_PACKAGES",
|
||||
"INSTALL_SHORTCUT",
|
||||
"INTERNAL_SYSTEM_WINDOW",
|
||||
"INTERNET",
|
||||
"KILL_BACKGROUND_PROCESSES",
|
||||
"LOCATION_HARDWARE",
|
||||
"MANAGE_ACCOUNTS",
|
||||
"MANAGE_APP_TOKENS",
|
||||
"MANAGE_DOCUMENTS",
|
||||
"MASTER_CLEAR",
|
||||
"MEDIA_CONTENT_CONTROL",
|
||||
"MODIFY_AUDIO_SETTINGS",
|
||||
"MODIFY_PHONE_STATE",
|
||||
"MOUNT_FORMAT_FILESYSTEMS",
|
||||
"MOUNT_UNMOUNT_FILESYSTEMS",
|
||||
"NFC",
|
||||
"PERSISTENT_ACTIVITY",
|
||||
"PROCESS_OUTGOING_CALLS",
|
||||
"READ_CALENDAR",
|
||||
"READ_CALL_LOG",
|
||||
"READ_CONTACTS",
|
||||
"READ_EXTERNAL_STORAGE",
|
||||
"READ_FRAME_BUFFER",
|
||||
"READ_HISTORY_BOOKMARKS",
|
||||
"READ_INPUT_STATE",
|
||||
"READ_LOGS",
|
||||
"READ_PHONE_STATE",
|
||||
"READ_PROFILE",
|
||||
"READ_SMS",
|
||||
"READ_SOCIAL_STREAM",
|
||||
"READ_SYNC_SETTINGS",
|
||||
"READ_SYNC_STATS",
|
||||
"READ_USER_DICTIONARY",
|
||||
"REBOOT",
|
||||
"RECEIVE_BOOT_COMPLETED",
|
||||
"RECEIVE_MMS",
|
||||
"RECEIVE_SMS",
|
||||
"RECEIVE_WAP_PUSH",
|
||||
"RECORD_AUDIO",
|
||||
"REORDER_TASKS",
|
||||
"RESTART_PACKAGES",
|
||||
"SEND_RESPOND_VIA_MESSAGE",
|
||||
"SEND_SMS",
|
||||
"SET_ACTIVITY_WATCHER",
|
||||
"SET_ALARM",
|
||||
"SET_ALWAYS_FINISH",
|
||||
"SET_ANIMATION_SCALE",
|
||||
"SET_DEBUG_APP",
|
||||
"SET_ORIENTATION",
|
||||
"SET_POINTER_SPEED",
|
||||
"SET_PREFERRED_APPLICATIONS",
|
||||
"SET_PROCESS_LIMIT",
|
||||
"SET_TIME",
|
||||
"SET_TIME_ZONE",
|
||||
"SET_WALLPAPER",
|
||||
"SET_WALLPAPER_HINTS",
|
||||
"SIGNAL_PERSISTENT_PROCESSES",
|
||||
"STATUS_BAR",
|
||||
"SUBSCRIBED_FEEDS_READ",
|
||||
"SUBSCRIBED_FEEDS_WRITE",
|
||||
"SYSTEM_ALERT_WINDOW",
|
||||
"TRANSMIT_IR",
|
||||
"UNINSTALL_SHORTCUT",
|
||||
"UPDATE_DEVICE_STATS",
|
||||
"USE_CREDENTIALS",
|
||||
"USE_SIP",
|
||||
"VIBRATE",
|
||||
"WAKE_LOCK",
|
||||
"WRITE_APN_SETTINGS",
|
||||
"WRITE_CALENDAR",
|
||||
"WRITE_CALL_LOG",
|
||||
"WRITE_CONTACTS",
|
||||
"WRITE_EXTERNAL_STORAGE",
|
||||
"WRITE_GSERVICES",
|
||||
"WRITE_HISTORY_BOOKMARKS",
|
||||
"WRITE_PROFILE",
|
||||
"WRITE_SECURE_SETTINGS",
|
||||
"WRITE_SETTINGS",
|
||||
"WRITE_SMS",
|
||||
"WRITE_SOCIAL_STREAM",
|
||||
"WRITE_SYNC_SETTINGS",
|
||||
"WRITE_USER_DICTIONARY",
|
||||
NULL};
|
||||
|
||||
class EditorExportPlatformAndroid : public EditorExportPlatform {
|
||||
|
||||
OBJ_TYPE( EditorExportPlatformAndroid,EditorExportPlatform );
|
||||
|
||||
|
||||
enum {
|
||||
MAX_USER_PERMISSIONS=20,
|
||||
SCREEN_SMALL=0,
|
||||
SCREEN_NORMAL=1,
|
||||
SCREEN_LARGE=2,
|
||||
SCREEN_XLARGE=3,
|
||||
SCREEN_MAX=4
|
||||
};
|
||||
|
||||
String custom_release_package;
|
||||
String custom_debug_package;
|
||||
|
||||
|
@ -47,6 +206,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||
Thread *device_thread;
|
||||
Ref<ImageTexture> logo;
|
||||
|
||||
Set<String> perms;
|
||||
String user_perms[MAX_USER_PERMISSIONS];
|
||||
bool screen_support[SCREEN_MAX];
|
||||
|
||||
volatile bool quit_request;
|
||||
|
||||
|
||||
|
@ -104,11 +267,33 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant&
|
|||
_signed=p_value;
|
||||
else if (n=="screen/orientation")
|
||||
orientation=p_value;
|
||||
else if (n=="screen/support_small")
|
||||
screen_support[SCREEN_SMALL]=p_value;
|
||||
else if (n=="screen/support_normal")
|
||||
screen_support[SCREEN_NORMAL]=p_value;
|
||||
else if (n=="screen/support_large")
|
||||
screen_support[SCREEN_LARGE]=p_value;
|
||||
else if (n=="screen/support_xlarge")
|
||||
screen_support[SCREEN_XLARGE]=p_value;
|
||||
else if (n=="keystore/release")
|
||||
release_keystore=p_value;
|
||||
else if (n=="keystore/release_user")
|
||||
release_username=p_value;
|
||||
else if (n.begins_with("permissions/")) {
|
||||
|
||||
String what = n.get_slice("/",1).to_upper();
|
||||
bool state = p_value;
|
||||
if (state)
|
||||
perms.insert(what);
|
||||
else
|
||||
perms.erase(what);
|
||||
} else if (n.begins_with("user_permissions/")) {
|
||||
|
||||
int which = n.get_slice("/",1).to_int();
|
||||
ERR_FAIL_INDEX_V(which,MAX_USER_PERMISSIONS,false);
|
||||
user_perms[which]=p_value;
|
||||
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -132,15 +317,33 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret)
|
|||
r_ret=_signed;
|
||||
else if (n=="screen/orientation")
|
||||
r_ret=orientation;
|
||||
else if (n=="screen/support_small")
|
||||
r_ret=screen_support[SCREEN_SMALL];
|
||||
else if (n=="screen/support_normal")
|
||||
r_ret=screen_support[SCREEN_NORMAL];
|
||||
else if (n=="screen/support_large")
|
||||
r_ret=screen_support[SCREEN_LARGE];
|
||||
else if (n=="screen/support_xlarge")
|
||||
r_ret=screen_support[SCREEN_XLARGE];
|
||||
else if (n=="keystore/release")
|
||||
r_ret=release_keystore;
|
||||
else if (n=="keystore/release_user")
|
||||
r_ret=release_username;
|
||||
else
|
||||
else if (n.begins_with("permissions/")) {
|
||||
|
||||
String what = n.get_slice("/",1).to_upper();
|
||||
r_ret = perms.has(what);
|
||||
} else if (n.begins_with("user_permissions/")) {
|
||||
|
||||
int which = n.get_slice("/",1).to_int();
|
||||
ERR_FAIL_INDEX_V(which,MAX_USER_PERMISSIONS,false);
|
||||
r_ret=user_perms[which];
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditorExportPlatformAndroid::_get_property_list( List<PropertyInfo> *p_list) const{
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_FILE,"apk"));
|
||||
|
@ -152,9 +355,25 @@ void EditorExportPlatformAndroid::_get_property_list( List<PropertyInfo> *p_list
|
|||
p_list->push_back( PropertyInfo( Variant::STRING, "package/icon",PROPERTY_HINT_FILE,"png") );
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "package/signed") );
|
||||
p_list->push_back( PropertyInfo( Variant::INT, "screen/orientation",PROPERTY_HINT_ENUM,"Landscape,Portrait") );
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_small") );
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_normal") );
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_large") );
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_xlarge") );
|
||||
p_list->push_back( PropertyInfo( Variant::STRING, "keystore/release",PROPERTY_HINT_FILE,"keystore") );
|
||||
p_list->push_back( PropertyInfo( Variant::STRING, "keystore/release_user" ) );
|
||||
|
||||
const char **perms = android_perms;
|
||||
while(*perms) {
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "permissions/"+String(*perms).to_lower()));
|
||||
perms++;
|
||||
}
|
||||
|
||||
for(int i=0;i<MAX_USER_PERMISSIONS;i++) {
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::STRING, "user_permissions/"+itos(i)));
|
||||
}
|
||||
|
||||
//p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)"));
|
||||
|
||||
}
|
||||
|
@ -536,6 +755,53 @@ void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest) {
|
|||
}
|
||||
}
|
||||
|
||||
if (tname=="uses-permission" && /*nspace=="android" &&*/ attrname=="name") {
|
||||
|
||||
if (value.begins_with("godot.custom")) {
|
||||
|
||||
int which = value.get_slice(".",2).to_int();
|
||||
if (which>=0 && which<MAX_USER_PERMISSIONS && user_perms[which].strip_edges()!="") {
|
||||
|
||||
string_table[attr_value]=user_perms[which].strip_edges();
|
||||
}
|
||||
|
||||
} else if (value.begins_with("godot.")) {
|
||||
String perm = value.get_slice(".",1);
|
||||
if (perms.has(perm)) {
|
||||
string_table[attr_value]="android.permission."+perm;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (tname=="supports-screens" ) {
|
||||
|
||||
if (attr_value==0xFFFFFFFF) {
|
||||
WARN_PRINT("Screen res name in a resource, should be plaintext")
|
||||
} else if (attrname=="smallScreens") {
|
||||
|
||||
print_line("SMALLSCREEN");
|
||||
string_table[attr_value]=screen_support[SCREEN_SMALL]?"true":"false";
|
||||
|
||||
} else if (attrname=="mediumScreens") {
|
||||
|
||||
print_line("MEDSCREEN");
|
||||
string_table[attr_value]=screen_support[SCREEN_NORMAL]?"true":"false";
|
||||
|
||||
} else if (attrname=="largeScreens") {
|
||||
|
||||
print_line("LARGECREEN");
|
||||
string_table[attr_value]=screen_support[SCREEN_LARGE]?"true":"false";
|
||||
|
||||
} else if (attrname=="xlargeScreens") {
|
||||
|
||||
print_line("XLARGECREEN");
|
||||
string_table[attr_value]=screen_support[SCREEN_XLARGE]?"true":"false";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
iofs+=20;
|
||||
}
|
||||
|
||||
|
@ -1144,6 +1410,9 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
|
|||
Image img( _android_logo );
|
||||
logo = Ref<ImageTexture>( memnew( ImageTexture ));
|
||||
logo->create_from_image(img);
|
||||
|
||||
for(int i=0;i<4;i++)
|
||||
screen_support[i]=true;
|
||||
}
|
||||
|
||||
bool EditorExportPlatformAndroid::can_export(String *r_error) const {
|
||||
|
|
|
@ -25,7 +25,11 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
});
|
||||
};
|
||||
|
||||
/* public string requestPurchasedTicket(){
|
||||
activity.getPaymentsManager()
|
||||
}
|
||||
|
||||
*/
|
||||
static public Godot.SingletonBase initialize(Activity p_activity) {
|
||||
|
||||
return new GodotPaymentV3(p_activity);
|
||||
|
@ -40,8 +44,8 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
|
|||
|
||||
|
||||
|
||||
public void callbackSuccess(){
|
||||
GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{});
|
||||
public void callbackSuccess(String ticket){
|
||||
GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket});
|
||||
}
|
||||
|
||||
public void callbackFail(){
|
||||
|
|
|
@ -61,7 +61,7 @@ abstract public class HandlePurchaseTask {
|
|||
pc.setConsumableFlag("block", productId, true);
|
||||
pc.setConsumableValue("token", productId, purchaseToken);
|
||||
|
||||
success(purchaseToken, productId);
|
||||
success(purchaseData);
|
||||
return;
|
||||
} catch (JSONException e) {
|
||||
error(e.getMessage());
|
||||
|
@ -71,7 +71,7 @@ abstract public class HandlePurchaseTask {
|
|||
}
|
||||
}
|
||||
|
||||
abstract protected void success(String purchaseToken, String sku);
|
||||
abstract protected void success(String ticket);
|
||||
abstract protected void error(String message);
|
||||
abstract protected void canceled();
|
||||
|
||||
|
|
|
@ -84,8 +84,9 @@ public class PaymentsManager {
|
|||
new HandlePurchaseTask(activity){
|
||||
|
||||
@Override
|
||||
protected void success(String purchaseToken, String sku) {
|
||||
validatePurchase(purchaseToken, sku);
|
||||
protected void success(String ticket) {
|
||||
godotPaymentV3.callbackSuccess(ticket);
|
||||
//validatePurchase(purchaseToken, sku);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -112,7 +113,7 @@ public class PaymentsManager {
|
|||
|
||||
@Override
|
||||
protected void success() {
|
||||
godotPaymentV3.callbackSuccess();
|
||||
godotPaymentV3.callbackSuccess("");
|
||||
|
||||
}
|
||||
|
||||
|
@ -145,7 +146,5 @@ public class PaymentsManager {
|
|||
this.godotPaymentV3 = godotPaymentV3;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -821,6 +821,17 @@ void CanvasItem::_bind_methods() {
|
|||
|
||||
}
|
||||
|
||||
Matrix32 CanvasItem::get_canvas_transform() const {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_scene(),Matrix32());
|
||||
|
||||
if (canvas_layer)
|
||||
return canvas_layer->get_transform();
|
||||
else
|
||||
return get_viewport()->get_canvas_transform();
|
||||
|
||||
}
|
||||
|
||||
Matrix32 CanvasItem::get_viewport_transform() const {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_scene(),Matrix32());
|
||||
|
|
|
@ -195,6 +195,8 @@ public:
|
|||
void set_block_transform_notify(bool p_enable);
|
||||
bool is_block_transform_notify_enabled() const;
|
||||
|
||||
|
||||
Matrix32 get_canvas_transform() const;
|
||||
Matrix32 get_viewport_transform() const;
|
||||
Rect2 get_viewport_rect() const;
|
||||
RID get_viewport_rid() const;
|
||||
|
|
|
@ -955,7 +955,7 @@ void Control::_window_input_event(InputEvent p_event) {
|
|||
|
||||
window->key_event_accepted=false;
|
||||
|
||||
Point2 mpos =(get_viewport_transform()).affine_inverse().xform(Point2(p_event.mouse_button.x,p_event.mouse_button.y));
|
||||
Point2 mpos =(get_canvas_transform()).affine_inverse().xform(Point2(p_event.mouse_button.x,p_event.mouse_button.y));
|
||||
|
||||
if (p_event.mouse_button.pressed) {
|
||||
|
||||
|
@ -1102,7 +1102,7 @@ void Control::_window_input_event(InputEvent p_event) {
|
|||
|
||||
window->key_event_accepted=false;
|
||||
|
||||
Matrix32 localizer = (get_viewport_transform()).affine_inverse();
|
||||
Matrix32 localizer = (get_canvas_transform()).affine_inverse();
|
||||
Size2 pos = localizer.xform(Size2(p_event.mouse_motion.x,p_event.mouse_motion.y)) - _window_get_pos();
|
||||
Vector2 speed = localizer.basis_xform(Point2(p_event.mouse_motion.speed_x,p_event.mouse_motion.speed_y));
|
||||
Vector2 rel = localizer.basis_xform(Point2(p_event.mouse_motion.relative_x,p_event.mouse_motion.relative_y));
|
||||
|
|
|
@ -516,7 +516,8 @@ bool SceneMainLoop::idle(float p_time){
|
|||
|
||||
|
||||
last_screen_size=win_size;
|
||||
root->set_rect(Rect2(Point2(),last_screen_size));
|
||||
_update_root_rect();
|
||||
|
||||
|
||||
emit_signal("screen_resized");
|
||||
|
||||
|
@ -849,6 +850,120 @@ int SceneMainLoop::get_node_count() const {
|
|||
return node_count;
|
||||
}
|
||||
|
||||
|
||||
void SceneMainLoop::_update_root_rect() {
|
||||
|
||||
|
||||
if (stretch_mode==STRETCH_MODE_DISABLED) {
|
||||
root->set_rect(Rect2(Point2(),last_screen_size));
|
||||
return; //user will take care
|
||||
}
|
||||
|
||||
//actual screen video mode
|
||||
Size2 video_mode = Size2(OS::get_singleton()->get_video_mode().width,OS::get_singleton()->get_video_mode().height);
|
||||
Size2 desired_res = stretch_min;
|
||||
|
||||
Size2 viewport_size;
|
||||
Size2 screen_size;
|
||||
|
||||
float viewport_aspect = desired_res.get_aspect();
|
||||
float video_mode_aspect = video_mode.get_aspect();
|
||||
|
||||
if (stretch_aspect==STRETCH_ASPECT_IGNORE || ABS(viewport_aspect - video_mode_aspect)<CMP_EPSILON) {
|
||||
//same aspect or ignore aspect
|
||||
viewport_size=desired_res;
|
||||
screen_size=video_mode;
|
||||
} else if (viewport_aspect < video_mode_aspect) {
|
||||
// screen ratio is smaller vertically
|
||||
|
||||
if (stretch_aspect==STRETCH_ASPECT_KEEP_HEIGHT) {
|
||||
|
||||
//will stretch horizontally
|
||||
viewport_size.x=desired_res.y*video_mode_aspect;
|
||||
viewport_size.y=desired_res.y;
|
||||
screen_size=video_mode;
|
||||
|
||||
} else {
|
||||
//will need black bars
|
||||
viewport_size=desired_res;
|
||||
screen_size.x = video_mode.y * viewport_aspect;
|
||||
screen_size.y=video_mode.y;
|
||||
}
|
||||
} else {
|
||||
//screen ratio is smaller horizontally
|
||||
if (stretch_aspect==STRETCH_ASPECT_KEEP_WIDTH) {
|
||||
|
||||
//will stretch horizontally
|
||||
viewport_size.x=desired_res.x;
|
||||
viewport_size.y=desired_res.x / video_mode_aspect;
|
||||
screen_size=video_mode;
|
||||
|
||||
} else {
|
||||
//will need black bars
|
||||
viewport_size=desired_res;
|
||||
screen_size.x=video_mode.x;
|
||||
screen_size.y = video_mode.x / viewport_aspect;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
screen_size = screen_size.floor();
|
||||
viewport_size = viewport_size.floor();
|
||||
|
||||
Size2 margin;
|
||||
Size2 offset;
|
||||
//black bars and margin
|
||||
if (screen_size.x < video_mode.x) {
|
||||
margin.x = Math::round((video_mode.x - screen_size.x)/2.0);
|
||||
VisualServer::get_singleton()->black_bars_set_margins(margin.x,0,margin.x,0);
|
||||
offset.x = Math::round(margin.x * viewport_size.y / screen_size.y);
|
||||
} else if (screen_size.y < video_mode.y) {
|
||||
|
||||
margin.y = Math::round((video_mode.y - screen_size.y)/2.0);
|
||||
VisualServer::get_singleton()->black_bars_set_margins(0,margin.y,0,margin.y);
|
||||
offset.y = Math::round(margin.y * viewport_size.x / screen_size.x);
|
||||
} else {
|
||||
VisualServer::get_singleton()->black_bars_set_margins(0,0,0,0);
|
||||
}
|
||||
|
||||
// print_line("VP SIZE: "+viewport_size+" OFFSET: "+offset+" = "+(offset*2+viewport_size));
|
||||
// print_line("SS: "+video_mode);
|
||||
switch (stretch_mode) {
|
||||
case STRETCH_MODE_2D: {
|
||||
|
||||
// root->set_rect(Rect2(Point2(),video_mode));
|
||||
root->set_as_render_target(false);
|
||||
root->set_rect(Rect2(margin,screen_size));
|
||||
root->set_size_override_stretch(true);
|
||||
root->set_size_override(true,viewport_size);
|
||||
|
||||
} break;
|
||||
case STRETCH_MODE_VIEWPORT: {
|
||||
|
||||
print_line("VP SIZE: "+viewport_size);
|
||||
root->set_rect(Rect2(Point2(),viewport_size));
|
||||
root->set_size_override_stretch(false);
|
||||
root->set_size_override(false,Size2());
|
||||
root->set_as_render_target(true);
|
||||
root->set_render_target_update_mode(Viewport::RENDER_TARGET_UPDATE_ALWAYS);
|
||||
root->set_render_target_to_screen_rect(Rect2(margin,screen_size));
|
||||
|
||||
} break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SceneMainLoop::set_screen_stretch(StretchMode p_mode,StretchAspect p_aspect,const Size2 p_minsize) {
|
||||
|
||||
stretch_mode=p_mode;
|
||||
stretch_aspect=p_aspect;
|
||||
stretch_min=p_minsize;
|
||||
_update_root_rect();
|
||||
}
|
||||
|
||||
|
||||
void SceneMainLoop::_bind_methods() {
|
||||
|
||||
|
||||
|
@ -874,6 +989,9 @@ void SceneMainLoop::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("get_frame"),&SceneMainLoop::get_frame);
|
||||
ObjectTypeDB::bind_method(_MD("quit"),&SceneMainLoop::quit);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_screen_stretch","mode","aspect","minsize"),&SceneMainLoop::set_screen_stretch);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("queue_delete","obj"),&SceneMainLoop::queue_delete);
|
||||
|
||||
|
||||
|
@ -899,6 +1017,14 @@ void SceneMainLoop::_bind_methods() {
|
|||
BIND_CONSTANT( GROUP_CALL_REALTIME );
|
||||
BIND_CONSTANT( GROUP_CALL_UNIQUE );
|
||||
|
||||
BIND_CONSTANT( STRETCH_MODE_DISABLED );
|
||||
BIND_CONSTANT( STRETCH_MODE_2D );
|
||||
BIND_CONSTANT( STRETCH_MODE_VIEWPORT );
|
||||
BIND_CONSTANT( STRETCH_ASPECT_IGNORE );
|
||||
BIND_CONSTANT( STRETCH_ASPECT_KEEP );
|
||||
BIND_CONSTANT( STRETCH_ASPECT_KEEP_WIDTH );
|
||||
BIND_CONSTANT( STRETCH_ASPECT_KEEP_HEIGHT );
|
||||
|
||||
}
|
||||
|
||||
SceneMainLoop::SceneMainLoop() {
|
||||
|
@ -927,6 +1053,9 @@ SceneMainLoop::SceneMainLoop() {
|
|||
root->set_as_audio_listener(true);
|
||||
root->set_as_audio_listener_2d(true);
|
||||
|
||||
stretch_mode=STRETCH_MODE_DISABLED;
|
||||
stretch_aspect=STRETCH_ASPECT_IGNORE;
|
||||
|
||||
last_screen_size=Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height );
|
||||
root->set_rect(Rect2(Point2(),last_screen_size));
|
||||
|
||||
|
@ -934,7 +1063,6 @@ SceneMainLoop::SceneMainLoop() {
|
|||
ScriptDebugger::get_singleton()->set_request_scene_tree_message_func(_debugger_request_tree,this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,25 @@ class SceneMainLoop : public MainLoop {
|
|||
_THREAD_SAFE_CLASS_
|
||||
|
||||
OBJ_TYPE( SceneMainLoop, MainLoop );
|
||||
public:
|
||||
|
||||
|
||||
enum StretchMode {
|
||||
|
||||
STRETCH_MODE_DISABLED,
|
||||
STRETCH_MODE_2D,
|
||||
STRETCH_MODE_VIEWPORT,
|
||||
};
|
||||
|
||||
enum StretchAspect {
|
||||
|
||||
STRETCH_ASPECT_IGNORE,
|
||||
STRETCH_ASPECT_KEEP,
|
||||
STRETCH_ASPECT_KEEP_WIDTH,
|
||||
STRETCH_ASPECT_KEEP_HEIGHT,
|
||||
};
|
||||
private:
|
||||
|
||||
|
||||
struct Group {
|
||||
|
||||
|
@ -95,6 +114,12 @@ class SceneMainLoop : public MainLoop {
|
|||
Set<Node*> call_skip; //skip erased nodes
|
||||
|
||||
|
||||
StretchMode stretch_mode;
|
||||
StretchAspect stretch_aspect;
|
||||
Size2i stretch_min;
|
||||
|
||||
void _update_root_rect();
|
||||
|
||||
List<ObjectID> delete_queue;
|
||||
|
||||
Map<UGCall,Vector<Variant> > unique_group_calls;
|
||||
|
@ -152,7 +177,6 @@ public:
|
|||
GROUP_CALL_MULIILEVEL=8,
|
||||
};
|
||||
|
||||
|
||||
_FORCE_INLINE_ Viewport *get_root() const { return root; }
|
||||
|
||||
uint32_t get_last_event_id() const;
|
||||
|
@ -196,10 +220,18 @@ public:
|
|||
|
||||
void get_nodes_in_group(const StringName& p_group,List<Node*> *p_list);
|
||||
|
||||
void set_screen_stretch(StretchMode p_mode,StretchAspect p_aspect,const Size2 p_minsize);
|
||||
|
||||
|
||||
SceneMainLoop();
|
||||
~SceneMainLoop();
|
||||
|
||||
};
|
||||
|
||||
|
||||
VARIANT_ENUM_CAST( SceneMainLoop::StretchMode );
|
||||
VARIANT_ENUM_CAST( SceneMainLoop::StretchAspect );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -86,8 +86,9 @@ void Viewport::_update_stretch_transform() {
|
|||
if (size_override_stretch && size_override) {
|
||||
|
||||
stretch_transform=Matrix32();
|
||||
stretch_transform.scale(rect.size/(size_override_size+size_override_margin*2));
|
||||
stretch_transform.elements[2]=size_override_margin;
|
||||
Size2 scale = rect.size/(size_override_size+size_override_margin*2);
|
||||
stretch_transform.scale(scale);
|
||||
stretch_transform.elements[2]=size_override_margin*scale;
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -629,7 +630,9 @@ Ref<World> Viewport::get_world() const{
|
|||
|
||||
Ref<World> Viewport::find_world() const{
|
||||
|
||||
if (world.is_valid())
|
||||
if (own_world.is_valid())
|
||||
return own_world;
|
||||
else if (world.is_valid())
|
||||
return world;
|
||||
else if (parent)
|
||||
return parent->find_world();
|
||||
|
@ -863,6 +866,60 @@ void Viewport::unhandled_input(const InputEvent& p_event) {
|
|||
}
|
||||
}
|
||||
|
||||
void Viewport::set_use_own_world(bool p_world) {
|
||||
|
||||
if (p_world==own_world.is_valid())
|
||||
return;
|
||||
|
||||
|
||||
if (is_inside_scene())
|
||||
_propagate_exit_world(this);
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
if (find_world().is_valid() && camera)
|
||||
camera->notification(Camera::NOTIFICATION_LOST_CURRENT);
|
||||
#endif
|
||||
|
||||
if (!p_world)
|
||||
own_world=Ref<World>();
|
||||
else
|
||||
own_world=Ref<World>( memnew( World ));
|
||||
|
||||
if (is_inside_scene())
|
||||
_propagate_enter_world(this);
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
if (find_world().is_valid() && camera)
|
||||
camera->notification(Camera::NOTIFICATION_BECAME_CURRENT);
|
||||
#endif
|
||||
|
||||
//propagate exit
|
||||
|
||||
if (is_inside_scene()) {
|
||||
VisualServer::get_singleton()->viewport_set_scenario(viewport,find_world()->get_scenario());
|
||||
}
|
||||
|
||||
_update_listener();
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool Viewport::is_using_own_world() const {
|
||||
|
||||
return own_world.is_valid();
|
||||
}
|
||||
|
||||
void Viewport::set_render_target_to_screen_rect(const Rect2& p_rect) {
|
||||
|
||||
to_screen_rect=p_rect;
|
||||
VisualServer::get_singleton()->viewport_set_render_target_to_screen_rect(viewport,to_screen_rect);
|
||||
}
|
||||
|
||||
Rect2 Viewport::get_render_target_to_screen_rect() const{
|
||||
|
||||
return to_screen_rect;
|
||||
}
|
||||
|
||||
|
||||
void Viewport::_bind_methods() {
|
||||
|
||||
|
@ -918,15 +975,20 @@ void Viewport::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method(_MD("update_worlds"), &Viewport::update_worlds);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_use_own_world","enable"), &Viewport::set_use_own_world);
|
||||
ObjectTypeDB::bind_method(_MD("is_using_own_world"), &Viewport::is_using_own_world);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_as_audio_listener","enable"), &Viewport::set_as_audio_listener);
|
||||
ObjectTypeDB::bind_method(_MD("is_audio_listener","enable"), &Viewport::is_audio_listener);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_as_audio_listener_2d","enable"), &Viewport::set_as_audio_listener_2d);
|
||||
ObjectTypeDB::bind_method(_MD("is_audio_listener_2d","enable"), &Viewport::is_audio_listener_2d);
|
||||
ObjectTypeDB::bind_method(_MD("set_render_target_to_screen_rect"), &Viewport::set_render_target_to_screen_rect);
|
||||
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::RECT2,"rect"), _SCS("set_rect"), _SCS("get_rect") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"own_world"), _SCS("set_use_own_world"), _SCS("is_using_own_world") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world",PROPERTY_HINT_RESOURCE_TYPE,"World"), _SCS("set_world"), _SCS("get_world") );
|
||||
// ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world_2d",PROPERTY_HINT_RESOURCE_TYPE,"World2D"), _SCS("set_world_2d"), _SCS("get_world_2d") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") );
|
||||
|
@ -969,6 +1031,7 @@ Viewport::Viewport() {
|
|||
render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE;
|
||||
render_target_texture = Ref<RenderTargetTexture>( memnew( RenderTargetTexture(this) ) );
|
||||
|
||||
|
||||
String id=itos(get_instance_ID());
|
||||
input_group = "_vp_input"+id;
|
||||
gui_input_group = "_vp_gui_input"+id;
|
||||
|
|
|
@ -101,6 +101,7 @@ friend class RenderTargetTexture;
|
|||
Matrix32 stretch_transform;
|
||||
|
||||
Rect2 rect;
|
||||
Rect2 to_screen_rect;
|
||||
|
||||
|
||||
bool size_override;
|
||||
|
@ -120,6 +121,7 @@ friend class RenderTargetTexture;
|
|||
|
||||
Ref<World2D> world_2d;
|
||||
Ref<World> world;
|
||||
Ref<World> own_world;
|
||||
|
||||
StringName input_group;
|
||||
StringName gui_input_group;
|
||||
|
@ -213,9 +215,15 @@ public:
|
|||
void queue_screen_capture();
|
||||
Image get_screen_capture() const;
|
||||
|
||||
void set_use_own_world(bool p_world);
|
||||
bool is_using_own_world() const;
|
||||
|
||||
void input(const InputEvent& p_event);
|
||||
void unhandled_input(const InputEvent& p_event);
|
||||
|
||||
void set_render_target_to_screen_rect(const Rect2& p_rect);
|
||||
Rect2 get_render_target_to_screen_rect() const;
|
||||
|
||||
Viewport();
|
||||
~Viewport();
|
||||
|
||||
|
|
|
@ -770,7 +770,7 @@ void Physics2DServerSW::body_remove_collision_exception(RID p_body, RID p_body_b
|
|||
Body2DSW *body = body_owner.get(p_body);
|
||||
ERR_FAIL_COND(!body);
|
||||
|
||||
body->remove_exception(p_body);
|
||||
body->remove_exception(p_body_b);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -494,6 +494,7 @@ public:
|
|||
};
|
||||
|
||||
virtual void canvas_begin()=0;
|
||||
virtual void canvas_disable_blending()=0;
|
||||
virtual void canvas_set_opacity(float p_opacity)=0;
|
||||
virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode)=0;
|
||||
virtual void canvas_begin_rect(const Matrix32& p_transform)=0;;
|
||||
|
|
|
@ -1384,7 +1384,7 @@ void RasterizerDummy::set_viewport(const VS::ViewportRect& p_viewport) {
|
|||
|
||||
}
|
||||
|
||||
void RasterizerDummy::set_render_target(RID p_render_target,bool p_transparent_bg) {
|
||||
void RasterizerDummy::set_render_target(RID p_render_target, bool p_transparent_bg, bool p_vflip) {
|
||||
|
||||
|
||||
}
|
||||
|
@ -1455,6 +1455,12 @@ void RasterizerDummy::canvas_begin() {
|
|||
|
||||
|
||||
}
|
||||
void RasterizerDummy::canvas_disable_blending() {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RasterizerDummy::canvas_set_opacity(float p_opacity) {
|
||||
|
||||
|
||||
|
|
|
@ -627,7 +627,7 @@ public:
|
|||
virtual void begin_frame();
|
||||
|
||||
virtual void set_viewport(const VS::ViewportRect& p_viewport);
|
||||
virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false);
|
||||
virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false,bool p_vflip=false);
|
||||
virtual void clear_viewport(const Color& p_color);
|
||||
virtual void capture_viewport(Image* r_capture);
|
||||
|
||||
|
@ -652,6 +652,7 @@ public:
|
|||
/* CANVAS API */
|
||||
|
||||
virtual void canvas_begin();
|
||||
virtual void canvas_disable_blending();
|
||||
virtual void canvas_set_opacity(float p_opacity);
|
||||
virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode);
|
||||
virtual void canvas_begin_rect(const Matrix32& p_transform);
|
||||
|
|
|
@ -1145,6 +1145,15 @@ void VisualServerRaster::viewport_set_render_target_vflip(RID p_viewport,bool p_
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect) {
|
||||
|
||||
Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
viewport->rt_to_screen_rect=p_rect;
|
||||
|
||||
}
|
||||
|
||||
bool VisualServerRaster::viewport_get_render_target_vflip(RID p_viewport) const{
|
||||
|
||||
const Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
|
@ -5458,6 +5467,8 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
|
|||
void VisualServerRaster::_draw_viewports() {
|
||||
|
||||
//draw viewports for render targets
|
||||
|
||||
List<Viewport*> to_blit;
|
||||
List<Viewport*> to_disable;
|
||||
for(SelfList<Viewport> *E=viewport_update_list.first();E;E=E->next()) {
|
||||
|
||||
|
@ -5472,6 +5483,9 @@ void VisualServerRaster::_draw_viewports() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (vp->rt_to_screen_rect!=Rect2())
|
||||
to_blit.push_back(vp);
|
||||
|
||||
rasterizer->set_render_target(vp->render_target,vp->transparent_bg,vp->render_target_vflip);
|
||||
_draw_viewport(vp,0,0,vp->rect.width,vp->rect.height);
|
||||
|
||||
|
@ -5491,6 +5505,38 @@ void VisualServerRaster::_draw_viewports() {
|
|||
to_disable.pop_front();
|
||||
}
|
||||
|
||||
|
||||
//draw RTs directly to screen when requested
|
||||
|
||||
for (List<Viewport*>::Element *E=to_blit.front();E;E=E->next()) {
|
||||
|
||||
int window_w = OS::get_singleton()->get_video_mode().width;
|
||||
int window_h = OS::get_singleton()->get_video_mode().height;
|
||||
|
||||
ViewportRect desired_rect;
|
||||
desired_rect.x = desired_rect.y = 0;
|
||||
desired_rect.width = window_w;
|
||||
desired_rect.height = window_h;
|
||||
|
||||
if ( viewport_rect.x != desired_rect.x ||
|
||||
viewport_rect.y != desired_rect.y ||
|
||||
viewport_rect.width != desired_rect.width ||
|
||||
viewport_rect.height != desired_rect.height ) {
|
||||
|
||||
viewport_rect=desired_rect;
|
||||
|
||||
rasterizer->set_viewport(viewport_rect);
|
||||
}
|
||||
|
||||
rasterizer->canvas_begin();
|
||||
rasterizer->canvas_disable_blending();
|
||||
rasterizer->canvas_begin_rect(Matrix32());
|
||||
rasterizer->canvas_draw_rect(E->get()->rt_to_screen_rect,0,Rect2(Point2(),E->get()->rt_to_screen_rect.size),E->get()->render_target_texture,Color(1,1,1));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//draw viewports attached to screen
|
||||
|
||||
for(Map<RID,int>::Element *E=screen_viewports.front();E;E=E->next()) {
|
||||
|
|
|
@ -481,6 +481,8 @@ class VisualServerRaster : public VisualServer {
|
|||
RID render_target;
|
||||
RID render_target_texture;
|
||||
|
||||
Rect2 rt_to_screen_rect;
|
||||
|
||||
bool hide_scenario;
|
||||
bool hide_canvas;
|
||||
bool transparent_bg;
|
||||
|
@ -913,6 +915,7 @@ public:
|
|||
virtual RID viewport_get_render_target_texture(RID p_viewport) const;
|
||||
virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable);
|
||||
virtual bool viewport_get_render_target_vflip(RID p_viewport) const;
|
||||
virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect);
|
||||
|
||||
virtual void viewport_queue_screen_capture(RID p_viewport);
|
||||
virtual Image viewport_get_screen_capture(RID p_viewport) const;
|
||||
|
|
|
@ -891,6 +891,7 @@ public:
|
|||
|
||||
FUNC2(viewport_set_render_target_vflip,RID,bool);
|
||||
FUNC1RC(bool,viewport_get_render_target_vflip,RID);
|
||||
FUNC2(viewport_set_render_target_to_screen_rect,RID,const Rect2&);
|
||||
|
||||
FUNC1(viewport_queue_screen_capture,RID);
|
||||
FUNC1RC(Image,viewport_get_screen_capture,RID);
|
||||
|
|
|
@ -592,6 +592,7 @@ public:
|
|||
|
||||
virtual void viewport_attach_to_screen(RID p_viewport,int p_screen=0)=0;
|
||||
virtual void viewport_detach(RID p_viewport)=0;
|
||||
virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect)=0;
|
||||
|
||||
enum RenderTargetUpdateMode {
|
||||
RENDER_TARGET_UPDATE_DISABLED,
|
||||
|
@ -611,6 +612,8 @@ public:
|
|||
virtual void viewport_queue_screen_capture(RID p_viewport)=0;
|
||||
virtual Image viewport_get_screen_capture(RID p_viewport) const=0;
|
||||
|
||||
|
||||
|
||||
struct ViewportRect {
|
||||
|
||||
int x,y,width,height;
|
||||
|
|
|
@ -3927,7 +3927,7 @@ EditorNode::EditorNode() {
|
|||
file_templates->set_mode(FileDialog::MODE_OPEN_FILE);
|
||||
file_templates->set_access(FileDialog::ACCESS_FILESYSTEM);
|
||||
file_templates->clear_filters();
|
||||
file_templates->add_filter("*.zip ; Zip Template Package");
|
||||
file_templates->add_filter("*.tpz ; Template Package");
|
||||
|
||||
|
||||
file = memnew( FileDialog );
|
||||
|
|
Loading…
Reference in a new issue