Compare commits

...

9 Commits
v155.4 ... sdl3

Author SHA1 Message Date
Anuken
66ea037add App name for SDL3 backend 2026-03-03 00:31:53 -05:00
Anuken
24c38894bb Fixed banned units on Coastline 2026-02-23 22:30:41 -05:00
Anuken
dc1e36bcd2 Fixed objective team selection 2026-02-23 00:53:51 -05:00
Anuken
48d3fa1c11 Proper backend 2026-02-16 17:32:00 -05:00
Anuken
88e487303d Revert "SDL3 is broken, reverting to SDL2 (Closes #11671, #11676)"
This reverts commit 0580e1af
2026-02-16 17:31:06 -05:00
Anuken
a6b29b854c Reapply "Removed borderless fullscreen option (window should always be borderless fullscreen anyway)"
This reverts commit a3682756dc.
2026-02-16 17:30:35 -05:00
Anuken
07d5b03e35 More achievement fixes 2026-02-16 13:30:21 -05:00
Anuken
3c239e8af0 Defer even firing until after unit is added 2026-02-16 13:22:32 -05:00
Anuken
9d759d03eb Correctly fire UnitCreateEvent in UnitAssembler 2026-02-16 13:21:56 -05:00
9 changed files with 87 additions and 95 deletions

View File

@@ -244,8 +244,6 @@ project(":desktop"){
implementation project(":core") implementation project(":core")
implementation arcModule("extensions:profiling") implementation arcModule("extensions:profiling")
implementation arcModule("extensions:discord") implementation arcModule("extensions:discord")
implementation arcModule("natives:natives-filedialogs")
implementation arcModule("extensions:filedialogs")
implementation arcModule("natives:natives-desktop") implementation arcModule("natives:natives-desktop")
implementation arcModule("natives:natives-freetype-desktop") implementation arcModule("natives:natives-freetype-desktop")
@@ -253,7 +251,7 @@ project(":desktop"){
implementation "com.github.Anuken:steamworks4j:$steamworksVersion" implementation "com.github.Anuken:steamworks4j:$steamworksVersion"
implementation arcModule("backends:backend-sdl") implementation arcModule("backends:backend-sdl3")
annotationProcessor 'com.github.Anuken:jabel:0.9.0' annotationProcessor 'com.github.Anuken:jabel:0.9.0'
} }
} }

View File

