diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/alphabetic_presentation_forms_extrawide_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/alphabetic_presentation_forms_extrawide_variable.tga deleted file mode 100644 index 390662bb4..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/alphabetic_presentation_forms_extrawide_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:aacb9c40e16823ec6e1b94b3c3c1a319bef9f79e4fff432531f24c82c6332cd0 -size 81938 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/ascii_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/ascii_variable.tga deleted file mode 100755 index 51f005914..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/ascii_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:afe6d721b7020fab1be93c09b3b99d67f745f0fbf12080d2a7d33c20bd7cab55 -size 327698 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/bengali_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/bengali_variable.tga deleted file mode 100755 index 3728195fc..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/bengali_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f28d09f763e3b016ae0df926de4c2ecb8dd22555c96cb8c2eb24caf4b016e39b -size 163858 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/braille_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/braille_variable.tga deleted file mode 100644 index 9e687264a..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/braille_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:859ed572e676877d736779e060ac3a079ba30c2fa958dba7e6f4742d144836dc -size 327698 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/cjkpunct.tga b/assets/graphics/fonts/terrarum-sans-bitmap/cjkpunct.tga deleted file mode 100755 index 3984604c5..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/cjkpunct.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d5693ce974b02b8e2baf82530b3aa5a03201179814344b6c69c6859f69ee50f -size 51244 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/cjkpunct_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/cjkpunct_variable.tga deleted file mode 100644 index 3eb21d049..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/cjkpunct_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:523d141f7a5391543e3898b37607bf5a77ddfc9069970de6e690be85d508987f -size 81938 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/control_pictures_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/control_pictures_variable.tga deleted file mode 100644 index 1268f910e..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/control_pictures_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43c781f7fdcecf5846e2853f473f5b5504df53d50d801effa5b60bbeaf5c5753 -size 81938 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/currencies_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/currencies_variable.tga deleted file mode 100644 index ece8b140a..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/currencies_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1c0159443a552ba4b53b7fcdd1cda07e46e42ff7b4b52d2ac543414834138149 -size 61458 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/cyrilic_bulgarian_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/cyrilic_bulgarian_variable.tga deleted file mode 100755 index 29f14613b..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/cyrilic_bulgarian_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:aae36e1fb7abf3f7962dd6c0f6faff6b71a1388cebd343c8433469e8bbd0b965 -size 122898 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/cyrilic_serbian_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/cyrilic_serbian_variable.tga deleted file mode 100755 index d766028e3..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/cyrilic_serbian_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4d3169bfffbe2cddc7a788bac270f19072fb31246908dccb3c088becc2ce975e -size 122898 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/cyrilic_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/cyrilic_variable.tga deleted file mode 100755 index 51f8499d1..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/cyrilic_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:08b5474e566640765a903154c4f364681e00274d691a75bd39ba65fb0cb0bccb -size 389138 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/devanagari_internal_extrawide_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/devanagari_internal_extrawide_variable.tga deleted file mode 100644 index 5f6852153..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/devanagari_internal_extrawide_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f65759b402237de56814f587622c95931618bcf001bd5a183c0b2ebaf041c0a1 -size 81938 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/devanagari_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/devanagari_variable.tga deleted file mode 100644 index 00d9892e4..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/devanagari_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bb0871941e2eed234eda0fc757c7136e0e30abf61881267e3797ada6a1e79c85 -size 1474578 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/diacritical_marks_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/diacritical_marks_variable.tga deleted file mode 100755 index c9542a303..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/diacritical_marks_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1a84f97ba227c517d9625a013646332b5cd760d65084e1f1b0544a3f58c8512d -size 143378 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/enclosed_alphanumeric_supplement_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/enclosed_alphanumeric_supplement_variable.tga deleted file mode 100644 index f96929762..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/enclosed_alphanumeric_supplement_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5fc38ac28b36e49eea89fcccf60bfd91a8a1f2106982f21400fadf7933b5ee3a -size 327698 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/futhark.tga b/assets/graphics/fonts/terrarum-sans-bitmap/futhark.tga deleted file mode 100755 index 7aeece46d..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/futhark.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f7fef0785183c24f2a52ef0a2aca5737da5ed14805b4dd7ab5c8a241b2e01f69 -size 69164 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/greek_polytonic_xyswap_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/greek_polytonic_xyswap_variable.tga deleted file mode 100755 index 30c286676..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/greek_polytonic_xyswap_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:59bdf6714718cb083939a373714c588b132fb7e0f4352b408aed774ab8c472c3 -size 327698 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/greek_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/greek_variable.tga deleted file mode 100755 index 2372723e9..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/greek_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:20faeeba488e789f88e70f704819b871ea498e2ce9bcd9c4ed9c48ad565bc248 -size 122898 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/halfwidth_fullwidth_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/halfwidth_fullwidth_variable.tga deleted file mode 100644 index ae00a6ad3..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/halfwidth_fullwidth_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:805b0b662b81146136313f3c685cedc583a0aeb96fd374f6450ca5968343478a -size 327698 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/hangul_johab.tga b/assets/graphics/fonts/terrarum-sans-bitmap/hangul_johab.tga deleted file mode 100644 index 0985c67eb..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/hangul_johab.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:051d882623fcb5e14a2a32aed68b3090a76efc4044472d521a188fbf4fc1ad89 -size 3588018 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/hayeren_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/hayeren_variable.tga deleted file mode 100755 index c657e9376..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/hayeren_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b8fd0eee31b88ad4c46379cdb372946129d1860cd04da8e3660d2e55604a4634 -size 122898 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/internal_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/internal_variable.tga deleted file mode 100644 index 997b919fa..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/internal_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:acd10775e2d8c2494c9896519c7172a7856cd36a4976e9779a8bcd088e5517a2 -size 327698 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/ipa_ext_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/ipa_ext_variable.tga deleted file mode 100755 index 4ce33de68..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/ipa_ext_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f76c223c431d3f8da64a76aa4d0b77e4f2b4c0895e593f52615baa2add6079f -size 225298 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/kana_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/kana_variable.tga deleted file mode 100644 index 29c69f17f..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/kana_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:daa80cfe1f516fb482fe2d95abcd4d2205249c956a4fa93f1c65737eb78a8ebd -size 327698 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/kartuli_allcaps_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/kartuli_allcaps_variable.tga deleted file mode 100755 index 100d4581f..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/kartuli_allcaps_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5924b39e366ef2041e09a77b33eec880c93010e1a51df213da6d8889c823c5d1 -size 61458 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/kartuli_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/kartuli_variable.tga deleted file mode 100755 index 5bd190b5a..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/kartuli_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:216d05c9f72e5396374eb44284dca26cce889dbb6d3be88591a075aa6bf1738c -size 61458 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/latinExtA_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/latinExtA_variable.tga deleted file mode 100755 index d7bc41e84..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/latinExtA_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1426ccf33386e54fb5fd42ce352ead197e8ce71d95cc4c11186b6b2e1db3d17b -size 163858 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/latinExtB_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/latinExtB_variable.tga deleted file mode 100755 index eb75c4fe2..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/latinExtB_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:568a839af1f250d91f72a417c428098a0bcf533ac7c4dc784a7ba4f2c5cbe117 -size 266258 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/latinExtC_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/latinExtC_variable.tga deleted file mode 100755 index 660b66d75..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/latinExtC_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f6cae863e7e8df87192b83715372b62d275a5ea7f9c8784b1a052e8f27835f8b -size 40978 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/latinExtD_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/latinExtD_variable.tga deleted file mode 100644 index ad34ce59c..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/latinExtD_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bebc1dc97ca54de08c27d01f49d994984cd772de055af3647ddf05b470f3b6c5 -size 286738 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/latinExt_additional_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/latinExt_additional_variable.tga deleted file mode 100755 index 34866b489..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/latinExt_additional_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7f32c98fb1e95ef17e2db96114f14782ae22741c146a0c9d6e25d4113dc28125 -size 327698 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/letterlike_symbols_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/letterlike_symbols_variable.tga deleted file mode 100644 index 88f4862f4..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/letterlike_symbols_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f5ed0220afe8e416205c4b860f84517d3a551c1c10a65af419e2ee36f087e4bc -size 102418 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/phonetic_extensions_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/phonetic_extensions_variable.tga deleted file mode 100644 index e57364626..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/phonetic_extensions_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5b4682a6dc0a237f795184d7a73c14094b0ca45020c71bcab8b1871569a55afe -size 245778 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/pua_codestyle_ascii_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/pua_codestyle_ascii_variable.tga deleted file mode 100644 index 4b4d5d0f3..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/pua_codestyle_ascii_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:278dd8d1bf3c7dca8a08f2fd3953f1fb7c225e8303f1779d84fe627b8023633d -size 122898 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/puae000-e0ff.tga b/assets/graphics/fonts/terrarum-sans-bitmap/puae000-e0ff.tga deleted file mode 100755 index 0287aee7d..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/puae000-e0ff.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:408eefade3bd4c465a93d8cd45ff5c1453b12270babcd3d2365577b6df93fdf9 -size 409618 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/richtext_furigana.tga b/assets/graphics/fonts/terrarum-sans-bitmap/richtext_furigana.tga deleted file mode 100755 index f8abe556b..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/richtext_furigana.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9ded39ee5d160e197c59aa5342d01f08c4a8b69b2f822e97079931ea8f1ddb3d -size 24620 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/sundanese_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/sundanese_variable.tga deleted file mode 100644 index 2fedfb5d5..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/sundanese_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:df567cc8b42badebbb47c3c11f71c95579139bb2e26c5306627038674f7cfbd7 -size 122898 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/tamil_extrawide_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/tamil_extrawide_variable.tga deleted file mode 100644 index 55ca80ae2..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/tamil_extrawide_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:df0eaea60ebfa8995faa48ecb7aa9ea2f94a5085877272375fab46c67f23afd2 -size 491538 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/thai_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/thai_variable.tga deleted file mode 100755 index 0fa454f3e..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/thai_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c5153ea9337af90d633b61bb7ddcbdf11066da4d1e26657765e0c3cb7fd19e73 -size 122898 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/tsalagi_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/tsalagi_variable.tga deleted file mode 100755 index 219130b65..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/tsalagi_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:49765b0f1a00c6adbb3a16c7896aab854903b7bce3c1897e62887407be3aeb45 -size 122898 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/unipunct_variable.tga b/assets/graphics/fonts/terrarum-sans-bitmap/unipunct_variable.tga deleted file mode 100755 index 81dfaa961..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/unipunct_variable.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a8f946a1b439d1e2dc4e5403805c500c5652252f4a0aca7b9fc315f12080fb0b -size 204818 diff --git a/assets/graphics/fonts/terrarum-sans-bitmap/wenquanyi.tga.gz b/assets/graphics/fonts/terrarum-sans-bitmap/wenquanyi.tga.gz deleted file mode 100644 index fe79a4be9..000000000 --- a/assets/graphics/fonts/terrarum-sans-bitmap/wenquanyi.tga.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b72db4deea7922d7b34779c95c4718c73c36024678954103414df5ad11d598db -size 1212274 diff --git a/assets/mods/dwarventech/wires/decayconsts.csv b/assets/mods/dwarventech/wires/decayconsts.csv new file mode 100644 index 000000000..51cefa3ba --- /dev/null +++ b/assets/mods/dwarventech/wires/decayconsts.csv @@ -0,0 +1,10 @@ +wireItemID;const +wire@dwarventech:1;0.995 +wire@dwarventech:2;0.995 +wire@dwarventech:3;0.995 +wire@dwarventech:4;0.995 +wire@dwarventech:5;0.995 +wire@dwarventech:6;0.999 +wire@dwarventech:7;0.999 +wire@dwarventech:8;0.999 + diff --git a/buildapp/Makefile b/buildapp/Makefile index 6df413837..7a7e9b192 100644 --- a/buildapp/Makefile +++ b/buildapp/Makefile @@ -5,6 +5,7 @@ what: assets: ./make_assets_release.sh || true + ./make_assets_archive.sh linux_x86: ./build_app_linux_x86.sh diff --git a/buildapp/build_app_linux_arm.sh b/buildapp/build_app_linux_arm.sh index cfaa95603..26a5ead80 100755 --- a/buildapp/build_app_linux_arm.sh +++ b/buildapp/build_app_linux_arm.sh @@ -9,8 +9,8 @@ RUNTIME="runtime-linux-arm" DESKTOPFILE="../out/build_autogen_linux.desktop" JARNAME="TerrarumBuild.jar" -if [ ! -f "out/assets.tar.zst" ] || [ ! -f "out/assets.manifest" ]; then - echo "'assets.tar.zst' or 'assets.manifest' not found in out/; run 'make assets' first." >&2 +if [ ! -f "out/assets.tevd" ]; then + echo "'assets.tevd' not found in out/; run 'make assets' first." >&2 exit 1 fi @@ -29,9 +29,8 @@ mkdir $DESTDIR/out cp -r "../out/$RUNTIME" $DESTDIR/out/ mv $DESTDIR/out/$RUNTIME/bin/java $DESTDIR/out/$RUNTIME/bin/java -# Copy over the asset archive, manifest, and jarfile -cp "out/assets.tar.zst" $DESTDIR/ -cp "out/assets.manifest" $DESTDIR/ +# Copy over the asset archive and jarfile +cp "out/assets.tevd" $DESTDIR/ cp "../out/$JARNAME" $DESTDIR/out/ # Pack everything to AppImage diff --git a/buildapp/build_app_linux_x86.sh b/buildapp/build_app_linux_x86.sh index 597a6d37f..fe0cb5e2f 100755 --- a/buildapp/build_app_linux_x86.sh +++ b/buildapp/build_app_linux_x86.sh @@ -9,8 +9,8 @@ RUNTIME="runtime-linux-x86" DESKTOPFILE="../out/build_autogen_linux.desktop" JARNAME="TerrarumBuild.jar" -if [ ! -f "out/assets.tar.zst" ] || [ ! -f "out/assets.manifest" ]; then - echo "'assets.tar.zst' or 'assets.manifest' not found in out/; run 'make assets' first." >&2 +if [ ! -f "out/assets.tevd" ]; then + echo "'assets.tevd' not found in out/; run 'make assets' first." >&2 exit 1 fi @@ -29,9 +29,8 @@ mkdir $DESTDIR/out cp -r "../out/$RUNTIME" $DESTDIR/out/ mv $DESTDIR/out/$RUNTIME/bin/java $DESTDIR/out/$RUNTIME/bin/java -# Copy over the asset archive, manifest, and jarfile -cp "out/assets.tar.zst" $DESTDIR/ -cp "out/assets.manifest" $DESTDIR/ +# Copy over the asset archive and jarfile +cp "out/assets.tevd" $DESTDIR/ cp "../out/$JARNAME" $DESTDIR/out/ # Pack everything to AppImage diff --git a/buildapp/build_app_mac_arm.sh b/buildapp/build_app_mac_arm.sh index 5e20ae6af..e95dd20ca 100755 --- a/buildapp/build_app_mac_arm.sh +++ b/buildapp/build_app_mac_arm.sh @@ -9,8 +9,8 @@ RUNTIME="runtime-osx-arm" PLISTFILE="../out/build_autogen_macos_Info.plist" JARNAME="TerrarumBuild.jar" -if [ ! -f "out/assets.tar.zst" ] || [ ! -f "out/assets.manifest" ]; then - echo "'assets.tar.zst' or 'assets.manifest' not found in out/; run 'make assets' first." >&2 +if [ ! -f "out/assets.tevd" ]; then + echo "'assets.tevd' not found in out/; run 'make assets' first." >&2 exit 1 fi @@ -32,9 +32,8 @@ 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/java -# Copy over the asset archive, manifest, and jarfile -cp "out/assets.tar.zst" $DESTDIR/Contents/MacOS/ -cp "out/assets.manifest" $DESTDIR/Contents/MacOS/ +# Copy over the asset archive and jarfile +cp "out/assets.tevd" $DESTDIR/Contents/MacOS/ cp "../out/$JARNAME" $DESTDIR/Contents/MacOS/out/ # zip everything diff --git a/buildapp/build_app_mac_x86.sh b/buildapp/build_app_mac_x86.sh index f5e9c6e35..269d8972a 100755 --- a/buildapp/build_app_mac_x86.sh +++ b/buildapp/build_app_mac_x86.sh @@ -9,8 +9,8 @@ RUNTIME="runtime-osx-x86" PLISTFILE="../out/build_autogen_macos_Info.plist" JARNAME="TerrarumBuild.jar" -if [ ! -f "out/assets.tar.zst" ] || [ ! -f "out/assets.manifest" ]; then - echo "'assets.tar.zst' or 'assets.manifest' not found in out/; run 'make assets' first." >&2 +if [ ! -f "out/assets.tevd" ]; then + echo "'assets.tevd' not found in out/; run 'make assets' first." >&2 exit 1 fi @@ -32,9 +32,8 @@ 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/java -# Copy over the asset archive, manifest, and jarfile -cp "out/assets.tar.zst" $DESTDIR/Contents/MacOS/ -cp "out/assets.manifest" $DESTDIR/Contents/MacOS/ +# Copy over the asset archive and jarfile +cp "out/assets.tevd" $DESTDIR/Contents/MacOS/ cp "../out/$JARNAME" $DESTDIR/Contents/MacOS/out/ # zip everything diff --git a/buildapp/build_app_windows_x86.sh b/buildapp/build_app_windows_x86.sh index 8bf1b85c4..2c0df619f 100755 --- a/buildapp/build_app_windows_x86.sh +++ b/buildapp/build_app_windows_x86.sh @@ -8,8 +8,8 @@ RUNTIME="runtime-windows-x86" RCFILE="../out/build_autogen_windows.rc" JARNAME="TerrarumBuild.jar" -if [ ! -f "out/assets.tar.zst" ] || [ ! -f "out/assets.manifest" ]; then - echo "'assets.tar.zst' or 'assets.manifest' not found in out/; run 'make assets' first." >&2 +if [ ! -f "out/assets.tevd" ]; then + echo "'assets.tevd' not found in out/; run 'make assets' first." >&2 exit 1 fi @@ -34,9 +34,8 @@ mkdir $DESTDIR/out cp -r "../out/$RUNTIME" $DESTDIR/out/ mv $DESTDIR/out/$RUNTIME/bin/java.exe $DESTDIR/out/$RUNTIME/bin/java.exe -# Copy over the asset archive, manifest, and jarfile -cp "out/assets.tar.zst" $DESTDIR/ -cp "out/assets.manifest" $DESTDIR/ +# Copy over the asset archive and jarfile +cp "out/assets.tevd" $DESTDIR/ cp "../out/$JARNAME" $DESTDIR/out/ # zip everything diff --git a/buildapp/make_assets_archive.sh b/buildapp/make_assets_archive.sh new file mode 100644 index 000000000..6c3f61541 --- /dev/null +++ b/buildapp/make_assets_archive.sh @@ -0,0 +1,43 @@ +#!/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%/*}" +SRCDIR="../assets_release" +OUTDIR="out" +JARNAME="TerrarumBuild.jar" +TVDJAR="../lib/TerranVirtualDisk.jar" + +if [ ! -d "$SRCDIR" ]; then + echo "Error: $SRCDIR does not exist. Run make_assets_release.sh first." >&2 + exit 1 +fi + +if [ ! -f "../out/$JARNAME" ]; then + echo "Error: ../out/$JARNAME not found. Build the project first." >&2 + exit 1 +fi + +if [ ! -f "$TVDJAR" ]; then + echo "Error: $TVDJAR not found." >&2 + exit 1 +fi + +mkdir -p "$OUTDIR" + +echo "Creating assets.tevd from $SRCDIR..." + +# Build classpath from project JAR and all library JARs +CP="../out/$JARNAME" +for jar in ../lib/*.jar; do + CP="$CP:$jar" +done + +java -cp "$CP" net.torvald.terrarum.AssetArchiveBuilderKt "$SRCDIR" "$OUTDIR/assets.tevd" + +if [ $? -ne 0 ]; then + echo "Error: Failed to create assets.tevd" >&2 + exit 1 +fi + +echo "Done. Output:" +echo " $OUTDIR/assets.tevd ($(du -h "$OUTDIR/assets.tevd" | cut -f1))" diff --git a/lib/TerranVirtualDisk-src.jar b/lib/TerranVirtualDisk-src.jar index 59696b283..d8afa5418 100644 --- a/lib/TerranVirtualDisk-src.jar +++ b/lib/TerranVirtualDisk-src.jar @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ec423b385c3ca9480ebfd28a8e06bee6f498fc7782dde5181baeb26753747cc5 -size 93580 +oid sha256:e5148d00a56a7decfcc4ef561fbbb38ad410af8234bc366e5cd5d3c2ffcacf58 +size 93607 diff --git a/lib/TerranVirtualDisk.jar b/lib/TerranVirtualDisk.jar index 95bf490b9..628638663 100644 --- a/lib/TerranVirtualDisk.jar +++ b/lib/TerranVirtualDisk.jar @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49a36b137be41f5da11ef2d82a75357f6681d5191f2236ec6a06d15821a3fd4d -size 5212250 +oid sha256:ce9fa6de2159931cb6251f150c559a5e90607bf04165da439cb6f5792af182d7 +size 5095118 diff --git a/lib/TerrarumSansBitmap.jar b/lib/TerrarumSansBitmap.jar index 108a9b6f4..d27b23054 100644 --- a/lib/TerrarumSansBitmap.jar +++ b/lib/TerrarumSansBitmap.jar @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eedebc3277c5d03bf8c6ce40a60a47815c1a02126719ace747941cbaf8f68975 -size 243589 +oid sha256:2f2c3a9b55b4824cdd301eb5b479d9352f06821649457a8652f79cf2fc57ad73 +size 2113833 diff --git a/src/net/torvald/btex/BTeXParser.kt b/src/net/torvald/btex/BTeXParser.kt index 33e7f98af..f1810ea83 100644 --- a/src/net/torvald/btex/BTeXParser.kt +++ b/src/net/torvald/btex/BTeXParser.kt @@ -2017,15 +2017,15 @@ object BTeXParser { private lateinit var subtitleFont: TerrarumSansBitmap fun preloadFonts() { - testFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha, textCacheSize = 4096) - partTitleFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha).also { + testFont = TerrarumSansBitmap(shadowAlpha = bodyTextShadowAlpha, textCacheSize = 4096) + partTitleFont = TerrarumSansBitmap(shadowAlpha = bodyTextShadowAlpha).also { it.interchar = 1 } - titleFont = TerrarumSansBitmap(App.FONT_DIR).also { + titleFont = TerrarumSansBitmap().also { it.interchar = 1 it.scale = 2 } - subtitleFont = TerrarumSansBitmap(App.FONT_DIR).also { + subtitleFont = TerrarumSansBitmap().also { it.interchar = 1 } fontInit = true diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index 6db30b032..3bd73f6f8 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -255,10 +255,6 @@ public class App implements ApplicationListener { public static DebugTimers debugTimers = new DebugTimers(); - public static final String FONT_DIR = "assets/graphics/fonts/terrarum-sans-bitmap"; - - - public static Texture[] ditherPatterns = new Texture[4]; // public static ShaderProgram shaderHicolour; public static ShaderProgram shaderDebugDiff; @@ -445,6 +441,7 @@ public class App implements ApplicationListener { // load configs getDefaultDirectory(); createDirs(); + AssetCache.INSTANCE.init(); initialiseConfig(); readConfigJson(); @@ -582,13 +579,13 @@ public class App implements ApplicationListener { if (!loadOrder.isEmpty()) { var modname = loadOrder.get(0).get(0); - var textureFile = Gdx.files.internal("assets/mods/"+modname+"/splashback.png"); + var textureFile = AssetCache.INSTANCE.getFileHandle("mods/"+modname+"/splashback.png"); if (textureFile.exists()) { splashBackdrop = new TextureRegion(new Texture(textureFile)); splashTextCol = new Color(0xeeeeeeff); } - var logoFile = Gdx.files.internal("assets/mods/"+modname+"/splashlogo.png"); + var logoFile = AssetCache.INSTANCE.getFileHandle("mods/"+modname+"/splashlogo.png"); if (logoFile.exists()) { splashScreenLogo = new TextureRegion(new Texture(logoFile)); } @@ -604,10 +601,10 @@ public class App implements ApplicationListener { } if (splashBackdrop == null) { - splashBackdrop = new TextureRegion(new Texture("assets/graphics/background_white.png")); + splashBackdrop = new TextureRegion(new Texture(AssetCache.INSTANCE.getFileHandle("graphics/background_white.png"))); } if (splashScreenLogo == null) { - splashScreenLogo = new TextureRegion(new Texture("assets/graphics/logo.png")); + splashScreenLogo = new TextureRegion(new Texture(AssetCache.INSTANCE.getFileHandle("graphics/logo.png"))); } Gdx.graphics.setContinuousRendering(true); @@ -622,13 +619,13 @@ public class App implements ApplicationListener { ShaderMgr.INSTANCE.compile(Gdx.files.classpath("shaders/shaders.csv")); - CommonResourcePool.INSTANCE.addToLoadingList("title_health1", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_take_a_break.tga"))); - CommonResourcePool.INSTANCE.addToLoadingList("title_health2", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_distance.tga"))); - CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bup", () -> new MusicContainer("haptic_bup", Gdx.files.internal("./assets/audio/effects/haptic_bup.ogg").file(), false, true, (AudioBank m) -> { return null; })); - CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bap", () -> new MusicContainer("haptic_bap", Gdx.files.internal("./assets/audio/effects/haptic_bap.ogg").file(), false, true, (AudioBank m) -> { return null; })); - CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bop", () -> new MusicContainer("haptic_bop", Gdx.files.internal("./assets/audio/effects/haptic_bop.ogg").file(), false, true, (AudioBank m) -> { return null; })); - CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bep", () -> new MusicContainer("haptic_bep", Gdx.files.internal("./assets/audio/effects/haptic_bep.ogg").file(), false, true, (AudioBank m) -> { return null; })); - CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bip", () -> new MusicContainer("haptic_bip", Gdx.files.internal("./assets/audio/effects/haptic_bip.ogg").file(), false, true, (AudioBank m) -> { highPrioritySoundPlaying = false; return null; })); + CommonResourcePool.INSTANCE.addToLoadingList("title_health1", () -> new Texture(AssetCache.INSTANCE.getFileHandle("graphics/gui/health_take_a_break.tga"))); + CommonResourcePool.INSTANCE.addToLoadingList("title_health2", () -> new Texture(AssetCache.INSTANCE.getFileHandle("graphics/gui/health_distance.tga"))); + CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bup", () -> new MusicContainer("haptic_bup", AssetCache.INSTANCE.getFileHandle("audio/effects/haptic_bup.ogg"), false, true, null, (AudioBank m) -> { return null; })); + CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bap", () -> new MusicContainer("haptic_bap", AssetCache.INSTANCE.getFileHandle("audio/effects/haptic_bap.ogg"), false, true, null, (AudioBank m) -> { return null; })); + CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bop", () -> new MusicContainer("haptic_bop", AssetCache.INSTANCE.getFileHandle("audio/effects/haptic_bop.ogg"), false, true, null, (AudioBank m) -> { return null; })); + CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bep", () -> new MusicContainer("haptic_bep", AssetCache.INSTANCE.getFileHandle("audio/effects/haptic_bep.ogg"), false, true, null, (AudioBank m) -> { return null; })); + CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bip", () -> new MusicContainer("haptic_bip", AssetCache.INSTANCE.getFileHandle("audio/effects/haptic_bip.ogg"), false, true, null, (AudioBank m) -> { highPrioritySoundPlaying = false; return null; })); // make loading list CommonResourcePool.INSTANCE.loadAll(); @@ -669,7 +666,7 @@ public class App implements ApplicationListener { rendererVendor = Gdx.graphics.getGLVersion().getVendorString(); - fontGame = new TerrarumSansBitmap(FONT_DIR, false, false, false, + fontGame = new TerrarumSansBitmap(false, false, false, false, 256, false, 0.5f, false ); @@ -1062,6 +1059,8 @@ public class App implements ApplicationListener { deleteTempfiles(); + AssetCache.INSTANCE.dispose(); + Toolkit.INSTANCE.dispose(); BlurMgr.INSTANCE.dispose(); @@ -1157,11 +1156,11 @@ public class App implements ApplicationListener { long t1 = System.nanoTime(); - 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("blockmarkings_common", () -> new TextureRegionPack(AssetCache.INSTANCE.getFileHandle("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("loading_circle_64", () -> new TextureRegionPack(AssetCache.INSTANCE.getFileHandle("graphics/gui/loading_circle_64.tga"), 64, 64, 0, 0, 0, 0, false, false, false)); + CommonResourcePool.INSTANCE.addToLoadingList("inline_loading_spinner", () -> new TextureRegionPack(AssetCache.INSTANCE.getFileHandle("graphics/gui/inline_loading_spinner.tga"), 20, 20, 0, 0, 0, 0, false, false, false)); + CommonResourcePool.INSTANCE.addToLoadingList("inventory_category", () -> new TextureRegionPack(AssetCache.INSTANCE.getFileHandle("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"); @@ -1226,12 +1225,12 @@ public class App implements ApplicationListener { else { environment = RunningEnvironment.PC; }*/ - fontUITitle = new TerrarumSansBitmap(FONT_DIR, false, false, false, + fontUITitle = new TerrarumSansBitmap(false, false, false, false, 64, false, 0.5f, false ); fontUITitle.setInterchar(1); - fontGameFBO = new TerrarumSansBitmap(FONT_DIR, false, true, false, + fontGameFBO = new TerrarumSansBitmap(false, true, false, false, 64, false, 203f/255f, false ); @@ -1514,6 +1513,8 @@ public class App implements ApplicationListener { /** defaultDir + "/Custom/Music" */ public static String customMusicDir; public static String customAmbientDir; + /** defaultDir + "/Caches" */ + public static String cachesDir; private static void getDefaultDirectory() { String OS = OSName.toUpperCase(); @@ -1551,6 +1552,7 @@ public class App implements ApplicationListener { customDir = defaultDir + "/Custom"; customMusicDir = customDir + "/Music"; customAmbientDir = customDir + "/Ambient"; + cachesDir = defaultDir + "/Caches"; System.out.println(String.format("os.name = %s (with identifier %s)", OSName, operationSystem)); System.out.println(String.format("os.version = %s", OSVersion)); diff --git a/src/net/torvald/terrarum/AssetArchiveBuilder.kt b/src/net/torvald/terrarum/AssetArchiveBuilder.kt new file mode 100644 index 000000000..08a108c52 --- /dev/null +++ b/src/net/torvald/terrarum/AssetArchiveBuilder.kt @@ -0,0 +1,59 @@ +package net.torvald.terrarum + +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClusteredFormatDOM +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.Clustfile +import java.io.File + +/** + * Build-time tool that creates assets.tevd from assets_release/ directory. + * + * Usage: java -cp net.torvald.terrarum.AssetArchiveBuilderKt [assets_release_dir] [output_file] + */ +fun main(args: Array) { + val srcDir = File(if (args.isNotEmpty()) args[0] else "assets_release") + val outFile = File(if (args.size > 1) args[1] else "out/assets.tevd") + + if (!srcDir.exists() || !srcDir.isDirectory) { + System.err.println("Error: Source directory '${srcDir.path}' does not exist or is not a directory.") + System.exit(1) + } + + outFile.parentFile?.mkdirs() + if (outFile.exists()) outFile.delete() + + println("Scanning $srcDir...") + var totalSize = 0L + var fileCount = 0 + srcDir.walkTopDown().filter { it.isFile }.forEach { + totalSize += it.length() + fileCount++ + } + + // Calculate capacity in sectors (4096 bytes per sector/cluster) + // Add overhead for FAT entries and directory structures + val clusterSize = ClusteredFormatDOM.CLUSTER_SIZE + val sectorsForData = (totalSize + clusterSize - 1) / clusterSize + // Add ~25% overhead for FAT, directory entries, and slack space + val capacityInSectors = ((sectorsForData * 1.25) + fileCount + 256).toLong() + .coerceAtMost(ClusteredFormatDOM.MAX_CAPA_IN_SECTORS.toLong()) + .toInt() + + println(" Files: $fileCount") + println(" Total size: ${totalSize / 1024} KB") + println(" Allocating $capacityInSectors sectors...") + + println("Creating archive: ${outFile.path}") + val diskArchive = ClusteredFormatDOM.createNewArchive(outFile, Charsets.UTF_8, "Terrarum Assets", capacityInSectors) + val dom = ClusteredFormatDOM(diskArchive) + + println("Importing files from ${srcDir.path}...") + val root = Clustfile(dom, "/") + root.importFrom(srcDir) + + println("Trimming archive...") + dom.trimArchive() + dom.dispose() + + println("Done. Output:") + println(" ${outFile.path} (${outFile.length() / 1024} KB, $fileCount files)") +} diff --git a/src/net/torvald/terrarum/AssetCache.kt b/src/net/torvald/terrarum/AssetCache.kt new file mode 100644 index 000000000..a8d703a28 --- /dev/null +++ b/src/net/torvald/terrarum/AssetCache.kt @@ -0,0 +1,68 @@ +package net.torvald.terrarum + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.files.FileHandle +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClusteredFormatDOM +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.Clustfile +import java.io.File +import java.io.RandomAccessFile + +/** + * Central accessor for the TerranVirtualDisk asset archive. + * In distribution mode, assets are read directly from assets.tevd. + * In development mode, assets are read from the local ./assets/ directory. + */ +object AssetCache { + + private val archivePath = File("./assets.tevd") + + /** Whether we're running from a distribution archive */ + val isDistribution: Boolean get() = archivePath.exists() + + private var dom: ClusteredFormatDOM? = null + + /** + * Open the archive on startup. Call early, after defaultDir is set. + */ + fun init() { + if (isDistribution) { + println("[AssetCache] Distribution mode: opening ${archivePath.path}") + dom = ClusteredFormatDOM(RandomAccessFile(archivePath, "r")) + println("[AssetCache] Archive opened successfully") + } else { + println("[AssetCache] No archive found, using loose assets (development mode)") + } + } + + /** + * Get a Clustfile for a path relative to the assets root. + */ + fun getClustfile(relativePath: String): Clustfile { + val path = if (relativePath.startsWith("/")) relativePath else "/$relativePath" + return Clustfile(dom!!, path) + } + + /** + * Get a GDX FileHandle — returns ClustfileHandle in distribution, Gdx.files.internal in dev. + */ + fun getFileHandle(relativePath: String): FileHandle { + return if (isDistribution) ClustfileHandle(getClustfile(relativePath)) + else Gdx.files.internal("./assets/$relativePath") + } + + /** + * Resolve a path string. In dev mode returns local path; in distribution mode throws + * as callers should use getFileHandle() instead. + */ + fun resolve(relativePath: String): String { + return if (isDistribution) throw UnsupportedOperationException( + "Use AssetCache.getFileHandle(\"$relativePath\") in distribution mode" + ) + else "./assets/$relativePath" + } + + fun dispose() { + dom?.dispose() + dom = null + } +} diff --git a/src/net/torvald/terrarum/ClustfileHandle.kt b/src/net/torvald/terrarum/ClustfileHandle.kt new file mode 100644 index 000000000..9b55c3eab --- /dev/null +++ b/src/net/torvald/terrarum/ClustfileHandle.kt @@ -0,0 +1,64 @@ +package net.torvald.terrarum + +import com.badlogic.gdx.files.FileHandle +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.Clustfile +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClustfileInputStream +import java.io.File +import java.io.InputStream + +/** + * A GDX FileHandle backed by a Clustfile from TerranVirtualDisk. + * Allows transparent asset loading from .tevd archives using all standard GDX APIs. + */ +class ClustfileHandle(private val clustfile: Clustfile) : FileHandle() { + + override fun read(): InputStream = ClustfileInputStream(clustfile) + + override fun readBytes(): ByteArray = clustfile.readBytes() + + override fun readString(charset: String?): String = String(readBytes(), charset(charset ?: "UTF-8")) + + override fun exists(): Boolean = clustfile.exists() + + override fun length(): Long = clustfile.length() + + override fun isDirectory(): Boolean = clustfile.isDirectory + + override fun name(): String = clustfile.name + + override fun path(): String = clustfile.path + + override fun extension(): String { + val n = name() + val dotIndex = n.lastIndexOf('.') + return if (dotIndex == -1) "" else n.substring(dotIndex + 1) + } + + override fun nameWithoutExtension(): String { + val n = name() + val dotIndex = n.lastIndexOf('.') + return if (dotIndex == -1) n else n.substring(0, dotIndex) + } + + override fun list(): Array { + return clustfile.listFiles()?.map { ClustfileHandle(it) }?.toTypedArray() ?: arrayOf() + } + + override fun child(name: String): FileHandle { + val childPath = if (clustfile.path.endsWith("/")) "${clustfile.path}$name" else "${clustfile.path}/$name" + return ClustfileHandle(Clustfile(clustfile.DOM, childPath)) + } + + override fun parent(): FileHandle { + val parentFile = clustfile.parentFile + return if (parentFile != null) ClustfileHandle(parentFile) + else ClustfileHandle(Clustfile(clustfile.DOM, "/")) + } + + override fun file(): File { + // Return a dummy File for logging/toString purposes only + return File(clustfile.path) + } + + override fun toString(): String = clustfile.path +} diff --git a/src/net/torvald/terrarum/ModMgr.kt b/src/net/torvald/terrarum/ModMgr.kt index 8916fa30d..363db83b6 100644 --- a/src/net/torvald/terrarum/ModMgr.kt +++ b/src/net/torvald/terrarum/ModMgr.kt @@ -103,7 +103,7 @@ object ModMgr { NOT_EVEN_THERE } - const val modDirInternal = "./assets/mods" + val modDirInternal: String get() = "./assets/mods" val modDirExternal = "${App.defaultDir}/Modules" /** Module name (directory name), ModuleMetadata */ @@ -161,21 +161,46 @@ object ModMgr { try { val modMetadata = Properties() - val _internalFile = File("$modDirInternal/$moduleName/$metaFilename") val _externalFile = File("$modDirExternal/$moduleName/$metaFilename") // external mod has precedence over the internal - val isInternal = if (_externalFile.exists()) false else if (_internalFile.exists()) true else throw FileNotFoundException() - val file = if (isInternal) _internalFile else _externalFile + val internalExists = if (AssetCache.isDistribution) + AssetCache.getFileHandle("mods/$moduleName/$metaFilename").exists() + else + File("$modDirInternal/$moduleName/$metaFilename").exists() + val isInternal = if (_externalFile.exists()) false else if (internalExists) true else throw FileNotFoundException() val modDir = if (isInternal) modDirInternal else modDirExternal - fun getGdxFile(path: String) = if (isInternal) Gdx.files.internal(path) else Gdx.files.absolute(path) + fun getGdxFileLocal(path: String) = if (isInternal) { + if (AssetCache.isDistribution) AssetCache.getFileHandle(path.removePrefix("./assets/")) + else Gdx.files.internal(path) + } else Gdx.files.absolute(path) - modMetadata.load(FileInputStream(file)) + // Load metadata + if (isInternal && AssetCache.isDistribution) { + val metaHandle = AssetCache.getFileHandle("mods/$moduleName/$metaFilename") + modMetadata.load(metaHandle.read()) + } else { + val file = if (isInternal) File("$modDirInternal/$moduleName/$metaFilename") else _externalFile + modMetadata.load(FileInputStream(file)) + } - if (File("$modDir/$moduleName/$defaultConfigFilename").exists()) { + // Load default config + val defaultConfigHandle = if (isInternal && AssetCache.isDistribution) + AssetCache.getFileHandle("mods/$moduleName/$defaultConfigFilename") + else + null + val defaultConfigExists = if (defaultConfigHandle != null) + defaultConfigHandle.exists() + else + File("$modDir/$moduleName/$defaultConfigFilename").exists() + + if (defaultConfigExists) { try { - val defaultConfig = JsonFetcher("$modDir/$moduleName/$defaultConfigFilename") + val defaultConfig = if (defaultConfigHandle != null) + JsonFetcher.invoke(defaultConfigHandle) + else + JsonFetcher("$modDir/$moduleName/$defaultConfigFilename") // read config and store it to the game var entry: JsonValue? = defaultConfig.child @@ -208,16 +233,29 @@ object ModMgr { val jar = modMetadata.getProperty("jar") val jarHash = modMetadata.getProperty("jarhash").uppercase() val dependency = modMetadata.getProperty("dependency").split(Regex(""";[ ]*""")).filter { it.isNotEmpty() }.toTypedArray() - val isDir = FileSystems.getDefault().getPath("$modDir/$moduleName").toFile().isDirectory + val isDir = if (isInternal && AssetCache.isDistribution) + true // internal mods in archive are always "directories" + else + FileSystems.getDefault().getPath("$modDir/$moduleName").toFile().isDirectory val configPlan = ArrayList() - File("$modDir/$moduleName/configplan.csv").let { - if (it.exists() && it.isFile) { - configPlan.addAll(it.readLines(Common.CHARSET).filter { it.isNotBlank() }) + val configPlanHandle = if (isInternal && AssetCache.isDistribution) + AssetCache.getFileHandle("mods/$moduleName/configplan.csv") + else + null + if (configPlanHandle != null) { + if (configPlanHandle.exists()) { + configPlan.addAll(configPlanHandle.readString("UTF-8").lines().filter { it.isNotBlank() }) + } + } else { + File("$modDir/$moduleName/configplan.csv").let { + if (it.exists() && it.isFile) { + configPlan.addAll(it.readLines(Common.CHARSET).filter { it.isNotBlank() }) + } } } - module = ModuleMetadata(index, isDir, getGdxFile("$modDir/$moduleName/icon.png"), properName, description, descTranslations, author, packageName, entryPoint, releaseDate, version, jar, dependency, isInternal, configPlan) + module = ModuleMetadata(index, isDir, getGdxFileLocal("$modDir/$moduleName/icon.png"), properName, description, descTranslations, author, packageName, entryPoint, releaseDate, version, jar, dependency, isInternal, configPlan) val versionNumeral = version.split('.') val versionNumber = versionNumeral.toVersionNumber() @@ -447,24 +485,36 @@ object ModMgr { /** Returning files are read-only */ fun getGdxFile(module: String, path: String): FileHandle { checkExistence(module) - return if (moduleInfo[module]!!.isInternal) - Gdx.files.internal("$modDirInternal/$module/$path") + return if (moduleInfo[module]!!.isInternal) { + if (AssetCache.isDistribution) + ClustfileHandle(AssetCache.getClustfile("mods/$module/$path")) + else + Gdx.files.internal("$modDirInternal/$module/$path") + } else Gdx.files.absolute("$modDirExternal/$module/$path") } - fun getFile(module: String, path: String): File { + // getGdxFile is preferred due to asset archiving + /*fun getFile(module: String, path: String): File { checkExistence(module) - return if (moduleInfo[module]!!.isInternal) - FileSystems.getDefault().getPath("$modDirInternal/$module/$path").toFile() + return if (moduleInfo[module]!!.isInternal) { + if (AssetCache.isDistribution) + throw UnsupportedOperationException("Use getGdxFile() for internal mod files in distribution mode (module=$module, path=$path)") + else + FileSystems.getDefault().getPath("$modDirInternal/$module/$path").toFile() + } else FileSystems.getDefault().getPath("$modDirExternal/$module/$path").toFile() - } + }*/ fun hasFile(module: String, path: String): Boolean { if (!moduleInfo.containsKey(module)) return false - return getFile(module, path).exists() + return getGdxFile(module, path).exists() } - fun getFiles(module: String, path: String): Array { + // getGdxFile is preferred due to asset archiving + /*fun getFiles(module: String, path: String): Array { checkExistence(module) + if (moduleInfo[module]!!.isInternal && AssetCache.isDistribution) + throw UnsupportedOperationException("Use getGdxFiles() for internal mod files in distribution mode (module=$module, path=$path)") val dir = getFile(module, path) if (!dir.isDirectory) { throw FileNotFoundException("The path is not a directory") @@ -472,7 +522,7 @@ object ModMgr { else { return dir.listFiles() } - } + }*/ fun getGdxFiles(module: String, path: String): Array { checkExistence(module) val dir = getGdxFile(module, path) @@ -487,20 +537,21 @@ object ModMgr { /** Get a common file (literal file or directory) from all the installed mods. Files are guaranteed to exist. If a mod does not * contain the file, the mod will be skipped. * - * @return List of pairs + * @return List of pairs */ - fun getFilesFromEveryMod(path: String): List> { + // getGdxFile is preferred due to asset archiving + /*fun getFilesFromEveryMod(path: String): List> { val path = path.sanitisePath() val moduleNames = moduleInfo.keys.toList() - val filesList = ArrayList>() + val filesList = ArrayList>() moduleNames.forEach { - val file = getFile(it, path) + val file = getGdxFile(it, path) if (file.exists()) filesList.add(it to file) } return filesList.toList() - } + }*/ /** Get a common file (literal file or directory) from all the installed mods. Files are guaranteed to exist. If a mod does not * contain the file, the mod will be skipped. @@ -739,7 +790,7 @@ object ModMgr { const val langPath = "locales/" @JvmStatic operator fun invoke(module: String) { - Lang.load(getFile(module, langPath)) + Lang.load(getGdxFile(module, langPath)) } } @@ -747,25 +798,25 @@ object ModMgr { const val keebPath = "keylayout/" @JvmStatic operator fun invoke(module: String) { - val FILE = getFile(module, keebPath) + val DIR = getGdxFile(module, keebPath) - FILE.listFiles { file, s -> s.endsWith(".${IME.KEYLAYOUT_EXTENSION}") }.sortedBy { it.name }.forEach { - printdbg(this, "Registering Low layer ${it.nameWithoutExtension.lowercase()}") - IME.registerLowLayer(it.nameWithoutExtension.lowercase(), IME.parseKeylayoutFile(it)) + DIR.list().filter { it.extension().equals(IME.KEYLAYOUT_EXTENSION, ignoreCase = true) }.sortedBy { it.name() }.forEach { + printdbg(this, "Registering Low layer ${it.nameWithoutExtension().lowercase()}") + IME.registerLowLayer(it.nameWithoutExtension().lowercase(), IME.parseKeylayoutFile(it)) } - FILE.listFiles { file, s -> s.endsWith(".${IME.IME_EXTENSION}") }.sortedBy { it.name }.forEach { - printdbg(this, "Registering High layer ${it.nameWithoutExtension.lowercase()}") - IME.registerHighLayer(it.nameWithoutExtension.lowercase(), IME.parseImeFile(it)) + DIR.list().filter { it.extension().equals(IME.IME_EXTENSION, ignoreCase = true) }.sortedBy { it.name() }.forEach { + printdbg(this, "Registering High layer ${it.nameWithoutExtension().lowercase()}") + IME.registerHighLayer(it.nameWithoutExtension().lowercase(), IME.parseImeFile(it)) } - val iconFile = getFile(module, keebPath + "icons.tga").let { - if (it.exists()) it else getFile(module, keebPath + "icons.png") + val iconFile = getGdxFile(module, keebPath + "icons.tga").let { + if (it.exists()) it else getGdxFile(module, keebPath + "icons.png") } if (iconFile.exists()) { - val iconSheet = TextureRegionPack(iconFile.path, 20, 20) - val iconPixmap = Pixmap(Gdx.files.absolute(iconFile.path)) + val iconSheet = TextureRegionPack(iconFile, 20, 20) + val iconPixmap = Pixmap(iconFile) for (k in 0 until iconPixmap.height step 20) { val langCode = StringBuilder() for (c in 0 until 20) { @@ -855,7 +906,7 @@ object ModMgr { } @JvmStatic operator fun invoke(module: String) { - getFiles(module, weatherPath).filter { it.isFile && it.name.lowercase().endsWith(".json") }.forEach { + getGdxFile(module, weatherPath).list().filter { !it.isDirectory && it.name().lowercase().endsWith(".json") }.forEach { Terrarum.weatherCodex.readFromJson(module, it) } } @@ -878,32 +929,21 @@ object ModMgr { } @JvmStatic operator fun invoke(module: String) { - val targetModNames = getFiles(module, retexturesPath).filter { it.isDirectory } + val targetModNames = getGdxFile(module, retexturesPath).list().filter { it.isDirectory } targetModNames.forEach { baseTargetModDir -> - // modules//retextures/basegame -// printdbg(this, "baseTargetModDir = $baseTargetModDir") - retexables.forEach { category -> - val dir = File(baseTargetModDir, category) - // modules//retextures/basegame/blocks - -// printdbg(this, "cats: ${dir.path}") + val dir = baseTargetModDir.child(category) if (dir.isDirectory && dir.exists()) { - dir.listFiles { it: File -> - it.name.contains('-') - }?.forEach { - // -.tga or .png - val tokens = it.name.split('-') + dir.list().filter { it.name().contains('-') }.forEach { + val tokens = it.name().split('-') if (tokens.size > 1) { val modname = tokens[0] val filename = tokens.tail().joinToString("-") - altFilePaths["$modDirInternal/$modname/$category/$filename"] = getGdxFile(module, "$retexturesPath${baseTargetModDir.name}/$category/${it.name}") + altFilePaths["$modDirInternal/$modname/$category/$filename"] = getGdxFile(module, "$retexturesPath${baseTargetModDir.name()}/$category/${it.name()}") } } } - -// retexableCallbacks[category]?.invoke() } } @@ -917,12 +957,12 @@ object ModMgr { const val smeltingPath = "smelting/" @JvmStatic operator fun invoke(module: String) { - getFile(module, recipePath).listFiles { it: File -> it.name.lowercase().endsWith(".json") }?.forEach { jsonFile -> - Terrarum.craftingCodex.addFromJson(JsonFetcher(jsonFile), module, jsonFile.name) + getGdxFile(module, recipePath).list().filter { !it.isDirectory && it.name().lowercase().endsWith(".json") }.forEach { jsonHandle -> + Terrarum.craftingCodex.addFromJson(JsonFetcher.invoke(jsonHandle), module, jsonHandle.name()) } - getFile(module, smeltingPath).listFiles { it: File -> it.name.lowercase().endsWith(".json") }?.forEach { jsonFile -> - Terrarum.craftingCodex.addSmeltingFromJson(JsonFetcher(jsonFile), module, jsonFile.name) + getGdxFile(module, smeltingPath).list().filter { !it.isDirectory && it.name().lowercase().endsWith(".json") }.forEach { jsonHandle -> + Terrarum.craftingCodex.addSmeltingFromJson(JsonFetcher.invoke(jsonHandle), module, jsonHandle.name()) } } } diff --git a/src/net/torvald/terrarum/audio/AudioHelper.kt b/src/net/torvald/terrarum/audio/AudioHelper.kt index f05fb9fc7..b0947dde0 100644 --- a/src/net/torvald/terrarum/audio/AudioHelper.kt +++ b/src/net/torvald/terrarum/audio/AudioHelper.kt @@ -1,13 +1,13 @@ package net.torvald.terrarum.audio import com.badlogic.gdx.Gdx +import com.badlogic.gdx.files.FileHandle import com.jme3.math.FastMath import net.torvald.reflection.forceInvoke import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.CommonResourcePool import net.torvald.terrarum.ModMgr import net.torvald.terrarum.serialise.toUint -import java.io.File /** * Created by minjaesong on 2024-01-24. @@ -26,7 +26,7 @@ object AudioHelper { return fft } else { - val ir = ModMgr.getFile(module, path) + val ir = ModMgr.getGdxFile(module, path) val fft = createIR(ir) CommonResourcePool.addToLoadingList(id) { fft } @@ -36,19 +36,20 @@ object AudioHelper { } } - private fun createIR(ir: File): Array { + private fun createIR(ir: FileHandle): Array { if (!ir.exists()) { - throw IllegalArgumentException("Impulse Response file '${ir.path}' does not exist.") + throw IllegalArgumentException("Impulse Response file '${ir.path()}' does not exist.") } - val sampleCount = (ir.length().toInt() / 8)//.coerceAtMost(65536) + val irBytes = ir.readBytes() + val sampleCount = (irBytes.size / 8)//.coerceAtMost(65536) val fftLen = FastMath.nextPowerOfTwo(sampleCount) - printdbg(this, "IR '${ir.path}' Sample Count = $sampleCount; FFT Length = $fftLen") + printdbg(this, "IR '${ir.path()}' Sample Count = $sampleCount; FFT Length = $fftLen") val conv = Array(2) { FloatArray(fftLen) } - ir.inputStream().let { + java.io.ByteArrayInputStream(irBytes).let { for (i in 0 until sampleCount) { val f1 = Float.fromBits(it.read().and(255) or it.read().and(255).shl(8) or @@ -79,7 +80,7 @@ object AudioHelper { return CommonResourcePool.getAs>(id) } else { - val file = ModMgr.getFile(module, path) + val file = ModMgr.getGdxFile(module, path) val samples = createAudioInSamples(file) CommonResourcePool.addToLoadingList(id) { samples } @@ -89,8 +90,8 @@ object AudioHelper { } } - private fun createAudioInSamples(static: File): Array { - val music = Gdx.audio.newMusic(Gdx.files.absolute(static.absolutePath)) + private fun createAudioInSamples(static: FileHandle): Array { + val music = Gdx.audio.newMusic(static) val readbuf = ByteArray(AudioProcessBuf.MP3_CHUNK_SIZE * 4) val OUTBUF_BLOCK_SIZE_IN_BYTES = (48000 * 60) * 2 * 2 var outbuf = ByteArray(OUTBUF_BLOCK_SIZE_IN_BYTES) diff --git a/src/net/torvald/terrarum/audio/audiobank/MusicContainer.kt b/src/net/torvald/terrarum/audio/audiobank/MusicContainer.kt index 3ff4301b4..7dbc61e30 100644 --- a/src/net/torvald/terrarum/audio/audiobank/MusicContainer.kt +++ b/src/net/torvald/terrarum/audio/audiobank/MusicContainer.kt @@ -18,13 +18,15 @@ import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RAT import net.torvald.terrarum.serialise.toUint import net.torvald.unsafe.UnsafeHelper import net.torvald.unsafe.UnsafePtr +import java.io.BufferedInputStream import java.io.File import java.io.FileInputStream import javax.sound.sampled.AudioSystem class MusicContainer( override val name: String, - val file: File, + val file: File?, + val fileHandle: FileHandle?, val looping: Boolean = false, val toRAM: Boolean = false, val samplingRateOverride: Float?, // this is FIXED sampling rate @@ -34,6 +36,15 @@ class MusicContainer( override var channels: Int val codec: String + // File-based constructors (existing API) + constructor( + name: String, + file: File, + looping: Boolean = false, + toRAM: Boolean = false, + samplingRateOverride: Float?, + songFinishedHook: (AudioBank) -> Unit = {} + ) : this(name, file, null, looping, toRAM, samplingRateOverride, songFinishedHook) // make Java code shorter constructor( name: String, @@ -41,27 +52,37 @@ class MusicContainer( looping: Boolean = false, toRAM: Boolean = false, songFinishedHook: (AudioBank) -> Unit = {} - ) : this(name, file, looping, toRAM, null, songFinishedHook) + ) : this(name, file, null, looping, toRAM, null, songFinishedHook) // make Java code shorter constructor( name: String, file: File, looping: Boolean = false, songFinishedHook: (AudioBank) -> Unit = {} - ) : this(name, file, looping, false, null, songFinishedHook) + ) : this(name, file, null, looping, false, null, songFinishedHook) // make Java code shorter constructor( name: String, file: File, songFinishedHook: (AudioBank) -> Unit = {} - ) : this(name, file, false, false, null, songFinishedHook) + ) : this(name, file, null, false, false, null, songFinishedHook) + + // FileHandle-based constructor (for TEVD archive support) + constructor( + name: String, + fileHandle: FileHandle, + looping: Boolean = false, + toRAM: Boolean = false, + samplingRateOverride: Float? = null, + songFinishedHook: (AudioBank) -> Unit = {} + ) : this(name, null, fileHandle, looping, toRAM, samplingRateOverride, songFinishedHook) var samplesReadCount = 0L; internal set override var totalSizeInSamples: Long private val totalSizeInBytes: Long - private val gdxMusic: Music = Gdx.audio.newMusic(FileHandle(file)) + private val gdxMusic: Music = if (file != null) Gdx.audio.newMusic(FileHandle(file)) else Gdx.audio.newMusic(fileHandle!!) private var soundBuf: UnsafePtr? = null; private set @@ -94,7 +115,10 @@ class MusicContainer( rate.toFloat() } is Mp3.Music -> { - val tempMusic = Gdx.audio.newMusic(Gdx.files.absolute(file.absolutePath)) + val tempMusic = if (file == null) + Gdx.audio.newMusic(fileHandle) + else + Gdx.audio.newMusic(Gdx.files.absolute(file.absolutePath)) val bitstream = tempMusic.extortField("bitstream")!! val header = bitstream.readFrame() val rate = header.sampleRate @@ -118,11 +142,22 @@ class MusicContainer( if (it.last() == "Music") it.dropLast(1).last() else it.last() } - totalSizeInSamples = when (gdxMusic) { - is Wav.Music -> getWavFileSampleCount(file) - is Ogg.Music -> getOggFileSampleCount(file) - is Mp3.Music -> getMp3FileSampleCount(file) - else -> Long.MAX_VALUE + totalSizeInSamples = if (file != null) { + when (gdxMusic) { + is Wav.Music -> getWavFileSampleCount(file) + is Ogg.Music -> getOggFileSampleCount(file) + is Mp3.Music -> getMp3FileSampleCount(file) + else -> Long.MAX_VALUE + } + } else if (fileHandle != null) { + when (gdxMusic) { + is Wav.Music -> getWavFileSampleCountFromHandle(fileHandle) + is Ogg.Music -> getOggFileSampleCountFromHandle(fileHandle) + is Mp3.Music -> getMp3FileSampleCountFromHandle(fileHandle) + else -> Long.MAX_VALUE + } + } else { + Long.MAX_VALUE } totalSizeInBytes = totalSizeInSamples * 2 * channels @@ -329,10 +364,65 @@ class MusicContainer( } } - override fun toString() = if (name.isEmpty()) file.nameWithoutExtension else name + private fun getWavFileSampleCountFromHandle(fh: FileHandle): Long { + return try { + val ais = AudioSystem.getAudioInputStream(BufferedInputStream(fh.read())) + val r = ais.frameLength + ais.close() + r + } + catch (_: Throwable) { + Long.MAX_VALUE + } + } - override fun equals(other: Any?) = this.file.path == (other as MusicContainer).file.path - fun equalInstance(other: Any?) = this.file.path == (other as MusicContainer).file.path && this.hash == (other as MusicContainer).hash + private fun getOggFileSampleCountFromHandle(fh: FileHandle): Long { + return try { + // VorbisFile requires a file path; use a temp file + val tempFile = java.io.File.createTempFile("terrarum_ogg_", ".ogg") + tempFile.deleteOnExit() + tempFile.writeBytes(fh.readBytes()) + val vorbisFile = VorbisFile(tempFile.absolutePath) + val r = vorbisFile.pcm_total(0) + tempFile.delete() + r + } + catch (_: Throwable) { + Long.MAX_VALUE + } + } + + private fun getMp3FileSampleCountFromHandle(fh: FileHandle): Long { + return try { + val input = BufferedInputStream(fh.read()) + val bs = Bitstream(input) + + var header = bs.readFrame() + val rate = header.frequency() + var totalSamples = 0L + + while (header != null) { + totalSamples += (header.ms_per_frame() * rate / 1000).toLong() + bs.closeFrame() + header = bs.readFrame() + } + + bs.close() + input.close() + + totalSamples + } + catch (_: Throwable) { + Long.MAX_VALUE + } + } + + private val identPath: String get() = file?.path ?: fileHandle?.path() ?: name + + override fun toString() = if (name.isEmpty()) (file?.nameWithoutExtension ?: fileHandle?.nameWithoutExtension() ?: "") else name + + override fun equals(other: Any?) = this.identPath == (other as MusicContainer).identPath + fun equalInstance(other: Any?) = this.identPath == (other as MusicContainer).identPath && this.hash == (other as MusicContainer).hash override fun dispose() { gdxMusic.dispose() @@ -340,7 +430,10 @@ class MusicContainer( } override fun makeCopy(): AudioBank { - val new = MusicContainer(name, file, looping, false, samplingRateOverride, songFinishedHook) + val new = if (file != null) + MusicContainer(name, file, looping, false, samplingRateOverride, songFinishedHook) + else + MusicContainer(name, fileHandle!!, looping, false, samplingRateOverride, songFinishedHook) synchronized(this) { if (this.toRAM) { diff --git a/src/net/torvald/terrarum/console/CommandDict.kt b/src/net/torvald/terrarum/console/CommandDict.kt index 69c32496c..0995a8de8 100644 --- a/src/net/torvald/terrarum/console/CommandDict.kt +++ b/src/net/torvald/terrarum/console/CommandDict.kt @@ -38,13 +38,13 @@ object CommandDict { ((listOf("$" to "net.torvald.terrarum")) + ModMgr.loadOrder.reversed().map { it to ModMgr.moduleInfo[it]?.packageName }).forEach { (modName, packageRoot) -> if (modName == "$" || modName != "$" && ModMgr.hasFile(modName, "commands.csv")) { - val commandsList = if (modName == "$") engineCommandList else ModMgr.getFile(modName, "commands.csv").readLines() + val commandsList = if (modName == "$") engineCommandList else ModMgr.getGdxFile(modName, "commands.csv").readString("UTF-8").lines() val packageConsole = "$packageRoot.console" printdbg(this, "Loading console commands from '${packageConsole}'") // printdbg(this, commandsList.joinToString()) - commandsList.forEach { commandName -> + commandsList.filter { it.isNotBlank() }.forEach { commandName -> val canonicalName = "$packageConsole.$commandName" val it = ModMgr.moduleClassloader[modName].let { if (it != null) diff --git a/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt b/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt index 4c5d56a45..db9b0f629 100644 --- a/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt +++ b/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt @@ -15,7 +15,7 @@ object FactionFactory { */ @Throws(IOException::class) fun create(module: String, path: String): Faction { - val jsonObj = JsonFetcher(ModMgr.getFile(module, path)) + val jsonObj = JsonFetcher(ModMgr.getGdxFile(module, path)) val factionObj = Faction(jsonObj.getString("factionname")) jsonObj.get("factionamicable").asStringArray().forEach { factionObj.addFactionAmicable(it) } diff --git a/src/net/torvald/terrarum/gamecontroller/IME.kt b/src/net/torvald/terrarum/gamecontroller/IME.kt index 4c2e0619f..1221f24f2 100644 --- a/src/net/torvald/terrarum/gamecontroller/IME.kt +++ b/src/net/torvald/terrarum/gamecontroller/IME.kt @@ -1,6 +1,7 @@ package net.torvald.terrarum.gamecontroller import com.badlogic.gdx.Gdx +import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.graphics.Pixmap import com.badlogic.gdx.graphics.g2d.TextureRegion import net.torvald.terrarum.App @@ -173,8 +174,13 @@ object IME { else -> throw IllegalArgumentException("Unknown candidates mode: $this") } - fun parseKeylayoutFile(file: File): TerrarumKeyLayout { - val src = file.readText(Charsets.UTF_8) + fun parseKeylayoutFile(fileHandle: FileHandle): TerrarumKeyLayout = + parseKeylayoutFromString(fileHandle.readString("UTF-8")) + + fun parseKeylayoutFile(file: File): TerrarumKeyLayout = + parseKeylayoutFromString(file.readText(Charsets.UTF_8)) + + private fun parseKeylayoutFromString(src: String): TerrarumKeyLayout { val jsval = context.eval("js", "'use strict';Object.freeze($src)") val name = jsval.getMember("n").asString() val capsmode = jsval.getMember("capslock").asString().toCapsMode() @@ -201,8 +207,6 @@ object IME { } } -// println("[IME] Test Keymap print for $name:"); for (keycode in 0 until 256) { print("$keycode:\t"); println(out[keycode].joinToString("\t")) } - return TerrarumKeyLayout(name, capsmode, out, physicalLayout) } @@ -215,8 +219,13 @@ object IME { else -> throw IllegalArgumentException("Unknown operation mode: $this") } - fun parseImeFile(file: File): TerrarumIME { - val code = file.readText(Charsets.UTF_8) + fun parseImeFile(fileHandle: FileHandle): TerrarumIME = + parseImeFromString(fileHandle.readString("UTF-8")) + + fun parseImeFile(file: File): TerrarumIME = + parseImeFromString(file.readText(Charsets.UTF_8)) + + private fun parseImeFromString(code: String): TerrarumIME { val jsval = context.eval("js", "\"use strict\";(function(){$code})()") val name = jsval.getMember("n").asString() val candidatesCount = jsval.getMember("v").asString().toViewCount() diff --git a/src/net/torvald/terrarum/langpack/Lang.kt b/src/net/torvald/terrarum/langpack/Lang.kt index c49b0e8ec..1c19abe39 100644 --- a/src/net/torvald/terrarum/langpack/Lang.kt +++ b/src/net/torvald/terrarum/langpack/Lang.kt @@ -1,5 +1,6 @@ package net.torvald.terrarum.langpack +import com.badlogic.gdx.files.FileHandle import net.torvald.terrarum.App import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.tail @@ -82,47 +83,62 @@ object Lang { } } + fun load(localesHandle: FileHandle) { + printdbg(this, "Loading languages from ${localesHandle.path()}") + + localesHandle.list().filter { it.isDirectory }.forEach { languageList.add(it.name()) } + + // temporary filter + languageList.remove("jaJPysi") + + for (lang in languageList) { + printdbg(this, "Loading langpack from ${localesHandle.path()}/$lang/") + + val langFiles = localesHandle.child(lang).list() + + langFiles.forEach { + if (!it.name().startsWith("Polyglot") && it.name().endsWith(".json")) { + processRegularLangfile(it, lang) + } + else if (it.name().startsWith("Polyglot") && it.name().endsWith(".json")) { + processPolyglotLangFile(it, lang) + } + } + } + } + private fun processRegularLangfile(file: File, lang: String) { val json = JsonFetcher(file) - /* - * Terrarum langpack JSON structure is: - * - * (root object) - * "<>" = "<>" - */ - //println(json.entrySet()) JsonFetcher.forEachSiblings(json) { key, value -> langpack.put("${key}_$lang", value.asString().trim()) } + } + private fun processRegularLangfile(fileHandle: FileHandle, lang: String) { + val json = JsonFetcher(fileHandle) + JsonFetcher.forEachSiblings(json) { key, value -> + langpack.put("${key}_$lang", value.asString().trim()) + } } private fun processPolyglotLangFile(file: File, lang: String) { val json = JsonFetcher(file) - /* - * Polyglot JSON structure is: - * - * (root object) - * "resources": object - * "polyglot": object - * (polyglot meta) - * "data": array - * [0]: object - * n = "CONTEXT_CHARACTER_CLASS" - * s = "Class" - * [1]: object - * n = "CONTEXT_CHARACTER_DELETE" - * s = "Delecte Character" - * (the array continues) - * - */ JsonFetcher.forEachSiblings(json.get("resources").get("data")) { _, entry -> langpack.put( "${entry.getString("n")}_$lang", entry.getString("s").trim() ) } + } + private fun processPolyglotLangFile(fileHandle: FileHandle, lang: String) { + val json = JsonFetcher(fileHandle) + JsonFetcher.forEachSiblings(json.get("resources").get("data")) { _, entry -> + langpack.put( + "${entry.getString("n")}_$lang", + entry.getString("s").trim() + ) + } } private val bindOp = ">>=" diff --git a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt index e3390dd2f..c8bc4caeb 100644 --- a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt +++ b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt @@ -161,10 +161,10 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) { try { - val file = ModMgr.getFile("basegame", "demoworld") - val reader = java.io.FileReader(file) + val fileHandle = ModMgr.getGdxFile("basegame", "demoworld") + val reader = fileHandle.reader("UTF-8") //ReadWorld.readWorldAndSetNewWorld(Terrarum.ingame!! as TerrarumIngame, reader) - val world = ReadSimpleWorld(reader, file) + val world = ReadSimpleWorld(reader, fileHandle.file()) demoWorld = world demoWorld.worldTime.timeDelta = 30 printdbg(this, "Demo world loaded") diff --git a/src/net/torvald/terrarum/modulebasegame/audio/audiobank/InstrumentLoader.kt b/src/net/torvald/terrarum/modulebasegame/audio/audiobank/InstrumentLoader.kt index f4edf8682..197e5a8b8 100644 --- a/src/net/torvald/terrarum/modulebasegame/audio/audiobank/InstrumentLoader.kt +++ b/src/net/torvald/terrarum/modulebasegame/audio/audiobank/InstrumentLoader.kt @@ -46,7 +46,7 @@ object InstrumentLoader { CommonResourcePool.getAs>("${baseResourceName}_$it") } - val masterFile = MusicContainer("${idBase}_${initialNote}", ModMgr.getFile(module, path)) + val masterFile = MusicContainer("${idBase}_${initialNote}", ModMgr.getGdxFile(module, path)) val masterSamplesL = FloatArray(masterFile.totalSizeInSamples.toInt()) val masterSamplesR = FloatArray(masterFile.totalSizeInSamples.toInt()) masterFile.readSamples(masterSamplesL, masterSamplesR) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorLobbed.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorLobbed.kt index 88e211ebf..8da9080f2 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorLobbed.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorLobbed.kt @@ -23,7 +23,7 @@ open class ActorLobbed(throwPitch: Float) : ActorWithBody() { @Transient private val pitch = throwPitch.coerceIn(0.5f, 2f) @Transient private val whooshSound = MusicContainer( - "throw_low_short", ModMgr.getFile("basegame", "audio/effects/throwing/throw_low_short.wav"), + "throw_low_short", ModMgr.getGdxFile("basegame", "audio/effects/throwing/throw_low_short.wav"), toRAM = true, samplingRateOverride = 48000f * pitch ) @@ -63,17 +63,17 @@ open class ActorPrimedBomb( private var explosionCalled = false @Transient private val boomSound = MusicContainer( - "boom", ModMgr.getFile("basegame", "audio/effects/explosion/bang_bomb.wav"), toRAM = true + "boom", ModMgr.getGdxFile("basegame", "audio/effects/explosion/bang_bomb.wav"), toRAM = true ) { this.flagDespawn() } @Transient private val fuseSound = MusicContainer( - "fuse", ModMgr.getFile("basegame", "audio/effects/explosion/fuse.wav"), toRAM = true + "fuse", ModMgr.getGdxFile("basegame", "audio/effects/explosion/fuse.wav"), toRAM = true ) { this.flagDespawn() } @Transient private val fuseSoundCont = MusicContainer( - "fuse_continue", ModMgr.getFile("basegame", "audio/effects/explosion/fuse_continue.wav"), toRAM = true + "fuse_continue", ModMgr.getGdxFile("basegame", "audio/effects/explosion/fuse_continue.wav"), toRAM = true ) { this.flagDespawn() } diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureAlloyingFurnace.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureAlloyingFurnace.kt index cc1a7f321..8db8adb04 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureAlloyingFurnace.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureAlloyingFurnace.kt @@ -171,7 +171,7 @@ class FixtureAlloyingFurnace : FixtureBase { } - @Transient val static = MusicContainer("bonfire", ModMgr.getFile("basegame", "audio/effects/static/bonfire.ogg"), true) + @Transient val static = MusicContainer("bonfire", ModMgr.getGdxFile("basegame", "audio/effects/static/bonfire.ogg"), true) @Transient val light = Cvec(0.5f, 0.18f, 0f, 0f) @Transient override var lightBoxList = arrayListOf(Lightbox(Hitbox(0.0, 0.0, TILE_SIZED * 2, TILE_SIZED * 2), light)) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureFurnaceAndAnvil.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureFurnaceAndAnvil.kt index d16de6535..88e294668 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureFurnaceAndAnvil.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureFurnaceAndAnvil.kt @@ -57,7 +57,7 @@ class FixtureFurnaceAndAnvil : FixtureBase, CraftingStation { } } - @Transient val static = MusicContainer("bonfire", ModMgr.getFile("basegame", "audio/effects/static/bonfire.ogg"), true) + @Transient val static = MusicContainer("bonfire", ModMgr.getGdxFile("basegame", "audio/effects/static/bonfire.ogg"), true) @Transient override var lightBoxList = arrayListOf(Lightbox(Hitbox(0.0, 0.0, TerrarumAppConfiguration.TILE_SIZED * 2, TerrarumAppConfiguration.TILE_SIZED * 2), Cvec(0.5f, 0.18f, 0f, 0f))) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSmelterBasic.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSmelterBasic.kt index bf1706add..0b2bba6eb 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSmelterBasic.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSmelterBasic.kt @@ -156,7 +156,7 @@ class FixtureSmelterBasic : FixtureBase { this.mainUI = UISmelterBasic(this) } - @Transient val static = MusicContainer("bonfire", ModMgr.getFile("basegame", "audio/effects/static/bonfire.ogg"), true) + @Transient val static = MusicContainer("bonfire", ModMgr.getGdxFile("basegame", "audio/effects/static/bonfire.ogg"), true) @Transient val light = Cvec(0.5f, 0.18f, 0f, 0f) @Transient override var lightBoxList = arrayListOf(Lightbox(Hitbox(0.0, 2*TILE_SIZED, TILE_SIZED * 2, TILE_SIZED * 2), light)) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTypewriter.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTypewriter.kt index 3173a86de..b56c50200 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTypewriter.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTypewriter.kt @@ -98,7 +98,7 @@ class FixtureTypewriter : FixtureBase { internal class TestLeafletPrimaryUseHandler : FileRefItemPrimaryUseHandler { override fun use(item: ItemFileRef): Long { - println(item.getAsFile().readText(Common.CHARSET)) + println(item.getAsGdxFile().readString(Common.CHARSET.displayName())) return 0L } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt index efe6c6c79..b58a9f503 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt @@ -24,7 +24,7 @@ object InjectCreatureRaw { * @param jsonFileName with extension */ operator fun invoke(actorValueRef: ActorValue, module: String, jsonFileName: String) { - val jsonObj = JsonFetcher(ModMgr.getFile(module, "creatures/$jsonFileName")) + val jsonObj = JsonFetcher(ModMgr.getGdxFile(module, "creatures/$jsonFileName")) JsonFetcher.forEachSiblings(jsonObj) { key, value -> if (!key.startsWith("_")) { diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt index af580adf7..900e64a0c 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt @@ -7,6 +7,7 @@ import net.torvald.terrarum.ModMgr import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.gameitems.ItemID +import com.badlogic.gdx.files.FileHandle import java.io.File import java.util.UUID @@ -42,7 +43,7 @@ open class ItemFileRef(originalID: ItemID) : GameItem(originalID) { */ open var refIsShared: Boolean = false - @Transient open lateinit var ref: File + @Transient open lateinit var ref: FileHandle /** * Application-defined. @@ -101,10 +102,10 @@ open class ItemFileRef(originalID: ItemID) : GameItem(originalID) { else ModMgr.getGdxFile(refModuleName, refPath) - fun getAsFile() = if (refIsShared) + /*fun getAsFile() = if (refIsShared) File(App.saveSharedDir + "/$refPath") else - ModMgr.getFile(refModuleName, refPath) + ModMgr.getFile(refModuleName, refPath)*/ @Transient private var classCache: FileRefItemPrimaryUseHandler? = null diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/MusicDisc.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/MusicDisc.kt index 29f55fb30..60f0608e8 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/MusicDisc.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/MusicDisc.kt @@ -22,7 +22,7 @@ data class MusicDiscMetadata(val title: String, val author: String, val album: S object MusicDiscHelper { fun getMetadata(musicFile: FileHandle): MusicDiscMetadata { val musicdbFile = musicFile.sibling("_musicdb.json") - val musicdb = JsonFetcher.invoke(musicdbFile.file()) + val musicdb = JsonFetcher.invoke(musicdbFile) val propForThisFile = musicdb.get(musicFile.name()) val artist = propForThisFile.get("artist").asString() @@ -37,7 +37,7 @@ open class MusicDiscPrototype(originalID: ItemID, module: String, path: String) override var refPath = path override var refModuleName = module override val canBeDynamic = false - @Transient override var ref = ModMgr.getFile(refModuleName, refPath) + @Transient override var ref = ModMgr.getGdxFile(refModuleName, refPath) override var mediumIdentifier = "music_disc" init { diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt index dda8a236b..8e33afd56 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt @@ -273,7 +273,7 @@ object PickaxeCore : TooltipListener() { private val soundCue = MusicContainer( "pickaxe_sound_cue", - ModMgr.getFile("basegame", "audio/effects/accessibility/pickaxe_valuable.ogg"), + ModMgr.getGdxFile("basegame", "audio/effects/accessibility/pickaxe_valuable.ogg"), toRAM = false ).also { App.disposables.add(it) diff --git a/src/net/torvald/terrarum/tests/UIElemTest.kt b/src/net/torvald/terrarum/tests/UIElemTest.kt index a387b0ad5..f2c845a78 100644 --- a/src/net/torvald/terrarum/tests/UIElemTest.kt +++ b/src/net/torvald/terrarum/tests/UIElemTest.kt @@ -30,7 +30,7 @@ class UIElemTest : ApplicationAdapter() { private lateinit var ui: UICanvas override fun create() { - App.fontGame = TerrarumSansBitmap(App.FONT_DIR, false, true, false, + App.fontGame = TerrarumSansBitmap(false, true, false, false, 256, false, 0.5f, false ) diff --git a/src/net/torvald/terrarum/utils/CSVFetcher.kt b/src/net/torvald/terrarum/utils/CSVFetcher.kt index 6889e588e..6d20837ca 100644 --- a/src/net/torvald/terrarum/utils/CSVFetcher.kt +++ b/src/net/torvald/terrarum/utils/CSVFetcher.kt @@ -40,7 +40,10 @@ object CSVFetcher { return csvRecordList } - fun readFromModule(module: String, path: String) = net.torvald.terrarum.utils.CSVFetcher.readFromFile(ModMgr.getGdxFile(module, path).path()) + fun readFromModule(module: String, path: String): List { + val content = ModMgr.getGdxFile(module, path).readString("UTF-8") + return readFromString(content) + } fun readFromString(csv: String): List { val preprocessed = preprocessCSV(csv) diff --git a/src/net/torvald/terrarum/utils/JsonFetcher.kt b/src/net/torvald/terrarum/utils/JsonFetcher.kt index 60c85f52c..34878db91 100644 --- a/src/net/torvald/terrarum/utils/JsonFetcher.kt +++ b/src/net/torvald/terrarum/utils/JsonFetcher.kt @@ -1,5 +1,6 @@ package net.torvald.terrarum.utils +import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.utils.JsonReader import com.badlogic.gdx.utils.JsonValue import net.torvald.terrarum.App.printdbg @@ -36,6 +37,13 @@ object JsonFetcher { return JsonReader().parse(jsonString.toString()) } + @Throws(java.io.IOException::class) + operator fun invoke(fileHandle: FileHandle): JsonValue { + val content = fileHandle.readString("UTF-8") + printdbg(this, "Reading JSON ${fileHandle.path()}") + return JsonReader().parse(content) + } + fun readFromJsonString(stringReader: Reader): JsonValue { return JsonReader().parse(stringReader.readText()) } diff --git a/src/net/torvald/terrarum/weather/WeatherCodex.kt b/src/net/torvald/terrarum/weather/WeatherCodex.kt index 8c819b3c7..eee064629 100644 --- a/src/net/torvald/terrarum/weather/WeatherCodex.kt +++ b/src/net/torvald/terrarum/weather/WeatherCodex.kt @@ -1,5 +1,6 @@ package net.torvald.terrarum.weather +import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.utils.Disposable @@ -40,24 +41,17 @@ class WeatherCodex : Disposable { fun readFromJson(modname: String, file: File) = readFromJson(modname, file.path) + fun readFromJson(modname: String, fileHandle: FileHandle) { + readFromJsonValue(modname, JsonFetcher.invoke(fileHandle)) + } + private val pathToImage = "weathers" fun readFromJson(modname: String, path: String) { - /* JSON structure: -{ - "skyboxGradColourMap": "colourmap/sky_colour.tga", // string (path to image) for dynamic. Image must be RGBA8888 or RGB888 - "extraImages": [ - // if any, it will be like: - sun01.tga, - clouds01.tga, - clouds02.tga, - auroraBlueViolet.tga - ] -} - */ - - val JSON = JsonFetcher(path) + readFromJsonValue(modname, JsonFetcher(path)) + } + private fun readFromJsonValue(modname: String, JSON: com.badlogic.gdx.utils.JsonValue) { val skyboxModel = JSON.getString("skyboxGradColourMap") val lightboxModel = JSON.getString("daylightClut")