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/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="$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/prtree.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-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="$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="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk8.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.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="$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/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/annotations/13.0/annotations-13.0.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/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/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>
|
||||
</artifact>
|
||||
</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
|
||||
|
||||
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 kotlin.coroutines.*
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
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.FixtureBase
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.modulecomputers.ui.UIHomeComputer
|
||||
import net.torvald.tsvm.*
|
||||
import net.torvald.tsvm.peripheral.AdapterConfig
|
||||
import net.torvald.tsvm.peripheral.GraphicsAdapter
|
||||
import net.torvald.tsvm.peripheral.VMProgramRom
|
||||
import net.torvald.unicode.*
|
||||
|
||||
/**
|
||||
* 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",
|
||||
"t":dislplayKeyLayouts,
|
||||
"l":"bgBG",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,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
|
||||
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",
|
||||
"tf":states.layouttable,
|
||||
"l":"elGR",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin,lowlayerkey)=>{
|
||||
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",
|
||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||
"l":"koKR",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
states.code = 1
|
||||
|
||||
let s = states.keylayouts[headkey][layer]
|
||||
let s = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||
|
||||
if (isHangul(s)) {
|
||||
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",
|
||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||
"l":"koKR",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
states.code = 1
|
||||
|
||||
let s = states.keylayouts[headkey][layer]
|
||||
let s = states.keylayouts[headkey][layer] || states.keylayouts[headkey][0]
|
||||
|
||||
if (isHangul(s)) {
|
||||
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",
|
||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||
"l":"koKR",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
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
|
||||
|
||||
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",
|
||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||
"l":"koKR",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
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
|
||||
|
||||
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",
|
||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||
"l":"koKR",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
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 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",
|
||||
"t":states.keylayouts.map(it => [it[0],it[1]]),
|
||||
"l":"koKR",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
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 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",
|
||||
"t":states.keylayouts,
|
||||
"l":"ruRU",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,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
|
||||
if (isDiacritics(s)) {
|
||||
|
||||
@@ -27,7 +27,7 @@ let states = {"keylayouts":[[""],[undefined],
|
||||
[undefined],
|
||||
[undefined],
|
||||
["ф","Ф","ƒ","ƒ"],
|
||||
["и","И"],
|
||||
["и","И","и","И"],
|
||||
["с","С","≠","≠"],
|
||||
["в","В","ћ","Ћ"],
|
||||
["у","У","ќ","Ќ"],
|
||||
@@ -69,10 +69,10 @@ let states = {"keylayouts":[[""],[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",
|
||||
"t":states.keylayouts,
|
||||
"l":"ruRU",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin + 2*altgrin
|
||||
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)) {
|
||||
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",
|
||||
"tf":states.layouttable,
|
||||
"l":"ruRU",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin,lowlayerkey)=>{
|
||||
let layer = 1*shiftin// + 2*altgrin
|
||||
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",
|
||||
"t":states.keylayouts,
|
||||
"l":"thTH",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin + 2*altgrin // use AltGr to type conventional numbers
|
||||
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]
|
||||
},
|
||||
"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",
|
||||
"t":states.keylayouts,
|
||||
"l":"thTH",
|
||||
// return: [displayed output, composed output]
|
||||
// return: [delete count, composed output]
|
||||
"accept":(headkey,shiftin,altgrin)=>{
|
||||
let layer = 1*shiftin + 2*altgrin // use AltGr to type conventional numbers
|
||||
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]
|
||||
},
|
||||
"backspace":()=>{
|
||||
|
||||
@@ -276,7 +276,7 @@ return Object.freeze({"n":"五仓简体 Qwerty","v":"many","c":"CuriousTo\uA75Bv
|
||||
"accept":(headkey,shiftin,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)
|
||||
|
||||
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)=>{
|
||||
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)
|
||||
|
||||
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",
|
||||
"MENU_LABEL_COPYRIGHT": "Copyright",
|
||||
"CONTEXT_TIME_MINUTE_PLURAL": "Minutes",
|
||||
"CONTEXT_TIME_SECOND_PLURAL": "Seconds",
|
||||
"COPYRIGHT_ALL_RIGHTS_RESERVED": "All rights reserved",
|
||||
"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_ZOOM" : "Zoom",
|
||||
"MENU_LABEL_RESET" : "Reset",
|
||||
"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_AUTOSAVE": "Autosave",
|
||||
"MENU_IO_IMPORT": "Import",
|
||||
"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",
|
||||
"MENU_IO_MANUAL_SAVE": "Manual Save",
|
||||
"MENU_LABEL_COPYRIGHT": "Copyright",
|
||||
"MENU_LABEL_DELETE": "Delete",
|
||||
"MENU_LABEL_EXTRA_JVM_ARGUMENTS": "Extra Arguments",
|
||||
"MENU_LABEL_IME": "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_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_ZOOM" : "ज़ूम",
|
||||
"MENU_LABEL_RESET" : "रीसेट",
|
||||
"MENU_OPTION_STREAMERS_LAYOUT": "Chat Overlay",
|
||||
"MENU_OPTIONS_STREAMERS_LAYOUT": "Chat Overlay",
|
||||
"MENU_LABEL_RESTART_REQUIRED": "पुनः शुरआत जरुरी है",
|
||||
"MENU_LABEL_KEYBOARD_LAYOUT": "कीबोर्ड विन्यास",
|
||||
"MENU_LABEL_IME": "इनपुट विधि",
|
||||
|
||||
@@ -2335,7 +2335,7 @@
|
||||
},
|
||||
{
|
||||
"n": "MENU_OPTIONS",
|
||||
"s": "Stillingar "
|
||||
"s": "Valkostir "
|
||||
},
|
||||
{
|
||||
"n": "MENU_OPTIONS_ADVANCEDGRAPHICS",
|
||||
@@ -2395,11 +2395,11 @@
|
||||
},
|
||||
{
|
||||
"n": "MENU_OPTIONS_GAMEPLAY",
|
||||
"s": "Gameplay Options"
|
||||
"s": "Leikvalkostir"
|
||||
},
|
||||
{
|
||||
"n": "MENU_OPTIONS_GRAPHICS",
|
||||
"s": "Grafíkstillingar"
|
||||
"s": "Grafíkvalkostir"
|
||||
},
|
||||
{
|
||||
"n": "MENU_OPTIONS_HUD",
|
||||
|
||||
@@ -15,5 +15,15 @@
|
||||
"MENU_OPTIONS_DITHER": "Dither",
|
||||
"MENU_OPTIONS_BLUR": "Óskýrt",
|
||||
"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": "캐릭터",
|
||||
"MENU_LABEL_COPYRIGHT": "저작권",
|
||||
"CONTEXT_TIME_MINUTE_PLURAL": "분",
|
||||
"CONTEXT_TIME_SECOND_PLURAL": "초",
|
||||
"COPYRIGHT_ALL_RIGHTS_RESERVED": "모든 권리 보유",
|
||||
"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_ZOOM" : "확대·축소",
|
||||
"MENU_LABEL_RESET" : "재설정",
|
||||
"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_AUTOSAVE": "자동 저장",
|
||||
"MENU_IO_IMPORT": "가져오기",
|
||||
"APP_NOMODULE_1": "현재 불러와진 모듈이 없습니다.",
|
||||
"APP_NOMODULE_2": "다음의 파일에서 불러오기 순서를 설정하고 게임을 재시작하십시오.",
|
||||
"MENU_LABEL_KEYCONFIG_HELP1": "키캡을 클릭해 컨트롤을 배정하십시오",
|
||||
"MENU_IO_MANUAL_SAVE": "수동 저장",
|
||||
"MENU_LABEL_COPYRIGHT": "저작권",
|
||||
"MENU_LABEL_DELETE": "삭제",
|
||||
"MENU_LABEL_EXTRA_JVM_ARGUMENTS": "추가 명령 인수",
|
||||
"MENU_LABEL_IME": "입력기",
|
||||
"MENU_LABEL_IME_TOGGLE": "입력기 켜고 끄기",
|
||||
"MENU_LABEL_KEYBOARD_LAYOUT": "자판 배열",
|
||||
"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_WARNING2": "请下载并安装最新的64位Java :",
|
||||
"GAME_32BIT_WARNING3": "https://www.java.com/en/download/",
|
||||
"MENU_OPTION_STREAMERS_LAYOUT": "聊天叠加",
|
||||
"MENU_OPTIONS_STREAMERS_LAYOUT": "聊天叠加",
|
||||
"MENU_LABEL_RESTART_REQUIRED": "需要重新启动",
|
||||
"MENU_LABEL_KEYBOARD_LAYOUT": "键盘布局",
|
||||
"MENU_LABEL_IME": "输入法",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"GAME_32BIT_WARNING1": "看起來您正在運行32位版本的Java。",
|
||||
"GAME_32BIT_WARNING2": "請下載並安裝最新的64位Java :",
|
||||
"GAME_32BIT_WARNING3": "https://www.java.com/en/download/",
|
||||
"MENU_OPTION_STREAMERS_LAYOUT": "聊天疊加",
|
||||
"MENU_OPTIONS_STREAMERS_LAYOUT": "聊天疊加",
|
||||
"MENU_LABEL_RESTART_REQUIRED": "需要重新啟動",
|
||||
"MENU_LABEL_KEYBOARD_LAYOUT": "鍵盤配置",
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
@@ -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"
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
"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,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,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,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,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,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"
|
||||
"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"
|
||||
@@ -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"
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
"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,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,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,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"
|
||||
"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"
|
||||
@@ -188,6 +188,7 @@
|
||||
## 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.
|
||||
## - 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 ##
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 179 and column 37.
|
@@ -22,6 +22,8 @@ Seed
|
||||
SetAV
|
||||
SetBulletin
|
||||
SetScale
|
||||
SetSol
|
||||
SetTurb
|
||||
SetTime
|
||||
SetTimeDelta
|
||||
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
|
||||
9;net.torvald.terrarum.modulebasegame.gameitems.WireCutterAll
|
||||
10;net.torvald.terrarum.modulebasegame.gameitems.ItemTypewriter
|
||||
11;net.torvald.terrarum.modulebasegame.gameitems.ItemWallCalendar
|
||||
|
||||
256;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorOak
|
||||
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",
|
||||
"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",
|
||||
"CONTEXT_GENERATOR_SEED": "Seed",
|
||||
"MENU_LABEL_PREV_SAVES": "Previous Saves",
|
||||
"MENU_LABEL_RENAME": "Rename",
|
||||
"GAME_ACTION_CRAFT": "Craft",
|
||||
"GAME_ACTION_GRAPPLE": "Grapple",
|
||||
"GAME_ACTION_QUICKSEL": "Quick Select",
|
||||
"GAME_ACTION_CRAFT": "Craft",
|
||||
"GAME_CRAFTING": "Crafting",
|
||||
"GAME_ACTION_TELEPORT": "Teleport",
|
||||
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
|
||||
"CONTEXT_WORLD_SEARCH": "World Search",
|
||||
"CONTEXT_WORLD_LIST": "Worlds List",
|
||||
"MENU_LABEL_RENAME": "Rename"
|
||||
"GAME_CRAFTING": "Crafting",
|
||||
"GAME_INVENTORY_BLOCKS": "Blocks",
|
||||
"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_FULL_COLLISION": "Urist Berdanrifot",
|
||||
"ACTORBLOCK_NO_COLLISION": "Urist Zafal",
|
||||
"ACTORBLOCK_NO_PASS_RIGHT": "Urist McPassLeft",
|
||||
"ACTORBLOCK_NO_PASS_LEFT": "Urist McPassRight",
|
||||
"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"
|
||||
"ACTORBLOCK_TILING_PLACEHOLDER": "Urist Berdanurdim"
|
||||
}
|
||||
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": "새 세계",
|
||||
"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": "메뉴",
|
||||
"CONTEXT_ITEM_MAP": "지도",
|
||||
"CONTEXT_GENERATOR_SEED": "시드",
|
||||
"MENU_LABEL_PREV_SAVES": "이전 세이브",
|
||||
"MENU_LABEL_RENAME": "이름 바꾸기",
|
||||
"MENU_MONITOR_CALI_TITLE": "모니터 확인",
|
||||
"GAME_ACTION_CRAFT": "제작하기",
|
||||
"GAME_ACTION_GRAPPLE": "매달리기",
|
||||
"GAME_ACTION_QUICKSEL": "빠른 선택",
|
||||
"GAME_ACTION_CRAFT": "제작하기",
|
||||
"GAME_ACTION_TELEPORT": "텔레포트하기",
|
||||
"GAME_CRAFTABLE_ITEMS": "제작 가능한 아이템",
|
||||
"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_STONE_MARBLE": "대리석",
|
||||
|
||||
"ITEM_STORAGE_CHEST": "보관상자",
|
||||
"ITEM_WIRE": "전선",
|
||||
"ITEM_WIRE_CUTTER": "전선 절단기",
|
||||
"ITEM_CALENDAR": "달력",
|
||||
"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",
|
||||
"daylightClut": "clut_daylight.tga",
|
||||
"classification": "generic",
|
||||
"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
|
||||
|
||||
# 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
|
||||
cp -r "../assets_release" $DESTDIR/
|
||||
mv $DESTDIR/assets_release $DESTDIR/assets
|
||||
cp -r "../out/TerrarumBuild.jar" $DESTDIR/assets/
|
||||
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
|
||||
|
||||
# Pack everything to AppImage
|
||||
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
|
||||
|
||||
# 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
|
||||
cp -r "../assets_release" $DESTDIR/
|
||||
mv $DESTDIR/assets_release $DESTDIR/assets
|
||||
cp -r "../out/TerrarumBuild.jar" $DESTDIR/assets/
|
||||
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
|
||||
|
||||
# Pack everything to AppImage
|
||||
"./$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%/*}"
|
||||
SRCFILES="terrarummac_arm"
|
||||
DESTDIR="out/TerrarumMac.arm.app"
|
||||
APPDIR="./TerrarumMac.arm.app"
|
||||
DESTDIR="out/$APPDIR"
|
||||
RUNTIME="runtime-osx-arm"
|
||||
|
||||
if [ ! -d "../assets_release" ]; then
|
||||
@@ -25,11 +26,17 @@ cp $SRCFILES/Terrarum.sh $DESTDIR/Contents/MacOS/
|
||||
chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
|
||||
|
||||
# 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
|
||||
cp -r "../assets_release" $DESTDIR/Contents/MacOS/
|
||||
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"
|
||||
|
||||
@@ -3,7 +3,8 @@ if (( $EUID == 0 )); then echo "The build process is not meant to be run with ro
|
||||
|
||||
cd "${0%/*}"
|
||||
SRCFILES="terrarummac_x86"
|
||||
DESTDIR="out/TerrarumMac.x86.app"
|
||||
APPDIR="./TerrarumMac.x86.app"
|
||||
DESTDIR="out/$APPDIR"
|
||||
RUNTIME="runtime-osx-x86"
|
||||
|
||||
if [ ! -d "../assets_release" ]; then
|
||||
@@ -25,11 +26,17 @@ cp $SRCFILES/Terrarum.sh $DESTDIR/Contents/MacOS/
|
||||
chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
|
||||
|
||||
# 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
|
||||
cp -r "../assets_release" $DESTDIR/Contents/MacOS/
|
||||
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"
|
||||
|
||||
@@ -16,15 +16,23 @@ rm -rf $DESTDIR || true
|
||||
mkdir $DESTDIR
|
||||
|
||||
# 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
|
||||
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
|
||||
cp -r "../assets_release" $DESTDIR/
|
||||
mv $DESTDIR/assets_release $DESTDIR/assets
|
||||
cp -r "../out/TerrarumBuild.jar" $DESTDIR/assets/
|
||||
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
|
||||
|
||||
# Temporary solution: zip everything
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
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.
|
||||
* Basically: ((1 - percent) * startValue) + (percent * endValue)
|
||||
@@ -231,6 +244,10 @@ final public class FastMath {
|
||||
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.
|
||||
* here is the interpolation matrix
|
||||
* 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) {
|
||||
return interpolateHermite(scale, p0, p1, p2, p3, 1f, 0f);
|
||||
}
|
||||
public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3, float tension, float bias) {
|
||||
// return interpolateHermite(scale, p0, p1, p2, p3, 0f, 0f);
|
||||
float mu2 = scale * scale;
|
||||
float mu3 = mu2 * scale;
|
||||
float biasTensionTerms = 0.5f;//(1f + bias) * (1f - tension) / 2f;
|
||||
|
||||
float m0 = (p1 - p0) * (1f + bias) * (1f - tension) / 2f;
|
||||
m0 += (p2 - p1) * (1f + bias) * (1f - tension) / 2f;
|
||||
float m1 = (p2 - p1) * (1f + bias) * (1f - tension) / 2f;
|
||||
m1 += (p3 - p2) * (1f + bias) * (1f - tension) / 2f;
|
||||
float m0 = (p1 - p0) * biasTensionTerms;
|
||||
float mTemp = (p2 - p1) * biasTensionTerms;
|
||||
m0 += mTemp;
|
||||
float m1 = mTemp;
|
||||
m1 += (p3 - p2) * biasTensionTerms;
|
||||
|
||||
float a0 = 2 * mu3 - 3 * mu2 + 1;
|
||||
float a1 = mu3 - 2 * mu2 + scale;
|
||||
float a2 = mu3 - mu2;
|
||||
float a3 = -2 * mu3 + 3 * mu2;
|
||||
float a0 = 2*mu3 - 3*mu2 + 1;
|
||||
float a1 = 1*mu3 - 2*mu2 + scale;
|
||||
float a2 = 1*mu3 - 1*mu2 + 0;
|
||||
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
|
||||
* into half precision (16 bit).
|
||||
@@ -871,31 +867,6 @@ final public class FastMath {
|
||||
| ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
|
||||
| ((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) {
|
||||
while (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 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])
|
||||
}
|
||||
@@ -123,7 +123,7 @@ fun RGB.linearise(): RGB {
|
||||
}
|
||||
val step = value.clampOne() * 255f // 0.0 .. 255.0
|
||||
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])
|
||||
}
|
||||
@@ -192,6 +192,16 @@ fun CIEXYZ.toColorRaw(): Color {
|
||||
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 {
|
||||
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.badlogic.gdx.graphics.Color
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* OBSOLETE; use CIELchUtil for natural-looking colour
|
||||
@@ -75,8 +77,8 @@ object HSVUtil {
|
||||
val g = color.g
|
||||
val b = color.b
|
||||
|
||||
val rgbMin = FastMath.min(r, g, b)
|
||||
val rgbMax = FastMath.max(r, g, b)
|
||||
val rgbMin = min(min(r, g), b)
|
||||
val rgbMax = max(max(r, g), b)
|
||||
|
||||
var h: Float
|
||||
val s: Float
|
||||
|
||||
@@ -110,7 +110,7 @@ public class HUSLColorConverter {
|
||||
float x = intersectLineLine(line, new float[]{-1 / m1, 0});
|
||||
float length = distanceFromPole(new float[]{x, b1 + x * m1});
|
||||
|
||||
min = FastMath.min(min, length);
|
||||
min = Math.min(min, length);
|
||||
}
|
||||
|
||||
return min;
|
||||
@@ -125,7 +125,7 @@ public class HUSLColorConverter {
|
||||
for (float[] bound : bounds) {
|
||||
Length length = lengthOfRayUntilIntersect(hrad, bound);
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
* @param r the red component
|
||||
|
||||
@@ -104,10 +104,10 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) {
|
||||
// operators
|
||||
fun max(x: Int, y: Int, other: Cvec) {
|
||||
val a = toAddr(x, y)
|
||||
array.setFloat(a + 0, maxOf(array.getFloat(a + 0), other.r))
|
||||
array.setFloat(a + 1, maxOf(array.getFloat(a + 1), other.g))
|
||||
array.setFloat(a + 2, maxOf(array.getFloat(a + 2), other.b))
|
||||
array.setFloat(a + 3, maxOf(array.getFloat(a + 3), other.a))
|
||||
array.setFloat(a + 0, kotlin.math.max(array.getFloat(a + 0), other.r))
|
||||
array.setFloat(a + 1, kotlin.math.max(array.getFloat(a + 1), other.g))
|
||||
array.setFloat(a + 2, kotlin.math.max(array.getFloat(a + 2), other.b))
|
||||
array.setFloat(a + 3, kotlin.math.max(array.getFloat(a + 3), other.a))
|
||||
}
|
||||
fun mul(x: Int, y: Int, scalar: Float) {
|
||||
val a = toAddr(x, y)
|
||||
@@ -202,10 +202,10 @@ internal class TestCvecArr(val width: Int, val height: Int) {
|
||||
|
||||
// operators
|
||||
inline fun max(x: Int, y: Int, other: Cvec) {
|
||||
setR(x, y, maxOf(getR(x, y), other.r))
|
||||
setG(x, y, maxOf(getG(x, y), other.g))
|
||||
setB(x, y, maxOf(getB(x, y), other.b))
|
||||
setA(x, y, maxOf(getA(x, y), other.a))
|
||||
setR(x, y, kotlin.math.max(getR(x, y), other.r))
|
||||
setG(x, y, kotlin.math.max(getG(x, y), other.g))
|
||||
setB(x, y, kotlin.math.max(getB(x, y), other.b))
|
||||
setA(x, y, kotlin.math.max(getA(x, y), other.a))
|
||||
}
|
||||
inline fun mul(x: Int, y: Int, scalar: Float) {
|
||||
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.colourutil.*
|
||||
import net.torvald.parametricsky.datasets.DatasetCIEXYZ
|
||||
import net.torvald.parametricsky.datasets.DatasetRGB
|
||||
import net.torvald.parametricsky.datasets.DatasetSpectral
|
||||
import net.torvald.terrarum.abs
|
||||
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.modulebasegame.worldgenerator.HALF_PI
|
||||
import net.torvald.terrarum.modulebasegame.worldgenerator.TWO_PI
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
import java.lang.Math.pow
|
||||
import javax.swing.*
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.*
|
||||
|
||||
|
||||
const val WIDTH = 1200
|
||||
const val HEIGHT = 600
|
||||
val INITIAL_TURBIDITY = 4.0
|
||||
val INITIAL_ALBEDO = 0.1
|
||||
val INITIAL_ELEV = 0.0
|
||||
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* 1. Canvas Y (theta)
|
||||
@@ -53,12 +65,12 @@ class Application : Game() {
|
||||
private lateinit var oneScreen: Pixmap
|
||||
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 albedo = 0.1
|
||||
var elevation = 0.0
|
||||
var scalefactor = 1f
|
||||
var solarBearing = Math.toRadians(90.0)
|
||||
var cameraHeading = Math.toRadians(90.0)
|
||||
|
||||
override fun getScreen(): Screen {
|
||||
return super.getScreen()
|
||||
@@ -68,20 +80,38 @@ class Application : Game() {
|
||||
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() {
|
||||
Gdx.graphics.setTitle("Daylight Model $EMDASH F: ${Gdx.graphics.framesPerSecond}")
|
||||
|
||||
if (turbidity <= 0) throw IllegalStateException()
|
||||
|
||||
// we need to use different modelstate to accomodate different albedo for each spectral band but oh well...
|
||||
genTexLoop(ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation))
|
||||
// we need to use different model-state to accommodate different albedo for each spectral band but oh well...
|
||||
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)
|
||||
tex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
||||
tex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||
|
||||
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()
|
||||
@@ -103,14 +133,48 @@ class Application : Game() {
|
||||
oneScreen.dispose()
|
||||
}
|
||||
|
||||
val outTexWidth = 256
|
||||
val outTexHeight = 256
|
||||
val outTexWidth = 1
|
||||
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;
|
||||
* 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 {
|
||||
var v = y.coerceAtLeast(0.0)
|
||||
@@ -120,20 +184,49 @@ class Application : Game() {
|
||||
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(
|
||||
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 0).toFloat().times(scalefactor / 10f),
|
||||
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 1).toFloat().times(scalefactor / 10f),
|
||||
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 2).toFloat().times(scalefactor / 10f)
|
||||
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 0).toFloat(),
|
||||
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 1).toFloat(),
|
||||
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
|
||||
|
||||
/*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.drawPixel(x, y)
|
||||
|
||||
@@ -142,140 +235,148 @@ class Application : Game() {
|
||||
|
||||
}
|
||||
|
||||
ymaxDisp.text = "${ys.max()}"
|
||||
ymaxDisp2.text = "${ys2.max()}"
|
||||
|
||||
//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() {
|
||||
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
|
||||
DatasetRGB
|
||||
// DatasetRGB
|
||||
|
||||
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(5.0, 1.0, 10.0, 0.1))
|
||||
val albedoControl = JSpinner(SpinnerNumberModel(0.1, 0.0, 1.0, 0.05))
|
||||
val elevationControl = JSpinner(SpinnerNumberModel(0.0, 0.0, 90.0, 0.5))
|
||||
val scalefactorControl = JSpinner(SpinnerNumberModel(1.0, 0.0, 2.0, 0.01))
|
||||
val turbidityControl = JSpinner(SpinnerNumberModel(INITIAL_TURBIDITY, 1.0, 10.0, 0.1)).also {
|
||||
it.preferredSize = dialSize
|
||||
it.addChangeListener { _ ->
|
||||
app.turbidity = it.value as Double
|
||||
app.regenerateModel()
|
||||
}
|
||||
}
|
||||
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 {
|
||||
val turbidityPanel = JPanel()
|
||||
val albedoPanel = JPanel()
|
||||
val elevationPanel = JPanel()
|
||||
val scalefactorPanel = JPanel()
|
||||
val atmosPanel = JPanel()
|
||||
val turbidityPanel = JPanel().also {
|
||||
it.add(JLabel("Turbidity (log_2)"))
|
||||
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)
|
||||
albedoControl.preferredSize = Dimension(45, 18)
|
||||
elevationControl.preferredSize = Dimension(45, 18)
|
||||
scalefactorControl.preferredSize = Dimension(45, 18)
|
||||
val sunPanel = JPanel()
|
||||
val elevationPanel = JPanel().also {
|
||||
it.add(JLabel("Elevation"))
|
||||
it.add(elevationControl)
|
||||
sunPanel.add(it)
|
||||
}
|
||||
val scalefactorPanel = JPanel().also {
|
||||
it.add(JLabel("Bearing"))
|
||||
it.add(solarBearing)
|
||||
sunPanel.add(it)
|
||||
}
|
||||
|
||||
turbidityPanel.add(JLabel("Turbidity"))
|
||||
turbidityPanel.add(turbidityControl)
|
||||
val cameraPanel = JPanel()
|
||||
val headingPanel = JPanel().also {
|
||||
it.add(JLabel("Heading"))
|
||||
it.add(cameraHeading)
|
||||
cameraPanel.add(it)
|
||||
}
|
||||
|
||||
albedoPanel.add(JLabel("Albedo"))
|
||||
albedoPanel.add(albedoControl)
|
||||
val statsPanel = JPanel()
|
||||
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"))
|
||||
elevationPanel.add(elevationControl)
|
||||
val mainPanel = JPanel()
|
||||
|
||||
scalefactorPanel.add(JLabel("Scaling Factor"))
|
||||
scalefactorPanel.add(scalefactorControl)
|
||||
|
||||
mainPanel.add(turbidityPanel)
|
||||
mainPanel.add(albedoPanel)
|
||||
mainPanel.add(elevationPanel)
|
||||
mainPanel.add(scalefactorPanel)
|
||||
mainPanel.layout = BoxLayout(mainPanel, BoxLayout.Y_AXIS)
|
||||
JPanel().also {
|
||||
it.layout = BorderLayout()
|
||||
it.add(JPanel().also { it.add(JLabel("Atmosphere")) }, BorderLayout.NORTH)
|
||||
it.add(atmosPanel, BorderLayout.CENTER)
|
||||
it.add(JSeparator(), BorderLayout.SOUTH)
|
||||
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.defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
|
||||
this.size = Dimension(300, 400)
|
||||
|
||||
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()
|
||||
}
|
||||
this.size = Dimension(300, 600)
|
||||
this.add(mainPanel, BorderLayout.CENTER)
|
||||
|
||||
}
|
||||
|
||||
@@ -285,7 +386,10 @@ class Application : Game() {
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
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 fis = FileInputStream(file)
|
||||
|
||||
val inputbuf = ByteArray(8)
|
||||
val ret = DoubleArray(entrysize) {
|
||||
val inputbuf = ByteArray(8)
|
||||
fis.read(inputbuf)
|
||||
val rawnum = inputbuf.toLittleInt64()
|
||||
Double.fromBits(rawnum)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package net.torvald.random
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.floorInt
|
||||
import net.torvald.terrarum.floorToInt
|
||||
import net.torvald.terrarum.gameworld.fmod
|
||||
import java.util.*
|
||||
|
||||
@@ -45,9 +45,9 @@ class TileableValueNoise(
|
||||
try {
|
||||
for (x in 0..width) {
|
||||
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 =
|
||||
(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 windowScale: Float = stepWithinWindow.toFloat() / (width / samples)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ public class XXHash32 {
|
||||
|
||||
public static int hashGeoCoord(int x, int y) {
|
||||
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) {
|
||||
|
||||
@@ -3,15 +3,15 @@ package net.torvald.reflection
|
||||
/**
|
||||
* 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 {
|
||||
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 {
|
||||
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 net.torvald.terrarum.ItemCodex
|
||||
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.gameitems.GameItem
|
||||
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.AssembleFrameBase
|
||||
import net.torvald.terrarum.spriteassembler.AssembleSheetPixmap
|
||||
import net.torvald.terrarum.tryDispose
|
||||
import java.io.InputStream
|
||||
import java.util.*
|
||||
|
||||
@@ -122,8 +123,8 @@ class AssembledSpriteAnimation(
|
||||
val drawPos = adp.origin + bodypartPos // imgCentre for held items are (0,0)
|
||||
val w = image.regionWidth * scale
|
||||
val h = image.regionHeight * scale
|
||||
val fposX = posX.floor() + drawPos.x * scale
|
||||
val fposY = posY.floor() + drawPos.y * scale - h
|
||||
val fposX = posX.floorToFloat() + drawPos.x * scale
|
||||
val fposY = posY.floorToFloat() + drawPos.y * scale - h
|
||||
|
||||
// draw
|
||||
if (flipHorizontal && flipVertical)
|
||||
@@ -146,8 +147,8 @@ class AssembledSpriteAnimation(
|
||||
val drawPos = adp.origin + bodypartPos - imgCentre
|
||||
val w = image.regionWidth * scale
|
||||
val h = image.regionHeight * scale
|
||||
val fposX = posX.floor() + drawPos.x * scale
|
||||
val fposY = posY.floor() + drawPos.y * scale
|
||||
val fposX = posX.floorToFloat() + drawPos.x * scale
|
||||
val fposY = posY.floorToFloat() + drawPos.y * scale
|
||||
|
||||
if (flipHorizontal && flipVertical)
|
||||
batch.draw(image, fposX + txFlp, fposY + tyFlp, -w, -h)
|
||||
@@ -172,7 +173,7 @@ class AssembledSpriteAnimation(
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
res.values.forEach { try { it?.texture?.dispose() } catch (_: GdxRuntimeException) {} }
|
||||
res.values.forEach { it?.texture?.tryDispose() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -31,7 +31,6 @@ import net.torvald.terrarum.langpack.Lang;
|
||||
import net.torvald.terrarum.modulebasegame.IngameRenderer;
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame;
|
||||
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory;
|
||||
import net.torvald.terrarum.savegame.DiskSkimmer;
|
||||
import net.torvald.terrarum.serialise.WriteConfig;
|
||||
import net.torvald.terrarum.ui.Toolkit;
|
||||
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 long VERSION_RAW = TerrarumAppConfiguration.VERSION_RAW;
|
||||
public static final String VERSION_TAG = TerrarumAppConfiguration.VERSION_TAG;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
*/
|
||||
@@ -201,11 +208,11 @@ public class App implements ApplicationListener {
|
||||
* Sorted by the lastplaytime, in reverse order (index 0 is the most recent game played)
|
||||
*/
|
||||
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 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 void updateListOfSavegames() {
|
||||
@@ -234,6 +241,7 @@ public class App implements ApplicationListener {
|
||||
public static ShaderProgram shaderColLUT;
|
||||
public static ShaderProgram shaderReflect;
|
||||
public static ShaderProgram shaderGhastlyWhite;
|
||||
public static Hq2x hq2x;
|
||||
|
||||
public static Mesh fullscreenQuad;
|
||||
private static OrthographicCamera camera;
|
||||
@@ -261,12 +269,13 @@ public class App implements ApplicationListener {
|
||||
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 final float showupTime = 100f / 1000f;
|
||||
|
||||
private static FloatFrameBuffer renderFBO;
|
||||
private static Float16FrameBuffer renderFBO;
|
||||
|
||||
public static HashSet<File> tempFilePool = new HashSet<>();
|
||||
|
||||
@@ -346,10 +355,13 @@ public class App implements ApplicationListener {
|
||||
processorVendor = "Unknown CPU";
|
||||
}
|
||||
|
||||
if (processor.startsWith("Apple M") && Objects.equals(systemArch, "aarch64")) {
|
||||
if (processor.startsWith("Apple M") && systemArch.equals("aarch64")) {
|
||||
isAppleM = true;
|
||||
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) {
|
||||
var p = UnsafeHelper.INSTANCE.allocate(64);
|
||||
@@ -374,8 +386,8 @@ public class App implements ApplicationListener {
|
||||
ShaderProgram.pedantic = false;
|
||||
|
||||
scr = new TerrarumScreenSize(getConfigInt("screenwidth"), getConfigInt("screenheight"));
|
||||
int width = (int) Math.round(scr.getWidth() * scr.getMagn());
|
||||
int height = (int) Math.round(scr.getHeight() * scr.getMagn());
|
||||
int width = scr.getWindowW();
|
||||
int height = scr.getWindowH();
|
||||
|
||||
Lwjgl3ApplicationConfiguration appConfig = new Lwjgl3ApplicationConfiguration();
|
||||
//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.setResizable(false);
|
||||
appConfig.setWindowedMode(width, height);
|
||||
appConfig.setTransparentFramebuffer(false);
|
||||
int fpsActive = Math.min(GLOBAL_FRAMERATE_LIMIT, getConfigInt("displayfps"));
|
||||
if (fpsActive <= 0) fpsActive = GLOBAL_FRAMERATE_LIMIT;
|
||||
int fpsBack = Math.min(GLOBAL_FRAMERATE_LIMIT, getConfigInt("displayfpsidle"));
|
||||
@@ -430,13 +443,10 @@ public class App implements ApplicationListener {
|
||||
|
||||
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_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
|
||||
|
||||
@@ -465,12 +475,9 @@ public class App implements ApplicationListener {
|
||||
shaderBayerSkyboxFill = loadShaderFromClasspath("shaders/default.vert",
|
||||
"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");
|
||||
shaderColLUT = loadShaderFromClasspath("shaders/default.vert", "shaders/passthrurgb.frag");
|
||||
shaderReflect = loadShaderFromClasspath("shaders/default.vert", "shaders/reflect.frag");
|
||||
shaderGhastlyWhite = loadShaderFromClasspath("shaders/default.vert", "shaders/ghastlywhite.frag");
|
||||
hq2x = new Hq2x(2);
|
||||
|
||||
fullscreenQuad = new Mesh(
|
||||
true, 4, 6,
|
||||
@@ -478,97 +485,21 @@ public class App implements ApplicationListener {
|
||||
VertexAttribute.ColorUnpacked(),
|
||||
VertexAttribute.TexCoords(0)
|
||||
);
|
||||
updateFullscreenQuad(scr.getWidth(), scr.getHeight());
|
||||
|
||||
updateFullscreenQuad(fullscreenQuad, scr.getWidth(), scr.getHeight());
|
||||
|
||||
// set up renderer info variables
|
||||
renderer = Gdx.graphics.getGLVersion().getRendererString();
|
||||
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,
|
||||
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 postProcessorOutFBO2;
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
@@ -627,30 +558,44 @@ public class App implements ApplicationListener {
|
||||
FrameBufferManager.end();
|
||||
|
||||
|
||||
|
||||
// process screenshot request
|
||||
if (screenshotRequested) {
|
||||
FrameBufferManager.begin(postProcessorOutFBO);
|
||||
screenshotRequested = false;
|
||||
try {
|
||||
Pixmap p = Pixmap.createFromFrameBuffer(0, 0, scr.getWidth(), scr.getHeight());
|
||||
PixmapIO.writePNG(Gdx.files.absolute(defaultDir+"/Screenshot-"+String.valueOf(System.currentTimeMillis())+".png"), p, 9, true);
|
||||
p.dispose();
|
||||
Terrarum.INSTANCE.getIngame().sendNotification("Screenshot taken");
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
Terrarum.INSTANCE.getIngame().sendNotification("Failed to take screenshot: "+e.getMessage());
|
||||
}
|
||||
processScreenshotRequest(postProcessorOutFBO);
|
||||
|
||||
|
||||
|
||||
if (getConfigString("screenmagnifyingfilter").equals("hq2x") ) {
|
||||
FrameBufferManager.begin(postProcessorOutFBO2);
|
||||
shaderPassthruRGBA.bind();
|
||||
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
|
||||
shaderPassthruRGBA.setUniformi("u_texture", 0);
|
||||
hq2x.renderToScreen(postProcessorOutFBO.getColorBufferTexture());
|
||||
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
|
||||
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() {
|
||||
int hash = 31 + GLOBAL_RENDER_TIMER + 0x165667B1 + GLOBAL_RENDER_TIMER * 0xC2B2AE3D;
|
||||
hash = Integer.rotateLeft(hash, 17) * 0x27D4EB2F;
|
||||
@@ -767,12 +732,9 @@ public class App implements ApplicationListener {
|
||||
@Override
|
||||
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");
|
||||
int width = Math.round(w / magn);
|
||||
int height = Math.round(h / magn);
|
||||
int width = (int) Math.floor(w0 / magn);
|
||||
int height = (int) Math.floor(h0 / magn);
|
||||
|
||||
|
||||
printdbg(this, "Resize called: "+width+","+height);
|
||||
@@ -782,22 +744,27 @@ public class App implements ApplicationListener {
|
||||
|
||||
//initViewPort(width, height);
|
||||
|
||||
scr.setDimension(width, height, magn, w, h);
|
||||
scr.setDimension(width, height, magn);
|
||||
|
||||
if (currentScreen != null) currentScreen.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 ||
|
||||
(renderFBO.getWidth() != scr.getWidth() ||
|
||||
renderFBO.getHeight() != scr.getHeight())
|
||||
) {
|
||||
renderFBO = new FloatFrameBuffer(
|
||||
renderFBO = new Float16FrameBuffer(
|
||||
scr.getWidth(),
|
||||
scr.getHeight(),
|
||||
false
|
||||
);
|
||||
postProcessorOutFBO2 = new Float16FrameBuffer(
|
||||
scr.getWidth() * 2,
|
||||
scr.getHeight() * 2,
|
||||
false
|
||||
);
|
||||
|
||||
|
||||
if (IS_DEVELOPMENT_BUILD) {
|
||||
@@ -850,12 +817,13 @@ public class App implements ApplicationListener {
|
||||
shaderColLUT.dispose();
|
||||
shaderReflect.dispose();
|
||||
shaderGhastlyWhite.dispose();
|
||||
hq2x.dispose();
|
||||
|
||||
CommonResourcePool.INSTANCE.dispose();
|
||||
fullscreenQuad.dispose();
|
||||
logoBatch.dispose();
|
||||
batch.dispose();
|
||||
shapeRender.dispose();
|
||||
// shapeRender.dispose();
|
||||
|
||||
fontGame.dispose();
|
||||
fontGameFBO.dispose();
|
||||
@@ -948,6 +916,93 @@ public class App implements ApplicationListener {
|
||||
* Init stuffs which needs GL context
|
||||
*/
|
||||
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
|
||||
|
||||
|
||||
@@ -1026,14 +1081,14 @@ public class App implements ApplicationListener {
|
||||
logoBatch.setProjectionMatrix(camera.combined);
|
||||
}
|
||||
|
||||
private void updateFullscreenQuad(int WIDTH, int HEIGHT) { // NOT y-flipped quads!
|
||||
fullscreenQuad.setVertices(new float[]{
|
||||
private void updateFullscreenQuad(Mesh mesh, int WIDTH, int HEIGHT) { // NOT y-flipped quads!
|
||||
mesh.setVertices(new float[]{
|
||||
0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 1f,
|
||||
WIDTH, 0f, 0f, 1f, 1f, 1f, 1f, 1f, 1f,
|
||||
WIDTH, HEIGHT, 0f, 1f, 1f, 1f, 1f, 1f, 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() {
|
||||
@@ -1133,6 +1188,11 @@ public class App implements ApplicationListener {
|
||||
|
||||
public static RunningEnvironment environment;
|
||||
|
||||
/** defaultDir + "/Recycled/Players" */
|
||||
public static String recycledPlayersDir;
|
||||
/** defaultDir + "/Recycled/Worlds" */
|
||||
public static String recycledWorldsDir;
|
||||
|
||||
private static void getDefaultDirectory() {
|
||||
String OS = OSName.toUpperCase();
|
||||
if (OS.contains("WIN")) {
|
||||
@@ -1162,6 +1222,8 @@ public class App implements ApplicationListener {
|
||||
worldsDir = defaultDir + "/Worlds";
|
||||
configDir = defaultDir + "/config.json";
|
||||
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.version = %s", OSVersion));
|
||||
@@ -1171,10 +1233,12 @@ public class App implements ApplicationListener {
|
||||
|
||||
private static void createDirs() {
|
||||
File[] dirs = {
|
||||
new File(saveDir),
|
||||
// new File(saveDir),
|
||||
new File(saveSharedDir),
|
||||
new File(playersDir),
|
||||
new File(worldsDir)
|
||||
new File(worldsDir),
|
||||
new File(recycledPlayersDir),
|
||||
new File(recycledWorldsDir),
|
||||
};
|
||||
|
||||
for (File it : dirs) {
|
||||
|
||||
@@ -33,9 +33,9 @@ object CommonResourcePool {
|
||||
addToLoadingList("itemplaceholder_48") {
|
||||
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) }
|
||||
}
|
||||
}*/
|
||||
loadAll()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.torvald.terrarum
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import net.torvald.unicode.BULLET
|
||||
import net.torvald.unicode.ENDASH
|
||||
|
||||
@@ -223,6 +224,22 @@ Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
""").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
|
||||
Version 3, 29 June 2007
|
||||
|
||||
@@ -10,6 +10,9 @@ import com.badlogic.gdx.Input
|
||||
object DefaultConfig {
|
||||
|
||||
val hashMap = hashMapOf<String, Any>(
|
||||
"jvm_xmx" to 4,
|
||||
"jvm_extra_cmd" to "",
|
||||
|
||||
"displayfps" to 0, // 0: no limit, non-zero: limit
|
||||
"displayfpsidle" to 0, // 0: no limit, non-zero: limit
|
||||
"displaycolourdepth" to 8,
|
||||
@@ -19,9 +22,9 @@ object DefaultConfig {
|
||||
"atlastexsize" to 2048,
|
||||
|
||||
"language" to App.getSysLang(),
|
||||
"notificationshowuptime" to 4096, // 4s
|
||||
"selecteditemnameshowuptime" to 4096, // 4s
|
||||
"autosaveinterval" to 262144, // 4m22s
|
||||
"notificationshowuptime" to 4000, // 4s
|
||||
"selecteditemnameshowuptime" to 4000, // 4s
|
||||
"autosaveinterval" to 300000, // 5m
|
||||
"multithread" to true,
|
||||
|
||||
"showhealthmessageonstartup" to true,
|
||||
@@ -109,6 +112,7 @@ object DefaultConfig {
|
||||
"inputmethod" to "none",
|
||||
|
||||
"screenmagnifying" to 1.0,
|
||||
"screenmagnifyingfilter" to "none", // "none", "bilinear", "hq2x"
|
||||
|
||||
"fx_newlight" to false,
|
||||
|
||||
@@ -116,6 +120,12 @@ object DefaultConfig {
|
||||
"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
|
||||
/*"buildingmakerfavs" to arrayOf(
|
||||
|
||||
@@ -64,8 +64,8 @@ object GlslTilingTest : ApplicationAdapter() {
|
||||
|
||||
|
||||
|
||||
val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILING_SIZE).ceil() + 1f
|
||||
val tilesInVertical = (Gdx.graphics.height.toFloat() / TILING_SIZE).ceil() + 1f
|
||||
val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILING_SIZE).ceilToFloat() + 1f
|
||||
val tilesInVertical = (Gdx.graphics.height.toFloat() / TILING_SIZE).ceilToFloat() + 1f
|
||||
|
||||
tilesQuad = Mesh(
|
||||
true, 4, 6,
|
||||
@@ -129,8 +129,8 @@ object GlslTilingTest : ApplicationAdapter() {
|
||||
Gdx.gl.glEnable(GL20.GL_BLEND)
|
||||
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILING_SIZE).ceil() + 1f
|
||||
val tilesInVertical = (Gdx.graphics.height.toFloat() / TILING_SIZE).ceil() + 1f
|
||||
val tilesInHorizontal = (Gdx.graphics.width.toFloat() / TILING_SIZE).ceilToFloat() + 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.ActorID
|
||||
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.gamecontroller.TerrarumKeyboardEvent
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
@@ -26,9 +27,12 @@ import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
import java.util.*
|
||||
import java.util.concurrent.locks.Lock
|
||||
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;
|
||||
@@ -49,8 +53,8 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
||||
|
||||
override fun getMax(axis: Int, t: ActorWithBody): Double =
|
||||
when (axis) {
|
||||
0 -> t.hitbox.endX
|
||||
1 -> t.hitbox.endY
|
||||
0 -> t.hitbox.endX - PHYS_EPSILON_DIST
|
||||
1 -> t.hitbox.endY - PHYS_EPSILON_DIST
|
||||
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 worldSavefileName: 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
|
||||
val ZOOM_MAXIMUM = 4.0f
|
||||
@@ -201,13 +205,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
||||
actorContainerInactive.forEach { it.dispose() }
|
||||
world.dispose()
|
||||
|
||||
disposables.forEach(Consumer {
|
||||
try { it.dispose() }
|
||||
catch (_: NullPointerException) { }
|
||||
catch (_: IllegalArgumentException) { }
|
||||
catch (_: GdxRuntimeException) { }
|
||||
catch (_: ConcurrentModificationException) { }
|
||||
})
|
||||
disposables.forEach(Consumer { it.tryDispose() })
|
||||
}
|
||||
|
||||
////////////
|
||||
@@ -406,6 +404,14 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
||||
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`
|
||||
*/
|
||||
@@ -422,25 +428,55 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
||||
// 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()) 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) {}
|
||||
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()) 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) {}
|
||||
try {
|
||||
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())
|
||||
file1.copyTo(file2, true)
|
||||
Files.move(file1.toPath(), file2.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
|
||||
|
||||
file.copyTo(file1, true)
|
||||
} 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
|
||||
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 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> {
|
||||
val outList = ArrayList<ActorWithBody>()
|
||||
try {
|
||||
actorsRTree.find(worldX, worldY, worldX + 1.0, worldY + 1.0, outList)
|
||||
actorsRTree.find(worldX, worldY, worldX, worldY, outList)
|
||||
}
|
||||
catch (e: NullPointerException) {}
|
||||
return outList
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.badlogic.gdx.utils.JsonValue
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.App.setToGameConfig
|
||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||
import net.torvald.terrarum.blockproperties.WireCodex
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.torvald.terrarum
|
||||
|
||||
import net.torvald.random.XXHash32
|
||||
import org.dyn4j.geometry.Vector2
|
||||
|
||||
/**
|
||||
@@ -115,6 +116,10 @@ class Point2i() {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = XXHash32.hashGeoCoord(x, y)
|
||||
|
||||
override fun toString() = "Point2i($x, $y)"
|
||||
|
||||
operator fun component1() = x
|
||||
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 java.util.*
|
||||
@@ -9,6 +9,7 @@ import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2017-07-13.
|
||||
@@ -46,7 +47,7 @@ object SanicLoadScreen : LoadScreenBase() {
|
||||
|
||||
textFbo = FrameBuffer(
|
||||
Pixmap.Format.RGBA4444,
|
||||
maxOf(
|
||||
max(
|
||||
App.fontGame.getWidth(Lang["MENU_IO_LOADING"]),
|
||||
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
|
||||
|
||||
|
||||
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.ShapeRenderer
|
||||
import com.badlogic.gdx.utils.Disposable
|
||||
import com.badlogic.gdx.utils.JsonReader
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.gdx.graphics.Cvec
|
||||
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.ItemCodex
|
||||
import net.torvald.terrarum.itemproperties.MaterialCodex
|
||||
import net.torvald.terrarum.savegame.ByteArray64Reader
|
||||
import net.torvald.terrarum.savegame.DiskSkimmer
|
||||
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||
@@ -38,10 +36,7 @@ import net.torvald.util.CircularArray
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.util.*
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.math.round
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
import kotlin.math.*
|
||||
|
||||
|
||||
typealias RGBA8888 = Int
|
||||
@@ -62,11 +57,11 @@ object Terrarum : Disposable {
|
||||
*/
|
||||
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)
|
||||
action(shapeRender)
|
||||
shapeRender.end()
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
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())
|
||||
/** Position of the cursor in the world, rounded */
|
||||
@JvmStatic val mouseTileX: Int
|
||||
get() = (mouseX / TILE_SIZE).floorInt()
|
||||
get() = (mouseX / TILE_SIZE).floorToInt()
|
||||
/** Position of the cursor in the world */
|
||||
@JvmStatic val mouseTileY: Int
|
||||
get() = (mouseY / TILE_SIZE).floorInt()
|
||||
get() = (mouseY / TILE_SIZE).floorToInt()
|
||||
/** Position of the cursor in the world, rounded */
|
||||
@JvmStatic val oldMouseTileX: Int
|
||||
get() = (oldMouseX / TILE_SIZE).floorInt()
|
||||
get() = (oldMouseX / TILE_SIZE).floorToInt()
|
||||
/** Position of the cursor in the world */
|
||||
@JvmStatic val oldMouseTileY: Int
|
||||
get() = (oldMouseY / TILE_SIZE).floorInt()
|
||||
get() = (oldMouseY / TILE_SIZE).floorToInt()
|
||||
inline val mouseScreenX: Int
|
||||
get() = Gdx.input.x.div(scr.magn).roundToInt()
|
||||
inline val mouseScreenY: Int
|
||||
@@ -319,8 +314,8 @@ object Terrarum : Disposable {
|
||||
|
||||
val mx = mouseX
|
||||
val my = mouseY
|
||||
val mtx = (mouseX / TILE_SIZE).floorInt()
|
||||
val mty = (mouseY / TILE_SIZE).floorInt()
|
||||
val mtx = (mouseX / TILE_SIZE).floorToInt()
|
||||
val mty = (mouseY / TILE_SIZE).floorToInt()
|
||||
val msx = mx fmod TILE_SIZED
|
||||
val msy = my fmod TILE_SIZED
|
||||
val vector = if (msx < SMALLGAP) { // X to the left
|
||||
@@ -397,8 +392,10 @@ inline fun FrameBuffer.inAction(camera: OrthographicCamera?, batch: SpriteBatch?
|
||||
//this.begin()
|
||||
FrameBufferManager.begin(this)
|
||||
|
||||
val oldCamPos = camera?.position?.cpy()
|
||||
|
||||
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()
|
||||
batch?.projectionMatrix = camera?.combined
|
||||
|
||||
@@ -408,6 +405,7 @@ inline fun FrameBuffer.inAction(camera: OrthographicCamera?, batch: SpriteBatch?
|
||||
FrameBufferManager.end()
|
||||
|
||||
camera?.setToOrtho(true, App.scr.wf, App.scr.hf)
|
||||
camera?.position?.set(oldCamPos)
|
||||
camera?.update()
|
||||
batch?.projectionMatrix = camera?.combined
|
||||
}
|
||||
@@ -419,8 +417,10 @@ inline fun FrameBuffer.inActionF(camera: OrthographicCamera?, batch: SpriteBatch
|
||||
//this.begin()
|
||||
FrameBufferManager.begin(this)
|
||||
|
||||
val oldCamPos = camera?.position?.cpy()
|
||||
|
||||
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()
|
||||
batch?.projectionMatrix = camera?.combined
|
||||
|
||||
@@ -430,6 +430,7 @@ inline fun FrameBuffer.inActionF(camera: OrthographicCamera?, batch: SpriteBatch
|
||||
FrameBufferManager.end()
|
||||
|
||||
camera?.setToOrtho(true, App.scr.wf, App.scr.hf)
|
||||
camera?.position?.set(oldCamPos)
|
||||
camera?.update()
|
||||
batch?.projectionMatrix = camera?.combined
|
||||
}
|
||||
@@ -609,27 +610,28 @@ val emphVerb = TerrarumSansBitmap.toColorCode(0xFFF6)
|
||||
|
||||
typealias Second = Float
|
||||
|
||||
fun Int.sqr(): Int = this * this
|
||||
fun Double.floorInt() = Math.floor(this).toInt()
|
||||
fun Float.floorInt() = FastMath.floor(this)
|
||||
fun Float.floor() = FastMath.floor(this).toFloat()
|
||||
fun Double.ceilInt() = Math.ceil(this).toInt()
|
||||
fun Float.ceil(): Float = FastMath.ceil(this).toFloat()
|
||||
fun Float.ceilInt() = FastMath.ceil(this)
|
||||
fun Float.round(): Float = round(this)
|
||||
fun Double.round() = Math.round(this).toDouble()
|
||||
fun Double.floor() = Math.floor(this)
|
||||
fun Double.ceil() = this.floor() + 1.0
|
||||
fun Double.abs() = Math.abs(this)
|
||||
fun Double.sqr() = this * this
|
||||
fun Float.sqr() = this * this
|
||||
fun Double.sqrt() = Math.sqrt(this)
|
||||
fun Float.sqrt() = FastMath.sqrt(this)
|
||||
fun Int.abs() = this.absoluteValue
|
||||
fun Double.bipolarClamp(limit: Double) = this.coerceIn(-limit, limit)
|
||||
fun Boolean.toInt(shift: Int = 0) = if (this) 1.shl(shift) else 0
|
||||
fun Int.bitCount() = java.lang.Integer.bitCount(this)
|
||||
fun Long.bitCount() = java.lang.Long.bitCount(this)
|
||||
inline fun Double.floorToInt() = floor(this).toInt()
|
||||
inline fun Float.floorToInt() = FastMath.floor(this)
|
||||
inline fun Double.ceilToInt() = Math.ceil(this).toInt()
|
||||
inline fun Float.ceilToFloat(): Float = FastMath.ceil(this).toFloat()
|
||||
inline fun Float.ceilToInt() = FastMath.ceil(this)
|
||||
inline fun Float.floorToFloat() = FastMath.floor(this).toFloat()
|
||||
inline fun Float.roundToFloat(): Float = round(this)
|
||||
//inline fun Double.round() = Math.round(this).toDouble()
|
||||
inline fun Double.floorToDouble() = floor(this)
|
||||
inline fun Double.ceilToDouble() = ceil(this)
|
||||
inline fun Int.sqr(): Int = this * this
|
||||
inline fun Double.sqr() = this * this
|
||||
inline fun Float.sqr() = this * this
|
||||
inline fun Double.sqrt() = Math.sqrt(this)
|
||||
inline fun Float.sqrt() = FastMath.sqrt(this)
|
||||
inline fun Int.abs() = this.absoluteValue
|
||||
inline fun Double.abs() = this.absoluteValue
|
||||
inline fun Double.bipolarClamp(limit: Double) = this.coerceIn(-limit, limit)
|
||||
inline fun Boolean.toInt(shift: Int = 0) = if (this) 1.shl(shift) else 0
|
||||
inline fun Boolean.toLong(shift: Int = 0) = if (this) 1L.shl(shift) else 0L
|
||||
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 {
|
||||
@@ -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.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 {
|
||||
if (startValue == endValue) {
|
||||
return startValue
|
||||
@@ -785,6 +786,7 @@ fun AppUpdateListOfSavegames() {
|
||||
|
||||
println("Listing saved worlds...")
|
||||
|
||||
|
||||
// create list of worlds
|
||||
File(worldsDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.mapNotNull { file ->
|
||||
try {
|
||||
@@ -797,15 +799,20 @@ fun AppUpdateListOfSavegames() {
|
||||
}
|
||||
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
||||
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 json = JsonReader().parse(ByteArray64Reader(jsonFile.bytes, Common.CHARSET).readText())
|
||||
val worldUUID = UUID.fromString(json.getString("worldIndex"))
|
||||
// val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
||||
// var worldUUID: UUID? = null
|
||||
// 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 (!App.savegameWorlds.contains(worldUUID)) {
|
||||
App.savegameWorlds[worldUUID] = it
|
||||
App.savegameWorlds[worldUUID] = collection
|
||||
App.savegameWorldsName[worldUUID] = it.getDiskName(Common.CHARSET)
|
||||
App.sortedSavegameWorlds.add(worldUUID)
|
||||
}
|
||||
@@ -827,20 +834,30 @@ fun AppUpdateListOfSavegames() {
|
||||
}
|
||||
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
||||
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 json = JsonReader().parse(ByteArray64Reader(jsonFile.bytes, Common.CHARSET).readText())
|
||||
val playerUUID = UUID.fromString(json.getString("uuid"))
|
||||
// val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
||||
// var playerUUID: UUID? = null
|
||||
// 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 (!App.savegamePlayers.contains(playerUUID)) {
|
||||
App.savegamePlayers[playerUUID] = it
|
||||
App.savegamePlayers[playerUUID] = collection
|
||||
App.savegamePlayersName[playerUUID] = it.getDiskName(Common.CHARSET)
|
||||
App.sortedPlayers.add(playerUUID)
|
||||
}
|
||||
}
|
||||
|
||||
println("SortedPlayers...")
|
||||
App.sortedPlayers.forEach {
|
||||
println(it)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -880,3 +897,11 @@ fun checkForSavegameDamage(skimmer: DiskSkimmer): Boolean {
|
||||
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
|
||||
# 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
|
||||
"""
|
||||
@@ -54,9 +62,12 @@ basegame
|
||||
* 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.1: 2278
|
||||
// Commit counts up to the Release 0.3.2: 2732
|
||||
|
||||
const val VERSION_TAG: String = "test001"
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// CONFIGURATION FOR TILE MAKER //
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.badlogic.gdx.math.Matrix4
|
||||
import com.badlogic.gdx.utils.Disposable
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.App.IS_DEVELOPMENT_BUILD
|
||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||
import net.torvald.terrarum.ui.BasicDebugInfoWindow
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
@@ -63,7 +64,7 @@ object TerrarumPostProcessor : Disposable {
|
||||
}
|
||||
|
||||
fun resize(w: Int, h: Int) {
|
||||
try { outFBO.dispose() } catch (_: UninitializedPropertyAccessException) {}
|
||||
if (::outFBO.isInitialized) outFBO.tryDispose()
|
||||
outFBO = FrameBuffer(Pixmap.Format.RGBA8888, w, h, false)
|
||||
}
|
||||
|
||||
@@ -71,10 +72,10 @@ object TerrarumPostProcessor : Disposable {
|
||||
batch.dispose()
|
||||
shapeRenderer.dispose()
|
||||
functionRowHelper.dispose()
|
||||
try { lutTex.dispose() } catch (_: UninitializedPropertyAccessException) {}
|
||||
shaderPostDither.dispose()
|
||||
shaderPostNoDither.dispose()
|
||||
outFBO.dispose()
|
||||
if (::lutTex.isInitialized) lutTex.tryDispose()
|
||||
if (::outFBO.isInitialized) outFBO.dispose()
|
||||
}
|
||||
|
||||
private var deltatBenchStr = "ΔF: Gathering data"
|
||||
@@ -150,9 +151,10 @@ object TerrarumPostProcessor : Disposable {
|
||||
}
|
||||
|
||||
// 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.color = safeAreaCol
|
||||
batch.color = if (IS_DEVELOPMENT_BUILD) safeAreaCol else colourNull
|
||||
App.fontGame.draw(it, thisIsDebugStr, 5f, App.scr.height - 24f)
|
||||
}
|
||||
}
|
||||
@@ -168,11 +170,11 @@ object TerrarumPostProcessor : Disposable {
|
||||
val average = tallies.average()
|
||||
|
||||
val halfPos = 0.5f * INGAME.deltaTeeBenchmarks.size
|
||||
val halfInd = halfPos.floorInt()
|
||||
val halfInd = halfPos.floorToInt()
|
||||
val low5pos = 0.05f * INGAME.deltaTeeBenchmarks.size
|
||||
val low5ind = low5pos.floorInt()
|
||||
val low5ind = low5pos.floorToInt()
|
||||
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 low5 = FastMath.interpolateLinear(low5pos - low5ind, tallies[low5ind], tallies[low5ind + 1])
|
||||
@@ -192,39 +194,40 @@ object TerrarumPostProcessor : Disposable {
|
||||
return outFBO
|
||||
}
|
||||
private val rng = HQRNG()
|
||||
private val colourNull = Color(0)
|
||||
|
||||
private fun Double.format(digits: Int) = "%.${digits}f".format(this)
|
||||
private fun Float.format(digits: Int) = "%.${digits}f".format(this)
|
||||
|
||||
private val swizzler = intArrayOf(
|
||||
1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1,
|
||||
1,0,0,0, 0,1,0,0, 0,0,0,1, 0,0,1,0,
|
||||
1,0,0,0, 0,0,1,0, 0,1,0,0, 0,0,0,1,
|
||||
1,0,0,0, 0,0,1,0, 0,0,0,1, 0,1,0,0,
|
||||
1,0,0,0, 0,0,0,1, 0,1,0,0, 0,0,1,0,
|
||||
1,0,0,0, 0,0,0,1, 0,0,1,0, 0,1,0,0,
|
||||
private val swizzler = floatArrayOf(
|
||||
1f,0f,0f,0f, 0f,1f,0f,0f, 0f,0f,1f,0f, 0f,0f,0f,1f,
|
||||
1f,0f,0f,0f, 0f,1f,0f,0f, 0f,0f,0f,1f, 0f,0f,1f,0f,
|
||||
1f,0f,0f,0f, 0f,0f,1f,0f, 0f,1f,0f,0f, 0f,0f,0f,1f,
|
||||
1f,0f,0f,0f, 0f,0f,1f,0f, 0f,0f,0f,1f, 0f,1f,0f,0f,
|
||||
1f,0f,0f,0f, 0f,0f,0f,1f, 0f,1f,0f,0f, 0f,0f,1f,0f,
|
||||
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,
|
||||
0,1,0,0, 1,0,0,0, 0,0,0,1, 0,0,1,0,
|
||||
0,1,0,0, 0,0,1,0, 1,0,0,0, 0,0,0,1,
|
||||
0,1,0,0, 0,0,1,0, 0,0,0,1, 1,0,0,0,
|
||||
0,1,0,0, 0,0,0,1, 1,0,0,0, 0,0,1,0,
|
||||
0,1,0,0, 0,0,0,1, 0,0,1,0, 1,0,0,0,
|
||||
0f,1f,0f,0f, 1f,0f,0f,0f, 0f,0f,1f,0f, 0f,0f,0f,1f,
|
||||
0f,1f,0f,0f, 1f,0f,0f,0f, 0f,0f,0f,1f, 0f,0f,1f,0f,
|
||||
0f,1f,0f,0f, 0f,0f,1f,0f, 1f,0f,0f,0f, 0f,0f,0f,1f,
|
||||
0f,1f,0f,0f, 0f,0f,1f,0f, 0f,0f,0f,1f, 1f,0f,0f,0f,
|
||||
0f,1f,0f,0f, 0f,0f,0f,1f, 1f,0f,0f,0f, 0f,0f,1f,0f,
|
||||
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,
|
||||
0,0,1,0, 1,0,0,0, 0,0,0,1, 0,1,0,0,
|
||||
0,0,1,0, 0,1,0,0, 1,0,0,0, 0,0,0,1,
|
||||
0,0,1,0, 0,1,0,0, 0,0,0,1, 1,0,0,0,
|
||||
0,0,1,0, 0,0,0,1, 1,0,0,0, 0,1,0,0,
|
||||
0,0,1,0, 0,0,0,1, 0,1,0,0, 1,0,0,0,
|
||||
0f,0f,1f,0f, 1f,0f,0f,0f, 0f,1f,0f,0f, 0f,0f,0f,1f,
|
||||
0f,0f,1f,0f, 1f,0f,0f,0f, 0f,0f,0f,1f, 0f,1f,0f,0f,
|
||||
0f,0f,1f,0f, 0f,1f,0f,0f, 1f,0f,0f,0f, 0f,0f,0f,1f,
|
||||
0f,0f,1f,0f, 0f,1f,0f,0f, 0f,0f,0f,1f, 1f,0f,0f,0f,
|
||||
0f,0f,1f,0f, 0f,0f,0f,1f, 1f,0f,0f,0f, 0f,1f,0f,0f,
|
||||
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,
|
||||
0,0,0,1, 1,0,0,0, 0,0,1,0, 0,1,0,0,
|
||||
0,0,0,1, 0,1,0,0, 1,0,0,0, 0,0,1,0,
|
||||
0,0,0,1, 0,1,0,0, 0,0,1,0, 1,0,0,0,
|
||||
0,0,0,1, 0,0,1,0, 1,0,0,0, 0,1,0,0,
|
||||
0,0,0,1, 0,0,1,0, 0,1,0,0, 1,0,0,0,
|
||||
).map { it.toFloat() }.toFloatArray()
|
||||
0f,0f,0f,1f, 1f,0f,0f,0f, 0f,1f,0f,0f, 0f,0f,1f,0f,
|
||||
0f,0f,0f,1f, 1f,0f,0f,0f, 0f,0f,1f,0f, 0f,1f,0f,0f,
|
||||
0f,0f,0f,1f, 0f,1f,0f,0f, 1f,0f,0f,0f, 0f,0f,1f,0f,
|
||||
0f,0f,0f,1f, 0f,1f,0f,0f, 0f,0f,1f,0f, 1f,0f,0f,0f,
|
||||
0f,0f,0f,1f, 0f,0f,1f,0f, 1f,0f,0f,0f, 0f,1f,0f,0f,
|
||||
0f,0f,0f,1f, 0f,0f,1f,0f, 0f,1f,0f,0f, 1f,0f,0f,0f,
|
||||
)
|
||||
|
||||
private fun postShader(projMat: Matrix4, fbo: FrameBuffer) {
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package net.torvald.terrarum
|
||||
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
|
||||
|
||||
companion object {
|
||||
const val minimumW = 1080
|
||||
const val minimumW = 1024
|
||||
const val minimumH = 720
|
||||
const val defaultW = 1280
|
||||
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 tvSafeActionHeight: Int; get() = Math.round(height * TV_SAFE_ACTION)
|
||||
|
||||
/** Apparent window size. `roundToEven(width * magn)` */
|
||||
var windowW: Int = 0; private set
|
||||
/** Apparent window size. `roundToEven(height * magn)` */
|
||||
var windowH: Int = 0; private set
|
||||
|
||||
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
|
||||
height = scrh and 0x7FFFFFFE
|
||||
wf = scrw.toFloat()
|
||||
@@ -54,11 +57,11 @@ class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
|
||||
|
||||
this.magn = magn
|
||||
|
||||
windowW = ww
|
||||
windowH = wh
|
||||
windowW = (scrw * magn).ceilToInt() and 0x7FFFFFFE
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ class UIItemInventoryCatBar(
|
||||
// set up underlined indicator
|
||||
init {
|
||||
// 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
|
||||
val col = /*if (x == 0)*/ /*0xffffff_80.toInt()*/
|
||||
/*else if (x == 1)*/ /*0xffffff_c0.toInt()*/
|
||||
|
||||
@@ -209,8 +209,8 @@ class BlockCodex {
|
||||
prop.isSolid = record.boolVal("solid")
|
||||
//prop.isClear = record.boolVal("clear")
|
||||
|
||||
prop.isPlatform = prop.tags.contains("PLATFORM")
|
||||
prop.isActorBlock = prop.tags.contains("ACTORBLOCK")
|
||||
prop.isPlatform = prop.hasTag("PLATFORM")
|
||||
prop.isActorBlock = prop.hasTag("ACTORBLOCK")
|
||||
|
||||
prop.isWallable = record.boolVal("wall")
|
||||
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