mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
custom asset archive loading
This commit is contained in:
@@ -342,6 +342,14 @@ public class App implements ApplicationListener {
|
||||
|
||||
public static boolean hasUpdate = true;
|
||||
|
||||
/**
|
||||
* Path to a specific .tevd assets archive supplied via the --assets command-line argument.
|
||||
* When non-null, this archive is used exclusively; the default ./assets.tevd and the
|
||||
* local ./assets/ directory are both ignored.
|
||||
*/
|
||||
@Nullable
|
||||
public static String overrideAssetArchive = null;
|
||||
|
||||
public static Screen getCurrentScreen() {
|
||||
return currentScreen;
|
||||
}
|
||||
@@ -381,6 +389,17 @@ public class App implements ApplicationListener {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// System.out.println("Arguments: "+String.join(",", args));
|
||||
|
||||
// Parse command-line arguments before anything else
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals("--assets") && i + 1 < args.length) {
|
||||
overrideAssetArchive = args[i + 1];
|
||||
System.out.println("Using custom assets: "+overrideAssetArchive);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
loadedTime_t = getTIME_T();
|
||||
|
||||
updateBogoflops(100_000_000L);
|
||||
@@ -441,7 +460,7 @@ public class App implements ApplicationListener {
|
||||
// load configs
|
||||
getDefaultDirectory();
|
||||
createDirs();
|
||||
AssetCache.INSTANCE.init();
|
||||
AssetCache.INSTANCE.init(overrideAssetArchive);
|
||||
initialiseConfig();
|
||||
readConfigJson();
|
||||
|
||||
|
||||
@@ -19,20 +19,30 @@ import java.io.RandomAccessFile
|
||||
*/
|
||||
object AssetCache {
|
||||
|
||||
private val archivePath = File("./assets.tevd")
|
||||
private val defaultArchivePath = File("./assets.tevd")
|
||||
|
||||
/** Whether we're running from a distribution archive */
|
||||
val isDistribution: Boolean get() = archivePath.exists()
|
||||
val isDistribution: Boolean get() = dom != null
|
||||
|
||||
private var dom: ClusteredFormatDOM? = null
|
||||
|
||||
/**
|
||||
* Open the archive on startup. Call early, after defaultDir is set.
|
||||
*
|
||||
* @param overridePath When non-null, load this specific .tevd archive exclusively,
|
||||
* ignoring both the default ./assets.tevd and the ./assets/ directory.
|
||||
*/
|
||||
fun init() {
|
||||
if (isDistribution) {
|
||||
println("[AssetCache] Distribution mode: opening ${archivePath.path}")
|
||||
dom = ClusteredFormatDOM(RandomAccessFile(archivePath, "r"))
|
||||
@JvmOverloads
|
||||
fun init(overridePath: String? = null) {
|
||||
if (overridePath != null) {
|
||||
val f = File(overridePath)
|
||||
if (!f.exists()) throw FileNotFoundException("Specified assets archive not found: $overridePath")
|
||||
println("[AssetCache] Override archive: opening ${f.path}")
|
||||
dom = ClusteredFormatDOM(RandomAccessFile(f, "r"))
|
||||
println("[AssetCache] Override archive opened successfully")
|
||||
} else if (defaultArchivePath.exists()) {
|
||||
println("[AssetCache] Distribution mode: opening ${defaultArchivePath.path}")
|
||||
dom = ClusteredFormatDOM(RandomAccessFile(defaultArchivePath, "r"))
|
||||
println("[AssetCache] Archive opened successfully")
|
||||
} else {
|
||||
println("[AssetCache] No archive found, using loose assets (development mode)")
|
||||
@@ -41,13 +51,12 @@ object AssetCache {
|
||||
|
||||
/**
|
||||
* Get a Clustfile for a path relative to the assets root.
|
||||
*
|
||||
* Note: nothing guarantees the file's actual existence!
|
||||
*/
|
||||
fun getClustfile(relativePath: String): Clustfile {
|
||||
val path = if (relativePath.startsWith("/")) relativePath else "/$relativePath"
|
||||
return Clustfile(dom!!, path).let {
|
||||
if (!it.exists()) throw FileNotFoundException("Clustfile not exists: /$relativePath")
|
||||
else it
|
||||
}
|
||||
return Clustfile(dom!!, path)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package net.torvald.terrarum
|
||||
|
||||
import com.badlogic.gdx.Files
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.Clustfile
|
||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClustfileInputStream
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
||||
|
||||
/**
|
||||
* A GDX FileHandle backed by a Clustfile from TerranVirtualDisk.
|
||||
* Allows transparent asset loading from .tevd archives using all standard GDX APIs.
|
||||
@@ -30,6 +33,10 @@ class ClustfileHandle(private val clustfile: Clustfile) : FileHandle() {
|
||||
|
||||
override fun path(): String = clustfile.path
|
||||
|
||||
init {
|
||||
type = Files.FileType.Internal // just a dummy value
|
||||
}
|
||||
|
||||
override fun extension(): String {
|
||||
val n = name()
|
||||
val dotIndex = n.lastIndexOf('.')
|
||||
@@ -62,5 +69,12 @@ class ClustfileHandle(private val clustfile: Clustfile) : FileHandle() {
|
||||
return File(clustfile.path)
|
||||
}
|
||||
|
||||
override fun sibling(name: String?): FileHandle {
|
||||
if (name == null) throw GdxRuntimeException("Sibling name must not be null.")
|
||||
val parentPath = clustfile.parent ?: throw GdxRuntimeException("Cannot get the sibling of the root.")
|
||||
val siblingPath = if (parentPath.endsWith("/")) "$parentPath$name" else "$parentPath/$name"
|
||||
return ClustfileHandle(Clustfile(clustfile.DOM, siblingPath))
|
||||
}
|
||||
|
||||
override fun toString(): String = clustfile.path
|
||||
}
|
||||
|
||||
@@ -340,9 +340,7 @@ object ModMgr {
|
||||
}
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
printdbgerr(this, "Module failed to load, skipping: $moduleName")
|
||||
printdbgerr(this, "\t$e")
|
||||
print(App.csiR); e.printStackTrace(System.out); print(App.csi0)
|
||||
printdbgerr(this, "Module failed to load, skipping: $moduleName\nstacktrace:\n${e.stackTraceToString()}")
|
||||
|
||||
logError(LoadErrorType.YOUR_FAULT, moduleName, e)
|
||||
|
||||
@@ -370,7 +368,7 @@ object ModMgr {
|
||||
printmsg(this, "Module processed: $moduleName")
|
||||
}
|
||||
catch (noSuchModule: FileNotFoundException) {
|
||||
printmsgerr(this, "No such module, skipping: $moduleName")
|
||||
printmsgerr(this, "No such module, skipping: $moduleName\nstacktrace:\n${noSuchModule.stackTraceToString()}")
|
||||
|
||||
logError(LoadErrorType.NOT_EVEN_THERE, moduleName, noSuchModule)
|
||||
|
||||
@@ -397,9 +395,7 @@ object ModMgr {
|
||||
// TODO: Instead of skipping module with error, just display the error message onto the face?
|
||||
|
||||
|
||||
printmsgerr(this, "There was an error while loading module $moduleName")
|
||||
printmsgerr(this, "\t$e")
|
||||
print(App.csiR); e.printStackTrace(System.out); print(App.csi0)
|
||||
printmsgerr(this, "There was an error while loading module $moduleName\nstacktrace:\n${e.stackTraceToString()}")
|
||||
|
||||
logError(LoadErrorType.YOUR_FAULT, moduleName, e)
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ import java.util.*;
|
||||
*/
|
||||
public class Principii {
|
||||
|
||||
private static KVHashMap gameConfig = new KVHashMap();
|
||||
private static final KVHashMap gameConfig = new KVHashMap();
|
||||
|
||||
private static String OSName = System.getProperty("os.name");
|
||||
private static final String OSName = System.getProperty("os.name");
|
||||
|
||||
private static String operationSystem;
|
||||
/** %appdata%/Terrarum, without trailing slash */
|
||||
@@ -27,27 +27,29 @@ public class Principii {
|
||||
/** defaultDir + "/config.json" */
|
||||
private static String configDir;
|
||||
|
||||
private static final String GAME_NAME = TerrarumAppConfiguration.INSTANCE.getGAME_NAME_FOR_FILESYSTEM();
|
||||
|
||||
public static void getDefaultDirRoot() {
|
||||
String OS = OSName.toUpperCase();
|
||||
if (OS.contains("WIN")) {
|
||||
operationSystem = "WINDOWS";
|
||||
defaultDir = System.getenv("APPDATA") + "/Terrarum";
|
||||
defaultDir = System.getenv("APPDATA") + "/" + GAME_NAME;
|
||||
}
|
||||
else if (OS.contains("OS X") || OS.contains("MACOS")) { // OpenJDK for mac will still report "Mac OS X" with version number "10.16", even on Big Sur and beyond
|
||||
operationSystem = "OSX";
|
||||
defaultDir = System.getProperty("user.home") + "/Library/Application Support/Terrarum";
|
||||
defaultDir = System.getProperty("user.home") + "/Library/Application Support/" + GAME_NAME;
|
||||
}
|
||||
else if (OS.contains("NUX") || OS.contains("NIX") || OS.contains("BSD")) {
|
||||
operationSystem = "LINUX";
|
||||
defaultDir = System.getProperty("user.home") + "/.Terrarum";
|
||||
defaultDir = System.getProperty("user.home") + "/." + GAME_NAME;
|
||||
}
|
||||
else if (OS.contains("SUNOS")) {
|
||||
operationSystem = "SOLARIS";
|
||||
defaultDir = System.getProperty("user.home") + "/.Terrarum";
|
||||
defaultDir = System.getProperty("user.home") + "/." + GAME_NAME;
|
||||
}
|
||||
else {
|
||||
operationSystem = "UNKNOWN";
|
||||
defaultDir = System.getProperty("user.home") + "/.Terrarum";
|
||||
defaultDir = System.getProperty("user.home") + "/." + GAME_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,8 +137,9 @@ public class Principii {
|
||||
cmd0.add("-Xms1G");
|
||||
cmd0.add("-Xmx"+xmx+"G");
|
||||
cmd0.add("-cp");
|
||||
cmd0.add("./out/TerrarumBuild.jar");
|
||||
cmd0.add("./out/" + TerrarumAppConfiguration.JAR_NAME);
|
||||
cmd0.add(cp);
|
||||
cmd0.addAll(List.of(args));
|
||||
var cmd = cmd0.stream().filter((it) -> !it.isBlank()).toList();
|
||||
|
||||
System.out.println(cmd);
|
||||
|
||||
@@ -17,6 +17,8 @@ object TerrarumAppConfiguration {
|
||||
// CONFIGURATION FOR THE APP ITSELF //
|
||||
//////////////////////////////////////
|
||||
const val GAME_NAME = "Terrarum"
|
||||
const val JAR_NAME = "TerrarumBuild.jar" // must match what's on the buildapp scripts
|
||||
val GAME_NAME_FOR_FILESYSTEM = GAME_NAME.replace(' ', '_')
|
||||
const val COPYRIGHT_DATE_NAME = "© 2013-2026 CuriousToꝛvald (minjaesong)"
|
||||
val COPYRIGHT_LICENSE: String; get() = Lang["COPYRIGHT_GNU_GPL_3"]
|
||||
const val COPYRIGHT_LICENSE_ENGLISH = "Distributed under GNU GPL 3"
|
||||
@@ -38,7 +40,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# Modules are loaded from top to bottom.
|
||||
# Name of the module corresponds with the name of the directory the module is stored in,
|
||||
# typically under:
|
||||
# 1. assets/mods of the installation path (the modules comes with the release of the game)
|
||||
# 1. assets.tevd/mods of the installation path (the modules comes with the release of the game)
|
||||
# 2. %APPDATA%/Modules (the modules installed by the user)
|
||||
# where %APPDATA% is:
|
||||
# Windows -- C:\Users\<username>\AppData\Roaming\Terrarum
|
||||
|
||||
Reference in New Issue
Block a user