Skip to content

Commit

Permalink
Encore mode and other stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
OFFTKP committed Aug 16, 2024
1 parent 0a02682 commit 4bca574
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 42 deletions.
40 changes: 32 additions & 8 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ typedef struct{
uint32_t draw_notifications;
uint32_t ra_needs_reload;
float gui_scale_factor;
uint32_t padding[222];
uint32_t only_one_notification;
uint32_t padding[221];
}persistent_settings_t;
_Static_assert(sizeof(persistent_settings_t)==1024, "persistent_settings_t must be exactly 1024 bytes");
#define SE_STATS_GRAPH_DATA 256
Expand Down Expand Up @@ -396,6 +397,7 @@ typedef struct {
int mem_dump_start_address;
bool sidebar_open;
bool retro_achievements_sidebar_open;
bool retro_achievements_encore_mode;
se_keybind_state_t key;
se_controller_state_t controller;
se_game_info_t recently_loaded_games[SE_NUM_RECENT_PATHS];
Expand Down Expand Up @@ -2667,6 +2669,7 @@ static void se_emulate_single_frame(){

#ifdef ENABLE_RETRO_ACHIEVEMENTS
if (gui_state.settings.ra_needs_reload) {
rc_client_set_encore_mode_enabled(retro_achievements_get_client(), gui_state.retro_achievements_encore_mode);
if (retro_achievements_load_game()) {
gui_state.settings.ra_needs_reload = false;
}
Expand Down Expand Up @@ -6300,6 +6303,7 @@ void se_draw_menu_panel(){
static char line1[256];
static char line2[256];
bool hardcore = gui_state.settings.hardcore_mode;
bool encore = gui_state.retro_achievements_encore_mode;
snprintf(line1, 256, se_localize_and_cache("Logged in as %s"), user->display_name);
snprintf(line2, 256, se_localize_and_cache("Points: %d"), hardcore ? user->score : user->score_softcore);
se_boxed_image_triple_label(line1, line2, NULL, 0, ICON_FK_USER, image, 0, offset1, offset2, false);
Expand All @@ -6311,33 +6315,49 @@ void se_draw_menu_panel(){
rc_client_logout(retro_achievements_get_client());
}

bool draw_checkboxes_bool[5] = {
bool draw_checkboxes_bool[6] = {
gui_state.settings.hardcore_mode,
gui_state.settings.draw_notifications,
gui_state.settings.draw_progress_indicators,
gui_state.settings.draw_leaderboard_trackers,
gui_state.settings.draw_challenge_indicators,
gui_state.settings.only_one_notification,
};

if (encore) se_push_disabled();
if (se_checkbox("Enable Hardcore Mode", &draw_checkboxes_bool[0]))
{
rc_client_set_hardcore_enabled(retro_achievements_get_client(), draw_checkboxes_bool[0]);
}
if (encore) se_pop_disabled();

if (se_checkbox("Enable Encore Mode", &gui_state.retro_achievements_encore_mode))
{
se_reset_core();
}

se_checkbox("Enable Notifications", &draw_checkboxes_bool[1]);
if (!gui_state.settings.draw_notifications) se_push_disabled();
igIndent(15);
se_checkbox("Only one notification at a time", &draw_checkboxes_bool[5]);
igUnindent(15);
if (!gui_state.settings.draw_notifications) se_pop_disabled();
se_checkbox("Enable Progress Indicators",&draw_checkboxes_bool[2]);
if (!hardcore&&!encore) se_push_disabled();
se_checkbox("Enable Leaderboard Trackers",&draw_checkboxes_bool[3]);
if (!hardcore&&!encore) se_pop_disabled();
se_checkbox("Enable Challenge Indicators",&draw_checkboxes_bool[4]);

uint32_t* checkboxes[5] = {
uint32_t* checkboxes[6] = {
&gui_state.settings.hardcore_mode,
&gui_state.settings.draw_notifications,
&gui_state.settings.draw_progress_indicators,
&gui_state.settings.draw_leaderboard_trackers,
&gui_state.settings.draw_challenge_indicators,
&gui_state.settings.only_one_notification,
};

for (int i = 0; i < 5; i++)
for (int i = 0; i < 6; i++)
{
*checkboxes[i] = draw_checkboxes_bool[i];
}
Expand Down Expand Up @@ -7380,10 +7400,10 @@ static void frame(void) {
float top = menu_height;
float right = screen_x+screen_width/se_dpi_scale();
float bottom = height/se_dpi_scale();
float padding = screen_width * 0.02;
float padding = screen_width/se_dpi_scale()* 0.02;

if (gui_state.settings.draw_notifications)
retro_achievements_draw_notifications(left+padding,top+padding,screen_width);
retro_achievements_draw_notifications(left+padding,top+padding,screen_width/se_dpi_scale(),gui_state.settings.only_one_notification);

if (gui_state.settings.draw_progress_indicators)
retro_achievements_draw_progress_indicator(right-padding,top+padding);
Expand All @@ -7392,7 +7412,7 @@ static void frame(void) {
retro_achievements_draw_leaderboard_trackers(left+padding,bottom-padding);

if (gui_state.settings.draw_challenge_indicators)
retro_achievements_draw_challenge_indicators(right-padding,bottom-padding);
retro_achievements_draw_challenge_indicators(right-padding,bottom-padding,screen_width/se_dpi_scale());
#endif

for(int i=0;i<SAPP_MAX_TOUCHPOINTS;++i){
Expand Down Expand Up @@ -7625,6 +7645,10 @@ void se_load_settings(){
gui_state.settings.draw_progress_indicators=1;
gui_state.settings.draw_leaderboard_trackers=1;
gui_state.settings.draw_notifications=1;
bool is_mobile = gui_state.ui_type == SE_UI_ANDROID || gui_state.ui_type == SE_UI_IOS;
if(is_mobile){
gui_state.settings.only_one_notification=1;
}
}
if(gui_state.settings.gui_scale_factor<0.5)gui_state.settings.gui_scale_factor=1.0;
if(gui_state.settings.gui_scale_factor>4.0)gui_state.settings.gui_scale_factor=1.0;
Expand All @@ -7647,7 +7671,7 @@ void se_load_settings(){
}
#ifdef ENABLE_RETRO_ACHIEVEMENTS
bool is_mobile = gui_state.ui_type == SE_UI_ANDROID || gui_state.ui_type == SE_UI_IOS;
retro_achievements_initialize(&emu_state,gui_state.settings.hardcore_mode,is_mobile);
retro_achievements_initialize(&emu_state,gui_state.settings.hardcore_mode);
#endif
}
static void se_compute_draw_lcd_rect(float *lcd_render_w, float *lcd_render_h, bool *hybrid_nds){
Expand Down
106 changes: 75 additions & 31 deletions src/retro_achievements.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// TODO: use some tool to simulate slow internet connection and try this

#include "sokol_gfx.h"

extern "C" {
Expand Down Expand Up @@ -51,7 +49,6 @@ const float notification_start_seconds = 0.75f;
const float notification_start_secondary_text_seconds = notification_start_seconds + 1.25f;
const float notification_end_seconds = 4.0f;
const float notification_fade_seconds = notification_end_seconds - notification_start_seconds;
bool only_one_notification = false;
const float padding = 7;

struct atlas_t;
Expand Down Expand Up @@ -111,6 +108,7 @@ struct ra_notification_t
std::string submessage{};
std::string submessage2{};
float start_time = 0;
uint32_t leaderboard_id = 0;
};

struct ra_game_state_t
Expand Down Expand Up @@ -178,25 +176,23 @@ namespace
rc_client_get_user_game_summary(ra_state->rc_client, &summary);

ra_notification_t notification;
notification.title = "Loaded " + std::string(game->title) + "!";
notification.title = game->title;

int achievement_count = summary.num_core_achievements + summary.num_unofficial_achievements;
bool unofficial_enabled = rc_client_get_unofficial_enabled(ra_state->rc_client);
int achievement_count = summary.num_core_achievements;
int unlocked_achievement_count = summary.num_unlocked_achievements;

if (achievement_count == 0)
{
notification.submessage = "This game has no achievements";
}
else
{
notification.submessage = std::to_string(achievement_count) + " achievements, " +
std::to_string(summary.points_core) + " points";
notification.submessage2 = "You have earned " +
std::to_string(summary.num_unlocked_achievements) +
" achievements";
notification.submessage = "You have " + std::to_string(unlocked_achievement_count) + " of " + std::to_string(achievement_count) + " achievements unlocked.";
notification.submessage2 = "Points: " + std::to_string(summary.points_unlocked) + "/" + std::to_string(summary.points_core);
}

notification.tile = game_state->game_image;
notification.start_time = se_time();

game_state->notifications.push_back(notification);
}
Expand Down Expand Up @@ -308,7 +304,6 @@ namespace
uint8_t bucket = rc_achievement->bucket;
std::unique_lock<std::mutex> lock(game_state->mutex);
ra_achievement_t* achievement = retro_achievements_move_bucket(game_state, id, bucket);
notification->start_time = se_time();
notification->tile = atlas_add_tile_from_url(game_state->atlas_map, url.c_str());
achievement->tile = notification->tile;
game_state->notifications.push_back(*notification);
Expand Down Expand Up @@ -430,6 +425,44 @@ namespace
retro_achievements_achievement_triggered(game_state, event->achievement);
break;
}
case RC_CLIENT_EVENT_LEADERBOARD_SCOREBOARD: {
ra_game_state_ptr game_state = ra_state->game_state;

std::unique_lock<std::mutex> lock(game_state->mutex);

// Find the existing notification from leaderboard_submitted and modify it
// leaderboard_scoreboard event was added later down the line to provide more
// information about the leaderboard submission so this is why we have to do it this way
ra_notification_t* current_notification = nullptr;
for (auto& notification : game_state->notifications)
{
if (notification.leaderboard_id == event->leaderboard_scoreboard->leaderboard_id)
{
current_notification = &notification;
break;
}
}

if (current_notification)
{
std::string score_type = "score";
std::string score_type_caps = "Score";
std::string score = event->leaderboard_scoreboard->submitted_score;
if (score.find(':') != std::string::npos)
{
score_type = "time";
score_type_caps = "Time";
}

current_notification->submessage = score_type_caps + ": " +
std::string(event->leaderboard_scoreboard->submitted_score) + "\nYour best " + score_type + ": " +
std::string(event->leaderboard_scoreboard->best_score);
current_notification->submessage2 = ICON_FK_TROPHY " Ranked " +
std::to_string(event->leaderboard_scoreboard->new_rank) + " out of " +
std::to_string(event->leaderboard_scoreboard->num_entries);
}
break;
}
case RC_CLIENT_EVENT_LEADERBOARD_STARTED:
{
ra_game_state_ptr game_state = ra_state->game_state;
Expand All @@ -440,7 +473,6 @@ namespace
std::string("Leaderboard attempt started: ") + event->leaderboard->title;
notification.submessage = event->leaderboard->description;
notification.tile = game_state->game_image;
notification.start_time = se_time();
game_state->notifications.push_back(notification);
break;
}
Expand All @@ -454,7 +486,6 @@ namespace
std::string("Leaderboard attempt failed: ") + event->leaderboard->title;
notification.submessage = event->leaderboard->description;
notification.tile = game_state->game_image;
notification.start_time = se_time();
game_state->notifications.push_back(notification);
break;
}
Expand All @@ -468,7 +499,7 @@ namespace
notification.submessage = std::string(event->leaderboard->tracker_value) + " for " +
event->leaderboard->title;
notification.tile = game_state->game_image;
notification.start_time = se_time();
notification.leaderboard_id = event->leaderboard->id;
game_state->notifications.push_back(notification);
break;
}
Expand Down Expand Up @@ -560,7 +591,6 @@ namespace
std::to_string(summary.num_core_achievements) +
" achievements unlocked";
notification.tile = game_state->game_image;
notification.start_time = se_time();
game_state->notifications.push_back(notification);
break;
}
Expand Down Expand Up @@ -650,8 +680,14 @@ namespace
std::to_string(summary.num_unlocked_achievements) + "/" +
std::to_string(summary.num_core_achievements) + " achievements";
bool hardcore = rc_client_get_hardcore_enabled(ra_state->rc_client);
bool encore = rc_client_get_encore_mode_enabled(ra_state->rc_client);
auto hardcore_str = hardcore ? "Hardcore mode" : "Softcore mode";
uint32_t hardcore_color = hardcore ? 0xff0000ff : 0xff00ff00; // TODO: make me nicer
if (encore)
{
hardcore_str = "Encore mode";
hardcore_color = 0xff00ffff;
}
sg_image image = {SG_INVALID_ID};
atlas_tile_t* tile = game_state->game_image;
ImVec2 uv0 = ImVec2{0, 0};
Expand Down Expand Up @@ -790,11 +826,8 @@ extern "C" uint32_t retro_achievements_read_memory_callback(uint32_t address, ui
uint32_t num_bytes,
rc_client_t* client);

void retro_achievements_initialize(void* state, bool hardcore, bool is_mobile)
void retro_achievements_initialize(void* state, bool hardcore)
{
if (is_mobile)
only_one_notification = true;

ra_state = new ra_state_t((sb_emu_state_t*)state);
ra_state->rc_client = rc_client_create(retro_achievements_read_memory_callback,
retro_achievements_server_callback);
Expand Down Expand Up @@ -994,7 +1027,7 @@ float easeOutBack(float t) {
return 1 + c3 * (t1 * t1 * t1) + c1 * (t1 * t1);
}

void retro_achievements_draw_notifications(float left, float top, float screen_width)
void retro_achievements_draw_notifications(float left, float top, float screen_width, bool only_one_notification)
{
ra_game_state_ptr game_state = ra_state->game_state;

Expand All @@ -1015,6 +1048,10 @@ void retro_achievements_draw_notifications(float left, float top, float screen_w
{
ra_notification_t& notification = *it;

if (notification.start_time == 0) {
notification.start_time = se_time();
}

float time = se_time() - notification.start_time;

if (time >= notification_end_seconds)
Expand All @@ -1039,8 +1076,13 @@ void retro_achievements_draw_notifications(float left, float top, float screen_w
}

float easing = easeOutBack(multiplier);
if (easing < 0.97f)
continue;
if (easing < 0.97f) {
if (!only_one_notification) {
continue;
} else {
break;
}
}

#define ALPHA(x) ((uint32_t)(multiplier * x) << 24)

Expand Down Expand Up @@ -1270,7 +1312,7 @@ void retro_achievements_draw_leaderboard_trackers(float left, float bottom)
igPopFont();
}

void retro_achievements_draw_challenge_indicators(float right, float bottom)
void retro_achievements_draw_challenge_indicators(float right, float bottom, float screen_width)
{
ra_game_state_ptr game_state = ra_state->game_state;

Expand All @@ -1282,8 +1324,10 @@ void retro_achievements_draw_challenge_indicators(float right, float bottom)
if (game_state->challenges.empty())
return;

float x = right - 32 * 3 - padding * 2;
float y = bottom - 32 * 3 - padding * 2;
float padding_adj = 0.005 * screen_width;
float x = right - padding_adj;
float y = bottom - padding_adj * 2;
float image_size = screen_width * 0.04f;
int i = 0;

for (const auto& item : game_state->challenges)
Expand All @@ -1295,20 +1339,20 @@ void retro_achievements_draw_challenge_indicators(float right, float bottom)
{
atlas_uvs_t uvs = atlas_get_tile_uvs(challenge.tile);
ImDrawList_AddImage(igGetWindowDrawList(),
(ImTextureID)(intptr_t)id, ImVec2{x, y},
ImVec2{x + 32, y + 32},
(ImTextureID)(intptr_t)id, ImVec2{x-image_size, y-image_size},
ImVec2{x, y},
ImVec2{uvs.x1, uvs.y1},
ImVec2{uvs.x2, uvs.y2}, 0x80ffffff);
}

if (i++ % 3 != 2)
{
x += 32 + padding;
x -= image_size + padding_adj;
}
else
{
x = right - 32 * 3 - padding * 2;
y += 32 + padding;
x = right - padding_adj;
y -= image_size + padding_adj;
}

if (i == 9)
Expand Down
Loading

0 comments on commit 4bca574

Please sign in to comment.