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" /> <property name="caretWidth" class="java.lang.Integer" />
</properties> </properties>
</component> </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" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
<component name="SuppressKotlinCodeStyleNotification"> <component name="SuppressKotlinCodeStyleNotification">

View File

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

View File

@@ -3,7 +3,7 @@
<option name="JAR_PATH" value="$PROJECT_DIR$/out/TerrarumBuild.jar" /> <option name="JAR_PATH" value="$PROJECT_DIR$/out/TerrarumBuild.jar" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" /> <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" /> <module name="terrarum.terrarum" />
<method v="2"> <method v="2">
<option name="BuildArtifacts" enabled="true"> <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: 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 ~/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 /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.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) 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 +assets
+runtime-linux +runtime-linux-aarch64
+runtime-osx +runtime-linux-amd64
+runtime-windows +runtime-osx-amd64
+runtime-osx-aarch64
+runtime-windows-amd64
start_game_linux.sh start_game_linux.sh
start_game_mac.sh start_game_mac.sh
start_game_windows.bat start_game_windows.bat

View File

@@ -12,11 +12,14 @@ import net.torvald.UnsafeHelper
*/ */
internal class UnsafeCvecArray(val width: Int, val height: Int) { 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) 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) private inline fun toAddr(x: Int, y: Int) = 16L * (y * width + x)
fun isDestroyed() = array.destroyed
init { init {
zerofill() zerofill()
} }

View File

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

View File

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

View File

@@ -160,8 +160,8 @@ open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = f
// add blockmarking_actor into the actorlist // add blockmarking_actor into the actorlist
(CommonResourcePool.get("blockmarking_actor") as BlockMarkerActor).let { (CommonResourcePool.get("blockmarking_actor") as BlockMarkerActor).let {
it.isVisible = false // make sure the actor is invisible on new instance forceRemoveActor(it)
if (actorContainerActive.searchFor(it.referenceID) { it.referenceID } != null) actorContainerActive.add(it) forceAddActor(it)
} }
gameInitialised = true gameInitialised = true
@@ -191,6 +191,8 @@ open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = f
printdbg(this, "dispose called by") printdbg(this, "dispose called by")
printStackTrace(this) printStackTrace(this)
blockMarkingActor.isVisible = false
actorContainerActive.forEach { it.dispose() } actorContainerActive.forEach { it.dispose() }
actorContainerInactive.forEach { it.dispose() } actorContainerInactive.forEach { it.dispose() }
world.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 * e.g. 0x02010034 will be translated as 2.1.52
* *
*/ */
const val VERSION_RAW = 0x00030000 const val VERSION_RAW = 0x00030001
// Commit counts up to the Release 0.3: 2259 (plz update!) // Commit counts up to the Release 0.3.0: 2259 (plz update!)
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// CONFIGURATION FOR TILE MAKER // // CONFIGURATION FOR TILE MAKER //

View File

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

View File

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

View File

