mirror of
https://github.com/hedge-dev/UnleashedRecomp
synced 2026-08-24 16:01:02 -04:00
Aspect ratio adjustments. (Part 1) (#90)
* Map CSD structures by full path. * Initial work for unstretching & aligning to edges. * Add extend flag, fix cast lookups. * Add right extend flag. * Fill the flags map with a bunch of casts. * Implement unstretching. * Set more title casts to unscretch. * Add some more flags. * Move CSD patches to its own file. * Replace CSD vertex shaders to get rid of pixel snapping. * Snap to pixel on the CPU. * Current work trying to get 3D screen position casts working correctly. * Fix and properly align font, handle most 3D screen positions. * Add stretch flags for background casts. * Use 4:3 as the base aspect ratio instead of 16:9. * Replicate the game's 4:3 downscaling behavior. * World map now identical to original 4:3. * Replace camera aspect ratio/field of view logic. * Make original 4:3 scaling a separate option, use custom behavior for auto. * Keep UI scale same only above Steam Deck aspect ratio. * Release paths when the YNCP file gets freed. * Add more path flags. * Interpolate to original 4:3 scale. * Scaling animation offset to prevent offscreen casts from showing up in ultrawide. * Queue draw calls without actually executing anything to extract the corner. * Clean unnecessary hooks. * Add result screen modifiers. * Stretch loading primitive 2D. * Scale DoF correctly at different aspect ratios. * Remove stretch option. * Make aspect ratio a global variable. * Ultrawide patch for HUD 3D items. * Fix world map 3D to 2D projection. * Right align world map info box. * Set medal positions. * Respect center option in more places. * Implement the aspect ratio option. * Use viewport dimensions for snapping CSD pixels. * Fix DoF fix not using viewport height. * Implement aspect ratio patches for 2D drop ring emitter. * Implement inspire letterbox. * Add cutscene aspect ratio option. * Shift subtitles by aspect ratio. * Fix crash in earth restoration cutscenes. * Offset scale patches for Tornado Defense. * Scale new record arrow casts. * Expose aspect ratio variables globally. * Properly center the achievements menu. * 4:3 scaling for options menu. * Fix procedural filtering logic in ImGui pixel shader. * Fix button guide offset. * UI scaling for installer. * Remove grid snaps in the installer. * Handle center UI scale option for rings going to HUD. * Remove unnecessary diff. * Revert temporary changes. * Fix typo.
This commit is contained in:
@@ -134,8 +134,8 @@ static void DrawHeaderContainer(const char* text)
|
||||
? Lerp(1, 0, colourMotion)
|
||||
: Lerp(0, 1, colourMotion);
|
||||
|
||||
ImVec2 min = { Scale(containerMarginX), Scale(136) };
|
||||
ImVec2 max = { min.x + textMarginX * 2 + textSize.x + Scale(5), Scale(196) };
|
||||
ImVec2 min = { Scale(g_aspectRatioOffsetX + containerMarginX), Scale(g_aspectRatioOffsetY + 136) };
|
||||
ImVec2 max = { min.x + textMarginX * 2 + textSize.x + Scale(5), Scale(g_aspectRatioOffsetY + 196) };
|
||||
|
||||
DrawPauseHeaderContainer(g_upWindow.get(), min, max, alpha);
|
||||
|
||||
@@ -568,8 +568,8 @@ static void DrawContentContainer()
|
||||
? Hermite(604, 573, motion)
|
||||
: Hermite(573, 604, motion);
|
||||
|
||||
ImVec2 min = { Scale(minX), Scale(minY) };
|
||||
ImVec2 max = { Scale(maxX), Scale(maxY) };
|
||||
ImVec2 min = { Scale(g_aspectRatioOffsetX + minX), Scale(g_aspectRatioOffsetY + minY) };
|
||||
ImVec2 max = { Scale(g_aspectRatioOffsetX + maxX), Scale(g_aspectRatioOffsetY + maxY) };
|
||||
|
||||
// Transparency fade animation.
|
||||
auto alpha = g_isClosing
|
||||
|
||||
@@ -229,11 +229,8 @@ void ButtonGuide::Draw()
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
auto& res = ImGui::GetIO().DisplaySize;
|
||||
|
||||
auto regionMarginX = Scale(g_sideMargins);
|
||||
auto regionHeight = Scale(102);
|
||||
|
||||
ImVec2 regionMin = { regionMarginX, res.y - regionHeight };
|
||||
ImVec2 regionMax = { res.x - regionMarginX, res.y };
|
||||
ImVec2 regionMin = { Scale(g_aspectRatioOffsetX + g_sideMargins), Scale(g_aspectRatioOffsetY * 2.0f + 720.0f - 102.0f) };
|
||||
ImVec2 regionMax = { Scale(g_aspectRatioOffsetX + 1280.0f - g_sideMargins), Scale(g_aspectRatioOffsetY * 2.0f + 720.0f) };
|
||||
|
||||
auto textMarginX = Scale(57);
|
||||
auto textMarginY = Scale(8);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <gpu/video.h>
|
||||
#include <app.h>
|
||||
#include <version.h>
|
||||
#include <patches/aspect_ratio_patches.h>
|
||||
|
||||
#define PIXELS_TO_UV_COORDS(textureWidth, textureHeight, x, y, width, height) \
|
||||
std::make_tuple(ImVec2((float)x / (float)textureWidth, (float)y / (float)textureHeight), \
|
||||
@@ -95,29 +96,26 @@ inline void ResetOutline()
|
||||
SetOutline(0.0f);
|
||||
}
|
||||
|
||||
// Aspect ratio aware.
|
||||
inline void SetProceduralOrigin(ImVec2 proceduralOrigin)
|
||||
{
|
||||
auto callbackData = AddImGuiCallback(ImGuiCallback::SetProceduralOrigin);
|
||||
callbackData->setProceduralOrigin.proceduralOrigin[0] = proceduralOrigin.x;
|
||||
callbackData->setProceduralOrigin.proceduralOrigin[1] = proceduralOrigin.y;
|
||||
}
|
||||
|
||||
inline void ResetProceduralOrigin()
|
||||
{
|
||||
SetProceduralOrigin({ 0.0f, 0.0f });
|
||||
}
|
||||
|
||||
inline float Scale(float size)
|
||||
{
|
||||
auto& io = ImGui::GetIO();
|
||||
|
||||
if (io.DisplaySize.x > io.DisplaySize.y)
|
||||
return size * std::max(1.0f, io.DisplaySize.y / 720.0f);
|
||||
if (g_aspectRatio >= NARROW_ASPECT_RATIO)
|
||||
return size * (io.DisplaySize.y / 720.0f);
|
||||
else
|
||||
return size * std::max(1.0f, io.DisplaySize.x / 1280.0f);
|
||||
}
|
||||
|
||||
// Not aspect ratio aware. Will stretch.
|
||||
inline float ScaleX(float x)
|
||||
{
|
||||
auto& io = ImGui::GetIO();
|
||||
return x * io.DisplaySize.x / 1280.0f;
|
||||
}
|
||||
|
||||
// Not aspect ratio aware. Will stretch.
|
||||
inline float ScaleY(float y)
|
||||
{
|
||||
auto& io = ImGui::GetIO();
|
||||
return y * io.DisplaySize.y / 720.0f;
|
||||
return size * (io.DisplaySize.x / 960.0f);
|
||||
}
|
||||
|
||||
inline double ComputeMotion(double duration, double offset, double total)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <hid/hid.h>
|
||||
#include <hid/hid_detail.h>
|
||||
#include <locale/locale.h>
|
||||
#include <patches/aspect_ratio_patches.h>
|
||||
#include <ui/imgui_utils.h>
|
||||
#include <ui/button_guide.h>
|
||||
#include <ui/message_window.h>
|
||||
@@ -447,8 +448,8 @@ static void DrawLeftImage()
|
||||
GuestTexture *guestTexture = g_installTextures[installTextureIndex % g_installTextures.size()].get();
|
||||
auto &res = ImGui::GetIO().DisplaySize;
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
ImVec2 min = { Scale(IMAGE_X), Scale(IMAGE_Y) };
|
||||
ImVec2 max = { Scale(IMAGE_X + IMAGE_WIDTH), Scale(IMAGE_Y + IMAGE_HEIGHT) };
|
||||
ImVec2 min = { Scale(g_aspectRatioOffsetX + IMAGE_X), Scale(g_aspectRatioOffsetY + IMAGE_Y) };
|
||||
ImVec2 max = { min.x + Scale(IMAGE_WIDTH), min.y + Scale(IMAGE_HEIGHT) };
|
||||
drawList->AddImage(guestTexture, min, max, ImVec2(0, 0), ImVec2(1, 1), IM_COL32(255, 255, 255, a));
|
||||
}
|
||||
|
||||
@@ -511,7 +512,7 @@ static void DrawHeaderIcons()
|
||||
{
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
|
||||
float iconsPosX = 253.0f;
|
||||
float iconsPosX = g_aspectRatioOffsetX + 253.0f;
|
||||
float iconsPosY = 79.0f;
|
||||
float iconsScale = 58;
|
||||
|
||||
@@ -577,7 +578,7 @@ static void DrawScanlineBars()
|
||||
// Installer text
|
||||
const std::string &headerText = Localise(g_currentPage == WizardPage::Installing ? "Installer_Header_Installing" : "Installer_Header_Installer");
|
||||
auto alphaMotion = ComputeMotionInstaller(g_appearTime, g_disappearTime, TITLE_ANIMATION_TIME, TITLE_ANIMATION_DURATION);
|
||||
DrawTextWithOutline(g_dfsogeistdFont, Scale(42.0f), { Scale(285.0f), Scale(57.0f) }, IM_COL32(255, 195, 0, 255 * alphaMotion), headerText.c_str(), 4, IM_COL32(0, 0, 0, 255 * alphaMotion), IMGUI_SHADER_MODIFIER_TITLE_BEVEL);
|
||||
DrawTextWithOutline(g_dfsogeistdFont, Scale(42.0f), { Scale(g_aspectRatioOffsetX + 285.0f), Scale(57.0f) }, IM_COL32(255, 195, 0, 255 * alphaMotion), headerText.c_str(), 4, IM_COL32(0, 0, 0, 255 * alphaMotion), IMGUI_SHADER_MODIFIER_TITLE_BEVEL);
|
||||
|
||||
// Top bar line
|
||||
drawList->AddLine
|
||||
@@ -601,11 +602,6 @@ static void DrawScanlineBars()
|
||||
DrawVersionString(g_newRodinFont, IM_COL32(255, 255, 255, 70 * alphaMotion));
|
||||
}
|
||||
|
||||
static float AlignToNextGrid(float value)
|
||||
{
|
||||
return floor(value / GRID_SIZE) * GRID_SIZE;
|
||||
}
|
||||
|
||||
static void DrawContainer(ImVec2 min, ImVec2 max, bool isTextArea)
|
||||
{
|
||||
auto &res = ImGui::GetIO().DisplaySize;
|
||||
@@ -641,8 +637,9 @@ static void DrawDescriptionContainer()
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
auto fontSize = Scale(26.0f);
|
||||
|
||||
ImVec2 descriptionMin = { Scale(AlignToNextGrid(CONTAINER_X)), Scale(AlignToNextGrid(CONTAINER_Y)) };
|
||||
ImVec2 descriptionMax = { Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH)), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT)) };
|
||||
ImVec2 descriptionMin = { Scale(g_aspectRatioOffsetX + CONTAINER_X), Scale(g_aspectRatioOffsetY + CONTAINER_Y) };
|
||||
ImVec2 descriptionMax = { Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH), Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT) };
|
||||
SetProceduralOrigin(descriptionMin);
|
||||
DrawContainer(descriptionMin, descriptionMax, true);
|
||||
|
||||
char descriptionText[512];
|
||||
@@ -692,8 +689,8 @@ static void DrawDescriptionContainer()
|
||||
|
||||
ImVec2 imageMin =
|
||||
{
|
||||
/* X */ Scale(CONTAINER_X) + (Scale(CONTAINER_WIDTH) / 2) - (imageScale / 2) - (hedgeDevTextSize.x / 2) - hedgeDevTextMarginX,
|
||||
/* Y */ Scale(CONTAINER_Y) + (Scale(CONTAINER_HEIGHT) / 2) - (imageScale / 2) + imageMarginY
|
||||
/* X */ Scale(g_aspectRatioOffsetX + CONTAINER_X) + (Scale(CONTAINER_WIDTH) / 2) - (imageScale / 2) - (hedgeDevTextSize.x / 2) - hedgeDevTextMarginX,
|
||||
/* Y */ Scale(g_aspectRatioOffsetY + CONTAINER_Y) + (Scale(CONTAINER_HEIGHT) / 2) - (imageScale / 2) + imageMarginY
|
||||
};
|
||||
|
||||
ImVec2 imageMax = { imageMin.x + imageScale, imageMin.y + imageScale };
|
||||
@@ -713,9 +710,9 @@ static void DrawDescriptionContainer()
|
||||
auto marqueeTextMarginX = Scale(5);
|
||||
auto marqueeTextMarginY = Scale(15);
|
||||
|
||||
ImVec2 textPos = { descriptionMax.x, Scale(CONTAINER_Y) + Scale(CONTAINER_HEIGHT) - marqueeTextSize.y - marqueeTextMarginY };
|
||||
ImVec2 textMin = { Scale(CONTAINER_X), textPos.y };
|
||||
ImVec2 textMax = { Scale(CONTAINER_X) + Scale(CONTAINER_WIDTH), Scale(CONTAINER_Y) + Scale(CONTAINER_HEIGHT) };
|
||||
ImVec2 textPos = { descriptionMax.x, Scale(g_aspectRatioOffsetY + CONTAINER_Y) + Scale(CONTAINER_HEIGHT) - marqueeTextSize.y - marqueeTextMarginY };
|
||||
ImVec2 textMin = { Scale(g_aspectRatioOffsetX + CONTAINER_X), textPos.y };
|
||||
ImVec2 textMax = { Scale(g_aspectRatioOffsetX + CONTAINER_X) + Scale(CONTAINER_WIDTH), Scale(g_aspectRatioOffsetY + CONTAINER_Y) + Scale(CONTAINER_HEIGHT) };
|
||||
|
||||
SetMarqueeFade(textMin, textMax, Scale(32));
|
||||
DrawTextWithMarquee(g_seuratFont, fontSize, textPos, textMin, textMax, IM_COL32_WHITE, CREDITS_TEXT, g_appearTime, 0.9, Scale(250));
|
||||
@@ -723,7 +720,7 @@ static void DrawDescriptionContainer()
|
||||
}
|
||||
|
||||
ImVec2 sideMin = { descriptionMax.x, descriptionMin.y };
|
||||
ImVec2 sideMax = { Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH + SIDE_CONTAINER_WIDTH)), descriptionMax.y };
|
||||
ImVec2 sideMax = { res.x, descriptionMax.y };
|
||||
DrawContainer(sideMin, sideMax, false);
|
||||
drawList->PopClipRect();
|
||||
|
||||
@@ -741,6 +738,8 @@ static void DrawDescriptionContainer()
|
||||
{
|
||||
ButtonGuide::Close();
|
||||
}
|
||||
|
||||
ResetProceduralOrigin();
|
||||
}
|
||||
|
||||
static void DrawButtonContainer(ImVec2 min, ImVec2 max, int baser, int baseg, float alpha)
|
||||
@@ -846,16 +845,16 @@ static void ComputeButtonColumnCoordinates(ButtonColumn buttonColumn, float &min
|
||||
switch (buttonColumn)
|
||||
{
|
||||
case ButtonColumnLeft:
|
||||
minX = Scale(AlignToNextGrid(CONTAINER_X) + CONTAINER_BUTTON_GAP);
|
||||
maxX = Scale(AlignToNextGrid(CONTAINER_X) + CONTAINER_BUTTON_GAP + CONTAINER_BUTTON_WIDTH);
|
||||
minX = Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_BUTTON_GAP);
|
||||
maxX = Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_BUTTON_GAP + CONTAINER_BUTTON_WIDTH);
|
||||
break;
|
||||
case ButtonColumnMiddle:
|
||||
minX = Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH / 2.0f) - CONTAINER_BUTTON_WIDTH / 2.0f);
|
||||
maxX = Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH / 2.0f) + CONTAINER_BUTTON_WIDTH / 2.0f);
|
||||
minX = Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH / 2.0f - CONTAINER_BUTTON_WIDTH / 2.0f);
|
||||
maxX = Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH / 2.0f + CONTAINER_BUTTON_WIDTH / 2.0f);
|
||||
break;
|
||||
case ButtonColumnRight:
|
||||
minX = Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH) - CONTAINER_BUTTON_GAP - CONTAINER_BUTTON_WIDTH);
|
||||
maxX = Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH) - CONTAINER_BUTTON_GAP);
|
||||
minX = Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH - CONTAINER_BUTTON_GAP - CONTAINER_BUTTON_WIDTH);
|
||||
maxX = Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH - CONTAINER_BUTTON_GAP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -867,8 +866,8 @@ static void DrawSourceButton(ButtonColumn buttonColumn, float yRatio, const char
|
||||
ComputeButtonColumnCoordinates(buttonColumn, minX, maxX);
|
||||
|
||||
float minusY = (CONTAINER_BUTTON_GAP + BUTTON_HEIGHT) * yRatio;
|
||||
ImVec2 min = { minX, Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) - CONTAINER_BUTTON_GAP - BUTTON_HEIGHT - minusY) };
|
||||
ImVec2 max = { maxX, Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) - CONTAINER_BUTTON_GAP - minusY) };
|
||||
ImVec2 min = { minX, Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT - CONTAINER_BUTTON_GAP - BUTTON_HEIGHT - minusY) };
|
||||
ImVec2 max = { maxX, Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT - CONTAINER_BUTTON_GAP - minusY) };
|
||||
DrawButton(min, max, sourceText, true, sourceSet, buttonPressed);
|
||||
}
|
||||
|
||||
@@ -881,8 +880,8 @@ static void DrawProgressBar(float progressRatio)
|
||||
const uint32_t innerColor1 = IM_COL32(0, 32, 0, 255 * alpha);
|
||||
float xPadding = Scale(6.0f);
|
||||
float yPadding = Scale(3.0f);
|
||||
ImVec2 min = { Scale(AlignToNextGrid(CONTAINER_X) + BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP) };
|
||||
ImVec2 max = { Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH) - BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP + BUTTON_HEIGHT) };
|
||||
ImVec2 min = { Scale(g_aspectRatioOffsetX + CONTAINER_X) + BOTTOM_X_GAP, Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT + BOTTOM_Y_GAP) };
|
||||
ImVec2 max = { Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH - BOTTOM_X_GAP), Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT + BOTTOM_Y_GAP + BUTTON_HEIGHT) };
|
||||
|
||||
DrawButtonContainer(min, max, 0, 0, alpha);
|
||||
|
||||
@@ -1069,8 +1068,8 @@ static void DrawLanguagePicker()
|
||||
ComputeButtonColumnCoordinates((i < 3) ? ButtonColumnLeft : ButtonColumnRight, minX, maxX);
|
||||
|
||||
float minusY = (CONTAINER_BUTTON_GAP + BUTTON_HEIGHT) * (float(i % 3));
|
||||
ImVec2 min = { minX, Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) - CONTAINER_BUTTON_GAP - BUTTON_HEIGHT - minusY) };
|
||||
ImVec2 max = { maxX, Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) - CONTAINER_BUTTON_GAP - minusY) };
|
||||
ImVec2 min = { minX, Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT - CONTAINER_BUTTON_GAP - BUTTON_HEIGHT - minusY) };
|
||||
ImVec2 max = { maxX, Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT - CONTAINER_BUTTON_GAP - minusY) };
|
||||
|
||||
// TODO: The active button should change its style to show an enabled toggle if it matches the current language.
|
||||
|
||||
@@ -1095,8 +1094,8 @@ static void DrawSourcePickers()
|
||||
ImVec2 textSize = ComputeTextSize(g_dfsogeistdFont, addFilesText.c_str(), 20.0f, squashRatio, ADD_BUTTON_MAX_TEXT_WIDTH);
|
||||
textSize.x += BUTTON_TEXT_GAP;
|
||||
|
||||
ImVec2 min = { Scale(AlignToNextGrid(CONTAINER_X) + BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP) };
|
||||
ImVec2 max = { Scale(AlignToNextGrid(CONTAINER_X) + BOTTOM_X_GAP + textSize.x * squashRatio), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP + BUTTON_HEIGHT) };
|
||||
ImVec2 min = { Scale(g_aspectRatioOffsetX + CONTAINER_X + BOTTOM_X_GAP), Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT + BOTTOM_Y_GAP) };
|
||||
ImVec2 max = { Scale(g_aspectRatioOffsetX + CONTAINER_X + BOTTOM_X_GAP + textSize.x * squashRatio), Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT + BOTTOM_Y_GAP + BUTTON_HEIGHT) };
|
||||
DrawButton(min, max, addFilesText.c_str(), false, true, buttonPressed, ADD_BUTTON_MAX_TEXT_WIDTH);
|
||||
if (buttonPressed)
|
||||
{
|
||||
@@ -1231,8 +1230,8 @@ static void DrawNextButton()
|
||||
ImVec2 textSize = ComputeTextSize(g_newRodinFont, buttonText.c_str(), 20.0f, squashRatio, NEXT_BUTTON_MAX_TEXT_WIDTH);
|
||||
textSize.x += BUTTON_TEXT_GAP;
|
||||
|
||||
ImVec2 min = { Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH) - textSize.x * squashRatio - BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP) };
|
||||
ImVec2 max = { Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH) - BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP + BUTTON_HEIGHT) };
|
||||
ImVec2 min = { Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH - textSize.x * squashRatio - BOTTOM_X_GAP), Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT + BOTTOM_Y_GAP) };
|
||||
ImVec2 max = { Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH - BOTTOM_X_GAP), Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT + BOTTOM_Y_GAP + BUTTON_HEIGHT) };
|
||||
|
||||
bool buttonPressed = false;
|
||||
DrawButton(min, max, buttonText.c_str(), false, nextButtonEnabled, buttonPressed, NEXT_BUTTON_MAX_TEXT_WIDTH);
|
||||
@@ -1317,10 +1316,10 @@ static void DrawHorizontalBorder(bool bottomBorder)
|
||||
const uint32_t FADE_COLOR_RIGHT = IM_COL32(155, 225, 155, 0);
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
double borderScale = 1.0 - ComputeMotionInstaller(g_appearTime, g_disappearTime, CONTAINER_LINE_ANIMATION_TIME, CONTAINER_LINE_ANIMATION_DURATION);
|
||||
float midX = Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH / 5));
|
||||
float minX = std::lerp(Scale(AlignToNextGrid(CONTAINER_X) - BORDER_SIZE - BORDER_OVERSHOOT), midX, borderScale);
|
||||
float maxX = std::lerp(Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH + SIDE_CONTAINER_WIDTH) + BORDER_OVERSHOOT), midX, borderScale);
|
||||
float minY = bottomBorder ? Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT)) : Scale(AlignToNextGrid(CONTAINER_Y) - BORDER_SIZE);
|
||||
float midX = Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH / 5);
|
||||
float minX = std::lerp(Scale(g_aspectRatioOffsetX + CONTAINER_X - BORDER_SIZE - BORDER_OVERSHOOT), midX, borderScale);
|
||||
float maxX = std::lerp(Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH + SIDE_CONTAINER_WIDTH + BORDER_OVERSHOOT), midX, borderScale);
|
||||
float minY = bottomBorder ? Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT) : Scale(g_aspectRatioOffsetY + CONTAINER_Y - BORDER_SIZE);
|
||||
float maxY = minY + Scale(BORDER_SIZE);
|
||||
drawList->AddRectFilledMultiColor
|
||||
(
|
||||
@@ -1349,11 +1348,11 @@ static void DrawVerticalBorder(bool rightBorder)
|
||||
const uint32_t FADE_COLOR = IM_COL32(155, rightBorder ? 225 : 155, 155, 0);
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
double borderScale = 1.0 - ComputeMotionInstaller(g_appearTime, g_disappearTime, CONTAINER_LINE_ANIMATION_TIME, CONTAINER_LINE_ANIMATION_DURATION);
|
||||
float minX = rightBorder ? Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH)) : Scale(AlignToNextGrid(CONTAINER_X) - BORDER_SIZE);
|
||||
float minX = rightBorder ? Scale(g_aspectRatioOffsetX + CONTAINER_X + CONTAINER_WIDTH) : Scale(g_aspectRatioOffsetX + CONTAINER_X - BORDER_SIZE);
|
||||
float maxX = minX + Scale(BORDER_SIZE);
|
||||
float midY = Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT / 2));
|
||||
float minY = std::lerp(Scale(AlignToNextGrid(CONTAINER_Y) - BORDER_OVERSHOOT), midY, borderScale);
|
||||
float maxY = std::lerp(Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BORDER_OVERSHOOT), midY, borderScale);
|
||||
float midY = Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT / 2);
|
||||
float minY = std::lerp(Scale(g_aspectRatioOffsetY + CONTAINER_Y - BORDER_OVERSHOOT), midY, borderScale);
|
||||
float maxY = std::lerp(Scale(g_aspectRatioOffsetY + CONTAINER_Y + CONTAINER_HEIGHT + BORDER_OVERSHOOT), midY, borderScale);
|
||||
drawList->AddRectFilledMultiColor
|
||||
(
|
||||
{ minX, minY },
|
||||
|
||||
@@ -42,9 +42,15 @@ static constexpr double CONTAINER_FULL_DURATION = CONTAINER_BACKGROUND_TIME + CO
|
||||
static constexpr double CONTAINER_CATEGORY_TIME = (CONTAINER_INNER_TIME + CONTAINER_BACKGROUND_TIME) / 2.0;
|
||||
static constexpr double CONTAINER_CATEGORY_DURATION = 12.0;
|
||||
|
||||
constexpr float COMMON_PADDING_POS_Y = 118.0f;
|
||||
constexpr float COMMON_PADDING_POS_X = 30.0f;
|
||||
constexpr float INFO_CONTAINER_POS_X = 870.0f;
|
||||
static constexpr float CONTAINER_POS_Y = 118.0f;
|
||||
|
||||
static constexpr float SETTINGS_WIDE_GRID_COUNT = 90.0f;
|
||||
static constexpr float INFO_WIDE_GRID_COUNT = 42.0f;
|
||||
static constexpr float PADDING_WIDE_GRID_COUNT = 3.0f;
|
||||
|
||||
static constexpr float SETTINGS_NARROW_GRID_COUNT = 70.0f;
|
||||
static constexpr float INFO_NARROW_GRID_COUNT = 34.0f;
|
||||
static constexpr float PADDING_NARROW_GRID_COUNT = 1.0f;
|
||||
|
||||
static constexpr int32_t g_categoryCount = 4;
|
||||
static int32_t g_categoryIndex;
|
||||
@@ -151,12 +157,18 @@ static void DrawScanlineBars()
|
||||
|
||||
SetShaderModifier(IMGUI_SHADER_MODIFIER_NONE);
|
||||
|
||||
float optionsX;
|
||||
if (g_aspectRatio >= WIDE_ASPECT_RATIO)
|
||||
optionsX = g_aspectRatioOffsetX;
|
||||
else
|
||||
optionsX = (1.0f - g_narrowOffsetScale) * -20.0f;
|
||||
|
||||
// Options text
|
||||
DrawTextWithOutline
|
||||
(
|
||||
g_dfsogeistdFont,
|
||||
Scale(48.0f),
|
||||
{ Scale(122.0f), Scale(56.0f) },
|
||||
{ Scale(optionsX + 122.0f), Scale(56.0f) },
|
||||
IM_COL32(255, 190, 33, 255),
|
||||
Localise("Options_Header_Name").c_str(),
|
||||
4,
|
||||
@@ -187,7 +199,7 @@ static void DrawScanlineBars()
|
||||
|
||||
static float AlignToNextGrid(float value)
|
||||
{
|
||||
return floor(value / GRID_SIZE) * GRID_SIZE;
|
||||
return round(value / GRID_SIZE) * GRID_SIZE;
|
||||
}
|
||||
|
||||
static void DrawContainer(ImVec2 min, ImVec2 max)
|
||||
@@ -306,8 +318,11 @@ static bool DrawCategories()
|
||||
auto clipRectMin = drawList->GetClipRectMin();
|
||||
auto clipRectMax = drawList->GetClipRectMax();
|
||||
|
||||
constexpr float NARROW_PADDING_GRID_COUNT = 1.5f;
|
||||
constexpr float WIDE_PADDING_GRID_COUNT = 3.0f;
|
||||
|
||||
float gridSize = Scale(GRID_SIZE);
|
||||
float textPadding = gridSize * 3.0f;
|
||||
float textPadding = gridSize * Lerp(NARROW_PADDING_GRID_COUNT, WIDE_PADDING_GRID_COUNT, g_narrowOffsetScale);
|
||||
float tabPadding = gridSize;
|
||||
|
||||
float size = Scale(32.0f);
|
||||
@@ -449,8 +464,11 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* conf
|
||||
auto clipRectMax = drawList->GetClipRectMax();
|
||||
auto& padState = SWA::CInputState::GetInstance()->GetPadState();
|
||||
|
||||
constexpr float OPTION_NARROW_GRID_COUNT = 36.0f;
|
||||
constexpr float OPTION_WIDE_GRID_COUNT = 54.0f;
|
||||
|
||||
auto gridSize = Scale(GRID_SIZE);
|
||||
auto optionWidth = gridSize * 54.0f;
|
||||
auto optionWidth = gridSize * floor(Lerp(OPTION_NARROW_GRID_COUNT, OPTION_WIDE_GRID_COUNT, g_narrowOffsetScale));
|
||||
auto optionHeight = gridSize * 5.5f;
|
||||
auto optionPadding = gridSize * 0.5f;
|
||||
auto valueWidth = Scale(192.0f);
|
||||
@@ -917,6 +935,7 @@ static void DrawConfigOptions()
|
||||
DrawConfigOption(rowCount++, yOffset, &Config::GITextureFiltering, true);
|
||||
DrawConfigOption(rowCount++, yOffset, &Config::MotionBlur, true);
|
||||
DrawConfigOption(rowCount++, yOffset, &Config::XboxColorCorrection, true);
|
||||
DrawConfigOption(rowCount++, yOffset, &Config::CutsceneAspectRatio, true);
|
||||
DrawConfigOption(rowCount++, yOffset, &Config::UIScaleMode, true);
|
||||
|
||||
break;
|
||||
@@ -998,13 +1017,11 @@ static void DrawConfigOptions()
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawSettingsPanel()
|
||||
static void DrawSettingsPanel(ImVec2 settingsMin, ImVec2 settingsMax)
|
||||
{
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
|
||||
ImVec2 settingsMin = { Scale(AlignToNextGrid(COMMON_PADDING_POS_X)), Scale(AlignToNextGrid(COMMON_PADDING_POS_Y)) };
|
||||
ImVec2 settingsMax = { Scale(AlignToNextGrid(INFO_CONTAINER_POS_X - COMMON_PADDING_POS_X)), Scale(AlignToNextGrid(720.0f - COMMON_PADDING_POS_Y)) };
|
||||
|
||||
SetProceduralOrigin(settingsMin);
|
||||
DrawContainer(settingsMin, settingsMax);
|
||||
|
||||
if (DrawCategories())
|
||||
@@ -1018,31 +1035,34 @@ static void DrawSettingsPanel()
|
||||
ResetSelection();
|
||||
}
|
||||
|
||||
ResetProceduralOrigin();
|
||||
|
||||
// Pop clip rect from DrawContainer
|
||||
drawList->PopClipRect();
|
||||
}
|
||||
|
||||
static void DrawInfoPanel()
|
||||
static void DrawInfoPanel(ImVec2 infoMin, ImVec2 infoMax)
|
||||
{
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
|
||||
ImVec2 infoMin = { Scale(AlignToNextGrid(INFO_CONTAINER_POS_X)), Scale(AlignToNextGrid(COMMON_PADDING_POS_Y)) };
|
||||
ImVec2 infoMax = { Scale(AlignToNextGrid(1280.0f - COMMON_PADDING_POS_X)), Scale(AlignToNextGrid(720.0f - COMMON_PADDING_POS_Y)) };
|
||||
|
||||
SetProceduralOrigin(infoMin);
|
||||
DrawContainer(infoMin, infoMax);
|
||||
|
||||
auto clipRectMin = drawList->GetClipRectMin();
|
||||
auto clipRectMax = drawList->GetClipRectMax();
|
||||
|
||||
ImVec2 thumbnailMax = { clipRectMax.x, clipRectMin.y + Scale(198.0f) };
|
||||
|
||||
if (g_selectedItem)
|
||||
{
|
||||
auto desc = g_selectedItem->GetDescription(Config::Language);
|
||||
auto thumbnail = GetThumbnail(g_selectedItem);
|
||||
|
||||
if (thumbnail)
|
||||
drawList->AddImage(thumbnail, clipRectMin, thumbnailMax);
|
||||
float aspectRatio = float(thumbnail->width) / thumbnail->height;
|
||||
float thumbnailHeight = (clipRectMax.x - clipRectMin.x) / aspectRatio;
|
||||
|
||||
ImVec2 thumbnailMin = { clipRectMin.x, clipRectMin.y + Scale(GRID_SIZE / 2.0f) };
|
||||
ImVec2 thumbnailMax = { clipRectMax.x, thumbnailMin.y + thumbnailHeight };
|
||||
|
||||
drawList->AddImage(thumbnail, thumbnailMin, thumbnailMax);
|
||||
|
||||
if (g_inaccessibleReason)
|
||||
{
|
||||
@@ -1057,8 +1077,8 @@ static void DrawInfoPanel()
|
||||
auto resScale = round(*(float*)g_selectedItem->GetValue() * 1000) / 1000;
|
||||
|
||||
std::snprintf(buf, sizeof(buf), desc.c_str(),
|
||||
(int)((float)GameWindow::s_width * resScale),
|
||||
(int)((float)GameWindow::s_height * resScale));
|
||||
(int)((float)Video::s_viewportWidth * resScale),
|
||||
(int)((float)Video::s_viewportHeight * resScale));
|
||||
|
||||
desc = buf;
|
||||
}
|
||||
@@ -1080,6 +1100,8 @@ static void DrawInfoPanel()
|
||||
);
|
||||
}
|
||||
|
||||
ResetProceduralOrigin();
|
||||
|
||||
// Pop clip rect from DrawContainer
|
||||
drawList->PopClipRect();
|
||||
}
|
||||
@@ -1197,8 +1219,25 @@ void OptionsMenu::Draw()
|
||||
drawList->AddRectFilled({ 0.0f, 0.0f }, res, IM_COL32(0, 0, 0, 223));
|
||||
|
||||
DrawScanlineBars();
|
||||
DrawSettingsPanel();
|
||||
DrawInfoPanel();
|
||||
|
||||
float settingsGridCount = floor(Lerp(SETTINGS_NARROW_GRID_COUNT, SETTINGS_WIDE_GRID_COUNT, g_narrowOffsetScale));
|
||||
float paddingGridCount = Lerp(PADDING_NARROW_GRID_COUNT, PADDING_WIDE_GRID_COUNT, g_narrowOffsetScale);
|
||||
float infoGridCount = floor(Lerp(INFO_NARROW_GRID_COUNT, INFO_WIDE_GRID_COUNT, g_narrowOffsetScale));
|
||||
float totalGridCount = settingsGridCount + paddingGridCount + infoGridCount;
|
||||
|
||||
float offsetX = g_aspectRatioOffsetX + (1280.0f - ((GRID_SIZE * totalGridCount) - 1)) / 2.0f;
|
||||
float minY = Scale(g_aspectRatioOffsetY + CONTAINER_POS_Y);
|
||||
float maxY = Scale(g_aspectRatioOffsetY + (720.0f - CONTAINER_POS_Y + 1.0f));
|
||||
|
||||
DrawSettingsPanel(
|
||||
{ Scale(offsetX), minY },
|
||||
{ Scale(offsetX + settingsGridCount * GRID_SIZE), maxY }
|
||||
);
|
||||
|
||||
DrawInfoPanel(
|
||||
{ Scale(offsetX + (settingsGridCount + paddingGridCount) * GRID_SIZE), minY },
|
||||
{ Scale(offsetX + totalGridCount * GRID_SIZE), maxY }
|
||||
);
|
||||
|
||||
if (g_isStage)
|
||||
DrawFadeTransition();
|
||||
|
||||
Reference in New Issue
Block a user