@@ -140,10 +140,10 @@ public class MapObjectivesDialog extends BaseDialog{
setInterpreter(Team.class, (cont, name, type, field, remover, indexer, get, set) -> { setInterpreter(Team.class, (cont, name, type, field, remover, indexer, get, set) -> {
name(cont, name, remover, indexer); name(cont, name, remover, indexer);
cont.table(t -> t.left().button( cont.table(t -> t.left().button(
b -> b.image(Tex.whiteui).size(iconSmall).update(i -> i.setColor(get.get().color)), b -> b.image(Tex.whiteui).update(i -> i.setColor(get.get().color)).grow(),
Styles.squarei, Styles.squarei,
() -> showTeamSelect(set) () -> showTeamSelect(set)
).fill().pad(4f)).growX().fillY(); ).margin(4f).pad(4f).size(50f)).growX().fillY();
}); });
setProvider(Color.class, (type, cons) -> cons.get(Pal.accent.cpy())); setProvider(Color.class, (type, cons) -> cons.get(Pal.accent.cpy()));

View File

@@ -304,7 +304,7 @@ public class GameService{
}); });
Events.on(UnitCreateEvent.class, e -> { Events.on(UnitCreateEvent.class, e -> {
if(campaign()){ if(campaign() && e.unit.team == state.rules.defaultTeam){
if(unitsBuilt.add(e.unit.type.name)){ if(unitsBuilt.add(e.unit.type.name)){
SStat.unitTypesBuilt.max(content.units().count(u -> unitsBuilt.contains(u.name) && !u.isHidden())); SStat.unitTypesBuilt.max(content.units().count(u -> unitsBuilt.contains(u.name) && !u.isHidden()));
save(); save();
@@ -316,6 +316,29 @@ public class GameService{
} }
}); });
Events.on(SaveLoadEvent.class, e -> Core.app.post(() -> Core.app.post(() -> {
if(campaign()){
boolean added = false;
for(UnitType type : Vars.content.units()){
var all = state.rules.defaultTeam.data().getUnits(type);
if(all != null && all.size > 0){
if(t5s.contains(type)){
buildT5.complete();
}
if(unitsBuilt.add(type.name)){
added = true;
}
}
}
if(added){
SStat.unitTypesBuilt.max(content.units().count(u -> unitsBuilt.contains(u.name) && !u.isHidden()));
save();
}
}
})));
Events.on(UnitControlEvent.class, e -> { Events.on(UnitControlEvent.class, e -> {
if(e.unit instanceof BlockUnitc unit && unit.tile().block == Blocks.router){ if(e.unit instanceof BlockUnitc unit && unit.tile().block == Blocks.router){
becomeRouter.complete(); becomeRouter.complete();

View File

@@ -426,12 +426,6 @@ public class SettingsMenuDialog extends BaseDialog{
if(!mobile){ if(!mobile){
graphics.checkPref("vsync", true, b -> Core.graphics.setVSync(b)); graphics.checkPref("vsync", true, b -> Core.graphics.setVSync(b));
graphics.checkPref("fullscreen", false, b -> { graphics.checkPref("fullscreen", false, b -> {
if(b && settings.getBool("borderlesswindow")){
Core.graphics.setWindowedMode(Core.graphics.getWidth(), Core.graphics.getHeight());
settings.put("borderlesswindow", false);
graphics.rebuild();
}
if(b){ if(b){
Core.graphics.setFullscreen(); Core.graphics.setFullscreen();
}else{ }else{
@@ -439,24 +433,12 @@ public class SettingsMenuDialog extends BaseDialog{
} }
}); });
graphics.checkPref("borderlesswindow", false, b -> {
if(b && settings.getBool("fullscreen")){
Core.graphics.setWindowedMode(Core.graphics.getWidth(), Core.graphics.getHeight());
settings.put("fullscreen", false);
graphics.rebuild();
}
Core.graphics.setBorderless(b);
});
Core.graphics.setVSync(Core.settings.getBool("vsync")); Core.graphics.setVSync(Core.settings.getBool("vsync"));
if(Core.settings.getBool("fullscreen")){ if(Core.settings.getBool("fullscreen")){
Core.app.post(() -> Core.graphics.setFullscreen()); Core.app.post(() -> Core.graphics.setFullscreen());
} }
if(Core.settings.getBool("borderlesswindow")){
Core.app.post(() -> Core.graphics.setBorderless(true));
}
}else if(!ios){ }else if(!ios){
graphics.checkPref("landscape", false, b -> { graphics.checkPref("landscape", false, b -> {
if(b){ if(b){

View File

@@ -10,7 +10,7 @@ import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.io.*; import arc.util.io.*;
import mindustry.Vars; import mindustry.*;
import mindustry.ai.types.*; import mindustry.ai.types.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
@@ -18,6 +18,7 @@ import mindustry.ctype.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.game.EventType.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.io.*; import mindustry.io.*;
@@ -547,6 +548,8 @@ public class UnitAssembler extends PayloadBlock{
progress = 0f; progress = 0f;
Fx.unitAssemble.at(spawn.x, spawn.y, rotdeg() - 90f, plan.unit); Fx.unitAssemble.at(spawn.x, spawn.y, rotdeg() - 90f, plan.unit);
blocks.clear(); blocks.clear();
Events.fire(new UnitCreateEvent(unit, this));
} }
@Override @Override

View File

@@ -3,10 +3,8 @@ package mindustry.desktop;
import arc.*; import arc.*;
import arc.Files.*; import arc.Files.*;
import arc.backend.sdl.*; import arc.backend.sdl.*;
import arc.backend.sdl.jni.*;
import arc.discord.*; import arc.discord.*;
import arc.discord.DiscordRPC.*; import arc.discord.DiscordRPC.*;
import arc.filedialogs.*;
import arc.files.*; import arc.files.*;
import arc.func.*; import arc.func.*;
import arc.math.*; import arc.math.*;
@@ -17,7 +15,7 @@ import arc.util.Log.*;
import arc.util.serialization.*; import arc.util.serialization.*;
import com.codedisaster.steamworks.*; import com.codedisaster.steamworks.*;
import mindustry.*; import mindustry.*;
import mindustry.core.*; import mindustry.core.Version;
import mindustry.desktop.steam.*; import mindustry.desktop.steam.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -28,6 +26,9 @@ import mindustry.net.Net.*;
import mindustry.service.*; import mindustry.service.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.ui.dialogs.*; import mindustry.ui.dialogs.*;
import org.lwjgl.*;
import org.lwjgl.sdl.*;
import org.lwjgl.system.*;
import java.io.*; import java.io.*;
@@ -55,6 +56,9 @@ public class DesktopLauncher extends ClientLauncher{
coreProfile = true; coreProfile = true;
width = 900; width = 900;
height = 700; height = 700;
this.appName = "Mindustry";
this.appIdentifier = "io.anuke.mindustry";
this.appVersion = Version.buildString();
//on Windows, Intel drivers might be buggy with OpenGL 3.x, so only use 2.x. See https://github.com/Anuken/Mindustry/issues/11041 //on Windows, Intel drivers might be buggy with OpenGL 3.x, so only use 2.x. See https://github.com/Anuken/Mindustry/issues/11041
if(IntelGpuCheck.wasIntel()){ if(IntelGpuCheck.wasIntel()){
@@ -328,57 +332,39 @@ public class DesktopLauncher extends ClientLauncher{
@Override @Override
public void showFileChooser(boolean open, String title, String extension, Cons<Fi> cons){ public void showFileChooser(boolean open, String title, String extension, Cons<Fi> cons){
showNativeFileChooser(title, open, cons, extension); showNativeFileChooser(open, cons, extension);
} }
@Override @Override
public void showMultiFileChooser(Cons<Fi> cons, String... extensions){ public void showMultiFileChooser(Cons<Fi> cons, String... extensions){
showNativeFileChooser("@open", true, cons, extensions); showNativeFileChooser(true, cons, extensions);
} }
void showNativeFileChooser(String title, boolean open, Cons<Fi> cons, String... shownExtensions){ void showNativeFileChooser(boolean open, Cons<Fi> cons, String... shownExtensions){
String formatted = (title.startsWith("@") ? Core.bundle.get(title.substring(1)) : title).replaceAll("\"", "'");
//this should never happen unless someone is being dumb with the parameters
String[] ext = shownExtensions == null || shownExtensions.length == 0 ? new String[]{""} : shownExtensions; String[] ext = shownExtensions == null || shownExtensions.length == 0 ? new String[]{""} : shownExtensions;
if(OS.isLinux){ SDL_DialogFileFilter.Buffer filters = SDL_DialogFileFilter.calloc(ext.length);
showZenity(open, formatted, shownExtensions, cons, () -> Platform.defaultFileDialog(open, title, ext[0], cons)); try(MemoryStack stack = MemoryStack.stackPush()){
return;
}
//native file dialog
Threads.daemon(() -> {
try{
FileDialogs.loadNatives();
String result;
String[] patterns = new String[ext.length];
for(int i = 0; i < ext.length; i++){ for(int i = 0; i < ext.length; i++){
patterns[i] = "*." + ext[i]; String extName = ext[i];
var filter = SDL_DialogFileFilter.calloc(stack)
.name(MemoryUtil.memUTF8(extName.isEmpty() ? "All Files" : "." + extName + " files"))
.pattern(MemoryUtil.memUTF8(extName.isEmpty() ? "*" : extName));
filters.put(i, filter);
} }
//on MacOS, .msav is not properly recognized until I put garbage into the array?
if(patterns.length == 1 && OS.isMac && open){
patterns = new String[]{"", "*." + ext[0]};
} }
SDL_DialogFileCallbackI callback = (userData, files, filter) -> {
if(files != 0){
PointerBuffer pointerBuffer = MemoryUtil.memPointerBuffer(files, 1);
long firstFile = pointerBuffer.get();
if(firstFile != 0){
String result = MemoryUtil.memUTF8(firstFile);
if(open){
result = FileDialogs.openFileDialog(formatted, FileChooser.getLastDirectory().absolutePath(), patterns, "." + ext[0] + " files", false);
}else{
result = FileDialogs.saveFileDialog(formatted, FileChooser.getLastDirectory().child("file." + ext[0]).absolutePath(), patterns, "." + ext[0] + " files");
}
if(result == null) return;
if(result.length() > 1 && result.contains("\n")){
result = result.split("\n")[0];
}
//cancelled selection, ignore result
if(result.isEmpty() || result.equals("\n")) return; if(result.isEmpty() || result.equals("\n")) return;
if(result.endsWith("\n")) result = result.substring(0, result.length() - 1); if(result.endsWith("\n")) result = result.substring(0, result.length() - 1);
if(result.contains("\n")) throw new IOException("invalid input: \"" + result + "\""); if(result.contains("\n")) return;
Fi file = Core.files.absolute(result); Fi file = Core.files.absolute(result);
Core.app.post(() -> { Core.app.post(() -> {
@@ -390,17 +376,17 @@ public class DesktopLauncher extends ClientLauncher{
cons.get(file); cons.get(file);
} }
}); });
}catch(Throwable error){ }
Log.err("Failure to execute native file chooser", error); }
Core.app.post(() -> { };
if(ext.length > 1){
showMultiFileChooser(cons, ext); if(open){
SDLDialog.SDL_ShowOpenFileDialog(callback, 0, ((SdlApplication)Core.app).getWindow(), filters, FileChooser.getLastDirectory().absolutePath(), false);
}else{ }else{
Platform.defaultFileDialog(open, formatted, ext[0], cons); SDLDialog.SDL_ShowSaveFileDialog(callback, 0, ((SdlApplication)Core.app).getWindow(), filters, FileChooser.getLastDirectory().absolutePath() + "/" + "export." + ext[0]);
} }
});
} filters.free();
});
} }
@@ -580,6 +566,6 @@ public class DesktopLauncher extends ClientLauncher{
} }
private static void message(String message){ private static void message(String message){
SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MESSAGEBOX_ERROR, "oh no", message); SDLMessageBox.SDL_ShowSimpleMessageBox(SDLMessageBox.SDL_MESSAGEBOX_ERROR, "oh no", message, 0);
} }
} }

View File

@@ -1,7 +1,7 @@
package mindustry.desktop; package mindustry.desktop;
import arc.backend.sdl.jni.*;
import arc.util.*; import arc.util.*;
import org.lwjgl.sdl.*;
import javax.swing.*; import javax.swing.*;
@@ -12,7 +12,7 @@ public class ErrorDialog{
Log.err(text); Log.err(text);
try{ try{
//will fail in the future on 32-bit platforms as no natives will be loaded //will fail in the future on 32-bit platforms as no natives will be loaded
SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MESSAGEBOX_ERROR, "it's over", text); SDLMessageBox.SDL_ShowSimpleMessageBox(SDLMessageBox.SDL_MESSAGEBOX_ERROR, "it's over", text, 0);
}catch(Throwable error){ }catch(Throwable error){
try{ try{
//usually won't work on packaged JVMs, but I won't be distributing those with 32 bit windows anyway //usually won't work on packaged JVMs, but I won't be distributing those with 32 bit windows anyway

View File

@@ -26,4 +26,4 @@ org.gradle.caching=true
org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.socketTimeout=100000
org.gradle.internal.http.connectionTimeout=100000 org.gradle.internal.http.connectionTimeout=100000
android.enableR8.fullMode=false android.enableR8.fullMode=false
archash=a3c7d2cbf3 archash=f9a551ad15