SDL backend / Valid mode sprites / Better layout
This commit is contained in:
17
build.gradle
17
build.gradle
@@ -134,6 +134,23 @@ project(":desktop"){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
project(":desktop-sdl"){
|
||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
dependencies{
|
||||||
|
compile project(":core")
|
||||||
|
compile project(":net")
|
||||||
|
|
||||||
|
if(debugged()) compile project(":debug")
|
||||||
|
|
||||||
|
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
|
||||||
|
compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
|
||||||
|
|
||||||
|
compile arcModule("backends:backend-sdl")
|
||||||
|
compile 'com.github.MinnDevelopment:java-discord-rpc:v2.0.2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
project(":ios"){
|
project(":ios"){
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
apply plugin: "robovm"
|
apply plugin: "robovm"
|
||||||
|
|||||||
BIN
core/assets-raw/sprites/ui/icons/icon-mode-attack.png
Normal file
BIN
core/assets-raw/sprites/ui/icons/icon-mode-attack.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
core/assets-raw/sprites/ui/icons/icon-mode-pvp.png
Normal file
BIN
core/assets-raw/sprites/ui/icons/icon-mode-pvp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
core/assets-raw/sprites/ui/icons/icon-mode-survival.png
Normal file
BIN
core/assets-raw/sprites/ui/icons/icon-mode-survival.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
core/assets/icons/icon.ico
Normal file
BIN
core/assets/icons/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 458 KiB After Width: | Height: | Size: 460 KiB |
@@ -63,6 +63,8 @@ public class Vars{
|
|||||||
public static final int iconsizesmall = 32;
|
public static final int iconsizesmall = 32;
|
||||||
/** size of UI icons (medium)*/
|
/** size of UI icons (medium)*/
|
||||||
public static final int iconsizemed = 30;
|
public static final int iconsizemed = 30;
|
||||||
|
/** size of UI icons (medium)*/
|
||||||
|
public static final int iconsizetiny = 16;
|
||||||
/** units outside of this bound will simply die instantly */
|
/** units outside of this bound will simply die instantly */
|
||||||
public static final float finalWorldBounds = worldBounds + 500;
|
public static final float finalWorldBounds = worldBounds + 500;
|
||||||
/** ticks spent out of bound until self destruct. */
|
/** ticks spent out of bound until self destruct. */
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ public class Maps implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
maps.add(map);
|
maps.add(map);
|
||||||
maps.sort();
|
//maps.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadCustomMaps(){
|
private void loadCustomMaps(){
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package io.anuke.mindustry.ui.dialogs;
|
package io.anuke.mindustry.ui.dialogs;
|
||||||
|
|
||||||
import io.anuke.arc.Core;
|
import io.anuke.arc.*;
|
||||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
import io.anuke.arc.graphics.g2d.*;
|
||||||
import io.anuke.arc.scene.ui.ImageButton;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.arc.scene.ui.ScrollPane;
|
import io.anuke.arc.scene.ui.*;
|
||||||
import io.anuke.arc.scene.ui.layout.Table;
|
import io.anuke.arc.scene.ui.layout.*;
|
||||||
import io.anuke.arc.util.Align;
|
import io.anuke.arc.util.*;
|
||||||
import io.anuke.arc.util.Scaling;
|
import io.anuke.mindustry.game.*;
|
||||||
import io.anuke.mindustry.maps.Map;
|
import io.anuke.mindustry.graphics.*;
|
||||||
import io.anuke.mindustry.ui.BorderImage;
|
import io.anuke.mindustry.maps.*;
|
||||||
|
import io.anuke.mindustry.ui.*;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ public class CustomGameDialog extends FloatingDialog{
|
|||||||
ScrollPane pane = new ScrollPane(maps);
|
ScrollPane pane = new ScrollPane(maps);
|
||||||
pane.setFadeScrollBars(false);
|
pane.setFadeScrollBars(false);
|
||||||
|
|
||||||
int maxwidth = (Core.graphics.isPortrait() ? 2 : 4);
|
int maxwidth = Mathf.clamp((int)(Core.graphics.getWidth() / Unit.dp.scl(200)), 1, 8);
|
||||||
float images = 146f;
|
float images = 146f;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -49,12 +50,27 @@ public class CustomGameDialog extends FloatingDialog{
|
|||||||
|
|
||||||
ImageButton image = new ImageButton(new TextureRegion(map.texture), "clear");
|
ImageButton image = new ImageButton(new TextureRegion(map.texture), "clear");
|
||||||
image.margin(5);
|
image.margin(5);
|
||||||
image.getImageCell().size(images);
|
|
||||||
image.top();
|
image.top();
|
||||||
|
|
||||||
|
Image img = image.getImage();
|
||||||
|
img.remove();
|
||||||
|
|
||||||
image.row();
|
image.row();
|
||||||
image.add("[accent]" + map.name()).pad(3f).growX().wrap().get().setAlignment(Align.center, Align.center);
|
image.table(t -> {
|
||||||
|
t.left();
|
||||||
|
for(Gamemode mode : Gamemode.all){
|
||||||
|
if(mode.valid(map) && Core.atlas.has("icon-mode-" + mode.name())){
|
||||||
|
t.addImage("icon-mode-" + mode.name()).size(16f).pad(4f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).left();
|
||||||
image.row();
|
image.row();
|
||||||
image.label((() -> Core.bundle.format("level.highscore", map.getHightScore()))).pad(3f);
|
image.add(map.name()).pad(1f).growX().wrap().left().get().setEllipsis(true);
|
||||||
|
image.row();
|
||||||
|
image.addImage("whiteui", Pal.gray).growX().pad(3).height(4f);
|
||||||
|
image.row();
|
||||||
|
image.add(img).size(images);
|
||||||
|
|
||||||
|
|
||||||
BorderImage border = new BorderImage(map.texture, 3f);
|
BorderImage border = new BorderImage(map.texture, 3f);
|
||||||
border.setScaling(Scaling.fit);
|
border.setScaling(Scaling.fit);
|
||||||
|
|||||||
@@ -64,6 +64,11 @@ public class MapPlayDialog extends FloatingDialog{
|
|||||||
cont.addImageTextButton("$customize", "icon-tools-small", iconsizesmall, () -> dialog.show(rules, () -> rules = (selectedGamemode == null ? map.rules() : selectedGamemode.apply(map.rules())))).width(230);
|
cont.addImageTextButton("$customize", "icon-tools-small", iconsizesmall, () -> dialog.show(rules, () -> rules = (selectedGamemode == null ? map.rules() : selectedGamemode.apply(map.rules())))).width(230);
|
||||||
cont.row();
|
cont.row();
|
||||||
cont.add(new BorderImage(map.texture, 3f)).size(mobile && !Core.graphics.isPortrait() ? 150f : 250f).get().setScaling(Scaling.fit);
|
cont.add(new BorderImage(map.texture, 3f)).size(mobile && !Core.graphics.isPortrait() ? 150f : 250f).get().setScaling(Scaling.fit);
|
||||||
|
//only maps with survival are valid for high scores
|
||||||
|
if(Gamemode.survival.valid(map)){
|
||||||
|
cont.row();
|
||||||
|
cont.label((() -> Core.bundle.format("level.highscore", map.getHightScore()))).pad(3f);
|
||||||
|
}
|
||||||
|
|
||||||
buttons.clearChildren();
|
buttons.clearChildren();
|
||||||
addCloseButton();
|
addCloseButton();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apply plugin: "java"
|
|||||||
sourceCompatibility = 1.8
|
sourceCompatibility = 1.8
|
||||||
sourceSets.main.java.srcDirs = [ "src/" ]
|
sourceSets.main.java.srcDirs = [ "src/" ]
|
||||||
|
|
||||||
project.ext.mainClassName = "io.anuke.mindustry.desktop.DesktopLauncher"
|
project.ext.mainClassName = "io.anuke.mindustry.desktopsdl.DesktopLauncher"
|
||||||
project.ext.assetsDir = new File("../core/assets")
|
project.ext.assetsDir = new File("../core/assets")
|
||||||
|
|
||||||
def IKVM_DIR = System.env.IKVM_HOME
|
def IKVM_DIR = System.env.IKVM_HOME
|
||||||
@@ -18,6 +18,14 @@ task run(dependsOn: classes, type: JavaExec) {
|
|||||||
if(System.getProperty("os.name").toLowerCase().contains("mac")){
|
if(System.getProperty("os.name").toLowerCase().contains("mac")){
|
||||||
jvmArgs("-XstartOnFirstThread", "-Djava.awt.headless=true")
|
jvmArgs("-XstartOnFirstThread", "-Djava.awt.headless=true")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(project.hasProperty("args")){
|
||||||
|
args Eval.me(project.getProperties()["args"])
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args.contains("debug")){
|
||||||
|
main = "io.anuke.mindustry.DebugLauncher"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task dist(type: Jar, dependsOn: classes) {
|
task dist(type: Jar, dependsOn: classes) {
|
||||||
@@ -55,6 +63,8 @@ task ikdist{
|
|||||||
def args = ["mono", "$IKVM_DIR/ikvmc.exe", "-target:winexe", "-static", "-out:build/libs/${filename}.exe", "build/libs/${filename}.jar"]
|
def args = ["mono", "$IKVM_DIR/ikvmc.exe", "-target:winexe", "-static", "-out:build/libs/${filename}.exe", "build/libs/${filename}.jar"]
|
||||||
if(file("../core/assets/sprites/icon.ico").exists()){
|
if(file("../core/assets/sprites/icon.ico").exists()){
|
||||||
args += ["-win32icon:../core/assets/sprites/icon.ico"]
|
args += ["-win32icon:../core/assets/sprites/icon.ico"]
|
||||||
|
}else if(file("../core/assets/icons/icon.ico").exists()){
|
||||||
|
args += ["-win32icon:../core/assets/icons/icon.ico"]
|
||||||
}
|
}
|
||||||
|
|
||||||
exec{
|
exec{
|
||||||
|
|||||||
BIN
desktop-sdl/build/distributions/Mindustry-windows-release.zip
Normal file
BIN
desktop-sdl/build/distributions/Mindustry-windows-release.zip
Normal file
Binary file not shown.
BIN
desktop-sdl/build/libs/Mindustry-windows-release.exe
Executable file
BIN
desktop-sdl/build/libs/Mindustry-windows-release.exe
Executable file
Binary file not shown.
BIN
desktop-sdl/build/libs/Mindustry-windows-release.jar
Normal file
BIN
desktop-sdl/build/libs/Mindustry-windows-release.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
desktop-sdl/build/libs/Mindustry-windows-release/Mindustry-windows-release.exe
Executable file
BIN
desktop-sdl/build/libs/Mindustry-windows-release/Mindustry-windows-release.exe
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
3
desktop-sdl/build/tmp/dist/MANIFEST.MF
vendored
Normal file
3
desktop-sdl/build/tmp/dist/MANIFEST.MF
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
Main-Class: io.anuke.mindustry.desktopsdl.DesktopLauncher
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package io.anuke.mindustry.desktopsdl;
|
||||||
|
import io.anuke.arc.Files.*;
|
||||||
|
import io.anuke.arc.backends.sdl.*;
|
||||||
|
import io.anuke.mindustry.Mindustry;
|
||||||
|
import io.anuke.mindustry.core.Platform;
|
||||||
|
import io.anuke.mindustry.net.*;
|
||||||
|
|
||||||
|
public class DesktopLauncher{
|
||||||
|
|
||||||
|
public static void main(String[] arg){
|
||||||
|
try{
|
||||||
|
|
||||||
|
Platform.instance = new DesktopPlatform(arg);
|
||||||
|
|
||||||
|
Net.setClientProvider(new ArcNetClient());
|
||||||
|
Net.setServerProvider(new ArcNetServer());
|
||||||
|
new SdlApplication(new Mindustry(), new SdlConfig(){{
|
||||||
|
title = "Mindustry";
|
||||||
|
maximized = true;
|
||||||
|
depth = 0;
|
||||||
|
stencil = 0;
|
||||||
|
width = 900;
|
||||||
|
height = 700;
|
||||||
|
setWindowIcon(FileType.Internal, "icons/icon.png");
|
||||||
|
}});
|
||||||
|
}catch(Throwable e){
|
||||||
|
DesktopPlatform.handleCrash(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
package io.anuke.mindustry.desktopsdl;
|
||||||
|
|
||||||
|
import club.minnced.discord.rpc.*;
|
||||||
|
import io.anuke.arc.collection.*;
|
||||||
|
import io.anuke.arc.files.*;
|
||||||
|
import io.anuke.arc.function.*;
|
||||||
|
import io.anuke.arc.util.*;
|
||||||
|
import io.anuke.arc.util.serialization.*;
|
||||||
|
import io.anuke.mindustry.core.GameState.*;
|
||||||
|
import io.anuke.mindustry.core.*;
|
||||||
|
import io.anuke.mindustry.net.*;
|
||||||
|
import io.anuke.mindustry.ui.dialogs.*;
|
||||||
|
import sdl.*;
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
|
public class DesktopPlatform extends Platform{
|
||||||
|
static boolean useDiscord = OS.is64Bit;
|
||||||
|
final static String applicationId = "398246104468291591";
|
||||||
|
String[] args;
|
||||||
|
|
||||||
|
public DesktopPlatform(String[] args){
|
||||||
|
this.args = args;
|
||||||
|
|
||||||
|
testMobile = Array.with(args).contains("-testMobile");
|
||||||
|
|
||||||
|
if(useDiscord){
|
||||||
|
try{
|
||||||
|
DiscordEventHandlers handlers = new DiscordEventHandlers();
|
||||||
|
DiscordRPC.INSTANCE.Discord_Initialize(applicationId, handlers, true, "");
|
||||||
|
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(DiscordRPC.INSTANCE::Discord_Shutdown));
|
||||||
|
}catch(Throwable t){
|
||||||
|
useDiscord = false;
|
||||||
|
Log.err("Failed to initialize discord.", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleCrash(Throwable e){
|
||||||
|
Consumer<Runnable> dialog = r -> new Thread(r).start();
|
||||||
|
boolean badGPU = false;
|
||||||
|
|
||||||
|
if(e.getMessage() != null && (e.getMessage().contains("Couldn't create window") || e.getMessage().contains("OpenGL 2.0 or higher"))){
|
||||||
|
|
||||||
|
dialog.accept(() -> message(
|
||||||
|
e.getMessage().contains("Couldn't create window") ? "A graphics initialization error has occured! Try to update your graphics drivers:\n" + e.getMessage() :
|
||||||
|
"Your graphics card does not support OpenGL 2.0!\n" +
|
||||||
|
"Try to update your graphics drivers.\n\n" +
|
||||||
|
"(If that doesn't work, your computer just doesn't support Mindustry.)"));
|
||||||
|
badGPU = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean fbgp = badGPU;
|
||||||
|
|
||||||
|
CrashSender.send(e, file -> {
|
||||||
|
if(!fbgp){
|
||||||
|
dialog.accept(() -> message("A crash has occured. It has been saved in:\n" + file.getAbsolutePath()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showFileChooser(String text, String content, Consumer<FileHandle> cons, boolean open, Predicate<String> filetype){
|
||||||
|
new FileChooser(text, file -> filetype.test(file.extension().toLowerCase()), open, cons).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRPC(){
|
||||||
|
|
||||||
|
if(!useDiscord) return;
|
||||||
|
|
||||||
|
DiscordRichPresence presence = new DiscordRichPresence();
|
||||||
|
|
||||||
|
if(!state.is(State.menu)){
|
||||||
|
presence.state = state.rules.pvp ? "PvP" : state.rules.waves ? "Survival" : "Attack";
|
||||||
|
if(world.getMap() == null){
|
||||||
|
presence.details = "Unknown Map";
|
||||||
|
}else if(!state.rules.waves){
|
||||||
|
presence.details = Strings.capitalize(world.getMap().name());
|
||||||
|
}else{
|
||||||
|
presence.details = Strings.capitalize(world.getMap().name()) + " | Wave " + state.wave;
|
||||||
|
presence.largeImageText = "Wave " + state.wave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Net.active() && playerGroup.size() > 1){
|
||||||
|
presence.state = (state.rules.pvp ? "PvP | " : "") + playerGroup.size() + " Players";
|
||||||
|
}else if(state.rules.waves){
|
||||||
|
presence.state = "Survival";
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(ui.editor != null && ui.editor.isShown()){
|
||||||
|
presence.state = "In Editor";
|
||||||
|
}else{
|
||||||
|
presence.state = "In Menu";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
presence.largeImageKey = "logo";
|
||||||
|
|
||||||
|
DiscordRPC.INSTANCE.Discord_UpdatePresence(presence);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUUID(){
|
||||||
|
try{
|
||||||
|
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
|
||||||
|
NetworkInterface out;
|
||||||
|
for(out = e.nextElement(); (out.getHardwareAddress() == null || !validAddress(out.getHardwareAddress())) && e.hasMoreElements(); out = e.nextElement());
|
||||||
|
|
||||||
|
byte[] bytes = out.getHardwareAddress();
|
||||||
|
byte[] result = new byte[8];
|
||||||
|
System.arraycopy(bytes, 0, result, 0, bytes.length);
|
||||||
|
|
||||||
|
String str = new String(Base64Coder.encode(result));
|
||||||
|
|
||||||
|
if(str.equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID.");
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}catch(Exception e){
|
||||||
|
return super.getUUID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void message(String message){
|
||||||
|
SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MESSAGEBOX_ERROR, "oh no", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validAddress(byte[] bytes){
|
||||||
|
if(bytes == null) return false;
|
||||||
|
byte[] result = new byte[8];
|
||||||
|
System.arraycopy(bytes, 0, result, 0, bytes.length);
|
||||||
|
return !new String(Base64Coder.encode(result)).equals("AAAAAAAAAOA=");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
include 'desktop', 'core', 'net', 'server', 'ios', 'annotations', 'tools', 'tests'
|
include 'desktop', 'desktop-sdl', 'core', 'net', 'server', 'ios', 'annotations', 'tools', 'tests'
|
||||||
|
|
||||||
def use = { String name ->
|
def use = { String name ->
|
||||||
include(name)
|
include(name)
|
||||||
@@ -29,6 +29,7 @@ if(!hasProperty("release")){
|
|||||||
use(':Arc:extensions:arcnet')
|
use(':Arc:extensions:arcnet')
|
||||||
use(':Arc:extensions:packer')
|
use(':Arc:extensions:packer')
|
||||||
use(':Arc:backends')
|
use(':Arc:backends')
|
||||||
|
use(':Arc:backends:backend-sdl')
|
||||||
use(':Arc:backends:backend-lwjgl3')
|
use(':Arc:backends:backend-lwjgl3')
|
||||||
use(':Arc:backends:backend-android')
|
use(':Arc:backends:backend-android')
|
||||||
use(':Arc:backends:backend-robovm')
|
use(':Arc:backends:backend-robovm')
|
||||||
|
|||||||
Reference in New Issue
Block a user