Use itch.io's stillCoverUrl for animated GIF covers so those games still get boxart (Godot can't decode GIFs)

This commit is contained in:
Jose Falanga 2026-08-06 18:46:02 -03:00
parent a9371bdbc2
commit 9cd4cb32e3
2 changed files with 18 additions and 6 deletions

View file

@ -143,13 +143,15 @@ func _load_library(caching_flags: int = Cache.FLAGS.LOAD | Cache.FLAGS.SAVE) ->
## boxart directory (user://boxart/local/). The built-in "local" BoxArtProvider
## picks those files up by <game name>-<layout>.png, so games show their real
## cover instead of the placeholder. Covers are only downloaded once (the task
## bails out if a layout file already exists).
## bails out if a layout file already exists). For games with an animated GIF
## cover, itch.io provides a stillCoverUrl (a static frame, served as PNG) which
## we prefer, since Godot has no GIF decoder.
func _queue_boxart(items: Array) -> void:
for i in items:
var item: LibraryLaunchItem = i
var game: Dictionary = item.metadata.get("game", {})
var title: String = game.get("title", "")
var cover_url: String = game.get("coverUrl", "")
var cover_url := _cover_url(game)
if title.is_empty() or cover_url.is_empty():
continue
if FileAccess.file_exists("/".join([_boxart_dir(), title + "-portrait.png"])):
@ -163,7 +165,7 @@ func _queue_boxart(items: Array) -> void:
## single image is reused for portrait, landscape, banner and logo.
func _ensure_boxart(game: Dictionary) -> void:
var title: String = game.get("title", "")
var cover_url: String = game.get("coverUrl", "")
var cover_url := _cover_url(game)
if title.is_empty() or cover_url.is_empty():
return
var dir := _boxart_dir()
@ -175,8 +177,8 @@ func _ensure_boxart(game: Dictionary) -> void:
logger.warn("Unable to download cover art for '" + title + "'")
return
if not _is_raster_image(body):
# OGPU's local provider only loads png/jpg; animated gif covers (rare)
# can't be rendered, so skip them rather than write an unloadable file.
# OGPU's local provider only loads png/jpg. If itch.io didn't give us a
# still for an animated cover, skip rather than write an unloadable file.
logger.warn("Skipping unsupported cover format for '" + title + "'")
return
@ -194,6 +196,16 @@ func _boxart_dir() -> String:
return ProjectSettings.globalize_path("user://boxart/local")
## itch.io exposes stillCoverUrl for games whose cover is an animated GIF: a
## static frame that the CDN serves as PNG. Prefer it over coverUrl so those
## games still get art (Godot can't decode GIFs at runtime).
func _cover_url(game: Dictionary) -> String:
var still: String = game.get("stillCoverUrl", "")
if not still.is_empty():
return still
return game.get("coverUrl", "")
## Blocking HTTPS GET of a single cover image, for use on a background thread.
func _download_cover(url: String) -> PackedByteArray:
var parts := url.split("/")

View file

@ -1,7 +1,7 @@
{
"plugin.id": "itch",
"plugin.name": "itch.io",
"plugin.version": "0.1.4",
"plugin.version": "0.1.5",
"plugin.min-api-version": "1.1.0",
"plugin.link": "https://github.com/YOUR_USERNAME/OpenGamepadUI-itch",
"plugin.source": "https://github.com/YOUR_USERNAME/OpenGamepadUI-itch",