mirror of
https://github.com/open-goal/jak-project
synced 2026-07-10 23:22:17 -04:00
a bunch of PC/GFX system fixes (#1465)
* rework fullscreen code a bit * Virtualization! * Fix resolution stuff not working properly! * yeah yeah whatever
This commit is contained in:
@@ -16,10 +16,6 @@
|
||||
|
||||
namespace {
|
||||
|
||||
bool renderer_is_correct(const GfxRendererModule* renderer, GfxPipeline pipeline) {
|
||||
return renderer->pipeline == pipeline;
|
||||
}
|
||||
|
||||
void set_main_display(std::shared_ptr<GfxDisplay> display) {
|
||||
if (Display::g_displays.size() > 0) {
|
||||
Display::g_displays[0] = display;
|
||||
@@ -36,66 +32,27 @@ void set_main_display(std::shared_ptr<GfxDisplay> display) {
|
||||
********************************
|
||||
*/
|
||||
|
||||
GfxDisplay::GfxDisplay(GLFWwindow* a_window) {
|
||||
set_renderer(GfxPipeline::OpenGL);
|
||||
set_window(a_window);
|
||||
}
|
||||
|
||||
GfxDisplay::~GfxDisplay() {
|
||||
m_renderer->kill_display(this);
|
||||
// window_generic_ptr = nullptr;
|
||||
}
|
||||
|
||||
void GfxDisplay::set_renderer(GfxPipeline pipeline) {
|
||||
if (is_active()) {
|
||||
lg::error("Can't change display's renderer while window exists.");
|
||||
return;
|
||||
}
|
||||
if (m_renderer != nullptr) {
|
||||
lg::error("A display changed renderer unexpectedly.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_renderer = Gfx::GetRenderer(pipeline);
|
||||
}
|
||||
|
||||
void GfxDisplay::set_window(GLFWwindow* window) {
|
||||
if (!renderer_is_correct(m_renderer, GfxPipeline::OpenGL)) {
|
||||
lg::error("Can't set OpenGL window when using {}", m_renderer->name);
|
||||
return;
|
||||
}
|
||||
if (is_active()) {
|
||||
lg::error("Already have a window. Close window first.");
|
||||
return;
|
||||
}
|
||||
|
||||
this->window_glfw = window;
|
||||
}
|
||||
|
||||
void GfxDisplay::set_title(const char* title) {
|
||||
if (!is_active()) {
|
||||
lg::error("No window to set title `{}`.", title);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO set title?
|
||||
m_title = title;
|
||||
}
|
||||
|
||||
void GfxDisplay::render_graphics() {
|
||||
m_renderer->render_display(this);
|
||||
}
|
||||
|
||||
int GfxDisplay::width() {
|
||||
int w;
|
||||
m_renderer->display_size(this, &w, NULL);
|
||||
get_size(&w, NULL);
|
||||
return w;
|
||||
}
|
||||
|
||||
int GfxDisplay::height() {
|
||||
int h;
|
||||
m_renderer->display_size(this, NULL, &h);
|
||||
get_size(NULL, &h);
|
||||
#ifdef _WIN32
|
||||
if (fullscreen_mode() == Gfx::DisplayMode::Borderless) {
|
||||
if (last_fullscreen_mode() == GfxDisplayMode::Borderless) {
|
||||
// windows borderless hack
|
||||
h--;
|
||||
}
|
||||
@@ -104,8 +61,8 @@ int GfxDisplay::height() {
|
||||
}
|
||||
|
||||
void GfxDisplay::backup_params() {
|
||||
m_renderer->display_size(this, &m_width, &m_height);
|
||||
m_renderer->display_position(this, &m_xpos, &m_ypos);
|
||||
get_size(&m_width, &m_height);
|
||||
get_position(&m_xpos, &m_ypos);
|
||||
fmt::print("backed up window: {},{} {}x{}\n", m_xpos, m_ypos, m_width, m_height);
|
||||
}
|
||||
|
||||
@@ -130,7 +87,7 @@ int InitMainDisplay(int width, int height, const char* title, GfxSettings& setti
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto display = Gfx::GetCurrentRenderer()->make_main_display(width, height, title, settings);
|
||||
auto display = Gfx::GetCurrentRenderer()->make_display(width, height, title, settings, true);
|
||||
if (display == NULL) {
|
||||
lg::error("Failed to make main display.");
|
||||
return 1;
|
||||
|
||||
+34
-35
@@ -5,19 +5,22 @@
|
||||
* Display for graphics. This is the game window, distinct from the runtime console.
|
||||
*/
|
||||
|
||||
#include "pipelines/opengl.h"
|
||||
#include "gfx.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "common/util/Assert.h"
|
||||
#include "gfx.h"
|
||||
|
||||
// lol hax
|
||||
#define __NYI_DEF \
|
||||
{ ASSERT_MSG(false, "nyi"); }
|
||||
|
||||
// a GfxDisplay class is equivalent to a window that displays stuff. This holds an actual internal
|
||||
// window pointer used by whichever renderer. It also contains functions for setting and
|
||||
// retrieving certain window parameters.
|
||||
// Maybe this is better implemented as an abstract class and renderers would have overrides?
|
||||
class GfxDisplay {
|
||||
const char* m_title;
|
||||
|
||||
const GfxRendererModule* m_renderer = nullptr;
|
||||
|
||||
// NOT actual size! just backups
|
||||
int m_width;
|
||||
int m_height;
|
||||
@@ -25,56 +28,52 @@ class GfxDisplay {
|
||||
int m_xpos;
|
||||
int m_ypos;
|
||||
|
||||
Gfx::DisplayMode m_fullscreen_mode = Gfx::DisplayMode::Windowed;
|
||||
Gfx::DisplayMode m_fullscreen_target_mode = Gfx::DisplayMode::Windowed;
|
||||
GfxDisplayMode m_fullscreen_target_mode = GfxDisplayMode::Windowed;
|
||||
GfxDisplayMode m_last_fullscreen_mode;
|
||||
int m_fullscreen_screen;
|
||||
int m_fullscreen_target_screen;
|
||||
|
||||
protected:
|
||||
bool m_main;
|
||||
|
||||
public:
|
||||
GfxDisplay(GLFWwindow* a_window); // OpenGL window constructor
|
||||
~GfxDisplay(); // destructor - this calls the renderer's function for getting rid of a window,
|
||||
// and we can then get rid of the GfxDisplay itself
|
||||
virtual ~GfxDisplay() {}
|
||||
|
||||
// all kinds of windows for the display
|
||||
union {
|
||||
void* window_generic_ptr = nullptr;
|
||||
GLFWwindow* window_glfw;
|
||||
};
|
||||
|
||||
bool is_active() const { return window_generic_ptr != nullptr; }
|
||||
void set_renderer(GfxPipeline pipeline);
|
||||
void set_window(GLFWwindow* window);
|
||||
virtual void* get_window() const __NYI_DEF;
|
||||
virtual void set_size(int w, int h) __NYI_DEF;
|
||||
virtual void update_fullscreen(GfxDisplayMode mode, int screen) __NYI_DEF;
|
||||
virtual void get_scale(float* x, float* y) __NYI_DEF;
|
||||
virtual void get_screen_size(int vmode_idx, s32* w, s32* h, s32* c) __NYI_DEF;
|
||||
virtual void get_position(int* x, int* y) __NYI_DEF;
|
||||
virtual void get_size(int* w, int* h) __NYI_DEF;
|
||||
virtual GfxDisplayMode get_fullscreen() __NYI_DEF;
|
||||
virtual void render() __NYI_DEF;
|
||||
bool is_active() const { return get_window() != nullptr; }
|
||||
void set_title(const char* title);
|
||||
void set_size(int w, int h) { m_renderer->display_set_size(this, w, h); }
|
||||
void get_scale(float* x, float* y) { m_renderer->display_scale(this, x, y); }
|
||||
void get_screen_size(s64 vmode_idx, s32* w, s32* h, s32* c) {
|
||||
m_renderer->screen_size(this, vmode_idx, 0, w, h, c);
|
||||
}
|
||||
const char* title() const { return m_title; }
|
||||
|
||||
bool fullscreen_pending() const { return m_fullscreen_mode != m_fullscreen_target_mode; }
|
||||
bool fullscreen_pending() { return get_fullscreen() != m_fullscreen_target_mode; }
|
||||
void fullscreen_flush() {
|
||||
m_renderer->set_fullscreen(this, m_fullscreen_target_mode, m_fullscreen_target_screen);
|
||||
m_fullscreen_mode = m_fullscreen_target_mode;
|
||||
update_fullscreen(m_fullscreen_target_mode, m_fullscreen_target_screen);
|
||||
// TODO no
|
||||
m_fullscreen_screen = m_fullscreen_target_screen;
|
||||
}
|
||||
void set_fullscreen(Gfx::DisplayMode mode, int screen) {
|
||||
void set_fullscreen(GfxDisplayMode mode, int screen) {
|
||||
m_fullscreen_target_mode = mode;
|
||||
m_fullscreen_target_screen = screen;
|
||||
}
|
||||
int fullscreen_mode() const { return m_fullscreen_mode; }
|
||||
void update_last_fullscreen_mode() { m_last_fullscreen_mode = get_fullscreen(); }
|
||||
GfxDisplayMode last_fullscreen_mode() const { return m_last_fullscreen_mode; }
|
||||
int fullscreen_screen() const { return m_fullscreen_screen; }
|
||||
bool windowed() const { return m_fullscreen_mode == Gfx::DisplayMode::Windowed; }
|
||||
bool windowed() { return get_fullscreen() == GfxDisplayMode::Windowed; }
|
||||
void backup_params();
|
||||
int width_backup() { return m_width; }
|
||||
int height_backup() { return m_height; }
|
||||
int xpos_backup() { return m_xpos; }
|
||||
int ypos_backup() { return m_ypos; }
|
||||
int width_backup() const { return m_width; }
|
||||
int height_backup() const { return m_height; }
|
||||
int xpos_backup() const { return m_xpos; }
|
||||
int ypos_backup() const { return m_ypos; }
|
||||
|
||||
int width();
|
||||
int height();
|
||||
|
||||
void render_graphics();
|
||||
};
|
||||
|
||||
namespace Display {
|
||||
|
||||
+13
-11
@@ -55,6 +55,7 @@ GfxSettings g_settings;
|
||||
void LoadSettings() {
|
||||
const auto filename = file_util::get_file_path({GAME_CONFIG_DIR_NAME, SETTINGS_GFX_FILE_NAME});
|
||||
if (std::filesystem::exists(filename)) {
|
||||
// this is just wrong LOL
|
||||
FILE* fp = fopen(filename.c_str(), "rb");
|
||||
lg::info("Found graphics configuration file. Checking version.");
|
||||
u64 version;
|
||||
@@ -83,13 +84,12 @@ void SaveSettings() {
|
||||
const GfxRendererModule* GetRenderer(GfxPipeline pipeline) {
|
||||
switch (pipeline) {
|
||||
case GfxPipeline::Invalid:
|
||||
lg::error("Requested invalid graphics pipeline!");
|
||||
lg::error("Requested invalid renderer", pipeline);
|
||||
return NULL;
|
||||
break;
|
||||
case GfxPipeline::OpenGL:
|
||||
return &moduleOpenGL;
|
||||
return &gRendererOpenGL;
|
||||
default:
|
||||
lg::error("Unknown graphics pipeline {}", (u64)pipeline);
|
||||
lg::error("Requested unknown renderer {}", (u64)pipeline);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ u32 Init() {
|
||||
}
|
||||
|
||||
if (g_main_thread_id != std::this_thread::get_id()) {
|
||||
lg::warn("Ran Gfx::Init outside main thread. Init display elsewhere?");
|
||||
lg::error("Ran Gfx::Init outside main thread. Init display elsewhere?");
|
||||
} else {
|
||||
Display::InitMainDisplay(640, 480, "OpenGOAL GL Window", g_settings);
|
||||
}
|
||||
@@ -133,7 +133,7 @@ void Loop(std::function<bool()> f) {
|
||||
// check if we have a display
|
||||
if (Display::GetMainDisplay()) {
|
||||
// lg::debug("run display");
|
||||
Display::GetMainDisplay()->render_graphics();
|
||||
Display::GetMainDisplay()->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,7 +184,9 @@ void set_levels(const std::vector<std::string>& levels) {
|
||||
}
|
||||
|
||||
void poll_events() {
|
||||
GetCurrentRenderer()->poll_events();
|
||||
if (GetCurrentRenderer()) {
|
||||
GetCurrentRenderer()->poll_events();
|
||||
}
|
||||
}
|
||||
|
||||
u64 get_window_width() {
|
||||
@@ -215,11 +217,11 @@ void get_window_scale(float* x, float* y) {
|
||||
}
|
||||
}
|
||||
|
||||
int get_fullscreen() {
|
||||
GfxDisplayMode get_fullscreen() {
|
||||
if (Display::GetMainDisplay()) {
|
||||
return Display::GetMainDisplay()->fullscreen_mode();
|
||||
return Display::GetMainDisplay()->get_fullscreen();
|
||||
} else {
|
||||
return DisplayMode::Windowed;
|
||||
return GfxDisplayMode::Windowed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +236,7 @@ void set_letterbox(int w, int h) {
|
||||
g_global_settings.lbox_h = h;
|
||||
}
|
||||
|
||||
void set_fullscreen(DisplayMode mode, int screen) {
|
||||
void set_fullscreen(GfxDisplayMode mode, int screen) {
|
||||
if (Display::GetMainDisplay()) {
|
||||
Display::GetMainDisplay()->set_fullscreen(mode, screen);
|
||||
}
|
||||
|
||||
+7
-16
@@ -19,20 +19,14 @@ class GfxDisplay;
|
||||
|
||||
// enum for rendering pipeline
|
||||
enum class GfxPipeline { Invalid = 0, OpenGL };
|
||||
enum GfxDisplayMode { Windowed = 0, Fullscreen = 1, Borderless = 2 };
|
||||
|
||||
// module for the different rendering pipelines
|
||||
struct GfxRendererModule {
|
||||
std::function<int(GfxSettings&)> init;
|
||||
std::function<std::shared_ptr<GfxDisplay>(int w, int h, const char* title, GfxSettings& settings)>
|
||||
make_main_display;
|
||||
std::function<void(GfxDisplay*)> kill_display;
|
||||
std::function<void(GfxDisplay*)> render_display;
|
||||
std::function<void(GfxDisplay*, int*, int*)> display_position;
|
||||
std::function<void(GfxDisplay*, int*, int*)> display_size;
|
||||
std::function<void(GfxDisplay*, int, int)> display_set_size;
|
||||
std::function<void(GfxDisplay*, float*, float*)> display_scale;
|
||||
std::function<void(GfxDisplay*, int, int)> set_fullscreen;
|
||||
std::function<void(GfxDisplay*, int, int, s32*, s32*, s32*)> screen_size;
|
||||
std::function<std::shared_ptr<
|
||||
GfxDisplay>(int width, int height, const char* title, GfxSettings& settings, bool is_main)>
|
||||
make_display;
|
||||
std::function<void()> exit;
|
||||
std::function<u32()> vsync;
|
||||
std::function<u32()> sync_path;
|
||||
@@ -47,6 +41,7 @@ struct GfxRendererModule {
|
||||
};
|
||||
|
||||
// store settings related to the gfx systems
|
||||
// TODO merge with globalsettings
|
||||
struct GfxSettings {
|
||||
// current version of the settings. this should be set up so that newer versions are always higher
|
||||
// than older versions
|
||||
@@ -98,13 +93,9 @@ namespace Gfx {
|
||||
|
||||
extern GfxGlobalSettings g_global_settings;
|
||||
extern GfxSettings g_settings;
|
||||
// extern const std::vector<const GfxRendererModule*> renderers;
|
||||
|
||||
const GfxRendererModule* GetRenderer(GfxPipeline pipeline);
|
||||
const GfxRendererModule* GetCurrentRenderer();
|
||||
|
||||
enum DisplayMode { Windowed = 0, Fullscreen = 1, Borderless = 2 };
|
||||
|
||||
u32 Init();
|
||||
void Loop(std::function<bool()> f);
|
||||
u32 Exit();
|
||||
@@ -120,10 +111,10 @@ u64 get_window_width();
|
||||
u64 get_window_height();
|
||||
void set_window_size(u64 w, u64 h);
|
||||
void get_window_scale(float* x, float* y);
|
||||
int get_fullscreen();
|
||||
GfxDisplayMode get_fullscreen();
|
||||
void get_screen_size(s64 vmode_idx, s32* w, s32* h, s32* c);
|
||||
void set_letterbox(int w, int h);
|
||||
void set_fullscreen(DisplayMode mode, int screen);
|
||||
void set_fullscreen(GfxDisplayMode mode, int screen);
|
||||
void input_mode_set(u32 enable);
|
||||
void input_mode_save();
|
||||
s64 get_mapped_button(s64 pad, s64 button);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* @file opengl.cpp
|
||||
* Lower-level OpenGL implementation.
|
||||
* Lower-level OpenGL interface. No actual rendering is performed here!
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
@@ -139,24 +139,31 @@ static void gl_exit() {
|
||||
gl_inited = false;
|
||||
}
|
||||
|
||||
static std::shared_ptr<GfxDisplay> gl_make_main_display(int width,
|
||||
int height,
|
||||
const char* title,
|
||||
GfxSettings& settings) {
|
||||
static std::shared_ptr<GfxDisplay> gl_make_display(int width,
|
||||
int height,
|
||||
const char* title,
|
||||
GfxSettings& settings,
|
||||
bool is_main) {
|
||||
GLFWwindow* window = glfwCreateWindow(width, height, title, NULL, NULL);
|
||||
|
||||
if (!window) {
|
||||
lg::error("gl_make_main_display failed - Could not create display window");
|
||||
lg::error("gl_make_display failed - Could not create display window");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
||||
if (!gl_inited && !gladLoadGL()) {
|
||||
lg::error("GL init fail");
|
||||
return NULL;
|
||||
if (!gl_inited) {
|
||||
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
||||
if (!gladLoadGL()) {
|
||||
lg::error("GL init fail");
|
||||
return NULL;
|
||||
}
|
||||
g_gfx_data = std::make_unique<GraphicsData>();
|
||||
|
||||
gl_inited = true;
|
||||
}
|
||||
|
||||
// window icon
|
||||
std::string image_path =
|
||||
(file_util::get_jak_project_dir() / "game" / "assets" / "appicon.png").string();
|
||||
|
||||
@@ -165,9 +172,6 @@ static std::shared_ptr<GfxDisplay> gl_make_main_display(int width,
|
||||
stbi_load(image_path.c_str(), &images[0].width, &images[0].height, 0, 4); // rgba channels
|
||||
glfwSetWindowIcon(window, 1, images);
|
||||
stbi_image_free(images[0].pixels);
|
||||
g_gfx_data = std::make_unique<GraphicsData>();
|
||||
|
||||
gl_inited = true;
|
||||
|
||||
// init framerate settings
|
||||
GLFWmonitor* primary_monitor = glfwGetPrimaryMonitor();
|
||||
@@ -201,11 +205,11 @@ static std::shared_ptr<GfxDisplay> gl_make_main_display(int width,
|
||||
Pad::initialize();
|
||||
|
||||
if (HasError()) {
|
||||
lg::error("gl_make_main_display error");
|
||||
lg::error("gl_make_display error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::shared_ptr<GfxDisplay> display = std::make_shared<GfxDisplay>(window);
|
||||
auto display = std::make_shared<GLDisplay>(window, is_main);
|
||||
// lg::debug("init display #x{:x}", (uintptr_t)display);
|
||||
|
||||
// setup imgui
|
||||
@@ -225,16 +229,23 @@ static std::shared_ptr<GfxDisplay> gl_make_main_display(int width,
|
||||
glfwGetError(NULL);
|
||||
|
||||
// set up the renderer
|
||||
ImGui_ImplOpenGL3_Init("#version 130");
|
||||
ImGui_ImplOpenGL3_Init("#version 430");
|
||||
|
||||
return display;
|
||||
return std::static_pointer_cast<GfxDisplay>(display);
|
||||
}
|
||||
|
||||
static void gl_kill_display(GfxDisplay* display) {
|
||||
GLDisplay::GLDisplay(GLFWwindow* window, bool is_main) : m_window(window) {
|
||||
m_main = is_main;
|
||||
}
|
||||
|
||||
GLDisplay::~GLDisplay() {
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
glfwDestroyWindow(display->window_glfw);
|
||||
glfwDestroyWindow(m_window);
|
||||
if (m_main) {
|
||||
gl_exit();
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -304,69 +315,76 @@ void render_game_frame(int width, int height, int lbox_width, int lbox_height) {
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_display_position(GfxDisplay* display, int* x, int* y) {
|
||||
glfwGetWindowPos(display->window_glfw, x, y);
|
||||
void GLDisplay::get_position(int* x, int* y) {
|
||||
glfwGetWindowPos(m_window, x, y);
|
||||
}
|
||||
|
||||
static void gl_display_size(GfxDisplay* display, int* width, int* height) {
|
||||
glfwGetFramebufferSize(display->window_glfw, width, height);
|
||||
void GLDisplay::get_size(int* width, int* height) {
|
||||
glfwGetFramebufferSize(m_window, width, height);
|
||||
}
|
||||
|
||||
static void gl_display_set_size(GfxDisplay* display, int width, int height) {
|
||||
glfwSetWindowSize(display->window_glfw, width, height);
|
||||
void GLDisplay::get_scale(float* xs, float* ys) {
|
||||
glfwGetWindowContentScale(m_window, xs, ys);
|
||||
}
|
||||
|
||||
static void gl_display_scale(GfxDisplay* display, float* xs, float* ys) {
|
||||
glfwGetWindowContentScale(display->window_glfw, xs, ys);
|
||||
void GLDisplay::set_size(int width, int height) {
|
||||
glfwSetWindowSize(m_window, width, height);
|
||||
}
|
||||
|
||||
static void gl_set_fullscreen(GfxDisplay* display, int mode, int /*screen*/) {
|
||||
void GLDisplay::update_fullscreen(GfxDisplayMode mode, int /*screen*/) {
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor(); // todo
|
||||
auto window = display->window_glfw;
|
||||
switch (mode) {
|
||||
case Gfx::DisplayMode::Windowed: {
|
||||
case GfxDisplayMode::Windowed: {
|
||||
// windowed
|
||||
glfwSetWindowAttrib(window, GLFW_DECORATED, GLFW_TRUE);
|
||||
glfwSetWindowFocusCallback(window, NULL);
|
||||
glfwSetWindowAttrib(window, GLFW_FLOATING, GLFW_FALSE);
|
||||
glfwSetWindowMonitor(window, NULL, display->xpos_backup(), display->ypos_backup(),
|
||||
display->width_backup(), display->height_backup(), GLFW_DONT_CARE);
|
||||
glfwSetWindowAttrib(m_window, GLFW_DECORATED, GLFW_TRUE);
|
||||
glfwSetWindowFocusCallback(m_window, NULL);
|
||||
glfwSetWindowAttrib(m_window, GLFW_FLOATING, GLFW_FALSE);
|
||||
glfwSetWindowMonitor(m_window, NULL, xpos_backup(), ypos_backup(), width_backup(),
|
||||
height_backup(), GLFW_DONT_CARE);
|
||||
} break;
|
||||
case Gfx::DisplayMode::Fullscreen: {
|
||||
case GfxDisplayMode::Fullscreen: {
|
||||
// fullscreen
|
||||
if (display->windowed()) {
|
||||
display->backup_params();
|
||||
if (windowed()) {
|
||||
backup_params();
|
||||
}
|
||||
const GLFWvidmode* vmode = glfwGetVideoMode(monitor);
|
||||
glfwSetWindowMonitor(window, monitor, 0, 0, vmode->width, vmode->height, 60);
|
||||
glfwSetWindowFocusCallback(window, FocusCallback);
|
||||
glfwSetWindowAttrib(m_window, GLFW_DECORATED, GLFW_TRUE);
|
||||
glfwSetWindowFocusCallback(m_window, NULL);
|
||||
glfwSetWindowAttrib(m_window, GLFW_FLOATING, GLFW_FALSE);
|
||||
glfwSetWindowMonitor(m_window, monitor, 0, 0, vmode->width, vmode->height, 60);
|
||||
} break;
|
||||
case Gfx::DisplayMode::Borderless: {
|
||||
case GfxDisplayMode::Borderless: {
|
||||
// borderless fullscreen
|
||||
if (display->windowed()) {
|
||||
display->backup_params();
|
||||
if (windowed()) {
|
||||
backup_params();
|
||||
}
|
||||
int x, y;
|
||||
glfwGetMonitorPos(monitor, &x, &y);
|
||||
const GLFWvidmode* vmode = glfwGetVideoMode(monitor);
|
||||
glfwSetWindowAttrib(window, GLFW_DECORATED, GLFW_FALSE);
|
||||
glfwSetWindowAttrib(window, GLFW_FLOATING, GLFW_TRUE);
|
||||
glfwSetWindowFocusCallback(window, FocusCallback);
|
||||
glfwSetWindowAttrib(m_window, GLFW_DECORATED, GLFW_FALSE);
|
||||
// glfwSetWindowAttrib(m_window, GLFW_FLOATING, GLFW_TRUE);
|
||||
// glfwSetWindowFocusCallback(m_window, FocusCallback);
|
||||
#ifdef _WIN32
|
||||
glfwSetWindowMonitor(window, NULL, x, y, vmode->width, vmode->height + 1, GLFW_DONT_CARE);
|
||||
glfwSetWindowMonitor(m_window, NULL, x, y, vmode->width, vmode->height + 1, GLFW_DONT_CARE);
|
||||
#else
|
||||
glfwSetWindowMonitor(window, NULL, x, y, vmode->width, vmode->height, GLFW_DONT_CARE);
|
||||
glfwSetWindowMonitor(m_window, NULL, x, y, vmode->width, vmode->height, GLFW_DONT_CARE);
|
||||
#endif
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_screen_size(GfxDisplay* /*display*/,
|
||||
int vmode_idx,
|
||||
int /*screen*/,
|
||||
s32* w_out,
|
||||
s32* h_out,
|
||||
s32* count_out) {
|
||||
GfxDisplayMode GLDisplay::get_fullscreen() {
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor(); // todo
|
||||
const GLFWvidmode* vmode = glfwGetVideoMode(monitor);
|
||||
if (width() >= vmode->width && height() >= vmode->height) {
|
||||
return glfwGetWindowAttrib(m_window, GLFW_DECORATED) == GLFW_TRUE ? GfxDisplayMode::Fullscreen
|
||||
: GfxDisplayMode::Borderless;
|
||||
} else {
|
||||
return GfxDisplayMode::Windowed;
|
||||
}
|
||||
}
|
||||
|
||||
void GLDisplay::get_screen_size(int vmode_idx, s32* w_out, s32* h_out, s32* count_out) {
|
||||
int count = 0;
|
||||
auto vmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
auto vmodes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count);
|
||||
@@ -402,14 +420,12 @@ void update_global_profiler() {
|
||||
/*!
|
||||
* Main function called to render graphics frames. This is called in a loop.
|
||||
*/
|
||||
static void gl_render_display(GfxDisplay* display) {
|
||||
GLFWwindow* window = display->window_glfw;
|
||||
|
||||
void GLDisplay::render() {
|
||||
// poll events
|
||||
{
|
||||
auto p = scoped_prof("poll-gamepads");
|
||||
glfwPollEvents();
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwMakeContextCurrent(m_window);
|
||||
Pad::update_gamepads();
|
||||
}
|
||||
|
||||
@@ -425,9 +441,9 @@ static void gl_render_display(GfxDisplay* display) {
|
||||
int width = Gfx::g_global_settings.lbox_w;
|
||||
int height = Gfx::g_global_settings.lbox_h;
|
||||
int fbuf_w, fbuf_h;
|
||||
glfwGetFramebufferSize(window, &fbuf_w, &fbuf_h);
|
||||
glfwGetFramebufferSize(m_window, &fbuf_w, &fbuf_h);
|
||||
#ifdef _WIN32
|
||||
if (display->fullscreen_mode() == 2) {
|
||||
if (last_fullscreen_mode() == GfxDisplayMode::Borderless) {
|
||||
// pretend the framebuffer is 1 pixel shorter on borderless. fullscreen issues!
|
||||
fbuf_h--;
|
||||
}
|
||||
@@ -437,7 +453,7 @@ static void gl_render_display(GfxDisplay* display) {
|
||||
// vertical letterbox size
|
||||
int lbox_h = (fbuf_h - height) / 2;
|
||||
#ifdef _WIN32
|
||||
if (display->fullscreen_mode() == 2) {
|
||||
if (last_fullscreen_mode() == GfxDisplayMode::Borderless) {
|
||||
// add one pixel of vertical letterbox on borderless to make up for extra line
|
||||
lbox_h++;
|
||||
}
|
||||
@@ -476,7 +492,7 @@ static void gl_render_display(GfxDisplay* display) {
|
||||
g_gfx_data->debug_gui.finish_frame();
|
||||
{
|
||||
auto p = scoped_prof("swap-buffers");
|
||||
glfwSwapBuffers(window);
|
||||
glfwSwapBuffers(m_window);
|
||||
}
|
||||
if (g_gfx_data->debug_gui.framelimiter) {
|
||||
auto p = scoped_prof("frame-limiter");
|
||||
@@ -488,9 +504,10 @@ static void gl_render_display(GfxDisplay* display) {
|
||||
prof().instant_event("ROOT");
|
||||
update_global_profiler();
|
||||
|
||||
if (display->fullscreen_pending()) {
|
||||
display->fullscreen_flush();
|
||||
if (fullscreen_pending()) {
|
||||
fullscreen_flush();
|
||||
}
|
||||
update_last_fullscreen_mode();
|
||||
|
||||
// toggle even odd and wake up engine waiting on vsync.
|
||||
{
|
||||
@@ -506,7 +523,7 @@ static void gl_render_display(GfxDisplay* display) {
|
||||
}
|
||||
|
||||
// exit if display window was closed
|
||||
if (glfwWindowShouldClose(window)) {
|
||||
if (glfwWindowShouldClose(m_window)) {
|
||||
std::unique_lock<std::mutex> lock(g_gfx_data->sync_mutex);
|
||||
MasterExit = RuntimeExitStatus::EXIT;
|
||||
g_gfx_data->sync_cv.notify_all();
|
||||
@@ -602,17 +619,9 @@ void gl_set_pmode_alp(float val) {
|
||||
g_gfx_data->pmode_alp = val;
|
||||
}
|
||||
|
||||
const GfxRendererModule moduleOpenGL = {
|
||||
const GfxRendererModule gRendererOpenGL = {
|
||||
gl_init, // init
|
||||
gl_make_main_display, // make_main_display
|
||||
gl_kill_display, // kill_display
|
||||
gl_render_display, // render_display
|
||||
gl_display_position, // display_position
|
||||
gl_display_size, // display_size
|
||||
gl_display_set_size, // display_set_size
|
||||
gl_display_scale, // display_scale
|
||||
gl_set_fullscreen, // set_fullscreen
|
||||
gl_screen_size, // screen_size
|
||||
gl_make_display, // make_display
|
||||
gl_exit, // exit
|
||||
gl_vsync, // vsync
|
||||
gl_sync_path, // sync_path
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "third-party/glad/include/glad/glad.h"
|
||||
#include "third-party/glfw/include/GLFW/glfw3.h"
|
||||
|
||||
#include "game/graphics/display.h"
|
||||
#include "game/graphics/gfx.h"
|
||||
|
||||
enum GlfwKeyAction {
|
||||
@@ -17,4 +18,22 @@ enum GlfwKeyAction {
|
||||
Repeat = GLFW_REPEAT // repeated input on hold e.g. when typing something
|
||||
};
|
||||
|
||||
extern const GfxRendererModule moduleOpenGL;
|
||||
class GLDisplay : public GfxDisplay {
|
||||
GLFWwindow* m_window;
|
||||
|
||||
public:
|
||||
GLDisplay(GLFWwindow* window, bool is_main);
|
||||
virtual ~GLDisplay();
|
||||
|
||||
void* get_window() const { return m_window; }
|
||||
void get_position(int* x, int* y);
|
||||
void get_size(int* w, int* h);
|
||||
void get_scale(float* x, float* y);
|
||||
void get_screen_size(int vmode_idx, s32* w, s32* h, s32* c);
|
||||
GfxDisplayMode get_fullscreen();
|
||||
void set_size(int w, int h);
|
||||
void update_fullscreen(GfxDisplayMode mode, int screen);
|
||||
void render();
|
||||
};
|
||||
|
||||
extern const GfxRendererModule gRendererOpenGL;
|
||||
|
||||
@@ -945,22 +945,22 @@ void prof_event(u32 name, u32 kind) {
|
||||
u32 get_fullscreen() {
|
||||
switch (Gfx::get_fullscreen()) {
|
||||
default:
|
||||
case Gfx::DisplayMode::Windowed:
|
||||
case GfxDisplayMode::Windowed:
|
||||
return intern_from_c("windowed").offset;
|
||||
case Gfx::DisplayMode::Borderless:
|
||||
case GfxDisplayMode::Borderless:
|
||||
return intern_from_c("borderless").offset;
|
||||
case Gfx::DisplayMode::Fullscreen:
|
||||
case GfxDisplayMode::Fullscreen:
|
||||
return intern_from_c("fullscreen").offset;
|
||||
}
|
||||
}
|
||||
|
||||
void set_fullscreen(u32 symptr, s64 screen) {
|
||||
if (symptr == intern_from_c("windowed").offset || symptr == s7.offset) {
|
||||
Gfx::set_fullscreen(Gfx::DisplayMode::Windowed, screen);
|
||||
Gfx::set_fullscreen(GfxDisplayMode::Windowed, screen);
|
||||
} else if (symptr == intern_from_c("borderless").offset) {
|
||||
Gfx::set_fullscreen(Gfx::DisplayMode::Borderless, screen);
|
||||
Gfx::set_fullscreen(GfxDisplayMode::Borderless, screen);
|
||||
} else if (symptr == intern_from_c("fullscreen").offset) {
|
||||
Gfx::set_fullscreen(Gfx::DisplayMode::Fullscreen, screen);
|
||||
Gfx::set_fullscreen(GfxDisplayMode::Fullscreen, screen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
(defglobalconstant PC_KERNEL_VERSION_BUILD #x0001)
|
||||
(defglobalconstant PC_KERNEL_VERSION_REVISION #x0005)
|
||||
|
||||
(defglobalconstant PC_KERNEL_VERSION_MINOR #x0003)
|
||||
(defglobalconstant PC_KERNEL_VERSION_MINOR #x0004)
|
||||
(defglobalconstant PC_KERNEL_VERSION_MAJOR #x0001)
|
||||
(defglobalconstant PC_KERNEL_VERSION (logior
|
||||
(ash PC_KERNEL_VERSION_MAJOR 48)
|
||||
@@ -191,10 +191,18 @@
|
||||
|
||||
;; "generic" graphics settings
|
||||
(target-fps int16) ;; the target framerate of the game
|
||||
(width int32) ;; the width of the rendering, may not match window
|
||||
;; game resolution?
|
||||
(width int32)
|
||||
(height int32)
|
||||
(win-width int32) ;; the width of the display window
|
||||
;; window size. resolution = window size in windowed mode.
|
||||
(win-width int32)
|
||||
(win-height int32)
|
||||
;; real window size from OS
|
||||
(real-width int32)
|
||||
(real-height int32)
|
||||
;; letterboxed window size
|
||||
(lbox-width int32)
|
||||
(lbox-height int32)
|
||||
(dpi-x float) ;; DPI width scale
|
||||
(dpi-y float) ;; DPI height scale
|
||||
(aspect-ratio-auto? symbol) ;; if on, aspect ratio is calculated automatically based on game display size.
|
||||
|
||||
+36
-26
@@ -53,19 +53,23 @@
|
||||
(defmethod set-display-mode! pc-settings ((obj pc-settings) (mode symbol))
|
||||
"sets the game's display mode"
|
||||
|
||||
;; changing to same mode, no-op
|
||||
(if (= (pc-get-fullscreen) mode)
|
||||
(return 0))
|
||||
|
||||
;; else change it and update it
|
||||
;; change the display mode.
|
||||
(set! (-> obj display-mode) mode)
|
||||
(pc-set-fullscreen mode 0)
|
||||
0)
|
||||
|
||||
(defmethod set-size! pc-settings ((obj pc-settings) (width int) (height int))
|
||||
"sets the size of the display window"
|
||||
(format #t "Setting size to ~D x ~D~%" width height)
|
||||
(pc-set-window-size width height)
|
||||
(cond
|
||||
((= 'windowed (-> obj display-mode))
|
||||
(set! (-> obj win-width) width)
|
||||
(set! (-> obj win-height) height)
|
||||
)
|
||||
(else
|
||||
(format 0 "Nope! No changing fullscreen resolution for now!")
|
||||
(format #t "Nope! No changing fullscreen resolution for now!")
|
||||
)
|
||||
)
|
||||
(none))
|
||||
|
||||
|
||||
@@ -100,9 +104,8 @@
|
||||
"Update settings from the C kernel to GOAL."
|
||||
|
||||
(set! (-> obj os) (pc-get-os))
|
||||
(pc-get-window-size (&-> obj win-width) (&-> obj win-height))
|
||||
(pc-get-window-size (&-> obj real-width) (&-> obj real-height))
|
||||
(pc-get-window-scale (&-> obj dpi-x) (&-> obj dpi-y))
|
||||
(set! (-> obj display-mode) 'windowed)
|
||||
|
||||
(when (-> obj use-vis?)
|
||||
(if (= (-> *setting-control* default aspect-ratio) 'aspect4x3)
|
||||
@@ -111,28 +114,28 @@
|
||||
)
|
||||
)
|
||||
|
||||
(let ((win-aspect (/ (the float (-> obj win-width)) (the float (-> obj win-height)))))
|
||||
(let ((win-aspect (/ (the float (-> obj real-width)) (the float (-> obj real-height)))))
|
||||
(cond
|
||||
((and (not (-> obj use-vis?)) (-> obj aspect-ratio-auto?))
|
||||
;; the window determines the resolution
|
||||
(set-aspect-ratio! obj win-aspect)
|
||||
(set! (-> obj width) (-> obj win-width))
|
||||
(set! (-> obj height) (-> obj win-height))
|
||||
(set! (-> obj lbox-width) (-> obj real-width))
|
||||
(set! (-> obj lbox-height) (-> obj real-height))
|
||||
)
|
||||
((> win-aspect (-> obj aspect-ratio))
|
||||
;; too wide
|
||||
(set! (-> obj width) (the int (* (the float (-> obj win-height)) (-> obj aspect-ratio))))
|
||||
(set! (-> obj height) (-> obj win-height))
|
||||
(set! (-> obj lbox-width) (the int (* (the float (-> obj real-height)) (-> obj aspect-ratio))))
|
||||
(set! (-> obj lbox-height) (-> obj real-height))
|
||||
)
|
||||
((< win-aspect (-> obj aspect-ratio))
|
||||
;; too tall
|
||||
(set! (-> obj width) (-> obj win-width))
|
||||
(set! (-> obj height) (the int (/ (the float (-> obj win-width)) (-> obj aspect-ratio))))
|
||||
(set! (-> obj lbox-width) (-> obj real-width))
|
||||
(set! (-> obj lbox-height) (the int (/ (the float (-> obj real-width)) (-> obj aspect-ratio))))
|
||||
)
|
||||
(else
|
||||
;; just right
|
||||
(set! (-> obj width) (-> obj win-width))
|
||||
(set! (-> obj height) (-> obj win-height))
|
||||
(set! (-> obj lbox-width) (-> obj real-width))
|
||||
(set! (-> obj lbox-height) (-> obj real-height))
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -145,14 +148,17 @@
|
||||
|
||||
(cond
|
||||
((-> obj letterbox?)
|
||||
;; AGH bad idea, this is meant for resolution! TODO fix this crap
|
||||
(pc-set-letterbox (-> obj width) (-> obj height))
|
||||
(pc-set-letterbox (-> obj lbox-width) (-> obj lbox-height))
|
||||
)
|
||||
(else
|
||||
(pc-set-letterbox (-> obj win-width) (-> obj win-height))
|
||||
(pc-set-letterbox (-> obj real-width) (-> obj real-height))
|
||||
)
|
||||
)
|
||||
|
||||
(pc-set-fullscreen (-> obj display-mode) 0)
|
||||
(if (= 'windowed (-> obj display-mode))
|
||||
(pc-set-window-size (max 320 (-> obj win-width)) (max 240 (-> obj win-height))))
|
||||
|
||||
(pc-discord-rpc-set (if (-> obj discord-rpc?) 1 0))
|
||||
|
||||
(when #t ;; (not (-> obj ps2-lod-dist?))
|
||||
@@ -459,8 +465,8 @@
|
||||
|
||||
(clear *pc-temp-string*)
|
||||
(format *pc-temp-string* "game resolution: ~D x ~D~%" (-> obj width) (-> obj height))
|
||||
(format *pc-temp-string* "window size: ~D x ~D (~,,1f x ~,,1f)~%" (-> obj win-width) (-> obj win-height) (-> obj dpi-x) (-> obj dpi-y))
|
||||
(format *pc-temp-string* "target aspect: ~,,3f/~,,3f A: ~A/~A L: ~A~%" (-> obj aspect-ratio) (/ (the float (-> obj win-width)) (the float (-> obj win-height))) (-> obj aspect-ratio-auto?) (-> obj use-vis?) (-> obj letterbox?))
|
||||
(format *pc-temp-string* "window size: ~D x ~D (~,,1f x ~,,1f)~%" (-> obj real-width) (-> obj real-height) (-> obj dpi-x) (-> obj dpi-y))
|
||||
(format *pc-temp-string* "target aspect: ~,,3f/~,,3f A: ~A/~A L: ~A~%" (-> obj aspect-ratio) (/ (the float (-> obj real-width)) (the float (-> obj real-height))) (-> obj aspect-ratio-auto?) (-> obj use-vis?) (-> obj letterbox?))
|
||||
(format *pc-temp-string* "display-type: ~A ~A~%" (-> obj display-mode) (-> obj vsync?))
|
||||
|
||||
(draw-string-xy *pc-temp-string* buf 0 (- 224 (* 8 4)) (font-color default) (font-flags shadow kerning))
|
||||
@@ -679,10 +685,13 @@
|
||||
(dosettings (file)
|
||||
(case-str *pc-temp-string*
|
||||
(("fps") (set! (-> obj target-fps) (file-stream-read-int file)))
|
||||
(("size")
|
||||
(("window-size")
|
||||
(set! (-> obj win-width) (file-stream-read-int file))
|
||||
(set! (-> obj win-height) (file-stream-read-int file))
|
||||
)
|
||||
(("game-size")
|
||||
(set! (-> obj width) (file-stream-read-int file))
|
||||
(set! (-> obj height) (file-stream-read-int file))
|
||||
(set-size! obj (-> obj width) (-> obj height))
|
||||
)
|
||||
(("aspect") (set-aspect! obj (file-stream-read-int file) (file-stream-read-int file)))
|
||||
(("aspect-test")
|
||||
@@ -801,7 +810,8 @@
|
||||
(format file "(settings #x~X~%" (-> obj version))
|
||||
|
||||
(format file " (fps ~D)~%" (-> obj target-fps))
|
||||
(format file " (size ~D ~D)~%" (-> obj win-width) (-> obj win-height))
|
||||
(format file " (game-size ~D ~D)~%" (-> obj width) (-> obj height))
|
||||
(format file " (window-size ~D ~D)~%" (-> obj win-width) (-> obj win-height))
|
||||
(format file " (aspect ~D ~D)~%" (-> obj width) (-> obj height))
|
||||
(format file " (aspect-test ~D ~D)~%" (-> obj aspect-custom-x) (-> obj aspect-custom-y))
|
||||
(format file " (aspect-auto ~A)~%" (-> obj aspect-ratio-auto?))
|
||||
|
||||
Reference in New Issue
Block a user