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:
ManDude
2022-06-17 03:46:12 +01:00
committed by GitHub
parent 3d468b25b2
commit 714ddf1d6f
9 changed files with 218 additions and 223 deletions
+7 -50
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+84 -75
View File
@@ -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
+20 -1
View File
@@ -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;
+6 -6
View File
@@ -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);
}
}
+11 -3
View File
@@ -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
View File
@@ -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?))