package de.geolykt.starloader.api.event.lifecycle; import java.util.Objects; import org.jetbrains.annotations.ApiStatus.AvailableSince; import org.jetbrains.annotations.ApiStatus.Internal; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.g2d.PixmapPacker; import de.geolykt.starloader.api.event.Event; import de.geolykt.starloader.api.resource.DataFolderProvider; import de.geolykt.starloader.impl.gui.s2d.PixmapAtlas; /** * Lifecycle event which is fired once the main texture atlas is being generated by the game. * *
Although texture atlas generation used to be handled by vanilla galimulator code for a long time, * the atlas is now being generated by SLAPI using the {@link PixmapPacker} class. As a side-effect, * texture atlas generation now only happens in-memory and the atlas is similarly retained only in memory. * This means that the "game.atlas" file is now no longer being written to, nor read when using SLAPI * without any further modifications. * *
This event exists to allow mods to submit their own textures to the main texture atlas. * Submitted textures can be obtained through the {@link AtlasPackedEvent}. * *
Pages within the main texture atlas are in vanilla galimulator 1024 x 1024 pixels in size. * However, SLAPI increases the default size to 4096 x 4096 pixels, though that size might * change in the future. Anyhow, that increased page size means that by default the first page * will be pretty sparsely populated by default, so mods should not hesitate adding their own * larger-ish sprites to it. * *
Without any further modifications all *.png files from the 'sprites' directory in the * game's {@link DataFolderProvider 'data'} directory get included in the main texture atlas. * *
The exact point in time in which the method is getting invoked is undefined, * though it will be called before any graphical ticking occurs, and by extension before * any ticking whatsoever. It will also be called before {@link AtlasPackedEvent}. * This method will only be called once, changes will be considered an API behaviour * break and will not happen on the same major version, as per SemVer. * * @since 2.0.0-a20260206 * @apiNote Keep in mind that the constructor of Event classes are in general not public APIs, * unless specified otherwise. This also means that subclassing this class is not supported when * it comes to preserving ABI constraints. */ @AvailableSince("2.0.0-a20260206") public class AtlasPackingEvent extends Event { @NotNull private final PixmapPacker packer; /** * This constructor is not public API, do not invoke manually. * * @param packer The {@link PixmapPacker} instance. * @since 2.0.0-a20260206 */ @Internal @Contract(pure = true, value = "null -> fail") public AtlasPackingEvent(@NotNull PixmapPacker packer) { this.packer = Objects.requireNonNull(packer); } /** * Packs a given {@link Pixmap} texture under the given path. * *
A null path is explicitly not supported by this method. * *
This method is agnostic to the version of libGDX being used. * Under libGDX, the {@link PixmapPacker#pack(String, Pixmap)} may have * a different return type depending on the version of libGDX used. * * @param path The path of the {@link Pixmap}. Used later on to query the texture from the region. * @param texture The {@link Pixmap} texture to pack. * @return The current {@link AtlasPackingEvent} instance, for chaining. * @since 2.0.0-a20260206 * @see PixmapPacker#pack(String, Pixmap) * @implSpec This method does not work for {@link Pixmap} objects that are * equal to or larger than the underlying texture of the {@link PixmapPacker}. * In other words, this method will fail to pack textures that are larger than, * or equal to in size of 4096x4096 pixels. It is recommended for the provided * {@link Pixmap} to be 2048 by 2048 in size at its largest. */ @AvailableSince("2.0.0-a20260206") @Contract(mutates = "this", pure = false, value = "null, _ -> fail; _, null -> fail; !null, !null -> this") @NotNull public AtlasPackingEvent packTexture(@NotNull String path, @NotNull Pixmap texture) { PixmapAtlas.libGDXAgnosticsPack(this.packer, Objects.requireNonNull(path, "'path' may not be null"), Objects.requireNonNull(texture, "'texture' may not be null")); return this; } }