@@ -13,56 +13,70 @@ object CommandDict {
internal val dict = hashMapOf<String, ConsoleCommand>() 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 { init {
printdbg(this, ModMgr.loadOrder.reversed()) printdbg(this, ModMgr.loadOrder.reversed())
printdbg(this, ModMgr.loadOrder.reversed().map { ModMgr.moduleInfo[it]?.packageName }) printdbg(this, ModMgr.loadOrder.reversed().map { ModMgr.moduleInfo[it]?.packageName })
(listOf("net.torvald.terrarum") + ModMgr.loadOrder.reversed().mapNotNull { ModMgr.moduleInfo[it]?.packageName }).forEach { packageRoot -> ((listOf("$" to "net.torvald.terrarum")) + ModMgr.loadOrder.reversed().map { it to ModMgr.moduleInfo[it]?.packageName }).forEach { (modName, packageRoot) ->
printdbg(this, packageRoot) val commandsList = if (modName == "$") engineCommandList else ModMgr.getFile(modName, "commands.csv").readLines()
val packageConsole = "$packageRoot.console" 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() printdbg(this, "> Trying to instantiate ${it.canonicalName}")
.filter { it.endsWith(".class") && !it.contains('$') }
.map { Class.forName("$packageConsole.${it.substring(0, it.lastIndexOf('.'))}") }
.forEach {
printdbg(this, "> Trying to instantiate ${it.canonicalName}") try {
val instance = it.kotlin.objectInstance ?: it.kotlin.java.newInstance()
try { val aliases = instance.javaClass.getAnnotation(ConsoleAlias::class.java)?.aliasesCSV?.split(',')?.map { it.trim() }
val instance = it.kotlin.objectInstance ?: it.kotlin.java.newInstance() val noexport = instance.javaClass.getAnnotation(ConsoleNoExport::class.java)
val aliases = instance.javaClass.getAnnotation(ConsoleAlias::class.java)?.aliasesCSV?.split(',')?.map { it.trim() } if (noexport == null) {
val noexport = instance.javaClass.getAnnotation(ConsoleNoExport::class.java)
if (noexport == null) { dict[instance.javaClass.simpleName.lowercase()] = instance as ConsoleCommand
aliases?.forEach {
dict[instance.javaClass.simpleName.lowercase()] = instance as ConsoleCommand dict[it] = 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)
}
} }
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 package net.torvald.terrarum.console
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.ccG import net.torvald.terrarum.ccG
import net.torvald.terrarum.ccW import net.torvald.terrarum.ccW
import net.torvald.terrarum.ccY import net.torvald.terrarum.ccY
@@ -32,8 +33,6 @@ internal object CommandInterpreter {
internal fun execute(command: String) { internal fun execute(command: String) {
val cmd: Array<CommandInput?> = parse(command) val cmd: Array<CommandInput?> = parse(command)
val error = Error()
for (single_command in cmd) { for (single_command in cmd) {
if (single_command == null || single_command.argsCount == 0) continue if (single_command == null || single_command.argsCount == 0) continue

View File

@@ -12,18 +12,19 @@ object ScreencapNogui: ConsoleCommand {
override fun execute(args: Array<String>) { override fun execute(args: Array<String>) {
if (args.size == 2) { if (args.size == 2) {
IngameRenderer.screencapExportCallback = { IngameRenderer.screencapExportCallback = {
val w = 960 val p = Pixmap.createFromFrameBuffer(0, 0, it.width, it.height)
val h = 640
val p = Pixmap.createFromFrameBuffer((it.width - w).ushr(1), (it.height - h).ushr(1), w, h)
PixmapIO2.writeTGA(Gdx.files.absolute(App.defaultDir + "/Exports/${args[1]}.tga"), p, true) PixmapIO2.writeTGA(Gdx.files.absolute(App.defaultDir + "/Exports/${args[1]}.tga"), p, true)
p.dispose() p.dispose()
} }
IngameRenderer.screencapRequested = true IngameRenderer.screencapRequested = true
Echo("FBO exported to$ccG Exports/${args[1]}.tga") Echo("FBO exported to$ccG Exports/${args[1]}.tga")
} }
else {
printUsage()
}
} }
override fun 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 net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import kotlin.math.floor import kotlin.math.floor
/**
* Used as construction markers and fixture ghost images
*/
class BlockMarkerActor : ActorWithBody(Actor.RenderOrder.OVERLAY, physProp = PhysProperties.MOBILE_OBJECT) { class BlockMarkerActor : ActorWithBody(Actor.RenderOrder.OVERLAY, physProp = PhysProperties.MOBILE_OBJECT) {
private val defaultSize = 16.0 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 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 IntArray.pickRandom(): Int = this[HQRNG().nextInt(this.size)]
fun DoubleArray.pickRandom(): Double = 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.gameactors.*
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.gameparticles.ParticleBase
import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.gameworld.WorldTime 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.weather.WeatherMixer
import net.torvald.terrarum.ui.UINSMenu import net.torvald.terrarum.ui.UINSMenu
import net.torvald.terrarum.worlddrawer.WorldCamera import net.torvald.terrarum.worlddrawer.WorldCamera
import net.torvald.util.CircularArray
/** /**
* Created by minjaesong on 2018-07-06. * Created by minjaesong on 2018-07-06.
@@ -385,10 +387,21 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
BlockPropUtil.dynamicLumFuncTickClock() BlockPropUtil.dynamicLumFuncTickClock()
} }
private val particles = CircularArray<ParticleBase>(16, true)
private fun renderGame() { private fun renderGame() {
_testMarkerDrawCalls = 0L _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) 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.random.HQRNG
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.App.measureDebugTime 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_SIZE
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
import net.torvald.terrarum.gameactors.ActorWithBody 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 // these codes will run regardless of the invocation of the "initialise()" function
// the "initialise()" function will also be called // the "initialise()" function will also be called
init { init {
// shaderBlurDither = App.loadShaderFromFile("assets/shaders/blur.vert", "assets/shaders/blur_dither.frag") // shaderBlurDither = App.loadShaderFromClasspath("shaders/blur.vert", "shaders/blur_dither.frag")
// shaderRGBOnlyDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_rgb1.frag") // shaderRGBOnlyDither = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/4096_bayer_rgb1.frag")
// shaderAtoGreyDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_aaa1.frag") // shaderAtoGreyDither = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/4096_bayer_aaa1.frag")
shaderBlur = App.loadShaderFromFile("assets/shaders/blur.vert", "assets/shaders/blur.frag") shaderBlur = App.loadShaderFromClasspath("shaders/blur.vert", "shaders/blur.frag")
shaderRGBOnly = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/rgbonly.frag") shaderRGBOnly = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/rgbonly.frag")
shaderAtoGrey = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/aonly.frag") shaderAtoGrey = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/aonly.frag")
shaderAlphaDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/alphadither.frag") shaderAlphaDither = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/alphadither.frag")
shaderBlendGlow = App.loadShaderFromFile("assets/shaders/blendGlow.vert", "assets/shaders/blendGlow.frag") shaderBlendGlow = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/blendGlow.frag")
shaderKawaseDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawasedown.frag") shaderKawaseDown = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/kawasedown.frag")
shaderKawaseUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawaseup.frag") shaderKawaseUp = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/kawaseup.frag")
if (!shaderBlendGlow.isCompiled) { if (!shaderBlendGlow.isCompiled) {
Gdx.app.log("shaderBlendGlow", shaderBlendGlow.log) Gdx.app.log("shaderBlendGlow", shaderBlendGlow.log)
@@ -196,22 +197,20 @@ object IngameRenderer : Disposable {
operator fun invoke( operator fun invoke(
gamePaused: Boolean, gamePaused: Boolean,
zoom: Float = 1f, zoom: Float = 1f,
actorsRenderBehind : List<ActorWithBody>? = null, actorsRenderBehind : List<ActorWithBody>,
actorsRenderMiddle : List<ActorWithBody>? = null, actorsRenderMiddle : List<ActorWithBody>,
actorsRenderMidTop : List<ActorWithBody>? = null, actorsRenderMidTop : List<ActorWithBody>,
actorsRenderFront : List<ActorWithBody>? = null, actorsRenderFront : List<ActorWithBody>,
actorsRenderOverlay: List<ActorWithBody>? = null, actorsRenderOverlay: List<ActorWithBody>,
particlesContainer : CircularArray<ParticleBase>? = null, particlesContainer : CircularArray<ParticleBase>,
player: ActorWithBody? = null, player: ActorWithBody? = null,
uiContainer: UIContainer? = null uiContainer: UIContainer? = null
) { ) {
renderingActorsCount = (actorsRenderBehind?.size ?: 0) + renderingActorsCount = (actorsRenderBehind.size) +
(actorsRenderMiddle?.size ?: 0) + (actorsRenderMiddle.size) +
(actorsRenderMidTop?.size ?: 0) + (actorsRenderMidTop.size) +
(actorsRenderFront?.size ?: 0) + (actorsRenderFront.size) +
(actorsRenderOverlay?.size ?: 0) (actorsRenderOverlay.size)
//renderingParticleCount = particlesContainer?.size ?: 0
//renderingParticleCount = (particlesContainer?.buffer?.map { (!it.flagDespawn).toInt() } ?: listOf(0)).sum()
renderingUIsCount = uiContainer?.countVisible() ?: 0 renderingUIsCount = uiContainer?.countVisible() ?: 0
invokeInit() invokeInit()
@@ -226,7 +225,7 @@ object IngameRenderer : Disposable {
measureDebugTime("Renderer.LightRun*") { measureDebugTime("Renderer.LightRun*") {
// recalculate for even frames, or if the sign of the cam-x changed // 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) { 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 oldCamX = WorldCamera.x
} }
@@ -404,9 +403,10 @@ object IngameRenderer : Disposable {
Gdx.gl.glDisable(GL20.GL_BLEND) Gdx.gl.glDisable(GL20.GL_BLEND)
} }
// processBlur(lightmapFboA, lightmapFboB) if (KeyToggler.isOn(Input.Keys.F5))
processKawaseBlur(lightmapFbo) processNoBlur(lightmapFbo)
// processNoBlur() else
processKawaseBlur(lightmapFbo)
blendNormal(batch) blendNormal(batch)
@@ -618,7 +618,9 @@ object IngameRenderer : Disposable {
batch.inUse { batch.inUse {
moveCameraToWorldCoord() moveCameraToWorldCoord()
actors?.forEach { it.drawBody(batch) } actors?.forEach {
it.drawBody(batch)
}
} }
setCameraPosition(0f, 0f) setCameraPosition(0f, 0f)
@@ -670,6 +672,22 @@ object IngameRenderer : Disposable {
private const val KAWASE_POWER = 1.5f 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) { fun processKawaseBlur(outFbo: FloatFrameBuffer) {
blurtex0.dispose() blurtex0.dispose()

View File

@@ -152,6 +152,9 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
init { 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 { private val wireActorsContainer = Array(maxRenderableWires) { WireActor(ReferencingRanges.ACTORS_WIRES.first + it).let {
forceAddActor(it) forceAddActor(it)
/*^let*/ it /*^let*/ it
@@ -1300,10 +1303,6 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
IngameRenderer.resize(App.scr.width, App.scr.height) IngameRenderer.resize(App.scr.width, App.scr.height)
val drawWidth = Toolkit.drawWidth val drawWidth = Toolkit.drawWidth
if (gameInitialised) {
//LightmapRenderer.fireRecalculateEvent()
}
if (gameFullyLoaded) { if (gameFullyLoaded) {
// resize UIs // resize UIs

View File

@@ -19,6 +19,7 @@ import net.torvald.terrarum.console.CommandDict
import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.gameactors.ai.ActorAI import net.torvald.terrarum.gameactors.ai.ActorAI
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.gameparticles.ParticleBase
import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.WorldTime import net.torvald.terrarum.gameworld.WorldTime
import net.torvald.terrarum.gameworld.fmod 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.ui.UICanvas
import net.torvald.terrarum.weather.WeatherMixer import net.torvald.terrarum.weather.WeatherMixer
import net.torvald.terrarum.worlddrawer.WorldCamera import net.torvald.terrarum.worlddrawer.WorldCamera
import net.torvald.util.CircularArray
import java.io.IOException import java.io.IOException
import kotlin.math.atan2 import kotlin.math.atan2
import kotlin.math.cos import kotlin.math.cos
@@ -285,6 +287,8 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
uiContainer.forEach { it?.update(delta) } uiContainer.forEach { it?.update(delta) }
} }
private val particles = CircularArray<ParticleBase>(16, true)
fun renderScreen() { fun renderScreen() {
Gdx.graphics.setTitle(TerrarumIngame.getCanonicalTitle()) 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 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 { else {
printdbgerr(this, "Demoworld is already been destroyed") 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 isDynamic = false
override val material = Material() override val material = Material()
override val itemImage: TextureRegion override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegion("itemplaceholder_32") get() = CommonResourcePool.getAsTextureRegion("itemplaceholder_48")
override var baseToolSize: Double? = baseMass override var baseToolSize: Double? = baseMass
init { init {

View File

@@ -33,19 +33,18 @@ object PickaxeCore {
) = mouseInInteractableRangeTools(actor, item) { ) = mouseInInteractableRangeTools(actor, item) {
// un-round the mx // un-round the mx
val ww = INGAME.world.width val ww = INGAME.world.width
val hpww = ww * TILE_SIZE / 2
val apos = actor.centrePosPoint val apos = actor.centrePosPoint
val mx = 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 > 0.0 && mx < ww / 2) mx + ww else if (apos.x - mx * TILE_SIZE >= hpww) mx + ww
else mx else mx
val wmx = mx * TILE_SIZED
val wmy = my * TILE_SIZED
var xoff = -(mw / 2) // implicit flooring var xoff = -(mw / 2) // implicit flooring
var yoff = -(mh / 2) // implicit flooring var yoff = -(mh / 2) // implicit flooring
// if mw or mh is even number, make it closer toward the actor // if mw or mh is even number, make it closer toward the actor
if (mw % 2 == 0 && apos.x > wmx) xoff += 1 if (mw % 2 == 0 && apos.x > mx * TILE_SIZE) xoff += 1
if (mh % 2 == 0 && apos.y > wmy) yoff += 1 if (mh % 2 == 0 && apos.y > my * TILE_SIZE) yoff += 1
var usageStatus = false var usageStatus = false
for (oy in 0 until mh) for (ox in 0 until mw) { 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. * Created by minjaesong on 2021-10-06.
*/ */
class GraphicsControlPanel(val remoCon: UIRemoCon) : UICanvas() { class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
override var width = 400 override var width = 400
override var height = 400 override var height = 400
@@ -27,11 +27,11 @@ class GraphicsControlPanel(val remoCon: UIRemoCon) : UICanvas() {
private val panelgap = 20 private val panelgap = 20
private val options = arrayOf( private val options = arrayOf(
arrayOf("fx_dither", Lang["MENU_OPTIONS_DITHER"], "toggle"), arrayOf("fx_dither", { Lang["MENU_OPTIONS_DITHER"] }, "toggle"),
arrayOf("fx_backgroundblur", Lang["MENU_OPTIONS_BLUR"], "toggle"), arrayOf("fx_backgroundblur", { Lang["MENU_OPTIONS_BLUR"] }, "toggle"),
arrayOf("fx_streamerslayout", Lang["MENU_OPTION_STREAMERS_LAYOUT"], "toggle"), arrayOf("fx_streamerslayout", { Lang["MENU_OPTION_STREAMERS_LAYOUT"] }, "toggle"),
arrayOf("usevsync", Lang["MENU_OPTIONS_VSYNC"]+"*", "toggle"), arrayOf("usevsync", { Lang["MENU_OPTIONS_VSYNC"]+"*" }, "toggle"),
arrayOf("maxparticles", Lang["MENU_OPTIONS_PARTICLES"], "spinner,256,1024,256") arrayOf("maxparticles", { Lang["MENU_OPTIONS_PARTICLES"] }, "spinner,256,1024,256")
) )
private fun makeButton(args: String, x: Int, y: Int, optionName: String): UIItem { 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 -> private val optionControllers = options.mapIndexed { index, strings ->
makeButton(options[index][2], makeButton(options[index][2] as String,
drawX + width - panelgap, drawX + width - panelgap,
drawY + panelgap - 2 + index * (20 + linegap), drawY + panelgap - 2 + index * (20 + linegap),
options[index][0] options[index][0] as String
) )
/*UIItemToggleButton(this, /*UIItemToggleButton(this,
drawX + width - panelgap - 75, drawX + width - panelgap - 75,
@@ -63,12 +63,12 @@ class GraphicsControlPanel(val remoCon: UIRemoCon) : UICanvas() {
if (it is UIItemToggleButton) { if (it is UIItemToggleButton) {
it.clickOnceListener = { _, _, _ -> it.clickOnceListener = { _, _, _ ->
it.toggle() it.toggle()
App.setConfig(options[i][0], it.getStatus()) App.setConfig(options[i][0] as String, it.getStatus())
} }
} }
else if (it is UIItemSpinner) { else if (it is UIItemSpinner) {
it.selectionChangeListener = { 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 batch.color = Color.WHITE
options.forEachIndexed { index, strings -> 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) } uiItems.forEach { it.render(batch, camera) }
App.fontGame.draw(batch, "* ${Lang["MENU_LABEL_RESTART_REQUIRED"]}", drawX + panelgap.toFloat(), drawY + height - panelgap - App.fontGame.lineHeight) 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.Terrarum.getWorldSaveFiledesc
import net.torvald.terrarum.blendNormal import net.torvald.terrarum.blendNormal
import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.TitleScreen import net.torvald.terrarum.modulebasegame.TitleScreen
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
@@ -30,10 +31,10 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
private val gameMenu = arrayOf( private val gameMenu = arrayOf(
"MENU_IO_SAVE_GAME", "MENU_IO_SAVE_GAME",
"MENU_LABEL_GRAPHICS",
"MENU_OPTIONS_CONTROLS", "MENU_OPTIONS_CONTROLS",
"MENU_CONTROLS_KEYBOARD",
"MENU_LABEL_LANGUAGE",
"MENU_LABEL_MAINMENU", "MENU_LABEL_MAINMENU",
// "MENU_LABEL_QUIT",
) )
private val gameMenuListHeight = DEFAULT_LINE_HEIGHT * gameMenu.size private val gameMenuListHeight = DEFAULT_LINE_HEIGHT * gameMenu.size
private val gameMenuListWidth = 400 private val gameMenuListWidth = 400
@@ -74,15 +75,21 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
defaultSelection = null defaultSelection = null
)*/ )*/
private val savingUI = UIItemSaving(this, (width - UIItemSaving.WIDTH) / 2, (height - UIItemSaving.HEIGHT) / 2) private val savingUI = UIItemSaving(this, (width - UIItemSaving.WIDTH) / 2, (height - UIItemSaving.HEIGHT) / 2)
private val keyConfigUI = UIKeyboardControlPanel(null) private val keyConfigUI = UIKeyboardControlPanel(null)
private val languageUI = UITitleLanguage(null)
private val keyboardSetupUI = UIKeyboardInputConfig(null)
private var oldScreen = 0 private var oldScreen = 0
private var screen = 0 private var screen = 0
fun toInitScreen() {
screen = 0
}
init { init {
uiItems.add(gameMenuButtons) uiItems.add(gameMenuButtons)
// `gameMenu` order
gameMenuButtons.selectionChangeListener = { _, new -> gameMenuButtons.selectionChangeListener = { _, new ->
when (new) { when (new) {
0 -> { 0 -> {
@@ -126,15 +133,18 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
} }
} }
2 -> { 1 -> {
screen = 4; gameMenuButtons.deselect() screen = 4; gameMenuButtons.deselect()
} }
2 -> {
screen = 1; gameMenuButtons.deselect()
}
3 -> { 3 -> {
screen = 5; gameMenuButtons.deselect()
}
4 -> {
screen = 2; gameMenuButtons.deselect() screen = 2; gameMenuButtons.deselect()
} }
/*4 -> {
screen = 1; gameMenuButtons.deselect()
}*/
} }
} }
areYouSureMainMenuButtons.selectionChangeListener = { _, new -> 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( private val screens = arrayOf(
gameMenuButtons, null, areYouSureMainMenuButtons, savingUI, keyConfigUI gameMenuButtons, keyboardSetupUI, areYouSureMainMenuButtons, savingUI, keyConfigUI, languageUI
) )
// `screens` order
private val screenRenders = arrayOf( private val screenRenders = arrayOf(
{ batch: SpriteBatch, camera: Camera -> { batch: SpriteBatch, camera: Camera ->
// control hints // control hints
App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20) App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
// text buttons // text buttons
gameMenuButtons.render(batch, camera) gameMenuButtons.render(batch, camera)
}, },
{ batch: SpriteBatch, camera: Camera -> { batch: SpriteBatch, camera: Camera ->
// control hints // control hints
App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20) App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
keyboardSetupUI.render(batch, camera)
// areYouSureQuitButtons.render(batch, camera)
}, },
{ batch: SpriteBatch, camera: Camera -> { batch: SpriteBatch, camera: Camera ->
// control hints // control hints
App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20) App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
areYouSureMainMenuButtons.render(batch, camera) areYouSureMainMenuButtons.render(batch, camera)
}, },
{ batch: SpriteBatch, camera: Camera -> { batch: SpriteBatch, camera: Camera ->
savingUI.render(batch, camera) savingUI.render(batch, camera)
}, },
{ batch: SpriteBatch, camera: Camera -> { batch: SpriteBatch, camera: Camera ->
// control hints
App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
keyConfigUI.render(batch, camera) 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() { override fun show() {
@@ -198,10 +245,21 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
override fun updateUI(delta: Float) { override fun updateUI(delta: Float) {
val yeet = screens[screen] val yeet = screens[screen]
if (oldScreen != 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) if (yeet is UIItem)
yeet.show() yeet.show()
else if (yeet is UICanvas) else if (yeet is UICanvas) {
yeet.show() yeet.show()
yeet.setPosition(0,0)
yeet.setAsOpen()
}
oldScreen = screen oldScreen = screen
} }
if (yeet is UIItem) if (yeet is UIItem)
@@ -216,6 +274,30 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
screenRenders[screen](batch, camera) 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) { override fun doOpening(delta: Float) {
} }

View File

@@ -8,7 +8,7 @@ import net.torvald.ENDASH
import net.torvald.getKeycapPC import net.torvald.getKeycapPC
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.App.* 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.langpack.Lang
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.Toolkit
@@ -206,6 +206,7 @@ class UIInventoryFull(
INGAME.setTooltipMessage(null) INGAME.setTooltipMessage(null)
transitionPanel.forcePosition(2) transitionPanel.forcePosition(2)
catBar.setSelectedPanel(2) catBar.setSelectedPanel(2)
transitionalEscMenu.toInitScreen()
it.setAsOpen() it.setAsOpen()
} }
else if (it.isOpened) else if (it.isOpened)
@@ -277,8 +278,6 @@ class UIInventoryFull(
transitionPanel.dispose() transitionPanel.dispose()
} }
override fun doOpening(delta: Float) { override fun doOpening(delta: Float) {
INGAME.pause() INGAME.pause()
INGAME.setTooltipMessage(null) 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.App
import net.torvald.terrarum.CommonResourcePool import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.DefaultConfig import net.torvald.terrarum.DefaultConfig
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.* 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.EMDASH
import net.torvald.terrarum.App import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.gamecontroller.IME import net.torvald.terrarum.gamecontroller.*
import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gamecontroller.TerrarumIME
import net.torvald.terrarum.gamecontroller.TerrarumKeyCapsMode
import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.linearSearch import net.torvald.terrarum.linearSearch
import net.torvald.terrarum.ui.* 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.Common
import net.torvald.terrarum.serialise.LoadSavegame import net.torvald.terrarum.serialise.LoadSavegame
import net.torvald.terrarum.serialise.ReadPlayer 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.Movement
import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UICanvas
@@ -602,7 +604,10 @@ class UIItemPlayerCells(
// player avatar // player avatar
batch.color = Color.WHITE batch.color = Color.WHITE
thumb?.let { 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 com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App import net.torvald.terrarum.App
import net.torvald.terrarum.Second import net.torvald.terrarum.Second
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItemTextButtonList import net.torvald.terrarum.ui.UIItemTextButtonList
class UITitleLanguage(val remoCon: UIRemoCon) : UICanvas() { class UITitleLanguage(remoCon: UIRemoCon?) : UICanvas() {
val menuLabels = arrayOf( val menuLabels = arrayOf(
"MENU_LABEL_RETURN" "MENU_LABEL_RETURN"
@@ -55,6 +56,7 @@ class UITitleLanguage(val remoCon: UIRemoCon) : UICanvas() {
defaultSelection = null defaultSelection = null
) )
private var initialMouseBlock = true
init { init {
@@ -93,10 +95,14 @@ class UITitleLanguage(val remoCon: UIRemoCon) : UICanvas() {
} }
override fun updateUI(delta: Float) { override fun updateUI(delta: Float) {
textArea1.update(delta) if (initialMouseBlock && !Terrarum.mouseDown) {
textArea2.update(delta) initialMouseBlock = false
}
//AppLoader.printdbg(this, "should be printing indefinitely") if (!initialMouseBlock) {
textArea1.update(delta)
textArea2.update(delta)
}
} }
override fun renderUI(batch: SpriteBatch, camera: Camera) { override fun renderUI(batch: SpriteBatch, camera: Camera) {
@@ -106,6 +112,14 @@ class UITitleLanguage(val remoCon: UIRemoCon) : UICanvas() {
textArea2.render(batch, camera) textArea2.render(batch, camera)
} }
override fun show() {
initialMouseBlock = true
}
override fun hide() {
initialMouseBlock = true
}
override fun doOpening(delta: Float) { override fun doOpening(delta: Float) {
} }

View File

@@ -14,7 +14,7 @@ object UITitleRemoConYaml {
val menuBase = """ val menuBase = """
- MENU_MODE_SINGLEPLAYER : net.torvald.terrarum.modulebasegame.ui.UILoadDemoSavefiles - MENU_MODE_SINGLEPLAYER : net.torvald.terrarum.modulebasegame.ui.UILoadDemoSavefiles
- MENU_OPTIONS - 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_OPTIONS_CONTROLS : net.torvald.terrarum.modulebasegame.ui.UIKeyboardControlPanel
- MENU_CONTROLS_KEYBOARD : net.torvald.terrarum.modulebasegame.ui.UIKeyboardInputConfig - MENU_CONTROLS_KEYBOARD : net.torvald.terrarum.modulebasegame.ui.UIKeyboardInputConfig
- MENU_LABEL_LANGUAGE : net.torvald.terrarum.modulebasegame.ui.UITitleLanguage - 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.Json
import com.badlogic.gdx.utils.JsonValue import com.badlogic.gdx.utils.JsonValue
import com.badlogic.gdx.utils.JsonWriter 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.console.EchoError
import net.torvald.terrarum.gameworld.BlockLayer import net.torvald.terrarum.gameworld.BlockLayer
import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.GameWorld
@@ -26,7 +28,7 @@ import java.util.zip.GZIPOutputStream
*/ */
object Common { object Common {
const val GENVER = 4 const val GENVER = TerrarumAppConfiguration.VERSION_RAW
const val COMP_NONE = 0 const val COMP_NONE = 0
const val COMP_GZIP = 1 const val COMP_GZIP = 1
const val COMP_LZMA = 2 const val COMP_LZMA = 2
@@ -187,6 +189,19 @@ object Common {
return UUID.fromString(jsonData.asString()) 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) 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.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.savegame.* import net.torvald.terrarum.savegame.*
import net.torvald.terrarum.worlddrawer.WorldCamera
import java.io.File import java.io.File
import java.io.Reader import java.io.Reader
import java.util.logging.Level import java.util.logging.Level
@@ -46,14 +47,17 @@ object WriteSavegame {
printdbg(this, "Save queued") printdbg(this, "Save queued")
if (hasThumbnail) { if (hasThumbnail) {
IngameRenderer.screencapExportCallback = { IngameRenderer.screencapExportCallback = { fb ->
printdbg(this, "Generating thumbnail...") printdbg(this, "Generating thumbnail...")
val w = 960 val w = 960
val h = 640 val h = 640
val x = (it.width - w).ushr(2).shl(1) // force the even-numbered position val cx = (1 - WorldCamera.x % 2)
val y = (it.height - h).ushr(2).shl(1) // force the even-numbered position 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) val p = Pixmap.createFromFrameBuffer(x, y, w, h)
IngameRenderer.fboRGBexport = p IngameRenderer.fboRGBexport = p

View File

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

View File

@@ -52,11 +52,11 @@ object AssembleSheetPixmap {
private fun drawAndGetCanvas(properties: ADProperties, fileGetter: (String) -> InputStream?, injectedItem: GameItem?): Pixmap { 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 canvas.blending = Pixmap.Blending.SourceOver
// actually draw // actually draw
properties.transforms.forEach { t, _ -> properties.transforms.forEach { (t, _) ->
drawThisFrame(t, canvas, properties, fileGetter, injectedItem) drawThisFrame(t, canvas, properties, fileGetter, injectedItem)
} }

View File

@@ -55,7 +55,9 @@ class ConsoleWindow : UICanvas() {
private var iMadeTheGameToPause = false 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 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 shaderKawaseDown = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/kawasedown.frag")
private val shaderKawaseUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawaseup.frag") private val shaderKawaseUp = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/kawaseup.frag")
private val shaderBoxDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxdown.frag") private val shaderBoxDown = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/boxdown.frag")
private val shaderBoxUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxup.frag") private val shaderBoxUp = App.loadShaderFromClasspath("shaders/4096.vert", "shaders/boxup.frag")
private lateinit var fboBlur: FloatFrameBuffer private lateinit var fboBlur: FloatFrameBuffer
private lateinit var fboBlurHalf: FloatFrameBuffer private lateinit var fboBlurHalf: FloatFrameBuffer

View File

@@ -64,6 +64,7 @@ class UIItemTextLineInput(
val maxLen: InputLenCap = InputLenCap(1000, InputLenCap.CharLenUnit.CODEPOINTS), val maxLen: InputLenCap = InputLenCap(1000, InputLenCap.CharLenUnit.CODEPOINTS),
// val enablePasteButton: Boolean = true, // val enablePasteButton: Boolean = true,
// val enableIMEButton: Boolean = true // val enableIMEButton: Boolean = true
var keyFilter: (TerrarumKeyboardEvent) -> Boolean = { true }
) : UIItem(parentUI, initialX, initialY) { ) : UIItem(parentUI, initialX, initialY) {
init { init {
@@ -203,138 +204,140 @@ class UIItemTextLineInput(
val (eventType, char, headkey, repeatCount, keycodes) = e val (eventType, char, headkey, repeatCount, keycodes) = e
try { if (keyFilter(e)) {
if (eventType == InputStrober.KEY_DOWN || eventType == InputStrober.KEY_CHANGE) { try {
fboUpdateLatch = true if (eventType == InputStrober.KEY_DOWN || eventType == InputStrober.KEY_CHANGE) {
forceLitCursor() fboUpdateLatch = true
val ime = getIME() forceLitCursor()
val lowLayer = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout")) 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)) { if (keycodes.contains(Input.Keys.V) && keycodes.containsSome(Input.Keys.CONTROL_LEFT, Input.Keys.CONTROL_RIGHT)) {
endComposing() endComposing()
paste(Clipboard.fetch().substringBefore('\n').substringBefore('\t').toCodePoints()) 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))) { else if (keycodes.contains(Input.Keys.C) && (keycodes.containsSome(Input.Keys.CONTROL_LEFT, Input.Keys.CONTROL_RIGHT))) {
endComposing() endComposing()
copyToClipboard() copyToClipboard()
} }
else if (keycodes.contains(Input.Keys.BACKSPACE) || (keycodes.contains(Input.Keys.CAPS_LOCK) && lowLayer.capsMode == TerrarumKeyCapsMode.BACK)) { 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 != null && ime.composing()) {
if (ime.config.mode == TerrarumIMEMode.CANDIDATES) { if (ime.config.mode == TerrarumIMEMode.CANDIDATES) {
candidates = ime.backspace().map { CodepointSequence(it.toCodePoints()) } 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)
} }
else if (ime.config.mode == TerrarumIMEMode.REWRITE) {
candidates = listOf()
val op = ime.backspace()
if (textbuf.isNotEmpty()) {
inputBackspaceOnce(1)
}
if (op.size > 0) { if (op.size > 0) {
val codepoints = op[0].toCodePoints() val codepoints = op[0].toCodePoints()
if (!maxLen.exceeds(textbuf, codepoints)) { if (!maxLen.exceeds(textbuf, codepoints)) {
textbuf.addAll(cursorX, codepoints) textbuf.addAll(cursorX, codepoints)
moveCursorToEnd(codepoints.size) moveCursorToEnd(codepoints.size)
}
} }
} }
} }
} else if (cursorX <= 0) {
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) {
cursorX = 0 cursorX = 0
cursorDrawX = 0 cursorDrawX = 0
cursorDrawScroll = 0 cursorDrawScroll = 0
} }
} else {
} endComposing()
else if (keycodes.contains(Input.Keys.RIGHT)) { inputBackspaceOnce(2)
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 if (ime.config.mode == TerrarumIMEMode.REWRITE) { }
candidates = listOf() else if (keycodes.contains(Input.Keys.LEFT)) {
val op = ime.acceptChar(headkey, shiftin, altgrin, char) endComposing()
// printdbg(this, "delcount: ${op.first[0].toInt()}, rewrite: '${op.second}'") if (cursorX > 0) {
cursorX -= 1
repeat(op.first[0].toInt()) { cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
if (textbuf.isNotEmpty()) { tryCursorForward()
// printdbg(this, "<del 1>") if (cursorX <= 0) {
inputBackspaceOnce(3) 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 (cursorX < textbuf.size) {
cursorX += 1
if (!maxLen.exceeds(textbuf, codepoints)) { cursorDrawX = App.fontGame.getWidth(CodepointSequence(textbuf.subList(0, cursorX)))
textbuf.addAll(cursorX, codepoints) tryCursorBack()
}
moveCursorToEnd(codepoints.size)
} }
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) {
catch (e: IndexOutOfBoundsException) { e.printStackTrace()
e.printStackTrace() }
} catch (e: NullPointerException) {
catch (e: NullPointerException) { e.printStackTrace()
e.printStackTrace() }
}
if (textbuf.size == 0) { if (textbuf.size == 0) {
currentPlaceholderText = CodepointSequence(placeholder().toCodePoints()) currentPlaceholderText = CodepointSequence(placeholder().toCodePoints())
}
} }
} }
else if (oldActive) { // just became deactivated else if (oldActive) { // just became deactivated

View File

@@ -85,7 +85,7 @@ internal object BlocksDrawer {
private lateinit var tilesQuad: Mesh 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 { init {

View File

@@ -60,8 +60,6 @@ object LightmapRenderer {
} }
finally { finally {
this.world = world this.world = world
//fireRecalculateEvent()
} }
} }
@@ -86,11 +84,6 @@ object LightmapRenderer {
private var _mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT) private var _mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
private var _mapThisTileOpacity2 = 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 private const val AIR = Block.AIR
const val DRAW_TILE_SIZE: Float = TILE_SIZE / IngameRenderer.lightmapDownsample 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 { try {
world.getTileFromTerrain(0, 0) // test inquiry world.getTileFromTerrain(0, 0) // test inquiry
} }
@@ -149,7 +149,7 @@ object LightmapRenderer {
return // quit prematurely return // quit prematurely
} }
catch (e: NullPointerException) { 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})") "(${world.layerTerrain.ptr})")
e.printStackTrace() e.printStackTrace()
return // something's wrong but we'll ignore it like a trustful AK 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") //println("$for_x_start..$for_x_end, $for_x\t$for_y_start..$for_y_end, $for_y")
App.measureDebugTime("Renderer.Lanterns") { App.measureDebugTime("Renderer.Lanterns") {
buildLanternmap(actorContainers) buildLanternmap(actorContainer)
} // usually takes 3000 ns } // usually takes 3000 ns
// set sunlight // set sunlight
@@ -205,27 +205,29 @@ object LightmapRenderer {
// 'NEWLIGHT2' LIGHT SWIPER // 'NEWLIGHT2' LIGHT SWIPER
// O((8*2)n) where n is a size of the map. // O((8*2)n) where n is a size of the map.
/* - */fun r1() { /* - */fun r1(lightmap: UnsafeCvecArray) {
swipeDiag = false swipeDiag = false
for (line in 1 until LIGHTMAP_HEIGHT - 1) { for (line in 1 until LIGHTMAP_HEIGHT - 1) {
swipeLight( swipeLight(
1, line, 1, line,
LIGHTMAP_WIDTH - 2, line, LIGHTMAP_WIDTH - 2, line,
1, 0 1, 0,
lightmap
) )
} }
} }
/* | */fun r2() { /* | */fun r2(lightmap: UnsafeCvecArray) {
swipeDiag = false swipeDiag = false
for (line in 1 until LIGHTMAP_WIDTH - 1) { for (line in 1 until LIGHTMAP_WIDTH - 1) {
swipeLight( swipeLight(
line, 1, line, 1,
line, LIGHTMAP_HEIGHT - 2, line, LIGHTMAP_HEIGHT - 2,
0, 1 0, 1,
lightmap
) )
} }
} }
/* \ */fun r3() { /* \ */fun r3(lightmap: UnsafeCvecArray) {
swipeDiag = true swipeDiag = true
/* construct indices such that: /* construct indices such that:
56789ABC 56789ABC
@@ -258,11 +260,12 @@ object LightmapRenderer {
swipeLight( swipeLight(
maxOf(1, i - LIGHTMAP_HEIGHT + 4), maxOf(1, LIGHTMAP_HEIGHT - 2 - i), 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), 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 swipeDiag = true
/* /*
1 w-2 1 w-2
@@ -291,7 +294,8 @@ object LightmapRenderer {
swipeLight( swipeLight(
maxOf(1, i - LIGHTMAP_HEIGHT + 4), minOf(LIGHTMAP_HEIGHT - 2, i + 1), 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), 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) // why dark spots appear in the first place)
// - Multithreading? I have absolutely no idea. // - Multithreading? I have absolutely no idea.
// - If you naively slice the screen (job area) to multithread, the seam will appear. // - If you naively slice the screen (job area) to multithread, the seam will appear.
r1(lightmap);r2(lightmap);r3(lightmap);r4(lightmap)
r1();r2();r3();r4() r1(lightmap);r2(lightmap);r3(lightmap);r4(lightmap) // two looks better than one
r1();r2();r3();r4() // two looks better than one
// no rendering trickery will eliminate the need of 2nd pass, even the "decay out" // 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() lanternMap.clear()
actorContainers.forEach { actorContainer -> actorContainer.forEach {
actorContainer?.forEach { if (it is Luminous) {
if (it is Luminous) { val lightBoxCopy = it.lightBoxList.subList(0, it.lightBoxList.size) // make copy to prevent ConcurrentModificationException
// 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()) {
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 swipeX = -1
private var swipeY = -1 private var swipeY = -1
private var swipeDiag = false 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 if (x2 < 0 || y2 < 0 || x2 >= LIGHTMAP_WIDTH || y2 >= LIGHTMAP_HEIGHT) return
_ambientAccumulator.r = _mapLightLevelThis.getR(x, y) _ambientAccumulator.r = _mapLightLevelThis.getR(x, y)
@@ -535,25 +539,25 @@ object LightmapRenderer {
_thisTileOpacity.g = _mapThisTileOpacity.getG(x, y) _thisTileOpacity.g = _mapThisTileOpacity.getG(x, y)
_thisTileOpacity.b = _mapThisTileOpacity.getB(x, y) _thisTileOpacity.b = _mapThisTileOpacity.getB(x, y)
_thisTileOpacity.a = _mapThisTileOpacity.getA(x, y) _thisTileOpacity.a = _mapThisTileOpacity.getA(x, y)
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity)) _ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity, lightmap))
} }
else { else {
_thisTileOpacity2.r = _mapThisTileOpacity2.getR(x, y) _thisTileOpacity2.r = _mapThisTileOpacity2.getR(x, y)
_thisTileOpacity2.g = _mapThisTileOpacity2.getG(x, y) _thisTileOpacity2.g = _mapThisTileOpacity2.getG(x, y)
_thisTileOpacity2.b = _mapThisTileOpacity2.getB(x, y) _thisTileOpacity2.b = _mapThisTileOpacity2.getB(x, y)
_thisTileOpacity2.a = _mapThisTileOpacity2.getA(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) _mapLightLevelThis.setVec(x, y, _ambientAccumulator)
lightmap.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 swipeX = sx; swipeY = sy
while (swipeX*dx <= ex*dx && swipeY*dy <= ey*dy) { while (swipeX*dx <= ex*dx && swipeY*dy <= ey*dy) {
// conduct the task #1 // conduct the task #1
// spread towards the end // spread towards the end
_swipeTask(swipeX, swipeY, swipeX-dx, swipeY-dy) _swipeTask(swipeX, swipeY, swipeX-dx, swipeY-dy, lightmap)
swipeX += dx swipeX += dx
swipeY += dy swipeY += dy
@@ -563,7 +567,7 @@ object LightmapRenderer {
while (swipeX*dx >= sx*dx && swipeY*dy >= sy*dy) { while (swipeX*dx >= sx*dx && swipeY*dy >= sy*dy) {
// conduct the task #2 // conduct the task #2
// spread towards the start // spread towards the start
_swipeTask(swipeX, swipeY, swipeX+dx, swipeY+dy) _swipeTask(swipeX, swipeY, swipeX+dx, swipeY+dy, lightmap)
swipeX -= dx swipeX -= dx
swipeY -= dy swipeY -= dy
@@ -682,7 +686,7 @@ object LightmapRenderer {
* @param darken (0-255) per channel * @param darken (0-255) per channel
* @return darkened data (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 // 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) // 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! // copied from BlocksDrawer, duh!
// FIXME 'lightBuffer' is not zoomable in this way // FIXME 'lightBuffer' is not zoomable in this way
val tilesInHorizontal = (App.scr.wf / TILE_SIZE).ceilInt() + 1 + LIGHTMAP_OVERRENDER * 2 val tilesInHorizontal = (App.scr.wf / TILE_SIZE).ceilInt() + 1 + LIGHTMAP_OVERRENDER * 2
val tilesInVertical = (App.scr.hf / 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) lightBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
lightmap.destroy() lightmap.destroy()
_mapLightLevelThis.destroy() _mapLightLevelThis.destroy()
_mapThisTileOpacity.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