Compare commits

..

225 Commits

Author SHA1 Message Date
minjaesong
b1e45f1743 character import wip 2023-08-25 00:24:12 +09:00
minjaesong
8dda7ac79b linear filter for clouds 2023-08-24 20:27:10 +09:00
minjaesong
74b8cc20b7 fix: bad cloud spawn position on certain directions 2023-08-24 17:59:55 +09:00
minjaesong
f75a7dd812 control presets 2023-08-24 17:24:39 +09:00
minjaesong
b2454e4ca2 changing ui toggle keys in-world should work now 2023-08-24 16:08:18 +09:00
minjaesong
45af955488 wide cloud for overcast weather 2023-08-24 15:08:30 +09:00
minjaesong
1f39b9d448 cloud texture touchups 2023-08-23 22:38:01 +09:00
minjaesong
26a4cdbce1 clouds will despawn of old age 2023-08-23 21:22:46 +09:00
minjaesong
bf87dc04cb randomised weather but i'm just faking it rn 2023-08-23 18:12:32 +09:00
minjaesong
8535b0ce13 forgot to enable the initial clouds spawning 2023-08-23 13:01:20 +09:00
minjaesong
6e0004f165 clouds can spawn and drift in any direction 2023-08-23 12:49:33 +09:00
minjaesong
845333f33d timeflow on the titlescreen need not be that complex 2023-08-23 10:10:01 +09:00
minjaesong
6988feb731 day-night cycle on the titlescreen 2023-08-22 23:39:09 +09:00
minjaesong
ac2c7b1148 clouds on titlescreen 2023-08-22 23:17:49 +09:00
minjaesong
d6145fd0da even more clouds 2023-08-22 22:27:39 +09:00
minjaesong
194089827c more cloud texture 2023-08-22 21:27:33 +09:00
minjaesong
d69d032f74 more cloud texture 2023-08-22 20:27:25 +09:00
minjaesong
a9dbea3d16 more clouds 2023-08-22 20:06:22 +09:00
minjaesong
52938a4b60 improved cloud draw perf 2023-08-22 17:43:53 +09:00
minjaesong
a21f986f30 cloud spawn z-pos probability change 2023-08-22 16:33:39 +09:00
minjaesong
547158a313 more depth to the distant clouds 2023-08-22 16:20:35 +09:00
minjaesong
0a8b5f33f4 clouds parallax and can drift in 3D 2023-08-22 09:50:03 +09:00
minjaesong
da8d620766 clouds with just right depths 2023-08-22 02:55:31 +09:00
minjaesong
7dd520393c more clouds 2023-08-22 00:06:03 +09:00
minjaesong
dc83e12170 more clouds 2023-08-21 21:39:11 +09:00
minjaesong
d6b2940d8f more clouds 2023-08-21 01:26:16 +09:00
minjaesong
c5dfe46b76 cloud wip 2023-08-20 19:10:43 +09:00
minjaesong
3d3926c08b windows build 2023-08-18 20:30:57 +09:00
minjaesong
9a90bf69d4 trying to use the proper method of running exe on exe 2023-08-18 10:57:40 +09:00
minjaesong
0ed5472d8a adjusting pos for 'save will be deleted' msg 2023-08-18 00:05:03 +09:00
minjaesong
97a7a36030 version tag on app configuration 2023-08-17 15:47:31 +09:00
minjaesong
662069466a skybox size adjustment 2023-08-17 02:04:05 +09:00
minjaesong
52cff00338 commit 2023-08-16 22:39:31 +09:00
minjaesong
1a40334f8e auto zip for .app packaging 2023-08-16 22:26:27 +09:00
minjaesong
763f512419 script for assets_release 2023-08-16 22:17:09 +09:00
minjaesong
620a1c6956 GL_UNSIGNED_SHORT works just fine on macOS?! 2023-08-16 21:56:04 +09:00
minjaesong
5f4fcdba69 apple m chip workaround (2) 2023-08-16 21:46:54 +09:00
minjaesong
7a79f444b2 apple m chip workaround 2023-08-16 21:38:23 +09:00
minjaesong
e4b947ce69 Float16FrameBuffer 2023-08-16 17:51:31 +09:00
minjaesong
fdfec960ca reverse gravity adaptation of the last commit 2023-08-16 16:33:53 +09:00
minjaesong
75021ecfa2 fixing issue #48 2023-08-16 16:03:54 +09:00
minjaesong
c90ef21bfa calendar UI mouseover 2023-08-15 19:02:25 +09:00
minjaesong
3fce5d7e95 calendar UI 2023-08-15 14:58:50 +09:00
minjaesong
8db1228e70 calendar wip 2023-08-15 04:54:43 +09:00
minjaesong
5f7f724058 tileatlas: atlas size will automatically expand if it's too small 2023-08-14 18:47:39 +09:00
minjaesong
fab4179068 fixing issue #47 using new tag on blocks.csv 2023-08-14 18:16:05 +09:00
minjaesong
32803b6f18 incomplete fix for horizontal bouncing on T-shaped platform arrangement 2023-08-14 04:10:10 +09:00
minjaesong
f8f75fb7b6 options to change atlas texture size 2023-08-14 03:53:25 +09:00
minjaesong
9919a99032 fix: phys ccd would only trigger on its last iteration due to a stupid oversight 2023-08-13 16:54:46 +09:00
minjaesong
6a43d1a5bd calendar sprite removing a spring 2023-08-13 15:36:24 +09:00
minjaesong
24c971e4b8 oh wait thats not it 2023-08-11 21:08:35 +09:00
minjaesong
62f0fd7c68 hiding the phys artefact by forcefully holding down-key for long enough 2023-08-11 21:05:47 +09:00
minjaesong
3dec312989 phys glitch kinda fixed but i'm no longer sure about that 2023-08-11 17:03:51 +09:00
minjaesong
77b51a45dd no highp on blur shader 2023-08-11 13:03:45 +09:00
minjaesong
d1b4ce3404 something's fixed but have no idea what 2023-08-11 12:35:36 +09:00
minjaesong
fd7b88307c . 2023-08-11 09:29:30 +09:00
minjaesong
579b6b5b29 somehow fixed but now jumping while walking against wall changes jump behav 2023-08-11 01:04:34 +09:00
minjaesong
cef58f6a73 phys debugging; see L818@ActorWithBody.kt 2023-08-10 23:49:43 +09:00
minjaesong
c0c98c3b80 some locale changes; remoCon changes on load menu 2023-08-08 17:44:23 +09:00
minjaesong
88d844cc09 actor draw planting offset 2023-08-08 17:14:13 +09:00
minjaesong
2411db17a7 calendar fixture wip 2023-08-08 16:41:40 +09:00
minjaesong
53d372be38 there's no way #33 is fixed so easily but im committing it anyway 2023-08-08 12:09:22 +09:00
minjaesong
88831051c8 revised ingame date format 2023-08-08 09:01:34 +09:00
minjaesong
87d92ecb74 some random ideas for future self 2023-08-08 01:39:33 +09:00
minjaesong
6672dffdbc new passwd for new version 2023-08-07 14:45:07 +09:00
minjaesong
cd00ab4c7f fix: hq2x results graphical issue on some systems 2023-08-07 14:30:36 +09:00
minjaesong
014306c209 2k skybox tex; trilinear blending of atmos vars 2023-08-07 13:59:45 +09:00
minjaesong
30fb57eca3 skybox: two different setup for AM/PN 2023-08-06 18:37:56 +09:00
minjaesong
52ad8f0c46 improved skybox model 2023-08-05 17:20:35 +09:00
minjaesong
1b08039018 updating numbers for v0.3.3 2023-08-05 00:45:35 +09:00
minjaesong
c701519cb9 unloading test_texture 2023-08-05 00:25:25 +09:00
minjaesong
75e6669d49 temp fix: platform-ladder not working 2023-08-05 00:16:00 +09:00
minjaesong
18631064d4 hosek skybox moved outside of basegame; moonlight impl 2023-08-04 13:43:14 +09:00
minjaesong
9fe6618cc9 fix: splash goes black when hq2x is enabled 2023-08-04 12:53:44 +09:00
minjaesong
7b8d6d6913 fix: bad number formatting on debug window 2023-08-04 00:53:30 +09:00
minjaesong
385a882937 stars: more realistic twinkle, change of axial tilt changes starmap 'altitude' 2023-08-03 23:55:19 +09:00
minjaesong
c73461a407 const-ifying shaders 2023-08-03 18:37:23 +09:00
minjaesong
f7e4987785 less crazy twinkling 2023-08-03 00:29:27 +09:00
minjaesong
78bd88858b twinkling stars 2023-08-03 00:11:17 +09:00
minjaesong
d2b1346252 diurnal motion on stars 2023-08-02 22:44:04 +09:00
minjaesong
fb28fd8a76 brought 'sunset orange' back 2023-08-02 22:14:25 +09:00
minjaesong
36d25c6479 the stars are rendered but still some works left 2023-08-02 18:55:41 +09:00
minjaesong
2ade76147c fix: skybox edge case on deg ±75 2023-08-02 18:44:12 +09:00
minjaesong
59d9adbbd1 stars wip 2023-08-02 17:52:42 +09:00
minjaesong
821c7c77d8 much more elegant solution than stretching texture using batch 2023-08-02 16:37:15 +09:00
minjaesong
3308f09e08 some other 'weather' elements (assets only) 2023-08-02 10:57:52 +09:00
minjaesong
37d45e22ad backdrop is stretched far enought so that the stretchedness is not observable 2023-08-01 22:01:56 +09:00
minjaesong
1ac861fa82 skybox lut 2023-08-01 17:22:45 +09:00
minjaesong
451808cd1c skybox atlas texture generation 2023-08-01 16:50:37 +09:00
minjaesong
0c00b3b7cc borders on quickslot images 2023-07-31 21:49:11 +09:00
minjaesong
1669f7fdd0 actual maths solution for the smoothLinear 2023-07-30 22:52:00 +09:00
minjaesong
f4bfe84009 better smooth-linear function 2023-07-30 18:35:36 +09:00
minjaesong
91cf08e93a 64 pixels for gradmap instead of 128 2023-07-30 03:36:31 +09:00
minjaesong
33a8112454 skybox: taller grad window, smooth grad clamping 2023-07-30 03:29:14 +09:00
minjaesong
439cde09fc this is the best curve 🫠 2023-07-26 15:10:15 +09:00
minjaesong
2a62435712 wtf was that 2023-07-26 00:58:17 +09:00
minjaesong
5495552db5 yet another sky model changes 2023-07-26 00:09:47 +09:00
minjaesong
e04d0284bb another experiments with the hosek model 2023-07-25 22:11:10 +09:00
minjaesong
ad601ffd7e oops forgot about the alpha channel 2023-07-25 16:57:13 +09:00
minjaesong
987ec1fd98 more sky model changes 2023-07-25 16:53:02 +09:00
minjaesong
4fb30821f1 sky model update 2023-07-25 15:15:12 +09:00
minjaesong
a73c536941 skybox model changes on negative deg 2023-07-25 03:47:59 +09:00
minjaesong
4c1f16fe91 executable renamed from 'java' to 'Terrarum' 2023-07-24 00:56:01 +09:00
minjaesong
6df78b59a9 screenshot taking extracted to its own function 2023-07-22 14:19:09 +09:00
minjaesong
28c4d8f11b texture2D -> texture 2023-07-22 03:45:21 +09:00
minjaesong
cdfc86398c hq2x shader using modernised syntax 2023-07-22 03:41:09 +09:00
minjaesong
91d94d2dab partially working hq2x, may not work on macOS tho 2023-07-21 20:29:17 +09:00
minjaesong
0af2e57368 wtf is going on 2023-07-21 17:41:22 +09:00
minjaesong
fbce707cac option for screen filtering mode 2023-07-21 13:14:02 +09:00
minjaesong
9d7bd37394 automated menuwork for control panel 2023-07-15 20:21:29 +09:00
minjaesong
df8bcf79af titlescreen: weather change is reflected to the skybox AND daylight 2023-07-15 13:33:09 +09:00
minjaesong
e328457259 improved control panel making 2023-07-14 17:03:04 +09:00
minjaesong
9baec6c7a1 improved slider mouse op 2023-07-14 16:50:25 +09:00
minjaesong
d05364f43f horizontal slider 2023-07-14 14:34:28 +09:00
minjaesong
e7ed3d8eae spinners will now round to nearest valid number 2023-07-13 21:08:41 +09:00
minjaesong
da6da79186 fix: previous 'centering' attempt was 8 pixels off 2023-07-13 20:08:20 +09:00
minjaesong
0767521441 uiloadmanage: going back to list will reset the list scroll 2023-07-13 16:34:01 +09:00
minjaesong
30aca57cbc savegame renaming 2023-07-13 15:45:35 +09:00
minjaesong
e512c6c7ad fix: textinput contained by sliding panel would not get text input 2023-07-13 15:12:30 +09:00
minjaesong
6ebf79a8e3 savelist cell width now matches management buttons; buttons and thumnail now well positioned 2023-07-13 14:13:37 +09:00
minjaesong
e5d5feeb38 fix: crafting UI is not centred 2023-07-13 13:49:50 +09:00
minjaesong
8e9d2371c8 mem gauge size changed to match the radiobutton-bar 2023-07-13 00:21:12 +09:00
minjaesong
1f5d032ad8 teleporter: no new world if memory is full 2023-07-12 21:45:22 +09:00
minjaesong
7993ccd2e5 memory gauge on teleporter world search 2023-07-12 21:30:50 +09:00
minjaesong
c77f1ffd23 removing auto/manual save selection: is practically useless 2023-07-12 10:40:21 +09:00
minjaesong
4eb7a8a77e fix: if two savegame has identical lastmodifiedtime, file with lower number will be preferred 2023-07-12 10:00:47 +09:00
minjaesong
10f92a11a9 loadlist: version number of the savegame 2023-07-12 02:23:49 +09:00
minjaesong
c5659e2833 loadlost: preloading game screenshots 2023-07-11 21:11:19 +09:00
minjaesong
173f99f87d two getthumbnail funs merget into one 2023-07-11 19:52:56 +09:00
minjaesong
64e05a4f17 load list: thumbnail on management scr 2023-07-11 15:18:44 +09:00
minjaesong
c033260ec5 debugpanel: solar altitude and atmos turbidity 2023-07-11 12:01:08 +09:00
minjaesong
22191bd377 daylight model edited to match the skybox 2023-07-11 01:55:15 +09:00
minjaesong
79f19120f2 replacing min/max usage with kotlin's 2023-07-11 01:54:46 +09:00
minjaesong
d96b7d1b84 fix: creating new game works again 2023-07-11 00:34:32 +09:00
minjaesong
2b62b4f413 fix: model having wrong turbidity value 2023-07-10 23:14:56 +09:00
minjaesong
f0fa5830bd moving hosek datasets to assets dir 2023-07-10 21:38:50 +09:00
minjaesong
ec24dc9870 no day-night cycle on titlescreen demo 2023-07-10 20:44:35 +09:00
minjaesong
6bc3d0e6ad deploying new skybox model 2023-07-10 19:47:44 +09:00
minjaesong
64c610e77e model improvements 2023-07-10 04:00:49 +09:00
minjaesong
b25ea9654c model improvements 2023-07-10 03:16:10 +09:00
minjaesong
b6b98562a2 preliminary skybox model 1 2023-07-10 02:57:41 +09:00
minjaesong
c93b70f537 world portal: rename and delete now working 2023-07-09 19:17:13 +09:00
minjaesong
fb67b0ef5a fix: not having IME set would cause NPE 2023-07-09 02:27:26 +09:00
minjaesong
7c7b3de68d swapping save delete/cancel button so that accidental double click would not delete the save 2023-07-09 02:20:38 +09:00
minjaesong
71df31b93d working autosave chooser 2023-07-08 23:26:47 +09:00
minjaesong
9b24014191 keyboard control symbol for IME will follow the current IME selection 2023-07-08 22:24:16 +09:00
minjaesong
02308a7918 autosave marker on save list 2023-07-08 22:12:08 +09:00
minjaesong
03c6061a12 game loading is back but newgame is broken 2023-07-08 21:53:19 +09:00
minjaesong
325e67f999 damaged savegame is handled by the management scr 2023-07-08 18:49:56 +09:00
minjaesong
211f936bd3 save manage scr 2023-07-08 16:12:15 +09:00
minjaesong
1f6fa49d19 minor improvements 2023-07-08 14:20:53 +09:00
minjaesong
13810fc09b working loading spinner; closing menu while loading will gracefully kill the loading thread 2023-07-08 14:04:14 +09:00
minjaesong
f95bc36c98 and now fa and fis works the same? wtf? 2023-07-08 03:33:02 +09:00
minjaesong
d507d84950 the file io is cursed 2023-07-08 03:12:15 +09:00
minjaesong
b31da6ffec . 2023-07-07 15:44:42 +09:00
minjaesong
3593894c0f hopefully more lightweight init 2023-07-07 12:27:54 +09:00
minjaesong
c28b286553 changes in fade-slide transition container 2023-07-07 00:19:56 +09:00
minjaesong
c0a3da1b66 fix: inscript - s key had wrong glyph 2023-07-06 22:43:08 +09:00
minjaesong
02cf5fdce5 tamil99 2023-07-06 22:07:21 +09:00
minjaesong
1e6f51e16c oops now it's broken but I still had to commit lol 2023-07-05 21:35:41 +09:00
minjaesong
c61c169048 more elegant UILoadSavegame wip 2023-07-05 20:16:53 +09:00
minjaesong
5c58c3006b inscript: ime update 2023-07-05 13:29:43 +09:00
minjaesong
742cabb81f is this the way? 2023-07-05 01:15:48 +09:00
minjaesong
07d5e571d6 windows build: smaller exe file 2023-07-05 01:11:06 +09:00
minjaesong
305242045f inscript keyboard layout for hindi 2023-07-05 00:44:13 +09:00
minjaesong
67388999f0 lang update 2023-07-04 21:50:20 +09:00
minjaesong
b0cc1180bb fix: app wont launch if its path contains whitespaces 2023-07-04 21:32:38 +09:00
minjaesong
453459e3b6 fix: some UIs won't fade in/out on open/close 2023-07-03 21:35:46 +09:00
minjaesong
bad72dd353 simple SAVING ui for teleportation 2023-07-03 20:26:30 +09:00
minjaesong
13185f0565 preliminary gui thing for teleportation 2023-07-03 17:46:57 +09:00
minjaesong
fcaf4c97f1 seemingly working world teleporter (no saving... ui tho) 2023-07-03 00:10:46 +09:00
minjaesong
9c396e7b8d new world via teleporter wip 2023-07-02 18:54:04 +09:00
minjaesong
afb7dff5d2 some comment elaboration 2023-07-02 01:25:34 +09:00
minjaesong
5d0514040c lang split into two files 2023-06-30 16:20:57 +09:00
minjaesong
7c1806946b worldportal: showing tooltip to tell why the button is disabled 2023-06-30 03:07:45 +09:00
minjaesong
e5e02681b8 weather only change on titlescreen 2023-06-30 00:53:46 +09:00
minjaesong
6db3baf691 clearing up interpolation functions 2023-06-30 00:14:28 +09:00
minjaesong
07cbcbe79b better title screen camera smoothing 2023-06-29 22:50:44 +09:00
minjaesong
57a9f7febc graph guidance colour scheme change; added easter egg where the camera might pan towards left 2023-06-29 02:56:33 +09:00
minjaesong
16cfaaea27 titlescreen follows the terrain better 2023-06-28 22:49:45 +09:00
minjaesong
72c742897e fix: load menu buttons are pushed when they should not listen to the touchdown event 2023-06-28 17:47:04 +09:00
minjaesong
23af64deb4 proper savegame backups sorting 2023-06-28 16:42:38 +09:00
minjaesong
bb017fa9b7 gui for load savegame 2023-06-28 16:10:15 +09:00
minjaesong
1745bb16db save deletion works but gui is still wip 2023-06-28 11:05:28 +09:00
minjaesong
370583d1af actual red button for DELETE 2023-06-28 00:55:36 +09:00
minjaesong
66b651c627 delete character file gui wip 2023-06-27 22:46:16 +09:00
minjaesong
c5874a7f3d finally working again: create new character
todo: make delete character work
2023-06-27 21:13:51 +09:00
minjaesong
057905c3b7 thumb generation for player saves 2023-06-27 01:21:05 +09:00
minjaesong
2b50562002 save juggling for autosaves 2023-06-26 23:10:52 +09:00
minjaesong
73a8198378 fix: loading a game would load the oldest backup save 2023-06-26 21:43:25 +09:00
minjaesong
1ef479124e actually working load manual/auto button 2023-06-26 20:18:00 +09:00
minjaesong
e5e8028b3f fix: clickOnceListener would not fired if screen is magnified 2023-06-26 19:07:25 +09:00
minjaesong
739b51af95 manual/auto selection for savegame loading 2023-06-26 18:18:59 +09:00
minjaesong
f9f49ab63c new savegame loader is not quite working yet 2023-06-26 01:09:47 +09:00
minjaesong
a497463349 some ui updates 2023-06-25 20:46:52 +09:00
minjaesong
253db56c4f the baloon now has opacity control 2023-06-25 13:58:37 +09:00
minjaesong
3d13941060 new savegame loading wip 2023-06-24 23:44:48 +09:00
minjaesong
592e489411 warning for apple rosetta 2023-06-24 02:06:22 +09:00
minjaesong
49b2011ea0 a little bit generalised titlescreen warning printing 2023-06-24 01:12:43 +09:00
minjaesong
61e6255b52 some warning for apple rosetta 2023-06-24 01:03:58 +09:00
minjaesong
2e956f89f5 fix for edge case where 64-bit x86 CPU not reporting itself as AMD64 2023-06-24 00:40:59 +09:00
minjaesong
e8ffd1f844 proper bootstrap codes 2023-06-23 18:44:05 +09:00
minjaesong
0882145f9c some autosave stuffs; bootloader to actually use bundled runtime 2023-06-23 17:29:49 +09:00
minjaesong
28e2179e44 don't xstartonfirstthread the bootstrapper 2023-06-23 12:11:19 +09:00
minjaesong
48eb1ffd8f printout child proc's out and err to console 2023-06-22 23:11:34 +09:00
minjaesong
6daccb2e62 locales 2023-06-22 22:27:56 +09:00
minjaesong
8c9d5a26fb more code trimming 2023-06-22 22:05:10 +09:00
minjaesong
ee3e5b14cd rm unused code snippet 2023-06-22 21:21:09 +09:00
minjaesong
5c39df9080 bootstrapper for the App so that the user can change the max heap in-game 2023-06-22 21:08:09 +09:00
minjaesong
5d77694316 windows build script now produces .exe 2023-06-21 23:49:42 +09:00
minjaesong
cf111d2507 world portal writing current world to actorvalue 'worldportaldict' if it's not there 2023-06-20 13:45:32 +09:00
minjaesong
724ace3f00 for now ui simply closes on teleport target selection 2023-06-20 13:22:14 +09:00
minjaesong
1457cbffb3 worldportal: submitting teleportrequest works, needs UI refinement 2023-06-20 00:15:53 +09:00
minjaesong
7a42066392 electric: rising/falling edge and level detection 2023-06-19 18:42:08 +09:00
minjaesong
528b975350 wiresim: signal sinking actors are only getting updated when the sim calls for 2023-06-19 16:34:39 +09:00
minjaesong
9e9064dd55 world portal: world search is now new world 2023-06-19 00:50:55 +09:00
minjaesong
138c6d22d2 some font stuffs for ui 2023-06-18 21:40:06 +09:00
minjaesong
a33f0e7ab4 world search ui integrated to world portal ui 2023-06-18 21:29:18 +09:00
minjaesong
93c427473d inventory backdrop is now image 2023-06-18 16:02:25 +09:00
minjaesong
6b8798a19e single screen ui for world portal 2023-06-18 01:28:51 +09:00
minjaesong
376595d7cd fix: scroll controller for portal listing is 2 px shorter that it should 2023-06-18 00:40:55 +09:00
minjaesong
4cc52b5585 fix: storage chest ui would be shifted to left and any mouse button would trigger the action 2023-06-17 23:19:09 +09:00
minjaesong
0ff71f39fe list scroll for portallisting 2023-06-17 17:10:13 +09:00
minjaesong
13f487a562 inventory navbar to its own uiitem 2023-06-17 16:46:15 +09:00
minjaesong
0599ce91b1 reflection function update 2023-06-12 15:08:42 +09:00
283 changed files with 11082 additions and 3231 deletions

