diff options
Diffstat (limited to 'platform')
| -rw-r--r-- | platform/android/export/export.cpp | 2 | ||||
| -rw-r--r-- | platform/iphone/app_delegate.mm | 3 | ||||
| -rw-r--r-- | platform/iphone/detect.py | 5 | ||||
| -rwxr-xr-x | platform/iphone/gl_view.h | 8 | ||||
| -rwxr-xr-x | platform/iphone/gl_view.mm | 122 | ||||
| -rw-r--r-- | platform/iphone/os_iphone.cpp | 13 | ||||
| -rw-r--r-- | platform/iphone/os_iphone.h | 3 | ||||
| -rw-r--r-- | platform/windows/SCsub | 1 | ||||
| -rw-r--r-- | platform/windows/os_windows.cpp | 4 | ||||
| -rw-r--r-- | platform/windows/packet_peer_udp_winsock.cpp | 202 | ||||
| -rw-r--r-- | platform/windows/packet_peer_udp_winsock.h | 56 | ||||
| -rw-r--r-- | platform/x11/detect.py | 2 |
12 files changed, 409 insertions, 12 deletions
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index bcc818dac..89f121c3f 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1533,7 +1533,7 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() { device_lock = Mutex::create(); quit_request=false; orientation=0; - remove_prev=false; + remove_prev=true; device_thread=Thread::create(_device_poll_thread,this); devices_changed=true; diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index 76c2d0608..e214b75bb 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -286,6 +286,9 @@ static int frame_count = 0; if (OS::get_singleton()->get_main_loop()) OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); [view_controller.view startAnimation]; // FIXME: resume seems to be recommended elsewhere + if (OSIPhone::get_singleton()->native_video_is_playing()) { + OSIPhone::get_singleton()->native_video_unpause(); + }; } - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration { diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index c25742a85..a5ce376b8 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -21,7 +21,8 @@ def get_opts(): return [ ('IPHONEPLATFORM', 'name of the iphone platform', 'iPhoneOS'), ('IPHONEPATH', 'the path to iphone toolchain', '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain'), - ('IOS_SDK_VERSION', 'The SDK version', 'iPhoneOS7.0'), + #('IOS_SDK_VERSION', 'The SDK version', 'iPhoneOS7.0'), + ('IOS_SDK_VERSION', 'The SDK version', 'iPhoneOS8.1'), ('IPHONESDK', 'path to the iphone SDK', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/${IOS_SDK_VERSION}.sdk/'), ('game_center', 'Support for game center', 'yes'), ('store_kit', 'Support for in-app store', 'yes'), @@ -79,6 +80,8 @@ def configure(env): '-framework', 'Security', #'-framework', 'AdSupport', '-framework', 'MediaPlayer', + '-framework', 'AVFoundation', + '-framework', 'CoreMedia', ]) if env['game_center'] == 'yes': diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h index 3e6181ab9..8ae7c2f87 100755 --- a/platform/iphone/gl_view.h +++ b/platform/iphone/gl_view.h @@ -32,6 +32,7 @@ #import <OpenGLES/ES1/gl.h> #import <OpenGLES/ES1/glext.h> #import <MediaPlayer/MediaPlayer.h> +#import <AVFoundation/AVFoundation.h> @protocol GLViewDelegate; @@ -66,6 +67,13 @@ @property(nonatomic, assign) id<GLViewDelegate> delegate; +// AVPlayer-related properties +@property(strong, nonatomic) AVAsset *avAsset; +@property(strong, nonatomic) AVPlayerItem *avPlayerItem; +@property(strong, nonatomic) AVPlayer *avPlayer; +@property(strong, nonatomic) AVPlayerLayer *avPlayerLayer; + +// Old videoplayer properties @property(strong, nonatomic) MPMoviePlayerController *moviePlayerController; @property(strong, nonatomic) UIWindow *backgroundWindow; diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index 06b679c30..55b5eabac 100755 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -52,6 +52,7 @@ static GLView* _instance = NULL; static bool video_found_error = false; static bool video_playing = false; static float video_previous_volume = 0.0f; +static CMTime video_current_time; void _show_keyboard(String p_existing) { keyboard_text = p_existing; @@ -65,6 +66,7 @@ void _hide_keyboard() { keyboard_text = ""; }; +/* bool _play_video(String p_path, float p_volume) { float player_volume = p_volume * AudioServer::get_singleton()->get_singleton()->get_stream_global_volume_scale(); @@ -96,24 +98,97 @@ bool _play_video(String p_path, float p_volume) { return true; } +*/ + +bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { + p_path = Globals::get_singleton()->globalize_path(p_path); + + NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease]; + //NSURL *file_url = [NSURL fileURLWithPath:file_path]; + + _instance.avAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:file_path]]; + _instance.avPlayerItem =[[AVPlayerItem alloc]initWithAsset:_instance.avAsset]; + [_instance.avPlayerItem addObserver:_instance forKeyPath:@"status" options:0 context:nil]; + + _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem]; + _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer]; + + [_instance.avPlayer addObserver:_instance forKeyPath:@"status" options:0 context:nil]; + [[NSNotificationCenter defaultCenter] addObserver:_instance + selector:@selector(playerItemDidReachEnd:) + name:AVPlayerItemDidPlayToEndTimeNotification + object:[_instance.avPlayer currentItem]]; + + [_instance.avPlayerLayer setFrame:_instance.bounds]; + [_instance.layer addSublayer:_instance.avPlayerLayer]; + [_instance.avPlayer play]; + + AVMediaSelectionGroup *audioGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicAudible]; + + for (id track in audioGroup.options) + { + NSString* language = [[track locale] localeIdentifier]; + NSLog(@"subtitle lang: %@", language); + + if ([language isEqualToString:[NSString stringWithUTF8String:p_audio_track.utf8()]]) + { + [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup: audioGroup]; + break; + } + } + + AVMediaSelectionGroup *subtitlesGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicLegible]; + NSArray *useableTracks = [AVMediaSelectionGroup mediaSelectionOptionsFromArray:subtitlesGroup.options withoutMediaCharacteristics:[NSArray arrayWithObject:AVMediaCharacteristicContainsOnlyForcedSubtitles]]; + + for (id track in useableTracks) + { + NSString* language = [[track locale] localeIdentifier]; + NSLog(@"subtitle lang: %@", language); + + if ([language isEqualToString:[NSString stringWithUTF8String:p_subtitle_track.utf8()]]) + { + [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup: subtitlesGroup]; + break; + } + } + + video_playing = true; + + return true; +} bool _is_video_playing() { //NSInteger playback_state = _instance.moviePlayerController.playbackState; - return video_playing || _instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying; + //return video_playing || _instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying; //if (video_found_error) // return false; //return (_instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying); + + return video_playing || (_instance.avPlayer.rate > 0 && !_instance.avPlayer.error); } void _pause_video() { - [_instance.moviePlayerController pause]; + //[_instance.moviePlayerController pause]; + video_current_time = _instance.avPlayer.currentTime; + [_instance.avPlayer pause]; video_playing = false; } +void _unpause_video() { + [_instance.avPlayer play]; + video_playing = true; + + //video_current_time = kCMTimeZero; +}; + void _stop_video() { - [_instance.moviePlayerController stop]; - [_instance.moviePlayerController.view removeFromSuperview]; + //[_instance.moviePlayerController stop]; + //[_instance.moviePlayerController.view removeFromSuperview]; //[[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume]; + + [_instance.avPlayer pause]; + [_instance.avPlayerLayer removeFromSuperlayer]; + _instance.avPlayer = nil; video_playing = false; } @@ -326,6 +401,11 @@ static void clear_touches() { active = TRUE; printf("start animation!\n"); animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES]; + + if (video_playing) + { + _unpause_video(); + } } - (void)stopAnimation @@ -337,6 +417,11 @@ static void clear_touches() { [animationTimer invalidate]; animationTimer = nil; clear_touches(); + + if (video_playing) + { + // save position + } } - (void)setAnimationInterval:(NSTimeInterval)interval @@ -375,9 +460,11 @@ static void clear_touches() { glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +#ifdef DEBUG_ENABLED GLenum err = glGetError(); if(err) NSLog(@"%x error", err); +#endif } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -523,6 +610,32 @@ static void clear_touches() { [super dealloc]; } +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object + change:(NSDictionary *)change context:(void *)context { + + if (object == _instance.avPlayerItem && [keyPath isEqualToString:@"status"]) { + if (_instance.avPlayerItem.status == AVPlayerStatusFailed || _instance.avPlayer.status == AVPlayerStatusFailed) { + _stop_video(); + video_found_error = true; + } + + if(_instance.avPlayer.status == AVPlayerStatusReadyToPlay && + _instance.avPlayerItem.status == AVPlayerItemStatusReadyToPlay && + CMTIME_COMPARE_INLINE(video_current_time, ==, kCMTimeZero)) { + + //NSLog(@"time: %@", video_current_time); + + [_instance.avPlayer seekToTime:video_current_time]; + video_current_time = kCMTimeZero; + } + } +} + +- (void)playerItemDidReachEnd:(NSNotification *)notification { + _stop_video(); +} + +/* - (void)moviePlayBackDidFinish:(NSNotification*)notification { @@ -557,5 +670,6 @@ static void clear_touches() { //[[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume]; video_playing = false; } +*/ @end diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index 2ef732183..c8a132c39 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -234,6 +234,7 @@ void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_ ev.mouse_button.x = ev.mouse_button.global_x = p_x; ev.mouse_button.y = ev.mouse_button.global_y = p_y; + input->set_mouse_pos(Point2(ev.mouse_motion.x,ev.mouse_motion.y)); ev.mouse_button.button_index = BUTTON_LEFT; ev.mouse_button.doubleclick = p_doubleclick; ev.mouse_button.pressed = p_pressed; @@ -485,13 +486,14 @@ String OSIPhone::get_locale() const { return locale_code; } -extern bool _play_video(String p_path, float p_volume); +extern bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); extern bool _is_video_playing(); extern void _pause_video(); +extern void _unpause_video(); extern void _stop_video(); -Error OSIPhone::native_video_play(String p_path, float p_volume) { - if ( _play_video(p_path, p_volume) ) +Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { + if ( _play_video(p_path, p_volume, p_audio_track, p_subtitle_track) ) return OK; return FAILED; } @@ -505,6 +507,11 @@ void OSIPhone::native_video_pause() { _pause_video(); } +void OSIPhone::native_video_unpause() { + _unpause_video(); +}; + + void OSIPhone::native_video_stop() { if (native_video_is_playing()) _stop_video(); diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 14b46816e..bf8c5bb1c 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -184,9 +184,10 @@ public: void set_unique_ID(String p_ID); String get_unique_ID() const; - virtual Error native_video_play(String p_path, float p_volume); + virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); virtual bool native_video_is_playing() const; virtual void native_video_pause(); + virtual void native_video_unpause(); virtual void native_video_stop(); OSIPhone(int width, int height); diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 08a775e68..a77428e95 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -7,6 +7,7 @@ common_win=[ "ctxgl_procaddr.cpp", "key_mapping_win.cpp", "tcp_server_winsock.cpp", + "packet_peer_udp_winsock.cpp", "stream_peer_winsock.cpp", ] diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index be53d2d46..8eb574694 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -45,6 +45,7 @@ #include "servers/visual/visual_server_wrap_mt.h" #include "tcp_server_winsock.h" +#include "packet_peer_udp_winsock.h" #include "stream_peer_winsock.h" #include "os/pc_joystick_map.h" #include "lang_table.h" @@ -173,6 +174,7 @@ void OS_Windows::initialize_core() { TCPServerWinsock::make_default(); StreamPeerWinsock::make_default(); + PacketPeerUDPWinsock::make_default(); mempool_static = new MemoryPoolStaticMalloc; #if 1 @@ -1492,7 +1494,7 @@ OS::Date OS_Windows::get_date() const { OS::Time OS_Windows::get_time() const { SYSTEMTIME systemtime; - GetSystemTime(&systemtime); + GetLocalTime(&systemtime); Time time; time.hour=systemtime.wHour; diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp new file mode 100644 index 000000000..aff92b8fc --- /dev/null +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -0,0 +1,202 @@ +#include "packet_peer_udp_winsock.h" + +#include <winsock2.h> + +int PacketPeerUDPWinsock::get_available_packet_count() const { + + Error err = const_cast<PacketPeerUDPWinsock*>(this)->_poll(false); + if (err!=OK) + return 0; + + return queue_count; +} + +Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer,int &r_buffer_size) const{ + + Error err = const_cast<PacketPeerUDPWinsock*>(this)->_poll(false); + if (err!=OK) + return err; + if (queue_count==0) + return ERR_UNAVAILABLE; + + uint32_t size; + rb.read((uint8_t*)&packet_ip.host,4,true); + rb.read((uint8_t*)&packet_port,4,true); + rb.read((uint8_t*)&size,4,true); + rb.read(packet_buffer,size,true); + --queue_count; + *r_buffer=packet_buffer; + r_buffer_size=size; + return OK; + +} +Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer,int p_buffer_size){ + + int sock = _get_socket(); + ERR_FAIL_COND_V( sock == -1, FAILED ); + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(peer_port); + addr.sin_addr = *((struct in_addr*)&peer_addr.host); + + + _set_blocking(true); + + errno = 0; + int err; + while ( (err = sendto(sock, (const char*)p_buffer, p_buffer_size, 0, (struct sockaddr*)&addr, sizeof(addr))) != p_buffer_size) { + + if (WSAGetLastError() != WSAEWOULDBLOCK) { + return FAILED; + }; + } + + return OK; +} + +int PacketPeerUDPWinsock::get_max_packet_size() const{ + + return 512; // uhm maybe not +} + + +void PacketPeerUDPWinsock::_set_blocking(bool p_blocking) { + //am no windows expert + //hope this is the right thing + + if (blocking==p_blocking) + return; + + blocking=p_blocking; + unsigned long par = blocking?0:1; + if (ioctlsocket(sockfd, FIONBIO, &par)) { + perror("setting non-block mode"); + //close(); + //return -1; + }; +} + +Error PacketPeerUDPWinsock::listen(int p_port, int p_recv_buffer_size){ + + close(); + int sock = _get_socket(); + if (sock == -1 ) + return ERR_CANT_CREATE; + sockaddr_in addr = {0}; + addr.sin_family = AF_INET; + addr.sin_port = htons(p_port); + addr.sin_addr.s_addr = INADDR_ANY; + if (bind(sock, (struct sockaddr*)&addr, sizeof(sockaddr_in)) == -1 ) { + close(); + return ERR_UNAVAILABLE; + } + + blocking=true; + + printf("UDP Connection listening on port %i\n", p_port); + rb.resize(nearest_shift(p_recv_buffer_size)); + return OK; +} + +void PacketPeerUDPWinsock::close(){ + + if (sockfd != -1) + ::closesocket(sockfd); + sockfd=-1; + rb.resize(8); + queue_count=0; +} + + +Error PacketPeerUDPWinsock::wait() { + + return _poll(true); +} +Error PacketPeerUDPWinsock::_poll(bool p_wait) { + + + _set_blocking(p_wait); + + + struct sockaddr_in from = {0}; + int len = sizeof(struct sockaddr_in); + int ret; + while ( (ret = recvfrom(sockfd, (char*)recv_buffer, MIN(sizeof(recv_buffer),rb.data_left()-12), 0, (struct sockaddr*)&from, &len)) > 0) { + rb.write((uint8_t*)&from.sin_addr, 4); + uint32_t port = ntohs(from.sin_port); + rb.write((uint8_t*)&port, 4); + rb.write((uint8_t*)&ret, 4); + rb.write(recv_buffer, ret); + + len = sizeof(struct sockaddr_in); + ++queue_count; + }; + + + if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) ) { + close(); + return FAILED; + }; + + + return OK; +} + +bool PacketPeerUDPWinsock::is_listening() const{ + + return sockfd!=-1; +} + +IP_Address PacketPeerUDPWinsock::get_packet_address() const { + + return packet_ip; +} + +int PacketPeerUDPWinsock::get_packet_port() const{ + + return packet_port; +} + +int PacketPeerUDPWinsock::_get_socket() { + + if (sockfd != -1) + return sockfd; + + sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + ERR_FAIL_COND_V( sockfd == -1, -1 ); + //fcntl(sockfd, F_SETFL, O_NONBLOCK); + + return sockfd; +} + + +void PacketPeerUDPWinsock::set_send_address(const IP_Address& p_address,int p_port) { + + peer_addr=p_address; + peer_port=p_port; +} + +void PacketPeerUDPWinsock::make_default() { + + PacketPeerUDP::_create = PacketPeerUDPWinsock::_create; +}; + + +PacketPeerUDP* PacketPeerUDPWinsock::_create() { + + return memnew(PacketPeerUDPWinsock); +}; + + +PacketPeerUDPWinsock::PacketPeerUDPWinsock() { + + sockfd=-1; + packet_port=0; + queue_count=0; + peer_port=0; +} + +PacketPeerUDPWinsock::~PacketPeerUDPWinsock() { + + close(); +} diff --git a/platform/windows/packet_peer_udp_winsock.h b/platform/windows/packet_peer_udp_winsock.h new file mode 100644 index 000000000..34dbcbee9 --- /dev/null +++ b/platform/windows/packet_peer_udp_winsock.h @@ -0,0 +1,56 @@ +#ifndef PACKET_PEER_UDP_WINSOCK_H +#define PACKET_PEER_UDP_WINSOCK_H + +#include "io/packet_peer_udp.h" +#include "ring_buffer.h" + +class PacketPeerUDPWinsock : public PacketPeerUDP { + + + enum { + PACKET_BUFFER_SIZE=65536 + }; + + mutable RingBuffer<uint8_t> rb; + uint8_t recv_buffer[PACKET_BUFFER_SIZE]; + mutable uint8_t packet_buffer[PACKET_BUFFER_SIZE]; + IP_Address packet_ip; + int packet_port; + mutable int queue_count; + int sockfd; + + IP_Address peer_addr; + int peer_port; + + _FORCE_INLINE_ int _get_socket(); + + static PacketPeerUDP* _create(); + + bool blocking; + void _set_blocking(bool p_blocking); + + Error _poll(bool p_wait); + +public: + + virtual int get_available_packet_count() const; + virtual Error get_packet(const uint8_t **r_buffer,int &r_buffer_size) const; + virtual Error put_packet(const uint8_t *p_buffer,int p_buffer_size); + + virtual int get_max_packet_size() const; + + virtual Error listen(int p_port,int p_recv_buffer_size=65536); + virtual void close(); + virtual Error wait(); + virtual bool is_listening() const; + + virtual IP_Address get_packet_address() const; + virtual int get_packet_port() const; + + virtual void set_send_address(const IP_Address& p_address,int p_port); + + static void make_default(); + PacketPeerUDPWinsock(); + ~PacketPeerUDPWinsock(); +}; +#endif // PACKET_PEER_UDP_WINSOCK_H diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 03de91fa2..1c8d231d4 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -123,7 +123,7 @@ def configure(env): if (is64 and env["bits"]=="32"): env.Append(CPPFLAGS=['-m32']) env.Append(LINKFLAGS=['-m32','-L/usr/lib/i386-linux-gnu']) - elif (not is64 and env["bits"]=="32"): + elif (not is64 and env["bits"]=="64"): env.Append(CPPFLAGS=['-m64']) env.Append(LINKFLAGS=['-m64','-L/usr/lib/i686-linux-gnu']) |
