mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-04-28 13:27:58 +03:00
Implement options menu TV static animation. (#403)
This commit is contained in:
parent
8f8b574e56
commit
5e8d15e334
5 changed files with 430 additions and 4 deletions
|
@ -158,7 +158,8 @@ set(UNLEASHED_RECOMP_UI_CXX_SOURCES
|
|||
"ui/installer_wizard.cpp"
|
||||
"ui/message_window.cpp"
|
||||
"ui/options_menu.cpp"
|
||||
"ui/options_menu_thumbnails.cpp"
|
||||
"ui/options_menu_thumbnails.cpp"
|
||||
"ui/tv_static.cpp"
|
||||
)
|
||||
|
||||
set(UNLEASHED_RECOMP_INSTALL_CXX_SOURCES
|
||||
|
@ -552,7 +553,9 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/op
|
|||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_off.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_off.dds" ARRAY_NAME "g_vsync_off" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/window_size.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/window_size.dds" ARRAY_NAME "g_window_size" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction.dds" ARRAY_NAME "g_xbox_color_correction" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static.dds" ARRAY_NAME "g_options_static" COMPRESSION_TYPE "zstd")
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static_flash.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static_flash.dds" ARRAY_NAME "g_options_static_flash" COMPRESSION_TYPE "zstd")
|
||||
|
||||
## Game Icon ##
|
||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon.bmp" ARRAY_NAME "g_game_icon")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "options_menu.h"
|
||||
#include "options_menu_thumbnails.h"
|
||||
#include "tv_static.h"
|
||||
|
||||
#include <api/SWA.h>
|
||||
#include <apu/audio.h>
|
||||
|
@ -1436,7 +1437,27 @@ static void DrawInfoPanel(ImVec2 infoMin, ImVec2 infoMax)
|
|||
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_isStage)
|
||||
{
|
||||
drawList->AddImage(thumbnail, thumbnailMin, thumbnailMax);
|
||||
}
|
||||
else
|
||||
{
|
||||
float time = g_appearTime + CONTAINER_FULL_DURATION / 60.0;
|
||||
|
||||
drawList->AddImage(
|
||||
thumbnail,
|
||||
thumbnailMin,
|
||||
thumbnailMax,
|
||||
{ 0.0f, 0.0f },
|
||||
{ 1.0f, 1.0f },
|
||||
IM_COL32(255, 255, 255, 255 * TVStatic::ComputeThumbnailAlpha(time)));
|
||||
|
||||
TVStatic::Draw(
|
||||
{ (thumbnailMin.x + thumbnailMax.x) / 2.0f, (thumbnailMin.y + thumbnailMax.y) / 2.0f },
|
||||
{ (thumbnailMax.x - thumbnailMin.x), (thumbnailMax.y - thumbnailMin.y) },
|
||||
time);
|
||||
}
|
||||
|
||||
if (g_inaccessibleReason)
|
||||
{
|
||||
|
@ -1688,6 +1709,8 @@ void OptionsMenu::Init()
|
|||
LoadThumbnails();
|
||||
|
||||
g_upMilesElectric = LOAD_ZSTD_TEXTURE(g_miles_electric);
|
||||
|
||||
TVStatic::Init();
|
||||
}
|
||||
|
||||
void OptionsMenu::Draw()
|
||||
|
|
392
UnleashedRecomp/ui/tv_static.cpp
Normal file
392
UnleashedRecomp/ui/tv_static.cpp
Normal file
|
@ -0,0 +1,392 @@
|
|||
#include "tv_static.h"
|
||||
#include "imgui_utils.h"
|
||||
|
||||
#include <decompressor.h>
|
||||
#include <gpu/video.h>
|
||||
#include <patches/aspect_ratio_patches.h>
|
||||
#include <res/images/options_menu/options_static.dds.h>
|
||||
#include <res/images/options_menu/options_static_flash.dds.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct FloatLinear
|
||||
{
|
||||
float value;
|
||||
float time;
|
||||
|
||||
static float Sample(const FloatLinear& a, const FloatLinear& b, float time)
|
||||
{
|
||||
const float t = std::clamp((time - a.time) / (b.time - a.time), 0.0f, 1.0f);
|
||||
return (b.value - a.value) * t + a.value;
|
||||
}
|
||||
};
|
||||
|
||||
struct FloatHermite
|
||||
{
|
||||
float value;
|
||||
float time;
|
||||
float inTangent;
|
||||
float outTangent;
|
||||
|
||||
static float Sample(const FloatHermite& a, const FloatHermite& b, float time)
|
||||
{
|
||||
const float t = std::clamp((time - a.time) / (b.time - a.time), 0.0f, 1.0f);
|
||||
|
||||
float valueDelta = b.value - a.value;
|
||||
float frameDelta = b.time - a.time;
|
||||
|
||||
float biasSquaric = t * t;
|
||||
float biasCubic = biasSquaric * t;
|
||||
|
||||
float valueCubic = (a.outTangent + a.inTangent) * frameDelta - valueDelta * 2.0f;
|
||||
float valueSquaric = valueDelta * 3.0f - (a.inTangent * 2.0f + a.outTangent) * frameDelta;
|
||||
float valueLinear = frameDelta * a.inTangent;
|
||||
|
||||
return valueCubic * biasCubic + valueSquaric * biasSquaric + valueLinear * t + a.value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
static auto Sample(const std::array<T, N>& keys, float time)
|
||||
{
|
||||
T firstKey = keys[0];
|
||||
T lastKey = keys[N - 1];
|
||||
|
||||
if (time < firstKey.time)
|
||||
return firstKey.value;
|
||||
|
||||
if (time > lastKey.time)
|
||||
return lastKey.value;
|
||||
|
||||
size_t keyIndex = 0;
|
||||
for (auto key : keys)
|
||||
{
|
||||
if (key.time >= time)
|
||||
break;
|
||||
|
||||
keyIndex++;
|
||||
}
|
||||
|
||||
if (keyIndex >= N)
|
||||
return keys[N - 1].value;
|
||||
|
||||
return T::Sample(keys[keyIndex - 1], keys[keyIndex], time);
|
||||
}
|
||||
|
||||
static std::unique_ptr<GuestTexture> g_flashTexture;
|
||||
static std::unique_ptr<GuestTexture> g_noiseTexture;
|
||||
|
||||
static constexpr float FRAME_OFFSET = 65.0f;
|
||||
static constexpr float FRAME_SCALE = 1.0f / 60.0f;
|
||||
static constexpr float FRAME_DURATION = 32.0f;
|
||||
|
||||
static std::array g_flashScaleX =
|
||||
{
|
||||
FloatHermite{ 0, 67 * FRAME_SCALE, 0, 0.673736f },
|
||||
FloatHermite{ 2, 70 * FRAME_SCALE, -0.003465f, -0.682543f },
|
||||
FloatHermite{ 0, 73 * FRAME_SCALE, 0, 0 },
|
||||
};
|
||||
static std::array g_flashScaleY =
|
||||
{
|
||||
FloatHermite{ 0, 67 * FRAME_SCALE, 0, 0.67238f },
|
||||
FloatHermite{ 2, 70 * FRAME_SCALE, -0.001741f, -0.664096f },
|
||||
FloatHermite{ 0, 73 * FRAME_SCALE, 0, 0 },
|
||||
};
|
||||
static std::array g_flashColor =
|
||||
{
|
||||
FloatLinear{ 255.0f, 67 * FRAME_SCALE },
|
||||
FloatLinear{ 160.0f, 70 * FRAME_SCALE },
|
||||
FloatLinear{ 255.0f, 73 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_flashAlpha =
|
||||
{
|
||||
FloatLinear{ 255.0f, 70 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 73 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseScale =
|
||||
{
|
||||
FloatLinear{ 0.0f, 70 * FRAME_SCALE },
|
||||
FloatLinear{ 1.0f, 75 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseTL_gradTL =
|
||||
{
|
||||
FloatLinear{ 0.0f, 77 * FRAME_SCALE },
|
||||
FloatLinear{ (192 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 90 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseTL_gradBL =
|
||||
{
|
||||
FloatLinear{ 0.0f, 73 * FRAME_SCALE },
|
||||
FloatLinear{ (223 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 94 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseTL_gradTR =
|
||||
{
|
||||
FloatLinear{ 0.0f, 74 * FRAME_SCALE },
|
||||
FloatLinear{ (223 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 93 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseTL_gradBR =
|
||||
{
|
||||
FloatLinear{ 0.0f, 70 * FRAME_SCALE },
|
||||
FloatLinear{ 1.0f, 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 97 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseTR_gradTL =
|
||||
{
|
||||
FloatLinear{ 0.0f, 74 * FRAME_SCALE },
|
||||
FloatLinear{ (223 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 93 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseTR_gradBL =
|
||||
{
|
||||
FloatLinear{ 0.0f, 70 * FRAME_SCALE },
|
||||
FloatLinear{ 1.0f, 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 97 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseTR_gradTR =
|
||||
{
|
||||
FloatLinear{ 0.0f, 77 * FRAME_SCALE },
|
||||
FloatLinear{ (192 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 90 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseTR_gradBR =
|
||||
{
|
||||
FloatLinear{ 0.0f, 73 * FRAME_SCALE },
|
||||
FloatLinear{ (223 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 94 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseBL_gradTL =
|
||||
{
|
||||
FloatLinear{ 0.0f, 73 * FRAME_SCALE },
|
||||
FloatLinear{ (223 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 94 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseBL_gradBL =
|
||||
{
|
||||
FloatLinear{ 0.0f, 77 * FRAME_SCALE },
|
||||
FloatLinear{ (192 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 90 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseBL_gradTR =
|
||||
{
|
||||
FloatLinear{ 0.0f, 70 * FRAME_SCALE },
|
||||
FloatLinear{ 1.0f, 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 97 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseBL_gradBR =
|
||||
{
|
||||
FloatLinear{ 0.0f, 74 * FRAME_SCALE },
|
||||
FloatLinear{ (223 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 93 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseBR_gradTL =
|
||||
{
|
||||
FloatLinear{ 0.0f, 70 * FRAME_SCALE },
|
||||
FloatLinear{ 1.0f, 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 97 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseBR_gradBL =
|
||||
{
|
||||
FloatLinear{ 0.0f, 74 * FRAME_SCALE },
|
||||
FloatLinear{ (223 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 93 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseBR_gradTR =
|
||||
{
|
||||
FloatLinear{ 0.0f, 73 * FRAME_SCALE },
|
||||
FloatLinear{ (223 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 94 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_noiseBR_gradBR =
|
||||
{
|
||||
FloatLinear{ 0.0f, 77 * FRAME_SCALE },
|
||||
FloatLinear{ (192 / 255.0f), 85 * FRAME_SCALE },
|
||||
FloatLinear{ 0.0f, 90 * FRAME_SCALE },
|
||||
};
|
||||
static std::array g_thumbnailAlpha =
|
||||
{
|
||||
FloatLinear{ 0.0f, 85 * FRAME_SCALE },
|
||||
FloatLinear{ 1.0f, 90 * FRAME_SCALE },
|
||||
};
|
||||
|
||||
static std::pair<ImVec2, ImVec2> ComputeRect(const ImVec2& center, const ImVec2& scale)
|
||||
{
|
||||
ImVec2 min = { center.x - scale.x / 2.0f, center.y - scale.y / 2.0f };
|
||||
ImVec2 max = { center.x + scale.x / 2.0f, center.y + scale.y / 2.0f };
|
||||
|
||||
return std::make_pair(min, max);
|
||||
}
|
||||
|
||||
static void DrawFlash(const ImVec2& center, const ImVec2& resolution, float time)
|
||||
{
|
||||
auto drawList = ImGui::GetBackgroundDrawList();
|
||||
|
||||
float baseScale = resolution.y / 135.0f * 100.0f;
|
||||
auto [min, max] = ComputeRect(center, { Sample(g_flashScaleX, time) * baseScale, Sample(g_flashScaleY, time) * baseScale});
|
||||
|
||||
float color = Sample(g_flashColor, time);
|
||||
float alpha = Sample(g_flashAlpha, time);
|
||||
|
||||
drawList->AddImage(g_flashTexture.get(), min, max, { 0.0f, 0.0f }, { 1.0f, 1.0f }, IM_COL32(color, 255, color, alpha));
|
||||
}
|
||||
|
||||
static void PrimRectUVColorCorners(ImDrawList* This, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max,
|
||||
ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left, bool reverse_order = false)
|
||||
{
|
||||
ImVec2 a(p_min), c(p_max), uv_a(uv_min), uv_c(uv_max);
|
||||
ImVec2 b(c.x, a.y), d(a.x, c.y), uv_b(uv_c.x, uv_a.y), uv_d(uv_a.x, uv_c.y);
|
||||
|
||||
if (reverse_order)
|
||||
{
|
||||
ImVec2 _a = a; a = b; b = _a;
|
||||
ImVec2 _c = c; c = d; d = _c;
|
||||
|
||||
ImVec2 _uv_a = uv_a; uv_a = uv_b; uv_b = _uv_a;
|
||||
ImVec2 _uv_c = uv_c; uv_c = uv_d; uv_d = _uv_c;
|
||||
}
|
||||
|
||||
ImDrawIdx idx = (ImDrawIdx)This->_VtxCurrentIdx;
|
||||
This->_IdxWritePtr[0] = idx; This->_IdxWritePtr[1] = (ImDrawIdx)(idx + 1); This->_IdxWritePtr[2] = (ImDrawIdx)(idx + 2);
|
||||
This->_IdxWritePtr[3] = idx; This->_IdxWritePtr[4] = (ImDrawIdx)(idx + 2); This->_IdxWritePtr[5] = (ImDrawIdx)(idx + 3);
|
||||
This->_VtxWritePtr[0].pos = a; This->_VtxWritePtr[0].uv = uv_a; This->_VtxWritePtr[0].col = reverse_order ? col_upr_right : col_upr_left;
|
||||
This->_VtxWritePtr[1].pos = b; This->_VtxWritePtr[1].uv = uv_b; This->_VtxWritePtr[1].col = reverse_order ? col_upr_left : col_upr_right;
|
||||
This->_VtxWritePtr[2].pos = c; This->_VtxWritePtr[2].uv = uv_c; This->_VtxWritePtr[2].col = reverse_order ? col_bot_left : col_bot_right;
|
||||
This->_VtxWritePtr[3].pos = d; This->_VtxWritePtr[3].uv = uv_d; This->_VtxWritePtr[3].col = reverse_order ? col_bot_right : col_bot_left;
|
||||
This->_VtxWritePtr += 4;
|
||||
This->_VtxCurrentIdx += 4;
|
||||
This->_IdxWritePtr += 6;
|
||||
}
|
||||
|
||||
static void AddImageGradient(ImDrawList* DrawList, ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max,
|
||||
ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left, bool reverse_order = false)
|
||||
{
|
||||
if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
const bool push_texture_id = user_texture_id && (user_texture_id != DrawList->_CmdHeader.TextureId);
|
||||
if (push_texture_id)
|
||||
DrawList->PushTextureID(user_texture_id);
|
||||
|
||||
DrawList->PrimReserve(6, 4);
|
||||
|
||||
const ImVec2 uv = DrawList->_Data->TexUvWhitePixel;
|
||||
|
||||
PrimRectUVColorCorners(DrawList, p_min, p_max,
|
||||
user_texture_id ? uv_min : uv,
|
||||
user_texture_id ? uv_max : uv,
|
||||
col_upr_left, col_upr_right, col_bot_right, col_bot_left,
|
||||
reverse_order);
|
||||
|
||||
if (push_texture_id)
|
||||
DrawList->PopTextureID();
|
||||
}
|
||||
|
||||
static void DrawStatic(const ImVec2& center, const ImVec2& resolution, float time)
|
||||
{
|
||||
auto drawList = ImGui::GetBackgroundDrawList();
|
||||
|
||||
const float scaleFactor = Sample(g_noiseScale, time);
|
||||
|
||||
const ImVec2 scale2D = { 1, scaleFactor };
|
||||
|
||||
auto [min, max] = ComputeRect(center, {scale2D.x * resolution.x, scale2D.y * resolution.y});
|
||||
|
||||
// Texture pixel size divided by image resolution (which must be divisible by 4) to get proper UV clipping.
|
||||
ImVec2 UV_MAX = { 270.0f / 272.0f,
|
||||
135.0f / 136.0f };
|
||||
|
||||
// Corner points
|
||||
|
||||
ImVec2 topCenter = { center.x, min.y };
|
||||
ImVec2 bottomCenter = { center.x, max.y };
|
||||
|
||||
ImVec2 centerLeft = { min.x, center.y };
|
||||
ImVec2 centerRight = { max.x, center.y };
|
||||
|
||||
bool flipUV = time >= (73 * FRAME_SCALE);
|
||||
|
||||
const float UV_1 = flipUV ? 0.0f : 1.0f;
|
||||
const float UV_0 = flipUV ? 1.0f : 0.0f;
|
||||
|
||||
// Top Left
|
||||
AddImageGradient(
|
||||
drawList,
|
||||
g_noiseTexture.get(),
|
||||
min,
|
||||
center,
|
||||
ImVec2(UV_0 * UV_MAX.x, 0.0f * UV_MAX.y),
|
||||
ImVec2(0.5f * UV_MAX.x, 0.5f * UV_MAX.y),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseTL_gradTL, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseTL_gradTR, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseTL_gradBR, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseTL_gradBL, time)),
|
||||
true);
|
||||
|
||||
// Top Right
|
||||
AddImageGradient(
|
||||
drawList,
|
||||
g_noiseTexture.get(),
|
||||
topCenter,
|
||||
centerRight,
|
||||
ImVec2(0.5f * UV_MAX.x, 0.0f * UV_MAX.y),
|
||||
ImVec2(UV_1 * UV_MAX.x, 0.5f * UV_MAX.y),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseTR_gradTL, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseTR_gradTR, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseTR_gradBR, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseTR_gradBL, time)),
|
||||
true);
|
||||
|
||||
// Bottom Right
|
||||
AddImageGradient(
|
||||
drawList,
|
||||
g_noiseTexture.get(),
|
||||
center,
|
||||
max,
|
||||
ImVec2(0.5f * UV_MAX.x, 0.5f * UV_MAX.y),
|
||||
ImVec2(UV_1 * UV_MAX.x, 1.0f * UV_MAX.y),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseBR_gradTL, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseBR_gradTR, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseBR_gradBR, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseBR_gradBL, time)),
|
||||
true);
|
||||
|
||||
// Bottom Left
|
||||
AddImageGradient(
|
||||
drawList,
|
||||
g_noiseTexture.get(),
|
||||
centerLeft,
|
||||
bottomCenter,
|
||||
ImVec2(UV_0 * UV_MAX.x, 0.5f * UV_MAX.y),
|
||||
ImVec2(0.5f * UV_MAX.x, 1.0f * UV_MAX.y),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseBL_gradTL, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseBL_gradTR, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseBL_gradBR, time)),
|
||||
IM_COL32(255, 255, 255, 255 * Sample(g_noiseBL_gradBL, time)),
|
||||
true);
|
||||
}
|
||||
|
||||
void TVStatic::Init()
|
||||
{
|
||||
g_flashTexture = LOAD_ZSTD_TEXTURE(g_options_static_flash);
|
||||
g_noiseTexture = LOAD_ZSTD_TEXTURE(g_options_static);
|
||||
}
|
||||
|
||||
static float ComputeTime(double appearTime)
|
||||
{
|
||||
return (ImGui::GetTime() - appearTime) + FRAME_OFFSET * FRAME_SCALE;
|
||||
}
|
||||
|
||||
float TVStatic::ComputeThumbnailAlpha(double appearTime)
|
||||
{
|
||||
return Sample(g_thumbnailAlpha, ComputeTime(appearTime));
|
||||
}
|
||||
|
||||
void TVStatic::Draw(const ImVec2& center, const ImVec2& resolution, double appearTime)
|
||||
{
|
||||
float time = ComputeTime(appearTime);
|
||||
|
||||
DrawStatic(center, resolution, time);
|
||||
DrawFlash(center, resolution, time);
|
||||
}
|
8
UnleashedRecomp/ui/tv_static.h
Normal file
8
UnleashedRecomp/ui/tv_static.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
struct TVStatic
|
||||
{
|
||||
static void Init();
|
||||
static float ComputeThumbnailAlpha(double appearTime);
|
||||
static void Draw(const ImVec2& center, const ImVec2& resolution, double appearTime);
|
||||
};
|
|
@ -1 +1 @@
|
|||
Subproject commit a2c4daf8f7f0b0ff4386933c4d872fa47239f0e4
|
||||
Subproject commit 5ba3baac5a62203d6c77c9476d7dc8f14adcdc10
|
Loading…
Add table
Add a link
Reference in a new issue