update Assets

- load bitmapfonts to assetmanager
- load adventure skinfile to assetmanager
- update ondestroy on android to dispose assets
- fix confirmpayment on mobile not displaying card images on hidden zone (ie shocklands that were put into play from library to battlefield)
- increase pagesize for CJK Fonts
This commit is contained in:
Anthony Calosa
2022-08-04 08:57:22 +08:00
parent 9aedef3a4a
commit a468d19408
6 changed files with 99 additions and 80 deletions

View File

@@ -259,6 +259,13 @@ public class Main extends AndroidApplication {
/*@Override /*@Override
protected void onDestroy() { protected void onDestroy() {
try {
final Forge forge = (Forge) Gdx.app.getApplicationListener();
if (forge != null)
forge.dispose();
} catch (Exception e) {
e.printStackTrace();
}
super.onDestroy(); super.onDestroy();
//ensure app doesn't stick around //ensure app doesn't stick around

View File

@@ -102,28 +102,31 @@ public class Controls {
switch (fontName) { switch (fontName) {
case "blackbig": case "blackbig":
case "big": case "big":
return Forge.getAssets().advBigFont; GetSkin().getFont("default").getData().setScale(2, 2);
return GetSkin().getFont("default");
default: default:
return Forge.getAssets().advDefaultFont; GetSkin().getFont("default").getData().setScale(1, 1);
return GetSkin().getFont("default");
} }
} }
static public Skin GetSkin() { static public Skin GetSkin() {
if (Forge.getAssets().skin == null) { FileHandle skinFile = Config.instance().getFile(Paths.SKIN);
Forge.getAssets().skin = new Skin(); if (!Forge.getAssets().manager().contains(skinFile.path(), Skin.class)) {
FileHandle skinFile = Config.instance().getFile(Paths.SKIN); Forge.getAssets().manager().load(skinFile.path(), Skin.class);
Forge.getAssets().manager().finishLoadingAsset(skinFile.path());
FileHandle atlasFile = skinFile.sibling(skinFile.nameWithoutExtension() + ".atlas"); FileHandle atlasFile = skinFile.sibling(skinFile.nameWithoutExtension() + ".atlas");
TextureAtlas atlas = new TextureAtlas(atlasFile); Forge.getAssets().manager().load(atlasFile.path(), TextureAtlas.class);
Forge.getAssets().manager().finishLoadingAsset(atlasFile.path());
//font //font
Forge.getAssets().advDefaultFont = new BitmapFont(Config.instance().getFile(Paths.SKIN).sibling("LanaPixel.fnt")); FileHandle pixelFont = Config.instance().getFile(Paths.SKIN).sibling("LanaPixel.fnt");
Forge.getAssets().advBigFont = new BitmapFont(Config.instance().getFile(Paths.SKIN).sibling("LanaPixel.fnt")); Forge.getAssets().manager().load(pixelFont.path(), BitmapFont.class);
Forge.getAssets().advBigFont.getData().setScale(2, 2); Forge.getAssets().manager().finishLoadingAsset(pixelFont.path());
Forge.getAssets().skin.add("default", Forge.getAssets().advDefaultFont); Forge.getAssets().manager().get(skinFile.path(), Skin.class).add("default", Forge.getAssets().manager().get(pixelFont.path(), BitmapFont.class), BitmapFont.class);
Forge.getAssets().skin.add("big", Forge.getAssets().advBigFont); Forge.getAssets().manager().get(skinFile.path(), Skin.class).addRegions(Forge.getAssets().manager().get(atlasFile.path(), TextureAtlas.class));
Forge.getAssets().skin.addRegions(atlas); Forge.getAssets().manager().finishLoadingAsset(skinFile.path());
Forge.getAssets().skin.load(skinFile);
} }
return Forge.getAssets().skin; return Forge.getAssets().manager().get(skinFile.path(), Skin.class);
} }
public static Label newLabel(String name) { public static Label newLabel(String name) {

View File

@@ -12,7 +12,6 @@ import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.TextureData; import com.badlogic.gdx.graphics.TextureData;
import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
import forge.Forge; import forge.Forge;
@@ -24,61 +23,67 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class Assets implements Disposable { public class Assets implements Disposable {
private MemoryTrackingAssetManager manager = new MemoryTrackingAssetManager(new AbsoluteFileHandleResolver()); private MemoryTrackingAssetManager manager;
private HashMap<Integer, FSkinFont> fonts = new HashMap<>(); private HashMap<Integer, FSkinFont> fonts;
private HashMap<String, FImageComplex> cardArtCache = new HashMap<>(1024); private HashMap<String, FImageComplex> cardArtCache;
private HashMap<String, FImage> avatarImages = new HashMap<>(); private HashMap<String, FImage> avatarImages;
private HashMap<String, FSkinImage> manaImages = new HashMap<>(128); private HashMap<String, FSkinImage> manaImages;
private HashMap<String, FSkinImage> symbolLookup = new HashMap<>(64); private HashMap<String, FSkinImage> symbolLookup;
private HashMap<FSkinProp, FSkinImage> images = new HashMap<>(512); private HashMap<FSkinProp, FSkinImage> images;
private HashMap<Integer, TextureRegion> avatars = new HashMap<>(150); private HashMap<Integer, TextureRegion> avatars;
private HashMap<Integer, TextureRegion> sleeves = new HashMap<>(64); private HashMap<Integer, TextureRegion> sleeves;
private HashMap<Integer, TextureRegion> cracks = new HashMap<>(16); private HashMap<Integer, TextureRegion> cracks;
private HashMap<Integer, TextureRegion> borders = new HashMap<>(); private HashMap<Integer, TextureRegion> borders;
private HashMap<Integer, TextureRegion> deckbox = new HashMap<>(); private HashMap<Integer, TextureRegion> deckbox;
private HashMap<Integer, TextureRegion> cursor = new HashMap<>(); private HashMap<Integer, TextureRegion> cursor;
private ObjectMap<Integer, BitmapFont> counterFonts = new ObjectMap<>(); private ObjectMap<Integer, BitmapFont> counterFonts;
private ObjectMap<String, Texture> generatedCards = new ObjectMap<>(512); private ObjectMap<String, Texture> generatedCards;
private ObjectMap<Integer, Texture> fallback_skins = new ObjectMap<>(); private ObjectMap<Integer, Texture> fallback_skins;
private ObjectMap<String, Texture> tmxMap = new ObjectMap<>(); private ObjectMap<String, Texture> tmxMap;
public Skin skin;
public BitmapFont advDefaultFont, advBigFont;
private Texture defaultImage, dummy; private Texture defaultImage, dummy;
private TextureParameter textureParameter; private TextureParameter textureParameter;
private int cGen = 0, cGenVal = 0, cFB = 0, cFBVal = 0, cTM, cTMVal = 0, cSF = 0, cSFVal = 0, cCF = 0, cCFVal = 0, aDF = 0, cDFVal = 0; private int cGen = 0, cGenVal = 0, cFB = 0, cFBVal = 0, cTM, cTMVal = 0, cSF = 0, cSFVal = 0, cCF = 0, cCFVal = 0, aDF = 0, cDFVal = 0;
public Assets() { public Assets() {
//init titlebg fallback //init titlebg fallback
fallback_skins.put(0, new Texture(GuiBase.isAndroid() fallback_skins().put(0, new Texture(GuiBase.isAndroid()
? Gdx.files.internal("fallback_skin").child("title_bg_lq.png") ? Gdx.files.internal("fallback_skin").child("title_bg_lq.png")
: Gdx.files.classpath("fallback_skin").child("title_bg_lq.png"))); : Gdx.files.local("fallback_skin").child("title_bg_lq.png")));
//init transition fallback //init transition fallback
fallback_skins.put(1, new Texture(GuiBase.isAndroid() fallback_skins().put(1, new Texture(GuiBase.isAndroid()
? Gdx.files.internal("fallback_skin").child("transition.png") ? Gdx.files.internal("fallback_skin").child("transition.png")
: Gdx.files.classpath("fallback_skin").child("transition.png"))); : Gdx.files.local("fallback_skin").child("transition.png")));
} }
@Override @Override
public void dispose() { public void dispose() {
manager.dispose();
for (BitmapFont bitmapFont : counterFonts.values()) for (BitmapFont bitmapFont : counterFonts.values())
bitmapFont.dispose(); bitmapFont.dispose();
for (Texture texture : generatedCards.values()) for (Texture texture : generatedCards.values())
texture.dispose(); texture.dispose();
for (FSkinFont fSkinFont : fonts.values())
fSkinFont.font.dispose();
for (Texture texture : fallback_skins.values()) for (Texture texture : fallback_skins.values())
texture.dispose(); texture.dispose();
for (Texture texture : tmxMap.values()) for (Texture texture : tmxMap.values())
texture.dispose(); texture.dispose();
if (advDefaultFont != null)
advDefaultFont.dispose();
if (advBigFont != null)
advBigFont.dispose();
if (skin != null)
skin.dispose();
if (defaultImage != null) if (defaultImage != null)
defaultImage.dispose(); defaultImage.dispose();
if (dummy != null) if (dummy != null)
dummy.dispose(); dummy.dispose();
cardArtCache.clear();
avatarImages.clear();
manaImages.clear();
symbolLookup.clear();
images.clear();
avatars.clear();
sleeves.clear();
cracks.clear();
borders.clear();
deckbox.clear();
cursor.clear();
fonts.clear();
counterFonts.clear();
generatedCards.clear();
fallback_skins.clear();
tmxMap.clear();
manager.dispose();
} }
public MemoryTrackingAssetManager manager() { public MemoryTrackingAssetManager manager() {
if (manager == null) if (manager == null)
@@ -237,7 +242,7 @@ public class Assets implements Disposable {
} }
memoryPerFile.put(fileName, textureSize); memoryPerFile.put(fileName, textureSize);
int sum = memoryPerFile.values().stream().mapToInt(Integer::intValue).sum() + calcFonts() + calcCounterFonts() + calcAdvFonts() int sum = memoryPerFile.values().stream().mapToInt(Integer::intValue).sum() + calcFonts() + calcCounterFonts()
+ calculateObjectMaps(generatedCards()) + calculateObjectMaps(fallback_skins()) + calculateObjectMaps(tmxMap()); + calculateObjectMaps(generatedCards()) + calculateObjectMaps(fallback_skins()) + calculateObjectMaps(tmxMap());
return sum; return sum;
} }
@@ -324,20 +329,6 @@ public class Assets implements Disposable {
cCFVal = val; cCFVal = val;
return cCFVal; return cCFVal;
} }
private int calcAdvFonts() {
if (!Forge.showFPS)
return 0;
if (advDefaultFont == null || advBigFont == null)
return 0;
if (aDF == -1)
return cDFVal;
int val = 0;
val += calcBitmapFont(advDefaultFont);
val += calcBitmapFont(advBigFont);
cDFVal = val;
aDF = -1;
return cDFVal;
}
private int calcBitmapFont(BitmapFont bitmapFont) { private int calcBitmapFont(BitmapFont bitmapFont) {
if (bitmapFont == null) if (bitmapFont == null)
return 0; return 0;

View File

@@ -384,7 +384,8 @@ public class FSkinFont {
} }
translationFile.close(); translationFile.close();
} catch (IOException e) { } catch (IOException e) {
System.err.println("Error reading translation file: " + translationFilePaths[i]); if (!"en-US".equalsIgnoreCase(langCode))
System.err.println("Error reading translation file: " + translationFilePaths[i]);
} }
} }
langUniqueCharacterSet.put(langCode, characters.toString()); langUniqueCharacterSet.put(langCode, characters.toString());
@@ -393,27 +394,28 @@ public class FSkinFont {
} }
private void updateFont() { private void updateFont() {
if (scale != 1) { //re-use font inside range if possible String fontName = "f";
if (fontSize > MAX_FONT_SIZE) { if (scale != 1) {
font = _get(MAX_FONT_SIZE).font; if (fontSize > MAX_FONT_SIZE)
} else { fontName += MAX_FONT_SIZE;
font = _get(MIN_FONT_SIZE).font; else
} fontName += MIN_FONT_SIZE;
return; } else {
fontName += fontSize;
} }
String fontName = "f" + fontSize;
if (Forge.locale.equals("zh-CN") || Forge.locale.equals("ja-JP") && !Forge.forcedEnglishonCJKMissing) { if (Forge.locale.equals("zh-CN") || Forge.locale.equals("ja-JP") && !Forge.forcedEnglishonCJKMissing) {
fontName += Forge.locale; fontName += Forge.locale;
} }
FileHandle fontFile = Gdx.files.absolute(ForgeConstants.FONTS_DIR + fontName + ".fnt"); FileHandle fontFile = Gdx.files.absolute(ForgeConstants.FONTS_DIR + fontName + ".fnt");
final boolean[] found = {false}; final boolean[] found = {false};
if (fontFile != null && fontFile.exists()) { if (fontFile != null && fontFile.exists()) {
final BitmapFontData data = new BitmapFontData(fontFile, false);
String finalFontName = fontName;
FThreads.invokeInEdtNowOrLater(() -> { //font must be initialized on UI thread FThreads.invokeInEdtNowOrLater(() -> { //font must be initialized on UI thread
try { try {
font = new BitmapFont(data, (TextureRegion) null, true); if (!Forge.getAssets().manager().contains(fontFile.path(), BitmapFont.class)) {
Forge.getAssets().manager().load(fontFile.path(), BitmapFont.class);
Forge.getAssets().manager().finishLoadingAsset(fontFile.path());
}
font = Forge.getAssets().manager().get(fontFile.path(), BitmapFont.class);
found[0] = true; found[0] = true;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -442,11 +444,15 @@ public class FSkinFont {
//approximate optimal page size //approximate optimal page size
int pageSize; int pageSize;
if (fontSize >= 28) { if (fontSize >= 50) {
pageSize = 1024;
} else if (fontSize >= 20) {
pageSize = 512;
} else {
pageSize = 256; pageSize = 256;
} }
else { if (Forge.locale.equals("zh-CN") || Forge.locale.equals("ja-JP") && !Forge.forcedEnglishonCJKMissing) {
pageSize = 128; pageSize = 1024;
} }
final PixmapPacker packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 2, false); final PixmapPacker packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 2, false);
@@ -475,7 +481,7 @@ public class FSkinFont {
textureRegions.addAll(new TextureRegion(texture)); textureRegions.addAll(new TextureRegion(texture));
} }
font = new BitmapFont(fontData, textureRegions, true); BitmapFont temp = new BitmapFont(fontData, textureRegions, true);
//create .fnt and .png files for font //create .fnt and .png files for font
FileHandle pixmapDir = Gdx.files.absolute(ForgeConstants.FONTS_DIR); FileHandle pixmapDir = Gdx.files.absolute(ForgeConstants.FONTS_DIR);
@@ -484,11 +490,16 @@ public class FSkinFont {
BitmapFontWriter.setOutputFormat(BitmapFontWriter.OutputFormat.Text); BitmapFontWriter.setOutputFormat(BitmapFontWriter.OutputFormat.Text);
String[] pageRefs = BitmapFontWriter.writePixmaps(packer.getPages(), pixmapDir, fontName); String[] pageRefs = BitmapFontWriter.writePixmaps(packer.getPages(), pixmapDir, fontName);
BitmapFontWriter.writeFont(font.getData(), pageRefs, fontFile, new BitmapFontWriter.FontInfo(fontName, fontSize), 1, 1); BitmapFontWriter.writeFont(temp.getData(), pageRefs, fontFile, new BitmapFontWriter.FontInfo(fontName, fontSize), 1, 1);
//load to assetManager
Forge.getAssets().manager().load(fontFile.path(), BitmapFont.class);
Forge.getAssets().manager().finishLoadingAsset(fontFile.path());
font = Forge.getAssets().manager().get(fontFile.path(), BitmapFont.class);
} }
generator.dispose(); generator.dispose();
packer.dispose(); packer.dispose();
temp.dispose();
} }
}); });
} }

View File

@@ -1175,6 +1175,9 @@ public class HumanCostDecision extends CostDecisionMakerBase {
cardView = CardView.getCardForUi(ImageUtil.getPaperCardFromImageKey(cardView.getImprintedCards().get(0).getCurrentState().getImageKey())); cardView = CardView.getCardForUi(ImageUtil.getPaperCardFromImageKey(cardView.getImprintedCards().get(0).getCurrentState().getImageKey()));
else if (ability.getTargets() != null && ability.getTargets().isTargetingAnyCard() && ability.getTargets().size() == 1) else if (ability.getTargets() != null && ability.getTargets().isTargetingAnyCard() && ability.getTargets().size() == 1)
cardView = CardView.get(ability.getTargetCard()); cardView = CardView.get(ability.getTargetCard());
else if (cardView.getZone() == null || cardView.getZone().isHidden()) {
cardView = CardView.getCardForUi(ImageUtil.getPaperCardFromImageKey(cardView.getCurrentState().getImageKey()));
}
return controller.getGui().confirm(cardView, message.replaceAll("\n", " ")); return controller.getGui().confirm(cardView, message.replaceAll("\n", " "));
} else { } else {
return controller.confirmPayment(costPart, message, ability); return controller.confirmPayment(costPart, message, ability);

View File

@@ -18,6 +18,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.TreeSet; import java.util.TreeSet;
import forge.util.ImageUtil;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.Range; import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -1784,6 +1785,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
@Override @Override
public boolean confirmPayment(final CostPart costPart, final String question, SpellAbility sa) { public boolean confirmPayment(final CostPart costPart, final String question, SpellAbility sa) {
if (GuiBase.getInterface().isLibgdxPort()) { if (GuiBase.getInterface().isLibgdxPort()) {
CardView cardView = sa.getView().getHostCard();
if (cardView.getZone() == null || cardView.getZone().isHidden())
cardView = CardView.getCardForUi(ImageUtil.getPaperCardFromImageKey(cardView.getCurrentState().getImageKey()));
return this.getGui().confirm(sa.getView().getHostCard(), question.replaceAll("\n", " ")); return this.getGui().confirm(sa.getView().getHostCard(), question.replaceAll("\n", " "));
} else { } else {
final InputConfirm inp = new InputConfirm(this, question, sa); final InputConfirm inp = new InputConfirm(this, question, sa);