mirror of
https://github.com/open-goal/jak-project
synced 2026-09-06 19:21:00 -04:00
split game framebuffers to allow custom resolutions/shaders (#1641)
* split rendering framebuffer * fix blackout * unhardcode c++ stuff * optimization * implement goal side of all this * fix msaa * sprite distort fixes * fix resolution menu options * save & load msaa * linear filtering on the game screen * fix bad texture units * fun! * unused * make screenshot button capture the framebuffer and not the window buffer * panik * screenshot settings * fix black screen on first frame of new framebuffer * default fullscreen resolution to the screen size * hide funny resolutions in windowed since it makes no sense
This commit is contained in:
@@ -274,6 +274,15 @@ void set_window_lock(bool lock) {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void input_mode_set(u32 enable) {
|
||||
if (enable == s7.offset + jak1_symbols::FIX_SYM_TRUE) { // #t
|
||||
Pad::g_input_mode_mapping = g_settings.pad_mapping_info;
|
||||
|
||||
@@ -76,6 +76,13 @@ struct GfxGlobalSettings {
|
||||
int lbox_w;
|
||||
int lbox_h;
|
||||
|
||||
// actual game resolution
|
||||
int game_res_w = 640;
|
||||
int game_res_h = 480;
|
||||
|
||||
// multi-sampled anti-aliasing sample count. 1 = disabled.
|
||||
int msaa_samples = 4;
|
||||
|
||||
// current renderer
|
||||
const GfxRendererModule* renderer;
|
||||
|
||||
@@ -137,6 +144,8 @@ void set_vsync(bool vsync);
|
||||
void set_letterbox(int w, int h);
|
||||
void set_fullscreen(GfxDisplayMode mode, int screen);
|
||||
void set_window_lock(bool lock);
|
||||
void set_game_resolution(int w, int h);
|
||||
void set_msaa(int samples);
|
||||
void input_mode_set(u32 enable);
|
||||
void input_mode_save();
|
||||
s64 get_mapped_button(s64 pad, s64 button);
|
||||
|
||||
@@ -16,6 +16,41 @@ struct LevelVis {
|
||||
u8 data[2048];
|
||||
};
|
||||
|
||||
struct FboState {
|
||||
GLuint fbo = -1;
|
||||
GLuint tex = -1;
|
||||
GLuint fbo2 = -1;
|
||||
GLuint tex2 = -1;
|
||||
GLuint zbuf = -1;
|
||||
GLenum render_targets[1] = {GL_COLOR_ATTACHMENT0};
|
||||
int width = 640;
|
||||
int height = 480;
|
||||
int msaa = 4;
|
||||
|
||||
void delete_objects() {
|
||||
if (fbo != -1) {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
fbo = -1;
|
||||
}
|
||||
if (tex != -1) {
|
||||
glDeleteTextures(1, &tex);
|
||||
tex = -1;
|
||||
}
|
||||
if (fbo2 != -1) {
|
||||
glDeleteFramebuffers(1, &fbo2);
|
||||
fbo2 = -1;
|
||||
}
|
||||
if (tex2 != -1) {
|
||||
glDeleteTextures(1, &tex2);
|
||||
tex2 = -1;
|
||||
}
|
||||
if (zbuf != -1) {
|
||||
glDeleteRenderbuffers(1, &zbuf);
|
||||
zbuf = -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class EyeRenderer;
|
||||
/*!
|
||||
* The main renderer will contain a single SharedRenderState that's passed to all bucket renderers.
|
||||
@@ -61,6 +96,8 @@ struct SharedRenderState {
|
||||
int window_height_px;
|
||||
int window_offset_x_px;
|
||||
int window_offset_y_px;
|
||||
|
||||
FboState fbo_state;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
@@ -274,8 +274,7 @@ void OpenGLRenderer::init_bucket_renderers() {
|
||||
init_bucket_renderer<DirectRenderer>("debug", BucketCategory::OTHER, BucketId::DEBUG, 0x20000);
|
||||
init_bucket_renderer<DirectRenderer>("debug-no-zbuf", BucketCategory::OTHER,
|
||||
BucketId::DEBUG_NO_ZBUF, 0x8000);
|
||||
init_bucket_renderer<DirectRenderer>("subtitle", BucketCategory::OTHER, BucketId::SUBTITLE,
|
||||
0x2000);
|
||||
init_bucket_renderer<DirectRenderer>("subtitle", BucketCategory::OTHER, BucketId::SUBTITLE, 2000);
|
||||
|
||||
// for now, for any unset renderers, just set them to an EmptyBucketRenderer.
|
||||
for (size_t i = 0; i < m_bucket_renderers.size(); i++) {
|
||||
@@ -303,8 +302,7 @@ void OpenGLRenderer::render(DmaFollower dma, const RenderOptions& settings) {
|
||||
|
||||
{
|
||||
auto prof = m_profiler.root()->make_scoped_child("frame-setup");
|
||||
setup_frame(settings.window_width_px, settings.window_height_px, settings.lbox_width_px,
|
||||
settings.lbox_height_px);
|
||||
setup_frame(settings);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -364,8 +362,8 @@ void OpenGLRenderer::render(DmaFollower dma, const RenderOptions& settings) {
|
||||
}
|
||||
|
||||
if (settings.save_screenshot) {
|
||||
finish_screenshot(settings.screenshot_path, settings.window_width_px, settings.window_height_px,
|
||||
settings.lbox_width_px, settings.lbox_height_px);
|
||||
finish_screenshot(settings.screenshot_path, m_render_state.fbo_state.width,
|
||||
m_render_state.fbo_state.height, 0, 0, m_render_state.fbo_state.fbo2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,21 +402,104 @@ void OpenGLRenderer::draw_renderer_selection_window() {
|
||||
/*!
|
||||
* Pre-render frame setup.
|
||||
*/
|
||||
void OpenGLRenderer::setup_frame(int window_width_px,
|
||||
int window_height_px,
|
||||
int offset_x,
|
||||
int offset_y) {
|
||||
glViewport(offset_x, offset_y, window_width_px, window_height_px);
|
||||
void OpenGLRenderer::setup_frame(const RenderOptions& settings) {
|
||||
auto& fbo_state = m_render_state.fbo_state;
|
||||
|
||||
// restart the buffers if settings changed.
|
||||
if (settings.game_res_w != fbo_state.width || settings.game_res_h != fbo_state.height ||
|
||||
settings.msaa_samples != fbo_state.msaa) {
|
||||
fbo_state.delete_objects();
|
||||
}
|
||||
|
||||
if (fbo_state.fbo == -1 || fbo_state.fbo2 == -1 || fbo_state.tex == -1 || fbo_state.tex2 == -1 ||
|
||||
fbo_state.zbuf == -1) {
|
||||
fbo_state.width = settings.game_res_w;
|
||||
fbo_state.height = settings.game_res_h;
|
||||
fbo_state.msaa = settings.msaa_samples;
|
||||
|
||||
bool bad = false;
|
||||
|
||||
// make framebuffer object
|
||||
if (fbo_state.fbo == -1) {
|
||||
glGenFramebuffers(1, &fbo_state.fbo);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo_state.fbo);
|
||||
|
||||
// make texture that will hold the colors of the framebuffer
|
||||
if (fbo_state.tex == -1) {
|
||||
glGenTextures(1, &fbo_state.tex);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, fbo_state.tex);
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, fbo_state.msaa, GL_RGBA8, fbo_state.width,
|
||||
fbo_state.height, GL_TRUE);
|
||||
|
||||
// make depth and stencil buffers that will hold the... depth and stencil buffers
|
||||
if (fbo_state.zbuf == -1) {
|
||||
glGenRenderbuffers(1, &fbo_state.zbuf);
|
||||
}
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, fbo_state.zbuf);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, fbo_state.msaa, GL_DEPTH24_STENCIL8,
|
||||
fbo_state.width, fbo_state.height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
fbo_state.zbuf);
|
||||
|
||||
// attach texture to framebuffer as target for colors
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
|
||||
fbo_state.tex, 0);
|
||||
|
||||
glDrawBuffers(1, fbo_state.render_targets);
|
||||
|
||||
bad |= glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE;
|
||||
|
||||
// make framebuffer object
|
||||
if (fbo_state.fbo2 == -1) {
|
||||
glGenFramebuffers(1, &fbo_state.fbo2);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo_state.fbo2);
|
||||
|
||||
// make texture that will hold the msaa resolved color buffer
|
||||
if (fbo_state.tex2 == -1) {
|
||||
glGenTextures(1, &fbo_state.tex2);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE30);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_state.tex2);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, fbo_state.width, fbo_state.height, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// attach texture to framebuffer as target for colors
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_state.tex2, 0);
|
||||
|
||||
glDrawBuffers(1, fbo_state.render_targets);
|
||||
|
||||
bad |= glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE;
|
||||
|
||||
if (!bad) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo_state.fbo);
|
||||
} else {
|
||||
lg::error("bad framebuffer setup. fbo: {}, tex: {}, zbuf: {}, fbo2: {}, tex2: {}",
|
||||
fbo_state.fbo, fbo_state.tex, fbo_state.zbuf, fbo_state.fbo2, fbo_state.tex2);
|
||||
fbo_state.delete_objects();
|
||||
}
|
||||
} else {
|
||||
// we have the objects. bind framebuffer.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo_state.fbo);
|
||||
}
|
||||
glViewport(0, 0, settings.game_res_w, settings.game_res_h);
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClearDepth(0.0);
|
||||
glDepthMask(GL_TRUE);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
m_render_state.window_width_px = window_width_px;
|
||||
m_render_state.window_height_px = window_height_px;
|
||||
m_render_state.window_offset_x_px = offset_x;
|
||||
m_render_state.window_offset_y_px = offset_y;
|
||||
m_render_state.window_width_px = settings.window_width_px;
|
||||
m_render_state.window_height_px = settings.window_height_px;
|
||||
m_render_state.window_offset_x_px = settings.lbox_width_px;
|
||||
m_render_state.window_offset_y_px = settings.lbox_height_px;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -488,10 +569,14 @@ void OpenGLRenderer::finish_screenshot(const std::string& output_name,
|
||||
int width,
|
||||
int height,
|
||||
int x,
|
||||
int y) {
|
||||
int y,
|
||||
GLuint fbo) {
|
||||
std::vector<u32> buffer(width * height);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadBuffer(GL_BACK);
|
||||
GLint oldbuf;
|
||||
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldbuf);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
|
||||
// flip upside down in place
|
||||
for (int h = 0; h < height / 2; h++) {
|
||||
@@ -505,19 +590,44 @@ void OpenGLRenderer::finish_screenshot(const std::string& output_name,
|
||||
px |= 0xff000000;
|
||||
}
|
||||
file_util::write_rgba_png(output_name, buffer.data(), width, height);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, oldbuf);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::do_pcrtc_effects(float alp,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof) {
|
||||
if (alp < 1) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
int w = render_state->fbo_state.width;
|
||||
int h = render_state->fbo_state.height;
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, render_state->fbo_state.fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, render_state->fbo_state.fbo2);
|
||||
glBlitFramebuffer(0, // srcX0
|
||||
0, // srcY0
|
||||
w, // srcX1
|
||||
h, // srcY1
|
||||
0, // dstX0
|
||||
0, // dstY0
|
||||
w, // dstX1
|
||||
h, // dstY1
|
||||
GL_COLOR_BUFFER_BIT, // mask
|
||||
GL_LINEAR // filter
|
||||
);
|
||||
|
||||
m_blackout_renderer.draw(Vector4f(0, 0, 0, 1.f - alp), render_state, prof);
|
||||
// Render to the screen directly now
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(render_state->window_offset_x_px, render_state->window_offset_y_px,
|
||||
render_state->window_width_px, render_state->window_height_px);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClearDepth(0.0);
|
||||
glDepthMask(GL_TRUE);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
m_blackout_renderer.draw(Vector4f(0, 0, 0, alp), render_state, prof);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ struct RenderOptions {
|
||||
bool draw_small_profiler_window = false;
|
||||
bool draw_subtitle_editor_window = false;
|
||||
|
||||
int msaa_samples = 4;
|
||||
int game_res_w = 640;
|
||||
int game_res_h = 480;
|
||||
|
||||
bool save_screenshot = false;
|
||||
std::string screenshot_path;
|
||||
|
||||
@@ -44,12 +48,12 @@ class OpenGLRenderer {
|
||||
void render(DmaFollower dma, const RenderOptions& settings);
|
||||
|
||||
private:
|
||||
void setup_frame(int window_width_px, int window_height_px, int offset_x, int offset_y);
|
||||
void setup_frame(const RenderOptions& settings);
|
||||
void dispatch_buckets(DmaFollower dma, ScopedProfilerNode& prof);
|
||||
void do_pcrtc_effects(float alp, SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
void init_bucket_renderers();
|
||||
void draw_renderer_selection_window();
|
||||
void finish_screenshot(const std::string& output_name, int px, int py, int x, int y);
|
||||
void finish_screenshot(const std::string& output_name, int px, int py, int x, int y, GLuint fbo);
|
||||
template <typename T, class... Args>
|
||||
T* init_bucket_renderer(const std::string& name,
|
||||
BucketCategory cat,
|
||||
|
||||
@@ -89,6 +89,7 @@ ShaderLibrary::ShaderLibrary() {
|
||||
at(ShaderId::MERC2) = {"merc2"};
|
||||
at(ShaderId::SPRITE_DISTORT) = {"sprite_distort"};
|
||||
at(ShaderId::SPRITE_DISTORT_INSTANCED) = {"sprite_distort_instanced"};
|
||||
at(ShaderId::POST_PROCESSING) = {"post_processing"};
|
||||
|
||||
for (auto& shader : m_shaders) {
|
||||
ASSERT_MSG(shader.okay(), "Shader compiled");
|
||||
|
||||
@@ -44,6 +44,7 @@ enum class ShaderId {
|
||||
MERC2 = 19,
|
||||
SPRITE_DISTORT = 20,
|
||||
SPRITE_DISTORT_INSTANCED = 21,
|
||||
POST_PROCESSING = 22,
|
||||
MAX_SHADERS
|
||||
};
|
||||
|
||||
|
||||
@@ -44,9 +44,9 @@ bool looks_like_distort_frame_data(const DmaFollower& dma) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
constexpr int SPRITE_RENDERER_MAX_SPRITES = 8000;
|
||||
constexpr int SPRITE_RENDERER_MAX_SPRITES = 1920 * 10;
|
||||
constexpr int SPRITE_RENDERER_MAX_DISTORT_SPRITES =
|
||||
256 * 8; // size of sprite-aux-list in GOAL code * SPRITE_MAX_AMOUNT_MULT
|
||||
256 * 10; // size of sprite-aux-list in GOAL code * SPRITE_MAX_AMOUNT_MULT
|
||||
|
||||
Sprite3::Sprite3(const std::string& name, BucketId my_id)
|
||||
: BucketRenderer(name, my_id), m_direct(name, my_id, 1024) {
|
||||
@@ -519,10 +519,10 @@ void Sprite3::distort_setup(ScopedProfilerNode& /*prof*/) {
|
||||
*/
|
||||
void Sprite3::distort_setup_instanced(SharedRenderState* render_state,
|
||||
ScopedProfilerNode& /*prof*/) {
|
||||
if (m_distort_instanced_ogl.last_window_width != render_state->window_width_px ||
|
||||
m_distort_instanced_ogl.last_window_height != render_state->window_height_px) {
|
||||
m_distort_instanced_ogl.last_window_width = render_state->window_width_px;
|
||||
m_distort_instanced_ogl.last_window_height = render_state->window_height_px;
|
||||
if (m_distort_instanced_ogl.last_width != render_state->fbo_state.width ||
|
||||
m_distort_instanced_ogl.last_height != render_state->fbo_state.height) {
|
||||
m_distort_instanced_ogl.last_width = render_state->fbo_state.width;
|
||||
m_distort_instanced_ogl.last_height = render_state->fbo_state.height;
|
||||
|
||||
// Window dimensions changed, which means the aspect ratio may have changed, which means we have
|
||||
// a new sine table
|
||||
@@ -702,22 +702,22 @@ void Sprite3::distort_draw_instanced(SharedRenderState* render_state, ScopedProf
|
||||
void Sprite3::distort_draw_common(SharedRenderState* render_state, ScopedProfilerNode& /*prof*/) {
|
||||
// The distort effect needs to read the current framebuffer, so copy what's been rendered so far
|
||||
// to a texture that we can then pass to the shader
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, render_state->fbo_state.fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_distort_ogl.fbo);
|
||||
|
||||
glBlitFramebuffer(render_state->window_offset_x_px, // srcX0
|
||||
render_state->window_offset_y_px, // srcY0
|
||||
render_state->window_width_px + render_state->window_offset_x_px, // srcX1
|
||||
render_state->window_height_px + render_state->window_offset_y_px, // srcY1
|
||||
0, // dstX0
|
||||
0, // dstY0
|
||||
m_distort_ogl.fbo_width, // dstX1
|
||||
m_distort_ogl.fbo_height, // dstY1
|
||||
GL_COLOR_BUFFER_BIT, // mask
|
||||
GL_NEAREST // filter
|
||||
glBlitFramebuffer(0, // srcX0
|
||||
0, // srcY0
|
||||
render_state->fbo_state.width, // srcX1
|
||||
render_state->fbo_state.height, // srcY1
|
||||
0, // dstX0
|
||||
0, // dstY0
|
||||
m_distort_ogl.fbo_width, // dstX1
|
||||
m_distort_ogl.fbo_height, // dstY1
|
||||
GL_COLOR_BUFFER_BIT, // mask
|
||||
GL_NEAREST // filter
|
||||
);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, render_state->fbo_state.fbo);
|
||||
|
||||
// Set up OpenGL state
|
||||
m_current_mode.set_depth_write_enable(!m_sprite_distorter_setup.zbuf.zmsk()); // zbuf
|
||||
@@ -732,10 +732,10 @@ void Sprite3::distort_draw_common(SharedRenderState* render_state, ScopedProfile
|
||||
|
||||
void Sprite3::distort_setup_framebuffer_dims(SharedRenderState* render_state) {
|
||||
// Distort framebuffer must be the same dimensions as the default window framebuffer
|
||||
if (m_distort_ogl.fbo_width != render_state->window_width_px ||
|
||||
m_distort_ogl.fbo_height != render_state->window_height_px) {
|
||||
m_distort_ogl.fbo_width = render_state->window_width_px;
|
||||
m_distort_ogl.fbo_height = render_state->window_height_px;
|
||||
if (m_distort_ogl.fbo_width != render_state->fbo_state.width ||
|
||||
m_distort_ogl.fbo_height != render_state->fbo_state.height) {
|
||||
m_distort_ogl.fbo_width = render_state->fbo_state.width;
|
||||
m_distort_ogl.fbo_height = render_state->fbo_state.height;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_distort_ogl.fbo_texture);
|
||||
|
||||
|
||||
@@ -117,8 +117,8 @@ class Sprite3 : public BucketRenderer {
|
||||
GLuint vao;
|
||||
GLuint vertex_buffer; // contains vertex data for each possible sprite resolution (3-11)
|
||||
GLuint instance_buffer; // contains all instance specific data for each sprite per frame
|
||||
int last_window_width = -1;
|
||||
int last_window_height = -1;
|
||||
int last_width = -1;
|
||||
int last_height = -1;
|
||||
bool vertex_data_changed = false;
|
||||
} m_distort_instanced_ogl;
|
||||
|
||||
|
||||
@@ -110,6 +110,9 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) {
|
||||
if (ImGui::BeginMenu("Screenshot")) {
|
||||
ImGui::MenuItem("Screenshot Next Frame!", nullptr, &m_want_screenshot);
|
||||
ImGui::InputText("File", m_screenshot_save_name, 50);
|
||||
ImGui::InputInt("Width", &screenshot_width);
|
||||
ImGui::InputInt("Height", &screenshot_height);
|
||||
ImGui::InputInt("MSAA", &screenshot_samples);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,10 @@ class OpenGlDebugGui {
|
||||
bool dump_events = false;
|
||||
bool want_reboot_in_debug = false;
|
||||
|
||||
int screenshot_width = 1920;
|
||||
int screenshot_height = 1080;
|
||||
int screenshot_samples = 16;
|
||||
|
||||
private:
|
||||
FrameTimeRecorder m_frame_timer;
|
||||
bool m_draw_frame_time = false;
|
||||
|
||||
@@ -140,11 +140,12 @@ void FullScreenDraw::draw(const math::Vector4f& color,
|
||||
ScopedProfilerNode& prof) {
|
||||
glBindVertexArray(m_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
|
||||
auto& shader = render_state->shaders[ShaderId::SOLID_COLOR];
|
||||
auto& shader = render_state->shaders[ShaderId::POST_PROCESSING];
|
||||
shader.activate();
|
||||
glUniform4f(glGetUniformLocation(shader.id(), "fragment_color"), color[0], color[1], color[2],
|
||||
color[3]);
|
||||
|
||||
prof.add_tri(2);
|
||||
prof.add_draw_call();
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#version 430 core
|
||||
|
||||
in vec2 screen_pos;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
uniform vec4 fragment_color;
|
||||
|
||||
layout (binding = 30) uniform sampler2D screen_tex;
|
||||
|
||||
void main() {
|
||||
color = vec4(texture(screen_tex, screen_pos).rgb * fragment_color.a, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#version 430 core
|
||||
|
||||
layout (location = 0) in vec2 position_in;
|
||||
|
||||
out vec2 screen_pos;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(position_in, 0, 1.0);
|
||||
screen_pos = (position_in + 1) / 2;
|
||||
}
|
||||
@@ -140,7 +140,6 @@ static int gl_init(GfxSettings& settings) {
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_FALSE);
|
||||
}
|
||||
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_SAMPLES, 1);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||
|
||||
return 0;
|
||||
@@ -263,7 +262,13 @@ static bool endsWith(std::string_view str, std::string_view suffix) {
|
||||
0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix);
|
||||
}
|
||||
|
||||
void render_game_frame(int width, int height, int lbox_width, int lbox_height) {
|
||||
void render_game_frame(int game_width,
|
||||
int game_height,
|
||||
int window_width,
|
||||
int window_height,
|
||||
int lbox_width,
|
||||
int lbox_height,
|
||||
int msaa_samples) {
|
||||
// wait for a copied chain.
|
||||
bool got_chain = false;
|
||||
{
|
||||
@@ -278,16 +283,32 @@ void render_game_frame(int width, int height, int lbox_width, int lbox_height) {
|
||||
if (got_chain) {
|
||||
g_gfx_data->frame_idx_of_input_data = g_gfx_data->frame_idx;
|
||||
RenderOptions options;
|
||||
options.window_height_px = height;
|
||||
options.window_width_px = width;
|
||||
options.game_res_w = game_width;
|
||||
options.game_res_h = game_height;
|
||||
options.window_height_px = window_height;
|
||||
options.window_width_px = window_width;
|
||||
options.lbox_height_px = lbox_height;
|
||||
options.lbox_width_px = lbox_width;
|
||||
options.msaa_samples = msaa_samples;
|
||||
options.draw_render_debug_window = g_gfx_data->debug_gui.should_draw_render_debug();
|
||||
options.draw_profiler_window = g_gfx_data->debug_gui.should_draw_profiler();
|
||||
options.draw_subtitle_editor_window = g_gfx_data->debug_gui.should_draw_subtitle_editor();
|
||||
options.save_screenshot = g_gfx_data->debug_gui.get_screenshot_flag();
|
||||
options.save_screenshot = false;
|
||||
if (g_gfx_data->debug_gui.get_screenshot_flag()) {
|
||||
options.save_screenshot = true;
|
||||
options.game_res_w = g_gfx_data->debug_gui.screenshot_width;
|
||||
options.game_res_h = g_gfx_data->debug_gui.screenshot_height;
|
||||
options.msaa_samples = g_gfx_data->debug_gui.screenshot_samples;
|
||||
}
|
||||
options.draw_small_profiler_window = g_gfx_data->debug_gui.small_profiler;
|
||||
options.pmode_alp_register = g_gfx_data->pmode_alp;
|
||||
|
||||
GLint msaa_max;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &msaa_max);
|
||||
if (options.msaa_samples > msaa_max) {
|
||||
options.msaa_samples = msaa_max;
|
||||
}
|
||||
|
||||
if (options.save_screenshot) {
|
||||
// ensure the screenshot has an extension
|
||||
std::string temp_path = g_gfx_data->debug_gui.screenshot_name();
|
||||
@@ -471,8 +492,8 @@ void GLDisplay::render() {
|
||||
}
|
||||
|
||||
// window size
|
||||
int width = Gfx::g_global_settings.lbox_w;
|
||||
int height = Gfx::g_global_settings.lbox_h;
|
||||
int win_w = Gfx::g_global_settings.lbox_w;
|
||||
int win_h = Gfx::g_global_settings.lbox_h;
|
||||
int fbuf_w, fbuf_h;
|
||||
glfwGetFramebufferSize(m_window, &fbuf_w, &fbuf_h);
|
||||
#ifdef _WIN32
|
||||
@@ -482,9 +503,9 @@ void GLDisplay::render() {
|
||||
}
|
||||
#endif
|
||||
// horizontal letterbox size
|
||||
int lbox_w = (fbuf_w - width) / 2;
|
||||
int lbox_w = (fbuf_w - win_w) / 2;
|
||||
// vertical letterbox size
|
||||
int lbox_h = (fbuf_h - height) / 2;
|
||||
int lbox_h = (fbuf_h - win_h) / 2;
|
||||
#ifdef _WIN32
|
||||
if (last_fullscreen_mode() == GfxDisplayMode::Borderless) {
|
||||
// add one pixel of vertical letterbox on borderless to make up for extra line
|
||||
@@ -495,7 +516,8 @@ void GLDisplay::render() {
|
||||
// render game!
|
||||
if (g_gfx_data->debug_gui.should_advance_frame()) {
|
||||
auto p = scoped_prof("game-render");
|
||||
render_game_frame(width, height, lbox_w, lbox_h);
|
||||
render_game_frame(Gfx::g_global_settings.game_res_w, Gfx::g_global_settings.game_res_h, win_w,
|
||||
win_h, lbox_w, lbox_h, Gfx::g_global_settings.msaa_samples);
|
||||
}
|
||||
|
||||
if (g_gfx_data->debug_gui.should_gl_finish()) {
|
||||
|
||||
@@ -586,6 +586,14 @@ void set_fullscreen(u32 symptr, s64 screen) {
|
||||
}
|
||||
}
|
||||
|
||||
void set_game_resolution(s64 w, s64 h) {
|
||||
Gfx::set_game_resolution(w, h);
|
||||
}
|
||||
|
||||
void set_msaa(s64 samples) {
|
||||
Gfx::set_msaa(samples);
|
||||
}
|
||||
|
||||
void InitMachine_PCPort() {
|
||||
// PC Port added functions
|
||||
|
||||
@@ -619,6 +627,8 @@ void InitMachine_PCPort() {
|
||||
make_function_symbol_from_c("pc-set-frame-rate", (void*)set_frame_rate);
|
||||
make_function_symbol_from_c("pc-set-vsync", (void*)set_vsync);
|
||||
make_function_symbol_from_c("pc-set-window-lock", (void*)set_window_lock);
|
||||
make_function_symbol_from_c("pc-set-game-resolution", (void*)set_game_resolution);
|
||||
make_function_symbol_from_c("pc-set-msaa", (void*)set_msaa);
|
||||
|
||||
// graphics things
|
||||
make_function_symbol_from_c("pc-set-letterbox", (void*)Gfx::set_letterbox);
|
||||
|
||||
@@ -4540,6 +4540,8 @@
|
||||
(function "2560 x 1440" #f (lambda () (set-size! *pc-settings* 2560 1440)))
|
||||
(function "2880 x 2160" #f (lambda () (set-size! *pc-settings* 2880 2160)))
|
||||
(function "3840 x 2160" #f (lambda () (set-size! *pc-settings* 3840 2160)))
|
||||
(function "512 x 224" #f (lambda () (set-size! *pc-settings* 512 224)))
|
||||
(function "512 x 256" #f (lambda () (set-size! *pc-settings* 512 256)))
|
||||
(function "512 x 448" #f (lambda () (set-size! *pc-settings* 512 448)))
|
||||
(function "512 x 512" #f (lambda () (set-size! *pc-settings* 512 512)))
|
||||
)
|
||||
|
||||
@@ -358,6 +358,8 @@
|
||||
(define-extern pc-sound-set-flava-hack (function int none))
|
||||
(define-extern pc-sound-set-fade-hack (function int none))
|
||||
(define-extern pc-set-window-lock (function symbol none))
|
||||
(define-extern pc-set-game-resolution (function int int none))
|
||||
(define-extern pc-set-msaa (function int none))
|
||||
|
||||
(defenum pc-prof-event
|
||||
(begin 0)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
|
||||
(defglobalconstant PC_KERNEL_VERSION_BUILD #x0001)
|
||||
(defglobalconstant PC_KERNEL_VERSION_REVISION #x0007)
|
||||
(defglobalconstant PC_KERNEL_VERSION_REVISION #x0008)
|
||||
|
||||
(defglobalconstant PC_KERNEL_VERSION_MINOR #x0006)
|
||||
(defglobalconstant PC_KERNEL_VERSION_MAJOR #x0001)
|
||||
@@ -256,7 +256,7 @@
|
||||
(gfx-renderer pc-gfx-renderer) ;; the renderer to use
|
||||
(gfx-resolution float) ;; for supersampling
|
||||
(gfx-anisotropy float) ;; for anisotropy
|
||||
(gfx-msaa int) ;; for MSAA
|
||||
(gfx-msaa int32) ;; for MSAA
|
||||
|
||||
;; ps2 settings
|
||||
(ps2-read-speed? symbol) ;; emulate DVD loads
|
||||
@@ -417,8 +417,7 @@
|
||||
"Set the default graphics settings"
|
||||
|
||||
(set! (-> obj target-fps) 60)
|
||||
(set! (-> obj width) PC_BASE_WIDTH)
|
||||
(set! (-> obj height) PC_BASE_HEIGHT)
|
||||
(pc-get-screen-size -1 (&-> obj width) (&-> obj height))
|
||||
(set! (-> obj use-vis?) #f)
|
||||
(set! (-> obj aspect-ratio-auto?) #f)
|
||||
(set! (-> obj vsync?) #t)
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
(set! (-> obj win-height) height)
|
||||
)
|
||||
(else
|
||||
(format 0 "Nope! No changing fullscreen resolution for now!~%")
|
||||
(format #t "Nope! No changing fullscreen resolution for now!~%")
|
||||
(set! (-> obj width) width)
|
||||
(set! (-> obj height) height)
|
||||
)
|
||||
)
|
||||
(none))
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
(defmethod set-frame-rate! pc-settings ((obj pc-settings) (rate int))
|
||||
"set the aspect ratio used for rendering."
|
||||
|
||||
|
||||
(pc-set-frame-rate rate)
|
||||
(if (and (!= 'fullscreen (-> obj display-mode))
|
||||
(!= (pc-get-screen-rate -1) rate))
|
||||
@@ -120,7 +120,7 @@
|
||||
(set-video-mode '150fps)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
rate)
|
||||
|
||||
(defmethod commit-to-file pc-settings ((obj pc-settings))
|
||||
@@ -187,7 +187,9 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; set fullscreen to what we want
|
||||
(pc-set-fullscreen (-> obj display-mode) 0)
|
||||
;; set window size and fps automatically if the window lock is enabled.
|
||||
(when (-> obj window-lock?)
|
||||
(pc-set-vsync (-> obj vsync?))
|
||||
|
||||
@@ -201,6 +203,21 @@
|
||||
(!= (-> obj win-height) (-> obj real-height))))
|
||||
(pc-set-window-size (max PC_MIN_WIDTH (-> obj win-width)) (max PC_MIN_HEIGHT (-> obj win-height))))
|
||||
)
|
||||
;; do game resolution
|
||||
(if (= (-> obj display-mode) 'windowed)
|
||||
(pc-set-game-resolution (-> obj win-width) (-> obj win-height))
|
||||
(pc-set-game-resolution (-> obj width) (-> obj height)))
|
||||
|
||||
;; set msaa sample rate. if invalid, just reset to 4.
|
||||
(let ((valid? #f))
|
||||
(dotimes (i 31)
|
||||
(if (= (-> obj gfx-msaa) (ash 1 i))
|
||||
(true! valid?))
|
||||
)
|
||||
|
||||
(if (not valid?) (set! (-> obj gfx-msaa) 4))
|
||||
(pc-set-msaa (-> obj gfx-msaa))
|
||||
)
|
||||
|
||||
(pc-discord-rpc-set (if (-> obj discord-rpc?) 1 0))
|
||||
|
||||
@@ -753,6 +770,7 @@
|
||||
(set! (-> obj width) (file-stream-read-int file))
|
||||
(set! (-> obj height) (file-stream-read-int file))
|
||||
)
|
||||
(("msaa") (set! (-> obj gfx-msaa) (file-stream-read-int file)))
|
||||
(("aspect") (set-aspect! obj (file-stream-read-int file) (file-stream-read-int file)))
|
||||
(("aspect-test")
|
||||
(set! (-> obj aspect-custom-x) (file-stream-read-int file))
|
||||
@@ -872,6 +890,7 @@
|
||||
|
||||
(format file " (fps ~D)~%" (-> obj target-fps))
|
||||
(format file " (game-size ~D ~D)~%" (-> obj width) (-> obj height))
|
||||
(format file " (msaa ~D)~%" (-> obj gfx-msaa))
|
||||
(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))
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
(subtitle-backup pc-subtitle-lang)
|
||||
(aspect-native-choice symbol)
|
||||
(current-carousell (array game-text-id))
|
||||
|
||||
|
||||
(selection int)
|
||||
(direction symbol)
|
||||
(transition symbol)
|
||||
@@ -127,7 +127,7 @@
|
||||
(new 'static 'game-option :option-type (game-option-type display-mode) :name (game-text-id display-mode) :scale #t)
|
||||
(new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vsync) :scale #t)
|
||||
(new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id aspect-ratio) :scale #t :param3 (game-option-menu aspect-ratio))
|
||||
;(new 'static 'game-option :option-type (game-option-type msaa) :name (game-text-id msaa) :scale #t)
|
||||
(new 'static 'game-option :option-type (game-option-type msaa) :name (game-text-id msaa) :scale #t)
|
||||
(new 'static 'game-option :option-type (game-option-type frame-rate) :name (game-text-id frame-rate) :scale #t)
|
||||
(new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id ps2-options) :scale #t :param3 (game-option-menu gfx-ps2-options))
|
||||
(new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t)
|
||||
@@ -139,7 +139,7 @@
|
||||
(new 'static 'game-option :option-type (game-option-type display-mode) :name (game-text-id display-mode) :scale #t)
|
||||
(new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vsync) :scale #t)
|
||||
(new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id aspect-ratio) :scale #t :param3 (game-option-menu aspect-ratio))
|
||||
;(new 'static 'game-option :option-type (game-option-type msaa) :name (game-text-id msaa) :scale #t)
|
||||
(new 'static 'game-option :option-type (game-option-type msaa) :name (game-text-id msaa) :scale #t)
|
||||
(new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id ps2-options) :scale #t :param3 (game-option-menu gfx-ps2-options))
|
||||
(new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t)
|
||||
)
|
||||
@@ -321,14 +321,14 @@
|
||||
|
||||
|
||||
(defun find-highest-resolution ()
|
||||
|
||||
|
||||
(let ((sx 0) (sy 0) (found #f) (mult GAME_MIN_RES_MULT) (lastr 0) (hir 0) (lor 0))
|
||||
(pc-get-screen-size -1 (the (pointer int32) (& sx)) (the (pointer int32) (& sy)))
|
||||
(if (> sy sx)
|
||||
(set! sy sx))
|
||||
|
||||
|
||||
(until found
|
||||
|
||||
|
||||
(dotimes (i (-> *resolutions* length))
|
||||
(let ((thisr (the int (* mult (the float (-> *resolutions* i))))))
|
||||
(cond
|
||||
@@ -342,15 +342,15 @@
|
||||
(set! lastr thisr))
|
||||
)
|
||||
))
|
||||
|
||||
|
||||
(if (not found)
|
||||
(*! mult 2))
|
||||
|
||||
|
||||
)
|
||||
(set! hir lastr)
|
||||
mult
|
||||
)
|
||||
|
||||
|
||||
)
|
||||
|
||||
(defmacro add-resolution-option (x y)
|
||||
@@ -361,7 +361,7 @@
|
||||
(set! (-> option param1) (the float ,x))
|
||||
(set! (-> option param2) (the float ,y))
|
||||
(set! (-> option scale) #t)
|
||||
|
||||
|
||||
(1+! (-> *temp-options* length))
|
||||
)
|
||||
)
|
||||
@@ -373,7 +373,7 @@
|
||||
(set! (-> option name) ,text-id)
|
||||
(set! (-> option param1) (the float ,flava))
|
||||
(set! (-> option scale) #t)
|
||||
|
||||
|
||||
(1+! (-> *temp-options* length))
|
||||
)
|
||||
)
|
||||
@@ -384,35 +384,34 @@
|
||||
(set! (-> option option-type) (game-option-type button))
|
||||
(set! (-> option name) (game-text-id back))
|
||||
(set! (-> option scale) #t)
|
||||
|
||||
|
||||
(1+! (-> *temp-options* length))
|
||||
)
|
||||
)
|
||||
|
||||
(defun build-resolution-options ((skip int) (amount int))
|
||||
|
||||
|
||||
(set! (-> *temp-options* length) 0)
|
||||
|
||||
(let ((done? #f) (mult (find-highest-resolution)) (sx 0) (sy 0) (flip? #f) (aspect 0.0)
|
||||
|
||||
(let* ((done? #f) (mult (find-highest-resolution)) (sx 0) (sy 0)
|
||||
(display-mode (pc-get-fullscreen))
|
||||
;; hack - do not use screen resolution in windowed mode, taskbar etc. messes it up and makes it useless!
|
||||
(skip? (= 'windowed (pc-get-fullscreen)))
|
||||
(skip? (= 'windowed display-mode))
|
||||
;; shortcut
|
||||
(max-options (1- (-> *temp-options* allocated-length))))
|
||||
|
||||
|
||||
;; get screen size (for capping)
|
||||
(pc-get-screen-size -1 (the (pointer int32) (& sx)) (the (pointer int32) (& sy)))
|
||||
;; portrait mode. unused
|
||||
(set! flip? (> sy sx))
|
||||
|
||||
(case (pc-get-fullscreen)
|
||||
(('fullscreen)
|
||||
|
||||
(case display-mode
|
||||
#|(('fullscreen)
|
||||
;; insert psyched out trollface here
|
||||
(set! sx 0)
|
||||
(set! sy 0)
|
||||
(countdown (i (pc-get-screen-vmode-count))
|
||||
(let ((thisx 0) (thisy 0))
|
||||
(pc-get-screen-size i (the (pointer int32) (& thisx)) (the (pointer int32) (& thisy)))
|
||||
|
||||
|
||||
(when (not (and (= thisx sx) (= thisy sy)))
|
||||
(add-resolution-option thisx thisy)
|
||||
)
|
||||
@@ -420,24 +419,32 @@
|
||||
(set! sy thisy)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
)|#
|
||||
|
||||
(else
|
||||
;; extra button when fullscreen
|
||||
(when (not skip?)
|
||||
(add-resolution-option sx sy)
|
||||
(set! (-> *temp-options* (1- (length *temp-options*)) name) (game-text-id fit-to-screen))
|
||||
)
|
||||
|
||||
;; supersampling in fullscreen and stuff. this results in way too many resolution options lol.
|
||||
(when (!= display-mode 'windowed)
|
||||
(*! sx 4)
|
||||
(*! sy 4)
|
||||
(*! mult 4)
|
||||
)
|
||||
|
||||
;; game aspect ratio
|
||||
(set! aspect (-> *pc-settings* aspect-ratio))
|
||||
|
||||
(let ((aspect (-> *pc-settings* aspect-ratio)))
|
||||
|
||||
(until (or done? (= (length *temp-options*) max-options))
|
||||
(countdown (i (-> *resolutions* length))
|
||||
(let* ((thisr (the int (* mult (the float (-> *resolutions* i)))))
|
||||
(thisx (the int (* aspect (the float thisr))))
|
||||
(thisy thisr)
|
||||
)
|
||||
|
||||
|
||||
(when (and (not skip?) (< (length *temp-options*) max-options)
|
||||
(<= thisy sy) (<= thisx sx)
|
||||
(= aspect (/ (the float thisx) (the float thisy)))
|
||||
@@ -446,31 +453,38 @@
|
||||
))
|
||||
(false! skip?)
|
||||
)
|
||||
|
||||
|
||||
(if (> mult GAME_MIN_RES_MULT)
|
||||
(*! mult 0.5)
|
||||
(/! mult 2)
|
||||
(true! done?))
|
||||
)
|
||||
))
|
||||
)
|
||||
)
|
||||
;; extra funny options
|
||||
(when (and (!= display-mode 'windowed)
|
||||
(< (length *temp-options*) (- (-> *temp-options* allocated-length) 3)))
|
||||
(add-resolution-option 512 224)
|
||||
(add-resolution-option 512 448)
|
||||
)
|
||||
|
||||
(add-back-option)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
*temp-options*
|
||||
)
|
||||
|
||||
(defun build-flava-player-options ((mus-idx int))
|
||||
|
||||
|
||||
(set! (-> *temp-options* length) 0)
|
||||
|
||||
|
||||
(dotimes (i (-> *music-flava-name-list* mus-idx length))
|
||||
(if (nonzero? (-> *music-flava-name-list* mus-idx i))
|
||||
(add-flava-player-option (-> *music-flava-name-list* mus-idx i) i)
|
||||
)
|
||||
)
|
||||
(add-back-option)
|
||||
|
||||
|
||||
*temp-options*
|
||||
)
|
||||
|
||||
@@ -511,7 +525,7 @@
|
||||
|
||||
(defun progress-draw-carousell-from-string-list ((options (array game-text-id)) (font font-context) (y-off int) (new-val int))
|
||||
"yep."
|
||||
|
||||
|
||||
(let ((old-lang (-> *progress-carousell* selection))
|
||||
(new-lang new-val)
|
||||
(max-lang (length options))
|
||||
@@ -647,12 +661,12 @@
|
||||
(set! (-> *options-remap* (progress-screen flava-player)) *temp-options*)
|
||||
(set! (-> *options-remap* (progress-screen memcard-disable-auto-save)) *yes-no-options*)
|
||||
(set! (-> *options-remap* (progress-screen memcard-auto-save-disabled)) *ok-options*)
|
||||
|
||||
|
||||
;; set default params
|
||||
(set! (-> *progress-state* aspect-ratio-choice) (get-aspect-ratio))
|
||||
(set! (-> *progress-state* video-mode-choice) (get-video-mode))
|
||||
(set! (-> *progress-state* yes-no-choice) #f)
|
||||
|
||||
|
||||
;; set variable pointers
|
||||
(set! (-> *game-options* 0 value-to-modify) (&-> *setting-control* default vibration))
|
||||
(set! (-> *game-options* 1 value-to-modify) (&-> *setting-control* default play-hints))
|
||||
@@ -677,11 +691,11 @@
|
||||
(set! (-> *game-options-pc* 7 value-to-modify) (&-> *progress-carousell* int-backup))
|
||||
(set! (-> *graphic-options-pc* 1 value-to-modify) (&-> *progress-carousell* int-backup))
|
||||
(set! (-> *graphic-options-pc* 2 value-to-modify) (&-> *pc-settings* vsync?))
|
||||
;(set! (-> *graphic-options-pc* 4 value-to-modify) (&-> *progress-carousell* int-backup))
|
||||
(set! (-> *graphic-options-pc* 4 value-to-modify) (&-> *progress-carousell* int-backup))
|
||||
(set! (-> *graphic-options-pc* 5 value-to-modify) (&-> *progress-carousell* int-backup))
|
||||
(set! (-> *graphic-options-no-frame-rate-pc* 1 value-to-modify) (&-> *progress-carousell* int-backup))
|
||||
(set! (-> *graphic-options-no-frame-rate-pc* 2 value-to-modify) (&-> *pc-settings* vsync?))
|
||||
;(set! (-> *graphic-options-pc* 4 value-to-modify) (&-> *progress-carousell* int-backup))
|
||||
(set! (-> *graphic-options-pc* 4 value-to-modify) (&-> *progress-carousell* int-backup))
|
||||
(set! (-> *misc-options* 0 value-to-modify) (&-> *pc-settings* discord-rpc?))
|
||||
(set! (-> *misc-options* 1 value-to-modify) (&-> *pc-settings* money-starburst?))
|
||||
(set! (-> *camera-options* 0 value-to-modify) (&-> *pc-settings* first-camera-h-inverted?))
|
||||
@@ -697,7 +711,7 @@
|
||||
(set! (-> *sound-options-pc* 2 value-to-modify) (&-> *setting-control* default dialog-volume))
|
||||
;(set! (-> *sound-options-pc* 3 value-to-modify) (&-> *pc-settings* music-fadein?))
|
||||
(set! (-> *progress-carousell* aspect-native-choice) (-> *pc-settings* use-vis?))
|
||||
|
||||
|
||||
;; scroll stuff!
|
||||
(progress-scroll-reset)
|
||||
(none)
|
||||
@@ -1339,7 +1353,7 @@
|
||||
|
||||
(defmethod respond-memcard progress ((obj progress))
|
||||
"logic for handling input in memcard screens."
|
||||
|
||||
|
||||
(let ((s5-0 (-> obj card-info)))
|
||||
(when (and s5-0 (not (-> obj in-transition)))
|
||||
(when (or (cpad-pressed? 0 x) (cpad-pressed? 0 circle))
|
||||
@@ -1993,7 +2007,7 @@
|
||||
|
||||
|
||||
;; override the post handler for progress-normal
|
||||
(set! (-> progress-normal post)
|
||||
(set! (-> progress-normal post)
|
||||
(lambda :behavior progress ()
|
||||
(when (progress-scrolling?)
|
||||
(seek! (-> *progress-scroll* transition) 1.0 (* (/ 1.75 512) (-> self transition-speed) (-> *display* time-adjust-ratio)))
|
||||
@@ -2156,7 +2170,7 @@
|
||||
))
|
||||
|
||||
;; override the enter handler for progress-going-out
|
||||
(set! (-> progress-going-out enter)
|
||||
(set! (-> progress-going-out enter)
|
||||
(lambda :behavior progress ()
|
||||
(sound-play "menu-close")
|
||||
(hide-progress-icons)
|
||||
|
||||
Reference in New Issue
Block a user