diff --git a/include/rewindow/types/cursors.h b/include/ReWindow/Cursors.hpp similarity index 100% rename from include/rewindow/types/cursors.h rename to include/ReWindow/Cursors.hpp diff --git a/include/rewindow/types/display.h b/include/ReWindow/Display.hpp similarity index 98% rename from include/rewindow/types/display.h rename to include/ReWindow/Display.hpp index 77d31e2..fb61428 100644 --- a/include/rewindow/types/display.h +++ b/include/ReWindow/Display.hpp @@ -1,6 +1,6 @@ #pragma once #include -#include +#include "J3ML/J3ML.hpp" namespace ReWindow { class FullscreenGraphicsMode; diff --git a/include/rewindow/types/gamepad.h b/include/ReWindow/Gamepad.hpp similarity index 82% rename from include/rewindow/types/gamepad.h rename to include/ReWindow/Gamepad.hpp index 990532b..8b71ee4 100644 --- a/include/rewindow/types/gamepad.h +++ b/include/ReWindow/Gamepad.hpp @@ -11,6 +11,11 @@ #pragma once namespace ReWindow { + class GamepadState { + public: + std::map PressedButtons; + }; + class Gamepad; class Xbox360Gamepad; class XboxOneGamepad; diff --git a/include/rewindow/types/gamepadbutton.h b/include/ReWindow/GamepadButton.hpp similarity index 99% rename from include/rewindow/types/gamepadbutton.h rename to include/ReWindow/GamepadButton.hpp index 0ee6552..9990425 100644 --- a/include/rewindow/types/gamepadbutton.h +++ b/include/ReWindow/GamepadButton.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include "J3ML/LinearAlgebra.hpp" namespace ReWindow { class GamepadButton; class GamepadTrigger; diff --git a/include/rewindow/data/GamepadScancodes.h b/include/ReWindow/GamepadScancodes.hpp similarity index 100% rename from include/rewindow/data/GamepadScancodes.h rename to include/ReWindow/GamepadScancodes.hpp diff --git a/include/rewindow/types/key.h b/include/ReWindow/Key.hpp similarity index 98% rename from include/rewindow/types/key.h rename to include/ReWindow/Key.hpp index 42e40f5..ca5b39b 100644 --- a/include/rewindow/types/key.h +++ b/include/ReWindow/Key.hpp @@ -6,9 +6,9 @@ #include #include #include -#include -#include -#include +#include "rewindow/X11Scancodes.hpp" +#include "rewindow/WindowsScancodes.hpp" +#include "J3ML/LinearAlgebra.hpp" class Key diff --git a/include/rewindow/types/keyboard.h b/include/ReWindow/Keyboard.hpp similarity index 84% rename from include/rewindow/types/keyboard.h rename to include/ReWindow/Keyboard.hpp index 4ae79b2..fa4b0ed 100644 --- a/include/rewindow/types/keyboard.h +++ b/include/ReWindow/Keyboard.hpp @@ -13,6 +13,10 @@ namespace ReWindow { + class KeyboardState { + public: + std::map PressedKeys; + }; class InputDevice {}; class Keyboard : public InputDevice diff --git a/include/rewindow/logger/logger.h b/include/ReWindow/Logger.hpp similarity index 100% rename from include/rewindow/logger/logger.h rename to include/ReWindow/Logger.hpp diff --git a/include/ReWindow/Mouse.hpp b/include/ReWindow/Mouse.hpp new file mode 100644 index 0000000..98848e6 --- /dev/null +++ b/include/ReWindow/Mouse.hpp @@ -0,0 +1,80 @@ +/// ReWindowLibrary +/// A C++20 Library for creating and managing windows in a platform-independent manner +/// Developed and Maintained by the boys @ Redacted Software. +/// (c) 2024 Redacted Software +/// This work is dedicated to the public domain. + +/// @file keyboard.h +/// @desc A class that models the functionality of a mouse / pointer device. +/// @edit 2024-07-29 + +#pragma once + + +namespace ReWindow +{ + class MouseState { + public: + struct + { + bool LMB = false; + bool RMB = false; + bool MMB = false; + bool SideButton1 = false; + bool SideButton2 = false; + bool MWheelUp = false; + bool MWheelDown = false; + } Buttons; + + + Vector2 Position; + int Wheel = 0; + + [[nodiscard]] bool IsDown(const MouseButton& btn) const + { + if (btn == MouseButtons::Left) return Buttons.LMB; + if (btn == MouseButtons::Right) return Buttons.RMB; + if (btn == MouseButtons::Middle) return Buttons.MMB; + if (btn == MouseButtons::Mouse4) return Buttons.SideButton1; + if (btn == MouseButtons::Mouse5) return Buttons.SideButton2; + //if (btn == MouseButtons::MWheelUp) return Buttons.MWheelUp; + //if (btn == MouseButtons::MWheelDown) return Buttons.MWheelDown; + + return false; // Unknown button? + } + + void Set(const MouseButton& btn, bool state) + { + if (btn == MouseButtons::Left) Buttons.LMB = state; + if (btn == MouseButtons::Right) Buttons.RMB = state; + if (btn == MouseButtons::Middle) Buttons.MMB = state; + if (btn == MouseButtons::Mouse4) Buttons.SideButton1 = state; + if (btn == MouseButtons::Mouse5) Buttons.SideButton2 = state; + //if (btn == MouseButtons::MWheelUp) Buttons.MWheelUp = state; + //if (btn == MouseButtons::MWheelDown) Buttons.MWheelDown = state; + } + + bool& operator[](const MouseButton& btn) + { + if (btn == MouseButtons::Left) return Buttons.LMB; + if (btn == MouseButtons::Right) return Buttons.RMB; + if (btn == MouseButtons::Middle) return Buttons.MMB; + if (btn == MouseButtons::Mouse4) return Buttons.SideButton1; + if (btn == MouseButtons::Mouse5) return Buttons.SideButton2; + //if (btn == MouseButtons::MWheelUp) return Buttons.MWheelUp; + //if (btn == MouseButtons::MWheelDown) return Buttons.MWheelDown; + + throw std::runtime_error("Attempted to handle unmapped mouse button"); + } + }; + + class InputDevice {}; // TODO: Remember to break InputDevice into it's own file and not define it twice!!! + + class Pointer : public InputDevice {}; + + + class Mouse : public Pointer + { + + }; +} \ No newline at end of file diff --git a/include/rewindow/types/mousebutton.h b/include/ReWindow/MouseButton.hpp similarity index 100% rename from include/rewindow/types/mousebutton.h rename to include/ReWindow/MouseButton.hpp diff --git a/include/ReWindow/RWindow.hpp b/include/ReWindow/RWindow.hpp new file mode 100644 index 0000000..c24f840 --- /dev/null +++ b/include/ReWindow/RWindow.hpp @@ -0,0 +1,223 @@ +#pragma once +#include +#include +#include "Event.h" +#include +#include +#include "Key.hpp" +#include "rewindow/Cursors.hpp" +#include "MouseButton.hpp" +#include "GamepadButton.hpp" +#include "J3ML/LinearAlgebra.hpp" +#include "WindowEvents.hpp" +#include +#include + +#include + + +namespace ReWindow { + enum class RenderingAPI: uint8_t { + OPENGL = 0, + //Vulkan is unimplemented. + VULKAN = 1, + }; + // + + class RWindowImpl; + class XLibImpl; + class Win32Impl; + class RWindow; +} + +class ReWindow::RWindow { +private: + RWindowImpl* Impl = nullptr; +public: + //RWindow() = default; + //RWindow(); + + static RWindowImpl* GetPlatformImplementation(const RWindowParams& args) { + +#if UNIX + return new XLibImpl(args); +#endif + +#if WIN32 + return new Win32Impl(args); +#endif + return nullptr; + } + + + explicit RWindow(const RWindowParams& params) + : Impl(GetPlatformImplementation(params)) { } + + RWindow() + : RWindow({ + .title = "Redacted Window", + .width = 640, .height = 480, + .fullscreen = false, + .resizable = true, + .vsync = false + }) { } + + // TODO: Is this one valid? + explicit RWindow(RWindowImpl* wImpl) + : Impl(wImpl) { } + + RWindow(RWindowImpl* wImpl, RenderImpl* wRenderImpl) + : Impl(wImpl), Renderer(wRenderImpl) { } + + /* + explicit RWindow(const std::string& wTitle, + int wWidth = 640, int wHeight = 480, + RenderingAPI wRenderer = RenderingAPI::OPENGL, + bool wFullscreen = false, + bool wResizable = true, + bool wVsync = false) : + RWindowImpl(wTitle, wWidth, wHeight, wRenderer, wFullscreen, wResizable, wVsync) {}; + */ + ~RWindow() = default; +public: + // Platform dependant + void Open() { Impl->Open(); }; + void Close() { Impl->Close(); }; + void PollEvents() { Impl->PollEvents(); }; + void Refresh() { Impl->Refresh(); }; +public: + // Shared + /// Returns whether the window currently has mouse and/or keyboard focus. + [[nodiscard]] bool IsFocused() const { return Impl->IsFocused(); }; + /// Returns whether the window is currently in Fullscreen. + // TODO: Support Fullscreen, FullscreenWindowed, and Windowed? + [[nodiscard]] bool IsFullscreen() const { return Impl->IsFullscreen(); } ; + /// Returns whether the window can be resized. + [[nodiscard]] bool IsResizable() const { return Impl->IsResizable(); } ; + /// Returns whether V-Sync is enabled. + [[nodiscard]] bool IsVsyncEnabled() const { return Impl->IsVsyncEnabled(); } ; + /// Returns whether the window is considered to be alive. Once dead, any logic loop should be terminated, and the cleanup procedure should run. + [[nodiscard]] bool IsAlive() const { return Impl->IsAlive(); } ; + // Should have IsOpen since window could be closed then reopened +public: + // Platform dependant + /// Sets whether or not to make the window fullscreen. + /// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given. + void SetFullscreen(bool fs) { Impl->SetFullscreen(fs); }; + /// Sets whether or not to make the window resizable. + /// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given. + void SetResizable(bool resizable) { Impl->SetResizable(resizable); }; + /// Sets whether or not to enable vertical synchronization. + /// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given. + void SetVsyncEnabled(bool vsync) { Impl->SetVsyncEnabled(vsync); }; + /// Requests the operating system to change the window size. + /// @param width + /// @param height + void SetSize(int width, int height) { Impl->SetSize(width, height); }; + /// Requests the operating system to change the window size. + /// @param size + void SetSize(const Vector2& size) { Impl->SetSize(size); }; + + // Shared + /// Sets the title of this window. + void SetTitle(const std::string& title) { Impl->SetTitle(title); }; +public: + // Shared + [[nodiscard]] std::string GetTitle() const { return Impl->GetTitle(); } ; + /// Returns the position of the window's top-left corner relative to the display + [[nodiscard]] Vector2 GetPos() const { return Impl->GetPos(); } ; + /// Returns the known size of the window, in {x,y} pixel measurement. + [[nodiscard]] Vector2 GetSize() const { return Impl->GetSize(); } ; + /// Returns the horizontal length of the renderable area in pixels. + [[nodiscard]] int GetWidth() const { return Impl->GetWidth(); } ; + /// Returns the vertical length of the renderable area, in pixels. + [[nodiscard]] int GetHeight() const { return Impl->GetHeight(); } ; + /// Returns the amount of time, in seconds, between the current and last frame. + /// Technically, no, it returns the elapsed time of the frame, start to finish. + [[nodiscard]] float GetDeltaTime() const { return Impl->GetDeltaTime(); } ; + /// Returns the approximate frames-per-second using delta time. + [[nodiscard]] float GetRefreshRate() const { return Impl->GetRefreshRate(); } ; + /// Returns the number of frames ran since the windows' creation. + [[nodiscard]] float GetRefreshCounter() const { return Impl->GetRefreshCounter(); } ; +public: + // Figure out what to do with these later + void Raise() const { Impl->Raise(); }; + void Lower() const { Impl->Lower(); }; + void DestroyOSWindowHandle() { Impl->DestroyOSWindowHandle(); }; + void SetCursorVisible(bool cursor_enable) { Impl->SetCursorVisible(cursor_enable); }; + Vector2 GetAccurateMouseCoordinates() const { return Impl->GetAccurateMouseCoordinates(); } ; + void GLSwapBuffers() { Impl->GLSwapBuffers(); }; + void Fullscreen() { Impl->Fullscreen(); }; + void RestoreFromFullscreen() { Impl->RestoreFromFullscreen(); }; + // I know this doesn't modify the class, but it indirectly modifies the window + // Making it const just seems deceptive. + void SetCursorStyle(CursorStyle style) const { return Impl->SetCursorStyle(style); } ; + Vector2 GetPositionOfRenderableArea() const { return Impl->GetPositionOfRenderableArea(); } ; + std::string getGraphicsDriverVendor() { return Impl->getGraphicsDriverVendor(); }; + void SetFlag(RWindowFlags flag, bool state) { Impl->SetFlag(flag, state); }; + void processKeyRelease (Key key) { Impl->processKeyRelease(key); }; + void processKeyPress (Key key) { Impl->processKeyPress(key); }; + void processOnClose() { Impl->processOnClose(); }; + void processOnOpen() { Impl->processOnOpen(); }; + void processMousePress(const MouseButton& btn) { Impl->processMousePress(btn); }; + void processMouseRelease(const MouseButton& btn) { Impl->processMouseRelease(btn); }; + void processFocusIn() { Impl->processFocusIn(); }; + void processFocusOut() { Impl->processFocusOut(); }; + void processMouseMove(Vector2 last_pos, Vector2 new_pos) { Impl->processMouseMove(last_pos, new_pos); }; + void processMouseWheel(int scrolls) { Impl->processMouseWheel(scrolls); }; + virtual void OnOpen() {} + virtual void OnClosing() {} + virtual void OnFocusLost(const RWindowEvent& e) {} + virtual void OnFocusGain(const RWindowEvent& e) {} + virtual void OnRefresh(float elapsed) {} + virtual void OnResizeSuccess() {} + virtual bool OnResizeRequest(const WindowResizeRequestEvent& e) { return true;} + virtual void OnKeyDown(const KeyDownEvent&) {} + virtual void OnKeyUp(const KeyUpEvent&) {} + virtual void OnMouseMove(const MouseMoveEvent&) {} + virtual void OnMouseButtonDown(const MouseButtonDownEvent&) {} + virtual void OnMouseButtonUp(const MouseButtonUpEvent&) {} + virtual void OnMouseWheel(const MouseWheelEvent&) {} + Event<> OnOpenEvent; + Event<> OnClosingEvent; + Event OnFocusLostEvent; + Event OnFocusGainEvent; + Event OnRefreshEvent; + Event OnResizeRequestEvent; + Event OnKeyDownEvent; + Event OnKeyUpEvent; + Event OnMouseMoveEvent; + Event OnMouseButtonDownEvent; + Event OnMouseButtonUpEvent; + Event OnMouseWheelEvent; + + Vector2 GetMouseCoordinates() const { return Impl->GetMouseCoordinates(); }; + bool GetFlag(RWindowFlags flag) const { return Impl->GetFlag(flag); }; + //bool IsAlive() const { return Impl-> + //IsAlive(); }; + void SetSizeWithoutEvent(const Vector2& size) { Impl->SetSizeWithoutEvent(size); }; + void LogEvent(const RWindowEvent& e) { Impl->LogEvent(e); }; + RWindowEvent GetLastEvent() const { return Impl->GetLastEvent(); } + void SetLastKnownWindowSize(const Vector2& size) { Impl->SetLastKnownWindowSize(size); }; + void SetRenderer(RenderingAPI api) { Impl->SetRenderer(api); }; + bool IsKeyDown(Key key) const { return Impl->IsKeyDown(key); }; + bool IsMouseButtonDown(const MouseButton &button) const { return Impl->IsMouseButtonDown(button); }; + void ManagedRefresh() { Impl->ManagedRefresh(); }; + float ComputeElapsedFrameTimeSeconds(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end) { return Impl->ComputeElapsedFrameTimeSeconds(start, end); }; + std::chrono::steady_clock::time_point GetTimestamp() { return Impl->GetTimestamp(); }; + void UpdateFrameTiming(float frame_time) { Impl->UpdateFrameTiming(frame_time); }; + //bool IsResizable() const { return Impl-> + //IsResizable(); }; + //bool IsFullscreen() const { return Impl-> + //IsFullscreen(); }; + //bool IsFocused() const { return Impl-> + //IsFocused(); }; + //bool IsVsyncEnabled() const { return Impl-> + //IsVsyncEnabled(); }; + void ForceClose() { Impl->ForceClose(); }; + void ForceCloseAndTerminateProgram() { Impl->ForceCloseAndTerminateProgram(); }; + int GetMouseWheelPersistent() const { return Impl->GetMouseWheelPersistent();} + [[nodiscard]] bool IsOpen() const { return Impl->IsOpen();} + [[nodiscard]] bool IsClosing() const { return Impl->IsClosing();} + +}; \ No newline at end of file diff --git a/include/ReWindow/RWindowImpl.hpp b/include/ReWindow/RWindowImpl.hpp new file mode 100644 index 0000000..a1211f6 --- /dev/null +++ b/include/ReWindow/RWindowImpl.hpp @@ -0,0 +1,167 @@ +#pragma once + +namespace ReWindow { class RWindowImpl; } + +class ReWindow::RWindowImpl { +protected: // Should maybe make private + int width = 1280; + int height = 720; + + bool open = false; // Is the underlying OS-Window-Handle actually open. + bool resizable = true; + bool fullscreen_mode = false; + bool focused = true; + bool vsync = false; + bool cursor_visible = true; + bool closing = false; + + float delta_time = 0.f; + float refresh_rate = 0.f; + unsigned int refresh_count = 0; + + std::string title = "Redacted Window"; + + Vector2 lastKnownWindowSize {0, 0}; + + // TODO: Implement ringbuffer / circular vector class of some sort. + float refresh_rate_prev_1 = 0.f; + float refresh_rate_prev_2 = 0.f; + float refresh_rate_prev_3 = 0.f; + float refresh_rate_prev_4 = 0.f; + float refresh_rate_prev_5 = 0.f; + + float avg_refresh_rate = 0.0f; + + // Figure out what to do with this shit later + bool flags[5]; + KeyboardState currentKeyboard; // current frame keyboard state. + KeyboardState previousKeyboard; // previous frame keyboard state. + MouseState currentMouse; // purrent frame mouse state. + MouseState previousMouse; // previous frame mouse state + RenderingAPI renderer = RenderingAPI::OPENGL; + // +public: + explicit RWindowImpl(const RWindowParams& params) + : RWindowImpl(params.title, params.width, params.height, RenderingAPI::OPENGL, params.fullscreen, p) + explicit RWindowImpl(const std::string& wTitle, + int wWidth = 640, int wHeight = 480, + RenderingAPI wRenderer = RenderingAPI::OPENGL, + bool wFullscreen = false, + bool wResizable = true, + bool wVsync = false); + ~RWindowImpl(); +public: + virtual void Open(); + virtual void Close(); + virtual void PollEvents(); + virtual void Refresh(); +public: + bool IsFocused() const; + bool IsFullscreen() const; + bool IsResizable() const; + bool IsVsyncEnabled() const; + bool IsAlive() const; +public: + void SetFullscreen(bool fs); + void SetResizable(bool fs); + void SetVsyncEnabled(bool vsync); + void SetSize(int width, int height); + void SetSize(const Vector2& size); + // Added here for now + void SetPos(int x, int y); + void SetPos(const Vector2& pos); + // + virtual void SetTitle(const std::string& title); +public: + std::string GetTitle() const; + Vector2 GetPos() const; + Vector2 GetSize() const; + int GetWidth() const; + int GetHeight() const; + float GetDeltaTime() const; + float GetRefreshRate() const; + float GetRefreshCounter() const; +public: + // Figure out what to do with these later + void Raise() const; + void Lower() const; + void DestroyOSWindowHandle(); + void SetCursorVisible(bool cursor_enable); + Vector2 GetAccurateMouseCoordinates() const; + void GLSwapBuffers(); + void Fullscreen(); + void RestoreFromFullscreen(); + // I know this doesn't modify the class, but it indirectly modifies the window + // Making it const just seems deceptive. + void SetCursorStyle(CursorStyle style) const; + Vector2 GetPositionOfRenderableArea() const; + std::string getGraphicsDriverVendor(); + void SetFlag(RWindowFlags flag, bool state); + // Make protected + void processKeyRelease (Key key); + void processKeyPress (Key key); + void processOnClose(); + void processOnOpen(); + void processMousePress(const MouseButton& btn); + void processMouseRelease(const MouseButton& btn); + void processFocusIn(); + void processFocusOut(); + void processMouseMove(Vector2 last_pos, Vector2 new_pos); + void processMouseWheel(int scrolls); + // + virtual void OnOpen() {} + virtual void OnClosing() {} + virtual void OnFocusLost(const RWindowEvent& e) {} + virtual void OnFocusGain(const RWindowEvent& e) {} + virtual void OnRefresh(float elapsed) {} + virtual void OnResizeSuccess() {} + virtual bool OnResizeRequest(const WindowResizeRequestEvent& e) { return true;} + virtual void OnKeyDown(const KeyDownEvent&) {} + virtual void OnKeyUp(const KeyUpEvent&) {} + virtual void OnMouseMove(const MouseMoveEvent&) {} + virtual void OnMouseButtonDown(const MouseButtonDownEvent&) {} + virtual void OnMouseButtonUp(const MouseButtonUpEvent&) {} + virtual void OnMouseWheel(const MouseWheelEvent&) {} + Event<> OnOpenEvent; + Event<> OnClosingEvent; + Event OnFocusLostEvent; + Event OnFocusGainEvent; + Event OnRefreshEvent; + Event OnResizeRequestEvent; + Event OnKeyDownEvent; + Event OnKeyUpEvent; + Event OnMouseMoveEvent; + Event OnMouseButtonDownEvent; + Event OnMouseButtonUpEvent; + Event OnMouseWheelEvent; + + Vector2 GetMouseCoordinates() const; + bool GetFlag(RWindowFlags flag) const; + //bool IsAlive() const; + void SetSizeWithoutEvent(const Vector2& size); + std::vector eventLog; + std::queue eventQueue; + void LogEvent(const RWindowEvent& e) { eventLog.push_back(e);}; + RWindowEvent GetLastEvent() const { + return eventLog.back(); + }; + void SetLastKnownWindowSize(const Vector2& size); + void SetRenderer(RenderingAPI api); + bool IsKeyDown(Key key) const; + bool IsMouseButtonDown(const MouseButton &button) const; + void ManagedRefresh(); + float ComputeElapsedFrameTimeSeconds(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end); + std::chrono::steady_clock::time_point GetTimestamp(); + void UpdateFrameTiming(float frame_time); + /* + bool IsResizable() const; + bool IsFullscreen() const; + bool IsFocused() const; + bool IsVsyncEnabled() const; + */ + void ForceClose(); + void ForceCloseAndTerminateProgram(); + int GetMouseWheelPersistent() const { return currentMouse.Wheel;} + [[nodiscard]] bool IsOpen() const { return open;} + [[nodiscard]] bool IsClosing() const { return closing;} +}; diff --git a/include/ReWindow/RWindowParams.hpp b/include/ReWindow/RWindowParams.hpp new file mode 100644 index 0000000..1368734 --- /dev/null +++ b/include/ReWindow/RWindowParams.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace ReWindow { + struct RWindowParams + { + std::string title; + int width; + int height; + bool fullscreen; + bool resizable; + bool vsync; + }; +} diff --git a/include/ReWindow/Win32Impl.hpp b/include/ReWindow/Win32Impl.hpp new file mode 100644 index 0000000..747ac87 --- /dev/null +++ b/include/ReWindow/Win32Impl.hpp @@ -0,0 +1,5 @@ +#pragma once + +class ReWindow::Win32Impl : ReWindow::RWindowImpl { +public: +}; diff --git a/include/rewindow/types/WindowEvents.hpp b/include/ReWindow/WindowEvents.hpp similarity index 96% rename from include/rewindow/types/WindowEvents.hpp rename to include/ReWindow/WindowEvents.hpp index 0f9c8d1..1dbbc7e 100644 --- a/include/rewindow/types/WindowEvents.hpp +++ b/include/ReWindow/WindowEvents.hpp @@ -1,8 +1,8 @@ #pragma once #include -#include -#include +#include "Key.hpp" +#include "MouseButton.hpp" namespace ReWindow { diff --git a/include/rewindow/data/WindowsScancodes.h b/include/ReWindow/WindowsScancodes.hpp similarity index 100% rename from include/rewindow/data/WindowsScancodes.h rename to include/ReWindow/WindowsScancodes.hpp diff --git a/include/rewindow/data/X11Scancodes.h b/include/ReWindow/X11Scancodes.hpp similarity index 100% rename from include/rewindow/data/X11Scancodes.h rename to include/ReWindow/X11Scancodes.hpp diff --git a/include/ReWindow/XLibImpl.hpp b/include/ReWindow/XLibImpl.hpp new file mode 100644 index 0000000..39cd37e --- /dev/null +++ b/include/ReWindow/XLibImpl.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include +#include "J3ML/LinearAlgebra.hpp" + + +namespace ReWindow { class XLibImpl; }; + +class ReWindow::XLibImpl : ReWindow::RWindowImpl { + Window window; + XEvent xev; + Display* display = XOpenDisplay(nullptr); + int defaultScreen = DefaultScreen(display); + XVisualInfo* visual; + XSetWindowAttributes xSetWindowAttributes; + XWindowAttributes windowAttributes; + Atom wmDeleteWindow; + // Make it start as floating because fuck tiling WMs + Atom windowTypeAtom; + Atom windowTypeUtilityAtom; + XSizeHints hints; + GLXContext glContext; + Cursor invisible_cursor = 0; + Vector2 render_area_position = {0, 0}; + Vector2 position = {0, 0}; + bool should_poll_x_for_mouse_pos = true; +public: + void Open() override; + void Close() override; + void PollEvents() override; + void SetTitle(const std::string &title) override; + void Refresh() override; +}; + diff --git a/include/rewindow/types/mouse.h b/include/rewindow/types/mouse.h deleted file mode 100644 index a3296d6..0000000 --- a/include/rewindow/types/mouse.h +++ /dev/null @@ -1,26 +0,0 @@ -/// ReWindowLibrary -/// A C++20 Library for creating and managing windows in a platform-independent manner -/// Developed and Maintained by the boys @ Redacted Software. -/// (c) 2024 Redacted Software -/// This work is dedicated to the public domain. - -/// @file keyboard.h -/// @desc A class that models the functionality of a mouse / pointer device. -/// @edit 2024-07-29 - -#pragma once - - -namespace ReWindow -{ - - class InputDevice {}; // TODO: Remember to break InputDevice into it's own file and not define it twice!!! - - class Pointer : public InputDevice {}; - - - class Mouse : public Pointer - { - - }; -} \ No newline at end of file diff --git a/include/rewindow/types/window.h b/include/rewindow/types/window.h deleted file mode 100644 index 91d972b..0000000 --- a/include/rewindow/types/window.h +++ /dev/null @@ -1,462 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -// Figure out what to do with this shit -enum class RWindowFlags: uint8_t { - IN_FOCUS, - FULLSCREEN, - RESIZABLE, - VSYNC, - QUIT, - MAX_FLAG -}; - -// Just throwing this in the header for now -std::string RWindowFlagToStr(RWindowFlags flag); /*{ - switch (flag) { - case RWindowFlags::IN_FOCUS: return "IN_FOCUS"; - case RWindowFlags::FULLSCREEN: return "FULLSCREEN"; - case RWindowFlags::RESIZABLE: return "RESIZEABLE"; - case RWindowFlags::VSYNC: return "VSYNC"; - case RWindowFlags::QUIT: return "QUIT"; - case RWindowFlags::MAX_FLAG: return "MAX_FLAG"; - default: - return "unimplemented flag"; - } - }; - */ - -using J3ML::LinearAlgebra::Vector2; - -namespace ReWindow { - - - class KeyboardState { - public: - std::map PressedKeys; - }; - - class GamepadState { - public: - std::map PressedButtons; - }; - - class MouseState { - public: - struct - { - bool LMB = false; - bool RMB = false; - bool MMB = false; - bool SideButton1 = false; - bool SideButton2 = false; - bool MWheelUp = false; - bool MWheelDown = false; - } Buttons; - - - Vector2 Position; - int Wheel = 0; - - [[nodiscard]] bool IsDown(const MouseButton& btn) const - { - if (btn == MouseButtons::Left) return Buttons.LMB; - if (btn == MouseButtons::Right) return Buttons.RMB; - if (btn == MouseButtons::Middle) return Buttons.MMB; - if (btn == MouseButtons::Mouse4) return Buttons.SideButton1; - if (btn == MouseButtons::Mouse5) return Buttons.SideButton2; - //if (btn == MouseButtons::MWheelUp) return Buttons.MWheelUp; - //if (btn == MouseButtons::MWheelDown) return Buttons.MWheelDown; - - return false; // Unknown button? - } - - void Set(const MouseButton& btn, bool state) - { - if (btn == MouseButtons::Left) Buttons.LMB = state; - if (btn == MouseButtons::Right) Buttons.RMB = state; - if (btn == MouseButtons::Middle) Buttons.MMB = state; - if (btn == MouseButtons::Mouse4) Buttons.SideButton1 = state; - if (btn == MouseButtons::Mouse5) Buttons.SideButton2 = state; - //if (btn == MouseButtons::MWheelUp) Buttons.MWheelUp = state; - //if (btn == MouseButtons::MWheelDown) Buttons.MWheelDown = state; - } - - bool& operator[](const MouseButton& btn) - { - if (btn == MouseButtons::Left) return Buttons.LMB; - if (btn == MouseButtons::Right) return Buttons.RMB; - if (btn == MouseButtons::Middle) return Buttons.MMB; - if (btn == MouseButtons::Mouse4) return Buttons.SideButton1; - if (btn == MouseButtons::Mouse5) return Buttons.SideButton2; - //if (btn == MouseButtons::MWheelUp) return Buttons.MWheelUp; - //if (btn == MouseButtons::MWheelDown) return Buttons.MWheelDown; - - throw std::runtime_error("Attempted to handle unmapped mouse button"); - } - }; - - enum class RenderingAPI: uint8_t { - OPENGL = 0, - //Vulkan is unimplemented. - VULKAN = 1, - }; - // - - class RWindowImpl; - class RWindow; -} - -class ReWindow::RWindowImpl { -private: - // Class for platform specific "global" variables, information, functionality, etc - // It is private as it should not be accessed outside the Impl. It has also - // purposefully been left undefined, so implementors can define it as they see fit. - // Make sure to do proper cleanup of the class and pointer if utilized. It should - // be handled with care. - // - // Example for initialization: - // RWindowImpl::RWindowImpl(ARGS) : pPlatform( new Platform ) { XYZ } - // - // Example for destruction: - // RWindowImpl::~RWindowImpl() { - // if (pPlatform) { delete pPlatform; }; - // } - // - // Example for definition: - // class RWindowImpl::Platform { - // public: - // Platform() = default; - // public: - // int a; - // int b; - // int c; - // }; - // - // - Maxine - class Platform; - Platform* pPlatform = nullptr; -protected: // Should maybe make private - int width = 1280; - int height = 720; - - bool open = false; // Is the underlying OS-Window-Handle actually open. - bool resizable = true; - bool fullscreen_mode = false; - bool focused = true; - bool vsync = false; - bool cursor_visible = true; - bool closing = false; - - float delta_time = 0.f; - float refresh_rate = 0.f; - unsigned int refresh_count = 0; - - std::string title = "Redacted Window"; - - Vector2 lastKnownWindowSize {0, 0}; - - // TODO: Implement ringbuffer / circular vector class of some sort. - float refresh_rate_prev_1 = 0.f; - float refresh_rate_prev_2 = 0.f; - float refresh_rate_prev_3 = 0.f; - float refresh_rate_prev_4 = 0.f; - float refresh_rate_prev_5 = 0.f; - - float avg_refresh_rate = 0.0f; - - // Figure out what to do with this shit later - bool flags[5]; - KeyboardState currentKeyboard; // current frame keyboard state. - KeyboardState previousKeyboard; // previous frame keyboard state. - MouseState currentMouse; // purrent frame mouse state. - MouseState previousMouse; // previous frame mouse state - RenderingAPI renderer = RenderingAPI::OPENGL; - // -public: - explicit RWindowImpl(const std::string& wTitle, - int wWidth = 640, int wHeight = 480, - RenderingAPI wRenderer = RenderingAPI::OPENGL, - bool wFullscreen = false, - bool wResizable = true, - bool wVsync = false); - ~RWindowImpl(); -public: - void Open(); - void Close(); - void PollEvents(); - void Refresh(); -public: - bool IsFocused() const; - bool IsFullscreen() const; - bool IsResizable() const; - bool IsVsyncEnabled() const; - bool IsAlive() const; -public: - void SetFullscreen(bool fs); - void SetResizable(bool fs); - void SetVsyncEnabled(bool vsync); - void SetSize(int width, int height); - void SetSize(const Vector2& size); - // Added here for now - void SetPos(int x, int y); - void SetPos(const Vector2& pos); - // - void SetTitle(const std::string& title); -public: - std::string GetTitle() const; - Vector2 GetPos() const; - Vector2 GetSize() const; - int GetWidth() const; - int GetHeight() const; - float GetDeltaTime() const; - float GetRefreshRate() const; - float GetRefreshCounter() const; -public: - // Figure out what to do with these later - void Raise() const; - void Lower() const; - void DestroyOSWindowHandle(); - void SetCursorVisible(bool cursor_enable); - Vector2 GetAccurateMouseCoordinates() const; - void GLSwapBuffers(); - void Fullscreen(); - void RestoreFromFullscreen(); - // I know this doesn't modify the class, but it indirectly modifies the window - // Making it const just seems deceptive. - void SetCursorStyle(CursorStyle style) const; - Vector2 GetPositionOfRenderableArea() const; - std::string getGraphicsDriverVendor(); - void SetFlag(RWindowFlags flag, bool state); - void processKeyRelease (Key key); - void processKeyPress (Key key); - void processOnClose(); - void processOnOpen(); - void processMousePress(const MouseButton& btn); - void processMouseRelease(const MouseButton& btn); - void processFocusIn(); - void processFocusOut(); - void processMouseMove(Vector2 last_pos, Vector2 new_pos); - void processMouseWheel(int scrolls); - virtual void OnOpen() {} - virtual void OnClosing() {} - virtual void OnFocusLost(const RWindowEvent& e) {} - virtual void OnFocusGain(const RWindowEvent& e) {} - virtual void OnRefresh(float elapsed) {} - virtual void OnResizeSuccess() {} - virtual bool OnResizeRequest(const WindowResizeRequestEvent& e) { return true;} - virtual void OnKeyDown(const KeyDownEvent&) {} - virtual void OnKeyUp(const KeyUpEvent&) {} - virtual void OnMouseMove(const MouseMoveEvent&) {} - virtual void OnMouseButtonDown(const MouseButtonDownEvent&) {} - virtual void OnMouseButtonUp(const MouseButtonUpEvent&) {} - virtual void OnMouseWheel(const MouseWheelEvent&) {} - Event<> OnOpenEvent; - Event<> OnClosingEvent; - Event OnFocusLostEvent; - Event OnFocusGainEvent; - Event OnRefreshEvent; - Event OnResizeRequestEvent; - Event OnKeyDownEvent; - Event OnKeyUpEvent; - Event OnMouseMoveEvent; - Event OnMouseButtonDownEvent; - Event OnMouseButtonUpEvent; - Event OnMouseWheelEvent; - - Vector2 GetMouseCoordinates() const; - bool GetFlag(RWindowFlags flag) const; - //bool IsAlive() const; - void SetSizeWithoutEvent(const Vector2& size); - std::vector eventLog; - std::queue eventQueue; - void LogEvent(const RWindowEvent& e) { eventLog.push_back(e);}; - RWindowEvent GetLastEvent() const { - return eventLog.back(); - }; - void SetLastKnownWindowSize(const Vector2& size); - void SetRenderer(RenderingAPI api); - bool IsKeyDown(Key key) const; - bool IsMouseButtonDown(const MouseButton &button) const; - void ManagedRefresh(); - float ComputeElapsedFrameTimeSeconds(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end); - std::chrono::steady_clock::time_point GetTimestamp(); - void UpdateFrameTiming(float frame_time); - /* - bool IsResizable() const; - bool IsFullscreen() const; - bool IsFocused() const; - bool IsVsyncEnabled() const; - */ - void ForceClose(); - void ForceCloseAndTerminateProgram(); - int GetMouseWheelPersistent() const { return currentMouse.Wheel;} - [[nodiscard]] bool IsOpen() const { return open;} - [[nodiscard]] bool IsClosing() const { return closing;} - - -}; - -class ReWindow::RWindow : private RWindowImpl { -public: - //RWindow() = default; - //RWindow(); - explicit RWindow(const std::string& wTitle, - int wWidth = 640, int wHeight = 480, - RenderingAPI wRenderer = RenderingAPI::OPENGL, - bool wFullscreen = false, - bool wResizable = true, - bool wVsync = false) : - RWindowImpl(wTitle, wWidth, wHeight, wRenderer, wFullscreen, wResizable, wVsync) {}; - ~RWindow() = default; -public: - // Platform dependant - void Open() { RWindowImpl::Open(); }; - void Close() { RWindowImpl::Close(); }; - void PollEvents() { RWindowImpl::PollEvents(); }; - void Refresh() { RWindowImpl::Refresh(); }; -public: - // Shared - /// Returns whether the window currently has mouse and/or keyboard focus. - [[nodiscard]] bool IsFocused() const { return RWindowImpl::IsFocused(); }; - /// Returns whether the window is currently in Fullscreen. - // TODO: Support Fullscreen, FullscreenWindowed, and Windowed? - [[nodiscard]] bool IsFullscreen() const { return RWindowImpl::IsFullscreen(); } ; - /// Returns whether the window can be resized. - [[nodiscard]] bool IsResizable() const { return RWindowImpl::IsResizable(); } ; - /// Returns whether V-Sync is enabled. - [[nodiscard]] bool IsVsyncEnabled() const { return RWindowImpl::IsVsyncEnabled(); } ; - /// Returns whether the window is considered to be alive. Once dead, any logic loop should be terminated, and the cleanup procedure should run. - [[nodiscard]] bool IsAlive() const { return RWindowImpl::IsAlive(); } ; - // Should have IsOpen since window could be closed then reopened -public: - // Platform dependant - /// Sets whether or not to make the window fullscreen. - /// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given. - void SetFullscreen(bool fs) { RWindowImpl::SetFullscreen(fs); }; - /// Sets whether or not to make the window resizable. - /// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given. - void SetResizable(bool resizable) { RWindowImpl::SetResizable(resizable); }; - /// Sets whether or not to enable vertical synchronization. - /// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given. - void SetVsyncEnabled(bool vsync) { RWindowImpl::SetVsyncEnabled(vsync); }; - /// Requests the operating system to change the window size. - /// @param width - /// @param height - void SetSize(int width, int height) { RWindowImpl::SetSize(width, height); }; - /// Requests the operating system to change the window size. - /// @param size - void SetSize(const Vector2& size) { RWindowImpl::SetSize(size); }; - - // Shared - /// Sets the title of this window. - void SetTitle(const std::string& title) { RWindowImpl::SetTitle(title); }; -public: - // Shared - [[nodiscard]] std::string GetTitle() const { return RWindowImpl::GetTitle(); } ; - /// Returns the position of the window's top-left corner relative to the display - [[nodiscard]] Vector2 GetPos() const { return RWindowImpl::GetPos(); } ; - /// Returns the known size of the window, in {x,y} pixel measurement. - [[nodiscard]] Vector2 GetSize() const { return RWindowImpl::GetSize(); } ; - /// Returns the horizontal length of the renderable area in pixels. - [[nodiscard]] int GetWidth() const { return RWindowImpl::GetWidth(); } ; - /// Returns the vertical length of the renderable area, in pixels. - [[nodiscard]] int GetHeight() const { return RWindowImpl::GetHeight(); } ; - /// Returns the amount of time, in seconds, between the current and last frame. - /// Technically, no, it returns the elapsed time of the frame, start to finish. - [[nodiscard]] float GetDeltaTime() const { return RWindowImpl::GetDeltaTime(); } ; - /// Returns the approximate frames-per-second using delta time. - [[nodiscard]] float GetRefreshRate() const { return RWindowImpl::GetRefreshRate(); } ; - /// Returns the number of frames ran since the windows' creation. - [[nodiscard]] float GetRefreshCounter() const { return RWindowImpl::GetRefreshCounter(); } ; -public: - // Figure out what to do with these later - void Raise() const { RWindowImpl::Raise(); }; - void Lower() const { RWindowImpl::Lower(); }; - void DestroyOSWindowHandle() { RWindowImpl::DestroyOSWindowHandle(); }; - void SetCursorVisible(bool cursor_enable) { RWindowImpl::SetCursorVisible(cursor_enable); }; - Vector2 GetAccurateMouseCoordinates() const { return RWindowImpl::GetAccurateMouseCoordinates(); } ; - void GLSwapBuffers() { RWindowImpl::GLSwapBuffers(); }; - void Fullscreen() { RWindowImpl::Fullscreen(); }; - void RestoreFromFullscreen() { RWindowImpl::RestoreFromFullscreen(); }; - // I know this doesn't modify the class, but it indirectly modifies the window - // Making it const just seems deceptive. - void SetCursorStyle(CursorStyle style) const { return RWindowImpl::SetCursorStyle(style); } ; - Vector2 GetPositionOfRenderableArea() const { return RWindowImpl::GetPositionOfRenderableArea(); } ; - std::string getGraphicsDriverVendor() { return RWindowImpl::getGraphicsDriverVendor(); }; - void SetFlag(RWindowFlags flag, bool state) { RWindowImpl::SetFlag(flag, state); }; - void processKeyRelease (Key key) { RWindowImpl::processKeyRelease(key); }; - void processKeyPress (Key key) { RWindowImpl::processKeyPress(key); }; - void processOnClose() { RWindowImpl::processOnClose(); }; - void processOnOpen() { RWindowImpl::processOnOpen(); }; - void processMousePress(const MouseButton& btn) { RWindowImpl::processMousePress(btn); }; - void processMouseRelease(const MouseButton& btn) { RWindowImpl::processMouseRelease(btn); }; - void processFocusIn() { RWindowImpl::processFocusIn(); }; - void processFocusOut() { RWindowImpl::processFocusOut(); }; - void processMouseMove(Vector2 last_pos, Vector2 new_pos) { RWindowImpl::processMouseMove(last_pos, new_pos); }; - void processMouseWheel(int scrolls) { RWindowImpl::processMouseWheel(scrolls); }; - virtual void OnOpen() {} - virtual void OnClosing() {} - virtual void OnFocusLost(const RWindowEvent& e) {} - virtual void OnFocusGain(const RWindowEvent& e) {} - virtual void OnRefresh(float elapsed) {} - virtual void OnResizeSuccess() {} - virtual bool OnResizeRequest(const WindowResizeRequestEvent& e) { return true;} - virtual void OnKeyDown(const KeyDownEvent&) {} - virtual void OnKeyUp(const KeyUpEvent&) {} - virtual void OnMouseMove(const MouseMoveEvent&) {} - virtual void OnMouseButtonDown(const MouseButtonDownEvent&) {} - virtual void OnMouseButtonUp(const MouseButtonUpEvent&) {} - virtual void OnMouseWheel(const MouseWheelEvent&) {} - Event<> OnOpenEvent; - Event<> OnClosingEvent; - Event OnFocusLostEvent; - Event OnFocusGainEvent; - Event OnRefreshEvent; - Event OnResizeRequestEvent; - Event OnKeyDownEvent; - Event OnKeyUpEvent; - Event OnMouseMoveEvent; - Event OnMouseButtonDownEvent; - Event OnMouseButtonUpEvent; - Event OnMouseWheelEvent; - - Vector2 GetMouseCoordinates() const { return RWindowImpl::GetMouseCoordinates(); }; - bool GetFlag(RWindowFlags flag) const { return RWindowImpl::GetFlag(flag); }; - //bool IsAlive() const { return RWindowImpl::IsAlive(); }; - void SetSizeWithoutEvent(const Vector2& size) { RWindowImpl::SetSizeWithoutEvent(size); }; - void LogEvent(const RWindowEvent& e) { RWindowImpl::LogEvent(e); }; - RWindowEvent GetLastEvent() const { return RWindowImpl::GetLastEvent(); } - void SetLastKnownWindowSize(const Vector2& size) { RWindowImpl::SetLastKnownWindowSize(size); }; - void SetRenderer(RenderingAPI api) { RWindowImpl::SetRenderer(api); }; - bool IsKeyDown(Key key) const { return RWindowImpl::IsKeyDown(key); }; - bool IsMouseButtonDown(const MouseButton &button) const { return RWindowImpl::IsMouseButtonDown(button); }; - void ManagedRefresh() { RWindowImpl::ManagedRefresh(); }; - float ComputeElapsedFrameTimeSeconds(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end) { return RWindowImpl::ComputeElapsedFrameTimeSeconds(start, end); }; - std::chrono::steady_clock::time_point GetTimestamp() { return RWindowImpl::GetTimestamp(); }; - void UpdateFrameTiming(float frame_time) { RWindowImpl::UpdateFrameTiming(frame_time); }; - //bool IsResizable() const { return RWindowImpl::IsResizable(); }; - //bool IsFullscreen() const { return RWindowImpl::IsFullscreen(); }; - //bool IsFocused() const { return RWindowImpl::IsFocused(); }; - //bool IsVsyncEnabled() const { return RWindowImpl::IsVsyncEnabled(); }; - void ForceClose() { RWindowImpl::ForceClose(); }; - void ForceCloseAndTerminateProgram() { RWindowImpl::ForceCloseAndTerminateProgram(); }; - int GetMouseWheelPersistent() const { return RWindowImpl::GetMouseWheelPersistent();} - [[nodiscard]] bool IsOpen() const { return RWindowImpl::IsOpen();} - [[nodiscard]] bool IsClosing() const { return RWindowImpl::IsClosing();} - -}; \ No newline at end of file diff --git a/main.cpp b/main.cpp index 774cf47..d19a37b 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,7 @@ #include -#include -#include -#include +#include +#include +#include //aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Windows :/ #if _WIN32 diff --git a/src/types/gamepadbutton.cpp b/src/ReWindow/GamepadButton.cpp similarity index 93% rename from src/types/gamepadbutton.cpp rename to src/ReWindow/GamepadButton.cpp index bd5b28f..dad4c3f 100644 --- a/src/types/gamepadbutton.cpp +++ b/src/ReWindow/GamepadButton.cpp @@ -1,4 +1,4 @@ -#include +#include bool ReWindow::GamepadButton::operator ==(const GamepadButton &rhs) const { return this->GetMnemonicButtonCode() == rhs.GetMnemonicButtonCode(); diff --git a/src/types/key.cpp b/src/ReWindow/Key.cpp similarity index 94% rename from src/types/key.cpp rename to src/ReWindow/Key.cpp index 79077dd..5a4f661 100644 --- a/src/types/key.cpp +++ b/src/ReWindow/Key.cpp @@ -1,5 +1,5 @@ -#include -//#include +#include +//#include //std::vector Key::keyboard = {}; std::vector Key::GetKeyboard() { return keyboard; } diff --git a/src/logger/logger.cpp b/src/ReWindow/Logger.cpp similarity index 91% rename from src/logger/logger.cpp rename to src/ReWindow/Logger.cpp index c275bfb..6f08664 100644 --- a/src/logger/logger.cpp +++ b/src/ReWindow/Logger.cpp @@ -1,4 +1,4 @@ -#include "rewindow/logger/logger.h" +#include namespace ReWindow::Logger { using namespace jlog; diff --git a/src/types/mousebutton.cpp b/src/ReWindow/MouseButton.cpp similarity index 93% rename from src/types/mousebutton.cpp rename to src/ReWindow/MouseButton.cpp index e51ee24..cb6f584 100644 --- a/src/types/mousebutton.cpp +++ b/src/ReWindow/MouseButton.cpp @@ -1,7 +1,7 @@ -#include +#include #include #include -#include "rewindow/logger/logger.h" +#include MouseButton::MouseButton(const std::string& charcode, unsigned int index) { diff --git a/src/platform/shared/window.cpp b/src/ReWindow/RWindowImpl.cpp similarity index 77% rename from src/platform/shared/window.cpp rename to src/ReWindow/RWindowImpl.cpp index a76042b..996f1a5 100644 --- a/src/platform/shared/window.cpp +++ b/src/ReWindow/RWindowImpl.cpp @@ -1,56 +1,4 @@ -#include -#include "rewindow/logger/logger.h" -/* -std::string RWindowFlagToStr(RWindowFlags flag) { - switch (flag) { - case RWindowFlags::IN_FOCUS: return "IN_FOCUS"; - case RWindowFlags::FULLSCREEN: return "FULLSCREEN"; - case RWindowFlags::RESIZABLE: return "RESIZEABLE"; - case RWindowFlags::VSYNC: return "VSYNC"; - case RWindowFlags::QUIT: return "QUIT"; - case RWindowFlags::MAX_FLAG: return "MAX_FLAG"; - default: - return "unimplemented flag"; - } -}; - */ - -std::string RWindowFlagToStr(RWindowFlags flag) { - switch (flag) { - case RWindowFlags::IN_FOCUS: return "IN_FOCUS"; - case RWindowFlags::FULLSCREEN: return "FULLSCREEN"; - case RWindowFlags::RESIZABLE: return "RESIZEABLE"; - case RWindowFlags::VSYNC: return "VSYNC"; - case RWindowFlags::QUIT: return "QUIT"; - case RWindowFlags::MAX_FLAG: return "MAX_FLAG"; - default: - return "unimplemented flag"; - } -}; - - -using namespace ReWindow; - - - -/* -RWindow::RWindow(const std::string& wTitle, int wWidth, int wHeight, RenderingAPI wRenderer, bool wFullscreen, bool wResizable, bool wVsync) -: title(wTitle), width(wWidth), height(wHeight), renderer(wRenderer), fullscreen_mode(wFullscreen), resizable(wResizable), vsync(wVsync), -flags{false,wFullscreen,wResizable,wVsync} { - -} - */ - - -//RWindow::~RWindow() { - /* - if (open) - DestroyOSWindowHandle(); - */ - //RWindowImpl::~RWindowImpl(); -//} - - +#include Vector2 RWindowImpl::GetMouseCoordinates() const { return currentMouse.Position; @@ -293,15 +241,39 @@ bool RWindowImpl::IsFocused() const { processOnClose(); } - void RWindowImpl::ForceClose() { - Close(); - DestroyOSWindowHandle(); - } +void RWindowImpl::Open() { + open = true; + processOnOpen(); +} - void RWindowImpl::ForceCloseAndTerminateProgram() { - ForceClose(); - exit(0); - } +void RWindowImpl::ForceClose() { + Close(); + DestroyOSWindowHandle(); +} +void RWindowImpl::ForceCloseAndTerminateProgram() { + ForceClose(); + exit(0); +} +void RWindowImpl::PollEvents() +{ + previousKeyboard = currentKeyboard; + previousMouse.Buttons = currentMouse.Buttons; +} + +void RWindowImpl::Refresh() +{ + PollEvents(); + OnRefresh(delta_time); + + // Only call once and cache the result. + currentMouse.Position = GetAccurateMouseCoordinates(); + + /// TODO: Implement optional minimum epsilon to trigger a Mouse Update. + if (currentMouse.Position != previousMouse.Position) { + processMouseMove(previousMouse.Position, currentMouse.Position); + previousMouse.Position = currentMouse.Position; + } +} diff --git a/src/platform/windows/window.cpp b/src/ReWindow/Win32Impl.cpp similarity index 99% rename from src/platform/windows/window.cpp rename to src/ReWindow/Win32Impl.cpp index b694dce..b5673e5 100644 --- a/src/platform/windows/window.cpp +++ b/src/ReWindow/Win32Impl.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include using namespace ReWindow; diff --git a/src/ReWindow/WindowEvents.cpp b/src/ReWindow/WindowEvents.cpp new file mode 100644 index 0000000..7fe9439 --- /dev/null +++ b/src/ReWindow/WindowEvents.cpp @@ -0,0 +1,7 @@ +#include + + +namespace ReWindow +{ + +} \ No newline at end of file diff --git a/src/platform/linux/window.cpp b/src/ReWindow/XLibImpl.cpp similarity index 95% rename from src/platform/linux/window.cpp rename to src/ReWindow/XLibImpl.cpp index b7cf401..9d0bd10 100644 --- a/src/platform/linux/window.cpp +++ b/src/ReWindow/XLibImpl.cpp @@ -4,10 +4,10 @@ #include #include #include -#include -#include +#include +#include #include -#include +#include @@ -79,6 +79,60 @@ RWindowImpl::~RWindowImpl() { DestroyOSWindowHandle(); } +void XLibImpl::SetTitle(const std::string &title) { + RWindowImpl::SetTitle(title); + XStoreName(pPlatform->display, pPlatform->window, title.c_str()); +} + +void XLibImpl::Open() { + + pPlatform->xSetWindowAttributes.border_pixel = BlackPixel(pPlatform->display, pPlatform->defaultScreen); + pPlatform->xSetWindowAttributes.background_pixel = BlackPixel(pPlatform->display, pPlatform->defaultScreen); + pPlatform->xSetWindowAttributes.override_redirect = True; + pPlatform->xSetWindowAttributes.event_mask = ExposureMask; + //SetVsyncEnabled(vsync); + if (renderer == RenderingAPI::OPENGL) { + GLint glAttributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None}; + pPlatform->visual = glXChooseVisual(pPlatform->display, pPlatform->defaultScreen, glAttributes); + pPlatform->glContext = glXCreateContext(pPlatform->display, pPlatform->visual, nullptr, GL_TRUE); + } + + pPlatform->xSetWindowAttributes.colormap = XCreateColormap(pPlatform->display, RootWindow(pPlatform->display, pPlatform->defaultScreen), pPlatform->visual->visual, AllocNone); + + pPlatform->window = XCreateWindow(pPlatform->display, RootWindow(pPlatform->display, pPlatform->defaultScreen), 0, 0, width, height, 0, pPlatform->visual->depth, + InputOutput, pPlatform->visual->visual, CWBackPixel | CWColormap | CWBorderPixel | NoEventMask, + &pPlatform->xSetWindowAttributes); + // Set window to floating because fucking tiling WMs + pPlatform->windowTypeAtom = XInternAtom(pPlatform->display, "_NET_WM_WINDOW_TYPE", False); + pPlatform->windowTypeUtilityAtom = XInternAtom(pPlatform->display, "_NET_WM_WINDOW_TYPE_UTILITY", False); + XChangeProperty(pPlatform->display, pPlatform->window, pPlatform->windowTypeAtom, XA_ATOM, 32, PropModeReplace, + (unsigned char *)&pPlatform->windowTypeUtilityAtom, 1); + // + XSelectInput(pPlatform->display, pPlatform->window, + ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | + PointerMotionHintMask | FocusChangeMask | StructureNotifyMask | SubstructureRedirectMask | + SubstructureNotifyMask | CWColormap ); + XMapWindow(pPlatform->display, pPlatform->window); + XStoreName(pPlatform->display, pPlatform->window, title.c_str()); + pPlatform->wmDeleteWindow = XInternAtom(pPlatform->display, "WM_DELETE_WINDOW", False); + XSetWMProtocols(pPlatform->display, pPlatform->window, &pPlatform->wmDeleteWindow, 1); + + if (renderer == RenderingAPI::OPENGL) + glXMakeCurrent(pPlatform->display, pPlatform->window, pPlatform->glContext); + + // Get the position of the renderable area relative to the rest of the window. + XGetWindowAttributes(pPlatform->display, pPlatform->window, &pPlatform->windowAttributes); + pPlatform->render_area_position = { (float) pPlatform->windowAttributes.x, (float) pPlatform->windowAttributes.y }; + RWindowImpl::Open(); +} + + +void XLibImpl::Close() +{ + RWindowImpl::Close(); +} + //using namespace ReWindow; void RWindowImpl::Raise() const { @@ -158,7 +212,7 @@ void RWindowImpl::SetFlag(RWindowFlags flag, bool state) { Logger::Debug(std::format("Set flag '{}' to state '{}' for window '{}'", RWindowFlagToStr(flag), state, this->title)); } -void RWindowImpl::PollEvents() { +void XLibImpl::PollEvents() { while(XPending(pPlatform->display)) { XNextEvent(pPlatform->display, &pPlatform->xev); @@ -277,28 +331,17 @@ void RWindowImpl::PollEvents() { } } - previousKeyboard = currentKeyboard; - previousMouse.Buttons = currentMouse.Buttons; + RWindowImpl::PollEvents(); } -void RWindowImpl::Refresh() { +void XLibImpl::Refresh() { // Essentially allows more than one window to be drawable // https://www.khronos.org/opengl/wiki/Programming_OpenGL_in_Linux:_GLX_and_Xlib // https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/glXMakeCurrent.xml glXMakeCurrent(pPlatform->display, pPlatform->window, pPlatform->glContext); - PollEvents(); - OnRefresh(delta_time); - - // Only call once and cache the result. - currentMouse.Position = GetAccurateMouseCoordinates(); - - /// TODO: Implement optional minimum epsilon to trigger a Mouse Update. - if (currentMouse.Position != previousMouse.Position) { - processMouseMove(previousMouse.Position, currentMouse.Position); - previousMouse.Position = currentMouse.Position; - } + RWindowImpl::Refresh(); } @@ -416,54 +459,11 @@ void RWindowImpl::SetCursorStyle(CursorStyle style) const { XDefineCursor(pPlatform->display, pPlatform->window, c); } -void RWindowImpl::Open() { - pPlatform->xSetWindowAttributes.border_pixel = BlackPixel(pPlatform->display, pPlatform->defaultScreen); - pPlatform->xSetWindowAttributes.background_pixel = BlackPixel(pPlatform->display, pPlatform->defaultScreen); - pPlatform->xSetWindowAttributes.override_redirect = True; - pPlatform->xSetWindowAttributes.event_mask = ExposureMask; - //SetVsyncEnabled(vsync); - if (renderer == RenderingAPI::OPENGL) { - GLint glAttributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None}; - pPlatform->visual = glXChooseVisual(pPlatform->display, pPlatform->defaultScreen, glAttributes); - pPlatform->glContext = glXCreateContext(pPlatform->display, pPlatform->visual, nullptr, GL_TRUE); - } - pPlatform->xSetWindowAttributes.colormap = XCreateColormap(pPlatform->display, RootWindow(pPlatform->display, pPlatform->defaultScreen), pPlatform->visual->visual, AllocNone); - - pPlatform->window = XCreateWindow(pPlatform->display, RootWindow(pPlatform->display, pPlatform->defaultScreen), 0, 0, width, height, 0, pPlatform->visual->depth, - InputOutput, pPlatform->visual->visual, CWBackPixel | CWColormap | CWBorderPixel | NoEventMask, - &pPlatform->xSetWindowAttributes); - // Set window to floating because fucking tiling WMs - pPlatform->windowTypeAtom = XInternAtom(pPlatform->display, "_NET_WM_WINDOW_TYPE", False); - pPlatform->windowTypeUtilityAtom = XInternAtom(pPlatform->display, "_NET_WM_WINDOW_TYPE_UTILITY", False); - XChangeProperty(pPlatform->display, pPlatform->window, pPlatform->windowTypeAtom, XA_ATOM, 32, PropModeReplace, - (unsigned char *)&pPlatform->windowTypeUtilityAtom, 1); - // - XSelectInput(pPlatform->display, pPlatform->window, - ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | - PointerMotionHintMask | FocusChangeMask | StructureNotifyMask | SubstructureRedirectMask | - SubstructureNotifyMask | CWColormap ); - XMapWindow(pPlatform->display, pPlatform->window); - XStoreName(pPlatform->display, pPlatform->window, title.c_str()); - pPlatform->wmDeleteWindow = XInternAtom(pPlatform->display, "WM_DELETE_WINDOW", False); - XSetWMProtocols(pPlatform->display, pPlatform->window, &pPlatform->wmDeleteWindow, 1); - - if (renderer == RenderingAPI::OPENGL) - glXMakeCurrent(pPlatform->display, pPlatform->window, pPlatform->glContext); - - // Get the position of the renderable area relative to the rest of the window. - XGetWindowAttributes(pPlatform->display, pPlatform->window, &pPlatform->windowAttributes); - pPlatform->render_area_position = { (float) pPlatform->windowAttributes.x, (float) pPlatform->windowAttributes.y }; - - open = true; - - processOnOpen(); -} void RWindowImpl::SetTitle(const std::string &title) { this->title = title; - XStoreName(pPlatform->display, pPlatform->window, title.c_str()); + } diff --git a/src/platform/linux/display.cpp b/src/platform/linux/display.cpp index c449856..65abc76 100644 --- a/src/platform/linux/display.cpp +++ b/src/platform/linux/display.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/platform/shared/display.cpp b/src/platform/shared/display.cpp index fb5dadf..6ed86b0 100644 --- a/src/platform/shared/display.cpp +++ b/src/platform/shared/display.cpp @@ -1,4 +1,4 @@ -#include +#include using namespace ReWindow; diff --git a/src/types/WindowEvents.cpp b/src/types/WindowEvents.cpp deleted file mode 100644 index 1496d5c..0000000 --- a/src/types/WindowEvents.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - - -namespace ReWindow -{ - -} \ No newline at end of file