#pragma once #include #include #include #include "common.hpp" #include "gfx_context.hpp" /// Requestable window flags, which may or may not be respected by the platform. enum class WindowFlags { None = 0, Resizable = 2, Borderless = 4, Hidden = 8 }; inline WindowFlags operator|(const WindowFlags a, const WindowFlags b) { return static_cast(static_cast(a) | static_cast(b)); } inline bool operator&(const WindowFlags a, const WindowFlags b) { return static_cast(a) & static_cast(b); } /// Represents a button. This includes keyboard, gamepad and mouse buttons. enum class InputButton { Invalid, C, V, X, Y, Z, Backspace, Enter, W, A, S, D, Q, Shift, Alt, Super, Escape, Tab, Ctrl, Space, LeftArrow, RightArrow, // gamepad inputs ButtonA, ButtonB, ButtonX, ButtonY, DPadUp, DPadDown, DPadLeft, DPadRight, // mouse inputs MouseLeft, MouseRight }; enum class PlatformFeature { Windowing }; /// On platforms that has a GUI with a seperate light/dark mode. enum class PlatformTheme { Light, Dark }; // note: a platform may be built with support for a specific context (e.g. ENABLE_VULKAN, ENABLE_DIRECTX, etc) // this only determines it at build-time, not at runtime. #ifdef ENABLE_VULKAN #include #include struct vulkan_information { std::vector surface_extensions; }; struct vulkan_surface_creation_info { VkInstance instance; }; struct vulkan_surface { VkSurfaceKHR surface; }; #endif #ifdef ENABLE_DIRECTX struct directx_surface_creation_info { // TODO: stub }; #endif #ifdef ENABLE_METAL #include #include struct metal_surface_creation_info { MTL::Device* device; }; struct metal_surface { MTL::PixelFormat format; }; using metal_next_image = CA::MetalDrawable*; #endif namespace platform { using window_ptr = void*; /// Returns a human readable platform name, e.g. Linux. const char* get_name(); /// Returns the current platform theme. PlatformTheme get_theme(); /// Queries whether or not the platform supports a certain feature. bool supports_feature(PlatformFeature feature); /* * This queries whether the context is supported by the platform at build-time. This does not mean the * context can be used properly at runtime, this is handled by GFX::is_supported(). */ bool supports_context(GFXContext context); /** * This initializes before window creation, for a specific gfx context type. This is designed to be called within * helper classes such as gfx_chooser, but may also be called within a platform implementation as well. * @param context */ void initialize_context(GFXContext context); /* * This is used in specific cases where the gfx backend may need to know important information before window * creation. A good example is the surface extension required by a specific window backend, but this is between * initialize_context and create_surface calls. * * the returned structs are in a naming scheme of X_information. */ void* get_context_information(); /** Opens a new window. @param title The title of the window. @param rect The requested size and position of the window. @param flags The requested window flags. @note Depending on the platform, some of these parameters might be unused. The best practice is to always assume that none of them may be used. @note On platforms that do not support the Windowing feature, calling open_window more than once is not supported. In this case, the same identifier is returned. @return A valid window identifier. */ window_ptr open_window(std::string_view title, prism::Rectangle rect, WindowFlags flags); bool is_main_window(window_ptr index); /* * This creates a new surface, with the gfx context type already set ahead of time (see initialize_context) * The parameter 'surface_creation_info' must be a type of the gfx context you want to use, and support must be * built at build-time (ENABLE_VULKAN, gfx context is Vulkan, and the struct would be vulkan_surface_creation_info.) * * The return type is usually {Your GFX Context}_surface, such as vulkan_surface. See each gfx context's struct for * more information. */ void* create_surface(window_ptr window, void* surface_creation_info); /* * This needs to be implemented under certain gfx contexts (such as metal) which calls [layer nextDrawable] * underneath can be no-op for contexts such as vulkan which can happen within it's own API. * * the return type is named as X_next_image. may be null. */ void* get_next_image(window_ptr window); /** Closes a window. @param index The window to close. */ void close_window(window_ptr window); /// Forces the platform to quit the application. This is not related to Engine::quit(). void force_quit(); /// Gets the content scale for the monitor. 1.0 would be 1x scale, 2.0 would be 2x scale, etc. float get_monitor_dpi(); /// Get the monitor resolution. prism::Rectangle get_monitor_resolution(); /// Get the monitor work area. For example on macOS this may exclude the areas of the menu bar and dock. prism::Rectangle get_monitor_work_area(); /// Get the window position. prism::Offset get_window_position(window_ptr window); /// Get the window size, note that in hidpi scenarios this is the non-scaled resolution. prism::Extent get_window_size(window_ptr window); /// Get the window's drawable size. Always use this instead of manually multiplying the window size by the content /// scale. prism::Extent get_window_drawable_size(window_ptr window); /// Query whether or not the window is focused. bool is_window_focused(window_ptr window); /// If possible, try to manually focus the window. void set_window_focused(window_ptr window); /// Sets the window position to the offset provided. void set_window_position(window_ptr window, prism::Offset offset); /// Sets the window to the specified size. The platform will handle the subsequent resize events. void set_window_size(window_ptr window, prism::Extent extent); /// Sets the window title. void set_window_title(window_ptr window, std::string_view title); /// Show window void show_window(window_ptr window); /// Queries whether or not the button is currently pressed. bool get_key_down(InputButton key); /// If available for the InputButton, returns the platform-specific keycode. int get_keycode(InputButton key); /// Returns the current moue cursor position, relative to the window. prism::Offset get_cursor_position(); /// Returns the current moue cursor position, relative to the monitor. prism::Offset get_screen_cursor_position(); /// Queries whether or not the mouse button requested is pressed or not. bool get_mouse_button_down(int button); /// Returns the current mouse wheel delta on both axes. std::tuple get_wheel_delta(); /// Returns the current right stick axes values from 0->1 std::tuple get_right_stick_position(); /// Returns the current left stick axes values from 0->1 std::tuple get_left_stick_position(); /// On platforms that support moue capture, this will lock the mouse cursor to the window and hide it. void capture_mouse(bool capture); // TODO: right now the OS intercepting and saying "We dont want text input anymore" ala software keyboards is NOT // supported yet void begin_text_input(); void end_text_input(); } // namespace platform