From 13597bc40200c04efb844d53a0d1aa42395c1f0f Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 21 Sep 2026 15:15:33 -0400 Subject: [PATCH] Begin refactoring mod sprite packing --- .../src/mindustry/ctype/UnlockableContent.java | 10 +++++----- core/src/mindustry/game/EventType.java | 8 ++++---- .../{MultiPacker.java => PackContext.java} | 5 ++--- core/src/mindustry/mod/DataManager.java | 4 ++-- core/src/mindustry/mod/Mod.java | 2 +- core/src/mindustry/mod/Mods.java | 6 +++--- core/src/mindustry/type/Item.java | 4 ++-- core/src/mindustry/type/SectorPreset.java | 4 ++-- core/src/mindustry/type/StatusEffect.java | 4 ++-- core/src/mindustry/type/UnitType.java | 4 ++-- core/src/mindustry/world/Block.java | 9 ++------- .../world/blocks/environment/Floor.java | 4 ++-- .../world/blocks/environment/OreBlock.java | 2 +- .../blocks/environment/ShallowLiquid.java | 2 +- .../src/mindustry/desktop/DesktopLauncher.java | 18 ------------------ gradle.properties | 2 +- tools/build.gradle | 2 +- tools/src/mindustry/tools/Generators.java | 5 ----- tools/src/mindustry/tools/ImagePacker.java | 2 -- 19 files changed, 33 insertions(+), 64 deletions(-) rename core/src/mindustry/graphics/{MultiPacker.java => PackContext.java} (94%) diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java index d11aeef93b..de59e6a00e 100644 --- a/core/src/mindustry/ctype/UnlockableContent.java +++ b/core/src/mindustry/ctype/UnlockableContent.java @@ -160,15 +160,15 @@ public abstract class UnlockableContent extends MappableContent{ * No regions are loaded at this point; grab pixmaps from the packer. * */ @CallSuper - public void createIcons(MultiPacker packer){ + public void packSprites(PackContext packer){ } - protected void makeOutline(MultiPacker packer, TextureRegion region, boolean makeNew, Color outlineColor, int outlineRadius){ + protected void makeOutline(PackContext packer, TextureRegion region, boolean makeNew, Color outlineColor, int outlineRadius){ makeOutline(packer, region, makeNew, outlineColor, outlineRadius, 0); } - protected void makeOutline(MultiPacker packer, TextureRegion region, boolean makeNew, Color outlineColor, int outlineRadius, int padding){ + protected void makeOutline(PackContext packer, TextureRegion region, boolean makeNew, Color outlineColor, int outlineRadius, int padding){ if(region instanceof AtlasRegion at && region.found()){ String name = at.name; if(!makeNew || !packer.has(name + "-outline")){ @@ -184,7 +184,7 @@ public abstract class UnlockableContent extends MappableContent{ } } - protected void makeOutline(MultiPacker packer, TextureRegion region, String name, Color outlineColor, int outlineRadius){ + protected void makeOutline(PackContext packer, TextureRegion region, String name, Color outlineColor, int outlineRadius){ if(region.found() && packer.registerOutlined(name)){ PixmapRegion base = packer.get(region); var result = Pixmaps.outline(base, outlineColor, outlineRadius); @@ -194,7 +194,7 @@ public abstract class UnlockableContent extends MappableContent{ } } - protected void makeOutline(MultiPacker packer, TextureRegion region, String name, Color outlineColor){ + protected void makeOutline(PackContext packer, TextureRegion region, String name, Color outlineColor){ makeOutline(packer, region, name, outlineColor, 4); } diff --git a/core/src/mindustry/game/EventType.java b/core/src/mindustry/game/EventType.java index 0ee3a942b7..80cb12e743 100644 --- a/core/src/mindustry/game/EventType.java +++ b/core/src/mindustry/game/EventType.java @@ -6,7 +6,7 @@ import arc.util.*; import mindustry.core.GameState.*; import mindustry.ctype.*; import mindustry.gen.*; -import mindustry.graphics.MultiPacker; +import mindustry.graphics.PackContext; import mindustry.mod.data.*; import mindustry.net.*; import mindustry.net.Packets.*; @@ -88,10 +88,10 @@ public class EventType{ public static class ContentInitEvent{} /** Called *after* all content has been added to the atlas, but before its pixmaps are disposed. */ public static class AtlasPackEvent{ - public final MultiPacker multiPacker; + public final PackContext packContext; - public AtlasPackEvent(MultiPacker multiPacker){ - this.multiPacker = multiPacker; + public AtlasPackEvent(PackContext packContext){ + this.packContext = packContext; } } /** Called *after* all mod content has been loaded, but before it has been initialized. */ diff --git a/core/src/mindustry/graphics/MultiPacker.java b/core/src/mindustry/graphics/PackContext.java similarity index 94% rename from core/src/mindustry/graphics/MultiPacker.java rename to core/src/mindustry/graphics/PackContext.java index a0e207d4e1..24e8f1d259 100644 --- a/core/src/mindustry/graphics/MultiPacker.java +++ b/core/src/mindustry/graphics/PackContext.java @@ -7,12 +7,11 @@ import arc.struct.*; import arc.util.*; import arc.util.Log.*; -//TODO: this needs to pack to a texture array -public class MultiPacker implements Disposable{ +public class PackContext implements Disposable{ private PixmapPacker packer; private ObjectSet outlined = new ObjectSet<>(); - public MultiPacker(int size){ + public PackContext(int size){ if(size > 0){ packer = new PixmapPacker(size, size, 2, true); } diff --git a/core/src/mindustry/mod/DataManager.java b/core/src/mindustry/mod/DataManager.java index 0c72f2d7c2..922d5c7e78 100644 --- a/core/src/mindustry/mod/DataManager.java +++ b/core/src/mindustry/mod/DataManager.java @@ -80,7 +80,7 @@ public class DataManager{ UnlockableContent[] currentContent = {null}; String[] currentHash = {null}; - MultiPacker saver = new MultiPacker(0){ + PackContext saver = new PackContext(0){ @Override public void add(String name, PixmapRegion region, int[] splits, int[] pads){ try{ @@ -137,7 +137,7 @@ public class DataManager{ currentHash[0] = hashes.get(content); try{ - content.createIcons(saver); + content.packSprites(saver); }catch(Throwable e){ Log.err(e); } diff --git a/core/src/mindustry/mod/Mod.java b/core/src/mindustry/mod/Mod.java index e570b74191..4c6e9ece11 100644 --- a/core/src/mindustry/mod/Mod.java +++ b/core/src/mindustry/mod/Mod.java @@ -28,7 +28,7 @@ public abstract class Mod{ } /** Called during sprite packing to allow adding custom textures */ - public void packSprites(MultiPacker packer){ + public void packSprites(PackContext packer){ } diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index 45bedb04ca..2721332fdc 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -156,7 +156,7 @@ public class Mods implements Loadable{ long startTime = Time.millis(); //TODO this should estimate sprite sizes per page - MultiPacker packer = new MultiPacker(4096); + PackContext packer = new PackContext(4096); var textureResize = new ObjectFloatMap(); int[] totalSprites = {0}; //all packing tasks to await @@ -244,7 +244,7 @@ public class Mods implements Loadable{ u.load(); u.loadIcon(); if(u.generateIcons && !c.minfo.mod.meta.pregenerated){ - u.createIcons(packer); + u.packSprites(packer); } } }); @@ -301,7 +301,7 @@ public class Mods implements Loadable{ } } - private void packSprites(MultiPacker packer, Seq sprites, LoadedMod mod, boolean prefix, Seq> tasks, ObjectFloatMap textureResize){ + private void packSprites(PackContext packer, Seq sprites, LoadedMod mod, boolean prefix, Seq> tasks, ObjectFloatMap textureResize){ boolean bleed = Core.settings.getBool("linear", true) && !mod.meta.pregenerated; float textureScale = mod.meta.texturescale; diff --git a/core/src/mindustry/type/Item.java b/core/src/mindustry/type/Item.java index 3705405aa0..46ee7291ff 100644 --- a/core/src/mindustry/type/Item.java +++ b/core/src/mindustry/type/Item.java @@ -119,8 +119,8 @@ public class Item extends UnlockableContent implements Senseable{ } @Override - public void createIcons(MultiPacker packer){ - super.createIcons(packer); + public void packSprites(PackContext packer){ + super.packSprites(packer); //create transitions if(frames > 0 && transitionFrames > 0){ diff --git a/core/src/mindustry/type/SectorPreset.java b/core/src/mindustry/type/SectorPreset.java index 03f5a45110..531806897e 100644 --- a/core/src/mindustry/type/SectorPreset.java +++ b/core/src/mindustry/type/SectorPreset.java @@ -119,8 +119,8 @@ public class SectorPreset extends UnlockableContent{ } @Override - public void createIcons(MultiPacker packer){ - super.createIcons(packer); + public void packSprites(PackContext packer){ + super.packSprites(packer); if(outline && Core.atlas.has("sector-" + name)){ makeOutline(packer, Core.atlas.find("sector-" + name), false, outlineColor, outlineRadius, outlineRadius); diff --git a/core/src/mindustry/type/StatusEffect.java b/core/src/mindustry/type/StatusEffect.java index 0df8f57742..ae689e9a21 100644 --- a/core/src/mindustry/type/StatusEffect.java +++ b/core/src/mindustry/type/StatusEffect.java @@ -231,8 +231,8 @@ public class StatusEffect extends UnlockableContent{ } @Override - public void createIcons(MultiPacker packer){ - super.createIcons(packer); + public void packSprites(PackContext packer){ + super.packSprites(packer); if(outline){ makeOutline(packer, uiIcon, false, Pal.gray, 3); diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index da096fa654..3f98e4bf30 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -1219,8 +1219,8 @@ public class UnitType extends UnlockableContent implements Senseable{ } @Override - public void createIcons(MultiPacker packer){ - super.createIcons(packer); + public void packSprites(PackContext packer){ + super.packSprites(packer); if(constructor == null) throw new IllegalArgumentException("No constructor set up for unit '" + name + "', add this argument to your units field: `constructor = UnitEntity::create`"); diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index de85946388..c6552e6693 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -977,11 +977,6 @@ public class Block extends UnlockableContent implements Senseable{ } } - /** @return special icons to outline and save with an -outline variant. Vanilla only. */ - public TextureRegion[] makeIconRegions(){ - return new TextureRegion[0]; - } - protected TextureRegion[] icons(){ //use team region in vanilla team blocks TextureRegion r = variants > 0 ? Core.atlas.find(name + "1") : region; @@ -1551,8 +1546,8 @@ public class Block extends UnlockableContent implements Senseable{ } @Override - public void createIcons(MultiPacker packer){ - super.createIcons(packer); + public void packSprites(PackContext packer){ + super.packSprites(packer); if(!synthetic()){ PixmapRegion image = packer.get(fullIcon); diff --git a/core/src/mindustry/world/blocks/environment/Floor.java b/core/src/mindustry/world/blocks/environment/Floor.java index ed270ed64f..02bbed993a 100644 --- a/core/src/mindustry/world/blocks/environment/Floor.java +++ b/core/src/mindustry/world/blocks/environment/Floor.java @@ -221,8 +221,8 @@ public class Floor extends Block{ } @Override - public void createIcons(MultiPacker packer){ - super.createIcons(packer); + public void packSprites(PackContext packer){ + super.packSprites(packer); if(blendGroup != this){ return; diff --git a/core/src/mindustry/world/blocks/environment/OreBlock.java b/core/src/mindustry/world/blocks/environment/OreBlock.java index d07fa1c39f..c5ebf6e031 100644 --- a/core/src/mindustry/world/blocks/environment/OreBlock.java +++ b/core/src/mindustry/world/blocks/environment/OreBlock.java @@ -41,7 +41,7 @@ public class OreBlock extends OverlayFloor{ @Override @OverrideCallSuper - public void createIcons(MultiPacker packer){ + public void packSprites(PackContext packer){ for(int i = 0; i < variants; i++){ //use name (e.g. "ore-copper1"), fallback to "copper1" as per the old naming system PixmapRegion shadow = Core.atlas.has(name + (i + 1)) ? diff --git a/core/src/mindustry/world/blocks/environment/ShallowLiquid.java b/core/src/mindustry/world/blocks/environment/ShallowLiquid.java index 1317b9532c..42c559eeb6 100644 --- a/core/src/mindustry/world/blocks/environment/ShallowLiquid.java +++ b/core/src/mindustry/world/blocks/environment/ShallowLiquid.java @@ -30,7 +30,7 @@ public class ShallowLiquid extends Floor{ } @Override - public void createIcons(MultiPacker packer){ + public void packSprites(PackContext packer){ //TODO might not be necessary at all, but I am not sure yet //super.createIcons(packer); diff --git a/desktop/src/mindustry/desktop/DesktopLauncher.java b/desktop/src/mindustry/desktop/DesktopLauncher.java index 715ba175ec..aca647a4df 100644 --- a/desktop/src/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/mindustry/desktop/DesktopLauncher.java @@ -46,7 +46,6 @@ public class DesktopLauncher extends ClientLauncher{ Vars.loadLogger(); Vars.loadFileLogger(new Fi(Version.isSteam ? "saves" : OS.getAppDataDirectoryString(appName)).child("last_log.txt")); - check32Bit(); checkJavaVersion(); new SdlApplication(new DesktopLauncher(arg), new SdlConfig(){{ @@ -129,23 +128,6 @@ public class DesktopLauncher extends ClientLauncher{ } } - static void check32Bit(){ - if(OS.isWindows && !OS.is64Bit){ - String versionWarning = ""; - - if(Version.isSteam){ - versionWarning = "\n\nIf you are unable to upgrade, consider switching to the legacy v7 branch on Steam, which is the last release that supported 32-bit windows:\n(properties -> betas -> select version-7.0 in the drop-down box)."; - }else if(OS.javaVersion.equals("1.8.0_151-1-ojdkbuild")){ //version string of JVM packaged with the 32-bit version of the game on itch/steam - versionWarning = "\n\nMake sure you have downloaded the 64-bit version of the game, not the 32-bit one."; - }else if(OS.javaVersionNumber < 25){ - //technically, java 25 isn't required yet, but it might be in the future, so tell users to get that one - versionWarning = "\n\nYour current Java version is: " + OS.javaVersionNumber + ". To run the game, upgrade to Java 25 on a 64-bit machine."; - } - - ErrorDialog.show("You are running a 32-bit installation of Windows and/or a 32-bit JVM. 32-bit windows is no longer supported." + versionWarning); - } - } - public DesktopLauncher(String[] args){ this.args = args; diff --git a/gradle.properties b/gradle.properties index 7b31c918db..b30e1f8a21 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,4 +26,4 @@ org.gradle.caching=true org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 android.enableR8.fullMode=false -archash=ac71a73ac8 +archash=5d6c339d56 diff --git a/tools/build.gradle b/tools/build.gradle index 84f64f2a40..5b5378d4bc 100644 --- a/tools/build.gradle +++ b/tools/build.gradle @@ -94,7 +94,7 @@ tasks.register('pack'){ println "Time taken for AA: ${(System.currentTimeMillis() - ms) / 1000f} seconds" } - println("\n\nPacking normal 4096 sprites...\n\n") + println("Running sprite packer...") //pack normal sprites TexturePacker.process(new File(rootDir, "core/assets-raw/sprites_out/").absolutePath, new File(rootDir, "core/assets/sprites/").absolutePath, "sprites.aatls") diff --git a/tools/src/mindustry/tools/Generators.java b/tools/src/mindustry/tools/Generators.java index a37d60af92..adf5969ef2 100644 --- a/tools/src/mindustry/tools/Generators.java +++ b/tools/src/mindustry/tools/Generators.java @@ -324,11 +324,6 @@ public class Generators{ TextureRegion[] regions = block.getGeneratedIcons(); - for(TextureRegion region : block.makeIconRegions()){ - GenRegion gen = (GenRegion)region; - save(get(region).outline(block.outlineColor, block.outlineRadius), gen.name + "-outline"); - } - Pixmap shardTeamTop = null; if(block.teamRegion.found()){ diff --git a/tools/src/mindustry/tools/ImagePacker.java b/tools/src/mindustry/tools/ImagePacker.java index a799b7867e..497deb1f0e 100644 --- a/tools/src/mindustry/tools/ImagePacker.java +++ b/tools/src/mindustry/tools/ImagePacker.java @@ -241,7 +241,6 @@ public class ImagePacker{ static void saveScaled(Pixmap pix, String name, int size){ Pixmap scaled = new Pixmap(size, size); - //TODO bad linear scaling scaled.draw(pix, 0, 0, pix.width, pix.height, 0, 0, size, size, true, true); save(scaled, name); } @@ -249,7 +248,6 @@ public class ImagePacker{ static void drawScaledFit(Pixmap base, Pixmap image){ Vec2 size = Scaling.fit.apply(image.width, image.height, base.width, base.height); int wx = (int)size.x, wy = (int)size.y; - //TODO bad linear scaling base.draw(image, 0, 0, image.width, image.height, base.width/2 - wx/2, base.height/2 - wy/2, wx, wy, true, true); }