much better cli! more ergonomic screen struct! window screen type still broken but working on it!
This commit is contained in:
parent
8890853656
commit
ac4619406d
|
@ -39,12 +39,30 @@ version = "0.6.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2755ff20a1d93490d26ba33a6f092a38a508398a5320df5d4b3014fcccce9410"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -57,7 +75,7 @@ version = "0.27.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.5.0",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
|
@ -76,12 +94,132 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlib"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "georgeemu"
|
||||
version = "0.1.0"
|
||||
|
@ -89,6 +227,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"bdf",
|
||||
"crossterm",
|
||||
"minifb",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
@ -109,12 +248,66 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"libc",
|
||||
"redox_syscall 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
|
@ -137,6 +330,41 @@ version = "2.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minifb"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c470a74618b43cd182c21b3dc1e6123501249f3bad9a0085e95d1304ca2478"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"dlib",
|
||||
"futures",
|
||||
"instant",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"orbclient",
|
||||
"raw-window-handle",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"tempfile",
|
||||
"wasm-bindgen-futures",
|
||||
"wayland-client",
|
||||
"wayland-cursor",
|
||||
"wayland-protocols",
|
||||
"winapi",
|
||||
"x11-dl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
|
@ -146,7 +374,37 @@ dependencies = [
|
|||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "orbclient"
|
||||
version = "0.3.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libredox",
|
||||
"sdl2",
|
||||
"sdl2-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -167,11 +425,29 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.5.2",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
|
@ -190,21 +466,78 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "sdl2"
|
||||
version = "0.35.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7959277b623f1fb9e04aea73686c3ca52f01b2145f8ea16f4ff30d8b7623b1a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"sdl2-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sdl2-sys"
|
||||
version = "0.35.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3586be2cf6c0a8099a79a12b4084357aa9b3e0b0d7980e3b67aaf7a9d55f9f0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.203"
|
||||
|
@ -264,6 +597,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
|
@ -281,6 +623,18 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.61"
|
||||
|
@ -341,12 +695,167 @@ version = "1.0.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"downcast-rs",
|
||||
"libc",
|
||||
"nix",
|
||||
"scoped-tls",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-commons"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"once_cell",
|
||||
"smallvec",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-cursor"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"wayland-client",
|
||||
"xcursor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"wayland-client",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-sys"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4"
|
||||
dependencies = [
|
||||
"dlib",
|
||||
"lazy_static",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -378,6 +887,15 @@ dependencies = [
|
|||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
|
@ -507,3 +1025,26 @@ checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
|
|||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11-dl"
|
||||
version = "2.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"once_cell",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xcursor"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911"
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193"
|
||||
|
|
|
@ -9,6 +9,7 @@ edition = "2021"
|
|||
anyhow = "1.0.81"
|
||||
bdf = "0.6.0"
|
||||
crossterm = "0.27.0"
|
||||
minifb = "0.27.0"
|
||||
# minifb = "0.25.0"
|
||||
# ratatui = "0.26.3"
|
||||
serde = { version = "1.0.197", features = ["serde_derive", "derive"] }
|
||||
|
|
239
src/cli.rs
239
src/cli.rs
|
@ -7,116 +7,163 @@ use std::{
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::memory::Mem;
|
||||
use crate::video::ScreenType;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Config {
|
||||
struct ConfigBuilder {
|
||||
rom: Option<String>,
|
||||
char_rom: Option<String>,
|
||||
rom: String,
|
||||
screen: ScreenType,
|
||||
}
|
||||
|
||||
pub fn get_input(memory: &mut Mem) {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
impl ConfigBuilder {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
rom: None,
|
||||
char_rom: None,
|
||||
screen: ScreenType::default(),
|
||||
}
|
||||
}
|
||||
|
||||
match args.len() {
|
||||
0 => {
|
||||
println!("george-emu must be run in the terminal, don't know what went wrong here!");
|
||||
exit(1)
|
||||
fn build(self) -> Config {
|
||||
let rom = match self.rom {
|
||||
Some(rom) => rom,
|
||||
None => {
|
||||
println!("no rom was provided :(");
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
let char_rom = self.char_rom;
|
||||
let screen = self.screen;
|
||||
|
||||
Config {
|
||||
rom,
|
||||
screen,
|
||||
char_rom,
|
||||
}
|
||||
1 => {
|
||||
let config: Config = match File::open("./george.toml") {
|
||||
Ok(mut file) => {
|
||||
let mut string = String::new();
|
||||
file.read_to_string(&mut string).unwrap();
|
||||
toml::from_str(string.as_str()).unwrap()
|
||||
}
|
||||
Err(_) => {
|
||||
println!("couldn't find a `george.toml` in the current directory!");
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
let rom = match std::fs::File::open(config.rom) {
|
||||
Ok(file) => file,
|
||||
Err(error) => panic!("Couldn't open main rom! {:?}", error),
|
||||
};
|
||||
if let Err(error) = memory.load_rom(rom) {
|
||||
println!("{:?}", error);
|
||||
};
|
||||
}
|
||||
2 => match &args[1] as &str {
|
||||
"help" => {
|
||||
println!("ʕ·ᴥ·ʔ- george-emu is an emulator for george:");
|
||||
println!("https://git.augustkline.com/august/george\n");
|
||||
println!("commands:");
|
||||
println!(" help: print this help screen");
|
||||
println!(" help <command>: print help info for any command");
|
||||
println!(" rom <path>: load a rom/binary from path\n");
|
||||
println!("configuration:");
|
||||
println!(" george-emu searches for a `george.toml` in the current directory. in `george.toml` you can specify a path for the character rom using the key `char_rom` and the main rom/binary with the key `rom`");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Config {
|
||||
pub rom: String,
|
||||
pub screen: ScreenType,
|
||||
pub char_rom: Option<String>,
|
||||
}
|
||||
|
||||
fn help(command: Option<String>) {
|
||||
let executable: String = env::args().next().unwrap();
|
||||
if let Some(command) = command {
|
||||
match &command as &str {
|
||||
"rom" | "--rom" | "-r" => {
|
||||
println!("{executable} {command} <path>\n\nload a rom/binary from path");
|
||||
exit(0);
|
||||
}
|
||||
"screen" | "--screen" | "-s" => {
|
||||
println!("{executable} {command} <path>\n\nload a rom/binary from path");
|
||||
exit(0);
|
||||
}
|
||||
"help" | "--help" | "-h" => {
|
||||
println!("{executable} {command} <command>\n\nshow help info for a given command");
|
||||
exit(0);
|
||||
}
|
||||
_ => {
|
||||
println!(
|
||||
"{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands",
|
||||
&args[1], &args[0]
|
||||
"{command:?} isn't a valid command!\n\nuse `{executable} help` to see all valid commands",
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
},
|
||||
3 => match &args[1] as &str {
|
||||
"help" => match &args[2] as &str {
|
||||
"rom" => {
|
||||
println!("{} rom <path>\n\nload a rom/binary from path", &args[0]);
|
||||
exit(0);
|
||||
}
|
||||
_ => {
|
||||
println!(
|
||||
"{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands",
|
||||
&args[2], &args[0]
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
},
|
||||
"rom" => {
|
||||
let rom = match std::fs::File::open(&args[2]) {
|
||||
Ok(file) => file,
|
||||
Err(error) => {
|
||||
match error.kind() {
|
||||
ErrorKind::NotFound => {
|
||||
println!("couldn't find the rom at {:?}", &args[2]);
|
||||
}
|
||||
ErrorKind::PermissionDenied => {
|
||||
println!(
|
||||
"didn't have sufficient permissions to open the rom at {:?}",
|
||||
&args[2]
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
println!("something went wrong! try again in a moment? really not sure why you're getting this error");
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
if let Err(error) = memory.load_rom(rom) {
|
||||
println!("oh no! this rom couldn't be loaded: {:?}", error);
|
||||
exit(1);
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
println!(
|
||||
"{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands",
|
||||
&args[1], &args[0]
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
println!(
|
||||
"too many arguments were provided!\n\nuse `{} help` to see all valid commands",
|
||||
&args[0]
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
println!("ʕ·ᴥ·ʔ- {executable} is an emulator for george:");
|
||||
println!("https://git.augustkline.com/august/george\n");
|
||||
println!("commands:");
|
||||
println!(" help, -h, --help <command>: print help info for any command");
|
||||
println!(" rom, -r, --rom <path>: load a rom/binary from path");
|
||||
println!(" screen, -s, --screen <type>: use the \"terminal\" or \"window\" display type");
|
||||
println!("\nconfiguration:");
|
||||
println!(" george-emu searches for a `george.toml` in the current directory.\n in `george.toml` you can specify a path for the character rom using the key `char_rom` and the main rom/binary with the key `rom`");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_input() -> Config {
|
||||
let executable: String = env::args().next().unwrap();
|
||||
let mut config = ConfigBuilder::new();
|
||||
|
||||
let len = env::args().len();
|
||||
|
||||
if len == 1 {
|
||||
config = match File::open("./george.toml") {
|
||||
Ok(mut file) => {
|
||||
let mut string = String::new();
|
||||
file.read_to_string(&mut string).unwrap();
|
||||
toml::from_str(string.as_str()).unwrap()
|
||||
}
|
||||
Err(_) => {
|
||||
println!("couldn't find a `george.toml` in the current directory!");
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
return config.build();
|
||||
}
|
||||
|
||||
let mut args = env::args().skip(1);
|
||||
|
||||
while let Some(arg) = args.next() {
|
||||
match &arg[..] {
|
||||
"--help" | "-h" | "help" => help(args.next()),
|
||||
"--rom" | "-r" | "rom" => {
|
||||
if let Some(path) = args.next() {
|
||||
match std::fs::File::open(&path) {
|
||||
Ok(_) => {
|
||||
config.rom = Some(path);
|
||||
}
|
||||
Err(error) => {
|
||||
match error.kind() {
|
||||
ErrorKind::NotFound => {
|
||||
println!("couldn't find the rom at {path:?}");
|
||||
}
|
||||
ErrorKind::PermissionDenied => {
|
||||
println!(
|
||||
"didn't have sufficient permissions to open the rom at {path:?}"
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
println!("something went wrong! try again in a moment? really not sure why you're getting this error");
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
println!("no rom specified!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
"--screen" | "-s" | "screen" => {
|
||||
let kind = args.next();
|
||||
match kind {
|
||||
Some(kind) => match &kind as &str {
|
||||
"terminal" | "Terminal" | "TERMINAL" | "t" | "term" => {}
|
||||
"window" | "Window" | "WINDOW" | "w" | "win" => {
|
||||
config.screen = ScreenType::Window
|
||||
}
|
||||
_ => {
|
||||
println!("{kind:?} isn't a valid screen type!\n\nuse \"{executable} --help screen\" to see all valid screen types");
|
||||
exit(1);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
println!("no screen type was provided!\n\nuse \"{executable} --help screen\" to see all valid screen types");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
println!("{arg:?} isn't a valid command!\n\nuse \"{executable} help\" to see all valid commands");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
config.build()
|
||||
}
|
||||
|
|
233
src/keyboard.rs
233
src/keyboard.rs
|
@ -1,5 +1,5 @@
|
|||
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
|
||||
// use minifb::{InputCallback, Key};
|
||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
||||
use minifb::{InputCallback, Key};
|
||||
|
||||
use crate::memory::{MemHandle, MemoryWriter};
|
||||
|
||||
|
@ -18,56 +18,61 @@ impl Keyboard {
|
|||
let mut row3 = 0;
|
||||
let mut row4 = 0;
|
||||
let mut row5 = 0;
|
||||
if key.kind == KeyEventKind::Press || key.kind == KeyEventKind::Repeat {
|
||||
match key.modifiers {
|
||||
KeyModifiers::SHIFT => row2 ^= 0b1000_0000,
|
||||
KeyModifiers::CONTROL => row3 ^= 0b1000_0000,
|
||||
KeyModifiers::ALT => row4 ^= 0b1000_0000,
|
||||
KeyModifiers::META => row5 ^= 0b1000_0000,
|
||||
KeyModifiers::SUPER => row5 ^= 0b0010_0000,
|
||||
_ => {}
|
||||
};
|
||||
match key.modifiers {
|
||||
KeyModifiers::SHIFT => row2 ^= 0b1000_0000,
|
||||
KeyModifiers::CONTROL => row3 ^= 0b1000_0000,
|
||||
KeyModifiers::ALT => row4 ^= 0b1000_0000,
|
||||
KeyModifiers::META => row5 ^= 0b1000_0000,
|
||||
KeyModifiers::SUPER => row5 ^= 0b0010_0000,
|
||||
_ => {}
|
||||
};
|
||||
|
||||
match key.code {
|
||||
KeyCode::Esc => row0 ^= 0b1000_0000,
|
||||
KeyCode::Char('w') => row0 ^= 0b0100_0000,
|
||||
KeyCode::Char('e') => row0 ^= 0b0010_0000,
|
||||
KeyCode::Char('r') => row0 ^= 0b0001_0000,
|
||||
KeyCode::Char('t') => row0 ^= 0b0000_1000,
|
||||
KeyCode::Char('u') => row0 ^= 0b0000_0100,
|
||||
KeyCode::Char('o') => row0 ^= 0b0000_0010,
|
||||
KeyCode::Backspace => row0 ^= 0b0000_0001,
|
||||
KeyCode::Tab => row1 ^= 0b1000_0000,
|
||||
KeyCode::Char('q') => row1 ^= 0b0100_0000,
|
||||
KeyCode::Char('s') => row1 ^= 0b0010_0000,
|
||||
KeyCode::Char('g') => row1 ^= 0b0001_0000,
|
||||
KeyCode::Char('y') => row1 ^= 0b0000_1000,
|
||||
KeyCode::Char('i') => row1 ^= 0b0000_0100,
|
||||
KeyCode::Char('p') => row1 ^= 0b0000_0010,
|
||||
KeyCode::Enter => row1 ^= 0b0000_0001,
|
||||
KeyCode::Char('d') => row2 ^= 0b0100_0000,
|
||||
KeyCode::Char('v') => row2 ^= 0b0010_0000,
|
||||
KeyCode::Char('h') => row2 ^= 0b0001_0000,
|
||||
KeyCode::Char('k') => row2 ^= 0b0000_1000,
|
||||
KeyCode::Char('\'') => row2 ^= 0b0000_0100,
|
||||
KeyCode::Char('/') => row2 ^= 0b0000_0010,
|
||||
KeyCode::Char('a') => row2 ^= 0b0000_0001,
|
||||
KeyCode::Char('z') => row3 ^= 0b0100_0000,
|
||||
KeyCode::Char('f') => row3 ^= 0b0010_0000,
|
||||
KeyCode::Char('b') => row3 ^= 0b0001_0000,
|
||||
KeyCode::Char('j') => row3 ^= 0b0000_1000,
|
||||
KeyCode::Char('l') => row3 ^= 0b0000_0100,
|
||||
KeyCode::Char('2') => row3 ^= 0b0000_0010,
|
||||
KeyCode::Char('4') => row3 ^= 0b0000_0001,
|
||||
KeyCode::Char('x') => row4 ^= 0b0100_0000,
|
||||
KeyCode::Char('c') => row4 ^= 0b0010_0000,
|
||||
KeyCode::Char('n') => row4 ^= 0b0001_0000,
|
||||
KeyCode::Char('m') => row4 ^= 0b0000_1000,
|
||||
KeyCode::Char(',') => row4 ^= 0b0000_0100,
|
||||
KeyCode::Char('1') => row4 ^= 0b0000_0010,
|
||||
KeyCode::Char('3') => row4 ^= 0b0000_0001,
|
||||
KeyCode::Char(' ') => row5 ^= 0b0100_0000,
|
||||
_ => {}
|
||||
match key.code {
|
||||
KeyCode::Esc => row0 ^= 0b1000_0000,
|
||||
KeyCode::Char('w') => row0 ^= 0b0100_0000,
|
||||
KeyCode::Char('e') => row0 ^= 0b0010_0000,
|
||||
KeyCode::Char('r') => row0 ^= 0b0001_0000,
|
||||
KeyCode::Char('t') => row0 ^= 0b0000_1000,
|
||||
KeyCode::Char('u') => row0 ^= 0b0000_0100,
|
||||
KeyCode::Char('o') => row0 ^= 0b0000_0010,
|
||||
KeyCode::Backspace => row0 ^= 0b0000_0001,
|
||||
KeyCode::Tab => row1 ^= 0b1000_0000,
|
||||
KeyCode::Char('q') => row1 ^= 0b0100_0000,
|
||||
KeyCode::Char('s') => row1 ^= 0b0010_0000,
|
||||
KeyCode::Char('g') => row1 ^= 0b0001_0000,
|
||||
KeyCode::Char('y') => row1 ^= 0b0000_1000,
|
||||
KeyCode::Char('i') => row1 ^= 0b0000_0100,
|
||||
KeyCode::Char('p') => row1 ^= 0b0000_0010,
|
||||
KeyCode::Enter => row1 ^= 0b0000_0001,
|
||||
KeyCode::Char('d') => row2 ^= 0b0100_0000,
|
||||
KeyCode::Char('v') => row2 ^= 0b0010_0000,
|
||||
KeyCode::Char('h') => row2 ^= 0b0001_0000,
|
||||
KeyCode::Char('k') => row2 ^= 0b0000_1000,
|
||||
KeyCode::Char('\'') => row2 ^= 0b0000_0100,
|
||||
KeyCode::Char('/') => row2 ^= 0b0000_0010,
|
||||
KeyCode::Char('a') => row2 ^= 0b0000_0001,
|
||||
KeyCode::Char('z') => row3 ^= 0b0100_0000,
|
||||
KeyCode::Char('f') => row3 ^= 0b0010_0000,
|
||||
KeyCode::Char('b') => row3 ^= 0b0001_0000,
|
||||
KeyCode::Char('j') => row3 ^= 0b0000_1000,
|
||||
KeyCode::Char('l') => row3 ^= 0b0000_0100,
|
||||
KeyCode::Char('2') => row3 ^= 0b0000_0010,
|
||||
KeyCode::Char('4') => row3 ^= 0b0000_0001,
|
||||
KeyCode::Char('x') => row4 ^= 0b0100_0000,
|
||||
KeyCode::Char('c') => row4 ^= 0b0010_0000,
|
||||
KeyCode::Char('n') => row4 ^= 0b0001_0000,
|
||||
KeyCode::Char('m') => row4 ^= 0b0000_1000,
|
||||
KeyCode::Char(',') => row4 ^= 0b0000_0100,
|
||||
KeyCode::Char('1') => row4 ^= 0b0000_0010,
|
||||
KeyCode::Char('3') => row4 ^= 0b0000_0001,
|
||||
KeyCode::Char(' ') => row5 ^= 0b0100_0000,
|
||||
_ => {
|
||||
row0 = 0;
|
||||
row1 = 0;
|
||||
row2 = 0;
|
||||
row3 = 0;
|
||||
row4 = 0;
|
||||
row5 = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -86,68 +91,68 @@ impl MemoryWriter for Keyboard {
|
|||
}
|
||||
}
|
||||
|
||||
// impl InputCallback for Keyboard {
|
||||
// fn add_char(&mut self, _uni_char: u32) {}
|
||||
// fn set_key_state(&mut self, key: Key, _state: bool) {
|
||||
// let mut row0 = 0;
|
||||
// let mut row1 = 0;
|
||||
// let mut row2 = 0;
|
||||
// let mut row3 = 0;
|
||||
// let mut row4 = 0;
|
||||
// let mut row5 = 0;
|
||||
impl InputCallback for Keyboard {
|
||||
fn add_char(&mut self, _uni_char: u32) {}
|
||||
fn set_key_state(&mut self, key: Key, _state: bool) {
|
||||
let mut row0 = 0;
|
||||
let mut row1 = 0;
|
||||
let mut row2 = 0;
|
||||
let mut row3 = 0;
|
||||
let mut row4 = 0;
|
||||
let mut row5 = 0;
|
||||
|
||||
// match key {
|
||||
// Key::Escape => row0 ^= 0b1000_0000,
|
||||
// Key::W => row0 ^= 0b0100_0000,
|
||||
// Key::E => row0 ^= 0b0010_0000,
|
||||
// Key::R => row0 ^= 0b0001_0000,
|
||||
// Key::T => row0 ^= 0b0000_1000,
|
||||
// Key::U => row0 ^= 0b0000_0100,
|
||||
// Key::O => row0 ^= 0b0000_0010,
|
||||
// Key::Backspace => row0 ^= 0b0000_0001,
|
||||
// Key::Tab => row1 ^= 0b1000_0000,
|
||||
// Key::Q => row1 ^= 0b0100_0000,
|
||||
// Key::S => row1 ^= 0b0010_0000,
|
||||
// Key::G => row1 ^= 0b0001_0000,
|
||||
// Key::Y => row1 ^= 0b0000_1000,
|
||||
// Key::I => row1 ^= 0b0000_0100,
|
||||
// Key::P => row1 ^= 0b0000_0010,
|
||||
// Key::Enter => row1 ^= 0b0000_0001,
|
||||
// Key::LeftShift | Key::RightShift => row2 ^= 0b1000_0000,
|
||||
// Key::D => row2 ^= 0b0100_0000,
|
||||
// Key::V => row2 ^= 0b0010_0000,
|
||||
// Key::H => row2 ^= 0b0001_0000,
|
||||
// Key::K => row2 ^= 0b0000_1000,
|
||||
// Key::Apostrophe => row2 ^= 0b0000_0100,
|
||||
// Key::Slash => row2 ^= 0b0000_0010,
|
||||
// Key::A => row2 ^= 0b0000_0001,
|
||||
// Key::LeftCtrl | Key::RightCtrl => row3 ^= 0b1000_0000,
|
||||
// Key::Z => row3 ^= 0b0100_0000,
|
||||
// Key::F => row3 ^= 0b0010_0000,
|
||||
// Key::B => row3 ^= 0b0001_0000,
|
||||
// Key::J => row3 ^= 0b0000_1000,
|
||||
// Key::L => row3 ^= 0b0000_0100,
|
||||
// Key::Key2 => row3 ^= 0b0000_0010,
|
||||
// Key::Key4 => row3 ^= 0b0000_0001,
|
||||
// Key::LeftAlt | Key::RightAlt => row4 ^= 0b1000_0000,
|
||||
// Key::X => row4 ^= 0b0100_0000,
|
||||
// Key::C => row4 ^= 0b0010_0000,
|
||||
// Key::N => row4 ^= 0b0001_0000,
|
||||
// Key::M => row4 ^= 0b0000_1000,
|
||||
// Key::Comma => row4 ^= 0b0000_0100,
|
||||
// Key::Key1 => row4 ^= 0b0000_0010,
|
||||
// Key::Key3 => row4 ^= 0b0000_0001,
|
||||
// Key::LeftSuper => row5 ^= 0b1000_0000,
|
||||
// Key::Space => row5 ^= 0b0100_0000,
|
||||
// Key::RightSuper => row5 ^= 0b0010_0000,
|
||||
// _ => {}
|
||||
// };
|
||||
match key {
|
||||
Key::Escape => row0 ^= 0b1000_0000,
|
||||
Key::W => row0 ^= 0b0100_0000,
|
||||
Key::E => row0 ^= 0b0010_0000,
|
||||
Key::R => row0 ^= 0b0001_0000,
|
||||
Key::T => row0 ^= 0b0000_1000,
|
||||
Key::U => row0 ^= 0b0000_0100,
|
||||
Key::O => row0 ^= 0b0000_0010,
|
||||
Key::Backspace => row0 ^= 0b0000_0001,
|
||||
Key::Tab => row1 ^= 0b1000_0000,
|
||||
Key::Q => row1 ^= 0b0100_0000,
|
||||
Key::S => row1 ^= 0b0010_0000,
|
||||
Key::G => row1 ^= 0b0001_0000,
|
||||
Key::Y => row1 ^= 0b0000_1000,
|
||||
Key::I => row1 ^= 0b0000_0100,
|
||||
Key::P => row1 ^= 0b0000_0010,
|
||||
Key::Enter => row1 ^= 0b0000_0001,
|
||||
Key::LeftShift | Key::RightShift => row2 ^= 0b1000_0000,
|
||||
Key::D => row2 ^= 0b0100_0000,
|
||||
Key::V => row2 ^= 0b0010_0000,
|
||||
Key::H => row2 ^= 0b0001_0000,
|
||||
Key::K => row2 ^= 0b0000_1000,
|
||||
Key::Apostrophe => row2 ^= 0b0000_0100,
|
||||
Key::Slash => row2 ^= 0b0000_0010,
|
||||
Key::A => row2 ^= 0b0000_0001,
|
||||
Key::LeftCtrl | Key::RightCtrl => row3 ^= 0b1000_0000,
|
||||
Key::Z => row3 ^= 0b0100_0000,
|
||||
Key::F => row3 ^= 0b0010_0000,
|
||||
Key::B => row3 ^= 0b0001_0000,
|
||||
Key::J => row3 ^= 0b0000_1000,
|
||||
Key::L => row3 ^= 0b0000_0100,
|
||||
Key::Key2 => row3 ^= 0b0000_0010,
|
||||
Key::Key4 => row3 ^= 0b0000_0001,
|
||||
Key::LeftAlt | Key::RightAlt => row4 ^= 0b1000_0000,
|
||||
Key::X => row4 ^= 0b0100_0000,
|
||||
Key::C => row4 ^= 0b0010_0000,
|
||||
Key::N => row4 ^= 0b0001_0000,
|
||||
Key::M => row4 ^= 0b0000_1000,
|
||||
Key::Comma => row4 ^= 0b0000_0100,
|
||||
Key::Key1 => row4 ^= 0b0000_0010,
|
||||
Key::Key3 => row4 ^= 0b0000_0001,
|
||||
Key::LeftSuper => row5 ^= 0b1000_0000,
|
||||
Key::Space => row5 ^= 0b0100_0000,
|
||||
Key::RightSuper => row5 ^= 0b0010_0000,
|
||||
_ => {}
|
||||
};
|
||||
|
||||
// self.memory.write(0x4400, row0);
|
||||
// self.memory.write(0x4401, row1);
|
||||
// self.memory.write(0x4402, row2);
|
||||
// self.memory.write(0x4403, row3);
|
||||
// self.memory.write(0x4404, row4);
|
||||
// self.memory.write(0x4405, row5);
|
||||
// }
|
||||
// }
|
||||
self.memory.write(0x4400, row0);
|
||||
self.memory.write(0x4401, row1);
|
||||
self.memory.write(0x4402, row2);
|
||||
self.memory.write(0x4403, row3);
|
||||
self.memory.write(0x4404, row4);
|
||||
self.memory.write(0x4405, row5);
|
||||
}
|
||||
}
|
||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -17,7 +17,7 @@ use crossterm::execute;
|
|||
use crossterm::terminal::{size, Clear, ClearType, SetSize};
|
||||
// use cpu::CpuController;
|
||||
use memory::MemHandle;
|
||||
// use minifb::{Scale, ScaleMode, Window, WindowOptions};
|
||||
use minifb::{Scale, ScaleMode, Window, WindowOptions};
|
||||
use std::io::{stdout, Result};
|
||||
use std::thread::{self, sleep};
|
||||
use std::time::Duration;
|
||||
|
@ -61,9 +61,10 @@ fn main() -> Result<()> {
|
|||
let mut stdout = stdout();
|
||||
let (cols, rows) = size()?;
|
||||
|
||||
let mut memory = Mem::new();
|
||||
let config = get_input();
|
||||
|
||||
get_input(&mut memory);
|
||||
let mut memory = Mem::new();
|
||||
let _ = memory.load_rom(&config.rom);
|
||||
|
||||
execute!(stdout, SetSize(64, 29), cursor::Hide, EnterAlternateScreen)?;
|
||||
enable_raw_mode()?;
|
||||
|
@ -82,20 +83,18 @@ fn main() -> Result<()> {
|
|||
cpu.cycle();
|
||||
});
|
||||
|
||||
let stdout_lock = stdout.lock();
|
||||
let renderer = TerminalRenderer::new(screen_memory, stdout_lock);
|
||||
let mut screen = Screen::new(renderer, cpu_controller);
|
||||
let mut screen = Screen::new(&config, cpu_controller, screen_memory);
|
||||
|
||||
loop {
|
||||
sleep(Duration::from_millis(16));
|
||||
screen.draw();
|
||||
if event::poll(std::time::Duration::from_millis(16))? {
|
||||
if let event::Event::Key(key) = event::read()? {
|
||||
keyboard.read_keys(key);
|
||||
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
||||
break;
|
||||
}
|
||||
// if event::poll(std::time::Duration::from_millis(16))? {
|
||||
if let event::Event::Key(key) = event::read()? {
|
||||
keyboard.read_keys(key);
|
||||
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
||||
break;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::{bail, Result};
|
||||
use std::cell::RefCell;
|
||||
use std::io::{self, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
@ -71,7 +71,14 @@ impl Mem {
|
|||
self.0[address as usize] = data;
|
||||
}
|
||||
|
||||
pub fn load_rom(&mut self, rom: File) -> Result<()> {
|
||||
pub fn load_rom<P>(&mut self, rom: P) -> Result<()>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let rom = match File::open(rom) {
|
||||
Ok(rom) => rom,
|
||||
Err(_) => bail!("rom could not be opened!"),
|
||||
};
|
||||
let bytes = rom.bytes();
|
||||
for (address, byte) in bytes.enumerate() {
|
||||
// println!("{address}");
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
.org $8000
|
||||
|
||||
n = $01 ; temporary storage for data stack operations
|
||||
key_buffer = $200
|
||||
|
||||
reset:
|
||||
sei
|
||||
|
@ -27,10 +28,40 @@ cleardisplay:
|
|||
cli
|
||||
|
||||
main:
|
||||
; jmp draw
|
||||
jmp cleardisplay
|
||||
; jsr read_keys
|
||||
; lda key_buffer
|
||||
lda $4402
|
||||
sta $6000
|
||||
jmp main
|
||||
|
||||
; first, let's do the simplest case of just the letter a being pressed
|
||||
; 1. check row 2 ($4402, where the a key is) for pressed keys
|
||||
; 2. if any keys are pressed, check if the key is a (bit 0)
|
||||
; 3. if the key is not a, store zero in the key buffer
|
||||
; 4. if the key is a, store the ascii for a in the key buffer
|
||||
; 5. return
|
||||
|
||||
; so u don't have to scroll: key_buffer = $200
|
||||
; key buffer just shows the current state of the keyboard
|
||||
; it is not a queue of keys to print
|
||||
|
||||
read_keys:
|
||||
lda $4402 ; check row 2
|
||||
beq check_key ; if there're any keys, check which
|
||||
clear_buffer:
|
||||
stz key_buffer
|
||||
rts
|
||||
check_key: ; if there is a key pressed, check if it's a
|
||||
ror
|
||||
bmi store_key
|
||||
rts
|
||||
store_key:
|
||||
; in a sec we'll set up ascii table lookup,
|
||||
; for now let's just load the ascii byte for a
|
||||
lda #$61
|
||||
sta key_buffer
|
||||
rts
|
||||
|
||||
draw:
|
||||
push_coords #0, #0
|
||||
push_char #$af
|
||||
|
@ -73,8 +104,6 @@ fill: ; fills an area from (x1, y1) to (x2, y2) will character c, (n1: c n2: x1
|
|||
jsr get_char_address
|
||||
|
||||
irq:
|
||||
|
||||
keyboard:
|
||||
rts
|
||||
|
||||
isr: ; interrupt service routine
|
||||
|
|
175
src/tui/mod.rs
175
src/tui/mod.rs
|
@ -1,175 +0,0 @@
|
|||
// use std::time::Duration;
|
||||
|
||||
mod tabs;
|
||||
mod term;
|
||||
use std::{
|
||||
io::Result,
|
||||
sync::{mpsc::Receiver, Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crossterm::event::{self, poll, Event, KeyCode, KeyEvent, KeyEventKind};
|
||||
use ratatui::{
|
||||
layout::Layout,
|
||||
prelude::*,
|
||||
widgets::{Block, Cell, Paragraph, Row, Table, TableState},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
cpu::{CpuController, CpuState},
|
||||
memory::{MemHandle, MemoryReader, MemoryWriter},
|
||||
};
|
||||
|
||||
pub struct App {
|
||||
cpu: CpuController,
|
||||
state: Receiver<CpuState>,
|
||||
memory: MemHandle,
|
||||
running: bool,
|
||||
table_state: TableState,
|
||||
}
|
||||
|
||||
impl MemoryReader for App {
|
||||
fn read(&self, address: u16) -> u8 {
|
||||
self.memory.read(address)
|
||||
}
|
||||
}
|
||||
impl MemoryWriter for App {
|
||||
fn write(&self, address: u16, data: u8) {
|
||||
self.memory.write(address, data)
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new(cpu: CpuController, memory: MemHandle, state: Receiver<CpuState>) -> Self {
|
||||
Self {
|
||||
cpu,
|
||||
memory,
|
||||
running: true,
|
||||
table_state: TableState::default(),
|
||||
state,
|
||||
}
|
||||
}
|
||||
pub fn update(&mut self, terminal: &mut Terminal<impl Backend>) -> Result<()> {
|
||||
self.draw(terminal)?;
|
||||
self.handle_events()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Draw a single frame of the app.
|
||||
fn draw(&self, terminal: &mut Terminal<impl Backend>) -> Result<()> {
|
||||
terminal
|
||||
.draw(|frame| {
|
||||
frame.render_widget(self, frame.size());
|
||||
})
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_events(&mut self) -> Result<()> {
|
||||
if poll(Duration::from_secs_f32(1.0 / 25.0))? {
|
||||
match event::read()? {
|
||||
Event::Key(key) if key.kind == KeyEventKind::Press => self.handle_key_press(key),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_key_press(&mut self, key: KeyEvent) {
|
||||
// let mut cpu = self.cpu.lock().unwrap();
|
||||
match key.code {
|
||||
KeyCode::Enter => {
|
||||
if !self.running {
|
||||
// cpu.cycle()
|
||||
}
|
||||
}
|
||||
KeyCode::Char(' ') => {
|
||||
self.running = !self.running;
|
||||
match self.running {
|
||||
true => self.cpu.stop(),
|
||||
false => self.cpu.resume(),
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement Widget for &App rather than for App as we would otherwise have to clone or copy the
|
||||
/// entire app state on every frame. For this example, the app state is small enough that it doesn't
|
||||
/// matter, but for larger apps this can be a significant performance improvement.
|
||||
impl Widget for &App {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
self.cpu.data();
|
||||
let [cpu_area, memory_area] =
|
||||
Layout::horizontal([Constraint::Percentage(50), Constraint::Fill(1)]).areas(area);
|
||||
let [memory_table, memory_info] =
|
||||
Layout::vertical([Constraint::Fill(1), Constraint::Percentage(10)]).areas(memory_area);
|
||||
|
||||
let cpu = self.state.recv().unwrap();
|
||||
let cpu_info = format!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = cpu.a, x = cpu.x, y = cpu.y, pc = cpu.pc, s = cpu.s, p = cpu.p, irq = cpu.irq, nmi = cpu.nmi);
|
||||
|
||||
Paragraph::new(cpu_info)
|
||||
.block(Block::bordered().title("cpu info!"))
|
||||
.render(cpu_area, buf);
|
||||
|
||||
// let table_height = memory_table.rows().count() - 2;
|
||||
// TODO: impl Iterator for MemHandle so we can get references to the underlying data from other threads without cloning
|
||||
// let rows: Vec<Row> = self.memory.data()[0..table_height * 16]
|
||||
// .chunks(16)
|
||||
// .map(|chunk| {
|
||||
// chunk
|
||||
// .iter()
|
||||
// .map(|content| Cell::from(Text::from(format!("{content:x}"))))
|
||||
// .collect::<Row>()
|
||||
// })
|
||||
// .collect();
|
||||
let zero = self.memory.read(0);
|
||||
let rows: Vec<Row> = vec![Row::new([format!("{zero}")])];
|
||||
let widths = vec![Constraint::Length(2); 16];
|
||||
Widget::render(
|
||||
Table::new(rows, widths)
|
||||
.header(
|
||||
Row::new(vec![
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e",
|
||||
"f",
|
||||
])
|
||||
.style(Style::new().bold()), // To add space between the header and the rest of the rows, specify the margin
|
||||
// .bottom_margin(1),
|
||||
)
|
||||
.block(Block::bordered().title_top("memory")),
|
||||
memory_table,
|
||||
buf,
|
||||
);
|
||||
Paragraph::new(format!("program counter: {:#04x}", cpu.pc))
|
||||
.block(Block::bordered().title_top("info"))
|
||||
.render(memory_info, buf);
|
||||
}
|
||||
}
|
||||
|
||||
// impl Widget for App {
|
||||
// fn render_title_bar(&self, area: Rect, buf: &mut Buffer) {
|
||||
// // let layout = Layout::horizontal([Constraint::Min(0), Constraint::Length(43)]);
|
||||
// // let [title] = layout.areas(area);
|
||||
|
||||
// Span::styled("Ratatui", Style::default()).render(area, buf);
|
||||
// // let titles = Tab::iter().map(Tab::title);
|
||||
// // Tabs::new(titles)
|
||||
// // .style(THEME.tabs)
|
||||
// // .highlight_style(THEME.tabs_selected)
|
||||
// // .select(self.tab as usize)
|
||||
// // .divider("")
|
||||
// // .padding("", "")
|
||||
// // .render(tabs, buf);
|
||||
// }
|
||||
|
||||
// // fn render_selected_tab(&self, area: Rect, buf: &mut Buffer) {
|
||||
// // match self.tab {
|
||||
// // Tab::About => self.about_tab.render(area, buf),
|
||||
// // Tab::Recipe => self.recipe_tab.render(area, buf),
|
||||
// // Tab::Email => self.email_tab.render(area, buf),
|
||||
// // Tab::Traceroute => self.traceroute_tab.render(area, buf),
|
||||
// // Tab::Weather => self.weather_tab.render(area, buf),
|
||||
// // };
|
||||
// // }
|
||||
// }
|
103
src/video.rs
103
src/video.rs
|
@ -3,28 +3,27 @@ use crossterm::{
|
|||
execute, queue,
|
||||
style::{Color, PrintStyledContent, Stylize},
|
||||
};
|
||||
use minifb::{Scale, ScaleMode, Window, WindowOptions};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
cli::Config,
|
||||
cpu::CpuController,
|
||||
memory::{MemHandle, MemoryReader},
|
||||
types::{Byte, Word},
|
||||
};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{Read, StdoutLock, Write},
|
||||
io::{self, Read, Write},
|
||||
path::Path,
|
||||
process::exit,
|
||||
sync::mpsc::Sender,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
const FG_COLOR: u32 = 0xFFCC00;
|
||||
const BG_COLOR: u32 = 0x110500;
|
||||
// // BGR for softbuffer
|
||||
// const FG_COLOR: u32 = 0x00CCFF;
|
||||
// const BG_COLOR: u32 = 0x000511;
|
||||
//
|
||||
pub fn get_char_bin<P>(char_rom: Option<P>) -> Vec<u8>
|
||||
const WIDTH: usize = 512;
|
||||
const HEIGHT: usize = 380;
|
||||
|
||||
pub fn get_char_bin<P>(char_rom: Option<P>) -> [u8; 0x8000]
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
|
@ -34,9 +33,9 @@ where
|
|||
let mut bin = vec![0; 0x8000];
|
||||
file.read_exact(&mut bin).unwrap();
|
||||
// println!("reading char rom");
|
||||
bin
|
||||
bin.try_into().unwrap()
|
||||
}
|
||||
None => include_bytes!("./roms/cozette.rom").to_vec(),
|
||||
None => *include_bytes!("./roms/cozette.rom"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,14 +43,21 @@ trait Renderer {
|
|||
fn render(&mut self) {}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
pub enum ScreenType {
|
||||
Window,
|
||||
#[default]
|
||||
Terminal,
|
||||
}
|
||||
|
||||
pub struct WindowRenderer {
|
||||
char_rom: Vec<u8>,
|
||||
window: Sender<Vec<u32>>,
|
||||
char_rom: [u8; 0x8000],
|
||||
window: Window,
|
||||
memory: MemHandle,
|
||||
}
|
||||
|
||||
impl WindowRenderer {
|
||||
pub fn new<P>(memory: MemHandle, char_rom: Option<P>, window: Sender<Vec<u32>>) -> Self
|
||||
pub fn new<P>(memory: MemHandle, char_rom: Option<P>, window: Window) -> Self
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
|
@ -70,7 +76,7 @@ impl Renderer for WindowRenderer {
|
|||
// based on the specifics of george's weird
|
||||
// display and characters... don't fuck around w it
|
||||
let mut i = 0;
|
||||
let mut buffer = vec![0; 512 * 380];
|
||||
let mut buffer = [0; 512 * 380];
|
||||
for char_row in 0..29 {
|
||||
for char_col in 0..64 {
|
||||
let ascii = self.read(0x6000 + i);
|
||||
|
@ -89,7 +95,9 @@ impl Renderer for WindowRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
let _ = self.window.send(buffer.clone());
|
||||
self.window
|
||||
.update_with_buffer(&buffer, WIDTH, HEIGHT)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,19 +108,23 @@ impl MemoryReader for WindowRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct TerminalRenderer<'a> {
|
||||
// pub struct TerminalRenderer<'a> {
|
||||
pub struct TerminalRenderer {
|
||||
memory: MemHandle,
|
||||
// stdout: Stdout,
|
||||
stdout: StdoutLock<'a>,
|
||||
// stdout: StdoutLock<'a>,
|
||||
}
|
||||
|
||||
impl<'a> TerminalRenderer<'a> {
|
||||
pub fn new(memory: MemHandle, stdout: StdoutLock<'a>) -> Self {
|
||||
Self { memory, stdout }
|
||||
// impl<'a> TerminalRenderer<'a> {
|
||||
impl TerminalRenderer {
|
||||
// pub fn new(memory: MemHandle, stdout: StdoutLock<'a>) -> Self {
|
||||
pub fn new(memory: MemHandle) -> Self {
|
||||
Self { memory }
|
||||
}
|
||||
}
|
||||
|
||||
impl MemoryReader for TerminalRenderer<'_> {
|
||||
// impl MemoryReader for TerminalRenderer<'_> {
|
||||
impl MemoryReader for TerminalRenderer {
|
||||
fn read(&self, address: Word) -> Byte {
|
||||
self.memory.read(address)
|
||||
}
|
||||
|
@ -135,10 +147,12 @@ const ASCII_LOOPUP: [&str; 256] = [
|
|||
"", "", "", "", "🎁", "", "", "", "", "⚐", "⚑", "", "", "",
|
||||
];
|
||||
|
||||
impl Renderer for TerminalRenderer<'_> {
|
||||
// impl Renderer for TerminalRenderer<'_> {
|
||||
impl Renderer for TerminalRenderer {
|
||||
fn render(&mut self) {
|
||||
// let now = Instant::now();
|
||||
let _ = execute!(self.stdout, SavePosition);
|
||||
let mut stdout = io::stdout();
|
||||
let _ = execute!(stdout, SavePosition);
|
||||
let mut i = 0;
|
||||
for char_row in 0..29 {
|
||||
for char_col in 0..64 {
|
||||
|
@ -148,7 +162,7 @@ impl Renderer for TerminalRenderer<'_> {
|
|||
let _ = queue!(
|
||||
// FG_COLOR = 0xFFCC00
|
||||
// BG_COLOR = 0x110500
|
||||
self.stdout,
|
||||
stdout,
|
||||
MoveTo(char_col, char_row),
|
||||
PrintStyledContent(
|
||||
char.with(Color::Rgb {
|
||||
|
@ -165,23 +179,46 @@ impl Renderer for TerminalRenderer<'_> {
|
|||
);
|
||||
}
|
||||
}
|
||||
let _ = self.stdout.flush();
|
||||
let _ = execute!(self.stdout, RestorePosition);
|
||||
let _ = stdout.flush();
|
||||
let _ = execute!(stdout, RestorePosition);
|
||||
// let elapsed = now.elapsed();
|
||||
// println!("{elapsed:?}");
|
||||
// exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Screen<'a> {
|
||||
// renderer: Box<dyn Renderer>,
|
||||
renderer: TerminalRenderer<'a>,
|
||||
// pub struct Screen<'a> {
|
||||
pub struct Screen {
|
||||
renderer: Box<dyn Renderer>,
|
||||
// renderer: TerminalRenderer<'a>,
|
||||
controller: CpuController,
|
||||
}
|
||||
|
||||
impl<'a> Screen<'a> {
|
||||
// pub fn new(cpu_controller: CpuController, renderer: Box<dyn Renderer>) -> Self {
|
||||
pub fn new(renderer: TerminalRenderer<'a>, controller: CpuController) -> Self {
|
||||
impl Screen {
|
||||
pub fn new(config: &Config, controller: CpuController, memory: MemHandle) -> Self {
|
||||
let renderer: Box<dyn Renderer> = match config.screen {
|
||||
ScreenType::Window => {
|
||||
let window = Window::new(
|
||||
"ʕ·ᴥ·ʔ-☆",
|
||||
512,
|
||||
380,
|
||||
WindowOptions {
|
||||
resize: true,
|
||||
borderless: true,
|
||||
title: true,
|
||||
transparency: false,
|
||||
scale: Scale::X2,
|
||||
scale_mode: ScaleMode::AspectRatioStretch,
|
||||
topmost: false,
|
||||
none: true,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
Box::new(WindowRenderer::new(memory, config.char_rom.clone(), window))
|
||||
}
|
||||
ScreenType::Terminal => Box::new(TerminalRenderer::new(memory)),
|
||||
};
|
||||
|
||||
Self {
|
||||
renderer,
|
||||
controller,
|
||||
|
|
Loading…
Reference in New Issue