Compare commits
16 Commits
input_refa
...
Prerelease
Author | SHA1 | Date | |
---|---|---|---|
e39881f2dc | |||
830dd954a2 | |||
e764dcf5b8 | |||
4b8479f1d3 | |||
f79164f89b | |||
a2ef397bdb | |||
6fd30ff25b | |||
8d8e14ef40 | |||
ee408c2fe6 | |||
f50280824d | |||
74d5f13c06 | |||
1950aee948 | |||
2d9f7e08b0 | |||
561e806b5f | |||
fa807256af | |||
b10a4d1d39 |
@@ -18,7 +18,7 @@ include(cmake/CPM.cmake)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME J3ML
|
||||
URL https://git.redacted.cc/josh/j3ml/archive/Release-3.2.zip
|
||||
URL https://git.redacted.cc/josh/j3ml/archive/3.4.5.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
@@ -43,11 +43,11 @@ file(GLOB_RECURSE HEADERS "include/logger/*.h" "include/logger/*.hpp")
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
|
||||
file(GLOB_RECURSE SOURCES "src/types/*.cpp" "src/platform/linux/*.cpp" "src/platform/shared/*.cpp" "src/logger/*.cpp" )
|
||||
file(GLOB_RECURSE SOURCES "src/types/*.cpp" "src/platform/linux/*.cpp" "src/platform/shared/*.cpp" "src/logger/*.cpp" "src/rewindow/*.cpp" )
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
file(GLOB_RECURSE SOURCES "src/types/*.cpp" "src/platform/windows/*.cpp" "src/platform/shared/*.cpp" "src/logger/*.cpp")
|
||||
file(GLOB_RECURSE SOURCES "src/types/*.cpp" "src/platform/windows/*.cpp" "src/platform/shared/*.cpp" "src/logger/*.cpp" "src/rewindow/*.cpp")
|
||||
endif()
|
||||
|
||||
include_directories("include")
|
||||
|
10
include/rewindow/clipboardservice.hpp
Normal file
10
include/rewindow/clipboardservice.hpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
/// X11 Clipboard API looked unhinged. So fuck it, use this system for now.
|
||||
namespace ClipboardService
|
||||
{
|
||||
std::string GetClipboard(int historyIndex = 0);
|
||||
void SetClipboard(const std::string& str, bool overwrites_last = false);
|
||||
unsigned int GetClipboardHistorySize();
|
||||
unsigned int GetClipboardHistoryMax();
|
||||
}
|
23
include/rewindow/inputservice.hpp
Normal file
23
include/rewindow/inputservice.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <Event.h>
|
||||
#include <rewindow/types/WindowEvents.hpp>
|
||||
|
||||
namespace InputService {
|
||||
using namespace ReWindow;
|
||||
|
||||
inline Event<KeyboardEvent> OnKeyboardEvent;
|
||||
inline Event<KeyboardEvent> OnKeyEvent;
|
||||
inline Event<KeyDownEvent> OnKeyDown;
|
||||
inline Event<KeyUpEvent> OnKeyUp;
|
||||
inline Event<MouseMoveEvent> OnMouseEvent;
|
||||
inline Event<MouseButtonEvent> OnMouseButtonEvent;
|
||||
inline Event<MouseMoveEvent> OnMouseMove;
|
||||
inline Event<MouseButtonDownEvent> OnMouseDown;
|
||||
inline Event<MouseButtonUpEvent> OnMouseUp;
|
||||
inline Event<MouseWheelEvent> OnMouseWheel;
|
||||
bool IsKeyDown(const Key& key);
|
||||
bool IsMouseButtonDown(const MouseButton& button);
|
||||
Vector2 GetMousePosition();
|
||||
Vector2 GetWindowSize();
|
||||
};
|
@@ -4,7 +4,11 @@
|
||||
|
||||
namespace ReWindow::Logger {
|
||||
using namespace jlog;
|
||||
using Logger = GenericLogger;
|
||||
|
||||
extern GenericLogger Fatal;
|
||||
extern GenericLogger Debug;
|
||||
extern Logger Info;
|
||||
extern Logger Fatal;
|
||||
extern Logger Error;
|
||||
extern Logger Warning;
|
||||
extern Logger Debug;
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include <chrono>
|
||||
#include <rewindow/types/key.h>
|
||||
#include <rewindow/types/mousebutton.h>
|
||||
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
||||
|
||||
namespace ReWindow {
|
||||
|
||||
@@ -11,10 +12,9 @@ namespace ReWindow {
|
||||
using precision_timestamp = precision_clock::time_point;
|
||||
|
||||
class TimestampedEvent {
|
||||
private:
|
||||
|
||||
public:
|
||||
precision_timestamp Timestamp;
|
||||
explicit TimestampedEvent(precision_timestamp timestamp) : Timestamp(timestamp) {}
|
||||
TimestampedEvent() : Timestamp(precision_clock::now())
|
||||
{ }
|
||||
};
|
||||
@@ -24,15 +24,41 @@ namespace ReWindow {
|
||||
RWindowEvent() : TimestampedEvent() { }
|
||||
};
|
||||
|
||||
class KeyboardEvent : public RWindowEvent {
|
||||
class InputDeviceEvent : public RWindowEvent {
|
||||
public:
|
||||
InputDeviceEvent() : RWindowEvent() { }
|
||||
};
|
||||
|
||||
class KeyboardEvent : public InputDeviceEvent {
|
||||
public:
|
||||
Key key;
|
||||
KeyState state;
|
||||
KeyboardEvent(Key key, KeyState state) : RWindowEvent(), key(key), state(state) {}
|
||||
KeyboardEvent(const Key& key, KeyState state) : InputDeviceEvent(), key(key), state(state) {}
|
||||
};
|
||||
class MouseEvent : public RWindowEvent {};
|
||||
class MouseEvent : public InputDeviceEvent {};
|
||||
|
||||
class GamepadEvent : public RWindowEvent {};
|
||||
class GamepadEvent : public InputDeviceEvent {};
|
||||
|
||||
class MouseButtonEvent : public MouseEvent {
|
||||
public:
|
||||
MouseButton Button;
|
||||
bool Pressed; // TODO: replace with MouseButtonState enum
|
||||
MouseButtonEvent() = default;
|
||||
MouseButtonEvent(const MouseButton& button, bool pressed) : MouseEvent(), Button(button), Pressed(pressed) {}
|
||||
};
|
||||
|
||||
class MouseButtonDownEvent : public MouseButtonEvent {
|
||||
public:
|
||||
MouseButtonDownEvent() = default;
|
||||
explicit MouseButtonDownEvent(const MouseButton& button) : MouseButtonEvent(button, true) {}
|
||||
};
|
||||
|
||||
class MouseButtonUpEvent : public MouseButtonEvent {
|
||||
public:
|
||||
|
||||
MouseButtonUpEvent() = default;
|
||||
explicit MouseButtonUpEvent(const MouseButton& button) : MouseButtonEvent(button, false) {}
|
||||
};
|
||||
|
||||
class MouseMoveEvent : public MouseEvent {
|
||||
public:
|
||||
@@ -46,12 +72,12 @@ namespace ReWindow {
|
||||
|
||||
class KeyDownEvent : public KeyboardEvent {
|
||||
public:
|
||||
KeyDownEvent(Key key) : KeyboardEvent(key, KeyState::Pressed) {}
|
||||
explicit KeyDownEvent(const Key& key) : KeyboardEvent(key, KeyState::Pressed) {}
|
||||
};
|
||||
|
||||
class KeyUpEvent : public KeyboardEvent {
|
||||
public:
|
||||
KeyUpEvent(Key key) : KeyboardEvent(key, KeyState::Released) {}
|
||||
explicit KeyUpEvent(const Key& key) : KeyboardEvent(key, KeyState::Released) {}
|
||||
};
|
||||
|
||||
class MouseWheelEvent : public MouseEvent
|
||||
@@ -62,22 +88,9 @@ namespace ReWindow {
|
||||
MouseWheelEvent(int wheel) : MouseEvent(), WheelMovement(wheel) {}
|
||||
};
|
||||
|
||||
class MouseButtonDownEvent : public MouseEvent {
|
||||
public:
|
||||
MouseButton Button;
|
||||
|
||||
MouseButtonDownEvent() = default;
|
||||
MouseButtonDownEvent(MouseButton button) : MouseEvent(), Button(button) {}
|
||||
};
|
||||
|
||||
class MouseButtonUpEvent : public MouseEvent {
|
||||
public:
|
||||
MouseButton Button;
|
||||
MouseButtonUpEvent() = default;
|
||||
MouseButtonUpEvent(MouseButton button) : MouseEvent(), Button(button) {}
|
||||
};
|
||||
|
||||
class WindowResizeRequestEvent : public RWindowEvent
|
||||
class WindowResizeRequestEvent : public MouseButtonEvent
|
||||
{
|
||||
public:
|
||||
Vector2 Size;
|
||||
|
@@ -10,17 +10,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ReWindow
|
||||
{
|
||||
namespace ReWindow {
|
||||
class Gamepad;
|
||||
class Xbox360Gamepad;
|
||||
class XboxOneGamepad;
|
||||
class PS4Gamepad;
|
||||
class Ultimate8BitDoPro2Gamepad;
|
||||
}
|
||||
|
||||
class InputDevice {}; // TODO: Remember to break InputDevice into it's own file and not define it twice!!!
|
||||
class ReWindow::Gamepad {
|
||||
public:
|
||||
virtual ~Gamepad() = default;
|
||||
};
|
||||
|
||||
class Gamepad : public InputDevice
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
|
||||
class XboxGamepad : public Gamepad {};
|
||||
class PS4Gamepad : public Gamepad {};
|
||||
}
|
||||
class ReWindow::XboxOneGamepad : public Gamepad {};
|
||||
class ReWindow::PS4Gamepad : public Gamepad {};
|
@@ -9,67 +9,101 @@
|
||||
/// @edit 2024-07-29
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <J3ML/LinearAlgebra.hpp>
|
||||
namespace ReWindow {
|
||||
class GamepadButton;
|
||||
class GamepadTrigger;
|
||||
class GamepadThumbstick;
|
||||
}
|
||||
|
||||
class GamepadButton {
|
||||
class ReWindow::GamepadButton {
|
||||
protected:
|
||||
std::string mnemonic_btn_code;
|
||||
public:
|
||||
explicit GamepadButton(const std::string& mnemonic) : mnemonic_btn_code(mnemonic) { }
|
||||
[[nodiscard]] std::string GetMnemonicButtonCode() const { return mnemonic_btn_code; }
|
||||
explicit GamepadButton(std::string mnemonic) : mnemonic_btn_code(std::move(mnemonic)){}
|
||||
[[nodiscard]] std::string GetMnemonicButtonCode() const;
|
||||
|
||||
/// Compares two GamepadButtons by their mnemonic button codes, not their activation state.
|
||||
bool operator ==(const GamepadButton& rhs) const;
|
||||
};
|
||||
|
||||
class GamepadTrigger {
|
||||
class ReWindow::GamepadTrigger {
|
||||
protected:
|
||||
std::string mnemonic_trigger_code;
|
||||
/// A float value between 0 and 1 representing how much the trigger has been pushed in by.
|
||||
float position = 0.0f;
|
||||
|
||||
/// The minimum possible movement of the trigger from the at-rest position.
|
||||
/// Movements less than this won't count.
|
||||
float dead_zone = 0.0f;
|
||||
public:
|
||||
|
||||
/// Returns a float value between 0-1 representing how much the trigger has been pushed in by.
|
||||
/// (0 being unpressed, 1 being fully pressed)
|
||||
float GetActuation() const;
|
||||
|
||||
/// TODO: Might be more appropriate in the Gamepad class representation.
|
||||
void SetActuationThreshold(float minimum = 0.01f) const;
|
||||
void SetDeadzone(float minimum = 0.01f);
|
||||
[[nodiscard]] float GetActuation() const;
|
||||
public:
|
||||
explicit GamepadTrigger(std::string mnemonic) : mnemonic_trigger_code(std::move(mnemonic)){}
|
||||
};
|
||||
|
||||
class GamepadThumbstick
|
||||
{
|
||||
class ReWindow::GamepadThumbstick {
|
||||
protected:
|
||||
std::string mnemonic_stick_code;
|
||||
// X -1 is all the way left, X +1 is all the way right.
|
||||
// Y -1 is all the way down, Y +1 is all the way up.
|
||||
Vector2 position = {0.0f, 0.0f};
|
||||
|
||||
// The minimum possible movement from the center in any direction.
|
||||
float dead_zone = 0.0f;
|
||||
public:
|
||||
/// Returns a Vector2 value representing the x,y coordinates of the joystick, with 0,0 being the center (at rest).
|
||||
/// This vector ranges from length = 0 to length = 1 (i.e. the unit circle).
|
||||
[[nodiscard]] Vector2 GetPosition() const;
|
||||
|
||||
|
||||
/// Sets the deadzone range of the thumbstick.
|
||||
/// Deadzone controls how far the stick must be moved before any movement is actually reported.
|
||||
/// This is because the thumbstick at-rest will often still report movement.
|
||||
/// If gamecode is architected to use the thumbstick position as a direction, without factoring in magnitude, this would cause problems.
|
||||
void SetDeadzone(float minimum = 0.01f) const;
|
||||
void SetDeadzone(float minimum = 0.01f);
|
||||
public:
|
||||
explicit GamepadThumbstick(std::string mnemonic) : mnemonic_stick_code(std::move(mnemonic)){}
|
||||
};
|
||||
|
||||
|
||||
|
||||
using J3ML::LinearAlgebra::Vector2;
|
||||
|
||||
namespace GamepadButtons {
|
||||
static const GamepadButton X {"X"};
|
||||
static const GamepadButton Y {"Y"};
|
||||
static const GamepadButton A {"A"};
|
||||
static const GamepadButton B {"B"};
|
||||
namespace ReWindow::GamepadButtons {
|
||||
static const GamepadButton Triangle("△");
|
||||
static const GamepadButton Square("□");
|
||||
static const GamepadButton Circle("○");
|
||||
static const GamepadButton Cross("X");
|
||||
|
||||
static const auto Triangle = Y;
|
||||
static const auto Square = X;
|
||||
static const auto Circle = A;
|
||||
static const auto Cross = B;
|
||||
// If you like xbox :shrug:
|
||||
static const GamepadButton Y = Triangle;
|
||||
static const GamepadButton X = Square;
|
||||
static const GamepadButton A = Cross;
|
||||
static const GamepadButton B = Circle;
|
||||
|
||||
static const GamepadButton LButton("LB");
|
||||
static const GamepadButton RButton("RB");
|
||||
|
||||
static const GamepadButton LeftBumper {"LB"};
|
||||
static const GamepadButton RightBumper {"RB"};
|
||||
/* For controllers where L2 & R2 is a button or counts as one when pressed all the way down.
|
||||
* Gamecube & PS2 controllers do this. - Redacted. */
|
||||
static const GamepadButton LButton2("LB2");
|
||||
static const GamepadButton RButton2("RB2");
|
||||
|
||||
// The buttons when you press in the sticks.
|
||||
static const GamepadButton LButton3("LB3");
|
||||
static const GamepadButton RButton3("RB3");
|
||||
|
||||
// Will eventually need to handle making it not possible to, for ex. Press left and right at the same time.
|
||||
static const GamepadButton DPadUp("DPU");
|
||||
static const GamepadButton DPadDown("DPD");
|
||||
static const GamepadButton DPadLeft("DPL");
|
||||
static const GamepadButton DPadRight("DPR");
|
||||
|
||||
static const GamepadButton Select("SEL");
|
||||
static const GamepadButton Start("START");
|
||||
}
|
||||
|
||||
namespace GamepadTriggers
|
||||
{
|
||||
static const GamepadTrigger Left;
|
||||
static const GamepadTrigger Right;
|
||||
namespace ReWindow::GamepadTriggers {
|
||||
static const ReWindow::GamepadTrigger Left {"LT"};
|
||||
static const ReWindow::GamepadTrigger Right {"RT"};
|
||||
}
|
||||
|
||||
namespace ReWindow::GamepadThumbsticks {
|
||||
static const GamepadThumbstick Left {"LS"};
|
||||
static const GamepadThumbstick Right {"RS"};
|
||||
}
|
@@ -8,7 +8,6 @@
|
||||
#include <string>
|
||||
#include <rewindow/data/X11Scancodes.h>
|
||||
#include <rewindow/data/WindowsScancodes.h>
|
||||
#include <J3ML/LinearAlgebra.hpp>
|
||||
|
||||
|
||||
class Key
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include <rewindow/types/gamepadbutton.h>
|
||||
#include <J3ML/LinearAlgebra.hpp>
|
||||
#include <rewindow/types/WindowEvents.hpp>
|
||||
#include <format>
|
||||
#include <queue>
|
||||
|
||||
|
||||
enum class RWindowFlags: uint8_t {
|
||||
@@ -99,17 +99,54 @@ namespace ReWindow
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Refactor RenderingAPI into a polymorphic class interface for greater reusability.
|
||||
class IRenderer {
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual void SwapBuffers();
|
||||
virtual std::string GetDriverVendor();
|
||||
virtual void SetVsync(bool enabled);
|
||||
virtual void SetViewportSize(int width, int height);
|
||||
virtual void MakeCurrent();
|
||||
};
|
||||
|
||||
class VulkanRenderBase : public IRenderer {};
|
||||
class GLRenderBase : public IRenderer {};
|
||||
class GLXRenderer : public GLRenderBase {};
|
||||
class WGLRenderer : public GLRenderBase {};
|
||||
|
||||
|
||||
|
||||
/// RWindow is a class implementation of a platform-independent window abstraction.
|
||||
/// This library also provides abstractions for user-input devices, and their interaction with the window.
|
||||
class RWindow {
|
||||
public:
|
||||
#pragma region Constructors
|
||||
/// The default constructor sets a default size and window title.
|
||||
RWindow();
|
||||
/// Constructs a window by explicitly setting title, width and height.
|
||||
RWindow(const std::string& title, int width, int height);
|
||||
/// The default constructor does not set any members, and are left uninitialized.
|
||||
RWindow() = default;
|
||||
/// Constructs a window by explicitly setting the title, width, height, and optionally; rendering API, fullscreen, resizable, and vsync.
|
||||
/// @param wTitle The window title text.
|
||||
/// @param wWidth
|
||||
/// @param wHeight
|
||||
/// @param wRenderer
|
||||
/// @param wFullscreen
|
||||
/// @param wResizable
|
||||
/// @param wVsync
|
||||
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);
|
||||
/// Constructs a window as above with the additional argument of explicitly setting which render API is to be used.
|
||||
RWindow(const std::string& title, int width, int height, RenderingAPI renderer);
|
||||
|
||||
/// The destructor deallocates and cleans up any memory used by the RWindow program.
|
||||
/// @note If the window handle is not already destroyed, it will be done here.
|
||||
~RWindow();
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Static Accessors
|
||||
static RWindow* GetExtant();
|
||||
#pragma endregion
|
||||
|
||||
/// Bindables are provided for hooking into window instances conveniently, without the need to derive and override for simple use cases.
|
||||
@@ -168,9 +205,20 @@ namespace ReWindow
|
||||
/// Calling this function, therefore, creates the real 'window' object on the operating system.
|
||||
void Open();
|
||||
|
||||
/// Cleans up and closes the window without destroying the handle.
|
||||
/// Tells the window that we want to close, without directly forcing it to. This gives us time to finalize any work we are performing.
|
||||
|
||||
[[nodiscard]] bool IsOpen() const { return open;}
|
||||
[[nodiscard]] bool IsClosing() const { return closing;}
|
||||
|
||||
|
||||
/// Cleans up and closes the window object.
|
||||
void Close();
|
||||
|
||||
/// Closes the window immediately, potentially without allowing finalization to occur.
|
||||
void ForceClose();
|
||||
|
||||
void ForceCloseAndTerminateProgram();
|
||||
|
||||
void CloseAndReopenInPlace();
|
||||
|
||||
void MessageBox(); // TODO: Must be implemented from scratch as a Motif Window in x11
|
||||
@@ -237,7 +285,7 @@ namespace ReWindow
|
||||
|
||||
/// Tells the underlying window manager to destroy this window and drop the handle.
|
||||
/// The window, in theory, can not be re-opened after this.
|
||||
void DestroyWindow();
|
||||
void DestroyOSWindowHandle();
|
||||
|
||||
/// Reads events from the operating system, and processes them accordingly.
|
||||
/// TODO: Move out of public API, consumers should call Refresh or ideally an update() call.
|
||||
@@ -321,6 +369,12 @@ namespace ReWindow
|
||||
/// Returns the number of frames ran since the windows' creation.
|
||||
[[nodiscard]] float GetRefreshCounter() const;
|
||||
protected:
|
||||
|
||||
void LogEvent(const RWindowEvent& e) { eventLog.push_back(e);}
|
||||
//void EnqueueEvent(const RWindowEvent& e) { eventQueue.push(e);}
|
||||
RWindowEvent GetLastEvent() const {
|
||||
return eventLog.back();
|
||||
}
|
||||
/// Requests the operating system to make the window fullscreen. Saves the previous window size as well.
|
||||
void Fullscreen();
|
||||
|
||||
@@ -329,47 +383,44 @@ namespace ReWindow
|
||||
|
||||
protected:
|
||||
#pragma region Data
|
||||
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";
|
||||
int width = 1280;
|
||||
int height = 720;
|
||||
|
||||
bool fullscreen_mode = false;
|
||||
bool focused = true;
|
||||
bool vsync = false;
|
||||
bool cursor_visible = true;
|
||||
bool open = false;
|
||||
bool resizable = true;
|
||||
|
||||
|
||||
Vector2 lastKnownWindowSize {0, 0};
|
||||
bool flags[5];
|
||||
std::vector<RWindowEvent> eventLog;
|
||||
|
||||
KeyboardState currentKeyboard; // Current Frame's Keyboard State
|
||||
KeyboardState previousKeyboard; // Previous Frame's Keyboard State
|
||||
MouseState currentMouse;
|
||||
MouseState previousMouse;
|
||||
|
||||
|
||||
std::vector<RWindowEvent> eventLog; // history of all logged window events.
|
||||
std::queue<RWindowEvent> eventQueue; //
|
||||
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;
|
||||
|
||||
//Vector2 mouse_coords = {0, 0};
|
||||
//Vector2 last_mouse_coords = {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 delta_time = 0.f;
|
||||
float refresh_rate = 0.f;
|
||||
unsigned int refresh_count = 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;
|
||||
float avg_refresh_rate = 0.0f;
|
||||
#pragma endregion
|
||||
#pragma region Internals
|
||||
/// Returns the most accurate and recent available mouse coordinates.
|
||||
|
66
main.cpp
66
main.cpp
@@ -1,8 +1,11 @@
|
||||
#include <iostream>
|
||||
#include <rewindow/types/window.h>
|
||||
#include <rewindow/types/display.h>
|
||||
#include <rewindow/logger/logger.h>
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Windows :/
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
@@ -26,7 +29,7 @@ class MyWindow : public ReWindow::RWindow {
|
||||
void OnKeyDown(const ReWindow::KeyDownEvent& e) override {}
|
||||
|
||||
void OnRefresh(float elapsed) override {
|
||||
glClearColor(255, 0, 0, 255);
|
||||
glClearColor(1, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
GLSwapBuffers();
|
||||
auto pos = GetMouseCoordinates();
|
||||
@@ -47,54 +50,40 @@ class MyWindow : public ReWindow::RWindow {
|
||||
if (IsMouseButtonDown(MouseButtons::Middle))
|
||||
std::cout << "Middle Mouse Button" << std::endl;
|
||||
|
||||
|
||||
if (IsMouseButtonDown(MouseButtons::Mouse4))
|
||||
std::cout << "Mouse4 Mouse Button" << std::endl;
|
||||
|
||||
if (IsMouseButtonDown(MouseButtons::Mouse5))
|
||||
std::cout << "Mouse5 Mouse Button" << std::endl;
|
||||
|
||||
|
||||
if (IsKeyDown(Keys::N))
|
||||
std::cout << "Gotteem" << std::endl;
|
||||
|
||||
RWindow::OnRefresh(elapsed);
|
||||
}
|
||||
|
||||
bool OnResizeRequest(const ReWindow::WindowResizeRequestEvent& e) override {
|
||||
std::cout << "resized to " << e.Size.x << ", " << e.Size.y << std::endl;
|
||||
//std::cout << "resized to " << e.Size.x << ", " << e.Size.y << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnMouseButtonDown(const ReWindow::MouseButtonDownEvent &e) override
|
||||
{
|
||||
std::cout << "Overload Down: " << e.Button.Mnemonic << std::endl;
|
||||
//std::cout << "Overload Down: " << e.Button.Mnemonic << std::endl;
|
||||
RWindow::OnMouseButtonDown(e);
|
||||
}
|
||||
|
||||
void OnMouseButtonUp(const ReWindow::MouseButtonUpEvent &e) override
|
||||
{
|
||||
std::cout << "Overload Up: " << e.Button.Mnemonic << std::endl;
|
||||
//std::cout << "Overload Up: " << e.Button.Mnemonic << std::endl;
|
||||
RWindow::OnMouseButtonUp(e);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
auto* window = new MyWindow("Test Window", 600, 480);
|
||||
jlog::Debug(std::format("New window '{}' created. width={} height={}", window->GetTitle(), window->GetWidth(),
|
||||
window->GetHeight()));
|
||||
|
||||
window->SetRenderer(RenderingAPI::OPENGL);
|
||||
jlog::Debug(std::format("Rendering API OPENGL set for window '{}'", window->GetTitle()));
|
||||
|
||||
window->Open();
|
||||
jlog::Debug(std::format("Opened window '{}'", window->GetTitle()));
|
||||
|
||||
// TODO: Cannot set flags until after window is open
|
||||
// Make this work somehow
|
||||
jlog::Debug("TODO: Cannot set flags until after window is open");
|
||||
window->SetFullscreen(false);
|
||||
window->SetVsyncEnabled(true);
|
||||
window->SetResizable(true);
|
||||
window->SetCursorVisible(false);
|
||||
|
||||
/*
|
||||
/*
|
||||
std::vector<ReWindow::Display> d = ReWindow::Display::getDisplaysFromWindowManager();
|
||||
for (ReWindow::Display& display : d) {
|
||||
|
||||
@@ -119,6 +108,26 @@ int main() {
|
||||
}
|
||||
*/
|
||||
|
||||
auto* window = new MyWindow("Test Window", 600, 480);
|
||||
jlog::Debug(std::format("New window '{}' created. width={} height={}", window->GetTitle(), window->GetWidth(),
|
||||
window->GetHeight()));
|
||||
|
||||
window->SetRenderer(RenderingAPI::OPENGL);
|
||||
jlog::Debug(std::format("Rendering API OPENGL set for window '{}'", window->GetTitle()));
|
||||
|
||||
window->Open();
|
||||
jlog::Debug(std::format("Opened window '{}'", window->GetTitle()));
|
||||
|
||||
// TODO: Cannot set flags until after window is open
|
||||
// Make this work somehow
|
||||
jlog::Debug("TODO: Cannot set flags until after window is open");
|
||||
window->SetFullscreen(false);
|
||||
window->SetVsyncEnabled(true);
|
||||
window->SetResizable(true);
|
||||
window->SetCursorVisible(false);
|
||||
|
||||
|
||||
|
||||
ReWindow::Logger::Debug(std::format("Window '{}' flags: IN_FOCUS={} FULLSCREEN={} RESIZEABLE={} VSYNC={} QUIT={}",
|
||||
window->GetTitle(),
|
||||
window->GetFlag(RWindowFlags::IN_FOCUS),
|
||||
@@ -142,10 +151,12 @@ int main() {
|
||||
std::cout << window->GetMouseWheelPersistent() << std::endl;
|
||||
};
|
||||
|
||||
while (window->IsAlive()) {
|
||||
window->PollEvents();
|
||||
while (!window->IsClosing()) {
|
||||
//window->PollEvents();
|
||||
window->ManagedRefresh();
|
||||
}
|
||||
|
||||
delete window;
|
||||
// Alternatively:
|
||||
/*
|
||||
* while (window->IsAlive()) {
|
||||
@@ -160,6 +171,9 @@ int main() {
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
//exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -2,6 +2,10 @@
|
||||
|
||||
namespace ReWindow::Logger {
|
||||
using namespace jlog;
|
||||
GenericLogger Fatal {"ReWindow::fatal", GlobalLogFile, Colors::Reds::Crimson, Colors::Gray, Colors::Gray, Colors::Reds::Crimson, Colors::White};
|
||||
GenericLogger Debug {"ReWindow::debug", GlobalLogFile, Colors::Purples::Purple, Colors::Gray, Colors::Gray, Colors::Purples::Purple, Colors::White};
|
||||
using namespace Colors;
|
||||
using Logger = GenericLogger;
|
||||
|
||||
Logger Info {"ReWindow", GlobalLogFile, Gray, Gray, Gray, Gray};
|
||||
Logger Fatal {"ReWindow::fatal", GlobalLogFile, Reds::Crimson, Gray, Gray, Reds::Crimson, White};
|
||||
Logger Debug {"ReWindow::debug", GlobalLogFile, Purples::Purple, Gray, Gray, Purples::Purple, White};
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@ Cursor invisible_cursor = 0;
|
||||
Vector2 render_area_position = {0, 0};
|
||||
Vector2 position = {0, 0};
|
||||
bool should_poll_x_for_mouse_pos = true;
|
||||
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
||||
|
||||
|
||||
using namespace ReWindow;
|
||||
@@ -54,12 +55,15 @@ void RWindow::Lower() const
|
||||
XLowerWindow(display, window);
|
||||
}
|
||||
|
||||
void RWindow::DestroyWindow() {
|
||||
void RWindow::DestroyOSWindowHandle() {
|
||||
Logger::Debug(std::format("Destroying window '{}'", this->title));
|
||||
XDestroySubwindows(display, window);
|
||||
Logger::Debug(std::format("Destroyed window '{}'", this->title));
|
||||
XDestroyWindow(display, window);
|
||||
delete this;
|
||||
|
||||
system("xset r on"); // Re-set X-server parameter to enable key-repeat.
|
||||
|
||||
open = false;
|
||||
}
|
||||
|
||||
//void RWindow::
|
||||
@@ -116,18 +120,14 @@ void RWindow::PollEvents() {
|
||||
XNextEvent(display, &xev);
|
||||
|
||||
if (xev.type == ClientMessage)
|
||||
Logger::Debug(std::format("Recieved event '{}'", "ClientMessage"));
|
||||
Logger::Info(std::format("Event '{}'", "ClientMessage"));
|
||||
|
||||
if (xev.xclient.message_type == XInternAtom(display, "WM_PROTOCOLS", False) && static_cast<Atom>(xev.xclient.data.l[0]) == wmDeleteWindow) {
|
||||
|
||||
processOnClose();
|
||||
DestroyWindow();
|
||||
system("xset r on");
|
||||
exit(0);
|
||||
Close();
|
||||
}
|
||||
|
||||
if (xev.type == FocusIn) {
|
||||
Logger::Debug(std::format("Recieved event '{}'", "FocusIn"));
|
||||
Logger::Debug(std::format("Event'{}'", "FocusIn"));
|
||||
XAutoRepeatOff(display);
|
||||
SetFlag(RWindowFlags::IN_FOCUS, true);
|
||||
|
||||
@@ -141,7 +141,7 @@ void RWindow::PollEvents() {
|
||||
}
|
||||
|
||||
if (xev.type == FocusOut) {
|
||||
Logger::Debug(std::format("Recieved event '{}'", "FocusOut"));
|
||||
Logger::Debug(std::format("Event '{}'", "FocusOut"));
|
||||
XAutoRepeatOn(display);
|
||||
|
||||
SetFlag(RWindowFlags::IN_FOCUS, false);
|
||||
@@ -152,14 +152,14 @@ void RWindow::PollEvents() {
|
||||
}
|
||||
|
||||
if (xev.type == KeyRelease) {
|
||||
Logger::Debug(std::format("Recieved event '{}'", "KeyRelease"));
|
||||
Logger::Debug(std::format("Event '{}'", "KeyRelease"));
|
||||
auto scancode = (X11Scancode) xev.xkey.keycode;
|
||||
auto key = GetKeyFromX11Scancode(scancode);
|
||||
processKeyRelease(key);
|
||||
}
|
||||
|
||||
if (xev.type == KeyPress) {
|
||||
Logger::Debug(std::format("Recieved event '{}'", "KeyPress"));
|
||||
Logger::Debug(std::format("Event '{}'", "KeyPress"));
|
||||
auto scancode = (X11Scancode) xev.xkey.keycode;
|
||||
auto key = GetKeyFromX11Scancode(scancode);
|
||||
processKeyPress(key);
|
||||
@@ -172,7 +172,7 @@ void RWindow::PollEvents() {
|
||||
// and only call on ButtonPress, otherwise it will appear to duplicate the mouse wheel scroll.
|
||||
if (xev.xbutton.button != 4 && xev.xbutton.button != 5) {
|
||||
MouseButton button = GetMouseButtonFromXButton(xev.xbutton.button);
|
||||
Logger::Debug(std::format("Recieved event '{}'", "ButtonRelease"));
|
||||
Logger::Debug(std::format("Event '{}'", "ButtonRelease"));
|
||||
processMouseRelease(button);
|
||||
}
|
||||
}
|
||||
@@ -190,7 +190,7 @@ void RWindow::PollEvents() {
|
||||
{
|
||||
MouseButton button = GetMouseButtonFromXButton(xev.xbutton.button);
|
||||
|
||||
Logger::Debug(std::format("Window event: MouseButtonPress {}", button.Mnemonic));
|
||||
Logger::Debug(std::format("Event: MouseButtonPress {}", button.Mnemonic));
|
||||
|
||||
processMousePress(button);
|
||||
}
|
||||
@@ -198,18 +198,18 @@ void RWindow::PollEvents() {
|
||||
|
||||
if (xev.type == Expose)
|
||||
{
|
||||
Logger::Debug(std::format("Recieved event '{}'", "Expose"));
|
||||
Logger::Debug(std::format("Event '{}'", "Expose"));
|
||||
}
|
||||
|
||||
// NOTE: This event is functionally useless, as it only informs of the very beginning and end of a mouse movement.
|
||||
if (xev.type == MotionNotify)
|
||||
{
|
||||
Logger::Debug(std::format("Recieved event '{}'", "MotionNotify"));
|
||||
Logger::Debug(std::format("Event '{}'", "MotionNotify"));
|
||||
}
|
||||
|
||||
if (xev.type == ConfigureNotify) {
|
||||
if (this->width != xev.xconfigurerequest.width || this->height != xev.xconfigurerequest.height) {
|
||||
Logger::Debug(std::format("Recieved event '{}'", "ResizeRequest"));
|
||||
Logger::Debug(std::format("Event '{}'", "ResizeRequest"));
|
||||
|
||||
this->width = xev.xconfigurerequest.width;
|
||||
this->height = xev.xconfigurerequest.height;
|
||||
@@ -241,7 +241,7 @@ void RWindow::SetSize(int newWidth, int newHeight) {
|
||||
this->height = newHeight;
|
||||
XResizeWindow(display, window, newWidth, newHeight);
|
||||
XFlush(display);
|
||||
Logger::Debug(std::format("Set size for window '{}'. width={} height={}", this->title, newWidth, newHeight));
|
||||
Logger::Info(std::format("Set size for '{}' to {} x {}", this->title, newWidth, newHeight));
|
||||
}
|
||||
|
||||
Vector2 RWindow::GetAccurateMouseCoordinates() const {
|
||||
@@ -293,9 +293,8 @@ void RWindow::GLSwapBuffers() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RWindow::Fullscreen() {
|
||||
Logger::Debug(std::format("Fullscreening window '{}'", this->title));
|
||||
Logger::Info(std::format("Fullscreening '{}'", this->title));
|
||||
fullscreen_mode = true;
|
||||
|
||||
XEvent xev;
|
||||
@@ -312,11 +311,11 @@ void RWindow::Fullscreen() {
|
||||
xev.xclient.data.l[1] = fullscreen_mode;
|
||||
xev.xclient.data.l[2] = 0;
|
||||
XSendEvent(display, DefaultRootWindow(display), False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
|
||||
Logger::Debug(std::format("Fullscreened window '{}'", this->title));
|
||||
Logger::Debug(std::format("Fullscreened '{}'", this->title));
|
||||
}
|
||||
|
||||
void RWindow::RestoreFromFullscreen() {
|
||||
Logger::Debug(std::format("Restoring window '{}' from Fullscreen", this->title));
|
||||
Logger::Debug(std::format("Restoring '{}' from Fullscreen", this->title));
|
||||
fullscreen_mode = false;
|
||||
XEvent xev;
|
||||
Atom wm_state = XInternAtom(display, "_NET_WM_STATE", False);
|
||||
@@ -330,7 +329,7 @@ void RWindow::RestoreFromFullscreen() {
|
||||
xev.xclient.data.l[1] = fullscreen_mode;
|
||||
xev.xclient.data.l[2] = 0;
|
||||
XSendEvent(display, DefaultRootWindow(display), False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
|
||||
Logger::Debug(std::format("Restored window '{}' from Fullscreen", this->title));
|
||||
Logger::Debug(std::format("Restored '{}' from Fullscreen", this->title));
|
||||
}
|
||||
|
||||
void RWindow::SetVsyncEnabled(bool b) {
|
||||
@@ -351,43 +350,78 @@ void RWindow::Open() {
|
||||
xSetWindowAttributes.background_pixel = BlackPixel(display, defaultScreen);
|
||||
xSetWindowAttributes.override_redirect = True;
|
||||
xSetWindowAttributes.event_mask = ExposureMask;
|
||||
//SetVsyncEnabled(vsync);
|
||||
|
||||
if (renderer == RenderingAPI::OPENGL) {
|
||||
GLint glAttributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None};
|
||||
visual = glXChooseVisual(display, defaultScreen, glAttributes);
|
||||
glContext = glXCreateContext(display, visual, nullptr, GL_TRUE);
|
||||
auto glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB");
|
||||
XVisualInfo* vi = nullptr;
|
||||
|
||||
// Fallback to the old way if you somehow don't have this.
|
||||
if (!glXCreateContextAttribsARB) {
|
||||
GLint glAttributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None};
|
||||
visual = glXChooseVisual(display, defaultScreen, glAttributes);
|
||||
glContext = glXCreateContext(display, visual, nullptr, GL_TRUE);
|
||||
window = XCreateWindow(display, RootWindow(display, defaultScreen), 0, 0, width, height, 0, visual->depth,
|
||||
InputOutput, visual->visual, CWBackPixel | CWColormap | CWBorderPixel | NoEventMask, &xSetWindowAttributes);
|
||||
|
||||
ReWindow::Logger::Debug("Created OpenGL Context with glXCreateContext.");
|
||||
}
|
||||
else {
|
||||
static int visual_attributes[]
|
||||
{
|
||||
GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
|
||||
GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8,
|
||||
GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8,
|
||||
GLX_DOUBLEBUFFER, True, None
|
||||
};
|
||||
|
||||
int fb_count;
|
||||
GLXFBConfig *fb_configurations = glXChooseFBConfig(display, defaultScreen, visual_attributes, &fb_count);
|
||||
if (!fb_configurations || fb_count == 0)
|
||||
throw std::runtime_error("Couldn't get framebuffer configuration.");
|
||||
|
||||
GLXFBConfig best_fbc = fb_configurations[0];
|
||||
vi = glXGetVisualFromFBConfig(display, best_fbc);
|
||||
|
||||
if (!vi)
|
||||
throw std::runtime_error("Couldn't visual info from framebuffer configuration.");
|
||||
|
||||
xSetWindowAttributes.colormap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone);
|
||||
window = XCreateWindow(display, RootWindow(display, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput,
|
||||
vi->visual, CWBackPixel | CWColormap | CWBorderPixel, &xSetWindowAttributes);
|
||||
|
||||
// TODO allow the user to specify what OpenGL version they want.
|
||||
int context_attributes[] { GLX_CONTEXT_MAJOR_VERSION_ARB, 2, GLX_CONTEXT_MINOR_VERSION_ARB, 1, None };
|
||||
glContext = glXCreateContextAttribsARB(display, best_fbc, nullptr, True, context_attributes);
|
||||
XFree(fb_configurations);
|
||||
}
|
||||
|
||||
if (!glContext)
|
||||
throw std::runtime_error("Couldn't create the OpenGL context.");
|
||||
if (!glXMakeCurrent(display, window, glContext))
|
||||
throw std::runtime_error("Couldn't change OpenGL context to current.");
|
||||
if (vi)
|
||||
XFree(vi);
|
||||
|
||||
ReWindow::Logger::Debug("Created OpenGL Context with glXCreateContextAttribsARB");
|
||||
}
|
||||
|
||||
xSetWindowAttributes.colormap = XCreateColormap(display, RootWindow(display, defaultScreen), visual->visual, AllocNone);
|
||||
|
||||
window = XCreateWindow(display, RootWindow(display, defaultScreen), 0, 0, width, height, 0, visual->depth,
|
||||
InputOutput, visual->visual, CWBackPixel | CWColormap | CWBorderPixel | NoEventMask,
|
||||
&xSetWindowAttributes);
|
||||
// Set window to floating because fucking tiling WMs
|
||||
windowTypeAtom = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
|
||||
windowTypeUtilityAtom = XInternAtom(display, "_NET_WM_WINDOW_TYPE_UTILITY", False);
|
||||
XChangeProperty(display, window, windowTypeAtom, XA_ATOM, 32, PropModeReplace,
|
||||
(unsigned char *)&windowTypeUtilityAtom, 1);
|
||||
//
|
||||
XSelectInput(display, window,
|
||||
ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask |
|
||||
PointerMotionHintMask | FocusChangeMask | StructureNotifyMask | SubstructureRedirectMask |
|
||||
SubstructureNotifyMask | CWColormap );
|
||||
XSelectInput(display, window, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
|
||||
PointerMotionHintMask | FocusChangeMask | StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask | CWColormap );
|
||||
XMapWindow(display, window);
|
||||
XStoreName(display, window, title.c_str());
|
||||
|
||||
windowTypeAtom = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
|
||||
windowTypeUtilityAtom = XInternAtom(display, "_NET_WM_WINDOW_TYPE_UTILITY", False);
|
||||
XChangeProperty(display, window, windowTypeAtom, XA_ATOM, 32, PropModeReplace, (unsigned char*)&windowTypeUtilityAtom, 1);
|
||||
|
||||
wmDeleteWindow = XInternAtom(display, "WM_DELETE_WINDOW", False);
|
||||
XSetWMProtocols(display, window, &wmDeleteWindow, 1);
|
||||
|
||||
if (renderer == RenderingAPI::OPENGL)
|
||||
glXMakeCurrent(display, window, glContext);
|
||||
|
||||
// Get the position of the renderable area relative to the rest of the window.
|
||||
XGetWindowAttributes(display, window, &windowAttributes);
|
||||
render_area_position = { (float) windowAttributes.x, (float) windowAttributes.y };
|
||||
render_area_position = {(float)windowAttributes.x, (float)windowAttributes.y};
|
||||
|
||||
open = true;
|
||||
|
||||
|
||||
processOnOpen();
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include <rewindow/types/window.h>
|
||||
#include <rewindow/inputservice.hpp>
|
||||
#include "rewindow/logger/logger.h"
|
||||
std::string RWindowFlagToStr(RWindowFlags flag) {
|
||||
switch (flag) {
|
||||
@@ -15,22 +16,21 @@ std::string RWindowFlagToStr(RWindowFlags flag) {
|
||||
|
||||
using namespace ReWindow;
|
||||
|
||||
RWindow::RWindow() {
|
||||
title = "ReWindow Application";
|
||||
width = 640;
|
||||
height = 480;
|
||||
//RWindow::singleton = this;
|
||||
|
||||
static RWindow* extant;
|
||||
|
||||
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} {
|
||||
extant = this;
|
||||
}
|
||||
|
||||
RWindow::RWindow(const std::string& title, int width, int height) : flags{false,false,false,false} {
|
||||
this->title = title;
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
//RWindow::singleton = this;
|
||||
RWindow::~RWindow() {
|
||||
if (open)
|
||||
DestroyOSWindowHandle();
|
||||
}
|
||||
|
||||
RWindow::RWindow(const std::string& title, int width, int height, RenderingAPI renderer) :
|
||||
title(title), width(width), height(height), renderer(renderer) {}
|
||||
|
||||
|
||||
Vector2 RWindow::GetMouseCoordinates() const {
|
||||
return currentMouse.Position;
|
||||
@@ -41,10 +41,9 @@ bool RWindow::GetFlag(RWindowFlags flag) const {
|
||||
}
|
||||
|
||||
bool RWindow::IsAlive() const {
|
||||
return true;
|
||||
return (!closing) && open;
|
||||
}
|
||||
|
||||
|
||||
void RWindow::SetFullscreen(bool fs) {
|
||||
if (fs)
|
||||
Fullscreen();
|
||||
@@ -52,11 +51,13 @@ void RWindow::SetFullscreen(bool fs) {
|
||||
RestoreFromFullscreen();
|
||||
}
|
||||
|
||||
#pragma region Event Processors Implementation
|
||||
void RWindow::processFocusIn()
|
||||
{
|
||||
RWindowEvent event {};
|
||||
OnFocusGain(event);
|
||||
OnFocusGainEvent(event);
|
||||
LogEvent(event);
|
||||
}
|
||||
|
||||
void RWindow::processFocusOut()
|
||||
@@ -64,31 +65,39 @@ void RWindow::processFocusOut()
|
||||
RWindowEvent event {};
|
||||
OnFocusLost(event);
|
||||
OnFocusLostEvent(event);
|
||||
LogEvent(event);
|
||||
}
|
||||
|
||||
void RWindow::processMousePress(const MouseButton& btn)
|
||||
{
|
||||
currentMouse.Set(btn, true);
|
||||
auto eventData = MouseButtonDownEvent(btn);
|
||||
OnMouseButtonDown(eventData);
|
||||
OnMouseButtonDownEvent(eventData);
|
||||
|
||||
auto event = MouseButtonDownEvent(btn);
|
||||
OnMouseButtonDown(event);
|
||||
OnMouseButtonDownEvent(event);
|
||||
InputService::OnMouseButtonEvent(MouseButtonEvent(btn, true));
|
||||
InputService::OnMouseDown(event);
|
||||
LogEvent(event);
|
||||
}
|
||||
|
||||
void RWindow::processMouseMove(Vector2 last_pos, Vector2 new_pos)
|
||||
{
|
||||
currentMouse.Position = new_pos;
|
||||
auto eventData = MouseMoveEvent(new_pos);
|
||||
OnMouseMove(eventData);
|
||||
OnMouseMoveEvent(eventData);
|
||||
auto event = MouseMoveEvent(new_pos);
|
||||
OnMouseMove(event);
|
||||
OnMouseMoveEvent(event);
|
||||
InputService::OnMouseMove(event);
|
||||
LogEvent(event);
|
||||
}
|
||||
|
||||
void RWindow::processMouseRelease(const MouseButton& btn)
|
||||
{
|
||||
currentMouse.Set(btn, false);
|
||||
auto eventData = MouseButtonUpEvent(btn);
|
||||
OnMouseButtonUp(eventData);
|
||||
OnMouseButtonUpEvent(eventData);
|
||||
auto event = MouseButtonUpEvent(btn);
|
||||
OnMouseButtonUp(event);
|
||||
OnMouseButtonUpEvent(event);
|
||||
InputService::OnMouseButtonEvent(MouseButtonEvent(btn, false));
|
||||
InputService::OnMouseUp(event);
|
||||
LogEvent(event);
|
||||
|
||||
}
|
||||
|
||||
@@ -96,9 +105,41 @@ void RWindow::processKeyRelease(Key key) {
|
||||
currentKeyboard.PressedKeys[key] = false;
|
||||
auto event = KeyUpEvent(key);
|
||||
OnKeyUp(event);
|
||||
OnKeyUpEvent(key);
|
||||
OnKeyUpEvent(event);
|
||||
InputService::OnKeyboardEvent(KeyboardEvent(key, KeyState::Released));
|
||||
InputService::OnKeyEvent(KeyboardEvent(key, KeyState::Released));
|
||||
InputService::OnKeyUp(event);
|
||||
LogEvent(event);
|
||||
}
|
||||
|
||||
void RWindow::processKeyPress(Key key) {
|
||||
currentKeyboard.PressedKeys[key] = true;
|
||||
auto event = KeyDownEvent(key);
|
||||
OnKeyDown(event);
|
||||
OnKeyDownEvent(event);
|
||||
InputService::OnKeyDown(event);
|
||||
InputService::OnKeyboardEvent(KeyboardEvent(key, KeyState::Pressed));
|
||||
InputService::OnKeyEvent(KeyboardEvent(key, KeyState::Pressed));
|
||||
LogEvent(event);
|
||||
}
|
||||
|
||||
void RWindow::processOnClose()
|
||||
{
|
||||
auto event = RWindowEvent();
|
||||
OnClosing();
|
||||
OnClosingEvent();
|
||||
LogEvent(event);
|
||||
}
|
||||
|
||||
void RWindow::processOnOpen()
|
||||
{
|
||||
auto event = RWindowEvent();
|
||||
OnOpen();
|
||||
OnOpenEvent();
|
||||
LogEvent(event);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
std::string RWindow::GetTitle() const {
|
||||
return this->title;
|
||||
@@ -141,10 +182,10 @@ void RWindow::SetSize(const Vector2& size) {
|
||||
}
|
||||
|
||||
bool RWindow::IsKeyDown(Key key) const {
|
||||
for (const auto& pair : currentKeyboard.PressedKeys)
|
||||
if (pair.first == key && pair.second)
|
||||
return true;
|
||||
return false;
|
||||
if (currentKeyboard.PressedKeys.contains(key))
|
||||
return currentKeyboard.PressedKeys.at(key);
|
||||
|
||||
return false; // NOTE: Key may not be mapped!!
|
||||
}
|
||||
|
||||
bool RWindow::IsMouseButtonDown(const MouseButton &button) const {
|
||||
@@ -152,24 +193,6 @@ bool RWindow::IsMouseButtonDown(const MouseButton &button) const {
|
||||
return currentMouse.IsDown(button);
|
||||
}
|
||||
|
||||
void RWindow::processKeyPress(Key key) {
|
||||
currentKeyboard.PressedKeys[key] = true;
|
||||
auto eventData = KeyDownEvent(key);
|
||||
OnKeyDown(eventData);
|
||||
OnKeyDownEvent(key);
|
||||
}
|
||||
|
||||
void RWindow::processOnClose()
|
||||
{
|
||||
OnClosing();
|
||||
OnClosingEvent();
|
||||
}
|
||||
|
||||
void RWindow::processOnOpen()
|
||||
{
|
||||
OnOpen();
|
||||
OnOpenEvent();
|
||||
}
|
||||
|
||||
void RWindow::ManagedRefresh()
|
||||
{
|
||||
@@ -194,7 +217,6 @@ void RWindow::Refresh() {
|
||||
processMouseMove(previousMouse.Position, currentMouse.Position);
|
||||
previousMouse.Position = currentMouse.Position;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float RWindow::ComputeElapsedFrameTimeSeconds(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end) {
|
||||
@@ -232,11 +254,6 @@ void RWindow::processMouseWheel(int scrolls)
|
||||
}
|
||||
|
||||
|
||||
void RWindow::Close() {
|
||||
/// TODO: Implement closing the window without destroying the handle.
|
||||
processOnClose();
|
||||
}
|
||||
|
||||
bool RWindow::IsResizable() const {
|
||||
return resizable;
|
||||
}
|
||||
@@ -259,3 +276,29 @@ bool RWindow::IsFocused() const {
|
||||
|
||||
float RWindow::GetRefreshCounter() const { return refresh_count; }
|
||||
|
||||
void RWindow::Close() {
|
||||
closing = true;
|
||||
processOnClose();
|
||||
}
|
||||
|
||||
void RWindow::ForceClose() {
|
||||
Close();
|
||||
DestroyOSWindowHandle();
|
||||
}
|
||||
|
||||
RWindow * RWindow::GetExtant() {
|
||||
return extant;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RWindow::ForceCloseAndTerminateProgram() {
|
||||
ForceClose();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -24,7 +24,8 @@ void RWindow::SetFlag(RWindowFlags flag, bool state) {
|
||||
SetWindowLong(hwnd, GWL_STYLE, style);
|
||||
SetWindowPos(hwnd, nullptr, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
}
|
||||
}wasd
|
||||
}
|
||||
|
||||
void RWindow::SetResizable(bool resizable) {
|
||||
SetFlag(RWindowFlags::RESIZABLE, resizable);;
|
||||
}
|
||||
@@ -300,3 +301,7 @@ void RWindow::GLSwapBuffers() {
|
||||
std::string RWindow::getGraphicsDriverVendor() {
|
||||
return std::string(reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
|
||||
}
|
||||
|
||||
void RWindow::DestroyOSWindowHandle() {
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
28
src/rewindow/clipboardservice.cpp
Normal file
28
src/rewindow/clipboardservice.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <rewindow/clipboardservice.hpp>
|
||||
|
||||
std::vector<std::string> clipboard_history;
|
||||
std::string clipboard;
|
||||
|
||||
|
||||
namespace ClipboardService {
|
||||
std::string GetClipboard(int historyIndex) {
|
||||
|
||||
if (historyIndex > 0) {
|
||||
return clipboard_history[historyIndex - 1];
|
||||
}
|
||||
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
void SetClipboard(const std::string& str, bool overwrites_last) {
|
||||
|
||||
if (!overwrites_last) {
|
||||
clipboard_history.push_back(clipboard);
|
||||
}
|
||||
|
||||
clipboard = str;
|
||||
}
|
||||
|
||||
}
|
17
src/rewindow/inputservice.cpp
Normal file
17
src/rewindow/inputservice.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <rewindow/inputservice.hpp>
|
||||
#include <rewindow/types/window.h>
|
||||
namespace InputService
|
||||
{
|
||||
bool IsKeyDown(const Key &key) {
|
||||
return RWindow::GetExtant()->IsKeyDown(key);
|
||||
}
|
||||
bool IsMouseButtonDown(const MouseButton &button) {
|
||||
return RWindow::GetExtant()->IsMouseButtonDown(button);
|
||||
}
|
||||
Vector2 GetMousePosition() {
|
||||
return RWindow::GetExtant()->GetMouseCoordinates();
|
||||
}
|
||||
Vector2 GetWindowSize() {
|
||||
return RWindow::GetExtant()->GetSize();
|
||||
}
|
||||
}
|
@@ -1,9 +1,25 @@
|
||||
#include <rewindow/types/gamepadbutton.h>
|
||||
|
||||
bool GamepadButton::operator==(const GamepadButton &rhs) const {
|
||||
bool ReWindow::GamepadButton::operator ==(const GamepadButton &rhs) const {
|
||||
return this->GetMnemonicButtonCode() == rhs.GetMnemonicButtonCode();
|
||||
}
|
||||
|
||||
void GamepadThumbstick::SetDeadzone(float minimum) const {
|
||||
|
||||
std::string ReWindow::GamepadButton::GetMnemonicButtonCode() const {
|
||||
return mnemonic_btn_code;
|
||||
}
|
||||
|
||||
void ReWindow::GamepadThumbstick::SetDeadzone(float minimum) {
|
||||
dead_zone = minimum;
|
||||
}
|
||||
|
||||
Vector2 ReWindow::GamepadThumbstick::GetPosition() const {
|
||||
return position;
|
||||
}
|
||||
|
||||
void ReWindow::GamepadTrigger::SetDeadzone(float minimum) {
|
||||
dead_zone = minimum;
|
||||
}
|
||||
|
||||
float ReWindow::GamepadTrigger::GetActuation() const {
|
||||
return position;
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#include <rewindow/types/mousebutton.h>
|
||||
#include <string>
|
||||
#include <X11/X.h>
|
||||
#include "rewindow/logger/logger.h"
|
||||
#include <rewindow/logger/logger.h>
|
||||
|
||||
|
||||
MouseButton::MouseButton(const std::string& charcode, unsigned int index) {
|
||||
|
Reference in New Issue
Block a user