Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
prism/engine/platform/include/platform.hpp

260 lines
8.1 KiB
C++
Executable file

#pragma once
#include <functional>
#include <string>
#include <string_view>
#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<WindowFlags>(static_cast<int>(a) | static_cast<int>(b));
}
inline bool operator&(const WindowFlags a, const WindowFlags b) {
return static_cast<int>(a) & static_cast<int>(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 <vector>
#include <vulkan/vulkan.h>
struct vulkan_information {
std::vector<const char*> 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 <Metal/Metal.hpp>
#include <QuartzCore/CAMetalDrawable.hpp>
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<float, float> get_wheel_delta();
/// Returns the current right stick axes values from 0->1
std::tuple<float, float> get_right_stick_position();
/// Returns the current left stick axes values from 0->1
std::tuple<float, float> 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