mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
Compare commits
167 Commits
v0.3.2-tes
...
v0.3.3-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1e45f1743 | ||
|
|
8dda7ac79b | ||
|
|
74b8cc20b7 | ||
|
|
f75a7dd812 | ||
|
|
b2454e4ca2 | ||
|
|
45af955488 | ||
|
|
1f39b9d448 | ||
|
|
26a4cdbce1 | ||
|
|
bf87dc04cb | ||
|
|
8535b0ce13 | ||
|
|
6e0004f165 | ||
|
|
845333f33d | ||
|
|
6988feb731 | ||
|
|
ac2c7b1148 | ||
|
|
d6145fd0da | ||
|
|
194089827c | ||
|
|
d69d032f74 | ||
|
|
a9dbea3d16 | ||
|
|
52938a4b60 | ||
|
|
a21f986f30 | ||
|
|
547158a313 | ||
|
|
0a8b5f33f4 | ||
|
|
da8d620766 | ||
|
|
7dd520393c | ||
|
|
dc83e12170 | ||
|
|
d6b2940d8f | ||
|
|
c5dfe46b76 | ||
|
|
3d3926c08b | ||
|
|
9a90bf69d4 | ||
|
|
0ed5472d8a | ||
|
|
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 |
@@ -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,77 +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) {
|
||||
super.doOpening(delta)
|
||||
fixture.startVM()
|
||||
}
|
||||
|
||||
|
||||
override fun dispose() {
|
||||
fbo.dispose()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
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.*
|
||||
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 = null,
|
||||
toggleButtonLiteral = "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(ControlPresets.getKey("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.
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,37 +1,43 @@
|
||||
{
|
||||
"CONTEXT_CHARACTER": "Character",
|
||||
"MENU_LABEL_COPYRIGHT": "Copyright",
|
||||
"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",
|
||||
"MENU_LABEL_JVM_DNT" : "JVM",
|
||||
"GAME_ACTION_MOVE_VERB" : "Move",
|
||||
"GAME_ACTION_ZOOM" : "Zoom",
|
||||
"MENU_LABEL_RESET" : "Reset",
|
||||
"MENU_OPTION_STREAMERS_LAYOUT": "Chat Overlay",
|
||||
"MENU_LABEL_RESTART_REQUIRED": "Restart Required",
|
||||
"MENU_LABEL_KEYBOARD_LAYOUT": "Keyboard Layout",
|
||||
"MENU_LABEL_IME": "IME",
|
||||
"MENU_OPTIONS_DITHER": "Dithering",
|
||||
"MENU_OPTIONS_BLUR": "Blur",
|
||||
"MENU_OPTIONS_PARTICLES": "Particles",
|
||||
"MENU_IO_IMPORT": "Import",
|
||||
"MENU_LABEL_IME_TOGGLE": "Toggle IME",
|
||||
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Paste from Clipboard",
|
||||
"MENU_OPTIONS_PERFORMANCE": "Performance",
|
||||
"MENU_LABEL_DELETE": "Delete",
|
||||
"MENU_OPTIONS_JVM_HEAP_MAX": "Max Heap Memory",
|
||||
"MENU_OPTIONS_AUTOSAVE": "Autosave",
|
||||
"CONTEXT_CHARACTER": "Character",
|
||||
"CONTEXT_TIME_MINUTE_PLURAL": "Minutes",
|
||||
"CONTEXT_TIME_SECOND_PLURAL": "Seconds",
|
||||
"MENU_LABEL_SYSTEM_INFO": "System Info",
|
||||
"MENU_OPTIONS_NOTIFICATION_DISPLAY_DURATION": "Show notification for",
|
||||
"MENU_LABEL_STREAMING": "Livestreaming",
|
||||
"MENU_LABEL_EXTRA_JVM_ARGUMENTS": "Extra Arguments",
|
||||
"MENU_IO_MANUAL_SAVE": "Manual Save",
|
||||
"COPYRIGHT_ALL_RIGHTS_RESERVED": "All rights reserved",
|
||||
"COPYRIGHT_GNU_GPL_3": "Distributed under GNU GPL 3",
|
||||
"GAME_ACTION_MOVE_VERB" : "Move",
|
||||
"GAME_ACTION_ZOOM" : "Zoom",
|
||||
"MENU_IO_AUTOSAVE": "Autosave",
|
||||
"MENU_OPTIONS_DEBUG_CONSOLE": "Debug Console"
|
||||
"MENU_IO_CLEAR": "Clear",
|
||||
"MENU_IO_IMPORT": "Import",
|
||||
"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_KEYBOARD_LAYOUT": "Keyboard Layout",
|
||||
"MENU_LABEL_PASTE": "Paste",
|
||||
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Paste from Clipboard",
|
||||
"MENU_LABEL_PRESS_START_SYMBOL": "Press >",
|
||||
"MENU_LABEL_RESET" : "Reset",
|
||||
"MENU_LABEL_RESTART_REQUIRED": "Restart Required",
|
||||
"MENU_LABEL_STREAMING": "Livestreaming",
|
||||
"MENU_LABEL_SYSTEM_INFO": "System Info",
|
||||
"MENU_MODULES" : "Modules",
|
||||
"MENU_OPTIONS_ATLAS_TEXTURE_SIZE": "Atlas Texture Size",
|
||||
"MENU_OPTIONS_AUTOSAVE": "Autosave",
|
||||
"MENU_OPTIONS_BLUR": "Blur",
|
||||
"MENU_OPTIONS_DEBUG_CONSOLE": "Debug Console",
|
||||
"MENU_OPTIONS_DITHER": "Dithering",
|
||||
"MENU_OPTIONS_JVM_HEAP_MAX": "Max Heap Memory",
|
||||
"MENU_OPTIONS_NOTIFICATION_DISPLAY_DURATION": "Show notification for",
|
||||
"MENU_OPTIONS_PARTICLES": "Particles",
|
||||
"MENU_OPTIONS_PERFORMANCE": "Performance",
|
||||
"MENU_OPTIONS_STREAMERS_LAYOUT": "Chat Overlay",
|
||||
"MENU_OPTIONS_NONE" : "None",
|
||||
|
||||
"MENU_CREDIT_GPL_DNT" : "GPL",
|
||||
"MENU_LABEL_JVM_DNT" : "JVM",
|
||||
"MENU_OPTIONS_FILTERING_HQ2X_DNT" : "Hq2x"
|
||||
}
|
||||
@@ -1,16 +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_PROGRESSES_WILL_BE_LOST": "저장하지 않은 변동사항을 잃게 됩니다."
|
||||
}
|
||||
"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": "इनपुट विधि",
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
{
|
||||
"CONTEXT_CHARACTER": "캐릭터",
|
||||
"MENU_LABEL_COPYRIGHT": "저작권",
|
||||
"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" : "재설정",
|
||||
"MENU_OPTION_STREAMERS_LAYOUT": "채팅창 오버레이",
|
||||
"MENU_LABEL_RESTART_REQUIRED": "재시작 필요",
|
||||
"MENU_LABEL_KEYBOARD_LAYOUT": "자판 배열",
|
||||
"MENU_LABEL_IME": "입력기",
|
||||
"MENU_OPTIONS_DITHER": "디더링",
|
||||
"MENU_OPTIONS_BLUR": "흐림",
|
||||
"MENU_OPTIONS_PARTICLES": "입자 수",
|
||||
"MENU_IO_IMPORT": "가져오기",
|
||||
"MENU_LABEL_IME_TOGGLE": "입력기 켜고 끄기",
|
||||
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "복사한 텍스트 붙여넣기",
|
||||
"MENU_OPTIONS_PERFORMANCE": "성능",
|
||||
"MENU_LABEL_DELETE": "삭제",
|
||||
"MENU_OPTIONS_JVM_HEAP_MAX": "최대 힙 메모리",
|
||||
"MENU_OPTIONS_AUTOSAVE": "자동 저장",
|
||||
"CONTEXT_CHARACTER": "캐릭터",
|
||||
"CONTEXT_TIME_MINUTE_PLURAL": "분",
|
||||
"CONTEXT_TIME_SECOND_PLURAL": "초",
|
||||
"MENU_LABEL_SYSTEM_INFO": "시스템 정보",
|
||||
"MENU_OPTIONS_NOTIFICATION_DISPLAY_DURATION": "알림 표시 시간",
|
||||
"MENU_LABEL_STREAMING": "실시간 방송",
|
||||
"MENU_LABEL_EXTRA_JVM_ARGUMENTS": "추가 명령 인수",
|
||||
"MENU_IO_MANUAL_SAVE": "수동 저장",
|
||||
"COPYRIGHT_ALL_RIGHTS_RESERVED": "모든 권리 보유",
|
||||
"COPYRIGHT_GNU_GPL_3": "GNU GPL 3에 따라 배포됨",
|
||||
"GAME_ACTION_MOVE_VERB" : "이동하기",
|
||||
"GAME_ACTION_ZOOM" : "확대·축소",
|
||||
"MENU_IO_AUTOSAVE": "자동 저장",
|
||||
"MENU_OPTIONS_DEBUG_CONSOLE": "디버그 콘솔"
|
||||
"MENU_IO_CLEAR": "지우기",
|
||||
"MENU_IO_IMPORT": "가져오기",
|
||||
"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": "붙여넣기",
|
||||
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "복사한 텍스트 붙여넣기",
|
||||
"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" : "없음"
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@
|
||||
"GAME_PREV_SAVE_WAS_LOADED2": "이전에 저장된 게임을 불러왔습니다.",
|
||||
"GAME_MORE_RECENT_AUTOSAVE1": "자동 저장된 게임이 수동으로 저장한 게임보다 더 최신입니다.",
|
||||
"GAME_MORE_RECENT_AUTOSAVE2": "불러올 게임을 선택해 주십시오.",
|
||||
"MENU_LABEL_SAVE_WILL_BE_DELETED": "선택된 세이브가 삭제됩니다."
|
||||
"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
|
||||
@@ -30,4 +32,5 @@ Teleport
|
||||
ToggleNoClip
|
||||
Zoom
|
||||
DynToStatic
|
||||
DebugFillInventory
|
||||
DebugFillInventory
|
||||
Uuid
|
||||
|
@@ -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_CRAFTABLE_ITEMS": "Craftable Items",
|
||||
"MENU_LABEL_RENAME": "Rename",
|
||||
"GAME_ACTION_TELEPORT": "Teleport",
|
||||
"CONTEXT_THIS_IS_A_WORLD_CURRENTLY_PLAYING": "This is a world currently playing."
|
||||
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
|
||||
"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"
|
||||
}
|
||||
5
assets/mods/basegame/locales/en/sentences.json
Normal file
5
assets/mods/basegame/locales/en/sentences.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"CONTEXT_THIS_IS_A_WORLD_CURRENTLY_PLAYING": "This is a world currently playing.",
|
||||
"CONTEXT_IMPORT_AVATAR_INSTRUCTION_1": "Copy the Avatar Code into the clipboard, then hit the Paste button below.",
|
||||
"CONTEXT_IMPORT_AVATAR_INSTRUCTION_2": ""
|
||||
}
|
||||
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,24 +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_CRAFTING": "제작",
|
||||
"GAME_CRAFTABLE_ITEMS": "제작 가능한 아이템",
|
||||
"MENU_LABEL_RENAME": "이름 바꾸기",
|
||||
"GAME_ACTION_TELEPORT": "텔레포트하기",
|
||||
"CONTEXT_THIS_IS_A_WORLD_CURRENTLY_PLAYING": "현재 플레이 중인 월드입니다."
|
||||
"GAME_CRAFTABLE_ITEMS": "제작 가능한 아이템",
|
||||
"GAME_CRAFTING": "제작",
|
||||
"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": "전선 절단기"
|
||||
}
|
||||
5
assets/mods/basegame/locales/koKR/sentences.json
Normal file
5
assets/mods/basegame/locales/koKR/sentences.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"CONTEXT_THIS_IS_A_WORLD_CURRENTLY_PLAYING": "현재 플레이 중인 월드입니다.",
|
||||
"CONTEXT_IMPORT_AVATAR_INSTRUCTION_1": "아바타 코드를 클립보드에 복사한 다음, 아래의 붙여넣기 버튼을 눌러주세요.",
|
||||
"CONTEXT_IMPORT_AVATAR_INSTRUCTION_2": ""
|
||||
}
|
||||
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,7 +1,22 @@
|
||||
{
|
||||
"skyboxGradColourMap": "generic_skybox.tga",
|
||||
"daylightClut": "clut_daylight.tga",
|
||||
"classification": "generic",
|
||||
"extraImages": [
|
||||
|
||||
]
|
||||
"cloudChance": 250,
|
||||
"cloudGamma": [0.48, 1.8],
|
||||
"cloudGammaVariance": [0.1, 0.1],
|
||||
"windSpeed": 10.25,
|
||||
"windSpeedVariance": 1.0,
|
||||
"clouds": {
|
||||
"cumulonimbus": {
|
||||
"filename": "cloud_large.png", "tw": 2048, "th": 1024, "probability": 0.2,
|
||||
"baseScale": 2.0, "scaleVariance": 0.3333333,
|
||||
"altLow": 80, "altHigh": 120
|
||||
},
|
||||
"cumulus": {
|
||||
"filename": "cloud_normal.png", "tw": 1024, "th": 512, "probability": 1.0,
|
||||
"baseScale": 1.0, "scaleVariance": 0.6,
|
||||
"altLow": 80, "altHigh": 800
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"globalLight": "generic_light.tga",
|
||||
"skyboxGradColourMap": "generic_skybox.tga",
|
||||
"classification": "genericrain",
|
||||
"extraImages": [
|
||||
"raindrop.tga"
|
||||
],
|
||||
"mixFrom": "__CURRENTWEATHER",
|
||||
"mixPercentage": 80.0
|
||||
}
|
||||
27
assets/mods/basegame/weathers/WeatherOvercast.json
Normal file
27
assets/mods/basegame/weathers/WeatherOvercast.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"skyboxGradColourMap": "generic_skybox.tga",
|
||||
"daylightClut": "clut_daylight.tga",
|
||||
"classification": "overcast",
|
||||
"cloudChance": 300,
|
||||
"cloudGamma": [2.2, 2.0],
|
||||
"cloudGammaVariance": [0.1, 0.1],
|
||||
"windSpeed": 10.45,
|
||||
"windSpeedVariance": 1.0,
|
||||
"clouds": {
|
||||
"cumulus": {
|
||||
"filename": "cloud_normal.png", "tw": 1024, "th": 512, "probability": 0.1,
|
||||
"baseScale": 0.8, "scaleVariance": 0.6,
|
||||
"altLow": 80, "altHigh": 800
|
||||
},
|
||||
"cumulonimbus": {
|
||||
"filename": "cloud_large.png", "tw": 2048, "th": 1024, "probability": 0.4,
|
||||
"baseScale": 2.0, "scaleVariance": 0.3333333,
|
||||
"altLow": 90, "altHigh": 120
|
||||
},
|
||||
"nimbostratus": {
|
||||
"filename": "cloud_wide.png", "tw": 4096, "th": 1024, "probability": 1.0,
|
||||
"baseScale": 4.0, "scaleVariance": 0.1,
|
||||
"altLow": 100, "altHigh": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
assets/mods/basegame/weathers/cloud_large.kra
LFS
Normal file
BIN
assets/mods/basegame/weathers/cloud_large.kra
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/weathers/cloud_large.png
LFS
Normal file
BIN
assets/mods/basegame/weathers/cloud_large.png
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/weathers/cloud_normal.kra
LFS
Normal file
BIN
assets/mods/basegame/weathers/cloud_normal.kra
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/weathers/cloud_normal.png
LFS
Normal file
BIN
assets/mods/basegame/weathers/cloud_normal.png
LFS
Normal file
Binary file not shown.
26
assets/mods/basegame/weathers/cloud_texture_instruction.md
Normal file
26
assets/mods/basegame/weathers/cloud_texture_instruction.md
Normal file
@@ -0,0 +1,26 @@
|
||||
## actually blending
|
||||
1. On Krita, load the cloudmap
|
||||
2. Select and isolate suitable piece of the cloud
|
||||
3. With liquefying brush, make the bottom flat
|
||||
4. On new tab, load the solidmap
|
||||
5. Resize the solidmap to 1024x1024
|
||||
6. Rotate the solidmap by 30 deg or so
|
||||
7. Overlay the processed solidmap to the cloudmap, opacity=30%
|
||||
8. With airbrush tool, manually add the shade (see cloud_normal.kra to get the gist of it)
|
||||
|
||||
### cloudmap
|
||||
1. On GIMP, prepare 4096x4096 canvas
|
||||
2. Create Simplex Noise with following parameters:
|
||||
- Scale: arbitrary (0.05 - 0.2)
|
||||
- Iterations: MAX
|
||||
- Seed: anything but 0
|
||||
|
||||
### solidmap
|
||||
1. On GIMP, prepare 4096x4096 canvas
|
||||
2. Create Solid Noise with following parameters:
|
||||
- XY Size: 16.0
|
||||
- Detail: MAX
|
||||
- Tileable: check
|
||||
- Turbulent: check
|
||||
- Seed: anything but 0
|
||||
|
||||
BIN
assets/mods/basegame/weathers/cloud_wide.kra
LFS
Normal file
BIN
assets/mods/basegame/weathers/cloud_wide.kra
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/weathers/cloud_wide.png
LFS
Normal file
BIN
assets/mods/basegame/weathers/cloud_wide.png
LFS
Normal file
Binary file not shown.
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.
@@ -25,6 +25,7 @@ chmod +x $DESTDIR/AppRun
|
||||
# Copy over a Java runtime
|
||||
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/
|
||||
|
||||
@@ -25,6 +25,7 @@ chmod +x $DESTDIR/AppRun
|
||||
# Copy over a Java runtime
|
||||
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/
|
||||
|
||||
@@ -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
|
||||
@@ -27,10 +28,15 @@ chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
|
||||
# Copy over a Java runtime
|
||||
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 "../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
|
||||
@@ -27,10 +28,15 @@ chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
|
||||
# Copy over a Java runtime
|
||||
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 "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/out/
|
||||
|
||||
cd "out"
|
||||
rm $APPDIR.zip
|
||||
7z a -tzip $APPDIR.zip $APPDIR
|
||||
|
||||
echo "Build successful: $DESTDIR"
|
||||
|
||||
@@ -21,11 +21,13 @@ then
|
||||
echo 'Mingw32 not found; please install mingw64-cross-gcc (or similar) to your system' >&2; exit 1;
|
||||
fi
|
||||
|
||||
x86_64-w64-mingw32-gcc -o $DESTDIR/Terrarum.exe $SRCFILES/Terrarum.c || { echo 'Building EXE failed' >&2; exit 1; }
|
||||
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
|
||||
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/
|
||||
@@ -33,6 +35,7 @@ mv $DESTDIR/assets_release $DESTDIR/assets
|
||||
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
|
||||
|
||||
# Temporary solution: zip everything
|
||||
rm "out/TerrarumWindows.x86.zip"
|
||||
zip -r -9 -l "out/TerrarumWindows.x86.zip" $DESTDIR
|
||||
rm -rf $DESTDIR || true
|
||||
echo "Build successful: $DESTDIR"
|
||||
|
||||
28
buildapp/make_assets_release.sh
Executable file
28
buildapp/make_assets_release.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/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 $DESTDIR/mods/basegame/weathers/*.txt
|
||||
rm $DESTDIR/mods/basegame/weathers/*.md
|
||||
rm $DESTDIR/mods/basegame/weathers/*.kra
|
||||
rm -r $DESTDIR/mods/basegame/sounds
|
||||
rm -r $DESTDIR/mods/dwarventech
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/bash
|
||||
cd "${0%/*}"
|
||||
./out/runtime-linux-arm/bin/java -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./out/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%/*}"
|
||||
./out/runtime-linux-x86/bin/java -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./out/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%/*}"
|
||||
./out/runtime-osx-arm/bin/java -jar ./out/TerrarumBuild.jar
|
||||
./out/runtime-osx-arm/bin/Terrarum -jar ./out/TerrarumBuild.jar
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/bash
|
||||
cd "${0%/*}"
|
||||
./out/runtime-osx-x86/bin/java -jar ./out/TerrarumBuild.jar
|
||||
./out/runtime-osx-x86/bin/Terrarum -jar ./out/TerrarumBuild.jar
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <tchar.h>
|
||||
|
||||
int main() {
|
||||
return system(".\\out\\runtime-windows-x86\\bin\\java -jar .\\out\\TerrarumBuild.jar");
|
||||
|
||||
ShellExecute(NULL, "open", "\".\\out\\runtime-windows-x86\\bin\\Terrarum.exe\"", "-jar \".\\out\\TerrarumBuild.jar\"", NULL, SW_HIDE);
|
||||
return 0;
|
||||
|
||||
//return system(".\\out\\runtime-windows-x86\\bin\\Terrarum.exe -jar .\\out\\TerrarumBuild.jar");
|
||||
}
|
||||
@@ -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)
|
||||
@@ -235,6 +248,10 @@ final public class FastMath {
|
||||
return interpolateCatmullRom(u, 0.5f, p0, p1, p2, p3);
|
||||
}
|
||||
|
||||
public static float interpolateCatmullRom(float u, float[] ps) {
|
||||
return interpolateCatmullRom(u, 0.5f, ps[0], ps[1], ps[2], ps[3]);
|
||||
}
|
||||
|
||||
/**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 ]
|
||||
@@ -318,8 +335,7 @@ final public class FastMath {
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3) {
|
||||
/*public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3) {
|
||||
// return interpolateHermite(scale, p0, p1, p2, p3, 0f, 0f);
|
||||
float mu2 = scale * scale;
|
||||
float mu3 = mu2 * scale;
|
||||
@@ -337,7 +353,7 @@ final public class FastMath {
|
||||
float a3 = -2*mu3 + 3*mu2 + 0;
|
||||
|
||||
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) {}
|
||||
|
||||
|
||||
@@ -800,28 +816,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).
|
||||
@@ -876,31 +870,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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,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;
|
||||
@@ -267,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 TICK_SPEED = 64;
|
||||
public static final float UPDATE_RATE = 1f / TICK_SPEED; // 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<>();
|
||||
|
||||
@@ -392,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"));
|
||||
@@ -439,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
|
||||
|
||||
@@ -474,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,
|
||||
@@ -487,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(1);
|
||||
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() {
|
||||
@@ -636,30 +558,44 @@ public class App implements ApplicationListener {
|
||||
FrameBufferManager.end();
|
||||
|
||||
|
||||
|
||||
// process screenshot request
|
||||
if (screenshotRequested) {
|
||||
FrameBufferManager.begin(postProcessorOutFBO);
|
||||
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();
|
||||
screenshotRequested = false;
|
||||
|
||||
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) {
|
||||
@@ -674,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;
|
||||
@@ -792,18 +748,23 @@ public class App implements ApplicationListener {
|
||||
|
||||
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) {
|
||||
@@ -856,6 +817,7 @@ public class App implements ApplicationListener {
|
||||
shaderColLUT.dispose();
|
||||
shaderReflect.dispose();
|
||||
shaderGhastlyWhite.dispose();
|
||||
hq2x.dispose();
|
||||
|
||||
CommonResourcePool.INSTANCE.dispose();
|
||||
fullscreenQuad.dispose();
|
||||
@@ -954,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
|
||||
|
||||
|
||||
@@ -1032,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() {
|
||||
@@ -1329,6 +1378,8 @@ public class App implements ApplicationListener {
|
||||
* @throws NullPointerException if the specified config simply does not exist.
|
||||
*/
|
||||
public static int getConfigInt(String key) {
|
||||
if (key == null) return -1;
|
||||
|
||||
Object cfg = getConfigMaster(key);
|
||||
|
||||
if (cfg instanceof Integer) return ((int) cfg);
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
90
src/net/torvald/terrarum/ControlPresets.kt
Normal file
90
src/net/torvald/terrarum/ControlPresets.kt
Normal file
@@ -0,0 +1,90 @@
|
||||
package net.torvald.terrarum
|
||||
|
||||
import com.badlogic.gdx.Input
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-08-24.
|
||||
*/
|
||||
object ControlPresets {
|
||||
|
||||
val wasd = hashMapOf<String, Int>(
|
||||
"control_key_up" to Input.Keys.W,
|
||||
"control_key_left" to Input.Keys.A,
|
||||
"control_key_down" to Input.Keys.S,
|
||||
"control_key_right" to Input.Keys.D,
|
||||
|
||||
"control_key_jump" to Input.Keys.SPACE,
|
||||
"control_key_movementaux" to Input.Keys.SHIFT_LEFT, // movement-auxiliary, or hookshot
|
||||
"control_key_inventory" to Input.Keys.Q,
|
||||
"control_key_interact" to Input.Keys.R,
|
||||
"control_key_discard" to Input.Keys.F,
|
||||
"control_key_close" to Input.Keys.X, // this or hard-coded ESC
|
||||
"control_key_zoom" to Input.Keys.Z,
|
||||
|
||||
"control_key_gamemenu" to Input.Keys.TAB,
|
||||
"control_key_crafting" to Input.Keys.E,
|
||||
"control_key_quicksel" to Input.Keys.CONTROL_LEFT, // pie menu is now LShift because CapsLock is actually used by the my bespoke keyboard input
|
||||
)
|
||||
|
||||
val esdf = hashMapOf<String, Int>(
|
||||
"control_key_up" to Input.Keys.E,
|
||||
"control_key_left" to Input.Keys.S,
|
||||
"control_key_down" to Input.Keys.D,
|
||||
"control_key_right" to Input.Keys.F, // ESDF Masterrace
|
||||
|
||||
"control_key_jump" to Input.Keys.SPACE,
|
||||
"control_key_movementaux" to Input.Keys.A, // movement-auxiliary, or hookshot
|
||||
"control_key_inventory" to Input.Keys.Q,
|
||||
"control_key_interact" to Input.Keys.R,
|
||||
"control_key_discard" to Input.Keys.T,
|
||||
"control_key_close" to Input.Keys.C, // this or hard-coded ESC
|
||||
"control_key_zoom" to Input.Keys.Z,
|
||||
|
||||
"control_key_gamemenu" to Input.Keys.TAB,
|
||||
"control_key_crafting" to Input.Keys.W,
|
||||
"control_key_quicksel" to Input.Keys.SHIFT_LEFT, // pie menu is now LShift because CapsLock is actually used by the my bespoke keyboard input
|
||||
)
|
||||
|
||||
val ijkl = hashMapOf<String, Int>(
|
||||
"control_key_up" to Input.Keys.I,
|
||||
"control_key_left" to Input.Keys.J,
|
||||
"control_key_down" to Input.Keys.K,
|
||||
"control_key_right" to Input.Keys.L,
|
||||
|
||||
"control_key_jump" to Input.Keys.SPACE,
|
||||
"control_key_movementaux" to Input.Keys.SEMICOLON, // movement-auxiliary, or hookshot
|
||||
"control_key_inventory" to Input.Keys.P,
|
||||
"control_key_interact" to Input.Keys.U,
|
||||
"control_key_discard" to Input.Keys.Y,
|
||||
"control_key_close" to Input.Keys.M, // this or hard-coded ESC
|
||||
"control_key_zoom" to Input.Keys.SLASH,
|
||||
|
||||
"control_key_gamemenu" to Input.Keys.LEFT_BRACKET,
|
||||
"control_key_crafting" to Input.Keys.O,
|
||||
"control_key_quicksel" to Input.Keys.APOSTROPHE, // pie menu is now LShift because CapsLock is actually used by the my bespoke keyboard input
|
||||
)
|
||||
|
||||
val empty = hashMapOf<String, Int>()
|
||||
|
||||
val presets = hashMapOf( // unordered
|
||||
"WASD" to wasd,
|
||||
"ESDF" to esdf,
|
||||
"IJKL" to ijkl,
|
||||
"Custom" to empty,
|
||||
)
|
||||
|
||||
val presetLabels = listOf( // ordered
|
||||
"WASD",
|
||||
"ESDF",
|
||||
"IJKL",
|
||||
"Custom",
|
||||
)
|
||||
|
||||
fun getKey(label: String?): Int {
|
||||
if (label == null) return -1
|
||||
|
||||
val presetName = App.getConfigString("control_preset_keyboard") ?: "Custom"
|
||||
|
||||
return (presets[presetName] ?: throw IllegalStateException("No such keyboard preset: $presetName")).getOrDefault(label, App.getConfigInt(label))
|
||||
}
|
||||
}
|
||||
@@ -24,13 +24,15 @@ object DefaultConfig {
|
||||
"language" to App.getSysLang(),
|
||||
"notificationshowuptime" to 4000, // 4s
|
||||
"selecteditemnameshowuptime" to 4000, // 4s
|
||||
"autosaveinterval" to 300000, // 5s
|
||||
"autosaveinterval" to 300000, // 5m
|
||||
"multithread" to true,
|
||||
|
||||
"showhealthmessageonstartup" to true,
|
||||
|
||||
"usexinput" to true, // when FALSE, LT+RT input on xbox controller is impossible
|
||||
|
||||
"control_preset_keyboard" to "WASD",
|
||||
|
||||
"control_gamepad_keyn" to 3,
|
||||
"control_gamepad_keyw" to 2,
|
||||
"control_gamepad_keys" to 0,
|
||||
@@ -112,6 +114,7 @@ object DefaultConfig {
|
||||
"inputmethod" to "none",
|
||||
|
||||
"screenmagnifying" to 1.0,
|
||||
"screenmagnifyingfilter" to "none", // "none", "bilinear", "hq2x"
|
||||
|
||||
"fx_newlight" to false,
|
||||
|
||||
@@ -119,6 +122,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
|
||||
}
|
||||
@@ -32,6 +32,7 @@ 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;
|
||||
@@ -64,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
|
||||
@@ -204,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() })
|
||||
}
|
||||
|
||||
////////////
|
||||
@@ -490,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, dist2, dist3)
|
||||
min(min(dist1, dist2), dist3)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -536,6 +531,9 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
fun onConfigChange() {
|
||||
}
|
||||
}
|
||||
|
||||
inline fun Lock.lock(body: () -> Unit) {
|
||||
|
||||
@@ -5,8 +5,7 @@ import net.torvald.terrarum.utils.JsonFetcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Bootstrapper that launches the bundled JVM and injects VM configs such as -Xmx
|
||||
@@ -25,7 +24,6 @@ public class Principii {
|
||||
/** defaultDir + "/config.json" */
|
||||
private static String configDir;
|
||||
|
||||
|
||||
public static void getDefaultDirRoot() {
|
||||
String OS = OSName.toUpperCase();
|
||||
if (OS.contains("WIN")) {
|
||||
@@ -63,7 +61,7 @@ public class Principii {
|
||||
devMode = true;
|
||||
}
|
||||
|
||||
String extracmd = devMode ? " -ea" : "";
|
||||
String extracmd0 = devMode ? " -ea" : "";
|
||||
String OS = OSName.toUpperCase();
|
||||
String CPUARCH = System.getProperty("os.arch").toUpperCase();
|
||||
String runtimeRoot;
|
||||
@@ -82,14 +80,14 @@ public class Principii {
|
||||
}
|
||||
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;
|
||||
extracmd += " -XstartOnFirstThread";
|
||||
extracmd0 += " -XstartOnFirstThread";
|
||||
}
|
||||
else {
|
||||
runtimeRoot = "runtime-linux-" + runtimeArch;
|
||||
extracmd += " -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd";
|
||||
extracmd0 += " -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd";
|
||||
}
|
||||
|
||||
String runtime = new File("out/"+runtimeRoot+"/bin/java").getAbsolutePath();
|
||||
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);
|
||||
|
||||
|
||||
@@ -102,13 +100,27 @@ public class Principii {
|
||||
|
||||
|
||||
int xmx = getConfigInt("jvm_xmx");
|
||||
String userDefinedExtraCmd = getConfigString("jvm_extra_cmd").trim();
|
||||
if (!userDefinedExtraCmd.isEmpty()) userDefinedExtraCmd = " "+userDefinedExtraCmd;
|
||||
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 {
|
||||
String[] cmd = (runtime+extracmd+userDefinedExtraCmd+" -Xms1G -Xmx"+xmx+"G -cp ./out/TerrarumBuild.jar net.torvald.terrarum.App").split(" ");
|
||||
ProcessBuilder pb = new ProcessBuilder(cmd);
|
||||
pb.inheritIO();
|
||||
System.exit(pb.start().waitFor());
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
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.savegame.DiskSkimmer
|
||||
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.
|
||||
@@ -14,7 +29,7 @@ import kotlin.io.path.Path
|
||||
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.sortedByDescending {
|
||||
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)
|
||||
@@ -57,22 +72,161 @@ class SavegameCollection(files0: List<DiskSkimmer>) {
|
||||
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)
|
||||
}
|
||||
|
||||
class SavegameCollectionPair(player: SavegameCollection?, world: SavegameCollection?) {
|
||||
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()}")
|
||||
}
|
||||
|
||||
private var manualPlayer: DiskSkimmer? = null
|
||||
private var manualWorld: DiskSkimmer? = null
|
||||
private var autoPlayer: DiskSkimmer? = null
|
||||
private var autoWorld: DiskSkimmer? = null
|
||||
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
|
||||
|
||||
var newerSaveIsDamaged = false // only when most recent save is corrupted
|
||||
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) {
|
||||
@@ -119,8 +273,11 @@ class SavegameCollectionPair(player: SavegameCollection?, world: SavegameCollect
|
||||
pc += 1
|
||||
wc += 1
|
||||
}
|
||||
else
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +304,7 @@ class SavegameCollectionPair(player: SavegameCollection?, world: SavegameCollect
|
||||
printdbg(this, "autoWorld = ${autoWorld?.diskFile?.path}")
|
||||
printdbg(this, "status = $status")
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
private fun DiskSkimmer.isAutosaved() = this.getSaveMode().and(0b0000_0010) != 0
|
||||
|
||||
@@ -162,7 +319,7 @@ class SavegameCollectionPair(player: SavegameCollection?, world: SavegameCollect
|
||||
fun moreRecentAutosaveAvailable() = (status == 2)
|
||||
fun saveAvaliable() = (status > 0)
|
||||
|
||||
fun getManualSave(): DiskPair? {
|
||||
/*fun getManualSave(): DiskPair? {
|
||||
if (status == 0) return null
|
||||
return DiskPair(manualPlayer!!, manualWorld!!)
|
||||
}
|
||||
@@ -178,7 +335,14 @@ class SavegameCollectionPair(player: SavegameCollection?, world: SavegameCollect
|
||||
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)
|
||||
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,13 +26,9 @@ 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.utils.JsonFetcher
|
||||
import net.torvald.terrarum.utils.forEachSiblings
|
||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||
import net.torvald.terrarumsansbitmap.gdx.TerrarumSansBitmap
|
||||
import net.torvald.unsafe.UnsafeHelper
|
||||
@@ -40,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
|
||||
@@ -238,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
|
||||
@@ -321,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
|
||||
@@ -399,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
|
||||
|
||||
@@ -410,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
|
||||
}
|
||||
@@ -421,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
|
||||
|
||||
@@ -432,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
|
||||
}
|
||||
@@ -611,28 +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 Boolean.toLong(shift: Int = 0) = if (this) 1L.shl(shift) else 0L
|
||||
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 {
|
||||
@@ -651,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
|
||||
@@ -788,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 {
|
||||
@@ -800,17 +799,20 @@ fun AppUpdateListOfSavegames() {
|
||||
}
|
||||
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
||||
println("${index+1}.\t${it.diskFile.absolutePath}")
|
||||
it.rebuild()
|
||||
// it.rebuild()
|
||||
|
||||
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 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] = SavegameCollection.collectFromBaseFilename(File(worldsDir), it.diskFile.name)
|
||||
App.savegameWorlds[worldUUID] = collection
|
||||
App.savegameWorldsName[worldUUID] = it.getDiskName(Common.CHARSET)
|
||||
App.sortedSavegameWorlds.add(worldUUID)
|
||||
}
|
||||
@@ -832,22 +834,30 @@ fun AppUpdateListOfSavegames() {
|
||||
}
|
||||
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
||||
println("${index+1}.\t${it.diskFile.absolutePath}")
|
||||
it.rebuild()
|
||||
// it.rebuild()
|
||||
|
||||
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 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] = SavegameCollection.collectFromBaseFilename(File(playersDir), it.diskFile.name)
|
||||
App.savegamePlayers[playerUUID] = collection
|
||||
App.savegamePlayersName[playerUUID] = it.getDiskName(Common.CHARSET)
|
||||
App.sortedPlayers.add(playerUUID)
|
||||
}
|
||||
}
|
||||
|
||||
println("SortedPlayers...")
|
||||
App.sortedPlayers.forEach {
|
||||
println(it)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -887,3 +897,11 @@ fun checkForSavegameDamage(skimmer: DiskSkimmer): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No lateinit!
|
||||
*/
|
||||
inline fun Disposable.tryDispose() {
|
||||
try { this.dispose() }
|
||||
catch (_: Throwable) {}
|
||||
}
|
||||
@@ -62,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 = "test002"
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// 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
|
||||
@@ -39,7 +40,7 @@ class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
|
||||
var windowH: Int = 0; private set
|
||||
|
||||
init {
|
||||
setDimension(maxOf(minimumW, scrw), maxOf(minimumH, scrh), App.getConfigDouble("screenmagnifying").toFloat())
|
||||
setDimension(max(minimumW, scrw), max(minimumH, scrh), App.getConfigDouble("screenmagnifying").toFloat())
|
||||
}
|
||||
|
||||
fun setDimension(scrw: Int, scrh: Int, magn: Float,) {
|
||||
@@ -56,8 +57,8 @@ class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
|
||||
|
||||
this.magn = magn
|
||||
|
||||
windowW = (scrw * magn).ceilInt() and 0x7FFFFFFE
|
||||
windowH = (scrh * magn).ceilInt() and 0x7FFFFFFE
|
||||
windowW = (scrw * magn).ceilToInt() and 0x7FFFFFFE
|
||||
windowH = (scrh * magn).ceilToInt() and 0x7FFFFFFE
|
||||
|
||||
|
||||
printdbg(this, "Window dim: $windowW x $windowH, called by:")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -75,6 +75,8 @@ class BlockProp {
|
||||
BlockCodex[BlockCodex.tileToVirtual[id]!![offset]]._lumCol.lane(channel)
|
||||
}
|
||||
|
||||
fun hasTag(s: String) = tags.contains(s)
|
||||
|
||||
/**
|
||||
* @param luminosity
|
||||
*/
|
||||
|
||||
@@ -108,7 +108,7 @@ object BlockPropUtil {
|
||||
return when (prop.dynamicLuminosityFunction) {
|
||||
1 -> getTorchFlicker(prop)
|
||||
2 -> (INGAME.world).globalLight.cpy() // current global light
|
||||
3 -> WeatherMixer.getGlobalLightOfTime(INGAME.world, WorldTime.DAY_LENGTH / 2).cpy() // daylight at noon
|
||||
3 -> WeatherMixer.getGlobalLightOfTimeOfNoon().cpy() // daylight at noon
|
||||
4 -> getSlowBreath(prop)
|
||||
5 -> getPulsate(prop)
|
||||
else -> prop.baseLumCol
|
||||
|
||||
@@ -19,11 +19,12 @@ import net.torvald.terrarum.toInt
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object MinimapComposer : Disposable {
|
||||
|
||||
private val threadExecutor = ThreadExecutor(maxOf(1, App.THREAD_COUNT.times(2).div(3)))
|
||||
private val threadExecutor = ThreadExecutor(max(1, App.THREAD_COUNT.times(2).div(3)))
|
||||
|
||||
const val SQUARE_SIZE = 13 // preferably in odd number
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user