mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-11 06:11:50 +09:00
bootstrapper for the App so that the user can change the max heap in-game
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: net.torvald.terrarum.App
|
||||
Main-Class: net.torvald.terrarum.Principii
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.badlogic.gdx.Input
|
||||
object DefaultConfig {
|
||||
|
||||
val hashMap = hashMapOf<String, Any>(
|
||||
"jvm_xmx" to 8,
|
||||
"displayfps" to 0, // 0: no limit, non-zero: limit
|
||||
"displayfpsidle" to 0, // 0: no limit, non-zero: limit
|
||||
"displaycolourdepth" to 8,
|
||||
@@ -21,7 +22,7 @@ object DefaultConfig {
|
||||
"language" to App.getSysLang(),
|
||||
"notificationshowuptime" to 4096, // 4s
|
||||
"selecteditemnameshowuptime" to 4096, // 4s
|
||||
"autosaveinterval" to 262144, // 4m22s
|
||||
"autosaveinterval" to 300000, // 5s
|
||||
"multithread" to true,
|
||||
|
||||
"showhealthmessageonstartup" to true,
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.badlogic.gdx.utils.JsonValue
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.App.setToGameConfig
|
||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||
import net.torvald.terrarum.blockproperties.WireCodex
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
|
||||
370
src/net/torvald/terrarum/Principii.java
Normal file
370
src/net/torvald/terrarum/Principii.java
Normal file
@@ -0,0 +1,370 @@
|
||||
package net.torvald.terrarum;
|
||||
|
||||
import com.badlogic.gdx.utils.JsonValue;
|
||||
import net.torvald.terrarum.serialise.WriteConfig;
|
||||
import net.torvald.terrarum.utils.JsonFetcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-06-22.
|
||||
*/
|
||||
public class Principii {
|
||||
|
||||
public static KVHashMap gameConfig = new KVHashMap();
|
||||
|
||||
public static String OSName = System.getProperty("os.name");
|
||||
|
||||
public static String operationSystem;
|
||||
/** %appdata%/Terrarum, without trailing slash */
|
||||
public static String defaultDir;
|
||||
/** defaultDir + "/config.json" */
|
||||
public static String configDir;
|
||||
|
||||
|
||||
public static void getDefaultDirRoot() {
|
||||
String OS = OSName.toUpperCase();
|
||||
if (OS.contains("WIN")) {
|
||||
operationSystem = "WINDOWS";
|
||||
defaultDir = System.getenv("APPDATA") + "/Terrarum";
|
||||
}
|
||||
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";
|
||||
}
|
||||
else if (OS.contains("NUX") || OS.contains("NIX") || OS.contains("BSD")) {
|
||||
operationSystem = "LINUX";
|
||||
defaultDir = System.getProperty("user.home") + "/.Terrarum";
|
||||
}
|
||||
else if (OS.contains("SUNOS")) {
|
||||
operationSystem = "SOLARIS";
|
||||
defaultDir = System.getProperty("user.home") + "/.Terrarum";
|
||||
}
|
||||
else {
|
||||
operationSystem = "UNKNOWN";
|
||||
defaultDir = System.getProperty("user.home") + "/.Terrarum";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
boolean devMode = false;
|
||||
|
||||
// if -ea flag is set, turn on all the debug prints
|
||||
try {
|
||||
assert false;
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
devMode = true;
|
||||
}
|
||||
|
||||
String runtimeDir = null;
|
||||
String extracmd = devMode ? " -ea" : "";
|
||||
String OS = OSName.toUpperCase();
|
||||
String CPUARCH = System.getProperty("os.arch").toUpperCase();
|
||||
if (OS.contains("WIN")) {
|
||||
if (CPUARCH.equals("AMD64"))
|
||||
runtimeDir = "runtime-windows-x86";
|
||||
}
|
||||
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
|
||||
extracmd += " -XstartOnFirstThread";
|
||||
if (CPUARCH.equals("AMD64"))
|
||||
runtimeDir = "runtime-osx-x86";
|
||||
else if (CPUARCH.equals("AARCH64"))
|
||||
runtimeDir = "runtime-osx-arm";
|
||||
}
|
||||
else {
|
||||
extracmd += " -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd";
|
||||
if (CPUARCH.equals("AMD64") || CPUARCH.equals("X86"))
|
||||
runtimeDir = "runtime-linux-x86";
|
||||
else if (CPUARCH.equals("AARCH64"))
|
||||
runtimeDir = "runtime-linux-arm";
|
||||
}
|
||||
|
||||
if (runtimeDir == null) {
|
||||
// TODO show error message of incompatible processor (possibly 32-bit?)
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
getDefaultDirRoot();
|
||||
configDir = defaultDir + "/config.json";
|
||||
|
||||
initialiseConfig();
|
||||
readConfigJson();
|
||||
|
||||
|
||||
int xmx = getConfigInt("jvm_xmx");
|
||||
|
||||
try {
|
||||
Process proc = Runtime.getRuntime().exec("java"+extracmd+" -Xms1G -Xmx"+xmx+"G -cp ./out/TerrarumBuild.jar net.torvald.terrarum.App");
|
||||
|
||||
// TODO redirect proc's PrintStream to System.out
|
||||
int size = 0;
|
||||
byte[] buffer = new byte[1024];
|
||||
while ((size = proc.getInputStream().read(buffer)) != -1) {
|
||||
System.out.write(buffer, 0, size);
|
||||
}
|
||||
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// CONFIG //
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return config from config set. If the config does not exist, default value will be returned.
|
||||
* @param key
|
||||
* *
|
||||
* @return Config from config set or default config if it does not exist.
|
||||
* *
|
||||
* @throws NullPointerException if the specified config simply does not exist.
|
||||
*/
|
||||
public static int getConfigInt(String key) {
|
||||
Object cfg = getConfigMaster(key);
|
||||
|
||||
if (cfg instanceof Integer) return ((int) cfg);
|
||||
|
||||
double value = (double) cfg;
|
||||
|
||||
if (Math.abs(value % 1.0) < 0.00000001)
|
||||
return (int) Math.round(value);
|
||||
return ((int) cfg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return config from config set. If the config does not exist, default value will be returned.
|
||||
* @param key
|
||||
* *
|
||||
* @return Config from config set or default config if it does not exist.
|
||||
* *
|
||||
* @throws NullPointerException if the specified config simply does not exist.
|
||||
*/
|
||||
public static double getConfigDouble(String key) {
|
||||
Object cfg = getConfigMaster(key);
|
||||
return (cfg instanceof Integer) ? (((Integer) cfg) * 1.0) : ((double) (cfg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return config from config set. If the config does not exist, default value will be returned.
|
||||
* @param key
|
||||
* *
|
||||
* @return Config from config set or default config if it does not exist.
|
||||
* *
|
||||
* @throws NullPointerException if the specified config simply does not exist.
|
||||
*/
|
||||
public static String getConfigString(String key) {
|
||||
Object cfg = getConfigMaster(key);
|
||||
return ((String) cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return config from config set. If the config does not exist, default value will be returned.
|
||||
* @param key
|
||||
* *
|
||||
* @return Config from config set or default config if it does not exist. If the default value is undefined, will return false.
|
||||
*/
|
||||
public static boolean getConfigBoolean(String key) {
|
||||
try {
|
||||
Object cfg = getConfigMaster(key);
|
||||
return ((boolean) cfg);
|
||||
}
|
||||
catch (NullPointerException keyNotFound) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*public static int[] getConfigIntArray(String key) {
|
||||
Object cfg = getConfigMaster(key);
|
||||
if (cfg instanceof JsonArray) {
|
||||
JsonArray jsonArray = ((JsonArray) cfg).getAsJsonArray();
|
||||
//return IntArray(jsonArray.size(), { i -> jsonArray[i].asInt })
|
||||
int[] intArray = new int[jsonArray.size()];
|
||||
for (int i = 0; i < jsonArray.size(); i++) {
|
||||
intArray[i] = jsonArray.get(i).getAsInt();
|
||||
}
|
||||
return intArray;
|
||||
}
|
||||
else
|
||||
return ((int[]) cfg);
|
||||
}*/
|
||||
|
||||
public static double[] getConfigDoubleArray(String key) {
|
||||
Object cfg = getConfigMaster(key);
|
||||
return ((double[]) cfg);
|
||||
}
|
||||
|
||||
public static int[] getConfigIntArray(String key) {
|
||||
double[] a = getConfigDoubleArray(key);
|
||||
int[] r = new int[a.length];
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
r[i] = ((int) a[i]);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*public static String[] getConfigStringArray(String key) {
|
||||
Object cfg = getConfigMaster(key);
|
||||
if (cfg instanceof JsonArray) {
|
||||
JsonArray jsonArray = ((JsonArray) cfg).getAsJsonArray();
|
||||
//return IntArray(jsonArray.size(), { i -> jsonArray[i].asInt })
|
||||
String[] intArray = new String[jsonArray.size()];
|
||||
for (int i = 0; i < jsonArray.size(); i++) {
|
||||
intArray[i] = jsonArray.get(i).getAsString();
|
||||
}
|
||||
return intArray;
|
||||
}
|
||||
else
|
||||
return ((String[]) cfg);
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Get config from config file. If the entry does not exist, get from defaults; if the entry is not in the default, NullPointerException will be thrown
|
||||
*/
|
||||
private static HashMap<String, Object> getDefaultConfig() {
|
||||
return DefaultConfig.INSTANCE.getHashMap();
|
||||
}
|
||||
|
||||
private static Object getConfigMaster(String key1) {
|
||||
String key = key1.toLowerCase();
|
||||
|
||||
Object config;
|
||||
try {
|
||||
config = gameConfig.get(key);
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
config = null;
|
||||
}
|
||||
|
||||
Object defaults;
|
||||
try {
|
||||
defaults = getDefaultConfig().get(key);
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
defaults = null;
|
||||
}
|
||||
|
||||
if (config == null) {
|
||||
if (defaults == null) {
|
||||
throw new NullPointerException("key not found: '" + key + "'");
|
||||
}
|
||||
else {
|
||||
return defaults;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setConfig(String key, Object value) {
|
||||
gameConfig.set(key.toLowerCase(), value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true on successful, false on failure.
|
||||
*/
|
||||
private static Boolean readConfigJson() {
|
||||
System.out.println("Config file: " + configDir);
|
||||
|
||||
|
||||
try {
|
||||
// read from disk and build config from it
|
||||
JsonValue map = JsonFetcher.INSTANCE.invoke(configDir);
|
||||
|
||||
// make config
|
||||
for (JsonValue entry = map.child; entry != null; entry = entry.next) {
|
||||
setToGameConfigForced(entry, null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (IOException e) {
|
||||
// write default config to game dir. Call th.is method again to read config from it.
|
||||
try {
|
||||
createConfigJson();
|
||||
}
|
||||
catch (IOException e1) {
|
||||
System.out.println("[Bootstrap] Unable to write config.json file");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void createConfigJson() throws IOException {
|
||||
File configFile = new File(configDir);
|
||||
|
||||
if (!configFile.exists() || configFile.length() == 0L) {
|
||||
WriteConfig.INSTANCE.invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads DefaultConfig to populate the gameConfig
|
||||
*/
|
||||
private static void initialiseConfig() {
|
||||
for (Map.Entry<String, Object> entry : DefaultConfig.INSTANCE.getHashMap().entrySet()) {
|
||||
gameConfig.set(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will forcibly overwrite previously loaded config value.
|
||||
*
|
||||
* Key naming convention will be 'modName:propertyName'; if modName is null, the key will be just propertyName.
|
||||
*
|
||||
* @param value JsonValue (the key-value pair)
|
||||
* @param modName module name, nullable
|
||||
*/
|
||||
public static void setToGameConfigForced(JsonValue value, String modName) {
|
||||
gameConfig.set((modName == null) ? value.name : modName+":"+value.name,
|
||||
value.isArray() ? value.asDoubleArray() :
|
||||
value.isDouble() ? value.asDouble() :
|
||||
value.isBoolean() ? value.asBoolean() :
|
||||
value.isLong() ? value.asInt() :
|
||||
value.asString()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will not overwrite previously loaded config value.
|
||||
*
|
||||
* Key naming convention will be 'modName:propertyName'; if modName is null, the key will be just propertyName.
|
||||
*
|
||||
* @param value JsonValue (the key-value pair)
|
||||
* @param modName module name, nullable
|
||||
*/
|
||||
public static void setToGameConfig(JsonValue value, String modName) {
|
||||
String key = (modName == null) ? value.name : modName+":"+value.name;
|
||||
if (gameConfig.get(key) == null) {
|
||||
gameConfig.set(key,
|
||||
value.isArray() ? value.asDoubleArray() :
|
||||
value.isDouble() ? value.asDouble() :
|
||||
value.isBoolean() ? value.asBoolean() :
|
||||
value.isLong() ? value.asInt() :
|
||||
value.asString()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -109,7 +109,8 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
|
||||
UIItemSpinner(this, x, y, App.getConfigDouble(optionName), arg[1].toDouble(), arg[2].toDouble(), arg[3].toDouble(), spinnerWidth, numberToTextFunction = { "${((it as Double)*100).toInt()}%" }) to { it: UIItem, optionStr: String ->
|
||||
(it as UIItemSpinner).selectionChangeListener = {
|
||||
App.setConfig(optionStr, it)
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args.startsWith("typeinint")) {
|
||||
// val arg = args.split(',') // args: none
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.Camera
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.ceilInt
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.ui.*
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import net.torvald.unicode.TIMES
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-06-22.
|
||||
*/
|
||||
class UIPerformanceControlPanel(remoCon: UIRemoCon?) : UICanvas() {
|
||||
|
||||
|
||||
private val linegap = 14
|
||||
private val panelgap = 20
|
||||
|
||||
private val rowheight = 20 + linegap
|
||||
|
||||
private val h1MarginTop = 16
|
||||
private val h1MarginBottom = 4
|
||||
|
||||
private val options = arrayOf(
|
||||
arrayOf("", { Lang["MENU_OPTIONS_GAMEPLAY"] }, "h1"),
|
||||
arrayOf("autosaveinterval", { Lang["MENU_OPTIONS_AUTOSAVE"] + " (${Lang["CONTEXT_TIME_MINUTE_PLURAL"]})" }, "spinnerimul,5,120,5,60000"),
|
||||
arrayOf("", { Lang["MENU_OPTIONS_PERFORMANCE"] }, "h1"),
|
||||
arrayOf("jvm_xmx", { Lang["MENU_OPTIONS_JVM_HEAP_MAX"] + " (GB)" }, "spinner,2,32,1"),
|
||||
arrayOf("", { "(${Lang["MENU_LABEL_RESTART_REQUIRED"]})" }, "p"),
|
||||
)
|
||||
|
||||
private val optionsYpos = IntArray(options.size + 1)
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("gui_hrule") {
|
||||
TextureRegionPack(Gdx.files.internal("assets/graphics/gui/hrule.tga"), 216, 20)
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
|
||||
|
||||
|
||||
var akku = 0
|
||||
options.forEachIndexed { index, row ->
|
||||
val option = row[2]
|
||||
|
||||
if (index > 0 && option == "h1") {
|
||||
akku += h1MarginTop
|
||||
}
|
||||
|
||||
optionsYpos[index] = akku
|
||||
|
||||
akku += when (option) {
|
||||
"h1" -> rowheight + h1MarginBottom
|
||||
else -> rowheight
|
||||
}
|
||||
}
|
||||
optionsYpos[optionsYpos.lastIndex] = akku
|
||||
}
|
||||
override var width = 560
|
||||
override var height = optionsYpos.last()
|
||||
|
||||
private val hrule = CommonResourcePool.getAsTextureRegionPack("gui_hrule")
|
||||
|
||||
private val spinnerWidth = 140
|
||||
private val drawX = (Toolkit.drawWidth - width) / 2
|
||||
private val drawY = (App.scr.height - height) / 2
|
||||
|
||||
// @return Pair of <UIItem, Init job for the item>
|
||||
private fun makeButton(args: String, x: Int, y: Int, optionName: String): Pair<UIItem, (UIItem, String) -> Unit> {
|
||||
return if (args.startsWith("h1") || args.startsWith("p")) {
|
||||
(object : UIItem(this, x, y) {
|
||||
override val width = 1
|
||||
override val height = 1
|
||||
override fun dispose() {}
|
||||
}) to { _, _ -> }
|
||||
}
|
||||
else if (args.startsWith("toggle")) {
|
||||
UIItemToggleButton(this, x, y, spinnerWidth, App.getConfigBoolean(optionName)) to { it: UIItem, optionStr: String ->
|
||||
(it as UIItemToggleButton).clickOnceListener = { _, _ ->
|
||||
it.toggle()
|
||||
App.setConfig(optionStr, it.getStatus())
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args.startsWith("spinner,")) {
|
||||
val arg = args.split(',')
|
||||
UIItemSpinner(this, x, y, App.getConfigInt(optionName), arg[1].toInt(), arg[2].toInt(), arg[3].toInt(), spinnerWidth, numberToTextFunction = { "${it.toLong()}" }) to { it: UIItem, optionStr: String ->
|
||||
(it as UIItemSpinner).selectionChangeListener = {
|
||||
App.setConfig(optionStr, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args.startsWith("spinnerd,")) {
|
||||
val arg = args.split(',')
|
||||
UIItemSpinner(this, x, y, App.getConfigDouble(optionName), arg[1].toDouble(), arg[2].toDouble(), arg[3].toDouble(), spinnerWidth, numberToTextFunction = { "${((it as Double)*100).toInt()}%" }) to { it: UIItem, optionStr: String ->
|
||||
(it as UIItemSpinner).selectionChangeListener = {
|
||||
App.setConfig(optionStr, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args.startsWith("spinnerimul,")) {
|
||||
val arg = args.split(',')
|
||||
val mult = arg[4].toInt()
|
||||
UIItemSpinner(this, x, y, App.getConfigInt(optionName) / mult, arg[1].toInt(), arg[2].toInt(), arg[3].toInt(), spinnerWidth, numberToTextFunction = { "${it.toLong()}" }) to { it: UIItem, optionStr: String ->
|
||||
(it as UIItemSpinner).selectionChangeListener = {
|
||||
App.setConfig(optionStr, it.toInt() * mult)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args.startsWith("typeinint")) {
|
||||
// val arg = args.split(',') // args: none
|
||||
UIItemTextLineInput(this, x, y, spinnerWidth, { "${App.getConfigInt(optionName)}" }, InputLenCap(4, InputLenCap.CharLenUnit.CODEPOINTS), { it.headkey in Input.Keys.NUM_0..Input.Keys.NUM_9 || it.headkey == Input.Keys.BACKSPACE }) to { it: UIItem, optionStr: String ->
|
||||
(it as UIItemTextLineInput).textCommitListener = {
|
||||
App.setConfig(optionStr, it.toInt()) // HAXXX!!!
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args.startsWith("typeinres")) {
|
||||
val keyWidth = optionName.substringBefore(',')
|
||||
val keyHeight = optionName.substringAfter(',')
|
||||
UIItemTextLineInput(this, x, y, spinnerWidth, { "${App.getConfigInt(keyWidth)}x${App.getConfigInt(keyHeight)}" }, InputLenCap(9, InputLenCap.CharLenUnit.CODEPOINTS), { it.headkey == Input.Keys.ENTER || it.headkey == Input.Keys.BACKSPACE || it.character?.matches(Regex("[0-9xX]")) == true }, UIItemTextButton.Companion.Alignment.CENTRE) to { it: UIItem, optionStr: String ->
|
||||
(it as UIItemTextLineInput).textCommitListener = { text ->
|
||||
val text = text.lowercase()
|
||||
if (text.matches(Regex("""[0-9]+x[0-9]+"""))) {
|
||||
it.markAsNormal()
|
||||
val width = text.substringBefore('x').toInt()
|
||||
val height = text.substringAfter('x').toInt()
|
||||
App.setConfig(keyWidth, width)
|
||||
App.setConfig(keyHeight, height)
|
||||
}
|
||||
else it.markAsInvalid()
|
||||
}
|
||||
}
|
||||
}
|
||||
else throw IllegalArgumentException(args)
|
||||
}
|
||||
|
||||
private val optionControllers: List<Pair<UIItem, (UIItem, String) -> Unit>> = options.mapIndexed { index, strings ->
|
||||
makeButton(options[index][2] as String,
|
||||
drawX + width / 2 + panelgap,
|
||||
drawY - 2 + optionsYpos[index],
|
||||
options[index][0] as String
|
||||
)
|
||||
}
|
||||
|
||||
init {
|
||||
optionControllers.forEachIndexed { i, it ->
|
||||
it.second.invoke(it.first, options[i][0] as String)
|
||||
addUIitem(it.first)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateUI(delta: Float) {
|
||||
uiItems.forEach { it.update(delta) }
|
||||
}
|
||||
|
||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||
/*batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, drawX, drawY, width, height)
|
||||
|
||||
batch.color = CELL_COL
|
||||
Toolkit.fillArea(batch, drawX, drawY, width, height)*/
|
||||
|
||||
options.forEachIndexed { index, strings ->
|
||||
val mode = strings[2]
|
||||
|
||||
val font = if (mode == "h1") App.fontUITitle else App.fontGame
|
||||
|
||||
val label = (strings[1] as () -> String).invoke()
|
||||
val labelWidth = font.getWidth(label)
|
||||
batch.color = when (mode) {
|
||||
"h1" -> Toolkit.Theme.COL_MOUSE_UP
|
||||
"p" -> Color.LIGHT_GRAY
|
||||
else -> Color.WHITE
|
||||
}
|
||||
|
||||
val xpos = if (mode == "p" || mode == "h1")
|
||||
drawX + (width - labelWidth)/2 // centre-aligned
|
||||
else
|
||||
drawX + width/2 - panelgap - labelWidth // right aligned at the middle of the panel, offsetted by panelgap
|
||||
|
||||
font.draw(batch, label, xpos.toFloat(), drawY + optionsYpos[index] - 2f)
|
||||
|
||||
// draw hrule
|
||||
if (mode == "h1") {
|
||||
val ruleWidth = ((width - 24 - labelWidth) / 2).toFloat()
|
||||
batch.draw(hrule.get(0,0), xpos - 24f - ruleWidth, drawY + optionsYpos[index].toFloat(), ruleWidth, hrule.tileH.toFloat())
|
||||
batch.draw(hrule.get(0,1), xpos + 24f + labelWidth, drawY + optionsYpos[index].toFloat(), ruleWidth, hrule.tileH.toFloat())
|
||||
}
|
||||
}
|
||||
uiItems.forEach { it.render(batch, camera) }
|
||||
|
||||
if (App.getConfigBoolean("fx_streamerslayout")) {
|
||||
val xstart = App.scr.width - App.scr.chatWidth
|
||||
|
||||
batch.color = Color(0x00f8ff_40)
|
||||
Toolkit.fillArea(batch, xstart + 1, 1, App.scr.chatWidth - 2, App.scr.height - 2)
|
||||
|
||||
batch.color = Toolkit.Theme.COL_MOUSE_UP
|
||||
Toolkit.drawBoxBorder(batch, xstart + 1, 1, App.scr.chatWidth - 2, App.scr.height - 2)
|
||||
|
||||
val overlayResTxt = "${(App.scr.chatWidth * App.scr.magn).ceilInt()}$TIMES${App.scr.windowH}"
|
||||
|
||||
App.fontGame.draw(batch, overlayResTxt,
|
||||
(xstart + (App.scr.chatWidth - App.fontGame.getWidth(overlayResTxt)) / 2).toFloat(),
|
||||
((App.scr.height - App.fontGame.lineHeight) / 2).toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ object UITitleRemoConYaml {
|
||||
- MENU_OPTIONS_CONTROLS : net.torvald.terrarum.modulebasegame.ui.UIKeyboardControlPanel
|
||||
- MENU_LABEL_IME : net.torvald.terrarum.modulebasegame.ui.UIIMEConfig
|
||||
- MENU_LABEL_LANGUAGE : net.torvald.terrarum.modulebasegame.ui.UITitleLanguage
|
||||
- GAME_GENRE_MISC : net.torvald.terrarum.modulebasegame.ui.UIPerformanceControlPanel
|
||||
- MENU_MODULES : net.torvald.terrarum.ModOptionsHost
|
||||
- MENU_LABEL_RETURN+WRITETOCONFIG
|
||||
- MENU_MODULES : net.torvald.terrarum.modulebasegame.ui.UITitleModules
|
||||
|
||||
Reference in New Issue
Block a user