From e78dd90eb1d0d71332dc2b4d0a11b70ff7ffa7fe Mon Sep 17 00:00:00 2001 From: Lucy Date: Mon, 16 Sep 2024 05:52:01 -0400 Subject: [PATCH] [PORT] GetFlatIcon improvements (#3422) * GetFlatIcon improvements. (#86077) ## About The Pull Request I've added an get_icon_dimensions() call to a place where `icon.Width()` and `icon.Height()` are called twice each. get_icon_dimensions uses a cache of values so follow-up getFlatIcon() calls with the same current icon won't have it call`icon.Width()` or `icon.Height()` which aren't exactly cheap procs iirc. I've also removed two of the fairly expensive `length(icon_states(icon(curicon, curstate, dir)))` checks, because all icon states have NORTH, EAST and WEST directions except 1-dir icon_states which are always facing SOUTH. That is, unless there is some farfetched procgenned bullshit that's probably not even possible and worth checking against. We'll see. ## Why It's Good For The Game GetFlatIcon is a very expensive proc, every bit of improvement is worth it. ## Changelog N/A * backport some other getFlatIcon improvements so it compiles --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- code/__HELPERS/icons.dm | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 0a743ee3a43d..54892b25294b 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -730,6 +730,10 @@ world } \ current_layer = base_layer + appearance.layer + current_layer / 1000; \ } \ + /* If we are using topdown rendering, chop that part off so things layer together as expected */ \ + if((current_layer >= TOPDOWN_LAYER && current_layer < EFFECTS_LAYER) || current_layer > TOPDOWN_LAYER + EFFECTS_LAYER) { \ + current_layer -= TOPDOWN_LAYER; \ + } \ for (var/index_to_compare_to in 1 to layers.len) { \ var/compare_to = layers[index_to_compare_to]; \ if (current_layer < layers[compare_to]) { \ @@ -741,9 +745,10 @@ world } var/static/icon/flat_template = icon('icons/blanks/32x32.dmi', "nothing") + var/icon/flat = icon(flat_template) if(!appearance || appearance.alpha <= 0) - return icon(flat_template) + return flat if(start) if(!defdir) @@ -771,15 +776,20 @@ world var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have - //Try to remove/optimize this section ASAP, CPU hog. - //Determines if there's directionals. - if(render_icon && curdir != SOUTH) - if ( - !length(icon_states(icon(curicon, curstate, NORTH))) \ - && !length(icon_states(icon(curicon, curstate, EAST))) \ - && !length(icon_states(icon(curicon, curstate, WEST))) \ - ) - base_icon_dir = SOUTH + if(render_icon) + //Try to remove/optimize this section if you can, it's a CPU hog. + //Determines if there're directionals. + if (curdir != SOUTH) + // icon states either have 1, 4 or 8 dirs. We only have to check + // one of NORTH, EAST or WEST to know that this isn't a 1-dir icon_state since they just have SOUTH. + if(!length(icon_states(icon(curicon, curstate, NORTH)))) + base_icon_dir = SOUTH + + var/list/icon_dimensions = get_icon_dimensions(curicon) + var/icon_width = icon_dimensions["width"] + var/icon_height = icon_dimensions["height"] + if(icon_width != 32 || icon_height != 32) + flat.Scale(icon_width, icon_height) if(!base_icon_dir) base_icon_dir = curdir @@ -787,7 +797,6 @@ world var/curblend = appearance.blend_mode || defblend if(appearance.overlays.len || appearance.underlays.len) - var/icon/flat = icon(flat_template) // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed var/list/layers = list() var/image/copy