chore: remove extra platforms
Former-commit-id: 694fbd23b097e1ff1f72875fa27da2dd070d195d Former-commit-id: 64da130bc04b6e9a766f2491e6f7e7c4169f1e1b
424
Cargo.lock
generated
|
@ -2,21 +2,6 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "addr2line"
|
|
||||||
version = "0.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
|
|
||||||
dependencies = [
|
|
||||||
"gimli",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "adler"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler32"
|
name = "adler32"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -32,25 +17,6 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android_liblog-sys"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "aaf82c031178ca72b38595a54d16df8a257df9deea7d97a8992870e5c6a738e7"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android_log"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cc00e0d3a060cce3fa338f9644ce9a93901c79f5405330891aeca69c9957009a"
|
|
||||||
dependencies = [
|
|
||||||
"android_liblog-sys",
|
|
||||||
"log 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ansi_term"
|
name = "ansi_term"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
@ -81,7 +47,7 @@ dependencies = [
|
||||||
"enum-primitive-derive",
|
"enum-primitive-derive",
|
||||||
"gdbstub",
|
"gdbstub",
|
||||||
"gdbstub_arch",
|
"gdbstub_arch",
|
||||||
"log 0.4.11",
|
"log",
|
||||||
"num",
|
"num",
|
||||||
"num-traits 0.2.12",
|
"num-traits 0.2.12",
|
||||||
"rustboyadvance-utils",
|
"rustboyadvance-utils",
|
||||||
|
@ -128,20 +94,6 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "backtrace"
|
|
||||||
version = "0.3.51"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec1931848a574faa8f7c71a12ea00453ff5effbb5f51afe7f77d7a48cace6ac1"
|
|
||||||
dependencies = [
|
|
||||||
"addr2line",
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
"libc",
|
|
||||||
"miniz_oxide 0.4.2",
|
|
||||||
"object",
|
|
||||||
"rustc-demangle",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base-x"
|
name = "base-x"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
@ -265,12 +217,6 @@ version = "1.3.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bytes"
|
|
||||||
version = "0.5.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytesize"
|
name = "bytesize"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -292,12 +238,6 @@ version = "1.0.60"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c"
|
checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cesu8"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
|
@ -360,27 +300,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "combine"
|
|
||||||
version = "4.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2809f67365382d65fd2b6d9c22577231b954ed27400efeafbe687bda75abcc0b"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"memchr",
|
|
||||||
"pin-project-lite",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "console_error_panic_hook"
|
|
||||||
version = "0.1.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const_fn"
|
name = "const_fn"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -639,29 +558,6 @@ dependencies = [
|
||||||
"syn 0.11.11",
|
"syn 0.11.11",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "env_logger"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
|
||||||
dependencies = [
|
|
||||||
"atty",
|
|
||||||
"humantime",
|
|
||||||
"log 0.4.11",
|
|
||||||
"regex",
|
|
||||||
"termcolor",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "error-chain"
|
|
||||||
version = "0.12.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
|
|
||||||
dependencies = [
|
|
||||||
"backtrace",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fake-simd"
|
name = "fake-simd"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -677,7 +573,7 @@ dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"libc",
|
"libc",
|
||||||
"miniz_oxide 0.3.7",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -688,7 +584,7 @@ checksum = "515fb7f6541dafe542c87c12a7ab6a52190cccb6c348b5951ef62d9978189ae8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"glob",
|
"glob",
|
||||||
"log 0.4.11",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
|
@ -701,12 +597,6 @@ dependencies = [
|
||||||
"rustboyadvance-utils",
|
"rustboyadvance-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures"
|
|
||||||
version = "0.1.29"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fuzzy-matcher"
|
name = "fuzzy-matcher"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -724,7 +614,7 @@ checksum = "32c95766e0414f8bfc1d07055574c621b67739466d6ba516c4fef8e99d30d2e6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"log 0.4.11",
|
"log",
|
||||||
"managed",
|
"managed",
|
||||||
"num-traits 0.2.12",
|
"num-traits 0.2.12",
|
||||||
"paste",
|
"paste",
|
||||||
|
@ -760,12 +650,6 @@ dependencies = [
|
||||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gimli"
|
|
||||||
version = "0.22.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "glob"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -778,7 +662,7 @@ version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d20fd25aa456527ce4f544271ae4fea65d2eda4a6561ea56f39fb3ee4f7e3884"
|
checksum = "d20fd25aa456527ce4f544271ae4fea65d2eda4a6561ea56f39fb3ee4f7e3884"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log 0.4.11",
|
"log",
|
||||||
"plain",
|
"plain",
|
||||||
"scroll",
|
"scroll",
|
||||||
]
|
]
|
||||||
|
@ -836,27 +720,6 @@ dependencies = [
|
||||||
"itertools 0.4.19",
|
"itertools 0.4.19",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "humantime"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
|
||||||
dependencies = [
|
|
||||||
"quick-error",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "instant"
|
|
||||||
version = "0.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
"js-sys",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.4.19"
|
version = "0.4.19"
|
||||||
|
@ -884,26 +747,6 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jni"
|
|
||||||
version = "0.17.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "36bcc950632e48b86da402c5c077590583da5ac0d480103611d5374e7c967a3c"
|
|
||||||
dependencies = [
|
|
||||||
"cesu8",
|
|
||||||
"combine",
|
|
||||||
"error-chain",
|
|
||||||
"jni-sys",
|
|
||||||
"log 0.4.11",
|
|
||||||
"walkdir",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jni-sys"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.45"
|
version = "0.3.45"
|
||||||
|
@ -938,40 +781,12 @@ version = "0.2.132"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libretro-backend"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "git+https://github.com/michelhe/libretro-backend.git?branch=rustboyadvance#cb525222a9151d10fe61fba95369ea6325dbc318"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"libretro-sys",
|
|
||||||
"log 0.4.11",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libretro-sys"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "207b060b02cecbcee6df3d0f5ed38691d5c4df1379dd1acd5c49c9b25d20b439"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "log"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
|
||||||
dependencies = [
|
|
||||||
"log 0.4.11",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.11"
|
version = "0.4.11"
|
||||||
|
@ -1023,12 +838,6 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memory_units"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
|
@ -1038,16 +847,6 @@ dependencies = [
|
||||||
"adler32",
|
"adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "miniz_oxide"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9"
|
|
||||||
dependencies = [
|
|
||||||
"adler",
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
|
@ -1182,12 +981,6 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "object"
|
|
||||||
version = "0.20.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "odds"
|
name = "odds"
|
||||||
version = "0.2.26"
|
version = "0.2.26"
|
||||||
|
@ -1218,12 +1011,6 @@ version = "1.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-project-lite"
|
|
||||||
version = "0.1.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4fe74897791e156a0cd8cce0db31b9b2198e67877316bf3086c3acd187f719f0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "plain"
|
name = "plain"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -1249,7 +1036,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-error-attr",
|
"proc-macro-error-attr",
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.42",
|
"syn 1.0.42",
|
||||||
"version_check",
|
"version_check",
|
||||||
|
@ -1261,7 +1048,7 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
@ -1272,15 +1059,6 @@ version = "0.5.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
|
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "0.4.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-xid 0.1.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.23"
|
version = "1.0.23"
|
||||||
|
@ -1290,34 +1068,19 @@ dependencies = [
|
||||||
"unicode-xid 0.2.1",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quick-error"
|
|
||||||
version = "1.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "0.6.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.4.30",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1433,7 +1196,7 @@ dependencies = [
|
||||||
"hex-literal",
|
"hex-literal",
|
||||||
"hexdump",
|
"hexdump",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log 0.4.11",
|
"log",
|
||||||
"memmem",
|
"memmem",
|
||||||
"nom",
|
"nom",
|
||||||
"num",
|
"num",
|
||||||
|
@ -1449,32 +1212,6 @@ dependencies = [
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustboyadvance-jni"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"android_log",
|
|
||||||
"env_logger",
|
|
||||||
"jni",
|
|
||||||
"log 0.4.11",
|
|
||||||
"rustboyadvance-core",
|
|
||||||
"rustboyadvance-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustboyadvance-libretro"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"bit",
|
|
||||||
"libc",
|
|
||||||
"libretro-backend",
|
|
||||||
"libretro-sys",
|
|
||||||
"log 0.4.11",
|
|
||||||
"rustboyadvance-core",
|
|
||||||
"rustboyadvance-utils",
|
|
||||||
"unsafe_unwrap",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustboyadvance-sdl2"
|
name = "rustboyadvance-sdl2"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1482,7 +1219,7 @@ dependencies = [
|
||||||
"bit",
|
"bit",
|
||||||
"bytesize",
|
"bytesize",
|
||||||
"flexi_logger",
|
"flexi_logger",
|
||||||
"log 0.4.11",
|
"log",
|
||||||
"ringbuf",
|
"ringbuf",
|
||||||
"rustboyadvance-core",
|
"rustboyadvance-core",
|
||||||
"rustboyadvance-utils",
|
"rustboyadvance-utils",
|
||||||
|
@ -1497,34 +1234,10 @@ name = "rustboyadvance-utils"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"goblin",
|
"goblin",
|
||||||
"instant",
|
"log",
|
||||||
"log 0.4.11",
|
|
||||||
"ringbuf",
|
"ringbuf",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustboyadvance-wasm"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"bit",
|
|
||||||
"console_error_panic_hook",
|
|
||||||
"js-sys",
|
|
||||||
"log 0.4.11",
|
|
||||||
"rustboyadvance-core",
|
|
||||||
"rustboyadvance-utils",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-console-logger",
|
|
||||||
"wasm-bindgen-test",
|
|
||||||
"web-sys",
|
|
||||||
"wee_alloc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc-demangle"
|
|
||||||
version = "0.1.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -1543,7 +1256,7 @@ dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
"libc",
|
"libc",
|
||||||
"log 0.4.11",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
"nix",
|
"nix",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
|
@ -1568,12 +1281,6 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scoped-tls"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -1595,7 +1302,7 @@ version = "0.10.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e367622f934864ffa1c704ba2b82280aab856e3d8213c84c5720257eb34b15b9"
|
checksum = "e367622f934864ffa1c704ba2b82280aab856e3d8213c84c5720257eb34b15b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.42",
|
"syn 1.0.42",
|
||||||
]
|
]
|
||||||
|
@ -1662,7 +1369,7 @@ version = "1.0.116"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
|
checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.42",
|
"syn 1.0.42",
|
||||||
]
|
]
|
||||||
|
@ -1704,7 +1411,7 @@ checksum = "48047e77b528151aaf841a10a9025f9459da80ba820e425ff7eb005708a76dc7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"colored 2.0.0",
|
"colored 2.0.0",
|
||||||
"log 0.4.11",
|
"log",
|
||||||
"time 0.3.14",
|
"time 0.3.14",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
@ -1715,7 +1422,7 @@ version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
|
checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.42",
|
"syn 1.0.42",
|
||||||
]
|
]
|
||||||
|
@ -1765,7 +1472,7 @@ version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
|
checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
@ -1779,7 +1486,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
|
checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base-x",
|
"base-x",
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
@ -1819,7 +1526,7 @@ checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.42",
|
"syn 1.0.42",
|
||||||
]
|
]
|
||||||
|
@ -1841,7 +1548,7 @@ version = "1.0.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228"
|
checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"unicode-xid 0.2.1",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
|
@ -1855,15 +1562,6 @@ dependencies = [
|
||||||
"unicode-xid 0.0.4",
|
"unicode-xid 0.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "termcolor"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
@ -1888,7 +1586,7 @@ version = "1.0.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.42",
|
"syn 1.0.42",
|
||||||
]
|
]
|
||||||
|
@ -1963,7 +1661,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa"
|
checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"standback",
|
"standback",
|
||||||
"syn 1.0.42",
|
"syn 1.0.42",
|
||||||
|
@ -2012,24 +1710,12 @@ version = "0.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unsafe_unwrap"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1230ec65f13e0f9b28d789da20d2d419511893ea9dac2c1f4ef67b8b14e5da80"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -2089,36 +1775,13 @@ checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log 0.4.11",
|
"log",
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.42",
|
"syn 1.0.42",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-console-logger"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7530a275e7faf7b5b83aabdf78244fb8d9a68a2ec4b26935a05ecc0c9b0185ed"
|
|
||||||
dependencies = [
|
|
||||||
"log 0.4.11",
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-futures"
|
|
||||||
version = "0.3.27"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
"futures",
|
|
||||||
"js-sys",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.68"
|
version = "0.2.68"
|
||||||
|
@ -2135,7 +1798,7 @@ version = "0.2.68"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
|
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.23",
|
"proc-macro2",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn 1.0.42",
|
"syn 1.0.42",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
|
@ -2148,31 +1811,6 @@ version = "0.2.68"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
|
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-test"
|
|
||||||
version = "0.2.50"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a2d9693b63a742d481c7f80587e057920e568317b2806988c59cd71618bc26c1"
|
|
||||||
dependencies = [
|
|
||||||
"console_error_panic_hook",
|
|
||||||
"futures",
|
|
||||||
"js-sys",
|
|
||||||
"scoped-tls",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-futures",
|
|
||||||
"wasm-bindgen-test-macro",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-test-macro"
|
|
||||||
version = "0.2.50"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0789dac148a8840bbcf9efe13905463b733fa96543bfbf263790535c11af7ba5"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.4.30",
|
|
||||||
"quote 0.6.13",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.45"
|
version = "0.3.45"
|
||||||
|
@ -2183,18 +1821,6 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wee_alloc"
|
|
||||||
version = "0.4.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
"libc",
|
|
||||||
"memory_units",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
|
@ -4,9 +4,6 @@ members = [
|
||||||
"arm7tdmi",
|
"arm7tdmi",
|
||||||
"utils",
|
"utils",
|
||||||
"platform/rustboyadvance-sdl2",
|
"platform/rustboyadvance-sdl2",
|
||||||
"platform/rustboyadvance-libretro",
|
|
||||||
"platform/rustboyadvance-wasm",
|
|
||||||
"platform/rustboyadvance-jni",
|
|
||||||
"fps_bench"
|
"fps_bench"
|
||||||
]
|
]
|
||||||
resolver = "1"
|
resolver = "1"
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
use log::info;
|
|
||||||
use simple_logger::SimpleLogger;
|
|
||||||
|
|
||||||
use gdbstub::common::Signal;
|
|
||||||
use gdbstub::conn::{Connection, ConnectionExt};
|
|
||||||
use gdbstub::stub::{run_blocking, GdbStub, SingleThreadStopReason};
|
|
||||||
use gdbstub::target::Target;
|
|
||||||
|
|
||||||
use arm7tdmi::gdb::wait_for_connection;
|
|
||||||
use arm7tdmi::{Arm7tdmiCore, SimpleMemory};
|
|
||||||
|
|
||||||
use rustboyadvance_utils::Shared;
|
|
||||||
|
|
||||||
struct SimpleEmulator {
|
|
||||||
cpu: Arm7tdmiCore<SimpleMemory>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SimpleEmulator {
|
|
||||||
fn new(program: &[u8]) -> SimpleEmulator {
|
|
||||||
let mut memory = SimpleMemory::new(0x4000);
|
|
||||||
memory.load_program(program);
|
|
||||||
|
|
||||||
let bus = Shared::new(memory);
|
|
||||||
let mut cpu = Arm7tdmiCore::new(bus);
|
|
||||||
cpu.reset();
|
|
||||||
|
|
||||||
SimpleEmulator { cpu }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl run_blocking::BlockingEventLoop for SimpleEmulator {
|
|
||||||
type Target = Arm7tdmiCore<SimpleMemory>;
|
|
||||||
type Connection = Box<dyn ConnectionExt<Error = std::io::Error>>;
|
|
||||||
type StopReason = SingleThreadStopReason<u32>;
|
|
||||||
|
|
||||||
fn wait_for_stop_reason(
|
|
||||||
target: &mut Self::Target,
|
|
||||||
conn: &mut Self::Connection,
|
|
||||||
) -> Result<
|
|
||||||
run_blocking::Event<SingleThreadStopReason<u32>>,
|
|
||||||
run_blocking::WaitForStopReasonError<
|
|
||||||
<Self::Target as Target>::Error,
|
|
||||||
<Self::Connection as Connection>::Error,
|
|
||||||
>,
|
|
||||||
> {
|
|
||||||
let mut steps = 0;
|
|
||||||
loop {
|
|
||||||
if conn.peek().map(|b| b.is_some()).unwrap_or(true) {
|
|
||||||
let byte = conn
|
|
||||||
.read()
|
|
||||||
.map_err(run_blocking::WaitForStopReasonError::Connection)?;
|
|
||||||
return Ok(run_blocking::Event::IncomingData(byte));
|
|
||||||
} else {
|
|
||||||
target.step();
|
|
||||||
if target.check_breakpoint().is_some() {
|
|
||||||
return Ok(run_blocking::Event::TargetStopped(
|
|
||||||
SingleThreadStopReason::SwBreak(()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
steps += 1;
|
|
||||||
if steps % 1024 == 0 {
|
|
||||||
return Ok(run_blocking::Event::TargetStopped(
|
|
||||||
SingleThreadStopReason::SwBreak(()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_interrupt(
|
|
||||||
_target: &mut Arm7tdmiCore<SimpleMemory>,
|
|
||||||
) -> Result<Option<SingleThreadStopReason<u32>>, <Arm7tdmiCore<SimpleMemory> as Target>::Error>
|
|
||||||
{
|
|
||||||
// Because this emulator runs as part of the GDB stub loop, there isn't any
|
|
||||||
// special action that needs to be taken to interrupt the underlying target. It
|
|
||||||
// is implicitly paused whenever the stub isn't within the
|
|
||||||
// `wait_for_stop_reason` callback.
|
|
||||||
Ok(Some(SingleThreadStopReason::Signal(Signal::SIGINT)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
SimpleLogger::new().env().init().unwrap();
|
|
||||||
|
|
||||||
let mut emulator = SimpleEmulator::new(include_bytes!("test_program/test.bin"));
|
|
||||||
|
|
||||||
let conn: Box<dyn ConnectionExt<Error = std::io::Error>> = Box::new(wait_for_connection(1337)?);
|
|
||||||
let gdb = GdbStub::new(conn);
|
|
||||||
let result = gdb.run_blocking::<SimpleEmulator>(&mut emulator.cpu);
|
|
||||||
|
|
||||||
info!("emulator stopped, gdb result {:?}", result);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
use arm7tdmi::memory::DebugRead;
|
|
||||||
use rustboyadvance_utils::elf::read_symbols;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_breakpoint() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let mut emulator = SimpleEmulator::new(include_bytes!("test_program/test.bin"));
|
|
||||||
let symbol_map = read_symbols(include_bytes!("test_program/test.elf"))?;
|
|
||||||
let breakpoint_addr = *symbol_map.get("breakpoint_on_me").unwrap();
|
|
||||||
println!("breakpoint_addr = {:08x}", breakpoint_addr);
|
|
||||||
let breakpoint_counter_addr = *symbol_map.get("breakpoint_count").unwrap();
|
|
||||||
emulator.cpu.breakpoints.push(breakpoint_addr);
|
|
||||||
|
|
||||||
for x in 0..10 {
|
|
||||||
println!("{}", x);
|
|
||||||
let timeout = std::time::Instant::now() + std::time::Duration::from_secs(1);
|
|
||||||
loop {
|
|
||||||
emulator.cpu.step();
|
|
||||||
if let Some(addr) = emulator.cpu.check_breakpoint() {
|
|
||||||
emulator.cpu.step();
|
|
||||||
assert_eq!(addr, breakpoint_addr);
|
|
||||||
assert_eq!(emulator.cpu.bus.debug_read_32(breakpoint_counter_addr), x);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert!(std::time::Instant::now() < timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
2
arm7tdmi/examples/test_program/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
/*.o
|
|
||||||
/*.gdb_history
|
|
|
@ -1,37 +0,0 @@
|
||||||
# Easiest to build this using `docker run -it --rm -v $(pwd):/code -w /code devkitpro/devkitarm:latest make
|
|
||||||
TOOLCHAIN := ${DEVKITARM}/bin/arm-none-eabi
|
|
||||||
CC := ${TOOLCHAIN}-gcc
|
|
||||||
OBJCOPY := ${TOOLCHAIN}-objcopy
|
|
||||||
OBJDUMP := ${TOOLCHAIN}-objdump
|
|
||||||
|
|
||||||
TARGET := test
|
|
||||||
|
|
||||||
CFLAGS := -O0 -g -std=c11 -march=armv4t -mthumb
|
|
||||||
LDFLAGS := -Wl,-static
|
|
||||||
|
|
||||||
|
|
||||||
SOURCES := $(wildcard *.[cs])
|
|
||||||
OBJECTS := $(filter %.o,$(SOURCES:%.c=%.o))
|
|
||||||
OBJECTS += $(filter %.o,$(SOURCES:%.s=%.o))
|
|
||||||
|
|
||||||
all: ${TARGET}.bin objdump
|
|
||||||
|
|
||||||
${OBJECTS}: ${SOURCES}
|
|
||||||
${CC} -c ${CFLAGS} $^
|
|
||||||
|
|
||||||
${TARGET}.elf ${TARGET}.map: ${OBJECTS} ${TARGET}.ld
|
|
||||||
${CC} ${LDFLAGS} -Wl,-Map=${TARGET}.map -Wl,-T${TARGET}.ld ${OBJECTS} -o $@
|
|
||||||
|
|
||||||
${TARGET}.bin: ${TARGET}.elf
|
|
||||||
$(OBJCOPY) -v -O binary $^ $@
|
|
||||||
|
|
||||||
objdump: ${TARGET}.elf
|
|
||||||
${OBJDUMP} -d $^
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f ${TARGET}.elf
|
|
||||||
rm -f ${TARGET}.bin
|
|
||||||
rm -f ${TARGET}.map
|
|
||||||
rm -f *.o
|
|
||||||
|
|
||||||
.PHONY: all clean
|
|
|
@ -1,40 +0,0 @@
|
||||||
.section ".init"
|
|
||||||
|
|
||||||
.global _interrupt_vector
|
|
||||||
.align 4
|
|
||||||
.arm
|
|
||||||
|
|
||||||
.section ".init.vector"
|
|
||||||
_interrupt_vector:
|
|
||||||
b _reset
|
|
||||||
b _not_implemented
|
|
||||||
b _not_implemented
|
|
||||||
b _not_implemented
|
|
||||||
b _not_implemented
|
|
||||||
b _not_implemented
|
|
||||||
b _not_implemented
|
|
||||||
b _not_implemented
|
|
||||||
|
|
||||||
.section ".init.text"
|
|
||||||
.global _reset
|
|
||||||
_reset:
|
|
||||||
mrs r1, cpsr @ save the mode bits from CPSR
|
|
||||||
bic r0, r1, #0x1F
|
|
||||||
orr r0, r0, #0x13 @ supervisor
|
|
||||||
ldr sp, =_stack_top
|
|
||||||
mov r0, #0
|
|
||||||
mov r1, #0
|
|
||||||
mov r2, #0
|
|
||||||
mov r3, #0
|
|
||||||
mov r4, #0
|
|
||||||
mov r5, #0
|
|
||||||
mov r6, #0
|
|
||||||
mov r7, #0
|
|
||||||
mov r9, #0
|
|
||||||
mov r10, #0
|
|
||||||
mov r11, #0
|
|
||||||
mov r12, #0
|
|
||||||
b main
|
|
||||||
|
|
||||||
_not_implemented:
|
|
||||||
b _not_implemented
|
|
|
@ -1,17 +0,0 @@
|
||||||
volatile int breakpoint_count = 0;
|
|
||||||
volatile int breakpoint_on_me() {
|
|
||||||
breakpoint_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x = 1337;
|
|
||||||
for (;;) {
|
|
||||||
x += 1;
|
|
||||||
if (x == 7331) {
|
|
||||||
breakpoint_on_me();
|
|
||||||
x = 1337;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
ENTRY(_reset)
|
|
||||||
|
|
||||||
MEMORY {
|
|
||||||
RAM : ORIGIN = 0x00000000, LENGTH = 16K
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTIONS {
|
|
||||||
. = ORIGIN(RAM);
|
|
||||||
|
|
||||||
.init : {
|
|
||||||
*(.init.vector);
|
|
||||||
*(.init*);
|
|
||||||
} > RAM
|
|
||||||
|
|
||||||
.text : ALIGN(4) {
|
|
||||||
*(.text)
|
|
||||||
*(.text.*)
|
|
||||||
} > RAM
|
|
||||||
.data : ALIGN(4) {
|
|
||||||
*(.rodata*);
|
|
||||||
*(.data*);
|
|
||||||
} > RAM
|
|
||||||
.bss : ALIGN(4) {
|
|
||||||
*(.bss*)
|
|
||||||
} > RAM
|
|
||||||
|
|
||||||
.stack : AT (0x00003000) {
|
|
||||||
_stack_bottom = .;
|
|
||||||
. += 0xfe0;
|
|
||||||
_stack_top = .;
|
|
||||||
} > RAM
|
|
||||||
}
|
|
|
@ -1,162 +0,0 @@
|
||||||
|
|
||||||
Memory Configuration
|
|
||||||
|
|
||||||
Name Origin Length Attributes
|
|
||||||
RAM 0x0000000000000000 0x0000000000004000
|
|
||||||
*default* 0x0000000000000000 0xffffffffffffffff
|
|
||||||
|
|
||||||
Linker script and memory map
|
|
||||||
|
|
||||||
LOAD /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crti.o
|
|
||||||
LOAD /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
0x0000000000000000 . = ORIGIN (RAM)
|
|
||||||
|
|
||||||
.init 0x0000000000000000 0x88
|
|
||||||
*(.init.vector)
|
|
||||||
.init.vector 0x0000000000000000 0x20 reset.o
|
|
||||||
0x0000000000000000 _interrupt_vector
|
|
||||||
*(.init*)
|
|
||||||
.init 0x0000000000000020 0xc /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crti.o
|
|
||||||
0x0000000000000020 _init
|
|
||||||
.init_array 0x000000000000002c 0x4 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
.init 0x0000000000000030 0x0 reset.o
|
|
||||||
.init.text 0x0000000000000030 0x4c reset.o
|
|
||||||
0x0000000000000030 _reset
|
|
||||||
.init 0x000000000000007c 0xc /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtn.o
|
|
||||||
|
|
||||||
.text 0x0000000000000088 0xbc
|
|
||||||
*(.text)
|
|
||||||
.text 0x0000000000000088 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crti.o
|
|
||||||
.text 0x0000000000000088 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
.text 0x0000000000000088 0x4c test.o
|
|
||||||
0x0000000000000088 breakpoint_on_me
|
|
||||||
0x00000000000000a8 main
|
|
||||||
.text 0x00000000000000d4 0x0 reset.o
|
|
||||||
.text 0x00000000000000d4 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtend.o
|
|
||||||
.text 0x00000000000000d4 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtn.o
|
|
||||||
*(.text.*)
|
|
||||||
.text.__do_global_dtors_aux
|
|
||||||
0x00000000000000d4 0x40 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
.text.frame_dummy
|
|
||||||
0x0000000000000114 0x30 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
|
|
||||||
.glue_7 0x0000000000000144 0x0
|
|
||||||
.glue_7 0x0000000000000144 0x0 linker stubs
|
|
||||||
|
|
||||||
.glue_7t 0x0000000000000144 0x0
|
|
||||||
.glue_7t 0x0000000000000144 0x0 linker stubs
|
|
||||||
|
|
||||||
.vfp11_veneer 0x0000000000000144 0x0
|
|
||||||
.vfp11_veneer 0x0000000000000144 0x0 linker stubs
|
|
||||||
|
|
||||||
.v4_bx 0x0000000000000144 0x0
|
|
||||||
.v4_bx 0x0000000000000144 0x0 linker stubs
|
|
||||||
|
|
||||||
.fini 0x0000000000000144 0x18
|
|
||||||
.fini 0x0000000000000144 0xc /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crti.o
|
|
||||||
0x0000000000000144 _fini
|
|
||||||
.fini 0x0000000000000150 0xc /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtn.o
|
|
||||||
|
|
||||||
.iplt 0x000000000000015c 0x0
|
|
||||||
.iplt 0x000000000000015c 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
|
|
||||||
.eh_frame 0x000000000000015c 0x4
|
|
||||||
.eh_frame 0x000000000000015c 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
.eh_frame 0x000000000000015c 0x4 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtend.o
|
|
||||||
|
|
||||||
.rel.dyn 0x0000000000000160 0x0
|
|
||||||
.rel.iplt 0x0000000000000160 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
|
|
||||||
.data 0x0000000000000160 0x4c
|
|
||||||
*(.rodata*)
|
|
||||||
.rodata.all_implied_fbits
|
|
||||||
0x0000000000000160 0x24 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
.rodata.all_implied_fbits
|
|
||||||
0x0000000000000184 0x24 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtend.o
|
|
||||||
*(.data*)
|
|
||||||
.data 0x00000000000001a8 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crti.o
|
|
||||||
.data 0x00000000000001a8 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
.data.__dso_handle
|
|
||||||
0x00000000000001a8 0x4 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
0x00000000000001a8 __dso_handle
|
|
||||||
.data 0x00000000000001ac 0x0 test.o
|
|
||||||
.data 0x00000000000001ac 0x0 reset.o
|
|
||||||
.data 0x00000000000001ac 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtend.o
|
|
||||||
.data 0x00000000000001ac 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtn.o
|
|
||||||
|
|
||||||
.fini_array 0x00000000000001ac 0x4
|
|
||||||
.fini_array 0x00000000000001ac 0x4 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
|
|
||||||
.igot.plt 0x00000000000001b0 0x0
|
|
||||||
.igot.plt 0x00000000000001b0 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
|
|
||||||
.bss 0x00000000000001b0 0x20
|
|
||||||
*(.bss*)
|
|
||||||
.bss 0x00000000000001b0 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crti.o
|
|
||||||
.bss 0x00000000000001b0 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
.bss.completed.1
|
|
||||||
0x00000000000001b0 0x1 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
*fill* 0x00000000000001b1 0x3
|
|
||||||
.bss.object.0 0x00000000000001b4 0x18 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
.bss 0x00000000000001cc 0x4 test.o
|
|
||||||
0x00000000000001cc breakpoint_count
|
|
||||||
.bss 0x00000000000001d0 0x0 reset.o
|
|
||||||
.bss 0x00000000000001d0 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtend.o
|
|
||||||
.bss 0x00000000000001d0 0x0 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtn.o
|
|
||||||
|
|
||||||
.stack 0x00000000000001d0 0xfe0 load address 0x0000000000003000
|
|
||||||
0x00000000000001d0 _stack_bottom = .
|
|
||||||
0x00000000000011b0 . = (. + 0xfe0)
|
|
||||||
*fill* 0x00000000000001d0 0xfe0
|
|
||||||
0x00000000000011b0 _stack_top = .
|
|
||||||
LOAD test.o
|
|
||||||
LOAD reset.o
|
|
||||||
START GROUP
|
|
||||||
LOAD /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/libgcc.a
|
|
||||||
LOAD /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/../../../../arm-none-eabi/lib/libc.a
|
|
||||||
LOAD /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/../../../../arm-none-eabi/lib/libsysbase.a
|
|
||||||
END GROUP
|
|
||||||
LOAD /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtend.o
|
|
||||||
LOAD /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtn.o
|
|
||||||
OUTPUT(test.elf elf32-littlearm)
|
|
||||||
LOAD linker stubs
|
|
||||||
|
|
||||||
.ARM.attributes
|
|
||||||
0x0000000000000000 0x26
|
|
||||||
.ARM.attributes
|
|
||||||
0x0000000000000000 0x1c /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crti.o
|
|
||||||
.ARM.attributes
|
|
||||||
0x000000000000001c 0x2a /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
.ARM.attributes
|
|
||||||
0x0000000000000046 0x2a test.o
|
|
||||||
.ARM.attributes
|
|
||||||
0x0000000000000070 0x1a reset.o
|
|
||||||
.ARM.attributes
|
|
||||||
0x000000000000008a 0x2a /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtend.o
|
|
||||||
.ARM.attributes
|
|
||||||
0x00000000000000b4 0x1c /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtn.o
|
|
||||||
|
|
||||||
.comment 0x0000000000000000 0x23
|
|
||||||
.comment 0x0000000000000000 0x23 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtbegin.o
|
|
||||||
0x24 (size before relaxing)
|
|
||||||
.comment 0x0000000000000023 0x24 test.o
|
|
||||||
.comment 0x0000000000000023 0x24 /opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/crtend.o
|
|
||||||
|
|
||||||
.debug_info 0x0000000000000000 0x7e
|
|
||||||
.debug_info 0x0000000000000000 0x7e test.o
|
|
||||||
|
|
||||||
.debug_abbrev 0x0000000000000000 0x77
|
|
||||||
.debug_abbrev 0x0000000000000000 0x77 test.o
|
|
||||||
|
|
||||||
.debug_aranges 0x0000000000000000 0x20
|
|
||||||
.debug_aranges
|
|
||||||
0x0000000000000000 0x20 test.o
|
|
||||||
|
|
||||||
.debug_line 0x0000000000000000 0x51
|
|
||||||
.debug_line 0x0000000000000000 0x51 test.o
|
|
||||||
|
|
||||||
.debug_str 0x0000000000000000 0x69
|
|
||||||
.debug_str 0x0000000000000000 0x69 test.o
|
|
||||||
|
|
||||||
.debug_frame 0x0000000000000000 0x4c
|
|
||||||
.debug_frame 0x0000000000000000 0x4c test.o
|
|
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 152 KiB |
14
platform/android/.gitignore
vendored
|
@ -1,14 +0,0 @@
|
||||||
*.iml
|
|
||||||
.gradle
|
|
||||||
/local.properties
|
|
||||||
/.idea/caches
|
|
||||||
/.idea/libraries
|
|
||||||
/.idea/modules.xml
|
|
||||||
/.idea/workspace.xml
|
|
||||||
/.idea/navEditor.xml
|
|
||||||
/.idea/assetWizardSettings.xml
|
|
||||||
.DS_Store
|
|
||||||
/build
|
|
||||||
/captures
|
|
||||||
.externalNativeBuild
|
|
||||||
.cxx
|
|
|
@ -1 +0,0 @@
|
||||||
RustdroidAdvance
|
|
|
@ -1,116 +0,0 @@
|
||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<code_scheme name="Project" version="173">
|
|
||||||
<codeStyleSettings language="XML">
|
|
||||||
<indentOptions>
|
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
|
||||||
</indentOptions>
|
|
||||||
<arrangement>
|
|
||||||
<rules>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>xmlns:android</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>xmlns:.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>BY_NAME</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*:id</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*:name</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>name</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>style</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>BY_NAME</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>BY_NAME</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
</rules>
|
|
||||||
</arrangement>
|
|
||||||
</codeStyleSettings>
|
|
||||||
</code_scheme>
|
|
||||||
</component>
|
|
|
@ -1,20 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
|
||||||
<component name="GradleSettings">
|
|
||||||
<option name="linkedExternalProjectsSettings">
|
|
||||||
<GradleProjectSettings>
|
|
||||||
<option name="testRunner" value="PLATFORM" />
|
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="modules">
|
|
||||||
<set>
|
|
||||||
<option value="$PROJECT_DIR$" />
|
|
||||||
<option value="$PROJECT_DIR$/app" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
|
||||||
</GradleProjectSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectType">
|
|
||||||
<option name="id" value="Android" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,12 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RunConfigurationProducerService">
|
|
||||||
<option name="ignoredProducers">
|
|
||||||
<set>
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
|
||||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,3 +0,0 @@
|
||||||
# RustdroidAdvance
|
|
||||||
|
|
||||||
RustdroidAdvance is an android frontend for my rustboyadvance emulator core
|
|
1
platform/android/app/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
/build
|
|
|
@ -1,59 +0,0 @@
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
|
|
||||||
android {
|
|
||||||
compileSdkVersion 29
|
|
||||||
buildToolsVersion "29.0.3"
|
|
||||||
defaultConfig {
|
|
||||||
applicationId "com.mrmichel.rustdroid_emu"
|
|
||||||
minSdkVersion 21
|
|
||||||
targetSdkVersion 26
|
|
||||||
versionCode 1
|
|
||||||
versionName "1.0"
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
||||||
}
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
minifyEnabled false
|
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'org.mozilla.rust-android-gradle.rust-android'
|
|
||||||
|
|
||||||
cargo {
|
|
||||||
prebuiltToolchains = true
|
|
||||||
verbose = true
|
|
||||||
profile = 'release'
|
|
||||||
module = "../../../platform/rustboyadvance-jni"
|
|
||||||
targetDirectory = '../../../target'
|
|
||||||
libname = "rustboyadvance_jni"
|
|
||||||
targets = ['x86', 'arm64']
|
|
||||||
apiLevel = 21
|
|
||||||
}
|
|
||||||
|
|
||||||
afterEvaluate {
|
|
||||||
// The `cargoBuild` task isn't available until after evaluation.
|
|
||||||
android.applicationVariants.all { variant ->
|
|
||||||
def productFlavor = ""
|
|
||||||
variant.productFlavors.each {
|
|
||||||
productFlavor += "${it.name.capitalize()}"
|
|
||||||
}
|
|
||||||
def buildType = "${variant.buildType.name.capitalize()}"
|
|
||||||
tasks["generate${productFlavor}${buildType}Assets"].dependsOn(tasks["cargoBuild"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
||||||
implementation 'androidx.appcompat:appcompat:1.0.2'
|
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
|
||||||
implementation 'com.google.android.material:material:1.1.0'
|
|
||||||
implementation "androidx.documentfile:documentfile:1.0.1"
|
|
||||||
implementation 'androidx.preference:preference:1.1.0'
|
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
|
||||||
implementation 'commons-io:commons-io:2.6'
|
|
||||||
testImplementation 'junit:junit:4.12'
|
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
|
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
|
||||||
}
|
|
21
platform/android/app/proguard-rules.pro
vendored
|
@ -1,21 +0,0 @@
|
||||||
# Add project specific ProGuard rules here.
|
|
||||||
# You can control the set of applied configuration files using the
|
|
||||||
# proguardFiles setting in build.gradle.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Uncomment this to preserve the line number information for
|
|
||||||
# debugging stack traces.
|
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
|
||||||
# hide the original source file name.
|
|
||||||
#-renamesourcefileattribute SourceFile
|
|
|
@ -1,27 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry;
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instrumented test, which will execute on an Android device.
|
|
||||||
*
|
|
||||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
|
||||||
public class ExampleInstrumentedTest {
|
|
||||||
@Test
|
|
||||||
public void useAppContext() {
|
|
||||||
// Context of the app under test.
|
|
||||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
|
||||||
|
|
||||||
assertEquals("com.mrmichel.rustdroid_emu", appContext.getPackageName());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="com.mrmichel.rustdroid_emu">
|
|
||||||
|
|
||||||
<uses-feature
|
|
||||||
android:glEsVersion="0x00200000"
|
|
||||||
android:required="true" />
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
||||||
|
|
||||||
<application
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:hardwareAccelerated="true"
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
|
||||||
android:isGame="true"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:supportsRtl="true"
|
|
||||||
android:theme="@style/AppTheme">
|
|
||||||
|
|
||||||
<!-- Needed for Android >= Nougat for file access -->
|
|
||||||
<provider
|
|
||||||
android:name="androidx.core.content.FileProvider"
|
|
||||||
android:authorities="com.mrmichel.rustdroid_emu.provider"
|
|
||||||
android:exported="false"
|
|
||||||
android:grantUriPermissions="true">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
|
||||||
android:resource="@xml/provider_paths" />
|
|
||||||
</provider>
|
|
||||||
|
|
||||||
<activity android:name=".ui.snapshots.SnapshotPickerActivity" />
|
|
||||||
<activity
|
|
||||||
android:name=".ui.snapshots.SnapshotListFragment"
|
|
||||||
android:label="@string/title_activity_snapshot" />
|
|
||||||
<activity
|
|
||||||
android:name=".ui.library.RomListActivity"
|
|
||||||
android:label="@string/title_activity_rom_list" />
|
|
||||||
<activity
|
|
||||||
android:name=".ui.EmulatorActivity"
|
|
||||||
android:label="@string/title_activity_emulator" />
|
|
||||||
<activity
|
|
||||||
android:name=".ui.SettingsActivity"
|
|
||||||
android:label="Settings" />
|
|
||||||
<activity android:name=".ui.SplashActivity">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
</application>
|
|
||||||
|
|
||||||
</manifest>
|
|
Before Width: | Height: | Size: 40 KiB |
|
@ -1,123 +0,0 @@
|
||||||
package com.mrmichel.rustboyadvance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JNI wrapper to the rust core
|
|
||||||
*/
|
|
||||||
public class EmulatorBindings {
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("rustboyadvance_jni");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a new emulator context
|
|
||||||
*
|
|
||||||
* @param bios bytearray of the GBA bios
|
|
||||||
* @param rom bytearray of the rom to run
|
|
||||||
* @param renderer renderer instance
|
|
||||||
* @param audioPlayer audio player instance
|
|
||||||
* @param keypad Keypad instance
|
|
||||||
* @param save_name name of the save file TODO remove this
|
|
||||||
* @param skipBios skip bios
|
|
||||||
* @return the emulator context to use pass to other methods in this class
|
|
||||||
* @throws NativeBindingException
|
|
||||||
*/
|
|
||||||
public static native long openEmulator(byte[] bios, byte[] rom, IFrameRenderer renderer, IAudioPlayer audioPlayer, Keypad keypad, String save_name, boolean skipBios) throws NativeBindingException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a new emulator context from a saved state buffer
|
|
||||||
*
|
|
||||||
* @param bios bytearray of the GBA bios
|
|
||||||
* @param rom bytearray of the rom to run
|
|
||||||
* @param savedState saved state buffer
|
|
||||||
* @param renderer renderer instance
|
|
||||||
* @param audioPlayer audio player instance
|
|
||||||
* @param keypad Keypad instance
|
|
||||||
* @return
|
|
||||||
* @throws NativeBindingException
|
|
||||||
*/
|
|
||||||
public static native long openSavedState(byte[] bios, byte[] rom, byte[] savedState, IFrameRenderer renderer, IAudioPlayer audioPlayer, Keypad keypad) throws NativeBindingException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroys the emulator instance
|
|
||||||
* should be put in a finalizer or else the emulator context may leak.
|
|
||||||
*
|
|
||||||
* @param ctx
|
|
||||||
*/
|
|
||||||
public static native void closeEmulator(long ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the emulation thread
|
|
||||||
*
|
|
||||||
* @param ctx
|
|
||||||
*/
|
|
||||||
public static native void runMainLoop(long ctx);
|
|
||||||
|
|
||||||
public static native void pause(long ctx);
|
|
||||||
|
|
||||||
public static native void resume(long ctx);
|
|
||||||
|
|
||||||
public static native void setTurbo(long ctx, boolean turbo);
|
|
||||||
|
|
||||||
public static native void stop(long ctx);
|
|
||||||
|
|
||||||
|
|
||||||
public static native int[] getFrameBuffer(long ctx);
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Runs the emulation for a single frame.
|
|
||||||
// * @param ctx
|
|
||||||
// * @param frame_buffer will be filled with the frame buffer to render
|
|
||||||
// */
|
|
||||||
// public static native void runFrame(long ctx, int[] frame_buffer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ctx
|
|
||||||
* @return The loaded ROM title
|
|
||||||
*/
|
|
||||||
public static native String getGameTitle(long ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ctx
|
|
||||||
* @return The loaded ROM game code
|
|
||||||
*/
|
|
||||||
public static native String getGameCode(long ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the keystate
|
|
||||||
*
|
|
||||||
* @param keyState
|
|
||||||
*/
|
|
||||||
public static native void setKeyState(long ctx, int keyState);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves the state
|
|
||||||
*
|
|
||||||
* @param ctx
|
|
||||||
* @return save state buffer
|
|
||||||
* @throws NativeBindingException
|
|
||||||
*/
|
|
||||||
public static native byte[] saveState(long ctx) throws NativeBindingException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a save state
|
|
||||||
*
|
|
||||||
* @param ctx
|
|
||||||
* @param state save state buffer
|
|
||||||
* @throws NativeBindingException
|
|
||||||
*/
|
|
||||||
public static native void loadState(long ctx, byte[] state) throws NativeBindingException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs the emulator state
|
|
||||||
*
|
|
||||||
* @return non-zero value on failure
|
|
||||||
*/
|
|
||||||
public static native void log(long ctx);
|
|
||||||
|
|
||||||
public class NativeBindingException extends Exception {
|
|
||||||
public NativeBindingException(String errorMessage) {
|
|
||||||
super(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package com.mrmichel.rustboyadvance;
|
|
||||||
|
|
||||||
public interface IAudioPlayer {
|
|
||||||
int audioWrite(short[] buffer, int offsetInShorts, int sizeInShorts);
|
|
||||||
|
|
||||||
void pause();
|
|
||||||
|
|
||||||
void play();
|
|
||||||
|
|
||||||
int getSampleCount();
|
|
||||||
|
|
||||||
int getSampleRate();
|
|
||||||
|
|
||||||
int availableBufferSize();
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package com.mrmichel.rustboyadvance;
|
|
||||||
|
|
||||||
public interface IFrameRenderer {
|
|
||||||
void renderFrame(int[] framebuffer);
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package com.mrmichel.rustboyadvance;
|
|
||||||
|
|
||||||
public class Keypad {
|
|
||||||
private int keyState;
|
|
||||||
|
|
||||||
public Keypad() {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
this.keyState = 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onKeyDown(Key key) {
|
|
||||||
this.keyState = this.keyState & ~(1 << key.keyBit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onKeyUp(Key key) {
|
|
||||||
this.keyState = this.keyState | (1 << key.keyBit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getKeyState() {
|
|
||||||
return keyState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Key {
|
|
||||||
ButtonA(0),
|
|
||||||
ButtonB(1),
|
|
||||||
Select(2),
|
|
||||||
Start(3),
|
|
||||||
Right(4),
|
|
||||||
Left(5),
|
|
||||||
Up(6),
|
|
||||||
Down(7),
|
|
||||||
ButtonR(8),
|
|
||||||
ButtonL(9);
|
|
||||||
|
|
||||||
private final int keyBit;
|
|
||||||
|
|
||||||
Key(int keyBit) {
|
|
||||||
this.keyBit = keyBit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package com.mrmichel.rustboyadvance;
|
|
||||||
|
|
||||||
public class RomHelper {
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("rustboyadvance_jni");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static native String getGameCode(byte[] romData);
|
|
||||||
|
|
||||||
public static native String getGameTitle(byte[] romData);
|
|
||||||
}
|
|
|
@ -1,164 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.core.content.FileProvider;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.ui.EmulatorActivity;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
|
|
||||||
public class Util {
|
|
||||||
|
|
||||||
private static final String TAG = "Util";
|
|
||||||
|
|
||||||
|
|
||||||
public static void startEmulator(Context context, byte[] bios, int romId) {
|
|
||||||
Intent intent = new Intent(context, EmulatorActivity.class);
|
|
||||||
intent.putExtra("bios", bios);
|
|
||||||
intent.putExtra("romId", romId);
|
|
||||||
context.startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void showAlertDialogAndExit(final Activity activity, Exception e) {
|
|
||||||
new AlertDialog.Builder(activity)
|
|
||||||
.setTitle(e.toString())
|
|
||||||
.setMessage(e.getMessage())
|
|
||||||
// Specifying a listener allows you to take an action before dismissing the dialog.
|
|
||||||
// The dialog is automatically dismissed when a dialog button is clicked.
|
|
||||||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
activity.finishAffinity();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showAlertDialog(final Activity activity, Exception e) {
|
|
||||||
new AlertDialog.Builder(activity)
|
|
||||||
.setTitle(e.toString())
|
|
||||||
.setMessage(e.getMessage())
|
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static byte[] compressBitmapToByteArray(Bitmap bitmap) {
|
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
||||||
bitmap.compress(Bitmap.CompressFormat.PNG, 10, byteArrayOutputStream);
|
|
||||||
return byteArrayOutputStream.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void writeCompressedFile(File file, byte[] bytes) {
|
|
||||||
try {
|
|
||||||
FileOutputStream fos = new FileOutputStream(file);
|
|
||||||
GZIPOutputStream gos = new GZIPOutputStream(fos);
|
|
||||||
|
|
||||||
gos.write(bytes);
|
|
||||||
gos.close();
|
|
||||||
fos.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "failed to write compressed file " + file.toString() + " error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] readCompressedFile(File file) {
|
|
||||||
try {
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
GZIPInputStream gis = new GZIPInputStream(new FileInputStream(file));
|
|
||||||
|
|
||||||
int len;
|
|
||||||
|
|
||||||
while ((len = gis.read(buffer, 0, 8192)) != -1) {
|
|
||||||
outputStream.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
gis.close();
|
|
||||||
return outputStream.toByteArray();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "failed to read compressed file " + file.toString() + " error: " + e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] readFile(File file) throws IOException {
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
FileInputStream fis = new FileInputStream(file);
|
|
||||||
|
|
||||||
int len;
|
|
||||||
|
|
||||||
while ((len = fis.read(buffer, 0, 8192)) != -1) {
|
|
||||||
outputStream.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
fis.close();
|
|
||||||
return outputStream.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String byteArrayToHexString(final byte[] bytes) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (byte b : bytes) {
|
|
||||||
sb.append(String.format("%02x", b & 0xff));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getHash(final byte[] bytes) {
|
|
||||||
MessageDigest md;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("SHA-256");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// impossible
|
|
||||||
Log.e("SnapshotManager", "SHA-256 algo not found");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
md.update(bytes);
|
|
||||||
return byteArrayToHexString(md.digest());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void shareFile(Context context, File file, String message) throws FileNotFoundException {
|
|
||||||
if (!file.exists()) {
|
|
||||||
throw new FileNotFoundException("file does not exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
final Uri uri;
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
uri = Uri.fromFile(file);
|
|
||||||
} else {
|
|
||||||
uri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", file);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uri == null) {
|
|
||||||
throw new FileNotFoundException("could not find file to share");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
|
|
||||||
intentShareFile.setType("*/*");
|
|
||||||
intentShareFile.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
||||||
intentShareFile.putExtra(Intent.EXTRA_STREAM, uri);
|
|
||||||
intentShareFile.putExtra(Intent.EXTRA_TEXT, message);
|
|
||||||
|
|
||||||
context.startActivity(Intent.createChooser(intentShareFile, message));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.core;
|
|
||||||
|
|
||||||
import android.media.AudioFormat;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.media.AudioTrack;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.mrmichel.rustboyadvance.IAudioPlayer;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple wrapper around the android AudioTrack class that implements IAudioPlayer
|
|
||||||
*/
|
|
||||||
public class AndroidAudioPlayer implements IAudioPlayer {
|
|
||||||
private static final String TAG = "AndroidAudioPlayer";
|
|
||||||
|
|
||||||
private static final int BUFFER_SIZE_IN_BYTES = 8192;
|
|
||||||
private static int SAMPLE_RATE_HZ = 44100;
|
|
||||||
|
|
||||||
private AudioTrack audioTrack;
|
|
||||||
|
|
||||||
public AndroidAudioPlayer() {
|
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
|
||||||
AudioTrack.Builder audioTrackBuilder = new AudioTrack.Builder()
|
|
||||||
.setAudioFormat(new AudioFormat.Builder()
|
|
||||||
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
|
|
||||||
.setSampleRate(SAMPLE_RATE_HZ)
|
|
||||||
.setChannelMask(AudioFormat.CHANNEL_IN_STEREO | AudioFormat.CHANNEL_OUT_STEREO)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.setBufferSizeInBytes(AndroidAudioPlayer.BUFFER_SIZE_IN_BYTES)
|
|
||||||
.setTransferMode(AudioTrack.MODE_STREAM);
|
|
||||||
if (Build.VERSION.SDK_INT >= 26) {
|
|
||||||
audioTrackBuilder.setPerformanceMode(AudioTrack.PERFORMANCE_MODE_LOW_LATENCY);
|
|
||||||
}
|
|
||||||
this.audioTrack = audioTrackBuilder.build();
|
|
||||||
} else {
|
|
||||||
this.audioTrack = new AudioTrack(
|
|
||||||
AudioManager.STREAM_MUSIC,
|
|
||||||
SAMPLE_RATE_HZ,
|
|
||||||
AudioFormat.CHANNEL_IN_STEREO | AudioFormat.CHANNEL_OUT_STEREO,
|
|
||||||
AudioFormat.ENCODING_PCM_16BIT,
|
|
||||||
AndroidAudioPlayer.BUFFER_SIZE_IN_BYTES,
|
|
||||||
AudioTrack.MODE_STREAM);
|
|
||||||
}
|
|
||||||
Log.d(TAG, "sampleCount = " + this.getSampleCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int audioWrite(short[] buffer, int offsetInShorts, int sizeInShorts) {
|
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
|
||||||
return this.audioTrack.write(buffer, offsetInShorts, sizeInShorts, AudioTrack.WRITE_NON_BLOCKING);
|
|
||||||
} else {
|
|
||||||
// Native bindings will do its best to make sure this doesn't block anyway
|
|
||||||
return this.audioTrack.write(buffer, offsetInShorts, sizeInShorts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pause() {
|
|
||||||
this.audioTrack.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void play() {
|
|
||||||
this.audioTrack.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSampleCount() {
|
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
|
||||||
return this.audioTrack.getBufferSizeInFrames();
|
|
||||||
} else {
|
|
||||||
return BUFFER_SIZE_IN_BYTES / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSampleRate() {
|
|
||||||
return this.audioTrack.getSampleRate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int availableBufferSize() {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.core;
|
|
||||||
|
|
||||||
import com.mrmichel.rustboyadvance.EmulatorBindings;
|
|
||||||
import com.mrmichel.rustboyadvance.IFrameRenderer;
|
|
||||||
import com.mrmichel.rustboyadvance.Keypad;
|
|
||||||
|
|
||||||
public class Emulator {
|
|
||||||
|
|
||||||
public Keypad keypad;
|
|
||||||
/// context received by the native binding
|
|
||||||
private long ctx = -1;
|
|
||||||
|
|
||||||
private AndroidAudioPlayer audioPlayer;
|
|
||||||
private IFrameRenderer frameRenderer;
|
|
||||||
public Emulator(IFrameRenderer frameRenderer, AndroidAudioPlayer audioPlayer) {
|
|
||||||
this.keypad = new Keypad();
|
|
||||||
this.frameRenderer = frameRenderer;
|
|
||||||
this.audioPlayer = audioPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Emulator(long ctx, IFrameRenderer frameRenderer, AndroidAudioPlayer audioPlayer) {
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.frameRenderer = frameRenderer;
|
|
||||||
this.audioPlayer = audioPlayer;
|
|
||||||
this.keypad = new Keypad();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the native emulator handle for caching
|
|
||||||
*/
|
|
||||||
public long getCtx() {
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runMainLoop() {
|
|
||||||
EmulatorBindings.runMainLoop(this.ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pause() {
|
|
||||||
EmulatorBindings.pause(this.ctx);
|
|
||||||
this.audioPlayer.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resume() {
|
|
||||||
EmulatorBindings.resume(this.ctx);
|
|
||||||
this.audioPlayer.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTurbo(boolean turbo) {
|
|
||||||
EmulatorBindings.setTurbo(ctx, turbo);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
EmulatorBindings.stop(this.ctx);
|
|
||||||
this.audioPlayer.pause();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getFrameBuffer() {
|
|
||||||
return EmulatorBindings.getFrameBuffer(this.ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized byte[] saveState() throws EmulatorBindings.NativeBindingException {
|
|
||||||
return EmulatorBindings.saveState(this.ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void loadState(byte[] state) throws EmulatorBindings.NativeBindingException, EmulatorException {
|
|
||||||
if (ctx != -1) {
|
|
||||||
EmulatorBindings.loadState(this.ctx, state);
|
|
||||||
} else {
|
|
||||||
throw new EmulatorException("Call open() first");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void open(byte[] bios, byte[] rom, String saveName, boolean skipBios) throws EmulatorBindings.NativeBindingException {
|
|
||||||
this.ctx = EmulatorBindings.openEmulator(bios, rom, this.frameRenderer, this.audioPlayer, this.keypad, saveName, skipBios);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void openSavedState(byte[] bios, byte[] rom, byte[] savedState) throws EmulatorBindings.NativeBindingException {
|
|
||||||
this.ctx = EmulatorBindings.openSavedState(bios, rom, savedState, this.frameRenderer, this.audioPlayer, this.keypad);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void close() {
|
|
||||||
if (this.ctx != -1) {
|
|
||||||
EmulatorBindings.closeEmulator(this.ctx);
|
|
||||||
this.ctx = -1;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGameCode() {
|
|
||||||
if (ctx != -1) {
|
|
||||||
return EmulatorBindings.getGameCode(ctx);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGameTitle() {
|
|
||||||
if (ctx != -1) {
|
|
||||||
return EmulatorBindings.getGameTitle(ctx);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOpen() {
|
|
||||||
return this.ctx != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws Throwable {
|
|
||||||
super.finalize();
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void log() {
|
|
||||||
EmulatorBindings.log(this.ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EmulatorException extends Exception {
|
|
||||||
public EmulatorException(String errorMessage) {
|
|
||||||
super(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,321 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.core;
|
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.documentfile.provider.DocumentFile;
|
|
||||||
|
|
||||||
import com.mrmichel.rustboyadvance.RomHelper;
|
|
||||||
import com.mrmichel.rustdroid_emu.Util;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class RomManager {
|
|
||||||
private static final String TAG = "RomManager";
|
|
||||||
private static RomManager instance;
|
|
||||||
private RomDatabaseHelper dbHelper;
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
public RomManager(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
this.dbHelper = new RomDatabaseHelper(this.context, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RomManager getInstance(Context context) {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new RomManager(context);
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String byteArrayToHexString(final byte[] bytes) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (byte b : bytes) {
|
|
||||||
sb.append(String.format("%02x", b & 0xff));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getHash(final byte[] bytes) {
|
|
||||||
MessageDigest md;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("SHA-256");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// impossible
|
|
||||||
Log.e(TAG, "SHA-256 algo not found");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
md.update(bytes);
|
|
||||||
return byteArrayToHexString(md.digest());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<RomMetadataEntry> getAllRomMetaData() {
|
|
||||||
return this.dbHelper.queryRomMetadata("SELECT * FROM " + RomDatabaseHelper.TABLE_METADATA + " ORDER BY lastPlayed DESC");
|
|
||||||
}
|
|
||||||
|
|
||||||
public RomMetadataEntry getRomMetadata(byte[] romData) {
|
|
||||||
String romHash = getHash(romData);
|
|
||||||
|
|
||||||
ArrayList<RomMetadataEntry> metadataEntries = dbHelper.queryRomMetadata(
|
|
||||||
"SELECT * FROM " + RomDatabaseHelper.TABLE_METADATA + " where hash == '" + romHash + "'");
|
|
||||||
|
|
||||||
if (metadataEntries.size() > 0) {
|
|
||||||
return metadataEntries.get(0);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public RomMetadataEntry getRomMetadata(int romId) {
|
|
||||||
ArrayList<RomMetadataEntry> metadataEntries = dbHelper.queryRomMetadata(
|
|
||||||
"SELECT * FROM " + RomDatabaseHelper.TABLE_METADATA + " where id = '" + romId + "'");
|
|
||||||
|
|
||||||
if (metadataEntries.size() > 0) {
|
|
||||||
return metadataEntries.get(0);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private byte[] readFromUri(Uri uri) throws IOException {
|
|
||||||
ContentResolver cr = context.getContentResolver();
|
|
||||||
|
|
||||||
InputStream is = cr.openInputStream(uri);
|
|
||||||
byte[] data = new byte[is.available()];
|
|
||||||
is.read(data);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void importRom(DocumentFile documentFile) {
|
|
||||||
|
|
||||||
Uri uri = documentFile.getUri();
|
|
||||||
|
|
||||||
byte[] romData;
|
|
||||||
try {
|
|
||||||
romData = readFromUri(uri);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "could not read rom file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null != getRomMetadata(romData)) {
|
|
||||||
Toast.makeText(context, "This rom is already imported!", Toast.LENGTH_LONG).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String hash = getHash(romData);
|
|
||||||
String gameCode = RomHelper.getGameCode(romData);
|
|
||||||
String gameTitle = RomHelper.getGameTitle(romData);
|
|
||||||
|
|
||||||
String romFileName = documentFile.getName();
|
|
||||||
|
|
||||||
// Multiple roms can have the same title+code combo, so we rely on a hash to be a unique identifier.
|
|
||||||
File baseDir = new File(context.getFilesDir(), hash);
|
|
||||||
baseDir.mkdirs();
|
|
||||||
|
|
||||||
File romFile = new File(baseDir, romFileName);
|
|
||||||
|
|
||||||
// cache the rom
|
|
||||||
try {
|
|
||||||
FileOutputStream fileOutputStream = new FileOutputStream(romFile);
|
|
||||||
fileOutputStream.write(romData);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "cannot cache rom file");
|
|
||||||
}
|
|
||||||
|
|
||||||
File backupFile = new File(baseDir, romFileName + ".sav");
|
|
||||||
|
|
||||||
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
|
||||||
|
|
||||||
ContentValues cv = new ContentValues();
|
|
||||||
|
|
||||||
cv.put("name", romFileName);
|
|
||||||
cv.put("gameTitle", gameTitle);
|
|
||||||
cv.put("gameCode", gameCode);
|
|
||||||
cv.put("hash", hash);
|
|
||||||
cv.put("path", romFile.getPath());
|
|
||||||
cv.put("backupPath", backupFile.getPath());
|
|
||||||
|
|
||||||
db.insertOrThrow(RomDatabaseHelper.TABLE_METADATA, null, cv);
|
|
||||||
db.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteRomMetadata(RomMetadataEntry romMetadataEntry) {
|
|
||||||
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
|
||||||
|
|
||||||
db.delete(RomDatabaseHelper.TABLE_METADATA, "id=" + romMetadataEntry.getId(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateLastPlayed(int romId) {
|
|
||||||
Timestamp now = new Timestamp(System.currentTimeMillis());
|
|
||||||
|
|
||||||
ContentValues cv = new ContentValues();
|
|
||||||
cv.put("lastPlayed", now.toString());
|
|
||||||
|
|
||||||
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
|
||||||
db.update(RomDatabaseHelper.TABLE_METADATA, cv, "id=" + romId, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateScreenshot(int romId, Bitmap bitmap) {
|
|
||||||
|
|
||||||
ContentValues cv = new ContentValues();
|
|
||||||
cv.put("screenshot", Util.compressBitmapToByteArray(bitmap));
|
|
||||||
|
|
||||||
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
|
||||||
db.update(RomDatabaseHelper.TABLE_METADATA, cv, "id=" + romId, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class RomMetadataEntry {
|
|
||||||
int id;
|
|
||||||
String name;
|
|
||||||
String gameTitle;
|
|
||||||
String gameCode;
|
|
||||||
File romFile;
|
|
||||||
File backupFile;
|
|
||||||
Bitmap screenshot;
|
|
||||||
Timestamp lastPlayed;
|
|
||||||
|
|
||||||
private RomMetadataEntry(int id, String name, String gameTitle, String gameCode, File romFile, File backupFile, Bitmap screenshot, Timestamp lastPlayed) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.gameTitle = gameTitle;
|
|
||||||
this.gameCode = gameCode;
|
|
||||||
this.romFile = romFile;
|
|
||||||
this.backupFile = backupFile;
|
|
||||||
this.screenshot = screenshot;
|
|
||||||
this.lastPlayed = lastPlayed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap getScreenshot() {
|
|
||||||
return screenshot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getBackupFile() {
|
|
||||||
return backupFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getRomFile() {
|
|
||||||
return romFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGameTitle() {
|
|
||||||
return gameTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGameCode() {
|
|
||||||
return gameCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getLastPlayed() {
|
|
||||||
return lastPlayed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RomDatabaseHelper extends SQLiteOpenHelper {
|
|
||||||
private static final String DATABASE_NAME = "rom_db";
|
|
||||||
|
|
||||||
private static final String TABLE_METADATA = "rom_metadata";
|
|
||||||
|
|
||||||
|
|
||||||
public RomDatabaseHelper(@Nullable Context context, int version) {
|
|
||||||
super(context, DATABASE_NAME, null, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(SQLiteDatabase db) {
|
|
||||||
db.execSQL("create table " + TABLE_METADATA +
|
|
||||||
" (id INTEGER PRIMARY KEY," +
|
|
||||||
"name TEXT UNIQUE," +
|
|
||||||
"hash TEXT UNIQUE," +
|
|
||||||
"gameTitle TEXT," +
|
|
||||||
"gameCode TEXT," +
|
|
||||||
"screenshot BLOB," +
|
|
||||||
"lastPlayed TIMESTAMP," +
|
|
||||||
"path TEXT UNIQUE," +
|
|
||||||
"backupPath TEXT UNIQUE" +
|
|
||||||
")");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<RomMetadataEntry> queryRomMetadata(String query) {
|
|
||||||
ArrayList<RomMetadataEntry> arrayList = new ArrayList<>();
|
|
||||||
|
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
|
||||||
Cursor cursor = db.rawQuery(query, null);
|
|
||||||
|
|
||||||
if (cursor.moveToFirst()) {
|
|
||||||
do {
|
|
||||||
|
|
||||||
String name = cursor.getString(cursor.getColumnIndex("name"));
|
|
||||||
|
|
||||||
File romFile = new File(cursor.getString(cursor.getColumnIndex("path")));
|
|
||||||
File backupFile = new File(cursor.getString(cursor.getColumnIndex("backupPath")));
|
|
||||||
|
|
||||||
byte[] screenshotBlob = cursor.getBlob(cursor.getColumnIndex("screenshot"));
|
|
||||||
Bitmap screenshot;
|
|
||||||
if (null != screenshotBlob) {
|
|
||||||
screenshot = BitmapFactory.decodeByteArray(screenshotBlob, 0, screenshotBlob.length);
|
|
||||||
} else {
|
|
||||||
screenshot = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String gameTitle = cursor.getString(cursor.getColumnIndex("gameTitle"));
|
|
||||||
String gameCode = cursor.getString(cursor.getColumnIndex("gameCode"));
|
|
||||||
|
|
||||||
int id = cursor.getInt(cursor.getColumnIndex("id"));
|
|
||||||
|
|
||||||
String lastPlayedString = cursor.getString(cursor.getColumnIndex("lastPlayed"));
|
|
||||||
Timestamp lastPlayed;
|
|
||||||
if (lastPlayedString != null) {
|
|
||||||
lastPlayed = Timestamp.valueOf(lastPlayedString);
|
|
||||||
} else {
|
|
||||||
lastPlayed = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
arrayList.add(new RomMetadataEntry(id, name, gameTitle, gameCode, romFile, backupFile, screenshot, lastPlayed));
|
|
||||||
|
|
||||||
} while (cursor.moveToNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cursor.close();
|
|
||||||
db.close();
|
|
||||||
|
|
||||||
return arrayList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_METADATA);
|
|
||||||
onCreate(db);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.core;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.Util;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class Snapshot {
|
|
||||||
private Bitmap preview;
|
|
||||||
private String gameCode;
|
|
||||||
private String gameTitle;
|
|
||||||
private long timestamp;
|
|
||||||
private File file;
|
|
||||||
|
|
||||||
public Snapshot(File file, String gameCode, String gameTitle, Bitmap preview) {
|
|
||||||
this.file = file;
|
|
||||||
this.gameCode = gameCode;
|
|
||||||
this.gameTitle = gameTitle;
|
|
||||||
this.preview = preview;
|
|
||||||
this.timestamp = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Snapshot(File file, String gameCode, String gameTitle, Bitmap preview, long timestamp) {
|
|
||||||
this.file = file;
|
|
||||||
this.gameCode = gameCode;
|
|
||||||
this.gameTitle = gameTitle;
|
|
||||||
this.preview = preview;
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getFile() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGameCode() {
|
|
||||||
return gameCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGameTitle() {
|
|
||||||
return gameTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap getPreview() {
|
|
||||||
return preview;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] load() {
|
|
||||||
return Util.readCompressedFile(this.file);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,169 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.core;
|
|
||||||
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.Util;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class SnapshotManager {
|
|
||||||
private static final String TAG = "SnapshotManager";
|
|
||||||
|
|
||||||
private static final String SNAPSHOT_ROOT = "snapshots";
|
|
||||||
private static final String DB_NAME = "snapshots";
|
|
||||||
|
|
||||||
static SnapshotManager instance;
|
|
||||||
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
private SnapshotDatabaseHelper dbHelper;
|
|
||||||
|
|
||||||
private SnapshotManager(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
this.dbHelper = new SnapshotDatabaseHelper(this.context);
|
|
||||||
// this.snapshotDB = context.openOrCreateDatabase("snapshots", Context.MODE_PRIVATE, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SnapshotManager getInstance(Context context) {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new SnapshotManager(context);
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private File getPreviewsDir(String gameCode) {
|
|
||||||
File d = new File(context.getFilesDir(), SNAPSHOT_ROOT + "/previews");
|
|
||||||
d.mkdirs();
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
private File getSnapshotDir(String gameCode) {
|
|
||||||
File d = new File(context.getFilesDir(), SNAPSHOT_ROOT + "/data");
|
|
||||||
d.mkdirs();
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveSnapshot(String gameCode, String gameTitle, Bitmap previewImage, byte[] data) {
|
|
||||||
byte[] previewImageBytes = Util.compressBitmapToByteArray(previewImage);
|
|
||||||
|
|
||||||
String hash = Util.getHash(data);
|
|
||||||
|
|
||||||
File previewsDir = getPreviewsDir(gameCode);
|
|
||||||
File snapshotsDir = getSnapshotDir(gameCode);
|
|
||||||
|
|
||||||
File previewFile = new File(previewsDir, hash);
|
|
||||||
Util.writeCompressedFile(previewFile, previewImageBytes);
|
|
||||||
|
|
||||||
File snapshotFile = new File(snapshotsDir, hash);
|
|
||||||
Util.writeCompressedFile(snapshotFile, data);
|
|
||||||
|
|
||||||
this.dbHelper.insertSnapshot(gameCode, gameTitle, previewFile, snapshotFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteSnapshot(Snapshot snapshot) {
|
|
||||||
|
|
||||||
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
|
||||||
|
|
||||||
File file = snapshot.getFile();
|
|
||||||
db.delete(SnapshotDatabaseHelper.TABLE_NAME, "dataFile = '" + file.toString() + "'", null);
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<Snapshot> getAllSnapshots() {
|
|
||||||
return this.dbHelper.getEntries();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<Snapshot> getByGameCode(String gameCode) {
|
|
||||||
return this.dbHelper.getEntries(gameCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SnapshotDBEntry {
|
|
||||||
String gameCode;
|
|
||||||
String gameTitle;
|
|
||||||
File previewFile;
|
|
||||||
File snapshotFile;
|
|
||||||
Timestamp timestamp;
|
|
||||||
|
|
||||||
public SnapshotDBEntry(String gameCode, File previewFile, File snapshotFile, Timestamp timestamp) {
|
|
||||||
this.gameCode = gameCode;
|
|
||||||
this.previewFile = previewFile;
|
|
||||||
this.snapshotFile = snapshotFile;
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SnapshotDatabaseHelper extends SQLiteOpenHelper {
|
|
||||||
public static final String TABLE_NAME = "snapshot_table";
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
public SnapshotDatabaseHelper(Context context) {
|
|
||||||
super(context, DB_NAME, null, 1);
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(SQLiteDatabase db) {
|
|
||||||
db.execSQL("create table " + TABLE_NAME +
|
|
||||||
" (id INTEGER PRIMARY KEY, gameCode TEXT, gameTitle TEXT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, previewImageFile TEXT, dataFile TEXT)"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insertSnapshot(String gameCode, String gameTitle, File previewCacheFile, File snapshotDataFile) {
|
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
values.put("gameCode", gameCode);
|
|
||||||
values.put("gameTitle", gameTitle);
|
|
||||||
values.put("previewImageFile", previewCacheFile.getPath());
|
|
||||||
values.put("dataFile", snapshotDataFile.getPath());
|
|
||||||
db.insertOrThrow(TABLE_NAME, null, values);
|
|
||||||
db.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<Snapshot> getEntriesByQuery(String query) {
|
|
||||||
ArrayList<Snapshot> arrayList = new ArrayList<>();
|
|
||||||
|
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
|
||||||
Cursor cursor = db.rawQuery(query, null);
|
|
||||||
|
|
||||||
if (cursor.moveToFirst()) {
|
|
||||||
do {
|
|
||||||
String gameCode = cursor.getString(1);
|
|
||||||
String gameTitle = cursor.getString(2);
|
|
||||||
Timestamp timestamp = Timestamp.valueOf(cursor.getString(3));
|
|
||||||
File previewImageFile = new File(cursor.getString(4));
|
|
||||||
File dataFile = new File(cursor.getString(5));
|
|
||||||
|
|
||||||
byte[] previewData = Util.readCompressedFile(previewImageFile);
|
|
||||||
Bitmap previewBitmap = BitmapFactory.decodeByteArray(previewData, 0, previewData.length);
|
|
||||||
|
|
||||||
arrayList.add(new Snapshot(dataFile, gameCode, gameTitle, previewBitmap, timestamp.getTime()));
|
|
||||||
} while (cursor.moveToNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.close();
|
|
||||||
db.close();
|
|
||||||
return arrayList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<Snapshot> getEntries() {
|
|
||||||
return getEntriesByQuery("SELECT * FROM " + TABLE_NAME + " ORDER BY timestamp DESC ");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<Snapshot> getEntries(String gameCode) {
|
|
||||||
return getEntriesByQuery("SELECT * FROM " + TABLE_NAME + " where gameCode = '" + gameCode + "' ORDER BY timestamp DESC ");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.core.Emulator;
|
|
||||||
|
|
||||||
public class EmulationThread extends Thread {
|
|
||||||
|
|
||||||
private static final String TAG = "EmulationThread";
|
|
||||||
|
|
||||||
public static final long NANOSECONDS_PER_MILLISECOND = 1000000;
|
|
||||||
public static final long FRAME_TIME = 1000000000 / 60;
|
|
||||||
|
|
||||||
private Emulator emulator;
|
|
||||||
private ScreenView screenView;
|
|
||||||
|
|
||||||
private boolean running;
|
|
||||||
|
|
||||||
public EmulationThread(Emulator emulator, ScreenView screenView) {
|
|
||||||
this.emulator = emulator;
|
|
||||||
this.screenView = screenView;
|
|
||||||
this.running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pauseEmulation() {
|
|
||||||
this.emulator.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resumeEmulation() {
|
|
||||||
this.emulator.resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
super.run();
|
|
||||||
|
|
||||||
// wait until renderer is ready
|
|
||||||
while (!screenView.getRenderer().isReady());
|
|
||||||
|
|
||||||
while (!emulator.isOpen());
|
|
||||||
|
|
||||||
running = true;
|
|
||||||
emulator.runMainLoop();
|
|
||||||
Log.d(TAG, "Native runMainLoop returned!");
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,573 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui;
|
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import com.mrmichel.rustboyadvance.EmulatorBindings;
|
|
||||||
import com.mrmichel.rustboyadvance.Keypad;
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
import com.mrmichel.rustdroid_emu.Util;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.AndroidAudioPlayer;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.Emulator;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.RomManager;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.Snapshot;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.SnapshotManager;
|
|
||||||
import com.mrmichel.rustdroid_emu.ui.snapshots.SnapshotPickerActivity;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
|
|
||||||
public class EmulatorActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener {
|
|
||||||
|
|
||||||
private static final String TAG = "EmulatorActivty";
|
|
||||||
|
|
||||||
private static final String TAG_EMULATOR_STATE = "EmulatorStateFragment";
|
|
||||||
|
|
||||||
private static final int LOAD_ROM_REQUESTCODE = 123;
|
|
||||||
private static final int LOAD_SNAPSHOT_REQUESTCODE = 124;
|
|
||||||
|
|
||||||
private Menu menu;
|
|
||||||
|
|
||||||
private RomManager.RomMetadataEntry romMetadata;
|
|
||||||
private byte[] bios;
|
|
||||||
private EmulationThread emulationThread;
|
|
||||||
private AndroidAudioPlayer audioPlayer;
|
|
||||||
private byte[] on_resume_saved_state = null;
|
|
||||||
|
|
||||||
private Emulator emulator;
|
|
||||||
private ScreenView screenView;
|
|
||||||
private CompoundButton turboButton;
|
|
||||||
|
|
||||||
private boolean isEmulatorRunning() {
|
|
||||||
return emulator.isOpen() && emulationThread != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (v.getId() == R.id.tbTurbo) {
|
|
||||||
if (!isEmulatorRunning()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emulator.setTurbo(((CompoundButton) findViewById(R.id.tbTurbo)).isChecked());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
Keypad.Key key = null;
|
|
||||||
switch (v.getId()) {
|
|
||||||
case R.id.bDpadUp:
|
|
||||||
key = Keypad.Key.Up;
|
|
||||||
break;
|
|
||||||
case R.id.bDpadDown:
|
|
||||||
key = Keypad.Key.Down;
|
|
||||||
break;
|
|
||||||
case R.id.bDpadLeft:
|
|
||||||
key = Keypad.Key.Left;
|
|
||||||
break;
|
|
||||||
case R.id.bDpadRight:
|
|
||||||
key = Keypad.Key.Right;
|
|
||||||
break;
|
|
||||||
case R.id.buttonA:
|
|
||||||
key = Keypad.Key.ButtonA;
|
|
||||||
break;
|
|
||||||
case R.id.buttonB:
|
|
||||||
key = Keypad.Key.ButtonB;
|
|
||||||
break;
|
|
||||||
case R.id.buttonL:
|
|
||||||
key = Keypad.Key.ButtonL;
|
|
||||||
break;
|
|
||||||
case R.id.buttonR:
|
|
||||||
key = Keypad.Key.ButtonR;
|
|
||||||
break;
|
|
||||||
case R.id.bStart:
|
|
||||||
key = Keypad.Key.Start;
|
|
||||||
break;
|
|
||||||
case R.id.bSelect:
|
|
||||||
key = Keypad.Key.Select;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int action = event.getAction();
|
|
||||||
if (key != null) {
|
|
||||||
if (action == MotionEvent.ACTION_DOWN) {
|
|
||||||
v.setPressed(true);
|
|
||||||
emulator.keypad.onKeyDown(key);
|
|
||||||
} else if (action == MotionEvent.ACTION_UP) {
|
|
||||||
v.setPressed(false);
|
|
||||||
emulator.keypad.onKeyUp(key);
|
|
||||||
} else if (action == MotionEvent.ACTION_OUTSIDE) {
|
|
||||||
v.setPressed(false);
|
|
||||||
emulator.keypad.onKeyUp(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Keypad.Key keyCodeToGbaKey(int keyCode) {
|
|
||||||
switch (keyCode) {
|
|
||||||
case KeyEvent.KEYCODE_DPAD_UP:
|
|
||||||
return Keypad.Key.Up;
|
|
||||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
|
||||||
return Keypad.Key.Down;
|
|
||||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
|
||||||
return Keypad.Key.Left;
|
|
||||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
|
||||||
return Keypad.Key.Right;
|
|
||||||
case KeyEvent.KEYCODE_Z:
|
|
||||||
return Keypad.Key.ButtonB;
|
|
||||||
case KeyEvent.KEYCODE_X:
|
|
||||||
return Keypad.Key.ButtonA;
|
|
||||||
case KeyEvent.KEYCODE_A:
|
|
||||||
return Keypad.Key.ButtonL;
|
|
||||||
case KeyEvent.KEYCODE_S:
|
|
||||||
return Keypad.Key.ButtonR;
|
|
||||||
case KeyEvent.KEYCODE_DEL:
|
|
||||||
return Keypad.Key.Select;
|
|
||||||
case KeyEvent.KEYCODE_COMMA:
|
|
||||||
return Keypad.Key.Start;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
|
|
||||||
if (!isEmulatorRunning()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Keypad.Key key = keyCodeToGbaKey(keyCode);
|
|
||||||
Log.d(TAG, "onKeyLongPress(: keyCode = " + keyCode + " GBAKey:" + key);
|
|
||||||
if (null != key) {
|
|
||||||
this.emulator.keypad.onKeyDown(key);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return super.onKeyDown(keyCode, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
||||||
if (!isEmulatorRunning()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Keypad.Key key = keyCodeToGbaKey(keyCode);
|
|
||||||
Log.d(TAG, "onKeyDown: keyCode = " + keyCode + " GBAKey:" + key);
|
|
||||||
if (null != key) {
|
|
||||||
switch (event.getAction()) {
|
|
||||||
case KeyEvent.ACTION_DOWN:
|
|
||||||
this.emulator.keypad.onKeyDown(key);
|
|
||||||
break;
|
|
||||||
case KeyEvent.ACTION_UP:
|
|
||||||
this.emulator.keypad.onKeyUp(key);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return event.getAction() == KeyEvent.ACTION_DOWN;
|
|
||||||
} else {
|
|
||||||
return super.onKeyDown(keyCode, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
// if (requestCode == LOAD_ROM_REQUESTCODE) {
|
|
||||||
// Uri uri = data.getData();
|
|
||||||
// try {
|
|
||||||
// InputStream inputStream = getContentResolver().openInputStream(uri);
|
|
||||||
// byte[] rom = new byte[inputStream.available()];
|
|
||||||
// inputStream.read(rom);
|
|
||||||
// inputStream.close();
|
|
||||||
//
|
|
||||||
// String filename = new File(uri.getPath()).getName();
|
|
||||||
//
|
|
||||||
// File saveRoot = getFilesDir();
|
|
||||||
// String savePath = saveRoot.getAbsolutePath() + "/" + filename + ".sav";
|
|
||||||
// onRomLoaded(rom, savePath);
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// Log.e(TAG, "got error while reading rom file");
|
|
||||||
// Util.showAlertDialogAndExit(this, e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
if (requestCode == LOAD_SNAPSHOT_REQUESTCODE) {
|
|
||||||
Snapshot pickedSnapshot = SnapshotPickerActivity.obtainPickedSnapshot();
|
|
||||||
|
|
||||||
Toast.makeText(this, "Loading snapshot from " + pickedSnapshot.getTimestamp(), Toast.LENGTH_LONG).show();
|
|
||||||
|
|
||||||
boolean emulatorWasRunning = isEmulatorRunning();
|
|
||||||
|
|
||||||
pauseEmulation();
|
|
||||||
try {
|
|
||||||
emulator.loadState(pickedSnapshot.load());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Util.showAlertDialogAndExit(this, e);
|
|
||||||
}
|
|
||||||
resumeEmulation();
|
|
||||||
|
|
||||||
if (!emulatorWasRunning) {
|
|
||||||
createThreads();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "got error for request code " + requestCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void killThreads() {
|
|
||||||
if (emulationThread != null) {
|
|
||||||
try {
|
|
||||||
emulator.stop();
|
|
||||||
emulationThread.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Log.e(TAG, "emulation thread join interrupted");
|
|
||||||
}
|
|
||||||
emulationThread = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createThreads() {
|
|
||||||
emulationThread = new EmulationThread(emulator, screenView);
|
|
||||||
emulator.setTurbo(turboButton.isChecked());
|
|
||||||
emulationThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onRomLoaded(byte[] rom, String savePath) {
|
|
||||||
// killThreads();
|
|
||||||
//
|
|
||||||
// try {
|
|
||||||
// emulator.open(bios, rom, savePath);
|
|
||||||
// } catch (EmulatorBindings.NativeBindingException e) {
|
|
||||||
// Util.showAlertDialogAndExit(this, e);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// createThreads();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doLoadRom() {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
|
||||||
intent.setType("*/*");
|
|
||||||
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
|
|
||||||
startActivityForResult(intent, LOAD_ROM_REQUESTCODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
|
|
||||||
if (!isEmulatorRunning()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// save the emulator state
|
|
||||||
try {
|
|
||||||
byte[] savedState = emulator.saveState();
|
|
||||||
|
|
||||||
File saveFile = new File(getCacheDir(), "saved_state");
|
|
||||||
FileOutputStream fis = new FileOutputStream(saveFile);
|
|
||||||
|
|
||||||
fis.write(savedState);
|
|
||||||
|
|
||||||
fis.close();
|
|
||||||
|
|
||||||
outState.putString("saveFile", saveFile.getPath());
|
|
||||||
outState.putInt("romId", this.romMetadata.getId());
|
|
||||||
|
|
||||||
outState.putBoolean("turbo", false);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Util.showAlertDialogAndExit(this, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_emulator);
|
|
||||||
|
|
||||||
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
||||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
|
||||||
|
|
||||||
this.audioPlayer = new AndroidAudioPlayer();
|
|
||||||
|
|
||||||
findViewById(R.id.bStart).setOnTouchListener(this);
|
|
||||||
findViewById(R.id.bSelect).setOnTouchListener(this);
|
|
||||||
findViewById(R.id.buttonA).setOnTouchListener(this);
|
|
||||||
findViewById(R.id.buttonB).setOnTouchListener(this);
|
|
||||||
findViewById(R.id.buttonL).setOnTouchListener(this);
|
|
||||||
findViewById(R.id.buttonR).setOnTouchListener(this);
|
|
||||||
findViewById(R.id.bDpadUp).setOnTouchListener(this);
|
|
||||||
findViewById(R.id.bDpadDown).setOnTouchListener(this);
|
|
||||||
findViewById(R.id.bDpadLeft).setOnTouchListener(this);
|
|
||||||
findViewById(R.id.bDpadRight).setOnTouchListener(this);
|
|
||||||
|
|
||||||
turboButton = findViewById(R.id.tbTurbo);
|
|
||||||
turboButton.setOnClickListener(this);
|
|
||||||
|
|
||||||
this.bios = getIntent().getByteArrayExtra("bios");
|
|
||||||
|
|
||||||
this.screenView = findViewById(R.id.gba_view);
|
|
||||||
this.emulator = new Emulator(this.screenView, this.audioPlayer);
|
|
||||||
|
|
||||||
final String saveFilePath;
|
|
||||||
|
|
||||||
SharedPreferences sharedPreferences =
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(this /* Activity context */);
|
|
||||||
boolean skipBios = sharedPreferences.getBoolean("skip_bios", false);
|
|
||||||
|
|
||||||
if (null != savedInstanceState && (saveFilePath = savedInstanceState.getString("saveFile")) != null) {
|
|
||||||
final EmulatorActivity thisActivity = this;
|
|
||||||
int romId = getIntent().getIntExtra("romId", -1);
|
|
||||||
|
|
||||||
// busy wait until surface view is ready
|
|
||||||
try {
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
byte[] buffer = new byte[4096];
|
|
||||||
File saveFile = new File(saveFilePath);
|
|
||||||
FileInputStream fis = new FileInputStream(saveFile);
|
|
||||||
|
|
||||||
int read = 0;
|
|
||||||
while ((read = fis.read(buffer)) != -1) {
|
|
||||||
outputStream.write(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
fis.close();
|
|
||||||
|
|
||||||
saveFile.delete();
|
|
||||||
|
|
||||||
byte[] savedState = outputStream.toByteArray();
|
|
||||||
RomManager romManager = RomManager.getInstance(this);
|
|
||||||
romManager.updateLastPlayed(romId);
|
|
||||||
this.romMetadata = romManager.getRomMetadata(romId);
|
|
||||||
|
|
||||||
byte[] romData;
|
|
||||||
try {
|
|
||||||
romData = Util.readFile(romMetadata.getRomFile());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Util.showAlertDialogAndExit(this, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emulator.openSavedState(this.bios, romData, savedState);
|
|
||||||
|
|
||||||
createThreads();
|
|
||||||
|
|
||||||
boolean turbo = savedInstanceState.getBoolean("turbo");
|
|
||||||
|
|
||||||
turboButton.setPressed(turbo);
|
|
||||||
emulator.setTurbo(turbo);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Util.showAlertDialogAndExit(thisActivity, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
int romId = getIntent().getIntExtra("romId", -1);
|
|
||||||
if (-1 != romId) {
|
|
||||||
RomManager romManager = RomManager.getInstance(this);
|
|
||||||
romManager.updateLastPlayed(romId);
|
|
||||||
this.romMetadata = romManager.getRomMetadata(romId);
|
|
||||||
|
|
||||||
byte[] romData;
|
|
||||||
try {
|
|
||||||
romData = Util.readFile(romMetadata.getRomFile());
|
|
||||||
this.emulator.open(bios, romData, romMetadata.getBackupFile().getAbsolutePath(), skipBios);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Util.showAlertDialogAndExit(this, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
createThreads();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
super.onCreateOptionsMenu(menu);
|
|
||||||
getMenuInflater().inflate(R.menu.menu_emulator, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.action_load_rom:
|
|
||||||
doLoadRom();
|
|
||||||
return true;
|
|
||||||
case R.id.action_view_snapshots:
|
|
||||||
doViewSnapshots();
|
|
||||||
return true;
|
|
||||||
case R.id.action_save_snapshot:
|
|
||||||
doSaveSnapshot();
|
|
||||||
return true;
|
|
||||||
case R.id.action_set_library_image:
|
|
||||||
doSaveScreenshotToLibrary();
|
|
||||||
return true;
|
|
||||||
case R.id.action_settings:
|
|
||||||
Intent intent = new Intent(this, SettingsActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
||||||
menu.findItem(R.id.action_save_snapshot).setEnabled(isEmulatorRunning());
|
|
||||||
return super.onPrepareOptionsMenu(menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void pauseEmulation() {
|
|
||||||
if (null != emulationThread) {
|
|
||||||
emulationThread.pauseEmulation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resumeEmulation() {
|
|
||||||
if (null != emulationThread) {
|
|
||||||
emulationThread.resumeEmulation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
pauseEmulation();
|
|
||||||
|
|
||||||
if (this.romMetadata != null) {
|
|
||||||
if (this.romMetadata.getScreenshot() == null) {
|
|
||||||
// Save current screenshot
|
|
||||||
Bitmap screenshot = Bitmap.createBitmap(
|
|
||||||
emulator.getFrameBuffer(),
|
|
||||||
240,
|
|
||||||
160,
|
|
||||||
Bitmap.Config.RGB_565);
|
|
||||||
|
|
||||||
RomManager.getInstance(this).updateScreenshot(this.romMetadata.getId(), screenshot);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
killThreads();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
pauseEmulation();
|
|
||||||
screenView.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
screenView.onResume();
|
|
||||||
resumeEmulation();
|
|
||||||
audioPlayer.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doSaveScreenshotToLibrary() {
|
|
||||||
if (!isEmulatorRunning() || null == this.romMetadata) {
|
|
||||||
Toast.makeText(this, "No game is running!", Toast.LENGTH_LONG).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pauseEmulation();
|
|
||||||
|
|
||||||
Bitmap screenshot = Bitmap.createBitmap(
|
|
||||||
emulator.getFrameBuffer(),
|
|
||||||
240,
|
|
||||||
160,
|
|
||||||
Bitmap.Config.RGB_565);
|
|
||||||
|
|
||||||
RomManager.getInstance(this).updateScreenshot(this.romMetadata.getId(), screenshot);
|
|
||||||
|
|
||||||
|
|
||||||
resumeEmulation();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doSaveSnapshot() {
|
|
||||||
if (!isEmulatorRunning()) {
|
|
||||||
Toast.makeText(this, "No game is running!", Toast.LENGTH_LONG).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SnapshotManager snapshotManager = SnapshotManager.getInstance(this);
|
|
||||||
|
|
||||||
pauseEmulation();
|
|
||||||
try {
|
|
||||||
String gameCode = emulator.getGameCode();
|
|
||||||
String gameTitle = emulator.getGameTitle();
|
|
||||||
byte[] saveState = emulator.saveState();
|
|
||||||
Bitmap preview = Bitmap.createBitmap(emulator.getFrameBuffer(), 240, 160, Bitmap.Config.RGB_565);
|
|
||||||
|
|
||||||
snapshotManager.saveSnapshot(gameCode, gameTitle, preview, saveState);
|
|
||||||
Toast.makeText(this, "Snapshot saved", Toast.LENGTH_LONG).show();
|
|
||||||
|
|
||||||
} catch (EmulatorBindings.NativeBindingException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
Util.showAlertDialogAndExit(this, e);
|
|
||||||
} finally {
|
|
||||||
resumeEmulation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doViewSnapshots() {
|
|
||||||
Intent intent = new Intent(this, SnapshotPickerActivity.class);
|
|
||||||
if (emulator.isOpen()) {
|
|
||||||
intent.putExtra("gameCode", emulator.getGameCode());
|
|
||||||
}
|
|
||||||
startActivityForResult(intent, LOAD_SNAPSHOT_REQUESTCODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
boolean emulatorIsRunning = isEmulatorRunning();
|
|
||||||
|
|
||||||
if (!emulatorIsRunning) {
|
|
||||||
super.onBackPressed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
new AlertDialog.Builder(this)
|
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
|
||||||
.setTitle("Closing Emulator")
|
|
||||||
.setCancelable(false)
|
|
||||||
.setMessage("Are you sure you want to close the emulator?")
|
|
||||||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
EmulatorActivity.super.onBackPressed();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNeutralButton("Yes - but save snapshot", new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
doSaveSnapshot();
|
|
||||||
EmulatorActivity.super.onBackPressed();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(android.R.string.no, null)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,265 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.opengl.GLES20;
|
|
||||||
import android.opengl.GLSurfaceView;
|
|
||||||
import android.opengl.GLUtils;
|
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.FloatBuffer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
import javax.microedition.khronos.egl.EGLConfig;
|
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
|
||||||
|
|
||||||
public class ScreenRenderer implements GLSurfaceView.Renderer {
|
|
||||||
|
|
||||||
private ScreenTexture texture;
|
|
||||||
private boolean ready = false;
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
public ScreenRenderer(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateTexture(int[] frameBuffer) {
|
|
||||||
this.texture.update(frameBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initTextureIfNotInitialized() {
|
|
||||||
if (this.texture == null) {
|
|
||||||
this.texture = new ScreenTexture(this.context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
|
||||||
initTextureIfNotInitialized();
|
|
||||||
ready = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
|
||||||
gl.glViewport(0, 0, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDrawFrame(GL10 gl) {
|
|
||||||
this.texture.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReady() {
|
|
||||||
return ready;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColorCorrection(boolean colorCorrection) {
|
|
||||||
this.texture.setColorCorrection(colorCorrection);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private class to manage the screen texture rendering
|
|
||||||
*/
|
|
||||||
private class ScreenTexture {
|
|
||||||
int normalShaderProgram;
|
|
||||||
int colorCorrectionShaderProgram;
|
|
||||||
int currentShaderProgram;
|
|
||||||
int positionHandle;
|
|
||||||
int texCoordHandle;
|
|
||||||
int samplerHandle;
|
|
||||||
int textureId;
|
|
||||||
|
|
||||||
private FloatBuffer vertexBuffer;
|
|
||||||
private FloatBuffer textureBuffer;
|
|
||||||
private ByteBuffer indicesBuffer;
|
|
||||||
|
|
||||||
private Bitmap bitmap;
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
// square vertices
|
|
||||||
private float[] vertices = {
|
|
||||||
-1.0f, 1.0f, 0.0f, // top left
|
|
||||||
-1.0f, -1.0f, 0.0f, // bottom left
|
|
||||||
1.0f, -1.0f, 0.0f, // bottom right
|
|
||||||
1.0f, 1.0f, 0.0f, // top right
|
|
||||||
};
|
|
||||||
|
|
||||||
// texture space vertices
|
|
||||||
private float[] textureVertices = {
|
|
||||||
0.0f, 0.0f,
|
|
||||||
0.0f, 1.0f,
|
|
||||||
1.0f, 1.0f,
|
|
||||||
1.0f, 0.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
// two triangles compose a rect
|
|
||||||
private byte[] indicies = {
|
|
||||||
0, 1, 2,
|
|
||||||
0, 2, 3
|
|
||||||
};
|
|
||||||
|
|
||||||
public ScreenTexture(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
this.bitmap = Bitmap.createBitmap(240, 160, Bitmap.Config.RGB_565);
|
|
||||||
|
|
||||||
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
// create vertex array
|
|
||||||
vertexBuffer = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
|
||||||
vertexBuffer.put(vertices);
|
|
||||||
vertexBuffer.position(0);
|
|
||||||
|
|
||||||
// create texture coordinate array
|
|
||||||
textureBuffer = ByteBuffer.allocateDirect(textureVertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
|
||||||
textureBuffer.put(textureVertices);
|
|
||||||
textureBuffer.position(0);
|
|
||||||
|
|
||||||
// create triangle index array
|
|
||||||
indicesBuffer = ByteBuffer.allocateDirect(indicies.length).order(ByteOrder.nativeOrder());
|
|
||||||
indicesBuffer.put(indicies);
|
|
||||||
indicesBuffer.position(0);
|
|
||||||
|
|
||||||
textureId = createTexture();
|
|
||||||
|
|
||||||
String vertexShader = readShaderResource(R.raw.screen_texture_vertex_shader);
|
|
||||||
String normalFragmentShader = readShaderResource(R.raw.screen_texture_fragment_shader);
|
|
||||||
String colorCorrectionFragmentShader = readShaderResource(R.raw.screen_texture_color_correction_fragment_shader);
|
|
||||||
|
|
||||||
normalShaderProgram = createShaderProgram(vertexShader, normalFragmentShader);
|
|
||||||
colorCorrectionShaderProgram = createShaderProgram(vertexShader, colorCorrectionFragmentShader);
|
|
||||||
|
|
||||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this.context);
|
|
||||||
boolean colorCorrection = sharedPreferences.getBoolean("color_correction", false);
|
|
||||||
setColorCorrection(colorCorrection);
|
|
||||||
|
|
||||||
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setColorCorrection(boolean colorCorrection) {
|
|
||||||
|
|
||||||
if (colorCorrection) {
|
|
||||||
currentShaderProgram = colorCorrectionShaderProgram;
|
|
||||||
} else {
|
|
||||||
currentShaderProgram = normalShaderProgram;
|
|
||||||
}
|
|
||||||
|
|
||||||
// use the program
|
|
||||||
GLES20.glUseProgram(currentShaderProgram);
|
|
||||||
|
|
||||||
positionHandle = GLES20.glGetAttribLocation(currentShaderProgram, "a_position");
|
|
||||||
|
|
||||||
texCoordHandle = GLES20.glGetAttribLocation(currentShaderProgram, "a_texCoord");
|
|
||||||
|
|
||||||
samplerHandle = GLES20.glGetUniformLocation(currentShaderProgram, "s_texture");
|
|
||||||
|
|
||||||
|
|
||||||
// load the vertex position
|
|
||||||
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
|
|
||||||
GLES20.glEnableVertexAttribArray(positionHandle);
|
|
||||||
// load texture coordinate
|
|
||||||
GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, textureBuffer);
|
|
||||||
GLES20.glEnableVertexAttribArray(texCoordHandle);
|
|
||||||
|
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
|
|
||||||
GLES20.glEnableVertexAttribArray(positionHandle);
|
|
||||||
// load texture coordinate
|
|
||||||
GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, textureBuffer);
|
|
||||||
GLES20.glEnableVertexAttribArray(texCoordHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int compileShader(int type, String code) {
|
|
||||||
int shader = GLES20.glCreateShader(type);
|
|
||||||
GLES20.glShaderSource(shader, code);
|
|
||||||
GLES20.glCompileShader(shader);
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void update(int[] frameBuffer) {
|
|
||||||
bitmap.setPixels(frameBuffer, 0, 240, 0, 0, 240, 160);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int createShaderProgram(String vertexShaderCode, String fragmentShaderCode) {
|
|
||||||
int vertexShader = compileShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
|
|
||||||
int fragmentShader = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
|
|
||||||
|
|
||||||
int program = GLES20.glCreateProgram();
|
|
||||||
GLES20.glAttachShader(program, vertexShader);
|
|
||||||
GLES20.glAttachShader(program, fragmentShader);
|
|
||||||
|
|
||||||
GLES20.glLinkProgram(program);
|
|
||||||
|
|
||||||
return program;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int createTexture() {
|
|
||||||
int[] texturesIds = new int[1];
|
|
||||||
|
|
||||||
GLES20.glGenTextures(1, texturesIds, 0);
|
|
||||||
if (texturesIds[0] == GLES20.GL_FALSE) {
|
|
||||||
throw new RuntimeException("Error loading texture");
|
|
||||||
}
|
|
||||||
// bind the texture
|
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturesIds[0]);
|
|
||||||
|
|
||||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
|
|
||||||
|
|
||||||
// set the parameters
|
|
||||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
|
||||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
|
||||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
|
||||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
|
||||||
|
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
return texturesIds[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private String readShaderResource(int resourceId) {
|
|
||||||
InputStream in = context.getResources().openRawResource(resourceId);
|
|
||||||
String code;
|
|
||||||
try {
|
|
||||||
code = IOUtils.toString(in, StandardCharsets.UTF_8);
|
|
||||||
} catch (IOException e) {
|
|
||||||
code = "";
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void destroy() {
|
|
||||||
GLES20.glDeleteProgram(normalShaderProgram);
|
|
||||||
GLES20.glDeleteProgram(colorCorrectionShaderProgram);
|
|
||||||
int[] textures = {textureId};
|
|
||||||
GLES20.glDeleteTextures(1, textures, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render() {
|
|
||||||
// use the shader program
|
|
||||||
GLES20.glUseProgram(currentShaderProgram);
|
|
||||||
|
|
||||||
// clear the color buffer
|
|
||||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
// bind the texture
|
|
||||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
|
|
||||||
|
|
||||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
|
|
||||||
|
|
||||||
// Set the sampler texture unit to 0
|
|
||||||
GLES20.glUniform1i(samplerHandle, 0);
|
|
||||||
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, 6, GLES20.GL_UNSIGNED_BYTE, indicesBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.opengl.GLSurfaceView;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import com.mrmichel.rustboyadvance.IFrameRenderer;
|
|
||||||
|
|
||||||
public class ScreenView extends GLSurfaceView implements SharedPreferences.OnSharedPreferenceChangeListener, IFrameRenderer {
|
|
||||||
private ScreenRenderer mRenderer;
|
|
||||||
|
|
||||||
public ScreenView(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScreenView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
this.setEGLContextClientVersion(2);
|
|
||||||
this.setPreserveEGLContextOnPause(true);
|
|
||||||
|
|
||||||
SharedPreferences sharedPreferences =
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext());
|
|
||||||
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
|
|
||||||
|
|
||||||
mRenderer = new ScreenRenderer(getContext());
|
|
||||||
this.setRenderer(mRenderer);
|
|
||||||
this.setRenderMode(RENDERMODE_WHEN_DIRTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScreenRenderer getRenderer() {
|
|
||||||
return mRenderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
|
||||||
if (key.equals("color_correction")) {
|
|
||||||
boolean colorCorrection = sharedPreferences.getBoolean("color_correction", false);
|
|
||||||
mRenderer.setColorCorrection(colorCorrection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderFrame(int[] frameBuffer) {
|
|
||||||
mRenderer.updateTexture(frameBuffer);
|
|
||||||
requestRender();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.ActionBar;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.preference.PreferenceFragmentCompat;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
|
|
||||||
public class SettingsActivity extends AppCompatActivity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_settings);
|
|
||||||
getSupportFragmentManager()
|
|
||||||
.beginTransaction()
|
|
||||||
.replace(R.id.settings, new SettingsFragment())
|
|
||||||
.commit();
|
|
||||||
ActionBar actionBar = getSupportActionBar();
|
|
||||||
if (actionBar != null) {
|
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SettingsFragment extends PreferenceFragmentCompat {
|
|
||||||
@Override
|
|
||||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
|
||||||
setPreferencesFromResource(R.xml.app_preferences, rootKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import androidx.preference.PreferenceFragment;
|
|
||||||
import androidx.preference.PreferenceFragmentCompat;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
|
|
||||||
|
|
||||||
public class SettingsFragment extends PreferenceFragmentCompat {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
|
||||||
setPreferencesFromResource(R.xml.app_preferences, rootKey);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,148 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.ConfigurationInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
import com.mrmichel.rustdroid_emu.ui.library.RomListActivity;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
public class SplashActivity extends AppCompatActivity {
|
|
||||||
|
|
||||||
private static final String TAG = "SplashActivity";
|
|
||||||
private static final int REQUEST_PERMISSION_CODE = 55;
|
|
||||||
private static final int BIOS_REQUEST_CODE = 66;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
||||||
if (requestCode == REQUEST_PERMISSION_CODE) {
|
|
||||||
if (permissions.length == 1 && permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
|
||||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
initCacheBios();
|
|
||||||
} else {
|
|
||||||
Toast.makeText(this, "WRITE_EXTERNAL_STORAGE not granted, need to quit", Toast.LENGTH_LONG).show();
|
|
||||||
this.finishAffinity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkOpenGLES20() {
|
|
||||||
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
|
||||||
ConfigurationInfo configurationInfo = am.getDeviceConfigurationInfo();
|
|
||||||
if (configurationInfo.reqGlEsVersion >= 0x20000) {
|
|
||||||
// Supported
|
|
||||||
} else {
|
|
||||||
new AlertDialog.Builder(this)
|
|
||||||
.setTitle("OpenGLES 2")
|
|
||||||
.setMessage("Your device doesn't support GLES20. reqGLEsVersion = " + configurationInfo.reqGlEsVersion)
|
|
||||||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
finishAffinity();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.splash_activity);
|
|
||||||
|
|
||||||
checkOpenGLES20();
|
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission(this,
|
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
|
||||||
|
|
||||||
// No explanation needed; request the permission
|
|
||||||
ActivityCompat.requestPermissions(this
|
|
||||||
,
|
|
||||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
|
|
||||||
REQUEST_PERMISSION_CODE);
|
|
||||||
} else {
|
|
||||||
// Permission has already been granted
|
|
||||||
initCacheBios();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cacheBiosInAppFiles(byte[] bios) throws IOException {
|
|
||||||
FileOutputStream fos = openFileOutput("gba_bios.bin", MODE_PRIVATE);
|
|
||||||
fos.write(bios);
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
if (requestCode == BIOS_REQUEST_CODE) {
|
|
||||||
Uri uri = data.getData();
|
|
||||||
try {
|
|
||||||
InputStream inputStream = getContentResolver().openInputStream(uri);
|
|
||||||
byte[] bios = new byte[inputStream.available()];
|
|
||||||
inputStream.read(bios);
|
|
||||||
inputStream.close();
|
|
||||||
|
|
||||||
cacheBiosInAppFiles(bios);
|
|
||||||
|
|
||||||
startLibraryActivity(bios);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "can't open bios file");
|
|
||||||
this.finishAffinity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "get error for request code " + requestCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initCacheBios() {
|
|
||||||
try {
|
|
||||||
FileInputStream fis = openFileInput("gba_bios.bin");
|
|
||||||
byte[] bios = new byte[fis.available()];
|
|
||||||
fis.read(bios);
|
|
||||||
startLibraryActivity(bios);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
|
||||||
intent.setType("*/*");
|
|
||||||
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
|
|
||||||
intent.putExtra(Intent.EXTRA_TITLE, "Please load the gba_bios.bin file");
|
|
||||||
startActivityForResult(intent, BIOS_REQUEST_CODE);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "Got IOException while reading from bios");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startLibraryActivity(byte[] bios) {
|
|
||||||
Intent intent = new Intent(this, RomListActivity.class);
|
|
||||||
intent.putExtra("bios", bios);
|
|
||||||
startActivity(intent);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,261 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui.library;
|
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.GridView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.documentfile.provider.DocumentFile;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
import com.mrmichel.rustdroid_emu.Util;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.RomManager;
|
|
||||||
import com.mrmichel.rustdroid_emu.ui.SettingsActivity;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class RomListActivity extends AppCompatActivity {
|
|
||||||
|
|
||||||
private static final String TAG = "RomListActivity";
|
|
||||||
|
|
||||||
private static final int REQUEST_IMPORT_ROM = 100;
|
|
||||||
private static final int REQUEST_IMPORT_DIR = 101;
|
|
||||||
private static final int REQUEST_SET_IMAGE = 102;
|
|
||||||
private static final int REQUEST_IMPORT_SAVE = 103;
|
|
||||||
|
|
||||||
private static String[] ALLOWED_EXTENSIONS = {"gba", "zip", "bin"};
|
|
||||||
|
|
||||||
private GridView mGridView;
|
|
||||||
private RomListItemAdapter itemAdapter;
|
|
||||||
|
|
||||||
private RomManager.RomMetadataEntry selectedEntry;
|
|
||||||
|
|
||||||
private byte[] bios;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_rom_list);
|
|
||||||
|
|
||||||
this.bios = getIntent().getByteArrayExtra("bios");
|
|
||||||
|
|
||||||
mGridView = findViewById(R.id.gridview_rom_list);
|
|
||||||
|
|
||||||
final RomManager romManager = RomManager.getInstance(this);
|
|
||||||
|
|
||||||
ArrayList<RomManager.RomMetadataEntry> entries = romManager.getAllRomMetaData();
|
|
||||||
|
|
||||||
itemAdapter = new RomListItemAdapter(this, entries);
|
|
||||||
mGridView.setAdapter(itemAdapter);
|
|
||||||
|
|
||||||
final Context context = this;
|
|
||||||
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
||||||
RomManager.RomMetadataEntry entry = itemAdapter.getItem(position);
|
|
||||||
romManager.updateLastPlayed(entry.getId());
|
|
||||||
Util.startEmulator(context, bios, entry.getId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
registerForContextMenu(mGridView);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
|
||||||
if (v.getId() == R.id.gridview_rom_list) {
|
|
||||||
MenuInflater inflater = getMenuInflater();
|
|
||||||
inflater.inflate(R.menu.menu_context_rom, menu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onContextItemSelected(@NonNull MenuItem item) {
|
|
||||||
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
|
|
||||||
|
|
||||||
RomManager romManager = RomManager.getInstance(this);
|
|
||||||
|
|
||||||
RomManager.RomMetadataEntry entry = itemAdapter.getItem(menuInfo.position);
|
|
||||||
|
|
||||||
selectedEntry = entry;
|
|
||||||
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.action_play:
|
|
||||||
romManager.updateLastPlayed(entry.getId());
|
|
||||||
Util.startEmulator(this, this.bios, entry.getId());
|
|
||||||
this.itemAdapter.notifyDataSetChanged();
|
|
||||||
return true;
|
|
||||||
case R.id.action_delete:
|
|
||||||
romManager.deleteRomMetadata(itemAdapter.getItem(menuInfo.position));
|
|
||||||
return true;
|
|
||||||
case R.id.action_set_screenshot:
|
|
||||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
|
||||||
intent.setType("image/*");
|
|
||||||
intent.putExtra("romId", entry.getId());
|
|
||||||
startActivityForResult(intent, REQUEST_SET_IMAGE);
|
|
||||||
return true;
|
|
||||||
case R.id.action_export_save_file:
|
|
||||||
File backupFile = entry.getBackupFile();
|
|
||||||
try {
|
|
||||||
Util.shareFile(this, backupFile, "Sending " + backupFile.getName());
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Util.showAlertDialog(this, e);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
case R.id.action_import_save_file:
|
|
||||||
intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
||||||
intent.setType("*/*");
|
|
||||||
startActivityForResult(intent, REQUEST_IMPORT_SAVE);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onContextItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
super.onCreateOptionsMenu(menu);
|
|
||||||
getMenuInflater().inflate(R.menu.menu_rom_list, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.action_import_rom:
|
|
||||||
doImportRom();
|
|
||||||
return true;
|
|
||||||
case R.id.action_import_directory:
|
|
||||||
doImportDirectory();
|
|
||||||
return true;
|
|
||||||
case R.id.action_settings:
|
|
||||||
Intent intent = new Intent(this, SettingsActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String getFileExtension(String name) {
|
|
||||||
if (name == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
int i = name.lastIndexOf('.');
|
|
||||||
String ext = i > 0 ? name.substring(i + 1) : "";
|
|
||||||
return ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
ContentResolver contentResolver = getContentResolver();
|
|
||||||
RomManager romManager = RomManager.getInstance(this);
|
|
||||||
switch (requestCode) {
|
|
||||||
case REQUEST_IMPORT_ROM:
|
|
||||||
Uri uri = data.getData();
|
|
||||||
contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
||||||
|
|
||||||
romManager.importRom(DocumentFile.fromSingleUri(this, uri));
|
|
||||||
|
|
||||||
break;
|
|
||||||
case REQUEST_IMPORT_DIR:
|
|
||||||
|
|
||||||
Uri treeUri = data.getData();
|
|
||||||
|
|
||||||
contentResolver.takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
|
||||||
|
|
||||||
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
|
|
||||||
|
|
||||||
for (DocumentFile file : pickedDir.listFiles()) {
|
|
||||||
|
|
||||||
String extension = getFileExtension(file.getName());
|
|
||||||
if (Arrays.asList(ALLOWED_EXTENSIONS).contains(extension)) {
|
|
||||||
Log.d(TAG, "Importing ROM " + file.getName() + " with size " + file.length() + " and type: " + extension);
|
|
||||||
romManager.importRom(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case REQUEST_SET_IMAGE:
|
|
||||||
int romId = selectedEntry.getId();
|
|
||||||
|
|
||||||
Bitmap bitmap;
|
|
||||||
try {
|
|
||||||
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData());
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Util.showAlertDialogAndExit(this, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(TAG, "found bitmap");
|
|
||||||
romManager.updateScreenshot(romId, bitmap);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case REQUEST_IMPORT_SAVE:
|
|
||||||
try {
|
|
||||||
InputStream inputStream = getContentResolver().openInputStream(data.getData());
|
|
||||||
byte[] saveData = new byte[inputStream.available()];
|
|
||||||
inputStream.read(saveData);
|
|
||||||
inputStream.close();
|
|
||||||
|
|
||||||
File file = selectedEntry.getBackupFile();
|
|
||||||
Log.d(TAG, "Saving imported save to " + file.getAbsolutePath());
|
|
||||||
FileOutputStream fos = new FileOutputStream(file);
|
|
||||||
fos.write(saveData);
|
|
||||||
fos.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Util.showAlertDialogAndExit(this, e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
this.itemAdapter.notifyDataSetChanged();
|
|
||||||
mGridView.setAdapter(new RomListItemAdapter(this, romManager.getAllRomMetaData()));
|
|
||||||
mGridView.invalidate();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "got error for request code " + requestCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void doImportRom() {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
||||||
intent.setType("*/*");
|
|
||||||
Log.d(TAG, "pressed import rom");
|
|
||||||
Intent chooser = Intent.createChooser(intent, "choose GBA rom file to import");
|
|
||||||
startActivityForResult(chooser, REQUEST_IMPORT_ROM);
|
|
||||||
}
|
|
||||||
|
|
||||||
void doImportDirectory() {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
|
||||||
startActivityForResult(intent, REQUEST_IMPORT_DIR);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui.library;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.RomManager.RomMetadataEntry;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class RomListItemAdapter extends ArrayAdapter<RomMetadataEntry> {
|
|
||||||
|
|
||||||
Context context;
|
|
||||||
ArrayList<RomMetadataEntry> items;
|
|
||||||
|
|
||||||
public RomListItemAdapter(Context context, ArrayList<RomMetadataEntry> romEntries) {
|
|
||||||
super(context, 0, romEntries);
|
|
||||||
this.context = context;
|
|
||||||
this.items = romEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
|
||||||
RomMetadataEntry item = getItem(position);
|
|
||||||
|
|
||||||
if (convertView == null) {
|
|
||||||
convertView = LayoutInflater.from(getContext()).inflate(R.layout.rom_item, parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageView screenshotImageView = convertView.findViewById(R.id.imageview_screenshot);
|
|
||||||
|
|
||||||
Bitmap screenshot = item.getScreenshot();
|
|
||||||
if (screenshot != null) {
|
|
||||||
screenshotImageView.setImageBitmap(screenshot);
|
|
||||||
} else {
|
|
||||||
screenshotImageView.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TextView tvTitle = convertView.findViewById(R.id.textview_game_title);
|
|
||||||
tvTitle.setText(item.getName());
|
|
||||||
|
|
||||||
return convertView;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui.snapshots;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.core.Snapshot;
|
|
||||||
|
|
||||||
public interface ISnapshotListener {
|
|
||||||
|
|
||||||
public void onSnapshotClicked(Snapshot snapshot);
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui.snapshots;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.Snapshot;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class SnapshotItemAdapter extends ArrayAdapter<Snapshot> {
|
|
||||||
|
|
||||||
Context context;
|
|
||||||
ArrayList<Snapshot> items;
|
|
||||||
|
|
||||||
public SnapshotItemAdapter(Context context, ArrayList<Snapshot> items) {
|
|
||||||
super(context, 0, items);
|
|
||||||
this.context = context;
|
|
||||||
this.items = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return items.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
|
||||||
Snapshot snapshot = getItem(position);
|
|
||||||
|
|
||||||
if (convertView == null) {
|
|
||||||
convertView = LayoutInflater.from(getContext()).inflate(R.layout.snapshot_item, parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageView preview = (ImageView) convertView.findViewById(R.id.imageview_snapshot_preview);
|
|
||||||
preview.setImageBitmap(snapshot.getPreview());
|
|
||||||
|
|
||||||
|
|
||||||
TextView tvTitle = (TextView) convertView.findViewById(R.id.textview_snapshot_title);
|
|
||||||
tvTitle.setText(snapshot.getGameTitle());
|
|
||||||
|
|
||||||
TextView tvTimestamp = (TextView) convertView.findViewById(R.id.textview_snapshot_timestmap);
|
|
||||||
Timestamp timestamp = new Timestamp(snapshot.getTimestamp());
|
|
||||||
tvTimestamp.setText(timestamp.toString());
|
|
||||||
|
|
||||||
return convertView;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui.snapshots;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.GridView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.Snapshot;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.SnapshotManager;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class SnapshotListFragment extends Fragment {
|
|
||||||
|
|
||||||
private static final String TAG = "SnapshotListFragment";
|
|
||||||
|
|
||||||
private GridView mGridView;
|
|
||||||
|
|
||||||
private ArrayList<Snapshot> snapshots;
|
|
||||||
|
|
||||||
private ISnapshotListener mListener;
|
|
||||||
|
|
||||||
public SnapshotListFragment() {
|
|
||||||
super();
|
|
||||||
mListener = new ISnapshotListener() {
|
|
||||||
@Override
|
|
||||||
public void onSnapshotClicked(Snapshot snapshot) {
|
|
||||||
Log.d(TAG, "stub onSnapshotClicked");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public SnapshotListFragment(ISnapshotListener listener) {
|
|
||||||
super();
|
|
||||||
mListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SnapshotListFragment newInstance(ISnapshotListener listener) {
|
|
||||||
return new SnapshotListFragment(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateContextMenu(@NonNull ContextMenu menu, @NonNull View v, @Nullable ContextMenu.ContextMenuInfo menuInfo) {
|
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
|
||||||
if (v.getId() == R.id.gridview_snapshots) {
|
|
||||||
MenuInflater inflater = getActivity().getMenuInflater();
|
|
||||||
inflater.inflate(R.menu.menu_context_snapshot, menu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onContextItemSelected(@NonNull MenuItem item) {
|
|
||||||
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
|
||||||
|
|
||||||
Snapshot snapshot = snapshots.get(menuInfo.position);
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.action_delete:
|
|
||||||
SnapshotManager.getInstance(getContext()).deleteSnapshot(snapshot);
|
|
||||||
snapshots.remove(menuInfo.position);
|
|
||||||
|
|
||||||
SnapshotItemAdapter adapter = new SnapshotItemAdapter(getContext(), snapshots);
|
|
||||||
mGridView.setAdapter(adapter);
|
|
||||||
mGridView.invalidate();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onContextItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
|
||||||
return inflater.inflate(R.layout.snapshot_list_fragment, container, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
Bundle args = getArguments();
|
|
||||||
|
|
||||||
SnapshotManager manager = SnapshotManager.getInstance(getContext());
|
|
||||||
|
|
||||||
String gameCode;
|
|
||||||
if (args != null && (gameCode = args.getString("gameCode")) != null) {
|
|
||||||
snapshots = manager.getByGameCode(gameCode);
|
|
||||||
} else {
|
|
||||||
snapshots = manager.getAllSnapshots();
|
|
||||||
}
|
|
||||||
|
|
||||||
mGridView = getActivity().findViewById(R.id.gridview_snapshots);
|
|
||||||
SnapshotItemAdapter adapter = new SnapshotItemAdapter(getContext(), snapshots);
|
|
||||||
mGridView.setAdapter(adapter);
|
|
||||||
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
||||||
final Snapshot snapshot = snapshots.get(position);
|
|
||||||
mListener.onSnapshotClicked(snapshot);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
registerForContextMenu(mGridView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu.ui.snapshots;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import com.mrmichel.rustdroid_emu.R;
|
|
||||||
import com.mrmichel.rustdroid_emu.core.Snapshot;
|
|
||||||
|
|
||||||
public class SnapshotPickerActivity extends AppCompatActivity implements ISnapshotListener {
|
|
||||||
|
|
||||||
static Snapshot pickedSnapshot;
|
|
||||||
|
|
||||||
public static Snapshot obtainPickedSnapshot() {
|
|
||||||
Snapshot ret = pickedSnapshot;
|
|
||||||
pickedSnapshot = null;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.snapshot_picker_activity);
|
|
||||||
if (savedInstanceState == null) {
|
|
||||||
getSupportFragmentManager().beginTransaction()
|
|
||||||
.replace(R.id.container, SnapshotListFragment.newInstance(this))
|
|
||||||
.commitNow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSnapshotClicked(Snapshot snapshot) {
|
|
||||||
Intent data = new Intent();
|
|
||||||
pickedSnapshot = snapshot;
|
|
||||||
setResult(RESULT_OK, data);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 3.7 KiB |
|
@ -1,5 +0,0 @@
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
<solid android:color="@color/colorAccent" />
|
|
||||||
<corners android:radius="500dp" />
|
|
||||||
</shape>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.EmulatorActivity">
|
|
||||||
|
|
||||||
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/fragment_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<include layout="@layout/content_emulator" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
|
@ -1,123 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:keepScreenOn="true"
|
|
||||||
android:background="@color/gbaBackground"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
|
|
||||||
<com.mrmichel.rustdroid_emu.ui.ScreenView
|
|
||||||
android:id="@+id/gba_view"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintDimensionRatio="V, 3:2"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_bias="0.0" />
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/include"
|
|
||||||
layout="@layout/dpad"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:alpha=".5"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonB"
|
|
||||||
style="@style/Widget.AppCompat.Button.Small"
|
|
||||||
android:layout_width="52dp"
|
|
||||||
android:layout_height="54dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginBottom="32dp"
|
|
||||||
android:background="@drawable/round_button"
|
|
||||||
android:text="B"
|
|
||||||
android:alpha=".5"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/buttonA"
|
|
||||||
tools:text="B" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonA"
|
|
||||||
style="@style/Widget.AppCompat.Button.Small"
|
|
||||||
android:layout_width="52dp"
|
|
||||||
android:layout_height="54dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginBottom="48dp"
|
|
||||||
android:background="@drawable/round_button"
|
|
||||||
android:text="A"
|
|
||||||
android:alpha=".5"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
tools:text="A" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/bSelect"
|
|
||||||
style="@style/Widget.AppCompat.Button.Small"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:text="select"
|
|
||||||
android:textSize="8dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/bStart"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/bStart"
|
|
||||||
style="@style/Widget.AppCompat.Button.Small"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginBottom="20dp"
|
|
||||||
android:text="start"
|
|
||||||
android:textSize="8dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/include"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonL"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:text="L"
|
|
||||||
android:alpha=".5"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonR"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:text="R"
|
|
||||||
android:alpha=".5"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<ToggleButton
|
|
||||||
android:id="@+id/tbTurbo"
|
|
||||||
android:layout_width="98dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:checked="false"
|
|
||||||
android:text="Turbo Mode"
|
|
||||||
android:textOff="Turbo OFF"
|
|
||||||
android:textOn="Turbo ON"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/bSelect"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@color/gbaBackground"
|
|
||||||
tools:context=".ui.EmulatorActivity">
|
|
||||||
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/fragment_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<include layout="@layout/content_emulator" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
|
@ -1,47 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
tools:context=".ui.library.RomListActivity">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:id="@+id/app_bar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/app_bar_height"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
android:theme="@style/AppTheme.AppBarOverlay">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
|
||||||
android:id="@+id/toolbar_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
app:contentScrim="?attr/colorAccent"
|
|
||||||
app:layout_scrollFlags="scroll|exitUntilCollapsed"
|
|
||||||
app:toolbarId="@+id/toolbar">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
app:layout_collapseMode="pin"
|
|
||||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
android:id="@+id/fab"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="@dimen/fab_margin"
|
|
||||||
app:layout_anchor="@id/app_bar"
|
|
||||||
app:layout_anchorGravity="bottom|end"
|
|
||||||
app:srcCompat="@android:drawable/ic_media_play" />
|
|
||||||
|
|
||||||
<include layout="@layout/content_rom_list" />
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/settings"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
</LinearLayout>
|
|
|
@ -1,124 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:keepScreenOn="true"
|
|
||||||
android:background="@color/gbaBackground"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/include"
|
|
||||||
layout="@layout/dpad"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginBottom="64dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<com.mrmichel.rustdroid_emu.ui.ScreenView
|
|
||||||
android:id="@+id/gba_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginTop="32dp"
|
|
||||||
app:layout_constraintDimensionRatio="H, 3:2"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.517"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonB"
|
|
||||||
style="@style/Widget.AppCompat.Button.Small"
|
|
||||||
android:layout_width="52dp"
|
|
||||||
android:layout_height="54dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginEnd="12dp"
|
|
||||||
android:background="@drawable/round_button"
|
|
||||||
android:text="B"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/buttonA"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/include"
|
|
||||||
tools:text="B" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonA"
|
|
||||||
style="@style/Widget.AppCompat.Button.Small"
|
|
||||||
android:layout_width="52dp"
|
|
||||||
android:layout_height="54dp"
|
|
||||||
android:layout_marginEnd="24dp"
|
|
||||||
android:background="@drawable/round_button"
|
|
||||||
android:text="A"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/include"
|
|
||||||
tools:text="A" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/bSelect"
|
|
||||||
style="@style/Widget.AppCompat.Button.Small"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="120dp"
|
|
||||||
android:layout_marginEnd="12dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:background="@drawable/round_button"
|
|
||||||
android:text="select"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/bStart"
|
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/include" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/bStart"
|
|
||||||
style="@style/Widget.AppCompat.Button.Small"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:background="@drawable/round_button"
|
|
||||||
android:text="start"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/bSelect" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonL"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="2dp"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:text="L"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/gba_view" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonR"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:layout_marginEnd="2dp"
|
|
||||||
android:text="R"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/gba_view" />
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
android:id="@+id/tbTurbo"
|
|
||||||
android:layout_width="98dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="24dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:checked="false"
|
|
||||||
android:text="Turbo Mode"
|
|
||||||
android:textOff="Turbo OFF"
|
|
||||||
android:textOn="Turbo ON"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvFPS"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/gba_view"
|
|
||||||
tools:layout_editor_absoluteX="176dp" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
|
||||||
tools:context=".ui.library.RomListActivity"
|
|
||||||
tools:showIn="@layout/activity_rom_list">
|
|
||||||
|
|
||||||
<GridView
|
|
||||||
android:id="@+id/gridview_rom_list"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:numColumns="auto_fit"
|
|
||||||
tools:context=".ui.library.RomListActivity"></GridView>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
|
@ -1,58 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/bDpadUp"
|
|
||||||
android:layout_width="48dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginStart="48dp"
|
|
||||||
android:layout_marginEnd="48dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@android:drawable/arrow_up_float" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/bDpadRight"
|
|
||||||
android:layout_width="48dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginStart="48dp"
|
|
||||||
android:layout_marginTop="48dp"
|
|
||||||
android:layout_marginBottom="48dp"
|
|
||||||
android:rotation="90"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/bDpadLeft"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@android:drawable/arrow_up_float" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/bDpadLeft"
|
|
||||||
android:layout_width="48dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginTop="48dp"
|
|
||||||
android:layout_marginEnd="48dp"
|
|
||||||
android:layout_marginBottom="48dp"
|
|
||||||
android:rotation="90"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/bDpadRight"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@android:drawable/arrow_down_float" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/bDpadDown"
|
|
||||||
android:layout_width="48dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginStart="48dp"
|
|
||||||
android:layout_marginTop="48dp"
|
|
||||||
android:layout_marginEnd="48dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/bDpadUp"
|
|
||||||
app:srcCompat="@android:drawable/arrow_down_float" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -1,38 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:padding="5dp"
|
|
||||||
>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageview_screenshot"
|
|
||||||
android:layout_width="180dp"
|
|
||||||
android:layout_height="120dp"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_margin="5dp"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:background="@drawable/round_button"
|
|
||||||
app:srcCompat="@mipmap/ic_launcher" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textview_game_title"
|
|
||||||
android:layout_width="180dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingBottom="4dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
android:text="Cool Game - III"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:layout_below="@+id/imageview_screenshot"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
|
@ -1,39 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageview_snapshot_preview"
|
|
||||||
android:layout_width="180dp"
|
|
||||||
android:layout_height="120dp"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
app:srcCompat="@mipmap/ic_launcher" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textview_snapshot_title"
|
|
||||||
android:layout_width="180dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Cool Game - III"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textview_snapshot_timestmap"
|
|
||||||
android:layout_width="180dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="1.1.2020"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:textSize="12sp"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
|
@ -1,42 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@color/colorAccent"
|
|
||||||
tools:context=".ui.snapshots.SnapshotListFragment">
|
|
||||||
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/edittext_snapshot_filter"
|
|
||||||
style="@style/Widget.AppCompat.EditText"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:ems="10"
|
|
||||||
android:hint="Search.."
|
|
||||||
android:inputType="textFilter|textPersonName"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<GridView
|
|
||||||
android:id="@+id/gridview_snapshots"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:numColumns="auto_fit"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/edittext_snapshot_filter"
|
|
||||||
tools:context=".ui.snapshots.SnapshotListFragment"
|
|
||||||
tools:showIn="@layout/snapshot_list_fragment">
|
|
||||||
|
|
||||||
</GridView>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.snapshots.SnapshotPickerActivity" />
|
|
|
@ -1,25 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.SplashActivity">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageView2"
|
|
||||||
android:layout_width="240dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="80dp"
|
|
||||||
android:layout_marginTop="285dp"
|
|
||||||
android:layout_marginEnd="80dp"
|
|
||||||
android:layout_marginBottom="286dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="1.0"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@mipmap/ic_launcher" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -1,41 +0,0 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
|
|
||||||
android:id="@+id/menu_context_rom"
|
|
||||||
tools:context="com.mrmichel.rustdroid_emu.ui.library.RomListActivity">
|
|
||||||
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_play"
|
|
||||||
android:icon="@android:drawable/ic_media_play"
|
|
||||||
android:title="@string/action_load_rom"
|
|
||||||
app:showAsAction="ifRoom|withText" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_set_screenshot"
|
|
||||||
android:title="@string/action_set_screenshot" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_view_snapshots"
|
|
||||||
android:title="@string/action_view_snapshot"
|
|
||||||
app:showAsAction="withText" />
|
|
||||||
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_delete"
|
|
||||||
android:icon="@android:drawable/ic_menu_delete"
|
|
||||||
android:title="@string/action_delete"
|
|
||||||
app:showAsAction="ifRoom|withText" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_import_save_file"
|
|
||||||
android:icon="@android:drawable/ic_menu_save"
|
|
||||||
android:title="Import Save File" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_export_save_file"
|
|
||||||
android:icon="@android:drawable/ic_menu_share"
|
|
||||||
android:title="Export Save File" />
|
|
||||||
|
|
||||||
</menu>
|
|
|
@ -1,12 +0,0 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
>
|
|
||||||
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_delete"
|
|
||||||
android:icon="@android:drawable/ic_menu_delete"
|
|
||||||
android:title="@string/action_delete"
|
|
||||||
app:showAsAction="ifRoom|withText" />
|
|
||||||
</menu>
|
|
|
@ -1,45 +0,0 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
tools:context="com.mrmichel.rustdroid_emu.ui.EmulatorActivity">
|
|
||||||
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_load_rom"
|
|
||||||
android:orderInCategory="1"
|
|
||||||
android:title="@string/action_load_rom" />
|
|
||||||
|
|
||||||
<!-- <item-->
|
|
||||||
<!-- android:title="@string/submenu_snapshots"-->
|
|
||||||
<!-- android:orderInCategory="2"-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- <menu>-->
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_save_snapshot"
|
|
||||||
android:enabled="false"
|
|
||||||
android:icon="@android:drawable/ic_menu_save"
|
|
||||||
android:orderInCategory="100"
|
|
||||||
android:title="@string/action_save_snapshot"
|
|
||||||
app:showAsAction="ifRoom|withText" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_view_snapshots"
|
|
||||||
android:icon="@android:drawable/ic_menu_gallery"
|
|
||||||
android:orderInCategory="101"
|
|
||||||
android:title="@string/action_view_snapshot"
|
|
||||||
app:showAsAction="ifRoom|withText" />
|
|
||||||
<!-- </menu>-->
|
|
||||||
<!-- </item>-->
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_set_library_image"
|
|
||||||
android:icon="@android:drawable/ic_menu_camera"
|
|
||||||
android:title="@string/action_set_library_image" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_settings"
|
|
||||||
android:menuCategory="system"
|
|
||||||
android:orderInCategory="100"
|
|
||||||
android:title="@string/action_settings"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
|
|
||||||
</menu>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
tools:context="com.mrmichel.rustdroid_emu.ui.library.RomListActivity">
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:title="@string/action_load_rom"
|
|
||||||
android:id="@+id/action_import_rom" />
|
|
||||||
<item
|
|
||||||
android:title="@string/action_import_directory"
|
|
||||||
android:id="@+id/action_import_directory" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_settings"
|
|
||||||
android:orderInCategory="100"
|
|
||||||
android:title="@string/action_settings"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
</menu>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
tools:context="com.mrmichel.rustdroid_emu.ui.snapshots.SnapshotListFragment">
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_settings"
|
|
||||||
android:orderInCategory="100"
|
|
||||||
android:title="@string/action_settings"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
</menu>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@color/ic_launcher_background"/>
|
|
||||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
|
||||||
</adaptive-icon>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@color/ic_launcher_background"/>
|
|
||||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
|
||||||
</adaptive-icon>
|
|
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 6 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 20 KiB |
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
Port of byuu's color correction shader as described in https://byuu.net/video/color-emulation
|
|
||||||
*/
|
|
||||||
|
|
||||||
precision mediump float;
|
|
||||||
|
|
||||||
varying vec2 v_texCoord;
|
|
||||||
uniform sampler2D s_texture;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
float lcdGamma = 4.0, outGamma = 2.2;
|
|
||||||
|
|
||||||
vec4 color = texture2D( s_texture, v_texCoord );
|
|
||||||
|
|
||||||
color.rgb = pow(color.rgb, vec3(lcdGamma));
|
|
||||||
gl_FragColor.r = pow(( 0.0 * color.b + 50.0 * color.g + 255.0 * color.r) / 255.0, 1.0 / outGamma) * 255.0 / 280.0;
|
|
||||||
gl_FragColor.g = pow(( 30.0 * color.b + 230.0 * color.g + 10.0 * color.r) / 255.0, 1.0 / outGamma) * 255.0 / 280.0;
|
|
||||||
gl_FragColor.b = pow((220.0 * color.b + 10.0 * color.g + 50.0 * color.r) / 255.0, 1.0 / outGamma) * 255.0 / 280.0;
|
|
||||||
gl_FragColor.a = 1.0;
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
precision mediump float;
|
|
||||||
varying vec2 v_texCoord;
|
|
||||||
uniform sampler2D s_texture;
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 color = texture2D( s_texture, v_texCoord );
|
|
||||||
gl_FragColor = color;
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
attribute vec4 a_position;
|
|
||||||
attribute vec2 a_texCoord;
|
|
||||||
varying vec2 v_texCoord;
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
gl_Position = a_position;
|
|
||||||
v_texCoord = a_texCoord;
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<color name="colorPrimary">#6c45c0</color>
|
|
||||||
<color name="colorPrimaryDark">#331573</color>
|
|
||||||
<color name="colorAccent">#ad8cf4</color>
|
|
||||||
<color name="gbaBackground">#6c45c0</color>
|
|
||||||
</resources>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<resources>
|
|
||||||
<dimen name="fab_margin">16dp</dimen>
|
|
||||||
<dimen name="app_bar_height">180dp</dimen>
|
|
||||||
<dimen name="text_margin">16dp</dimen>
|
|
||||||
</resources>
|
|
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<color name="ic_launcher_background">#A4A5DF</color>
|
|
||||||
</resources>
|
|
|
@ -1,25 +0,0 @@
|
||||||
<resources>
|
|
||||||
<string name="app_name">RustdroidAdvance</string>
|
|
||||||
<string name="title_activity_emulator">RustdroidAdvance</string>
|
|
||||||
<string name="title_activity_rom_list">Rom Library</string>
|
|
||||||
|
|
||||||
<string name="action_load_rom">Load ROM</string>
|
|
||||||
<string name="action_import_directory">Import Directory</string>
|
|
||||||
<string name="action_settings">Settings</string>
|
|
||||||
|
|
||||||
<string name="submenu_snapshots">Snapshots</string>
|
|
||||||
<string name="action_save_snapshot">Save Snapshot</string>
|
|
||||||
<string name="action_view_snapshot">View Snapshots</string>
|
|
||||||
|
|
||||||
<string name="action_set_screenshot">Set Image</string>
|
|
||||||
|
|
||||||
<string name="action_delete">Delete</string>
|
|
||||||
<string name="action_set_library_image"> Take screenshot for library view </string>
|
|
||||||
|
|
||||||
<string name="title_activity_snapshot">Snapshot Manager</string>
|
|
||||||
|
|
||||||
<string name="color_correction_setting">Apply color correction shader</string>
|
|
||||||
<string name="color_correction_summary">
|
|
||||||
Makes colors look closer to the real GBA LCD screen.
|
|
||||||
</string>
|
|
||||||
</resources>
|
|
|
@ -1,20 +0,0 @@
|
||||||
<resources>
|
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
|
||||||
<item name="colorAccent">@color/colorAccent</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="AppTheme.NoActionBar">
|
|
||||||
<item name="windowActionBar">false</item>
|
|
||||||
<item name="windowNoTitle">true</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
|
|
||||||
|
|
||||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
|
||||||
|
|
||||||
</resources>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<PreferenceScreen
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<PreferenceCategory app:title="Emulation">
|
|
||||||
<SwitchPreferenceCompat
|
|
||||||
app:key="skip_bios"
|
|
||||||
app:title="Skip bios boot animation"/>
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory app:title="Graphics">
|
|
||||||
<SwitchPreferenceCompat
|
|
||||||
app:key="color_correction"
|
|
||||||
app:title="@string/color_correction_setting"
|
|
||||||
app:summary="@string/color_correction_summary"
|
|
||||||
/>
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
|
|
@ -1,4 +0,0 @@
|
||||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<files-path name="internal_files" path="./"/>
|
|
||||||
<files-path name="snapshots" path="snapshots/"/>
|
|
||||||
</paths>
|
|
|
@ -1,17 +0,0 @@
|
||||||
package com.mrmichel.rustdroid_emu;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
|
||||||
*
|
|
||||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
|
||||||
*/
|
|
||||||
public class ExampleUnitTest {
|
|
||||||
@Test
|
|
||||||
public void addition_isCorrect() {
|
|
||||||
assertEquals(4, 2 + 2);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
|
||||||
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
jcenter()
|
|
||||||
maven {
|
|
||||||
url "https://plugins.gradle.org/m2/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
|
||||||
classpath 'gradle.plugin.org.mozilla.rust-android-gradle:plugin:0.8.3'
|
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
|
||||||
// in the individual module build.gradle files
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
jcenter()
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task clean(type: Delete) {
|
|
||||||
delete rootProject.buildDir
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
# Project-wide Gradle settings.
|
|
||||||
# IDE (e.g. Android Studio) users:
|
|
||||||
# Gradle settings configured through the IDE *will override*
|
|
||||||
# any settings specified in this file.
|
|
||||||
# For more details on how to configure your build environment visit
|
|
||||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
|
||||||
# org.gradle.parallel=true
|
|
||||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
|
||||||
# Android operating system, and which are packaged with your app's APK
|
|
||||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
|
||||||
android.useAndroidX=true
|
|
||||||
# Automatically convert third-party libraries to use AndroidX
|
|
||||||
android.enableJetifier=true
|
|
||||||
|
|
BIN
platform/android/gradle/wrapper/gradle-wrapper.jar
vendored
|
@ -1,6 +0,0 @@
|
||||||
#Sat Feb 22 01:01:17 IST 2020
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
|
||||||
distributionPath=wrapper/dists
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
|
172
platform/android/gradlew
vendored
|
@ -1,172 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
##
|
|
||||||
## Gradle start up script for UN*X
|
|
||||||
##
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
|
||||||
# Resolve links: $0 may be a link
|
|
||||||
PRG="$0"
|
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
|
||||||
ls=`ls -ld "$PRG"`
|
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
|
||||||
PRG="$link"
|
|
||||||
else
|
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=`basename "$0"`
|
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
DEFAULT_JVM_OPTS=""
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
|
||||||
MAX_FD="maximum"
|
|
||||||
|
|
||||||
warn () {
|
|
||||||
echo "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
die () {
|
|
||||||
echo
|
|
||||||
echo "$*"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
|
||||||
cygwin=false
|
|
||||||
msys=false
|
|
||||||
darwin=false
|
|
||||||
nonstop=false
|
|
||||||
case "`uname`" in
|
|
||||||
CYGWIN* )
|
|
||||||
cygwin=true
|
|
||||||
;;
|
|
||||||
Darwin* )
|
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
|
||||||
else
|
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
|
||||||
fi
|
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
JAVACMD="java"
|
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
|
||||||
if [ $? -eq 0 ] ; then
|
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
ulimit -n $MAX_FD
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin, switch paths to Windows format before running java
|
|
||||||
if $cygwin ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=$((i+1))
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
(0) set -- ;;
|
|
||||||
(1) set -- "$args0" ;;
|
|
||||||
(2) set -- "$args0" "$args1" ;;
|
|
||||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Escape application args
|
|
||||||
save () {
|
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
|
||||||
echo " "
|
|
||||||
}
|
|
||||||
APP_ARGS=$(save "$@")
|
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
|
||||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
|