diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.cpp b/rpcs3/Emu/RSX/GL/GLOverlays.cpp index 25913b3f92..9822cdb62d 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.cpp +++ b/rpcs3/Emu/RSX/GL/GLOverlays.cpp @@ -1,7 +1,5 @@ #include "GLOverlays.h" -extern u64 get_system_time(); - namespace gl { void overlay_pass::create() @@ -514,12 +512,11 @@ namespace gl { program_handle.uniforms["viewport"] = color4f(static_cast(viewport.width()), static_cast(viewport.height()), static_cast(viewport.x1), static_cast(viewport.y1)); program_handle.uniforms["ui_scale"] = color4f(static_cast(ui.virtual_width), static_cast(ui.virtual_height), 1.f, 1.f); - program_handle.uniforms["time"] = static_cast(get_system_time() / 1000) * 0.005f; saved_sampler_state save_30(30, m_sampler); saved_sampler_state save_31(31, m_sampler); - for (auto &cmd : ui.get_compiled().draw_commands) + for (auto& cmd : ui.get_compiled().draw_commands) { set_primitive_type(cmd.config.primitives); upload_vertex_data(cmd.verts.data(), ::size32(cmd.verts)); @@ -530,7 +527,7 @@ namespace gl { case rsx::overlays::image_resource_id::game_icon: case rsx::overlays::image_resource_id::backbuffer: - //TODO + // TODO case rsx::overlays::image_resource_id::none: { texture_read = GL_FALSE; @@ -557,6 +554,7 @@ namespace gl } } + program_handle.uniforms["time"] = cmd.config.get_sinus_value(); program_handle.uniforms["color"] = cmd.config.color; program_handle.uniforms["sampler_mode"] = texture_read; program_handle.uniforms["pulse_glow"] = static_cast(cmd.config.pulse_glow); diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h index 6006a6943d..f0e8e53360 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.h @@ -30,6 +30,8 @@ #include #endif +extern u64 get_system_time(); + // Definitions for common UI controls and their routines namespace rsx { @@ -228,6 +230,8 @@ namespace rsx color4f color = { 1.f, 1.f, 1.f, 1.f }; bool pulse_glow = false; + f32 pulse_sinus_offset = 0.0f; // The current pulse offset + f32 pulse_speed_modifier = 0.005f; areaf clip_rect = {}; bool clip_region = false; @@ -251,6 +255,12 @@ namespace rsx texture_ref = image_resource_id::font_file; font_ref = ref; } + + // Analog to overlay_element::set_sinus_offset + f32 get_sinus_value() const + { + return (static_cast(get_system_time() / 1000) * pulse_speed_modifier) - pulse_sinus_offset; + } }; struct command @@ -344,6 +354,24 @@ namespace rsx color4f back_color = { 0.f, 0.f, 0.f, 1.f }; color4f fore_color = { 1.f, 1.f, 1.f, 1.f }; bool pulse_effect_enabled = false; + f32 pulse_sinus_offset = 0.0f; // The current pulse offset + f32 pulse_speed_modifier = 0.005f; + + // Analog to command_config::get_sinus_value + // Apply modifier for sinus pulse. Resets the pulse. For example: + // 0 -> reset to 0.5 rising + // 0.5 -> reset to 0 + // 1 -> reset to 0.5 falling + // 1.5 -> reset to 1 + void set_sinus_offset(f32 sinus_modifier) + { + if (sinus_modifier >= 0) + { + static const f32 PI = 3.14159265f; + const f32 pulse_sinus_x = static_cast(get_system_time() / 1000) * pulse_speed_modifier; + pulse_sinus_offset = fmod(pulse_sinus_x + sinus_modifier * PI, 2.0f * PI); + } + } compiled_resource compiled_resources; bool is_compiled = false; @@ -561,6 +589,8 @@ namespace rsx config.color = back_color; config.pulse_glow = pulse_effect_enabled; + config.pulse_sinus_offset = pulse_sinus_offset; + config.pulse_speed_modifier = pulse_speed_modifier; auto& verts = compiled_resources_temp.draw_commands.front().verts; verts.resize(4); @@ -1066,6 +1096,8 @@ namespace rsx u16 caret_position = 0; u16 vertical_scroll_offset = 0; + bool m_reset_caret_pulse = 0; + using label::label; void move_caret(direction dir); diff --git a/rpcs3/Emu/RSX/Overlays/overlay_edit_text.cpp b/rpcs3/Emu/RSX/Overlays/overlay_edit_text.cpp index 611ea99c5a..d1750d403d 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_edit_text.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_edit_text.cpp @@ -31,6 +31,8 @@ namespace rsx void edit_text::move_caret(direction dir) { + m_reset_caret_pulse = true; + switch (dir) { case direction::left: @@ -112,6 +114,7 @@ namespace rsx } caret_position += ::narrow(str.length()); + m_reset_caret_pulse = true; refresh(); } @@ -136,6 +139,7 @@ namespace rsx } caret_position--; + m_reset_caret_pulse = true; refresh(); } @@ -155,6 +159,13 @@ namespace rsx caret.back_color = fore_color; caret.pulse_effect_enabled = true; + if (m_reset_caret_pulse) + { + // Reset the pulse slightly below 1 rising on each user interaction + caret.set_sinus_offset(1.6f); + m_reset_caret_pulse = false; + } + compiled.add(caret.get_compiled()); for (auto& cmd : compiled.draw_commands) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_list_view.cpp b/rpcs3/Emu/RSX/Overlays/overlay_list_view.cpp index 2b506be0aa..e18071b87b 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_list_view.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_list_view.cpp @@ -108,11 +108,18 @@ namespace rsx { const s32 max_entry = m_elements_count - 1; + // Reset the pulse slightly below 1 rising on each user interaction + m_highlight_box->set_sinus_offset(1.6f); + if (m_selected_entry != entry) { m_selected_entry = std::max(0, std::min(entry, max_entry)); update_selection(); } + else + { + refresh(); + } } void list_view::select_next(u16 count) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp index f123e40775..8093808539 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp @@ -383,7 +383,7 @@ namespace rsx { const auto index_limit = (num_columns * num_rows) - 1; - auto on_accept = [&]() + const auto on_accept = [this]() { const u32 current_index = (selected_y * num_columns) + selected_x; const auto& current_cell = m_grid[current_index]; @@ -441,11 +441,10 @@ namespace rsx if (m_grid[get_cell_geometry(current_index).first].enabled) { update_selection_by_index(current_index); - m_update = true; break; } } - + m_reset_pulse = true; break; } case pad_button::dpad_left: @@ -461,7 +460,6 @@ namespace rsx if (m_grid[get_cell_geometry(current_index).first].enabled) { update_selection_by_index(current_index); - m_update = true; break; } } @@ -470,6 +468,7 @@ namespace rsx break; } } + m_reset_pulse = true; break; } case pad_button::dpad_down: @@ -486,10 +485,10 @@ namespace rsx if (m_grid[get_cell_geometry(current_index).first].enabled) { update_selection_by_index(current_index); - m_update = true; break; } } + m_reset_pulse = true; break; } case pad_button::dpad_up: @@ -501,10 +500,10 @@ namespace rsx if (m_grid[get_cell_geometry(current_index).first].enabled) { update_selection_by_index(current_index); - m_update = true; break; } } + m_reset_pulse = true; break; } case pad_button::select: @@ -530,6 +529,7 @@ namespace rsx case pad_button::cross: { on_accept(); + m_reset_pulse = true; break; } case pad_button::circle: @@ -550,6 +550,11 @@ namespace rsx default: break; } + + if (m_reset_pulse) + { + m_update = true; + } } void osk_dialog::on_text_changed() @@ -706,6 +711,12 @@ namespace rsx m_label.back_color = { 0.f, 0.f, 0.f, 0.f }; m_label.set_padding(0, 0, 10, 0); + if (m_reset_pulse) + { + // Reset the pulse slightly above 0 falling on each user interaction + m_key_pulse_cache.set_sinus_offset(0.6f); + } + for (const auto& c : m_grid) { u16 x = u16(c.pos.x); @@ -764,16 +775,19 @@ namespace rsx tmp.set_pos(x, y); tmp.set_size(w, h); tmp.pulse_effect_enabled = c.selected; + tmp.pulse_sinus_offset = m_key_pulse_cache.pulse_sinus_offset; m_cached_resource.add(tmp.get_compiled()); if (render_label) { m_label.pulse_effect_enabled = c.selected; + m_label.pulse_sinus_offset = m_key_pulse_cache.pulse_sinus_offset; m_cached_resource.add(m_label.get_compiled()); } } + m_reset_pulse = false; m_update = false; } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.h b/rpcs3/Emu/RSX/Overlays/overlay_osk.h index 8d81e3e854..a66c4072db 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.h @@ -66,6 +66,9 @@ namespace rsx // Fade in/out animation_color_interpolate fade_animation; + bool m_reset_pulse = false; + overlay_element m_key_pulse_cache; // Let's use this to store the pulse offset of the key, since we don't seem to cache the keys themselves. + bool m_update = true; compiled_resource m_cached_resource; diff --git a/rpcs3/Emu/RSX/Overlays/overlays.h b/rpcs3/Emu/RSX/Overlays/overlays.h index f949b1208d..049a442099 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.h +++ b/rpcs3/Emu/RSX/Overlays/overlays.h @@ -84,7 +84,6 @@ namespace rsx public: s32 return_code = 0; // CELL_OK - public: void update() override {} compiled_resource get_compiled() override = 0; diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.cpp b/rpcs3/Emu/RSX/VK/VKOverlays.cpp index ffb9e3e2a3..2d419db032 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.cpp +++ b/rpcs3/Emu/RSX/VK/VKOverlays.cpp @@ -715,7 +715,6 @@ namespace vk vk::data_heap& upload_heap, rsx::overlays::overlay& ui) { m_scale_offset = color4f(ui.virtual_width, ui.virtual_height, 1.f, 1.f); - m_time = static_cast(get_system_time() / 1000) * 0.005f; m_viewport = { { static_cast(viewport.x1), static_cast(viewport.y1) }, { static_cast(viewport.width()), static_cast(viewport.height()) } }; std::vector image_views @@ -731,6 +730,7 @@ namespace vk upload_vertex_data(command.verts.data(), num_drawable_elements); set_primitive_type(command.config.primitives); + m_time = command.config.get_sinus_value(); m_skip_texture_read = false; m_color = command.config.color; m_pulse_glow = command.config.pulse_glow;