mirror of
https://github.com/perfect-dark-pc-port/perfect_dark.git
synced 2026-10-23 15:52:41 +02:00
Merge pull request #538 from ZenithMDC/revamp-video-options
Allow changing video resolution at runtime + more
This commit is contained in:
10 files changed
+857
-47
No files matched your search
+118
-7
@@ -30,10 +30,30 @@ static uint64_t qpc_freq;
|
|||||||
#define FRAME_INTERVAL_US_NUMERATOR 1000000
|
#define FRAME_INTERVAL_US_NUMERATOR 1000000
|
||||||
#define FRAME_INTERVAL_US_DENOMINATOR (target_fps)
|
#define FRAME_INTERVAL_US_DENOMINATOR (target_fps)
|
||||||
|
|
||||||
static void set_fullscreen(bool on, bool call_callback) {
|
static int32_t gfx_sdl_get_maximized_state(void) {
|
||||||
if (fullscreen_state == on) {
|
return (int32_t)maximized_state;
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
static int32_t gfx_sdl_get_fullscreen_state(void) {
|
||||||
|
return (int32_t)fullscreen_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t gfx_sdl_get_fullscreen_flag_mode(void) {
|
||||||
|
return fullscreen_flag == SDL_WINDOW_FULLSCREEN_DESKTOP ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_sdl_set_fullscreen_flag(int32_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case 0: {
|
||||||
|
fullscreen_flag = SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
|
} break;
|
||||||
|
case 1: {
|
||||||
|
fullscreen_flag = SDL_WINDOW_FULLSCREEN;
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_fullscreen(bool on, bool call_callback) {
|
||||||
fullscreen_state = on;
|
fullscreen_state = on;
|
||||||
SDL_SetWindowFullscreen(wnd, on ? fullscreen_flag : 0);
|
SDL_SetWindowFullscreen(wnd, on ? fullscreen_flag : 0);
|
||||||
if (call_callback && on_fullscreen_changed_callback) {
|
if (call_callback && on_fullscreen_changed_callback) {
|
||||||
@@ -42,9 +62,6 @@ static void set_fullscreen(bool on, bool call_callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void set_maximize_window(bool on) {
|
static void set_maximize_window(bool on) {
|
||||||
if (maximized_state == on) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
maximized_state = on;
|
maximized_state = on;
|
||||||
if (on) {
|
if (on) {
|
||||||
SDL_MaximizeWindow(wnd);
|
SDL_MaximizeWindow(wnd);
|
||||||
@@ -95,6 +112,13 @@ static void gfx_sdl_init(const struct GfxWindowInitSettings *set) {
|
|||||||
posY = 100;
|
posY = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (set->centered) {
|
||||||
|
SDL_DisplayMode mode = {};
|
||||||
|
SDL_GetCurrentDisplayMode(0, &mode);
|
||||||
|
posX = mode.w / 2 - window_width / 2;
|
||||||
|
posY = mode.h / 2 - window_height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (set->fullscreen_is_exclusive) {
|
if (set->fullscreen_is_exclusive) {
|
||||||
fullscreen_flag = SDL_WINDOW_FULLSCREEN;
|
fullscreen_flag = SDL_WINDOW_FULLSCREEN;
|
||||||
}
|
}
|
||||||
@@ -222,6 +246,43 @@ static void gfx_sdl_set_cursor_visibility(bool visible) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_centered_positions_native(int32_t width, int32_t height, int32_t *posX, int32_t *posY) {
|
||||||
|
const int disp_idx = SDL_GetWindowDisplayIndex(wnd);
|
||||||
|
SDL_DisplayMode mode = {};
|
||||||
|
SDL_GetDesktopDisplayMode(disp_idx, &mode);
|
||||||
|
*posX = mode.w / 2 - width / 2;
|
||||||
|
*posY = mode.h / 2 - height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_sdl_get_centered_positions(int32_t width, int32_t height, int32_t *posX, int32_t *posY) {
|
||||||
|
const int disp_idx = SDL_GetWindowDisplayIndex(wnd);
|
||||||
|
SDL_DisplayMode mode = {};
|
||||||
|
SDL_GetCurrentDisplayMode(disp_idx, &mode);
|
||||||
|
*posX = mode.w / 2 - width / 2;
|
||||||
|
*posY = mode.h / 2 - height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_sdl_set_closest_resolution(int32_t width, int32_t height, bool should_center) {
|
||||||
|
const SDL_DisplayMode mode = {.w = width, .h = height};
|
||||||
|
const int disp_idx = SDL_GetWindowDisplayIndex(wnd);
|
||||||
|
SDL_DisplayMode closest = {};
|
||||||
|
if (SDL_GetClosestDisplayMode(disp_idx, &mode, &closest)) {
|
||||||
|
SDL_SetWindowDisplayMode(wnd, &closest);
|
||||||
|
SDL_SetWindowSize(wnd, closest.w, closest.h);
|
||||||
|
if (should_center) {
|
||||||
|
int32_t posX = 0;
|
||||||
|
int32_t posY = 0;
|
||||||
|
get_centered_positions_native(closest.w, closest.h, &posX, &posY);
|
||||||
|
SDL_SetWindowPosition(wnd, posX, posY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_sdl_set_dimensions(uint32_t width, uint32_t height, int32_t posX, int32_t posY) {
|
||||||
|
SDL_SetWindowSize(wnd, width, height);
|
||||||
|
SDL_SetWindowPosition(wnd, posX, posY);
|
||||||
|
}
|
||||||
|
|
||||||
static void gfx_sdl_get_dimensions(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY) {
|
static void gfx_sdl_get_dimensions(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY) {
|
||||||
SDL_GL_GetDrawableSize(wnd, static_cast<int*>((void*)width), static_cast<int*>((void*)height));
|
SDL_GL_GetDrawableSize(wnd, static_cast<int*>((void*)width), static_cast<int*>((void*)height));
|
||||||
SDL_GetWindowPosition(wnd, static_cast<int*>(posX), static_cast<int*>(posY));
|
SDL_GetWindowPosition(wnd, static_cast<int*>(posX), static_cast<int*>(posY));
|
||||||
@@ -240,6 +301,9 @@ static void gfx_sdl_handle_events(void) {
|
|||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||||
SDL_GL_GetDrawableSize(wnd, &window_width, &window_height);
|
SDL_GL_GetDrawableSize(wnd, &window_width, &window_height);
|
||||||
|
if (!fullscreen_state) {
|
||||||
|
maximized_state = SDL_GetWindowFlags(wnd) & SDL_WINDOW_MAXIMIZED ? true : false;
|
||||||
|
}
|
||||||
} else if (event.window.event == SDL_WINDOWEVENT_CLOSE &&
|
} else if (event.window.event == SDL_WINDOWEVENT_CLOSE &&
|
||||||
event.window.windowID == SDL_GetWindowID(wnd)) {
|
event.window.windowID == SDL_GetWindowID(wnd)) {
|
||||||
// We listen specifically for main window close because closing main window
|
// We listen specifically for main window close because closing main window
|
||||||
@@ -304,6 +368,10 @@ static double gfx_sdl_get_time(void) {
|
|||||||
return SDL_GetPerformanceCounter() / (double)qpc_freq;
|
return SDL_GetPerformanceCounter() / (double)qpc_freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t gfx_sdl_get_target_fps(void) {
|
||||||
|
return target_fps;
|
||||||
|
}
|
||||||
|
|
||||||
static void gfx_sdl_set_target_fps(int fps) {
|
static void gfx_sdl_set_target_fps(int fps) {
|
||||||
target_fps = fps;
|
target_fps = fps;
|
||||||
}
|
}
|
||||||
@@ -320,6 +388,10 @@ static void gfx_sdl_set_window_title(const char *title) {
|
|||||||
SDL_SetWindowTitle(wnd, title);
|
SDL_SetWindowTitle(wnd, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gfx_sdl_get_swap_interval(void) {
|
||||||
|
return SDL_GL_GetSwapInterval();
|
||||||
|
}
|
||||||
|
|
||||||
static bool gfx_sdl_set_swap_interval(int interval) {
|
static bool gfx_sdl_set_swap_interval(int interval) {
|
||||||
const bool success = SDL_GL_SetSwapInterval(interval) >= 0;
|
const bool success = SDL_GL_SetSwapInterval(interval) >= 0;
|
||||||
vsync_enabled = success && (interval != 0);
|
vsync_enabled = success && (interval != 0);
|
||||||
@@ -329,24 +401,63 @@ static bool gfx_sdl_set_swap_interval(int interval) {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GfxWindowManagerAPI gfx_sdl = {
|
int gfx_sdl_get_display_mode(int modenum, int *out_w, int *out_h) {
|
||||||
|
const int display_in_use = SDL_GetWindowDisplayIndex(wnd);
|
||||||
|
SDL_DisplayMode sdlmode;
|
||||||
|
if (SDL_GetDisplayMode(display_in_use, modenum, &sdlmode) == 0) {
|
||||||
|
*out_w = sdlmode.w;
|
||||||
|
*out_h = sdlmode.h;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gfx_sdl_get_current_display_mode(int *out_w, int *out_h) {
|
||||||
|
const int display_in_use = SDL_GetWindowDisplayIndex(wnd);
|
||||||
|
SDL_DisplayMode sdlmode;
|
||||||
|
if (SDL_GetCurrentDisplayMode(display_in_use, &sdlmode) == 0) {
|
||||||
|
*out_w = sdlmode.w;
|
||||||
|
*out_h = sdlmode.h;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gfx_sdl_get_num_display_modes(void) {
|
||||||
|
const int display_in_use = SDL_GetWindowDisplayIndex(wnd);
|
||||||
|
return SDL_GetNumDisplayModes(display_in_use);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GfxWindowManagerAPI gfx_sdl = {
|
||||||
gfx_sdl_init,
|
gfx_sdl_init,
|
||||||
gfx_sdl_close,
|
gfx_sdl_close,
|
||||||
|
gfx_sdl_get_display_mode,
|
||||||
|
gfx_sdl_get_current_display_mode,
|
||||||
|
gfx_sdl_get_num_display_modes,
|
||||||
|
gfx_sdl_get_fullscreen_state,
|
||||||
gfx_sdl_set_fullscreen_changed_callback,
|
gfx_sdl_set_fullscreen_changed_callback,
|
||||||
gfx_sdl_set_fullscreen,
|
gfx_sdl_set_fullscreen,
|
||||||
gfx_sdl_set_fullscreen_exclusive,
|
gfx_sdl_set_fullscreen_exclusive,
|
||||||
|
gfx_sdl_set_fullscreen_flag,
|
||||||
|
gfx_sdl_get_fullscreen_flag_mode,
|
||||||
|
gfx_sdl_get_maximized_state,
|
||||||
gfx_sdl_set_maximize_window,
|
gfx_sdl_set_maximize_window,
|
||||||
gfx_sdl_get_active_window_refresh_rate,
|
gfx_sdl_get_active_window_refresh_rate,
|
||||||
gfx_sdl_set_cursor_visibility,
|
gfx_sdl_set_cursor_visibility,
|
||||||
|
gfx_sdl_set_closest_resolution,
|
||||||
|
gfx_sdl_set_dimensions,
|
||||||
gfx_sdl_get_dimensions,
|
gfx_sdl_get_dimensions,
|
||||||
|
gfx_sdl_get_centered_positions,
|
||||||
gfx_sdl_handle_events,
|
gfx_sdl_handle_events,
|
||||||
gfx_sdl_start_frame,
|
gfx_sdl_start_frame,
|
||||||
gfx_sdl_swap_buffers_begin,
|
gfx_sdl_swap_buffers_begin,
|
||||||
gfx_sdl_swap_buffers_end,
|
gfx_sdl_swap_buffers_end,
|
||||||
gfx_sdl_get_time,
|
gfx_sdl_get_time,
|
||||||
|
gfx_sdl_get_target_fps,
|
||||||
gfx_sdl_set_target_fps,
|
gfx_sdl_set_target_fps,
|
||||||
gfx_sdl_can_disable_vsync,
|
gfx_sdl_can_disable_vsync,
|
||||||
gfx_sdl_get_window_handle,
|
gfx_sdl_get_window_handle,
|
||||||
gfx_sdl_set_window_title,
|
gfx_sdl_set_window_title,
|
||||||
|
gfx_sdl_get_swap_interval,
|
||||||
gfx_sdl_set_swap_interval,
|
gfx_sdl_set_swap_interval,
|
||||||
};
|
};
|
||||||
@@ -13,28 +13,41 @@ struct GfxWindowInitSettings {
|
|||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
bool fullscreen_is_exclusive;
|
bool fullscreen_is_exclusive;
|
||||||
bool maximized;
|
bool maximized;
|
||||||
|
bool centered;
|
||||||
bool allow_hidpi;
|
bool allow_hidpi;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GfxWindowManagerAPI {
|
struct GfxWindowManagerAPI {
|
||||||
void (*init)(const struct GfxWindowInitSettings *settings);
|
void (*init)(const struct GfxWindowInitSettings *settings);
|
||||||
void (*close)(void);
|
void (*close)(void);
|
||||||
|
int (*get_display_mode)(int modenum, int *out_w, int *out_h);
|
||||||
|
int (*get_current_display_mode)(int *out_w, int *out_h);
|
||||||
|
int (*get_num_display_modes)(void);
|
||||||
|
int32_t (*get_fullscreen_state)(void);
|
||||||
void (*set_fullscreen_changed_callback)(void (*on_fullscreen_changed)(bool is_now_fullscreen));
|
void (*set_fullscreen_changed_callback)(void (*on_fullscreen_changed)(bool is_now_fullscreen));
|
||||||
void (*set_fullscreen)(bool enable);
|
void (*set_fullscreen)(bool enable);
|
||||||
void (*set_fullscreen_exclusive)(bool exc);
|
void (*set_fullscreen_exclusive)(bool exc);
|
||||||
|
void (*set_fullscreen_flag)(int32_t mode);
|
||||||
|
int32_t (*get_fullscreen_flag_mode)(void);
|
||||||
|
int32_t (*get_maximized_state)(void);
|
||||||
void (*set_maximize)(bool enable);
|
void (*set_maximize)(bool enable);
|
||||||
void (*get_active_window_refresh_rate)(uint32_t* refresh_rate);
|
void (*get_active_window_refresh_rate)(uint32_t* refresh_rate);
|
||||||
void (*set_cursor_visibility)(bool visible);
|
void (*set_cursor_visibility)(bool visible);
|
||||||
|
void (*set_closest_resolution)(int32_t width, int32_t height, bool should_center);
|
||||||
|
void (*set_dimensions)(uint32_t width, uint32_t height, int32_t posX, int32_t posY);
|
||||||
void (*get_dimensions)(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY);
|
void (*get_dimensions)(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY);
|
||||||
|
void (*get_centered_positions)(int32_t width, int32_t height, int32_t *posX, int32_t *posY);
|
||||||
void (*handle_events)(void);
|
void (*handle_events)(void);
|
||||||
bool (*start_frame)(void);
|
bool (*start_frame)(void);
|
||||||
void (*swap_buffers_begin)(void);
|
void (*swap_buffers_begin)(void);
|
||||||
void (*swap_buffers_end)(void);
|
void (*swap_buffers_end)(void);
|
||||||
double (*get_time)(void); // For debug
|
double (*get_time)(void); // For debug
|
||||||
|
int32_t (*get_target_fps)(void);
|
||||||
void (*set_target_fps)(int fps);
|
void (*set_target_fps)(int fps);
|
||||||
bool (*can_disable_vsync)(void);
|
bool (*can_disable_vsync)(void);
|
||||||
void *(*get_window_handle)(void);
|
void *(*get_window_handle)(void);
|
||||||
void (*set_window_title)(const char *);
|
void (*set_window_title)(const char *);
|
||||||
|
int (*get_swap_interval)(void);
|
||||||
bool (*set_swap_interval)(int);
|
bool (*set_swap_interval)(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,17 @@
|
|||||||
#define VIDEO_MAX_FPS 240
|
#define VIDEO_MAX_FPS 240
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
s32 width;
|
||||||
|
s32 height;
|
||||||
|
} displaymode;
|
||||||
|
|
||||||
s32 videoInit(void);
|
s32 videoInit(void);
|
||||||
void videoStartFrame(void);
|
void videoStartFrame(void);
|
||||||
void videoSubmitCommands(Gfx *cmds);
|
void videoSubmitCommands(Gfx *cmds);
|
||||||
void videoClearScreen(void);
|
void videoClearScreen(void);
|
||||||
void videoEndFrame(void);
|
void videoEndFrame(void);
|
||||||
|
f64 videoGetDiffTime(void);
|
||||||
|
|
||||||
void *videoGetWindowHandle(void);
|
void *videoGetWindowHandle(void);
|
||||||
|
|
||||||
@@ -27,17 +33,35 @@ s32 videoGetWidth(void);
|
|||||||
s32 videoGetHeight(void);
|
s32 videoGetHeight(void);
|
||||||
f32 videoGetAspect(void);
|
f32 videoGetAspect(void);
|
||||||
s32 videoGetFullscreen(void);
|
s32 videoGetFullscreen(void);
|
||||||
|
s32 videoGetFullscreenMode(void);
|
||||||
s32 videoGetMaximizeWindow(void);
|
s32 videoGetMaximizeWindow(void);
|
||||||
void videoSetMaximizeWindow(s32 fs);
|
void videoSetMaximizeWindow(s32 fs);
|
||||||
|
s32 videoGetCenterWindow(void);
|
||||||
|
void videoSetCenterWindow(s32 center);
|
||||||
u32 videoGetTextureFilter(void);
|
u32 videoGetTextureFilter(void);
|
||||||
s32 videoGetTextureFilter2D(void);
|
s32 videoGetTextureFilter2D(void);
|
||||||
s32 videoGetDetailTextures(void);
|
s32 videoGetDetailTextures(void);
|
||||||
|
s32 videoGetDisplayModeIndex(void);
|
||||||
|
s32 videoGetDisplayMode(displaymode *out, const s32 index);
|
||||||
|
s32 videoGetNumDisplayModes(void);
|
||||||
|
s32 videoGetVsync(void);
|
||||||
|
s32 videoGetFramerateLimit(void);
|
||||||
|
s32 videoGetDisplayFPS(void);
|
||||||
|
s32 videoGetDisplayFPSDivisor(void);
|
||||||
|
s32 videoGetMSAA(void);
|
||||||
|
|
||||||
void videoSetWindowOffset(s32 x, s32 y);
|
void videoSetWindowOffset(s32 x, s32 y);
|
||||||
void videoSetFullscreen(s32 fs);
|
void videoSetFullscreen(s32 fs);
|
||||||
|
void videoSetFullscreenMode(s32 mode);
|
||||||
void videoSetTextureFilter(u32 filter);
|
void videoSetTextureFilter(u32 filter);
|
||||||
void videoSetTextureFilter2D(s32 filter);
|
void videoSetTextureFilter2D(s32 filter);
|
||||||
void videoSetDetailTextures(s32 detail);
|
void videoSetDetailTextures(s32 detail);
|
||||||
|
void videoSetDisplayMode(const s32 index);
|
||||||
|
void videoSetVsync(const s32 vsync);
|
||||||
|
void videoSetFramerateLimit(const s32 limit);
|
||||||
|
void videoSetDisplayFPS(const s32 displayfps);
|
||||||
|
void videoSetDisplayFPSDivisor(const s32 divisor);
|
||||||
|
void videoSetMSAA(const s32 msaa);
|
||||||
|
|
||||||
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize);
|
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize);
|
||||||
void videoSetFramebuffer(s32 target);
|
void videoSetFramebuffer(s32 target);
|
||||||
@@ -49,4 +73,6 @@ s32 videoFramebuffersSupported(void);
|
|||||||
void videoResetTextureCache(void);
|
void videoResetTextureCache(void);
|
||||||
void videoFreeCachedTexture(const void *texptr);
|
void videoFreeCachedTexture(const void *texptr);
|
||||||
|
|
||||||
|
void videoShutdown(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -36,6 +36,7 @@ u32 g_VmNumPageReplaces = 0;
|
|||||||
u8 g_VmShowStats = 0;
|
u8 g_VmShowStats = 0;
|
||||||
|
|
||||||
s32 g_TickRateDiv = 1;
|
s32 g_TickRateDiv = 1;
|
||||||
|
s32 g_TickRateDivOverride = 0;
|
||||||
s32 g_TickExtraSleep = true;
|
s32 g_TickExtraSleep = true;
|
||||||
|
|
||||||
s32 g_SkipIntro = false;
|
s32 g_SkipIntro = false;
|
||||||
@@ -88,6 +89,7 @@ static void cleanup(void)
|
|||||||
sysLogPrintf(LOG_NOTE, "shutdown");
|
sysLogPrintf(LOG_NOTE, "shutdown");
|
||||||
inputSaveBinds();
|
inputSaveBinds();
|
||||||
configSave(CONFIG_PATH);
|
configSave(CONFIG_PATH);
|
||||||
|
videoShutdown();
|
||||||
crashShutdown();
|
crashShutdown();
|
||||||
// TODO: actually shut down all subsystems
|
// TODO: actually shut down all subsystems
|
||||||
}
|
}
|
||||||
@@ -164,6 +166,7 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
|
|||||||
configRegisterInt("Game.MenuMouseControl", &g_MenuMouseControl, 0, 1);
|
configRegisterInt("Game.MenuMouseControl", &g_MenuMouseControl, 0, 1);
|
||||||
configRegisterFloat("Game.ScreenShakeIntensity", &g_ViShakeIntensityMult, 0.f, 10.f);
|
configRegisterFloat("Game.ScreenShakeIntensity", &g_ViShakeIntensityMult, 0.f, 10.f);
|
||||||
configRegisterInt("Game.TickRateDivisor", &g_TickRateDiv, 0, 10);
|
configRegisterInt("Game.TickRateDivisor", &g_TickRateDiv, 0, 10);
|
||||||
|
configRegisterInt("Game.TickRateDivisorOverride", &g_TickRateDivOverride, 0, 1);
|
||||||
configRegisterInt("Game.ExtraSleep", &g_TickExtraSleep, 0, 1);
|
configRegisterInt("Game.ExtraSleep", &g_TickExtraSleep, 0, 1);
|
||||||
configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1);
|
configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1);
|
||||||
configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1);
|
configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1);
|
||||||
|
|||||||
+362
-10
@@ -698,6 +698,29 @@ static MenuItemHandlerResult menuhandlerFullScreen(s32 operation, struct menuite
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerFullScreenMode(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
static const char *opts[] = {
|
||||||
|
"Borderless",
|
||||||
|
"Exclusive"
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_GETOPTIONCOUNT:
|
||||||
|
data->dropdown.value = ARRAYCOUNT(opts);
|
||||||
|
break;
|
||||||
|
case MENUOP_GETOPTIONTEXT:
|
||||||
|
return (intptr_t)opts[data->dropdown.value];
|
||||||
|
case MENUOP_SET:
|
||||||
|
videoSetFullscreenMode(data->dropdown.value);
|
||||||
|
break;
|
||||||
|
case MENUOP_GETSELECTEDINDEX:
|
||||||
|
data->dropdown.value = videoGetFullscreenMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static MenuItemHandlerResult menuhandlerMaximizeWindow(s32 operation, struct menuitem *item, union handlerdata *data)
|
static MenuItemHandlerResult menuhandlerMaximizeWindow(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
@@ -711,6 +734,146 @@ static MenuItemHandlerResult menuhandlerMaximizeWindow(s32 operation, struct men
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerCenterWindow(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_GET:
|
||||||
|
return videoGetCenterWindow();
|
||||||
|
case MENUOP_SET:
|
||||||
|
videoSetCenterWindow(data->checkbox.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerVsync(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
static const char *opts[] = {
|
||||||
|
"Adaptive",
|
||||||
|
"Off",
|
||||||
|
"On (Every Frame)",
|
||||||
|
"On (Every 2 Frames)",
|
||||||
|
"On (Every 3 Frames)",
|
||||||
|
"On (Every 4 Frames)",
|
||||||
|
"On (Every 5 Frames)",
|
||||||
|
"On (Every 6 Frames)",
|
||||||
|
"On (Every 7 Frames)",
|
||||||
|
"On (Every 8 Frames)",
|
||||||
|
"On (Every 9 Frames)",
|
||||||
|
"On (Every 10 Frames)"
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_GETOPTIONCOUNT:
|
||||||
|
data->dropdown.value = ARRAYCOUNT(opts);
|
||||||
|
break;
|
||||||
|
case MENUOP_GETOPTIONTEXT:
|
||||||
|
return (intptr_t)opts[data->dropdown.value];
|
||||||
|
case MENUOP_SET:
|
||||||
|
videoSetVsync(data->dropdown.value - 1);
|
||||||
|
case MENUOP_GETSELECTEDINDEX:
|
||||||
|
data->dropdown.value = videoGetVsync() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerFramerateLimit(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_GETSLIDER:
|
||||||
|
data->slider.value = videoGetFramerateLimit();
|
||||||
|
break;
|
||||||
|
case MENUOP_SET:
|
||||||
|
if (!g_TickRateDivOverride) {
|
||||||
|
g_TickRateDiv = (data->slider.value == 0 || data->slider.value > 60) ? 0 : 1;
|
||||||
|
}
|
||||||
|
videoSetFramerateLimit(data->slider.value);
|
||||||
|
break;
|
||||||
|
case MENUOP_GETSLIDERLABEL:
|
||||||
|
// NOTE: data->slider.label length must not exceed 15.
|
||||||
|
if (data->slider.value == 0) {
|
||||||
|
strcpy(data->slider.label, "Off");
|
||||||
|
} else {
|
||||||
|
sprintf(data->slider.label, "%d FPS", data->slider.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerMSAA(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
s32 msaa;
|
||||||
|
static const char *opts[] = {
|
||||||
|
"Off",
|
||||||
|
"2x (MSAA)",
|
||||||
|
"4x (MSAA)",
|
||||||
|
"8x (MSAA)",
|
||||||
|
"16x (MSAA)"
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_GETOPTIONCOUNT:
|
||||||
|
data->dropdown.value = ARRAYCOUNT(opts);
|
||||||
|
break;
|
||||||
|
case MENUOP_GETOPTIONTEXT:
|
||||||
|
return (intptr_t)opts[data->dropdown.value];
|
||||||
|
case MENUOP_SET:
|
||||||
|
videoSetMSAA(1 << data->dropdown.value);
|
||||||
|
break;
|
||||||
|
case MENUOP_GETSELECTEDINDEX:
|
||||||
|
msaa = videoGetMSAA();
|
||||||
|
if (msaa < 2) {
|
||||||
|
data->dropdown.value = 0;
|
||||||
|
} else if (msaa < 4) {
|
||||||
|
data->dropdown.value = 1;
|
||||||
|
} else if (msaa < 8) {
|
||||||
|
data->dropdown.value = 2;
|
||||||
|
} else if (msaa < 16) {
|
||||||
|
data->dropdown.value = 3;
|
||||||
|
} else {
|
||||||
|
data->dropdown.value = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerResolution(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
static char resstring[32];
|
||||||
|
static const char *rescustom = "Custom";
|
||||||
|
displaymode mode;
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_CHECKDISABLED:
|
||||||
|
if (videoGetFullscreen() && videoGetFullscreenMode() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MENUOP_GETOPTIONCOUNT:
|
||||||
|
data->dropdown.value = videoGetNumDisplayModes();
|
||||||
|
break;
|
||||||
|
case MENUOP_GETOPTIONTEXT:
|
||||||
|
videoGetDisplayMode(&mode, data->dropdown.value);
|
||||||
|
if (mode.width == 0 && mode.height == 0) {
|
||||||
|
return (intptr_t)rescustom;
|
||||||
|
} else {
|
||||||
|
snprintf(resstring, sizeof(resstring), "%dx%d", mode.width, mode.height);
|
||||||
|
}
|
||||||
|
return (intptr_t)resstring;
|
||||||
|
case MENUOP_SET:
|
||||||
|
videoSetDisplayMode(data->dropdown.value);
|
||||||
|
break;
|
||||||
|
case MENUOP_GETSELECTEDINDEX:
|
||||||
|
data->dropdown.value = videoGetDisplayModeIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static MenuItemHandlerResult menuhandlerTexFilter(s32 operation, struct menuitem *item, union handlerdata *data)
|
static MenuItemHandlerResult menuhandlerTexFilter(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
{
|
{
|
||||||
static const char *opts[] = {
|
static const char *opts[] = {
|
||||||
@@ -755,12 +918,46 @@ static MenuItemHandlerResult menuhandlerTexFilter2D(s32 operation, struct menuit
|
|||||||
return videoGetTextureFilter2D();
|
return videoGetTextureFilter2D();
|
||||||
case MENUOP_SET:
|
case MENUOP_SET:
|
||||||
videoSetTextureFilter2D(data->checkbox.value);
|
videoSetTextureFilter2D(data->checkbox.value);
|
||||||
|
g_TexFilter2D = videoGetTextureFilter2D() ? G_TF_BILERP : G_TF_POINT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerDisplayFPS(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_GET:
|
||||||
|
return videoGetDisplayFPS();
|
||||||
|
case MENUOP_SET:
|
||||||
|
videoSetDisplayFPS(data->checkbox.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerDisplayFPSInterval(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_GETSLIDER:
|
||||||
|
data->slider.value = videoGetDisplayFPSDivisor() - 1;
|
||||||
|
break;
|
||||||
|
case MENUOP_SET:
|
||||||
|
videoSetDisplayFPSDivisor(data->dropdown.value + 1);
|
||||||
|
break;
|
||||||
|
case MENUOP_GETSLIDERLABEL:
|
||||||
|
// NOTE: data->slider.label length must not exceed 15.
|
||||||
|
if (data->slider.value == 0) {
|
||||||
|
strcpy(data->slider.label, "1 Sec");
|
||||||
|
} else {
|
||||||
|
sprintf(data->slider.label, "1/%d Secs", data->slider.value + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static MenuItemHandlerResult menuhandlerGeMuzzleFlashes(s32 operation, struct menuitem *item, union handlerdata *data)
|
static MenuItemHandlerResult menuhandlerGeMuzzleFlashes(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
@@ -774,6 +971,49 @@ static MenuItemHandlerResult menuhandlerGeMuzzleFlashes(s32 operation, struct me
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerTickrateDivisorOverride(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
s32 framerateLimit;
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_GET:
|
||||||
|
return g_TickRateDivOverride;
|
||||||
|
case MENUOP_SET:
|
||||||
|
g_TickRateDivOverride = data->checkbox.value;
|
||||||
|
if (!g_TickRateDivOverride) {
|
||||||
|
framerateLimit = videoGetFramerateLimit();
|
||||||
|
g_TickRateDiv = (framerateLimit == 0 || framerateLimit > 60) ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerTickrateDivisor(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
s32 framerateLimit;
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_CHECKHIDDEN:
|
||||||
|
if (!g_TickRateDivOverride) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MENUOP_GETSLIDER:
|
||||||
|
data->slider.value = g_TickRateDiv;
|
||||||
|
break;
|
||||||
|
case MENUOP_SET:
|
||||||
|
if (g_TickRateDivOverride) {
|
||||||
|
g_TickRateDiv = data->slider.value;
|
||||||
|
} else {
|
||||||
|
framerateLimit = videoGetFramerateLimit();
|
||||||
|
g_TickRateDiv = (framerateLimit == 0 || framerateLimit > 60) ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static MenuItemHandlerResult menuhandlerCenterHUD(s32 operation, struct menuitem *item, union handlerdata *data)
|
static MenuItemHandlerResult menuhandlerCenterHUD(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
{
|
{
|
||||||
static const char *opts[] = {
|
static const char *opts[] = {
|
||||||
@@ -831,6 +1071,22 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
|
|||||||
0,
|
0,
|
||||||
menuhandlerFullScreen,
|
menuhandlerFullScreen,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_DROPDOWN,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Full Screen Mode",
|
||||||
|
0,
|
||||||
|
menuhandlerFullScreenMode,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_DROPDOWN,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Resolution",
|
||||||
|
0,
|
||||||
|
menuhandlerResolution,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_CHECKBOX,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
0,
|
0,
|
||||||
@@ -843,9 +1099,73 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
|
|||||||
MENUITEMTYPE_CHECKBOX,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
0,
|
0,
|
||||||
MENUITEMFLAG_LITERAL_TEXT,
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
(uintptr_t)"Detail Textures",
|
(uintptr_t)"Center Window",
|
||||||
0,
|
0,
|
||||||
menuhandlerTexDetail,
|
menuhandlerCenterWindow,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_DROPDOWN,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"HUD Centering",
|
||||||
|
0,
|
||||||
|
menuhandlerCenterHUD,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SEPARATOR,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_DROPDOWN,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Vsync",
|
||||||
|
0,
|
||||||
|
menuhandlerVsync,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SLIDER,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE | MENUITEMFLAG_SLIDER_DEFERRED,
|
||||||
|
(uintptr_t)"Framerate Limit",
|
||||||
|
VIDEO_MAX_FPS,
|
||||||
|
menuhandlerFramerateLimit,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_CHECKBOX,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Display FPS",
|
||||||
|
0,
|
||||||
|
menuhandlerDisplayFPS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SLIDER,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||||
|
(uintptr_t)"Display FPS Interval",
|
||||||
|
31,
|
||||||
|
menuhandlerDisplayFPSInterval,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SEPARATOR,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_DROPDOWN,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Anti-aliasing",
|
||||||
|
0,
|
||||||
|
menuhandlerMSAA,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_DROPDOWN,
|
MENUITEMTYPE_DROPDOWN,
|
||||||
@@ -863,6 +1183,22 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
|
|||||||
0,
|
0,
|
||||||
menuhandlerTexFilter2D,
|
menuhandlerTexFilter2D,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SEPARATOR,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_CHECKBOX,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Detail Textures",
|
||||||
|
0,
|
||||||
|
menuhandlerTexDetail,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_CHECKBOX,
|
MENUITEMTYPE_CHECKBOX,
|
||||||
0,
|
0,
|
||||||
@@ -871,14 +1207,6 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
|
|||||||
0,
|
0,
|
||||||
menuhandlerGeMuzzleFlashes,
|
menuhandlerGeMuzzleFlashes,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
MENUITEMTYPE_DROPDOWN,
|
|
||||||
0,
|
|
||||||
MENUITEMFLAG_LITERAL_TEXT,
|
|
||||||
(uintptr_t)"HUD Centering",
|
|
||||||
0,
|
|
||||||
menuhandlerCenterHUD,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_SLIDER,
|
MENUITEMTYPE_SLIDER,
|
||||||
0,
|
0,
|
||||||
@@ -895,6 +1223,30 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
|
|||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_CHECKBOX,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Override Tickrate Divisor",
|
||||||
|
0,
|
||||||
|
menuhandlerTickrateDivisorOverride,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SLIDER,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
|
||||||
|
(uintptr_t)"Tickrate Divisor",
|
||||||
|
10,
|
||||||
|
menuhandlerTickrateDivisor,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SEPARATOR,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_SELECTABLE,
|
MENUITEMTYPE_SELECTABLE,
|
||||||
0,
|
0,
|
||||||
|
|||||||
+250
-18
@@ -6,6 +6,7 @@
|
|||||||
#include <PR/gbi.h>
|
#include <PR/gbi.h>
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "system.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
|
||||||
#include "../fast3d/gfx_api.h"
|
#include "../fast3d/gfx_api.h"
|
||||||
@@ -35,10 +36,17 @@ static s32 vidFramebuffers = true;
|
|||||||
static s32 vidFullscreen = DEFAULT_VID_FULLSCREEN;
|
static s32 vidFullscreen = DEFAULT_VID_FULLSCREEN;
|
||||||
static s32 vidFullscreenExclusive = DEFAULT_VID_FULLSCREEN_EXCLUSIVE;
|
static s32 vidFullscreenExclusive = DEFAULT_VID_FULLSCREEN_EXCLUSIVE;
|
||||||
static s32 vidMaximize = false;
|
static s32 vidMaximize = false;
|
||||||
|
static s32 vidCenter = false;
|
||||||
static s32 vidAllowHiDpi = false;
|
static s32 vidAllowHiDpi = false;
|
||||||
static s32 vidVsync = 1;
|
static s32 vidVsync = 1;
|
||||||
static s32 vidMSAA = 1;
|
static s32 vidMSAA = 1;
|
||||||
static s32 vidFramerateLimit = 0;
|
static s32 vidFramerateLimit = 0;
|
||||||
|
static s32 vidDisplayFPS = 0;
|
||||||
|
static s32 vidDisplayFPSDivisor = 16;
|
||||||
|
static displaymode vidModeDefault;
|
||||||
|
static s32 vidNumModes = 1;
|
||||||
|
static displaymode *vidModes = &vidModeDefault;
|
||||||
|
static f64 vidDiffTime;
|
||||||
|
|
||||||
static s32 texFilter = FILTER_LINEAR;
|
static s32 texFilter = FILTER_LINEAR;
|
||||||
static s32 texFilter2D = true;
|
static s32 texFilter2D = true;
|
||||||
@@ -46,8 +54,9 @@ static s32 texDetail = true;
|
|||||||
|
|
||||||
static u32 dlcount = 0;
|
static u32 dlcount = 0;
|
||||||
static u32 frames = 0;
|
static u32 frames = 0;
|
||||||
static u32 framesPerSec = 0;
|
static f64 startTime, endTime;
|
||||||
static f64 startTime, endTime, fpsTime;
|
|
||||||
|
static s32 videoInitDisplayModes(void);
|
||||||
|
|
||||||
s32 videoInit(void)
|
s32 videoInit(void)
|
||||||
{
|
{
|
||||||
@@ -73,22 +82,17 @@ s32 videoInit(void)
|
|||||||
.fullscreen = vidFullscreen,
|
.fullscreen = vidFullscreen,
|
||||||
.fullscreen_is_exclusive = vidFullscreenExclusive,
|
.fullscreen_is_exclusive = vidFullscreenExclusive,
|
||||||
.maximized = vidMaximize,
|
.maximized = vidMaximize,
|
||||||
|
.centered = vidCenter,
|
||||||
.allow_hidpi = vidAllowHiDpi
|
.allow_hidpi = vidAllowHiDpi
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gfx_init(&set);
|
gfx_init(&set);
|
||||||
|
|
||||||
if (!wmAPI->set_swap_interval(vidVsync)) {
|
videoInitDisplayModes();
|
||||||
vidVsync = 0;
|
videoSetVsync(vidVsync);
|
||||||
}
|
videoSetFramerateLimit(vidFramerateLimit);
|
||||||
|
|
||||||
if (vidVsync == 0 && vidFramerateLimit == 0) {
|
|
||||||
// cap FPS if there's no vsync to prevent the game from exploding
|
|
||||||
vidFramerateLimit = VIDEO_MAX_FPS;
|
|
||||||
}
|
|
||||||
|
|
||||||
wmAPI->set_target_fps(vidFramerateLimit); // disabled because vsync is on
|
|
||||||
gfx_set_texture_filter((enum FilteringMode)texFilter);
|
gfx_set_texture_filter((enum FilteringMode)texFilter);
|
||||||
|
|
||||||
initDone = true;
|
initDone = true;
|
||||||
@@ -101,6 +105,10 @@ void videoStartFrame(void)
|
|||||||
startTime = wmAPI->get_time();
|
startTime = wmAPI->get_time();
|
||||||
gfx_start_frame();
|
gfx_start_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Synchronize with their backend counterparts.
|
||||||
|
vidFullscreen = videoGetFullscreen();
|
||||||
|
vidMaximize = videoGetMaximizeWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void videoSubmitCommands(Gfx *cmds)
|
void videoSubmitCommands(Gfx *cmds)
|
||||||
@@ -113,26 +121,33 @@ void videoSubmitCommands(Gfx *cmds)
|
|||||||
|
|
||||||
void videoEndFrame(void)
|
void videoEndFrame(void)
|
||||||
{
|
{
|
||||||
|
static f64 accumTime = 0.0;
|
||||||
|
|
||||||
if (!initDone) {
|
if (!initDone) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx_end_frame();
|
gfx_end_frame();
|
||||||
|
|
||||||
endTime = wmAPI->get_time();
|
|
||||||
|
|
||||||
++frames;
|
++frames;
|
||||||
++framesPerSec;
|
|
||||||
|
|
||||||
if (endTime >= fpsTime) {
|
endTime = wmAPI->get_time();
|
||||||
|
accumTime += endTime - startTime;
|
||||||
|
|
||||||
|
if (accumTime >= 1.0 / (f64)vidDisplayFPSDivisor) {
|
||||||
char tmp[128];
|
char tmp[128];
|
||||||
snprintf(tmp, sizeof(tmp), "fps %3u frt %lf frm %u", framesPerSec, endTime - startTime, frames);
|
vidDiffTime = endTime - startTime;
|
||||||
|
accumTime = 0.0;
|
||||||
|
snprintf(tmp, sizeof(tmp), "fps %3u frt %lf frm %u", (u32)(1.0 / vidDiffTime), vidDiffTime, frames);
|
||||||
wmAPI->set_window_title(tmp);
|
wmAPI->set_window_title(tmp);
|
||||||
framesPerSec = 0;
|
|
||||||
fpsTime = endTime + 1.0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f64 videoGetDiffTime(void)
|
||||||
|
{
|
||||||
|
return vidDiffTime;
|
||||||
|
}
|
||||||
|
|
||||||
void videoClearScreen(void)
|
void videoClearScreen(void)
|
||||||
{
|
{
|
||||||
videoStartFrame();
|
videoStartFrame();
|
||||||
@@ -177,19 +192,164 @@ s32 videoGetHeight(void)
|
|||||||
|
|
||||||
s32 videoGetFullscreen(void)
|
s32 videoGetFullscreen(void)
|
||||||
{
|
{
|
||||||
|
vidFullscreen = wmAPI->get_fullscreen_state();
|
||||||
return vidFullscreen;
|
return vidFullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 videoGetFullscreenMode(void)
|
||||||
|
{
|
||||||
|
vidFullscreenExclusive = wmAPI->get_fullscreen_flag_mode();
|
||||||
|
return vidFullscreenExclusive;
|
||||||
|
}
|
||||||
|
|
||||||
s32 videoGetMaximizeWindow(void)
|
s32 videoGetMaximizeWindow(void)
|
||||||
{
|
{
|
||||||
|
vidMaximize = wmAPI->get_maximized_state();
|
||||||
return vidMaximize;
|
return vidMaximize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 videoGetCenterWindow(void)
|
||||||
|
{
|
||||||
|
return vidCenter;
|
||||||
|
}
|
||||||
|
|
||||||
f32 videoGetAspect(void)
|
f32 videoGetAspect(void)
|
||||||
{
|
{
|
||||||
return gfx_current_dimensions.aspect_ratio;
|
return gfx_current_dimensions.aspect_ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 videoGetDisplayModeIndex(void)
|
||||||
|
{
|
||||||
|
for (s32 i = 1; i < vidNumModes; ++i) {
|
||||||
|
if (vidModes[i].width == gfx_current_dimensions.width &&
|
||||||
|
vidModes[i].height == gfx_current_dimensions.height) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Current dimensions don't match any known mode, so return index 0, "Custom".
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 videoGetMSAA(void)
|
||||||
|
{
|
||||||
|
vidMSAA = (s32)gfx_msaa_level;
|
||||||
|
return vidMSAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 videoGetVsync(void)
|
||||||
|
{
|
||||||
|
vidVsync = wmAPI->get_swap_interval();
|
||||||
|
return vidVsync;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 videoGetFramerateLimit(void)
|
||||||
|
{
|
||||||
|
vidFramerateLimit = wmAPI->get_target_fps();
|
||||||
|
return vidFramerateLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 videoGetDisplayFPS(void)
|
||||||
|
{
|
||||||
|
return vidDisplayFPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 videoGetDisplayFPSDivisor(void)
|
||||||
|
{
|
||||||
|
return vidDisplayFPSDivisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32 videoInitDisplayModes(void)
|
||||||
|
{
|
||||||
|
if (!wmAPI->get_current_display_mode(&vidModeDefault.width, &vidModeDefault.height)) {
|
||||||
|
vidModeDefault.width = 640;
|
||||||
|
vidModeDefault.height = 480;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const s32 numBaseModes = wmAPI->get_num_display_modes();
|
||||||
|
if (!numBaseModes) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const s32 numCustomModes = 1;
|
||||||
|
displaymode *modeList = sysMemZeroAlloc((numBaseModes + numCustomModes) * sizeof(displaymode));
|
||||||
|
if (!modeList) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
modeList[0].width = 0;
|
||||||
|
modeList[0].height = 0;
|
||||||
|
|
||||||
|
s32 numModes = 1;
|
||||||
|
s32 w = -1, h = w, neww = w, newh = w;
|
||||||
|
|
||||||
|
// SDL modes are guaranteed to be sorted high to low
|
||||||
|
for (s32 i = 0; i < numBaseModes; ++i) {
|
||||||
|
wmAPI->get_display_mode(i, &neww, &newh);
|
||||||
|
|
||||||
|
if (neww != w || newh != h) {
|
||||||
|
w = neww;
|
||||||
|
h = newh;
|
||||||
|
modeList[numModes].width = w;
|
||||||
|
modeList[numModes].height = h;
|
||||||
|
++numModes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modeList = sysMemRealloc(modeList, numModes * sizeof(displaymode));
|
||||||
|
if (!modeList) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vidModes = modeList;
|
||||||
|
vidNumModes = numModes;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 videoGetDisplayMode(displaymode *out, const s32 index)
|
||||||
|
{
|
||||||
|
if (index >= 0 && index < vidNumModes) {
|
||||||
|
*out = vidModes[index];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 videoGetNumDisplayModes(void)
|
||||||
|
{
|
||||||
|
return vidNumModes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void videoSetDisplayMode(const s32 index)
|
||||||
|
{
|
||||||
|
const displaymode dm = vidModes[index];
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
// "Custom" video mode.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vidWidth = dm.width;
|
||||||
|
vidHeight = dm.height;
|
||||||
|
|
||||||
|
s32 posX = 100;
|
||||||
|
s32 posY = 100;
|
||||||
|
if (vidCenter) {
|
||||||
|
wmAPI->get_centered_positions(vidWidth, vidHeight, &posX, &posY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vidFullscreen) {
|
||||||
|
wmAPI->set_closest_resolution(vidWidth, vidHeight, vidCenter);
|
||||||
|
} else {
|
||||||
|
if (vidMaximize) {
|
||||||
|
videoSetMaximizeWindow(false);
|
||||||
|
} else {
|
||||||
|
wmAPI->set_dimensions(vidWidth, vidHeight, posX, posY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s32 videoGetTextureFilter2D(void)
|
s32 videoGetTextureFilter2D(void)
|
||||||
{
|
{
|
||||||
return texFilter2D;
|
return texFilter2D;
|
||||||
@@ -215,7 +375,22 @@ void videoSetFullscreen(s32 fs)
|
|||||||
{
|
{
|
||||||
if (fs != vidFullscreen) {
|
if (fs != vidFullscreen) {
|
||||||
vidFullscreen = !!fs;
|
vidFullscreen = !!fs;
|
||||||
|
wmAPI->set_closest_resolution(vidWidth, vidHeight, vidCenter);
|
||||||
wmAPI->set_fullscreen(vidFullscreen);
|
wmAPI->set_fullscreen(vidFullscreen);
|
||||||
|
if (!vidFullscreen && vidMaximize) {
|
||||||
|
wmAPI->set_maximize(false);
|
||||||
|
wmAPI->set_maximize(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void videoSetFullscreenMode(s32 mode)
|
||||||
|
{
|
||||||
|
vidFullscreenExclusive = mode;
|
||||||
|
wmAPI->set_fullscreen_flag(mode);
|
||||||
|
if (vidFullscreen) {
|
||||||
|
wmAPI->set_fullscreen(false);
|
||||||
|
wmAPI->set_fullscreen(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,6 +399,23 @@ void videoSetMaximizeWindow(s32 fs)
|
|||||||
if (fs != vidMaximize) {
|
if (fs != vidMaximize) {
|
||||||
vidMaximize = !!fs;
|
vidMaximize = !!fs;
|
||||||
wmAPI->set_maximize(vidMaximize);
|
wmAPI->set_maximize(vidMaximize);
|
||||||
|
if (vidCenter && !vidMaximize) {
|
||||||
|
s32 posX = 0;
|
||||||
|
s32 posY = 0;
|
||||||
|
wmAPI->get_centered_positions(vidWidth, vidHeight, &posX, &posY);
|
||||||
|
wmAPI->set_dimensions(vidWidth, vidHeight, posX, posY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void videoSetCenterWindow(s32 center)
|
||||||
|
{
|
||||||
|
vidCenter = center;
|
||||||
|
if (vidCenter && !vidMaximize) {
|
||||||
|
s32 posX = 0;
|
||||||
|
s32 posY = 0;
|
||||||
|
wmAPI->get_centered_positions(vidWidth, vidHeight, &posX, &posY);
|
||||||
|
wmAPI->set_dimensions(vidWidth, vidHeight, posX, posY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +443,38 @@ s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize)
|
|||||||
return gfx_create_framebuffer(w, h, upscale, autoresize);
|
return gfx_create_framebuffer(w, h, upscale, autoresize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void videoSetMSAA(const s32 msaa)
|
||||||
|
{
|
||||||
|
vidMSAA = msaa;
|
||||||
|
gfx_msaa_level = (u32)vidMSAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
void videoSetVsync(const s32 vsync)
|
||||||
|
{
|
||||||
|
vidVsync = wmAPI->set_swap_interval(vsync) ? vsync : 0;
|
||||||
|
|
||||||
|
if (vidVsync == 0 && vidFramerateLimit == 0) {
|
||||||
|
// cap FPS if there's no vsync to prevent the game from exploding
|
||||||
|
videoSetFramerateLimit(VIDEO_MAX_FPS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void videoSetFramerateLimit(const s32 limit)
|
||||||
|
{
|
||||||
|
vidFramerateLimit = (vidVsync == 0 && limit == 0) ? VIDEO_MAX_FPS : limit;
|
||||||
|
wmAPI->set_target_fps(vidFramerateLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void videoSetDisplayFPS(const s32 displayfps)
|
||||||
|
{
|
||||||
|
vidDisplayFPS = displayfps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void videoSetDisplayFPSDivisor(const s32 divisor)
|
||||||
|
{
|
||||||
|
vidDisplayFPSDivisor = divisor;
|
||||||
|
}
|
||||||
|
|
||||||
void videoSetFramebuffer(s32 target)
|
void videoSetFramebuffer(s32 target)
|
||||||
{
|
{
|
||||||
return gfx_set_framebuffer(target, 1.f);
|
return gfx_set_framebuffer(target, 1.f);
|
||||||
@@ -287,6 +511,11 @@ void videoFreeCachedTexture(const void *texptr)
|
|||||||
gfx_texture_cache_delete(texptr);
|
gfx_texture_cache_delete(texptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void videoShutdown(void)
|
||||||
|
{
|
||||||
|
free(vidModes);
|
||||||
|
}
|
||||||
|
|
||||||
PD_CONSTRUCTOR static void videoConfigInit(void)
|
PD_CONSTRUCTOR static void videoConfigInit(void)
|
||||||
{
|
{
|
||||||
configRegisterInt("Video.DefaultFullscreen", &vidFullscreen, 0, 1);
|
configRegisterInt("Video.DefaultFullscreen", &vidFullscreen, 0, 1);
|
||||||
@@ -294,10 +523,13 @@ PD_CONSTRUCTOR static void videoConfigInit(void)
|
|||||||
configRegisterInt("Video.DefaultWidth", &vidWidth, 0, 32767);
|
configRegisterInt("Video.DefaultWidth", &vidWidth, 0, 32767);
|
||||||
configRegisterInt("Video.DefaultHeight", &vidHeight, 0, 32767);
|
configRegisterInt("Video.DefaultHeight", &vidHeight, 0, 32767);
|
||||||
configRegisterInt("Video.ExclusiveFullscreen", &vidFullscreenExclusive, 0, 1);
|
configRegisterInt("Video.ExclusiveFullscreen", &vidFullscreenExclusive, 0, 1);
|
||||||
|
configRegisterInt("Video.CenterWindow", &vidCenter, 0, 1);
|
||||||
configRegisterInt("Video.AllowHiDpi", &vidAllowHiDpi, 0, 1);
|
configRegisterInt("Video.AllowHiDpi", &vidAllowHiDpi, 0, 1);
|
||||||
configRegisterInt("Video.VSync", &vidVsync, -1, 10);
|
configRegisterInt("Video.VSync", &vidVsync, -1, 10);
|
||||||
configRegisterInt("Video.FramebufferEffects", &vidFramebuffers, 0, 1);
|
configRegisterInt("Video.FramebufferEffects", &vidFramebuffers, 0, 1);
|
||||||
configRegisterInt("Video.FramerateLimit", &vidFramerateLimit, 0, VIDEO_MAX_FPS);
|
configRegisterInt("Video.FramerateLimit", &vidFramerateLimit, 0, VIDEO_MAX_FPS);
|
||||||
|
configRegisterInt("Video.DisplayFPS", &vidDisplayFPS, 0, 1);
|
||||||
|
configRegisterInt("Video.DisplayFPSDivisor", &vidDisplayFPSDivisor, 1, 32);
|
||||||
configRegisterInt("Video.MSAA", &vidMSAA, 1, 16);
|
configRegisterInt("Video.MSAA", &vidMSAA, 1, 16);
|
||||||
configRegisterInt("Video.TextureFilter", &texFilter, 0, 2);
|
configRegisterInt("Video.TextureFilter", &texFilter, 0, 2);
|
||||||
configRegisterInt("Video.TextureFilter2D", &texFilter2D, 0, 1);
|
configRegisterInt("Video.TextureFilter2D", &texFilter2D, 0, 1);
|
||||||
|
|||||||
@@ -96,6 +96,9 @@
|
|||||||
#include "lib/vars.h"
|
#include "lib/vars.h"
|
||||||
#include "lib/vi.h"
|
#include "lib/vi.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
#include "video.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sndstate *g_MiscSfxAudioHandles[3];
|
struct sndstate *g_MiscSfxAudioHandles[3];
|
||||||
u32 var800aa5bc;
|
u32 var800aa5bc;
|
||||||
@@ -951,6 +954,35 @@ void lvFindThreats(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
Gfx *lvRenderFPS(Gfx *gdl)
|
||||||
|
{
|
||||||
|
s32 x = 27, y = 13;
|
||||||
|
f32 fps = 1.0f / videoGetDiffTime();
|
||||||
|
s32 ifps = (s32)fps;
|
||||||
|
u8 r = (ifps <= 30) ? 255 : (ifps <= 60) ? roundf(255 * (1.0f - (ifps - 30.0f) / 30.0f)) : 0;
|
||||||
|
u8 g = (ifps <= 30) ? roundf(255 * (ifps - 1.0f) / 29.0f) : 255;
|
||||||
|
u8 b = (ifps > 60 && ifps <= 90) ? roundf(255 * (ifps - 60.0f) / 30.0f) : (ifps > 90) ? 255 : 0;
|
||||||
|
u8 a = 160;
|
||||||
|
u32 color = r << 24 | g << 16 | b << 8 | a;
|
||||||
|
char buffer[16];
|
||||||
|
|
||||||
|
if (g_CharsNumeric && g_FontNumeric) {
|
||||||
|
snprintf(buffer, sizeof buffer, "%.2f", fps);
|
||||||
|
|
||||||
|
gSPSetExtraGeometryModeEXT(gdl++, g_HudAlignModeL);
|
||||||
|
|
||||||
|
gdl = text0f153628(gdl);
|
||||||
|
gdl = textRender(gdl, &x, &y, buffer, g_CharsNumeric, g_FontNumeric, color, 0x000000a0, viGetWidth(), viGetHeight(), 0, 0);
|
||||||
|
gdl = text0f153780(gdl);
|
||||||
|
|
||||||
|
gSPClearExtraGeometryModeEXT(gdl++, g_HudAlignModeL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gdl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a complete frame for all players, and also does some other game logic
|
* Renders a complete frame for all players, and also does some other game logic
|
||||||
* that really doesn't belong here.
|
* that really doesn't belong here.
|
||||||
@@ -1745,6 +1777,12 @@ Gfx *lvRender(Gfx *gdl)
|
|||||||
|
|
||||||
gDPSetScissor(gdl++, G_SC_NON_INTERLACE, 0, 0, viGetWidth(), viGetHeight());
|
gDPSetScissor(gdl++, G_SC_NON_INTERLACE, 0, 0, viGetWidth(), viGetHeight());
|
||||||
|
|
||||||
|
#ifndef PLATFORM_N64
|
||||||
|
if (videoGetDisplayFPS()) {
|
||||||
|
gdl = lvRenderFPS(gdl);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if VERSION < VERSION_NTSC_1_0
|
#if VERSION < VERSION_NTSC_1_0
|
||||||
if ((uintptr_t)gdl < (uintptr_t)g_GfxBuffers[g_GfxActiveBufferIndex]
|
if ((uintptr_t)gdl < (uintptr_t)g_GfxBuffers[g_GfxActiveBufferIndex]
|
||||||
|| (uintptr_t)gdl > (uintptr_t)g_GfxBuffers[g_GfxActiveBufferIndex + 1]) {
|
|| (uintptr_t)gdl > (uintptr_t)g_GfxBuffers[g_GfxActiveBufferIndex + 1]) {
|
||||||
|
|||||||
+44
-11
@@ -50,6 +50,8 @@ u8 g_KeyboardKeys[5][10] = {
|
|||||||
{ '1','2','1','2','1','2','3','1','2','3' },
|
{ '1','2','1','2','1','2','3','1','2','3' },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static s32 deferredindex = -1;
|
||||||
|
|
||||||
s32 func0f0e5ce0(s32 value)
|
s32 func0f0e5ce0(s32 value)
|
||||||
{
|
{
|
||||||
if (value < var800711a4) {
|
if (value < var800711a4) {
|
||||||
@@ -2266,7 +2268,7 @@ Gfx* menuitemColorBoxRender(Gfx *gdl, struct menurendercontext *context)
|
|||||||
return gdl;
|
return gdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Gfx *menuitemSelectableRender(Gfx *gdl, struct menurendercontext *context)
|
Gfx *menuitemSelectableRender(Gfx *gdl, struct menurendercontext *context)
|
||||||
{
|
{
|
||||||
@@ -2427,8 +2429,15 @@ Gfx *menuitemSliderRender(Gfx *gdl, struct menurendercontext *context)
|
|||||||
extray = 0;
|
extray = 0;
|
||||||
|
|
||||||
if (context->item->handler != NULL) {
|
if (context->item->handler != NULL) {
|
||||||
context->item->handler(MENUOP_GETSLIDER, context->item, &data);
|
if ((context->item->flags & MENUITEMFLAG_SLIDER_DEFERRED) &&
|
||||||
slidervalue = (s16) data.slider.value;
|
deferredindex != -1 &&
|
||||||
|
context->dialog->dimmed &&
|
||||||
|
context->focused) {
|
||||||
|
slidervalue = (s16) deferredindex;
|
||||||
|
} else {
|
||||||
|
context->item->handler(MENUOP_GETSLIDER, context->item, &data);
|
||||||
|
slidervalue = (s16) data.slider.value;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
slidervalue = 0;
|
slidervalue = 0;
|
||||||
}
|
}
|
||||||
@@ -2567,9 +2576,14 @@ bool menuitemSliderTick(struct menuitem *item, struct menudialog *dialog, struct
|
|||||||
index = item->param3;
|
index = item->param3;
|
||||||
}
|
}
|
||||||
if (item->handler) {
|
if (item->handler) {
|
||||||
item->handler(MENUOP_GET, item, &handlerdata);
|
if ((item->flags & MENUITEMFLAG_SLIDER_DEFERRED) &&
|
||||||
handlerdata.slider.value = index;
|
(tickflags & MENUTICKFLAG_DIALOGISDIMMED)) {
|
||||||
item->handler(MENUOP_SET, item, &handlerdata);
|
deferredindex = index;
|
||||||
|
} else {
|
||||||
|
item->handler(MENUOP_GET, item, &handlerdata);
|
||||||
|
handlerdata.slider.value = index;
|
||||||
|
item->handler(MENUOP_SET, item, &handlerdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2579,8 +2593,17 @@ bool menuitemSliderTick(struct menuitem *item, struct menudialog *dialog, struct
|
|||||||
|
|
||||||
if (tickflags & MENUTICKFLAG_DIALOGISDIMMED) {
|
if (tickflags & MENUTICKFLAG_DIALOGISDIMMED) {
|
||||||
if (item->handler) {
|
if (item->handler) {
|
||||||
item->handler(MENUOP_GETSLIDER, item, &handlerdata);
|
if (item->flags & MENUITEMFLAG_SLIDER_DEFERRED) {
|
||||||
index = (s16) handlerdata.slider.value;
|
if (deferredindex == -1) {
|
||||||
|
item->handler(MENUOP_GETSLIDER, item, &handlerdata);
|
||||||
|
deferredindex = (s16) handlerdata.slider.value;
|
||||||
|
}
|
||||||
|
index = deferredindex;
|
||||||
|
} else {
|
||||||
|
item->handler(MENUOP_GETSLIDER, item, &handlerdata);
|
||||||
|
index = (s16) handlerdata.slider.value;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
@@ -2660,11 +2683,21 @@ bool menuitemSliderTick(struct menuitem *item, struct menudialog *dialog, struct
|
|||||||
inputs->leftright = 0;
|
inputs->leftright = 0;
|
||||||
handlerdata.slider.value = index;
|
handlerdata.slider.value = index;
|
||||||
|
|
||||||
if (item->handler) {
|
if (item->flags & MENUITEMFLAG_SLIDER_DEFERRED) {
|
||||||
item->handler(MENUOP_SET, item, &handlerdata);
|
deferredindex = index;
|
||||||
|
} else {
|
||||||
|
if (item->handler) {
|
||||||
|
item->handler(MENUOP_SET, item, &handlerdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputs->select) {
|
if (inputs->select) {
|
||||||
|
if (item->flags & MENUITEMFLAG_SLIDER_DEFERRED) {
|
||||||
|
deferredindex = -1;
|
||||||
|
if (item->handler) {
|
||||||
|
item->handler(MENUOP_SET, item, &handlerdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
dialog->dimmed = false;
|
dialog->dimmed = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2704,7 +2737,7 @@ Gfx *menuitemCarouselRender(Gfx *gdl, struct menurendercontext *context)
|
|||||||
|
|
||||||
#ifdef PLATFORM_N64
|
#ifdef PLATFORM_N64
|
||||||
s16 chevronOffset = 0;
|
s16 chevronOffset = 0;
|
||||||
#else
|
#else
|
||||||
s16 chevronOffset = 3;
|
s16 chevronOffset = 3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1666,6 +1666,7 @@
|
|||||||
#define MENUITEMFLAG_CAROUSEL_04000000 0x04000000
|
#define MENUITEMFLAG_CAROUSEL_04000000 0x04000000
|
||||||
#define MENUITEMFLAG_LITERAL_TEXT 0x08000000
|
#define MENUITEMFLAG_LITERAL_TEXT 0x08000000
|
||||||
#define MENUITEMFLAG_SLIDER_WIDE 0x10000000
|
#define MENUITEMFLAG_SLIDER_WIDE 0x10000000
|
||||||
|
#define MENUITEMFLAG_SLIDER_DEFERRED 0x20000000
|
||||||
|
|
||||||
#define MENUITEMTYPE_LABEL 0x01
|
#define MENUITEMTYPE_LABEL 0x01
|
||||||
#define MENUITEMTYPE_LIST 0x02
|
#define MENUITEMTYPE_LIST 0x02
|
||||||
@@ -1696,7 +1697,7 @@
|
|||||||
|
|
||||||
#ifndef PLATFORM_N64
|
#ifndef PLATFORM_N64
|
||||||
#define MENUITEMTYPE_COLORBOX 0x1b
|
#define MENUITEMTYPE_COLORBOX 0x1b
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MENUMODELFLAG_HASSCALE 0x01
|
#define MENUMODELFLAG_HASSCALE 0x01
|
||||||
#define MENUMODELFLAG_HASPOSITION 0x02
|
#define MENUMODELFLAG_HASPOSITION 0x02
|
||||||
|
|||||||
@@ -551,6 +551,7 @@ extern s32 g_BlurFb;
|
|||||||
extern s32 g_BlurFbCapTimer;
|
extern s32 g_BlurFbCapTimer;
|
||||||
extern bool g_BlurFbDirty;
|
extern bool g_BlurFbDirty;
|
||||||
extern s32 g_TickRateDiv;
|
extern s32 g_TickRateDiv;
|
||||||
|
extern s32 g_TickRateDivOverride;
|
||||||
extern s32 g_TickExtraSleep;
|
extern s32 g_TickExtraSleep;
|
||||||
extern s32 g_MusicDisableMpDeath;
|
extern s32 g_MusicDisableMpDeath;
|
||||||
extern s32 g_BgunGeMuzzleFlashes;
|
extern s32 g_BgunGeMuzzleFlashes;
|
||||||
|
|||||||
Reference in new issue
Block a user