From 1a59524f0298f3059a0e14d0d6c3231868f3c810 Mon Sep 17 00:00:00 2001 From: Trevor Merritt Date: Sun, 18 Aug 2024 18:15:42 -0400 Subject: [PATCH] gotta take a break --- Cargo.lock | 1143 +++++++++++++++++++++++++-- emma/Cargo.toml | 8 + emma/src/bin/emma.rs | 426 +--------- emma/src/bin/emmagui.rs | 35 + emma/src/bin/font/mod.rs | 55 -- emma/src/bin/font/text_rendering.rs | 8 +- emma/src/bin/support/clipboard.rs | 18 + emma/src/bin/support/mod.rs | 165 ++++ emma/src/chip8/computer.rs | 329 ++++++++ emma/src/chip8/cpu_states.rs | 8 + emma/src/chip8/delay_timer.rs | 0 emma/src/chip8/instructions.rs | 38 + emma/src/chip8/keypad.rs | 37 + emma/src/chip8/sound_timer.rs | 0 emma/src/chip8/system_memory.rs | 117 +++ emma/src/chip8/video.rs | 66 ++ emma/src/constants.rs | 6 + emma/src/lib.rs | 12 + 18 files changed, 1939 insertions(+), 532 deletions(-) create mode 100644 emma/src/bin/emmagui.rs delete mode 100644 emma/src/bin/font/mod.rs create mode 100644 emma/src/bin/support/clipboard.rs create mode 100644 emma/src/bin/support/mod.rs create mode 100644 emma/src/chip8/computer.rs create mode 100644 emma/src/chip8/cpu_states.rs create mode 100644 emma/src/chip8/delay_timer.rs create mode 100644 emma/src/chip8/instructions.rs create mode 100644 emma/src/chip8/keypad.rs create mode 100644 emma/src/chip8/sound_timer.rs create mode 100644 emma/src/chip8/system_memory.rs create mode 100644 emma/src/chip8/video.rs create mode 100644 emma/src/constants.rs create mode 100644 emma/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a2bb392..803df16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,6 +33,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "ahash" version = "0.8.11" @@ -46,6 +52,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "aligned-vec" version = "0.5.0" @@ -75,7 +90,7 @@ dependencies = [ "ndk 0.8.0", "ndk-context", "ndk-sys 0.5.0+25.2.9519653", - "num_enum", + "num_enum 0.7.2", "thiserror", ] @@ -96,7 +111,7 @@ dependencies = [ "ndk 0.9.0", "ndk-context", "ndk-sys 0.6.0+11769913", - "num_enum", + "num_enum 0.7.2", "thiserror", ] @@ -130,7 +145,7 @@ dependencies = [ "objc2-app-kit", "objc2-foundation", "parking_lot", - "x11rb", + "x11rb 0.13.1", ] [[package]] @@ -141,7 +156,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.71", ] [[package]] @@ -150,6 +165,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "arrayvec" version = "0.7.4" @@ -181,10 +202,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" dependencies = [ "anyhow", - "arrayvec", + "arrayvec 0.7.4", "log", "nom", - "num-rational", + "num-rational 0.4.2", "v_frame", ] @@ -194,7 +215,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" dependencies = [ - "arrayvec", + "arrayvec 0.7.4", ] [[package]] @@ -207,7 +228,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", ] @@ -312,6 +333,20 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +[[package]] +name = "calloop" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" +dependencies = [ + "bitflags 1.3.2", + "log", + "nix 0.25.1", + "slotmap", + "thiserror", + "vec_map", +] + [[package]] name = "calloop" version = "0.12.4" @@ -349,7 +384,7 @@ dependencies = [ "calloop 0.12.4", "rustix", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", ] [[package]] @@ -361,7 +396,7 @@ dependencies = [ "calloop 0.13.0", "rustix", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", ] [[package]] @@ -457,6 +492,61 @@ dependencies = [ "error-code", ] +[[package]] +name = "cmake" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" +dependencies = [ + "cc", +] + +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics 0.22.3", + "foreign-types 0.3.2", + "libc", + "objc", +] + +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics 0.23.2", + "foreign-types 0.5.0", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -496,6 +586,20 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "copypasta" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "133fc8675ee3a4ec9aa513584deda9aa0faeda3586b87f7f0f2ba082c66fb172" +dependencies = [ + "clipboard-win 3.1.1", + "objc", + "objc-foundation", + "objc_id", + "smithay-clipboard 0.6.6", + "x11-clipboard 0.7.1", +] + [[package]] name = "copypasta" version = "0.10.1" @@ -506,8 +610,8 @@ dependencies = [ "objc", "objc-foundation", "objc_id", - "smithay-clipboard", - "x11-clipboard", + "smithay-clipboard 0.7.2", + "x11-clipboard 0.9.2", ] [[package]] @@ -526,6 +630,19 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", +] + [[package]] name = "core-graphics" version = "0.23.2" @@ -535,7 +652,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation", "core-graphics-types", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -550,6 +667,18 @@ dependencies = [ "libc", ] +[[package]] +name = "core-text" +version = "20.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5" +dependencies = [ + "core-foundation", + "core-graphics 0.23.2", + "foreign-types 0.5.0", + "libc", +] + [[package]] name = "crc32fast" version = "1.4.2" @@ -584,6 +713,29 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crossfont" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb5a3822b594afc99b503cc1859b94686d3c3efdd60507a28587dab80ee1071" +dependencies = [ + "cocoa 0.25.0", + "core-foundation", + "core-foundation-sys", + "core-graphics 0.23.2", + "core-text", + "dwrote", + "foreign-types 0.5.0", + "freetype-rs", + "libc", + "log", + "objc", + "once_cell", + "pkg-config", + "servo-fontconfig", + "winapi", +] + [[package]] name = "crossterm" version = "0.28.1" @@ -592,7 +744,7 @@ checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ "bitflags 2.6.0", "crossterm_winapi", - "mio", + "mio 1.0.2", "parking_lot", "rustix", "signal-hook", @@ -615,12 +767,63 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + [[package]] name = "cursor-icon" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -651,6 +854,20 @@ dependencies = [ "mint", ] +[[package]] +name = "dwrote" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" +dependencies = [ + "lazy_static", + "libc", + "serde", + "serde_derive", + "winapi", + "wio", +] + [[package]] name = "either" version = "1.13.0" @@ -661,7 +878,28 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" name = "emmaemu" version = "0.1.0" dependencies = [ + "copypasta 0.8.2", + "glium", + "image 0.23.14", + "imgui", + "imgui-glium-renderer", + "imgui-winit-support", + "pretty_env_logger", "ratatui", + "winit 0.27.5", +] + +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", ] [[package]] @@ -686,6 +924,16 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" +[[package]] +name = "expat-sys" +version = "2.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" +dependencies = [ + "cmake", + "pkg-config", +] + [[package]] name = "exr" version = "1.72.0" @@ -696,7 +944,7 @@ dependencies = [ "flume", "half", "lebe", - "miniz_oxide", + "miniz_oxide 0.7.4", "rayon-core", "smallvec", "zune-inflate", @@ -718,7 +966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.7.4", ] [[package]] @@ -736,6 +984,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + [[package]] name = "foreign-types" version = "0.5.0" @@ -743,7 +1000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared", + "foreign-types-shared 0.3.1", ] [[package]] @@ -754,15 +1011,53 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.71", ] +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "foreign-types-shared" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "freetype-rs" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb" +dependencies = [ + "bitflags 1.3.2", + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" +dependencies = [ + "cmake", + "libc", + "pkg-config", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "gethostname" version = "0.4.3" @@ -784,6 +1079,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gif" version = "0.13.1" @@ -823,7 +1128,7 @@ dependencies = [ "glutin 0.31.3", "glutin-winit 0.4.2", "lazy_static", - "memoffset", + "memoffset 0.9.1", "raw-window-handle 0.5.2", "smallvec", "takeable-option", @@ -849,7 +1154,7 @@ dependencies = [ "objc2 0.4.1", "once_cell", "raw-window-handle 0.5.2", - "wayland-sys", + "wayland-sys 0.31.4", "windows-sys 0.48.0", "x11-dl", ] @@ -874,7 +1179,7 @@ dependencies = [ "objc2-foundation", "once_cell", "raw-window-handle 0.6.2", - "wayland-sys", + "wayland-sys 0.31.4", "windows-sys 0.52.0", "x11-dl", ] @@ -999,6 +1304,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "icrate" version = "0.0.4" @@ -1010,6 +1321,31 @@ dependencies = [ "objc2 0.4.1", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "image" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "gif 0.11.4", + "jpeg-decoder 0.1.22", + "num-iter", + "num-rational 0.3.2", + "num-traits", + "png 0.16.8", + "scoped_threadpool", + "tiff 0.6.1", +] + [[package]] name = "image" version = "0.25.2" @@ -1020,15 +1356,15 @@ dependencies = [ "byteorder-lite", "color_quant", "exr", - "gif", + "gif 0.13.1", "image-webp", "num-traits", - "png", + "png 0.17.13", "qoi", "ravif", "rayon", "rgb", - "tiff", + "tiff 0.9.1", "zune-core", "zune-jpeg", ] @@ -1111,7 +1447,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c" dependencies = [ "quote", - "syn", + "syn 2.0.71", +] + +[[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]] @@ -1122,7 +1470,18 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.71", +] + +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -1180,6 +1539,15 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" +dependencies = [ + "rayon", +] + [[package]] name = "jpeg-decoder" version = "0.3.1" @@ -1321,6 +1689,15 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + [[package]] name = "memmap2" version = "0.9.4" @@ -1330,6 +1707,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -1345,6 +1731,25 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + [[package]] name = "miniz_oxide" version = "0.7.4" @@ -1361,6 +1766,18 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff" +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "mio" version = "1.0.2" @@ -1374,6 +1791,20 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys 0.4.1+23.1.7779620", + "num_enum 0.5.11", + "raw-window-handle 0.5.2", + "thiserror", +] + [[package]] name = "ndk" version = "0.8.0" @@ -1384,7 +1815,7 @@ dependencies = [ "jni-sys", "log", "ndk-sys 0.5.0+25.2.9519653", - "num_enum", + "num_enum 0.7.2", "raw-window-handle 0.5.2", "raw-window-handle 0.6.2", "thiserror", @@ -1400,7 +1831,7 @@ dependencies = [ "jni-sys", "log", "ndk-sys 0.6.0+11769913", - "num_enum", + "num_enum 0.7.2", "raw-window-handle 0.6.2", "thiserror", ] @@ -1411,6 +1842,44 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" +[[package]] +name = "ndk-glue" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0434fabdd2c15e0aab768ca31d5b7b333717f03cf02037d5a0a3ff3c278ed67f" +dependencies = [ + "libc", + "log", + "ndk 0.7.0", + "ndk-context", + "ndk-macro", + "ndk-sys 0.4.1+23.1.7779620", + "once_cell", + "parking_lot", +] + +[[package]] +name = "ndk-macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" +dependencies = [ + "darling", + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + [[package]] name = "ndk-sys" version = "0.5.0+25.2.9519653" @@ -1435,6 +1904,31 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[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 0.6.5", +] + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + [[package]] name = "nom" version = "7.1.3" @@ -1469,7 +1963,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.71", ] [[package]] @@ -1481,6 +1975,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.2" @@ -1501,13 +2017,34 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + [[package]] name = "num_enum" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ - "num_enum_derive", + "num_enum_derive 0.7.2", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1516,10 +2053,10 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn", + "syn 2.0.71", ] [[package]] @@ -1855,7 +2392,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.71", ] [[package]] @@ -1870,6 +2407,18 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "deflate", + "miniz_oxide 0.3.7", +] + [[package]] name = "png" version = "0.17.13" @@ -1880,7 +2429,7 @@ dependencies = [ "crc32fast", "fdeflate", "flate2", - "miniz_oxide", + "miniz_oxide 0.7.4", ] [[package]] @@ -1908,6 +2457,26 @@ dependencies = [ "zerocopy-derive", ] +[[package]] +name = "pretty_env_logger" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c" +dependencies = [ + "env_logger", + "log", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -1942,7 +2511,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" dependencies = [ "quote", - "syn", + "syn 2.0.71", ] [[package]] @@ -2037,7 +2606,7 @@ checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" dependencies = [ "arbitrary", "arg_enum_proc_macro", - "arrayvec", + "arrayvec 0.7.4", "av1-grain", "bitstream-io", "built", @@ -2078,6 +2647,15 @@ dependencies = [ "rgb", ] +[[package]] +name = "raw-window-handle" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" +dependencies = [ + "cty", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -2137,6 +2715,35 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + [[package]] name = "rgb" version = "0.8.45" @@ -2177,6 +2784,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "safe_arch" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ff3d6d9696af502cc3110dacce942840fb06ff4514cad92236ecc455f2ce05" +dependencies = [ + "bytemuck", +] + [[package]] name = "same-file" version = "1.0.6" @@ -2192,12 +2808,30 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sctk-adwaita" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61270629cc6b4d77ec1907db1033d5c2e1a404c412743621981a871dc9c12339" +dependencies = [ + "crossfont", + "log", + "smithay-client-toolkit 0.16.1", + "tiny-skia 0.7.0", +] + [[package]] name = "sctk-adwaita" version = "0.8.3" @@ -2206,9 +2840,9 @@ checksum = "70b31447ca297092c5a9916fc3b955203157b37c19ca8edde4f52e9843e602c7" dependencies = [ "ab_glyph", "log", - "memmap2", + "memmap2 0.9.4", "smithay-client-toolkit 0.18.1", - "tiny-skia", + "tiny-skia 0.11.4", ] [[package]] @@ -2219,9 +2853,9 @@ checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" dependencies = [ "ab_glyph", "log", - "memmap2", + "memmap2 0.9.4", "smithay-client-toolkit 0.19.2", - "tiny-skia", + "tiny-skia 0.11.4", ] [[package]] @@ -2241,7 +2875,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.71", ] [[package]] @@ -2253,6 +2887,27 @@ dependencies = [ "serde", ] +[[package]] +name = "servo-fontconfig" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" +dependencies = [ + "libc", + "servo-fontconfig-sys", +] + +[[package]] +name = "servo-fontconfig-sys" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" +dependencies = [ + "expat-sys", + "freetype-sys", + "pkg-config", +] + [[package]] name = "signal-hook" version = "0.3.17" @@ -2270,7 +2925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", - "mio", + "mio 1.0.2", "signal-hook", ] @@ -2307,12 +2962,40 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "smithay-client-toolkit" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" +dependencies = [ + "bitflags 1.3.2", + "calloop 0.10.6", + "dlib", + "lazy_static", + "log", + "memmap2 0.5.10", + "nix 0.24.3", + "pkg-config", + "wayland-client 0.29.5", + "wayland-cursor 0.29.5", + "wayland-protocols 0.29.5", +] + [[package]] name = "smithay-client-toolkit" version = "0.18.1" @@ -2325,16 +3008,16 @@ dependencies = [ "cursor-icon", "libc", "log", - "memmap2", + "memmap2 0.9.4", "rustix", "thiserror", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", "wayland-csd-frame", - "wayland-cursor", + "wayland-cursor 0.31.5", "wayland-protocols 0.31.2", "wayland-protocols-wlr 0.2.0", - "wayland-scanner", + "wayland-scanner 0.31.4", "xkeysym", ] @@ -2350,19 +3033,29 @@ dependencies = [ "cursor-icon", "libc", "log", - "memmap2", + "memmap2 0.9.4", "rustix", "thiserror", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", "wayland-csd-frame", - "wayland-cursor", + "wayland-cursor 0.31.5", "wayland-protocols 0.32.3", "wayland-protocols-wlr 0.3.3", - "wayland-scanner", + "wayland-scanner 0.31.4", "xkeysym", ] +[[package]] +name = "smithay-clipboard" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" +dependencies = [ + "smithay-client-toolkit 0.16.1", + "wayland-client 0.29.5", +] + [[package]] name = "smithay-clipboard" version = "0.7.2" @@ -2404,6 +3097,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strum" version = "0.26.3" @@ -2423,7 +3122,18 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 2.0.71", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] @@ -2462,6 +3172,15 @@ version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2" +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.63" @@ -2479,7 +3198,18 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.71", +] + +[[package]] +name = "tiff" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437" +dependencies = [ + "jpeg-decoder 0.1.22", + "miniz_oxide 0.4.4", + "weezl", ] [[package]] @@ -2489,10 +3219,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" dependencies = [ "flate2", - "jpeg-decoder", + "jpeg-decoder 0.3.1", "weezl", ] +[[package]] +name = "tiny-skia" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "bytemuck", + "cfg-if", + "png 0.17.13", + "safe_arch", + "tiny-skia-path 0.7.0", +] + [[package]] name = "tiny-skia" version = "0.11.4" @@ -2500,11 +3245,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" dependencies = [ "arrayref", - "arrayvec", + "arrayvec 0.7.4", "bytemuck", "cfg-if", "log", - "tiny-skia-path", + "tiny-skia-path 0.11.4", +] + +[[package]] +name = "tiny-skia-path" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c114d32f0c2ee43d585367cb013dfaba967ab9f62b90d9af0d696e955e70fa6c" +dependencies = [ + "arrayref", + "bytemuck", ] [[package]] @@ -2539,6 +3294,17 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.21.1" @@ -2591,11 +3357,11 @@ name = "trevors_chip8_toy" version = "0.1.0" dependencies = [ "arboard", - "copypasta", + "copypasta 0.10.1", "glium", "glutin 0.32.0", "glutin-winit 0.5.0", - "image", + "image 0.25.2", "imgui", "imgui-glium-renderer", "imgui-winit-support", @@ -2651,6 +3417,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version-compare" version = "0.2.0" @@ -2700,7 +3472,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.71", "wasm-bindgen-shared", ] @@ -2734,7 +3506,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.71", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2756,7 +3528,23 @@ dependencies = [ "rustix", "scoped-tls", "smallvec", - "wayland-sys", + "wayland-sys 0.31.4", +] + +[[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 0.24.3", + "scoped-tls", + "wayland-commons", + "wayland-scanner 0.29.5", + "wayland-sys 0.29.5", ] [[package]] @@ -2768,7 +3556,19 @@ dependencies = [ "bitflags 2.6.0", "rustix", "wayland-backend", - "wayland-scanner", + "wayland-scanner 0.31.4", +] + +[[package]] +name = "wayland-commons" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +dependencies = [ + "nix 0.24.3", + "once_cell", + "smallvec", + "wayland-sys 0.29.5", ] [[package]] @@ -2782,6 +3582,17 @@ dependencies = [ "wayland-backend", ] +[[package]] +name = "wayland-cursor" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" +dependencies = [ + "nix 0.24.3", + "wayland-client 0.29.5", + "xcursor", +] + [[package]] name = "wayland-cursor" version = "0.31.5" @@ -2789,10 +3600,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95" dependencies = [ "rustix", - "wayland-client", + "wayland-client 0.31.5", "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 0.29.5", + "wayland-commons", + "wayland-scanner 0.29.5", +] + [[package]] name = "wayland-protocols" version = "0.31.2" @@ -2801,8 +3624,8 @@ checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ "bitflags 2.6.0", "wayland-backend", - "wayland-client", - "wayland-scanner", + "wayland-client 0.31.5", + "wayland-scanner 0.31.4", ] [[package]] @@ -2813,8 +3636,8 @@ checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" dependencies = [ "bitflags 2.6.0", "wayland-backend", - "wayland-client", - "wayland-scanner", + "wayland-client 0.31.5", + "wayland-scanner 0.31.4", ] [[package]] @@ -2825,9 +3648,9 @@ checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ "bitflags 2.6.0", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", "wayland-protocols 0.31.2", - "wayland-scanner", + "wayland-scanner 0.31.4", ] [[package]] @@ -2838,9 +3661,9 @@ checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" dependencies = [ "bitflags 2.6.0", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", "wayland-protocols 0.32.3", - "wayland-scanner", + "wayland-scanner 0.31.4", ] [[package]] @@ -2851,9 +3674,9 @@ checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ "bitflags 2.6.0", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", "wayland-protocols 0.31.2", - "wayland-scanner", + "wayland-scanner 0.31.4", ] [[package]] @@ -2864,9 +3687,20 @@ checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" dependencies = [ "bitflags 2.6.0", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", "wayland-protocols 0.32.3", - "wayland-scanner", + "wayland-scanner 0.31.4", +] + +[[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]] @@ -2880,6 +3714,17 @@ dependencies = [ "quote", ] +[[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 = "wayland-sys" version = "0.31.4" @@ -2953,12 +3798,34 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "winapi-wsapoll" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1eafc5f679c576995526e81635d0cf9695841736712b4e892f87abbe6fed3f28" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -3050,6 +3917,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -3068,6 +3941,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -3092,6 +3971,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -3110,6 +3995,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -3146,6 +4037,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -3164,6 +4061,40 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winit" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" +dependencies = [ + "bitflags 1.3.2", + "cocoa 0.24.1", + "core-foundation", + "core-graphics 0.22.3", + "dispatch", + "instant", + "libc", + "log", + "mint", + "mio 0.8.11", + "ndk 0.7.0", + "ndk-glue", + "objc", + "once_cell", + "parking_lot", + "percent-encoding", + "raw-window-handle 0.4.3", + "raw-window-handle 0.5.2", + "sctk-adwaita 0.4.3", + "smithay-client-toolkit 0.16.1", + "wasm-bindgen", + "wayland-client 0.29.5", + "wayland-protocols 0.29.5", + "web-sys", + "windows-sys 0.36.1", + "x11-dl", +] + [[package]] name = "winit" version = "0.29.15" @@ -3178,13 +4109,13 @@ dependencies = [ "calloop 0.12.4", "cfg_aliases 0.1.1", "core-foundation", - "core-graphics", + "core-graphics 0.23.2", "cursor-icon", "icrate", "js-sys", "libc", "log", - "memmap2", + "memmap2 0.9.4", "ndk 0.8.0", "ndk-sys 0.5.0+25.2.9519653", "objc2 0.4.1", @@ -3202,14 +4133,14 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", "wayland-protocols 0.31.2", "wayland-protocols-plasma 0.2.0", "web-sys", "web-time 0.2.4", "windows-sys 0.48.0", "x11-dl", - "x11rb", + "x11rb 0.13.1", "xkbcommon-dl", ] @@ -3229,12 +4160,12 @@ dependencies = [ "cfg_aliases 0.2.1", "concurrent-queue", "core-foundation", - "core-graphics", + "core-graphics 0.23.2", "cursor-icon", "dpi", "js-sys", "libc", - "memmap2", + "memmap2 0.9.4", "ndk 0.9.0", "objc2 0.5.2", "objc2-app-kit", @@ -3254,14 +4185,14 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wayland-backend", - "wayland-client", + "wayland-client 0.31.5", "wayland-protocols 0.32.3", "wayland-protocols-plasma 0.3.3", "web-sys", "web-time 1.1.0", "windows-sys 0.52.0", "x11-dl", - "x11rb", + "x11rb 0.13.1", "xkbcommon-dl", ] @@ -3283,6 +4214,24 @@ dependencies = [ "memchr", ] +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + +[[package]] +name = "x11-clipboard" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "980b9aa9226c3b7de8e2adb11bf20124327c054e0e5812d2aac0b5b5a87e7464" +dependencies = [ + "x11rb 0.10.1", +] + [[package]] name = "x11-clipboard" version = "0.9.2" @@ -3290,7 +4239,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98785a09322d7446e28a13203d2cae1059a0dd3dfb32cb06d0a225f023d8286" dependencies = [ "libc", - "x11rb", + "x11rb 0.13.1", ] [[package]] @@ -3304,6 +4253,19 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "x11rb" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" +dependencies = [ + "gethostname 0.2.3", + "nix 0.24.3", + "winapi", + "winapi-wsapoll", + "x11rb-protocol 0.10.0", +] + [[package]] name = "x11rb" version = "0.13.1" @@ -3311,12 +4273,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" dependencies = [ "as-raw-xcb-connection", - "gethostname", + "gethostname 0.4.3", "libc", "libloading", "once_cell", "rustix", - "x11rb-protocol", + "x11rb-protocol 0.13.1", +] + +[[package]] +name = "x11rb-protocol" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" +dependencies = [ + "nix 0.24.3", ] [[package]] @@ -3374,7 +4345,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.71", ] [[package]] diff --git a/emma/Cargo.toml b/emma/Cargo.toml index e2b7193..b747c4b 100644 --- a/emma/Cargo.toml +++ b/emma/Cargo.toml @@ -6,3 +6,11 @@ autobenches = true [dependencies] ratatui = "0.28.0" +glium = { version = "0.34.0", default-features = true } +image = "0.23" +imgui = { version ="0.12.0", features = ["tables-api"] } +imgui-glium-renderer = { version = "0.12.0" } +imgui-winit-support = { version = "0.12.0" } +winit = { version = "0.27", features = ["x11", "mint"] } +pretty_env_logger = "0.5.0" +copypasta = "0.8" diff --git a/emma/src/bin/emma.rs b/emma/src/bin/emma.rs index b2a8222..b201812 100644 --- a/emma/src/bin/emma.rs +++ b/emma/src/bin/emma.rs @@ -1,6 +1,6 @@ use std::io::{stdout, Result}; -use font::load_fonts_into_memory; +use emmaemu::{chip8::{computer::Chip8Computer, video::Chip8Video}, constants::{CHIP8_MEMORY_SIZE, CHIP8_REGISTER_COUNT, CHIP8_ROM_SIZE, CHIP8_VIDEO_MEMORY}}; use ratatui::{ backend::CrosstermBackend, crossterm::{ @@ -9,82 +9,11 @@ use ratatui::{ ExecutableCommand, }, layout::{Alignment, Rect}, - style::Stylize, - widgets::{List, Paragraph}, + style::{Style, Stylize}, + widgets::{List, Paragraph, Widget}, Frame, Terminal, }; -// nnn or addr - A 12-bit value, the lowest 12 bits of the instruction -pub fn read_addr_from_instruction(instruction_to_read_from: u16) -> u16 { - instruction_to_read_from & 0b0000111111111111 -} - -// n or nibble - A 4-bit value, the lowest 4 bits of the instruction -pub fn read_nibble_from_instruction(instruction_to_read_from: u16) -> u16 { - instruction_to_read_from & 0b0000000000001111 -} - -// x - A 4-bit value, the lower 4 bits of the high byte of the instruction -pub fn read_x_from_instruction(instruction_to_read_from: u16) -> u16 { - (instruction_to_read_from & 0b0000111100000000).rotate_right(8) -} - -// y - A 4-bit value, the upper 4 bits of the low byte of the instruction -pub fn read_y_from_instruction(instruction_to_read_from: u16) -> u16 { - (instruction_to_read_from & 0b0000000011110000).rotate_right(4) -} - -// kk or byte - An 8-bit value, the lowest 8 bits of the instruction -pub fn read_byte_from_instruction(instruction_to_read_from: u16) -> u16 { - (instruction_to_read_from & 0b0000000011111111) -} - -mod font; - -#[derive(Clone)] -struct Chip8CpuData { - pub pc: u16, - pub sp: u8, - pub memory: [u8; CHIP8_MEMORY_SIZE as usize], - pub video_memory: [bool; CHIP8_VIDEO_MEMORY], - pub registers: [u8; 16], - pub sound_timer: u8, - pub delay_timer: u8, - pub i_register: u16, -} -const CHIP8_REGISTER_COUNT: i32 = 16; -const CHIP8_MEMORY_SIZE: i32 = 2048i32; -const CHIP8_VIDEO_WIDTH: i32 = 64i32; -const CHIP8_VIDEO_HEIGHT: i32 = 32i32; -const CHIP8_VIDEO_MEMORY: usize = (CHIP8_VIDEO_HEIGHT * CHIP8_VIDEO_WIDTH) as usize; -const CHIP8_ROM_SIZE: usize = 512; - -impl Default for Chip8CpuData { - fn default() -> Self { - let mut memory: [u8; 2048] = [0; 2048]; - - memory = load_fonts_into_memory(memory); - - dump_memory_to_console(memory); - - Self { - pc: 0x0200, - sp: 0x00, - memory: [0; 2048], - video_memory: [false; CHIP8_VIDEO_MEMORY], - registers: [0; CHIP8_REGISTER_COUNT as usize], - sound_timer: 0xFF, - delay_timer: 0xFF, - i_register: 0x0000, - } - } -} - -impl Chip8CpuData { - pub fn new() -> Self { - Chip8CpuData::default() - } -} fn system_memory_to_text_render(data_to_dump: [u8; 2048]) -> String { let mut to_return = String::new(); @@ -107,311 +36,25 @@ fn dump_memory_to_console(data_to_dump: [u8; 2048]) { panic!("DONE DUMPING"); } -fn display_data_to_text_render(data_display: [bool; 2048]) -> String { - let mut output = String::new(); - for row in 0..32 { - let row_offset = row * 32; - for column in 0..64 { - let data_position = row_offset + column; - println!("DP {} {} {} {}", data_position, row, row_offset, column); - output += if data_display[data_position] { - "*" - } else { - " " - }; - } - output += "\n"; - } - output +struct ControlKeyboard { + } -fn render_display(display_data: [bool; 2048]) { - println!("{}", display_data_to_text_render(display_data)); -} - -#[derive(Clone)] -enum Chip8CpuStates { - WaitingForInstruction, - ExecutingInstruction, - Error, -} - -struct Chip8CpuState { - state: Chip8CpuStates, - cpu: Chip8CpuData -} - -enum Chip8CpuInstructions { - SysAddr(u16), // 0x0nnn Exit to System Call - CLS, // 0x00E0 Clear Screen - RET, // 0x00EE Return from Subroutine - JpAddr(u16), // 0x1nnn Jump to Address - CallAddr(u16), // 0x2nnn Call Subroutine - SeVxByte(u16, u16), // 0x3xkk Skip next instruction if Vx = kk. - SneVxByte(u16, u16), // 0x4xkk Skip next instruction if Vx != kk - SeVxVy(u16, u16), // 0x5xy0 Skip next instruction if Vx == Vy - LdVxByte(u16, u16), // 0x6xkk Set Vx = kk - AddVxByte(u16, u16), // 0x7xkk Set Vx = Vx + kk - LdVxVy(u16, u16), // 0x8xy0 Set value of Vy in Vx - OrVxVy(u16, u16), // 0x8xy1 Set Vx = Vx OR Vy - AndVxVy(u16, u16), // 0x8xy2 Set Vx = Vx AND Vy - XorVxVy(u16, u16), // 0x8xy3 Set Vx = Vx XOR Vy - AddVxVy(u16, u16), // 0x8xy4 Set Vx = Vx + Vy (SET VF on Carry) - SubVxVy(u16, u16), // 0x8xy5 Set Vx = Vx - Vy (Set VF NOT Borrow) - ShrVxVy(u16, u16), // 0x8xy6 Set Vx = Vx SHR 1 (Shift Rotated Right 1) - SubnVxVy(u16, u16), // 0x8xy7 Set Vx = Vy - Vx (Set VF NOT Borrow) - ShlVxVy(u16, u16), // 0x8xyE Shift Left - SneVxVy(u16, u16), // 0x9xy0 Skip next instruction if Vx != Vy - LdIAddr(u16), // 0xAnnn VI = nnn - JpV0Addr(u16), // 0xBnnn Jump to nnn+V0 - RndVxByte(u16, u16), // 0xCxkk Vx = random byte AND kk - DrawVxVyNibble(u16, u16, u16), // 0xDxyn Display N byte sprite starting at Vx to Vy - SkpVx(u16), // 0xE09E Skip next instruction if key in Vx pressed - SnkpVx(u16), // 0xE0A1 Skip next instruction if key in Vx NOT pressed - LdVxDt(u16), // 0xFx07 Set Vx = Delay timer - LdVxK(u16), // 0xFx0A Wait for key, put in Vx - LdDtVx(u16), // 0xFx15 Set Delay Timer - LdStVx(u16), // 0xFx18 Set Sount Timer - AddIVx(u16), // 0xFx1E I = I + Vx - LdFVu(u16), // 0xFx29 Set I = Location of sprite for Digit Vx - LdBVx(u16), // 0xFx33 Store BCD of Vx in I, I+1, I+2 - LdIVx(u16), // 0xFx55 Store V0 to Vx in memory starting at I - LdVxI(u16), // 0xFx65 Load V0 to Vx in memory starting at I - XXXXERRORINSTRUCTION, -} - -fn bytes_to_instruction(to_read: u16) -> Chip8CpuInstructions { - let mut decoded_instruction = Chip8CpuInstructions::XXXXERRORINSTRUCTION; - - match to_read { - 0x00E0 => { - // 00E0 - CLS - // Clear the display. - decoded_instruction = Chip8CpuInstructions::CLS; - } - 0x00EE => { - // 00EE - RET - // Return from a subroutine. - - decoded_instruction = Chip8CpuInstructions::RET; - } - 0x0000..=0x0FFF => { - // 0nnn - SYS addr - // Jump to a machine code routine at nnn. - decoded_instruction = - Chip8CpuInstructions::SysAddr(read_addr_from_instruction(to_read)); - } - 0x1000..=0x1FFF => { - // 1nnn - JP addr - // Jump to location nnn. - decoded_instruction = Chip8CpuInstructions::JpAddr(read_addr_from_instruction(to_read)); - } - 0x2000..=0x2FFF => { - // 2nnn - CALL addr - // Call subroutine at nnn. - decoded_instruction = - Chip8CpuInstructions::CallAddr(read_addr_from_instruction(to_read)); - } - 0x3000..=0x3FFF => { - // 3xkk - SE Vx, byte - // Skip next instruction if Vx = kk. - decoded_instruction = Chip8CpuInstructions::SeVxByte( - read_x_from_instruction(to_read), - read_byte_from_instruction(to_read), - ) - } - 0x4000..=0x4FFF => { - // 4xkk - SNE Vx, byte - // Skip next instruction if Vx != kk. - decoded_instruction = Chip8CpuInstructions::SneVxByte( - read_x_from_instruction(to_read), - read_byte_from_instruction(to_read), - ); - } - 0x5000..=0x5FF0 => { - // 5xy0 - SE Vx, Vy - // Skip next instruction if Vx = Vy. - decoded_instruction = Chip8CpuInstructions::SeVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ) - } - 0x6000..=0x6FFF => { - // 6xkk - LD Vx, byte - // Set Vx = kk. - decoded_instruction = Chip8CpuInstructions::LdVxVy( - read_x_from_instruction(to_read), - read_byte_from_instruction(to_read), - ); - } - 0x7000..=0x7FFF => { - // ADD Vx, Byte - decoded_instruction = Chip8CpuInstructions::AddVxByte( - read_x_from_instruction(to_read), - read_byte_from_instruction(to_read), - ); - } - 0x8000..=0x8FFE => { - // 0x8000 Series - let last_nibble = to_read | 0x8000; - match last_nibble { - 0x0 => { - // LD Vx, Vy - decoded_instruction = Chip8CpuInstructions::LdVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - 0x1 => { - // OR Vx, Vy - decoded_instruction = Chip8CpuInstructions::OrVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - 0x2 => { - // AND Vx, Vy - decoded_instruction = Chip8CpuInstructions::AndVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - 0x3 => { - // XOR Vx, Vy - decoded_instruction = Chip8CpuInstructions::XorVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - 0x4 => { - // AND Vx, Vy - decoded_instruction = Chip8CpuInstructions::AndVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - 0x5 => { - // SUB Vx, Vy - decoded_instruction = Chip8CpuInstructions::SubnVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - 0x6 => { - // SHR Vx, {, Vy } - decoded_instruction = Chip8CpuInstructions::ShrVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - 0x7 => { - // SUBN Vx, Vy - decoded_instruction = Chip8CpuInstructions::SubnVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - 0xE => { - // SHL Vx, {, Vy} - decoded_instruction = Chip8CpuInstructions::ShlVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - _ => { - panic!("UNABLE TO DECODE 0x8000 SERIES INSTRUCTION"); - } - } - } - 0x9000..=0x9FF0 => { - // SNE Vx, Vy - decoded_instruction = Chip8CpuInstructions::SneVxVy( - read_x_from_instruction(to_read), - read_y_from_instruction(to_read), - ); - } - 0xA000..=0xAFFF => { - // LD I, Addr - decoded_instruction = - Chip8CpuInstructions::LdIAddr(read_addr_from_instruction(to_read)); - } - 0xB000..=0xBFFF => { - // JP V0, Addr - } - 0xC000..=0xCFFF => { - // RND Vx, byte - } - 0xD000..0xDFFF => { - // DRAW Vx, Vy, nibble - } - 0xE09E..=0xEFA1 => {} - _ => { - panic!("UNABLE TO DECODE INSTRUCTION") - } - } - - return decoded_instruction; -} - -impl Chip8CpuState { - fn execute(&mut self, event: Chip8CpuInstructions) { - match (self.state.clone(), event) { - (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SysAddr(new_address)) => { - self.cpu.pc = new_address; - }, - _ => () - } +impl Widget for ControlKeyboard { + fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer) + where + Self: Sized { + let style = Style::new(); + buf.set_string(0, 0, "F1 to cycle foreground - F2 to cycle background", style) } } -#[derive(Clone)] -struct Chip8System { - pub system_memory: [u8; 2048], - pub rom: [u8; 512], - pub sound_timer: u8, - pub system_timer: u8, -} - -impl Default for Chip8System { - fn default() -> Self { - // init by loading the fonts... - let mut working_system_memory: [u8; CHIP8_MEMORY_SIZE as usize] = - [0; CHIP8_MEMORY_SIZE as usize]; - - // Load fonts to memory - working_system_memory = load_fonts_into_memory(working_system_memory); - - Self { - system_memory: working_system_memory, - rom: [0; CHIP8_ROM_SIZE], - sound_timer: 0, - system_timer: 0, - } - } -} - -impl Chip8System { - fn add_fonts_to_memory( - to_add_fonts_to: [u8; CHIP8_MEMORY_SIZE as usize], - ) -> [u8; CHIP8_MEMORY_SIZE as usize] { - panic!("DONT USE THIS USE \"load_fonts_into_memory\" INSTEAD"); - } - - pub fn new() -> Self { - Chip8System { - system_memory: [0; CHIP8_MEMORY_SIZE as usize], - rom: [0; CHIP8_ROM_SIZE as usize], - sound_timer: 0, - system_timer: 0, - } - } -} #[derive(Clone)] struct AppState { - menu_items: Vec, - selected_menu_item: i32, - system: Chip8CpuData, + pub menu_items: Vec, + pub selected_menu_item: i32, + pub system: Chip8Computer, } impl Default for AppState { @@ -424,7 +67,7 @@ impl Default for AppState { "Item 3".into(), ], selected_menu_item: 0, - system: Chip8CpuData { + system: Chip8Computer { ..Default::default() }, } @@ -432,21 +75,22 @@ impl Default for AppState { } fn main() -> Result<()> { - // stdout().execute(EnterAlternateScreen)?; - // enable_raw_mode()?; - // let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; - // terminal.clear()?; + stdout().execute(EnterAlternateScreen)?; + enable_raw_mode()?; + let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; + terminal.clear()?; let app = AppState::default(); loop { // Draw Ui... - - // terminal.draw(|frame| { - // render_menu_list(app.clone(), frame); - // render_cpu_state(app.system.clone(), frame); - // })?; - + terminal.draw(|frame| { + frame.render_widget(app.system.memory, frame.area()); + // frame.render_widget(app.control_keyboard, area); + //render_cpu_state(app.system.clone(), frame); + // render_video_state(app.system.video_memory, frame); + // render_menu_list(app.clone(), frame); + })?; // ...handle Events. if event::poll(std::time::Duration::from_millis(16))? { if let event::Event::Key(key) = event::read()? { @@ -458,13 +102,11 @@ fn main() -> Result<()> { KeyCode::F(12) => { println!("Resetting CPU"); } + KeyCode::Char('q') => { break; } _ => (), }, _ => (), } - if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { - break; - } } } } @@ -476,21 +118,27 @@ fn main() -> Result<()> { #[cfg(test)] mod test { + use emmaemu::constants::{CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH}; + use crate::*; #[test] fn blank_screen_renders_to_text() { + let test_video = Chip8Video::default(); + + let blank_data: [bool; CHIP8_VIDEO_MEMORY] = [false; CHIP8_VIDEO_MEMORY]; let blank_screen = (" ".repeat(CHIP8_VIDEO_WIDTH.try_into().unwrap()) + "\n") .repeat(CHIP8_VIDEO_HEIGHT.try_into().unwrap()); - assert_eq!(display_data_to_text_render(blank_data), blank_screen); - } + + assert_eq!(Chip8Video::new(blank_data).format_as_string(), blank_screen); + } #[test] fn filled_screen_renders_to_text() { let filled_data: [bool; CHIP8_VIDEO_MEMORY] = [true; CHIP8_VIDEO_MEMORY]; let filled_screen = ("*".repeat(CHIP8_VIDEO_WIDTH.try_into().unwrap()) + "\n") .repeat(CHIP8_VIDEO_HEIGHT.try_into().unwrap()); - assert_eq!(display_data_to_text_render(filled_data), filled_screen); + assert_eq!(Chip8Video::new(filled_data).format_as_string(), filled_screen); } #[test] @@ -511,6 +159,6 @@ mod test { } } - assert_eq!(display_data_to_text_render(grid_data), expected_data); + assert_eq!(Chip8Video::new(grid_data).format_as_string(), expected_data); } } diff --git a/emma/src/bin/emmagui.rs b/emma/src/bin/emmagui.rs new file mode 100644 index 0000000..2939fc9 --- /dev/null +++ b/emma/src/bin/emmagui.rs @@ -0,0 +1,35 @@ +use emmaemu::{ + chip8::computer::Chip8Computer, + constants::{CHIP8_MEMORY_SIZE, CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH}, +}; +use imgui::*; +use ratatui::symbols::half_block; +use sys::{ImColor, ImVec2, ImVector_ImU32}; + +mod support; +fn main() { + let system = Chip8Computer::default(); + let mut value = 1; + let choices = ["test test this is 1", "test test this is 2"]; + support::simple_init(file!(), move |_, ui| { + ui.window("EmmaGui") + .size([300.0, 110.0], Condition::FirstUseEver) + .build(|| { + system.memory.gui_render(ui); + ui.text_wrapped("Hello world!"); + ui.text_wrapped("こんにちは世界!"); + if ui.button(choices[value]) { + value += 1; + value %= 2; + } + + ui.button("This...is...imgui-rs!"); + ui.separator(); + let mouse_pos = ui.io().mouse_pos; + ui.text(format!( + "Mouse Position: ({:.1},{:.1})", + mouse_pos[0], mouse_pos[1] + )); + }); + }); +} diff --git a/emma/src/bin/font/mod.rs b/emma/src/bin/font/mod.rs deleted file mode 100644 index c4a99bb..0000000 --- a/emma/src/bin/font/mod.rs +++ /dev/null @@ -1,55 +0,0 @@ -use crate::CHIP8_MEMORY_SIZE; - - -pub mod text_rendering; - -pub const CHIP8FONT_0: [u8; 5] = [0xF0, 0x90, 0x90, 0x90, 0xF0]; -pub const CHIP8FONT_1: [u8; 5] = [0x20, 0x60, 0x20, 0x20, 0x70]; -pub const CHIP8FONT_2: [u8; 5] = [0xF0, 0x10, 0xF0, 0x80, 0xF0]; -pub const CHIP8FONT_3: [u8; 5] = [0xF0, 0x10, 0xF0, 0x10, 0xF0]; -pub const CHIP8FONT_4: [u8; 5] = [0x90, 0x90, 0xF0, 0x10, 0x10]; -pub const CHIP8FONT_5: [u8; 5] = [0xF0, 0x80, 0xF0, 0x10, 0xF0]; -pub const CHIP8FONT_6: [u8; 5] = [0xF0, 0x80, 0xF0, 0x90, 0xF0]; -pub const CHIP8FONT_7: [u8; 5] = [0xF0, 0x10, 0x20, 0x40, 0x40]; -pub const CHIP8FONT_8: [u8; 5] = [0xF0, 0x90, 0xF0, 0x90, 0xF0]; -pub const CHIP8FONT_9: [u8; 5] = [0xF0, 0x90, 0xF0, 0x10, 0xF0]; -pub const CHIP8FONT_A: [u8; 5] = [0xF0, 0x90, 0xF0, 0x90, 0x90]; -pub const CHIP8FONT_B: [u8; 5] = [0xE0, 0x90, 0xE0, 0x90, 0xE0]; -pub const CHIP8FONT_C: [u8; 5] = [0xF0, 0x80, 0x80, 0x80, 0xF0]; -pub const CHIP8FONT_D: [u8; 5] = [0xE0, 0x90, 0x90, 0x90, 0xE0]; -pub const CHIP8FONT_E: [u8; 5] = [0xF0, 0x80, 0xF0, 0x80, 0xF0]; -pub const CHIP8FONT_F: [u8; 5] = [0xF0, 0x80, 0xF0, 0x80, 0x80]; - -pub fn load_fonts_into_memory(to_add_fonts_to: [u8; CHIP8_MEMORY_SIZE as usize]) - -> [u8; CHIP8_MEMORY_SIZE as usize] { - - let mut memory = to_add_fonts_to.clone(); - - let all_font_characters = [ - CHIP8FONT_0, - CHIP8FONT_1, - CHIP8FONT_2, - CHIP8FONT_3, - CHIP8FONT_4, - CHIP8FONT_5, - CHIP8FONT_6, - CHIP8FONT_7, - CHIP8FONT_8, - CHIP8FONT_9, - CHIP8FONT_A, - CHIP8FONT_B, - CHIP8FONT_C, - CHIP8FONT_D, - CHIP8FONT_E, - CHIP8FONT_F, - ]; - - for (font_index, current_font) in all_font_characters.iter().enumerate() { - for font_mem_offset in 0..=4 { - let real_offset = font_index * 5 + font_mem_offset; - memory[real_offset] = current_font[font_mem_offset]; - } - } - - memory - } \ No newline at end of file diff --git a/emma/src/bin/font/text_rendering.rs b/emma/src/bin/font/text_rendering.rs index a2b9150..0781aea 100644 --- a/emma/src/bin/font/text_rendering.rs +++ b/emma/src/bin/font/text_rendering.rs @@ -1,9 +1,9 @@ use ratatui::{style::Stylize, widgets::{List, Paragraph}, Frame}; -use crate::{AppState, Chip8CpuData, CHIP8_REGISTER_COUNT}; +use crate::{AppState, Chip8Computer, CHIP8_REGISTER_COUNT, CHIP8_VIDEO_MEMORY}; -pub fn render_cpu_state(cpu_state: Chip8CpuData, frame: &mut Frame) { +pub fn render_cpu_state(cpu_state: Chip8Computer, frame: &mut Frame) { let mut area = frame.area(); let mut current_state: Vec = vec![]; @@ -34,3 +34,7 @@ pub fn render_hello_world(frame: &mut Frame) { area, ); } + +pub fn render_video_state(video_memory: [bool; CHIP8_VIDEO_MEMORY], frame: &mut Frame) { + +} \ No newline at end of file diff --git a/emma/src/bin/support/clipboard.rs b/emma/src/bin/support/clipboard.rs new file mode 100644 index 0000000..dd74d06 --- /dev/null +++ b/emma/src/bin/support/clipboard.rs @@ -0,0 +1,18 @@ +use copypasta::{ClipboardContext, ClipboardProvider}; +use imgui::ClipboardBackend; + +pub struct ClipboardSupport(pub ClipboardContext); + +pub fn init() -> Option { + ClipboardContext::new().ok().map(ClipboardSupport) +} + +impl ClipboardBackend for ClipboardSupport { + fn get(&mut self) -> Option { + self.0.get_contents().ok() + } + fn set(&mut self, text: &str) { + // ignore errors? + let _ = self.0.set_contents(text.to_owned()); + } +} diff --git a/emma/src/bin/support/mod.rs b/emma/src/bin/support/mod.rs new file mode 100644 index 0000000..c989f43 --- /dev/null +++ b/emma/src/bin/support/mod.rs @@ -0,0 +1,165 @@ +use glium::glutin::surface::WindowSurface; +use glium::{Display, Surface}; +use imgui::{Context, FontConfig, FontGlyphRanges, FontSource, Ui}; +use imgui_glium_renderer::Renderer; +use imgui_winit_support::winit::dpi::LogicalSize; +use imgui_winit_support::winit::event::{Event, WindowEvent}; +use imgui_winit_support::winit::event_loop::EventLoop; +use imgui_winit_support::winit::window::WindowBuilder; +use imgui_winit_support::{HiDpiMode, WinitPlatform}; +use std::path::Path; +use std::time::Instant; + +pub mod clipboard; + +pub const FONT_SIZE: f32 = 13.0; + +#[allow(dead_code)] // annoyingly, RA yells that this is unusued +pub fn simple_init(title: &str, run_ui: F) { + init_with_startup(title, |_, _, _| {}, run_ui); +} + +pub fn init_with_startup(title: &str, mut startup: FInit, mut run_ui: FUi) +where + FInit: FnMut(&mut Context, &mut Renderer, &Display) + 'static, + FUi: FnMut(&mut bool, &mut Ui) + 'static, +{ + let mut imgui = create_context(); + + let title = match Path::new(&title).file_name() { + Some(file_name) => file_name.to_str().unwrap(), + None => title, + }; + let event_loop = EventLoop::new().expect("Failed to create EventLoop"); + + let builder = WindowBuilder::new() + .with_maximized(true) + .with_title(title); + // .with_inner_size(LogicalSize::new(1024, 768)); + let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new() + .set_window_builder(builder) + .build(&event_loop); + let mut renderer = Renderer::init(&mut imgui, &display).expect("Failed to initialize renderer"); + + if let Some(backend) = clipboard::init() { + imgui.set_clipboard_backend(backend); + } else { + eprintln!("Failed to initialize clipboard"); + } + + let mut platform = WinitPlatform::init(&mut imgui); + { + let dpi_mode = if let Ok(factor) = std::env::var("IMGUI_EXAMPLE_FORCE_DPI_FACTOR") { + // Allow forcing of HiDPI factor for debugging purposes + match factor.parse::() { + Ok(f) => HiDpiMode::Locked(f), + Err(e) => panic!("Invalid scaling factor: {}", e), + } + } else { + HiDpiMode::Default + }; + + platform.attach_window(imgui.io_mut(), &window, dpi_mode); + } + + let mut last_frame = Instant::now(); + + startup(&mut imgui, &mut renderer, &display); + + event_loop + .run(move |event, window_target| match event { + Event::NewEvents(_) => { + let now = Instant::now(); + imgui.io_mut().update_delta_time(now - last_frame); + last_frame = now; + } + Event::AboutToWait => { + platform + .prepare_frame(imgui.io_mut(), &window) + .expect("Failed to prepare frame"); + window.request_redraw(); + } + Event::WindowEvent { + event: WindowEvent::RedrawRequested, + .. + } => { + let ui = imgui.frame(); + + let mut run = true; + run_ui(&mut run, ui); + if !run { + window_target.exit(); + } + + let mut target = display.draw(); + target.clear_color_srgb(1.0, 1.0, 1.0, 1.0); + platform.prepare_render(ui, &window); + let draw_data = imgui.render(); + renderer + .render(&mut target, draw_data) + .expect("Rendering failed"); + target.finish().expect("Failed to swap buffers"); + } + Event::WindowEvent { + event: WindowEvent::Resized(new_size), + .. + } => { + if new_size.width > 0 && new_size.height > 0 { + display.resize((new_size.width, new_size.height)); + } + platform.handle_event(imgui.io_mut(), &window, &event); + } + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } => window_target.exit(), + event => { + platform.handle_event(imgui.io_mut(), &window, &event); + } + }) + .expect("EventLoop error"); +} + +/// Creates the imgui context +pub fn create_context() -> imgui::Context { + let mut imgui = Context::create(); + // Fixed font size. Note imgui_winit_support uses "logical + // pixels", which are physical pixels scaled by the devices + // scaling factor. Meaning, 13.0 pixels should look the same size + // on two different screens, and thus we do not need to scale this + // value (as the scaling is handled by winit) + imgui.fonts().add_font(&[ + FontSource::TtfData { + data: include_bytes!("../../../../resources/Roboto-Regular.ttf"), + size_pixels: FONT_SIZE, + config: Some(FontConfig { + // As imgui-glium-renderer isn't gamma-correct with + // it's font rendering, we apply an arbitrary + // multiplier to make the font a bit "heavier". With + // default imgui-glow-renderer this is unnecessary. + rasterizer_multiply: 1.5, + // Oversampling font helps improve text rendering at + // expense of larger font atlas texture. + oversample_h: 4, + oversample_v: 4, + ..FontConfig::default() + }), + }, + FontSource::TtfData { + data: include_bytes!("../../../../resources/mplus-1p-regular.ttf"), + size_pixels: FONT_SIZE, + config: Some(FontConfig { + // Oversampling font helps improve text rendering at + // expense of larger font atlas texture. + oversample_h: 4, + oversample_v: 4, + // Range of glyphs to rasterize + glyph_ranges: FontGlyphRanges::japanese(), + ..FontConfig::default() + }), + }, + ]); + imgui.set_ini_filename(None); + + imgui +} diff --git a/emma/src/chip8/computer.rs b/emma/src/chip8/computer.rs new file mode 100644 index 0000000..680f5ca --- /dev/null +++ b/emma/src/chip8/computer.rs @@ -0,0 +1,329 @@ +use crate::constants::{CHIP8_MEMORY_SIZE, CHIP8_REGISTER_COUNT}; + +use super::{ + cpu_states::Chip8CpuStates, instructions::Chip8CpuInstructions, system_memory::Chip8SystemMemory, video::Chip8Video +}; + + +#[derive(Clone, Copy)] +pub struct Chip8Computer { + pub pc: u16, + pub sp: u8, + pub memory: Chip8SystemMemory, + pub registers: [u8; 16], + pub sound_timer: u8, + pub delay_timer: u8, + pub i_register: u16, + pub video_memory: Chip8Video, + pub state: Chip8CpuStates +} + +impl Default for Chip8Computer { + fn default() -> Self { + Self { + pc: 0x0200, + sp: 0x00, + memory: Chip8SystemMemory::default(), + video_memory: Chip8Video::default(), + registers: [0; CHIP8_REGISTER_COUNT as usize], + sound_timer: 0xFF, + delay_timer: 0xFF, + i_register: 0x0000, + state: Chip8CpuStates::WaitingForInstruction + } + } +} + +impl Chip8Computer { + pub fn new() -> Self { + Chip8Computer::default() + } + + pub fn step_system(mut self) -> Self { + // read the next instruction + + let mut working_instruction: u16 = 0b0000000000000000; + let high_byte = (self.memory.clone().peek(self.pc) as u16).rotate_left(8); + let low_byte = self.memory.clone().peek(self.pc + 1) as u16; + working_instruction = high_byte | low_byte; + + let decided_instruction = + Chip8Computer::decode_instruction(self.clone(), working_instruction); + + + match (self.state, decided_instruction) { + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SysAddr(target_address)) => { + self.pc = target_address; + }, + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::CLS) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::RET) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::JpAddr(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::CallAddr(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SeVxByte(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SneVxByte(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SeVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdVxByte(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::AddVxByte(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::OrVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::AndVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::XorVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::AddVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SubVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::ShrVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SubnVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::ShlVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SneVxVy(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdIAddr(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::JpV0Addr(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::RndVxByte(_, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::DrawVxVyNibble(_, _, _)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SkpVx(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SnkpVx(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdVxDt(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdVxK(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdDtVx(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdStVx(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::AddIVx(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdFVu(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdBVx(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdIVx(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::LdVxI(_)) => todo!(), + (Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::XXXXERRORINSTRUCTION) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::SysAddr(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::CLS) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::RET) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::JpAddr(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::CallAddr(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::SeVxByte(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::SneVxByte(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::SeVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdVxByte(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::AddVxByte(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::OrVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::AndVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::XorVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::AddVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::SubVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::ShrVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::SubnVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::ShlVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::SneVxVy(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdIAddr(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::JpV0Addr(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::RndVxByte(_, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::DrawVxVyNibble(_, _, _)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::SkpVx(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::SnkpVx(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdVxDt(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdVxK(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdDtVx(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdStVx(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::AddIVx(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdFVu(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdBVx(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdIVx(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::LdVxI(_)) => todo!(), + (Chip8CpuStates::ExecutingInstruction, Chip8CpuInstructions::XXXXERRORINSTRUCTION) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::SysAddr(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::CLS) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::RET) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::JpAddr(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::CallAddr(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::SeVxByte(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::SneVxByte(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::SeVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdVxByte(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::AddVxByte(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::OrVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::AndVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::XorVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::AddVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::SubVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::ShrVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::SubnVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::ShlVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::SneVxVy(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdIAddr(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::JpV0Addr(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::RndVxByte(_, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::DrawVxVyNibble(_, _, _)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::SkpVx(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::SnkpVx(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdVxDt(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdVxK(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdDtVx(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdStVx(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::AddIVx(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdFVu(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdBVx(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdIVx(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::LdVxI(_)) => todo!(), + (Chip8CpuStates::Error, Chip8CpuInstructions::XXXXERRORINSTRUCTION) => todo!(), + } + + self.clone() + } + + // nnn or addr - A 12-bit value, the lowest 12 bits of the instruction + pub fn read_addr_from_instruction(&self, instruction_to_read_from: u16) -> u16 { + instruction_to_read_from & 0b0000111111111111 + } + + // n or nibble - A 4-bit value, the lowest 4 bits of the instruction + pub fn read_nibble_from_instruction(&self, instruction_to_read_from: u16) -> u16 { + instruction_to_read_from & 0b0000000000001111 + } + + // x - A 4-bit value, the lower 4 bits of the high byte of the instruction + pub fn read_x_from_instruction(&self, instruction_to_read_from: u16) -> u16 { + (instruction_to_read_from & 0b0000111100000000).rotate_right(8) + } + + // y - A 4-bit value, the upper 4 bits of the low byte of the instruction + pub fn read_y_from_instruction(&self, instruction_to_read_from: u16) -> u16 { + (instruction_to_read_from & 0b0000000011110000).rotate_right(4) + } + + // kk or byte - An 8-bit value, the lowest 8 bits of the instruction + pub fn read_byte_from_instruction(&self, instruction_to_read_from: u16) -> u16 { + (instruction_to_read_from & 0b0000000011111111) + } + + fn decode_instruction(self, to_read: u16) -> Chip8CpuInstructions { + let mut decoded_instruction = Chip8CpuInstructions::XXXXERRORINSTRUCTION; + + let x_param = self.read_x_from_instruction(to_read); + let y_param = self.read_y_from_instruction(to_read); + let addr_param = self.read_addr_from_instruction(to_read); + let byte_param = self.read_byte_from_instruction(to_read); + let nibble_param = self.read_nibble_from_instruction(to_read); + + match to_read { + 0x00E0 => { + // 00E0 - CLS + // Clear the display. + decoded_instruction = Chip8CpuInstructions::CLS; + } + 0x00EE => { + // 00EE - RET + // Return from a subroutine. + + decoded_instruction = Chip8CpuInstructions::RET; + } + 0x0000..=0x0FFF => { + // 0nnn - SYS addr + // Jump to a machine code routine at nnn. + decoded_instruction = Chip8CpuInstructions::SysAddr(addr_param); + } + 0x1000..=0x1FFF => { + // 1nnn - JP addr + // Jump to location nnn. + decoded_instruction = Chip8CpuInstructions::JpAddr(addr_param); + } + 0x2000..=0x2FFF => { + // 2nnn - CALL addr + // Call subroutine at nnn. + decoded_instruction = Chip8CpuInstructions::CallAddr(addr_param); + } + 0x3000..=0x3FFF => { + // 3xkk - SE Vx, byte + // Skip next instruction if Vx = kk. + decoded_instruction = Chip8CpuInstructions::SeVxByte(x_param, byte_param) + } + 0x4000..=0x4FFF => { + // 4xkk - SNE Vx, byte + // Skip next instruction if Vx != kk. + decoded_instruction = Chip8CpuInstructions::SneVxByte(x_param, byte_param); + } + 0x5000..=0x5FF0 => { + // 5xy0 - SE Vx, Vy + // Skip next instruction if Vx = Vy. + decoded_instruction = Chip8CpuInstructions::SeVxVy(x_param, y_param) + } + 0x6000..=0x6FFF => { + // 6xkk - LD Vx, byte + // Set Vx = kk. + decoded_instruction = Chip8CpuInstructions::LdVxVy(x_param, byte_param); + } + 0x7000..=0x7FFF => { + // ADD Vx, Byte + decoded_instruction = Chip8CpuInstructions::AddVxByte(x_param, byte_param); + } + 0x8000..=0x8FFE => { + // 0x8000 Series + let last_nibble = to_read | 0x8000; + match last_nibble { + 0x0 => { + // LD Vx, Vy + decoded_instruction = Chip8CpuInstructions::LdVxVy(x_param, y_param); + } + 0x1 => { + // OR Vx, Vy + decoded_instruction = Chip8CpuInstructions::OrVxVy(x_param, y_param); + } + 0x2 => { + // AND Vx, Vy + decoded_instruction = Chip8CpuInstructions::AndVxVy(x_param, y_param); + } + 0x3 => { + // XOR Vx, Vy + decoded_instruction = Chip8CpuInstructions::XorVxVy(x_param, y_param); + } + 0x4 => { + // AND Vx, Vy + decoded_instruction = Chip8CpuInstructions::AndVxVy(x_param, y_param); + } + 0x5 => { + // SUB Vx, Vy + decoded_instruction = Chip8CpuInstructions::SubnVxVy(x_param, y_param); + } + 0x6 => { + // SHR Vx, {, Vy } + decoded_instruction = Chip8CpuInstructions::ShrVxVy(x_param, y_param); + } + 0x7 => { + // SUBN Vx, Vy + decoded_instruction = Chip8CpuInstructions::SubnVxVy(x_param, y_param); + } + 0xE => { + // SHL Vx, {, Vy} + decoded_instruction = Chip8CpuInstructions::ShlVxVy(x_param, y_param); + } + _ => { + panic!("UNABLE TO DECODE 0x8000 SERIES INSTRUCTION"); + } + } + } + 0x9000..=0x9FF0 => { + // SNE Vx, Vy + decoded_instruction = Chip8CpuInstructions::SneVxVy(x_param, y_param); + } + 0xA000..=0xAFFF => { + // LD I, Addr + decoded_instruction = Chip8CpuInstructions::LdIAddr(addr_param); + } + 0xB000..=0xBFFF => { + decoded_instruction = Chip8CpuInstructions::JpV0Addr(addr_param); + // JP V0, Addr + } + 0xC000..=0xCFFF => { + // RND Vx, byte + decoded_instruction = Chip8CpuInstructions::RndVxByte(x_param, byte_param); + } + 0xD000..0xDFFF => { + // DRAW Vx, Vy, nibble + decoded_instruction = + Chip8CpuInstructions::DrawVxVyNibble(x_param, y_param, nibble_param); + } + 0xE09E..=0xEFA1 => {} + _ => { + panic!("UNABLE TO DECODE INSTRUCTION") + } + } + + return decoded_instruction; + } +} diff --git a/emma/src/chip8/cpu_states.rs b/emma/src/chip8/cpu_states.rs new file mode 100644 index 0000000..382f62b --- /dev/null +++ b/emma/src/chip8/cpu_states.rs @@ -0,0 +1,8 @@ +#[derive(Clone, Copy, Default)] +pub enum Chip8CpuStates { + #[default] + WaitingForInstruction, + ExecutingInstruction, + Error, +} + diff --git a/emma/src/chip8/delay_timer.rs b/emma/src/chip8/delay_timer.rs new file mode 100644 index 0000000..e69de29 diff --git a/emma/src/chip8/instructions.rs b/emma/src/chip8/instructions.rs new file mode 100644 index 0000000..8a6b0ef --- /dev/null +++ b/emma/src/chip8/instructions.rs @@ -0,0 +1,38 @@ +pub enum Chip8CpuInstructions { + SysAddr(u16), // 0x0nnn Exit to System Call + CLS, // 0x00E0 Clear Screen + RET, // 0x00EE Return from Subroutine + JpAddr(u16), // 0x1nnn Jump to Address + CallAddr(u16), // 0x2nnn Call Subroutine + SeVxByte(u16, u16), // 0x3xkk Skip next instruction if Vx = kk. + SneVxByte(u16, u16), // 0x4xkk Skip next instruction if Vx != kk + SeVxVy(u16, u16), // 0x5xy0 Skip next instruction if Vx == Vy + LdVxByte(u16, u16), // 0x6xkk Set Vx = kk + AddVxByte(u16, u16), // 0x7xkk Set Vx = Vx + kk + LdVxVy(u16, u16), // 0x8xy0 Set value of Vy in Vx + OrVxVy(u16, u16), // 0x8xy1 Set Vx = Vx OR Vy + AndVxVy(u16, u16), // 0x8xy2 Set Vx = Vx AND Vy + XorVxVy(u16, u16), // 0x8xy3 Set Vx = Vx XOR Vy + AddVxVy(u16, u16), // 0x8xy4 Set Vx = Vx + Vy (SET VF on Carry) + SubVxVy(u16, u16), // 0x8xy5 Set Vx = Vx - Vy (Set VF NOT Borrow) + ShrVxVy(u16, u16), // 0x8xy6 Set Vx = Vx SHR 1 (Shift Rotated Right 1) + SubnVxVy(u16, u16), // 0x8xy7 Set Vx = Vy - Vx (Set VF NOT Borrow) + ShlVxVy(u16, u16), // 0x8xyE Shift Left + SneVxVy(u16, u16), // 0x9xy0 Skip next instruction if Vx != Vy + LdIAddr(u16), // 0xAnnn VI = nnn + JpV0Addr(u16), // 0xBnnn Jump to nnn+V0 + RndVxByte(u16, u16), // 0xCxkk Vx = random byte AND kk + DrawVxVyNibble(u16, u16, u16), // 0xDxyn Display N byte sprite starting at Vx to Vy + SkpVx(u16), // 0xE09E Skip next instruction if key in Vx pressed + SnkpVx(u16), // 0xE0A1 Skip next instruction if key in Vx NOT pressed + LdVxDt(u16), // 0xFx07 Set Vx = Delay timer + LdVxK(u16), // 0xFx0A Wait for key, put in Vx + LdDtVx(u16), // 0xFx15 Set Delay Timer + LdStVx(u16), // 0xFx18 Set Sount Timer + AddIVx(u16), // 0xFx1E I = I + Vx + LdFVu(u16), // 0xFx29 Set I = Location of sprite for Digit Vx + LdBVx(u16), // 0xFx33 Store BCD of Vx in I, I+1, I+2 + LdIVx(u16), // 0xFx55 Store V0 to Vx in memory starting at I + LdVxI(u16), // 0xFx65 Load V0 to Vx in memory starting at I + XXXXERRORINSTRUCTION, +} diff --git a/emma/src/chip8/keypad.rs b/emma/src/chip8/keypad.rs new file mode 100644 index 0000000..3d36b24 --- /dev/null +++ b/emma/src/chip8/keypad.rs @@ -0,0 +1,37 @@ +use ratatui::{ + style::{Style, Stylize}, + widgets::Widget, +}; + +pub struct Keypad { + keys: [bool; 0x10], +} + +impl Keypad { + pub fn push_key(&mut self, key_index: u8) { + self.keys[key_index as usize] = true; + } + + pub fn release_key(&mut self, key_index: u8) { + self.keys[key_index as usize] = false; + } + + pub fn key_state(&self, key_index: u8) -> bool { + self.keys[key_index as usize] + } +} + +impl Widget for Keypad { + fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) + where + Self: Sized, + { + let mut working_string = String::new(); + for i in 0..16 { + working_string += if self.key_state(i) { "X" } else { "O" } + } + + let style = Style::new().cyan(); + buf.set_string(0, 0, working_string, style); + } +} diff --git a/emma/src/chip8/sound_timer.rs b/emma/src/chip8/sound_timer.rs new file mode 100644 index 0000000..e69de29 diff --git a/emma/src/chip8/system_memory.rs b/emma/src/chip8/system_memory.rs new file mode 100644 index 0000000..41f5fe1 --- /dev/null +++ b/emma/src/chip8/system_memory.rs @@ -0,0 +1,117 @@ +use imgui::Ui; +use ratatui::{style::Style, widgets::Widget}; + +use crate::constants::{CHIP8_MEMORY_SIZE, CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH}; + +pub const CHIP8FONT_0: [u8; 5] = [0xF0, 0x90, 0x90, 0x90, 0xF0]; +pub const CHIP8FONT_1: [u8; 5] = [0x20, 0x60, 0x20, 0x20, 0x70]; +pub const CHIP8FONT_2: [u8; 5] = [0xF0, 0x10, 0xF0, 0x80, 0xF0]; +pub const CHIP8FONT_3: [u8; 5] = [0xF0, 0x10, 0xF0, 0x10, 0xF0]; +pub const CHIP8FONT_4: [u8; 5] = [0x90, 0x90, 0xF0, 0x10, 0x10]; +pub const CHIP8FONT_5: [u8; 5] = [0xF0, 0x80, 0xF0, 0x10, 0xF0]; +pub const CHIP8FONT_6: [u8; 5] = [0xF0, 0x80, 0xF0, 0x90, 0xF0]; +pub const CHIP8FONT_7: [u8; 5] = [0xF0, 0x10, 0x20, 0x40, 0x40]; +pub const CHIP8FONT_8: [u8; 5] = [0xF0, 0x90, 0xF0, 0x90, 0xF0]; +pub const CHIP8FONT_9: [u8; 5] = [0xF0, 0x90, 0xF0, 0x10, 0xF0]; +pub const CHIP8FONT_A: [u8; 5] = [0xF0, 0x90, 0xF0, 0x90, 0x90]; +pub const CHIP8FONT_B: [u8; 5] = [0xE0, 0x90, 0xE0, 0x90, 0xE0]; +pub const CHIP8FONT_C: [u8; 5] = [0xF0, 0x80, 0x80, 0x80, 0xF0]; +pub const CHIP8FONT_D: [u8; 5] = [0xE0, 0x90, 0x90, 0x90, 0xE0]; +pub const CHIP8FONT_E: [u8; 5] = [0xF0, 0x80, 0xF0, 0x80, 0xF0]; +pub const CHIP8FONT_F: [u8; 5] = [0xF0, 0x80, 0xF0, 0x80, 0x80]; + +#[derive(Clone, Copy)] +pub struct Chip8SystemMemory { + memory: [u8; CHIP8_MEMORY_SIZE as usize], +} + +impl Default for Chip8SystemMemory { + fn default() -> Self { + Self { + memory: Chip8SystemMemory::load_to_memory([0x00; CHIP8_MEMORY_SIZE as usize]), + } + } +} + +impl Widget for Chip8SystemMemory { + fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) + where + Self: Sized, + { + // build the text version of the system memory... + // ...and stuff it in the display. + let style = Style::new(); + let string = String::new(); + buf.set_string(0, 0, string, style) + } + // Display the system memory as a widget +} + +const cell_width: i32 = 5i32; +const cell_height: i32 = 5i32; + +impl Chip8SystemMemory { + pub fn gui_render(self, ui: &Ui) { + let draw_list = ui.get_foreground_draw_list(); + let mut idx = 0; + for row in 0..CHIP8_VIDEO_HEIGHT { + for column in 0..CHIP8_VIDEO_HEIGHT { + let x_offset = (row * cell_width) + column; + let y_offset = (row * cell_width); + let memory_offset = (row * CHIP8_VIDEO_WIDTH) + column; + println!( + "DRAWING IDX: {} {}x{} to {}x{} with {}", + idx, + x_offset, + y_offset, + x_offset + cell_width, + y_offset + cell_height, + self.memory[memory_offset as usize] + ); + idx += 1; + } + } + } + + pub fn peek(self, address: u16) -> u8 { + self.memory[address as usize] + } + + pub fn poke(mut self, address: u16, value: u8) -> Chip8SystemMemory { + self.memory[address as usize] = value; + self + } + + pub fn load_to_memory( + to_load_into: [u8; CHIP8_MEMORY_SIZE as usize], + ) -> [u8; CHIP8_MEMORY_SIZE as usize] { + let mut working = to_load_into.clone(); + let all_font_characters = [ + CHIP8FONT_0, + CHIP8FONT_1, + CHIP8FONT_2, + CHIP8FONT_3, + CHIP8FONT_4, + CHIP8FONT_5, + CHIP8FONT_6, + CHIP8FONT_7, + CHIP8FONT_8, + CHIP8FONT_9, + CHIP8FONT_A, + CHIP8FONT_B, + CHIP8FONT_C, + CHIP8FONT_D, + CHIP8FONT_E, + CHIP8FONT_F, + ]; + + for (font_index, current_font) in all_font_characters.iter().enumerate() { + for font_mem_offset in 0..=4 { + let real_offset = font_index * 5 + font_mem_offset; + working[real_offset] = current_font[font_mem_offset]; + } + } + println!("__FINISHED LOADING FONTS__"); + working + } +} diff --git a/emma/src/chip8/video.rs b/emma/src/chip8/video.rs new file mode 100644 index 0000000..e56b240 --- /dev/null +++ b/emma/src/chip8/video.rs @@ -0,0 +1,66 @@ +use ratatui::prelude::*; +use ratatui::{layout::Rect, style::Style, widgets::Widget}; + +use crate::constants::CHIP8_VIDEO_MEMORY; + + +#[derive(Clone, Copy)] +pub struct Chip8Video { + memory: [bool; CHIP8_VIDEO_MEMORY] +} + +impl Chip8Video { + pub fn new(initial_configuration: [bool; CHIP8_VIDEO_MEMORY]) -> Self { + Self { + memory: initial_configuration + } + } + + pub fn peek(self, address: u16) -> bool { + self.memory[address as usize] + } + + pub fn poke(mut self, address: u16, new_value: bool) -> Self { + self.memory[address as usize] = new_value; + self + } + + pub fn format_as_string(self) -> String { + let mut output = String::new(); + for row in 0..32 { + let row_offset = row * 32; + for column in 0..64 { + let data_position = row_offset + column; + println!("DP {} {} {} {}", data_position, row, row_offset, column); + output += if self.memory[data_position] { + "*" + } else { + " " + }; + } + output += "\n"; + } + panic!("{}", output); + output + } + + pub fn dump_to_console(self) { + println!("{}", self.format_as_string()); + } +} + +impl Default for Chip8Video { + fn default() -> Self { + Self { memory: [false; CHIP8_VIDEO_MEMORY as usize] } + } +} + +impl Widget for Chip8Video { + fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer) + where + Self: Sized { + println!("STARTING TO RENDER VIDEO!"); + let style = Style::new().on_cyan(); + buf.set_string(0, 0, self.format_as_string(), style) + } +} diff --git a/emma/src/constants.rs b/emma/src/constants.rs new file mode 100644 index 0000000..6f11c9e --- /dev/null +++ b/emma/src/constants.rs @@ -0,0 +1,6 @@ +pub const CHIP8_REGISTER_COUNT: i32 = 16; +pub const CHIP8_MEMORY_SIZE: i32 = 2048i32; +pub const CHIP8_VIDEO_WIDTH: i32 = 64i32; +pub const CHIP8_VIDEO_HEIGHT: i32 = 32i32; +pub const CHIP8_VIDEO_MEMORY: usize = (CHIP8_VIDEO_HEIGHT * CHIP8_VIDEO_WIDTH) as usize; +pub const CHIP8_ROM_SIZE: usize = 512; diff --git a/emma/src/lib.rs b/emma/src/lib.rs new file mode 100644 index 0000000..e2943f8 --- /dev/null +++ b/emma/src/lib.rs @@ -0,0 +1,12 @@ +pub mod chip8 { + pub mod video; + pub mod sound_timer; + pub mod delay_timer; + pub mod keypad; + pub mod computer; + pub mod system_memory; + pub mod instructions; + pub mod cpu_states; +} + +pub mod constants; \ No newline at end of file