/* * Copyright (C) Volition, Inc. 1999. All rights reserved. * * All source code herein is the property of Volition, Inc. You may not sell * or otherwise commercially exploit the source or things you created based on the * source. * */ /** @defgroup osapi The OS API * Provides a number of function to interact with the operating system. The API is the same for every platform. */ /** @file * @ingroup osapi */ #ifndef _OSAPI_H #define _OSAPI_H #include "globalincs/pstypes.h" #include "osapi/osregistry.h" #include "osapi/dialogs.h" #include "globalincs/flagset.h" #include #include // -------------------------------------------------------------------------------------------------- // OSAPI DEFINES/VARS // // set if running under MsDev - done after os_init(...) has returned extern int Os_debugger_running; #ifdef SCP_UNIX const char* os_get_legacy_user_dir(); #endif // -------------------------------------------------------------------------------------------------- // OSAPI FUNCTIONS // // initialization/shutdown functions ----------------------------------------------- // If app_name is NULL or ommited, then TITLE is used // for the app name, which is where registry keys are stored. void os_init(const char * wclass, const char * title, const char * app_name = nullptr); // set the main window title void os_set_title( const char * title ); // call at program end void os_cleanup(); // window management --------------------------------------------------------------- // Returns false if app is not the foreground app. bool os_foreground(); // process management -------------------------------------------------------------- /** * @brief Defers all pending events to be handled later */ void os_defer_events_on_load_screen(); // removes key events that may unintentionally skip the cutscene void os_remove_deferred_cutscene_key_events(); // call to process windows messages. only does something in non THREADED mode void os_poll(); // Sleeps for n milliseconds or until app becomes active. void os_sleep(uint ms); /** * @brief Determines if FSO is running in legacy config mode */ bool os_is_legacy_mode(); /** * @brief Gets a path to a configuration file * A relative path to the wanted file or directory. Directories should be separated with '/' * @param subpath The path of the wanted file or directory, may be emtpy to get the config directory * * @returns The path to the specified config path */ SCP_string os_get_config_path(const SCP_string& subpath = ""); /* Special functions for Android */ #ifdef __ANDROID__ // Get working folder absolute path from Android Java Class SCP_string os_android_get_working_folder_path(); // Calls to display the touch overlay depending on its last state void os_android_touch_overlay_init(); // Enable or disable the touch UI overlay void os_android_touch_overlay_toggle(bool status); // Send the JSON flags string to the Android Java layer void os_android_set_flags_string(const char* json); #endif namespace os { /** * @defgroup os_graphics_api Graphics operations abstraction * @see @ref graphics_api_page * @ingroup osapi */ /** * @brief Flags for OpenGL context creation * @ingroup os_graphics_api */ FLAG_LIST(OpenGLContextFlags) { Debug = 0, ForwardCompatible, NUM_VALUES }; /** * @brief The required context profile * @ingroup os_graphics_api */ enum class OpenGLProfile { Core, Compatibility, ES }; /** * @brief Attributes for OpenGL context creation * @ingroup os_graphics_api */ struct OpenGLContextAttributes { uint32_t major_version; //!< The major version of the created context uint32_t minor_version; //!< The minor version of the created context flagset flags; //!< The OpenGL context flags OpenGLProfile profile; //!< The desired OpenGL profile }; /** * @brief Pixel format of a viewport * @ingroup os_graphics_api */ struct ViewportPixelFormat { uint32_t red_size; uint32_t green_size; uint32_t blue_size; uint32_t alpha_size; uint32_t depth_size; uint32_t stencil_size; uint32_t multi_samples; //!< The amount of multi-sampling, use 0 for no multi-sampling }; /** * @brief A function pointer for loading an OpenGL function * @ingroup os_graphics_api */ typedef void* (*OpenGLLoadProc)(const char *name); /** * @brief An OpenGL context * Can be deleted which will properly free the resources of the underlying OpenGL context * @ingroup os_graphics_api */ class OpenGLContext { public: virtual ~OpenGLContext() {} /** * @brief Gets an OpenGL loader function */ virtual OpenGLLoadProc getLoaderFunction() = 0; /** * @brief Sets the swap interval */ virtual bool setSwapInterval(int status) = 0; }; /** * @brief Flags for viewport creation * @ingroup os_graphics_api */ FLAG_LIST(ViewPortFlags) { Fullscreen = 0, Borderless, Resizeable, Capture_Mouse, NUM_VALUES }; /** * @brief Properties of a viewport that should be created * @ingroup os_graphics_api */ struct ViewPortProperties { bool enable_opengl = false; //!< Set to true if the viewport should support OpenGL rendering OpenGLContextAttributes gl_attributes; bool enable_vulkan = false; //!< Set to true if the viewport should support Vulkan rendering ViewportPixelFormat pixel_format; SCP_string title; uint32_t width; uint32_t height; flagset flags; SDL_DisplayID display; }; /** * @brief State of a viewport * @ingroup os_graphics_api */ enum class ViewportState { Windowed = 0, Borderless = 1, Fullscreen = 2 }; /** * @brief A viewport supporting graphics operations * * A viewport is something that supports rendering operations. Typically this is a window but here it's more * abstract. * * @ingroup os_graphics_api */ class Viewport { public: virtual ~Viewport() {} /** * @brief Returns a SDL_Window handle for this viewport * * @note The returned handle is owned by the viewport and may not be destroyed by the caller. * * @return The window handle or @c nullptr if the viewport can't be represented as an SDL_Window */ virtual SDL_Window* toSDLWindow() = 0; /** * @brief Gets the size of this viewport * * @note This is the actual window size. On HiDPI systems the size of the renderable area might be bigger if * the window is created with support for that. * * @return A (width, height) pair */ virtual std::pair getSize() = 0; /** * @brief Swaps the buffers of this window */ virtual void swapBuffers() = 0; /** * @brief Sets the window state of the viewport * * @note Implementation may ignore invocations of this function * * @param state The desired state */ virtual void setState(ViewportState state) = 0; /** * @brief Minimizes the viewport * * @note Implementation may ignore invocations of this function */ virtual void minimize() = 0; /** * @brief Restores/Maximizes the viewport * * @note Implementation may ignore invocations of this function */ virtual void restore() = 0; }; /** * @brief Abstraction for various graphics operations * * This is used for providing platform specific functionality for various graphics operations. * * @ingroup os_graphics_api */ class GraphicsOperations { public: virtual ~GraphicsOperations() {} /** * @brief Creates an OpenGL contex * * Uses the specified attributes and creates an OpenGL context. The width and height * values may be used for creating the main window. * * @warning The viewport must be configured to support OpenGL! * * @param viewport The viewport to create the context for. * * @return A pointer to the OpenGL context or @c nullptr if the creation has failed */ virtual std::unique_ptr createOpenGLContext(Viewport* viewport, const OpenGLContextAttributes& gl_attrs) = 0; /** * @brief Makes an OpenGL context current * * @warning The viewport must be configured to support OpenGL! * * @param view The viewport to make the context current on * @param ctx The OpenGL context to make current, may be @c nullptr */ virtual void makeOpenGLContextCurrent(Viewport* view, OpenGLContext* ctx) = 0; /** * @brief Creates a new viewport * * @note Implementations may choose to dissallow viewport creation after a certain number of viewports are * created. E.g. FRED may not want to create more than one viewport. * * @param props The desired properties of the new viewport. * @return The created viewport, may be @c nullptr if the viewport can't be created */ virtual std::unique_ptr createViewport(const ViewPortProperties& props) = 0; }; /** * @brief Adds a viewport to the osapi list * * The osapi system will automatically free these viewports when it is shut down. * * @param viewport The viewport to add. The osapi system assumes ownership over the pointer * @return The pointer of the viewport * * @ingroup os_graphics_api */ Viewport* addViewport(std::unique_ptr&& viewport); /** * @brief Sets the main viewport of the application * @param mainView The viewport to set * * @ingroup os_graphics_api */ void setMainViewPort(Viewport* mainView); /** * @brief Gets the main viewport of the application * @return The main viewport, can be @c nullptr if it hasn't been set yet * * @ingroup os_graphics_api */ Viewport* getMainViewport(); /** * @brief Gets the SDL handle of the main window * @return The SDL handle or @c nullptr if there is no main window or if the main window can't be represented as * an SDL window * * @ingroup os_graphics_api */ SDL_Window* getSDLMainWindow(); void closeAllViewports(); /** * @defgroup eventhandling API for consuming OS events * @ingroup osapi * See \ref eventhandling_page for more information. * @{ */ namespace events { /** * @brief The default weight of a listener. * The default event handler use this weight so other event handlers should have a weight that is less than this. */ const int DEFAULT_LISTENER_WEIGHT = 0; /** * @brief An event handler * Gets the generated sdl event and must return if it handled the event or not. */ typedef std::function Listener; /** * @brief An identification for a listener */ typedef size_t ListenerIdentifier; /** * @brief Adds a new event handler * @param type The type of events to handle * @param weigth The weight of this handler, used for determining in which order handlers are called. * @param listener The listener that will be called * @return An idfentification which can be used to remove this handler again * @see removeEventListener() */ ListenerIdentifier addEventListener(SDL_EventType type, int weigth, const Listener& listener); /** * @brief Removes the event handler with the given identifier * @param identifier The identifier of the event handler that should be removed * @return @c true if the event handler was removed, @c false otherwise */ bool removeEventListener(ListenerIdentifier identifier); /** * @brief Checks if the event belongs to a window * This can be used to handle multiple windows correctly and only handle the events * that belong to a specific window. * * @param e The event that should be checked * @param window The window the event should belong to * @return @c true if the event belongs to the window, @c false otherwise */ bool isWindowEvent(const SDL_Event& e, SDL_Window* window); } /** @} */ // end of OsAPI } // Documentation pages /** * @page osapi_page The OS API * @subpage eventhandling_page * @subpage graphics_api_page */ /** * @page eventhandling_page OS Event handling API * The OS-API exposed a generic event handler interface to allow user code to consume SDL events. The handler will * be passed the SDL_Event structure and should return @c true if it handled the event or @c false if not. If it handled the event then the processing of this event will be stopped and it will not be delivered to subsequent * listeners. */ /** * @page graphics_api_page OS Graphics API * Since multiple different applications need to use the FSO rendering engine it's necessary to provide an abstraction * of how an OpenGL context is created. Furthermore, since FSO may want to use multiple viewports it's also necessary to * provide an abstraction for that. This is done via the @ref GraphicsOperations class which must be implemented by users * of the FSO rendering engine. This class allows to create viewports and OpenGL contexts. First, a viewport will be * created which can be a standalone window or a part of a GUI. Then an OpenGL context will be created based on that * viewport which will be used for further rendering. * * @see @ref os_graphics_api */ #endif // _OSAPI_H