Compare commits

...

19 Commits

Author SHA1 Message Date
minjaesong
97d3edf1b9 new instruction for Java 17 deployment 2022-02-10 10:27:40 +09:00
minjaesong
e69cb5845c fixed a bug where barehand digging 'box' would not align as intended 2022-02-09 17:42:25 +09:00
minjaesong
4612493566 adding extra headroom to the assembled sprite so that a large held item wouldn't get cropped 2022-02-07 11:38:26 +09:00
minjaesong
e64bd5d389 fixture ghost is working again 2022-02-07 11:13:31 +09:00
minjaesong
24d6634257 changed world's GENVER spec so that it will always save the game's version number 2022-02-06 19:50:56 +09:00
minjaesong
efe5c49463 serialisation of HRQNG is fixed so it would not make illegal reflective access on Java 17 2022-02-04 11:03:59 +09:00
minjaesong
5d587dcc12 working config panels on esc menu 2022-01-28 12:52:48 +09:00
minjaesong
fe5a4bcfb0 lanternmap will blend when multiple blocks occupy the same block 2022-01-28 11:31:34 +09:00
minjaesong
ff400d1e2f key config menu working on ingame 2022-01-28 10:49:02 +09:00
minjaesong
956c9d44e1 moved essential resources out of the assets directory and into the jar 2022-01-28 10:30:08 +09:00
minjaesong
e3b82ae5b6 console command loading from command list on the module directory 2022-01-28 09:50:05 +09:00
minjaesong
a301ec57ae abandoning the async idea: updating on the main thread is actually faster when it's called often enough -- maybe something to do with the optimisation on runtime? 2022-01-27 18:42:22 +09:00
minjaesong
c500a5ca39 asynchronous lightmap update wip 2022-01-27 17:11:09 +09:00
minjaesong
119b7fc022 particles must be disposed of before overwritten 2022-01-27 12:35:50 +09:00
minjaesong
82897e0d6c *this* should force even-numbered position on thumbnail generation 2022-01-27 09:57:18 +09:00
minjaesong
d1d3086879 using 'correct' gl version 2022-01-27 00:09:39 +09:00
minjaesong
71176dcc9e change control working on the esc menu 2022-01-26 23:28:44 +09:00
minjaesong
9b4dd019ca prints out system info on the game crash 2022-01-24 21:04:13 +09:00
minjaesong
ce276f05f3 hopefully fix the bug that occurs when you minimise the screen? 2022-01-24 19:59:23 +09:00
115 changed files with 655 additions and 2132 deletions

2
.idea/misc.xml generated
View File

@@ -38,7 +38,7 @@
<property name="caretWidth" class="java.lang.Integer" />
</properties>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="SuppressKotlinCodeStyleNotification">

View File

@@ -4,7 +4,7 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="11" />
<option name="ALTERNATIVE_JRE_PATH" value="17" />
<module name="terrarum.terrarum" />
<method v="2">
<option name="BuildArtifacts" enabled="true">

View File

@@ -3,7 +3,7 @@
<option name="JAR_PATH" value="$PROJECT_DIR$/out/TerrarumBuild.jar" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="11" />
<option name="ALTERNATIVE_JRE_PATH" value="17" />
<module name="terrarum.terrarum" />
<method v="2">
<option name="BuildArtifacts" enabled="true">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 B

View File

@@ -0,0 +1,31 @@
CatStdout
CheatWarnTest
CodexEdictis
ExportCodices
ExportMap
ForceGC
GetAV
GetFaction
GetLocale
GetTime
ImportLayerData
ImportWorld
Inventory
KillActor
LangTest
MoneyDisp
MusicTest
Possess
PrintWorld
Save
Seed
SetAV
SetBulletin
SetScale
SetTime
SetTimeDelta
SpawnPhysTestBall
StreamerMode
Teleport
ToggleNoClip
Zoom
1 CatStdout
2 CheatWarnTest
3 CodexEdictis
4 ExportCodices
5 ExportMap
6 ForceGC
7 GetAV
8 GetFaction
9 GetLocale
10 GetTime
11 ImportLayerData
12 ImportWorld
13 Inventory
14 KillActor
15 LangTest
16 MoneyDisp
17 MusicTest
18 Possess
19 PrintWorld
20 Save
21 Seed
22 SetAV
23 SetBulletin
24 SetScale
25 SetTime
26 SetTimeDelta
27 SpawnPhysTestBall
28 StreamerMode
29 Teleport
30 ToggleNoClip
31 Zoom

Binary file not shown.

View File

@@ -1,108 +0,0 @@
#version 120
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_color;
varying vec2 v_texCoords;
// all 3 must have the same dimension!
// the divisor of 2 input and an output must be the same. I.e. either divide all by 4, or not.
uniform sampler2D shades;
uniform sampler2D lights;
// WARNING -- Gdx.Color.toIntBits returns ABGR, but GLSL expects RGBA. Use the function Color.toRGBA() in LightmapRenderNew
uniform sampler2D u_texture;
uniform vec2 outSize;
uniform float multiplier = 4.0; // if divided by four, put 4.0 in there
#define TRAVERSE_SIZE 128 // should be good for screen size up to 1920 for tile size of 16
vec4 sampleFrom(sampler2D from, vec2 which) {
return texture2D(from, which / outSize);
}
int traceRayCount(vec2 delta) {
vec2 absDelta = abs(delta);
int arraySize = int(max(absDelta.x, absDelta.y));
return arraySize + 1;
}
vec2[TRAVERSE_SIZE] traceRay(int arraySize, vec2 from, vec2 to) {
vec2 delta = to - from;
vec2[TRAVERSE_SIZE] returnArray;
int arri = 0;
// if the line is not vertical...
if (delta.x != 0) {
float deltaError = abs(delta.y / delta.x);
float error = 0.0;
float traceY = from.y;
for (float traceX = from.x; traceX <= to.x; traceX++) {
// plot(traceX, traceY)
returnArray[arri] = vec2(traceX, traceY);
arri = arri + 1;
error = error + deltaError;
if (error >= 0.5) {
traceY = traceY + sign(delta.y);
error = error - 1.0;
}
}
}
else {
for (float traceY = from.y; traceY <= to.y; traceY++) {
returnArray[arri] = vec2(from.x, traceY);
}
}
return returnArray;
}
void main() {
// this code will produce y-flipped image. It's your job to flip it again (e.g. using y-flipped fullscreen quad)
// Nice try, but it kills GPU :(
// reason: looks like traceRayCount() returns value greater than TRAVERSE_SIZE.
// even if I make traceRayCount() to return constant 3, I get less than 1 fps on GTX 970.
vec4 outColor = vec4(0.0,0.0,0.0,0.0);
// 1. pick a light source
for (int y = 0; y < int(outSize.y); y++) {
for (int x = 0; x < int(outSize.x); x++) {
vec2 from = vec2(x + 0.5, y + 0.5); // +0.5 is used because gl_FragCoord does
vec2 to = gl_FragCoord.xy;
vec2 delta = to - from;
int traceCount = traceRayCount(delta);
vec4 light = sampleFrom(lights, from);
// 2. get a trace path
vec2[TRAVERSE_SIZE] returnArray = traceRay(traceCount, from, to);
// 2.1 get angular darkening coefficient
vec2 unitVec = delta / max(delta.x, delta.y);
float angularDimming = sqrt(unitVec.x * unitVec.x + unitVec.y * unitVec.y);
//float angularDimming = 1.0; // TODO depends on the angle of (lightPos, gl_FragCoord.x)
// 3. traverse the light path to dim the "light"
// var "light" will be attenuated after this loop
for (int i = 0; i < traceCount; i++) {
vec4 shade = sampleFrom(shades, returnArray[i]) * angularDimming;
light = light - shade;
}
// 4. mix the incoming light into the light buffer.
outColor = max(outColor, light);
}
}
gl_FragColor = outColor * multiplier;
//gl_FragColor = vec4(0,1,0,1);
//gl_FragColor = sampleFrom(lights, gl_FragCoord.xy) * multiplier;
}

View File

