Skip to content

Commit

Permalink
Refactor to use texture atlas for achievements
Browse files Browse the repository at this point in the history
  • Loading branch information
OFFTKP committed Feb 21, 2024
1 parent ab893ff commit a324d68
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 77 deletions.
81 changes: 26 additions & 55 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,18 +518,18 @@ typedef struct se_ra_tracker_node{
}se_ra_tracker_node_t;
typedef struct se_ra_challenge_indicator_node{
uint32_t id;
sg_image image;
ra_image image;
struct se_ra_challenge_indicator_node* next;
} se_ra_challenge_indicator_node_t;
typedef struct{
char username[256];
char password[256];
sg_image image;
sg_image** achievement_images;
ra_image image;
ra_image** achievement_images;
// TODO: make widgets that use these lists and progress indicator
se_ra_tracker_node_t* tracker_list;
se_ra_challenge_indicator_node_t* challenge_indicator_list;
sg_image progress_indicator_image;
ra_image progress_indicator_image;
bool progress_indicator_shown;
char measured_progress[24];
mutex_t mutex; // for synchronization between ui thread and threads opened by http requests
Expand Down Expand Up @@ -1733,41 +1733,14 @@ static uint32_t se_ra_read_memory_callback(uint32_t address, uint8_t* buffer, ui
}
return 0;
}
static void se_ra_load_image_callback(const uint8_t* pixel_data, size_t image_size, int width, int height, void* user_data){
sg_image* achievement_image=(sg_image*)user_data;
if(pixel_data){
sg_image_data im_data={0};
im_data.subimage[0][0].ptr = pixel_data;
im_data.subimage[0][0].size = width*height*4;
sg_image_desc desc={
.type= SG_IMAGETYPE_2D,
.render_target= false,
.width= width,
.height= height,
.num_slices= 1,
.num_mipmaps= 1,
.usage= SG_USAGE_IMMUTABLE,
.pixel_format= SG_PIXELFORMAT_RGBA8,
.sample_count= 1,
.min_filter= SG_FILTER_LINEAR,
.mag_filter= SG_FILTER_LINEAR,
.wrap_u= SG_WRAP_CLAMP_TO_EDGE,
.wrap_v= SG_WRAP_CLAMP_TO_EDGE,
.wrap_w= SG_WRAP_CLAMP_TO_EDGE,
.border_color= SG_BORDERCOLOR_OPAQUE_BLACK,
.max_anisotropy= 1,
.min_lod= 0.0f,
.max_lod= 1e9f,
.data= im_data
};
*achievement_image = sg_make_image(&desc);
}else{
printf("[rcheevos]: failed to load game image\n");
}
static void se_ra_load_image_callback(ra_image image, void* user_data){
// TODO: if this works, remove the callback and instead of user_data pass ra_image*
ra_image* destination = (ra_image*)user_data;
*destination = image;
}
static void se_ra_game_cleanup(){
if(ra_info.image.id != SG_INVALID_ID){
se_free_image_deferred(ra_info.image);
sg_destroy_image((sg_image){ra_info.image.id});
ra_info.image.id = SG_INVALID_ID;
}
rc_client_achievement_list_t* list = ra_get_achievements();
Expand All @@ -1776,11 +1749,6 @@ static void se_ra_game_cleanup(){
{
if(ra_info.achievement_images[i] != NULL)
{
for (int j = 0; j < list->buckets[i].num_achievements; j++)
{
if(ra_info.achievement_images[i][j].id != SG_INVALID_ID)
se_free_image_deferred(ra_info.achievement_images[i][j]);
}
free(ra_info.achievement_images[i]);
}
}
Expand Down Expand Up @@ -1822,12 +1790,12 @@ static void se_ra_load_game_callback(int result, const char* error_message, rc_c
mutex_lock(ra_info.mutex);
ra_invalidate_achievements();
rc_client_achievement_list_t* list = ra_get_achievements();
ra_info.achievement_images = (sg_image**)malloc(sizeof(sg_image*)*list->num_buckets);
ra_info.achievement_images = (ra_image**)malloc(sizeof(ra_image*)*list->num_buckets);
for (int i = 0; i < list->num_buckets; i++)
{
uint32_t num_achievements=list->buckets[i].num_achievements;
ra_info.achievement_images[i] = (sg_image*)malloc(sizeof(sg_image)*num_achievements);
memset(ra_info.achievement_images[i], 0, sizeof(sg_image)*num_achievements);
ra_info.achievement_images[i] = (ra_image*)malloc(sizeof(ra_image)*num_achievements);
memset(ra_info.achievement_images[i], 0, sizeof(ra_image)*num_achievements);
for (int j = 0; j < num_achievements; j++)
{
char url[512];
Expand Down Expand Up @@ -4663,7 +4631,7 @@ bool se_selectable_with_box(const char * first_label, const char* second_label,
return clicked;
}

void se_boxed_image_dual_label(const char * first_label, const char* second_label, const char* box, sg_image* image, int reduce_width){
void se_boxed_image_dual_label(const char * first_label, const char* second_label, const char* box, sg_image image, int reduce_width, ImVec2 uv0, ImVec2 uv1){
ImVec2 win_min,win_sz,win_max;
win_min.x=0;
win_min.y=0; // content boundaries min (roughly (0,0)-Scroll), in window coordinates
Expand Down Expand Up @@ -4699,7 +4667,7 @@ void se_boxed_image_dual_label(const char * first_label, const char* second_labe
igSetCursorPosY(igGetCursorPosY()-5);
se_text_disabled(second_label);
igSetCursorPos(curr_pos);
if(image)igImageButton((ImTextureID)(intptr_t)image->id,(ImVec2){box_w,box_h},(ImVec2){0,0},(ImVec2){1,1},0,(ImVec4){1,1,1,1},(ImVec4){1,1,1,1});
if(image.id != SG_INVALID_ID)igImageButton((ImTextureID)(intptr_t)image.id,(ImVec2){box_w,box_h},uv0,uv1,0,(ImVec4){1,1,1,1},(ImVec4){1,1,1,1});
else se_text_centered_in_box((ImVec2){0,0}, (ImVec2){box_w,box_h},box);
igDummy((ImVec2){1,1});
igSetCursorPos(next_pos);
Expand Down Expand Up @@ -6367,16 +6335,16 @@ void se_draw_menu_panel(){
}else {
const rc_client_game_t* game = rc_client_get_game_info(ra_get_client());
ImVec2 pos;
sg_image * image = NULL;
sg_image image;
const char* play_string = "No Game Loaded";
char line1[256];
char line2[256];
snprintf(line1,256,se_localize_and_cache("Logged in as %s"),user->display_name);
if(game){
if(ra_info.image.id!=SG_INVALID_ID)image=&ra_info.image;
image.id=ra_info.image.id;
snprintf(line2,256,se_localize_and_cache("Playing: %s"),game->title);
}else snprintf(line2,256,"%s",se_localize_and_cache("No Game Loaded"));
se_boxed_image_dual_label(line1,line2, ICON_FK_TROPHY, image, 0);
se_boxed_image_dual_label(line1,line2, ICON_FK_TROPHY, image, 0, (ImVec2){0,0}, (ImVec2){1,1});
if(se_button(ICON_FK_SIGN_OUT " Logout", (ImVec2){0,0})){
char login_info_path[SB_FILE_PATH_SIZE];
snprintf(login_info_path,SB_FILE_PATH_SIZE,"%sra_token.txt",se_get_pref_path());
Expand All @@ -6389,14 +6357,17 @@ void se_draw_menu_panel(){
for (int i = 0; i < list->num_buckets; i++){
se_text(ICON_FK_LOCK " %s",list->buckets[i].label);
for (int j = 0; j < list->buckets[i].num_achievements; j++){
sg_image * image = NULL;
// TODO: some games need a lot of images for achievements - instead of creating all sg_images at once, we should create them on demand
// or at least increase the sg_images limit.
if(ra_info.achievement_images && ra_info.achievement_images[i] && ra_info.achievement_images[i][j].id!=SG_INVALID_ID){
image = &ra_info.achievement_images[i][j];
sg_image image;
ImVec2 uv0, uv1;
if(ra_info.achievement_images && ra_info.achievement_images[i]){
image.id = ra_info.achievement_images[i][j].id;
float size = ra_get_atlas_size();
ra_image* ra_image = &ra_info.achievement_images[i][j];
uv0 = (ImVec2){ (float)ra_image->offset_x / size, (float)ra_image->offset_y / size };
uv1 = (ImVec2){ (float)(ra_image->offset_x + ra_image->width) / size, (float)(ra_image->offset_y + ra_image->height) / size };
}
se_boxed_image_dual_label(list->buckets[i].achievements[j]->title,
list->buckets[i].achievements[j]->description, ICON_FK_SPINNER, image, 0);
list->buckets[i].achievements[j]->description, ICON_FK_SPINNER, image, 0, uv0, uv1);
}
}
}
Expand Down
Loading

0 comments on commit a324d68

Please sign in to comment.