diff --git a/core/src/io/anuke/mindustry/Mindustry.java b/core/src/io/anuke/mindustry/Mindustry.java
index 1bc490e7d4..fbbfa3766a 100644
--- a/core/src/io/anuke/mindustry/Mindustry.java
+++ b/core/src/io/anuke/mindustry/Mindustry.java
@@ -3,7 +3,7 @@ package io.anuke.mindustry;
import io.anuke.mindustry.core.*;
import io.anuke.mindustry.io.BlockLoader;
import io.anuke.mindustry.io.BundleLoader;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.ucore.modules.ModuleCore;
import io.anuke.ucore.util.Log;
diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java
index f7a3b756a2..8c12f3ea9a 100644
--- a/core/src/io/anuke/mindustry/Vars.java
+++ b/core/src/io/anuke/mindustry/Vars.java
@@ -10,7 +10,7 @@ import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.effect.Shield;
import io.anuke.mindustry.entities.enemies.Enemy;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.net.ClientDebug;
import io.anuke.mindustry.net.ServerDebug;
import io.anuke.ucore.UCore;
diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java
index 213c98d4c5..3c67a53230 100644
--- a/core/src/io/anuke/mindustry/core/Control.java
+++ b/core/src/io/anuke/mindustry/core/Control.java
@@ -13,7 +13,6 @@ import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.DefaultKeybinds;
import io.anuke.mindustry.input.DesktopInput;
import io.anuke.mindustry.input.InputHandler;
-import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.io.Saves;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.resource.Item;
diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java
index 2df2ef14c4..d2da6b091d 100644
--- a/core/src/io/anuke/mindustry/core/NetClient.java
+++ b/core/src/io/anuke/mindustry/core/NetClient.java
@@ -10,7 +10,6 @@ import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.entities.enemies.Enemy;
-import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.NetworkIO;
diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java
index ce48cc0827..8723bf1c55 100644
--- a/core/src/io/anuke/mindustry/core/NetServer.java
+++ b/core/src/io/anuke/mindustry/core/NetServer.java
@@ -5,7 +5,6 @@ import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.game.EventType.GameOverEvent;
-import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.io.Version;
import io.anuke.mindustry.net.*;
import io.anuke.mindustry.net.Administration.PlayerInfo;
diff --git a/core/src/io/anuke/mindustry/io/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java
similarity index 64%
rename from core/src/io/anuke/mindustry/io/Platform.java
rename to core/src/io/anuke/mindustry/core/Platform.java
index b280fdf4d0..8ded30670e 100644
--- a/core/src/io/anuke/mindustry/io/Platform.java
+++ b/core/src/io/anuke/mindustry/core/Platform.java
@@ -1,5 +1,6 @@
-package io.anuke.mindustry.io;
+package io.anuke.mindustry.core;
+import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.utils.Base64Coder;
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
import io.anuke.ucore.core.Settings;
@@ -12,26 +13,40 @@ import java.util.Locale;
import java.util.Random;
public abstract class Platform {
+ /**Each separate game platform should set this instance to their own implementation.*/
public static Platform instance = new Platform() {};
+ /**Format the date using the default date formatter.*/
public String format(Date date){return "invalid";}
+ /**Format a number by adding in commas or periods where needed.*/
public String format(int number){return "invalid";}
+ /**Show a native error dialog.*/
public void showError(String text){}
+ /**Add a text input dialog that should show up after the field is tapped.*/
public void addDialog(TextField field){
addDialog(field, 16);
}
+ /**See addDialog().*/
public void addDialog(TextField field, int maxLength){}
+ /**Update discord RPC.*/
public void updateRPC(){}
+ /**Called when the game is exited.*/
public void onGameExit(){}
+ /**Open donation dialog. Currently android only.*/
public void openDonations(){}
+ /**Whether discord RPC is supported.*/
public boolean hasDiscord(){return true;}
+ /**Request Android permissions for writing files.*/
public void requestWritePerms(){}
+ /**Return the localized name for the locale. This is basically a workaround for GWT not supporting getName().*/
public String getLocaleName(Locale locale){
return locale.toString();
}
+ /**Whether joining games is supported.*/
public boolean canJoinGame(){
return true;
}
+ /**Whether debug mode is enabled.*/
public boolean isDebug(){return false;}
/**Must be 8 bytes in length.*/
public byte[] getUUID(){
@@ -46,6 +61,9 @@ public abstract class Platform {
}
return Base64Coder.decode(uuid);
}
+ /**Only used for iOS or android: open the share menu for a map pixmap.*/
+ public void shareImage(Pixmap pixmap){}
+ /**Use the default thread provider from the kryonet module for this.*/
public ThreadProvider getThreadProvider(){
return new ThreadProvider() {
@Override public boolean isOnThread() {return true;}
diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java
index fe28e973cd..e4775c63b1 100644
--- a/core/src/io/anuke/mindustry/core/UI.java
+++ b/core/src/io/anuke/mindustry/core/UI.java
@@ -7,7 +7,6 @@ import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.utils.Align;
import io.anuke.mindustry.Vars;
-import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.mapeditor.MapEditorDialog;
import io.anuke.mindustry.ui.dialogs.*;
import io.anuke.mindustry.ui.fragments.*;
diff --git a/core/src/io/anuke/mindustry/io/BundleLoader.java b/core/src/io/anuke/mindustry/io/BundleLoader.java
index e9aa011b4c..a66da1b7b5 100644
--- a/core/src/io/anuke/mindustry/io/BundleLoader.java
+++ b/core/src/io/anuke/mindustry/io/BundleLoader.java
@@ -3,6 +3,7 @@ package io.anuke.mindustry.io;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.I18NBundle;
+import io.anuke.mindustry.core.Platform;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.util.Log;
diff --git a/core/src/io/anuke/mindustry/io/SaveMeta.java b/core/src/io/anuke/mindustry/io/SaveMeta.java
index 277a7dca1e..d937c90603 100644
--- a/core/src/io/anuke/mindustry/io/SaveMeta.java
+++ b/core/src/io/anuke/mindustry/io/SaveMeta.java
@@ -1,5 +1,6 @@
package io.anuke.mindustry.io;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.game.Difficulty;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.world.Map;
diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java
index df17f9f36c..e52ae3dd07 100644
--- a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java
+++ b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java
@@ -4,7 +4,7 @@ import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.ui.dialogs.FileChooser;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.ColorMapper;
@@ -55,24 +55,7 @@ public class MapEditorDialog extends Dialog{
dialog = new MapGenerateDialog(editor);
view = new MapView(editor);
- openFile = new FileChooser("$text.loadimage", FileChooser.pngFilter, true, file -> {
- ui.loadfrag.show();
- Timers.run(3f, () -> {
- try{
- Pixmap pixmap = new Pixmap(file);
- if(verifySize(pixmap)){
- editor.setPixmap(pixmap);
- view.clearStack();
- }else{
- ui.showError(Bundles.format("text.editor.badsize", Arrays.toString(MapEditor.validMapSizes)));
- }
- }catch (Exception e){
- ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
- Log.err(e);
- }
- ui.loadfrag.hide();
- });
- });
+ openFile = new FileChooser("$text.loadimage", FileChooser.pngFilter, true, this::tryLoadMap);
saveFile = new FileChooser("$saveimage", false, file -> {
if(!file.extension().toLowerCase().equals(".png")){
@@ -237,16 +220,25 @@ public class MapEditorDialog extends Dialog{
).text("$text.editor.savemap");
row();
+
+ //iOS does not support loading raw files.
+ if(!ios) {
+
+ new imagebutton("icon-load-image", isize, () ->
+ openFile.show()
+ ).text("$text.editor.loadimage");
+
+ row();
+ }
- new imagebutton("icon-load-image", isize, () ->
- openFile.show()
- ).text("$text.editor.loadimage");
-
- row();
-
- new imagebutton("icon-save-image", isize, () ->
- saveFile.show()
- ).text("$text.editor.saveimage");
+ new imagebutton("icon-save-image", isize, () -> {
+ //iOS doesn't really support saving raw files. Sharing is used instead.
+ if(!ios){
+ saveFile.show()
+ }else {
+ Platforms.instance.shareImage(editor.pixmap());
+ }
+ }).text("$text.editor.saveimage");
row();
@@ -329,6 +321,25 @@ public class MapEditorDialog extends Dialog{
}}.grow().end();
}
+ public void tryLoadMap(FileHandle file){
+ ui.loadfrag.show();
+ Timers.runTask(3f, () -> {
+ try{
+ Pixmap pixmap = new Pixmap(file);
+ if(verifySize(pixmap)){
+ editor.setPixmap(pixmap);
+ view.clearStack();
+ }else{
+ ui.showError(Bundles.format("text.editor.badsize", Arrays.toString(MapEditor.validMapSizes)));
+ }
+ }catch (Exception e){
+ ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
+ Log.err(e);
+ }
+ ui.loadfrag.hide();
+ });
+ }
+
private void doInput(){
//tool select
for(int i = 0; i < EditorTool.values().length; i ++){
diff --git a/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java
index 3090325975..40ab7cae61 100644
--- a/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java
+++ b/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java
@@ -1,6 +1,6 @@
package io.anuke.mindustry.mapeditor;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Map;
import io.anuke.ucore.function.Consumer;
diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java
index e41b960694..43e65dcd72 100644
--- a/core/src/io/anuke/mindustry/net/Net.java
+++ b/core/src/io/anuke/mindustry/net/Net.java
@@ -9,7 +9,7 @@ import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.reflect.ClassReflection;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.net.Packet.ImportantPacket;
import io.anuke.mindustry.net.Packet.UnimportantPacket;
import io.anuke.mindustry.net.Streamable.StreamBegin;
diff --git a/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java b/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java
index a96d8ebc8c..2d3650d701 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java
@@ -6,7 +6,7 @@ import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pools;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.Consumer;
diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java
index 270d911f26..318dc163cb 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java
@@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.io.Version;
import io.anuke.mindustry.net.Host;
import io.anuke.mindustry.net.Net;
diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LanguageDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LanguageDialog.java
index 755db669a7..1c50fcc6a9 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/LanguageDialog.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/LanguageDialog.java
@@ -1,6 +1,6 @@
package io.anuke.mindustry.ui.dialogs;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ScrollPane;
diff --git a/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java b/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java
index 9d28551304..81148da437 100644
--- a/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java
+++ b/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java
@@ -8,7 +8,7 @@ import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.ucore.core.Core;
diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java
index f27999450d..9ae9bc22e3 100644
--- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java
+++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java
@@ -2,7 +2,7 @@ package io.anuke.mindustry.ui.fragments;
import com.badlogic.gdx.Gdx;
import io.anuke.mindustry.core.GameState.State;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.io.Version;
import io.anuke.mindustry.ui.MenuButton;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java
index b431c606ba..d87332c76a 100644
--- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java
+++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java
@@ -5,7 +5,7 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import io.anuke.kryonet.KryoClient;
import io.anuke.kryonet.KryoServer;
import io.anuke.mindustry.Mindustry;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.net.Net;
public class DesktopLauncher {
diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java
index 422a466a2d..71c5ec750b 100644
--- a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java
+++ b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java
@@ -7,7 +7,7 @@ import com.badlogic.gdx.utils.Base64Coder;
import io.anuke.kryonet.DefaultThreadImpl;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.UCore;
import io.anuke.ucore.core.Settings;
diff --git a/html/src/io/anuke/mindustry/client/HtmlLauncher.java b/html/src/io/anuke/mindustry/client/HtmlLauncher.java
index 542f3362d6..e8699b2a77 100644
--- a/html/src/io/anuke/mindustry/client/HtmlLauncher.java
+++ b/html/src/io/anuke/mindustry/client/HtmlLauncher.java
@@ -16,7 +16,7 @@ import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.i18n.shared.DateTimeFormat;
import com.google.gwt.user.client.ui.*;
import io.anuke.mindustry.Mindustry;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.core.Settings;
diff --git a/html/src/io/anuke/mindustry/client/WebsocketClient.java b/html/src/io/anuke/mindustry/client/WebsocketClient.java
index 75bb3339f7..3f661007ec 100644
--- a/html/src/io/anuke/mindustry/client/WebsocketClient.java
+++ b/html/src/io/anuke/mindustry/client/WebsocketClient.java
@@ -6,7 +6,7 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
import com.badlogic.gdx.utils.reflect.ReflectionException;
import com.sksamuel.gwt.websockets.Websocket;
import com.sksamuel.gwt.websockets.WebsocketListener;
-import io.anuke.mindustry.io.Platform;
+import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.net.*;
import io.anuke.mindustry.net.Net.ClientProvider;
import io.anuke.mindustry.net.Net.SendMode;
diff --git a/ios/Info.plist.xml b/ios/Info.plist.xml
index 2ef2621f00..dda5b181f8 100644
--- a/ios/Info.plist.xml
+++ b/ios/Info.plist.xml
@@ -49,6 +49,24 @@
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
+
+ CFBundleDocumentTypes
+
+
+ CFBundleTypeIconFiles
+
+ icon-72.png
+
+ CFBundleTypeRole
+ Editor
+ LSHandlerRank
+ Owner
+ LSItemContentTypes
+
+ public.png
+
+
+