@@ -4,11 +4,12 @@ Download and unzip the JDK for the appropriate operation systems first! JDKs can
Then, on the terminal, run following commands:
jlink --add-modules java.base,java.desktop,java.logging,jdk.unsupported --output /home/installed/Documents/Terrarum/out/runtime-linux --no-header-files --no-man-pages --strip-debug --compress=2
jlink --add-modules java.base,java.desktop,java.logging,jdk.unsupported --output ~/Documents/Terrarum/out/runtime-linux-amd64 --no-header-files --no-man-pages --strip-debug --compress=2
jlink --module-path /home/installed/Documents/openjdk/jdk-11.0.2-windows/jmods:mods --add-modules java.base,java.desktop,java.logging,jdk.unsupported --output /home/installed/Documents/Terrarum/out/runtime-windows --no-header-files --no-man-pages --strip-debug --compress=2
jlink --module-path /home/installed/Documents/openjdk/jdk-11.0.2.jdk-mac/Contents/Home/jmods:mods --add-modules java.base,java.desktop,java.logging,jdk.unsupported --output /home/installed/Documents/Terrarum/out/runtime-osx --no-header-files --no-man-pages --strip-debug --compress=2
jlink --module-path ~/Documents/openjdk/jdk-17.0.1-aarch64/jmods:mods --add-modules java.base,java.desktop,java.logging,jdk.unsupported --output ~/Documents/Terrarum/out/runtime-linux-aarch64 --no-header-files --no-man-pages --strip-debug --compress=2
jlink --module-path ~/Documents/openjdk/jdk-17.0.1-windows/jmods:mods --add-modules java.base,java.desktop,java.logging,jdk.unsupported --output ~/Documents/Terrarum/out/runtime-windows-amd64 --no-header-files --no-man-pages --strip-debug --compress=2
jlink --module-path ~/Documents/openjdk/jdk-17.0.1.jdk-aarch64/Contents/Home/jmods:mods --add-modules java.base,java.desktop,java.logging,jdk.unsupported --output ~/Documents/Terrarum/out/runtime-osx-aarch64 --no-header-files --no-man-pages --strip-debug --compress=2
jlink --module-path ~/Documents/openjdk/jdk-17.0.1.jdk-amd64/Contents/Home/jmods:mods --add-modules java.base,java.desktop,java.logging,jdk.unsupported --output ~/Documents/Terrarum/out/runtime-osx-amd64 --no-header-files --no-man-pages --strip-debug --compress=2
This process assumes that the game does NOT use the Java 9+ modules and every single required libraries are fat-jar'd (their contents extracted right into the Jar)
@@ -18,9 +19,11 @@ Create an output directory; its contents shall be:
```
+assets
+runtime-linux
+runtime-osx
+runtime-windows
+runtime-linux-aarch64
+runtime-linux-amd64
+runtime-osx-amd64
+runtime-osx-aarch64
+runtime-windows-amd64
start_game_linux.sh
start_game_mac.sh
start_game_windows.bat

View File

@@ -12,11 +12,14 @@ import net.torvald.UnsafeHelper
*/
internal class UnsafeCvecArray(val width: Int, val height: Int) {
private val TOTAL_SIZE_IN_BYTES = 16L * (width + 1) * (height + 1)
val TOTAL_SIZE_IN_BYTES = 16L * (width + 1) * (height + 1)
private val array = UnsafeHelper.allocate(TOTAL_SIZE_IN_BYTES)
val ptr = array.ptr
private inline fun toAddr(x: Int, y: Int) = 16L * (y * width + x)
fun isDestroyed() = array.destroyed
init {
zerofill()
}

View File

@@ -11,12 +11,12 @@ import java.util.Random;
*/
public class HQRNG extends Random {
private static final long DOUBLE_MASK = (1L << 53) - 1;
private static final double NORM_53 = 1. / (1L << 53);
private static final long FLOAT_MASK = (1L << 24) - 1;
private static final double NORM_24 = 1. / (1L << 24);
transient private static final long DOUBLE_MASK = (1L << 53) - 1;
transient private static final double NORM_53 = 1. / (1L << 53);
transient private static final long FLOAT_MASK = (1L << 24) - 1;
transient private static final double NORM_24 = 1. / (1L << 24);
private static final long serialVersionUID = 1018744536171610262L;
transient private static final long serialVersionUID = 1018744536171610262L;
private long state0, state1;

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Files;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.AudioDevice;
@@ -20,7 +21,6 @@ import com.badlogic.gdx.utils.JsonValue;
import com.github.strikerx3.jxinput.XInputDevice;
import net.torvald.gdx.graphics.PixmapIO2;
import net.torvald.getcpuname.GetCpuName;
import net.torvald.terrarum.concurrent.ThreadExecutor;
import net.torvald.terrarum.controller.GdxControllerAdapter;
import net.torvald.terrarum.controller.TerrarumController;
import net.torvald.terrarum.controller.XinputControllerAdapter;
@@ -60,9 +60,9 @@ import static net.torvald.terrarum.TerrarumKt.*;
*/
public class App implements ApplicationListener {
public static final long startupTime = System.currentTimeMillis() / 1000L;
public static final String GAME_NAME = TerrarumAppConfiguration.GAME_NAME;
public static final int VERSION_RAW = TerrarumAppConfiguration.VERSION_RAW;
public static final String getVERSION_STRING() {
@@ -357,7 +357,7 @@ public class App implements ApplicationListener {
Lwjgl3ApplicationConfiguration appConfig = new Lwjgl3ApplicationConfiguration();
//appConfig.useGL30 = false; // https://stackoverflow.com/questions/46753218/libgdx-should-i-use-gl30
appConfig.useOpenGL3(true, 3, 0);
appConfig.useOpenGL3(true, 3, 2);
appConfig.useVsync(getConfigBoolean("usevsync"));
appConfig.setResizable(false);
appConfig.setWindowedMode(width, height);
@@ -371,17 +371,17 @@ public class App implements ApplicationListener {
//appConfig.samples = 4; // force the AA on, if the graphics driver didn't do already
// load app icon
int[] appIconSizes = new int[]{256, 128, 64, 32, 16};
ArrayList<String> appIconPaths = new ArrayList<>();
for (int size : appIconSizes) {
String name = "assets/appicon" + size + ".png";
if (new File("./" + name).exists()) {
appIconPaths.add("./" + name);
}
}
Object[] iconPathsTemp = appIconPaths.toArray();
appConfig.setWindowIcon(Arrays.copyOf(iconPathsTemp, iconPathsTemp.length, String[].class));
appConfig.setWindowIcon(Files.FileType.Classpath,
"res/appicon512.png",
"res/appicon256.png",
"res/appicon144.png",
"res/appicon128.png",
"res/appicon96.png",
"res/appicon64.png",
"res/appicon48.png",
"res/appicon32.png",
"res/appicon16.png"
);
// set some more configuration vars
MULTITHREAD = THREAD_COUNT >= 3 && getConfigBoolean("multithread");
@@ -432,20 +432,20 @@ public class App implements ApplicationListener {
// set GL graphics constants
for (int i = 0; i < ditherPatterns.length; i++) {
Texture t = new Texture(Gdx.files.internal("assets/shaders/dither_512_"+i+".tga"));
Texture t = new Texture(Gdx.files.classpath("shaders/dither_512_"+i+".tga"));
t.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Linear);
t.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
ditherPatterns[i] = t;
}
shaderBayerSkyboxFill = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_skyboxfill.frag");
shaderHicolour = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/hicolour.frag");
shaderDebugDiff = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/diff.frag");
shaderBayerSkyboxFill = loadShaderFromClasspath("shaders/4096.vert", "shaders/4096_bayer_skyboxfill.frag");
shaderHicolour = loadShaderFromClasspath("shaders/4096.vert", "shaders/hicolour.frag");
shaderDebugDiff = loadShaderFromClasspath("shaders/4096.vert", "shaders/diff.frag");
shaderPassthruRGBA = SpriteBatch.createDefaultShader();
shaderDitherRGBA = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer.frag"); // always load the shader regardless of config because the config may cange
shaderColLUT = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/passthrurgb.frag");
shaderReflect = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/reflect.frag");
shaderGhastlyWhite = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/ghastlywhite.frag");
shaderDitherRGBA = loadShaderFromClasspath("shaders/4096.vert", "shaders/4096_bayer.frag"); // always load the shader regardless of config because the config may cange
shaderColLUT = loadShaderFromClasspath("shaders/4096.vert", "shaders/passthrurgb.frag");
shaderReflect = loadShaderFromClasspath("shaders/4096.vert", "shaders/reflect.frag");
shaderGhastlyWhite = loadShaderFromClasspath("shaders/4096.vert", "shaders/ghastlywhite.frag");
fullscreenQuad = new Mesh(
true, 4, 6,
@@ -718,9 +718,11 @@ public class App implements ApplicationListener {
@Override
public void resize(int width, int height) {
printdbg(this, "Resize called");
printdbg(this, "Resize called: "+width+","+height);
printStackTrace(this);
if (width < 2 || height < 2) return;
//initViewPort(width, height);
scr.setDimension(width, height);
@@ -1361,6 +1363,16 @@ public class App implements ApplicationListener {
System.out.println(csiR + "[" + out + "] " + message + csi0);
}
public static ShaderProgram loadShaderFromClasspath(String vert, String frag) {
ShaderProgram s = new ShaderProgram(Gdx.files.classpath(vert), Gdx.files.classpath(frag));
if (s.getLog().toLowerCase().contains("error")) {
throw new Error(String.format("Shader program loaded with %s, %s failed:\n%s", vert, frag, s.getLog()));
}
return s;
}
public static ShaderProgram loadShaderFromFile(String vert, String frag) {
ShaderProgram s = new ShaderProgram(Gdx.files.internal(vert), Gdx.files.internal(frag));

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum
import com.badlogic.gdx.Gdx
import java.awt.BorderLayout
import java.awt.Color
import java.awt.Dimension
@@ -58,6 +59,24 @@ class GameCrashHandler(e: Throwable) : JFrame() {
this.add(border, BorderLayout.CENTER)
this.title = TerrarumAppConfiguration.GAME_NAME
val uptime = App.getTIME_T() - App.startupTime
// print out device info
printStream.println("== System Info ==")
printStream.println("Uptime: ${uptime / 3600}h${(uptime % 3600) / 60}m${uptime % 60}s")
printStream.println("Java version: ${System.getProperty("java.version")}")
printStream.println("OS Name: ${App.OSName}")
printStream.println("OS Version: ${App.OSVersion}")
printStream.println("System architecture: ${App.systemArch}")
printStream.println("Processor: ${App.processor} x${Runtime.getRuntime().availableProcessors()} (${App.processorVendor})")
printStream.println()
printStream.println("== OpenGL Info ==")
printStream.println(Gdx.graphics.glVersion.debugVersionString)
printStream.println()
printStream.println("== The Error Info ==")
e.printStackTrace(printStream)
e.printStackTrace()

View File

@@ -160,8 +160,8 @@ open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = f
// add blockmarking_actor into the actorlist
(CommonResourcePool.get("blockmarking_actor") as BlockMarkerActor).let {
it.isVisible = false // make sure the actor is invisible on new instance
if (actorContainerActive.searchFor(it.referenceID) { it.referenceID } != null) actorContainerActive.add(it)
forceRemoveActor(it)
forceAddActor(it)
}
gameInitialised = true
@@ -191,6 +191,8 @@ open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = f
printdbg(this, "dispose called by")
printStackTrace(this)
blockMarkingActor.isVisible = false
actorContainerActive.forEach { it.dispose() }
actorContainerInactive.forEach { it.dispose() }
world.dispose()

View File

@@ -48,8 +48,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
* e.g. 0x02010034 will be translated as 2.1.52
*
*/
const val VERSION_RAW = 0x00030000
// Commit counts up to the Release 0.3: 2259 (plz update!)
const val VERSION_RAW = 0x00030001
// Commit counts up to the Release 0.3.0: 2259 (plz update!)
//////////////////////////////////////////////////////////
// CONFIGURATION FOR TILE MAKER //

View File

@@ -7,7 +7,7 @@ import org.lwjgl.opengl.GL11
class TerrarumGLinfo {
private var _initialised = false
val MINIMAL_GL_VERSION = 430
val MINIMAL_GL_VERSION = 320
var GL_VERSION = -1; private set
get() = if (_initialised) field else throw UninitializedPropertyAccessException()

View File

@@ -33,8 +33,11 @@ internal object Authenticator : ConsoleCommand {
val pwd = args[1]
val hashedPwd = DigestUtils.sha256Hex(pwd)
if ("65b9aa150332ed7096134efb20220e5ebec04d4dbe1c537ff3816f68c2391c1c".equals(hashedPwd, ignoreCase = true)) {
// aryll
println("auth passwd: '$pwd'")
println("hash: $hashedPwd")
if ("09ccf5067db6f58265b004829e33e715e819ba0984f1e1fcef49c36fcd5f745f".equals(hashedPwd, ignoreCase = true)) {
// beedle
val msg = if (a) "Locked" else "Authenticated"
Echo(msg)
println("[Authenticator] " + msg)

View File

@@ -13,56 +13,70 @@ object CommandDict {
internal val dict = hashMapOf<String, ConsoleCommand>()
private val engineCommandList = listOf(
"ActorsList",
"Authenticator",
"AVTracker",
"Batch",
"Echo",
"EchoConsole",
"EchoError",
"Pause",
"QuitApp",
"ResizeScreen",
"ScreencapNogui",
"SetGlobalLightOverride",
"SetLocale",
"TakeScreenshot",
"Unpause",
"Version"
)
init {
printdbg(this, ModMgr.loadOrder.reversed())
printdbg(this, ModMgr.loadOrder.reversed().map { ModMgr.moduleInfo[it]?.packageName })
(listOf("net.torvald.terrarum") + ModMgr.loadOrder.reversed().mapNotNull { ModMgr.moduleInfo[it]?.packageName }).forEach { packageRoot ->
printdbg(this, packageRoot)
((listOf("$" to "net.torvald.terrarum")) + ModMgr.loadOrder.reversed().map { it to ModMgr.moduleInfo[it]?.packageName }).forEach { (modName, packageRoot) ->
val commandsList = if (modName == "$") engineCommandList else ModMgr.getFile(modName, "commands.csv").readLines()
val packageConsole = "$packageRoot.console"
val stream = ClassLoader.getSystemClassLoader().getResourceAsStream(packageConsole.replace('.', '/'))
if (stream != null) { // not all modules have extra console commands
printdbg(this, "Loading console commands from '${packageConsole}'")
// printdbg(this, commandsList.joinToString())
val reader = BufferedReader(InputStreamReader(stream))
commandsList.forEach { commandName ->
val canonicalName = "$packageConsole.$commandName"
val it = Class.forName(canonicalName)
reader.lines()
.filter { it.endsWith(".class") && !it.contains('$') }
.map { Class.forName("$packageConsole.${it.substring(0, it.lastIndexOf('.'))}") }
.forEach {
printdbg(this, "> Trying to instantiate ${it.canonicalName}")
printdbg(this, "> Trying to instantiate ${it.canonicalName}")
try {
val instance = it.kotlin.objectInstance ?: it.kotlin.java.newInstance()
try {
val instance = it.kotlin.objectInstance ?: it.kotlin.java.newInstance()
val aliases = instance.javaClass.getAnnotation(ConsoleAlias::class.java)?.aliasesCSV?.split(',')?.map { it.trim() }
val noexport = instance.javaClass.getAnnotation(ConsoleNoExport::class.java)
val aliases = instance.javaClass.getAnnotation(ConsoleAlias::class.java)?.aliasesCSV?.split(',')?.map { it.trim() }
val noexport = instance.javaClass.getAnnotation(ConsoleNoExport::class.java)
if (noexport == null) {
if (noexport == null) {
dict[instance.javaClass.simpleName.lowercase()] = instance as ConsoleCommand
aliases?.forEach {
dict[it] = instance as ConsoleCommand
}
printdbg(this, "Class instantiated: ${instance.javaClass.simpleName}")
if (aliases != null)
printdbg(this, " Annotations: $aliases")
}
}
catch (e: ClassCastException) {
printdbgerr(this, "${it.canonicalName} is not a ConsoleCommand")
}
catch (e: InstantiationException) {
printdbgerr(this, "Could not instantiate ${it.canonicalName}")
e.printStackTrace(System.err)
}
dict[instance.javaClass.simpleName.lowercase()] = instance as ConsoleCommand
aliases?.forEach {
dict[it] = instance as ConsoleCommand
}
printdbg(this, "Class instantiated: ${instance.javaClass.simpleName}")
if (aliases != null)
printdbg(this, " Annotations: $aliases")
}
}
catch (e: ClassCastException) {
printdbgerr(this, "${it.canonicalName} is not a ConsoleCommand")
}
catch (e: InstantiationException) {
printdbgerr(this, "Could not instantiate ${it.canonicalName}")
e.printStackTrace(System.err)
}
}
}
}
}

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.console
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.ccG
import net.torvald.terrarum.ccW
import net.torvald.terrarum.ccY
@@ -32,8 +33,6 @@ internal object CommandInterpreter {
internal fun execute(command: String) {
val cmd: Array<CommandInput?> = parse(command)
val error = Error()
for (single_command in cmd) {
if (single_command == null || single_command.argsCount == 0) continue

View File

@@ -12,18 +12,19 @@ object ScreencapNogui: ConsoleCommand {
override fun execute(args: Array<String>) {
if (args.size == 2) {
IngameRenderer.screencapExportCallback = {
val w = 960
val h = 640
val p = Pixmap.createFromFrameBuffer((it.width - w).ushr(1), (it.height - h).ushr(1), w, h)
val p = Pixmap.createFromFrameBuffer(0, 0, it.width, it.height)
PixmapIO2.writeTGA(Gdx.files.absolute(App.defaultDir + "/Exports/${args[1]}.tga"), p, true)
p.dispose()
}
IngameRenderer.screencapRequested = true
Echo("FBO exported to$ccG Exports/${args[1]}.tga")
}
else {
printUsage()
}
}
override fun printUsage() {
Echo("Usage: screencapnogui <output filename>")
}
}

View File

@@ -10,6 +10,9 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import kotlin.math.floor
/**
* Used as construction markers and fixture ghost images
*/
class BlockMarkerActor : ActorWithBody(Actor.RenderOrder.OVERLAY, physProp = PhysProperties.MOBILE_OBJECT) {
private val defaultSize = 16.0

View File

@@ -384,6 +384,6 @@ fun mouseInInteractableRangeTools(actor: ActorWithBody, item: GameItem?, reachMu
if (dist <= minOf(toolDistMax, distMax).sqr()) return action() else return false
}
fun IntRange.pickRandom() = HQRNG().nextInt(this.endInclusive - this.start + 1) + this.start // count() on 200 million entries? Se on vitun hyvää idea
fun IntRange.pickRandom() = HQRNG().nextInt(this.last - this.first + 1) + this.first // count() on 200 million entries? Se on vitun hyvää idea
fun IntArray.pickRandom(): Int = this[HQRNG().nextInt(this.size)]
fun DoubleArray.pickRandom(): Double = this[HQRNG().nextInt(this.size)]

View File

@@ -13,6 +13,7 @@ import net.torvald.terrarum.blockproperties.BlockPropUtil
import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.gameparticles.ParticleBase
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.gameworld.WorldTime
@@ -22,6 +23,7 @@ import net.torvald.terrarum.modulebasegame.ui.UIPaletteSelector
import net.torvald.terrarum.weather.WeatherMixer
import net.torvald.terrarum.ui.UINSMenu
import net.torvald.terrarum.worlddrawer.WorldCamera
import net.torvald.util.CircularArray
/**
* Created by minjaesong on 2018-07-06.
@@ -385,10 +387,21 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
BlockPropUtil.dynamicLumFuncTickClock()
}
private val particles = CircularArray<ParticleBase>(16, true)
private fun renderGame() {
_testMarkerDrawCalls = 0L
IngameRenderer.invoke(false, actorsRenderOverlay = if (showSelection) actorsRenderOverlay + essentialOverlays else essentialOverlays, uiContainer = uiContainer)
IngameRenderer.invoke(false,
1f,
listOf(),
listOf(),
listOf(),
listOf(),
if (showSelection) actorsRenderOverlay + essentialOverlays else essentialOverlays,
particles,
uiContainer = uiContainer
)
App.setDebugTime("Test.MarkerDrawCalls", _testMarkerDrawCalls)
}

View File

@@ -12,6 +12,7 @@ import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.random.HQRNG
import net.torvald.terrarum.*
import net.torvald.terrarum.App.measureDebugTime
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
import net.torvald.terrarum.gameactors.ActorWithBody
@@ -114,21 +115,21 @@ object IngameRenderer : Disposable {
// these codes will run regardless of the invocation of the "initialise()" function
// the "initialise()" function will also be called
init {
// shaderBlurDither = App.loadShaderFromFile("assets/shaders/blur.vert", "assets/shaders/blur_dither.frag")
// shaderRGBOnlyDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_rgb1.frag")
// shaderAtoGreyDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_aaa1.frag")
// shaderBlurDither = App.loadShaderFromClasspath("shaders/blur.vert", "shaders/blur_dither.frag")
// shaderRGBOnlyDither = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/4096_bayer_rgb1.frag")
// shaderAtoGreyDither = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/4096_bayer_aaa1.frag")
shaderBlur = App.loadShaderFromFile("assets/shaders/blur.vert", "assets/shaders/blur.frag")
shaderRGBOnly = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/rgbonly.frag")
shaderAtoGrey = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/aonly.frag")
shaderBlur = App.loadShaderFromClasspath("shaders/blur.vert", "shaders/blur.frag")
shaderRGBOnly = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/rgbonly.frag")
shaderAtoGrey = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/aonly.frag")
shaderAlphaDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/alphadither.frag")
shaderBlendGlow = App.loadShaderFromFile("assets/shaders/blendGlow.vert", "assets/shaders/blendGlow.frag")
shaderAlphaDither = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/alphadither.frag")
shaderBlendGlow = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/blendGlow.frag")
shaderKawaseDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawasedown.frag")
shaderKawaseUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawaseup.frag")
shaderKawaseDown = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/kawasedown.frag")
shaderKawaseUp = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/kawaseup.frag")
if (!shaderBlendGlow.isCompiled) {
Gdx.app.log("shaderBlendGlow", shaderBlendGlow.log)
@@ -196,22 +197,20 @@ object IngameRenderer : Disposable {
operator fun invoke(
gamePaused: Boolean,
zoom: Float = 1f,
actorsRenderBehind : List<ActorWithBody>? = null,
actorsRenderMiddle : List<ActorWithBody>? = null,
actorsRenderMidTop : List<ActorWithBody>? = null,
actorsRenderFront : List<ActorWithBody>? = null,
actorsRenderOverlay: List<ActorWithBody>? = null,
particlesContainer : CircularArray<ParticleBase>? = null,
actorsRenderBehind : List<ActorWithBody>,
actorsRenderMiddle : List<ActorWithBody>,
actorsRenderMidTop : List<ActorWithBody>,
actorsRenderFront : List<ActorWithBody>,
actorsRenderOverlay: List<ActorWithBody>,
particlesContainer : CircularArray<ParticleBase>,
player: ActorWithBody? = null,
uiContainer: UIContainer? = null
) {
renderingActorsCount = (actorsRenderBehind?.size ?: 0) +
(actorsRenderMiddle?.size ?: 0) +
(actorsRenderMidTop?.size ?: 0) +
(actorsRenderFront?.size ?: 0) +
(actorsRenderOverlay?.size ?: 0)
//renderingParticleCount = particlesContainer?.size ?: 0
//renderingParticleCount = (particlesContainer?.buffer?.map { (!it.flagDespawn).toInt() } ?: listOf(0)).sum()
renderingActorsCount = (actorsRenderBehind.size) +
(actorsRenderMiddle.size) +
(actorsRenderMidTop.size) +
(actorsRenderFront.size) +
(actorsRenderOverlay.size)
renderingUIsCount = uiContainer?.countVisible() ?: 0
invokeInit()
@@ -226,7 +225,7 @@ object IngameRenderer : Disposable {
measureDebugTime("Renderer.LightRun*") {
// recalculate for even frames, or if the sign of the cam-x changed
if (App.GLOBAL_RENDER_TIMER % 3 == 0 || Math.abs(WorldCamera.x - oldCamX) >= world.width * 0.85f * TILE_SIZEF || newWorldLoadedLatch) {
LightmapRenderer.fireRecalculateEvent(actorsRenderBehind, actorsRenderFront, actorsRenderMidTop, actorsRenderMiddle, actorsRenderOverlay)
LightmapRenderer.recalculate(actorsRenderBehind + actorsRenderFront + actorsRenderMidTop + actorsRenderMiddle + actorsRenderOverlay)
}
oldCamX = WorldCamera.x
}
@@ -404,9 +403,10 @@ object IngameRenderer : Disposable {
Gdx.gl.glDisable(GL20.GL_BLEND)
}
// processBlur(lightmapFboA, lightmapFboB)
processKawaseBlur(lightmapFbo)
// processNoBlur()
if (KeyToggler.isOn(Input.Keys.F5))
processNoBlur(lightmapFbo)
else
processKawaseBlur(lightmapFbo)
blendNormal(batch)
@@ -618,7 +618,9 @@ object IngameRenderer : Disposable {
batch.inUse {
moveCameraToWorldCoord()
actors?.forEach { it.drawBody(batch) }
actors?.forEach {
it.drawBody(batch)
}
}
setCameraPosition(0f, 0f)
@@ -670,6 +672,22 @@ object IngameRenderer : Disposable {
private const val KAWASE_POWER = 1.5f
fun processNoBlur(outFbo: FloatFrameBuffer) {
blurtex0.dispose()
outFbo.inAction(camera, batch) {
blurtex0 = LightmapRenderer.draw()
blurtex0.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
blurtex0.bind(0)
App.shaderPassthruRGBA.bind()
App.shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined)
App.shaderPassthruRGBA.setUniformi("u_texture", 0)
blurWriteQuad.render(App.shaderPassthruRGBA, GL20.GL_TRIANGLES)
}
}
fun processKawaseBlur(outFbo: FloatFrameBuffer) {
blurtex0.dispose()

View File

@@ -152,6 +152,9 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
init {
particlesContainer.overwritingPolicy = {
it.dispose()
}
}
@@ -886,7 +889,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
)
}
private val maxRenderableWires = ReferencingRanges.ACTORS_WIRES.endInclusive - ReferencingRanges.ACTORS_WIRES.first + 1
private val maxRenderableWires = ReferencingRanges.ACTORS_WIRES.last - ReferencingRanges.ACTORS_WIRES.first + 1
private val wireActorsContainer = Array(maxRenderableWires) { WireActor(ReferencingRanges.ACTORS_WIRES.first + it).let {
forceAddActor(it)
/*^let*/ it
@@ -1300,10 +1303,6 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
IngameRenderer.resize(App.scr.width, App.scr.height)
val drawWidth = Toolkit.drawWidth
if (gameInitialised) {
//LightmapRenderer.fireRecalculateEvent()
}
if (gameFullyLoaded) {
// resize UIs

View File

@@ -19,6 +19,7 @@ import net.torvald.terrarum.console.CommandDict
import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.gameactors.ai.ActorAI
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.gameparticles.ParticleBase
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.WorldTime
import net.torvald.terrarum.gameworld.fmod
@@ -31,6 +32,7 @@ import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.weather.WeatherMixer
import net.torvald.terrarum.worlddrawer.WorldCamera
import net.torvald.util.CircularArray
import java.io.IOException
import kotlin.math.atan2
import kotlin.math.cos
@@ -285,6 +287,8 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
uiContainer.forEach { it?.update(delta) }
}
private val particles = CircularArray<ParticleBase>(16, true)
fun renderScreen() {
Gdx.graphics.setTitle(TerrarumIngame.getCanonicalTitle())
@@ -296,7 +300,17 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
if (!demoWorld.layerTerrain.ptr.destroyed) { // FIXME q&d hack to circumvent the dangling pointer issue #26
IngameRenderer.invoke(gamePaused = false, uiContainer = uiContainer)
IngameRenderer.invoke(
false,
1f,
listOf(),
listOf(),
listOf(),
listOf(),
listOf(),
particles,
uiContainer = uiContainer
)
}
else {
printdbgerr(this, "Demoworld is already been destroyed")

View File

@@ -1,36 +0,0 @@
package net.torvald.terrarum.modulebasegame.console
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input
import net.torvald.terrarum.console.ConsoleAlias
import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo
//import net.torvald.terrarum.swingapp.IMStringReader
/**
* Created by minjaesong on 2017-02-05.
*/
@ConsoleAlias("imtest")
internal object JavaIMTest : ConsoleCommand {
override fun execute(args: Array<String>) {
/*IMStringReader(
{ Echo("[JavaIMTest -> IMStringReader] $it") }, // send input to Echo
"JavaIMTest"
)*/
val inputListener = object : Input.TextInputListener {
override fun input(text: String?) {
Echo("[TextInputText] $text")
}
override fun canceled() {
Echo("[TextInputText] (input canceled)")
}
}
Gdx.input.getTextInput(inputListener, "TextInputTest", "", "type anything!")
}
override fun printUsage() {
Echo("Tests Swing input window to get non-English text input")
}
}

View File

@@ -1,20 +0,0 @@
package net.torvald.terrarum.modulebasegame.console
import net.torvald.terrarum.console.ConsoleAlias
import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo
/**
* Created by minjaesong on 2016-07-04.
*/
@ConsoleAlias("tips")
internal object PrintRandomTips : ConsoleCommand {
override fun execute(args: Array<String>) {
Echo("Nope.")
//Echo(Lang["GAME_TIPS_${Random().nextInt(Lang.TIPS_COUNT) + 1}"])
}
override fun printUsage() {
Echo("Prints random tips for game.")
}
}

View File

@@ -1,26 +0,0 @@
package net.torvald.terrarum.modulebasegame.console
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.modulebasegame.gameactors.PhysTestLuarLander
/**
* Created by minjaesong on 2018-01-18.
*/
internal object SpawnPhysTestLunarLander : ConsoleCommand {
override fun execute(args: Array<String>) {
val mouseX = Terrarum.mouseX
val mouseY = Terrarum.mouseY
val lander = PhysTestLuarLander()
lander.setPosition(mouseX, mouseY)
INGAME.queueActorAddition(lander)
}
override fun printUsage() {
Echo("control it with arrow keys")
}
}

View File

@@ -1,26 +0,0 @@
package net.torvald.terrarum.modulebasegame.console
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.modulebasegame.gameactors.DecodeTapestry
import java.io.File
/**
* Created by minjaesong on 2017-01-14.
*/
internal object SpawnTapestry : ConsoleCommand {
override fun execute(args: Array<String>) {
if (args.size < 2) {
printUsage()
return
}
val tapestry = DecodeTapestry(File(args[1]))
INGAME.queueActorAddition(tapestry)
}
override fun printUsage() {
Echo("Usage: spawntapestry <tapestry_file>")
}
}

View File

@@ -1,25 +0,0 @@
package net.torvald.terrarum.modulebasegame.console
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.ConsoleNoExport
import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.modulebasegame.gameactors.FixtureTikiTorch
/**
* Created by minjaesong on 2016-12-17.
*/
@ConsoleNoExport
internal object SpawnTikiTorch : ConsoleCommand {
override fun execute(args: Array<String>) {
val torch = FixtureTikiTorch()
torch.setPosition(Terrarum.mouseX, Terrarum.mouseY)
INGAME.queueActorAddition(torch)
}
override fun printUsage() {
Echo("Usage: spawntorch")
}
}

View File

@@ -1,30 +0,0 @@
package net.torvald.terrarum.modulebasegame.gameactors
/**
* A wrapper to support instant player changing (or possessing other NPCs maybe)
*
* @param actor : here you 'attach' the actor you wish to control
* Created by minjaesong on 2016-10-23.
*/
@Deprecated("The ingame should discriminate 'theRealGamer' and 'actorNowPlaying'")
class PlayableActorDelegate(@Transient val actor: ActorHumanoid) {
/*init {
if (actor !is Controllable)
throw IllegalArgumentException("Player must be 'Controllable'!")
}
fun update(delta: Float) {
//val oldTilewisePos = actor.hIntTilewiseHitbox
actor.update(delta)
// fire lightmap recalculate event upon tilewise pos change
//val newTilewisePos = actor.hIntTilewiseHitbox
//if (oldTilewisePos != newTilewisePos) {
// LightmapRenderer.fireRecalculateEvent()
//}
// not going to work: think about stationery tiki torches, global lights, etc
}*/
}

View File

@@ -21,7 +21,7 @@ class ItemStorageChest(originalID: ItemID) : FixtureItemBase(originalID, "net.to
override val isDynamic = false
override val material = Material()
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegion("itemplaceholder_32")
get() = CommonResourcePool.getAsTextureRegion("itemplaceholder_48")
override var baseToolSize: Double? = baseMass
init {

View File

@@ -33,19 +33,18 @@ object PickaxeCore {
) = mouseInInteractableRangeTools(actor, item) {
// un-round the mx
val ww = INGAME.world.width
val hpww = ww * TILE_SIZE / 2
val apos = actor.centrePosPoint
val mx = if (apos.x < 0.0 && mx >= ww / 2) mx - ww
else if (apos.x > 0.0 && mx < ww / 2) mx + ww
val mx = if (apos.x - mx * TILE_SIZE< -hpww) mx - ww
else if (apos.x - mx * TILE_SIZE >= hpww) mx + ww
else mx
val wmx = mx * TILE_SIZED
val wmy = my * TILE_SIZED
var xoff = -(mw / 2) // implicit flooring
var yoff = -(mh / 2) // implicit flooring
// if mw or mh is even number, make it closer toward the actor
if (mw % 2 == 0 && apos.x > wmx) xoff += 1
if (mh % 2 == 0 && apos.y > wmy) yoff += 1
if (mw % 2 == 0 && apos.x > mx * TILE_SIZE) xoff += 1
if (mh % 2 == 0 && apos.y > my * TILE_SIZE) yoff += 1
var usageStatus = false
for (oy in 0 until mh) for (ox in 0 until mw) {

View File

@@ -12,7 +12,7 @@ import net.torvald.terrarum.ui.*
/**
* Created by minjaesong on 2021-10-06.
*/
class GraphicsControlPanel(val remoCon: UIRemoCon) : UICanvas() {
class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
override var width = 400
override var height = 400
@@ -27,11 +27,11 @@ class GraphicsControlPanel(val remoCon: UIRemoCon) : UICanvas() {
private val panelgap = 20
private val options = arrayOf(
arrayOf("fx_dither", Lang["MENU_OPTIONS_DITHER"], "toggle"),
arrayOf("fx_backgroundblur", Lang["MENU_OPTIONS_BLUR"], "toggle"),
arrayOf("fx_streamerslayout", Lang["MENU_OPTION_STREAMERS_LAYOUT"], "toggle"),
arrayOf("usevsync", Lang["MENU_OPTIONS_VSYNC"]+"*", "toggle"),
arrayOf("maxparticles", Lang["MENU_OPTIONS_PARTICLES"], "spinner,256,1024,256")
arrayOf("fx_dither", { Lang["MENU_OPTIONS_DITHER"] }, "toggle"),
arrayOf("fx_backgroundblur", { Lang["MENU_OPTIONS_BLUR"] }, "toggle"),
arrayOf("fx_streamerslayout", { Lang["MENU_OPTION_STREAMERS_LAYOUT"] }, "toggle"),
arrayOf("usevsync", { Lang["MENU_OPTIONS_VSYNC"]+"*" }, "toggle"),
arrayOf("maxparticles", { Lang["MENU_OPTIONS_PARTICLES"] }, "spinner,256,1024,256")
)
private fun makeButton(args: String, x: Int, y: Int, optionName: String): UIItem {
@@ -46,10 +46,10 @@ class GraphicsControlPanel(val remoCon: UIRemoCon) : UICanvas() {
}
private val optionControllers = options.mapIndexed { index, strings ->
makeButton(options[index][2],
makeButton(options[index][2] as String,
drawX + width - panelgap,
drawY + panelgap - 2 + index * (20 + linegap),
options[index][0]
options[index][0] as String
)
/*UIItemToggleButton(this,
drawX + width - panelgap - 75,
@@ -63,12 +63,12 @@ class GraphicsControlPanel(val remoCon: UIRemoCon) : UICanvas() {
if (it is UIItemToggleButton) {
it.clickOnceListener = { _, _, _ ->
it.toggle()
App.setConfig(options[i][0], it.getStatus())
App.setConfig(options[i][0] as String, it.getStatus())
}
}
else if (it is UIItemSpinner) {
it.selectionChangeListener = {
App.setConfig(options[i][0], it)
App.setConfig(options[i][0] as String, it)
}
}
@@ -89,7 +89,7 @@ class GraphicsControlPanel(val remoCon: UIRemoCon) : UICanvas() {
batch.color = Color.WHITE
options.forEachIndexed { index, strings ->
App.fontGame.draw(batch, strings[1], drawX + panelgap.toFloat(), drawY + panelgap + index * (20f + linegap))
App.fontGame.draw(batch, (strings[1] as () -> String).invoke(), drawX + panelgap.toFloat(), drawY + panelgap + index * (20f + linegap))
}
uiItems.forEach { it.render(batch, camera) }
App.fontGame.draw(batch, "* ${Lang["MENU_LABEL_RESTART_REQUIRED"]}", drawX + panelgap.toFloat(), drawY + height - panelgap - App.fontGame.lineHeight)

View File

@@ -10,6 +10,7 @@ import net.torvald.terrarum.Terrarum.getPlayerSaveFiledesc
import net.torvald.terrarum.Terrarum.getWorldSaveFiledesc
import net.torvald.terrarum.blendNormal
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.TitleScreen
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
@@ -30,10 +31,10 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
private val gameMenu = arrayOf(
"MENU_IO_SAVE_GAME",
"MENU_LABEL_GRAPHICS",
"MENU_OPTIONS_CONTROLS",
"MENU_CONTROLS_KEYBOARD",
"MENU_LABEL_LANGUAGE",
"MENU_LABEL_MAINMENU",
// "MENU_LABEL_QUIT",
)
private val gameMenuListHeight = DEFAULT_LINE_HEIGHT * gameMenu.size
private val gameMenuListWidth = 400
@@ -74,15 +75,21 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
defaultSelection = null
)*/
private val savingUI = UIItemSaving(this, (width - UIItemSaving.WIDTH) / 2, (height - UIItemSaving.HEIGHT) / 2)
private val keyConfigUI = UIKeyboardControlPanel(null)
private val languageUI = UITitleLanguage(null)
private val keyboardSetupUI = UIKeyboardInputConfig(null)
private var oldScreen = 0
private var screen = 0
fun toInitScreen() {
screen = 0
}
init {
uiItems.add(gameMenuButtons)
// `gameMenu` order
gameMenuButtons.selectionChangeListener = { _, new ->
when (new) {
0 -> {
@@ -126,15 +133,18 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
}
}
2 -> {
1 -> {
screen = 4; gameMenuButtons.deselect()
}
2 -> {
screen = 1; gameMenuButtons.deselect()
}
3 -> {
screen = 5; gameMenuButtons.deselect()
}
4 -> {
screen = 2; gameMenuButtons.deselect()
}
/*4 -> {
screen = 1; gameMenuButtons.deselect()
}*/
}
}
areYouSureMainMenuButtons.selectionChangeListener = { _, new ->
@@ -148,47 +158,84 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
}
}
}
/*areYouSureQuitButtons.selectionChangeListener = { _, new ->
when (new) {
2 -> Gdx.app.exit()
3 -> {
screen = 0; areYouSureQuitButtons.deselect()
}
}
}*/
}
// Completely unrelated to the gameMenuButtons order
private val screens = arrayOf(
gameMenuButtons, null, areYouSureMainMenuButtons, savingUI, keyConfigUI
gameMenuButtons, keyboardSetupUI, areYouSureMainMenuButtons, savingUI, keyConfigUI, languageUI
)
// `screens` order
private val screenRenders = arrayOf(
{ batch: SpriteBatch, camera: Camera ->
// control hints
App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
// text buttons
gameMenuButtons.render(batch, camera)
},
{ batch: SpriteBatch, camera: Camera ->
// control hints
App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
// areYouSureQuitButtons.render(batch, camera)
keyboardSetupUI.render(batch, camera)
},
{ batch: SpriteBatch, camera: Camera ->
// control hints
App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
areYouSureMainMenuButtons.render(batch, camera)
},
{ batch: SpriteBatch, camera: Camera ->
savingUI.render(batch, camera)
},
{ batch: SpriteBatch, camera: Camera ->
// control hints
App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
keyConfigUI.render(batch, camera)
},
{ batch: SpriteBatch, camera: Camera ->
// control hints
App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
languageUI.render(batch, camera)
},
)
// `screens` order
private val screenTouchDowns = arrayOf(
{ screenX: Int, screenY: Int, pointer: Int, button: Int -> },
{ screenX: Int, screenY: Int, pointer: Int, button: Int ->
keyboardSetupUI.touchDown(screenX, screenY, pointer, button)
},
{ screenX: Int, screenY: Int, pointer: Int, button: Int -> },
{ screenX: Int, screenY: Int, pointer: Int, button: Int -> },
{ screenX: Int, screenY: Int, pointer: Int, button: Int ->
keyConfigUI.touchDown(screenX, screenY, pointer, button)
},
{ screenX: Int, screenY: Int, pointer: Int, button: Int -> },
)
// `screens` order
private val screenTouchUps = arrayOf(
{ screenX: Int, screenY: Int, pointer: Int, button: Int -> },
{ screenX: Int, screenY: Int, pointer: Int, button: Int ->
keyboardSetupUI.touchUp(screenX, screenY, pointer, button)
},
{ screenX: Int, screenY: Int, pointer: Int, button: Int -> },
{ screenX: Int, screenY: Int, pointer: Int, button: Int -> },
{ screenX: Int, screenY: Int, pointer: Int, button: Int ->
keyConfigUI.touchUp(screenX, screenY, pointer, button)
},
{ screenX: Int, screenY: Int, pointer: Int, button: Int -> },
)
// `screens` order
private val screenScrolls = arrayOf(
{ amountX: Float, amountY: Float -> },
{ amountX: Float, amountY: Float ->
keyboardSetupUI.scrolled(amountX, amountY)
},
{ amountX: Float, amountY: Float -> },
{ amountX: Float, amountY: Float -> },
{ amountX: Float, amountY: Float -> },
{ amountX: Float, amountY: Float -> },
)
override fun show() {
@@ -198,10 +245,21 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
override fun updateUI(delta: Float) {
val yeet = screens[screen]
if (oldScreen != screen) {
val yeOlde = screens[oldScreen]
if (yeOlde is UIItem)
yeOlde.hide()
else if (yeOlde is UICanvas) {
yeOlde.setAsClose()
}
if (yeet is UIItem)
yeet.show()
else if (yeet is UICanvas)
else if (yeet is UICanvas) {
yeet.show()
yeet.setPosition(0,0)
yeet.setAsOpen()
}
oldScreen = screen
}
if (yeet is UIItem)
@@ -216,6 +274,30 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
screenRenders[screen](batch, camera)
}
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
super.touchDown(screenX, screenY, pointer, button)
screenTouchDowns[screen](screenX, screenY, pointer, button)
return true
}
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
super.touchUp(screenX, screenY, pointer, button)
screenTouchUps[screen](screenX, screenY, pointer, button)
return true
}
override fun scrolled(amountX: Float, amountY: Float): Boolean {
super.scrolled(amountX, amountY)
screenScrolls[screen](amountX, amountY)
return true
}
override fun inputStrobed(e: TerrarumKeyboardEvent) {
if (screens[screen] == keyboardSetupUI) {
keyboardSetupUI.inputStrobed(e)
}
}
override fun doOpening(delta: Float) {
}

View File

@@ -8,7 +8,7 @@ import net.torvald.ENDASH
import net.torvald.getKeycapPC
import net.torvald.terrarum.*
import net.torvald.terrarum.App.*
import net.torvald.terrarum.blockstats.MinimapComposer
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.ui.Toolkit
@@ -206,6 +206,7 @@ class UIInventoryFull(
INGAME.setTooltipMessage(null)
transitionPanel.forcePosition(2)
catBar.setSelectedPanel(2)
transitionalEscMenu.toInitScreen()
it.setAsOpen()
}
else if (it.isOpened)
@@ -277,8 +278,6 @@ class UIInventoryFull(
transitionPanel.dispose()
}
override fun doOpening(delta: Float) {
INGAME.pause()
INGAME.setTooltipMessage(null)

View File

@@ -9,6 +9,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.DefaultConfig
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.*

View File

@@ -8,10 +8,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.EMDASH
import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.gamecontroller.IME
import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gamecontroller.TerrarumIME
import net.torvald.terrarum.gamecontroller.TerrarumKeyCapsMode
import net.torvald.terrarum.gamecontroller.*
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.linearSearch
import net.torvald.terrarum.ui.*

View File

@@ -25,6 +25,8 @@ import net.torvald.terrarum.savegame.EntryFile
import net.torvald.terrarum.serialise.Common
import net.torvald.terrarum.serialise.LoadSavegame
import net.torvald.terrarum.serialise.ReadPlayer
import net.torvald.terrarum.spriteassembler.ADProperties.Companion.EXTRA_HEADROOM_X
import net.torvald.terrarum.spriteassembler.ADProperties.Companion.EXTRA_HEADROOM_Y
import net.torvald.terrarum.ui.Movement
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas
@@ -602,7 +604,10 @@ class UIItemPlayerCells(
// player avatar
batch.color = Color.WHITE
thumb?.let {
batch.draw(it, x + FastMath.ceil((106f - it.regionWidth) / 2f), y + FastMath.ceil((height - it.regionHeight) / 2f))
batch.draw(it,
x + FastMath.ceil((106f - it.regionWidth) / 2f) + EXTRA_HEADROOM_X / 2,
y + FastMath.ceil((height - it.regionHeight) / 2f) - EXTRA_HEADROOM_Y / 2
)
}
}

View File

@@ -5,12 +5,13 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App
import net.torvald.terrarum.Second
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItemTextButtonList
class UITitleLanguage(val remoCon: UIRemoCon) : UICanvas() {
class UITitleLanguage(remoCon: UIRemoCon?) : UICanvas() {
val menuLabels = arrayOf(
"MENU_LABEL_RETURN"
@@ -55,6 +56,7 @@ class UITitleLanguage(val remoCon: UIRemoCon) : UICanvas() {
defaultSelection = null
)
private var initialMouseBlock = true
init {
@@ -93,10 +95,14 @@ class UITitleLanguage(val remoCon: UIRemoCon) : UICanvas() {
}
override fun updateUI(delta: Float) {
textArea1.update(delta)
textArea2.update(delta)
if (initialMouseBlock && !Terrarum.mouseDown) {
initialMouseBlock = false
}
//AppLoader.printdbg(this, "should be printing indefinitely")
if (!initialMouseBlock) {
textArea1.update(delta)
textArea2.update(delta)
}
}
override fun renderUI(batch: SpriteBatch, camera: Camera) {
@@ -106,6 +112,14 @@ class UITitleLanguage(val remoCon: UIRemoCon) : UICanvas() {
textArea2.render(batch, camera)
}
override fun show() {
initialMouseBlock = true
}
override fun hide() {
initialMouseBlock = true
}
override fun doOpening(delta: Float) {
}

View File

@@ -14,7 +14,7 @@ object UITitleRemoConYaml {
val menuBase = """
- MENU_MODE_SINGLEPLAYER : net.torvald.terrarum.modulebasegame.ui.UILoadDemoSavefiles
- MENU_OPTIONS
- MENU_LABEL_GRAPHICS : net.torvald.terrarum.modulebasegame.ui.GraphicsControlPanel
- MENU_LABEL_GRAPHICS : net.torvald.terrarum.modulebasegame.ui.UIGraphicsControlPanel
- MENU_OPTIONS_CONTROLS : net.torvald.terrarum.modulebasegame.ui.UIKeyboardControlPanel
- MENU_CONTROLS_KEYBOARD : net.torvald.terrarum.modulebasegame.ui.UIKeyboardInputConfig
- MENU_LABEL_LANGUAGE : net.torvald.terrarum.modulebasegame.ui.UITitleLanguage

View File

@@ -3,6 +3,8 @@ package net.torvald.terrarum.serialise
import com.badlogic.gdx.utils.Json
import com.badlogic.gdx.utils.JsonValue
import com.badlogic.gdx.utils.JsonWriter
import net.torvald.random.HQRNG
import net.torvald.terrarum.TerrarumAppConfiguration
import net.torvald.terrarum.console.EchoError
import net.torvald.terrarum.gameworld.BlockLayer
import net.torvald.terrarum.gameworld.GameWorld
@@ -26,7 +28,7 @@ import java.util.zip.GZIPOutputStream
*/
object Common {
const val GENVER = 4
const val GENVER = TerrarumAppConfiguration.VERSION_RAW
const val COMP_NONE = 0
const val COMP_GZIP = 1
const val COMP_LZMA = 2
@@ -187,6 +189,19 @@ object Common {
return UUID.fromString(jsonData.asString())
}
})
// HQRNG
jsoner.setSerializer(HQRNG::class.java, object : Json.Serializer<HQRNG> {
override fun write(json: Json, obj: HQRNG, knownType: Class<*>?) {
json.writeValue("${obj.state0.toString()},${obj.state1.toString()}")
}
override fun read(json: Json, jsonData: JsonValue, type: Class<*>?): HQRNG {
val rng = HQRNG()
val seedstr = jsonData.asString().split(',')
rng.setSeed(seedstr[0].toLong(), seedstr[1].toLong())
return rng
}
})
}
private data class LayerInfo(val h: String, val b: String, val x: Int, val y: Int)

View File

@@ -14,6 +14,7 @@ import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.savegame.*
import net.torvald.terrarum.worlddrawer.WorldCamera
import java.io.File
import java.io.Reader
import java.util.logging.Level
@@ -46,14 +47,17 @@ object WriteSavegame {
printdbg(this, "Save queued")
if (hasThumbnail) {
IngameRenderer.screencapExportCallback = {
IngameRenderer.screencapExportCallback = { fb ->
printdbg(this, "Generating thumbnail...")
val w = 960
val h = 640
val x = (it.width - w).ushr(2).shl(1) // force the even-numbered position
val y = (it.height - h).ushr(2).shl(1) // force the even-numbered position
val cx = (1 - WorldCamera.x % 2)
val cy = (1 - WorldCamera.y % 2)
val x = (fb.width - w) - cx // force the even-numbered position
val y = (fb.height - h) - cy // force the even-numbered position
val p = Pixmap.createFromFrameBuffer(x, y, w, h)
IngameRenderer.fboRGBexport = p

View File

@@ -76,6 +76,8 @@ class ADProperties {
companion object {
const val ALL_JOINT_SELECT_KEY = "ALL"
const val EXTRA_HEADROOM_X = 32
const val EXTRA_HEADROOM_Y = 16
}
constructor(gdxFile: FileHandle) {
@@ -118,8 +120,8 @@ class ADProperties {
baseFilename = get("SPRITESHEET")[0].name
extension = get("EXTENSION")[0].name
val frameSizeVec = get("CONFIG").linearSearchBy { it.name == "SIZE" }!!.input as ADPropertyObject.Vector2i
frameWidth = frameSizeVec.x
frameHeight = frameSizeVec.y
frameWidth = frameSizeVec.x + EXTRA_HEADROOM_X
frameHeight = frameSizeVec.y + EXTRA_HEADROOM_Y
originX = (get("CONFIG").linearSearchBy { it.name == "ORIGINX" }!!.input as Float).toInt()
var maxColFinder = -1

View File

@@ -52,11 +52,11 @@ object AssembleSheetPixmap {
private fun drawAndGetCanvas(properties: ADProperties, fileGetter: (String) -> InputStream?, injectedItem: GameItem?): Pixmap {
val canvas = Pixmap(properties.cols * properties.frameWidth, properties.rows * properties.frameHeight, Pixmap.Format.RGBA8888)
val canvas = Pixmap(properties.cols * (properties.frameWidth), properties.rows * (properties.frameHeight), Pixmap.Format.RGBA8888)
canvas.blending = Pixmap.Blending.SourceOver
// actually draw
properties.transforms.forEach { t, _ ->
properties.transforms.forEach { (t, _) ->
drawThisFrame(t, canvas, properties, fileGetter, injectedItem)
}

View File

@@ -55,7 +55,9 @@ class ConsoleWindow : UICanvas() {
private var iMadeTheGameToPause = false
private val textinput = UIItemTextLineInput(this, 0, 0, this.width)
private val textinput = UIItemTextLineInput(this, 0, 0, this.width, keyFilter = { e ->
!e.keycodes.contains(Input.Keys.GRAVE)
})
private var clickLatched = false

View File

@@ -29,10 +29,10 @@ object Toolkit : Disposable {
}
private val shaderKawaseDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawasedown.frag")
private val shaderKawaseUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawaseup.frag")
private val shaderBoxDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxdown.frag")
private val shaderBoxUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxup.frag")
private val shaderKawaseDown = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/kawasedown.frag")
private val shaderKawaseUp = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/kawaseup.frag")
private val shaderBoxDown = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/boxdown.frag")
private val shaderBoxUp = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/boxup.frag")
private lateinit var fboBlur: FloatFrameBuffer
private lateinit var fboBlurHalf: FloatFrameBuffer

View File

@@ -64,6 +64,7 @@ class UIItemTextLineInput(
val maxLen: InputLenCap = InputLenCap(1000, InputLenCap.CharLenUnit.CODEPOINTS),
// val enablePasteButton: Boolean = true,
// val enableIMEButton: Boolean = true
var keyFilter: (TerrarumKeyboardEvent) -> Boolean = { true }
) : UIItem(parentUI, initialX, initialY) {
init {
@@ -203,138 +204,140 @@ class UIItemTextLineInput(
val (eventType, char, headkey, repeatCount, keycodes) = e
try {
if (eventType == InputStrober.KEY_DOWN || eventType == InputStrober.KEY_CHANGE) {
fboUpdateLatch = true
forceLitCursor()
val ime = getIME()
val lowLayer = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout"))
if (keyFilter(e)) {
try {
if (eventType == InputStrober.KEY_DOWN || eventType == InputStrober.KEY_CHANGE) {
fboUpdateLatch = true
forceLitCursor()
val ime = getIME()
val lowLayer = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout"))
if (keycodes.contains(Input.Keys.V) && keycodes.containsSome(Input.Keys.CONTROL_LEFT, Input.Keys.CONTROL_RIGHT)) {
endComposing()
paste(Clipboard.fetch().substringBefore('\n').substringBefore('\t').toCodePoints())
}
else if (keycodes.contains(Input.Keys.C) && (keycodes.containsSome(Input.Keys.CONTROL_LEFT, Input.Keys.CONTROL_RIGHT))) {
endComposing()
copyToClipboard()
}
else if (keycodes.contains(Input.Keys.BACKSPACE) || (keycodes.contains(Input.Keys.CAPS_LOCK) && lowLayer.capsMode == TerrarumKeyCapsMode.BACK)) {
if (keycodes.contains(Input.Keys.V) && keycodes.containsSome(Input.Keys.CONTROL_LEFT, Input.Keys.CONTROL_RIGHT)) {
endComposing()
paste(Clipboard.fetch().substringBefore('\n').substringBefore('\t').toCodePoints())
}
else if (keycodes.contains(Input.Keys.C) && (keycodes.containsSome(Input.Keys.CONTROL_LEFT, Input.Keys.CONTROL_RIGHT))) {
endComposing()
copyToClipboard()
}
else if (keycodes.contains(Input.Keys.BACKSPACE) || (keycodes.contains(Input.Keys.CAPS_LOCK) && lowLayer.capsMode == TerrarumKeyCapsMode.BACK)) {
// printdbg(this, "BACKSPACE hit; ime.composing=${ime?.composing?.invoke()}; buflen=${textbuf.size}")
// printdbg(this, "BACKSPACE hit; ime.composing=${ime?.composing?.invoke()}; buflen=${textbuf.size}")
if (ime != null && ime.composing()) {
if (ime.config.mode == TerrarumIMEMode.CANDIDATES) {
candidates = ime.backspace().map { CodepointSequence(it.toCodePoints()) }
}
else if (ime.config.mode == TerrarumIMEMode.REWRITE) {
candidates = listOf()
val op = ime.backspace()
if (textbuf.isNotEmpty()) {
inputBackspaceOnce(1)
if (ime != null && ime.composing()) {
if (ime.config.mode == TerrarumIMEMode.CANDIDATES) {
candidates = ime.backspace().map { CodepointSequence(it.toCodePoints()) }
}
else if (ime.config.mode == TerrarumIMEMode.REWRITE) {
candidates = listOf()
val op = ime.backspace()
if (textbuf.isNotEmpty()) {
inputBackspaceOnce(1)
}
if (op.size > 0) {
val codepoints = op[0].toCodePoints()
if (!maxLen.exceeds(textbuf, codepoints)) {
textbuf.addAll(cursorX, codepoints)
if (op.size > 0) {
val codepoints = op[0].toCodePoints()
if (!maxLen.exceeds(textbuf, codepoints)) {
textbuf.addAll(cursorX, codepoints)
moveCursorToEnd(codepoints.size)
moveCursorToEnd(codepoints.size)
}
}
}
}
}
else if (cursorX <= 0) {
cursorX = 0
cursorDrawX = 0
cursorDrawScroll = 0
}
else {
endComposing()
inputBackspaceOnce(2)
}
}
else if (keycodes.contains(Input.Keys.LEFT)) {
endComposing()
if (cursorX > 0) {
cursorX -= 1
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
tryCursorForward()
if (cursorX <= 0) {
else if (cursorX <= 0) {
cursorX = 0
cursorDrawX = 0
cursorDrawScroll = 0
}
}
}
else if (keycodes.contains(Input.Keys.RIGHT)) {
endComposing()
if (cursorX < textbuf.size) {
cursorX += 1
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
tryCursorBack()
}
}
else if (keycodes.containsSome(Input.Keys.ENTER, Input.Keys.NUMPAD_ENTER)) {
endComposing()
// println("END COMPOSING!!")
}
// accept:
// - literal "<"
// - keysymbol that does not start with "<" (not always has length of 1 because UTF-16)
else if (char != null && char.length > 0 && char[0].code >= 32 && (char == "<" || !char.startsWith("<"))) {
val shiftin = keycodes.containsSome(Input.Keys.SHIFT_LEFT, Input.Keys.SHIFT_RIGHT)
val altgrin = keycodes.contains(Input.Keys.ALT_RIGHT) || keycodes.containsAll(Input.Keys.ALT_LEFT, Input.Keys.CONTROL_LEFT)
val codepoints = if (ime != null) {
if (ime.config.mode == TerrarumIMEMode.CANDIDATES) {
val newStatus = ime.acceptChar(headkey, shiftin, altgrin, char)
candidates = newStatus.first.map { CodepointSequence(it.toCodePoints()) }
newStatus.second.toCodePoints()
else {
endComposing()
inputBackspaceOnce(2)
}
else if (ime.config.mode == TerrarumIMEMode.REWRITE) {
candidates = listOf()
val op = ime.acceptChar(headkey, shiftin, altgrin, char)
}
else if (keycodes.contains(Input.Keys.LEFT)) {
endComposing()
// printdbg(this, "delcount: ${op.first[0].toInt()}, rewrite: '${op.second}'")
repeat(op.first[0].toInt()) {
if (textbuf.isNotEmpty()) {
// printdbg(this, "<del 1>")
inputBackspaceOnce(3)
}
if (cursorX > 0) {
cursorX -= 1
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
tryCursorForward()
if (cursorX <= 0) {
cursorX = 0
cursorDrawX = 0
cursorDrawScroll = 0
}
op.second.toCodePoints()
}
else throw IllegalArgumentException("Unknown IME Operation mode: ${ime.config.mode}")
}
else char.toCodePoints()
else if (keycodes.contains(Input.Keys.RIGHT)) {
endComposing()
// printdbg(this, "textinput codepoints: ${codepoints.map { it.toString(16) }.joinToString()}")
if (!maxLen.exceeds(textbuf, codepoints)) {
textbuf.addAll(cursorX, codepoints)
moveCursorToEnd(codepoints.size)
if (cursorX < textbuf.size) {
cursorX += 1
cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
tryCursorBack()
}
}
else if (keycodes.containsSome(Input.Keys.ENTER, Input.Keys.NUMPAD_ENTER)) {
endComposing()
// println("END COMPOSING!!")
}
// accept:
// - literal "<"
// - keysymbol that does not start with "<" (not always has length of 1 because UTF-16)
else if (char != null && char.length > 0 && char[0].code >= 32 && (char == "<" || !char.startsWith("<"))) {
val shiftin = keycodes.containsSome(Input.Keys.SHIFT_LEFT, Input.Keys.SHIFT_RIGHT)
val altgrin = keycodes.contains(Input.Keys.ALT_RIGHT) || keycodes.containsAll(Input.Keys.ALT_LEFT, Input.Keys.CONTROL_LEFT)
val codepoints = if (ime != null) {
if (ime.config.mode == TerrarumIMEMode.CANDIDATES) {
val newStatus = ime.acceptChar(headkey, shiftin, altgrin, char)
candidates = newStatus.first.map { CodepointSequence(it.toCodePoints()) }
newStatus.second.toCodePoints()
}
else if (ime.config.mode == TerrarumIMEMode.REWRITE) {
candidates = listOf()
val op = ime.acceptChar(headkey, shiftin, altgrin, char)
// printdbg(this, "delcount: ${op.first[0].toInt()}, rewrite: '${op.second}'")
repeat(op.first[0].toInt()) {
if (textbuf.isNotEmpty()) {
// printdbg(this, "<del 1>")
inputBackspaceOnce(3)
}
}
op.second.toCodePoints()
}
else throw IllegalArgumentException("Unknown IME Operation mode: ${ime.config.mode}")
}
else char.toCodePoints()
// printdbg(this, "textinput codepoints: ${codepoints.map { it.toString(16) }.joinToString()}")
if (!maxLen.exceeds(textbuf, codepoints)) {
textbuf.addAll(cursorX, codepoints)
moveCursorToEnd(codepoints.size)
}
}
// don't put innards of tryCursorBack/Forward here -- you absolutely don't want that behaviour
}
// don't put innards of tryCursorBack/Forward here -- you absolutely don't want that behaviour
}
}
catch (e: IndexOutOfBoundsException) {
e.printStackTrace()
}
catch (e: NullPointerException) {
e.printStackTrace()
}
catch (e: IndexOutOfBoundsException) {
e.printStackTrace()
}
catch (e: NullPointerException) {
e.printStackTrace()
}
if (textbuf.size == 0) {
currentPlaceholderText = CodepointSequence(placeholder().toCodePoints())
if (textbuf.size == 0) {
currentPlaceholderText = CodepointSequence(placeholder().toCodePoints())
}
}
}
else if (oldActive) { // just became deactivated

View File

@@ -85,7 +85,7 @@ internal object BlocksDrawer {
private lateinit var tilesQuad: Mesh
private val shader = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/tiling_dither.frag")
private val shader = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/tiling_dither.frag")
init {

View File

@@ -60,8 +60,6 @@ object LightmapRenderer {
}
finally {
this.world = world
//fireRecalculateEvent()
}
}
@@ -86,11 +84,6 @@ object LightmapRenderer {
private var _mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
init {
LightmapHDRMap.invoke()
printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque")
}
private const val AIR = Block.AIR
const val DRAW_TILE_SIZE: Float = TILE_SIZE / IngameRenderer.lightmapDownsample
@@ -141,7 +134,14 @@ object LightmapRenderer {
}
}
fun fireRecalculateEvent(vararg actorContainers: List<ActorWithBody>?) {
init {
LightmapHDRMap.invoke()
printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque")
}
fun recalculate(actorContainer: List<ActorWithBody>) = _recalculate(actorContainer, lightmap)
private fun _recalculate(actorContainer: List<ActorWithBody>, lightmap: UnsafeCvecArray) {
try {
world.getTileFromTerrain(0, 0) // test inquiry
}
@@ -149,7 +149,7 @@ object LightmapRenderer {
return // quit prematurely
}
catch (e: NullPointerException) {
System.err.println("[LightmapRendererNew.fireRecalculateEvent] Attempted to refer destroyed unsafe array " +
System.err.println("[LightmapRendererNew.recalculate] Attempted to refer destroyed unsafe array " +
"(${world.layerTerrain.ptr})")
e.printStackTrace()
return // something's wrong but we'll ignore it like a trustful AK
@@ -177,7 +177,7 @@ object LightmapRenderer {
//println("$for_x_start..$for_x_end, $for_x\t$for_y_start..$for_y_end, $for_y")
App.measureDebugTime("Renderer.Lanterns") {
buildLanternmap(actorContainers)
buildLanternmap(actorContainer)
} // usually takes 3000 ns
// set sunlight
@@ -205,27 +205,29 @@ object LightmapRenderer {
// 'NEWLIGHT2' LIGHT SWIPER
// O((8*2)n) where n is a size of the map.
/* - */fun r1() {
/* - */fun r1(lightmap: UnsafeCvecArray) {
swipeDiag = false
for (line in 1 until LIGHTMAP_HEIGHT - 1) {
swipeLight(
1, line,
LIGHTMAP_WIDTH - 2, line,
1, 0
1, 0,
lightmap
)
}
}
/* | */fun r2() {
/* | */fun r2(lightmap: UnsafeCvecArray) {
swipeDiag = false
for (line in 1 until LIGHTMAP_WIDTH - 1) {
swipeLight(
line, 1,
line, LIGHTMAP_HEIGHT - 2,
0, 1
0, 1,
lightmap
)
}
}
/* \ */fun r3() {
/* \ */fun r3(lightmap: UnsafeCvecArray) {
swipeDiag = true
/* construct indices such that:
56789ABC
@@ -258,11 +260,12 @@ object LightmapRenderer {
swipeLight(
maxOf(1, i - LIGHTMAP_HEIGHT + 4), maxOf(1, LIGHTMAP_HEIGHT - 2 - i),
minOf(LIGHTMAP_WIDTH - 2, i + 1), minOf(LIGHTMAP_HEIGHT - 2, (LIGHTMAP_WIDTH + LIGHTMAP_HEIGHT - 5) - i),
1, 1
1, 1,
lightmap
)
}
}
/* / */fun r4() {
/* / */fun r4(lightmap: UnsafeCvecArray) {
swipeDiag = true
/*
1 w-2
@@ -291,7 +294,8 @@ object LightmapRenderer {
swipeLight(
maxOf(1, i - LIGHTMAP_HEIGHT + 4), minOf(LIGHTMAP_HEIGHT - 2, i + 1),
minOf(LIGHTMAP_WIDTH - 2, i + 1), maxOf(1, (LIGHTMAP_HEIGHT - 2) - (LIGHTMAP_WIDTH + LIGHTMAP_HEIGHT - 6) + i),
1, -1
1, -1,
lightmap
)
}
}
@@ -313,34 +317,34 @@ object LightmapRenderer {
// why dark spots appear in the first place)
// - Multithreading? I have absolutely no idea.
// - If you naively slice the screen (job area) to multithread, the seam will appear.
r1();r2();r3();r4()
r1();r2();r3();r4() // two looks better than one
r1(lightmap);r2(lightmap);r3(lightmap);r4(lightmap)
r1(lightmap);r2(lightmap);r3(lightmap);r4(lightmap) // two looks better than one
// no rendering trickery will eliminate the need of 2nd pass, even the "decay out"
}
}
private fun buildLanternmap(actorContainers: Array<out List<ActorWithBody>?>) {
private fun buildLanternmap(actorContainer: List<ActorWithBody>) {
lanternMap.clear()
actorContainers.forEach { actorContainer ->
actorContainer?.forEach {
if (it is Luminous) {
// put lanterns to the area the luminantBox is occupying
for (lightBox in it.lightBoxList) {
val lightBoxX = it.hitbox.startX + lightBox.startX
val lightBoxY = it.hitbox.startY + lightBox.startY
val lightBoxW = lightBox.width
val lightBoxH = lightBox.height
for (y in lightBoxY.div(TILE_SIZE).floorInt()
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
for (x in lightBoxX.div(TILE_SIZE).floorInt()
..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) {
actorContainer.forEach {
if (it is Luminous) {
val lightBoxCopy = it.lightBoxList.subList(0, it.lightBoxList.size) // make copy to prevent ConcurrentModificationException
val normalisedCvec = it.color//.cpy().mul(DIV_FLOAT)
// put lanterns to the area the luminantBox is occupying
for (lightBox in lightBoxCopy) {
val lightBoxX = it.hitbox.startX + lightBox.startX
val lightBoxY = it.hitbox.startY + lightBox.startY
val lightBoxW = lightBox.width
val lightBoxH = lightBox.height
for (y in lightBoxY.div(TILE_SIZE).floorInt()
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
for (x in lightBoxX.div(TILE_SIZE).floorInt()
..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) {
lanternMap[LandUtil.getBlockAddr(world, x, y)] = normalisedCvec
}
val oldLight = lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: Cvec(0) // if two or more luminous actors share the same block, mix the light
val actorLight = it.color
lanternMap[LandUtil.getBlockAddr(world, x, y)] = oldLight.maxAndAssign(actorLight)
}
}
}
@@ -522,7 +526,7 @@ object LightmapRenderer {
private var swipeX = -1
private var swipeY = -1
private var swipeDiag = false
private fun _swipeTask(x: Int, y: Int, x2: Int, y2: Int) {
private fun _swipeTask(x: Int, y: Int, x2: Int, y2: Int, lightmap: UnsafeCvecArray) {
if (x2 < 0 || y2 < 0 || x2 >= LIGHTMAP_WIDTH || y2 >= LIGHTMAP_HEIGHT) return
_ambientAccumulator.r = _mapLightLevelThis.getR(x, y)
@@ -535,25 +539,25 @@ object LightmapRenderer {
_thisTileOpacity.g = _mapThisTileOpacity.getG(x, y)
_thisTileOpacity.b = _mapThisTileOpacity.getB(x, y)
_thisTileOpacity.a = _mapThisTileOpacity.getA(x, y)
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity))
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity, lightmap))
}
else {
_thisTileOpacity2.r = _mapThisTileOpacity2.getR(x, y)
_thisTileOpacity2.g = _mapThisTileOpacity2.getG(x, y)
_thisTileOpacity2.b = _mapThisTileOpacity2.getB(x, y)
_thisTileOpacity2.a = _mapThisTileOpacity2.getA(x, y)
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity2))
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity2, lightmap))
}
_mapLightLevelThis.setVec(x, y, _ambientAccumulator)
lightmap.setVec(x, y, _ambientAccumulator)
}
private fun swipeLight(sx: Int, sy: Int, ex: Int, ey: Int, dx: Int, dy: Int) {
private fun swipeLight(sx: Int, sy: Int, ex: Int, ey: Int, dx: Int, dy: Int, lightmap: UnsafeCvecArray) {
swipeX = sx; swipeY = sy
while (swipeX*dx <= ex*dx && swipeY*dy <= ey*dy) {
// conduct the task #1
// spread towards the end
_swipeTask(swipeX, swipeY, swipeX-dx, swipeY-dy)
_swipeTask(swipeX, swipeY, swipeX-dx, swipeY-dy, lightmap)
swipeX += dx
swipeY += dy
@@ -563,7 +567,7 @@ object LightmapRenderer {
while (swipeX*dx >= sx*dx && swipeY*dy >= sy*dy) {
// conduct the task #2
// spread towards the start
_swipeTask(swipeX, swipeY, swipeX+dx, swipeY+dy)
_swipeTask(swipeX, swipeY, swipeX+dx, swipeY+dy, lightmap)
swipeX -= dx
swipeY -= dy
@@ -682,7 +686,7 @@ object LightmapRenderer {
* @param darken (0-255) per channel
* @return darkened data (0-255) per channel
*/
fun darkenColoured(x: Int, y: Int, darken: Cvec): Cvec {
internal fun darkenColoured(x: Int, y: Int, darken: Cvec, lightmap: UnsafeCvecArray): Cvec {
// use equation with magic number 8.0
// this function, when done recursively (A_x = darken(A_x-1, C)), draws exponential curve. (R^2 = 1)
@@ -740,6 +744,7 @@ object LightmapRenderer {
// copied from BlocksDrawer, duh!
// FIXME 'lightBuffer' is not zoomable in this way
val tilesInHorizontal = (App.scr.wf / TILE_SIZE).ceilInt() + 1 + LIGHTMAP_OVERRENDER * 2
val tilesInVertical = (App.scr.hf / TILE_SIZE).ceilInt() + 1 + LIGHTMAP_OVERRENDER * 2
@@ -754,6 +759,7 @@ object LightmapRenderer {
}
lightBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
lightmap.destroy()
_mapLightLevelThis.destroy()
_mapThisTileOpacity.destroy()

BIN
src/res/appicon128.png LFS Normal file

Binary file not shown.

BIN
src/res/appicon144.png LFS Normal file

Binary file not shown.

BIN
src/res/appicon16.png LFS Normal file

Binary file not shown.

BIN
src/res/appicon256.png LFS Normal file

Binary file not shown.

BIN
src/res/appicon32.png LFS Normal file

Binary file not shown.

BIN
src/res/appicon48.png LFS Normal file

Binary file not shown.

BIN
src/res/appicon512.png LFS Normal file

Binary file not shown.

BIN
src/res/appicon64.png LFS Normal file

Binary file not shown.

BIN
src/res/appicon96.png LFS Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More