2021-03-09 23:51:28 -05:00
|
|
|
/*!
|
|
|
|
* @file gfx.cpp
|
2021-08-09 19:16:39 -04:00
|
|
|
* Graphics component for the runtime. Abstraction layer for the main graphics routines.
|
2021-03-09 23:51:28 -05:00
|
|
|
*/
|
|
|
|
|
2022-06-22 23:37:46 -04:00
|
|
|
#include "gfx.h"
|
|
|
|
|
2021-08-16 10:43:12 -04:00
|
|
|
#include <cstdio>
|
2022-06-22 23:37:46 -04:00
|
|
|
#include <functional>
|
2022-08-14 17:21:02 -04:00
|
|
|
#include <utility>
|
2021-08-13 20:06:16 -04:00
|
|
|
|
2021-03-09 23:51:28 -05:00
|
|
|
#include "display.h"
|
2021-08-09 19:16:39 -04:00
|
|
|
|
2021-08-14 16:00:50 -04:00
|
|
|
#include "common/log/log.h"
|
2022-06-22 23:37:46 -04:00
|
|
|
#include "common/symbols.h"
|
2021-08-16 10:43:12 -04:00
|
|
|
#include "common/util/FileUtil.h"
|
2022-08-19 11:28:06 -04:00
|
|
|
#include "common/util/json_util.h"
|
2022-06-22 23:37:46 -04:00
|
|
|
|
2021-08-16 10:43:12 -04:00
|
|
|
#include "game/common/file_paths.h"
|
2022-06-26 18:17:11 -04:00
|
|
|
#include "game/kernel/common/kscheme.h"
|
2022-06-23 18:44:27 -04:00
|
|
|
#include "game/kernel/svnrev.h"
|
2021-08-14 16:00:50 -04:00
|
|
|
#include "game/runtime.h"
|
|
|
|
#include "game/system/newpad.h"
|
2022-06-22 23:37:46 -04:00
|
|
|
#include "pipelines/opengl.h"
|
2021-08-14 16:00:50 -04:00
|
|
|
|
2021-08-09 19:16:39 -04:00
|
|
|
namespace {
|
|
|
|
// initializes a gfx settings.
|
|
|
|
// TODO save and load from file
|
|
|
|
void InitSettings(GfxSettings& settings) {
|
2021-08-13 20:06:16 -04:00
|
|
|
// set the current settings version
|
|
|
|
settings.version = GfxSettings::CURRENT_VERSION;
|
|
|
|
|
2021-08-09 19:16:39 -04:00
|
|
|
// use opengl by default for now
|
2021-08-16 10:43:12 -04:00
|
|
|
settings.renderer = GfxPipeline::OpenGL; // Gfx::renderers[0];
|
2021-08-09 19:16:39 -04:00
|
|
|
|
|
|
|
// 1 screen update per frame
|
|
|
|
settings.vsync = 1;
|
|
|
|
|
2021-08-13 20:06:16 -04:00
|
|
|
// debug for now
|
|
|
|
settings.debug = true;
|
|
|
|
|
2021-08-14 16:00:50 -04:00
|
|
|
// use buffered input mode
|
|
|
|
settings.pad_mapping_info.buffer_mode = true;
|
|
|
|
// debug input settings
|
|
|
|
settings.pad_mapping_info.debug = true;
|
2022-08-19 11:28:06 -04:00
|
|
|
|
|
|
|
Pad::DefaultMapping(Gfx::g_settings.pad_mapping_info);
|
2021-08-09 19:16:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
2021-03-09 23:51:28 -05:00
|
|
|
|
|
|
|
namespace Gfx {
|
|
|
|
|
2022-08-14 17:21:02 -04:00
|
|
|
std::function<void()> vsync_callback;
|
2021-12-30 18:48:37 -05:00
|
|
|
GfxGlobalSettings g_global_settings;
|
2021-08-09 19:16:39 -04:00
|
|
|
GfxSettings g_settings;
|
2022-08-19 11:28:06 -04:00
|
|
|
|
|
|
|
Pad::MappingInfo& get_button_mapping() {
|
|
|
|
return g_settings.pad_mapping_info;
|
|
|
|
}
|
|
|
|
|
2021-08-09 19:16:39 -04:00
|
|
|
// const std::vector<const GfxRendererModule*> renderers = {&moduleOpenGL};
|
|
|
|
|
2022-08-19 11:28:06 -04:00
|
|
|
// Not crazy about this declaration
|
|
|
|
const std::pair<std::string, Pad::Button> gamepad_map[] = {{"Select", Pad::Button::Select},
|
|
|
|
{"L3", Pad::Button::L3},
|
|
|
|
{"R3", Pad::Button::R3},
|
|
|
|
{"Start", Pad::Button::Start},
|
|
|
|
{"Up", Pad::Button::Up},
|
|
|
|
{"Right", Pad::Button::Right},
|
|
|
|
{"Down", Pad::Button::Down},
|
|
|
|
{"Left", Pad::Button::Left},
|
|
|
|
{"L1", Pad::Button::L1},
|
|
|
|
{"R1", Pad::Button::R1},
|
|
|
|
{"Triangle", Pad::Button::Triangle},
|
|
|
|
{"Circle", Pad::Button::Circle},
|
|
|
|
{"X", Pad::Button::X},
|
|
|
|
{"Square", Pad::Button::Square}};
|
|
|
|
|
|
|
|
const std::pair<std::string, Pad::Analog> analog_map[] = {
|
|
|
|
{"Left X Axis", Pad::Analog::Left_X},
|
|
|
|
{"Left Y Axis", Pad::Analog::Left_Y},
|
|
|
|
{"Right X Axis", Pad::Analog::Right_X},
|
|
|
|
{"Right Y Axis", Pad::Analog::Right_Y},
|
|
|
|
};
|
|
|
|
|
|
|
|
bool g_is_debug_menu_visible_on_startup = false;
|
|
|
|
|
|
|
|
bool get_debug_menu_visible_on_startup() {
|
|
|
|
return g_is_debug_menu_visible_on_startup;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DumpToJson(ghc::filesystem::path& filename) {
|
|
|
|
nlohmann::json json;
|
|
|
|
json["Debug Menu Visibility"] = false; // Assume start up debug display is disabled
|
|
|
|
auto& peripherals_json = json["Peripherals"];
|
2022-08-21 19:00:13 -04:00
|
|
|
json["Use Mouse"] = g_settings.pad_mapping_info.use_mouse;
|
2022-08-19 11:28:06 -04:00
|
|
|
|
|
|
|
for (uint32_t i = 0; i < Pad::CONTROLLER_COUNT; ++i) {
|
|
|
|
nlohmann::json peripheral_json;
|
|
|
|
peripheral_json["ID"] = i + 1;
|
|
|
|
|
|
|
|
auto& controller_json = peripheral_json["Controller"];
|
|
|
|
auto& controller_buttons_json = controller_json["Buttons"];
|
|
|
|
for (const auto& [name, value] : gamepad_map) {
|
|
|
|
controller_buttons_json[name] =
|
|
|
|
g_settings.pad_mapping_info.controller_button_mapping[i][(int)value];
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& keyboard_json = peripheral_json["Keyboard+Mouse"];
|
|
|
|
auto& keyboard_buttons_json = keyboard_json["Buttons"];
|
|
|
|
for (const auto& [name, value] : gamepad_map) {
|
|
|
|
keyboard_buttons_json[name] =
|
|
|
|
g_settings.pad_mapping_info.keyboard_button_mapping[i][(int)value];
|
2021-08-16 10:43:12 -04:00
|
|
|
}
|
2022-08-19 11:28:06 -04:00
|
|
|
|
|
|
|
auto& keyboard_analogs_json = keyboard_json["Analog"];
|
|
|
|
for (const auto& [name, value] : analog_map) {
|
|
|
|
if (g_settings.pad_mapping_info.keyboard_analog_mapping[i][(int)value].mode ==
|
|
|
|
Pad::AnalogMappingMode::AnalogInput) {
|
|
|
|
keyboard_analogs_json[name]["Axis Id"] =
|
|
|
|
g_settings.pad_mapping_info.keyboard_analog_mapping[i][(int)value].axis_id;
|
|
|
|
} else {
|
|
|
|
keyboard_analogs_json[name]["Positive Key"] =
|
|
|
|
g_settings.pad_mapping_info.keyboard_analog_mapping[i][(int)value].positive_key;
|
|
|
|
keyboard_analogs_json[name]["Negative Key"] =
|
|
|
|
g_settings.pad_mapping_info.keyboard_analog_mapping[i][(int)value].negative_key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
peripheral_json["X-Axis Mouse Sensitivity"] =
|
|
|
|
g_settings.pad_mapping_info.mouse_x_axis_sensitivities[i];
|
|
|
|
peripheral_json["Y-Axis Mouse Sensitivity"] =
|
|
|
|
g_settings.pad_mapping_info.mouse_y_axis_sensitivities[i];
|
|
|
|
peripherals_json.emplace_back(peripheral_json);
|
2021-08-16 10:43:12 -04:00
|
|
|
}
|
2022-08-19 11:28:06 -04:00
|
|
|
|
|
|
|
file_util::write_text_file(filename, json.dump(4));
|
2021-08-16 10:43:12 -04:00
|
|
|
}
|
|
|
|
|
2022-08-19 11:28:06 -04:00
|
|
|
void SavePeripheralSettings() {
|
|
|
|
auto filename = (file_util::get_user_config_dir() / "controller" / "controller-settings.json");
|
|
|
|
file_util::create_dir_if_needed_for_file(filename);
|
|
|
|
|
|
|
|
DumpToJson(filename);
|
2021-08-29 14:41:35 -04:00
|
|
|
lg::info("Saved graphics configuration file.");
|
2021-08-16 10:43:12 -04:00
|
|
|
}
|
|
|
|
|
2022-08-19 11:28:06 -04:00
|
|
|
void LoadPeripheralSettings(const ghc::filesystem::path& filepath) {
|
|
|
|
Pad::DefaultMapping(g_settings.pad_mapping_info);
|
|
|
|
|
2022-10-01 11:58:36 -04:00
|
|
|
lg::info("reading {}", filepath.string());
|
2022-08-19 11:28:06 -04:00
|
|
|
auto file_txt = file_util::read_text_file(filepath);
|
|
|
|
auto configuration = parse_commented_json(file_txt, filepath.string());
|
|
|
|
|
|
|
|
if (configuration.find("Debug Menu Visibility") != configuration.end()) {
|
|
|
|
g_is_debug_menu_visible_on_startup = configuration["Debug Menu Visibility"].get<bool>();
|
|
|
|
}
|
|
|
|
|
2022-09-11 13:31:41 -04:00
|
|
|
if (configuration.find("Use Mouse") != configuration.end()) {
|
2022-08-26 11:59:11 -04:00
|
|
|
g_settings.pad_mapping_info.use_mouse = configuration["Use Mouse"].get<bool>();
|
|
|
|
}
|
2022-08-19 11:28:06 -04:00
|
|
|
int controller_index = 0;
|
|
|
|
for (const auto& peripheral : configuration["Peripherals"]) {
|
|
|
|
auto& controller_buttons_json = peripheral["Controller"]["Buttons"];
|
|
|
|
auto& keyboard_buttons_json = peripheral["Keyboard+Mouse"]["Buttons"];
|
|
|
|
|
|
|
|
for (const auto& [name, button] : gamepad_map) {
|
|
|
|
if (controller_buttons_json.find(name) != controller_buttons_json.end()) {
|
|
|
|
g_settings.pad_mapping_info.controller_button_mapping[controller_index][(int)button] =
|
|
|
|
controller_buttons_json[name].get<int>();
|
|
|
|
} else {
|
|
|
|
lg::warn(
|
|
|
|
"Controller button override not found for {}. Using controller default value: {}", name,
|
|
|
|
g_settings.pad_mapping_info.controller_button_mapping[controller_index][(int)button]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keyboard_buttons_json.find(name) != keyboard_buttons_json.end()) {
|
|
|
|
g_settings.pad_mapping_info.keyboard_button_mapping[controller_index][(int)button] =
|
|
|
|
keyboard_buttons_json[name].get<int>();
|
|
|
|
} else {
|
|
|
|
lg::warn(
|
|
|
|
"Keyboard button override not found for {}. Using keyboard default value: {}", name,
|
|
|
|
g_settings.pad_mapping_info.keyboard_button_mapping[controller_index][(int)button]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& keyboard_analogs_json = peripheral["Keyboard+Mouse"]["Analog"];
|
|
|
|
for (const auto& [name, value] : analog_map) {
|
|
|
|
Pad::AnalogMappingInfo analog_mapping;
|
|
|
|
if (keyboard_analogs_json[name].contains("Axis Id") == true) {
|
|
|
|
analog_mapping.mode = Pad::AnalogMappingMode::AnalogInput;
|
|
|
|
analog_mapping.axis_id = keyboard_analogs_json[name]["Axis Id"].get<int>();
|
|
|
|
g_settings.pad_mapping_info.keyboard_analog_mapping[controller_index][(int)value] =
|
|
|
|
analog_mapping;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keyboard_analogs_json[name].contains("Positive Key") == true) {
|
|
|
|
analog_mapping.positive_key = keyboard_analogs_json[name]["Positive Key"].get<int>();
|
|
|
|
} else {
|
|
|
|
lg::warn("Keyboard analog override not found for {}. Using keyboard default value: {}",
|
|
|
|
name,
|
|
|
|
g_settings.pad_mapping_info.keyboard_analog_mapping[controller_index][(int)value]
|
|
|
|
.positive_key);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keyboard_analogs_json[name].contains("Negative Key") == true) {
|
|
|
|
analog_mapping.negative_key = keyboard_analogs_json[name]["Negative Key"].get<int>();
|
|
|
|
} else {
|
|
|
|
lg::warn("Keyboard analog override not found for {}. Using keyboard default value: {}",
|
|
|
|
name,
|
|
|
|
g_settings.pad_mapping_info.keyboard_analog_mapping[controller_index][(int)value]
|
|
|
|
.negative_key);
|
|
|
|
}
|
|
|
|
g_settings.pad_mapping_info.keyboard_analog_mapping[controller_index][(int)value] =
|
|
|
|
analog_mapping;
|
|
|
|
}
|
|
|
|
g_settings.pad_mapping_info.mouse_x_axis_sensitivities[controller_index] =
|
|
|
|
peripheral["X-Axis Mouse Sensitivity"].get<double>();
|
|
|
|
g_settings.pad_mapping_info.mouse_y_axis_sensitivities[controller_index] =
|
|
|
|
peripheral["Y-Axis Mouse Sensitivity"].get<double>();
|
|
|
|
controller_index++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LoadSettings() {
|
|
|
|
auto filename = (file_util::get_user_config_dir() / "controller" / "controller-settings.json");
|
|
|
|
if (fs::exists(filename)) {
|
|
|
|
LoadPeripheralSettings(filename);
|
|
|
|
lg::info("Loaded graphics configuration file.");
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
SavePeripheralSettings();
|
|
|
|
lg::info("Couldn't find controller-settings.json creating new controller settings file.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-09 19:16:39 -04:00
|
|
|
const GfxRendererModule* GetRenderer(GfxPipeline pipeline) {
|
|
|
|
switch (pipeline) {
|
|
|
|
case GfxPipeline::Invalid:
|
2022-06-16 22:46:12 -04:00
|
|
|
lg::error("Requested invalid renderer", pipeline);
|
2021-08-09 19:16:39 -04:00
|
|
|
return NULL;
|
|
|
|
case GfxPipeline::OpenGL:
|
2022-06-16 22:46:12 -04:00
|
|
|
return &gRendererOpenGL;
|
2021-08-09 19:16:39 -04:00
|
|
|
default:
|
2022-06-16 22:46:12 -04:00
|
|
|
lg::error("Requested unknown renderer {}", (u64)pipeline);
|
2021-08-09 19:16:39 -04:00
|
|
|
return NULL;
|
|
|
|
}
|
2021-03-09 23:51:28 -05:00
|
|
|
}
|
|
|
|
|
2021-12-30 18:48:37 -05:00
|
|
|
void SetRenderer(GfxPipeline pipeline) {
|
|
|
|
g_global_settings.renderer = GetRenderer(pipeline);
|
|
|
|
g_settings.renderer = pipeline;
|
|
|
|
}
|
|
|
|
|
2021-08-16 10:43:12 -04:00
|
|
|
const GfxRendererModule* GetCurrentRenderer() {
|
2021-12-30 18:48:37 -05:00
|
|
|
return g_global_settings.renderer;
|
2021-08-16 10:43:12 -04:00
|
|
|
}
|
|
|
|
|
2022-06-30 21:11:58 -04:00
|
|
|
u32 Init(GameVersion version) {
|
2021-08-09 19:16:39 -04:00
|
|
|
lg::info("GFX Init");
|
|
|
|
// initialize settings
|
|
|
|
InitSettings(g_settings);
|
2021-08-14 16:00:50 -04:00
|
|
|
// guarantee we have no keys detected by pad
|
|
|
|
Pad::ForceClearKeys();
|
2021-03-09 23:51:28 -05:00
|
|
|
|
2021-08-16 10:43:12 -04:00
|
|
|
LoadSettings();
|
2021-12-30 18:48:37 -05:00
|
|
|
SetRenderer(g_settings.renderer);
|
2021-08-16 10:43:12 -04:00
|
|
|
|
|
|
|
if (GetCurrentRenderer()->init(g_settings)) {
|
2021-08-09 19:16:39 -04:00
|
|
|
lg::error("Gfx::Init error");
|
2021-03-09 23:51:28 -05:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_main_thread_id != std::this_thread::get_id()) {
|
2022-06-16 22:46:12 -04:00
|
|
|
lg::error("Ran Gfx::Init outside main thread. Init display elsewhere?");
|
2021-03-09 23:51:28 -05:00
|
|
|
} else {
|
2022-06-30 21:11:58 -04:00
|
|
|
Display::InitMainDisplay(640, 480,
|
|
|
|
fmt::format("OpenGOAL - Work in Progress - {}", GIT_VERSION).c_str(),
|
|
|
|
g_settings, version);
|
2021-03-09 23:51:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-06-23 22:07:17 -04:00
|
|
|
void Loop(std::function<bool()> f) {
|
2021-08-09 19:16:39 -04:00
|
|
|
lg::info("GFX Loop");
|
2021-06-23 22:07:17 -04:00
|
|
|
while (f()) {
|
2021-08-09 19:16:39 -04:00
|
|
|
// check if we have a display
|
|
|
|
if (Display::GetMainDisplay()) {
|
2021-06-23 22:07:17 -04:00
|
|
|
// lg::debug("run display");
|
2022-06-16 22:46:12 -04:00
|
|
|
Display::GetMainDisplay()->render();
|
2021-06-23 22:07:17 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-09 23:51:28 -05:00
|
|
|
u32 Exit() {
|
2021-08-09 19:16:39 -04:00
|
|
|
lg::info("GFX Exit");
|
2021-08-13 20:06:16 -04:00
|
|
|
Display::KillMainDisplay();
|
2021-08-16 10:43:12 -04:00
|
|
|
GetCurrentRenderer()->exit();
|
2021-03-09 23:51:28 -05:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-08-14 17:21:02 -04:00
|
|
|
void register_vsync_callback(std::function<void()> f) {
|
|
|
|
vsync_callback = std::move(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear_vsync_callback() {
|
|
|
|
vsync_callback = nullptr;
|
|
|
|
}
|
|
|
|
|
2021-08-09 21:42:05 -04:00
|
|
|
u32 vsync() {
|
2021-12-30 18:48:37 -05:00
|
|
|
if (GetCurrentRenderer()) {
|
2022-08-14 17:21:02 -04:00
|
|
|
// Inform the IOP kernel that we're vsyncing so it can run the vblank handler
|
|
|
|
if (vsync_callback != nullptr)
|
|
|
|
vsync_callback();
|
2021-12-30 18:48:37 -05:00
|
|
|
return GetCurrentRenderer()->vsync();
|
|
|
|
}
|
|
|
|
return 0;
|
2021-08-09 21:42:05 -04:00
|
|
|
}
|
|
|
|
|
2021-08-10 21:31:15 -04:00
|
|
|
u32 sync_path() {
|
2021-12-30 18:48:37 -05:00
|
|
|
if (GetCurrentRenderer()) {
|
|
|
|
return GetCurrentRenderer()->sync_path();
|
|
|
|
}
|
|
|
|
return 0;
|
2021-08-10 21:31:15 -04:00
|
|
|
}
|
|
|
|
|
2021-08-09 21:42:05 -04:00
|
|
|
void send_chain(const void* data, u32 offset) {
|
2021-08-16 10:43:12 -04:00
|
|
|
if (GetCurrentRenderer()) {
|
|
|
|
GetCurrentRenderer()->send_chain(data, offset);
|
2021-08-09 21:54:40 -04:00
|
|
|
}
|
2021-08-09 21:42:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void texture_upload_now(const u8* tpage, int mode, u32 s7_ptr) {
|
2021-08-16 10:43:12 -04:00
|
|
|
if (GetCurrentRenderer()) {
|
|
|
|
GetCurrentRenderer()->texture_upload_now(tpage, mode, s7_ptr);
|
2021-08-09 21:54:40 -04:00
|
|
|
}
|
2021-08-09 21:42:05 -04:00
|
|
|
}
|
|
|
|
|
2021-08-11 19:36:15 -04:00
|
|
|
void texture_relocate(u32 destination, u32 source, u32 format) {
|
2021-08-16 10:43:12 -04:00
|
|
|
if (GetCurrentRenderer()) {
|
|
|
|
GetCurrentRenderer()->texture_relocate(destination, source, format);
|
2021-08-09 21:54:40 -04:00
|
|
|
}
|
2021-08-09 21:42:05 -04:00
|
|
|
}
|
|
|
|
|
2022-03-02 20:01:37 -05:00
|
|
|
void set_levels(const std::vector<std::string>& levels) {
|
|
|
|
if (GetCurrentRenderer()) {
|
|
|
|
GetCurrentRenderer()->set_levels(levels);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-15 22:50:36 -04:00
|
|
|
void poll_events() {
|
2022-06-16 22:46:12 -04:00
|
|
|
if (GetCurrentRenderer()) {
|
|
|
|
GetCurrentRenderer()->poll_events();
|
|
|
|
}
|
2021-08-15 22:50:36 -04:00
|
|
|
}
|
|
|
|
|
2021-12-30 18:48:37 -05:00
|
|
|
u64 get_window_width() {
|
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
return Display::GetMainDisplay()->width();
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
u64 get_window_height() {
|
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
return Display::GetMainDisplay()->height();
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_window_size(u64 w, u64 h) {
|
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
Display::GetMainDisplay()->set_size(w, h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void get_window_scale(float* x, float* y) {
|
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
Display::GetMainDisplay()->get_scale(x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-19 23:28:20 -05:00
|
|
|
std::tuple<double, double> get_mouse_pos() {
|
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
return Display::GetMainDisplay()->get_mouse_pos();
|
|
|
|
} else {
|
|
|
|
return {0, 0};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 22:46:12 -04:00
|
|
|
GfxDisplayMode get_fullscreen() {
|
2022-04-11 18:38:54 -04:00
|
|
|
if (Display::GetMainDisplay()) {
|
2022-07-31 13:31:17 -04:00
|
|
|
return Display::GetMainDisplay()->fullscreen_mode();
|
2022-04-11 18:38:54 -04:00
|
|
|
} else {
|
2022-06-16 22:46:12 -04:00
|
|
|
return GfxDisplayMode::Windowed;
|
2022-04-11 18:38:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-25 11:05:20 -04:00
|
|
|
int get_screen_vmode_count() {
|
2022-04-11 18:38:54 -04:00
|
|
|
if (Display::GetMainDisplay()) {
|
2022-06-25 11:05:20 -04:00
|
|
|
return Display::GetMainDisplay()->get_screen_vmode_count();
|
2022-04-11 18:38:54 -04:00
|
|
|
}
|
2022-06-25 11:05:20 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int get_screen_rate(s64 vmode_idx) {
|
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
return Display::GetMainDisplay()->get_screen_rate(vmode_idx);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-07-31 13:31:17 -04:00
|
|
|
int get_monitor_count() {
|
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
return Display::GetMainDisplay()->get_monitor_count();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-06-25 11:05:20 -04:00
|
|
|
void get_screen_size(s64 vmode_idx, s32* w, s32* h) {
|
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
Display::GetMainDisplay()->get_screen_size(vmode_idx, w, h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_vsync(bool vsync) {
|
|
|
|
g_global_settings.vsync = vsync;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_frame_rate(int rate) {
|
|
|
|
g_global_settings.target_fps = rate;
|
2022-04-11 18:38:54 -04:00
|
|
|
}
|
|
|
|
|
2021-12-30 18:48:37 -05:00
|
|
|
void set_letterbox(int w, int h) {
|
|
|
|
g_global_settings.lbox_w = w;
|
|
|
|
g_global_settings.lbox_h = h;
|
|
|
|
}
|
|
|
|
|
2022-06-16 22:46:12 -04:00
|
|
|
void set_fullscreen(GfxDisplayMode mode, int screen) {
|
2021-12-30 18:48:37 -05:00
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
Display::GetMainDisplay()->set_fullscreen(mode, screen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-21 19:21:51 -04:00
|
|
|
void set_window_lock(bool lock) {
|
|
|
|
if (Display::GetMainDisplay()) {
|
|
|
|
Display::GetMainDisplay()->set_lock(lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-14 21:37:03 -04:00
|
|
|
void set_game_resolution(int w, int h) {
|
|
|
|
g_global_settings.game_res_w = w;
|
|
|
|
g_global_settings.game_res_h = h;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_msaa(int samples) {
|
|
|
|
g_global_settings.msaa_samples = samples;
|
|
|
|
}
|
|
|
|
|
2021-08-16 02:44:05 -04:00
|
|
|
void input_mode_set(u32 enable) {
|
2022-06-08 18:34:52 -04:00
|
|
|
if (enable == s7.offset + jak1_symbols::FIX_SYM_TRUE) { // #t
|
2021-12-04 15:34:03 -05:00
|
|
|
Pad::g_input_mode_mapping = g_settings.pad_mapping_info;
|
2021-08-16 02:44:05 -04:00
|
|
|
Pad::EnterInputMode();
|
|
|
|
} else {
|
|
|
|
Pad::ExitInputMode(enable != s7.offset); // use #f for graceful exit, or 'canceled for abrupt
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-16 09:57:15 -04:00
|
|
|
void input_mode_save() {
|
|
|
|
if (Pad::input_mode_get() == (u64)Pad::InputModeStatus::Enabled) {
|
|
|
|
lg::error("Can't save controller mapping while mapping controller.");
|
|
|
|
} else if (Pad::input_mode_get() == (u64)Pad::InputModeStatus::Disabled) {
|
2021-08-16 11:01:34 -04:00
|
|
|
g_settings.pad_mapping_info_backup = g_settings.pad_mapping_info; // copy to backup
|
|
|
|
g_settings.pad_mapping_info = Pad::g_input_mode_mapping; // set current mapping
|
2021-08-16 10:43:12 -04:00
|
|
|
|
2022-08-19 11:28:06 -04:00
|
|
|
SavePeripheralSettings();
|
2021-08-16 09:57:15 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s64 get_mapped_button(s64 pad, s64 button) {
|
|
|
|
if (pad < 0 || pad > Pad::CONTROLLER_COUNT || button < 0 || button > 16) {
|
|
|
|
lg::error("Invalid parameters to get_mapped_button({}, {})", pad, button);
|
|
|
|
return -1;
|
|
|
|
}
|
2022-08-19 11:28:06 -04:00
|
|
|
|
|
|
|
return (Pad::GetGamepadState(pad) > -1)
|
|
|
|
? (s64)g_settings.pad_mapping_info.controller_button_mapping[pad][button]
|
|
|
|
: (s64)g_settings.pad_mapping_info.keyboard_button_mapping[pad][button];
|
2021-08-16 09:57:15 -04:00
|
|
|
}
|
|
|
|
|
2021-08-14 16:00:50 -04:00
|
|
|
int PadIsPressed(Pad::Button button, int port) {
|
|
|
|
return Pad::IsPressed(g_settings.pad_mapping_info, button, port);
|
|
|
|
}
|
|
|
|
|
2022-08-19 11:28:06 -04:00
|
|
|
int PadGetAnalogValue(Pad::Analog analog, int port) {
|
|
|
|
return Pad::GetAnalogValue(g_settings.pad_mapping_info, analog, port);
|
2021-11-13 22:41:15 -05:00
|
|
|
}
|
|
|
|
|
2022-02-15 18:42:48 -05:00
|
|
|
void SetLod(RendererTreeType tree, int lod) {
|
|
|
|
switch (tree) {
|
|
|
|
case RendererTreeType::TFRAG3:
|
|
|
|
g_global_settings.lod_tfrag = lod;
|
|
|
|
break;
|
|
|
|
case RendererTreeType::TIE3:
|
|
|
|
g_global_settings.lod_tie = lod;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
lg::error("Invalid tree {} specified for SetLod ({})", tree, lod);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-30 14:48:24 -04:00
|
|
|
bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id) {
|
|
|
|
int arr_idx = mask_id / 32;
|
|
|
|
int arr_ofs = mask_id % 32;
|
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Mode:
|
|
|
|
return (g_global_settings.collision_mode_mask[arr_idx] >> arr_ofs) & 1;
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Event:
|
|
|
|
return (g_global_settings.collision_event_mask[arr_idx] >> arr_ofs) & 1;
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Material:
|
|
|
|
return (g_global_settings.collision_material_mask[arr_idx] >> arr_ofs) & 1;
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Skip:
|
|
|
|
ASSERT(arr_idx == 0);
|
|
|
|
return (g_global_settings.collision_skip_mask >> arr_ofs) & 1;
|
|
|
|
default:
|
|
|
|
lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, mode, mask_id);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id) {
|
|
|
|
int arr_idx = mask_id / 32;
|
|
|
|
int arr_ofs = mask_id % 32;
|
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Mode:
|
|
|
|
g_global_settings.collision_mode_mask[arr_idx] |= 1 << arr_ofs;
|
|
|
|
break;
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Event:
|
|
|
|
g_global_settings.collision_event_mask[arr_idx] |= 1 << arr_ofs;
|
|
|
|
break;
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Material:
|
|
|
|
g_global_settings.collision_material_mask[arr_idx] |= 1 << arr_ofs;
|
|
|
|
break;
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Skip:
|
|
|
|
ASSERT(arr_idx == 0);
|
|
|
|
g_global_settings.collision_skip_mask |= 1 << arr_ofs;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, mode, mask_id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id) {
|
|
|
|
int arr_idx = mask_id / 32;
|
|
|
|
int arr_ofs = mask_id % 32;
|
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Mode:
|
|
|
|
g_global_settings.collision_mode_mask[arr_idx] &= ~(1 << arr_ofs);
|
|
|
|
break;
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Event:
|
|
|
|
g_global_settings.collision_event_mask[arr_idx] &= ~(1 << arr_ofs);
|
|
|
|
break;
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Material:
|
|
|
|
g_global_settings.collision_material_mask[arr_idx] &= ~(1 << arr_ofs);
|
|
|
|
break;
|
|
|
|
case GfxGlobalSettings::CollisionRendererMode::Skip:
|
|
|
|
ASSERT(arr_idx == 0);
|
|
|
|
g_global_settings.collision_skip_mask &= ~(1 << arr_ofs);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, mode, mask_id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CollisionRendererSetMode(GfxGlobalSettings::CollisionRendererMode mode) {
|
|
|
|
g_global_settings.collision_mode = mode;
|
|
|
|
}
|
|
|
|
|
2021-03-09 23:51:28 -05:00
|
|
|
} // namespace Gfx
|