mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-07-08 20:24:52 -04:00
Launcher background (#58)
* Begin implementing launcher background * Add keyframe system for launcher. * Mirror Banjo. * More work on animations. * Update RecompFrontend. * Update RT64. * Fix linux build * adjust launcher anim and launcher --------- Co-authored-by: Dario <dariosamo@gmail.com> Co-authored-by: Reonu <reonuyt@gmail.com> Co-authored-by: thecozies <79979276+thecozies@users.noreply.github.com>
This commit is contained in:
@@ -140,6 +140,7 @@ add_custom_command(OUTPUT
|
||||
add_executable(BanjoRecompiled)
|
||||
|
||||
set (SOURCES
|
||||
${CMAKE_SOURCE_DIR}/src/main/launcher_animation.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/main/main.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/main/register_overlays.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/main/register_patches.cpp
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1054 1044" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-348,-18)">
|
||||
<g transform="matrix(0.965901,0,0,0.965901,29.8367,18.4135)">
|
||||
<rect x="330" y="0" width="1090" height="1080" style="fill:rgb(255,201,69);"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 682 B |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 2180 2160" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(0.837799,0,0,0.823158,362.599,628.361)">
|
||||
<path d="M2169.26,-763.354L2169.26,1860.69L-432.8,1860.69L-432.8,-763.354L2169.26,-763.354ZM576.269,847.984L660.512,1167.98L950.699,1088.84C912.269,1067.12 882.2,1030.18 869.936,983.6C845.93,892.416 899.177,798.549 988.767,774.117C1078.36,749.684 1170.58,803.878 1194.59,895.062C1206.85,941.647 1198.96,988.933 1176.35,1027.3L1466.53,948.162L1382.27,628.092C1360.47,662.883 1326.33,689.805 1284.12,701.316C1194.53,725.75 1102.3,671.558 1078.3,580.372C1054.29,489.188 1107.54,395.321 1197.13,370.888C1239.34,359.377 1282.13,365.317 1318.1,384.358L1250.56,127.805L960.463,206.919C983.019,168.569 990.892,121.33 978.639,74.789C954.634,-16.395 862.407,-70.589 772.817,-46.157C683.227,-21.724 629.98,72.143 653.985,163.327C666.238,209.868 696.263,246.771 734.637,268.505L444.539,347.619L512.06,604.091C476.111,585.098 433.361,579.18 391.193,590.679C301.6,615.113 248.356,708.979 272.362,800.163C296.368,891.349 388.591,945.541 478.184,921.108C520.352,909.608 554.468,882.73 576.269,847.984Z" style="fill:#1A5698"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1275 1346" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-505,-288)">
|
||||
<g transform="matrix(1,0,0,1,182,432)">
|
||||
<g transform="matrix(1.60405,0.926099,-0.849835,1.47196,-1141.53,-1729.71)">
|
||||
<path d="M1708.78,2.179L1708.78,916.607L1476.3,1062.88L1476.3,148.447L1708.78,2.179Z" style="fill:white;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 800 B |
@@ -0,0 +1,16 @@
|
||||
#ifndef __BANJO_LAUNCHER_H__
|
||||
#define __BANJO_LAUNCHER_H__
|
||||
|
||||
#include "recompui/recompui.h"
|
||||
|
||||
namespace banjo {
|
||||
void launcher_animation_setup(recompui::LauncherMenu *menu, recompui::Element *title);
|
||||
void launcher_animation_update(recompui::LauncherMenu *menu);
|
||||
|
||||
constexpr float launcher_options_right_position_start = 96.0f;
|
||||
constexpr float launcher_options_right_position_end = 96.0f + 24.0f;
|
||||
constexpr float launcher_options_top_offset = 96.0f;
|
||||
constexpr float launcher_options_title_offset = 120.0f;
|
||||
}
|
||||
|
||||
#endif
|
||||
+1
-1
Submodule lib/RecompFrontend updated: 0ea1e75a40...62f2f0652f
@@ -0,0 +1,308 @@
|
||||
#include "banjo_launcher.h"
|
||||
|
||||
struct KeyframeRot {
|
||||
float seconds;
|
||||
float deg;
|
||||
};
|
||||
|
||||
struct Keyframe2D {
|
||||
float seconds;
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
enum class InterpolationMethod {
|
||||
Linear,
|
||||
Smootherstep
|
||||
};
|
||||
|
||||
struct AnimationData {
|
||||
uint32_t keyframe_index = 0;
|
||||
uint32_t loop_keyframe_index = UINT32_MAX;
|
||||
float seconds = 0.0f;
|
||||
InterpolationMethod interpolation_method = InterpolationMethod::Linear;
|
||||
};
|
||||
|
||||
struct AnimatedSvg {
|
||||
recompui::Element *svg = nullptr;
|
||||
std::vector<Keyframe2D> position_keyframes;
|
||||
std::vector<Keyframe2D> scale_keyframes;
|
||||
std::vector<KeyframeRot> rotation_keyframes;
|
||||
AnimationData position_animation;
|
||||
AnimationData scale_animation;
|
||||
AnimationData rotation_animation;
|
||||
float width = 0;
|
||||
float height = 0;
|
||||
};
|
||||
|
||||
struct LauncherContext {
|
||||
AnimatedSvg banjo_svg;
|
||||
AnimatedSvg kazooie_svg;
|
||||
AnimatedSvg jiggy_color_svg;
|
||||
AnimatedSvg jiggy_shine_svg;
|
||||
AnimatedSvg jiggy_hole_svg;
|
||||
recompui::Element *wrapper;
|
||||
recompui::Element *title;
|
||||
std::chrono::steady_clock::time_point last_update_time;
|
||||
std::chrono::steady_clock::time_point start_time;
|
||||
bool started = false;
|
||||
} launcher_context;
|
||||
|
||||
float interpolate_value(float a, float b, float t, InterpolationMethod method) {
|
||||
switch (method) {
|
||||
case InterpolationMethod::Smootherstep:
|
||||
return a + (b - a) * (t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f));
|
||||
case InterpolationMethod::Linear:
|
||||
default:
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
}
|
||||
|
||||
void calculate_rot_from_keyframes(const std::vector<KeyframeRot> &kf, AnimationData &an, float delta_time, float °) {
|
||||
if (kf.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
an.seconds += delta_time;
|
||||
|
||||
while ((an.keyframe_index < (kf.size() - 1) && (an.seconds >= kf[an.keyframe_index + 1].seconds))) {
|
||||
an.keyframe_index++;
|
||||
}
|
||||
|
||||
if (an.keyframe_index >= (kf.size() - 1)) {
|
||||
deg = kf[an.keyframe_index].deg;
|
||||
}
|
||||
else {
|
||||
float t = (an.seconds - kf[an.keyframe_index].seconds) / (kf[an.keyframe_index + 1].seconds - kf[an.keyframe_index].seconds);
|
||||
deg = interpolate_value(kf[an.keyframe_index].deg, kf[an.keyframe_index + 1].deg, t, an.interpolation_method);
|
||||
}
|
||||
}
|
||||
|
||||
void calculate_2d_from_keyframes(const std::vector<Keyframe2D> &kf, AnimationData &an, float delta_time, float &x, float &y) {
|
||||
if (kf.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
an.seconds += delta_time;
|
||||
|
||||
while ((an.keyframe_index < (kf.size() - 1) && (an.seconds >= kf[an.keyframe_index + 1].seconds))) {
|
||||
an.keyframe_index++;
|
||||
}
|
||||
|
||||
if ((an.loop_keyframe_index != UINT32_MAX) && (an.keyframe_index >= (kf.size() - 1))) {
|
||||
an.seconds = kf[an.loop_keyframe_index].seconds + (an.seconds - kf[an.keyframe_index].seconds);
|
||||
an.keyframe_index = an.loop_keyframe_index;
|
||||
}
|
||||
|
||||
if (an.keyframe_index >= (kf.size() - 1)) {
|
||||
x = kf[an.keyframe_index].x;
|
||||
y = kf[an.keyframe_index].y;
|
||||
}
|
||||
else {
|
||||
float t = (an.seconds - kf[an.keyframe_index].seconds) / (kf[an.keyframe_index + 1].seconds - kf[an.keyframe_index].seconds);
|
||||
x = interpolate_value(kf[an.keyframe_index].x, kf[an.keyframe_index + 1].x, t, an.interpolation_method);
|
||||
y = interpolate_value(kf[an.keyframe_index].y, kf[an.keyframe_index + 1].y, t, an.interpolation_method);
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedSvg create_animated_svg(recompui::ContextId context, recompui::Element *parent, const std::string &svg_path, float width, float height) {
|
||||
AnimatedSvg animated_svg;
|
||||
animated_svg.width = width;
|
||||
animated_svg.height = height;
|
||||
animated_svg.svg = context.create_element<recompui::Svg>(parent, svg_path);
|
||||
animated_svg.svg->set_position(recompui::Position::Absolute);
|
||||
animated_svg.svg->set_width(width, recompui::Unit::Dp);
|
||||
animated_svg.svg->set_height(height, recompui::Unit::Dp);
|
||||
return animated_svg;
|
||||
}
|
||||
|
||||
void update_animated_svg(AnimatedSvg &animated_svg, float delta_time, float bg_width, float bg_height) {
|
||||
float position_x = 0.0f, position_y = 0.0f;
|
||||
float scale_x = 1.0f, scale_y = 1.0f;
|
||||
float rotation_degrees = 0.0f;
|
||||
calculate_2d_from_keyframes(animated_svg.position_keyframes, animated_svg.position_animation, delta_time, position_x, position_y);
|
||||
calculate_2d_from_keyframes(animated_svg.scale_keyframes, animated_svg.scale_animation, delta_time, scale_x, scale_y);
|
||||
calculate_rot_from_keyframes(animated_svg.rotation_keyframes, animated_svg.rotation_animation, delta_time, rotation_degrees);
|
||||
animated_svg.svg->set_translate_2D(position_x + bg_width / 2.0f - animated_svg.width / 2.0f, position_y + bg_height / 2.0f - animated_svg.height / 2.0f);
|
||||
animated_svg.svg->set_scale_2D(scale_x, scale_y);
|
||||
animated_svg.svg->set_rotation(rotation_degrees);
|
||||
}
|
||||
|
||||
const float jiggy_scale_anim_start = 0.4f;
|
||||
const float jiggy_scale_anim_length = 0.75f;
|
||||
const float jiggy_scale_anim_end = jiggy_scale_anim_start + jiggy_scale_anim_length;
|
||||
const float jiggy_move_over_start = jiggy_scale_anim_end + 0.5f;
|
||||
const float jiggy_move_over_length = 0.75f;
|
||||
const float jiggy_move_over_end = jiggy_move_over_start + jiggy_move_over_length;
|
||||
const float jiggy_shine_start = jiggy_move_over_end - 0.5f;
|
||||
const float jiggy_shine_length = 0.8f;
|
||||
|
||||
void banjo::launcher_animation_setup(recompui::LauncherMenu *menu, recompui::Element *title) {
|
||||
auto context = recompui::get_current_context();
|
||||
recompui::Element *background_container = menu->get_background_container();
|
||||
background_container->set_background_color({ 0x1A, 0x56, 0x98, 0xFF });
|
||||
|
||||
launcher_context.wrapper = context.create_element<recompui::Element>(background_container, 0);
|
||||
launcher_context.wrapper->set_position(recompui::Position::Absolute);
|
||||
launcher_context.wrapper->set_width(100, recompui::Unit::Percent);
|
||||
launcher_context.wrapper->set_height(100, recompui::Unit::Percent);
|
||||
launcher_context.wrapper->set_top(0);
|
||||
|
||||
// The creation order of these is important.
|
||||
launcher_context.jiggy_color_svg = create_animated_svg(context, launcher_context.wrapper, "JiggyColor.svg", 1054.0f, 1044.0f);
|
||||
launcher_context.jiggy_shine_svg = create_animated_svg(context, launcher_context.wrapper, "JiggyShine.svg", 219.0f, 1080.0f);
|
||||
launcher_context.jiggy_hole_svg = create_animated_svg(context, launcher_context.wrapper, "JiggyHole.svg", 2180.0f, 2160.0f);
|
||||
launcher_context.banjo_svg = create_animated_svg(context, launcher_context.wrapper, "Banjo.svg", 649.0f, 622.0f);
|
||||
launcher_context.kazooie_svg = create_animated_svg(context, launcher_context.wrapper, "Kazooie.svg", 626.0f, 774.0f);
|
||||
|
||||
// Animate the jiggy hole.
|
||||
launcher_context.jiggy_hole_svg.position_keyframes = {
|
||||
{ 0.0f, 0.0f, 0.0f },
|
||||
{ 3.0f, 0.0f, -5.0f },
|
||||
{ 6.0f, 0.0f, 5.0f },
|
||||
{ 9.0f, 0.0f, -5.0f },
|
||||
};
|
||||
|
||||
launcher_context.jiggy_hole_svg.scale_keyframes = {
|
||||
{ 0.0f, 0.0f, 0.0f },
|
||||
{ jiggy_scale_anim_start + 0.0f, 0.0f, 0.0f },
|
||||
{ jiggy_scale_anim_start + jiggy_scale_anim_length, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
launcher_context.jiggy_hole_svg.rotation_keyframes = {
|
||||
{ 0.0f, -45.0f },
|
||||
{ jiggy_scale_anim_start + 0.0f, -45.0f },
|
||||
{ jiggy_scale_anim_start + jiggy_scale_anim_length, 0.0f },
|
||||
};
|
||||
|
||||
launcher_context.jiggy_hole_svg.position_animation.loop_keyframe_index = 1;
|
||||
launcher_context.jiggy_hole_svg.position_animation.interpolation_method = InterpolationMethod::Smootherstep;
|
||||
launcher_context.jiggy_hole_svg.scale_animation.interpolation_method = InterpolationMethod::Smootherstep;
|
||||
launcher_context.jiggy_hole_svg.rotation_animation.interpolation_method = InterpolationMethod::Smootherstep;
|
||||
|
||||
// Copy keyframes from the hole to the color.
|
||||
launcher_context.jiggy_color_svg.position_keyframes = launcher_context.jiggy_hole_svg.position_keyframes;
|
||||
launcher_context.jiggy_color_svg.position_animation = launcher_context.jiggy_hole_svg.position_animation;
|
||||
launcher_context.jiggy_color_svg.scale_keyframes = launcher_context.jiggy_hole_svg.scale_keyframes;
|
||||
launcher_context.jiggy_color_svg.scale_animation = launcher_context.jiggy_hole_svg.scale_animation;
|
||||
launcher_context.jiggy_color_svg.rotation_keyframes = launcher_context.jiggy_hole_svg.rotation_keyframes;
|
||||
launcher_context.jiggy_color_svg.rotation_animation = launcher_context.jiggy_hole_svg.rotation_animation;
|
||||
|
||||
// Animate the jiggy shine.
|
||||
launcher_context.jiggy_shine_svg.position_keyframes = {
|
||||
{ 0.0f, 700.0f, 0.0f },
|
||||
{ jiggy_shine_start, 700.0f, 0.0f },
|
||||
{ jiggy_shine_start + jiggy_shine_length, -700.0f, 0.0f },
|
||||
};
|
||||
|
||||
launcher_context.jiggy_shine_svg.scale_keyframes = {
|
||||
{ 0.0f, 0.0f, 0.0f },
|
||||
{ jiggy_shine_start, 0.0f, 0.0f },
|
||||
{ jiggy_shine_start + 0.01f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
launcher_context.jiggy_shine_svg.position_animation.interpolation_method = InterpolationMethod::Smootherstep;
|
||||
|
||||
// Animate Banjo.
|
||||
launcher_context.banjo_svg.position_keyframes = {
|
||||
{ 0.0f, -1200.0f, 0.0f },
|
||||
{ 1.0f, -220.0f, 0.0f },
|
||||
{ 2.0f, -220.0f, -5.0f },
|
||||
{ 5.0f, -220.0f, 5.0f },
|
||||
{ 8.0f, -220.0f, -5.0f },
|
||||
};
|
||||
|
||||
launcher_context.banjo_svg.scale_keyframes = {
|
||||
{ 0.0f, 0.0f, 0.0f },
|
||||
{ 0.1f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
launcher_context.banjo_svg.rotation_keyframes = {
|
||||
{ 0.0f, -20.0f },
|
||||
{ 1.0f, 0.0f },
|
||||
};
|
||||
|
||||
launcher_context.banjo_svg.position_animation.loop_keyframe_index = 2;
|
||||
launcher_context.banjo_svg.position_animation.interpolation_method = InterpolationMethod::Smootherstep;
|
||||
launcher_context.banjo_svg.rotation_animation.interpolation_method = InterpolationMethod::Smootherstep;
|
||||
|
||||
// Animate Kazooie. Mirror all of Banjo's keyframes except for the scale.
|
||||
launcher_context.kazooie_svg.position_keyframes = launcher_context.banjo_svg.position_keyframes;
|
||||
launcher_context.kazooie_svg.position_animation = launcher_context.banjo_svg.position_animation;
|
||||
launcher_context.kazooie_svg.scale_keyframes = launcher_context.banjo_svg.scale_keyframes;
|
||||
launcher_context.kazooie_svg.scale_animation = launcher_context.banjo_svg.scale_animation;
|
||||
launcher_context.kazooie_svg.rotation_keyframes = launcher_context.banjo_svg.rotation_keyframes;
|
||||
launcher_context.kazooie_svg.rotation_animation = launcher_context.banjo_svg.rotation_animation;
|
||||
|
||||
for (auto &kf : launcher_context.kazooie_svg.position_keyframes) {
|
||||
kf.x = -kf.x;
|
||||
}
|
||||
|
||||
launcher_context.kazooie_svg.position_keyframes[2].seconds += 1.5f;
|
||||
launcher_context.kazooie_svg.position_keyframes[3].seconds += 1.5f;
|
||||
launcher_context.kazooie_svg.position_keyframes[4].seconds += 1.5f;
|
||||
|
||||
for (auto &kf : launcher_context.kazooie_svg.rotation_keyframes) {
|
||||
kf.deg = -kf.deg;
|
||||
}
|
||||
|
||||
launcher_context.start_time = std::chrono::steady_clock::now();
|
||||
|
||||
launcher_context.title = title;
|
||||
}
|
||||
|
||||
void banjo::launcher_animation_update(recompui::LauncherMenu *menu) {
|
||||
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||
float delta_time = launcher_context.started ? std::chrono::duration_cast<std::chrono::milliseconds>(now - launcher_context.last_update_time).count() / 1000.0f : 0.0f;
|
||||
launcher_context.last_update_time = now;
|
||||
launcher_context.started = true;
|
||||
|
||||
recompui::Element *background_container = menu->get_background_container();
|
||||
float dp_to_pixel_ratio = background_container->get_dp_to_pixel_ratio();
|
||||
float bg_width = background_container->get_client_width() / dp_to_pixel_ratio;
|
||||
float bg_height = background_container->get_client_height() / dp_to_pixel_ratio;
|
||||
update_animated_svg(launcher_context.banjo_svg, delta_time, bg_width, bg_height);
|
||||
update_animated_svg(launcher_context.kazooie_svg, delta_time, bg_width, bg_height);
|
||||
update_animated_svg(launcher_context.jiggy_color_svg, delta_time, bg_width, bg_height);
|
||||
update_animated_svg(launcher_context.jiggy_shine_svg, delta_time, bg_width, bg_height);
|
||||
update_animated_svg(launcher_context.jiggy_hole_svg, delta_time, bg_width, bg_height);
|
||||
|
||||
auto elapsed = now - launcher_context.start_time;
|
||||
float elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
|
||||
float from_ms = jiggy_move_over_start * 1000.0f;
|
||||
float to_ms = jiggy_move_over_end * 1000.0f;
|
||||
if (elapsed_ms > from_ms && elapsed_ms < to_ms) {
|
||||
float now_ms = elapsed_ms;
|
||||
float t = (now_ms - from_ms) / (to_ms - from_ms);
|
||||
float x_translation = interpolate_value(0, 1440 * -0.2f, t, InterpolationMethod::Smootherstep);
|
||||
launcher_context.wrapper->set_translate_2D(x_translation, 0, recompui::Unit::Dp);
|
||||
float y_translation = interpolate_value(0, launcher_options_top_offset, t, InterpolationMethod::Smootherstep);
|
||||
launcher_context.wrapper->set_top(y_translation);
|
||||
float scale = interpolate_value(1, 0.666f, t, InterpolationMethod::Smootherstep);
|
||||
launcher_context.wrapper->set_scale_2D(scale, scale);
|
||||
|
||||
float game_option_menu_opacity = interpolate_value(0, 1.0f, t, InterpolationMethod::Smootherstep);
|
||||
for (auto option : menu->get_game_options_menu()->get_options()) {
|
||||
option->set_opacity(game_option_menu_opacity);
|
||||
}
|
||||
launcher_context.title->set_opacity(game_option_menu_opacity);
|
||||
|
||||
float game_option_menu_right = interpolate_value(
|
||||
launcher_options_right_position_start, launcher_options_right_position_end, t, InterpolationMethod::Smootherstep);
|
||||
menu->get_game_options_menu()->set_right(game_option_menu_right);
|
||||
}
|
||||
|
||||
if (elapsed_ms <= from_ms) {
|
||||
for (auto option : menu->get_game_options_menu()->get_options()) {
|
||||
option->set_opacity(0);
|
||||
}
|
||||
launcher_context.title->set_opacity(0.0f);
|
||||
menu->get_game_options_menu()->set_right(launcher_options_right_position_start);
|
||||
} else if (elapsed_ms >= to_ms) {
|
||||
for (auto option : menu->get_game_options_menu()->get_options()) {
|
||||
option->set_opacity(1.0f);
|
||||
}
|
||||
launcher_context.title->set_opacity(1.0f);
|
||||
menu->get_game_options_menu()->set_right(launcher_options_right_position_end);
|
||||
}
|
||||
}
|
||||
+38
-12
@@ -40,6 +40,7 @@
|
||||
#include "banjo_sound.h"
|
||||
#include "banjo_support.h"
|
||||
#include "banjo_game.h"
|
||||
#include "banjo_launcher.h"
|
||||
#include "recomp_data.h"
|
||||
#include "ovl_patches.hpp"
|
||||
#include "theme.h"
|
||||
@@ -82,7 +83,7 @@ ultramodern::gfx_callbacks_t::gfx_data_t create_gfx() {
|
||||
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) > 0) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC) > 0) {
|
||||
exit_error("Failed to initialize SDL2: %s\n", SDL_GetError());
|
||||
}
|
||||
|
||||
@@ -151,7 +152,7 @@ ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::
|
||||
flags |= SDL_WINDOW_VULKAN;
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindow("Banjo: Recompiled", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1600, 960, flags);
|
||||
window = SDL_CreateWindow("Banjo: Recompiled", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1600, 900, flags);
|
||||
|
||||
if (window == nullptr) {
|
||||
exit_error("Failed to create window: %s\n", SDL_GetError());
|
||||
@@ -546,19 +547,43 @@ void on_launcher_init(recompui::LauncherMenu *menu) {
|
||||
supported_games[0].mod_game_id,
|
||||
recompui::GameOptionsMenuLayout::Center
|
||||
);
|
||||
|
||||
game_options_menu->add_default_options();
|
||||
|
||||
constexpr float banjo_apsect_ratio = 1.0434f;
|
||||
constexpr float banjo_height = 500.0f;
|
||||
for (auto option : game_options_menu->get_options()) {
|
||||
option->set_justify_content(recompui::JustifyContent::FlexEnd);
|
||||
option->set_border_radius(0);
|
||||
|
||||
// TODO: Style launcher and get better background.
|
||||
auto bg_element = menu->set_launcher_background_svg("Banjo.svg");
|
||||
bg_element->set_top(50.0f, recompui::Unit::Percent);
|
||||
bg_element->set_left(50.0f, recompui::Unit::Percent);
|
||||
bg_element->set_height(banjo_height, recompui::Unit::Dp);
|
||||
bg_element->set_width(banjo_height * banjo_apsect_ratio, recompui::Unit::Dp);
|
||||
bg_element->set_translate_2D(-50.0f, -50.0f, recompui::Unit::Percent);
|
||||
bg_element->set_opacity(0.25f);
|
||||
std::vector<recompui::Style *> hover_focus = {&option->hover_style, &option->focus_style};
|
||||
for (auto style : hover_focus) {
|
||||
style->set_background_color(recompui::theme::color::Transparent);
|
||||
}
|
||||
}
|
||||
|
||||
recompui::Element *menu_container = menu->get_menu_container();
|
||||
menu_container->set_width(1440);
|
||||
menu_container->unset_left();
|
||||
menu_container->set_top(banjo::launcher_options_top_offset);
|
||||
menu_container->set_bottom(-banjo::launcher_options_top_offset);
|
||||
menu_container->set_right(50, recompui::Unit::Percent);
|
||||
menu_container->set_translate_2D(50.0f, 0.0f, recompui::Unit::Percent);
|
||||
|
||||
game_options_menu->unset_left();
|
||||
game_options_menu->set_bottom(50.0f, recompui::Unit::Percent);
|
||||
game_options_menu->set_translate_2D(0.0f, 50.0f, recompui::Unit::Percent);
|
||||
game_options_menu->set_right(banjo::launcher_options_right_position_start);
|
||||
|
||||
menu->remove_default_title();
|
||||
|
||||
recompui::ContextId context = recompui::get_current_context();
|
||||
recompui::Label* title_label = context.create_element<recompui::Label>(menu, "Banjo: Recompiled", recompui::theme::Typography::Header1);
|
||||
title_label->set_position(recompui::Position::Absolute);
|
||||
title_label->set_top(banjo::launcher_options_title_offset);
|
||||
title_label->set_right(50.0f, recompui::Unit::Percent);
|
||||
title_label->set_translate_2D(50.0f, 0.0f, recompui::Unit::Percent);
|
||||
title_label->set_color(recompui::theme::color::White);
|
||||
|
||||
banjo::launcher_animation_setup(menu, title_label);
|
||||
}
|
||||
|
||||
#define REGISTER_FUNC(name) recomp::overlays::register_base_export(#name, name)
|
||||
@@ -682,6 +707,7 @@ int main(int argc, char** argv) {
|
||||
banjo::init_config();
|
||||
|
||||
recompui::register_launcher_init_callback(on_launcher_init);
|
||||
recompui::register_launcher_update_callback(banjo::launcher_animation_update);
|
||||
|
||||
recomp::rsp::callbacks_t rsp_callbacks{
|
||||
.get_rsp_microcode = get_rsp_microcode,
|
||||
|
||||
Reference in New Issue
Block a user