diff --git a/src/retro_achievements.cpp b/src/retro_achievements.cpp index 086956c4e..25ef3d2a4 100644 --- a/src/retro_achievements.cpp +++ b/src/retro_achievements.cpp @@ -31,6 +31,7 @@ double se_time(); #include #include #include +#include #include #include #include @@ -80,6 +81,7 @@ struct ra_achievement_t uint32_t id; std::string title; std::string description; + uint8_t percentage = 0; }; struct ra_bucket_t @@ -747,6 +749,116 @@ namespace achievement->description.c_str(), ICON_FK_SPINNER, image, 0, uv0, uv1); } + + struct Ray { + float distance; + float velocity; + float angle; + float angle_velocity; + float alpha; + float alpha_velocity; + uint32_t color; + }; + + const int ray_count = 100; + static bool rays_initialized = false; + static Ray rays[ray_count]; + + if (!rays_initialized) { + for (int i = 0; i < ray_count; i++) { + rays[i].distance = 30 + static_cast(rand() % 30); + rays[i].velocity = 0.1f + static_cast(rand() % 100) / 100.0f; + rays[i].angle = static_cast(rand() % 360); + rays[i].angle_velocity = 0.1f + static_cast(rand() % 10) / 100.0f; + rays[i].alpha = 0.5f + static_cast(rand() % 5) / 10.0f; + rays[i].alpha_velocity = 0.1f + static_cast(rand() % 10) / 10.0f; + rays[i].color = 0x8ffffd; + } + rays_initialized = true; + } + + auto ig = igGetWindowDrawList(); + for (int i = 0; i < ray_count; i++) { + rays[i].angle += rays[i].angle_velocity; + if (rays[i].angle > 360) { + rays[i].angle -= 360; + } + rays[i].distance += rays[i].velocity; + if (rays[i].distance < 30) { + rays[i].distance = 30; + rays[i].velocity = 0.1f + static_cast(rand() % 10) / 10.0f; + } else if (rays[i].distance > 60) { + rays[i].distance = 60; + rays[i].velocity = -0.1f - static_cast(rand() % 10) / 10.0f; + } + rays[i].alpha += rays[i].alpha_velocity; + if (rays[i].alpha < 0.4f) { + rays[i].alpha = 0.4f; + rays[i].alpha_velocity = 0.0015f + static_cast(rand() % 10) / 1000.0f; + } else if (rays[i].alpha > 0.95f) { + rays[i].alpha = 0.95f; + rays[i].alpha_velocity = -0.0015f - static_cast(rand() % 10) / 1000.0f; + } + + float angle = rays[i].angle; + float distance = rays[i].distance; + float distance_2 = distance / 3; + + float distance_x = distance * cosf(angle * 0.0174533f); + float distance_y = distance * sinf(angle * 0.0174533f); + + if (distance_x > 40) { + distance_x = 40; + } else if (distance_x < -40) { + distance_x = -40; + } + + if (distance_y > 40) { + distance_y = 40; + } else if (distance_y < -40) { + distance_y = -40; + } + + ImVec2 center = {100, 100}; + ImVec2 target = ImVec2{center.x + distance_x, center.y + distance_y}; + center.x += distance_x / 2.3; + center.y += distance_y / 2.3; + auto vert_start = ig->VtxBuffer.Size; + ImDrawList_PathLineTo(ig, center); + // Create rotated polygon to target + // need 2 more points for the left and right edges + ImVec2 target_1 = ImVec2{center.x + distance_2 * cosf((angle + 70) * 0.0174533f), + center.y + distance_2 * sinf((angle + 70) * 0.0174533f)}; + ImVec2 target_2 = ImVec2{center.x + distance_2 * cosf((angle - 70) * 0.0174533f), + center.y + distance_2 * sinf((angle - 70) * 0.0174533f)}; + ImDrawList_PathLineTo(ig, target_1); + ImDrawList_PathLineTo(ig, target); + ImDrawList_PathLineTo(ig, target_2); + ImDrawList_PathFillConvex(ig, 0); + + ImDrawVert* vert = ig->VtxBuffer.Data + vert_start; + vert->col = rays[i].color | (int(rays[i].alpha * 255) << 24); + vert++; + vert->col = 0; + vert++; + vert->col = 0; + vert++; + vert->col = 0; + } + int j = 0; + const auto& achievement = bucket->achievements[j]; + sg_image image = {SG_INVALID_ID}; + ImVec2 uv0, uv1; + if (bucket->achievements[j]->tile) + { + atlas_tile_t* tile = bucket->achievements[j]->tile; + uv0 = ImVec2{tile->x1, tile->y1}; + uv1 = ImVec2{tile->x2, tile->y2}; + image.id = tile->atlas_id; + } + ImVec2 center = {100, 100}; + igSetCursorPos(ImVec2{center.x - 25, center.y - 50}); + igImage((ImTextureID)(intptr_t)image.id, ImVec2{50, 50}, uv0, uv1, ImVec4{1, 1, 1, 1}, ImVec4{0, 0, 0, 0}); } } } // namespace @@ -778,6 +890,7 @@ void ra_achievement_list_t::initialize(ra_game_state_ptr game_state, buckets[i].achievements[j]->id = list->buckets[i].achievements[j]->id; buckets[i].achievements[j]->title = list->buckets[i].achievements[j]->title; buckets[i].achievements[j]->description = list->buckets[i].achievements[j]->description; + buckets[i].achievements[j]->percentage = list->buckets[i].achievements[j]->measured_percent; const rc_client_achievement_t* achievement = list->buckets[i].achievements[j]; if (rc_client_achievement_get_image_url(achievement, achievement->state, &url[0],