diff --git a/lime/system/Display.hx b/lime/system/Display.hx new file mode 100644 index 000000000..4b7280a0d --- /dev/null +++ b/lime/system/Display.hx @@ -0,0 +1,184 @@ +package lime.system; +import lime.math.Rectangle; +import lime.math.Vector2; +import lime.system.Display; + +/** + * ... + * @author larsiusprime + */ +class Display { + + /********STATIC*********/ + + public static var devices = new Map (); + + /**How many display devices are currently connected and actively displaying visuals**/ + public static var numDisplays(get, null):Int; + + /** + * Sync with the OS to get the current display device information + */ + + public static function init():Void { + + for (i in 0...numDisplays) { + + var d = new Display(i); + d.sync(); + devices.set(i, d); + + } + + } + + /** + * Get the display device with the given id + * @param id + * @return + */ + + public static function get(id:Int):Display { + + if (devices.exists(id)) { + + return devices.get(id); + + } + + return null; + } + + /** + * Get the total number of connected displays + * @return + */ + + private static function get_numDisplays():Int { + + return lime_display_get_num_devices(); + + } + + /*********INSTANCE**********/ + + + /**Which number is assigned to the display device by the OS**/ + public var id (default, null):Int; + + /**The name of the device, such as "Samsung SyncMaster P2350", "iPhone 6", "Occulus Rift DK2", etc.**/ + public var name (default, null):String; + + /**Number of horizontal and vertical pixels currently being displayed**/ + public var resolution(default, null):Resolution; + + /**Horizontal resolution / Vertical resolution**/ + public var aspectRatio(get, null):Float; + + /**The current display mode**/ + public var mode(default, null):DisplayMode; + + /**All of the display modes supported by this device**/ + public var modes(default, null):Array; + + /**The desktop area represented by this display, with the upper-leftmost display at 0,0**/ + public var bounds(default, null):Rectangle; + + private function new(id:Int) { + + this.id = id; + sync(); + + } + + + /** + * Updates this object's data with the latest information from the OS about the device + */ + public function sync():Void { + + name = lime_display_get_name(id); + + var obj = null; + + obj = lime_display_get_current_display_mode(id); + mode = new DisplayMode(obj.width, obj.height, obj.refresh_rate, obj.format); + resolution = new Resolution(mode.width, mode.height); + + obj = lime_display_get_display_bounds(id); + bounds = new Rectangle(obj.x, obj.y, obj.width, obj.height); + + modes = []; + var numModes = lime_display_get_num_display_modes(id); + + for (i in 0...numModes) { + + obj = lime_display_get_display_mode(id, i); + modes.push(new DisplayMode(obj.width, obj.height, obj.refresh_rate, obj.format)); + + } + } + + /**GET / SET**/ + + private function get_aspectRatio():Float { + + if (resolution.height != 0) { + + return resolution.width / resolution.height; + + } + + return 0; + } + + // Native Methods + + #if (cpp || neko || nodejs) + + private static var lime_display_get_num_devices = System.load("lime", "lime_display_get_num_devices", 0); + private static var lime_display_get_name = System.load ("lime", "lime_display_get_name", 1); + private static var lime_display_get_num_display_modes = System.load ("lime", "lime_display_get_num_display_modes", 1); + private static var lime_display_get_display_bounds = System.load ("lime", "lime_display_get_display_bounds", 1); + private static var lime_display_get_display_mode = System.load ("lime", "lime_display_get_display_mode", 2); + private static var lime_display_get_current_display_mode = System.load ("lime", "lime_display_get_current_display_mode", 1); + + #end +} + +class DisplayMode { + + /**horizontal resolution**/ + public var width(default, null):Int; + + /**vertical resolution**/ + public var height(default, null):Int; + + /**refresh rate in Hz**/ + public var refreshRate(default, null):Int; + + /**pixel color format**/ + public var format(default, null):Int; + + public function new(width:Int, height:Int, refreshRate:Int, format:Int) { + + this.width = width; + this.height = height; + this.refreshRate = refreshRate; + this.format = format; + + } + +} + +abstract Resolution (Vector2) from Vector2 { + + public inline function new (width:Float = 0, height:Float = 0) this = new Vector2(width, height); + + public var width(get, never):Float; + public var height(get, never):Float; + + inline function get_width ():Float return this.x; + inline function get_height ():Float return this.y; + +} \ No newline at end of file diff --git a/project/Build.xml b/project/Build.xml index de7e4bbb9..e5a3cb4e9 100644 --- a/project/Build.xml +++ b/project/Build.xml @@ -178,6 +178,7 @@ + diff --git a/project/include/system/Display.h b/project/include/system/Display.h new file mode 100644 index 000000000..93e2111a2 --- /dev/null +++ b/project/include/system/Display.h @@ -0,0 +1,25 @@ +#ifndef LIME_SYSTEM_DISPLAY_H +#define LIME_SYSTEM_DISPLAY_H + +#include +#include + +namespace lime { + + + class Display { + + public: + + static value GetCurrentDisplayMode (int displayIndex); + static value GetDisplayMode (int displayIndex, int modeIndex); + static value GetDisplayBounds (int displayIndex); + static int GetNumDevices (); + static const char* GetDisplayName (int displayIndex); + static int GetNumDisplayModes (int displayIndex); + + }; +} + + +#endif \ No newline at end of file diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 64dbb50a9..bc295fbc6 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -390,6 +391,41 @@ namespace lime { } + value lime_display_get_display_bounds (value displayIndex) { + + return Display::GetDisplayBounds(val_int(displayIndex)); + + } + + value lime_display_get_current_display_mode (value displayIndex) { + + return Display::GetCurrentDisplayMode(val_int(displayIndex)); + + } + + value lime_display_get_display_mode (value displayIndex, value modeIndex) { + + return Display::GetDisplayMode(val_int(displayIndex), val_int(modeIndex)); + + } + + value lime_display_get_name (value displayIndex) { + + return alloc_string (Display::GetDisplayName (val_int (displayIndex))); + + } + + value lime_display_get_num_devices () { + + return alloc_int (Display::GetNumDevices()); + + } + + value lime_display_get_num_display_modes (value displayIndex) { + + return alloc_int (Display::GetNumDisplayModes(val_int (displayIndex))); + + } value lime_gamepad_add_mappings (value mappings) { @@ -1172,6 +1208,12 @@ namespace lime { DEFINE_PRIM (lime_font_render_glyph, 3); DEFINE_PRIM (lime_font_render_glyphs, 3); DEFINE_PRIM (lime_font_set_size, 2); + DEFINE_PRIM (lime_display_get_display_bounds, 1); + DEFINE_PRIM (lime_display_get_current_display_mode, 1); + DEFINE_PRIM (lime_display_get_display_mode, 2); + DEFINE_PRIM (lime_display_get_name, 1); + DEFINE_PRIM (lime_display_get_num_devices, 0); + DEFINE_PRIM (lime_display_get_num_display_modes, 1); DEFINE_PRIM (lime_gamepad_add_mappings, 1); DEFINE_PRIM (lime_gamepad_event_manager_register, 2); DEFINE_PRIM (lime_gamepad_get_device_guid, 1); diff --git a/project/src/backend/sdl/SDLDisplay.cpp b/project/src/backend/sdl/SDLDisplay.cpp new file mode 100644 index 000000000..ec9bafa0e --- /dev/null +++ b/project/src/backend/sdl/SDLDisplay.cpp @@ -0,0 +1,67 @@ +#include + + +namespace lime { + + + value Display::GetDisplayBounds (int displayIndex) { + + SDL_Rect rect = { 0, 0, 0, 0}; + SDL_GetDisplayBounds(displayIndex, &rect); + + value mValue = alloc_empty_object (); + alloc_field (mValue, val_id("x"), alloc_int(rect.x)); + alloc_field (mValue, val_id("y"), alloc_int(rect.y)); + alloc_field (mValue, val_id("width"), alloc_int(rect.w)); + alloc_field (mValue, val_id("height"), alloc_int(rect.h)); + return mValue; + + } + + value Display::GetCurrentDisplayMode (int displayIndex) { + + SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 }; + SDL_GetCurrentDisplayMode(displayIndex, &mode); + + value mValue = alloc_empty_object (); + alloc_field (mValue, val_id("width"), alloc_int(mode.w)); + alloc_field (mValue, val_id("height"), alloc_int(mode.h)); + alloc_field (mValue, val_id("refresh_rate"), alloc_int(mode.refresh_rate)); + alloc_field (mValue, val_id("format"), alloc_int(mode.format)); + return mValue; + + } + + value Display::GetDisplayMode (int displayIndex, int modeIndex) { + + SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 }; + SDL_GetDisplayMode(displayIndex, modeIndex, &mode); + + value mValue = alloc_empty_object (); + alloc_field (mValue, val_id("width"), alloc_int(mode.w)); + alloc_field (mValue, val_id("height"), alloc_int(mode.h)); + alloc_field (mValue, val_id("refresh_rate"), alloc_int(mode.refresh_rate)); + alloc_field (mValue, val_id("format"), alloc_int(mode.format)); + return mValue; + + } + + int Display::GetNumDevices() { + + return SDL_GetNumVideoDisplays(); + + } + + const char* Display::GetDisplayName (int displayIndex) { + + return SDL_GetDisplayName(displayIndex); + + } + + int Display::GetNumDisplayModes (int displayIndex) { + + return SDL_GetNumDisplayModes(displayIndex); + + } + +} \ No newline at end of file