View File

@@ -13,6 +13,10 @@
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-controllers-desktop-2.2.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/GetCpuName.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/jxinput-1.0.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk7.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk8.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-csv-1.8.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/prtree.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/Terrarum_Joise.jar" path-in-jar="/" />
@@ -72,21 +76,17 @@
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.11.0-natives-armeabi-v7a.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.11.0-natives-desktop.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.11.0-natives-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.21/kotlin-stdlib-1.8.21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.21/kotlin-stdlib-common-1.8.21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-test/1.8.21/kotlin-test-1.8.21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.8.21/kotlin-reflect-1.8.21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk8.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib-jdk7.jar" path-in-jar="/" />
<element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-stdlib.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/graal-sdk-22.3.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/icu4j-71.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-22.3.1-edit.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.21/kotlin-stdlib-1.8.21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.21/kotlin-stdlib-common-1.8.21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-test/1.8.21/kotlin-test-1.8.21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-scriptengine-22.3.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/regex-22.3.1-edit.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/truffle-api-22.3.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/icu4j-71.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/regex-22.3.1-edit.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/js-22.3.1-edit.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/graal-sdk-22.3.1.jar" path-in-jar="/" />
</root>
</artifact>
</component>

19
.idea/runConfigurations/Principii.xml generated Normal file
View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Principii" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="net.torvald.terrarum.Principii" />
<module name="TerrarumBuild" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="net.torvald.terrarum.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="BuildArtifacts" enabled="true">
<artifact name="ModuleComputers" />
<artifact name="TerrarumBuild" />
</option>
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -1,26 +1,17 @@
package net.torvald.terrarum.modulecomputers.gameactors
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.utils.Disposable
import kotlin.coroutines.*
import net.torvald.terrarum.*
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.gameactors.BlockBox
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.modulecomputers.ui.UIHomeComputer
import net.torvald.tsvm.*
import net.torvald.tsvm.peripheral.AdapterConfig
import net.torvald.tsvm.peripheral.GraphicsAdapter
import net.torvald.tsvm.peripheral.VMProgramRom
import net.torvald.unicode.*
/**
* Created by minjaesong on 2021-12-04.
@@ -131,84 +122,3 @@ class FixtureHomeComputer : FixtureBase {
}
}
internal class UIHomeComputer : UICanvas(
toggleKeyLiteral = Input.Keys.ESCAPE, // FIXME why do I have specify ESC for it to function? ESC should be work as the default key
toggleButtonLiteral = App.getConfigInt("control_gamepad_start"),
) {
override var width = 640
override var height = 480
override var openCloseTime = 0f
private val drawOffX = (width - 560).div(2).toFloat()
private val drawOffY = (height - 448).div(2).toFloat()
private var batch: FlippingSpriteBatch
private var camera: OrthographicCamera
internal lateinit var vm: VM
internal lateinit var fixture: FixtureHomeComputer
init {
batch = FlippingSpriteBatch()
camera = OrthographicCamera(width.toFloat(), height.toFloat())
//val m = Matrix4()
//m.setToOrtho2D(0f, 0f, width.toFloat(), height.toFloat())
batch.projectionMatrix = camera.combined
}
private val fbo = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
private val controlHelp =
"${getKeycapPC(App.getConfigInt("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}\u3000 " +
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_T$KEYCAP_R Terminate\u3000" +
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_S Reset\u3000" +
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_Q SysRq"
override fun updateUI(delta: Float) {
}
override fun renderUI(otherBatch: SpriteBatch, otherCamera: Camera) {
otherBatch.end()
fbo.inAction(camera, batch) {
Gdx.gl.glClearColor(0f,0f,0f,1f)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) // to hide the crap might be there
(vm.peripheralTable[1].peripheral as? GraphicsAdapter)?.let { gpu ->
val clearCol = gpu.getBackgroundColour()
Gdx.gl.glClearColor(clearCol.r, clearCol.g, clearCol.b, clearCol.a)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
gpu.render(Gdx.graphics.deltaTime, batch, drawOffX, drawOffY, true, fbo) // gpu.render will internally end() the fbo then begin() again before using the batch I've fed in
}
}
otherBatch.begin()
otherBatch.shader = null
blendNormalStraightAlpha(otherBatch)
otherBatch.color = Color.WHITE
otherBatch.draw(fbo.colorBufferTexture, posX.toFloat(), posY.toFloat(), width.toFloat(), height.toFloat())
otherBatch.color = Toolkit.Theme.COL_INACTIVE
Toolkit.drawBoxBorder(otherBatch, posX - 1, posY - 1, width + 2, height + 2)
App.fontGame.draw(otherBatch, controlHelp, posX, posY + height + 4)
}
override fun doOpening(delta: Float) {
fixture.startVM()
}
override fun doClosing(delta: Float) {
}
override fun endOpening(delta: Float) {
}
override fun endClosing(delta: Float) {
}
override fun dispose() {
fbo.dispose()
}
}

View File

@@ -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

Binary file not shown.

BIN
assets/graphics/astrum.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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)) {

View File

@@ -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

View 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!='')
})

View File

@@ -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 :

View File

@@ -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 :

View File

@@ -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)) {

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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

View File

@@ -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)) {

View File

@@ -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', '']

View File

@@ -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

View 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!='')
})

View File

@@ -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":()=>{

View File

@@ -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":()=>{

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -0,0 +1,4 @@
{
"INPUT_KEYBOARD_DEFAULT_LAYOUT": "en_intl_qwertz",
"INPUT_KEYBOARD_DEFAULT_IME": "none"
}

View File

@@ -1,31 +1,43 @@
{
"APP_WARNING_HEALTH_AND_SAFETY": "WARNING-HEALTH AND SAFETY",
"CONTEXT_CHARACTER": "Character",
"MENU_LABEL_COPYRIGHT": "Copyright",
"CONTEXT_TIME_MINUTE_PLURAL": "Minutes",
"CONTEXT_TIME_SECOND_PLURAL": "Seconds",
"COPYRIGHT_ALL_RIGHTS_RESERVED": "All rights reserved",
"COPYRIGHT_GNU_GPL_3": "Distributed under GNU GPL 3",
"APP_WARNING_HEALTH_AND_SAFETY": "WARNING-HEALTH AND SAFETY",
"MENU_LABEL_PRESS_START_SYMBOL": "Press >",
"MENU_MODULES" : "Modules",
"MENU_CREDIT_GPL_DNT" : "GPL",
"GAME_ACTION_MOVE_VERB" : "Move",
"GAME_ACTION_ZOOM" : "Zoom",
"MENU_LABEL_RESET" : "Reset",
"GAME_32BIT_WARNING1": "It looks like youre running a 32-Bit version of Java.",
"GAME_32BIT_WARNING2": "Please download and install the latest 64-Bit Java at:",
"GAME_32BIT_WARNING3": "https://www.java.com/en/download/",
"MENU_OPTION_STREAMERS_LAYOUT": "Chat Overlay",
"MENU_LABEL_RESTART_REQUIRED": "Restart Required",
"MENU_LABEL_KEYBOARD_LAYOUT": "Keyboard Layout",
"MENU_LABEL_IME": "IME",
"MENU_OPTIONS_DITHER": "Dithering",
"MENU_OPTIONS_BLUR": "Blur",
"MENU_OPTIONS_PARTICLES": "Particles",
"MENU_IO_AUTOSAVE": "Autosave",
"MENU_IO_CLEAR": "Clear",
"MENU_IO_IMPORT": "Import",
"APP_NOMODULE_1": "No Module is currently loaded.",
"APP_NOMODULE_2": "Please configure your Load Order and restart:",
"MENU_LABEL_KEYCONFIG_HELP1": "Click On the Keycap to Assign Actions",
"MENU_IO_MANUAL_SAVE": "Manual Save",
"MENU_LABEL_COPYRIGHT": "Copyright",
"MENU_LABEL_DELETE": "Delete",
"MENU_LABEL_EXTRA_JVM_ARGUMENTS": "Extra Arguments",
"MENU_LABEL_IME": "IME",
"MENU_LABEL_IME_TOGGLE": "Toggle IME",
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Paste from Cliboard",
"MENU_LABEL_KEYBOARD_LAYOUT": "Keyboard Layout",
"MENU_LABEL_PASTE": "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_LABEL_DELETE": "Delete"
"MENU_OPTIONS_STREAMERS_LAYOUT": "Chat Overlay",
"MENU_OPTIONS_NONE" : "None",
"MENU_CREDIT_GPL_DNT" : "GPL",
"MENU_LABEL_JVM_DNT" : "JVM",
"MENU_OPTIONS_FILTERING_HQ2X_DNT" : "Hq2x"
}

View File

@@ -0,0 +1,16 @@
{
"GAME_32BIT_WARNING1": "It looks like youre 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."
}

View File

@@ -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": "इनपुट विधि",

View File

@@ -2335,7 +2335,7 @@
},
{
"n": "MENU_OPTIONS",
"s": "Stillingar "
"s": "Valkostir "
},
{
"n": "MENU_OPTIONS_ADVANCEDGRAPHICS",
@@ -2395,11 +2395,11 @@
},
{
"n": "MENU_OPTIONS_GAMEPLAY",
"s": "Gameplay Options"
"s": "Leikvalkostir"
},
{
"n": "MENU_OPTIONS_GRAPHICS",
"s": "Grafíkstillingar"
"s": "Grafíkvalkostir"
},
{
"n": "MENU_OPTIONS_HUD",

View File

@@ -15,5 +15,15 @@
"MENU_OPTIONS_DITHER": "Dither",
"MENU_OPTIONS_BLUR": "Óskýrt",
"MENU_OPTIONS_PARTICLES": "Eind",
"MENU_IO_IMPORT": "Flytja inn"
"MENU_IO_IMPORT": "Flytja inn",
"APP_NOMODULE_1": "Engin eining er hlaðin eins og er.",
"APP_NOMODULE_2": "Vinsamlega stilltu hleðslupöntunina þína og endurræstu:",
"MENU_LABEL_KEYCONFIG_HELP1": "Smelltu á lyklalokið til að úthluta aðgerðum",
"MENU_LABEL_IME_TOGGLE": "Breyttu IME",
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Límdu frá klemmuspjald",
"MENU_OPTIONS_PERFORMANCE": "Afköst",
"MENU_LABEL_DELETE": "Eyða",
"MENU_OPTIONS_JVM_HEAP_MAX": "Hámarks hrúguminni",
"MENU_OPTIONS_AUTOSAVE": "Sjálfvirk vistun",
"CONTEXT_TIME_MINUTE_PLURAL": "Mínútur"
}

View File

@@ -1,29 +1,39 @@
{
"APP_WARNING_HEALTH_AND_SAFETY": "경고—건강과 안전을 위하여",
"CONTEXT_CHARACTER": "캐릭터",
"MENU_LABEL_COPYRIGHT": "저작권",
"CONTEXT_TIME_MINUTE_PLURAL": "",
"CONTEXT_TIME_SECOND_PLURAL": "초",
"COPYRIGHT_ALL_RIGHTS_RESERVED": "모든 권리 보유",
"COPYRIGHT_GNU_GPL_3": "GNU GPL 3에 따라 배포됨",
"APP_WARNING_HEALTH_AND_SAFETY": "경고—건강과 안전을 위하여",
"MENU_LABEL_PRESS_START_SYMBOL": ">을 누르세요",
"MENU_MODULES" : "모듈",
"GAME_ACTION_MOVE_VERB" : "이동하기",
"GAME_ACTION_ZOOM" : "확대·축소",
"MENU_LABEL_RESET" : "재설정",
"GAME_32BIT_WARNING1": "32비트 버전의 Java를 사용중인 것 같습니다.",
"GAME_32BIT_WARNING2": "아래 링크에서 최신 64비트 Java를 내려받아 설치해주세요.",
"GAME_32BIT_WARNING3": "https://www.java.com/ko/download/",
"MENU_OPTION_STREAMERS_LAYOUT": "채팅창 오버레이",
"MENU_LABEL_RESTART_REQUIRED": "재시작 필요",
"MENU_LABEL_KEYBOARD_LAYOUT": "자판 배열",
"MENU_LABEL_IME": "입력기",
"MENU_OPTIONS_DITHER": "디더링",
"MENU_OPTIONS_BLUR": "흐림",
"MENU_OPTIONS_PARTICLES": "입자 수",
"MENU_IO_AUTOSAVE": "자동 저장",
"MENU_IO_CLEAR": "지우기",
"MENU_IO_IMPORT": "가져오기",
"APP_NOMODULE_1": "현재 불러와진 모듈이 없습니다.",
"APP_NOMODULE_2": "다음의 파일에서 불러오기 순서를 설정하고 게임을 재시작하십시오.",
"MENU_LABEL_KEYCONFIG_HELP1": "키캡을 클릭해 컨트롤을 배정하십시오",
"MENU_IO_MANUAL_SAVE": "수동 저장",
"MENU_LABEL_COPYRIGHT": "저작권",
"MENU_LABEL_DELETE": "삭제",
"MENU_LABEL_EXTRA_JVM_ARGUMENTS": "추가 명령 인수",
"MENU_LABEL_IME": "입력기",
"MENU_LABEL_IME_TOGGLE": "입력기 켜고 끄기",
"MENU_LABEL_KEYBOARD_LAYOUT": "자판 배열",
"MENU_LABEL_PASTE": "붙여넣기",
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "복사한 텍스트 붙여넣기",
"MENU_OPTIONS_PERFORMANCE": "성능"
"MENU_LABEL_PRESS_START_SYMBOL": ">을 누르세요",
"MENU_LABEL_RESET" : "재설정",
"MENU_LABEL_RESTART_REQUIRED": "재시작 필요",
"MENU_LABEL_STREAMING": "실시간 방송",
"MENU_LABEL_SYSTEM_INFO": "시스템 정보",
"MENU_MODULES" : "모듈",
"MENU_OPTIONS_ATLAS_TEXTURE_SIZE": "아틀라스 텍스처 크기",
"MENU_OPTIONS_AUTOSAVE": "자동 저장",
"MENU_OPTIONS_BLUR": "흐림",
"MENU_OPTIONS_DEBUG_CONSOLE": "디버그 콘솔",
"MENU_OPTIONS_DITHER": "디더링",
"MENU_OPTIONS_JVM_HEAP_MAX": "최대 힙 메모리",
"MENU_OPTIONS_NOTIFICATION_DISPLAY_DURATION": "알림 표시 시간",
"MENU_OPTIONS_PARTICLES": "입자 수",
"MENU_OPTIONS_PERFORMANCE": "성능",
"MENU_OPTIONS_STREAMERS_LAYOUT": "채팅창 오버레이",
"MENU_OPTIONS_NONE" : "없음"
}

View File

@@ -0,0 +1,16 @@
{
"GAME_32BIT_WARNING1": "32비트 버전의 Java를 사용중인 것 같습니다.",
"GAME_32BIT_WARNING2": "아래 링크에서 최신 64비트 Java를 내려받아 설치해주세요.",
"GAME_32BIT_WARNING3": "https://www.java.com/ko/download/",
"GAME_APPLE_ROSETTA_WARNING1": "Apple Silicon이 탑재된 Mac을 사용 중이지만 x86 빌드의 게임을 실행 중입니다.",
"GAME_APPLE_ROSETTA_WARNING2": "최적의 성능과 게임 경험을 위해 Apple Silicon용 빌드의 게임을 이용해 주십시오.",
"APP_NOMODULE_1": "현재 불러와진 모듈이 없습니다.",
"APP_NOMODULE_2": "다음의 파일에서 불러오기 순서를 설정하고 게임을 재시작하십시오.",
"MENU_LABEL_KEYCONFIG_HELP1": "키캡을 클릭해 컨트롤을 배정하십시오",
"GAME_PREV_SAVE_WAS_LOADED1": "가장 최근에 저장된 게임이 손상되었습니다.",
"GAME_PREV_SAVE_WAS_LOADED2": "이전에 저장된 게임을 불러왔습니다.",
"GAME_MORE_RECENT_AUTOSAVE1": "자동 저장된 게임이 수동으로 저장한 게임보다 더 최신입니다.",
"GAME_MORE_RECENT_AUTOSAVE2": "불러올 게임을 선택해 주십시오.",
"MENU_LABEL_SAVE_WILL_BE_DELETED": "선택된 세이브가 삭제됩니다.",
"MENU_LABEL_UNSAVED_PROGRESS_WILL_BE_LOST": "저장하지 않은 진행 상황을 잃게 됩니다."
}

View File

@@ -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": "输入法",

View File

@@ -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": "輸入法",

View File

@@ -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.

View File

@@ -22,6 +22,8 @@ Seed
SetAV
SetBulletin
SetScale
SetSol
SetTurb
SetTime
SetTimeDelta
SpawnPhysTestBall
@@ -30,4 +32,5 @@ Teleport
ToggleNoClip
Zoom
DynToStatic
DebugFillInventory
DebugFillInventory
Uuid
1 CatStdout
22 SetAV
23 SetBulletin
24 SetScale
25 SetSol
26 SetTurb
27 SetTime
28 SetTimeDelta
29 SpawnPhysTestBall
32 ToggleNoClip
33 Zoom
34 DynToStatic
35 DebugFillInventory
36 Uuid

Binary file not shown.

View File

@@ -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
1 id classname
8 8 net.torvald.terrarum.modulebasegame.gameitems.ItemLogicSignalEmitter
9 9 net.torvald.terrarum.modulebasegame.gameitems.WireCutterAll
10 10 net.torvald.terrarum.modulebasegame.gameitems.ItemTypewriter
11 11 net.torvald.terrarum.modulebasegame.gameitems.ItemWallCalendar
12 256 net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorOak
13 257 net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorEbony
14 258 net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorBirch

View 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}"
}

View File

@@ -1,23 +1,24 @@
{
"CONTEXT_GENERATOR_SEED": "Seed",
"CONTEXT_ITEM_MAP": "Map",
"CONTEXT_ITEM_TOOL_PLURAL": "Tools",
"CONTEXT_PLACE_COORDINATE": "Coordinate",
"CONTEXT_WORLD_COUNT": "Worlds: ",
"CONTEXT_WORLD_NEW": "New World",
"MENU_LABEL_DELETE_WORLD": "Delete World",
"CONTEXT_WORLD_COUNT": "Worlds: ",
"GAME_INVENTORY_INGREDIENTS": "Ingredients",
"GAME_INVENTORY_POTIONS": "Potions",
"GAME_INVENTORY_BLOCKS": "Blocks",
"GAME_INVENTORY_WALLS": "Walls",
"CONTEXT_ITEM_TOOL_PLURAL": "Tools",
"GAME_INVENTORY_FAVORITES": "Favorites",
"GAME_INVENTORY_REGISTER": "Register",
"CONTEXT_ITEM_MAP": "Map",
"MENU_LABEL_MENU": "Menu",
"CONTEXT_GENERATOR_SEED": "Seed",
"MENU_LABEL_PREV_SAVES": "Previous Saves",
"MENU_LABEL_RENAME": "Rename",
"GAME_ACTION_CRAFT": "Craft",
"GAME_ACTION_GRAPPLE": "Grapple",
"GAME_ACTION_QUICKSEL": "Quick Select",
"GAME_ACTION_CRAFT": "Craft",
"GAME_CRAFTING": "Crafting",
"GAME_ACTION_TELEPORT": "Teleport",
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
"CONTEXT_WORLD_SEARCH": "World Search",
"CONTEXT_WORLD_LIST": "Worlds List",
"MENU_LABEL_RENAME": "Rename"
"GAME_CRAFTING": "Crafting",
"GAME_INVENTORY_BLOCKS": "Blocks",
"GAME_INVENTORY_FAVORITES": "Favorites",
"GAME_INVENTORY_INGREDIENTS": "Ingredients",
"GAME_INVENTORY_POTIONS": "Potions",
"GAME_INVENTORY_REGISTER": "Register",
"GAME_INVENTORY_WALLS": "Walls"
}

View File

@@ -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"
}

View 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": ""
}

View 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}"
}

View File

@@ -1,21 +1,25 @@
{
"CONTEXT_GENERATOR_SEED": "시드",
"CONTEXT_ITEM_MAP": "지도",
"CONTEXT_ITEM_TOOL_PLURAL": "도구",
"CONTEXT_PLACE_COORDINATE": "좌표",
"CONTEXT_WORLD_COUNT": "새계: ",
"CONTEXT_WORLD_NEW": "새 세계",
"MENU_LABEL_DELETE_WORLD": "새계 삭제",
"CONTEXT_WORLD_COUNT": "새계: ",
"MENU_MONITOR_CALI_TITLE": "모니터 확인",
"GAME_INVENTORY_INGREDIENTS": "재료",
"GAME_INVENTORY_POTIONS": "물약",
"GAME_INVENTORY_BLOCKS": "블록",
"GAME_INVENTORY_WALLS": "벽지",
"CONTEXT_ITEM_TOOL_PLURAL": "도구",
"GAME_INVENTORY_FAVORITES": "즐겨찾기",
"GAME_INVENTORY_REGISTER": "등록하기",
"MENU_LABEL_MENU": "메뉴",
"CONTEXT_ITEM_MAP": "지도",
"CONTEXT_GENERATOR_SEED": "시드",
"MENU_LABEL_PREV_SAVES": "이전 세이브",
"MENU_LABEL_RENAME": "이름 바꾸기",
"MENU_MONITOR_CALI_TITLE": "모니터 확인",
"GAME_ACTION_CRAFT": "제작하기",
"GAME_ACTION_GRAPPLE": "매달리기",
"GAME_ACTION_QUICKSEL": "빠른 선택",
"GAME_ACTION_CRAFT": "제작하기",
"GAME_ACTION_TELEPORT": "텔레포트하기",
"GAME_CRAFTABLE_ITEMS": "제작 가능한 아이템",
"GAME_CRAFTING": "제작",
"GAME_CRAFTABLE_ITEMS": "제작 가능한 아이템"
"GAME_INVENTORY_BLOCKS": "블록",
"GAME_INVENTORY_FAVORITES": "즐겨찾기",
"GAME_INVENTORY_INGREDIENTS": "재료",
"GAME_INVENTORY_POTIONS": "물약",
"GAME_INVENTORY_REGISTER": "등록하기",
"GAME_INVENTORY_WALLS": "벽지"
}

View File

@@ -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": "전선 절단기"
}

View File

@@ -0,0 +1,5 @@
{
"CONTEXT_THIS_IS_A_WORLD_CURRENTLY_PLAYING": "현재 플레이 중인 월드입니다.",
"CONTEXT_IMPORT_AVATAR_INSTRUCTION_1": "아바타 코드를 클립보드에 복사한 다음, 아래의 붙여넣기 버튼을 눌러주세요.",
"CONTEXT_IMPORT_AVATAR_INSTRUCTION_2": ""
}

Binary file not shown.

View File

@@ -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
}
}
}

View File

@@ -1,10 +0,0 @@
{
"globalLight": "generic_light.tga",
"skyboxGradColourMap": "generic_skybox.tga",
"classification": "genericrain",
"extraImages": [
"raindrop.tga"
],
"mixFrom": "__CURRENTWEATHER",
"mixPercentage": 80.0
}

View 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
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -23,12 +23,14 @@ cp $SRCFILES/AppRun $DESTDIR/AppRun
chmod +x $DESTDIR/AppRun
# Copy over a Java runtime
cp -r "../out/$RUNTIME" $DESTDIR/
mkdir $DESTDIR/out
cp -r "../out/$RUNTIME" $DESTDIR/out/
mv $DESTDIR/out/$RUNTIME/bin/java $DESTDIR/out/$RUNTIME/bin/Terrarum
# Copy over all the assets and a jarfile
cp -r "../assets_release" $DESTDIR/
mv $DESTDIR/assets_release $DESTDIR/assets
cp -r "../out/TerrarumBuild.jar" $DESTDIR/assets/
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
# Pack everything to AppImage
ARCH=arm_aarch64 "./$APPIMAGETOOL" $DESTDIR "out/$DESTDIR.AppImage" || { echo 'Building AppImage failed' >&2; exit 1; }

View File

@@ -23,12 +23,14 @@ cp $SRCFILES/AppRun $DESTDIR/AppRun
chmod +x $DESTDIR/AppRun
# Copy over a Java runtime
cp -r "../out/$RUNTIME" $DESTDIR/
mkdir $DESTDIR/out
cp -r "../out/$RUNTIME" $DESTDIR/out/
mv $DESTDIR/out/$RUNTIME/bin/java $DESTDIR/out/$RUNTIME/bin/Terrarum
# Copy over all the assets and a jarfile
cp -r "../assets_release" $DESTDIR/
mv $DESTDIR/assets_release $DESTDIR/assets
cp -r "../out/TerrarumBuild.jar" $DESTDIR/assets/
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
# Pack everything to AppImage
"./$APPIMAGETOOL" $DESTDIR "out/$DESTDIR.AppImage" || { echo 'Building AppImage failed' >&2; exit 1; }

View File

@@ -3,7 +3,8 @@ if (( $EUID == 0 )); then echo "The build process is not meant to be run with ro
cd "${0%/*}"
SRCFILES="terrarummac_arm"
DESTDIR="out/TerrarumMac.arm.app"
APPDIR="./TerrarumMac.arm.app"
DESTDIR="out/$APPDIR"
RUNTIME="runtime-osx-arm"
if [ ! -d "../assets_release" ]; then
@@ -25,11 +26,17 @@ cp $SRCFILES/Terrarum.sh $DESTDIR/Contents/MacOS/
chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
# Copy over a Java runtime
cp -r "../out/$RUNTIME" $DESTDIR/Contents/MacOS/
mkdir $DESTDIR/Contents/MacOS/out
cp -r "../out/$RUNTIME" $DESTDIR/Contents/MacOS/out/
mv $DESTDIR/Contents/MacOS/out/$RUNTIME/bin/java $DESTDIR/Contents/MacOS/out/$RUNTIME/bin/Terrarum
# Copy over all the assets and a jarfile
cp -r "../assets_release" $DESTDIR/Contents/MacOS/
mv $DESTDIR/Contents/MacOS/assets_release $DESTDIR/Contents/MacOS/assets
cp -r "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/assets/
cp "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/out/
cd "out"
rm $APPDIR.zip
7z a -tzip $APPDIR.zip $APPDIR
echo "Build successful: $DESTDIR"

View File

@@ -3,7 +3,8 @@ if (( $EUID == 0 )); then echo "The build process is not meant to be run with ro
cd "${0%/*}"
SRCFILES="terrarummac_x86"
DESTDIR="out/TerrarumMac.x86.app"
APPDIR="./TerrarumMac.x86.app"
DESTDIR="out/$APPDIR"
RUNTIME="runtime-osx-x86"
if [ ! -d "../assets_release" ]; then
@@ -25,11 +26,17 @@ cp $SRCFILES/Terrarum.sh $DESTDIR/Contents/MacOS/
chmod +x $DESTDIR/Contents/MacOS/Terrarum.sh
# Copy over a Java runtime
cp -r "../out/$RUNTIME" $DESTDIR/Contents/MacOS/
mkdir $DESTDIR/Contents/MacOS/out
cp -r "../out/$RUNTIME" $DESTDIR/Contents/MacOS/out/
mv $DESTDIR/Contents/MacOS/out/$RUNTIME/bin/java $DESTDIR/Contents/MacOS/out/$RUNTIME/bin/Terrarum
# Copy over all the assets and a jarfile
cp -r "../assets_release" $DESTDIR/Contents/MacOS/
mv $DESTDIR/Contents/MacOS/assets_release $DESTDIR/Contents/MacOS/assets
cp -r "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/assets/
cp "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/out/
cd "out"
rm $APPDIR.zip
7z a -tzip $APPDIR.zip $APPDIR
echo "Build successful: $DESTDIR"

View File

@@ -16,17 +16,26 @@ rm -rf $DESTDIR || true
mkdir $DESTDIR
# Prepare an application
cp $SRCFILES/Terrarum.bat $DESTDIR/
if ! command -v x86_64-w64-mingw32-gcc &> /dev/null
then
echo 'Mingw32 not found; please install mingw64-cross-gcc (or similar) to your system' >&2; exit 1;
fi
x86_64-w64-mingw32-gcc -Os -s -o $DESTDIR/Terrarum.exe $SRCFILES/Terrarum.c || { echo 'Building EXE failed' >&2; exit 1; }
# TODO add icon to the exe (use x86_64-w64-mingw32-windres?)
# Copy over a Java runtime
cp -r "../out/$RUNTIME" $DESTDIR/
mkdir $DESTDIR/out
cp -r "../out/$RUNTIME" $DESTDIR/out/
mv $DESTDIR/out/$RUNTIME/bin/java.exe $DESTDIR/out/$RUNTIME/bin/Terrarum.exe
# Copy over all the assets and a jarfile
cp -r "../assets_release" $DESTDIR/
mv $DESTDIR/assets_release $DESTDIR/assets
cp -r "../out/TerrarumBuild.jar" $DESTDIR/assets/
cp "../out/TerrarumBuild.jar" $DESTDIR/out/
# Temporary solution: zip everything
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
View 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

View File

@@ -1,3 +1,3 @@
#!/bin/bash
cd "${0%/*}"
./runtime-linux-arm/bin/java -Xms1G -Xmx6G -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./assets/TerrarumBuild.jar
./out/runtime-linux-arm/bin/Terrarum -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./out/TerrarumBuild.jar

View File

@@ -1,3 +1,3 @@
#!/bin/bash
cd "${0%/*}"
./runtime-linux-x86/bin/java -Xms1G -Xmx6G -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./assets/TerrarumBuild.jar
./out/runtime-linux-x86/bin/Terrarum -Dswing.aatext=true -Dawt.useSystemAAFontSettings=lcd -jar ./out/TerrarumBuild.jar

View File

@@ -1,3 +1,3 @@
#!/bin/bash
cd "${0%/*}"
./runtime-osx-arm/bin/java -XstartOnFirstThread -Xms1G -Xmx6G -jar ./assets/TerrarumBuild.jar
./out/runtime-osx-arm/bin/Terrarum -jar ./out/TerrarumBuild.jar

View File

@@ -1,3 +1,3 @@
#!/bin/bash
cd "${0%/*}"
./runtime-osx-x86/bin/java -XstartOnFirstThread -Xms1G -Xmx6G -jar ./assets/TerrarumBuild.jar
./out/runtime-osx-x86/bin/Terrarum -jar ./out/TerrarumBuild.jar

View File

@@ -1,2 +0,0 @@
cd /D "%~dp0"
.\runtime-windows-x86\bin\java -Xms1G -Xmx6G -jar .\assets\TerrarumBuild.jar

View File

@@ -0,0 +1,11 @@
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
int main() {
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");
}

View File

@@ -1,3 +1,3 @@
Manifest-Version: 1.0
Main-Class: net.torvald.terrarum.App
Main-Class: net.torvald.terrarum.Principii

View File

@@ -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;
}
}
}

View File

@@ -166,6 +166,19 @@ final public class FastMath {
return ((1f - scale) * startValue) + (scale * endValue);
}
public static double interpolateLinear(double scale, double startValue, double endValue) {
if (startValue == endValue) {
return startValue;
}
if (scale <= 0.0) {
return startValue;
}
if (scale >= 1.0) {
return endValue;
}
return ((1.0 - scale) * startValue) + (scale * endValue);
}
/**
* Linear interpolation from startValue to endValue by the given percent.
* Basically: ((1 - percent) * startValue) + (percent * endValue)
@@ -231,6 +244,14 @@ final public class FastMath {
return (float) (((c4 * u + c3) * u + c2) * u + c1);
}
public static float interpolateCatmullRom(float u, float p0, float p1, float p2, float p3) {
return interpolateCatmullRom(u, 0.5f, p0, p1, p2, p3);
}
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 ]
@@ -314,26 +335,26 @@ final public class FastMath {
return l;
}
public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3) {
return interpolateHermite(scale, p0, p1, p2, p3, 1f, 0f);
}
public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3, float tension, float bias) {
/*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;
float biasTensionTerms = 0.5f;//(1f + bias) * (1f - tension) / 2f;
float m0 = (p1 - p0) * (1f + bias) * (1f - tension) / 2f;
m0 += (p2 - p1) * (1f + bias) * (1f - tension) / 2f;
float m1 = (p2 - p1) * (1f + bias) * (1f - tension) / 2f;
m1 += (p3 - p2) * (1f + bias) * (1f - tension) / 2f;
float m0 = (p1 - p0) * biasTensionTerms;
float mTemp = (p2 - p1) * biasTensionTerms;
m0 += mTemp;
float m1 = mTemp;
m1 += (p3 - p2) * biasTensionTerms;
float a0 = 2 * mu3 - 3 * mu2 + 1;
float a1 = mu3 - 2 * mu2 + scale;
float a2 = mu3 - mu2;
float a3 = -2 * mu3 + 3 * mu2;
float a0 = 2*mu3 - 3*mu2 + 1;
float a1 = 1*mu3 - 2*mu2 + scale;
float a2 = 1*mu3 - 1*mu2 + 0;
float a3 = -2*mu3 + 3*mu2 + 0;
return a0 * p1 + a1 * m0 + a2 * m1 + a3 * p2;
}
return a0*p1 + a1*m0 + a2*m1 + a3*p2;
}*/
//public static float interpolateHermite(float scale, float p0, float p1, float p2, float p3, float tension, float bias) {}
/**
@@ -795,28 +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).
@@ -871,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;

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -18,7 +18,7 @@ public class XXHash32 {
public static int hashGeoCoord(int x, int y) {
int p = ((x & 65535) << 16) | (y & 65535);
return hash(new byte[]{(byte) p, (byte)(p >>> 8), (byte)(p >>> 16), (byte)(p >>> 24)}, 10000);
return hash(new byte[]{(byte) p, (byte)(p >>> 8), (byte)(p >>> 16), (byte)(p >>> 24)}, x ^ y);
}
public static int hash(byte[] data, int seed) {

View File

@@ -3,15 +3,15 @@ package net.torvald.reflection
/**
* Created by minjaesong on 2023-03-25.
*/
fun Any.extortField(name: String): Any? { // yes I'm deliberately using negative words for the function name
inline fun <reified T> Any.extortField(name: String): T? { // yes I'm deliberately using negative words for the function name
return this.javaClass.getDeclaredField(name).let {
it.isAccessible = true
it.get(this)
it.get(this) as T?
}
}
fun Any.forceInvoke(name: String, params: Array<Any>): Any? { // yes I'm deliberately using negative words for the function name
inline fun <reified T> Any.forceInvoke(name: String, params: Array<Any>): T? { // yes I'm deliberately using negative words for the function name
return this.javaClass.getDeclaredMethod(name, *(params.map { it.javaClass }.toTypedArray())).let {
it.isAccessible = true
it.invoke(this, *params)
it.invoke(this, *params) as T?
}
}

View File

@@ -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 {

View File

@@ -31,7 +31,6 @@ import net.torvald.terrarum.langpack.Lang;
import net.torvald.terrarum.modulebasegame.IngameRenderer;
import net.torvald.terrarum.modulebasegame.TerrarumIngame;
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory;
import net.torvald.terrarum.savegame.DiskSkimmer;
import net.torvald.terrarum.serialise.WriteConfig;
import net.torvald.terrarum.ui.Toolkit;
import net.torvald.terrarum.utils.JsonFetcher;
@@ -63,9 +62,11 @@ public class App implements ApplicationListener {
public static final String GAME_NAME = TerrarumAppConfiguration.GAME_NAME;
public static final long VERSION_RAW = TerrarumAppConfiguration.VERSION_RAW;
public static final String VERSION_TAG = TerrarumAppConfiguration.VERSION_TAG;
public static final String getVERSION_STRING() {
return String.format("%d.%d.%d", VERSION_RAW >>> 48, (VERSION_RAW & 0xffff000000L) >>> 24, VERSION_RAW & 0xffffffL);
return String.format("%d.%d.%d", VERSION_RAW >>> 48, (VERSION_RAW & 0xffff000000L) >>> 24, VERSION_RAW & 0xffffffL) +
(VERSION_TAG.isBlank() ? "" : "-"+VERSION_TAG);
}
/**
@@ -142,6 +143,12 @@ public class App implements ApplicationListener {
public static final int GLOBAL_FRAMERATE_LIMIT = 300;
private static String undesirableConditions;
public static String getUndesirableConditions() {
return undesirableConditions;
}
/**
* These languages won't distinguish regional differences (e.g. enUS and enUK, frFR and frCA)
*/
@@ -201,11 +208,11 @@ public class App implements ApplicationListener {
* Sorted by the lastplaytime, in reverse order (index 0 is the most recent game played)
*/
public static ArrayList<UUID> sortedSavegameWorlds = new ArrayList();
public static HashMap<UUID, DiskSkimmer> savegameWorlds = new HashMap<>(); // UNSORTED even with the TreeMap
public static HashMap<UUID, SavegameCollection> savegameWorlds = new HashMap<>(); // UNSORTED even with the TreeMap
public static HashMap<UUID, String> savegameWorldsName = new HashMap<>();
public static ArrayList<UUID> sortedPlayers = new ArrayList();
public static HashMap<UUID, DiskSkimmer> savegamePlayers = new HashMap<>();
public static HashMap<UUID, SavegameCollection> savegamePlayers = new HashMap<>();
public static HashMap<UUID, String> savegamePlayersName = new HashMap<>();
public static void updateListOfSavegames() {
@@ -234,6 +241,7 @@ public class App implements ApplicationListener {
public static ShaderProgram shaderColLUT;
public static ShaderProgram shaderReflect;
public static ShaderProgram shaderGhastlyWhite;
public static Hq2x hq2x;
public static Mesh fullscreenQuad;
private static OrthographicCamera camera;
@@ -261,12 +269,13 @@ public class App implements ApplicationListener {
Gdx.gl20.glViewport(0, 0, width, height);
}
public static final float UPDATE_RATE = 1f / 64f; // apparent framerate will be limited by update rate
public static final int 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<>();
@@ -346,10 +355,13 @@ public class App implements ApplicationListener {
processorVendor = "Unknown CPU";
}
if (processor.startsWith("Apple M") && Objects.equals(systemArch, "aarch64")) {
if (processor.startsWith("Apple M") && systemArch.equals("aarch64")) {
isAppleM = true;
System.out.println("Apple Proprietary "+processor+" detected; don't expect smooth sailing...");
}
if (processor.startsWith("Apple M") && !systemArch.equals("aarch64")) {
undesirableConditions = "apple_execution_through_rosetta";
}
if (!IS_DEVELOPMENT_BUILD) {
var p = UnsafeHelper.INSTANCE.allocate(64);
@@ -374,8 +386,8 @@ public class App implements ApplicationListener {
ShaderProgram.pedantic = false;
scr = new TerrarumScreenSize(getConfigInt("screenwidth"), getConfigInt("screenheight"));
int width = (int) Math.round(scr.getWidth() * scr.getMagn());
int height = (int) Math.round(scr.getHeight() * scr.getMagn());
int width = scr.getWindowW();
int height = scr.getWindowH();
Lwjgl3ApplicationConfiguration appConfig = new Lwjgl3ApplicationConfiguration();
//appConfig.useGL30 = false; // https://stackoverflow.com/questions/46753218/libgdx-should-i-use-gl30
@@ -383,6 +395,7 @@ public class App implements ApplicationListener {
appConfig.useVsync(getConfigBoolean("usevsync"));
appConfig.setResizable(false);
appConfig.setWindowedMode(width, height);
appConfig.setTransparentFramebuffer(false);
int fpsActive = Math.min(GLOBAL_FRAMERATE_LIMIT, getConfigInt("displayfps"));
if (fpsActive <= 0) fpsActive = GLOBAL_FRAMERATE_LIMIT;
int fpsBack = Math.min(GLOBAL_FRAMERATE_LIMIT, getConfigInt("displayfpsidle"));
@@ -430,13 +443,10 @@ public class App implements ApplicationListener {
glInfo.create();
CommonResourcePool.INSTANCE.addToLoadingList("blockmarkings_common", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/blocks/block_markings_common.tga"), 16, 16, 0, 0, 0, 0, false, false, false));
CommonResourcePool.INSTANCE.addToLoadingList("blockmarking_actor", () -> new BlockMarkerActor());
CommonResourcePool.INSTANCE.addToLoadingList("loading_circle_64", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/gui/loading_circle_64.tga"), 64, 64, 0, 0, 0, 0, false, false, false));
CommonResourcePool.INSTANCE.addToLoadingList("inline_loading_spinner", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/gui/inline_loading_spinner.tga"), 20, 20, 0, 0, 0, 0, false, false, false));
CommonResourcePool.INSTANCE.addToLoadingList("inventory_category", () -> new TextureRegionPack("./assets/graphics/gui/inventory/category.tga", 20, 20, 0, 0, 0, 0, false, false, false));
CommonResourcePool.INSTANCE.addToLoadingList("title_health1", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_take_a_break.tga")));
CommonResourcePool.INSTANCE.addToLoadingList("title_health2", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_distance.tga")));
// make loading list
CommonResourcePool.INSTANCE.loadAll();
newTempFile("wenquanyi.tga"); // temp file required by the font
@@ -465,12 +475,9 @@ public class App implements ApplicationListener {
shaderBayerSkyboxFill = loadShaderFromClasspath("shaders/default.vert",
"shaders/float_to_disp_dither_static.frag"
);
shaderHicolour = loadShaderFromClasspath("shaders/default.vert", "shaders/hicolour.frag");
shaderDebugDiff = loadShaderFromClasspath("shaders/default.vert", "shaders/diff.frag");
shaderPassthruRGBA = loadShaderFromClasspath("shaders/gl32spritebatch.vert", "shaders/gl32spritebatch.frag");
shaderColLUT = loadShaderFromClasspath("shaders/default.vert", "shaders/passthrurgb.frag");
shaderReflect = loadShaderFromClasspath("shaders/default.vert", "shaders/reflect.frag");
shaderGhastlyWhite = loadShaderFromClasspath("shaders/default.vert", "shaders/ghastlywhite.frag");
hq2x = new Hq2x(2);
fullscreenQuad = new Mesh(
true, 4, 6,
@@ -478,97 +485,21 @@ public class App implements ApplicationListener {
VertexAttribute.ColorUnpacked(),
VertexAttribute.TexCoords(0)
);
updateFullscreenQuad(scr.getWidth(), scr.getHeight());
updateFullscreenQuad(fullscreenQuad, scr.getWidth(), scr.getHeight());
// set up renderer info variables
renderer = Gdx.graphics.getGLVersion().getRendererString();
rendererVendor = Gdx.graphics.getGLVersion().getVendorString();
// make gamepad(s)
if (App.getConfigBoolean("usexinput")) {
try {
gamepad = new XinputControllerAdapter(XInputDevice.getDeviceFor(0));
}
catch (Throwable e) {
gamepad = null;
}
// nullify if not actually connected
try {
if (!((XinputControllerAdapter) gamepad).getC().isConnected()) {
gamepad = null;
}
}
catch (NullPointerException notQuiteWindows) {
gamepad = null;
}
}
if (gamepad == null) {
try {
gamepad = new GdxControllerAdapter(Controllers.getControllers().get(0));
}
catch (Throwable e) {
gamepad = null;
}
}
// tell the game that we have a gamepad
environment = RunningEnvironment.PC;
if (gamepad != null) {
String name = gamepad.getName().toLowerCase();
for (String allowedName : gamepadWhitelist) {
if (name.contains(allowedName)) {
environment = RunningEnvironment.CONSOLE;
break;
}
}
}
/*if (gamepad != null) {
environment = RunningEnvironment.CONSOLE;
// calibrate the sticks
printdbg(this, "Calibrating the gamepad...");
float[] axesZeroPoints = new float[]{
gamepad.getAxisRaw(0),
gamepad.getAxisRaw(1),
gamepad.getAxisRaw(2),
gamepad.getAxisRaw(3)
};
setConfig("control_gamepad_axiszeropoints", axesZeroPoints);
for (int i = 0; i < 4; i++) {
printdbg(this, "Axis " + i + ": " + axesZeroPoints[i]);
}
}
else {
environment = RunningEnvironment.PC;
}*/
fontGame = new TerrarumSansBitmap(FONT_DIR, false, false, false,
false,
256, false, 0.5f, false
);
fontUITitle = new TerrarumSansBitmap(FONT_DIR, false, false, false,
false,
64, false, 0.5f, false
);
fontUITitle.setInterchar(2);
fontGameFBO = new TerrarumSansBitmap(FONT_DIR, false, true, false,
false,
64, false, 203f/255f, false
);
Lang.invoke();
// make loading list
CommonResourcePool.INSTANCE.loadAll();
}
private FrameBuffer postProcessorOutFBO;
private FrameBuffer postProcessorOutFBO2;
@Override
public void render() {
@@ -627,30 +558,44 @@ public class App implements ApplicationListener {
FrameBufferManager.end();
// process screenshot request
if (screenshotRequested) {
FrameBufferManager.begin(postProcessorOutFBO);
screenshotRequested = false;
try {
Pixmap p = Pixmap.createFromFrameBuffer(0, 0, scr.getWidth(), scr.getHeight());
PixmapIO.writePNG(Gdx.files.absolute(defaultDir+"/Screenshot-"+String.valueOf(System.currentTimeMillis())+".png"), p, 9, true);
p.dispose();
Terrarum.INSTANCE.getIngame().sendNotification("Screenshot taken");
}
catch (Throwable e) {
e.printStackTrace();
Terrarum.INSTANCE.getIngame().sendNotification("Failed to take screenshot: "+e.getMessage());
}
processScreenshotRequest(postProcessorOutFBO);
if (getConfigString("screenmagnifyingfilter").equals("hq2x") ) {
FrameBufferManager.begin(postProcessorOutFBO2);
shaderPassthruRGBA.bind();
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
shaderPassthruRGBA.setUniformi("u_texture", 0);
hq2x.renderToScreen(postProcessorOutFBO.getColorBufferTexture());
FrameBufferManager.end();
shaderPassthruRGBA.bind();
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
shaderPassthruRGBA.setUniformi("u_texture", 0);
postProcessorOutFBO2.getColorBufferTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
postProcessorOutFBO2.getColorBufferTexture().bind(0);
fullscreenQuad.render(shaderPassthruRGBA, GL20.GL_TRIANGLES);
}
else if (getConfigDouble("screenmagnifying") < 1.01 || getConfigString("screenmagnifyingfilter").equals("none")) {
shaderPassthruRGBA.bind();
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
shaderPassthruRGBA.setUniformi("u_texture", 0);
postProcessorOutFBO.getColorBufferTexture().setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
postProcessorOutFBO.getColorBufferTexture().bind(0);
fullscreenQuad.render(shaderPassthruRGBA, GL20.GL_TRIANGLES);
}
else if (getConfigString("screenmagnifyingfilter").equals("bilinear")) {
shaderPassthruRGBA.bind();
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
shaderPassthruRGBA.setUniformi("u_texture", 0);
postProcessorOutFBO.getColorBufferTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
postProcessorOutFBO.getColorBufferTexture().bind(0);
fullscreenQuad.render(shaderPassthruRGBA, GL20.GL_TRIANGLES);
}
shaderPassthruRGBA.bind();
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
shaderPassthruRGBA.setUniformi("u_texture", 0);
postProcessorOutFBO.getColorBufferTexture().bind(0);
fullscreenQuad.render(shaderPassthruRGBA, GL20.GL_TRIANGLES);
// process resize request
if (resizeRequested) {
@@ -665,6 +610,26 @@ public class App implements ApplicationListener {
}
private static void processScreenshotRequest(FrameBuffer fb) {
if (screenshotRequested) {
String msg = "Screenshot taken";
FrameBufferManager.begin(fb);
try {
Pixmap p = Pixmap.createFromFrameBuffer(0, 0, fb.getWidth(), fb.getHeight());
PixmapIO.writePNG(Gdx.files.absolute(defaultDir+"/Screenshot-"+String.valueOf(System.currentTimeMillis())+".png"), p, 9, true);
p.dispose();
}
catch (Throwable e) {
e.printStackTrace();
msg = ("Failed to take screenshot: "+e.getMessage());
}
FrameBufferManager.end();
screenshotRequested = false;
Terrarum.INSTANCE.getIngame().sendNotification(msg);
}
}
public static Texture getCurrentDitherTex() {
int hash = 31 + GLOBAL_RENDER_TIMER + 0x165667B1 + GLOBAL_RENDER_TIMER * 0xC2B2AE3D;
hash = Integer.rotateLeft(hash, 17) * 0x27D4EB2F;
@@ -767,12 +732,9 @@ public class App implements ApplicationListener {
@Override
public void resize(int w0, int h0) {
int w = (w0%2==0)?w0:w0+1;
int h = (h0%2==0)?h0:h0+1;
float magn = (float) getConfigDouble("screenmagnifying");
int width = Math.round(w / magn);
int height = Math.round(h / magn);
int width = (int) Math.floor(w0 / magn);
int height = (int) Math.floor(h0 / magn);
printdbg(this, "Resize called: "+width+","+height);
@@ -782,22 +744,27 @@ public class App implements ApplicationListener {
//initViewPort(width, height);
scr.setDimension(width, height, magn, w, h);
scr.setDimension(width, height, magn);
if (currentScreen != null) currentScreen.resize(scr.getWidth(), scr.getHeight());
TerrarumPostProcessor.INSTANCE.resize(scr.getWidth(), scr.getHeight());
updateFullscreenQuad(scr.getWidth(), scr.getHeight());
updateFullscreenQuad(fullscreenQuad, scr.getWidth(), scr.getHeight());
if (renderFBO == null ||
(renderFBO.getWidth() != scr.getWidth() ||
renderFBO.getHeight() != scr.getHeight())
) {
renderFBO = new FloatFrameBuffer(
renderFBO = new Float16FrameBuffer(
scr.getWidth(),
scr.getHeight(),
false
);
postProcessorOutFBO2 = new Float16FrameBuffer(
scr.getWidth() * 2,
scr.getHeight() * 2,
false
);
if (IS_DEVELOPMENT_BUILD) {
@@ -850,12 +817,13 @@ public class App implements ApplicationListener {
shaderColLUT.dispose();
shaderReflect.dispose();
shaderGhastlyWhite.dispose();
hq2x.dispose();
CommonResourcePool.INSTANCE.dispose();
fullscreenQuad.dispose();
logoBatch.dispose();
batch.dispose();
shapeRender.dispose();
// shapeRender.dispose();
fontGame.dispose();
fontGameFBO.dispose();
@@ -948,6 +916,93 @@ public class App implements ApplicationListener {
* Init stuffs which needs GL context
*/
private void postInit() {
CommonResourcePool.INSTANCE.addToLoadingList("blockmarkings_common", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/blocks/block_markings_common.tga"), 16, 16, 0, 0, 0, 0, false, false, false));
CommonResourcePool.INSTANCE.addToLoadingList("blockmarking_actor", () -> new BlockMarkerActor());
CommonResourcePool.INSTANCE.addToLoadingList("loading_circle_64", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/gui/loading_circle_64.tga"), 64, 64, 0, 0, 0, 0, false, false, false));
CommonResourcePool.INSTANCE.addToLoadingList("inline_loading_spinner", () -> new TextureRegionPack(Gdx.files.internal("assets/graphics/gui/inline_loading_spinner.tga"), 20, 20, 0, 0, 0, 0, false, false, false));
CommonResourcePool.INSTANCE.addToLoadingList("inventory_category", () -> new TextureRegionPack("./assets/graphics/gui/inventory/category.tga", 20, 20, 0, 0, 0, 0, false, false, false));
CommonResourcePool.INSTANCE.loadAll();
shaderHicolour = loadShaderFromClasspath("shaders/default.vert", "shaders/hicolour.frag");
shaderDebugDiff = loadShaderFromClasspath("shaders/default.vert", "shaders/diff.frag");
shaderColLUT = loadShaderFromClasspath("shaders/default.vert", "shaders/rgbonly.frag");
shaderGhastlyWhite = loadShaderFromClasspath("shaders/default.vert", "shaders/ghastlywhite.frag");
// make gamepad(s)
if (App.getConfigBoolean("usexinput")) {
try {
gamepad = new XinputControllerAdapter(XInputDevice.getDeviceFor(0));
}
catch (Throwable e) {
gamepad = null;
}
// nullify if not actually connected
try {
if (!((XinputControllerAdapter) gamepad).getC().isConnected()) {
gamepad = null;
}
}
catch (NullPointerException notQuiteWindows) {
gamepad = null;
}
}
if (gamepad == null) {
try {
gamepad = new GdxControllerAdapter(Controllers.getControllers().get(0));
}
catch (Throwable e) {
gamepad = null;
}
}
// tell the game that we have a gamepad
environment = RunningEnvironment.PC;
if (gamepad != null) {
String name = gamepad.getName().toLowerCase();
for (String allowedName : gamepadWhitelist) {
if (name.contains(allowedName)) {
environment = RunningEnvironment.CONSOLE;
break;
}
}
}
/*if (gamepad != null) {
environment = RunningEnvironment.CONSOLE;
// calibrate the sticks
printdbg(this, "Calibrating the gamepad...");
float[] axesZeroPoints = new float[]{
gamepad.getAxisRaw(0),
gamepad.getAxisRaw(1),
gamepad.getAxisRaw(2),
gamepad.getAxisRaw(3)
};
setConfig("control_gamepad_axiszeropoints", axesZeroPoints);
for (int i = 0; i < 4; i++) {
printdbg(this, "Axis " + i + ": " + axesZeroPoints[i]);
}
}
else {
environment = RunningEnvironment.PC;
}*/
fontUITitle = new TerrarumSansBitmap(FONT_DIR, false, false, false,
false,
64, false, 0.5f, false
);
fontUITitle.setInterchar(1);
fontGameFBO = new TerrarumSansBitmap(FONT_DIR, false, true, false,
false,
64, false, 203f/255f, false
);
Lang.invoke();
ModMgr.INSTANCE.invoke(); // invoke Module Manager
@@ -1026,14 +1081,14 @@ public class App implements ApplicationListener {
logoBatch.setProjectionMatrix(camera.combined);
}
private void updateFullscreenQuad(int WIDTH, int HEIGHT) { // NOT y-flipped quads!
fullscreenQuad.setVertices(new float[]{
private void updateFullscreenQuad(Mesh mesh, int WIDTH, int HEIGHT) { // NOT y-flipped quads!
mesh.setVertices(new float[]{
0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 1f,
WIDTH, 0f, 0f, 1f, 1f, 1f, 1f, 1f, 1f,
WIDTH, HEIGHT, 0f, 1f, 1f, 1f, 1f, 1f, 0f,
0f, HEIGHT, 0f, 1f, 1f, 1f, 1f, 0f, 0f
});
fullscreenQuad.setIndices(new short[]{0, 1, 2, 2, 3, 0});
mesh.setIndices(new short[]{0, 1, 2, 2, 3, 0});
}
public static void setGamepadButtonLabels() {
@@ -1133,6 +1188,11 @@ public class App implements ApplicationListener {
public static RunningEnvironment environment;
/** defaultDir + "/Recycled/Players" */
public static String recycledPlayersDir;
/** defaultDir + "/Recycled/Worlds" */
public static String recycledWorldsDir;
private static void getDefaultDirectory() {
String OS = OSName.toUpperCase();
if (OS.contains("WIN")) {
@@ -1162,6 +1222,8 @@ public class App implements ApplicationListener {
worldsDir = defaultDir + "/Worlds";
configDir = defaultDir + "/config.json";
loadOrderDir = defaultDir + "/LoadOrder.txt";
recycledPlayersDir = defaultDir + "/Recycled/Players";
recycledWorldsDir = defaultDir + "/Recycled/Worlds";
System.out.println(String.format("os.name = %s (with identifier %s)", OSName, operationSystem));
System.out.println(String.format("os.version = %s", OSVersion));
@@ -1171,10 +1233,12 @@ public class App implements ApplicationListener {
private static void createDirs() {
File[] dirs = {
new File(saveDir),
// new File(saveDir),
new File(saveSharedDir),
new File(playersDir),
new File(worldsDir)
new File(worldsDir),
new File(recycledPlayersDir),
new File(recycledWorldsDir),
};
for (File it : dirs) {
@@ -1314,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);

View File

@@ -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()
}

View 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))
}
}

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum
import com.badlogic.gdx.Gdx
import net.torvald.unicode.BULLET
import net.torvald.unicode.ENDASH
@@ -223,6 +224,22 @@ Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
""").split('\n')
private val javaVersion = System.getProperty("java.version")
private val osName = App.OSName
private val osVersion = App.OSVersion
private val sysArch = App.systemArch
private val processor = App.processor
private val processorVendor = App.processorVendor
private val glinfo = Gdx.graphics.glVersion.debugVersionString
val systeminfo: List<String>; get() = """
JRE Version: $javaVersion
Operation System: $osName $osVersion
Architecture: $sysArch
Processor: $processor ($processorVendor)
GL Info: $glinfo
""".split('\n')
val gpl3: List<String>; get() = """ GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007

View File

@@ -10,6 +10,9 @@ import com.badlogic.gdx.Input
object DefaultConfig {
val hashMap = hashMapOf<String, Any>(
"jvm_xmx" to 4,
"jvm_extra_cmd" to "",
"displayfps" to 0, // 0: no limit, non-zero: limit
"displayfpsidle" to 0, // 0: no limit, non-zero: limit
"displaycolourdepth" to 8,
@@ -19,15 +22,17 @@ object DefaultConfig {
"atlastexsize" to 2048,
"language" to App.getSysLang(),
"notificationshowuptime" to 4096, // 4s
"selecteditemnameshowuptime" to 4096, // 4s
"autosaveinterval" to 262144, // 4m22s
"notificationshowuptime" to 4000, // 4s
"selecteditemnameshowuptime" to 4000, // 4s
"autosaveinterval" to 300000, // 5m
"multithread" to true,
"showhealthmessageonstartup" to true,
"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,
@@ -109,6 +114,7 @@ object DefaultConfig {
"inputmethod" to "none",
"screenmagnifying" to 1.0,
"screenmagnifyingfilter" to "none", // "none", "bilinear", "hq2x"
"fx_newlight" to false,
@@ -116,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(

View File

@@ -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

View 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
}

View File

@@ -7,6 +7,7 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorID
import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.gameactors.ActorWithBody.Companion.PHYS_EPSILON_DIST
import net.torvald.terrarum.gameactors.BlockMarkerActor
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
import net.torvald.terrarum.gameitems.ItemID
@@ -26,9 +27,12 @@ import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import java.util.*
import java.util.concurrent.locks.Lock
import java.util.function.Consumer
import kotlin.math.min
/**
* Although the game (as product) can have infinitely many stages/planets/etc., those stages must be manually managed by YOU;
@@ -49,8 +53,8 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
override fun getMax(axis: Int, t: ActorWithBody): Double =
when (axis) {
0 -> t.hitbox.endX
1 -> t.hitbox.endY
0 -> t.hitbox.endX - PHYS_EPSILON_DIST
1 -> t.hitbox.endY - PHYS_EPSILON_DIST
else -> throw IllegalArgumentException("nonexistent axis $axis for ${dimensions}-dimensional object")
}
}
@@ -61,7 +65,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
lateinit var playerDisk: VirtualDisk; internal set
lateinit var worldSavefileName: String; internal set
lateinit var playerSavefileName: String; internal set
var savegameNickname: String = "SplinesReticulated"; internal set
var worldName: String = "SplinesReticulated"; internal set // worldName is stored as a name of the disk
var screenZoom = 1.0f
val ZOOM_MAXIMUM = 4.0f
@@ -201,13 +205,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
actorContainerInactive.forEach { it.dispose() }
world.dispose()
disposables.forEach(Consumer {
try { it.dispose() }
catch (_: NullPointerException) { }
catch (_: IllegalArgumentException) { }
catch (_: GdxRuntimeException) { }
catch (_: ConcurrentModificationException) { }
})
disposables.forEach(Consumer { it.tryDispose() })
}
////////////
@@ -406,6 +404,14 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
return uiTooltip.message
}
open fun requestForceSave(callback: () -> Unit) {
}
open fun saveTheGame(onSuccessful: () -> Unit, onError: (Throwable) -> Unit) {
}
/**
* Copies most recent `save` to `save.1`, leaving `save` for overwriting, previous `save.1` will be copied to `save.2`
*/
@@ -422,25 +428,55 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
// do not overwrite clean .2 with dirty .1
val flags3 = FileInputStream(file3).let { it.skip(49L); val r = it.read(); it.close(); r }
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
if (!(flags3 == 0 && flags2 != 0) || !file3.exists()) file2.copyTo(file3, true)
if (!(flags3 == 0 && flags2 != 0) || !file3.exists()) Files.move(file2.toPath(), file3.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
try {
// do not overwrite clean .2 with dirty .1
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
val flags1 = FileInputStream(file1).let { it.skip(49L); val r = it.read(); it.close(); r }
if (!(flags2 == 0 && flags1 != 0) || !file2.exists()) file1.copyTo(file2, true)
if (!(flags2 == 0 && flags1 != 0) || !file2.exists()) Files.move(file1.toPath(), file2.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
try {
if (file2.exists() && !file3.exists())
file2.copyTo(file3, true)
Files.move(file2.toPath(), file3.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
if (file1.exists() && !file2.exists())
file1.copyTo(file2, true)
Files.move(file1.toPath(), file2.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
file.copyTo(file1, true)
} catch (e: IOException) {}
}
fun makeSavegameBackupCopyAuto(file0: File): File {
val file1 = File("${file0.absolutePath}.a")
val file2 = File("${file0.absolutePath}.b")
val file3 = File("${file0.absolutePath}.c")
try {
// do not overwrite clean .2 with dirty .1
val flags3 = FileInputStream(file3).let { it.skip(49L); val r = it.read(); it.close(); r }
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
if (!(flags3 == 0 && flags2 != 0) || !file3.exists()) Files.move(file2.toPath(), file3.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
try {
// do not overwrite clean .2 with dirty .1
val flags2 = FileInputStream(file2).let { it.skip(49L); val r = it.read(); it.close(); r }
val flags1 = FileInputStream(file1).let { it.skip(49L); val r = it.read(); it.close(); r }
if (!(flags2 == 0 && flags1 != 0) || !file2.exists()) Files.move(file1.toPath(), file2.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
} catch (e: NoSuchFileException) {} catch (e: FileNotFoundException) {}
try {
if (file2.exists() && !file3.exists())
Files.move(file2.toPath(), file3.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
if (file1.exists() && !file2.exists())
Files.move(file1.toPath(), file2.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
file0.copyTo(file1, true)
} catch (e: IOException) {}
return file1
}
// simple euclidean norm, squared
private val actorDistanceCalculator = DistanceCalculator<ActorWithBody> { t: ActorWithBody, p: PointND ->
@@ -449,7 +485,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
val dist2 = (p.getOrd(0) - (t.hitbox.centeredX - world.width * TILE_SIZE)).sqr() + (p.getOrd(1) - t.hitbox.centeredY).sqr()
val dist3 = (p.getOrd(0) - (t.hitbox.centeredX + world.width * TILE_SIZE)).sqr() + (p.getOrd(1) - t.hitbox.centeredY).sqr()
minOf(dist1, minOf(dist2, dist3))
min(min(dist1, dist2), dist3)
}
/**
@@ -467,7 +503,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
fun getActorsAt(worldX: Double, worldY: Double): List<ActorWithBody> {
val outList = ArrayList<ActorWithBody>()
try {
actorsRTree.find(worldX, worldY, worldX + 1.0, worldY + 1.0, outList)
actorsRTree.find(worldX, worldY, worldX, worldY, outList)
}
catch (e: NullPointerException) {}
return outList
@@ -495,6 +531,9 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
else
null
}
fun onConfigChange() {
}
}
inline fun Lock.lock(body: () -> Unit) {

View File

@@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.utils.JsonValue
import net.torvald.terrarum.App.*
import net.torvald.terrarum.App.setToGameConfig
import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.blockproperties.WireCodex
import net.torvald.terrarum.gameitems.GameItem

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum
import net.torvald.random.XXHash32
import org.dyn4j.geometry.Vector2
/**
@@ -115,6 +116,10 @@ class Point2i() {
return this
}
override fun hashCode(): Int = XXHash32.hashGeoCoord(x, y)
override fun toString() = "Point2i($x, $y)"
operator fun component1() = x
operator fun component2() = y
}

Some files were not shown because too many files have changed in this diff Show More