diff --git a/README.md b/README.md index 9fec705..b0a66d1 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Support of games primarily depends on who developed them - Games with structural * [ ] Moorhuhn Winter * [ ] Moorhuhn 3 * [ ] Moorhuhn X - * [ ] Moorhuhn Kart 2 + * [ ] Moorhuhn Kart 2 (Renderware) * [ ] Moorhuhn Remake * [ ] Moorhuhn Invasion * [x] Moorhuhn Schatzjäger 1 diff --git a/godot/mhjnr/profile/player_profile.gd b/godot/mhjnr/profile/player_profile.gd new file mode 100644 index 0000000..fcea3a7 --- /dev/null +++ b/godot/mhjnr/profile/player_profile.gd @@ -0,0 +1,39 @@ +extends Resource + +class_name PlayerProfile + +const Statistics = preload("res://mhjnr/profile/statistics.gd") +const Status = preload("res://mhjnr/profile/status.gd") + +@export var name: String + +@export var volume_music: int +@export var volume_sfx: int + +@export var current_level: int +@export var game_finished: bool + +@export var input_keys: Array[int] = [] +@export var input_buttons: Array[int] = [] + +@export var status: Status = Status.new() +@export var statistics: Statistics = Statistics.new() + +func from_object_data(data: ObjectData): + name = data["name"] + volume_music = data["volumeMusic"] + volume_sfx = data["volumeSfx"] + + for i in range(7): + input_keys.push_back(data["input %d key"] % i) + input_buttons.push_back(data["input %d button"] % i) + + current_level = data["currentLevel"] + game_finished = data["gameFinished"] != 0 + + for child in data.children: + match child.resource_type: + "Status": + status.from_object_data(child) + "Statistics": + statistics.from_object_data(child) diff --git a/godot/mhjnr/profile/statistics.gd b/godot/mhjnr/profile/statistics.gd new file mode 100644 index 0000000..aacb35f --- /dev/null +++ b/godot/mhjnr/profile/statistics.gd @@ -0,0 +1,18 @@ +extends Resource + +class_name Statistics + +@export var num_shots_fired: int +@export var num_coins_collected: int +@export var num_diamonds_collected: int +@export var enemies_bonus: int +@export var num_powerups_collected: int +@export var num_gold_statues: int + +func from_object_data(data: ObjectData): + num_shots_fired = data["numShotsFired"] + num_coins_collected = data["numCoinsCollected"] + num_diamonds_collected = data["numDiamondsCollected"] + enemies_bonus = data["enemiesBonus"] + num_powerups_collected = data["numPowerupsCollected"] + num_gold_statues = data["numGoldStatues"] diff --git a/godot/mhjnr/profile/status.gd b/godot/mhjnr/profile/status.gd new file mode 100644 index 0000000..c3c03c1 --- /dev/null +++ b/godot/mhjnr/profile/status.gd @@ -0,0 +1,12 @@ +extends Resource + +class_name Status + +@export var lives: int +@export var score: int +@export var bullets: int + +func from_object_data(data: ObjectData): + lives = data["lives"] + score = data["score"] + bullets = data["bullets"] diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 7448e98..dc29136 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -2,30 +2,12 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "array-init" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "base64" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" - [[package]] name = "binrw" version = "0.11.1" @@ -50,366 +32,24 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "bit_field" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bumpalo" -version = "3.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" - [[package]] name = "bytemuck" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "either" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" -[[package]] -name = "encoding_rs" -version = "0.8.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "exr" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd2162b720141a91a054640662d3edce3d50a944a50ffca5313cd951abb35b4" -dependencies = [ - "bit_field", - "flume", - "half", - "lebe", - "miniz_oxide 0.6.2", - "rayon-core", - "smallvec", - "zune-inflate", -] - -[[package]] -name = "fdeflate" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "flate2" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" -dependencies = [ - "crc32fast", - "miniz_oxide 0.7.1", -] - -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "pin-project", - "spin", -] - -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "getrandom" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gif" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" -dependencies = [ - "color_quant", - "weezl", -] - -[[package]] -name = "glam" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c" - -[[package]] -name = "godot" -version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?branch=master#5d5132cffecc584f9c9ed1b55306dcbb60ec3972" -dependencies = [ - "godot-core", - "godot-macros", -] - -[[package]] -name = "godot-bindings" -version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?branch=master#5d5132cffecc584f9c9ed1b55306dcbb60ec3972" -dependencies = [ - "godot4-prebuilt", -] - -[[package]] -name = "godot-codegen" -version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?branch=master#5d5132cffecc584f9c9ed1b55306dcbb60ec3972" -dependencies = [ - "godot-bindings", - "heck", - "nanoserde", - "proc-macro2", - "quote", -] - -[[package]] -name = "godot-core" -version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?branch=master#5d5132cffecc584f9c9ed1b55306dcbb60ec3972" -dependencies = [ - "glam", - "godot-codegen", - "godot-ffi", -] - -[[package]] -name = "godot-ffi" -version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?branch=master#5d5132cffecc584f9c9ed1b55306dcbb60ec3972" -dependencies = [ - "godot-bindings", - "godot-codegen", - "paste", -] - -[[package]] -name = "godot-macros" -version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?branch=master#5d5132cffecc584f9c9ed1b55306dcbb60ec3972" -dependencies = [ - "proc-macro2", - "quote", - "venial", -] - -[[package]] -name = "godot4-prebuilt" -version = "0.0.0" -source = "git+https://github.com/godot-rust/godot4-prebuilt?branch=4.0.1#f9e8cfec0ec565201801b02160ef836800746617" - -[[package]] -name = "half" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" -dependencies = [ - "crunchy", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "image" -version = "0.24.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "exr", - "gif", - "jpeg-decoder", - "num-rational", - "num-traits", - "png", - "qoi", - "tiff", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "jpeg-decoder" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" -dependencies = [ - "rayon", -] - -[[package]] -name = "js-sys" -version = "0.3.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lebe" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" - -[[package]] -name = "libc" -version = "0.2.142" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" - -[[package]] -name = "lock_api" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.17" @@ -419,164 +59,12 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "memoffset" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mhjnr" -version = "0.1.0" -dependencies = [ - "base64", - "binrw", - "encoding_rs", - "godot", - "image", - "itertools", - "serde", - "serde-xml-rs", - "unicode-segmentation", -] - -[[package]] -name = "miniz_oxide" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" -dependencies = [ - "adler", -] - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", - "simd-adler32", -] - -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom", -] - -[[package]] -name = "nanoserde" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755e7965536bc54d7c9fba2df5ada5bf835b0443fd613f0a53fa199a301839d3" -dependencies = [ - "nanoserde-derive", -] - -[[package]] -name = "nanoserde-derive" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7a94da6c6181c35d043fc61c43ac96d3a5d739e7b8027f77650ba41504d6ab" - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" - [[package]] name = "owo-colors" version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" -[[package]] -name = "paste" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" - -[[package]] -name = "pin-project" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "png" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa" -dependencies = [ - "bitflags", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide 0.7.1", -] - [[package]] name = "proc-macro2" version = "1.0.56" @@ -586,15 +74,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "qoi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" -dependencies = [ - "bytemuck", -] - [[package]] name = "quote" version = "1.0.26" @@ -605,38 +84,14 @@ dependencies = [ ] [[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +name = "renderwarelib" +version = "0.1.0" [[package]] name = "serde" -version = "1.0.160" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" dependencies = [ "serde_derive", ] @@ -655,9 +110,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", @@ -665,24 +120,12 @@ dependencies = [ ] [[package]] -name = "simd-adler32" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +name = "springylib" +version = "0.1.0" dependencies = [ - "lock_api", + "binrw", + "serde", + "serde-xml-rs", ] [[package]] @@ -727,116 +170,14 @@ dependencies = [ "syn 2.0.15", ] -[[package]] -name = "tiff" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" -dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", -] - [[package]] name = "unicode-ident" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - -[[package]] -name = "venial" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61584a325b16f97b5b25fcc852eb9550843a251057a5e3e5992d2376f3df4bb2" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 1.0.109", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" - -[[package]] -name = "weezl" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" - [[package]] name = "xml-rs" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" - -[[package]] -name = "zune-inflate" -version = "0.2.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" -dependencies = [ - "simd-adler32", -] +checksum = "40e1a60e6e271dfb0db2db95987551348db75ebd6a78be07b9039b036f7dae2a" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 62fe4bc..c129f4a 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,23 +1,3 @@ -[package] -name = "mhjnr" -version = "0.1.0" -edition = "2021" +[workspace] -[[bin]] -name = "mhjnr-viewer" -path = "src/main.rs" - -[lib] -name = "mhjnr" -crate-type = ["cdylib", "lib"] - -[dependencies] -itertools = "0.10.5" -unicode-segmentation = "1.10.1" -encoding_rs = "0.8.32" -binrw = "0.11.1" -serde = {version = "1.0.160", features = ["derive"]} -serde-xml-rs = "0.6.0" -image = "0.24.6" -base64 = "0.21.0" -godot = { git = "https://github.com/godot-rust/gdext", branch = "master" } +members = ["renderwarelib", "springylib"] diff --git a/rust/Cargo.toml.x b/rust/Cargo.toml.x new file mode 100644 index 0000000..62fe4bc --- /dev/null +++ b/rust/Cargo.toml.x @@ -0,0 +1,23 @@ +[package] +name = "mhjnr" +version = "0.1.0" +edition = "2021" + +[[bin]] +name = "mhjnr-viewer" +path = "src/main.rs" + +[lib] +name = "mhjnr" +crate-type = ["cdylib", "lib"] + +[dependencies] +itertools = "0.10.5" +unicode-segmentation = "1.10.1" +encoding_rs = "0.8.32" +binrw = "0.11.1" +serde = {version = "1.0.160", features = ["derive"]} +serde-xml-rs = "0.6.0" +image = "0.24.6" +base64 = "0.21.0" +godot = { git = "https://github.com/godot-rust/gdext", branch = "master" } diff --git a/rust/renderwarelib/Cargo.toml b/rust/renderwarelib/Cargo.toml new file mode 100644 index 0000000..5d79978 --- /dev/null +++ b/rust/renderwarelib/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "renderwarelib" +version = "0.1.0" +edition = "2021" \ No newline at end of file diff --git a/rust/renderwarelib/src/lib.rs b/rust/renderwarelib/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/rust/renderwarelib/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/rust/springylib/Cargo.toml b/rust/springylib/Cargo.toml new file mode 100644 index 0000000..5cb5e9d --- /dev/null +++ b/rust/springylib/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "springylib" +version = "0.1.0" +edition = "2021" + +[dependencies] +binrw = "0.11.1" +serde = {version = "1.0.160", features = ["derive"]} +serde-xml-rs = "0.6.0" diff --git a/rust/springylib/README.md b/rust/springylib/README.md new file mode 100644 index 0000000..cedd3e6 --- /dev/null +++ b/rust/springylib/README.md @@ -0,0 +1,3 @@ +# SpringyLib + +A library for reading data from the Sproing Engine. diff --git a/rust/springylib/src/archive/error.rs b/rust/springylib/src/archive/error.rs new file mode 100644 index 0000000..b5d69cd --- /dev/null +++ b/rust/springylib/src/archive/error.rs @@ -0,0 +1,34 @@ +use std::fmt::{Display, Formatter}; + +pub type Result = std::result::Result; + +#[derive(Debug)] +pub enum Error { + BinRw(binrw::Error), + Io(std::io::Error), + Unsupported { reason: String }, +} + +impl From for Error { + fn from(value: binrw::Error) -> Self { + Error::BinRw(value) + } +} + +impl From for Error { + fn from(value: std::io::Error) -> Self { + Error::Io(value) + } +} + +impl std::error::Error for Error {} + +impl Display for Error { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Error::BinRw(e) => write!(f, "{}", e), + Error::Io(e) => write!(f, "{}", e), + Error::Unsupported { reason } => write!(f, "Unsupported Archive: {}", reason), + } + } +} diff --git a/rust/springylib/src/archive/mhjnr.rs b/rust/springylib/src/archive/mhjnr.rs new file mode 100644 index 0000000..e32bea1 --- /dev/null +++ b/rust/springylib/src/archive/mhjnr.rs @@ -0,0 +1,48 @@ +use crate::archive::{Archive, FilePointer}; +use binrw::prelude::binread; +use binrw::NullString; + +#[binread] +#[br(little)] +#[derive(Debug)] +pub struct Container { + #[br(align_after = 0x20)] + pub name: NullString, + #[br(temp)] + pub count: u32, + #[br(align_after = 0x20)] + pub unk1: u32, + #[br(count = count)] + pub files: Vec, +} + +impl From for Archive { + fn from(value: Container) -> Self { + Archive( + value + .files + .into_iter() + .map(|it| (it.name.to_string(), it.into())) + .collect(), + ) + } +} + +#[derive(Debug)] +#[binread] +pub struct FileEntry { + #[br(pad_size_to = 0x68)] + pub name: NullString, + pub pos: u32, + #[br(pad_after = 0x10)] + pub len: u32, +} + +impl From for FilePointer { + fn from(value: FileEntry) -> Self { + FilePointer { + position: value.pos as usize, + length: value.len as usize, + } + } +} diff --git a/rust/springylib/src/archive/mod.rs b/rust/springylib/src/archive/mod.rs new file mode 100644 index 0000000..8df3e9e --- /dev/null +++ b/rust/springylib/src/archive/mod.rs @@ -0,0 +1,96 @@ +use binrw::prelude::BinRead; +use binrw::NullString; +use std::collections::HashMap; +use std::io::{Read, Seek}; +use std::ops::Deref; + +pub mod error; +mod mhjnr; +mod standard; + +use crate::archive::error::{Error, Result}; + +/// Archive info +pub struct Archive(HashMap); + +/// Pointer to the file inside the archive +pub struct FilePointer { + pub position: usize, + pub length: usize, +} + +impl Deref for Archive { + type Target = HashMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From> for Archive { + fn from(value: HashMap) -> Self { + Archive(value) + } +} + +/// These are all slightly divergent data layouts +enum ArchiveKind { + /// Appears in a variety of Moorhuhn Shoot 'em Up + /// games, starting with Moorhuhn Winter. + /// + /// The name can have a max length of 0x30, however the header + /// does not store the amount of files and instead is delimited + /// by a final entry with the name `****` + /// + /// File Entries have a max path length of 0x30 with a total entry + /// size of 0x40. + V1, + /// Appears in Moorhuhn Jump 'n Run games as well + /// as Moorhuhn Kart 2, starting with Moorhuhn Kart 2. + /// + /// This one has a name with a max length of 0x20, + /// with a total header size of 0x40 + /// + /// File Entries have a max path length of 0x68, + /// with a total entry size of 0x80 + V2, + /// Appears in later Moorhuhn Shoot 'em Up games, starting with Moorhuhn + /// Invasion. + /// + /// Works the same as V2, but has the maximum header and path string size + /// increased from 0x30 to 0x40 + V3, +} + +impl ArchiveKind { + /// Guesses the archive type based on the file type + pub fn guess(reader: &mut R) -> Result + where + R: Read + Seek, + { + let name = NullString::read(reader)?.to_string(); + reader.rewind()?; + match name.as_str() { + "MHJNR-XXL" | "MHJNR-XS" | "Moorhuhn Kart 2" => Ok(ArchiveKind::V1), + "MH-W V1.0" | "MH3 V1.0 " | "MH 1 REMAKE" => Ok(ArchiveKind::V2), + "MHP XXL" | "MHINV XXL V1.0" => Ok(ArchiveKind::V3), + name => Err(Error::Unsupported { + reason: name.to_string(), + }), + } + } +} + +impl Archive { + /// Reads the archive info from a binary stream + pub fn read(reader: &mut R) -> Result + where + R: Read + Seek, + { + match ArchiveKind::guess(reader)? { + ArchiveKind::V1 => Ok(standard::Container::read_args(reader, (0x30,))?.into()), + ArchiveKind::V2 => Ok(mhjnr::Container::read(reader)?.into()), + ArchiveKind::V3 => Ok(standard::Container::read_args(reader, (0x40,))?.into()), + } + } +} diff --git a/rust/springylib/src/archive/standard.rs b/rust/springylib/src/archive/standard.rs new file mode 100644 index 0000000..ca1775c --- /dev/null +++ b/rust/springylib/src/archive/standard.rs @@ -0,0 +1,52 @@ +use crate::archive::{Archive, FilePointer}; +use binrw::{binread, parser, until_exclusive, BinResult, NullString}; + +#[binread] +#[br(little, import(string_size: usize))] +#[derive(Debug)] +pub struct Container { + #[br(temp, args(string_size))] + pub header: FileEntry, + #[br(parse_with = until_end, args_raw(string_size))] + pub entries: Vec, +} + +#[parser(reader, endian)] +fn until_end(string_size: usize) -> BinResult> { + until_exclusive(|entry: &FileEntry| entry.name.to_string().as_str() == "****")( + reader, + endian, + (string_size,), + ) +} + +impl From for Archive { + fn from(value: Container) -> Self { + Archive( + value + .entries + .into_iter() + .map(|entry| (entry.name.to_string(), entry.into())) + .collect(), + ) + } +} + +#[binread] +#[br(little, import(string_size: usize))] +#[derive(Debug)] +pub struct FileEntry { + #[br(pad_size_to = string_size)] + pub name: NullString, + #[br(pad_size_to = 0x10)] + pub pointer: [u32; 2], +} + +impl From for FilePointer { + fn from(value: FileEntry) -> Self { + FilePointer { + position: value.pointer[0] as usize, + length: value.pointer[1] as usize, + } + } +} diff --git a/rust/springylib/src/lib.rs b/rust/springylib/src/lib.rs new file mode 100644 index 0000000..4193e3e --- /dev/null +++ b/rust/springylib/src/lib.rs @@ -0,0 +1 @@ +pub mod archive; diff --git a/rust/src/formats/datafile.rs b/rust/src/formats/datafile.rs deleted file mode 100644 index 5cc6514..0000000 --- a/rust/src/formats/datafile.rs +++ /dev/null @@ -1,46 +0,0 @@ -use binrw::{binread, NullString}; -use std::collections::HashMap; - -#[binread] -#[br(little, magic = b"MHJNR")] -#[derive(Debug)] -pub struct Datafile { - #[br(align_after = 0x20)] - pub edition: Edition, - - #[br(temp)] - pub count: u32, - #[br(align_after = 0x20)] - pub unk1: u32, - - #[br(count = count)] - pub files: Vec, -} - -#[binread] -#[derive(Debug)] -pub enum Edition { - #[br(magic = b"-XS")] - Xs, - #[br(magic = b"-XXL")] - Xxl, -} - -#[derive(Debug)] -#[binread] -pub struct FileEntry { - #[br(pad_size_to = 0x68)] - pub name: NullString, - pub pos: u32, - #[br(pad_after = 0x10)] - pub len: u32, -} - -impl Datafile { - pub fn into_index(self) -> HashMap { - self.files - .into_iter() - .map(|entry| (entry.name.to_string(), entry)) - .collect() - } -} diff --git a/rust/src/godot/charset.txt b/rust/src/godot/charset.txt new file mode 100644 index 0000000..1b4ad89 --- /dev/null +++ b/rust/src/godot/charset.txt @@ -0,0 +1 @@ +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,;.:!?+-*/=<>()[]{}\"$%&#~_^@|IGՌSޟigsע \ No newline at end of file diff --git a/rust/src/godot/font.rs b/rust/src/godot/font.rs index 1871f57..5a9d6af 100644 --- a/rust/src/godot/font.rs +++ b/rust/src/godot/font.rs @@ -1,14 +1,13 @@ +use encoding_rs::WINDOWS_1252; use godot::builtin::{Rect2, Vector2, Vector2i}; use godot::engine::{FontFile, Image}; use godot::prelude::utilities::prints; -use godot::prelude::{Color, Gd, Share, ToVariant}; +use godot::prelude::{Gd, Share, ToVariant}; -const CHARSET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜabcdefghijklmnopqrstuvwxyzäöüß0123456789,;.:!?\ - +-*/=<>()[]{}\"$%&#~_’^@|¡¿™©®º¹²³ªÀÁÂÃÅÆÇÈÉÊËÌÍÎÏIÐGÑÒÓÔÕŒØSŠÙÚÛÝÞŸŽàáâãåæçèéêëìíî\ - ïiðgñòóôõœøsšùúûýþÿž£¥ƒ¤¯¦¬¸¨·§×¢±÷µ«»"; +const CHARSET: &[u8] = include_bytes!("charset.txt"); pub fn load_bitmap_font(image: Gd) -> Gd { - let mut font_chars = CHARSET.as_bytes().iter(); + let mut font_chars = CHARSET.iter(); let mut font_file = FontFile::new(); @@ -27,11 +26,16 @@ pub fn load_bitmap_font(image: Gd) -> Gd { if !was_empty_column && is_empty_column { let char = font_chars.next().expect("Font has too many characters!"); - let glyph = *char as i64; - /*let mut glyph = 0i64; - for (i, c) in char.bytes().rev().enumerate() { - glyph |= (c as i64) << (i * 8); - }*/ + let mut glyph = 0i64; + for (i, c) in WINDOWS_1252 + .decode(&[*char]) + .0 + .as_bytes() + .iter() + .enumerate() + { + glyph |= (*c as i64) << (i * 8); + } let glyph_offset = Vector2 { x: char_x as f32,