Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions gpu/vk/vk_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,8 @@ const char* tx_robust(int v) {
return (unsigned)v < 3 ? t[v] : t[0];
}
const char* tx_preset(int v) {
static const char* t[] = {"Custom", "Minimum (4GB)", "Low (6GB)", "Balanced (8GB)", "High (12GB)", "Ultra (16GB+)"};
return t[std::min(std::max(v, 0), 5)];
static const char* t[] = {"Custom", "Minimum (4GB)", "Low (6GB)", "Balanced (8GB)", "High (12GB)", "Ultra (16GB+)", "PS3-style (720p)"};
return t[std::min(std::max(v, 0), 6)];
}
void sync_preset_budgets(int p) {
switch (p) {
Expand Down Expand Up @@ -544,6 +544,12 @@ void apply_preset(int p) {
opts.resolution = 1; opts.upscale = 2; opts.sharpness = 50;
opts.pace = 1; opts.realtime = 1; opts.handheld = 0;
break;
case 6: // PS3-style: 67% of a 1920x1080 output is about 1280x720
opts.output_res = 3; opts.native_scene = 1; opts.resolution = 3;
opts.upscale = 2; opts.sharpness = 30; opts.anisotropy = 0;
opts.pace = 1; opts.realtime = 1; opts.handheld = 0;
opts.sampler_cache = 1;
break;
default:
break;
}
Expand All @@ -558,7 +564,8 @@ MENU_HINTS(hn_preset, 0, "Each row as you set it. Changing most rows yourself co
"Resolution 75% (with DLSS its nearest mode), Lanczos, Sharpness 30%, the Handheld Profile.",
"Resolution 100% (with DLSS its nearest mode), Catmull-Rom, Sharpness 30%.",
"Resolution 100% (with DLSS its nearest mode), Lanczos, Sharpness 40%.",
"Resolution 100% (with DLSS its nearest mode), Lanczos, Sharpness 50%.")
"Resolution 100% (with DLSS its nearest mode), Lanczos, Sharpness 50%.",
"A 1920x1080 output with the 3D at about 1280x720, Lanczos scaling, low anisotropic filtering and the texture-streaming cache. A PS3-era performance look, not GTA V assets.")
MENU_HINTS(hn_gpu, 0, "The best dedicated GPU.")
/// Frame generation: how many frames are made for each of the game's
const char* hn_framegen(int v, int variant) {
Expand Down Expand Up @@ -635,7 +642,7 @@ MENU_HINTS(hn_prompts, 0,
Row rows[] = {
// Graphics (Reflex, Anti-Lag 2, the Upscaler and the DLSS model only where they run here; HDR's paper white and peak
// brightness only with HDR on: row_shown)
{TAB_GRAPHICS, "Quality preset", &opts.preset, 0, 5, 1, tx_preset,
{TAB_GRAPHICS, "Quality preset", &opts.preset, 0, 6, 1, tx_preset,
"Sets the scaling rows and memory limits for a GPU with that much memory. The Upscaler and Frame generation stay yours.",
hn_preset},
{TAB_GRAPHICS, "Fullscreen", &opts.fullscreen, 0, 1, 1, tx_onoff,
Expand Down Expand Up @@ -673,13 +680,17 @@ Row rows[] = {
"Which of NVIDIA's DLSS networks draws the picture.", hn_dlss_model, false, true},
{TAB_GRAPHICS, "Render resolution", &opts.resolution, 0, ur::kValues - 1, 1, tx_resolution,
"The share of the output the 3D is drawn at; the Upscaler fills in the rest.", hn_resolution},
{TAB_GRAPHICS, "Native 3D resolution", &opts.native_scene, 0, 1, 1, tx_onoff,
"Uses the full scene base scale instead of the game's 0.8 scale. Sharper 3D, with more GPU work. Applies after a restart." , nullptr, true},
{TAB_GRAPHICS, "Window scaling filter", &opts.upscale, 0, 2, 1, tx_filter,
"How the finished picture is scaled to the window, when its size differs from the Output resolution.", hn_filter},
{TAB_GRAPHICS, "Sharpness", &opts.sharpness, 0, 100, 10, tx_percent,
"Sharpens the picture as it goes to the window, with any filter. Too much shows halos around edges.", hn_sharpness},
{TAB_GRAPHICS, "Anisotropic filtering", &opts.anisotropy, 0, 4, 1, tx_anisotropy,
"Keeps textures sharp on surfaces seen at a slant, such as the ground ahead: higher is sharper in the distance, for a "
"little GPU time. Game's is the console's own (1x or 2x).", nullptr},
{TAB_GRAPHICS, "Texture streaming cache", &opts.sampler_cache, 0, 1, 1, tx_onoff,
"Keeps sampler settings on the replay thread, avoiding a registration lock while textures stream. Can reduce stalls when entering new areas. Applies after a restart.", nullptr, true},
{TAB_GRAPHICS, "Profile", &opts.handheld, 0, 1, 1, tx_profile,
"Runs the game as the console docked or handheld. Applies after a restart.", hn_handheld, true},
{TAB_GRAPHICS, "Ultrawide", &opts.ultrawide, 0, 1, 1, tx_ultrawide,
Expand Down Expand Up @@ -802,9 +813,6 @@ Row rows[] = {
{TAB_DEBUG, "Descriptor reuse", &opts.descriptor_reuse, 0, 1, 1, tx_onoff,
"A draw keeps its descriptors while the texture slots it samples are unchanged, so streaming elsewhere in the game no longer "
"rebuilds every set each frame. Applies after restart.", nullptr, true},
{TAB_DEBUG, "Sampler cache", &opts.sampler_cache, 0, 1, 1, tx_onoff,
"What a sampler holds is kept beside it on the replay thread, so resolving a sampler that was not registered anew takes no "
"lock. Helps while the game streams textures. Applies after restart.", nullptr, true},
// (Restart and Quit stay the table's last two: kRestartRow and kQuitRow count back from its end)
{TAB_GAMEPLAY, "Restart", nullptr, 0, 0, 0, nullptr,
"Starts the game again. Save your progress first. Press Enter or A twice to restart. Esc or B "
Expand Down Expand Up @@ -1077,6 +1085,8 @@ const char* ini_key(const Row& r) {
if (r.value == &opts.upscale) return "upscaling";
if (r.value == &opts.dlss) return "dlss"; // (as opts.dlss and RX_VK_DLSS)
if (r.value == &opts.handheld) return "handheld_profile"; // (the Profile row; host/nn_applet.c reads it at the start)
if (r.value == &opts.sampler_cache) return "sampler_cache"; // (gpu/vk_draw.cpp reads it before the menu loads)
if (r.value == &opts.native_scene) return "native_3d_resolution"; // (host/hos_main.c reads it at the start)
static char k[32];
size_t n = 0;
for (const char* p = r.name; *p && n + 1 < sizeof k; p++) k[n++] = *p == ' ' ? '_' : (char)tolower(*p);
Expand Down
1 change: 1 addition & 0 deletions gpu/vk/vk_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct Options {
int fps_cap = 0; // (hookshot) Frame rate cap: 0 60 (the console's), 90, 120, 144, 165, 240 (host/nn_vi.c reads frame_rate_cap= at the start)
int resolution = 0; // the 3D's (Render resolution): 0 Auto (the game's dynamic resolution), else a share of the output,
// 1..6 = 100%, 75%, 67%, 50%, 58%, 33% (upscaler_rows.h; nx2/oot_patches.py)
int native_scene = 1; // the game's 0.8 scene base scale changed to 1.0 (host/hos_main.c, nx2/oot_native_resolution.py)
int output_res = 0; // the game's whole frame, docked: 0 its 2048x1152, 1 2560x1440, 2 3840x2160, 3 1920x1080, 4 5120x1440, 5 5120x2880,
// 6 the player's own (vk_menu.cpp custom_output); saved as the size (output_res=3840x2160) and read once, at the start
// (host/nn_applet.c)
Expand Down
2 changes: 2 additions & 0 deletions hookshot_env.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
RX_VK_NOOPT=1
RX_VK_CHECKPOINTS=1
12 changes: 8 additions & 4 deletions host/hos_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,7 @@ volatile uint64_t hos_wide_out, hos_wide_scene;
HOS_SCENE_NATIVE=0/1 over it */
volatile int hos_native_scene;
volatile int hos_fix_res; /* (nx2/oot_native_resolution.py's cached-scale refresh: HOS_FIX_RES=1; #849's fixed-scale patch does it by default) */
volatile float hos_wide_ratio, hos_wide_squeeze, hos_wide_margin;
volatile float hos_wide_ratio, hos_wide_squeeze, hos_wide_vertical_squeeze, hos_wide_margin;
volatile uint32_t hos_wide_keep_mask = 0xf; /* (nx2/oot_wide.py KEEP_VTABLES: the screens that keep the whole picture, a bit each; MkwVkHost.wide_menus) */
/* (nx2/oot_occlusion.py) read by the game's code where it decides to make occlusion queries: 1, none (HOOKSHOT_OCCLUSION_OFF=1) */
volatile int hos_occlusion_off;
Expand Down Expand Up @@ -1471,11 +1471,13 @@ static int game_main(int argc, char **argv) {
const int sw = GetSystemMetrics(SM_CXSCREEN), sh = GetSystemMetrics(SM_CYSCREEN);
if (on && sh > 0) want = (float)sw / (float)sh;
}
if (getenv("HOS_SCENE_NATIVE")) hos_native_scene = atoi(getenv("HOS_SCENE_NATIVE")) != 0;
int hos_ini_option(const char *key, int otherwise); /* (host/nn_applet.c: the Graphics menu's saved choice) */
hos_native_scene = getenv("HOS_SCENE_NATIVE") ? atoi(getenv("HOS_SCENE_NATIVE")) != 0
: hos_ini_option("native_3d_resolution", 1) != 0;
if (getenv("HOS_FIX_RES")) hos_fix_res = atoi(getenv("HOS_FIX_RES")) != 0;
if (hos_native_scene) hos_log("boot: HOS_SCENE_NATIVE=1: the scene's base scale 1.0 (the game's 0.8 otherwise)");
extern volatile uint64_t hos_wide_out, hos_wide_scene;
extern volatile float hos_wide_ratio, hos_wide_squeeze, hos_wide_margin;
extern volatile float hos_wide_ratio, hos_wide_squeeze, hos_wide_vertical_squeeze, hos_wide_margin;
const double game = 16.0 / 9.0;
/* (a screen narrower than 16:9 too, 16:10 to 5:4: the picture keeps the game's height and is narrower, the
cameras take its ratio, and the HUD fills its width instead of a middle 16:9 wider than the screen. A 4:3 CRT
Expand All @@ -1496,7 +1498,9 @@ static int game_main(int argc, char **argv) {
hos_wide_out = (uint64_t)oh << 32 | ow;
hos_wide_scene = (uint64_t)sh << 32 | sw;
hos_wide_ratio = (float)ow / (float)oh;
hos_wide_squeeze = (float)fmin(1.0, game / ((double)ow / oh)); /* (a narrower screen: the whole width) */
const double ratio = (double)ow / oh;
hos_wide_squeeze = (float)fmin(1.0, game / ratio); /* horizontal scale for a wider-than-16:9 HUD */
hos_wide_vertical_squeeze = (float)fmin(1.0, ratio / game); /* vertical scale for a narrower-than-16:9 HUD */
hos_wide_margin = (1.0f - hos_wide_squeeze) / 2.0f;
hos_aspect_ratio = hos_wide_ratio;
hos_log("boot: widescreen: picture %ux%u, scene %ux%u, camera ratio %.4f, HUD and movies in the middle %.1f%%", ow, oh, sw, sh,
Expand Down
4 changes: 4 additions & 0 deletions loader.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@echo off
set RX_VK_GPU_UNSWIZZLE=1
set RX_VK_BATCH=1
hookshot.exe
12 changes: 9 additions & 3 deletions nx2/oot_wide.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,18 @@ def _size(name):
% (name, name, name))


HUD = ("{ extern volatile float hos_wide_squeeze; const float _q = hos_wide_squeeze; if (_q > 0.0f) { float _m00, _m11; "
HUD = ("{ extern volatile float hos_wide_squeeze, hos_wide_vertical_squeeze; "
"const float _qx = hos_wide_squeeze, _qy = hos_wide_vertical_squeeze; "
"if (_qx > 0.0f || _qy > 0.0f) { float _m00, _m11; "
"memcpy(&_m00, c->vreg[1], 4); memcpy(&_m11, (const uint8_t *)c->vreg[4] + 4, 4); "
"if (_m00 == %s && _m11 == %s) { const uint64_t _vt = recomp_load64(c, c->x[0] - 0x1b8); "
"extern volatile uint32_t hos_wide_keep_mask; const uint32_t _kb = %s; "
"if (!(_kb & hos_wide_keep_mask)) { float _row[4]; memcpy(_row, c->vreg[1], 16); for (int _k = 0; _k < 4; _k++) _row[_k] *= _q; "
"memcpy(c->vreg[1], _row, 16); } } } } /* (nx2/oot_wide.py: HUD in the middle 16:9) */"
"if (!(_kb & hos_wide_keep_mask)) { float _row[4]; "
"if (_qx > 0.0f && _qx < 1.0f) { memcpy(_row, c->vreg[1], 16); "
"for (int _k = 0; _k < 4; _k++) _row[_k] *= _qx; memcpy(c->vreg[1], _row, 16); } "
"else if (_qy > 0.0f && _qy < 1.0f) { memcpy(_row, (const uint8_t *)c->vreg[4] + 4, 16); "
"for (int _k = 0; _k < 4; _k++) _row[_k] *= _qy; memcpy((uint8_t *)c->vreg[4] + 4, _row, 16); } "
"} } } } /* (nx2/oot_wide.py: HUD keeps 16:9 on wide and narrow screens) */"
% (UI_M00, UI_M11, " : ".join("_vt == 0x%xULL ? %du" % (v, 1 << k) for k, v in enumerate(KEEP_VTABLES)) + " : 0u"))

MOVIE = ("{ extern volatile float hos_wide_margin; const float _m = hos_wide_margin; if (_m > 0.0f) { "
Expand Down
6 changes: 4 additions & 2 deletions tests/test_env_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def main():
"HOS_T_BESIDE=1\nHOS_T_SHARED=beside\nVK_ADD_LAYER_PATH=/x\nLD_PRELOAD=/x.so\nPATH=C:\\x\nSDL_DYNAMIC_API=/x.so\n"
"HOS_ENV_FILE=other.txt\nHOS_SAMPLE_FILE=/home/x/.bashrc\nRX_VK_DUMP_DIR=C:\\Users\\x\nRX_VK_SKIP_CODE=2c56,ab\n"
"RX_VK_DLSS_DIR=/opt/ngx\nHOS_T_HOME=~\nSDL_VULKAN_LIBRARY=x.dll\nSDL_VIDEO_EGL_DRIVER=x.so\n"
"SDL_AUDIODRIVER=pulseaudio\nHOS_T_UP=..\nHOS_SAMPLE_FILE=hookshot_vk.dll\nRX_VK_FRAME_LOG=x.txt\n"
"SDL_AUDIO_DRIVER=pulseaudio\nSDL_AUDIODRIVER=pulseaudio\nHOS_T_UP=..\nHOS_SAMPLE_FILE=hookshot_vk.dll\nRX_VK_FRAME_LOG=x.txt\n"
"RX_VK_DUMP_DIR=dumps\nHOS_PRESENT_TRACE=t.txt\nRX_VK_DLSS_DIR=\\\\server\\share\n"
"HOS_AUDIO_DUMP=image.bin\nRX_VK_HANG_DUMP=hookshot_options.ini\nRX_VK_SHOTS=user\n"
"HOS_INPUT_SCRIPT=1:A,2:A\nRX_VK_MENU_SCRIPT=1:INS\n", encoding="utf-8")
Expand Down Expand Up @@ -83,7 +83,8 @@ def main():
CHECK(is("HOS_INPUT_SCRIPT", NULL) && is("RX_VK_MENU_SCRIPT", NULL));
CHECK(is("RX_VK_SKIP_CODE", "2c56,ab") && is("RX_VK_DLSS_DIR", "/opt/ngx"));
CHECK(is("SDL_VULKAN_LIBRARY", NULL) && is("SDL_VIDEO_EGL_DRIVER", NULL) && is("HOS_T_UP", NULL));
CHECK(is("SDL_AUDIODRIVER", "pulseaudio") && is("HOS_SAMPLE_FILE", NULL) && is("RX_VK_FRAME_LOG", NULL));
CHECK(is("SDL_AUDIO_DRIVER", "pulseaudio") && is("SDL_AUDIODRIVER", "pulseaudio"));
CHECK(is("HOS_SAMPLE_FILE", NULL) && is("RX_VK_FRAME_LOG", NULL));
CHECK(is("RX_VK_DUMP_DIR", NULL) && is("HOS_PRESENT_TRACE", NULL));
CHECK(getenv("LD_PRELOAD") == NULL || strcmp(getenv("LD_PRELOAD"), "/x.so"));
CHECK(getenv("PATH") == NULL || strcmp(getenv("PATH"), "C:\\x"));
Expand Down Expand Up @@ -119,3 +120,4 @@ def main():

if __name__ == "__main__":
main()

Loading