diff --git a/core/src/avm2/globals/flash/display.rs b/core/src/avm2/globals/flash/display.rs index f5c0f49d82d57..347e9b21d377b 100644 --- a/core/src/avm2/globals/flash/display.rs +++ b/core/src/avm2/globals/flash/display.rs @@ -11,6 +11,7 @@ pub mod loader; pub mod loader_info; pub mod morph_shape; pub mod movie_clip; +pub mod screen; pub mod shader_data; pub mod shader_job; pub mod shader_parameter; diff --git a/core/src/avm2/globals/flash/display/Screen.as b/core/src/avm2/globals/flash/display/Screen.as new file mode 100644 index 0000000000000..61f3cccf383a2 --- /dev/null +++ b/core/src/avm2/globals/flash/display/Screen.as @@ -0,0 +1,66 @@ +package flash.display +{ + import __ruffle__.stub_getter; + import flash.geom.Rectangle; + + [API("661")] + public final class Screen + { + private static var _screens:Array; + private var _width:int; + private var _height:int; + + [API(661)] + public var mode:ScreenMode; + + public function Screen(width:int, height:int) + { + _width = width; + _height = height; + mode = new ScreenMode(width, height); + } + + public static function get mainScreen():Screen + { + return screens[0]; + } + + public static native function getScreensInternal():Array; + + public static function get screens():Array + { + if (!_screens) + { + _screens = getScreensInternal().map(function(screen:Array, _idx:int, _arr:Array):Screen + { + return new Screen(screen[0], screen[1]); + }); + } + return _screens; + } + + public function get colorDepth():Number + { + stub_getter("flash.display.Screen", "colorDepth"); + return 24; + } + + public function get bounds():Rectangle + { + return new Rectangle(0, 0, _width, _height); + } + + public function get visibleBounds():Rectangle + { + stub_getter("flash.display.Screen", "visibleBounds"); + return bounds; + } + + [API(661)] + public function get modes():Array + { + stub_getter("flash.display.Screen", "modes"); + return []; + } + } +} \ No newline at end of file diff --git a/core/src/avm2/globals/flash/display/ScreenMode.as b/core/src/avm2/globals/flash/display/ScreenMode.as new file mode 100644 index 0000000000000..b6d2c97806848 --- /dev/null +++ b/core/src/avm2/globals/flash/display/ScreenMode.as @@ -0,0 +1,40 @@ +package flash.display +{ + import __ruffle__.stub_getter; + import flash.geom.Rectangle; + + [API(661)] + public class ScreenMode + { + private var _width:int; + private var _height:int; + + public function ScreenMode(width:int, height:int) + { + _width = width; + _height = height; + } + + public function get colorDepth():Number + { + stub_getter("flash.display.ScreenMode", "colorDepth"); + return 24; + } + + public function get refreshRate():Number + { + stub_getter("flash.display.ScreenMode", "refreshRate"); + return 0; + } + + public function get height():int + { + return _height; + } + + public function get width():int + { + return _width; + } + } +} \ No newline at end of file diff --git a/core/src/avm2/globals/flash/display/screen.rs b/core/src/avm2/globals/flash/display/screen.rs new file mode 100644 index 0000000000000..5b268e4ed9bb7 --- /dev/null +++ b/core/src/avm2/globals/flash/display/screen.rs @@ -0,0 +1,21 @@ +use crate::avm2::{Activation, ArrayObject, ArrayStorage, Error, Object, Value}; + +pub fn get_screens_internal<'gc>( + activation: &mut Activation<'_, 'gc>, + _this: Object<'gc>, + _args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let screens = activation + .context + .ui + .get_screens_sizes() + .into_iter() + .map(|screen| { + let storage = + ArrayStorage::from_storage(vec![Some(screen.0.into()), Some(screen.1.into())]); + Ok(Some(ArrayObject::from_storage(activation, storage)?.into())) + }) + .collect::>>, Error<'gc>>>()?; + let storage = ArrayStorage::from_storage(screens); + Ok(ArrayObject::from_storage(activation, storage)?.into()) +} diff --git a/core/src/avm2/globals/globals.as b/core/src/avm2/globals/globals.as index 281ee0db731b5..6f8f74b900487 100644 --- a/core/src/avm2/globals/globals.as +++ b/core/src/avm2/globals/globals.as @@ -104,6 +104,8 @@ include "flash/display/NativeMenuItem.as" include "flash/display/PixelSnapping.as" include "flash/display/PNGEncoderOptions.as" include "flash/display/Scene.as" +include "flash/display/Screen.as" +include "flash/display/ScreenMode.as" include "flash/display/Shader.as" include "flash/display/ShaderData.as" include "flash/display/ShaderInput.as" diff --git a/core/src/backend/ui.rs b/core/src/backend/ui.rs index f5c55823699ad..f5bf5b4c45ded 100644 --- a/core/src/backend/ui.rs +++ b/core/src/backend/ui.rs @@ -83,6 +83,10 @@ pub trait UiBackend: Downcast { fn set_fullscreen(&mut self, is_full: bool) -> Result<(), FullscreenError>; + /// Returns width and height of screens. + /// First element must be the main screen. + fn get_screens_sizes(&self) -> Vec<(u32, u32)>; + /// Displays a message about an error during root movie download. /// In particular, on web this can be a CORS error, which we can sidestep /// by providing a direct .swf link instead. @@ -344,6 +348,10 @@ impl UiBackend for NullUiBackend { Ok(()) } + fn get_screens_sizes(&self) -> Vec<(u32, u32)> { + vec![(0, 0)] + } + fn display_root_movie_download_failed_message(&self, _invalid_swf: bool) {} fn message(&self, _message: &str) {} diff --git a/desktop/src/backends/ui.rs b/desktop/src/backends/ui.rs index b40a73614f97c..3e6dba049e1ea 100644 --- a/desktop/src/backends/ui.rs +++ b/desktop/src/backends/ui.rs @@ -198,6 +198,16 @@ impl UiBackend for DesktopUiBackend { Ok(()) } + fn get_screens_sizes(&self) -> Vec<(u32, u32)> { + self.window + .available_monitors() + .map(|m| { + let size = m.size(); + (size.width, size.height) + }) + .collect() + } + fn display_root_movie_download_failed_message(&self, _invalid_swf: bool) { let dialog = MessageDialog::new() .set_level(MessageLevel::Warning) diff --git a/tests/framework/src/backends/ui.rs b/tests/framework/src/backends/ui.rs index 4905098f1d080..bd34c9f118c40 100644 --- a/tests/framework/src/backends/ui.rs +++ b/tests/framework/src/backends/ui.rs @@ -1,3 +1,5 @@ +use std::vec; + use crate::test::Font; use chrono::{DateTime, Utc}; use ruffle_core::backend::ui::{ @@ -187,4 +189,8 @@ impl UiBackend for TestUiBackend { } fn close_file_dialog(&mut self) {} + + fn get_screens_sizes(&self) -> Vec<(u32, u32)> { + vec![(800, 600)] + } } diff --git a/web/src/ui.rs b/web/src/ui.rs index 27aa45fbaf653..702a42c70a4be 100644 --- a/web/src/ui.rs +++ b/web/src/ui.rs @@ -211,6 +211,10 @@ impl UiBackend for WebUiBackend { self.update_mouse_cursor(); } + fn get_screens_sizes(&self) -> Vec<(u32, u32)> { + vec![(self.canvas.width(), self.canvas.height())] + } + fn set_mouse_cursor(&mut self, cursor: MouseCursor) { self.cursor = cursor; self.update_mouse_cursor();