mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
Compare commits
195 Commits
v0.3.2-tes
...
v0.3.3-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97a7a36030 | ||
|
|
662069466a | ||
|
|
52cff00338 | ||
|
|
1a40334f8e | ||
|
|
763f512419 | ||
|
|
620a1c6956 | ||
|
|
5f4fcdba69 | ||
|
|
7a79f444b2 | ||
|
|
e4b947ce69 | ||
|
|
fdfec960ca | ||
|
|
75021ecfa2 | ||
|
|
c90ef21bfa | ||
|
|
3fce5d7e95 | ||
|
|
8db1228e70 | ||
|
|
5f7f724058 | ||
|
|
fab4179068 | ||
|
|
32803b6f18 | ||
|
|
f8f75fb7b6 | ||
|
|
9919a99032 | ||
|
|
6a43d1a5bd | ||
|
|
24c971e4b8 | ||
|
|
62f0fd7c68 | ||
|
|
3dec312989 | ||
|
|
77b51a45dd | ||
|
|
d1b4ce3404 | ||
|
|
fd7b88307c | ||
|
|
579b6b5b29 | ||
|
|
cef58f6a73 | ||
|
|
c0c98c3b80 | ||
|
|
88d844cc09 | ||
|
|
2411db17a7 | ||
|
|
53d372be38 | ||
|
|
88831051c8 | ||
|
|
87d92ecb74 | ||
|
|
6672dffdbc | ||
|
|
cd00ab4c7f | ||
|
|
014306c209 | ||
|
|
30fb57eca3 | ||
|
|
52ad8f0c46 | ||
|
|
1b08039018 | ||
|
|
c701519cb9 | ||
|
|
75e6669d49 | ||
|
|
18631064d4 | ||
|
|
9fe6618cc9 | ||
|
|
7b8d6d6913 | ||
|
|
385a882937 | ||
|
|
c73461a407 | ||
|
|
f7e4987785 | ||
|
|
78bd88858b | ||
|
|
d2b1346252 | ||
|
|
fb28fd8a76 | ||
|
|
36d25c6479 | ||
|
|
2ade76147c | ||
|
|
59d9adbbd1 | ||
|
|
821c7c77d8 | ||
|
|
3308f09e08 | ||
|
|
37d45e22ad | ||
|
|
1ac861fa82 | ||
|
|
451808cd1c | ||
|
|
0c00b3b7cc | ||
|
|
1669f7fdd0 | ||
|
|
f4bfe84009 | ||
|
|
91cf08e93a | ||
|
|
33a8112454 | ||
|
|
439cde09fc | ||
|
|
2a62435712 | ||
|
|
5495552db5 | ||
|
|
e04d0284bb | ||
|
|
ad601ffd7e | ||
|
|
987ec1fd98 | ||
|
|
4fb30821f1 | ||
|
|
a73c536941 | ||
|
|
4c1f16fe91 | ||
|
|
6df78b59a9 | ||
|
|
28c4d8f11b | ||
|
|
cdfc86398c | ||
|
|
91d94d2dab | ||
|
|
0af2e57368 | ||
|
|
fbce707cac | ||
|
|
9d7bd37394 | ||
|
|
df8bcf79af | ||
|
|
e328457259 | ||
|
|
9baec6c7a1 | ||
|
|
d05364f43f | ||
|
|
e7ed3d8eae | ||
|
|
da6da79186 | ||
|
|
0767521441 | ||
|
|
30aca57cbc | ||
|
|
e512c6c7ad | ||
|
|
6ebf79a8e3 | ||
|
|
e5d5feeb38 | ||
|
|
8e9d2371c8 | ||
|
|
1f5d032ad8 | ||
|
|
7993ccd2e5 | ||
|
|
c77f1ffd23 | ||
|
|
4eb7a8a77e | ||
|
|
10f92a11a9 | ||
|
|
c5659e2833 | ||
|
|
173f99f87d | ||
|
|
64e05a4f17 | ||
|
|
c033260ec5 | ||
|
|
22191bd377 | ||
|
|
79f19120f2 | ||
|
|
d96b7d1b84 | ||
|
|
2b62b4f413 | ||
|
|
f0fa5830bd | ||
|
|
ec24dc9870 | ||
|
|
6bc3d0e6ad | ||
|
|
64c610e77e | ||
|
|
b25ea9654c | ||
|
|
b6b98562a2 | ||
|
|
c93b70f537 | ||
|
|
fb67b0ef5a | ||
|
|
7c7b3de68d | ||
|
|
71df31b93d | ||
|
|
9b24014191 | ||
|
|
02308a7918 | ||
|
|
03c6061a12 | ||
|
|
325e67f999 | ||
|
|
211f936bd3 | ||
|
|
1f6fa49d19 | ||
|
|
13810fc09b | ||
|
|
f95bc36c98 | ||
|
|
d507d84950 | ||
|
|
b31da6ffec | ||
|
|
3593894c0f | ||
|
|
c28b286553 | ||
|
|
c0a3da1b66 | ||
|
|
02cf5fdce5 | ||
|
|
1e6f51e16c | ||
|
|
c61c169048 | ||
|
|
5c58c3006b | ||
|
|
742cabb81f | ||
|
|
07d5e571d6 | ||
|
|
305242045f | ||
|
|
67388999f0 | ||
|
|
b0cc1180bb | ||
|
|
453459e3b6 | ||
|
|
bad72dd353 | ||
|
|
13185f0565 | ||
|
|
fcaf4c97f1 | ||
|
|
9c396e7b8d | ||
|
|
afb7dff5d2 | ||
|
|
5d0514040c | ||
|
|
7c1806946b | ||
|
|
e5e02681b8 | ||
|
|
6db3baf691 | ||
|
|
07cbcbe79b | ||
|
|
57a9f7febc | ||
|
|
16cfaaea27 | ||
|
|
72c742897e | ||
|
|
23af64deb4 | ||
|
|
bb017fa9b7 | ||
|
|
1745bb16db | ||
|
|
370583d1af | ||
|
|
66b651c627 | ||
|
|
c5874a7f3d | ||
|
|
057905c3b7 | ||
|
|
2b50562002 | ||
|
|
73a8198378 | ||
|
|
1ef479124e | ||
|
|
e5e8028b3f | ||
|
|
739b51af95 | ||
|
|
f9f49ab63c | ||
|
|
a497463349 | ||
|
|
253db56c4f | ||
|
|
3d13941060 | ||
|
|
592e489411 | ||
|
|
49b2011ea0 | ||
|
|
61e6255b52 | ||
|
|
2e956f89f5 | ||
|
|
e8ffd1f844 | ||
|
|
0882145f9c | ||
|
|
28e2179e44 | ||
|
|
48eb1ffd8f | ||
|
|
6daccb2e62 | ||
|
|
8c9d5a26fb | ||
|
|
ee3e5b14cd | ||
|
|
5c39df9080 | ||
|
|
5d77694316 | ||
|
|
cf111d2507 | ||
|
|
724ace3f00 | ||
|
|
1457cbffb3 | ||
|
|
7a42066392 | ||
|
|
528b975350 | ||
|
|
9e9064dd55 | ||
|
|
138c6d22d2 | ||
|
|
a33f0e7ab4 | ||
|
|
93c427473d | ||
|
|
6b8798a19e | ||
|
|
376595d7cd | ||
|
|
4cc52b5585 | ||
|
|
0ff71f39fe | ||
|
|
13f487a562 | ||
|
|
0599ce91b1 |
24
.idea/artifacts/TerrarumBuild.xml
generated
24
.idea/artifacts/TerrarumBuild.xml
generated
@@ -13,6 +13,10 @@
|
|||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-controllers-desktop-2.2.1.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-controllers-desktop-2.2.1.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/GetCpuName.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/GetCpuName.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/jxinput-1.0.0.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/jxinput-1.0.0.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk7.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk8.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-csv-1.8.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-csv-1.8.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/prtree.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/prtree.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/Terrarum_Joise.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/Terrarum_Joise.jar" path-in-jar="/" />
|
||||||
@@ -72,21 +76,17 @@
|
|||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.11.0-natives-armeabi-v7a.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.11.0-natives-armeabi-v7a.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.11.0-natives-desktop.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.11.0-natives-desktop.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.11.0-natives-x86_64.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.11.0-natives-x86_64.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.21/kotlin-stdlib-1.8.21.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.21/kotlin-stdlib-common-1.8.21.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-test/1.8.21/kotlin-test-1.8.21.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.8.21/kotlin-reflect-1.8.21.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.8.21/kotlin-reflect-1.8.21.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk8.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.21/kotlin-stdlib-1.8.21.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.21/kotlin-stdlib-common-1.8.21.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk7.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-test/1.8.21/kotlin-test-1.8.21.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/graal-sdk-22.3.1.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/icu4j-71.1.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-22.3.1-edit.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-scriptengine-22.3.1.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-scriptengine-22.3.1.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/regex-22.3.1-edit.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/truffle-api-22.3.1.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/truffle-api-22.3.1.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/icu4j-71.1.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/regex-22.3.1-edit.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-22.3.1-edit.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/graal-sdk-22.3.1.jar" path-in-jar="/" />
|
||||||
</root>
|
</root>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
19
.idea/runConfigurations/Principii.xml
generated
Normal file
19
.idea/runConfigurations/Principii.xml
generated
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Principii" type="Application" factoryName="Application" nameIsGenerated="true">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="net.torvald.terrarum.Principii" />
|
||||||
|
<module name="TerrarumBuild" />
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="net.torvald.terrarum.*" />
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<method v="2">
|
||||||
|
<option name="BuildArtifacts" enabled="true">
|
||||||
|
<artifact name="ModuleComputers" />
|
||||||
|
<artifact name="TerrarumBuild" />
|
||||||
|
</option>
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -1,26 +1,17 @@
|
|||||||
package net.torvald.terrarum.modulecomputers.gameactors
|
package net.torvald.terrarum.modulecomputers.gameactors
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
|
||||||
import com.badlogic.gdx.Input
|
|
||||||
import com.badlogic.gdx.graphics.*
|
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
|
||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import kotlin.coroutines.*
|
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||||
import net.torvald.terrarum.gameactors.AVKey
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
import net.torvald.terrarum.langpack.Lang
|
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.BlockBox
|
import net.torvald.terrarum.modulebasegame.gameactors.BlockBox
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.modulecomputers.ui.UIHomeComputer
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
|
||||||
import net.torvald.tsvm.*
|
import net.torvald.tsvm.*
|
||||||
import net.torvald.tsvm.peripheral.AdapterConfig
|
import net.torvald.tsvm.peripheral.AdapterConfig
|
||||||
import net.torvald.tsvm.peripheral.GraphicsAdapter
|
import net.torvald.tsvm.peripheral.GraphicsAdapter
|
||||||
import net.torvald.tsvm.peripheral.VMProgramRom
|
import net.torvald.tsvm.peripheral.VMProgramRom
|
||||||
import net.torvald.unicode.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2021-12-04.
|
* Created by minjaesong on 2021-12-04.
|
||||||
@@ -131,84 +122,3 @@ class FixtureHomeComputer : FixtureBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class UIHomeComputer : UICanvas(
|
|
||||||
toggleKeyLiteral = Input.Keys.ESCAPE, // FIXME why do I have specify ESC for it to function? ESC should be work as the default key
|
|
||||||
toggleButtonLiteral = App.getConfigInt("control_gamepad_start"),
|
|
||||||
) {
|
|
||||||
override var width = 640
|
|
||||||
override var height = 480
|
|
||||||
override var openCloseTime = 0f
|
|
||||||
|
|
||||||
private val drawOffX = (width - 560).div(2).toFloat()
|
|
||||||
private val drawOffY = (height - 448).div(2).toFloat()
|
|
||||||
|
|
||||||
private var batch: FlippingSpriteBatch
|
|
||||||
private var camera: OrthographicCamera
|
|
||||||
|
|
||||||
internal lateinit var vm: VM
|
|
||||||
internal lateinit var fixture: FixtureHomeComputer
|
|
||||||
|
|
||||||
init {
|
|
||||||
batch = FlippingSpriteBatch()
|
|
||||||
camera = OrthographicCamera(width.toFloat(), height.toFloat())
|
|
||||||
//val m = Matrix4()
|
|
||||||
//m.setToOrtho2D(0f, 0f, width.toFloat(), height.toFloat())
|
|
||||||
batch.projectionMatrix = camera.combined
|
|
||||||
}
|
|
||||||
|
|
||||||
private val fbo = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
|
|
||||||
|
|
||||||
private val controlHelp =
|
|
||||||
"${getKeycapPC(App.getConfigInt("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}\u3000 " +
|
|
||||||
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_T$KEYCAP_R Terminate\u3000" +
|
|
||||||
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_S Reset\u3000" +
|
|
||||||
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_Q SysRq"
|
|
||||||
|
|
||||||
override fun updateUI(delta: Float) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun renderUI(otherBatch: SpriteBatch, otherCamera: Camera) {
|
|
||||||
otherBatch.end()
|
|
||||||
|
|
||||||
fbo.inAction(camera, batch) {
|
|
||||||
Gdx.gl.glClearColor(0f,0f,0f,1f)
|
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) // to hide the crap might be there
|
|
||||||
|
|
||||||
(vm.peripheralTable[1].peripheral as? GraphicsAdapter)?.let { gpu ->
|
|
||||||
val clearCol = gpu.getBackgroundColour()
|
|
||||||
Gdx.gl.glClearColor(clearCol.r, clearCol.g, clearCol.b, clearCol.a)
|
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
|
||||||
|
|
||||||
gpu.render(Gdx.graphics.deltaTime, batch, drawOffX, drawOffY, true, fbo) // gpu.render will internally end() the fbo then begin() again before using the batch I've fed in
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
otherBatch.begin()
|
|
||||||
otherBatch.shader = null
|
|
||||||
blendNormalStraightAlpha(otherBatch)
|
|
||||||
otherBatch.color = Color.WHITE
|
|
||||||
otherBatch.draw(fbo.colorBufferTexture, posX.toFloat(), posY.toFloat(), width.toFloat(), height.toFloat())
|
|
||||||
otherBatch.color = Toolkit.Theme.COL_INACTIVE
|
|
||||||
Toolkit.drawBoxBorder(otherBatch, posX - 1, posY - 1, width + 2, height + 2)
|
|
||||||
|
|
||||||
App.fontGame.draw(otherBatch, controlHelp, posX, posY + height + 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doOpening(delta: Float) {
|
|
||||||
fixture.startVM()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doClosing(delta: Float) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun endOpening(delta: Float) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun endClosing(delta: Float) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispose() {
|
|
||||||
fbo.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package net.torvald.terrarum.modulecomputers.ui
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.Input
|
||||||
|
import com.badlogic.gdx.graphics.*
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
|
import net.torvald.terrarum.App
|
||||||
|
import net.torvald.terrarum.FlippingSpriteBatch
|
||||||
|
import net.torvald.terrarum.blendNormalStraightAlpha
|
||||||
|
import net.torvald.terrarum.inAction
|
||||||
|
import net.torvald.terrarum.langpack.Lang
|
||||||
|
import net.torvald.terrarum.modulecomputers.gameactors.FixtureHomeComputer
|
||||||
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
|
import net.torvald.tsvm.VM
|
||||||
|
import net.torvald.tsvm.peripheral.GraphicsAdapter
|
||||||
|
import net.torvald.unicode.*
|
||||||
|
|
||||||
|
internal class UIHomeComputer : UICanvas(
|
||||||
|
toggleKeyLiteral = Input.Keys.ESCAPE, // FIXME why do I have specify ESC for it to function? ESC should be work as the default key
|
||||||
|
toggleButtonLiteral = App.getConfigInt("control_gamepad_start"),
|
||||||
|
) {
|
||||||
|
override var width = 640
|
||||||
|
override var height = 480
|
||||||
|
override var openCloseTime = 0f
|
||||||
|
|
||||||
|
private val drawOffX = (width - 560).div(2).toFloat()
|
||||||
|
private val drawOffY = (height - 448).div(2).toFloat()
|
||||||
|
|
||||||
|
private var batch: FlippingSpriteBatch
|
||||||
|
private var camera: OrthographicCamera
|
||||||
|
|
||||||
|
internal lateinit var vm: VM
|
||||||
|
internal lateinit var fixture: FixtureHomeComputer
|
||||||
|
|
||||||
|
init {
|
||||||
|
batch = FlippingSpriteBatch()
|
||||||
|
camera = OrthographicCamera(width.toFloat(), height.toFloat())
|
||||||
|
//val m = Matrix4()
|
||||||
|
//m.setToOrtho2D(0f, 0f, width.toFloat(), height.toFloat())
|
||||||
|
batch.projectionMatrix = camera.combined
|
||||||
|
}
|
||||||
|
|
||||||
|
private val fbo = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
|
||||||
|
|
||||||
|
private val controlHelp =
|
||||||
|
"${getKeycapPC(App.getConfigInt("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}\u3000 " +
|
||||||
|
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_T$KEYCAP_R Terminate\u3000" +
|
||||||
|
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_S Reset\u3000" +
|
||||||
|
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_Q SysRq"
|
||||||
|
|
||||||
|
override fun updateUI(delta: Float) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun renderUI(otherBatch: SpriteBatch, otherCamera: Camera) {
|
||||||
|
otherBatch.end()
|
||||||
|
|
||||||
|
fbo.inAction(camera, batch) {
|
||||||
|
Gdx.gl.glClearColor(0f,0f,0f,1f)
|
||||||
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) // to hide the crap might be there
|
||||||
|
|
||||||
|
(vm.peripheralTable[1].peripheral as? GraphicsAdapter)?.let { gpu ->
|
||||||
|
val clearCol = gpu.getBackgroundColour()
|
||||||
|
Gdx.gl.glClearColor(clearCol.r, clearCol.g, clearCol.b, clearCol.a)
|
||||||
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
|
gpu.render(Gdx.graphics.deltaTime, batch, drawOffX, drawOffY, true, fbo) // gpu.render will internally end() the fbo then begin() again before using the batch I've fed in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
otherBatch.begin()
|
||||||
|
otherBatch.shader = null
|
||||||
|
blendNormalStraightAlpha(otherBatch)
|
||||||
|
otherBatch.color = Color.WHITE
|
||||||
|
otherBatch.draw(fbo.colorBufferTexture, posX.toFloat(), posY.toFloat(), width.toFloat(), height.toFloat())
|
||||||
|
otherBatch.color = Toolkit.Theme.COL_INACTIVE
|
||||||
|
Toolkit.drawBoxBorder(otherBatch, posX - 1, posY - 1, width + 2, height + 2)
|
||||||
|
|
||||||
|
App.fontGame.draw(otherBatch, controlHelp, posX, posY + height + 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doOpening(delta: Float) {
|
||||||
|
super.doOpening(delta)
|
||||||
|
fixture.startVM()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
fbo.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
assets/clut/skybox.png
LFS
Normal file
BIN
assets/clut/skybox.png
LFS
Normal file
Binary file not shown.
BIN
assets/graphics/astrum.png
LFS
Normal file
BIN
assets/graphics/astrum.png
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/graphics/gui/apple_rosetta_warning.tga
LFS
Normal file
BIN
assets/graphics/gui/apple_rosetta_warning.tga
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -379,11 +379,11 @@ let isDiacritics = (s) => s !== undefined && inRange(s.charCodeAt(0), 0x0300, 0x
|
|||||||
return Object.freeze({"n":"\uDBBF\uDFC1Бъл. Многоезична\uDBBF\uDFC0","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"\uDBBF\uDFC1Бъл. Многоезична\uDBBF\uDFC0","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":dislplayKeyLayouts,
|
"t":dislplayKeyLayouts,
|
||||||
"l":"bgBG",
|
"l":"bgBG",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin + 2*altgrin
|
let layer = 1*shiftin + 2*altgrin
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = (states.keylayouts[headkey][layer] || states.keylayouts[headkey][1*shiftin]) || states.keylayouts[headkey][0]
|
||||||
|
|
||||||
// typing seq for diacritics: diacritics THEN a character
|
// typing seq for diacritics: diacritics THEN a character
|
||||||
if (isDiacritics(s)) {
|
if (isDiacritics(s)) {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ let isDiacritics = (s) => s !== undefined && inRange(s.charCodeAt(0), 0x0300, 0x
|
|||||||
return Object.freeze({"n":"Ελ. Φωνητικό","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"Ελ. Φωνητικό","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"tf":states.layouttable,
|
"tf":states.layouttable,
|
||||||
"l":"elGR",
|
"l":"elGR",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin,lowlayerkey)=>{
|
"accept":(headkey,shiftin,altgrin,lowlayerkey)=>{
|
||||||
let layer = 1*shiftin + 2*altgrin
|
let layer = 1*shiftin + 2*altgrin
|
||||||
|
|
||||||
|
|||||||
283
assets/keylayout/hi_in_inscript.ime
Normal file
283
assets/keylayout/hi_in_inscript.ime
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
let states = {"keylayouts":[[""],[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
["0",")","\u0966",")"],
|
||||||
|
["1","\u090D","\u0967","!"],
|
||||||
|
["2","\u0945","\u0968","@"],
|
||||||
|
["3","\u094D\u0930","\u0969","#"],
|
||||||
|
["4","\u0930\u094D","\u096A","$"],
|
||||||
|
["5","\u091C\u094D\u091E","\u096B","%"],
|
||||||
|
["6","\u0924\u094D\u0930","\u096C","^"],
|
||||||
|
["7","\u0915\u094D\u0937","\u096D","&"],
|
||||||
|
["8","\u0936\u094D\u0930","\u096E","*"],
|
||||||
|
["9","(","\u096F","("],
|
||||||
|
["*"],
|
||||||
|
["#"],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
["\u094B","\u0913"],
|
||||||
|
["\u0935","\u0934"],
|
||||||
|
["\u092E","\u0923","\u0954","\u0923"],
|
||||||
|
["\u094D","\u0905"],
|
||||||
|
["\u093E","\u0906"],
|
||||||
|
["\u093F","\u0907","\u0962","\u090C"],
|
||||||
|
["\u0941","\u0909"],
|
||||||
|
["\u092A","\u092B","\u092A","\u095E"],
|
||||||
|
["\u0917","\u0918","\u095A","\u0918"],
|
||||||
|
["\u0930","\u0931"],
|
||||||
|
["\u0915","\u0916","\u0958","\u0959"],
|
||||||
|
["\u0924","\u0925"],
|
||||||
|
["\u0938","\u0936"],
|
||||||
|
["\u0932","\u0933"],
|
||||||
|
["\u0926","\u0927"],
|
||||||
|
["\u091C","\u091D","\u095B","\u091D"],
|
||||||
|
["\u094C","\u0914"],
|
||||||
|
["\u0940","\u0908","\u0963","\u0961"],
|
||||||
|
["\u0947","\u090F"],
|
||||||
|
["\u0942","\u090A"],
|
||||||
|
["\u0939","\u0919"],
|
||||||
|
["\u0928","\u0929"],
|
||||||
|
["\u0948","\u0910"],
|
||||||
|
["\u0902","\u0901","\u0902","\u0950"],
|
||||||
|
["\u092C","\u092D"],
|
||||||
|
["\u0946","\u090E","\u0953","\u090E"],
|
||||||
|
[",","\u0937","\u0970","\u0970"],
|
||||||
|
[".","\u0964","\u0965","\u093D"],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[" "],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
["\n"],
|
||||||
|
["\x08"],
|
||||||
|
["\u094A","\u0912"],
|
||||||
|
["-","\u0903"],
|
||||||
|
["\u0943","\u090B","\u0944","\u0960"],
|
||||||
|
["\u0921","\u0922","\u095C","\u095D"],
|
||||||
|
["\u093C","\u091E"],
|
||||||
|
["\u0949","\u0911"],
|
||||||
|
["\u091A","\u091B","\u0952","\u091B"],
|
||||||
|
["\u091F","\u0920","\u0951","\u0920"],
|
||||||
|
["\u092F","\u095F"],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
["0"],
|
||||||
|
["1"],
|
||||||
|
["2"],
|
||||||
|
["3"],
|
||||||
|
["4"],
|
||||||
|
["5"],
|
||||||
|
["6"],
|
||||||
|
["7"],
|
||||||
|
["8"],
|
||||||
|
["9"],
|
||||||
|
["/"],
|
||||||
|
["*"],
|
||||||
|
["-"],
|
||||||
|
["+"],
|
||||||
|
["."],
|
||||||
|
["."],
|
||||||
|
["\n"],
|
||||||
|
["="],
|
||||||
|
["("],
|
||||||
|
[")"],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined]
|
||||||
|
],
|
||||||
|
"code":""} // practically unused as long as there are no diacritics on the keyboard
|
||||||
|
let reset = () => {
|
||||||
|
states.code = 0
|
||||||
|
}
|
||||||
|
let inRange = (s,a,b) => (a <= s && s <= b)
|
||||||
|
return Object.freeze({"n":"इनस्क्रिप्ट","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
|
"t":states.keylayouts.slice(0,10).concat([["3","\uDBBF\uDE01\u094D\u0930","\u0969","#"], ["4","\u0930\u094D\uDBBF\uDE01","\u096A","$"]], states.keylayouts.slice(12)),
|
||||||
|
"l":"hiIN",
|
||||||
|
// return: [delete count, composed output]
|
||||||
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
|
let layer = 1*shiftin + 2*altgrin
|
||||||
|
|
||||||
|
let s = (states.keylayouts[headkey][layer] || states.keylayouts[headkey][1*shiftin]) || states.keylayouts[headkey][0]
|
||||||
|
|
||||||
|
return ['0', s]
|
||||||
|
},
|
||||||
|
"backspace":()=>{
|
||||||
|
reset()
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
"end":()=>{
|
||||||
|
reset()
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
"reset":()=>{ reset() },
|
||||||
|
"composing":()=>(states.code!='')
|
||||||
|
})
|
||||||
@@ -346,12 +346,12 @@ let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" :
|
|||||||
return Object.freeze({"n":"두벌식 표준","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"두벌식 표준","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||||
"l":"koKR",
|
"l":"koKR",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin// + 2*altgrin
|
let layer = 1*shiftin// + 2*altgrin
|
||||||
states.code = 1
|
states.code = 1
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||||
|
|
||||||
if (isHangul(s)) {
|
if (isHangul(s)) {
|
||||||
let bufIndex = (isJongseongConsonant(s) && isConsonant(states.buf[0]) && undefined !== states.buf[1]) ? 2 :
|
let bufIndex = (isJongseongConsonant(s) && isConsonant(states.buf[0]) && undefined !== states.buf[1]) ? 2 :
|
||||||
|
|||||||
@@ -346,12 +346,12 @@ let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" :
|
|||||||
return Object.freeze({"n":"두벌식 수정 표준","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"두벌식 수정 표준","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||||
"l":"koKR",
|
"l":"koKR",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin// + 2*altgrin
|
let layer = 1*shiftin// + 2*altgrin
|
||||||
states.code = 1
|
states.code = 1
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||||
|
|
||||||
if (isHangul(s)) {
|
if (isHangul(s)) {
|
||||||
let bufIndex = (isJongseongConsonant(s) && isConsonant(states.buf[0]) && undefined !== states.buf[1]) ? 2 :
|
let bufIndex = (isJongseongConsonant(s) && isConsonant(states.buf[0]) && undefined !== states.buf[1]) ? 2 :
|
||||||
|
|||||||
@@ -375,12 +375,12 @@ let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" :
|
|||||||
return Object.freeze({"n":"세벌식 3-90","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"세벌식 3-90","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||||
"l":"koKR",
|
"l":"koKR",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin// + 2*altgrin
|
let layer = 1*shiftin// + 2*altgrin
|
||||||
states.code = 1
|
states.code = 1
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||||
let bufIndex = isJungseong(s) ? 1 : isJongseong(s) ? 2 : 0
|
let bufIndex = isJungseong(s) ? 1 : isJongseong(s) ? 2 : 0
|
||||||
|
|
||||||
if (isHangul(s)) {
|
if (isHangul(s)) {
|
||||||
|
|||||||
@@ -375,12 +375,12 @@ let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" :
|
|||||||
return Object.freeze({"n":"세벌식 공자판","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"세벌식 공자판","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||||
"l":"koKR",
|
"l":"koKR",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin// + 2*altgrin
|
let layer = 1*shiftin// + 2*altgrin
|
||||||
states.code = 1
|
states.code = 1
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||||
let bufIndex = isJungseong(s) ? 1 : isJongseong(s) ? 2 : 0
|
let bufIndex = isJungseong(s) ? 1 : isJongseong(s) ? 2 : 0
|
||||||
|
|
||||||
if (isHangul(s)) {
|
if (isHangul(s)) {
|
||||||
|
|||||||
@@ -385,12 +385,12 @@ let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" :
|
|||||||
return Object.freeze({"n":"신세벌식 ’03","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"신세벌식 ’03","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||||
"l":"koKR",
|
"l":"koKR",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin// + 2*altgrin
|
let layer = 1*shiftin// + 2*altgrin
|
||||||
states.code = 1
|
states.code = 1
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||||
let s2 = states.keylayouts[headkey][2]
|
let s2 = states.keylayouts[headkey][2]
|
||||||
let bufIndex = isJungseong(s) ? 1 : isJongseong(s) ? 2 : 0
|
let bufIndex = isJungseong(s) ? 1 : isJongseong(s) ? 2 : 0
|
||||||
|
|
||||||
|
|||||||
@@ -385,12 +385,12 @@ let bufDebugStringify = (buf) => [0,1,2].map(i => (buf[i] == undefined) ? "·" :
|
|||||||
return Object.freeze({"n":"신세벌식 P2","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"신세벌식 P2","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||||
"l":"koKR",
|
"l":"koKR",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin// + 2*altgrin
|
let layer = 1*shiftin// + 2*altgrin
|
||||||
states.code = 1
|
states.code = 1
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||||
let s2 = states.keylayouts[headkey][2]
|
let s2 = states.keylayouts[headkey][2]
|
||||||
let bufIndex = isJungseong(s) ? 1 : isJongseong(s) ? 2 : 0
|
let bufIndex = isJungseong(s) ? 1 : isJongseong(s) ? 2 : 0
|
||||||
|
|
||||||
|
|||||||
@@ -375,11 +375,11 @@ let isDiacritics = (s) => s !== undefined && inRange(s.charCodeAt(0), 0x0300, 0x
|
|||||||
return Object.freeze({"n":"ЙЦУКЕН Многоязычна","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"ЙЦУКЕН Многоязычна","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts,
|
"t":states.keylayouts,
|
||||||
"l":"ruRU",
|
"l":"ruRU",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin + 2*altgrin
|
let layer = 1*shiftin + 2*altgrin
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = (states.keylayouts[headkey][layer] || states.keylayouts[headkey][1*shiftin]) || states.keylayouts[headkey][0]
|
||||||
|
|
||||||
// typing seq for diacritics: diacritics THEN a character
|
// typing seq for diacritics: diacritics THEN a character
|
||||||
if (isDiacritics(s)) {
|
if (isDiacritics(s)) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ let states = {"keylayouts":[[""],[undefined],
|
|||||||
[undefined],
|
[undefined],
|
||||||
[undefined],
|
[undefined],
|
||||||
["ф","Ф","ƒ","ƒ"],
|
["ф","Ф","ƒ","ƒ"],
|
||||||
["и","И"],
|
["и","И","и","И"],
|
||||||
["с","С","≠","≠"],
|
["с","С","≠","≠"],
|
||||||
["в","В","ћ","Ћ"],
|
["в","В","ћ","Ћ"],
|
||||||
["у","У","ќ","Ќ"],
|
["у","У","ќ","Ќ"],
|
||||||
@@ -69,10 +69,10 @@ let states = {"keylayouts":[[""],[undefined],
|
|||||||
["-","_","—","–"],
|
["-","_","—","–"],
|
||||||
["=","+","»","«"],
|
["=","+","»","«"],
|
||||||
["х","Х","“","“"],
|
["х","Х","“","“"],
|
||||||
["ъ","Ъ"],
|
["ъ","Ъ","ъ","Ъ"],
|
||||||
["ё","Ё"],
|
["ё","Ё","ё","Ё"],
|
||||||
["ж","Ж","…","…"],
|
["ж","Ж","…","…"],
|
||||||
["э",'Э'],
|
["э",'Э',"э",'Э'],
|
||||||
["/","?","„","„"],
|
["/","?","„","„"],
|
||||||
[undefined],
|
[undefined],
|
||||||
[undefined],
|
[undefined],
|
||||||
@@ -263,12 +263,12 @@ let isDiacritics = (s) => s !== undefined && inRange(s.charCodeAt(0), 0x0300, 0x
|
|||||||
return Object.freeze({"n":"ЙЦУКЕН (Рус. Apple)","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"ЙЦУКЕН (Рус. Apple)","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts,
|
"t":states.keylayouts,
|
||||||
"l":"ruRU",
|
"l":"ruRU",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin + 2*altgrin
|
let layer = 1*shiftin + 2*altgrin
|
||||||
states.code = 1
|
states.code = 1
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = (states.keylayouts[headkey][layer] || states.keylayouts[headkey][1*shiftin]) || states.keylayouts[headkey][0]
|
||||||
|
|
||||||
if (isDiacritics(s)) {
|
if (isDiacritics(s)) {
|
||||||
return ['1', '']
|
return ['1', '']
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ let isDiacritics = (s) => s !== undefined && inRange(s.charCodeAt(0), 0x0300, 0x
|
|||||||
return Object.freeze({"n":"Рус. Фонетическая","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"Рус. Фонетическая","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"tf":states.layouttable,
|
"tf":states.layouttable,
|
||||||
"l":"ruRU",
|
"l":"ruRU",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin,lowlayerkey)=>{
|
"accept":(headkey,shiftin,altgrin,lowlayerkey)=>{
|
||||||
let layer = 1*shiftin// + 2*altgrin
|
let layer = 1*shiftin// + 2*altgrin
|
||||||
states.code = 1
|
states.code = 1
|
||||||
|
|||||||
290
assets/keylayout/ta_in_tamil99.ime
Normal file
290
assets/keylayout/ta_in_tamil99.ime
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
let states = {"keylayouts":[[""],[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
["0",")"],
|
||||||
|
["1","!"],
|
||||||
|
["2","@"],
|
||||||
|
["3","#"],
|
||||||
|
["4","$"],
|
||||||
|
["5","%"],
|
||||||
|
["6","^"],
|
||||||
|
["7","&"],
|
||||||
|
["8","*"],
|
||||||
|
["9","("],
|
||||||
|
["*"],
|
||||||
|
["#"],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
["\u0B85","\u0BF9"],
|
||||||
|
["\u0B99","\u0BF7"],
|
||||||
|
["\u0B92","\u0BF5","\u0BCA"],
|
||||||
|
["\u0B89","\u0BF8","\u0BC1"],
|
||||||
|
["\u0B8A","\u0B9C","\u0BC2"],
|
||||||
|
["\u0BCD","\u0B83"],
|
||||||
|
["\u0B8E","\u0B8E","\u0BC6"],
|
||||||
|
["\u0B95","\u0B95"],
|
||||||
|
["\u0BA9","\u0BA9"],
|
||||||
|
["\u0BAA","\u0BAA"],
|
||||||
|
["\u0BAE",'"'],
|
||||||
|
["\u0BA4",":"],
|
||||||
|
["\u0BB0","/"],
|
||||||
|
["\u0BB2","\u0BB2"],
|
||||||
|
["\u0B9F","["],
|
||||||
|
["\u0BA3","]"],
|
||||||
|
["\u0B86","\u0BB8","\u0BBE"],
|
||||||
|
["\u0B90","\u0BB9","\u0BC8"],
|
||||||
|
["\u0B87","\u0BFA","\u0BBF"],
|
||||||
|
["\u0B8F","\u0B95\u0BCD\u0BB7","\u0BC7"],
|
||||||
|
["\u0BB1","\u0BB1"],
|
||||||
|
["\u0BB5","\u0BF6"],
|
||||||
|
["\u0B88","\u0BB7","\u0BC0"],
|
||||||
|
["\u0B93","\u0BF4","\u0BCB"],
|
||||||
|
["\u0BB3","\u0BB8\u0BCD\u0BB0\u0BC0"],
|
||||||
|
["\u0B94","\u0BF3","\u0BCC"],
|
||||||
|
[",","<"],
|
||||||
|
[".",">"],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[" "],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
["\n"],
|
||||||
|
["\x08"],
|
||||||
|
["`","~"],
|
||||||
|
["-","_"],
|
||||||
|
["=","+"],
|
||||||
|
["\u0B9A","{"],
|
||||||
|
["\u0B9E","}"],
|
||||||
|
["\\","|"],
|
||||||
|
["\u0BA8",";"],
|
||||||
|
["\u0BAF","'"],
|
||||||
|
["\u0BB4","?"],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
["0"],
|
||||||
|
["1"],
|
||||||
|
["2"],
|
||||||
|
["3"],
|
||||||
|
["4"],
|
||||||
|
["5"],
|
||||||
|
["6"],
|
||||||
|
["7"],
|
||||||
|
["8"],
|
||||||
|
["9"],
|
||||||
|
["/"],
|
||||||
|
["*"],
|
||||||
|
["-"],
|
||||||
|
["+"],
|
||||||
|
["."],
|
||||||
|
["."],
|
||||||
|
["\n"],
|
||||||
|
["="],
|
||||||
|
["("],
|
||||||
|
[")"],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined],
|
||||||
|
[undefined]
|
||||||
|
],
|
||||||
|
"code":""} // the last character typed
|
||||||
|
let reset = () => {
|
||||||
|
states.code = ""
|
||||||
|
}
|
||||||
|
let inRange = (s,a,b) => (a <= s && s <= b)
|
||||||
|
let isConsonant = (s) => s !== undefined && (inRange(s, 0x0B95, 0x0BB9) || s == 0x0BD0 || inRange(s, 0x0BE6, 0x0BFA)) // determines the behaviour of the vowel key
|
||||||
|
return Object.freeze({"n":"தமிழ் 99","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
|
"t":states.keylayouts,
|
||||||
|
"l":"taIN",
|
||||||
|
// return: [delete count, composed output]
|
||||||
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
|
let layer = 1*shiftin
|
||||||
|
|
||||||
|
let s = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||||
|
|
||||||
|
if (layer == 0 && states.code != "" && isConsonant(states.code.charCodeAt(states.code.length - 1))) {
|
||||||
|
s = states.keylayouts[headkey][2] || states.keylayouts[headkey][0]
|
||||||
|
}
|
||||||
|
|
||||||
|
states.code = s
|
||||||
|
|
||||||
|
return ['0', s]
|
||||||
|
},
|
||||||
|
"backspace":()=>{
|
||||||
|
reset()
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
"end":()=>{
|
||||||
|
reset()
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
"reset":()=>{ reset() },
|
||||||
|
"composing":()=>(states.code!='')
|
||||||
|
})
|
||||||
@@ -269,12 +269,12 @@ let isDiacritics = (s) => s !== undefined && inRange(s.charCodeAt(0), 0x0300, 0x
|
|||||||
return Object.freeze({"n":"แป้นพิมพ์เกษมณี","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"แป้นพิมพ์เกษมณี","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts,
|
"t":states.keylayouts,
|
||||||
"l":"thTH",
|
"l":"thTH",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin + 2*altgrin // use AltGr to type conventional numbers
|
let layer = 1*shiftin + 2*altgrin // use AltGr to type conventional numbers
|
||||||
states.code = 0
|
states.code = 0
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = (states.keylayouts[headkey][layer] || states.keylayouts[headkey][1*shiftin]) || states.keylayouts[headkey][0]
|
||||||
return ['0', s]
|
return ['0', s]
|
||||||
},
|
},
|
||||||
"backspace":()=>{
|
"backspace":()=>{
|
||||||
|
|||||||
@@ -269,12 +269,12 @@ let isDiacritics = (s) => s !== undefined && (inRange(s.charCodeAt(0), 0x0E31, 0
|
|||||||
return Object.freeze({"n":"แป้นพิมพ์ปัตตะโชติ","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
return Object.freeze({"n":"แป้นพิมพ์ปัตตะโชติ","v":"none","c":"CuriousTo\uA75Bvald","m":"rewrite",
|
||||||
"t":states.keylayouts,
|
"t":states.keylayouts,
|
||||||
"l":"thTH",
|
"l":"thTH",
|
||||||
// return: [displayed output, composed output]
|
// return: [delete count, composed output]
|
||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin + 2*altgrin // use AltGr to type conventional numbers
|
let layer = 1*shiftin + 2*altgrin // use AltGr to type conventional numbers
|
||||||
states.code = 0
|
states.code = 0
|
||||||
|
|
||||||
let s = states.keylayouts[headkey][layer]
|
let s = (states.keylayouts[headkey][layer] || states.keylayouts[headkey][1*shiftin]) || states.keylayouts[headkey][0]
|
||||||
return ['0', s]
|
return ['0', s]
|
||||||
},
|
},
|
||||||
"backspace":()=>{
|
"backspace":()=>{
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ return Object.freeze({"n":"五仓简体 Qwerty","v":"many","c":"CuriousTo\uA75Bv
|
|||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin// + 2*altgrin
|
let layer = 1*shiftin// + 2*altgrin
|
||||||
|
|
||||||
let cjkey = states.keylayouts[headkey][layer]
|
let cjkey = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||||
let cjkeyAsc = cjkey.codePointAt(0)
|
let cjkeyAsc = cjkey.codePointAt(0)
|
||||||
|
|
||||||
if (states.code == 1 && 48 <= cjkeyAsc && cjkeyAsc <= 57) {
|
if (states.code == 1 && 48 <= cjkeyAsc && cjkeyAsc <= 57) {
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ return Object.freeze({"n":"五倉正體 Qwerty","v":"many","c":"CuriousTo\uA75Bv
|
|||||||
"accept":(headkey,shiftin,altgrin)=>{
|
"accept":(headkey,shiftin,altgrin)=>{
|
||||||
let layer = 1*shiftin// + 2*altgrin
|
let layer = 1*shiftin// + 2*altgrin
|
||||||
|
|
||||||
let cjkey = states.keylayouts[headkey][layer]
|
let cjkey = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||||
let cjkeyAsc = cjkey.codePointAt(0)
|
let cjkeyAsc = cjkey.codePointAt(0)
|
||||||
|
|
||||||
if (states.code == 1 && 48 <= cjkeyAsc && cjkeyAsc <= 57) {
|
if (states.code == 1 && 48 <= cjkeyAsc && cjkeyAsc <= 57) {
|
||||||
|
|||||||
4
assets/locales/de/input.json
Normal file
4
assets/locales/de/input.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"INPUT_KEYBOARD_DEFAULT_LAYOUT": "en_intl_qwertz",
|
||||||
|
"INPUT_KEYBOARD_DEFAULT_IME": "none"
|
||||||
|
}
|
||||||
@@ -1,31 +1,41 @@
|
|||||||
{
|
{
|
||||||
|
"APP_WARNING_HEALTH_AND_SAFETY": "WARNING-HEALTH AND SAFETY",
|
||||||
"CONTEXT_CHARACTER": "Character",
|
"CONTEXT_CHARACTER": "Character",
|
||||||
"MENU_LABEL_COPYRIGHT": "Copyright",
|
"CONTEXT_TIME_MINUTE_PLURAL": "Minutes",
|
||||||
|
"CONTEXT_TIME_SECOND_PLURAL": "Seconds",
|
||||||
"COPYRIGHT_ALL_RIGHTS_RESERVED": "All rights reserved",
|
"COPYRIGHT_ALL_RIGHTS_RESERVED": "All rights reserved",
|
||||||
"COPYRIGHT_GNU_GPL_3": "Distributed under GNU GPL 3",
|
"COPYRIGHT_GNU_GPL_3": "Distributed under GNU GPL 3",
|
||||||
"APP_WARNING_HEALTH_AND_SAFETY": "WARNING-HEALTH AND SAFETY",
|
|
||||||
"MENU_LABEL_PRESS_START_SYMBOL": "Press >",
|
|
||||||
"MENU_MODULES" : "Modules",
|
|
||||||
"MENU_CREDIT_GPL_DNT" : "GPL",
|
|
||||||
"GAME_ACTION_MOVE_VERB" : "Move",
|
"GAME_ACTION_MOVE_VERB" : "Move",
|
||||||
"GAME_ACTION_ZOOM" : "Zoom",
|
"GAME_ACTION_ZOOM" : "Zoom",
|
||||||
"MENU_LABEL_RESET" : "Reset",
|
"MENU_IO_AUTOSAVE": "Autosave",
|
||||||
"GAME_32BIT_WARNING1": "It looks like you’re running a 32-Bit version of Java.",
|
|
||||||
"GAME_32BIT_WARNING2": "Please download and install the latest 64-Bit Java at:",
|
|
||||||
"GAME_32BIT_WARNING3": "https://www.java.com/en/download/",
|
|
||||||
"MENU_OPTION_STREAMERS_LAYOUT": "Chat Overlay",
|
|
||||||
"MENU_LABEL_RESTART_REQUIRED": "Restart Required",
|
|
||||||
"MENU_LABEL_KEYBOARD_LAYOUT": "Keyboard Layout",
|
|
||||||
"MENU_LABEL_IME": "IME",
|
|
||||||
"MENU_OPTIONS_DITHER": "Dithering",
|
|
||||||
"MENU_OPTIONS_BLUR": "Blur",
|
|
||||||
"MENU_OPTIONS_PARTICLES": "Particles",
|
|
||||||
"MENU_IO_IMPORT": "Import",
|
"MENU_IO_IMPORT": "Import",
|
||||||
"APP_NOMODULE_1": "No Module is currently loaded.",
|
"MENU_IO_MANUAL_SAVE": "Manual Save",
|
||||||
"APP_NOMODULE_2": "Please configure your Load Order and restart:",
|
"MENU_LABEL_COPYRIGHT": "Copyright",
|
||||||
"MENU_LABEL_KEYCONFIG_HELP1": "Click On the Keycap to Assign Actions",
|
"MENU_LABEL_DELETE": "Delete",
|
||||||
|
"MENU_LABEL_EXTRA_JVM_ARGUMENTS": "Extra Arguments",
|
||||||
|
"MENU_LABEL_IME": "IME",
|
||||||
"MENU_LABEL_IME_TOGGLE": "Toggle IME",
|
"MENU_LABEL_IME_TOGGLE": "Toggle IME",
|
||||||
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Paste from Cliboard",
|
"MENU_LABEL_KEYBOARD_LAYOUT": "Keyboard Layout",
|
||||||
|
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Paste from Clipboard",
|
||||||
|
"MENU_LABEL_PRESS_START_SYMBOL": "Press >",
|
||||||
|
"MENU_LABEL_RESET" : "Reset",
|
||||||
|
"MENU_LABEL_RESTART_REQUIRED": "Restart Required",
|
||||||
|
"MENU_LABEL_STREAMING": "Livestreaming",
|
||||||
|
"MENU_LABEL_SYSTEM_INFO": "System Info",
|
||||||
|
"MENU_MODULES" : "Modules",
|
||||||
|
"MENU_OPTIONS_ATLAS_TEXTURE_SIZE": "Atlas Texture Size",
|
||||||
|
"MENU_OPTIONS_AUTOSAVE": "Autosave",
|
||||||
|
"MENU_OPTIONS_BLUR": "Blur",
|
||||||
|
"MENU_OPTIONS_DEBUG_CONSOLE": "Debug Console",
|
||||||
|
"MENU_OPTIONS_DITHER": "Dithering",
|
||||||
|
"MENU_OPTIONS_JVM_HEAP_MAX": "Max Heap Memory",
|
||||||
|
"MENU_OPTIONS_NOTIFICATION_DISPLAY_DURATION": "Show notification for",
|
||||||
|
"MENU_OPTIONS_PARTICLES": "Particles",
|
||||||
"MENU_OPTIONS_PERFORMANCE": "Performance",
|
"MENU_OPTIONS_PERFORMANCE": "Performance",
|
||||||
"MENU_LABEL_DELETE": "Delete"
|
"MENU_OPTIONS_STREAMERS_LAYOUT": "Chat Overlay",
|
||||||
|
"MENU_OPTIONS_NONE" : "None",
|
||||||
|
|
||||||
|
"MENU_CREDIT_GPL_DNT" : "GPL",
|
||||||
|
"MENU_LABEL_JVM_DNT" : "JVM",
|
||||||
|
"MENU_OPTIONS_FILTERING_HQ2X_DNT" : "Hq2x"
|
||||||
}
|
}
|
||||||
16
assets/locales/en/terrarum_sentences.json
Normal file
16
assets/locales/en/terrarum_sentences.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"GAME_32BIT_WARNING1": "It looks like you’re running a 32-Bit version of Java.",
|
||||||
|
"GAME_32BIT_WARNING2": "Please download and install the latest 64-Bit Java at:",
|
||||||
|
"GAME_32BIT_WARNING3": "https://www.java.com/en/download/",
|
||||||
|
"GAME_APPLE_ROSETTA_WARNING1": "It seems you are using a Mac with Apple Silicon but running the x86 build of the game.",
|
||||||
|
"GAME_APPLE_ROSETTA_WARNING2": "Please use the native build for improved performance and gameplay experiences.",
|
||||||
|
"APP_NOMODULE_1": "No Module is currently loaded.",
|
||||||
|
"APP_NOMODULE_2": "Please configure your Load Order and restart:",
|
||||||
|
"MENU_LABEL_KEYCONFIG_HELP1": "Click On the Keycap to Assign Actions",
|
||||||
|
"GAME_PREV_SAVE_WAS_LOADED1": "The most recently saved game was corrupted.",
|
||||||
|
"GAME_PREV_SAVE_WAS_LOADED2": "The previously saved game was loaded.",
|
||||||
|
"GAME_MORE_RECENT_AUTOSAVE1": "The Autosave is more recent than the manual save.",
|
||||||
|
"GAME_MORE_RECENT_AUTOSAVE2": "Please select the saved game you wish to play:",
|
||||||
|
"MENU_LABEL_SAVE_WILL_BE_DELETED": "The selected save file will be deleted.",
|
||||||
|
"MENU_LABEL_UNSAVED_PROGRESS_WILL_BE_LOST": "Unsaved progress will be lost."
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
"GAME_ACTION_MOVE_VERB" : "हिलना",
|
"GAME_ACTION_MOVE_VERB" : "हिलना",
|
||||||
"GAME_ACTION_ZOOM" : "ज़ूम",
|
"GAME_ACTION_ZOOM" : "ज़ूम",
|
||||||
"MENU_LABEL_RESET" : "रीसेट",
|
"MENU_LABEL_RESET" : "रीसेट",
|
||||||
"MENU_OPTION_STREAMERS_LAYOUT": "Chat Overlay",
|
"MENU_OPTIONS_STREAMERS_LAYOUT": "Chat Overlay",
|
||||||
"MENU_LABEL_RESTART_REQUIRED": "पुनः शुरआत जरुरी है",
|
"MENU_LABEL_RESTART_REQUIRED": "पुनः शुरआत जरुरी है",
|
||||||
"MENU_LABEL_KEYBOARD_LAYOUT": "कीबोर्ड विन्यास",
|
"MENU_LABEL_KEYBOARD_LAYOUT": "कीबोर्ड विन्यास",
|
||||||
"MENU_LABEL_IME": "इनपुट विधि",
|
"MENU_LABEL_IME": "इनपुट विधि",
|
||||||
|
|||||||
@@ -2335,7 +2335,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"n": "MENU_OPTIONS",
|
"n": "MENU_OPTIONS",
|
||||||
"s": "Stillingar "
|
"s": "Valkostir "
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"n": "MENU_OPTIONS_ADVANCEDGRAPHICS",
|
"n": "MENU_OPTIONS_ADVANCEDGRAPHICS",
|
||||||
@@ -2395,11 +2395,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"n": "MENU_OPTIONS_GAMEPLAY",
|
"n": "MENU_OPTIONS_GAMEPLAY",
|
||||||
"s": "Gameplay Options"
|
"s": "Leikvalkostir"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"n": "MENU_OPTIONS_GRAPHICS",
|
"n": "MENU_OPTIONS_GRAPHICS",
|
||||||
"s": "Grafíkstillingar"
|
"s": "Grafíkvalkostir"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"n": "MENU_OPTIONS_HUD",
|
"n": "MENU_OPTIONS_HUD",
|
||||||
|
|||||||
@@ -15,5 +15,15 @@
|
|||||||
"MENU_OPTIONS_DITHER": "Dither",
|
"MENU_OPTIONS_DITHER": "Dither",
|
||||||
"MENU_OPTIONS_BLUR": "Óskýrt",
|
"MENU_OPTIONS_BLUR": "Óskýrt",
|
||||||
"MENU_OPTIONS_PARTICLES": "Eind",
|
"MENU_OPTIONS_PARTICLES": "Eind",
|
||||||
"MENU_IO_IMPORT": "Flytja inn"
|
"MENU_IO_IMPORT": "Flytja inn",
|
||||||
|
"APP_NOMODULE_1": "Engin eining er hlaðin eins og er.",
|
||||||
|
"APP_NOMODULE_2": "Vinsamlega stilltu hleðslupöntunina þína og endurræstu:",
|
||||||
|
"MENU_LABEL_KEYCONFIG_HELP1": "Smelltu á lyklalokið til að úthluta aðgerðum",
|
||||||
|
"MENU_LABEL_IME_TOGGLE": "Breyttu IME",
|
||||||
|
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Límdu frá klemmuspjald",
|
||||||
|
"MENU_OPTIONS_PERFORMANCE": "Afköst",
|
||||||
|
"MENU_LABEL_DELETE": "Eyða",
|
||||||
|
"MENU_OPTIONS_JVM_HEAP_MAX": "Hámarks hrúguminni",
|
||||||
|
"MENU_OPTIONS_AUTOSAVE": "Sjálfvirk vistun",
|
||||||
|
"CONTEXT_TIME_MINUTE_PLURAL": "Mínútur"
|
||||||
}
|
}
|
||||||
@@ -1,29 +1,37 @@
|
|||||||
{
|
{
|
||||||
|
"APP_WARNING_HEALTH_AND_SAFETY": "경고—건강과 안전을 위하여",
|
||||||
"CONTEXT_CHARACTER": "캐릭터",
|
"CONTEXT_CHARACTER": "캐릭터",
|
||||||
"MENU_LABEL_COPYRIGHT": "저작권",
|
"CONTEXT_TIME_MINUTE_PLURAL": "분",
|
||||||
|
"CONTEXT_TIME_SECOND_PLURAL": "초",
|
||||||
"COPYRIGHT_ALL_RIGHTS_RESERVED": "모든 권리 보유",
|
"COPYRIGHT_ALL_RIGHTS_RESERVED": "모든 권리 보유",
|
||||||
"COPYRIGHT_GNU_GPL_3": "GNU GPL 3에 따라 배포됨",
|
"COPYRIGHT_GNU_GPL_3": "GNU GPL 3에 따라 배포됨",
|
||||||
"APP_WARNING_HEALTH_AND_SAFETY": "경고—건강과 안전을 위하여",
|
|
||||||
"MENU_LABEL_PRESS_START_SYMBOL": ">을 누르세요",
|
|
||||||
"MENU_MODULES" : "모듈",
|
|
||||||
"GAME_ACTION_MOVE_VERB" : "이동하기",
|
"GAME_ACTION_MOVE_VERB" : "이동하기",
|
||||||
"GAME_ACTION_ZOOM" : "확대·축소",
|
"GAME_ACTION_ZOOM" : "확대·축소",
|
||||||
"MENU_LABEL_RESET" : "재설정",
|
"MENU_IO_AUTOSAVE": "자동 저장",
|
||||||
"GAME_32BIT_WARNING1": "32비트 버전의 Java를 사용중인 것 같습니다.",
|
|
||||||
"GAME_32BIT_WARNING2": "아래 링크에서 최신 64비트 Java를 내려받아 설치해주세요.",
|
|
||||||
"GAME_32BIT_WARNING3": "https://www.java.com/ko/download/",
|
|
||||||
"MENU_OPTION_STREAMERS_LAYOUT": "채팅창 오버레이",
|
|
||||||
"MENU_LABEL_RESTART_REQUIRED": "재시작 필요",
|
|
||||||
"MENU_LABEL_KEYBOARD_LAYOUT": "자판 배열",
|
|
||||||
"MENU_LABEL_IME": "입력기",
|
|
||||||
"MENU_OPTIONS_DITHER": "디더링",
|
|
||||||
"MENU_OPTIONS_BLUR": "흐림",
|
|
||||||
"MENU_OPTIONS_PARTICLES": "입자 수",
|
|
||||||
"MENU_IO_IMPORT": "가져오기",
|
"MENU_IO_IMPORT": "가져오기",
|
||||||
"APP_NOMODULE_1": "현재 불러와진 모듈이 없습니다.",
|
"MENU_IO_MANUAL_SAVE": "수동 저장",
|
||||||
"APP_NOMODULE_2": "다음의 파일에서 불러오기 순서를 설정하고 게임을 재시작하십시오.",
|
"MENU_LABEL_COPYRIGHT": "저작권",
|
||||||
"MENU_LABEL_KEYCONFIG_HELP1": "키캡을 클릭해 컨트롤을 배정하십시오",
|
"MENU_LABEL_DELETE": "삭제",
|
||||||
|
"MENU_LABEL_EXTRA_JVM_ARGUMENTS": "추가 명령 인수",
|
||||||
|
"MENU_LABEL_IME": "입력기",
|
||||||
"MENU_LABEL_IME_TOGGLE": "입력기 켜고 끄기",
|
"MENU_LABEL_IME_TOGGLE": "입력기 켜고 끄기",
|
||||||
|
"MENU_LABEL_KEYBOARD_LAYOUT": "자판 배열",
|
||||||
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "복사한 텍스트 붙여넣기",
|
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "복사한 텍스트 붙여넣기",
|
||||||
"MENU_OPTIONS_PERFORMANCE": "성능"
|
"MENU_LABEL_PRESS_START_SYMBOL": ">을 누르세요",
|
||||||
|
"MENU_LABEL_RESET" : "재설정",
|
||||||
|
"MENU_LABEL_RESTART_REQUIRED": "재시작 필요",
|
||||||
|
"MENU_LABEL_STREAMING": "실시간 방송",
|
||||||
|
"MENU_LABEL_SYSTEM_INFO": "시스템 정보",
|
||||||
|
"MENU_MODULES" : "모듈",
|
||||||
|
"MENU_OPTIONS_ATLAS_TEXTURE_SIZE": "아틀라스 텍스처 크기",
|
||||||
|
"MENU_OPTIONS_AUTOSAVE": "자동 저장",
|
||||||
|
"MENU_OPTIONS_BLUR": "흐림",
|
||||||
|
"MENU_OPTIONS_DEBUG_CONSOLE": "디버그 콘솔",
|
||||||
|
"MENU_OPTIONS_DITHER": "디더링",
|
||||||
|
"MENU_OPTIONS_JVM_HEAP_MAX": "최대 힙 메모리",
|
||||||
|
"MENU_OPTIONS_NOTIFICATION_DISPLAY_DURATION": "알림 표시 시간",
|
||||||
|
"MENU_OPTIONS_PARTICLES": "입자 수",
|
||||||
|
"MENU_OPTIONS_PERFORMANCE": "성능",
|
||||||
|
"MENU_OPTIONS_STREAMERS_LAYOUT": "채팅창 오버레이",
|
||||||
|
"MENU_OPTIONS_NONE" : "없음"
|
||||||
}
|
}
|
||||||
|
|||||||
16
assets/locales/koKR/terrarum_sentences.json
Normal file
16
assets/locales/koKR/terrarum_sentences.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"GAME_32BIT_WARNING1": "32비트 버전의 Java를 사용중인 것 같습니다.",
|
||||||
|
"GAME_32BIT_WARNING2": "아래 링크에서 최신 64비트 Java를 내려받아 설치해주세요.",
|
||||||
|
"GAME_32BIT_WARNING3": "https://www.java.com/ko/download/",
|
||||||
|
"GAME_APPLE_ROSETTA_WARNING1": "Apple Silicon이 탑재된 Mac을 사용 중이지만 x86 빌드의 게임을 실행 중입니다.",
|
||||||
|
"GAME_APPLE_ROSETTA_WARNING2": "최적의 성능과 게임 경험을 위해 Apple Silicon용 빌드의 게임을 이용해 주십시오.",
|
||||||
|
"APP_NOMODULE_1": "현재 불러와진 모듈이 없습니다.",
|
||||||
|
"APP_NOMODULE_2": "다음의 파일에서 불러오기 순서를 설정하고 게임을 재시작하십시오.",
|
||||||
|
"MENU_LABEL_KEYCONFIG_HELP1": "키캡을 클릭해 컨트롤을 배정하십시오",
|
||||||
|
"GAME_PREV_SAVE_WAS_LOADED1": "가장 최근에 저장된 게임이 손상되었습니다.",
|
||||||
|
"GAME_PREV_SAVE_WAS_LOADED2": "이전에 저장된 게임을 불러왔습니다.",
|
||||||
|
"GAME_MORE_RECENT_AUTOSAVE1": "자동 저장된 게임이 수동으로 저장한 게임보다 더 최신입니다.",
|
||||||
|
"GAME_MORE_RECENT_AUTOSAVE2": "불러올 게임을 선택해 주십시오.",
|
||||||
|
"MENU_LABEL_SAVE_WILL_BE_DELETED": "선택된 세이브가 삭제됩니다.",
|
||||||
|
"MENU_LABEL_UNSAVED_PROGRESS_WILL_BE_LOST": "저장하지 않은 진행 상황을 잃게 됩니다."
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"GAME_32BIT_WARNING1": "看起来您正在运行32位版本的Java。",
|
"GAME_32BIT_WARNING1": "看起来您正在运行32位版本的Java。",
|
||||||
"GAME_32BIT_WARNING2": "请下载并安装最新的64位Java :",
|
"GAME_32BIT_WARNING2": "请下载并安装最新的64位Java :",
|
||||||
"GAME_32BIT_WARNING3": "https://www.java.com/en/download/",
|
"GAME_32BIT_WARNING3": "https://www.java.com/en/download/",
|
||||||
"MENU_OPTION_STREAMERS_LAYOUT": "聊天叠加",
|
"MENU_OPTIONS_STREAMERS_LAYOUT": "聊天叠加",
|
||||||
"MENU_LABEL_RESTART_REQUIRED": "需要重新启动",
|
"MENU_LABEL_RESTART_REQUIRED": "需要重新启动",
|
||||||
"MENU_LABEL_KEYBOARD_LAYOUT": "键盘布局",
|
"MENU_LABEL_KEYBOARD_LAYOUT": "键盘布局",
|
||||||
"MENU_LABEL_IME": "输入法",
|
"MENU_LABEL_IME": "输入法",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"GAME_32BIT_WARNING1": "看起來您正在運行32位版本的Java。",
|
"GAME_32BIT_WARNING1": "看起來您正在運行32位版本的Java。",
|
||||||
"GAME_32BIT_WARNING2": "請下載並安裝最新的64位Java :",
|
"GAME_32BIT_WARNING2": "請下載並安裝最新的64位Java :",
|
||||||
"GAME_32BIT_WARNING3": "https://www.java.com/en/download/",
|
"GAME_32BIT_WARNING3": "https://www.java.com/en/download/",
|
||||||
"MENU_OPTION_STREAMERS_LAYOUT": "聊天疊加",
|
"MENU_OPTIONS_STREAMERS_LAYOUT": "聊天疊加",
|
||||||
"MENU_LABEL_RESTART_REQUIRED": "需要重新啟動",
|
"MENU_LABEL_RESTART_REQUIRED": "需要重新啟動",
|
||||||
"MENU_LABEL_KEYBOARD_LAYOUT": "鍵盤配置",
|
"MENU_LABEL_KEYBOARD_LAYOUT": "鍵盤配置",
|
||||||
"MENU_LABEL_IME": "輸入法",
|
"MENU_LABEL_IME": "輸入法",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"id";"drop";"spawn";"name";"shdr";"shdg";"shdb";"shduv";"str";"dsty";"mate";"solid";"wall";"grav";"dlfn";"fv";"fr";"lumr";"lumg";"lumb";"lumuv";"colour";"vscs";"refl";"tags"
|
"id";"drop";"spawn";"name";"shdr";"shdg";"shdb";"shduv";"str";"dsty";"mate";"solid";"wall";"grav";"dlfn";"fv";"fr";"lumr";"lumg";"lumb";"lumuv";"colour";"vscs";"refl";"tags"
|
||||||
"0";"0";"0";"BLOCK_AIR";"0.0312";"0.0312";"0.0312";"0.0312";"1";"1";"NULL";"0";"1";"N/A";"0";"0";"4";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";""
|
"0";"0";"0";"BLOCK_AIR";"0.0312";"0.0312";"0.0312";"0.0312";"1";"1";"NULL";"0";"1";"N/A";"0";"0";"4";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"INCONSEQUENTIAL"
|
||||||
"16";"17";"17";"BLOCK_STONE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURAL"
|
"16";"17";"17";"BLOCK_STONE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURAL"
|
||||||
"17";"17";"17";"BLOCK_STONE_QUARRIED";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK"
|
"17";"17";"17";"BLOCK_STONE_QUARRIED";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK"
|
||||||
"18";"18";"18";"BLOCK_STONE_TILE_WHITE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.18";"STONE"
|
"18";"18";"18";"BLOCK_STONE_TILE_WHITE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.18";"STONE"
|
||||||
@@ -23,12 +23,12 @@
|
|||||||
"65";"65";"65";"BLOCK_TRUNK_EBONY";"0.0312";"0.0312";"0.0312";"0.0312";"19";"1200";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,NATURAL"
|
"65";"65";"65";"BLOCK_TRUNK_EBONY";"0.0312";"0.0312";"0.0312";"0.0312";"19";"1200";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,NATURAL"
|
||||||
"66";"66";"66";"BLOCK_TRUNK_BIRCH";"0.0312";"0.0312";"0.0312";"0.0312";"15";"670";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,NATURAL"
|
"66";"66";"66";"BLOCK_TRUNK_BIRCH";"0.0312";"0.0312";"0.0312";"0.0312";"15";"670";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,NATURAL"
|
||||||
"67";"67";"67";"BLOCK_TRUNK_BLOODROSE";"0.0312";"0.0312";"0.0312";"0.0312";"17";"900";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,NATURAL"
|
"67";"67";"67";"BLOCK_TRUNK_BLOODROSE";"0.0312";"0.0312";"0.0312";"0.0312";"17";"900";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,NATURAL"
|
||||||
"80";"80";"80";"BLOCK_SAND";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL"
|
"80";"80";"80";"BLOCK_SAND";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL,WARM"
|
||||||
"81";"81";"81";"BLOCK_SAND_WHITE";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL"
|
"81";"81";"81";"BLOCK_SAND_WHITE";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL,WARM"
|
||||||
"82";"82";"82";"BLOCK_SAND_RED";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL"
|
"82";"82";"82";"BLOCK_SAND_RED";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL,WARM"
|
||||||
"83";"83";"83";"BLOCK_SAND_DESERT";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL"
|
"83";"83";"83";"BLOCK_SAND_DESERT";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL,WARM"
|
||||||
"84";"84";"84";"BLOCK_SAND_BLACK";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL"
|
"84";"84";"84";"BLOCK_SAND_BLACK";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL,WARM"
|
||||||
"85";"85";"85";"BLOCK_SAND_GREEN";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL"
|
"85";"85";"85";"BLOCK_SAND_GREEN";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"SAND";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.06";"SAND,NATURAL,WARM"
|
||||||
"96";"96";"96";"BLOCK_GRAVEL";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"GRVL";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GRAVEL,NATURAL"
|
"96";"96";"96";"BLOCK_GRAVEL";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"GRVL";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GRAVEL,NATURAL"
|
||||||
"97";"97";"97";"BLOCK_GRAVEL_GREY";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"GRVL";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GRAVEL,NATURAL"
|
"97";"97";"97";"BLOCK_GRAVEL_GREY";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"GRVL";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GRAVEL,NATURAL"
|
||||||
"112";"112";"112";"BLOCK_ORE_MALACHITE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"OORE";"1";"0";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ORE,NATURAL"
|
"112";"112";"112";"BLOCK_ORE_MALACHITE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"OORE";"1";"0";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ORE,NATURAL"
|
||||||
@@ -44,10 +44,10 @@
|
|||||||
"132";"132";"132";"BLOCK_GEM_DIAMOND";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"OGEM";"1";"0";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GEM,NATURAL"
|
"132";"132";"132";"BLOCK_GEM_DIAMOND";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"OGEM";"1";"0";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GEM,NATURAL"
|
||||||
"133";"133";"133";"BLOCK_GEM_AMETHYST";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"OGEM";"1";"0";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GEM,NATURAL"
|
"133";"133";"133";"BLOCK_GEM_AMETHYST";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"OGEM";"1";"0";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GEM,NATURAL"
|
||||||
"134";"134";"134";"BLOCK_GEM_QUARTZ";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"OGEM";"1";"0";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GEM,NATURAL"
|
"134";"134";"134";"BLOCK_GEM_QUARTZ";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"OGEM";"1";"0";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GEM,NATURAL"
|
||||||
"144";"144";"144";"BLOCK_SNOW";"0.1252";"0.1252";"0.1252";"0.1252";"24";"500";"SNOW";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"SNOW,NATURAL"
|
"144";"144";"144";"BLOCK_SNOW";"0.1252";"0.1252";"0.1252";"0.1252";"24";"500";"SNOW";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"SNOW,NATURAL,COLD"
|
||||||
"145";"N/A";"N/A";"BLOCK_ICE_FRAGILE";"0.0508";"0.0508";"0.0508";"0.0508";"5";"930";"ICEI";"1";"0";"N/A";"0";"0";"4";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ICE,NATURAL,FRAGIEL"
|
"145";"N/A";"N/A";"BLOCK_ICE_FRAGILE";"0.0508";"0.0508";"0.0508";"0.0508";"5";"930";"ICEI";"1";"0";"N/A";"0";"0";"4";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ICE,NATURAL,FRAGILE,COLD"
|
||||||
"146";"146";"146";"BLOCK_ICE_NATURAL";"0.1016";"0.1016";"0.1016";"0.1016";"35";"930";"ICEI";"1";"1";"N/A";"0";"0";"4";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ICE,NATURAL"
|
"146";"146";"146";"BLOCK_ICE_NATURAL";"0.1016";"0.1016";"0.1016";"0.1016";"35";"930";"ICEI";"1";"1";"N/A";"0";"0";"4";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ICE,NATURAL,COLD"
|
||||||
"147";"147";"147";"BLOCK_ICE_CLEAR_MAGICAL";"0.1252";"0.1252";"0.1252";"0.1252";"48";"3720";"ICEX";"1";"1";"N/A";"0";"0";"4";"0.0744";"0.1252";"0.2268";"0.0000";"N/A";"N/A";"0.0";"ICE"
|
"147";"147";"147";"BLOCK_ICE_CLEAR_MAGICAL";"0.1252";"0.1252";"0.1252";"0.1252";"48";"3720";"ICEX";"1";"1";"N/A";"0";"0";"4";"0.0744";"0.1252";"0.2268";"0.0000";"N/A";"N/A";"0.0";"ICE,COLD"
|
||||||
"148";"148";"148";"BLOCK_GLASS_CRUDE";"0.0876";"0.0424";"0.0876";"0.1252";"5";"2500";"GLAS";"1";"1";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GLASS"
|
"148";"148";"148";"BLOCK_GLASS_CRUDE";"0.0876";"0.0424";"0.0876";"0.1252";"5";"2500";"GLAS";"1";"1";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GLASS"
|
||||||
"149";"149";"149";"BLOCK_GLASS_CLEAN";"0.0424";"0.0424";"0.0424";"0.0636";"5";"2203";"GLAS";"1";"1";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GLASS"
|
"149";"149";"149";"BLOCK_GLASS_CLEAN";"0.0424";"0.0424";"0.0424";"0.0636";"5";"2203";"GLAS";"1";"1";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GLASS"
|
||||||
"160";"160";"160";"BLOCK_PLATFORM_STONE";"0.0312";"0.0312";"0.0312";"0.0312";"5";"2400";"ROCK";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"PLATFORM"
|
"160";"160";"160";"BLOCK_PLATFORM_STONE";"0.0312";"0.0312";"0.0312";"0.0312";"5";"2400";"ROCK";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"PLATFORM"
|
||||||
@@ -188,6 +188,7 @@
|
|||||||
## Some tags are reserved for internal use, which are:
|
## Some tags are reserved for internal use, which are:
|
||||||
## - INTERNAL: denotes that the tile is internal-use. Will not be rendered unless debug window is on.
|
## - INTERNAL: denotes that the tile is internal-use. Will not be rendered unless debug window is on.
|
||||||
## - DORENDER: this internal tile must go through the standard-issue tile drawing routine.
|
## - DORENDER: this internal tile must go through the standard-issue tile drawing routine.
|
||||||
|
## - INCONSEQUENTIAL: denotes that this tile can be overwritten without dropping it. Usually used with flower tiles.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
## References ##
|
## References ##
|
||||||
|
|||||||
|
Can't render this file because it contains an unexpected character in line 179 and column 37.
|
@@ -22,6 +22,8 @@ Seed
|
|||||||
SetAV
|
SetAV
|
||||||
SetBulletin
|
SetBulletin
|
||||||
SetScale
|
SetScale
|
||||||
|
SetSol
|
||||||
|
SetTurb
|
||||||
SetTime
|
SetTime
|
||||||
SetTimeDelta
|
SetTimeDelta
|
||||||
SpawnPhysTestBall
|
SpawnPhysTestBall
|
||||||
|
|||||||
|
BIN
assets/mods/basegame/gui/backdrop01.tga
LFS
Normal file
BIN
assets/mods/basegame/gui/backdrop01.tga
LFS
Normal file
Binary file not shown.
@@ -8,6 +8,7 @@ id;classname
|
|||||||
8;net.torvald.terrarum.modulebasegame.gameitems.ItemLogicSignalEmitter
|
8;net.torvald.terrarum.modulebasegame.gameitems.ItemLogicSignalEmitter
|
||||||
9;net.torvald.terrarum.modulebasegame.gameitems.WireCutterAll
|
9;net.torvald.terrarum.modulebasegame.gameitems.WireCutterAll
|
||||||
10;net.torvald.terrarum.modulebasegame.gameitems.ItemTypewriter
|
10;net.torvald.terrarum.modulebasegame.gameitems.ItemTypewriter
|
||||||
|
11;net.torvald.terrarum.modulebasegame.gameitems.ItemWallCalendar
|
||||||
|
|
||||||
256;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorOak
|
256;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorOak
|
||||||
257;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorEbony
|
257;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorEbony
|
||||||
|
|||||||
|
34
assets/mods/basegame/locales/en/calendar.json
Normal file
34
assets/mods/basegame/locales/en/calendar.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"MENU_CALENDAR_CALENDAR": "Calendar",
|
||||||
|
"MENU_CALENDAR_EVENTS": "Events",
|
||||||
|
"MENU_CALENDAR_ADD_NEW_EVENT": "Add New Event",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_SPRING": "Spring",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_SUMMER": "Summer",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_AUTUMN": "Autumn",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_WINTER": "Winter",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_SPRI": "Spri",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_SUMM": "Summ",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_AUTM": "Autm",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_WINT": "Wint",
|
||||||
|
"CONTEXT_CALENDAR_DATE_FORMAT_Y": "Year {0}",
|
||||||
|
"CONTEXT_CALENDAR_DATE_FORMAT_YMD": "Year {0} {1} {2}",
|
||||||
|
"CONTEXT_CALENDAR_DATE_FORMAT_YMD_DDD": "Year {0} {1} {2} {3}",
|
||||||
|
|
||||||
|
"CONTEXT_CALENDAR_DAY_MONDAG_DNT": "Mondag",
|
||||||
|
"CONTEXT_CALENDAR_DAY_TYSDAG_DNT": "Tysdag",
|
||||||
|
"CONTEXT_CALENDAR_DAY_MIDTVEKE_DNT": "Midtveke",
|
||||||
|
"CONTEXT_CALENDAR_DAY_TORSDAG_DNT": "Torsdag",
|
||||||
|
"CONTEXT_CALENDAR_DAY_FREDAG_DNT": "Fredag",
|
||||||
|
"CONTEXT_CALENDAR_DAY_LAURDAG_DNT": "Laurdag",
|
||||||
|
"CONTEXT_CALENDAR_DAY_SUNDAG_DNT": "Sundag",
|
||||||
|
"CONTEXT_CALENDAR_DAY_VERDDAG_DNT": "Verddag",
|
||||||
|
"CONTEXT_CALENDAR_DAY_MON_DNT": "Mon",
|
||||||
|
"CONTEXT_CALENDAR_DAY_TYS_DNT": "Tys",
|
||||||
|
"CONTEXT_CALENDAR_DAY_MID_DNT": "Mid",
|
||||||
|
"CONTEXT_CALENDAR_DAY_TOR_DNT": "Tor",
|
||||||
|
"CONTEXT_CALENDAR_DAY_FRE_DNT": "Fre",
|
||||||
|
"CONTEXT_CALENDAR_DAY_LAU_DNT": "Lau",
|
||||||
|
"CONTEXT_CALENDAR_DAY_SUN_DNT": "Sun",
|
||||||
|
"CONTEXT_CALENDAR_DAY_VER_DNT": "Ver",
|
||||||
|
"CONTEXT_CALENDAR_DATE_FORMAT_YMD_SHORT_DNT": "ɣ{0}-{1}-{2}"
|
||||||
|
}
|
||||||
@@ -1,23 +1,24 @@
|
|||||||
{
|
{
|
||||||
|
"CONTEXT_GENERATOR_SEED": "Seed",
|
||||||
|
"CONTEXT_ITEM_MAP": "Map",
|
||||||
|
"CONTEXT_ITEM_TOOL_PLURAL": "Tools",
|
||||||
|
"CONTEXT_PLACE_COORDINATE": "Coordinate",
|
||||||
|
"CONTEXT_WORLD_COUNT": "Worlds: ",
|
||||||
"CONTEXT_WORLD_NEW": "New World",
|
"CONTEXT_WORLD_NEW": "New World",
|
||||||
"MENU_LABEL_DELETE_WORLD": "Delete World",
|
"MENU_LABEL_DELETE_WORLD": "Delete World",
|
||||||
"CONTEXT_WORLD_COUNT": "Worlds: ",
|
|
||||||
"GAME_INVENTORY_INGREDIENTS": "Ingredients",
|
|
||||||
"GAME_INVENTORY_POTIONS": "Potions",
|
|
||||||
"GAME_INVENTORY_BLOCKS": "Blocks",
|
|
||||||
"GAME_INVENTORY_WALLS": "Walls",
|
|
||||||
"CONTEXT_ITEM_TOOL_PLURAL": "Tools",
|
|
||||||
"GAME_INVENTORY_FAVORITES": "Favorites",
|
|
||||||
"GAME_INVENTORY_REGISTER": "Register",
|
|
||||||
"CONTEXT_ITEM_MAP": "Map",
|
|
||||||
"MENU_LABEL_MENU": "Menu",
|
"MENU_LABEL_MENU": "Menu",
|
||||||
"CONTEXT_GENERATOR_SEED": "Seed",
|
"MENU_LABEL_PREV_SAVES": "Previous Saves",
|
||||||
|
"MENU_LABEL_RENAME": "Rename",
|
||||||
|
"GAME_ACTION_CRAFT": "Craft",
|
||||||
"GAME_ACTION_GRAPPLE": "Grapple",
|
"GAME_ACTION_GRAPPLE": "Grapple",
|
||||||
"GAME_ACTION_QUICKSEL": "Quick Select",
|
"GAME_ACTION_QUICKSEL": "Quick Select",
|
||||||
"GAME_ACTION_CRAFT": "Craft",
|
"GAME_ACTION_TELEPORT": "Teleport",
|
||||||
"GAME_CRAFTING": "Crafting",
|
|
||||||
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
|
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
|
||||||
"CONTEXT_WORLD_SEARCH": "World Search",
|
"GAME_CRAFTING": "Crafting",
|
||||||
"CONTEXT_WORLD_LIST": "Worlds List",
|
"GAME_INVENTORY_BLOCKS": "Blocks",
|
||||||
"MENU_LABEL_RENAME": "Rename"
|
"GAME_INVENTORY_FAVORITES": "Favorites",
|
||||||
|
"GAME_INVENTORY_INGREDIENTS": "Ingredients",
|
||||||
|
"GAME_INVENTORY_POTIONS": "Potions",
|
||||||
|
"GAME_INVENTORY_REGISTER": "Register",
|
||||||
|
"GAME_INVENTORY_WALLS": "Walls"
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
{
|
{
|
||||||
|
"BLOCK_STONE_DEEP": "Deepstone",
|
||||||
|
"BLOCK_SCAFFOLDING_NORMAL": "Scaffolding",
|
||||||
|
"BLOCK_STONE_MARBLE": "Marble",
|
||||||
|
|
||||||
|
"ITEM_CALENDAR": "Calendar",
|
||||||
|
"ITEM_LOGIC_SIGNAL_EMITTER": "Logic Signal Emitter",
|
||||||
|
"ITEM_STORAGE_CHEST": "Storage Chest",
|
||||||
|
"ITEM_TIKI_TORCH": "Tiki Torch",
|
||||||
|
"ITEM_TYPEWRITER": "Typewriter",
|
||||||
|
"ITEM_WIRE": "Wire",
|
||||||
|
"ITEM_WIRE_CUTTER": "Wire Cutter",
|
||||||
|
|
||||||
"ACTORBLOCK_ALLOW_MOVE_DOWN": "Urist Arôlcustith",
|
"ACTORBLOCK_ALLOW_MOVE_DOWN": "Urist Arôlcustith",
|
||||||
"ACTORBLOCK_FULL_COLLISION": "Urist Berdanrifot",
|
"ACTORBLOCK_FULL_COLLISION": "Urist Berdanrifot",
|
||||||
"ACTORBLOCK_NO_COLLISION": "Urist Zafal",
|
"ACTORBLOCK_NO_COLLISION": "Urist Zafal",
|
||||||
"ACTORBLOCK_NO_PASS_RIGHT": "Urist McPassLeft",
|
"ACTORBLOCK_NO_PASS_RIGHT": "Urist McPassLeft",
|
||||||
"ACTORBLOCK_NO_PASS_LEFT": "Urist McPassRight",
|
"ACTORBLOCK_NO_PASS_LEFT": "Urist McPassRight",
|
||||||
"ACTORBLOCK_TILING_PLACEHOLDER": "Urist Berdanurdim",
|
"ACTORBLOCK_TILING_PLACEHOLDER": "Urist Berdanurdim"
|
||||||
|
|
||||||
"BLOCK_STONE_DEEP": "Deepstone",
|
|
||||||
"BLOCK_SCAFFOLDING_NORMAL": "Scaffolding",
|
|
||||||
"BLOCK_STONE_MARBLE": "Marble",
|
|
||||||
|
|
||||||
"ITEM_STORAGE_CHEST": "Storage Chest",
|
|
||||||
"ITEM_WIRE": "Wire",
|
|
||||||
"ITEM_WIRE_CUTTER": "Wire Cutter",
|
|
||||||
"ITEM_LOGIC_SIGNAL_EMITTER": "Logic Signal Emitter",
|
|
||||||
"ITEM_TIKI_TORCH": "Tiki Torch"
|
|
||||||
}
|
}
|
||||||
3
assets/mods/basegame/locales/en/sentences.json
Normal file
3
assets/mods/basegame/locales/en/sentences.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"CONTEXT_THIS_IS_A_WORLD_CURRENTLY_PLAYING": "This is a world currently playing."
|
||||||
|
}
|
||||||
16
assets/mods/basegame/locales/koKR/calendar.json
Normal file
16
assets/mods/basegame/locales/koKR/calendar.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"MENU_CALENDAR_CALENDAR": "달력",
|
||||||
|
"MENU_CALENDAR_EVENTS": "일정",
|
||||||
|
"MENU_CALENDAR_ADD_NEW_EVENT": "새 일정 추가",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_SPRING": "봄",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_SUMMER": "여름",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_AUTUMN": "가을",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_WINTER": "겨울",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_SPRI": "봄",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_SUMM": "여름",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_AUTM": "가을",
|
||||||
|
"CONTEXT_CALENDAR_SEASON_WINT": "겨울",
|
||||||
|
"CONTEXT_CALENDAR_DATE_FORMAT_Y": "{0}년",
|
||||||
|
"CONTEXT_CALENDAR_DATE_FORMAT_YMD": "{0}년 {1} {2}일",
|
||||||
|
"CONTEXT_CALENDAR_DATE_FORMAT_YMD_DDD": "{0}년 {1} {2}일 {3}"
|
||||||
|
}
|
||||||
@@ -1,21 +1,25 @@
|
|||||||
{
|
{
|
||||||
|
"CONTEXT_GENERATOR_SEED": "시드",
|
||||||
|
"CONTEXT_ITEM_MAP": "지도",
|
||||||
|
"CONTEXT_ITEM_TOOL_PLURAL": "도구",
|
||||||
|
"CONTEXT_PLACE_COORDINATE": "좌표",
|
||||||
|
"CONTEXT_WORLD_COUNT": "새계: ",
|
||||||
"CONTEXT_WORLD_NEW": "새 세계",
|
"CONTEXT_WORLD_NEW": "새 세계",
|
||||||
"MENU_LABEL_DELETE_WORLD": "새계 삭제",
|
"MENU_LABEL_DELETE_WORLD": "새계 삭제",
|
||||||
"CONTEXT_WORLD_COUNT": "새계: ",
|
|
||||||
"MENU_MONITOR_CALI_TITLE": "모니터 확인",
|
|
||||||
"GAME_INVENTORY_INGREDIENTS": "재료",
|
|
||||||
"GAME_INVENTORY_POTIONS": "물약",
|
|
||||||
"GAME_INVENTORY_BLOCKS": "블록",
|
|
||||||
"GAME_INVENTORY_WALLS": "벽지",
|
|
||||||
"CONTEXT_ITEM_TOOL_PLURAL": "도구",
|
|
||||||
"GAME_INVENTORY_FAVORITES": "즐겨찾기",
|
|
||||||
"GAME_INVENTORY_REGISTER": "등록하기",
|
|
||||||
"MENU_LABEL_MENU": "메뉴",
|
"MENU_LABEL_MENU": "메뉴",
|
||||||
"CONTEXT_ITEM_MAP": "지도",
|
"MENU_LABEL_PREV_SAVES": "이전 세이브",
|
||||||
"CONTEXT_GENERATOR_SEED": "시드",
|
"MENU_LABEL_RENAME": "이름 바꾸기",
|
||||||
|
"MENU_MONITOR_CALI_TITLE": "모니터 확인",
|
||||||
|
"GAME_ACTION_CRAFT": "제작하기",
|
||||||
"GAME_ACTION_GRAPPLE": "매달리기",
|
"GAME_ACTION_GRAPPLE": "매달리기",
|
||||||
"GAME_ACTION_QUICKSEL": "빠른 선택",
|
"GAME_ACTION_QUICKSEL": "빠른 선택",
|
||||||
"GAME_ACTION_CRAFT": "제작하기",
|
"GAME_ACTION_TELEPORT": "텔레포트하기",
|
||||||
|
"GAME_CRAFTABLE_ITEMS": "제작 가능한 아이템",
|
||||||
"GAME_CRAFTING": "제작",
|
"GAME_CRAFTING": "제작",
|
||||||
"GAME_CRAFTABLE_ITEMS": "제작 가능한 아이템"
|
"GAME_INVENTORY_BLOCKS": "블록",
|
||||||
|
"GAME_INVENTORY_FAVORITES": "즐겨찾기",
|
||||||
|
"GAME_INVENTORY_INGREDIENTS": "재료",
|
||||||
|
"GAME_INVENTORY_POTIONS": "물약",
|
||||||
|
"GAME_INVENTORY_REGISTER": "등록하기",
|
||||||
|
"GAME_INVENTORY_WALLS": "벽지"
|
||||||
}
|
}
|
||||||
@@ -3,9 +3,11 @@
|
|||||||
"BLOCK_SCAFFOLDING_NORMAL": "발판",
|
"BLOCK_SCAFFOLDING_NORMAL": "발판",
|
||||||
"BLOCK_STONE_MARBLE": "대리석",
|
"BLOCK_STONE_MARBLE": "대리석",
|
||||||
|
|
||||||
"ITEM_STORAGE_CHEST": "보관상자",
|
"ITEM_CALENDAR": "달력",
|
||||||
"ITEM_WIRE": "전선",
|
|
||||||
"ITEM_WIRE_CUTTER": "전선 절단기",
|
|
||||||
"ITEM_LOGIC_SIGNAL_EMITTER": "신호발생기",
|
"ITEM_LOGIC_SIGNAL_EMITTER": "신호발생기",
|
||||||
"ITEM_TIKI_TORCH": "티키 토치"
|
"ITEM_STORAGE_CHEST": "보관상자",
|
||||||
|
"ITEM_TIKI_TORCH": "티키 토치",
|
||||||
|
"ITEM_TYPEWRITER": "타자기",
|
||||||
|
"ITEM_WIRE": "전선",
|
||||||
|
"ITEM_WIRE_CUTTER": "전선 절단기"
|
||||||
}
|
}
|
||||||
3
assets/mods/basegame/locales/koKR/sentences.json
Normal file
3
assets/mods/basegame/locales/koKR/sentences.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"CONTEXT_THIS_IS_A_WORLD_CURRENTLY_PLAYING": "현재 플레이 중인 월드입니다."
|
||||||
|
}
|
||||||
BIN
assets/mods/basegame/sprites/fixtures/calendar.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/calendar.tga
LFS
Normal file
Binary file not shown.
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"skyboxGradColourMap": "generic_skybox.tga",
|
"skyboxGradColourMap": "generic_skybox.tga",
|
||||||
|
"daylightClut": "clut_daylight.tga",
|
||||||
"classification": "generic",
|
"classification": "generic",
|
||||||
"extraImages": [
|
"extraImages": [
|
||||||
|
|
||||||
|
|||||||
BIN
assets/mods/basegame/weathers/clut_daylight.tga
LFS
Normal file
BIN
assets/mods/basegame/weathers/clut_daylight.tga
LFS
Normal file
Binary file not shown.
@@ -23,12 +23,14 @@ cp $SRCFILES/AppRun $DESTDIR/AppRun
|
|||||||
chmod +x $DESTDIR/AppRun
|
chmod +x $DESTDIR/AppRun
|
||||||
|
|
||||||
# Copy over a Java runtime
|
# Copy over a Java runtime
|
||||||
cp -r "../out/$RUNTIME" $DESTDIR/
|
mkdir $DESTDIR/out
|
||||||
|
cp -r "../out/$RUNTIME" $DESTDIR/out/
|
||||||
|
mv $DESTDIR/out/$RUNTIME/bin/java $DESTDIR/out/$RUNTIME/bin/Terrarum
|
||||||
|
|
||||||
# Copy over all the assets and a jarfile
|
# Copy over all the assets and a jarfile
|
||||||
cp -r "../assets_release" $DESTDIR/
|
cp -r "../assets_release" $DESTDIR/
|
||||||
mv $DESTDIR/assets_release $DESTDIR/assets
|
mv $DESTDIR/assets_release $DESTDIR/assets
|
||||||
cp -r "../out/TerrarumBuild.jar" $DESTDIR/assets/
|
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
|
||||||
|
|
||||||
# Pack everything to AppImage
|
# Pack everything to AppImage
|
||||||
ARCH=arm_aarch64 "./$APPIMAGETOOL" $DESTDIR "out/$DESTDIR.AppImage" || { echo 'Building AppImage failed' >&2; exit 1; }
|
ARCH=arm_aarch64 "./$APPIMAGETOOL" $DESTDIR "out/$DESTDIR.AppImage" || { echo 'Building AppImage failed' >&2; exit 1; }
|
||||||
|
|||||||
@@ -23,12 +23,14 @@ cp $SRCFILES/AppRun $DESTDIR/AppRun
|
|||||||
chmod +x $DESTDIR/AppRun
|
chmod +x $DESTDIR/AppRun
|
||||||
|
|
||||||
# Copy over a Java runtime
|
# Copy over a Java runtime
|
||||||
cp -r "../out/$RUNTIME" $DESTDIR/
|
mkdir $DESTDIR/out
|
||||||
|
cp -r "../out/$RUNTIME" $DESTDIR/out/
|
||||||
|
mv $DESTDIR/out/$RUNTIME/bin/java $DESTDIR/out/$RUNTIME/bin/Terrarum
|
||||||
|
|
||||||
# Copy over all the assets and a jarfile
|
# Copy over all the assets and a jarfile
|
||||||
cp -r "../assets_release" $DESTDIR/
|
cp -r "../assets_release" $DESTDIR/
|
||||||
mv $DESTDIR/assets_release $DESTDIR/assets
|
mv $DESTDIR/assets_release $DESTDIR/assets
|
||||||
cp -r "../out/TerrarumBuild.jar" $DESTDIR/assets/
|
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
|
||||||
|
|
||||||
# Pack everything to AppImage
|
# Pack everything to AppImage
|
||||||
"./$APPIMAGETOOL" $DESTDIR "out/$DESTDIR.AppImage" || { echo 'Building AppImage failed' >&2; exit 1; }
|
"./$APPIMAGETOOL" $DESTDIR "out/$DESTDIR.AppImage" || { echo 'Building AppImage failed' >&2; exit 1; }
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ if (( $EUID == 0 )); then echo "The build process is not meant to be run with ro
|
|||||||
|
|
||||||
cd "${0%/*}"
|
cd "${0%/*}"
|
||||||
SRCFILES="terrarummac_arm"
|
SRCFILES="terrarummac_arm"
|
||||||
DESTDIR="out/TerrarumMac.arm.app"
|
APPDIR="./TerrarumMac.arm.app"
|
||||||
|
DESTDIR="out/$APPDIR"
|
||||||
RUNTIME="runtime-osx-arm"
|
RUNTIME="runtime-osx-arm"
|
||||||
|
|
||||||
if [ ! -d "../assets_release" ]; then
|
if [ ! -d "../assets_release" ]; then
|
||||||
@@ -25,11 +26,17 @@ cp $SRCFILES/Terrarum.sh $DESTDIR/Contents/MacOS/
|
|||||||
chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
|
chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
|
||||||
|
|
||||||
# Copy over a Java runtime
|
# Copy over a Java runtime
|
||||||
cp -r "../out/$RUNTIME" $DESTDIR/Contents/MacOS/
|
mkdir $DESTDIR/Contents/MacOS/out
|
||||||
|
cp -r "../out/$RUNTIME" $DESTDIR/Contents/MacOS/out/
|
||||||
|
mv $DESTDIR/Contents/MacOS/out/$RUNTIME/bin/java $DESTDIR/Contents/MacOS/out/$RUNTIME/bin/Terrarum
|
||||||
|
|
||||||
# Copy over all the assets and a jarfile
|
# Copy over all the assets and a jarfile
|
||||||
cp -r "../assets_release" $DESTDIR/Contents/MacOS/
|
cp -r "../assets_release" $DESTDIR/Contents/MacOS/
|
||||||
mv $DESTDIR/Contents/MacOS/assets_release $DESTDIR/Contents/MacOS/assets
|
mv $DESTDIR/Contents/MacOS/assets_release $DESTDIR/Contents/MacOS/assets
|
||||||
cp -r "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/assets/
|
cp "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/out/
|
||||||
|
|
||||||
|
cd "out"
|
||||||
|
rm $APPDIR.zip
|
||||||
|
7z a -tzip $APPDIR.zip $APPDIR
|
||||||
|
|
||||||
echo "Build successful: $DESTDIR"
|
echo "Build successful: $DESTDIR"
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ if (( $EUID == 0 )); then echo "The build process is not meant to be run with ro
|
|||||||
|
|
||||||
cd "${0%/*}"
|
cd "${0%/*}"
|
||||||
SRCFILES="terrarummac_x86"
|
SRCFILES="terrarummac_x86"
|
||||||
DESTDIR="out/TerrarumMac.x86.app"
|
APPDIR="./TerrarumMac.x86.app"
|
||||||
|
DESTDIR="out/$APPDIR"
|
||||||
RUNTIME="runtime-osx-x86"
|
RUNTIME="runtime-osx-x86"
|
||||||
|
|
||||||
if [ ! -d "../assets_release" ]; then
|
if [ ! -d "../assets_release" ]; then
|
||||||
@@ -25,11 +26,17 @@ cp $SRCFILES/Terrarum.sh $DESTDIR/Contents/MacOS/
|
|||||||
chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
|
chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
|
||||||
|
|
||||||
# Copy over a Java runtime
|
# Copy over a Java runtime
|
||||||
cp -r "../out/$RUNTIME" $DESTDIR/Contents/MacOS/
|
mkdir $DESTDIR/Contents/MacOS/out
|
||||||
|
cp -r "../out/$RUNTIME" $DESTDIR/Contents/MacOS/out/
|
||||||
|
mv $DESTDIR/Contents/MacOS/out/$RUNTIME/bin/java $DESTDIR/Contents/MacOS/out/$RUNTIME/bin/Terrarum
|
||||||
|
|
||||||
# Copy over all the assets and a jarfile
|
# Copy over all the assets and a jarfile
|
||||||
cp -r "../assets_release" $DESTDIR/Contents/MacOS/
|
cp -r "../assets_release" $DESTDIR/Contents/MacOS/
|
||||||
mv $DESTDIR/Contents/MacOS/assets_release $DESTDIR/Contents/MacOS/assets
|
mv $DESTDIR/Contents/MacOS/assets_release $DESTDIR/Contents/MacOS/assets
|
||||||
cp -r "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/assets/
|
cp "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/out/
|
||||||
|
|
||||||
|
cd "out"
|
||||||
|
rm $APPDIR.zip
|
||||||
|
7z a -tzip $APPDIR.zip $APPDIR
|
||||||
|
|
||||||
echo "Build successful: $DESTDIR"
|
echo "Build successful: $DESTDIR"
|
||||||
|
|||||||
@@ -16,15 +16,23 @@ rm -rf $DESTDIR || true
|
|||||||
mkdir $DESTDIR
|
mkdir $DESTDIR
|
||||||
|
|
||||||
# Prepare an application
|
# Prepare an application
|
||||||
cp $SRCFILES/Terrarum.bat $DESTDIR/
|
if ! command -v x86_64-w64-mingw32-gcc &> /dev/null
|
||||||
|
then
|
||||||
|
echo 'Mingw32 not found; please install mingw64-cross-gcc (or similar) to your system' >&2; exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
x86_64-w64-mingw32-gcc -Os -s -o $DESTDIR/Terrarum.exe $SRCFILES/Terrarum.c || { echo 'Building EXE failed' >&2; exit 1; }
|
||||||
|
# TODO add icon to the exe (use x86_64-w64-mingw32-windres?)
|
||||||
|
|
||||||
# Copy over a Java runtime
|
# Copy over a Java runtime
|
||||||
cp -r "../out/$RUNTIME" $DESTDIR/
|
mkdir $DESTDIR/out
|
||||||
|
cp -r "../out/$RUNTIME" $DESTDIR/out/
|
||||||
|
mv $DESTDIR/out/$RUNTIME/bin/java.exe $DESTDIR/out/$RUNTIME/bin/Terrarum.exe
|
||||||
|
|
||||||
# Copy over all the assets and a jarfile
|
# Copy over all the assets and a jarfile
|
||||||
cp -r "../assets_release" $DESTDIR/
|
cp -r "../assets_release" $DESTDIR/
|
||||||
mv $DESTDIR/assets_release $DESTDIR/assets
|
mv $DESTDIR/assets_release $DESTDIR/assets
|
||||||
cp -r "../out/TerrarumBuild.jar" $DESTDIR/assets/
|
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
|
||||||
|
|
||||||
# Temporary solution: zip everything
|
# Temporary solution: zip everything
|
||||||
zip -r -9 -l "out/TerrarumWindows.x86.zip" $DESTDIR
|
zip -r -9 -l "out/TerrarumWindows.x86.zip" $DESTDIR
|
||||||
|
|||||||
25
buildapp/make_assets_release.sh
Executable file
25
buildapp/make_assets_release.sh
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
if (( $EUID == 0 )); then echo "The build process is not meant to be run with root privilege, exiting now." >&2; exit 1; fi
|
||||||
|
|
||||||
|
cd "${0%/*}"
|
||||||
|
DESTDIR="../assets_release"
|
||||||
|
|
||||||
|
rm -r $DESTDIR
|
||||||
|
cp -r "../assets" $DESTDIR
|
||||||
|
|
||||||
|
rm $DESTDIR/loopey.wav
|
||||||
|
rm $DESTDIR/ktGrepExample.kts
|
||||||
|
rm $DESTDIR/batchtest.txt
|
||||||
|
rm $DESTDIR/test_texture.tga
|
||||||
|
rm $DESTDIR/worldbacktest.tga
|
||||||
|
rm -r $DESTDIR/books
|
||||||
|
rm $DESTDIR/clut/skybox.tga
|
||||||
|
rm $DESTDIR/graphics/*.bat
|
||||||
|
rm $DESTDIR/keylayout/*.not_ime
|
||||||
|
rm $DESTDIR/mods/basegame/blocks/*.gz
|
||||||
|
rm $DESTDIR/mods/basegame/blocks/*.txt
|
||||||
|
rm -r $DESTDIR/mods/basegame/sounds
|
||||||
|
rm -r $DESTDIR/mods/dwarventech
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cd "${0%/*}"
|
cd "${0%/*}"
|
||||||
./runtime-linux-arm/bin/java -Xms1G -Xmx6G -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./assets/TerrarumBuild.jar
|
./out/runtime-linux-arm/bin/Terrarum -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./out/TerrarumBuild.jar
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cd "${0%/*}"
|
cd "${0%/*}"
|
||||||
./runtime-linux-x86/bin/java -Xms1G -Xmx6G -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./assets/TerrarumBuild.jar
|
./out/runtime-linux-x86/bin/Terrarum -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./out/TerrarumBuild.jar
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cd "${0%/*}"
|
cd "${0%/*}"
|
||||||
./runtime-osx-arm/bin/java -XstartOnFirstThread -Xms1G -Xmx6G -jar ./assets/TerrarumBuild.jar
|
./out/runtime-osx-arm/bin/Terrarum -jar ./out/TerrarumBuild.jar
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cd "${0%/*}"
|
cd "${0%/*}"
|
||||||
./runtime-osx-x86/bin/java -XstartOnFirstThread -Xms1G -Xmx6G -jar ./assets/TerrarumBuild.jar
|
./out/runtime-osx-x86/bin/Terrarum -jar ./out/TerrarumBuild.jar
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
cd /D "%~dp0"
|
|
||||||
.\runtime-windows-x86\bin\java -Xms1G -Xmx6G -jar .\assets\TerrarumBuild.jar
|
|
||||||
6
buildapp/terrarumwindows_x86/Terrarum.c
Normal file
6
buildapp/terrarumwindows_x86/Terrarum.c
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return system(".\\out\\runtime-windows-x86\\bin\\Terrarum.exe -jar .\\out\\TerrarumBuild.jar");
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
Manifest-Version: 1.0
|
Manifest-Version: 1.0
|
||||||
Main-Class: net.torvald.terrarum.App
|
Main-Class: net.torvald.terrarum.Principii
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.badlogic.gdx.graphics.glutils;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Application;
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
|
import com.badlogic.gdx.graphics.GL30;
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
|
import net.torvald.terrarum.App;
|
||||||
|
|
||||||
|
// typealias Float16FrameBuffer = FloatFrameBuffer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2023-08-16.
|
||||||
|
*/
|
||||||
|
public class Float16FrameBuffer extends FrameBuffer {
|
||||||
|
|
||||||
|
Float16FrameBuffer () {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a GLFrameBuffer from the specifications provided by bufferBuilder
|
||||||
|
*
|
||||||
|
* @param bufferBuilder **/
|
||||||
|
protected Float16FrameBuffer (GLFrameBufferBuilder<? extends GLFrameBuffer<Texture>> bufferBuilder) {
|
||||||
|
super(bufferBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a new FrameBuffer with a float backing texture, having the given dimensions and potentially a depth buffer
|
||||||
|
* attached.
|
||||||
|
*
|
||||||
|
* @param width the width of the framebuffer in pixels
|
||||||
|
* @param height the height of the framebuffer in pixels
|
||||||
|
* @param hasDepth whether to attach a depth buffer
|
||||||
|
* @throws GdxRuntimeException in case the FrameBuffer could not be created */
|
||||||
|
public Float16FrameBuffer (int width, int height, boolean hasDepth) {
|
||||||
|
if (App.isAppleM) { // disable float framebuffer for Apple M chips
|
||||||
|
FrameBufferBuilder bufferBuilder = new FrameBufferBuilder(width, height);
|
||||||
|
bufferBuilder.addColorTextureAttachment(GL20.GL_RGBA, GL20.GL_RGBA, GL20.GL_UNSIGNED_SHORT); // but 16bpp int works perfectly?!
|
||||||
|
if (hasDepth) bufferBuilder.addBasicDepthRenderBuffer();
|
||||||
|
this.bufferBuilder = bufferBuilder;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FloatFrameBufferBuilder bufferBuilder = new FloatFrameBufferBuilder(width, height);
|
||||||
|
bufferBuilder.addFloatAttachment(GL30.GL_RGBA16F, GL30.GL_RGBA, GL30.GL_FLOAT, false); // FIXME sporadic black screen on GL_RGBA16F? or maybe it was Plasma bugging out?
|
||||||
|
if (hasDepth) bufferBuilder.addBasicDepthRenderBuffer();
|
||||||
|
this.bufferBuilder = bufferBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture createTexture (FrameBufferTextureAttachmentSpec attachmentSpec) {
|
||||||
|
if (App.isAppleM) {
|
||||||
|
GLOnlyTextureData data = new GLOnlyTextureData(bufferBuilder.width, bufferBuilder.height, 0, attachmentSpec.internalFormat,
|
||||||
|
attachmentSpec.format, attachmentSpec.type);
|
||||||
|
Texture result = new Texture(data);
|
||||||
|
result.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
|
||||||
|
result.setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FloatTextureData data = new FloatTextureData(bufferBuilder.width, bufferBuilder.height, attachmentSpec.internalFormat,
|
||||||
|
attachmentSpec.format, attachmentSpec.type, attachmentSpec.isGpuOnly);
|
||||||
|
Texture result = new Texture(data);
|
||||||
|
result.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
|
||||||
|
result.setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -166,6 +166,19 @@ final public class FastMath {
|
|||||||
return ((1f - scale) * startValue) + (scale * endValue);
|
return ((1f - scale) * startValue) + (scale * endValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double interpolateLinear(double scale, double startValue, double endValue) {
|
||||||
|
if (startValue == endValue) {
|
||||||
|
return startValue;
|
||||||
|
}
|
||||||
|
if (scale <= 0.0) {
|
||||||
|
return startValue;
|
||||||
|
}
|
||||||
|
if (scale >= 1.0) {
|
||||||
|
return endValue;
|
||||||
|
}
|
||||||
|
return ((1.0 - scale) * startValue) + (scale * endValue);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linear interpolation from startValue to endValue by the given percent.
|
* Linear interpolation from startValue to endValue by the given percent.
|
||||||
* Basically: ((1 - percent) * startValue) + (percent * endValue)
|
* Basically: ((1 - percent) * startValue) + (percent * endValue)
|
||||||
@@ -231,6 +244,10 @@ final public class FastMath {
|
|||||||
return (float) (((c4 * u + c3) * u + c2) * u + c1);
|
return (float) (((c4 * u + c3) * u + c2) * u + c1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float interpolateCatmullRom(float u, float p0, float p1, float p2, float p3) {
|
||||||
|
return interpolateCatmullRom(u, 0.5f, p0, p1, p2, p3);
|
||||||
|
}
|
||||||
|
|
||||||
/**Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
|
/**Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
|
||||||
* here is the interpolation matrix
|
* here is the interpolation matrix
|
||||||
* m = [ 0.0 1.0 0.0 0.0 ]
|
* m = [ 0.0 1.0 0.0 0.0 ]
|
||||||
@@ -316,24 +333,25 @@ final public class FastMath {
|
|||||||
|
|
||||||
|
|
||||||
public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3) {
|
public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3) {
|
||||||
return interpolateHermite(scale, p0, p1, p2, p3, 1f, 0f);
|
// return interpolateHermite(scale, p0, p1, p2, p3, 0f, 0f);
|
||||||
}
|
|
||||||
public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3, float tension, float bias) {
|
|
||||||
float mu2 = scale * scale;
|
float mu2 = scale * scale;
|
||||||
float mu3 = mu2 * scale;
|
float mu3 = mu2 * scale;
|
||||||
|
float biasTensionTerms = 0.5f;//(1f + bias) * (1f - tension) / 2f;
|
||||||
|
|
||||||
float m0 = (p1 - p0) * (1f + bias) * (1f - tension) / 2f;
|
float m0 = (p1 - p0) * biasTensionTerms;
|
||||||
m0 += (p2 - p1) * (1f + bias) * (1f - tension) / 2f;
|
float mTemp = (p2 - p1) * biasTensionTerms;
|
||||||
float m1 = (p2 - p1) * (1f + bias) * (1f - tension) / 2f;
|
m0 += mTemp;
|
||||||
m1 += (p3 - p2) * (1f + bias) * (1f - tension) / 2f;
|
float m1 = mTemp;
|
||||||
|
m1 += (p3 - p2) * biasTensionTerms;
|
||||||
|
|
||||||
float a0 = 2 * mu3 - 3 * mu2 + 1;
|
float a0 = 2*mu3 - 3*mu2 + 1;
|
||||||
float a1 = mu3 - 2 * mu2 + scale;
|
float a1 = 1*mu3 - 2*mu2 + scale;
|
||||||
float a2 = mu3 - mu2;
|
float a2 = 1*mu3 - 1*mu2 + 0;
|
||||||
float a3 = -2 * mu3 + 3 * mu2;
|
float a3 = -2*mu3 + 3*mu2 + 0;
|
||||||
|
|
||||||
return a0 * p1 + a1 * m0 + a2 * m1 + a3 * p2;
|
return a0*p1 + a1*m0 + a2*m1 + a3*p2;
|
||||||
}
|
}
|
||||||
|
//public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3, float tension, float bias) {}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -795,28 +813,6 @@ final public class FastMath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Take a float input and clamp it between min and max.
|
|
||||||
*
|
|
||||||
* @param input
|
|
||||||
* @param min
|
|
||||||
* @param max
|
|
||||||
* @return clamped input
|
|
||||||
*/
|
|
||||||
public static float clamp(float input, float min, float max) {
|
|
||||||
return (input < min) ? min : (input > max) ? max : input;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clamps the given float to be between 0 and 1.
|
|
||||||
*
|
|
||||||
* @param input
|
|
||||||
* @return input clamped between 0 and 1.
|
|
||||||
*/
|
|
||||||
public static float saturate(float input) {
|
|
||||||
return clamp(input, 0f, 1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a single precision (32 bit) floating point value
|
* Converts a single precision (32 bit) floating point value
|
||||||
* into half precision (16 bit).
|
* into half precision (16 bit).
|
||||||
@@ -871,31 +867,6 @@ final public class FastMath {
|
|||||||
| ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
|
| ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
|
||||||
| ((f >> 13) & 0x03ff));
|
| ((f >> 13) & 0x03ff));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float min(float... f) {
|
|
||||||
float min = f[0];
|
|
||||||
for (int i = 1; i < f.length; i++) min = (f[i] < min) ? f[i] : min;
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float max(float... f) {
|
|
||||||
float max = f[0];
|
|
||||||
for (int i = 1; i < f.length; i++) max = (f[i] > max) ? f[i] : max;
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int min(int... f) {
|
|
||||||
int min = f[0];
|
|
||||||
for (int i = 1; i < f.length; i++) min = (f[i] < min) ? f[i] : min;
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int max(int... f) {
|
|
||||||
int max = f[0];
|
|
||||||
for (int i = 1; i < f.length; i++) max = (f[i] > max) ? f[i] : max;
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getGCD(int a, int b) {
|
public static int getGCD(int a, int b) {
|
||||||
while (a != b) {
|
while (a != b) {
|
||||||
if (a > b) a = a-b;
|
if (a > b) a = a-b;
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ fun Color.toXYZ(): CIEXYZ = RGB(this).toXYZ()
|
|||||||
}
|
}
|
||||||
val step = value.clampOne() * 255f // 0.0 .. 255.0
|
val step = value.clampOne() * 255f // 0.0 .. 255.0
|
||||||
val intStep = step.toInt() // 0 .. 255
|
val intStep = step.toInt() // 0 .. 255
|
||||||
val NeXTSTEP = minOf(intStep + 1, 255) // 1 .. 255
|
val NeXTSTEP = min(intStep + 1, 255) // 1 .. 255
|
||||||
|
|
||||||
out[i] = interpolateLinear(step - intStep, rgbLinLUT[intStep], rgbLinLUT[NeXTSTEP])
|
out[i] = interpolateLinear(step - intStep, rgbLinLUT[intStep], rgbLinLUT[NeXTSTEP])
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ fun RGB.linearise(): RGB {
|
|||||||
}
|
}
|
||||||
val step = value.clampOne() * 255f // 0.0 .. 255.0
|
val step = value.clampOne() * 255f // 0.0 .. 255.0
|
||||||
val intStep = step.toInt() // 0 .. 255
|
val intStep = step.toInt() // 0 .. 255
|
||||||
val NeXTSTEP = minOf(intStep + 1, 255) // 1 .. 255
|
val NeXTSTEP = min(intStep + 1, 255) // 1 .. 255
|
||||||
|
|
||||||
out[i] = interpolateLinear(step - intStep, rgbUnLinLUT[intStep], rgbUnLinLUT[NeXTSTEP])
|
out[i] = interpolateLinear(step - intStep, rgbUnLinLUT[intStep], rgbUnLinLUT[NeXTSTEP])
|
||||||
}
|
}
|
||||||
@@ -192,6 +192,16 @@ fun CIEXYZ.toColorRaw(): Color {
|
|||||||
return Color(rgb.r, rgb.g, rgb.b, rgb.alpha)
|
return Color(rgb.r, rgb.g, rgb.b, rgb.alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun CIEXYZ.toYXY(): CIEYXY {
|
||||||
|
val dot = this.X + this.Y + this.Z
|
||||||
|
return CIEYXY(
|
||||||
|
this.Y,
|
||||||
|
this.X / dot,
|
||||||
|
this.Y / dot,
|
||||||
|
this.alpha
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun CIEYXY.toXYZ(): CIEXYZ {
|
fun CIEYXY.toXYZ(): CIEXYZ {
|
||||||
return CIEXYZ(x * yy / y, yy, (1f - x - y) * yy / y)
|
return CIEXYZ(x * yy / y, yy, (1f - x - y) * yy / y)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package net.torvald.colourutil
|
|||||||
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OBSOLETE; use CIELchUtil for natural-looking colour
|
* OBSOLETE; use CIELchUtil for natural-looking colour
|
||||||
@@ -75,8 +77,8 @@ object HSVUtil {
|
|||||||
val g = color.g
|
val g = color.g
|
||||||
val b = color.b
|
val b = color.b
|
||||||
|
|
||||||
val rgbMin = FastMath.min(r, g, b)
|
val rgbMin = min(min(r, g), b)
|
||||||
val rgbMax = FastMath.max(r, g, b)
|
val rgbMax = max(max(r, g), b)
|
||||||
|
|
||||||
var h: Float
|
var h: Float
|
||||||
val s: Float
|
val s: Float
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public class HUSLColorConverter {
|
|||||||
float x = intersectLineLine(line, new float[]{-1 / m1, 0});
|
float x = intersectLineLine(line, new float[]{-1 / m1, 0});
|
||||||
float length = distanceFromPole(new float[]{x, b1 + x * m1});
|
float length = distanceFromPole(new float[]{x, b1 + x * m1});
|
||||||
|
|
||||||
min = FastMath.min(min, length);
|
min = Math.min(min, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return min;
|
return min;
|
||||||
@@ -125,7 +125,7 @@ public class HUSLColorConverter {
|
|||||||
for (float[] bound : bounds) {
|
for (float[] bound : bounds) {
|
||||||
Length length = lengthOfRayUntilIntersect(hrad, bound);
|
Length length = lengthOfRayUntilIntersect(hrad, bound);
|
||||||
if (length.greaterEqualZero) {
|
if (length.greaterEqualZero) {
|
||||||
min = FastMath.min(min, length.length);
|
min = Math.min(min, length.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ class Cvec {
|
|||||||
this.a = color.a
|
this.a = color.a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(rgb: Color, alpha: Float) {
|
||||||
|
this.r = rgb.r
|
||||||
|
this.g = rgb.g
|
||||||
|
this.b = rgb.b
|
||||||
|
this.a = alpha
|
||||||
|
}
|
||||||
|
|
||||||
/** Constructor, sets the components of the color
|
/** Constructor, sets the components of the color
|
||||||
*
|
*
|
||||||
* @param r the red component
|
* @param r the red component
|
||||||
|
|||||||
@@ -104,10 +104,10 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) {
|
|||||||
// operators
|
// operators
|
||||||
fun max(x: Int, y: Int, other: Cvec) {
|
fun max(x: Int, y: Int, other: Cvec) {
|
||||||
val a = toAddr(x, y)
|
val a = toAddr(x, y)
|
||||||
array.setFloat(a + 0, maxOf(array.getFloat(a + 0), other.r))
|
array.setFloat(a + 0, kotlin.math.max(array.getFloat(a + 0), other.r))
|
||||||
array.setFloat(a + 1, maxOf(array.getFloat(a + 1), other.g))
|
array.setFloat(a + 1, kotlin.math.max(array.getFloat(a + 1), other.g))
|
||||||
array.setFloat(a + 2, maxOf(array.getFloat(a + 2), other.b))
|
array.setFloat(a + 2, kotlin.math.max(array.getFloat(a + 2), other.b))
|
||||||
array.setFloat(a + 3, maxOf(array.getFloat(a + 3), other.a))
|
array.setFloat(a + 3, kotlin.math.max(array.getFloat(a + 3), other.a))
|
||||||
}
|
}
|
||||||
fun mul(x: Int, y: Int, scalar: Float) {
|
fun mul(x: Int, y: Int, scalar: Float) {
|
||||||
val a = toAddr(x, y)
|
val a = toAddr(x, y)
|
||||||
@@ -202,10 +202,10 @@ internal class TestCvecArr(val width: Int, val height: Int) {
|
|||||||
|
|
||||||
// operators
|
// operators
|
||||||
inline fun max(x: Int, y: Int, other: Cvec) {
|
inline fun max(x: Int, y: Int, other: Cvec) {
|
||||||
setR(x, y, maxOf(getR(x, y), other.r))
|
setR(x, y, kotlin.math.max(getR(x, y), other.r))
|
||||||
setG(x, y, maxOf(getG(x, y), other.g))
|
setG(x, y, kotlin.math.max(getG(x, y), other.g))
|
||||||
setB(x, y, maxOf(getB(x, y), other.b))
|
setB(x, y, kotlin.math.max(getB(x, y), other.b))
|
||||||
setA(x, y, maxOf(getA(x, y), other.a))
|
setA(x, y, kotlin.math.max(getA(x, y), other.a))
|
||||||
}
|
}
|
||||||
inline fun mul(x: Int, y: Int, scalar: Float) {
|
inline fun mul(x: Int, y: Int, scalar: Float) {
|
||||||
setR(x, y, getR(x, y) * scalar)
|
setR(x, y, getR(x, y) * scalar)
|
||||||
|
|||||||
@@ -12,24 +12,36 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|||||||
import net.torvald.unicode.EMDASH
|
import net.torvald.unicode.EMDASH
|
||||||
import net.torvald.colourutil.*
|
import net.torvald.colourutil.*
|
||||||
import net.torvald.parametricsky.datasets.DatasetCIEXYZ
|
import net.torvald.parametricsky.datasets.DatasetCIEXYZ
|
||||||
import net.torvald.parametricsky.datasets.DatasetRGB
|
import net.torvald.terrarum.abs
|
||||||
import net.torvald.parametricsky.datasets.DatasetSpectral
|
import net.torvald.terrarum.clut.Skybox
|
||||||
|
import net.torvald.terrarum.clut.Skybox.coerceInSmoothly
|
||||||
|
import net.torvald.terrarum.clut.Skybox.mapCircle
|
||||||
import net.torvald.terrarum.inUse
|
import net.torvald.terrarum.inUse
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.HALF_PI
|
import net.torvald.terrarum.modulebasegame.worldgenerator.HALF_PI
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.TWO_PI
|
import java.awt.BorderLayout
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
|
import java.lang.Math.pow
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
import kotlin.math.PI
|
import kotlin.math.*
|
||||||
import kotlin.math.pow
|
|
||||||
|
|
||||||
|
|
||||||
const val WIDTH = 1200
|
val INITIAL_TURBIDITY = 4.0
|
||||||
const val HEIGHT = 600
|
val INITIAL_ALBEDO = 0.1
|
||||||
|
val INITIAL_ELEV = 0.0
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2018-08-01.
|
* Created by minjaesong on 2018-08-01.
|
||||||
*/
|
*/
|
||||||
class Application : Game() {
|
class Application(val WIDTH: Int, val HEIGHT: Int) : Game() {
|
||||||
|
|
||||||
|
private val HW = WIDTH / 2
|
||||||
|
private val HH = HEIGHT / 2
|
||||||
|
|
||||||
|
private val wf = WIDTH.toFloat()
|
||||||
|
private val hf = HEIGHT.toFloat()
|
||||||
|
private val hwf = HW.toFloat()
|
||||||
|
// private val hhf = HH.toFloat()
|
||||||
|
|
||||||
/* Variables:
|
/* Variables:
|
||||||
* 1. Canvas Y (theta)
|
* 1. Canvas Y (theta)
|
||||||
@@ -53,12 +65,12 @@ class Application : Game() {
|
|||||||
private lateinit var oneScreen: Pixmap
|
private lateinit var oneScreen: Pixmap
|
||||||
private lateinit var batch: SpriteBatch
|
private lateinit var batch: SpriteBatch
|
||||||
|
|
||||||
private lateinit var testTex: Texture
|
var turbidity = INITIAL_TURBIDITY
|
||||||
|
var albedo = INITIAL_ALBEDO
|
||||||
|
var elevation = Math.toRadians(INITIAL_ELEV)
|
||||||
|
|
||||||
var turbidity = 5.0
|
var solarBearing = Math.toRadians(90.0)
|
||||||
var albedo = 0.1
|
var cameraHeading = Math.toRadians(90.0)
|
||||||
var elevation = 0.0
|
|
||||||
var scalefactor = 1f
|
|
||||||
|
|
||||||
override fun getScreen(): Screen {
|
override fun getScreen(): Screen {
|
||||||
return super.getScreen()
|
return super.getScreen()
|
||||||
@@ -68,20 +80,38 @@ class Application : Game() {
|
|||||||
super.setScreen(screen)
|
super.setScreen(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var model = ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation.abs())
|
||||||
|
|
||||||
|
fun regenerateModel() {
|
||||||
|
model = ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation.abs())
|
||||||
|
}
|
||||||
|
|
||||||
override fun render() {
|
override fun render() {
|
||||||
Gdx.graphics.setTitle("Daylight Model $EMDASH F: ${Gdx.graphics.framesPerSecond}")
|
Gdx.graphics.setTitle("Daylight Model $EMDASH F: ${Gdx.graphics.framesPerSecond}")
|
||||||
|
|
||||||
if (turbidity <= 0) throw IllegalStateException()
|
if (turbidity <= 0) throw IllegalStateException()
|
||||||
|
|
||||||
// we need to use different modelstate to accomodate different albedo for each spectral band but oh well...
|
// we need to use different model-state to accommodate different albedo for each spectral band but oh well...
|
||||||
genTexLoop(ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation))
|
genTexLoop(model, elevation)
|
||||||
|
// println("$elevation\t${ymaxDisp.text}\t${ymaxDisp2.text}")
|
||||||
|
|
||||||
|
|
||||||
|
/*for (elev in -75..75) {
|
||||||
|
val elevation = Math.toRadians(elev.toDouble())
|
||||||
|
val model = ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation.abs())
|
||||||
|
genTexLoop(model, elevation)
|
||||||
|
println("$elev\t${ymaxDisp.text}\t${ymaxDisp2.text}")
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
val tex = Texture(oneScreen)
|
val tex = Texture(oneScreen)
|
||||||
tex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
tex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.draw(tex, 0f, 0f, WIDTH.toFloat(), HEIGHT.toFloat())
|
// batch.draw(tex, hwf, 0f, hwf, hf)
|
||||||
|
// batch.draw(tex, hwf, 0f, -hwf, hf)
|
||||||
|
|
||||||
|
batch.draw(tex, 0f, 0f, wf, hf)
|
||||||
}
|
}
|
||||||
|
|
||||||
tex.dispose()
|
tex.dispose()
|
||||||
@@ -103,14 +133,48 @@ class Application : Game() {
|
|||||||
oneScreen.dispose()
|
oneScreen.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
val outTexWidth = 256
|
val outTexWidth = 1
|
||||||
val outTexHeight = 256
|
val outTexHeight = 128
|
||||||
|
|
||||||
|
private fun Float.scaleFun() =
|
||||||
|
(1f - 1f / 2f.pow(this/6f)) * 0.97f
|
||||||
|
|
||||||
|
private fun CIEXYZ.scaleToFit(elevation: Double): CIEXYZ {
|
||||||
|
return if (elevation >= 0) {
|
||||||
|
CIEXYZ(
|
||||||
|
this.X.scaleFun(),
|
||||||
|
this.Y.scaleFun(),
|
||||||
|
this.Z.scaleFun(),
|
||||||
|
this.alpha
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// maths model: https://www.desmos.com/calculator/cwi7iyzygg
|
||||||
|
|
||||||
|
val x = -Math.toDegrees(elevation).toFloat()
|
||||||
|
// val elevation2 = -Math.toDegrees(elevation) / 28.5
|
||||||
|
val p = 3.5f
|
||||||
|
val q = 7.5f
|
||||||
|
val s = -0.2f
|
||||||
|
val f = (1f - (1f - 1f / 1.8f.pow(x)) * 0.97f).toFloat()
|
||||||
|
// val g = (1.0 - (elevation2.pow(E) / E.pow(elevation2))*0.8).toFloat()
|
||||||
|
val h = ((x / q).pow(p) + 1f).pow(s)
|
||||||
|
CIEXYZ(
|
||||||
|
this.X.scaleFun() * f * h,
|
||||||
|
this.Y.scaleFun() * f * h,
|
||||||
|
this.Z.scaleFun() * f * h,
|
||||||
|
this.alpha
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Double.mapCircle() = sin(HALF_PI * this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generated texture is as if you took the panorama picture of sky: up 70deg to horizon, east-south-west;
|
* Generated texture is as if you took the panorama picture of sky: up 70deg to horizon, east-south-west;
|
||||||
* with sun not moving (sun is at exact south, sun's height is adjustable)
|
* with sun not moving (sun is at exact south, sun's height is adjustable)
|
||||||
*/
|
*/
|
||||||
private fun genTexLoop(state: ArHosekSkyModelState) {
|
private fun genTexLoop(state: ArHosekSkyModelState, elevation: Double) {
|
||||||
|
|
||||||
fun normaliseY(y: Double): Float {
|
fun normaliseY(y: Double): Float {
|
||||||
var v = y.coerceAtLeast(0.0)
|
var v = y.coerceAtLeast(0.0)
|
||||||
@@ -120,20 +184,49 @@ class Application : Game() {
|
|||||||
return v.toFloat()
|
return v.toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ys = ArrayList<Float>()
|
||||||
|
val ys2 = ArrayList<Float>()
|
||||||
|
|
||||||
|
val halfHeight = oneScreen.height * 0.5
|
||||||
|
val elevationDeg = Math.toDegrees(elevation)
|
||||||
|
|
||||||
|
for (x in 0 until oneScreen.width) {
|
||||||
|
for (y in 0 until oneScreen.height) {
|
||||||
|
|
||||||
|
// sky-sphere mapping
|
||||||
|
/*val xf = ((x + 0.5) / oneScreen.width) * 2.0 - 1.0
|
||||||
|
val yf = ((y + 0.5) / oneScreen.height) * 2.0 - 1.0
|
||||||
|
val gamma = atan2(yf, xf) + PI
|
||||||
|
val theta = sqrt(xf*xf + yf*yf) * HALF_PI*/
|
||||||
|
|
||||||
|
// AM-PM mapping (use with WIDTH=1)
|
||||||
|
val yp = y % (oneScreen.height / 2)
|
||||||
|
val yi = yp - 3
|
||||||
|
val xf = -elevationDeg / 90.0
|
||||||
|
var yf = (yi / 58.0).coerceIn(0.0, 1.0).mapCircle().coerceInSmoothly(0.0, 0.95)
|
||||||
|
if (elevationDeg < 0) yf *= Skybox.superellipsoidDecay(1.0 / 3.0, xf)
|
||||||
|
val theta = yf * HALF_PI
|
||||||
|
val gamma = if (y < halfHeight) HALF_PI else 3 * HALF_PI
|
||||||
|
|
||||||
for (y in 0 until oneScreen.height) {
|
|
||||||
for (x in 0 until oneScreen.width) {
|
|
||||||
val gamma = (x / oneScreen.width.toDouble()) * TWO_PI // 0deg..360deg
|
|
||||||
val theta = (1.0 - (y / oneScreen.height.toDouble())) * HALF_PI // 90deg..0deg
|
|
||||||
|
|
||||||
val xyz = CIEXYZ(
|
val xyz = CIEXYZ(
|
||||||
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 0).toFloat().times(scalefactor / 10f),
|
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 0).toFloat(),
|
||||||
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 1).toFloat().times(scalefactor / 10f),
|
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 1).toFloat(),
|
||||||
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 2).toFloat().times(scalefactor / 10f)
|
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 2).toFloat(),
|
||||||
)
|
)
|
||||||
val rgb = xyz.toRGB().toColor()
|
val xyz2 = xyz.scaleToFit(elevation)
|
||||||
|
ys.add(xyz.Y)
|
||||||
|
ys2.add(xyz2.Y)
|
||||||
|
val rgb = xyz2.toRGB().toColor()
|
||||||
rgb.a = 1f
|
rgb.a = 1f
|
||||||
|
|
||||||
|
/*val rgb2 = Color(
|
||||||
|
((rgb.r * 255f).roundToInt() xor 0xAA) / 255f,
|
||||||
|
((rgb.g * 255f).roundToInt() xor 0xAA) / 255f,
|
||||||
|
((rgb.b * 255f).roundToInt() xor 0xAA) / 255f,
|
||||||
|
rgb.a
|
||||||
|
)*/
|
||||||
|
|
||||||
oneScreen.setColor(rgb)
|
oneScreen.setColor(rgb)
|
||||||
oneScreen.drawPixel(x, y)
|
oneScreen.drawPixel(x, y)
|
||||||
|
|
||||||
@@ -142,140 +235,148 @@ class Application : Game() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ymaxDisp.text = "${ys.max()}"
|
||||||
|
ymaxDisp2.text = "${ys2.max()}"
|
||||||
|
|
||||||
//System.exit(0)
|
//System.exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generated texture is as if you took the panorama picture of sky: up 70deg to horizon, east-south-west;
|
|
||||||
* with sun not moving (sun is at exact south, sun's height is adjustable)
|
|
||||||
*/
|
|
||||||
/*private fun genTexLoop2(T: Double, theta_s: Double) {
|
|
||||||
|
|
||||||
fun hazeFun(T: Double): Double {
|
|
||||||
val T = T - 1
|
|
||||||
if (T >= 10) return 1.0
|
|
||||||
else return 2.0.pow(T).div(1024.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop thru gamma and theta
|
|
||||||
for (y in 0..outTexDim) { // theta
|
|
||||||
for (x in 0..outTexDim) { // gamma
|
|
||||||
val theta = Math.toRadians(y * (90.0 / outTexDim.toDouble())) // of observer
|
|
||||||
val gamma = Math.toRadians(x * (90.0 / outTexDim.toDouble())) // of observer
|
|
||||||
|
|
||||||
val Y_z = Model.getAbsoluteZenithLuminance(T, theta_s)
|
|
||||||
val x_z = Model.getZenithChromaX(T, theta_s)
|
|
||||||
val y_z = Model.getZenithChromaY(T, theta_s)
|
|
||||||
|
|
||||||
val Y_p = Y_z * Model.getFforLuma(theta, gamma, T) / Model.getFforLuma(0.0, theta_s, T)
|
|
||||||
val Y_oc = Y_z * (1.0 + 2.0 * Math.cos(theta)) / 3.0
|
|
||||||
val x_p = (x_z * Model.getFforChromaX(theta, gamma, T) / Model.getFforChromaX(0.0, theta_s, T)).coerceIn(0.0, 1.0)
|
|
||||||
val y_p = (y_z * Model.getFforChromaY(theta, gamma, T) / Model.getFforChromaY(0.0, theta_s, T)).coerceIn(0.0, 1.0)
|
|
||||||
|
|
||||||
val normalisedY = Y_p.toFloat().pow(0.5f).div(10f)
|
|
||||||
val normalisedY_oc = Y_oc.toFloat().pow(0.5f).div(10f)
|
|
||||||
|
|
||||||
//println("$Y_p -> $normalisedY, $x_p, $y_p")
|
|
||||||
|
|
||||||
if (T < 11) {
|
|
||||||
val rgbColour = CIEYXY(normalisedY, x_p.toFloat(), y_p.toFloat()).toXYZ().toColorRaw()
|
|
||||||
val hazeColour = CIEYXY(normalisedY_oc, 0.3128f, 0.3290f).toXYZ().toColorRaw()
|
|
||||||
|
|
||||||
val hazeAmount = hazeFun(T).toFloat()
|
|
||||||
val newColour = Color(
|
|
||||||
FastMath.interpolateLinear(hazeAmount, rgbColour.r, hazeColour.r),
|
|
||||||
FastMath.interpolateLinear(hazeAmount, rgbColour.g, hazeColour.g),
|
|
||||||
FastMath.interpolateLinear(hazeAmount, rgbColour.b, hazeColour.b),
|
|
||||||
1f
|
|
||||||
)
|
|
||||||
|
|
||||||
oneScreen.setColor(newColour)
|
|
||||||
oneScreen.drawPixel(x, y)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val hazeColour = CIEYXY(normalisedY_oc, 0.3128f, 0.3290f).toXYZ().toColorRaw()
|
|
||||||
oneScreen.setColor(hazeColour)
|
|
||||||
oneScreen.drawPixel(x, y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// end loop
|
|
||||||
}*/
|
|
||||||
|
|
||||||
override fun create() {
|
override fun create() {
|
||||||
batch = SpriteBatch()
|
batch = SpriteBatch()
|
||||||
testTex = Texture(Gdx.files.internal("assets/test_texture.tga"))
|
|
||||||
|
|
||||||
oneScreen = Pixmap(outTexWidth * 2, outTexHeight, Pixmap.Format.RGBA8888)
|
oneScreen = Pixmap(outTexWidth, outTexHeight, Pixmap.Format.RGBA8888)
|
||||||
|
|
||||||
DatasetSpectral
|
// DatasetSpectral
|
||||||
DatasetCIEXYZ
|
DatasetCIEXYZ
|
||||||
DatasetRGB
|
// DatasetRGB
|
||||||
|
|
||||||
ApplicationController(this)
|
ApplicationController(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ymaxDisp = JTextField().also {
|
||||||
|
it.preferredSize = Dimension(64, 20)
|
||||||
|
}
|
||||||
|
val ymaxDisp2 = JTextField().also {
|
||||||
|
it.preferredSize = Dimension(64, 20)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApplicationController(val app: Application) : JFrame() {
|
||||||
|
|
||||||
class ApplicationController(app: Application) : JFrame() {
|
val dialSize = Dimension(45, 20)
|
||||||
|
|
||||||
val mainPanel = JPanel()
|
val turbidityControl = JSpinner(SpinnerNumberModel(INITIAL_TURBIDITY, 1.0, 10.0, 0.1)).also {
|
||||||
|
it.preferredSize = dialSize
|
||||||
val turbidityControl = JSpinner(SpinnerNumberModel(5.0, 1.0, 10.0, 0.1))
|
it.addChangeListener { _ ->
|
||||||
val albedoControl = JSpinner(SpinnerNumberModel(0.1, 0.0, 1.0, 0.05))
|
app.turbidity = it.value as Double
|
||||||
val elevationControl = JSpinner(SpinnerNumberModel(0.0, 0.0, 90.0, 0.5))
|
app.regenerateModel()
|
||||||
val scalefactorControl = JSpinner(SpinnerNumberModel(1.0, 0.0, 2.0, 0.01))
|
}
|
||||||
|
}
|
||||||
|
val albedoControl = JSpinner(SpinnerNumberModel(INITIAL_ALBEDO, 0.0, 1.0, 0.05)).also {
|
||||||
|
it.preferredSize = dialSize
|
||||||
|
it.addChangeListener { _ ->
|
||||||
|
app.albedo = it.value as Double
|
||||||
|
app.regenerateModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val elevationControl = JSpinner(SpinnerNumberModel(INITIAL_ELEV, -75.0, 75.0, 0.5)).also {
|
||||||
|
it.preferredSize = dialSize
|
||||||
|
it.addChangeListener { _ ->
|
||||||
|
app.elevation = Math.toRadians(it.value as Double)
|
||||||
|
app.regenerateModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val solarBearing = JSpinner(SpinnerNumberModel(90.0, 0.0, 180.0, 1.0)).also {
|
||||||
|
it.preferredSize = dialSize
|
||||||
|
it.addChangeListener { _ ->
|
||||||
|
app.solarBearing = (it.value as Double)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val cameraHeading = JSpinner(SpinnerNumberModel(90.0, 0.0, 180.0, 1.0)).also {
|
||||||
|
it.preferredSize = dialSize
|
||||||
|
it.addChangeListener { _ ->
|
||||||
|
app.cameraHeading = (it.value as Double)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val turbidityPanel = JPanel()
|
val atmosPanel = JPanel()
|
||||||
val albedoPanel = JPanel()
|
val turbidityPanel = JPanel().also {
|
||||||
val elevationPanel = JPanel()
|
it.add(JLabel("Turbidity (log_2)"))
|
||||||
val scalefactorPanel = JPanel()
|
it.add(turbidityControl)
|
||||||
|
atmosPanel.add(it)
|
||||||
|
}
|
||||||
|
val albedoPanel = JPanel().also {
|
||||||
|
it.add(JLabel("Albedo"))
|
||||||
|
it.add(albedoControl)
|
||||||
|
atmosPanel.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
turbidityControl.preferredSize = Dimension(45, 18)
|
val sunPanel = JPanel()
|
||||||
albedoControl.preferredSize = Dimension(45, 18)
|
val elevationPanel = JPanel().also {
|
||||||
elevationControl.preferredSize = Dimension(45, 18)
|
it.add(JLabel("Elevation"))
|
||||||
scalefactorControl.preferredSize = Dimension(45, 18)
|
it.add(elevationControl)
|
||||||
|
sunPanel.add(it)
|
||||||
|
}
|
||||||
|
val scalefactorPanel = JPanel().also {
|
||||||
|
it.add(JLabel("Bearing"))
|
||||||
|
it.add(solarBearing)
|
||||||
|
sunPanel.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
turbidityPanel.add(JLabel("Turbidity"))
|
val cameraPanel = JPanel()
|
||||||
turbidityPanel.add(turbidityControl)
|
val headingPanel = JPanel().also {
|
||||||
|
it.add(JLabel("Heading"))
|
||||||
|
it.add(cameraHeading)
|
||||||
|
cameraPanel.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
albedoPanel.add(JLabel("Albedo"))
|
val statsPanel = JPanel()
|
||||||
albedoPanel.add(albedoControl)
|
val ymaxPanel = JPanel().also {
|
||||||
|
it.add(JLabel("Ymax (CIEXYZ)"))
|
||||||
|
it.add(app.ymaxDisp)
|
||||||
|
statsPanel.add(it)
|
||||||
|
}
|
||||||
|
val ymaxPanel2 = JPanel().also {
|
||||||
|
it.add(JLabel("Ymax (scaled)"))
|
||||||
|
it.add(app.ymaxDisp2)
|
||||||
|
statsPanel.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
elevationPanel.add(JLabel("Elevation"))
|
val mainPanel = JPanel()
|
||||||
elevationPanel.add(elevationControl)
|
|
||||||
|
|
||||||
scalefactorPanel.add(JLabel("Scaling Factor"))
|
mainPanel.layout = BoxLayout(mainPanel, BoxLayout.Y_AXIS)
|
||||||
scalefactorPanel.add(scalefactorControl)
|
JPanel().also {
|
||||||
|
it.layout = BorderLayout()
|
||||||
mainPanel.add(turbidityPanel)
|
it.add(JPanel().also { it.add(JLabel("Atmosphere")) }, BorderLayout.NORTH)
|
||||||
mainPanel.add(albedoPanel)
|
it.add(atmosPanel, BorderLayout.CENTER)
|
||||||
mainPanel.add(elevationPanel)
|
it.add(JSeparator(), BorderLayout.SOUTH)
|
||||||
mainPanel.add(scalefactorPanel)
|
mainPanel.add(it)
|
||||||
|
}
|
||||||
|
JPanel().also {
|
||||||
|
it.layout = BorderLayout()
|
||||||
|
it.add(JPanel().also { it.add(JLabel("Sun")) }, BorderLayout.NORTH)
|
||||||
|
it.add(sunPanel, BorderLayout.CENTER)
|
||||||
|
it.add(JSeparator(), BorderLayout.SOUTH)
|
||||||
|
mainPanel.add(it)
|
||||||
|
}
|
||||||
|
JPanel().also {
|
||||||
|
it.layout = BorderLayout()
|
||||||
|
it.add(JPanel().also { it.add(JLabel("Camera")) }, BorderLayout.NORTH)
|
||||||
|
it.add(cameraPanel, BorderLayout.CENTER)
|
||||||
|
it.add(JSeparator(), BorderLayout.SOUTH)
|
||||||
|
mainPanel.add(it)
|
||||||
|
}
|
||||||
|
JPanel().also {
|
||||||
|
it.layout = BorderLayout()
|
||||||
|
it.add(JPanel().also { it.add(JLabel("Statistics")) }, BorderLayout.NORTH)
|
||||||
|
it.add(statsPanel, BorderLayout.CENTER)
|
||||||
|
mainPanel.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
this.isVisible = true
|
this.isVisible = true
|
||||||
this.defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
|
this.defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
|
||||||
this.size = Dimension(300, 400)
|
this.size = Dimension(300, 600)
|
||||||
|
this.add(mainPanel, BorderLayout.CENTER)
|
||||||
this.add(mainPanel)
|
|
||||||
|
|
||||||
|
|
||||||
turbidityControl.addChangeListener {
|
|
||||||
app.turbidity = turbidityControl.value as Double
|
|
||||||
}
|
|
||||||
|
|
||||||
albedoControl.addChangeListener {
|
|
||||||
app.albedo = albedoControl.value as Double
|
|
||||||
}
|
|
||||||
|
|
||||||
elevationControl.addChangeListener {
|
|
||||||
app.elevation = Math.toRadians(elevationControl.value as Double)
|
|
||||||
}
|
|
||||||
|
|
||||||
scalefactorControl.addChangeListener {
|
|
||||||
app.scalefactor = (scalefactorControl.value as Double).toFloat()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +386,10 @@ class Application : Game() {
|
|||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val config = Lwjgl3ApplicationConfiguration()
|
val config = Lwjgl3ApplicationConfiguration()
|
||||||
config.setWindowedMode(WIDTH, HEIGHT)
|
|
||||||
|
|
||||||
Lwjgl3Application(Application(), config)
|
val WIDTH = 2048
|
||||||
|
val HEIGHT = 2048
|
||||||
|
|
||||||
|
config.setWindowedMode(WIDTH, HEIGHT)
|
||||||
|
Lwjgl3Application(Application(WIDTH, HEIGHT), config)
|
||||||
}
|
}
|
||||||
@@ -11,8 +11,8 @@ object DatasetOp {
|
|||||||
val entrysize = file.length().toInt() / 8
|
val entrysize = file.length().toInt() / 8
|
||||||
val fis = FileInputStream(file)
|
val fis = FileInputStream(file)
|
||||||
|
|
||||||
|
val inputbuf = ByteArray(8)
|
||||||
val ret = DoubleArray(entrysize) {
|
val ret = DoubleArray(entrysize) {
|
||||||
val inputbuf = ByteArray(8)
|
|
||||||
fis.read(inputbuf)
|
fis.read(inputbuf)
|
||||||
val rawnum = inputbuf.toLittleInt64()
|
val rawnum = inputbuf.toLittleInt64()
|
||||||
Double.fromBits(rawnum)
|
Double.fromBits(rawnum)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package net.torvald.random
|
package net.torvald.random
|
||||||
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.terrarum.floorInt
|
import net.torvald.terrarum.floorToInt
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -45,9 +45,9 @@ class TileableValueNoise(
|
|||||||
try {
|
try {
|
||||||
for (x in 0..width) {
|
for (x in 0..width) {
|
||||||
val thisSampleStart: Int = // 0-256 -> 0-4 -> 0-256(qnt)
|
val thisSampleStart: Int = // 0-256 -> 0-4 -> 0-256(qnt)
|
||||||
(x / width.toFloat() * samples).floorInt() * (width / samples)
|
(x / width.toFloat() * samples).floorToInt() * (width / samples)
|
||||||
val nextSampleStart: Int =
|
val nextSampleStart: Int =
|
||||||
(x / width.toFloat() * samples).floorInt().plus(1) * (width / samples)
|
(x / width.toFloat() * samples).floorToInt().plus(1) * (width / samples)
|
||||||
val stepWithinWindow: Int = x % (nextSampleStart - thisSampleStart)
|
val stepWithinWindow: Int = x % (nextSampleStart - thisSampleStart)
|
||||||
val windowScale: Float = stepWithinWindow.toFloat() / (width / samples)
|
val windowScale: Float = stepWithinWindow.toFloat() / (width / samples)
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class XXHash32 {
|
|||||||
|
|
||||||
public static int hashGeoCoord(int x, int y) {
|
public static int hashGeoCoord(int x, int y) {
|
||||||
int p = ((x & 65535) << 16) | (y & 65535);
|
int p = ((x & 65535) << 16) | (y & 65535);
|
||||||
return hash(new byte[]{(byte) p, (byte)(p >>> 8), (byte)(p >>> 16), (byte)(p >>> 24)}, 10000);
|
return hash(new byte[]{(byte) p, (byte)(p >>> 8), (byte)(p >>> 16), (byte)(p >>> 24)}, x ^ y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int hash(byte[] data, int seed) {
|
public static int hash(byte[] data, int seed) {
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ package net.torvald.reflection
|
|||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2023-03-25.
|
* Created by minjaesong on 2023-03-25.
|
||||||
*/
|
*/
|
||||||
fun Any.extortField(name: String): Any? { // yes I'm deliberately using negative words for the function name
|
inline fun <reified T> Any.extortField(name: String): T? { // yes I'm deliberately using negative words for the function name
|
||||||
return this.javaClass.getDeclaredField(name).let {
|
return this.javaClass.getDeclaredField(name).let {
|
||||||
it.isAccessible = true
|
it.isAccessible = true
|
||||||
it.get(this)
|
it.get(this) as T?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun Any.forceInvoke(name: String, params: Array<Any>): Any? { // yes I'm deliberately using negative words for the function name
|
inline fun <reified T> Any.forceInvoke(name: String, params: Array<Any>): T? { // yes I'm deliberately using negative words for the function name
|
||||||
return this.javaClass.getDeclaredMethod(name, *(params.map { it.javaClass }.toTypedArray())).let {
|
return this.javaClass.getDeclaredMethod(name, *(params.map { it.javaClass }.toTypedArray())).let {
|
||||||
it.isAccessible = true
|
it.isAccessible = true
|
||||||
it.invoke(this, *params)
|
it.invoke(this, *params) as T?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion
|
|||||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||||
import net.torvald.terrarum.ItemCodex
|
import net.torvald.terrarum.ItemCodex
|
||||||
import net.torvald.terrarum.Second
|
import net.torvald.terrarum.Second
|
||||||
import net.torvald.terrarum.floor
|
import net.torvald.terrarum.floorToFloat
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.gameitems.GameItem
|
import net.torvald.terrarum.gameitems.GameItem
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||||
@@ -19,6 +19,7 @@ import net.torvald.terrarum.spriteassembler.ADProperties
|
|||||||
import net.torvald.terrarum.spriteassembler.ADPropertyObject
|
import net.torvald.terrarum.spriteassembler.ADPropertyObject
|
||||||
import net.torvald.terrarum.spriteassembler.AssembleFrameBase
|
import net.torvald.terrarum.spriteassembler.AssembleFrameBase
|
||||||
import net.torvald.terrarum.spriteassembler.AssembleSheetPixmap
|
import net.torvald.terrarum.spriteassembler.AssembleSheetPixmap
|
||||||
|
import net.torvald.terrarum.tryDispose
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -122,8 +123,8 @@ class AssembledSpriteAnimation(
|
|||||||
val drawPos = adp.origin + bodypartPos // imgCentre for held items are (0,0)
|
val drawPos = adp.origin + bodypartPos // imgCentre for held items are (0,0)
|
||||||
val w = image.regionWidth * scale
|
val w = image.regionWidth * scale
|
||||||
val h = image.regionHeight * scale
|
val h = image.regionHeight * scale
|
||||||
val fposX = posX.floor() + drawPos.x * scale
|
val fposX = posX.floorToFloat() + drawPos.x * scale
|
||||||
val fposY = posY.floor() + drawPos.y * scale - h
|
val fposY = posY.floorToFloat() + drawPos.y * scale - h
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
if (flipHorizontal && flipVertical)
|
if (flipHorizontal && flipVertical)
|
||||||
@@ -146,8 +147,8 @@ class AssembledSpriteAnimation(
|
|||||||
val drawPos = adp.origin + bodypartPos - imgCentre
|
val drawPos = adp.origin + bodypartPos - imgCentre
|
||||||
val w = image.regionWidth * scale
|
val w = image.regionWidth * scale
|
||||||
val h = image.regionHeight * scale
|
val h = image.regionHeight * scale
|
||||||
val fposX = posX.floor() + drawPos.x * scale
|
val fposX = posX.floorToFloat() + drawPos.x * scale
|
||||||
val fposY = posY.floor() + drawPos.y * scale
|
val fposY = posY.floorToFloat() + drawPos.y * scale
|
||||||
|
|
||||||
if (flipHorizontal && flipVertical)
|
if (flipHorizontal && flipVertical)
|
||||||
batch.draw(image, fposX + txFlp, fposY + tyFlp, -w, -h)
|
batch.draw(image, fposX + txFlp, fposY + tyFlp, -w, -h)
|
||||||
@@ -172,7 +173,7 @@ class AssembledSpriteAnimation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
res.values.forEach { try { it?.texture?.dispose() } catch (_: GdxRuntimeException) {} }
|
res.values.forEach { it?.texture?.tryDispose() }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import net.torvald.terrarum.langpack.Lang;
|
|||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer;
|
import net.torvald.terrarum.modulebasegame.IngameRenderer;
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame;
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame;
|
||||||
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory;
|
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory;
|
||||||
import net.torvald.terrarum.savegame.DiskSkimmer;
|
|
||||||
import net.torvald.terrarum.serialise.WriteConfig;
|
import net.torvald.terrarum.serialise.WriteConfig;
|
||||||
import net.torvald.terrarum.ui.Toolkit;
|
import net.torvald.terrarum.ui.Toolkit;
|
||||||
import net.torvald.terrarum.utils.JsonFetcher;
|
import net.torvald.terrarum.utils.JsonFetcher;
|
||||||
@@ -63,9 +62,11 @@ public class App implements ApplicationListener {
|
|||||||
|
|
||||||
public static final String GAME_NAME = TerrarumAppConfiguration.GAME_NAME;
|
public static final String GAME_NAME = TerrarumAppConfiguration.GAME_NAME;
|
||||||
public static final long VERSION_RAW = TerrarumAppConfiguration.VERSION_RAW;
|
public static final long VERSION_RAW = TerrarumAppConfiguration.VERSION_RAW;
|
||||||
|
public static final String VERSION_TAG = TerrarumAppConfiguration.VERSION_TAG;
|
||||||
|
|
||||||
public static final String getVERSION_STRING() {
|
public static final String getVERSION_STRING() {
|
||||||
return String.format("%d.%d.%d", VERSION_RAW >>> 48, (VERSION_RAW & 0xffff000000L) >>> 24, VERSION_RAW & 0xffffffL);
|
return String.format("%d.%d.%d", VERSION_RAW >>> 48, (VERSION_RAW & 0xffff000000L) >>> 24, VERSION_RAW & 0xffffffL) +
|
||||||
|
(VERSION_TAG.isBlank() ? "" : "-"+VERSION_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,6 +143,12 @@ public class App implements ApplicationListener {
|
|||||||
|
|
||||||
public static final int GLOBAL_FRAMERATE_LIMIT = 300;
|
public static final int GLOBAL_FRAMERATE_LIMIT = 300;
|
||||||
|
|
||||||
|
private static String undesirableConditions;
|
||||||
|
|
||||||
|
public static String getUndesirableConditions() {
|
||||||
|
return undesirableConditions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These languages won't distinguish regional differences (e.g. enUS and enUK, frFR and frCA)
|
* These languages won't distinguish regional differences (e.g. enUS and enUK, frFR and frCA)
|
||||||
*/
|
*/
|
||||||
@@ -201,11 +208,11 @@ public class App implements ApplicationListener {
|
|||||||
* Sorted by the lastplaytime, in reverse order (index 0 is the most recent game played)
|
* Sorted by the lastplaytime, in reverse order (index 0 is the most recent game played)
|
||||||
*/
|
*/
|
||||||
public static ArrayList<UUID> sortedSavegameWorlds = new ArrayList();
|
public static ArrayList<UUID> sortedSavegameWorlds = new ArrayList();
|
||||||
public static HashMap<UUID, DiskSkimmer> savegameWorlds = new HashMap<>(); // UNSORTED even with the TreeMap
|
public static HashMap<UUID, SavegameCollection> savegameWorlds = new HashMap<>(); // UNSORTED even with the TreeMap
|
||||||
public static HashMap<UUID, String> savegameWorldsName = new HashMap<>();
|
public static HashMap<UUID, String> savegameWorldsName = new HashMap<>();
|
||||||
|
|
||||||
public static ArrayList<UUID> sortedPlayers = new ArrayList();
|
public static ArrayList<UUID> sortedPlayers = new ArrayList();
|
||||||
public static HashMap<UUID, DiskSkimmer> savegamePlayers = new HashMap<>();
|
public static HashMap<UUID, SavegameCollection> savegamePlayers = new HashMap<>();
|
||||||
public static HashMap<UUID, String> savegamePlayersName = new HashMap<>();
|
public static HashMap<UUID, String> savegamePlayersName = new HashMap<>();
|
||||||
|
|
||||||
public static void updateListOfSavegames() {
|
public static void updateListOfSavegames() {
|
||||||
@@ -234,6 +241,7 @@ public class App implements ApplicationListener {
|
|||||||
public static ShaderProgram shaderColLUT;
|
public static ShaderProgram shaderColLUT;
|
||||||
public static ShaderProgram shaderReflect;
|
public static ShaderProgram shaderReflect;
|
||||||
public static ShaderProgram shaderGhastlyWhite;
|
public static ShaderProgram shaderGhastlyWhite;
|
||||||
|
public static Hq2x hq2x;
|
||||||
|
|
||||||
public static Mesh fullscreenQuad;
|
public static Mesh fullscreenQuad;
|
||||||
private static OrthographicCamera camera;
|
private static OrthographicCamera camera;
|
||||||
@@ -261,12 +269,13 @@ public class App implements ApplicationListener {
|
|||||||
Gdx.gl20.glViewport(0, 0, width, height);
|
Gdx.gl20.glViewport(0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final float UPDATE_RATE = 1f / 64f; // apparent framerate will be limited by update rate
|
public static final int TICKS = 64;
|
||||||
|
public static final float UPDATE_RATE = 1f / TICKS; // apparent framerate will be limited by update rate
|
||||||
|
|
||||||
private static float loadTimer = 0f;
|
private static float loadTimer = 0f;
|
||||||
private static final float showupTime = 100f / 1000f;
|
private static final float showupTime = 100f / 1000f;
|
||||||
|
|
||||||
private static FloatFrameBuffer renderFBO;
|
private static Float16FrameBuffer renderFBO;
|
||||||
|
|
||||||
public static HashSet<File> tempFilePool = new HashSet<>();
|
public static HashSet<File> tempFilePool = new HashSet<>();
|
||||||
|
|
||||||
@@ -346,10 +355,13 @@ public class App implements ApplicationListener {
|
|||||||
processorVendor = "Unknown CPU";
|
processorVendor = "Unknown CPU";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processor.startsWith("Apple M") && Objects.equals(systemArch, "aarch64")) {
|
if (processor.startsWith("Apple M") && systemArch.equals("aarch64")) {
|
||||||
isAppleM = true;
|
isAppleM = true;
|
||||||
System.out.println("Apple Proprietary "+processor+" detected; don't expect smooth sailing...");
|
System.out.println("Apple Proprietary "+processor+" detected; don't expect smooth sailing...");
|
||||||
}
|
}
|
||||||
|
if (processor.startsWith("Apple M") && !systemArch.equals("aarch64")) {
|
||||||
|
undesirableConditions = "apple_execution_through_rosetta";
|
||||||
|
}
|
||||||
|
|
||||||
if (!IS_DEVELOPMENT_BUILD) {
|
if (!IS_DEVELOPMENT_BUILD) {
|
||||||
var p = UnsafeHelper.INSTANCE.allocate(64);
|
var p = UnsafeHelper.INSTANCE.allocate(64);
|
||||||
@@ -374,8 +386,8 @@ public class App implements ApplicationListener {
|
|||||||
ShaderProgram.pedantic = false;
|
ShaderProgram.pedantic = false;
|
||||||
|
|
||||||
scr = new TerrarumScreenSize(getConfigInt("screenwidth"), getConfigInt("screenheight"));
|
scr = new TerrarumScreenSize(getConfigInt("screenwidth"), getConfigInt("screenheight"));
|
||||||
int width = (int) Math.round(scr.getWidth() * scr.getMagn());
|
int width = scr.getWindowW();
|
||||||
int height = (int) Math.round(scr.getHeight() * scr.getMagn());
|
int height = scr.getWindowH();
|
||||||
|
|
||||||
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
|
||||||
@@ -383,6 +395,7 @@ public class App implements ApplicationListener {
|
|||||||
appConfig.useVsync(getConfigBoolean("usevsync"));
|
appConfig.useVsync(getConfigBoolean("usevsync"));
|
||||||
appConfig.setResizable(false);
|
appConfig.setResizable(false);
|
||||||
appConfig.setWindowedMode(width, height);
|
appConfig.setWindowedMode(width, height);
|
||||||
|
appConfig.setTransparentFramebuffer(false);
|
||||||
int fpsActive = Math.min(GLOBAL_FRAMERATE_LIMIT, getConfigInt("displayfps"));
|
int fpsActive = Math.min(GLOBAL_FRAMERATE_LIMIT, getConfigInt("displayfps"));
|
||||||
if (fpsActive <= 0) fpsActive = GLOBAL_FRAMERATE_LIMIT;
|
if (fpsActive <= 0) fpsActive = GLOBAL_FRAMERATE_LIMIT;
|
||||||
int fpsBack = Math.min(GLOBAL_FRAMERATE_LIMIT, getConfigInt("displayfpsidle"));
|
int fpsBack = Math.min(GLOBAL_FRAMERATE_LIMIT, getConfigInt("displayfpsidle"));
|
||||||
@@ -430,13 +443,10 @@ public class App implements ApplicationListener {
|
|||||||
|
|
||||||
glInfo.create();
|
glInfo.create();
|
||||||
|
|
||||||
CommonResourcePool.INSTANCE.addToLoadingList("blockmarkings_common", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/blocks/block_markings_common.tga"), 16, 16, 0, 0, 0, 0, false, false, false));
|
|
||||||
CommonResourcePool.INSTANCE.addToLoadingList("blockmarking_actor", () -> new BlockMarkerActor());
|
|
||||||
CommonResourcePool.INSTANCE.addToLoadingList("loading_circle_64", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/gui/loading_circle_64.tga"), 64, 64, 0, 0, 0, 0, false, false, false));
|
|
||||||
CommonResourcePool.INSTANCE.addToLoadingList("inline_loading_spinner", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/gui/inline_loading_spinner.tga"), 20, 20, 0, 0, 0, 0, false, false, false));
|
|
||||||
CommonResourcePool.INSTANCE.addToLoadingList("inventory_category", () -> new TextureRegionPack("./assets/graphics/gui/inventory/category.tga", 20, 20, 0, 0, 0, 0, false, false, false));
|
|
||||||
CommonResourcePool.INSTANCE.addToLoadingList("title_health1", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_take_a_break.tga")));
|
CommonResourcePool.INSTANCE.addToLoadingList("title_health1", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_take_a_break.tga")));
|
||||||
CommonResourcePool.INSTANCE.addToLoadingList("title_health2", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_distance.tga")));
|
CommonResourcePool.INSTANCE.addToLoadingList("title_health2", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_distance.tga")));
|
||||||
|
// make loading list
|
||||||
|
CommonResourcePool.INSTANCE.loadAll();
|
||||||
|
|
||||||
newTempFile("wenquanyi.tga"); // temp file required by the font
|
newTempFile("wenquanyi.tga"); // temp file required by the font
|
||||||
|
|
||||||
@@ -465,12 +475,9 @@ public class App implements ApplicationListener {
|
|||||||
shaderBayerSkyboxFill = loadShaderFromClasspath("shaders/default.vert",
|
shaderBayerSkyboxFill = loadShaderFromClasspath("shaders/default.vert",
|
||||||
"shaders/float_to_disp_dither_static.frag"
|
"shaders/float_to_disp_dither_static.frag"
|
||||||
);
|
);
|
||||||
shaderHicolour = loadShaderFromClasspath("shaders/default.vert", "shaders/hicolour.frag");
|
|
||||||
shaderDebugDiff = loadShaderFromClasspath("shaders/default.vert", "shaders/diff.frag");
|
|
||||||
shaderPassthruRGBA = loadShaderFromClasspath("shaders/gl32spritebatch.vert", "shaders/gl32spritebatch.frag");
|
shaderPassthruRGBA = loadShaderFromClasspath("shaders/gl32spritebatch.vert", "shaders/gl32spritebatch.frag");
|
||||||
shaderColLUT = loadShaderFromClasspath("shaders/default.vert", "shaders/passthrurgb.frag");
|
|
||||||
shaderReflect = loadShaderFromClasspath("shaders/default.vert", "shaders/reflect.frag");
|
shaderReflect = loadShaderFromClasspath("shaders/default.vert", "shaders/reflect.frag");
|
||||||
shaderGhastlyWhite = loadShaderFromClasspath("shaders/default.vert", "shaders/ghastlywhite.frag");
|
hq2x = new Hq2x(2);
|
||||||
|
|
||||||
fullscreenQuad = new Mesh(
|
fullscreenQuad = new Mesh(
|
||||||
true, 4, 6,
|
true, 4, 6,
|
||||||
@@ -478,97 +485,21 @@ public class App implements ApplicationListener {
|
|||||||
VertexAttribute.ColorUnpacked(),
|
VertexAttribute.ColorUnpacked(),
|
||||||
VertexAttribute.TexCoords(0)
|
VertexAttribute.TexCoords(0)
|
||||||
);
|
);
|
||||||
updateFullscreenQuad(scr.getWidth(), scr.getHeight());
|
updateFullscreenQuad(fullscreenQuad, scr.getWidth(), scr.getHeight());
|
||||||
|
|
||||||
|
|
||||||
// set up renderer info variables
|
// set up renderer info variables
|
||||||
renderer = Gdx.graphics.getGLVersion().getRendererString();
|
renderer = Gdx.graphics.getGLVersion().getRendererString();
|
||||||
rendererVendor = Gdx.graphics.getGLVersion().getVendorString();
|
rendererVendor = Gdx.graphics.getGLVersion().getVendorString();
|
||||||
|
|
||||||
|
|
||||||
// make gamepad(s)
|
|
||||||
if (App.getConfigBoolean("usexinput")) {
|
|
||||||
try {
|
|
||||||
gamepad = new XinputControllerAdapter(XInputDevice.getDeviceFor(0));
|
|
||||||
}
|
|
||||||
catch (Throwable e) {
|
|
||||||
gamepad = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// nullify if not actually connected
|
|
||||||
try {
|
|
||||||
if (!((XinputControllerAdapter) gamepad).getC().isConnected()) {
|
|
||||||
gamepad = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (NullPointerException notQuiteWindows) {
|
|
||||||
gamepad = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamepad == null) {
|
|
||||||
try {
|
|
||||||
gamepad = new GdxControllerAdapter(Controllers.getControllers().get(0));
|
|
||||||
}
|
|
||||||
catch (Throwable e) {
|
|
||||||
gamepad = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// tell the game that we have a gamepad
|
|
||||||
environment = RunningEnvironment.PC;
|
|
||||||
|
|
||||||
if (gamepad != null) {
|
|
||||||
String name = gamepad.getName().toLowerCase();
|
|
||||||
for (String allowedName : gamepadWhitelist) {
|
|
||||||
if (name.contains(allowedName)) {
|
|
||||||
environment = RunningEnvironment.CONSOLE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*if (gamepad != null) {
|
|
||||||
environment = RunningEnvironment.CONSOLE;
|
|
||||||
|
|
||||||
// calibrate the sticks
|
|
||||||
printdbg(this, "Calibrating the gamepad...");
|
|
||||||
float[] axesZeroPoints = new float[]{
|
|
||||||
gamepad.getAxisRaw(0),
|
|
||||||
gamepad.getAxisRaw(1),
|
|
||||||
gamepad.getAxisRaw(2),
|
|
||||||
gamepad.getAxisRaw(3)
|
|
||||||
};
|
|
||||||
setConfig("control_gamepad_axiszeropoints", axesZeroPoints);
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
printdbg(this, "Axis " + i + ": " + axesZeroPoints[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
environment = RunningEnvironment.PC;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
fontGame = new TerrarumSansBitmap(FONT_DIR, false, false, false,
|
fontGame = new TerrarumSansBitmap(FONT_DIR, false, false, false,
|
||||||
false,
|
false,
|
||||||
256, false, 0.5f, false
|
256, false, 0.5f, false
|
||||||
);
|
);
|
||||||
fontUITitle = new TerrarumSansBitmap(FONT_DIR, false, false, false,
|
|
||||||
false,
|
|
||||||
64, false, 0.5f, false
|
|
||||||
);
|
|
||||||
fontUITitle.setInterchar(2);
|
|
||||||
fontGameFBO = new TerrarumSansBitmap(FONT_DIR, false, true, false,
|
|
||||||
false,
|
|
||||||
64, false, 203f/255f, false
|
|
||||||
);
|
|
||||||
Lang.invoke();
|
|
||||||
|
|
||||||
// make loading list
|
|
||||||
CommonResourcePool.INSTANCE.loadAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private FrameBuffer postProcessorOutFBO;
|
private FrameBuffer postProcessorOutFBO;
|
||||||
|
private FrameBuffer postProcessorOutFBO2;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render() {
|
public void render() {
|
||||||
@@ -627,30 +558,44 @@ public class App implements ApplicationListener {
|
|||||||
FrameBufferManager.end();
|
FrameBufferManager.end();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// process screenshot request
|
// process screenshot request
|
||||||
if (screenshotRequested) {
|
processScreenshotRequest(postProcessorOutFBO);
|
||||||
FrameBufferManager.begin(postProcessorOutFBO);
|
|
||||||
screenshotRequested = false;
|
|
||||||
try {
|
|
||||||
Pixmap p = Pixmap.createFromFrameBuffer(0, 0, scr.getWidth(), scr.getHeight());
|
if (getConfigString("screenmagnifyingfilter").equals("hq2x") ) {
|
||||||
PixmapIO.writePNG(Gdx.files.absolute(defaultDir+"/Screenshot-"+String.valueOf(System.currentTimeMillis())+".png"), p, 9, true);
|
FrameBufferManager.begin(postProcessorOutFBO2);
|
||||||
p.dispose();
|
shaderPassthruRGBA.bind();
|
||||||
Terrarum.INSTANCE.getIngame().sendNotification("Screenshot taken");
|
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
|
||||||
}
|
shaderPassthruRGBA.setUniformi("u_texture", 0);
|
||||||
catch (Throwable e) {
|
hq2x.renderToScreen(postProcessorOutFBO.getColorBufferTexture());
|
||||||
e.printStackTrace();
|
|
||||||
Terrarum.INSTANCE.getIngame().sendNotification("Failed to take screenshot: "+e.getMessage());
|
|
||||||
}
|
|
||||||
FrameBufferManager.end();
|
FrameBufferManager.end();
|
||||||
|
|
||||||
|
shaderPassthruRGBA.bind();
|
||||||
|
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
|
||||||
|
shaderPassthruRGBA.setUniformi("u_texture", 0);
|
||||||
|
postProcessorOutFBO2.getColorBufferTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
|
||||||
|
postProcessorOutFBO2.getColorBufferTexture().bind(0);
|
||||||
|
fullscreenQuad.render(shaderPassthruRGBA, GL20.GL_TRIANGLES);
|
||||||
|
}
|
||||||
|
else if (getConfigDouble("screenmagnifying") < 1.01 || getConfigString("screenmagnifyingfilter").equals("none")) {
|
||||||
|
shaderPassthruRGBA.bind();
|
||||||
|
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
|
||||||
|
shaderPassthruRGBA.setUniformi("u_texture", 0);
|
||||||
|
postProcessorOutFBO.getColorBufferTexture().setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
|
||||||
|
postProcessorOutFBO.getColorBufferTexture().bind(0);
|
||||||
|
fullscreenQuad.render(shaderPassthruRGBA, GL20.GL_TRIANGLES);
|
||||||
|
}
|
||||||
|
else if (getConfigString("screenmagnifyingfilter").equals("bilinear")) {
|
||||||
|
shaderPassthruRGBA.bind();
|
||||||
|
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
|
||||||
|
shaderPassthruRGBA.setUniformi("u_texture", 0);
|
||||||
|
postProcessorOutFBO.getColorBufferTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
|
||||||
|
postProcessorOutFBO.getColorBufferTexture().bind(0);
|
||||||
|
fullscreenQuad.render(shaderPassthruRGBA, GL20.GL_TRIANGLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shaderPassthruRGBA.bind();
|
|
||||||
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
|
|
||||||
shaderPassthruRGBA.setUniformi("u_texture", 0);
|
|
||||||
postProcessorOutFBO.getColorBufferTexture().bind(0);
|
|
||||||
fullscreenQuad.render(shaderPassthruRGBA, GL20.GL_TRIANGLES);
|
|
||||||
|
|
||||||
// process resize request
|
// process resize request
|
||||||
if (resizeRequested) {
|
if (resizeRequested) {
|
||||||
@@ -665,6 +610,26 @@ public class App implements ApplicationListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void processScreenshotRequest(FrameBuffer fb) {
|
||||||
|
if (screenshotRequested) {
|
||||||
|
String msg = "Screenshot taken";
|
||||||
|
FrameBufferManager.begin(fb);
|
||||||
|
try {
|
||||||
|
Pixmap p = Pixmap.createFromFrameBuffer(0, 0, fb.getWidth(), fb.getHeight());
|
||||||
|
PixmapIO.writePNG(Gdx.files.absolute(defaultDir+"/Screenshot-"+String.valueOf(System.currentTimeMillis())+".png"), p, 9, true);
|
||||||
|
p.dispose();
|
||||||
|
}
|
||||||
|
catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
msg = ("Failed to take screenshot: "+e.getMessage());
|
||||||
|
}
|
||||||
|
FrameBufferManager.end();
|
||||||
|
screenshotRequested = false;
|
||||||
|
|
||||||
|
Terrarum.INSTANCE.getIngame().sendNotification(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Texture getCurrentDitherTex() {
|
public static Texture getCurrentDitherTex() {
|
||||||
int hash = 31 + GLOBAL_RENDER_TIMER + 0x165667B1 + GLOBAL_RENDER_TIMER * 0xC2B2AE3D;
|
int hash = 31 + GLOBAL_RENDER_TIMER + 0x165667B1 + GLOBAL_RENDER_TIMER * 0xC2B2AE3D;
|
||||||
hash = Integer.rotateLeft(hash, 17) * 0x27D4EB2F;
|
hash = Integer.rotateLeft(hash, 17) * 0x27D4EB2F;
|
||||||
@@ -767,12 +732,9 @@ public class App implements ApplicationListener {
|
|||||||
@Override
|
@Override
|
||||||
public void resize(int w0, int h0) {
|
public void resize(int w0, int h0) {
|
||||||
|
|
||||||
int w = (w0%2==0)?w0:w0+1;
|
|
||||||
int h = (h0%2==0)?h0:h0+1;
|
|
||||||
|
|
||||||
float magn = (float) getConfigDouble("screenmagnifying");
|
float magn = (float) getConfigDouble("screenmagnifying");
|
||||||
int width = Math.round(w / magn);
|
int width = (int) Math.floor(w0 / magn);
|
||||||
int height = Math.round(h / magn);
|
int height = (int) Math.floor(h0 / magn);
|
||||||
|
|
||||||
|
|
||||||
printdbg(this, "Resize called: "+width+","+height);
|
printdbg(this, "Resize called: "+width+","+height);
|
||||||
@@ -782,22 +744,27 @@ public class App implements ApplicationListener {
|
|||||||
|
|
||||||
//initViewPort(width, height);
|
//initViewPort(width, height);
|
||||||
|
|
||||||
scr.setDimension(width, height, magn, w, h);
|
scr.setDimension(width, height, magn);
|
||||||
|
|
||||||
if (currentScreen != null) currentScreen.resize(scr.getWidth(), scr.getHeight());
|
if (currentScreen != null) currentScreen.resize(scr.getWidth(), scr.getHeight());
|
||||||
TerrarumPostProcessor.INSTANCE.resize(scr.getWidth(), scr.getHeight());
|
TerrarumPostProcessor.INSTANCE.resize(scr.getWidth(), scr.getHeight());
|
||||||
updateFullscreenQuad(scr.getWidth(), scr.getHeight());
|
updateFullscreenQuad(fullscreenQuad, scr.getWidth(), scr.getHeight());
|
||||||
|
|
||||||
|
|
||||||
if (renderFBO == null ||
|
if (renderFBO == null ||
|
||||||
(renderFBO.getWidth() != scr.getWidth() ||
|
(renderFBO.getWidth() != scr.getWidth() ||
|
||||||
renderFBO.getHeight() != scr.getHeight())
|
renderFBO.getHeight() != scr.getHeight())
|
||||||
) {
|
) {
|
||||||
renderFBO = new FloatFrameBuffer(
|
renderFBO = new Float16FrameBuffer(
|
||||||
scr.getWidth(),
|
scr.getWidth(),
|
||||||
scr.getHeight(),
|
scr.getHeight(),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
postProcessorOutFBO2 = new Float16FrameBuffer(
|
||||||
|
scr.getWidth() * 2,
|
||||||
|
scr.getHeight() * 2,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
if (IS_DEVELOPMENT_BUILD) {
|
if (IS_DEVELOPMENT_BUILD) {
|
||||||
@@ -850,12 +817,13 @@ public class App implements ApplicationListener {
|
|||||||
shaderColLUT.dispose();
|
shaderColLUT.dispose();
|
||||||
shaderReflect.dispose();
|
shaderReflect.dispose();
|
||||||
shaderGhastlyWhite.dispose();
|
shaderGhastlyWhite.dispose();
|
||||||
|
hq2x.dispose();
|
||||||
|
|
||||||
CommonResourcePool.INSTANCE.dispose();
|
CommonResourcePool.INSTANCE.dispose();
|
||||||
fullscreenQuad.dispose();
|
fullscreenQuad.dispose();
|
||||||
logoBatch.dispose();
|
logoBatch.dispose();
|
||||||
batch.dispose();
|
batch.dispose();
|
||||||
shapeRender.dispose();
|
// shapeRender.dispose();
|
||||||
|
|
||||||
fontGame.dispose();
|
fontGame.dispose();
|
||||||
fontGameFBO.dispose();
|
fontGameFBO.dispose();
|
||||||
@@ -948,6 +916,93 @@ public class App implements ApplicationListener {
|
|||||||
* Init stuffs which needs GL context
|
* Init stuffs which needs GL context
|
||||||
*/
|
*/
|
||||||
private void postInit() {
|
private void postInit() {
|
||||||
|
CommonResourcePool.INSTANCE.addToLoadingList("blockmarkings_common", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/blocks/block_markings_common.tga"), 16, 16, 0, 0, 0, 0, false, false, false));
|
||||||
|
CommonResourcePool.INSTANCE.addToLoadingList("blockmarking_actor", () -> new BlockMarkerActor());
|
||||||
|
CommonResourcePool.INSTANCE.addToLoadingList("loading_circle_64", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/gui/loading_circle_64.tga"), 64, 64, 0, 0, 0, 0, false, false, false));
|
||||||
|
CommonResourcePool.INSTANCE.addToLoadingList("inline_loading_spinner", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/gui/inline_loading_spinner.tga"), 20, 20, 0, 0, 0, 0, false, false, false));
|
||||||
|
CommonResourcePool.INSTANCE.addToLoadingList("inventory_category", () -> new TextureRegionPack("./assets/graphics/gui/inventory/category.tga", 20, 20, 0, 0, 0, 0, false, false, false));
|
||||||
|
CommonResourcePool.INSTANCE.loadAll();
|
||||||
|
|
||||||
|
shaderHicolour = loadShaderFromClasspath("shaders/default.vert", "shaders/hicolour.frag");
|
||||||
|
shaderDebugDiff = loadShaderFromClasspath("shaders/default.vert", "shaders/diff.frag");
|
||||||
|
shaderColLUT = loadShaderFromClasspath("shaders/default.vert", "shaders/rgbonly.frag");
|
||||||
|
shaderGhastlyWhite = loadShaderFromClasspath("shaders/default.vert", "shaders/ghastlywhite.frag");
|
||||||
|
|
||||||
|
// make gamepad(s)
|
||||||
|
if (App.getConfigBoolean("usexinput")) {
|
||||||
|
try {
|
||||||
|
gamepad = new XinputControllerAdapter(XInputDevice.getDeviceFor(0));
|
||||||
|
}
|
||||||
|
catch (Throwable e) {
|
||||||
|
gamepad = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nullify if not actually connected
|
||||||
|
try {
|
||||||
|
if (!((XinputControllerAdapter) gamepad).getC().isConnected()) {
|
||||||
|
gamepad = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NullPointerException notQuiteWindows) {
|
||||||
|
gamepad = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gamepad == null) {
|
||||||
|
try {
|
||||||
|
gamepad = new GdxControllerAdapter(Controllers.getControllers().get(0));
|
||||||
|
}
|
||||||
|
catch (Throwable e) {
|
||||||
|
gamepad = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// tell the game that we have a gamepad
|
||||||
|
environment = RunningEnvironment.PC;
|
||||||
|
|
||||||
|
if (gamepad != null) {
|
||||||
|
String name = gamepad.getName().toLowerCase();
|
||||||
|
for (String allowedName : gamepadWhitelist) {
|
||||||
|
if (name.contains(allowedName)) {
|
||||||
|
environment = RunningEnvironment.CONSOLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*if (gamepad != null) {
|
||||||
|
environment = RunningEnvironment.CONSOLE;
|
||||||
|
|
||||||
|
// calibrate the sticks
|
||||||
|
printdbg(this, "Calibrating the gamepad...");
|
||||||
|
float[] axesZeroPoints = new float[]{
|
||||||
|
gamepad.getAxisRaw(0),
|
||||||
|
gamepad.getAxisRaw(1),
|
||||||
|
gamepad.getAxisRaw(2),
|
||||||
|
gamepad.getAxisRaw(3)
|
||||||
|
};
|
||||||
|
setConfig("control_gamepad_axiszeropoints", axesZeroPoints);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
printdbg(this, "Axis " + i + ": " + axesZeroPoints[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
environment = RunningEnvironment.PC;
|
||||||
|
}*/
|
||||||
|
fontUITitle = new TerrarumSansBitmap(FONT_DIR, false, false, false,
|
||||||
|
false,
|
||||||
|
64, false, 0.5f, false
|
||||||
|
);
|
||||||
|
fontUITitle.setInterchar(1);
|
||||||
|
fontGameFBO = new TerrarumSansBitmap(FONT_DIR, false, true, false,
|
||||||
|
false,
|
||||||
|
64, false, 203f/255f, false
|
||||||
|
);
|
||||||
|
Lang.invoke();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ModMgr.INSTANCE.invoke(); // invoke Module Manager
|
ModMgr.INSTANCE.invoke(); // invoke Module Manager
|
||||||
|
|
||||||
|
|
||||||
@@ -1026,14 +1081,14 @@ public class App implements ApplicationListener {
|
|||||||
logoBatch.setProjectionMatrix(camera.combined);
|
logoBatch.setProjectionMatrix(camera.combined);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFullscreenQuad(int WIDTH, int HEIGHT) { // NOT y-flipped quads!
|
private void updateFullscreenQuad(Mesh mesh, int WIDTH, int HEIGHT) { // NOT y-flipped quads!
|
||||||
fullscreenQuad.setVertices(new float[]{
|
mesh.setVertices(new float[]{
|
||||||
0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 1f,
|
0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 1f,
|
||||||
WIDTH, 0f, 0f, 1f, 1f, 1f, 1f, 1f, 1f,
|
WIDTH, 0f, 0f, 1f, 1f, 1f, 1f, 1f, 1f,
|
||||||
WIDTH, HEIGHT, 0f, 1f, 1f, 1f, 1f, 1f, 0f,
|
WIDTH, HEIGHT, 0f, 1f, 1f, 1f, 1f, 1f, 0f,
|
||||||
0f, HEIGHT, 0f, 1f, 1f, 1f, 1f, 0f, 0f
|
0f, HEIGHT, 0f, 1f, 1f, 1f, 1f, 0f, 0f
|
||||||
});
|
});
|
||||||
fullscreenQuad.setIndices(new short[]{0, 1, 2, 2, 3, 0});
|
mesh.setIndices(new short[]{0, 1, 2, 2, 3, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setGamepadButtonLabels() {
|
public static void setGamepadButtonLabels() {
|
||||||
@@ -1133,6 +1188,11 @@ public class App implements ApplicationListener {
|
|||||||
|
|
||||||
public static RunningEnvironment environment;
|
public static RunningEnvironment environment;
|
||||||
|
|
||||||
|
/** defaultDir + "/Recycled/Players" */
|
||||||
|
public static String recycledPlayersDir;
|
||||||
|
/** defaultDir + "/Recycled/Worlds" */
|
||||||
|
public static String recycledWorldsDir;
|
||||||
|
|
||||||
private static void getDefaultDirectory() {
|
private static void getDefaultDirectory() {
|
||||||
String OS = OSName.toUpperCase();
|
String OS = OSName.toUpperCase();
|
||||||
if (OS.contains("WIN")) {
|
if (OS.contains("WIN")) {
|
||||||
@@ -1162,6 +1222,8 @@ public class App implements ApplicationListener {
|
|||||||
worldsDir = defaultDir + "/Worlds";
|
worldsDir = defaultDir + "/Worlds";
|
||||||
configDir = defaultDir + "/config.json";
|
configDir = defaultDir + "/config.json";
|
||||||
loadOrderDir = defaultDir + "/LoadOrder.txt";
|
loadOrderDir = defaultDir + "/LoadOrder.txt";
|
||||||
|
recycledPlayersDir = defaultDir + "/Recycled/Players";
|
||||||
|
recycledWorldsDir = defaultDir + "/Recycled/Worlds";
|
||||||
|
|
||||||
System.out.println(String.format("os.name = %s (with identifier %s)", OSName, operationSystem));
|
System.out.println(String.format("os.name = %s (with identifier %s)", OSName, operationSystem));
|
||||||
System.out.println(String.format("os.version = %s", OSVersion));
|
System.out.println(String.format("os.version = %s", OSVersion));
|
||||||
@@ -1171,10 +1233,12 @@ public class App implements ApplicationListener {
|
|||||||
|
|
||||||
private static void createDirs() {
|
private static void createDirs() {
|
||||||
File[] dirs = {
|
File[] dirs = {
|
||||||
new File(saveDir),
|
// new File(saveDir),
|
||||||
new File(saveSharedDir),
|
new File(saveSharedDir),
|
||||||
new File(playersDir),
|
new File(playersDir),
|
||||||
new File(worldsDir)
|
new File(worldsDir),
|
||||||
|
new File(recycledPlayersDir),
|
||||||
|
new File(recycledWorldsDir),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (File it : dirs) {
|
for (File it : dirs) {
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ object CommonResourcePool {
|
|||||||
addToLoadingList("itemplaceholder_48") {
|
addToLoadingList("itemplaceholder_48") {
|
||||||
TextureRegion(Texture("assets/item_kari_48.tga")).also { it.flip(false, false) }
|
TextureRegion(Texture("assets/item_kari_48.tga")).also { it.flip(false, false) }
|
||||||
}
|
}
|
||||||
addToLoadingList("test_texture") {
|
/*addToLoadingList("test_texture") {
|
||||||
TextureRegion(Texture("assets/test_texture.tga")).also { it.flip(false, false) }
|
TextureRegion(Texture("assets/test_texture.tga")).also { it.flip(false, false) }
|
||||||
}
|
}*/
|
||||||
loadAll()
|
loadAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum
|
package net.torvald.terrarum
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
import net.torvald.unicode.BULLET
|
import net.torvald.unicode.BULLET
|
||||||
import net.torvald.unicode.ENDASH
|
import net.torvald.unicode.ENDASH
|
||||||
|
|
||||||
@@ -223,6 +224,22 @@ Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
|||||||
""").split('\n')
|
""").split('\n')
|
||||||
|
|
||||||
|
|
||||||
|
private val javaVersion = System.getProperty("java.version")
|
||||||
|
private val osName = App.OSName
|
||||||
|
private val osVersion = App.OSVersion
|
||||||
|
private val sysArch = App.systemArch
|
||||||
|
private val processor = App.processor
|
||||||
|
private val processorVendor = App.processorVendor
|
||||||
|
private val glinfo = Gdx.graphics.glVersion.debugVersionString
|
||||||
|
|
||||||
|
val systeminfo: List<String>; get() = """
|
||||||
|
JRE Version: $javaVersion
|
||||||
|
Operation System: $osName $osVersion
|
||||||
|
Architecture: $sysArch
|
||||||
|
Processor: $processor ($processorVendor)
|
||||||
|
GL Info: $glinfo
|
||||||
|
""".split('\n')
|
||||||
|
|
||||||
|
|
||||||
val gpl3: List<String>; get() = """ GNU GENERAL PUBLIC LICENSE
|
val gpl3: List<String>; get() = """ GNU GENERAL PUBLIC LICENSE
|
||||||
Version 3, 29 June 2007
|
Version 3, 29 June 2007
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import com.badlogic.gdx.Input
|
|||||||
object DefaultConfig {
|
object DefaultConfig {
|
||||||
|
|
||||||
val hashMap = hashMapOf<String, Any>(
|
val hashMap = hashMapOf<String, Any>(
|
||||||
|
"jvm_xmx" to 4,
|
||||||
|
"jvm_extra_cmd" to "",
|
||||||
|
|
||||||
"displayfps" to 0, // 0: no limit, non-zero: limit
|
"displayfps" to 0, // 0: no limit, non-zero: limit
|
||||||
"displayfpsidle" to 0, // 0: no limit, non-zero: limit
|
"displayfpsidle" to 0, // 0: no limit, non-zero: limit
|
||||||
"displaycolourdepth" to 8,
|
"displaycolourdepth" to 8,
|
||||||
@@ -19,9 +22,9 @@ object DefaultConfig {
|
|||||||
"atlastexsize" to 2048,
|
"atlastexsize" to 2048,
|
||||||
|
|
||||||
"language" to App.getSysLang(),
|
"language" to App.getSysLang(),
|
||||||
"notificationshowuptime" to 4096, // 4s
|
"notificationshowuptime" to 4000, // 4s
|
||||||
"selecteditemnameshowuptime" to 4096, // 4s
|
"selecteditemnameshowuptime" to 4000, // 4s
|
||||||
"autosaveinterval" to 262144, // 4m22s
|
"autosaveinterval" to 300000, // 5m
|
||||||
"multithread" to true,
|
"multithread" to true,
|
||||||
|
|
||||||
"showhealthmessageonstartup" to true,
|
"showhealthmessageonstartup" to true,
|
||||||
@@ -109,6 +112,7 @@ object DefaultConfig {
|
|||||||
"inputmethod" to "none",
|
"inputmethod" to "none",
|
||||||
|
|
||||||
"screenmagnifying" to 1.0,
|
"screenmagnifying" to 1.0,
|
||||||
|
"screenmagnifyingfilter" to "none", // "none", "bilinear", "hq2x"
|
||||||
|
|
||||||
"fx_newlight" to false,
|
"fx_newlight" to false,
|
||||||
|
|
||||||
@@ -116,6 +120,12 @@ object DefaultConfig {
|
|||||||
"debug_deltat_benchmark_sample_sizes" to 2048,
|
"debug_deltat_benchmark_sample_sizes" to 2048,
|
||||||
|
|
||||||
|
|
||||||
|
"mastervolume" to 1.0,
|
||||||
|
"musicvolume" to 1.0,
|
||||||
|
"bgmvolume" to 1.0,
|
||||||
|
"sfxvolume" to 1.0,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// settings regarding debugger
|
// settings regarding debugger
|
||||||
/*"buildingmakerfavs" to arrayOf(
|
/*"buildingmakerfavs" to arrayOf(
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ object GlslTilingTest : ApplicationAdapter() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILING_SIZE).ceil() + 1f
|
val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILING_SIZE).ceilToFloat() + 1f
|
||||||
val tilesInVertical = (Gdx.graphics.height.toFloat() / TILING_SIZE).ceil() + 1f
|
val tilesInVertical = (Gdx.graphics.height.toFloat() / TILING_SIZE).ceilToFloat() + 1f
|
||||||
|
|
||||||
tilesQuad = Mesh(
|
tilesQuad = Mesh(
|
||||||
true, 4, 6,
|
true, 4, 6,
|
||||||
@@ -129,8 +129,8 @@ object GlslTilingTest : ApplicationAdapter() {
|
|||||||
Gdx.gl.glEnable(GL20.GL_BLEND)
|
Gdx.gl.glEnable(GL20.GL_BLEND)
|
||||||
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA)
|
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
|
||||||
val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILING_SIZE).ceil() + 1f
|
val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILING_SIZE).ceilToFloat() + 1f
|
||||||
val tilesInVertical = (Gdx.graphics.height.toFloat() / TILING_SIZE).ceil() + 1f
|
val tilesInVertical = (Gdx.graphics.height.toFloat() / TILING_SIZE).ceilToFloat() + 1f
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
214
src/net/torvald/terrarum/Hq2x.kt
Normal file
214
src/net/torvald/terrarum/Hq2x.kt
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
package net.torvald.terrarum
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.files.FileHandle
|
||||||
|
import com.badlogic.gdx.graphics.*
|
||||||
|
import com.badlogic.gdx.graphics.VertexAttributes.Usage
|
||||||
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
|
import com.badlogic.gdx.math.Matrix4
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [HQnX](https://en.wikipedia.org/wiki/Pixel-art_scaling_algorithms#hqnx_family)
|
||||||
|
* upscale algorithm GLSL implementation based on
|
||||||
|
* [CrossVR](https://github.com/CrossVR/hqx-shader/tree/master/glsl) project.
|
||||||
|
*/
|
||||||
|
class Hq2x : Disposable {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TEXTURE_HANDLE0 = 0
|
||||||
|
private const val TEXTURE_HANDLE1 = 1
|
||||||
|
|
||||||
|
private const val U_TEXTURE = "u_texture"
|
||||||
|
private const val U_LUT = "u_lut"
|
||||||
|
private const val U_TEXTURE_SIZE = "u_textureSize"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val mesh = ViewportQuadMesh(
|
||||||
|
VertexAttribute(Usage.Position, 2, "a_position"),
|
||||||
|
VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoord0"))
|
||||||
|
|
||||||
|
private val program: ShaderProgram
|
||||||
|
private val lutTexture: Texture
|
||||||
|
private val scaleFactor: Int
|
||||||
|
|
||||||
|
private var dstBuffer: FrameBuffer? = null
|
||||||
|
private var dstWidth = 0
|
||||||
|
private var dstHeight = 0
|
||||||
|
|
||||||
|
/** @param scaleFactor should be 2, 3 or 4 value. */
|
||||||
|
constructor(scaleFactor: Int) {
|
||||||
|
if (scaleFactor !in 2..4) {
|
||||||
|
throw GdxRuntimeException("Scale factor should be 2, 3 or 4.")
|
||||||
|
}
|
||||||
|
|
||||||
|
program = compileShader(
|
||||||
|
Gdx.files.classpath("shaders/hq2x.vert"),
|
||||||
|
Gdx.files.classpath("shaders/hq2x.frag"),
|
||||||
|
"")
|
||||||
|
|
||||||
|
lutTexture = Texture(Gdx.files.classpath("shaders/hq${scaleFactor}x.png"))
|
||||||
|
|
||||||
|
this.scaleFactor = scaleFactor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
mesh.dispose()
|
||||||
|
program.dispose()
|
||||||
|
lutTexture.dispose()
|
||||||
|
dstBuffer?.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun rebind() {
|
||||||
|
program.bind()
|
||||||
|
program.setUniformi(U_TEXTURE, TEXTURE_HANDLE0)
|
||||||
|
program.setUniformi(U_LUT, TEXTURE_HANDLE1)
|
||||||
|
program.setUniformf(U_TEXTURE_SIZE,
|
||||||
|
dstWidth / scaleFactor.toFloat(),
|
||||||
|
dstHeight / scaleFactor.toFloat())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun renderToScreen(src: Texture) {
|
||||||
|
validate(src)
|
||||||
|
|
||||||
|
lutTexture.bind(TEXTURE_HANDLE1)
|
||||||
|
src.bind(TEXTURE_HANDLE0)
|
||||||
|
src.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
||||||
|
|
||||||
|
program.bind()
|
||||||
|
mesh.render(program)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun renderToBuffer(src: Texture): Texture {
|
||||||
|
validate(src)
|
||||||
|
validateDstBuffer()
|
||||||
|
|
||||||
|
lutTexture.bind(TEXTURE_HANDLE1)
|
||||||
|
src.bind(TEXTURE_HANDLE0)
|
||||||
|
src.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
||||||
|
|
||||||
|
dstBuffer!!.begin()
|
||||||
|
program.bind()
|
||||||
|
mesh.render(program)
|
||||||
|
dstBuffer!!.end()
|
||||||
|
|
||||||
|
return dstBuffer!!.colorBufferTexture
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validate(src: Texture) {
|
||||||
|
val targetWidth = src.width * scaleFactor
|
||||||
|
val targetHeight = src.height * scaleFactor
|
||||||
|
|
||||||
|
// println("[Hq2x] $targetWidth x $targetHeight")
|
||||||
|
|
||||||
|
if (dstWidth != targetWidth || dstHeight != targetHeight) {
|
||||||
|
dstWidth = targetWidth
|
||||||
|
dstHeight = targetHeight
|
||||||
|
rebind()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validateDstBuffer() {
|
||||||
|
if (dstBuffer == null || dstBuffer!!.width != dstWidth || dstBuffer!!.height != dstHeight) {
|
||||||
|
dstBuffer?.dispose()
|
||||||
|
dstBuffer = FrameBuffer(Pixmap.Format.RGB888, dstWidth, dstHeight, false)
|
||||||
|
dstBuffer!!.colorBufferTexture.setFilter(
|
||||||
|
Texture.TextureFilter.Nearest,
|
||||||
|
Texture.TextureFilter.Nearest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates a fullscreen quad mesh. Geometry is aligned to the viewport corners.
|
||||||
|
*
|
||||||
|
* @author bmanuel
|
||||||
|
* @author metaphore
|
||||||
|
*/
|
||||||
|
private class ViewportQuadMesh : Disposable {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val VERT_SIZE = 16
|
||||||
|
private const val X1 = 0
|
||||||
|
private const val Y1 = 1
|
||||||
|
private const val U1 = 2
|
||||||
|
private const val V1 = 3
|
||||||
|
private const val X2 = 4
|
||||||
|
private const val Y2 = 5
|
||||||
|
private const val U2 = 6
|
||||||
|
private const val V2 = 7
|
||||||
|
private const val X3 = 8
|
||||||
|
private const val Y3 = 9
|
||||||
|
private const val U3 = 10
|
||||||
|
private const val V3 = 11
|
||||||
|
private const val X4 = 12
|
||||||
|
private const val Y4 = 13
|
||||||
|
private const val U4 = 14
|
||||||
|
private const val V4 = 15
|
||||||
|
|
||||||
|
private val verts: FloatArray
|
||||||
|
|
||||||
|
init {
|
||||||
|
verts = FloatArray(VERT_SIZE)
|
||||||
|
|
||||||
|
// Vertex coords
|
||||||
|
verts[X1] = -1f
|
||||||
|
verts[Y1] = -1f
|
||||||
|
verts[X2] = 1f
|
||||||
|
verts[Y2] = -1f
|
||||||
|
verts[X3] = 1f
|
||||||
|
verts[Y3] = 1f
|
||||||
|
verts[X4] = -1f
|
||||||
|
verts[Y4] = 1f
|
||||||
|
|
||||||
|
// Tex coords
|
||||||
|
verts[U1] = 0f
|
||||||
|
verts[V1] = 0f
|
||||||
|
verts[U2] = 1f
|
||||||
|
verts[V2] = 0f
|
||||||
|
verts[U3] = 1f
|
||||||
|
verts[V3] = 1f
|
||||||
|
verts[U4] = 0f
|
||||||
|
verts[V4] = 1f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val mesh: Mesh
|
||||||
|
|
||||||
|
constructor(vararg attributes: VertexAttribute) {
|
||||||
|
mesh = Mesh(true, 4, 0, *attributes)
|
||||||
|
mesh.setVertices(verts)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
mesh.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Renders the quad with the specified shader program. */
|
||||||
|
fun render(program: ShaderProgram) {
|
||||||
|
mesh.render(program, GL20.GL_TRIANGLE_FAN, 0, 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun compileShader(vertexFile: FileHandle, fragmentFile: FileHandle, defines: String): ShaderProgram {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
sb.append("Compiling \"").append(vertexFile.name()).append('/').append(fragmentFile.name()).append('\"')
|
||||||
|
if (defines.isNotEmpty()) {
|
||||||
|
sb.append(" w/ (").append(defines.replace("\n", ", ")).append(")")
|
||||||
|
}
|
||||||
|
sb.append("...")
|
||||||
|
Gdx.app.log("HqnxEffect", sb.toString())
|
||||||
|
|
||||||
|
val srcVert = vertexFile.readString()
|
||||||
|
val srcFrag = fragmentFile.readString()
|
||||||
|
val shader = ShaderProgram(
|
||||||
|
"$defines\n$srcVert".trimIndent(),
|
||||||
|
"$defines\n$srcFrag".trimIndent())
|
||||||
|
|
||||||
|
if (!shader.isCompiled) {
|
||||||
|
throw GdxRuntimeException("Shader compilation error: ${vertexFile.name()}/${fragmentFile.name()}\n${shader.log}")
|
||||||
|
}
|
||||||
|
return shader
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
|||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.gameactors.ActorID
|
import net.torvald.terrarum.gameactors.ActorID
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
|
import net.torvald.terrarum.gameactors.ActorWithBody.Companion.PHYS_EPSILON_DIST
|
||||||
import net.torvald.terrarum.gameactors.BlockMarkerActor
|
import net.torvald.terrarum.gameactors.BlockMarkerActor
|
||||||
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
@@ -26,9 +27,12 @@ import java.io.File
|
|||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.locks.Lock
|
import java.util.concurrent.locks.Lock
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Although the game (as product) can have infinitely many stages/planets/etc., those stages must be manually managed by YOU;
|
* Although the game (as product) can have infinitely many stages/planets/etc., those stages must be manually managed by YOU;
|
||||||
@@ -49,8 +53,8 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
|||||||
|
|
||||||
override fun getMax(axis: Int, t: ActorWithBody): Double =
|
override fun getMax(axis: Int, t: ActorWithBody): Double =
|
||||||
when (axis) {
|
when (axis) {
|
||||||
0 -> t.hitbox.endX
|
0 -> t.hitbox.endX - PHYS_EPSILON_DIST
|
||||||
1 -> t.hitbox.endY
|
1 -> t.hitbox.endY - PHYS_EPSILON_DIST
|
||||||
else -> throw IllegalArgumentException("nonexistent axis $axis for ${dimensions}-dimensional object")
|
else -> throw IllegalArgumentException("nonexistent axis $axis for ${dimensions}-dimensional object")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,7 +65,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
|||||||
lateinit var playerDisk: VirtualDisk; internal set
|
lateinit var playerDisk: VirtualDisk; internal set
|
||||||
lateinit var worldSavefileName: String; internal set
|
lateinit var worldSavefileName: String; internal set
|
||||||
lateinit var playerSavefileName: String; internal set
|
lateinit var playerSavefileName: String; internal set
|
||||||
var savegameNickname: String = "SplinesReticulated"; internal set
|
var worldName: String = "SplinesReticulated"; internal set // worldName is stored as a name of the disk
|
||||||
|
|
||||||
var screenZoom = 1.0f
|
var screenZoom = 1.0f
|
||||||
val ZOOM_MAXIMUM = 4.0f
|
val ZOOM_MAXIMUM = 4.0f
|
||||||
@@ -201,13 +205,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
|||||||
actorContainerInactive.forEach { it.dispose() }
|
actorContainerInactive.forEach { it.dispose() }
|
||||||
world.dispose()
|
world.dispose()
|
||||||
|
|
||||||
disposables.forEach(Consumer {
|
disposables.forEach(Consumer { it.tryDispose() })
|
||||||
try { it.dispose() }
|
|
||||||
catch (_: NullPointerException) { }
|
|
||||||
catch (_: IllegalArgumentException) { }
|
|
||||||
catch (_: GdxRuntimeException) { }
|
|
||||||
catch (_: ConcurrentModificationException) { }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
@@ -406,6 +404,14 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
|||||||
return uiTooltip.message
|
return uiTooltip.message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun requestForceSave(callback: () -> Unit) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun saveTheGame(onSuccessful: () -> Unit, onError: (Throwable) -> Unit) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies most recent `save` to `save.1`, leaving `save` for overwriting, previous `save.1` will be copied to `save.2`
|
* Copies most recent `save` to `save.1`, leaving `save` for overwriting, previous `save.1` will be copied to `save.2`
|
||||||
*/
|
*/
|
||||||
@@ -422,25 +428,55 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
|||||||
// do not overwrite clean .2 with dirty .1
|
// do not overwrite clean .2 with dirty .1
|
||||||
val flags3 = FileInputStream(file3).let { it.skip(49L); val r = it.read(); it.close(); r }
|
val flags3 = FileInputStream(file3).let { it.skip(49L); val r = it.read(); it.close(); r }
|
||||||
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
|
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
|
||||||
if (!(flags3 == 0 && flags2 != 0) || !file3.exists()) file2.copyTo(file3, true)
|
if (!(flags3 == 0 && flags2 != 0) || !file3.exists()) Files.move(file2.toPath(), file3.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||||
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
|
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
|
||||||
try {
|
try {
|
||||||
// do not overwrite clean .2 with dirty .1
|
// do not overwrite clean .2 with dirty .1
|
||||||
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
|
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
|
||||||
val flags1 = FileInputStream(file1).let { it.skip(49L); val r = it.read(); it.close(); r }
|
val flags1 = FileInputStream(file1).let { it.skip(49L); val r = it.read(); it.close(); r }
|
||||||
if (!(flags2 == 0 && flags1 != 0) || !file2.exists()) file1.copyTo(file2, true)
|
if (!(flags2 == 0 && flags1 != 0) || !file2.exists()) Files.move(file1.toPath(), file2.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||||
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
|
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
|
||||||
try {
|
try {
|
||||||
if (file2.exists() && !file3.exists())
|
if (file2.exists() && !file3.exists())
|
||||||
file2.copyTo(file3, true)
|
Files.move(file2.toPath(), file3.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||||
if (file1.exists() && !file2.exists())
|
if (file1.exists() && !file2.exists())
|
||||||
file1.copyTo(file2, true)
|
Files.move(file1.toPath(), file2.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
|
||||||
file.copyTo(file1, true)
|
file.copyTo(file1, true)
|
||||||
} catch (e: IOException) {}
|
} catch (e: IOException) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun makeSavegameBackupCopyAuto(file0: File): File {
|
||||||
|
val file1 = File("${file0.absolutePath}.a")
|
||||||
|
val file2 = File("${file0.absolutePath}.b")
|
||||||
|
val file3 = File("${file0.absolutePath}.c")
|
||||||
|
|
||||||
|
try {
|
||||||
|
// do not overwrite clean .2 with dirty .1
|
||||||
|
val flags3 = FileInputStream(file3).let { it.skip(49L); val r = it.read(); it.close(); r }
|
||||||
|
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
|
||||||
|
if (!(flags3 == 0 && flags2 != 0) || !file3.exists()) Files.move(file2.toPath(), file3.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
|
||||||
|
try {
|
||||||
|
// do not overwrite clean .2 with dirty .1
|
||||||
|
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
|
||||||
|
val flags1 = FileInputStream(file1).let { it.skip(49L); val r = it.read(); it.close(); r }
|
||||||
|
if (!(flags2 == 0 && flags1 != 0) || !file2.exists()) Files.move(file1.toPath(), file2.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
|
||||||
|
try {
|
||||||
|
if (file2.exists() && !file3.exists())
|
||||||
|
Files.move(file2.toPath(), file3.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
if (file1.exists() && !file2.exists())
|
||||||
|
Files.move(file1.toPath(), file2.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
|
||||||
|
file0.copyTo(file1, true)
|
||||||
|
} catch (e: IOException) {}
|
||||||
|
|
||||||
|
return file1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// simple euclidean norm, squared
|
// simple euclidean norm, squared
|
||||||
private val actorDistanceCalculator = DistanceCalculator<ActorWithBody> { t: ActorWithBody, p: PointND ->
|
private val actorDistanceCalculator = DistanceCalculator<ActorWithBody> { t: ActorWithBody, p: PointND ->
|
||||||
@@ -449,7 +485,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
|||||||
val dist2 = (p.getOrd(0) - (t.hitbox.centeredX - world.width * TILE_SIZE)).sqr() + (p.getOrd(1) - t.hitbox.centeredY).sqr()
|
val dist2 = (p.getOrd(0) - (t.hitbox.centeredX - world.width * TILE_SIZE)).sqr() + (p.getOrd(1) - t.hitbox.centeredY).sqr()
|
||||||
val dist3 = (p.getOrd(0) - (t.hitbox.centeredX + world.width * TILE_SIZE)).sqr() + (p.getOrd(1) - t.hitbox.centeredY).sqr()
|
val dist3 = (p.getOrd(0) - (t.hitbox.centeredX + world.width * TILE_SIZE)).sqr() + (p.getOrd(1) - t.hitbox.centeredY).sqr()
|
||||||
|
|
||||||
minOf(dist1, minOf(dist2, dist3))
|
min(min(dist1, dist2), dist3)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -467,7 +503,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
|||||||
fun getActorsAt(worldX: Double, worldY: Double): List<ActorWithBody> {
|
fun getActorsAt(worldX: Double, worldY: Double): List<ActorWithBody> {
|
||||||
val outList = ArrayList<ActorWithBody>()
|
val outList = ArrayList<ActorWithBody>()
|
||||||
try {
|
try {
|
||||||
actorsRTree.find(worldX, worldY, worldX + 1.0, worldY + 1.0, outList)
|
actorsRTree.find(worldX, worldY, worldX, worldY, outList)
|
||||||
}
|
}
|
||||||
catch (e: NullPointerException) {}
|
catch (e: NullPointerException) {}
|
||||||
return outList
|
return outList
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx
|
|||||||
import com.badlogic.gdx.files.FileHandle
|
import com.badlogic.gdx.files.FileHandle
|
||||||
import com.badlogic.gdx.utils.JsonValue
|
import com.badlogic.gdx.utils.JsonValue
|
||||||
import net.torvald.terrarum.App.*
|
import net.torvald.terrarum.App.*
|
||||||
|
import net.torvald.terrarum.App.setToGameConfig
|
||||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
import net.torvald.terrarum.blockproperties.WireCodex
|
import net.torvald.terrarum.blockproperties.WireCodex
|
||||||
import net.torvald.terrarum.gameitems.GameItem
|
import net.torvald.terrarum.gameitems.GameItem
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum
|
package net.torvald.terrarum
|
||||||
|
|
||||||
|
import net.torvald.random.XXHash32
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,6 +116,10 @@ class Point2i() {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int = XXHash32.hashGeoCoord(x, y)
|
||||||
|
|
||||||
|
override fun toString() = "Point2i($x, $y)"
|
||||||
|
|
||||||
operator fun component1() = x
|
operator fun component1() = x
|
||||||
operator fun component2() = y
|
operator fun component2() = y
|
||||||
}
|
}
|
||||||
|
|||||||
346
src/net/torvald/terrarum/Principii.java
Normal file
346
src/net/torvald/terrarum/Principii.java
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
package net.torvald.terrarum;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.JsonValue;
|
||||||
|
import net.torvald.terrarum.utils.JsonFetcher;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrapper that launches the bundled JVM and injects VM configs such as -Xmx
|
||||||
|
*
|
||||||
|
* Created by minjaesong on 2023-06-22.
|
||||||
|
*/
|
||||||
|
public class Principii {
|
||||||
|
|
||||||
|
private static KVHashMap gameConfig = new KVHashMap();
|
||||||
|
|
||||||
|
private static String OSName = System.getProperty("os.name");
|
||||||
|
|
||||||
|
private static String operationSystem;
|
||||||
|
/** %appdata%/Terrarum, without trailing slash */
|
||||||
|
private static String defaultDir;
|
||||||
|
/** defaultDir + "/config.json" */
|
||||||
|
private static String configDir;
|
||||||
|
|
||||||
|
public static void getDefaultDirRoot() {
|
||||||
|
String OS = OSName.toUpperCase();
|
||||||
|
if (OS.contains("WIN")) {
|
||||||
|
operationSystem = "WINDOWS";
|
||||||
|
defaultDir = System.getenv("APPDATA") + "/Terrarum";
|
||||||
|
}
|
||||||
|
else if (OS.contains("OS X") || OS.contains("MACOS")) { // OpenJDK for mac will still report "Mac OS X" with version number "10.16", even on Big Sur and beyond
|
||||||
|
operationSystem = "OSX";
|
||||||
|
defaultDir = System.getProperty("user.home") + "/Library/Application Support/Terrarum";
|
||||||
|
}
|
||||||
|
else if (OS.contains("NUX") || OS.contains("NIX") || OS.contains("BSD")) {
|
||||||
|
operationSystem = "LINUX";
|
||||||
|
defaultDir = System.getProperty("user.home") + "/.Terrarum";
|
||||||
|
}
|
||||||
|
else if (OS.contains("SUNOS")) {
|
||||||
|
operationSystem = "SOLARIS";
|
||||||
|
defaultDir = System.getProperty("user.home") + "/.Terrarum";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
operationSystem = "UNKNOWN";
|
||||||
|
defaultDir = System.getProperty("user.home") + "/.Terrarum";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
boolean devMode = false;
|
||||||
|
|
||||||
|
// if -ea flag is set, turn on all the debug prints
|
||||||
|
try {
|
||||||
|
assert false;
|
||||||
|
}
|
||||||
|
catch (AssertionError e) {
|
||||||
|
devMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String extracmd0 = devMode ? " -ea" : "";
|
||||||
|
String OS = OSName.toUpperCase();
|
||||||
|
String CPUARCH = System.getProperty("os.arch").toUpperCase();
|
||||||
|
String runtimeRoot;
|
||||||
|
String runtimeArch;
|
||||||
|
if (!CPUARCH.equals("AMD64") && !CPUARCH.equals("X86_64") && !CPUARCH.equals("AARCH64")) { // macOS Rosetta2 reports X86_64
|
||||||
|
System.err.println("Unsupported CPU architecture: " + CPUARCH);
|
||||||
|
System.exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
runtimeArch = (CPUARCH.equals("AMD64") || CPUARCH.equals("X86_64")) ? "x86" : "arm";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OS.contains("WIN")) {
|
||||||
|
runtimeRoot = "runtime-windows-" + runtimeArch;
|
||||||
|
}
|
||||||
|
else if (OS.contains("OS X") || OS.contains("MACOS")) { // OpenJDK for mac will still report "Mac OS X" with version number "10.16", even on Big Sur and beyond
|
||||||
|
runtimeRoot = "runtime-osx-" + runtimeArch;
|
||||||
|
extracmd0 += " -XstartOnFirstThread";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
runtimeRoot = "runtime-linux-" + runtimeArch;
|
||||||
|
extracmd0 += " -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd";
|
||||||
|
}
|
||||||
|
|
||||||
|
String runtime = new File("out/"+runtimeRoot+"/bin/Terrarum").getAbsolutePath(); // /bin/Terrarum is just a renamed version of /bin/java
|
||||||
|
System.out.println("Runtime path: "+runtime);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
getDefaultDirRoot();
|
||||||
|
configDir = defaultDir + "/config.json";
|
||||||
|
|
||||||
|
initialiseConfig();
|
||||||
|
readConfigJson();
|
||||||
|
|
||||||
|
|
||||||
|
int xmx = getConfigInt("jvm_xmx");
|
||||||
|
String userDefinedExtraCmd0 = getConfigString("jvm_extra_cmd").trim();
|
||||||
|
if (!userDefinedExtraCmd0.isEmpty()) userDefinedExtraCmd0 = " "+userDefinedExtraCmd0;
|
||||||
|
|
||||||
|
// String[] cmd = (runtime+extracmd0+userDefinedExtraCmd0+" -Xms1G -Xmx"+xmx+"G -cp ./out/TerrarumBuild.jar net.torvald.terrarum.App").split(" ");
|
||||||
|
|
||||||
|
List<String> extracmds = Arrays.stream(extracmd0.split(" ")).toList();
|
||||||
|
List<String> userDefinedExtraCmds = Arrays.stream(userDefinedExtraCmd0.split(" +")).filter((it) -> !it.isBlank()).toList();
|
||||||
|
ArrayList<String> cmd0 = new ArrayList<>();
|
||||||
|
cmd0.add(runtime);
|
||||||
|
cmd0.addAll(extracmds);
|
||||||
|
cmd0.addAll(userDefinedExtraCmds);
|
||||||
|
cmd0.add("-Xms1G");
|
||||||
|
cmd0.add("-Xmx"+xmx+"G");
|
||||||
|
cmd0.add("-cp");
|
||||||
|
cmd0.add("./out/TerrarumBuild.jar");
|
||||||
|
cmd0.add("net.torvald.terrarum.App");
|
||||||
|
var cmd = cmd0.stream().filter((it) -> !it.isBlank()).toList();
|
||||||
|
|
||||||
|
System.out.println(cmd);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ProcessBuilder pb = new ProcessBuilder(cmd);
|
||||||
|
pb.inheritIO();
|
||||||
|
System.exit(pb.start().waitFor());
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CONFIG //
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return config from config set. If the config does not exist, default value will be returned.
|
||||||
|
* @param key
|
||||||
|
* *
|
||||||
|
* @return Config from config set or default config if it does not exist.
|
||||||
|
* *
|
||||||
|
* @throws NullPointerException if the specified config simply does not exist.
|
||||||
|
*/
|
||||||
|
private static int getConfigInt(String key) {
|
||||||
|
Object cfg = getConfigMaster(key);
|
||||||
|
|
||||||
|
if (cfg instanceof Integer) return ((int) cfg);
|
||||||
|
|
||||||
|
double value = (double) cfg;
|
||||||
|
|
||||||
|
if (Math.abs(value % 1.0) < 0.00000001)
|
||||||
|
return (int) Math.round(value);
|
||||||
|
return ((int) cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return config from config set. If the config does not exist, default value will be returned.
|
||||||
|
* @param key
|
||||||
|
* *
|
||||||
|
* @return Config from config set or default config if it does not exist.
|
||||||
|
* *
|
||||||
|
* @throws NullPointerException if the specified config simply does not exist.
|
||||||
|
*/
|
||||||
|
private static double getConfigDouble(String key) {
|
||||||
|
Object cfg = getConfigMaster(key);
|
||||||
|
return (cfg instanceof Integer) ? (((Integer) cfg) * 1.0) : ((double) (cfg));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return config from config set. If the config does not exist, default value will be returned.
|
||||||
|
* @param key
|
||||||
|
* *
|
||||||
|
* @return Config from config set or default config if it does not exist.
|
||||||
|
* *
|
||||||
|
* @throws NullPointerException if the specified config simply does not exist.
|
||||||
|
*/
|
||||||
|
private static String getConfigString(String key) {
|
||||||
|
Object cfg = getConfigMaster(key);
|
||||||
|
return ((String) cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return config from config set. If the config does not exist, default value will be returned.
|
||||||
|
* @param key
|
||||||
|
* *
|
||||||
|
* @return Config from config set or default config if it does not exist. If the default value is undefined, will return false.
|
||||||
|
*/
|
||||||
|
private static boolean getConfigBoolean(String key) {
|
||||||
|
try {
|
||||||
|
Object cfg = getConfigMaster(key);
|
||||||
|
return ((boolean) cfg);
|
||||||
|
}
|
||||||
|
catch (NullPointerException keyNotFound) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*private static int[] getConfigIntArray(String key) {
|
||||||
|
Object cfg = getConfigMaster(key);
|
||||||
|
if (cfg instanceof JsonArray) {
|
||||||
|
JsonArray jsonArray = ((JsonArray) cfg).getAsJsonArray();
|
||||||
|
//return IntArray(jsonArray.size(), { i -> jsonArray[i].asInt })
|
||||||
|
int[] intArray = new int[jsonArray.size()];
|
||||||
|
for (int i = 0; i < jsonArray.size(); i++) {
|
||||||
|
intArray[i] = jsonArray.get(i).getAsInt();
|
||||||
|
}
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return ((int[]) cfg);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
private static double[] getConfigDoubleArray(String key) {
|
||||||
|
Object cfg = getConfigMaster(key);
|
||||||
|
return ((double[]) cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[] getConfigIntArray(String key) {
|
||||||
|
double[] a = getConfigDoubleArray(key);
|
||||||
|
int[] r = new int[a.length];
|
||||||
|
for (int i = 0; i < a.length; i++) {
|
||||||
|
r[i] = ((int) a[i]);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*private static String[] getConfigStringArray(String key) {
|
||||||
|
Object cfg = getConfigMaster(key);
|
||||||
|
if (cfg instanceof JsonArray) {
|
||||||
|
JsonArray jsonArray = ((JsonArray) cfg).getAsJsonArray();
|
||||||
|
//return IntArray(jsonArray.size(), { i -> jsonArray[i].asInt })
|
||||||
|
String[] intArray = new String[jsonArray.size()];
|
||||||
|
for (int i = 0; i < jsonArray.size(); i++) {
|
||||||
|
intArray[i] = jsonArray.get(i).getAsString();
|
||||||
|
}
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return ((String[]) cfg);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get config from config file. If the entry does not exist, get from defaults; if the entry is not in the default, NullPointerException will be thrown
|
||||||
|
*/
|
||||||
|
private static HashMap<String, Object> getDefaultConfig() {
|
||||||
|
return DefaultConfig.INSTANCE.getHashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object getConfigMaster(String key1) {
|
||||||
|
String key = key1.toLowerCase();
|
||||||
|
|
||||||
|
Object config;
|
||||||
|
try {
|
||||||
|
config = gameConfig.get(key);
|
||||||
|
}
|
||||||
|
catch (NullPointerException e) {
|
||||||
|
config = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object defaults;
|
||||||
|
try {
|
||||||
|
defaults = getDefaultConfig().get(key);
|
||||||
|
}
|
||||||
|
catch (NullPointerException e) {
|
||||||
|
defaults = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config == null) {
|
||||||
|
if (defaults == null) {
|
||||||
|
throw new NullPointerException("key not found: '" + key + "'");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return true on successful, false on failure.
|
||||||
|
*/
|
||||||
|
private static Boolean readConfigJson() {
|
||||||
|
System.out.println("Config file: " + configDir);
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// read from disk and build config from it
|
||||||
|
JsonValue map = JsonFetcher.INSTANCE.invoke(configDir);
|
||||||
|
|
||||||
|
// make config
|
||||||
|
for (JsonValue entry = map.child; entry != null; entry = entry.next) {
|
||||||
|
setToGameConfigForced(entry, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// write default config to game dir. Call th.is method again to read config from it.
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads DefaultConfig to populate the gameConfig
|
||||||
|
*/
|
||||||
|
private static void initialiseConfig() {
|
||||||
|
for (Map.Entry<String, Object> entry : DefaultConfig.INSTANCE.getHashMap().entrySet()) {
|
||||||
|
gameConfig.set(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will forcibly overwrite previously loaded config value.
|
||||||
|
*
|
||||||
|
* Key naming convention will be 'modName:propertyName'; if modName is null, the key will be just propertyName.
|
||||||
|
*
|
||||||
|
* @param value JsonValue (the key-value pair)
|
||||||
|
* @param modName module name, nullable
|
||||||
|
*/
|
||||||
|
private static void setToGameConfigForced(JsonValue value, String modName) {
|
||||||
|
gameConfig.set((modName == null) ? value.name : modName+":"+value.name,
|
||||||
|
value.isArray() ? value.asDoubleArray() :
|
||||||
|
value.isDouble() ? value.asDouble() :
|
||||||
|
value.isBoolean() ? value.asBoolean() :
|
||||||
|
value.isLong() ? value.asInt() :
|
||||||
|
value.asString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.torvald.terrarum.modulebasegame
|
package net.torvald.terrarum
|
||||||
|
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -9,6 +9,7 @@ import com.jme3.math.FastMath
|
|||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2017-07-13.
|
* Created by minjaesong on 2017-07-13.
|
||||||
@@ -46,7 +47,7 @@ object SanicLoadScreen : LoadScreenBase() {
|
|||||||
|
|
||||||
textFbo = FrameBuffer(
|
textFbo = FrameBuffer(
|
||||||
Pixmap.Format.RGBA4444,
|
Pixmap.Format.RGBA4444,
|
||||||
maxOf(
|
max(
|
||||||
App.fontGame.getWidth(Lang["MENU_IO_LOADING"]),
|
App.fontGame.getWidth(Lang["MENU_IO_LOADING"]),
|
||||||
App.fontGame.getWidth(Lang["ERROR_GENERIC_TEXT"])
|
App.fontGame.getWidth(Lang["ERROR_GENERIC_TEXT"])
|
||||||
),
|
),
|
||||||
@@ -61,7 +62,7 @@ object SanicLoadScreen : LoadScreenBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val textX: Float; get() = (App.scr.width * 0.72f).floor()
|
val textX: Float; get() = (App.scr.width * 0.72f).floorToFloat()
|
||||||
|
|
||||||
private var genuineSonic = false // the "NOW LOADING..." won't appear unless the arrow first run passes it
|
private var genuineSonic = false // the "NOW LOADING..." won't appear unless the arrow first run passes it
|
||||||
|
|
||||||
|
|||||||
348
src/net/torvald/terrarum/SavegameCollection.kt
Normal file
348
src/net/torvald/terrarum/SavegameCollection.kt
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
package net.torvald.terrarum
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
|
import com.badlogic.gdx.graphics.Texture
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
|
import com.badlogic.gdx.utils.JsonWriter
|
||||||
|
import net.torvald.terrarum.App.printdbg
|
||||||
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
|
import net.torvald.terrarum.savegame.*
|
||||||
|
import net.torvald.terrarum.savegame.VDFileID.PLAYER_SCREENSHOT
|
||||||
|
import net.torvald.terrarum.savegame.VDFileID.ROOT
|
||||||
|
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||||
|
import net.torvald.terrarum.savegame.VDFileID.WORLD_SCREENSHOT
|
||||||
|
import net.torvald.terrarum.serialise.Common
|
||||||
|
import net.torvald.terrarum.utils.JsonFetcher
|
||||||
|
import net.torvald.terrarum.utils.forEachSiblings
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
|
import java.util.*
|
||||||
|
import java.util.zip.GZIPInputStream
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2023-06-24.
|
||||||
|
*/
|
||||||
|
class SavegameCollection(files0: List<DiskSkimmer>) {
|
||||||
|
|
||||||
|
/** Sorted in reverse by the last modified time of the files, index zero being the most recent */
|
||||||
|
val files = files0.sortedBy { it.diskFile.name }.sortedByDescending {
|
||||||
|
it.getLastModifiedTime().shl(2) or
|
||||||
|
it.diskFile.extension.matches(Regex("^[abc]${'$'}")).toLong(1) or
|
||||||
|
it.diskFile.extension.isBlank().toLong(0)
|
||||||
|
}
|
||||||
|
/** Sorted in reverse by the last modified time of the files, index zero being the most recent */
|
||||||
|
val autoSaves = files.filter { it.diskFile.extension.matches(Regex("[a-z]")) }
|
||||||
|
/** Sorted in reverse by the last modified time of the files, index zero being the most recent */
|
||||||
|
val manualSaves = files.filter { !it.diskFile.extension.matches(Regex("[a-z]")) }
|
||||||
|
|
||||||
|
init {
|
||||||
|
files.forEach { it.rebuild() }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun collectFromBaseFilename(basedir: File, name: String): SavegameCollection {
|
||||||
|
val files = basedir.listFiles().filter { it.name.startsWith(name) }
|
||||||
|
.mapNotNull { try { DiskSkimmer(it, true) } catch (e: Throwable) { null } }
|
||||||
|
return SavegameCollection(files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent not-corrupted file
|
||||||
|
*/
|
||||||
|
fun loadable(): DiskSkimmer {
|
||||||
|
return files.first()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun moveToRecycle(basedir: String) {
|
||||||
|
files.forEach {
|
||||||
|
try {
|
||||||
|
Files.move(it.diskFile.toPath(), Path(basedir, it.diskFile.name), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
}
|
||||||
|
catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBaseFile(): DiskSkimmer {
|
||||||
|
return files.first { it.diskFile.extension.isBlank() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getUUID(): UUID {
|
||||||
|
var uuid: UUID? = null
|
||||||
|
loadable().getFile(SAVEGAMEINFO)!!.let {
|
||||||
|
JsonFetcher.readFromJsonString(ByteArray64Reader(it.bytes, Common.CHARSET)).forEachSiblings { name, value ->
|
||||||
|
if (name == "worldIndex" || name == "uuid") uuid = UUID.fromString(value.asString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uuid!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun renamePlayer(name: String) {
|
||||||
|
files.forEach { skimmer ->
|
||||||
|
skimmer.rebuild()
|
||||||
|
skimmer.getFile(SAVEGAMEINFO)!!.let { file ->
|
||||||
|
val json = JsonFetcher.readFromJsonString(ByteArray64Reader(file.bytes, Common.CHARSET))
|
||||||
|
|
||||||
|
json["actorValue"]["hashMap"]["name"]["value"].set(name) // getChild() does NOT work as [] does
|
||||||
|
|
||||||
|
val jsonBytes = json.prettyPrint(JsonWriter.OutputType.json, 0).encodeToByteArray().toByteArray64()
|
||||||
|
val newEntry = DiskEntry(SAVEGAMEINFO, ROOT, skimmer.requestFile(SAVEGAMEINFO)!!.creationDate, App.getTIME_T(), EntryFile(jsonBytes))
|
||||||
|
|
||||||
|
skimmer.appendEntry(newEntry)
|
||||||
|
|
||||||
|
skimmer.setDiskName(name, Common.CHARSET)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun renameWorld(name: String) {
|
||||||
|
files.forEach { skimmer ->
|
||||||
|
skimmer.setDiskName(name, Common.CHARSET)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getThumbnail(width: Int, height: Int, shrinkage: Double) = this.loadable().getThumbnail(width, height, shrinkage)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DiskSkimmer.getTgaGz(vid: EntryID, width: Int, height: Int, shrinkage: Double): TextureRegion? {
|
||||||
|
return this.requestFile(vid).let { file ->
|
||||||
|
if (file != null) {
|
||||||
|
val zippedTga = (file.contents as EntryFile).bytes
|
||||||
|
val gzin = GZIPInputStream(ByteArray64InputStream(zippedTga))
|
||||||
|
val tgaFileContents = gzin.readAllBytes(); gzin.close()
|
||||||
|
val pixmap = Pixmap(tgaFileContents, 0, tgaFileContents.size)
|
||||||
|
TextureRegion(Texture(pixmap)).also {
|
||||||
|
App.disposables.add(it.texture)
|
||||||
|
// do cropping and resizing
|
||||||
|
it.setRegion(
|
||||||
|
((pixmap.width - width*2) / shrinkage).roundToInt(),
|
||||||
|
((pixmap.height - height*2) / shrinkage).roundToInt(),
|
||||||
|
(width * shrinkage).roundToInt(),
|
||||||
|
(height * shrinkage).roundToInt()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun DiskSkimmer.getTgaGzPixmap(vid: EntryID, width: Int, height: Int, shrinkage: Double): Pixmap? {
|
||||||
|
return this.requestFile(vid).let { file ->
|
||||||
|
if (file != null) {
|
||||||
|
val zippedTga = (file.contents as EntryFile).bytes
|
||||||
|
val gzin = GZIPInputStream(ByteArray64InputStream(zippedTga))
|
||||||
|
val tgaFileContents = gzin.readAllBytes(); gzin.close()
|
||||||
|
val pixmap = Pixmap(tgaFileContents, 0, tgaFileContents.size)
|
||||||
|
return pixmap
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun DiskSkimmer.getThumbnail(width: Int, height: Int, shrinkage: Double) =
|
||||||
|
when (this.getSaveKind()) {
|
||||||
|
1 -> this.getTgaGz(PLAYER_SCREENSHOT, width, height, shrinkage)
|
||||||
|
2 -> this.getTgaGz(WORLD_SCREENSHOT, width, height, shrinkage)
|
||||||
|
else -> throw IllegalArgumentException("Unknown save kind: ${this.getSaveKind()}")
|
||||||
|
}
|
||||||
|
fun DiskSkimmer.getThumbnailPixmap(width: Int, height: Int, shrinkage: Double) =
|
||||||
|
when (this.getSaveKind()) {
|
||||||
|
1 -> this.getTgaGzPixmap(PLAYER_SCREENSHOT, width, height, shrinkage)
|
||||||
|
2 -> this.getTgaGzPixmap(WORLD_SCREENSHOT, width, height, shrinkage)
|
||||||
|
else -> throw IllegalArgumentException("Unknown save kind: ${this.getSaveKind()}")
|
||||||
|
}
|
||||||
|
|
||||||
|
class SavegameCollectionPair(private val player: SavegameCollection?, private val world: SavegameCollection?) {
|
||||||
|
|
||||||
|
// private var manualPlayer: DiskSkimmer? = null
|
||||||
|
// private var manualWorld: DiskSkimmer? = null
|
||||||
|
// private var autoPlayer: DiskSkimmer? = null
|
||||||
|
// private var autoWorld: DiskSkimmer? = null
|
||||||
|
|
||||||
|
/* removing auto/manual discrimination: on Local Asynchronous Multiplayer, if newer autosave is available, there is
|
||||||
|
* no choice but loading one to preserve the data; then why bother having two? */
|
||||||
|
private var playerDisk: DiskSkimmer? = null; private set
|
||||||
|
private var worldDisk: DiskSkimmer? = null; private set
|
||||||
|
|
||||||
|
var status = 0 // 0: none available, 1: loadable manual save is newer than loadable auto; 2: loadable autosave is newer than loadable manual
|
||||||
|
private set
|
||||||
|
|
||||||
|
val newerSaveIsDamaged: Boolean // only when most recent save is corrupted
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (player != null && world != null) {
|
||||||
|
printdbg(this, "player files: " + player.files.joinToString { it.diskFile.name })
|
||||||
|
printdbg(this, "world files:" + world.files.joinToString { it.diskFile.name })
|
||||||
|
|
||||||
|
var pc = 0
|
||||||
|
var wc = 0
|
||||||
|
|
||||||
|
playerDisk = player.files[pc]
|
||||||
|
worldDisk = world.files[wc]
|
||||||
|
|
||||||
|
while (pc < player.files.size && wc < world.files.size) {
|
||||||
|
// 0b pw
|
||||||
|
val dmgflag = playerDiskNotDamaged(playerDisk!!).toInt(1) or worldDiskNotDamaged(worldDisk!!).toInt()
|
||||||
|
|
||||||
|
when (dmgflag) {
|
||||||
|
3 -> break
|
||||||
|
2 -> {
|
||||||
|
worldDisk = world.files[++wc]
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
playerDisk = player.files[++pc]
|
||||||
|
}
|
||||||
|
0 -> {
|
||||||
|
worldDisk = world.files[++wc]
|
||||||
|
playerDisk = player.files[++pc]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's time to exit the loop and all tested saves were damaged:
|
||||||
|
if (pc == player.files.size) playerDisk = null
|
||||||
|
if (wc == world.files.size) worldDisk = null
|
||||||
|
}
|
||||||
|
|
||||||
|
newerSaveIsDamaged = (pc + wc > 0)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newerSaveIsDamaged = false
|
||||||
|
}
|
||||||
|
|
||||||
|
status = if (playerDisk != null && worldDisk != null && (playerDisk!!.isAutosaved() || worldDisk!!.isAutosaved()))
|
||||||
|
2
|
||||||
|
else (player != null && world != null).toInt()
|
||||||
|
|
||||||
|
printdbg(this, "playerDisk = ${playerDisk?.diskFile?.path}")
|
||||||
|
printdbg(this, "worldDisk = ${worldDisk?.diskFile?.path}")
|
||||||
|
printdbg(this, "status = $status")
|
||||||
|
}
|
||||||
|
|
||||||
|
/*init {
|
||||||
|
printdbg(this, "init ($player, $world)")
|
||||||
|
|
||||||
|
if (player != null && world != null) {
|
||||||
|
|
||||||
|
printdbg(this, "player files: " + player.files.joinToString { it.diskFile.name })
|
||||||
|
printdbg(this, "world files:" + world.files.joinToString { it.diskFile.name })
|
||||||
|
|
||||||
|
// if a pair of files were saved successfully, they must have identical lastModifiedTime()
|
||||||
|
var pc = 0; val pt = player.files[0].getLastModifiedTime()
|
||||||
|
var wc = 0; val wt = world.files[0].getLastModifiedTime()
|
||||||
|
while (pc < player.files.size && wc < world.files.size) {
|
||||||
|
val pcf = player.files[pc]
|
||||||
|
val pcm = pcf.getLastModifiedTime()
|
||||||
|
val wcf = world.files[wc]
|
||||||
|
val wcm = wcf.getLastModifiedTime()
|
||||||
|
|
||||||
|
printdbg(this, "pc=$pc, wc=$wc, pcm=$pcm, wcm=$wcm")
|
||||||
|
|
||||||
|
if (playerDiskNotDamaged(pcf) && worldDiskNotDamaged(wcf)) {
|
||||||
|
|
||||||
|
printdbg(this, "pcf.autosaved=${pcf.isAutosaved()}, wcf.autosaved=${wcf.isAutosaved()}")
|
||||||
|
|
||||||
|
when (pcf.isAutosaved().toInt(1) or wcf.isAutosaved().toInt()) {
|
||||||
|
3 -> {
|
||||||
|
if (autoPlayer == null && autoWorld == null) {
|
||||||
|
autoPlayer = pcf
|
||||||
|
autoWorld = wcf
|
||||||
|
}
|
||||||
|
pc += 1
|
||||||
|
wc += 1
|
||||||
|
}
|
||||||
|
0 -> {
|
||||||
|
if (manualPlayer == null && manualWorld == null) {
|
||||||
|
manualPlayer = pcf
|
||||||
|
manualWorld = wcf
|
||||||
|
}
|
||||||
|
pc += 1
|
||||||
|
wc += 1
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
if (pcm > wcm)
|
||||||
|
pc += 1
|
||||||
|
else if (pcm == wcm) {
|
||||||
|
pc += 1
|
||||||
|
wc += 1
|
||||||
|
}
|
||||||
|
// world is modified after another player playing on the same world but only left an autosave
|
||||||
|
// there is no choice but loading the autosave in such scenario to preserve the data
|
||||||
|
else {
|
||||||
|
wc += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (manualPlayer != null && manualWorld != null && autoPlayer != null && autoWorld != null)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manualPlayer != null && manualWorld != null && autoPlayer != null && autoWorld != null) {
|
||||||
|
status = if (manualPlayer!!.getLastModifiedTime() > autoPlayer!!.getLastModifiedTime()) 1 else 2
|
||||||
|
}
|
||||||
|
else if (manualPlayer != null && manualWorld != null || autoPlayer != null && autoWorld != null) {
|
||||||
|
status = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
status = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
printdbg(this, "manualPlayer = ${manualPlayer?.diskFile?.path}")
|
||||||
|
printdbg(this, "manualWorld = ${manualWorld?.diskFile?.path}")
|
||||||
|
printdbg(this, "autoPlayer = ${autoPlayer?.diskFile?.path}")
|
||||||
|
printdbg(this, "autoWorld = ${autoWorld?.diskFile?.path}")
|
||||||
|
printdbg(this, "status = $status")
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
private fun DiskSkimmer.isAutosaved() = this.getSaveMode().and(0b0000_0010) != 0
|
||||||
|
|
||||||
|
private fun playerDiskNotDamaged(disk: DiskSkimmer): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun worldDiskNotDamaged(disk: DiskSkimmer): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun moreRecentAutosaveAvailable() = (status == 2)
|
||||||
|
fun saveAvaliable() = (status > 0)
|
||||||
|
|
||||||
|
/*fun getManualSave(): DiskPair? {
|
||||||
|
if (status == 0) return null
|
||||||
|
return DiskPair(manualPlayer!!, manualWorld!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAutoSave(): DiskPair? {
|
||||||
|
if (status != 2) return null
|
||||||
|
return DiskPair(autoPlayer!!, autoWorld!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLoadableSave(): DiskPair? {
|
||||||
|
if (status == 0) return null
|
||||||
|
return if (manualPlayer != null && manualWorld != null)
|
||||||
|
DiskPair(manualPlayer!!, manualWorld!!)
|
||||||
|
else
|
||||||
|
DiskPair(autoPlayer!!, autoWorld!!)
|
||||||
|
}*/
|
||||||
|
|
||||||
|
fun getLoadableSave(): DiskPair? {
|
||||||
|
return if (status == 0) null
|
||||||
|
else DiskPair(playerDisk!!, worldDisk!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class DiskPair(val player: DiskSkimmer, val world: DiskSkimmer) {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import com.badlogic.gdx.utils.JsonReader
|
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.gdx.graphics.Cvec
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
@@ -26,9 +26,7 @@ import net.torvald.terrarum.gameworld.fmod
|
|||||||
import net.torvald.terrarum.itemproperties.CraftingCodex
|
import net.torvald.terrarum.itemproperties.CraftingCodex
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
import net.torvald.terrarum.itemproperties.MaterialCodex
|
import net.torvald.terrarum.itemproperties.MaterialCodex
|
||||||
import net.torvald.terrarum.savegame.ByteArray64Reader
|
|
||||||
import net.torvald.terrarum.savegame.DiskSkimmer
|
import net.torvald.terrarum.savegame.DiskSkimmer
|
||||||
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
|
||||||
import net.torvald.terrarum.serialise.Common
|
import net.torvald.terrarum.serialise.Common
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
@@ -38,10 +36,7 @@ import net.torvald.util.CircularArray
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.*
|
||||||
import kotlin.math.round
|
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typealias RGBA8888 = Int
|
typealias RGBA8888 = Int
|
||||||
@@ -62,11 +57,11 @@ object Terrarum : Disposable {
|
|||||||
*/
|
*/
|
||||||
const val PLAYER_REF_ID: Int = 0x91A7E2
|
const val PLAYER_REF_ID: Int = 0x91A7E2
|
||||||
|
|
||||||
inline fun inShapeRenderer(shapeRendererType: ShapeRenderer.ShapeType = ShapeRenderer.ShapeType.Filled, action: (ShapeRenderer) -> Unit) {
|
/*inline fun inShapeRenderer(shapeRendererType: ShapeRenderer.ShapeType = ShapeRenderer.ShapeType.Filled, action: (ShapeRenderer) -> Unit) {
|
||||||
shapeRender.begin(shapeRendererType)
|
shapeRender.begin(shapeRendererType)
|
||||||
action(shapeRender)
|
action(shapeRender)
|
||||||
shapeRender.end()
|
shapeRender.end()
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
var blockCodex = BlockCodex(); internal set
|
var blockCodex = BlockCodex(); internal set
|
||||||
@@ -236,16 +231,16 @@ object Terrarum : Disposable {
|
|||||||
get() = WorldCamera.zoomedY + (Gdx.input.y - Gdx.input.deltaY) / (ingame?.screenZoom ?: 1f).times(scr.magn.toDouble())
|
get() = WorldCamera.zoomedY + (Gdx.input.y - Gdx.input.deltaY) / (ingame?.screenZoom ?: 1f).times(scr.magn.toDouble())
|
||||||
/** Position of the cursor in the world, rounded */
|
/** Position of the cursor in the world, rounded */
|
||||||
@JvmStatic val mouseTileX: Int
|
@JvmStatic val mouseTileX: Int
|
||||||
get() = (mouseX / TILE_SIZE).floorInt()
|
get() = (mouseX / TILE_SIZE).floorToInt()
|
||||||
/** Position of the cursor in the world */
|
/** Position of the cursor in the world */
|
||||||
@JvmStatic val mouseTileY: Int
|
@JvmStatic val mouseTileY: Int
|
||||||
get() = (mouseY / TILE_SIZE).floorInt()
|
get() = (mouseY / TILE_SIZE).floorToInt()
|
||||||
/** Position of the cursor in the world, rounded */
|
/** Position of the cursor in the world, rounded */
|
||||||
@JvmStatic val oldMouseTileX: Int
|
@JvmStatic val oldMouseTileX: Int
|
||||||
get() = (oldMouseX / TILE_SIZE).floorInt()
|
get() = (oldMouseX / TILE_SIZE).floorToInt()
|
||||||
/** Position of the cursor in the world */
|
/** Position of the cursor in the world */
|
||||||
@JvmStatic val oldMouseTileY: Int
|
@JvmStatic val oldMouseTileY: Int
|
||||||
get() = (oldMouseY / TILE_SIZE).floorInt()
|
get() = (oldMouseY / TILE_SIZE).floorToInt()
|
||||||
inline val mouseScreenX: Int
|
inline val mouseScreenX: Int
|
||||||
get() = Gdx.input.x.div(scr.magn).roundToInt()
|
get() = Gdx.input.x.div(scr.magn).roundToInt()
|
||||||
inline val mouseScreenY: Int
|
inline val mouseScreenY: Int
|
||||||
@@ -319,8 +314,8 @@ object Terrarum : Disposable {
|
|||||||
|
|
||||||
val mx = mouseX
|
val mx = mouseX
|
||||||
val my = mouseY
|
val my = mouseY
|
||||||
val mtx = (mouseX / TILE_SIZE).floorInt()
|
val mtx = (mouseX / TILE_SIZE).floorToInt()
|
||||||
val mty = (mouseY / TILE_SIZE).floorInt()
|
val mty = (mouseY / TILE_SIZE).floorToInt()
|
||||||
val msx = mx fmod TILE_SIZED
|
val msx = mx fmod TILE_SIZED
|
||||||
val msy = my fmod TILE_SIZED
|
val msy = my fmod TILE_SIZED
|
||||||
val vector = if (msx < SMALLGAP) { // X to the left
|
val vector = if (msx < SMALLGAP) { // X to the left
|
||||||
@@ -397,8 +392,10 @@ inline fun FrameBuffer.inAction(camera: OrthographicCamera?, batch: SpriteBatch?
|
|||||||
//this.begin()
|
//this.begin()
|
||||||
FrameBufferManager.begin(this)
|
FrameBufferManager.begin(this)
|
||||||
|
|
||||||
|
val oldCamPos = camera?.position?.cpy()
|
||||||
|
|
||||||
camera?.setToOrtho(true, this.width.toFloat(), this.height.toFloat())
|
camera?.setToOrtho(true, this.width.toFloat(), this.height.toFloat())
|
||||||
camera?.position?.set((this.width / 2f).round(), (this.height / 2f).round(), 0f) // TODO floor? ceil? round?
|
camera?.position?.set((this.width / 2f).roundToFloat(), (this.height / 2f).roundToFloat(), 0f) // TODO floor? ceil? round?
|
||||||
camera?.update()
|
camera?.update()
|
||||||
batch?.projectionMatrix = camera?.combined
|
batch?.projectionMatrix = camera?.combined
|
||||||
|
|
||||||
@@ -408,6 +405,7 @@ inline fun FrameBuffer.inAction(camera: OrthographicCamera?, batch: SpriteBatch?
|
|||||||
FrameBufferManager.end()
|
FrameBufferManager.end()
|
||||||
|
|
||||||
camera?.setToOrtho(true, App.scr.wf, App.scr.hf)
|
camera?.setToOrtho(true, App.scr.wf, App.scr.hf)
|
||||||
|
camera?.position?.set(oldCamPos)
|
||||||
camera?.update()
|
camera?.update()
|
||||||
batch?.projectionMatrix = camera?.combined
|
batch?.projectionMatrix = camera?.combined
|
||||||
}
|
}
|
||||||
@@ -419,8 +417,10 @@ inline fun FrameBuffer.inActionF(camera: OrthographicCamera?, batch: SpriteBatch
|
|||||||
//this.begin()
|
//this.begin()
|
||||||
FrameBufferManager.begin(this)
|
FrameBufferManager.begin(this)
|
||||||
|
|
||||||
|
val oldCamPos = camera?.position?.cpy()
|
||||||
|
|
||||||
camera?.setToOrtho(false, this.width.toFloat(), this.height.toFloat())
|
camera?.setToOrtho(false, this.width.toFloat(), this.height.toFloat())
|
||||||
camera?.position?.set((this.width / 2f).round(), (this.height / 2f).round(), 0f) // TODO floor? ceil? round?
|
camera?.position?.set((this.width / 2f).roundToFloat(), (this.height / 2f).roundToFloat(), 0f) // TODO floor? ceil? round?
|
||||||
camera?.update()
|
camera?.update()
|
||||||
batch?.projectionMatrix = camera?.combined
|
batch?.projectionMatrix = camera?.combined
|
||||||
|
|
||||||
@@ -430,6 +430,7 @@ inline fun FrameBuffer.inActionF(camera: OrthographicCamera?, batch: SpriteBatch
|
|||||||
FrameBufferManager.end()
|
FrameBufferManager.end()
|
||||||
|
|
||||||
camera?.setToOrtho(true, App.scr.wf, App.scr.hf)
|
camera?.setToOrtho(true, App.scr.wf, App.scr.hf)
|
||||||
|
camera?.position?.set(oldCamPos)
|
||||||
camera?.update()
|
camera?.update()
|
||||||
batch?.projectionMatrix = camera?.combined
|
batch?.projectionMatrix = camera?.combined
|
||||||
}
|
}
|
||||||
@@ -609,27 +610,28 @@ val emphVerb = TerrarumSansBitmap.toColorCode(0xFFF6)
|
|||||||
|
|
||||||
typealias Second = Float
|
typealias Second = Float
|
||||||
|
|
||||||
fun Int.sqr(): Int = this * this
|
inline fun Double.floorToInt() = floor(this).toInt()
|
||||||
fun Double.floorInt() = Math.floor(this).toInt()
|
inline fun Float.floorToInt() = FastMath.floor(this)
|
||||||
fun Float.floorInt() = FastMath.floor(this)
|
inline fun Double.ceilToInt() = Math.ceil(this).toInt()
|
||||||
fun Float.floor() = FastMath.floor(this).toFloat()
|
inline fun Float.ceilToFloat(): Float = FastMath.ceil(this).toFloat()
|
||||||
fun Double.ceilInt() = Math.ceil(this).toInt()
|
inline fun Float.ceilToInt() = FastMath.ceil(this)
|
||||||
fun Float.ceil(): Float = FastMath.ceil(this).toFloat()
|
inline fun Float.floorToFloat() = FastMath.floor(this).toFloat()
|
||||||
fun Float.ceilInt() = FastMath.ceil(this)
|
inline fun Float.roundToFloat(): Float = round(this)
|
||||||
fun Float.round(): Float = round(this)
|
//inline fun Double.round() = Math.round(this).toDouble()
|
||||||
fun Double.round() = Math.round(this).toDouble()
|
inline fun Double.floorToDouble() = floor(this)
|
||||||
fun Double.floor() = Math.floor(this)
|
inline fun Double.ceilToDouble() = ceil(this)
|
||||||
fun Double.ceil() = this.floor() + 1.0
|
inline fun Int.sqr(): Int = this * this
|
||||||
fun Double.abs() = Math.abs(this)
|
inline fun Double.sqr() = this * this
|
||||||
fun Double.sqr() = this * this
|
inline fun Float.sqr() = this * this
|
||||||
fun Float.sqr() = this * this
|
inline fun Double.sqrt() = Math.sqrt(this)
|
||||||
fun Double.sqrt() = Math.sqrt(this)
|
inline fun Float.sqrt() = FastMath.sqrt(this)
|
||||||
fun Float.sqrt() = FastMath.sqrt(this)
|
inline fun Int.abs() = this.absoluteValue
|
||||||
fun Int.abs() = this.absoluteValue
|
inline fun Double.abs() = this.absoluteValue
|
||||||
fun Double.bipolarClamp(limit: Double) = this.coerceIn(-limit, limit)
|
inline fun Double.bipolarClamp(limit: Double) = this.coerceIn(-limit, limit)
|
||||||
fun Boolean.toInt(shift: Int = 0) = if (this) 1.shl(shift) else 0
|
inline fun Boolean.toInt(shift: Int = 0) = if (this) 1.shl(shift) else 0
|
||||||
fun Int.bitCount() = java.lang.Integer.bitCount(this)
|
inline fun Boolean.toLong(shift: Int = 0) = if (this) 1L.shl(shift) else 0L
|
||||||
fun Long.bitCount() = java.lang.Long.bitCount(this)
|
inline fun Int.bitCount() = java.lang.Integer.bitCount(this)
|
||||||
|
inline fun Long.bitCount() = java.lang.Long.bitCount(this)
|
||||||
|
|
||||||
|
|
||||||
fun absMax(left: Double, right: Double): Double {
|
fun absMax(left: Double, right: Double): Double {
|
||||||
@@ -648,7 +650,6 @@ fun absMax(left: Double, right: Double): Double {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Double.magnSqr() = if (this >= 0.0) this.sqr() else -this.sqr()
|
fun Double.magnSqr() = if (this >= 0.0) this.sqr() else -this.sqr()
|
||||||
fun Double.sign() = if (this > 0.0) 1.0 else if (this < 0.0) -1.0 else 0.0
|
|
||||||
fun interpolateLinear(scale: Double, startValue: Double, endValue: Double): Double {
|
fun interpolateLinear(scale: Double, startValue: Double, endValue: Double): Double {
|
||||||
if (startValue == endValue) {
|
if (startValue == endValue) {
|
||||||
return startValue
|
return startValue
|
||||||
@@ -785,6 +786,7 @@ fun AppUpdateListOfSavegames() {
|
|||||||
|
|
||||||
println("Listing saved worlds...")
|
println("Listing saved worlds...")
|
||||||
|
|
||||||
|
|
||||||
// create list of worlds
|
// create list of worlds
|
||||||
File(worldsDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.mapNotNull { file ->
|
File(worldsDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.mapNotNull { file ->
|
||||||
try {
|
try {
|
||||||
@@ -797,15 +799,20 @@ fun AppUpdateListOfSavegames() {
|
|||||||
}
|
}
|
||||||
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
||||||
println("${index+1}.\t${it.diskFile.absolutePath}")
|
println("${index+1}.\t${it.diskFile.absolutePath}")
|
||||||
it.rebuild() // disk skimmer was created without initialisation, so do it now
|
// it.rebuild()
|
||||||
|
|
||||||
val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
// val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
||||||
val json = JsonReader().parse(ByteArray64Reader(jsonFile.bytes, Common.CHARSET).readText())
|
// var worldUUID: UUID? = null
|
||||||
val worldUUID = UUID.fromString(json.getString("worldIndex"))
|
// JsonFetcher.readFromJsonString(ByteArray64Reader(jsonFile.bytes, Common.CHARSET)).forEachSiblings { name, value ->
|
||||||
|
// if (name == "worldIndex") worldUUID = UUID.fromString(value.asString())
|
||||||
|
// }
|
||||||
|
|
||||||
|
val collection = SavegameCollection.collectFromBaseFilename(File(worldsDir), it.diskFile.name)
|
||||||
|
val worldUUID = collection.getUUID()
|
||||||
|
|
||||||
// if multiple valid savegames with same UUID exist, only the most recent one is retained
|
// if multiple valid savegames with same UUID exist, only the most recent one is retained
|
||||||
if (!App.savegameWorlds.contains(worldUUID)) {
|
if (!App.savegameWorlds.contains(worldUUID)) {
|
||||||
App.savegameWorlds[worldUUID] = it
|
App.savegameWorlds[worldUUID] = collection
|
||||||
App.savegameWorldsName[worldUUID] = it.getDiskName(Common.CHARSET)
|
App.savegameWorldsName[worldUUID] = it.getDiskName(Common.CHARSET)
|
||||||
App.sortedSavegameWorlds.add(worldUUID)
|
App.sortedSavegameWorlds.add(worldUUID)
|
||||||
}
|
}
|
||||||
@@ -827,20 +834,30 @@ fun AppUpdateListOfSavegames() {
|
|||||||
}
|
}
|
||||||
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
||||||
println("${index+1}.\t${it.diskFile.absolutePath}")
|
println("${index+1}.\t${it.diskFile.absolutePath}")
|
||||||
it.rebuild() // disk skimmer was created without initialisation, so do it now
|
// it.rebuild()
|
||||||
|
|
||||||
val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
// val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
||||||
val json = JsonReader().parse(ByteArray64Reader(jsonFile.bytes, Common.CHARSET).readText())
|
// var playerUUID: UUID? = null
|
||||||
val playerUUID = UUID.fromString(json.getString("uuid"))
|
// JsonFetcher.readFromJsonString(ByteArray64Reader(jsonFile.bytes, Common.CHARSET)).forEachSiblings { name, value ->
|
||||||
|
// if (name == "uuid") playerUUID = UUID.fromString(value.asString())
|
||||||
|
// }
|
||||||
|
|
||||||
|
val collection = SavegameCollection.collectFromBaseFilename(File(playersDir), it.diskFile.name)
|
||||||
|
val playerUUID = collection.getUUID()
|
||||||
|
|
||||||
// if multiple valid savegames with same UUID exist, only the most recent one is retained
|
// if multiple valid savegames with same UUID exist, only the most recent one is retained
|
||||||
if (!App.savegamePlayers.contains(playerUUID)) {
|
if (!App.savegamePlayers.contains(playerUUID)) {
|
||||||
App.savegamePlayers[playerUUID] = it
|
App.savegamePlayers[playerUUID] = collection
|
||||||
App.savegamePlayersName[playerUUID] = it.getDiskName(Common.CHARSET)
|
App.savegamePlayersName[playerUUID] = it.getDiskName(Common.CHARSET)
|
||||||
App.sortedPlayers.add(playerUUID)
|
App.sortedPlayers.add(playerUUID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println("SortedPlayers...")
|
||||||
|
App.sortedPlayers.forEach {
|
||||||
|
println(it)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -880,3 +897,11 @@ fun checkForSavegameDamage(skimmer: DiskSkimmer): Boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No lateinit!
|
||||||
|
*/
|
||||||
|
inline fun Disposable.tryDispose() {
|
||||||
|
try { this.dispose() }
|
||||||
|
catch (_: Throwable) {}
|
||||||
|
}
|
||||||
@@ -31,7 +31,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
"""
|
"""
|
||||||
const val DEFAULT_LOADORDER_FILE = """# Load Order
|
const val DEFAULT_LOADORDER_FILE = """# Load Order
|
||||||
# Modules are loaded from top to bottom.
|
# Modules are loaded from top to bottom.
|
||||||
# You can disable basegame, but we don't recommend.
|
# Name of the module corresponds with the name of the directory the module is stored in,
|
||||||
|
# typically under:
|
||||||
|
# 1. assets/mods of the installation path (the modules comes with the release of the game)
|
||||||
|
# 2. %APPDATA%/Modules (the modules installed by the user)
|
||||||
|
# where %APPDATA% is:
|
||||||
|
# Windows -- C:\Users\<username>\AppData\Roaming\Terrarum
|
||||||
|
# macOS -- /Users/<username>/Library/Application Support/Terrarum
|
||||||
|
# Linux -- /home/<username>/.Terrarum
|
||||||
|
# Please refrain from removing 'basegame' on the load order -- it may render the game unpalyable.
|
||||||
|
|
||||||
basegame
|
basegame
|
||||||
"""
|
"""
|
||||||
@@ -54,9 +62,12 @@ basegame
|
|||||||
* e.g. 0x02010034 will be translated as 2.1.52
|
* e.g. 0x02010034 will be translated as 2.1.52
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const val VERSION_RAW: Long = 0x0000_000003_000002
|
const val VERSION_RAW: Long = 0x0000_000003_000003
|
||||||
// Commit counts up to the Release 0.3.0: 2259
|
// Commit counts up to the Release 0.3.0: 2259
|
||||||
// Commit counts up to the Release 0.3.1: 2278
|
// Commit counts up to the Release 0.3.1: 2278
|
||||||
|
// Commit counts up to the Release 0.3.2: 2732
|
||||||
|
|
||||||
|
const val VERSION_TAG: String = "test001"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
// CONFIGURATION FOR TILE MAKER //
|
// CONFIGURATION FOR TILE MAKER //
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.badlogic.gdx.math.Matrix4
|
|||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
|
import net.torvald.terrarum.App.IS_DEVELOPMENT_BUILD
|
||||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||||
import net.torvald.terrarum.ui.BasicDebugInfoWindow
|
import net.torvald.terrarum.ui.BasicDebugInfoWindow
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
@@ -63,7 +64,7 @@ object TerrarumPostProcessor : Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun resize(w: Int, h: Int) {
|
fun resize(w: Int, h: Int) {
|
||||||
try { outFBO.dispose() } catch (_: UninitializedPropertyAccessException) {}
|
if (::outFBO.isInitialized) outFBO.tryDispose()
|
||||||
outFBO = FrameBuffer(Pixmap.Format.RGBA8888, w, h, false)
|
outFBO = FrameBuffer(Pixmap.Format.RGBA8888, w, h, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,10 +72,10 @@ object TerrarumPostProcessor : Disposable {
|
|||||||
batch.dispose()
|
batch.dispose()
|
||||||
shapeRenderer.dispose()
|
shapeRenderer.dispose()
|
||||||
functionRowHelper.dispose()
|
functionRowHelper.dispose()
|
||||||
try { lutTex.dispose() } catch (_: UninitializedPropertyAccessException) {}
|
|
||||||
shaderPostDither.dispose()
|
shaderPostDither.dispose()
|
||||||
shaderPostNoDither.dispose()
|
shaderPostNoDither.dispose()
|
||||||
outFBO.dispose()
|
if (::lutTex.isInitialized) lutTex.tryDispose()
|
||||||
|
if (::outFBO.isInitialized) outFBO.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var deltatBenchStr = "ΔF: Gathering data"
|
private var deltatBenchStr = "ΔF: Gathering data"
|
||||||
@@ -150,9 +151,10 @@ object TerrarumPostProcessor : Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// draw dev build notifiers
|
// draw dev build notifiers
|
||||||
if (App.IS_DEVELOPMENT_BUILD && Terrarum.ingame != null) {
|
// omitting this screws up HQ2X render for some reason
|
||||||
|
if (Terrarum.ingame != null) {
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.color = safeAreaCol
|
batch.color = if (IS_DEVELOPMENT_BUILD) safeAreaCol else colourNull
|
||||||
App.fontGame.draw(it, thisIsDebugStr, 5f, App.scr.height - 24f)
|
App.fontGame.draw(it, thisIsDebugStr, 5f, App.scr.height - 24f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,11 +170,11 @@ object TerrarumPostProcessor : Disposable {
|
|||||||
val average = tallies.average()
|
val average = tallies.average()
|
||||||
|
|
||||||
val halfPos = 0.5f * INGAME.deltaTeeBenchmarks.size
|
val halfPos = 0.5f * INGAME.deltaTeeBenchmarks.size
|
||||||
val halfInd = halfPos.floorInt()
|
val halfInd = halfPos.floorToInt()
|
||||||
val low5pos = 0.05f * INGAME.deltaTeeBenchmarks.size
|
val low5pos = 0.05f * INGAME.deltaTeeBenchmarks.size
|
||||||
val low5ind = low5pos.floorInt()
|
val low5ind = low5pos.floorToInt()
|
||||||
val low1pos = 0.01f * INGAME.deltaTeeBenchmarks.size
|
val low1pos = 0.01f * INGAME.deltaTeeBenchmarks.size
|
||||||
val low1ind = low1pos.floorInt()
|
val low1ind = low1pos.floorToInt()
|
||||||
|
|
||||||
val median = FastMath.interpolateLinear(halfPos - halfInd, tallies[halfInd], tallies[halfInd + 1])
|
val median = FastMath.interpolateLinear(halfPos - halfInd, tallies[halfInd], tallies[halfInd + 1])
|
||||||
val low5 = FastMath.interpolateLinear(low5pos - low5ind, tallies[low5ind], tallies[low5ind + 1])
|
val low5 = FastMath.interpolateLinear(low5pos - low5ind, tallies[low5ind], tallies[low5ind + 1])
|
||||||
@@ -192,39 +194,40 @@ object TerrarumPostProcessor : Disposable {
|
|||||||
return outFBO
|
return outFBO
|
||||||
}
|
}
|
||||||
private val rng = HQRNG()
|
private val rng = HQRNG()
|
||||||
|
private val colourNull = Color(0)
|
||||||
|
|
||||||
private fun Double.format(digits: Int) = "%.${digits}f".format(this)
|
private fun Double.format(digits: Int) = "%.${digits}f".format(this)
|
||||||
private fun Float.format(digits: Int) = "%.${digits}f".format(this)
|
private fun Float.format(digits: Int) = "%.${digits}f".format(this)
|
||||||
|
|
||||||
private val swizzler = intArrayOf(
|
private val swizzler = floatArrayOf(
|
||||||
1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1,
|
1f,0f,0f,0f, 0f,1f,0f,0f, 0f,0f,1f,0f, 0f,0f,0f,1f,
|
||||||
1,0,0,0, 0,1,0,0, 0,0,0,1, 0,0,1,0,
|
1f,0f,0f,0f, 0f,1f,0f,0f, 0f,0f,0f,1f, 0f,0f,1f,0f,
|
||||||
1,0,0,0, 0,0,1,0, 0,1,0,0, 0,0,0,1,
|
1f,0f,0f,0f, 0f,0f,1f,0f, 0f,1f,0f,0f, 0f,0f,0f,1f,
|
||||||
1,0,0,0, 0,0,1,0, 0,0,0,1, 0,1,0,0,
|
1f,0f,0f,0f, 0f,0f,1f,0f, 0f,0f,0f,1f, 0f,1f,0f,0f,
|
||||||
1,0,0,0, 0,0,0,1, 0,1,0,0, 0,0,1,0,
|
1f,0f,0f,0f, 0f,0f,0f,1f, 0f,1f,0f,0f, 0f,0f,1f,0f,
|
||||||
1,0,0,0, 0,0,0,1, 0,0,1,0, 0,1,0,0,
|
1f,0f,0f,0f, 0f,0f,0f,1f, 0f,0f,1f,0f, 0f,1f,0f,0f,
|
||||||
|
|
||||||
0,1,0,0, 1,0,0,0, 0,0,1,0, 0,0,0,1,
|
0f,1f,0f,0f, 1f,0f,0f,0f, 0f,0f,1f,0f, 0f,0f,0f,1f,
|
||||||
0,1,0,0, 1,0,0,0, 0,0,0,1, 0,0,1,0,
|
0f,1f,0f,0f, 1f,0f,0f,0f, 0f,0f,0f,1f, 0f,0f,1f,0f,
|
||||||
0,1,0,0, 0,0,1,0, 1,0,0,0, 0,0,0,1,
|
0f,1f,0f,0f, 0f,0f,1f,0f, 1f,0f,0f,0f, 0f,0f,0f,1f,
|
||||||
0,1,0,0, 0,0,1,0, 0,0,0,1, 1,0,0,0,
|
0f,1f,0f,0f, 0f,0f,1f,0f, 0f,0f,0f,1f, 1f,0f,0f,0f,
|
||||||
0,1,0,0, 0,0,0,1, 1,0,0,0, 0,0,1,0,
|
0f,1f,0f,0f, 0f,0f,0f,1f, 1f,0f,0f,0f, 0f,0f,1f,0f,
|
||||||
0,1,0,0, 0,0,0,1, 0,0,1,0, 1,0,0,0,
|
0f,1f,0f,0f, 0f,0f,0f,1f, 0f,0f,1f,0f, 1f,0f,0f,0f,
|
||||||
|
|
||||||
0,0,1,0, 1,0,0,0, 0,1,0,0, 0,0,0,1,
|
0f,0f,1f,0f, 1f,0f,0f,0f, 0f,1f,0f,0f, 0f,0f,0f,1f,
|
||||||
0,0,1,0, 1,0,0,0, 0,0,0,1, 0,1,0,0,
|
0f,0f,1f,0f, 1f,0f,0f,0f, 0f,0f,0f,1f, 0f,1f,0f,0f,
|
||||||
0,0,1,0, 0,1,0,0, 1,0,0,0, 0,0,0,1,
|
0f,0f,1f,0f, 0f,1f,0f,0f, 1f,0f,0f,0f, 0f,0f,0f,1f,
|
||||||
0,0,1,0, 0,1,0,0, 0,0,0,1, 1,0,0,0,
|
0f,0f,1f,0f, 0f,1f,0f,0f, 0f,0f,0f,1f, 1f,0f,0f,0f,
|
||||||
0,0,1,0, 0,0,0,1, 1,0,0,0, 0,1,0,0,
|
0f,0f,1f,0f, 0f,0f,0f,1f, 1f,0f,0f,0f, 0f,1f,0f,0f,
|
||||||
0,0,1,0, 0,0,0,1, 0,1,0,0, 1,0,0,0,
|
0f,0f,1f,0f, 0f,0f,0f,1f, 0f,1f,0f,0f, 1f,0f,0f,0f,
|
||||||
|
|
||||||
0,0,0,1, 1,0,0,0, 0,1,0,0, 0,0,1,0,
|
0f,0f,0f,1f, 1f,0f,0f,0f, 0f,1f,0f,0f, 0f,0f,1f,0f,
|
||||||
0,0,0,1, 1,0,0,0, 0,0,1,0, 0,1,0,0,
|
0f,0f,0f,1f, 1f,0f,0f,0f, 0f,0f,1f,0f, 0f,1f,0f,0f,
|
||||||
0,0,0,1, 0,1,0,0, 1,0,0,0, 0,0,1,0,
|
0f,0f,0f,1f, 0f,1f,0f,0f, 1f,0f,0f,0f, 0f,0f,1f,0f,
|
||||||
0,0,0,1, 0,1,0,0, 0,0,1,0, 1,0,0,0,
|
0f,0f,0f,1f, 0f,1f,0f,0f, 0f,0f,1f,0f, 1f,0f,0f,0f,
|
||||||
0,0,0,1, 0,0,1,0, 1,0,0,0, 0,1,0,0,
|
0f,0f,0f,1f, 0f,0f,1f,0f, 1f,0f,0f,0f, 0f,1f,0f,0f,
|
||||||
0,0,0,1, 0,0,1,0, 0,1,0,0, 1,0,0,0,
|
0f,0f,0f,1f, 0f,0f,1f,0f, 0f,1f,0f,0f, 1f,0f,0f,0f,
|
||||||
).map { it.toFloat() }.toFloatArray()
|
)
|
||||||
|
|
||||||
private fun postShader(projMat: Matrix4, fbo: FrameBuffer) {
|
private fun postShader(projMat: Matrix4, fbo: FrameBuffer) {
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package net.torvald.terrarum
|
package net.torvald.terrarum
|
||||||
|
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
|
import kotlin.math.max
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
|
class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val minimumW = 1080
|
const val minimumW = 1024
|
||||||
const val minimumH = 720
|
const val minimumH = 720
|
||||||
const val defaultW = 1280
|
const val defaultW = 1280
|
||||||
const val defaultH = 720
|
const val defaultH = 720
|
||||||
@@ -33,14 +34,16 @@ class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
|
|||||||
val tvSafeActionWidth: Int; get() = Math.round(width * TV_SAFE_ACTION)
|
val tvSafeActionWidth: Int; get() = Math.round(width * TV_SAFE_ACTION)
|
||||||
val tvSafeActionHeight: Int; get() = Math.round(height * TV_SAFE_ACTION)
|
val tvSafeActionHeight: Int; get() = Math.round(height * TV_SAFE_ACTION)
|
||||||
|
|
||||||
|
/** Apparent window size. `roundToEven(width * magn)` */
|
||||||
var windowW: Int = 0; private set
|
var windowW: Int = 0; private set
|
||||||
|
/** Apparent window size. `roundToEven(height * magn)` */
|
||||||
var windowH: Int = 0; private set
|
var windowH: Int = 0; private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setDimension(maxOf(minimumW, scrw), maxOf(minimumH, scrh), App.getConfigDouble("screenmagnifying").toFloat(), maxOf(minimumW, scrw), maxOf(minimumH, scrh))
|
setDimension(max(minimumW, scrw), max(minimumH, scrh), App.getConfigDouble("screenmagnifying").toFloat())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDimension(scrw: Int, scrh: Int, magn: Float, ww: Int, wh: Int) {
|
fun setDimension(scrw: Int, scrh: Int, magn: Float,) {
|
||||||
width = scrw and 0x7FFFFFFE
|
width = scrw and 0x7FFFFFFE
|
||||||
height = scrh and 0x7FFFFFFE
|
height = scrh and 0x7FFFFFFE
|
||||||
wf = scrw.toFloat()
|
wf = scrw.toFloat()
|
||||||
@@ -54,11 +57,11 @@ class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
|
|||||||
|
|
||||||
this.magn = magn
|
this.magn = magn
|
||||||
|
|
||||||
windowW = ww
|
windowW = (scrw * magn).ceilToInt() and 0x7FFFFFFE
|
||||||
windowH = wh
|
windowH = (scrh * magn).ceilToInt() and 0x7FFFFFFE
|
||||||
|
|
||||||
|
|
||||||
printdbg(this, "Window dim: $ww x $wh, called by:")
|
printdbg(this, "Window dim: $windowW x $windowH, called by:")
|
||||||
printStackTrace(this)
|
printStackTrace(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ class UIItemInventoryCatBar(
|
|||||||
// set up underlined indicator
|
// set up underlined indicator
|
||||||
init {
|
init {
|
||||||
// procedurally generate texture
|
// procedurally generate texture
|
||||||
val pixmap = Pixmap(catIcons.tileW + buttonGapSize.floorInt(), 1, Pixmap.Format.RGBA8888)
|
val pixmap = Pixmap(catIcons.tileW + buttonGapSize.floorToInt(), 1, Pixmap.Format.RGBA8888)
|
||||||
for (x in 0 until pixmap.width.plus(1).ushr(1)) { // eqv. of ceiling the half-int
|
for (x in 0 until pixmap.width.plus(1).ushr(1)) { // eqv. of ceiling the half-int
|
||||||
val col = /*if (x == 0)*/ /*0xffffff_80.toInt()*/
|
val col = /*if (x == 0)*/ /*0xffffff_80.toInt()*/
|
||||||
/*else if (x == 1)*/ /*0xffffff_c0.toInt()*/
|
/*else if (x == 1)*/ /*0xffffff_c0.toInt()*/
|
||||||
|
|||||||
@@ -209,8 +209,8 @@ class BlockCodex {
|
|||||||
prop.isSolid = record.boolVal("solid")
|
prop.isSolid = record.boolVal("solid")
|
||||||
//prop.isClear = record.boolVal("clear")
|
//prop.isClear = record.boolVal("clear")
|
||||||
|
|
||||||
prop.isPlatform = prop.tags.contains("PLATFORM")
|
prop.isPlatform = prop.hasTag("PLATFORM")
|
||||||
prop.isActorBlock = prop.tags.contains("ACTORBLOCK")
|
prop.isActorBlock = prop.hasTag("ACTORBLOCK")
|
||||||
|
|
||||||
prop.isWallable = record.boolVal("wall")
|
prop.isWallable = record.boolVal("wall")
|
||||||
prop.maxSupport = record.intVal("grav")
|
prop.maxSupport = record.intVal("grav")
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user