Files
Tyler Wilding d3cc739e43 jakx: Commit existing work from other PRs (#4112)
This attempts to get into master whatever work was done in this PR /
it's earlier PR https://github.com/open-goal/jak-project/pull/3965

I don't want this work to be lost / floating around in massive PRs.

However the changes are:
- switch to ntsc_v1 instead of PAL as the development target, as we have
done for all other games
- remove most of the copied-from-jak2/3 changes as they need to be
confirmed during the decompilation process not just assumed
- avoids committing any changes to `game/kernel/common` as it was not
clear to me if these were changes made in jak x's kernel that were not
properly broken out into it's own functions. We don't want to
accidentally introduce bugs into jak1-3's kernel code.
- in other words, if the change in the kernel only happens in jak x...it
should likely be specific to jak x's kernel, not common.

---------

Co-authored-by: VodBox <dillon@vodbox.io>
Co-authored-by: yodah <greenboyyodah@gmail.com>
2025-12-31 21:08:44 -05:00

225 lines
6.7 KiB
C++

/*!
* @file gfx.cpp
* Graphics component for the runtime. Abstraction layer for the main graphics routines.
*/
#include "gfx.h"
#include <cstdio>
#include <functional>
#include <utility>
#include "display.h"
#include "common/global_profiler/GlobalProfiler.h"
#include "common/log/log.h"
#include "common/symbols.h"
#include "common/util/FileUtil.h"
#include "common/util/json_util.h"
#include "game/common/file_paths.h"
#include "game/kernel/common/kmachine.h"
#include "game/kernel/common/kscheme.h"
#include "game/runtime.h"
#include "pipelines/opengl.h"
namespace Gfx {
std::function<void()> vsync_callback;
GfxGlobalSettings g_global_settings;
game_settings::DebugSettings g_debug_settings;
const GfxRendererModule* GetRenderer(GfxPipeline pipeline) {
switch (pipeline) {
case GfxPipeline::Invalid:
lg::error("Requested invalid renderer", fmt::underlying(pipeline));
return NULL;
case GfxPipeline::OpenGL:
return &gRendererOpenGL;
default:
lg::error("Requested unknown renderer {}", fmt::underlying(pipeline));
return NULL;
}
}
void SetRenderer(GfxPipeline pipeline) {
g_global_settings.renderer = GetRenderer(pipeline);
}
const GfxRendererModule* GetCurrentRenderer() {
return g_global_settings.renderer;
}
u32 Init(GameVersion version) {
lg::info("GFX Init");
prof().instant_event("ROOT");
g_debug_settings = game_settings::DebugSettings();
g_debug_settings.load_settings();
{
auto p = scoped_prof("startup::gfx::get_renderer");
g_global_settings.renderer = GetRenderer(GfxPipeline::OpenGL);
}
{
auto p = scoped_prof("startup::gfx::init_current_renderer");
if (GetCurrentRenderer()->init(g_global_settings)) {
lg::error("Gfx::Init error");
return 1;
}
}
if (g_main_thread_id != std::this_thread::get_id()) {
lg::error("Ran Gfx::Init outside main thread. Init display elsewhere?");
} else {
{
auto p = scoped_prof("startup::gfx::init_main_display");
std::string title = "OpenGOAL";
if (g_game_version == GameVersion::Jak2 || g_game_version == GameVersion::Jak3 ||
g_game_version == GameVersion::JakX) {
title += " - Work in Progress";
}
title += fmt::format(" - {} - {}", version_to_game_name_external(g_game_version),
build_revision());
Display::InitMainDisplay(640, 480, title.c_str(), g_global_settings, version);
}
}
return 0;
}
void Loop(std::function<bool()> f) {
lg::info("GFX Loop");
while (f()) {
auto p = scoped_prof("gfx loop");
// check if we have a display
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->render();
}
}
}
u32 Exit() {
lg::info("GFX Exit");
Display::KillMainDisplay();
GetCurrentRenderer()->exit();
g_debug_settings.save_settings();
return 0;
}
void register_vsync_callback(std::function<void()> f) {
vsync_callback = std::move(f);
}
void clear_vsync_callback() {
vsync_callback = nullptr;
}
u32 vsync() {
if (GetCurrentRenderer()) {
// Inform the IOP kernel that we're vsyncing so it can run the vblank handler
if (vsync_callback != nullptr)
vsync_callback();
return GetCurrentRenderer()->vsync();
}
return 0;
}
u32 sync_path() {
if (GetCurrentRenderer()) {
return GetCurrentRenderer()->sync_path();
}
return 0;
}
bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 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:
if (mask_id == -1) {
return g_global_settings.collision_skip_nomask_allowed;
} else {
return g_global_settings.collision_skip_mask & mask_id;
}
case GfxGlobalSettings::CollisionRendererMode::SkipHide:
return g_global_settings.collision_skip_hide_mask & mask_id;
default:
lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, fmt::underlying(mode), mask_id);
return false;
}
}
void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 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:
if (mask_id == -1) {
g_global_settings.collision_skip_nomask_allowed = true;
} else {
g_global_settings.collision_skip_mask |= mask_id;
}
break;
case GfxGlobalSettings::CollisionRendererMode::SkipHide:
g_global_settings.collision_skip_hide_mask |= mask_id;
break;
default:
lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, fmt::underlying(mode), mask_id);
break;
}
}
void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, s64 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:
if (mask_id == -1) {
g_global_settings.collision_skip_nomask_allowed = false;
} else {
g_global_settings.collision_skip_mask &= ~mask_id;
}
break;
case GfxGlobalSettings::CollisionRendererMode::SkipHide:
g_global_settings.collision_skip_hide_mask &= ~mask_id;
break;
default:
lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, fmt::underlying(mode), mask_id);
break;
}
}
void CollisionRendererSetMode(GfxGlobalSettings::CollisionRendererMode mode) {
g_global_settings.collision_mode = mode;
}
} // namespace Gfx