jak-project/game/graphics/display.cpp
ManDude a7eee4fdc9
[game] pc port progress menu (#1281)
* fix typo

* more typo

* shorten discord rpc text

* allow expanding enums after the fact (untested)

* make `game_text` work similar to subtitles

* update progress decomp

* update some types + `do-not-decompile` in bitfield

* fixes and fall back to original progress code

* update `progress` decomp with new enums

* update config files

* fix enums and debug menu

* always allocate (but not use) a lot of particles

* small rework to display mode options

* revert resolution/aspect-ratio symbol mess

* begin the override stuff

* make `progress-draw` more readable

* more fixes

* codacy good boy points

* first step overriding code

* finish progress overrides, game options menu fully functional!

* minor fixes

* Update game.gp

* Update sparticle-launcher.gc

* clang

* change camera controls text

* oops

* some cleanup

* derp

* nice job

* implement menu scrolling lol

* make scrollable menus less cramped, fix arrows

* make some carousell things i guess

* add msaa carousell to test

* oops

* Update progress-pc.gc

* make `pc-get-screen-size` (untested)

* resolution menu

* input fixes

* return when selecting resolution

* scroll fixes

* Update progress-pc.gc

* add "fit to screen" button

* bug

* complete resolutions menu

* aspect ratio menu

* subtitles language

* subtitle speaker

* final adjustments

* ref test

* fix tests

* fix ref!

* reduce redundancy a bit

* fix mem leaks?

* save settings on progress exit

* fix init reorder

* remove unused code

* rename goal project-like files to the project extension

* sha display toggle

* aspect ratio settings fixes

* dont store text db's in compiler

* properly save+load native aspect stuff
2022-04-11 18:38:54 -04:00

167 lines
3.8 KiB
C++

/*!
* @file display.cpp
* Display for graphics. This is the game window, distinct from the runtime console.
*/
#include "display.h"
#include "gfx.h"
#include "common/log/log.h"
/*
********************************
* Internal functions
********************************
*/
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;
} else {
Display::g_displays.push_back(display);
}
}
} // namespace
/*
********************************
* GfxDisplay
********************************
*/
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;
}
m_title = title;
}
void GfxDisplay::render_graphics() {
m_renderer->render_display(this);
}
int GfxDisplay::width() {
int w;
m_renderer->display_size(this, &w, NULL);
return w;
}
int GfxDisplay::height() {
int h;
m_renderer->display_size(this, NULL, &h);
#ifdef _WIN32
if (fullscreen_mode() == Gfx::DisplayMode::Borderless) {
// windows borderless hack
h--;
}
#endif
return h;
}
void GfxDisplay::backup_params() {
m_renderer->display_size(this, &m_width, &m_height);
m_renderer->display_position(this, &m_xpos, &m_ypos);
fmt::print("backed up window: {},{} {}x{}\n", m_xpos, m_ypos, m_width, m_height);
}
/*
********************************
* DISPLAY
********************************
*/
namespace Display {
std::vector<std::shared_ptr<GfxDisplay>> g_displays;
std::shared_ptr<GfxDisplay> GetMainDisplay() {
if (g_displays.size() == 0)
return NULL;
return g_displays.front()->is_active() ? g_displays.front() : NULL;
}
int InitMainDisplay(int width, int height, const char* title, GfxSettings& settings) {
if (GetMainDisplay() != NULL) {
lg::warn("InitMainDisplay called when main display already exists.");
return 1;
}
auto display = Gfx::GetCurrentRenderer()->make_main_display(width, height, title, settings);
if (display == NULL) {
lg::error("Failed to make main display.");
return 1;
}
set_main_display(display);
return 0;
}
void KillMainDisplay() {
KillDisplay(GetMainDisplay());
}
void KillDisplay(std::shared_ptr<GfxDisplay> display) {
// lg::debug("kill display #x{:x}", (uintptr_t)display);
if (!display->is_active()) {
lg::warn("display #x{:x} cant be killed because it is not active");
return;
}
if (GetMainDisplay() == display) {
// killing the main display, kill all children displays too!
while (g_displays.size() > 1) {
KillDisplay(g_displays.at(1));
}
}
// find this display in the list and remove it from there
// if everything went right the smart pointer should delete the display.
auto this_disp = std::find(g_displays.begin(), g_displays.end(), display);
g_displays.erase(this_disp);
}
} // namespace Display