game: Migrate from GLFW to SDL2 & attempt to rewrite / simplify display and input code (#2397)

Co-authored-by: Hat Kid <6624576+Hat-Kid@users.noreply.github.com>
This commit is contained in:
Tyler Wilding
2023-06-04 14:34:37 -05:00
committed by GitHub
parent 08741f0a42
commit bdaf088d4b
1973 changed files with 903017 additions and 118529 deletions
+521 -186
View File
@@ -9,6 +9,8 @@
#include "common/util/Timer.h"
#include "common/util/string_util.h"
#include "game/external/discord.h"
#include "game/graphics/display.h"
#include "game/graphics/gfx.h"
#include "game/kernel/common/Ptr.h"
#include "game/kernel/common/kernel_types.h"
@@ -19,6 +21,7 @@
#include "game/sce/libpad.h"
#include "game/sce/libscf.h"
#include "game/sce/sif_ee.h"
#include "game/system/vm/vm.h"
/*!
* Where does OVERLORD load its data from?
@@ -350,157 +353,6 @@ void DecodeTime(u32 ptr) {
sceCdReadClock(clock.c());
}
/*!
* PC PORT FUNCTIONS BEGIN
*/
/*!
* Get a 300MHz timer value.
* Called from EE thread
*/
u64 read_ee_timer() {
u64 ns = ee_clock_timer.getNs();
return (ns * 3) / 10;
}
/*!
* Do a fast memory copy.
*/
void c_memmove(u32 dst, u32 src, u32 size) {
memmove(Ptr<u8>(dst).c(), Ptr<u8>(src).c(), size);
}
void set_game_resolution(s64 w, s64 h) {
Gfx::set_game_resolution(w, h);
}
void set_msaa(s64 samples) {
Gfx::set_msaa(samples);
}
/*!
* Returns size of window. Called from game thread
*/
void get_window_size(u32 w_ptr, u32 h_ptr) {
if (w_ptr) {
auto w = Ptr<u32>(w_ptr).c();
*w = Gfx::get_window_width();
}
if (h_ptr) {
auto h = Ptr<u32>(h_ptr).c();
*h = Gfx::get_window_height();
}
}
/*!
* Returns scale of window. This is for DPI stuff.
*/
void get_window_scale(u32 x_ptr, u32 y_ptr) {
float* x = x_ptr ? Ptr<float>(x_ptr).c() : NULL;
float* y = y_ptr ? Ptr<float>(y_ptr).c() : NULL;
Gfx::get_window_scale(x, y);
}
/*!
* Returns resolution of the monitor.
*/
void get_screen_size(s64 vmode_idx, u32 w_ptr, u32 h_ptr) {
s32 *w_out = 0, *h_out = 0;
if (w_ptr) {
w_out = Ptr<s32>(w_ptr).c();
}
if (h_ptr) {
h_out = Ptr<s32>(h_ptr).c();
}
Gfx::get_screen_size(vmode_idx, w_out, h_out);
}
/*!
* Returns refresh rate of the monitor.
*/
s64 get_screen_rate(s64 vmode_idx) {
return Gfx::get_screen_rate(vmode_idx);
}
/*!
* Returns amount of video modes of the monitor.
*/
s64 get_screen_vmode_count() {
return Gfx::get_screen_vmode_count();
}
/*!
* Returns the number of available monitors.
*/
int get_monitor_count() {
return Gfx::get_monitor_count();
}
int get_unix_timestamp() {
return std::time(nullptr);
}
void mkdir_path(u32 filepath) {
auto filepath_str = std::string(Ptr<String>(filepath).c()->data());
file_util::create_dir_if_needed_for_file(filepath_str);
}
u64 filepath_exists(u32 filepath) {
auto filepath_str = std::string(Ptr<String>(filepath).c()->data());
if (fs::exists(filepath_str)) {
return s7.offset + true_symbol_offset(g_game_version);
}
return s7.offset;
}
void prof_event(u32 name, u32 kind) {
prof().event(Ptr<String>(name).c()->data(), (ProfNode::Kind)kind);
}
void set_frame_rate(s64 rate) {
Gfx::set_frame_rate(rate);
}
void set_vsync(u32 symptr) {
Gfx::set_vsync(symptr != s7.offset);
}
void set_window_lock(u32 symptr) {
Gfx::set_window_lock(symptr == s7.offset);
}
void set_collision(u32 symptr) {
Gfx::g_global_settings.collision_enable = symptr != s7.offset;
}
void set_collision_wireframe(u32 symptr) {
Gfx::g_global_settings.collision_wireframe = symptr != s7.offset;
}
void set_collision_mask(GfxGlobalSettings::CollisionRendererMode mode, int mask, u32 symptr) {
if (symptr != s7.offset) {
Gfx::CollisionRendererSetMask(mode, mask);
} else {
Gfx::CollisionRendererClearMask(mode, mask);
}
}
u32 get_collision_mask(GfxGlobalSettings::CollisionRendererMode mode, int mask) {
return Gfx::CollisionRendererGetMask(mode, mask) ? s7.offset + true_symbol_offset(g_game_version)
: s7.offset;
}
void set_gfx_hack(u64 which, u32 symptr) {
switch (which) {
case 0: // no tex
Gfx::g_global_settings.hack_no_tex = symptr != s7.offset;
break;
}
}
/*!
* PC PORT FUNCTIONS END
*/
void vif_interrupt_callback(int bucket_id) {
// added for the PC port for faking VIF interrupts from the graphics system.
if (vif1_interrupt_handler && MasterExit == RuntimeExitStatus::RUNNING) {
@@ -508,39 +360,18 @@ void vif_interrupt_callback(int bucket_id) {
}
}
/*!
* Added in PC port.
*/
/// PC PORT FUNCTIONS BEGIN
u32 offset_of_s7() {
return s7.offset;
}
/*!
* Called from the game thread at initialization.
* The game thread is the only one to touch the mips2c function table (through the linker and
* through this function), so no locking is needed.
*/
u64 pc_get_mips2c(u32 name) {
const char* n = Ptr<String>(name).c()->data();
return Mips2C::gLinkedFunctionTable.get(n);
inline bool symbol_to_bool(const u32 symptr) {
return symptr != s7.offset;
}
/*!
* Called from game thread to submit rendering DMA chain.
*/
void send_gfx_dma_chain(u32 /*bank*/, u32 chain) {
Gfx::send_chain(g_ee_main_mem, chain);
}
/*!
* Called from game thread to upload a texture outside of the main DMA chain.
*/
void pc_texture_upload_now(u32 page, u32 mode) {
Gfx::texture_upload_now(Ptr<u8>(page).c(), mode, s7.offset);
}
void pc_texture_relocate(u32 dst, u32 src, u32 format) {
Gfx::texture_relocate(dst, src, format);
inline u64 bool_to_symbol(const bool val) {
return val ? static_cast<u64>(s7.offset) + true_symbol_offset(g_game_version) : s7.offset;
}
u64 pc_filter_debug_string(u32 str_ptr, u32 dist_ptr) {
@@ -549,40 +380,544 @@ u64 pc_filter_debug_string(u32 str_ptr, u32 dist_ptr) {
memcpy(&dist, &dist_ptr, 4);
// Check distance first
if (Gfx::g_debug_settings.debug_text_check_range) {
if (dist / 4096.F > Gfx::g_debug_settings.debug_text_max_range) {
return s7.offset + true_symbol_offset(g_game_version);
if (Gfx::g_debug_settings.text_check_range) {
if (dist / 4096.F > Gfx::g_debug_settings.text_max_range) {
return bool_to_symbol(true);
}
}
// Get the current filters
const auto& filters = Gfx::g_debug_settings.debug_text_filters;
const auto& filters = Gfx::g_debug_settings.text_filters;
if (filters.empty()) {
// there are no filters, exit early
return s7.offset;
return bool_to_symbol(false);
}
// Currently very dumb contains check
for (const auto& filter : filters) {
if (filter.type == DebugTextFilter::Type::CONTAINS) {
if (!str.empty() && !filter.content.empty() && !str_util::contains(str, filter.content)) {
return s7.offset + true_symbol_offset(g_game_version);
return bool_to_symbol(true);
}
} else if (filter.type == DebugTextFilter::Type::NOT_CONTAINS) {
if (!str.empty() && !filter.content.empty() && str_util::contains(str, filter.content)) {
return s7.offset + true_symbol_offset(g_game_version);
return bool_to_symbol(true);
}
} else if (filter.type == DebugTextFilter::Type::REGEX) {
if (str_util::valid_regex(filter.content) &&
std::regex_match(str, std::regex(filter.content))) {
return s7.offset + true_symbol_offset(g_game_version);
return bool_to_symbol(true);
}
}
}
return bool_to_symbol(false);
}
CommonPCPortFunctionWrappers g_pc_port_funcs;
u64 read_ee_timer() {
u64 ns = ee_clock_timer.getNs();
return (ns * 3) / 10;
}
void pc_memmove(u32 dst, u32 src, u32 size) {
memmove(Ptr<u8>(dst).c(), Ptr<u8>(src).c(), size);
}
void send_gfx_dma_chain(u32 bank, u32 chain) {
if (Gfx::GetCurrentRenderer()) {
Gfx::GetCurrentRenderer()->send_chain(g_ee_main_mem, chain);
}
}
void pc_texture_upload_now(u32 page, u32 mode) {
if (Gfx::GetCurrentRenderer()) {
Gfx::GetCurrentRenderer()->texture_upload_now(Ptr<u8>(page).c(), mode, s7.offset);
}
}
void pc_texture_relocate(u32 dst, u32 src, u32 format) {
if (Gfx::GetCurrentRenderer()) {
Gfx::GetCurrentRenderer()->texture_relocate(dst, src, format);
}
}
u64 pc_get_mips2c(u32 name) {
const char* n = Ptr<String>(name).c()->data();
return Mips2C::gLinkedFunctionTable.get(n);
}
u64 pc_get_display_name(u32 id) {
std::string name = "";
if (Display::GetMainDisplay()) {
name = Display::GetMainDisplay()->get_display_manager()->get_connected_display_name(id);
}
if (name.empty()) {
return s7.offset;
}
return g_pc_port_funcs.make_string_from_c(str_util::to_upper(name).c_str());
}
u32 pc_get_display_mode() {
auto display_mode = WindowDisplayMode::Windowed;
if (Display::GetMainDisplay()) {
display_mode = Display::GetMainDisplay()->get_display_manager()->get_window_display_mode();
}
switch (display_mode) {
case WindowDisplayMode::Borderless:
return g_pc_port_funcs.intern_from_c("borderless").offset;
case WindowDisplayMode::Fullscreen:
return g_pc_port_funcs.intern_from_c("fullscreen").offset;
default:
case WindowDisplayMode::Windowed:
return g_pc_port_funcs.intern_from_c("windowed").offset;
}
}
void pc_set_display_mode(u32 symptr) {
if (!Display::GetMainDisplay()) {
return;
}
if (symptr == g_pc_port_funcs.intern_from_c("windowed").offset || symptr == s7.offset) {
Display::GetMainDisplay()->get_display_manager()->set_window_display_mode(
WindowDisplayMode::Windowed);
} else if (symptr == g_pc_port_funcs.intern_from_c("borderless").offset) {
Display::GetMainDisplay()->get_display_manager()->set_window_display_mode(
WindowDisplayMode::Borderless);
} else if (symptr == g_pc_port_funcs.intern_from_c("fullscreen").offset) {
Display::GetMainDisplay()->get_display_manager()->set_window_display_mode(
WindowDisplayMode::Fullscreen);
}
}
u64 pc_get_display_count() {
if (Display::GetMainDisplay()) {
return Display::GetMainDisplay()->get_display_manager()->num_connected_displays();
}
return 0;
}
void pc_get_active_display_size(u32 w_ptr, u32 h_ptr) {
if (!Display::GetMainDisplay()) {
return;
}
if (w_ptr) {
auto w_out = Ptr<u32>(w_ptr).c();
if (w_out) {
*w_out = Display::GetMainDisplay()->get_display_manager()->get_screen_width();
}
}
if (h_ptr) {
auto h_out = Ptr<u32>(h_ptr).c();
if (h_out) {
*h_out = Display::GetMainDisplay()->get_display_manager()->get_screen_height();
}
}
}
s64 pc_get_active_display_refresh_rate() {
if (Display::GetMainDisplay()) {
return Display::GetMainDisplay()->get_display_manager()->get_active_display_refresh_rate();
}
return 0;
}
void pc_get_window_size(u32 w_ptr, u32 h_ptr) {
if (!Display::GetMainDisplay()) {
return;
}
if (w_ptr) {
auto w = Ptr<u32>(w_ptr).c();
if (w) {
*w = Display::GetMainDisplay()->get_display_manager()->get_window_width();
}
}
if (h_ptr) {
auto h = Ptr<u32>(h_ptr).c();
if (h) {
*h = Display::GetMainDisplay()->get_display_manager()->get_window_height();
}
}
}
void pc_get_window_scale(u32 x_ptr, u32 y_ptr) {
if (!Display::GetMainDisplay()) {
return;
}
if (x_ptr) {
auto x = Ptr<float>(x_ptr).c();
if (x) {
*x = Display::GetMainDisplay()->get_display_manager()->get_window_scale_x();
}
}
if (y_ptr) {
auto y = Ptr<float>(y_ptr).c();
if (y) {
*y = Display::GetMainDisplay()->get_display_manager()->get_window_scale_y();
}
}
}
void pc_get_fullscreen_display(u64 display_id) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_display_manager()->set_fullscreen_display_id(display_id);
}
}
void pc_set_window_size(u64 width, u64 height) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_display_manager()->set_window_size(width, height);
}
}
s64 pc_get_num_resolutions() {
if (Display::GetMainDisplay()) {
return Display::GetMainDisplay()->get_display_manager()->get_num_resolutions();
}
return 0;
}
void pc_get_resolution(u32 id, u32 w_ptr, u32 h_ptr) {
if (Display::GetMainDisplay()) {
auto res = Display::GetMainDisplay()->get_display_manager()->get_resolution(id);
auto w = Ptr<u32>(w_ptr).c();
if (w) {
*w = res.width;
}
auto h = Ptr<u32>(h_ptr).c();
if (h) {
*h = res.height;
}
}
}
u64 pc_get_controller_name(u32 id) {
std::string name = "";
if (Display::GetMainDisplay()) {
name = Display::GetMainDisplay()->get_input_manager()->get_controller_name(id);
}
if (name.empty()) {
return s7.offset;
}
return g_pc_port_funcs.make_string_from_c(str_util::to_upper(name).c_str());
}
u64 pc_get_current_bind(s32 bind_assignment_info) {
if (!Display::GetMainDisplay()) {
// TODO - return something that lets the runtime use a translatable string if unknown
return g_pc_port_funcs.make_string_from_c(str_util::to_upper("unknown").c_str());
}
auto info = bind_assignment_info ? Ptr<BindAssignmentInfo>(bind_assignment_info).c() : NULL;
auto port = (int)info->port;
auto device_type = (int)info->device_type;
auto for_button = info->buttons != s7.offset;
auto input_idx = (int)info->input_idx;
auto analog_min_range = info->analog_min_range != s7.offset;
if (Display::GetMainDisplay()) {
auto name = Display::GetMainDisplay()->get_input_manager()->get_current_bind(
port, (InputDeviceType)device_type, for_button, input_idx, analog_min_range);
if (name.empty()) {
return s7.offset;
}
return g_pc_port_funcs.make_string_from_c(str_util::to_upper(name).c_str());
}
// TODO - return something that lets the runtime use a translatable string if unknown
return g_pc_port_funcs.make_string_from_c(str_util::to_upper("unknown").c_str());
}
u64 pc_get_controller_count() {
if (Display::GetMainDisplay()) {
return Display::GetMainDisplay()->get_input_manager()->get_num_controllers();
}
return 0;
}
void pc_get_controller(u32 controller_id, u32 port) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_input_manager()->set_controller_for_port(controller_id, port);
}
}
void pc_set_keyboard_enabled(u32 sym_val) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_input_manager()->enable_keyboard(symbol_to_bool(sym_val));
}
}
void pc_set_mouse_options(u32 enabled, u32 control_camera, u32 control_movement) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_input_manager()->update_mouse_options(
symbol_to_bool(enabled), symbol_to_bool(control_camera), symbol_to_bool(control_movement));
}
}
void pc_set_mouse_camera_sens(u32 xsens, u32 ysens) {
float xsens_val;
memcpy(&xsens_val, &xsens, 4);
float ysens_val;
memcpy(&ysens_val, &ysens, 4);
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_input_manager()->set_camera_sens(xsens_val, ysens_val);
}
}
void pc_ignore_background_controller_events(u32 sym_val) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_input_manager()->ignore_background_controller_events(
symbol_to_bool(sym_val));
}
}
u64 pc_current_controller_has_led() {
if (Display::GetMainDisplay()) {
return bool_to_symbol(Display::GetMainDisplay()->get_input_manager()->controller_has_led(0));
}
return bool_to_symbol(false);
}
void pc_set_controller_led(const int port, const u8 red, const u8 green, const u8 blue) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_input_manager()->set_controller_led(port, red, green, blue);
}
}
u64 pc_waiting_for_bind() {
if (Display::GetMainDisplay()) {
return bool_to_symbol(Display::GetMainDisplay()->get_input_manager()->get_waiting_for_bind());
}
return bool_to_symbol(false);
}
void pc_set_waiting_for_bind(InputDeviceType device_type,
u32 for_analog,
u32 for_minimum_analog,
s32 input_idx) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_input_manager()->set_wait_for_bind(
device_type, symbol_to_bool(for_analog), symbol_to_bool(for_minimum_analog), input_idx);
}
}
void pc_stop_waiting_for_bind() {
if (Display::GetMainDisplay()) {
return Display::GetMainDisplay()->get_input_manager()->stop_waiting_for_bind();
}
}
void pc_reset_bindings_to_defaults(const int port, const InputDeviceType device_type) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_input_manager()->reset_input_bindings_to_defaults(port,
device_type);
}
}
void pc_set_auto_hide_cursor(u32 val) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_input_manager()->set_auto_hide_mouse(symbol_to_bool(val));
}
}
void pc_set_vsync(u32 sym_val) {
Gfx::g_global_settings.vsync = symbol_to_bool(sym_val);
}
void pc_set_msaa(int samples) {
Gfx::g_global_settings.msaa_samples = samples;
}
void pc_set_frame_rate(int rate) {
Gfx::g_global_settings.target_fps = rate;
}
void pc_set_game_resolution(int w, int h) {
Gfx::g_global_settings.game_res_w = w;
Gfx::g_global_settings.game_res_h = h;
}
void pc_set_letterbox(int w, int h) {
Gfx::g_global_settings.lbox_w = w;
Gfx::g_global_settings.lbox_h = h;
}
void pc_renderer_tree_set_lod(Gfx::RendererTreeType tree, int lod) {
switch (tree) {
case Gfx::RendererTreeType::TFRAG3:
Gfx::g_global_settings.lod_tfrag = lod;
break;
case Gfx::RendererTreeType::TIE3:
Gfx::g_global_settings.lod_tie = lod;
break;
default:
lg::error("Invalid tree {} specified for SetLod ({})", fmt::underlying(tree), lod);
break;
}
}
void pc_set_collision_mask(GfxGlobalSettings::CollisionRendererMode mode, int mask, u32 symptr) {
if (!symbol_to_bool(symptr)) {
Gfx::CollisionRendererSetMask(mode, mask);
} else {
Gfx::CollisionRendererClearMask(mode, mask);
}
}
u32 pc_get_collision_mask(GfxGlobalSettings::CollisionRendererMode mode, int mask) {
return Gfx::CollisionRendererGetMask(mode, mask) ? s7.offset + true_symbol_offset(g_game_version)
: s7.offset;
}
void pc_set_collision_wireframe(u32 symptr) {
Gfx::g_global_settings.collision_wireframe = symbol_to_bool(symptr);
}
void pc_set_collision(u32 symptr) {
Gfx::g_global_settings.collision_enable = symbol_to_bool(symptr);
}
void pc_set_gfx_hack(u64 which, u32 symptr) {
switch (which) {
case 0: // no tex
Gfx::g_global_settings.hack_no_tex = symbol_to_bool(symptr);
break;
}
}
u32 pc_get_os() {
#ifdef _WIN32
return g_pc_port_funcs.intern_from_c("windows").offset;
#elif __linux__
return g_pc_port_funcs.intern_from_c("linux").offset;
#elif __APPLE__
return g_pc_port_funcs.intern_from_c("darwin").offset;
#else
return s7.offset;
#endif
}
time_t pc_get_unix_timestamp() {
return std::time(nullptr);
}
u64 pc_filepath_exists(u32 filepath) {
auto filepath_str = std::string(Ptr<String>(filepath).c()->data());
return bool_to_symbol(fs::exists(filepath_str));
}
u64 pc_mkdir_filepath(u32 filepath) {
auto filepath_str = std::string(Ptr<String>(filepath).c()->data());
return bool_to_symbol(file_util::create_dir_if_needed_for_file(filepath_str));
}
void pc_prof(u32 name, ProfNode::Kind kind) {
prof().event(Ptr<String>(name).c()->data(), kind);
}
std::mt19937 extra_random_generator;
u32 pc_rand() {
return (u32)extra_random_generator();
}
/// Initializes all functions that are common across all game versions
/// These functions have the same implementation and do not use any game specific functions (other
/// than the one to create a function in the first place)
void init_common_pc_port_functions(
std::function<Ptr<Function>(const char*, void*)> make_func_symbol_func,
std::function<InternFromCInfo(const char*)> intern_from_c_func,
std::function<u64(const char*)> make_string_from_c_func) {
g_pc_port_funcs.intern_from_c = intern_from_c_func;
g_pc_port_funcs.make_string_from_c = make_string_from_c_func;
// Get a 300MHz timer value. Called from EE thread
make_func_symbol_func("__read-ee-timer", (void*)read_ee_timer);
// Do a fast memory copy.
make_func_symbol_func("__mem-move", (void*)pc_memmove);
// Called from game thread to submit rendering DMA chain.
make_func_symbol_func("__send-gfx-dma-chain", (void*)send_gfx_dma_chain);
// Called from game thread to upload a texture outside of the main DMA chain.
make_func_symbol_func("__pc-texture-upload-now", (void*)pc_texture_upload_now);
make_func_symbol_func("__pc-texture-relocate", (void*)pc_texture_relocate);
// Called from the game thread at initialization. The game thread is the only one to touch the
// mips2c function table (through the linker and ugh this function), so no locking is needed.
make_func_symbol_func("__pc-get-mips2c", (void*)pc_get_mips2c);
// -- DISPLAY RELATED --
// Returns the name of the display with the given id or #f if not found / empty
make_func_symbol_func("pc-get-display-name", (void*)pc_get_display_name);
make_func_symbol_func("pc-get-display-mode", (void*)pc_get_display_mode);
make_func_symbol_func("pc-set-display-mode", (void*)pc_set_display_mode);
make_func_symbol_func("pc-get-display-count", (void*)pc_get_display_count);
// Returns resolution of the monitor's current display mode
make_func_symbol_func("pc-get-active-display-size", (void*)pc_get_active_display_size);
// Returns the current refresh rate of the currently selected monitor's display mode.
make_func_symbol_func("pc-get-active-display-refresh-rate",
(void*)pc_get_active_display_refresh_rate);
// Returns size of window. Called from game thread
make_func_symbol_func("pc-get-window-size", (void*)pc_get_window_size);
// Returns scale of window. This is for DPI stuff.
make_func_symbol_func("pc-get-window-scale", (void*)pc_get_window_scale);
make_func_symbol_func("pc-set-fullscreen-display", (void*)pc_get_fullscreen_display);
make_func_symbol_func("pc-set-window-size", (void*)pc_set_window_size);
make_func_symbol_func("pc-get-num-resolutions", (void*)pc_get_num_resolutions);
make_func_symbol_func("pc-get-resolution", (void*)pc_get_resolution);
// -- INPUT RELATED --
// Returns the name of the display with the given id or #f if not found / empty
make_func_symbol_func("pc-get-controller-name", (void*)pc_get_controller_name);
make_func_symbol_func("pc-get-current-bind", (void*)pc_get_current_bind);
make_func_symbol_func("pc-get-controller-count", (void*)pc_get_controller_count);
make_func_symbol_func("pc-set-controller!", (void*)pc_get_controller);
make_func_symbol_func("pc-set-keyboard-enabled!", (void*)pc_set_keyboard_enabled);
make_func_symbol_func("pc-set-mouse-options!", (void*)pc_set_mouse_options);
make_func_symbol_func("pc-set-mouse-camera-sens!", (void*)pc_set_mouse_camera_sens);
make_func_symbol_func("pc-ignore-background-controller-events!",
(void*)pc_ignore_background_controller_events);
make_func_symbol_func("pc-current-controller-has-led?", (void*)pc_current_controller_has_led);
make_func_symbol_func("pc-set-controller-led!", (void*)pc_set_controller_led);
make_func_symbol_func("pc-waiting-for-bind?", (void*)pc_waiting_for_bind);
make_func_symbol_func("pc-set-waiting-for-bind!", (void*)pc_set_waiting_for_bind);
make_func_symbol_func("pc-stop-waiting-for-bind!", (void*)pc_stop_waiting_for_bind);
make_func_symbol_func("pc-reset-bindings-to-defaults!", (void*)pc_reset_bindings_to_defaults);
make_func_symbol_func("pc-set-auto-hide-cursor!", (void*)pc_set_auto_hide_cursor);
// graphics things
make_func_symbol_func("pc-set-vsync", (void*)pc_set_vsync);
make_func_symbol_func("pc-set-msaa", (void*)pc_set_msaa);
make_func_symbol_func("pc-set-frame-rate", (void*)pc_set_frame_rate);
make_func_symbol_func("pc-set-game-resolution", (void*)pc_set_game_resolution);
make_func_symbol_func("pc-set-letterbox", (void*)pc_set_letterbox);
make_func_symbol_func("pc-renderer-tree-set-lod", (void*)pc_renderer_tree_set_lod);
make_func_symbol_func("pc-set-collision-mode", (void*)Gfx::CollisionRendererSetMode);
make_func_symbol_func("pc-set-collision-mask", (void*)pc_set_collision_mask);
make_func_symbol_func("pc-get-collision-mask", (void*)pc_get_collision_mask);
make_func_symbol_func("pc-set-collision-wireframe", (void*)pc_set_collision_wireframe);
make_func_symbol_func("pc-set-collision", (void*)pc_set_collision);
make_func_symbol_func("pc-set-gfx-hack", (void*)pc_set_gfx_hack);
// -- OTHER --
// Return the current OS as a symbol. Actually returns what it was compiled for!
make_func_symbol_func("pc-get-os", (void*)pc_get_os);
make_func_symbol_func("pc-get-unix-timestamp", (void*)pc_get_unix_timestamp);
// file related functions
make_func_symbol_func("pc-filepath-exists?", (void*)pc_filepath_exists);
make_func_symbol_func("pc-mkdir-file-path", (void*)pc_mkdir_filepath);
// discord rich presence
make_func_symbol_func("pc-discord-rpc-set", (void*)set_discord_rpc);
// profiler
make_func_symbol_func("pc-prof", (void*)pc_prof);
// RNG
make_func_symbol_func("pc-rand", (void*)pc_rand);
// debugging tools
make_func_symbol_func("pc-filter-debug-string?", (void*)pc_filter_debug_string);
// init ps2 VM
if (VM::use) {
make_func_symbol_func("vm-ptr", (void*)VM::get_vm_ptr);
VM::vm_init();
}
}