diff --git a/.gitignore b/.gitignore index ea8c4bf..a851572 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +**/*.env \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 7af2f3a..0d3ac28 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,9 @@ { "rust-analyzer.check.command": "clippy", "editor.formatOnSave": true, - "rust-analyzer.cargo.features": "all" -} \ No newline at end of file + "rust-analyzer.cargo.features": "all", + "files.eol": "\n", + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true, + "files.trimTrailingWhitespace": true +} diff --git a/Cargo.lock b/Cargo.lock index f8df113..86a5b9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ dependencies = [ "atspi-common", "serde", "thiserror 1.0.69", - "zvariant 4.2.0", + "zvariant", ] [[package]] @@ -78,7 +78,7 @@ dependencies = [ "futures-lite", "futures-util", "serde", - "zbus 4.4.0", + "zbus", ] [[package]] @@ -212,25 +212,6 @@ dependencies = [ "libloading", ] -[[package]] -name = "ashpd" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" -dependencies = [ - "async-fs", - "async-net", - "enumflags2", - "futures-channel", - "futures-util", - "rand 0.9.1", - "raw-window-handle", - "serde", - "serde_repr", - "url", - "zbus 5.7.1", -] - [[package]] name = "assembler" version = "0.2.0" @@ -319,17 +300,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "async-net" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" -dependencies = [ - "async-io", - "blocking", - "futures-lite", -] - [[package]] name = "async-process" version = "2.3.1" @@ -421,11 +391,11 @@ dependencies = [ "enumflags2", "serde", "static_assertions", - "zbus 4.4.0", + "zbus", "zbus-lockstep", "zbus-lockstep-macros", - "zbus_names 3.0.0", - "zvariant 4.2.0", + "zbus_names", + "zvariant", ] [[package]] @@ -437,7 +407,7 @@ dependencies = [ "atspi-common", "atspi-proxies", "futures-lite", - "zbus 4.4.0", + "zbus", ] [[package]] @@ -448,8 +418,8 @@ checksum = "a5e6c5de3e524cf967569722446bcd458d5032348554d9a17d7d72b041ab7496" dependencies = [ "atspi-common", "serde", - "zbus 4.4.0", - "zvariant 4.2.0", + "zbus", + "zvariant", ] [[package]] @@ -512,15 +482,6 @@ dependencies = [ "objc2 0.5.2", ] -[[package]] -name = "block2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" -dependencies = [ - "objc2 0.6.1", -] - [[package]] name = "blocking" version = "1.6.1" @@ -848,18 +809,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" -[[package]] -name = "dispatch2" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0d569e003ff27784e0e14e4a594048698e0c0f0b66cabcb51511be55a7caa0" -dependencies = [ - "bitflags 2.9.1", - "block2 0.6.1", - "libc", - "objc2 0.6.1", -] - [[package]] name = "dispatch2" version = "0.3.0" @@ -921,6 +870,12 @@ dependencies = [ "serde", ] +[[package]] +name = "dyn-clone" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" + [[package]] name = "ecolor" version = "0.31.1" @@ -1023,6 +978,16 @@ dependencies = [ "winit", ] +[[package]] +name = "egui_file" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e7289fecaa1af3f4944a7ac6e1c187d0700e32716c2a4c76d6bad7ffd255d72" +dependencies = [ + "dyn-clone", + "egui", +] + [[package]] name = "egui_glow" version = "0.31.1" @@ -1061,9 +1026,10 @@ dependencies = [ "dsa_editor", "eframe", "egui", - "rfd", + "egui_file", "serde", "toml", + "winit", ] [[package]] @@ -1227,15 +1193,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", -] - [[package]] name = "futures-core" version = "0.3.31" @@ -1376,7 +1333,7 @@ dependencies = [ "bitflags 2.9.1", "cfg_aliases", "cgl", - "dispatch2 0.3.0", + "dispatch2", "glutin_egl_sys", "glutin_glx_sys", "glutin_wgl_sys", @@ -1914,19 +1871,6 @@ dependencies = [ "memoffset", ] -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "cfg_aliases", - "libc", - "memoffset", -] - [[package]] name = "nohash-hasher" version = "0.2.0" @@ -2025,7 +1969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.9.1", - "block2 0.5.1", + "block2", "libc", "objc2 0.5.2", "objc2-core-data", @@ -2041,7 +1985,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" dependencies = [ "bitflags 2.9.1", - "block2 0.6.1", "objc2 0.6.1", "objc2-core-foundation", "objc2-core-graphics", @@ -2055,7 +1998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.9.1", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", @@ -2067,7 +2010,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -2079,7 +2022,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.9.1", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -2091,7 +2034,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ "bitflags 2.9.1", - "dispatch2 0.3.0", + "dispatch2", "objc2 0.6.1", ] @@ -2102,7 +2045,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" dependencies = [ "bitflags 2.9.1", - "dispatch2 0.3.0", + "dispatch2", "objc2 0.6.1", "objc2-core-foundation", "objc2-io-surface", @@ -2114,7 +2057,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", "objc2-metal", @@ -2126,7 +2069,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-contacts", "objc2-foundation 0.2.2", @@ -2145,7 +2088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.9.1", - "block2 0.5.1", + "block2", "dispatch", "libc", "objc2 0.5.2", @@ -2179,7 +2122,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-app-kit 0.2.2", "objc2-foundation 0.2.2", @@ -2192,7 +2135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.9.1", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -2204,7 +2147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.9.1", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", "objc2-metal", @@ -2227,7 +2170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.9.1", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", @@ -2247,7 +2190,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -2259,7 +2202,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.9.1", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", @@ -2432,12 +2375,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "pollster" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" - [[package]] name = "potential_utf" version = "0.1.2" @@ -2528,7 +2465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bd9640e0addc098a3481fd53bdc23970e5dd0edf6b349403aa680fb576c8f83" dependencies = [ "cfg-if", - "nix 0.29.0", + "nix", "quork-proc", "thiserror 2.0.12", "windows-sys 0.59.0", @@ -2569,18 +2506,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_chacha", + "rand_core", ] [[package]] @@ -2590,17 +2517,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", + "rand_core", ] [[package]] @@ -2612,15 +2529,6 @@ dependencies = [ "getrandom 0.2.16", ] -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.3", -] - [[package]] name = "raw-window-handle" version = "0.6.2" @@ -2662,30 +2570,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" -[[package]] -name = "rfd" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c844748fdc82aae252ee4594a89b6e7ebef1063de7951545564cbc4e57075d" -dependencies = [ - "ashpd", - "block2 0.6.1", - "dispatch2 0.2.0", - "js-sys", - "log", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "pollster", - "raw-window-handle", - "urlencoding", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-sys 0.59.0", -] - [[package]] name = "rustc-hash" version = "1.1.0" @@ -3245,15 +3129,8 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] -[[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -4010,7 +3887,7 @@ dependencies = [ "android-activity", "atomic-waker", "bitflags 2.9.1", - "block2 0.5.1", + "block2", "bytemuck", "calloop", "cfg_aliases", @@ -4195,9 +4072,9 @@ dependencies = [ "futures-sink", "futures-util", "hex", - "nix 0.29.0", + "nix", "ordered-stream", - "rand 0.8.5", + "rand", "serde", "serde_repr", "sha1", @@ -4206,42 +4083,9 @@ dependencies = [ "uds_windows", "windows-sys 0.52.0", "xdg-home", - "zbus_macros 4.4.0", - "zbus_names 3.0.0", - "zvariant 4.2.0", -] - -[[package]] -name = "zbus" -version = "5.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a7c7cee313d044fca3f48fa782cb750c79e4ca76ba7bc7718cd4024cdf6f68" -dependencies = [ - "async-broadcast", - "async-executor", - "async-io", - "async-lock", - "async-process", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "enumflags2", - "event-listener", - "futures-core", - "futures-lite", - "hex", - "nix 0.30.1", - "ordered-stream", - "serde", - "serde_repr", - "tracing", - "uds_windows", - "windows-sys 0.59.0", - "winnow", - "zbus_macros 5.7.1", - "zbus_names 4.2.0", - "zvariant 5.5.3", + "zbus_macros", + "zbus_names", + "zvariant", ] [[package]] @@ -4251,7 +4095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ca2c5dceb099bddaade154055c926bb8ae507a18756ba1d8963fd7b51d8ed1d" dependencies = [ "zbus_xml", - "zvariant 4.2.0", + "zvariant", ] [[package]] @@ -4265,7 +4109,7 @@ dependencies = [ "syn", "zbus-lockstep", "zbus_xml", - "zvariant 4.2.0", + "zvariant", ] [[package]] @@ -4278,22 +4122,7 @@ dependencies = [ "proc-macro2", "quote", "syn", - "zvariant_utils 2.1.0", -] - -[[package]] -name = "zbus_macros" -version = "5.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e7e5eec1550f747e71a058df81a9a83813ba0f6a95f39c4e218bdc7ba366a" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", - "zbus_names 4.2.0", - "zvariant 5.5.3", - "zvariant_utils 3.2.0", + "zvariant_utils", ] [[package]] @@ -4304,19 +4133,7 @@ checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" dependencies = [ "serde", "static_assertions", - "zvariant 4.2.0", -] - -[[package]] -name = "zbus_names" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" -dependencies = [ - "serde", - "static_assertions", - "winnow", - "zvariant 5.5.3", + "zvariant", ] [[package]] @@ -4328,8 +4145,8 @@ dependencies = [ "quick-xml 0.30.0", "serde", "static_assertions", - "zbus_names 3.0.0", - "zvariant 4.2.0", + "zbus_names", + "zvariant", ] [[package]] @@ -4416,22 +4233,7 @@ dependencies = [ "enumflags2", "serde", "static_assertions", - "zvariant_derive 4.2.0", -] - -[[package]] -name = "zvariant" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d30786f75e393ee63a21de4f9074d4c038d52c5b1bb4471f955db249f9dffb1" -dependencies = [ - "endi", - "enumflags2", - "serde", - "url", - "winnow", - "zvariant_derive 5.5.3", - "zvariant_utils 3.2.0", + "zvariant_derive", ] [[package]] @@ -4444,20 +4246,7 @@ dependencies = [ "proc-macro2", "quote", "syn", - "zvariant_utils 2.1.0", -] - -[[package]] -name = "zvariant_derive" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75fda702cd42d735ccd48117b1630432219c0e9616bf6cb0f8350844ee4d9580" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", - "zvariant_utils 3.2.0", + "zvariant_utils", ] [[package]] @@ -4470,17 +4259,3 @@ dependencies = [ "quote", "syn", ] - -[[package]] -name = "zvariant_utils" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "static_assertions", - "syn", - "winnow", -] diff --git a/assembler/src/tooling/project.rs b/assembler/src/tooling/project.rs index 9195872..bdab388 100644 --- a/assembler/src/tooling/project.rs +++ b/assembler/src/tooling/project.rs @@ -20,7 +20,7 @@ pub fn tool_libcreate() { _ => panic!("Invalid project type"), }; - let path = format!("{}/{}.dsa", project_path, project_name); + let path = format!("{project_path}/{project_name}.dsa"); std::fs::write(path, template).expect("Unable to write file"); } diff --git a/assembler/src/util/mod.rs b/assembler/src/util/mod.rs index ea56139..01f628d 100644 --- a/assembler/src/util/mod.rs +++ b/assembler/src/util/mod.rs @@ -3,7 +3,7 @@ pub mod logging; use std::io::Write; pub fn input(prompt: &str) -> String { - print!("{}\n > ", prompt); + print!("{prompt}\n > "); std::io::stdout().flush().unwrap(); let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); diff --git a/emulator/Cargo.toml b/emulator/Cargo.toml index b72f082..fb37322 100644 --- a/emulator/Cargo.toml +++ b/emulator/Cargo.toml @@ -7,6 +7,7 @@ default-run = "emulator" [lib] name = "dsa_rs" path = "src/lib.rs" +crate-type = ["cdylib", "rlib"] [[bin]] name = "emulator" @@ -16,15 +17,24 @@ required-features = ["config"] common = { path = "../common" } assembler = { path = "../assembler" } dsa_editor = { path = "../dsa_editor" } -eframe = "0.31.1" +eframe = { version = "0.31.1" } egui = "0.31.1" -rfd = "0.15.3" dirs = "6.0.0" discord-presence = { version = "1.6.0", optional = true } toml = { version = "0.8.23", optional = true } serde = { version = "1.0.219", features = ["derive"], optional = true } +egui_file = "0.22.1" [features] default = ["config"] discord-rpc = ["dep:discord-presence"] config = ["dep:toml", "dep:serde"] + +# Add support for Android for the fun of it. +[target.'cfg(target_os = "android")'.dependencies] +winit = { version = "0.30.11", features = ["android-native-activity"] } +# jni = "0.21.1" + +[target.'cfg(target_os = "android")'.dependencies.eframe] +version = "0.31.1" +features = ["android-native-activity"] diff --git a/emulator/src/emulator/misc/mod.rs b/emulator/src/emulator/misc/mod.rs index 7689ddb..06a3fd0 100644 --- a/emulator/src/emulator/misc/mod.rs +++ b/emulator/src/emulator/misc/mod.rs @@ -1,2 +1 @@ -#[cfg(feature = "discord-rpc")] pub mod rpc; diff --git a/emulator/src/emulator/misc/rpc.rs b/emulator/src/emulator/misc/rpc.rs index c548874..3ef47e3 100644 --- a/emulator/src/emulator/misc/rpc.rs +++ b/emulator/src/emulator/misc/rpc.rs @@ -7,7 +7,7 @@ //! //! # Configuration //! -//! This may be disabled like so in your `.dsarc.toml` file: +//! This may be disabled like so in your `.dsa.emulator.toml` file: //! //! ```toml //! [misc] @@ -16,24 +16,23 @@ //! //! Alternatively, you can hide this in your Discord settings. -use std::{ - path::PathBuf, - sync::{ - Arc, - mpsc::{Receiver, Sender}, - }, - time::Duration, -}; +#[cfg(feature = "discord-rpc")] +use std::{path::PathBuf, sync::Arc, time::Duration}; +use std::sync::mpsc::{Receiver, Sender}; + +#[cfg(feature = "discord-rpc")] use discord_presence::{Client, DiscordError, models::ActivityTimestamps}; use crate::emulator::config::Config; #[derive(Debug)] +#[cfg(feature = "discord-rpc")] pub enum RpcClientError { Client(DiscordError), } +#[cfg(feature = "discord-rpc")] impl std::fmt::Display for RpcClientError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -42,8 +41,10 @@ impl std::fmt::Display for RpcClientError { } } +#[cfg(feature = "discord-rpc")] impl std::error::Error for RpcClientError {} +#[cfg(feature = "discord-rpc")] impl From for RpcClientError { fn from(err: DiscordError) -> Self { Self::Client(err) @@ -52,6 +53,7 @@ impl From for RpcClientError { /// The type of activity the user is currently doing. #[derive(Debug, Clone)] +#[cfg(feature = "discord-rpc")] pub enum Activity { Idle, EditingFile(PathBuf), @@ -59,6 +61,7 @@ pub enum Activity { /// Messages to send over the wire. #[derive(Debug)] +#[cfg(feature = "discord-rpc")] pub enum Message { /// Sent when we want to update the [`Context`]. Update(Activity), @@ -66,9 +69,11 @@ pub enum Message { Stop, } +#[cfg(feature = "discord-rpc")] unsafe impl Send for Message {} #[derive(Debug, Clone)] +#[cfg(feature = "discord-rpc")] pub struct RpcClient { /// Sends updates to [`Context`] (our state). sender: Sender, @@ -76,6 +81,7 @@ pub struct RpcClient { thread_handle: Option>>, } +#[cfg(feature = "discord-rpc")] impl RpcClient { #[expect(clippy::unreadable_literal)] /// Sets up the [`RpcClient`]. @@ -169,6 +175,7 @@ impl RpcClient { } // Possibly unneeded but good practice. +#[cfg(feature = "discord-rpc")] impl Drop for RpcClient { fn drop(&mut self) { self.stop(); @@ -181,14 +188,31 @@ impl Drop for RpcClient { } } +/// Stub for when the feature is disabled. +#[cfg(not(feature = "discord-rpc"))] +pub struct RpcClient {} + +/// Stub for when the feature is disabled. +#[cfg(not(feature = "discord-rpc"))] +pub enum Message {} + +/// Stub for when the feature is disabled. +#[cfg(not(feature = "discord-rpc"))] +pub enum Activity {} + /// Gets the discord [`RpcClient`] or returns None if this has been disabled in the config /// options. #[cfg(feature = "config")] +#[allow(clippy::needless_pass_by_value, unused_variables)] pub fn get_rpc_client_or_none( config: &Config, rpc_sender: Sender, rpc_reciever: Receiver, ) -> Result, Box> { + #[cfg(not(feature = "discord-rpc"))] + return Ok(None); + + #[cfg(feature = "discord-rpc")] if config.misc.use_discord_rpc { Ok(Some(RpcClient::new(rpc_sender, rpc_reciever)?)) } else { diff --git a/emulator/src/emulator/system/emulator.rs b/emulator/src/emulator/system/emulator.rs index 6619b8d..24daa34 100644 --- a/emulator/src/emulator/system/emulator.rs +++ b/emulator/src/emulator/system/emulator.rs @@ -1,4 +1,3 @@ -#[cfg(feature = "discord-rpc")] use std::sync::Arc; use std::{ sync::mpsc::{self, Receiver, Sender}, @@ -6,7 +5,7 @@ use std::{ time::Duration, }; -#[cfg(feature = "discord-rpc")] +#[allow(unused_imports)] use crate::emulator::misc::rpc::{Activity, RpcClient}; use crate::emulator::system::{ @@ -17,11 +16,12 @@ use crate::emulator::system::{ use common::prelude::*; #[expect(clippy::too_many_lines)] +#[allow(unused_variables)] pub fn run_emulator( cmd_rx: &Receiver, state_tx: &Sender, mut processor: Processor, - #[cfg(feature = "discord-rpc")] rpc_client: Option<&Arc>, + rpc_client: Option<&Arc>, ) { println!("INFO: Starting emulator."); diff --git a/emulator/src/emulator/ui/editor.rs b/emulator/src/emulator/ui/editor.rs index 6d55504..3a15aca 100644 --- a/emulator/src/emulator/ui/editor.rs +++ b/emulator/src/emulator/ui/editor.rs @@ -1,10 +1,14 @@ -use std::{ffi::OsStr, path::PathBuf, sync::mpsc::Sender}; +use std::{ + ffi::OsStr, + path::{Path, PathBuf}, + sync::mpsc::Sender, +}; use common::prelude::Instruction; use egui::{Align, Context, Key, Layout, Ui}; -use rfd::FileDialog; use dsa_editor::{CodeEditor, ColorTheme, Syntax}; +use egui_file::FileDialog; use crate::emulator::{ system::model::{Command, State}, @@ -29,6 +33,10 @@ pub struct Editor { cursor_col: usize, cursor_line: usize, + // file dialogs + open_file_dialog: Option, + save_file_dialog: Option, + // other visible: bool, sender: Sender, @@ -98,6 +106,8 @@ impl Editor { load_offset: 0, offset_str: String::new(), error: None, + open_file_dialog: None, + save_file_dialog: None, } } @@ -130,36 +140,31 @@ impl Editor { } fn save(&mut self) { - let work_dir = std::env::current_dir().unwrap_or_else(|_| { - dirs::home_dir().expect( - "Couldn't get your current working directory or your home directory.", - ) - }); - - if let Some(path) = &self.path { - if let Err(why) = std::fs::write(path, &self.text) { - self.error = Some(format!("Failed to save file: {why}")); - return; - } - - self.buffer = self.text.clone(); - self.unsaved = false; - return; + if self.open_file_dialog.is_some() { + // TODO: Flash an error stating you can only have one menu open at once. + self.open_file_dialog = None; } - if let Some(path) = FileDialog::new() - .add_filter("Assembly Files or Binaries", &["dsa", "dsb"]) - .add_filter("all", &["*"]) - .set_directory(&work_dir) - .save_file() - { - if let Err(why) = std::fs::write(&path, &self.text) { + if let Some(path) = &self.path { + // Save to existing path + if let Err(why) = std::fs::write(path, &self.text) { self.error = Some(format!("Failed to save file: {why}")); } else { - self.path = Some(path); - self.buffer = self.text.clone(); self.unsaved = false; } + } else { + // Open the save dialog. + let work_dir = std::env::current_dir().unwrap_or_else(|_| { + dirs::home_dir().expect( + "Couldn't get your current working directory or your home directory.", + ) + }); + + if self.save_file_dialog.is_none() { + let mut dialog = FileDialog::save_file(Some(work_dir)); + dialog.open(); + self.save_file_dialog = Some(dialog); + } } } @@ -170,46 +175,125 @@ impl Editor { ) }); - if let Some(path) = FileDialog::new() - .add_filter("Assembly Files or Binaries", &["dsa", "dsb"]) - .add_filter("all", &["*"]) - .set_directory(&work_dir) - .pick_file() - { - match path.extension().and_then(|ext| ext.to_str()) { - Some("dsb") => { - let contents = match std::fs::read(&path) { - Ok(contents) => contents, - Err(why) => { - self.error = Some(format!("Failed to read file: {why}")); - return; - } - }; + // if let Some(path) = FileDialog::new() + // .add_filter("Assembly Files or Binaries", &["dsa", "dsb"]) + // .add_filter("all", &["*"]) + // .set_directory(&work_dir) + // .pick_file() + // { + // match path.extension().and_then(|ext| ext.to_str()) { + // Some("dsb") => { + // let contents = match std::fs::read(&path) { + // Ok(contents) => contents, + // Err(why) => { + // self.error = Some(format!("Failed to read file: {why}")); + // return; + // } + // }; - self.path = Some(path.clone()); - self.output = contents; - self.unsaved = false; - self.text = String::from("Loaded Binary File!"); - self.buffer = self.text.clone(); - self.unsaved = false; - } - _ => { - if let Ok(contents) = std::fs::read_to_string(&path) { - self.path = Some(path.clone()); - self.text.clone_from(&contents); - self.buffer = contents; - self.unsaved = false; - } - } + // self.path = Some(path.clone()); + // self.output = contents; + // self.unsaved = false; + // self.text = String::from("Loaded Binary File!"); + // self.buffer = self.text.clone(); + // self.unsaved = false; + // } + // _ => { + // if let Ok(contents) = std::fs::read_to_string(&path) { + // self.path = Some(path.clone()); + // self.text.clone_from(&contents); + // self.buffer = contents; + // self.unsaved = false; + // } + // } + // } + if self.save_file_dialog.is_some() { + // TODO: Flash an error stating you can only have one menu open at once. + self.save_file_dialog = None; + } + + if self.open_file_dialog.is_none() { + if let Some(p) = &self.path { + let path = p.parent().map(Path::to_path_buf); + let mut dialog = FileDialog::open_file(path); + dialog.open(); + self.open_file_dialog = Some(dialog); + } else { + let mut dialog = FileDialog::open_file(Some(work_dir)); + dialog.open(); + self.open_file_dialog = Some(dialog); } - - std::env::set_current_dir( - path.parent().expect("A file should be in a directory!"), - ) - .expect("ERROR: Failed to set current working directory."); } } + fn handle_file_dialogs(&mut self, ctx: &egui::Context) { + // Handle open dialog + if let Some(dialog) = &mut self.open_file_dialog { + if dialog.show(ctx).selected() { + if let Some(file) = dialog.path() { + match std::fs::read_to_string(file) { + Ok(content) => { + self.text = content; + self.path = Some(file.to_path_buf()); + self.unsaved = false; + self.error = None; + } + Err(e) => { + self.error = Some(format!("Failed to read file: {e}")); + } + } + } + self.open_file_dialog = None; + } + } + + // Handle save dialog + if let Some(dialog) = &mut self.save_file_dialog { + if dialog.show(ctx).selected() { + if let Some(file) = dialog.path() { + match std::fs::write(file, &self.text) { + Ok(()) => { + self.path = Some(file.to_path_buf()); + self.unsaved = false; + self.error = None; + } + Err(e) => { + self.error = Some(format!("Failed to save file: {e}")); + } + } + } + self.save_file_dialog = None; + } + } + } + + // fn open(&mut self) { + // let work_dir = std::env::current_dir().unwrap_or_else(|_| { + // dirs::home_dir().expect( + // "Couldn't get your current working directory or your home directory.", + // ) + // }); + + // if let Some(path) = FileDialog::new() + // .add_filter("Assembly Files or Binaries", &["dsa", "dsb"]) + // .add_filter("all", &["*"]) + // .set_directory(&work_dir) + // .pick_file() + // { + // if let Ok(contents) = std::fs::read_to_string(&path) { + // self.path = Some(path.clone()); + // self.text.clone_from(&contents); + // self.buffer = contents; + // self.unsaved = false; + // } + + // std::env::set_current_dir( + // path.parent().expect("A file should be in a directory!"), + // ) + // .expect("ERROR: Failed to set current working directory."); + // } + // } + fn render_output(&self, _state: &mut State, ui: &mut Ui, _ctx: &Context) { // Output area with synchronized scrolling egui::ScrollArea::vertical() @@ -336,7 +420,9 @@ impl Editor { }); } - fn render_toolbar(&mut self, _state: &mut State, ui: &mut Ui, _ctx: &Context) { + fn render_toolbar(&mut self, _state: &mut State, ui: &mut Ui, ctx: &Context) { + self.handle_file_dialogs(ctx); + ui.horizontal(|ui| { ui.label(format!("File type: {}", self.extension())); ui.label(format!("Filename: {}", self.filename())); diff --git a/emulator/src/lib.rs b/emulator/src/lib.rs index 5374434..19558c4 100644 --- a/emulator/src/lib.rs +++ b/emulator/src/lib.rs @@ -13,3 +13,117 @@ )] pub mod emulator; + +use std::{ + sync::{ + Arc, + mpsc::{Receiver, Sender}, + }, + thread, +}; + +#[cfg(target_os = "android")] +use winit::platform::android::{EventLoopBuilderExtAndroid, activity::AndroidApp}; + +use crate::emulator::{ + misc::rpc::RpcClient, + system::{ + emulator::run_emulator, + memory::MainStore, + model::{Command, State}, + processor::Processor, + }, + ui::{ + control_unit::ControlPanel, display::Display, editor::Editor, + interface::EmulatorUI, memory_inspector::MemoryInspector, + stack_inspector::StackInspector, + }, +}; + +#[cfg(target_os = "android")] +#[unsafe(no_mangle)] +pub fn android_main(app: AndroidApp) -> Result<(), Box> { + use crate::emulator::{config::Config, misc::rpc::get_rpc_client_or_none}; + use std::path::Path; + + // Initialize channels and read in configuration. + let (cmd_sender, cmd_receiver) = std::sync::mpsc::channel(); + let (state_sender, state_reciever) = std::sync::mpsc::channel(); + let config = Config::load(Path::new(".dsa.emulator.toml"))?; + + // Setup RPC if enabled. + let (rpc_sender, rpc_reciever) = std::sync::mpsc::channel(); + + let rpc_client = + get_rpc_client_or_none(&config, rpc_sender, rpc_reciever)?.map(Arc::new); + + setup_emulator(cmd_receiver, state_sender, rpc_client); + + let ui = setup_ui(cmd_sender, state_reciever); + + // Run UI. + #[allow(unused_variables)] + let options = eframe::NativeOptions { + viewport: egui::ViewportBuilder::default().with_inner_size([800.0, 600.0]), + event_loop_builder: Some(Box::new(move |builder| { + #[cfg(target_os = "android")] + builder.with_android_app(app); + })), + ..Default::default() + }; + + eframe::run_native( + "DSA Simulator (Damn Simple Architecture 🔥)", + options, + Box::new(move |cc| { + cc.egui_ctx.set_visuals(egui::Visuals::default()); + Ok(Box::new(ui)) + }), + )?; + + Ok(()) +} + +pub fn setup_emulator( + cmd_receiver: Receiver, + state_sender: Sender, + rpc_client: Option>, +) { + let main_store = MainStore::new(); + let processor = Processor::new(Box::new(main_store), vec![]); + + thread::spawn(move || { + run_emulator(&cmd_receiver, &state_sender, processor, rpc_client.as_ref()); + }); +} + +/// Creates the [`EmulatorUI`]. +#[must_use] +pub fn setup_ui( + cmd_sender: Sender, + state_reciever: Receiver, +) -> EmulatorUI { + let mut ui = EmulatorUI::new(cmd_sender.clone(), state_reciever); + + // Create UI modules. + let control_unit = ControlPanel::new(cmd_sender.clone()); + + ui.add_component(Box::new(control_unit)); + + let mem_inspector = MemoryInspector::new(cmd_sender.clone()); + ui.add_component(Box::new(mem_inspector)); + + let stack_inspector = StackInspector::new(); + ui.add_component(Box::new(stack_inspector)); + + let editor = Editor::new(cmd_sender); + ui.add_component(Box::new(editor)); + + let display = Display::new(); + ui.add_component(Box::new(display)); + + let history = emulator::ui::history::History::new(); + ui.add_component(Box::new(history)); + + ui +} diff --git a/emulator/src/main.rs b/emulator/src/main.rs index fef27a5..b074df9 100644 --- a/emulator/src/main.rs +++ b/emulator/src/main.rs @@ -1,28 +1,7 @@ -#[cfg(feature = "discord-rpc")] +use std::path::Path; use std::sync::Arc; -use std::{ - path::Path, - sync::mpsc::{Receiver, Sender}, - thread, -}; -#[cfg(feature = "discord-rpc")] -use dsa_rs::emulator::misc::rpc::{RpcClient, get_rpc_client_or_none}; - -use dsa_rs::emulator::{ - config::Config, - system::{ - emulator::run_emulator, - memory::MainStore, - model::{Command, State}, - processor::Processor, - }, - ui::{ - control_unit::ControlPanel, display::Display, editor::Editor, - interface::EmulatorUI, memory_inspector::MemoryInspector, - stack_inspector::StackInspector, - }, -}; +use dsa_rs::emulator::{config::Config, misc::rpc::get_rpc_client_or_none}; fn main() -> Result<(), Box> { // Initialize channels and read in configuration. @@ -31,21 +10,17 @@ fn main() -> Result<(), Box> { let config = Config::load(Path::new(".dsa.emulator.toml"))?; // Setup RPC if enabled. - #[cfg(feature = "discord-rpc")] let (rpc_sender, rpc_reciever) = std::sync::mpsc::channel(); - #[cfg(feature = "discord-rpc")] let rpc_client = get_rpc_client_or_none(&config, rpc_sender, rpc_reciever)?.map(Arc::new); - #[cfg(feature = "discord-rpc")] - setup_emulator(cmd_receiver, state_sender, rpc_client); - #[cfg(not(feature = "discord-rpc"))] - setup_emulator(cmd_receiver, state_sender); + dsa_rs::setup_emulator(cmd_receiver, state_sender, rpc_client); - let ui = setup_ui(cmd_sender, state_reciever); + let ui = dsa_rs::setup_ui(cmd_sender, state_reciever); // Run UI. + #[allow(unused_variables)] let options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default().with_inner_size([800.0, 600.0]), ..Default::default() @@ -62,47 +37,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -fn setup_emulator( - cmd_receiver: Receiver, - state_sender: Sender, - #[cfg(feature = "discord-rpc")] rpc_client: Option>, -) { - let main_store = MainStore::new(); - let processor = Processor::new(Box::new(main_store), vec![]); - - thread::spawn(move || { - #[cfg(feature = "discord-rpc")] - run_emulator(&cmd_receiver, &state_sender, processor, rpc_client.as_ref()); - - #[cfg(not(feature = "discord-rpc"))] - run_emulator(&cmd_receiver, &state_sender, processor); - }); -} - -/// Creates the [`EmulatorUI`]. -fn setup_ui(cmd_sender: Sender, state_reciever: Receiver) -> EmulatorUI { - let mut ui = EmulatorUI::new(cmd_sender.clone(), state_reciever); - - // Create UI modules. - let control_unit = ControlPanel::new(cmd_sender.clone()); - - ui.add_component(Box::new(control_unit)); - - let mem_inspector = MemoryInspector::new(cmd_sender.clone()); - ui.add_component(Box::new(mem_inspector)); - - let stack_inspector = StackInspector::new(); - ui.add_component(Box::new(stack_inspector)); - - let editor = Editor::new(cmd_sender.clone()); - ui.add_component(Box::new(editor)); - - let display = Display::new(); - ui.add_component(Box::new(display)); - - let history = dsa_rs::emulator::ui::history::History::new(); - ui.add_component(Box::new(history)); - - ui -} diff --git a/resources/emulator/AndroidManifest.xml b/resources/emulator/AndroidManifest.xml new file mode 100644 index 0000000..21292bf --- /dev/null +++ b/resources/emulator/AndroidManifest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/resources/emulator/AppIcon.png b/resources/emulator/AppIcon.png new file mode 100644 index 0000000..4f58b16 Binary files /dev/null and b/resources/emulator/AppIcon.png differ diff --git a/resources/emulator/build_android.ps1 b/resources/emulator/build_android.ps1 new file mode 100644 index 0000000..1e11e65 --- /dev/null +++ b/resources/emulator/build_android.ps1 @@ -0,0 +1,74 @@ +#!/usr/bin/env pwsh + +$env:ANDROID_HOME = "C:\Users\jacob\AppData\Local\Android\Sdk" +$TOOL_PREFIX = "$env:ANDROID_HOME\build-tools\35.0.1" + +# Only really works on Windows, for aarch64. + +# Create directories +New-Item -ItemType Directory -Force -Path "..\target\apk_build\lib\arm64-v8a" +New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\values" +New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\mipmap-hdpi" +New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\mipmap-mdpi" +New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\mipmap-xhdpi" +New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\mipmap-xxhdpi" + +# Copy the shared library +Copy-Item "..\target\aarch64-linux-android\release\libdsa_rs.so" "..\target\apk_build\lib\arm64-v8a\" + +# Copy the manifest +Copy-Item "..\resources\emulator\AndroidManifest.xml" "..\target\apk_build\AndroidManifest.xml" + +# Copy the icons +Copy-Item "..\resources\emulator\AppIcon.png" "..\target\apk_build\res\mipmap-hdpi\ic_launcher.png" +Copy-Item "..\resources\emulator\AppIcon.png" "..\target\apk_build\res\mipmap-mdpi\ic_launcher.png" +Copy-Item "..\resources\emulator\AppIcon.png" "..\target\apk_build\res\mipmap-xhdpi\ic_launcher.png" +Copy-Item "..\resources\emulator\AppIcon.png" "..\target\apk_build\res\mipmap-xxhdpi\ic_launcher.png" + +# Create strings.xml +@" + + + DSA Emulator + +"@ | Out-File -FilePath "..\target\apk_build\res\values\strings.xml" -Encoding utf8 + +# Change to build directory +Push-Location "..\target\apk_build" + +try { + # Compile resources + & "$TOOL_PREFIX\aapt2.exe" compile --dir res -o compiled_resources.zip + + # Link resources + & "$TOOL_PREFIX\aapt2.exe" link -o unaligned.apk ` + -I "$env:ANDROID_HOME\platforms\android-35\android.jar" ` + --manifest AndroidManifest.xml ` + compiled_resources.zip + + # Add native libraries to APK + & "C:\Program Files\7-Zip\7z.exe" a -tzip unaligned.apk lib\* + + # Align APK + & "$TOOL_PREFIX\zipalign.exe" -v 4 unaligned.apk aligned.apk + + # Generate debug keystore if it doesn't exist + if (-not (Test-Path "debug.keystore")) { + & keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 -storepass android -keypass android -dname "CN=Android Debug,O=Android,C=US" + } + + # Sign APK + & "$TOOL_PREFIX\apksigner.bat" sign --ks debug.keystore --ks-key-alias androiddebugkey --ks-pass pass:android --key-pass pass:android --out dsa_emulator.apk aligned.apk + + # Copy final APK + Copy-Item "dsa_emulator.apk" "..\dsa_emulator.apk" + + Write-Host "APK created successfully at: ..\target\dsa_emulator.apk" -ForegroundColor Green +} +catch { + Write-Error "Build failed: $_" +} +finally { + # Return to original directory + Pop-Location +} diff --git a/resources/emulator/build_android.sh b/resources/emulator/build_android.sh new file mode 100644 index 0000000..fba7943 --- /dev/null +++ b/resources/emulator/build_android.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +export ANDROID_HOME="/mnt/c/Users/jacob/AppData/Local/Android/Sdk" +export TOOL_PREFIX="$ANDROID_HOME/build-tools/35.0.1" + +# Only really works on Linux, for aarch64. + +mkdir -p ../target/apk_build/lib/arm64-v8a +mkdir -p ../target/apk_build/res/values +mkdir -p ../target/apk_build/res/mipmap-hdpi +mkdir -p ../target/apk_build/res/mipmap-mdpi +mkdir -p ../target/apk_build/res/mipmap-xhdpi +mkdir -p ../target/apk_build/res/mipmap-xxhdpi + +# Copy the shared library. +cp ../target/aarch64-linux-android/release/libdsa_rs.so ../target/apk_build/lib/arm64-v8a/ + +# Copy the manifest. +cp AndroidManifest.xml ../target/apk_build/AndroidManifest.xml + +cat << EOF > ../target/apk_build/res/values/strings.xml + + + DSA Emulator + +EOF + +pushd ../target/apk_build + +$TOOL_PREFIX/aapt2 compile --dir res -o compiled_resources.zip +$TOOL_PREFIX/aapt2 link -o unaligned.apk \ + -I "$ANDROID_HOME/platforms/android-35/android.jar" \ + --manifest AndroidManifest.xml \ + compiled_resources.zip + +zip -r unaligned.apk lib/ + +$TOOL_PREFIX/zipalign -v 4 unaligned.apk aligned.apk + +keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 -storepass android -keypass android -dname "CN=Android Debug,O=Android,C=US" + +$TOOL_PREFIX/apksigner sign --ks debug.keystore --ks-key-alias androiddebugkey --ks-pass pass:android --key-pass pass:android --out dsa_emulator.apk aligned.apk + +cp dsa_emulator.apk ../dsa_emulator.apk + +popd