diff --git a/Cargo.lock b/Cargo.lock index 29b287c..32fe98d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "atomic-polyfill" @@ -23,6 +23,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + [[package]] name = "bitflags" version = "1.3.2" @@ -31,9 +37,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "byteorder" @@ -93,6 +99,29 @@ dependencies = [ "winapi", ] +[[package]] +name = "embedded-graphics" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0649998afacf6d575d126d83e68b78c0ab0e00ca2ac7e9b3db11b4cbe8274ef0" +dependencies = [ + "az", + "byteorder", + "embedded-graphics-core", + "float-cmp", + "micromath", +] + +[[package]] +name = "embedded-graphics-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044" +dependencies = [ + "az", + "byteorder", +] + [[package]] name = "embedded-hal" version = "1.0.0" @@ -117,6 +146,15 @@ dependencies = [ "neotron-sdk", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + [[package]] name = "hash32" version = "0.2.1" @@ -142,9 +180,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "lock_api" @@ -158,9 +196,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "menu" @@ -168,6 +206,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b03d7f798bfe97329ad6df937951142eec93886b37d87010502dd25e8cc75fd5" +[[package]] +name = "micromath" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815" + [[package]] name = "mio" version = "0.8.11" @@ -186,7 +230,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82c00f842e7006421002e67a53866b90ddd6f7d86137b52d2147f5e38b35e82f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "neotron-ffi", ] @@ -196,7 +240,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67d6c96706b6f3ec069abfb042cadfd2d701980fa4940f407c0bc28ee1e1c493" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "neotron-ffi", ] @@ -228,6 +272,7 @@ name = "neotron-os" version = "0.8.1" dependencies = [ "chrono", + "embedded-graphics", "embedded-sdmmc", "heapless", "menu", @@ -239,6 +284,7 @@ dependencies = [ "postcard", "r0", "serde", + "tinybmp", "vte", ] @@ -291,7 +337,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -302,9 +348,9 @@ checksum = "ed089a1fbffe3337a1a345501c981f1eb1e47e69de5a40e852433e12953c3174" [[package]] name = "postcard" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +checksum = "20ee10b999a00ca189ac2cb99f5db1ca71fb7371e3d5f493b879ca95d2a67220" dependencies = [ "cobs", "heapless", @@ -313,9 +359,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -337,11 +383,11 @@ checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211" [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -367,18 +413,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", @@ -397,9 +443,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", "mio", @@ -438,15 +484,23 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" -version = "2.0.66" +version = "2.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "tinybmp" +version = "0.5.0" +source = "git+https://github.com/embedded-graphics/tinybmp?rev=247718592bb7a1904f4846e5f1adef87d33e1781#247718592bb7a1904f4846e5f1adef87d33e1781" +dependencies = [ + "embedded-graphics", +] + [[package]] name = "unicode-ident" version = "1.0.12" @@ -455,9 +509,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "vte" @@ -472,9 +526,9 @@ dependencies = [ [[package]] name = "vte_generate_state_changes" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" dependencies = [ "proc-macro2", "quote", @@ -534,18 +588,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -556,9 +610,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -568,9 +622,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -580,15 +634,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -598,9 +652,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -610,9 +664,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -622,9 +676,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -634,6 +688,6 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index 9fca006..505e645 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,3 @@ panic = "abort" [profile.dev] panic = "abort" - diff --git a/neotron-os/Cargo.toml b/neotron-os/Cargo.toml index ab7dc16..232f9ce 100644 --- a/neotron-os/Cargo.toml +++ b/neotron-os/Cargo.toml @@ -32,6 +32,7 @@ required-features = ["native-log"] [dependencies] chrono = { version = "0.4", default-features = false } +embedded-graphics = "0.8.1" embedded-sdmmc = { version = "0.7", default-features = false } heapless = "0.7" menu = "0.3" @@ -43,6 +44,7 @@ pc-keyboard = "0.7" postcard = "1.0" r0 = "1.0" serde = { version = "1.0", default-features = false } +tinybmp = { git = "https://github.com/embedded-graphics/tinybmp", rev="247718592bb7a1904f4846e5f1adef87d33e1781" } vte = "0.12" [features] diff --git a/neotron-os/build.rs b/neotron-os/build.rs index 1a31183..a91e548 100644 --- a/neotron-os/build.rs +++ b/neotron-os/build.rs @@ -37,9 +37,9 @@ fn main() { if option_env!("ROMFS_PATH").is_some() { println!("cargo::rustc-cfg=romfs_enabled=\"yes\""); - println!("cargo::rustc-check-cfg=cfg(romfs_enabled, values(\"yes\"))"); println!("cargo::rerun-if-env-changed=ROMFS_PATH"); } + println!("cargo::rustc-check-cfg=cfg(romfs_enabled, values(\"yes\"))"); } /// Put the given script in our output directory and ensure it's on the linker diff --git a/neotron-os/neotron-flash-0002.ld b/neotron-os/neotron-flash-0002.ld index 59626d9..0ff3547 100644 --- a/neotron-os/neotron-flash-0002.ld +++ b/neotron-os/neotron-flash-0002.ld @@ -22,7 +22,7 @@ MEMORY { /* The first 128 KiB is for the BIOS. We get the rest. */ - FLASH (rx) : ORIGIN = 0x00020000, LENGTH = 256K + FLASH (rx) : ORIGIN = 0x00020000, LENGTH = 512K /* * We get the bottom 4KB of RAM. Anything above that is for applications * (up to wherever the BIOS tells us we can use.) diff --git a/neotron-os/neotron-flash-0802.ld b/neotron-os/neotron-flash-0802.ld index 3a961ab..b982b79 100644 --- a/neotron-os/neotron-flash-0802.ld +++ b/neotron-os/neotron-flash-0802.ld @@ -22,7 +22,7 @@ MEMORY { /* The first 128 KiB is for the BIOS. We get the rest. */ - FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 256K + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 512K /* * We get the bottom 4KB of RAM. Anything above that is for applications * (up to wherever the BIOS tells us we can use.) diff --git a/neotron-os/neotron-flash-1002.ld b/neotron-os/neotron-flash-1002.ld index 0ba14c0..e7ff580 100644 --- a/neotron-os/neotron-flash-1002.ld +++ b/neotron-os/neotron-flash-1002.ld @@ -22,7 +22,7 @@ MEMORY { /* The first 128 KiB is for the BIOS. We get the rest. */ - FLASH (rx) : ORIGIN = 0x10020000, LENGTH = 256K + FLASH (rx) : ORIGIN = 0x10020000, LENGTH = 512K /* * The RAM reserved for the OS. Above this is the Transient Program Area. diff --git a/neotron-os/src/commands/fs.rs b/neotron-os/src/commands/fs.rs index 56728b2..194cf03 100644 --- a/neotron-os/src/commands/fs.rs +++ b/neotron-os/src/commands/fs.rs @@ -190,7 +190,7 @@ fn romfn(_menu: &menu::Menu, _item: &menu::Item, args: &[&str], ctx: & osprintln!("No ROM available"); return; }; - if let Some(arg) = args.get(0) { + if let Some(arg) = args.first() { let Some(entry) = romfs.find(arg) else { osprintln!("Couldn't find {} in ROM", arg); return; @@ -199,14 +199,12 @@ fn romfn(_menu: &menu::Menu, _item: &menu::Item, args: &[&str], ctx: & osprintln!("Error: {:?}", e); } } else { - for entry in romfs.into_iter() { - if let Ok(entry) = entry { - osprintln!( - "{} ({} bytes)", - entry.metadata.file_name, - entry.metadata.file_size - ); - } + for entry in romfs.into_iter().flatten() { + osprintln!( + "{} ({} bytes)", + entry.metadata.file_name, + entry.metadata.file_size + ); } } } diff --git a/neotron-os/src/commands/mod.rs b/neotron-os/src/commands/mod.rs index 3c3324e..ae1d8e4 100644 --- a/neotron-os/src/commands/mod.rs +++ b/neotron-os/src/commands/mod.rs @@ -36,6 +36,7 @@ pub static OS_MENU: menu::Menu = menu::Menu { &screen::CLS_ITEM, &screen::MODE_ITEM, &screen::GFX_ITEM, + &screen::DEMO_ITEM, &input::KBTEST_ITEM, &hardware::SHUTDOWN_ITEM, &sound::MIXER_ITEM, diff --git a/neotron-os/src/commands/screen.rs b/neotron-os/src/commands/screen.rs index f64b8e8..4e70d08 100644 --- a/neotron-os/src/commands/screen.rs +++ b/neotron-os/src/commands/screen.rs @@ -1,5 +1,22 @@ //! Screen-related commands for Neotron OS +static SLIDES: [&[u8]; 11] = [ + include_bytes!("../slide_pico_vga.bmp"), + include_bytes!("../slide_pico_audio.bmp"), + include_bytes!("../slide_bios.bmp"), + include_bytes!("../slide_os.bmp"), + include_bytes!("../slide_oss.bmp"), + include_bytes!("../slide_sdk.bmp"), + include_bytes!("../slide_stars.bmp"), + include_bytes!("../slide_px3.bmp"), + include_bytes!("../slide_pi.bmp"), + include_bytes!("../slide_win30.bmp"), + include_bytes!("../slide_win31.bmp"), +]; + +use neotron_common_bios::video::Timing; +use pc_keyboard::DecodedKey; + use crate::{ bios::{ video::{Format, Mode}, @@ -47,6 +64,15 @@ pub static GFX_ITEM: menu::Item = menu::Item { help: Some("Test a graphics mode"), }; +pub static DEMO_ITEM: menu::Item = menu::Item { + item_type: menu::ItemType::Callback { + function: demo_cmd, + parameters: &[], + }, + command: "demo", + help: Some("Run demo"), +}; + /// Called when the "cls" command is executed. fn cls_cmd(_menu: &menu::Menu, _item: &menu::Item, _args: &[&str], _ctx: &mut Ctx) { // Reset SGR, go home, clear screen, @@ -221,4 +247,153 @@ fn print_modes() { } } +/// Called when the "demo" command is executed. +fn demo_cmd(_menu: &menu::Menu, _item: &menu::Item, _args: &[&str], ctx: &mut Ctx) { + let api = crate::API.get(); + let old_mode = (api.video_get_mode)(); + let old_ptr = (api.video_get_framebuffer)(); + let buffer = ctx.tpa.as_slice_u32(); + let buffer_ptr = buffer.as_mut_ptr(); + let old_palette = [ + (api.video_get_palette)(0), + (api.video_get_palette)(1), + (api.video_get_palette)(2), + (api.video_get_palette)(3), + (api.video_get_palette)(4), + (api.video_get_palette)(5), + (api.video_get_palette)(6), + (api.video_get_palette)(7), + (api.video_get_palette)(8), + (api.video_get_palette)(9), + (api.video_get_palette)(10), + (api.video_get_palette)(11), + (api.video_get_palette)(12), + (api.video_get_palette)(13), + (api.video_get_palette)(14), + (api.video_get_palette)(15), + ]; + + 'slides: for slide_bytes in SLIDES.iter().cycle().cloned() { + if let Err(_e) = show_slide(slide_bytes, api, buffer_ptr) { + break; + } + // Now wait for user input - Q to quit, ' ' to skip + 'wait: for _ in 0..450 { + // 450 frames = 7.5 seconds + (api.video_wait_for_line)(478); + (api.video_wait_for_line)(479); + let keyin = crate::STD_INPUT.lock().get_raw(); + if let Some(DecodedKey::Unicode('Q') | DecodedKey::Unicode('q')) = keyin { + break 'slides; + } + if let Some(DecodedKey::Unicode(' ')) = keyin { + break 'wait; + } + } + } + + // Put it back as it was + unsafe { + (api.video_set_mode)(old_mode, old_ptr); + for (idx, colour) in old_palette.iter().enumerate() { + if let neotron_common_bios::FfiOption::Some(colour) = colour { + (api.video_set_palette)(idx as u8, *colour); + } + } + } +} + +enum SlideError { + Unspecified, +} + +fn show_slide( + data: &[u8], + api: &neotron_common_bios::Api, + buffer_ptr: *mut u32, +) -> Result<(), SlideError> { + use embedded_graphics::pixelcolor::RgbColor; + + let raw_bmp = tinybmp::RawBmp::from_slice(data).map_err(|_| SlideError::Unspecified)?; + let header = raw_bmp.header(); + if header.image_size.width > 640 || header.image_size.height > 480 { + return Err(SlideError::Unspecified); + } + + let Some(table) = raw_bmp.color_table() else { + // can only do palettised images + return Err(SlideError::Unspecified); + }; + + // Set palette to black + for entry in 0..table.len() { + (api.video_set_palette)(entry as u8, neotron_common_bios::video::RGBColour::BLACK); + } + + let (mode, bpp, px_per_word_shift) = match (header.bpp, table.len() <= 4) { + (tinybmp::Bpp::Bits4, true) => (Mode::new(Timing::T640x480, Format::Chunky2), 2, 4), + (tinybmp::Bpp::Bits4, false) => (Mode::new(Timing::T640x480, Format::Chunky4), 4, 3), + b => { + // can't display it + osprintln!("Couldn't handle {:?}", b); + return Err(SlideError::Unspecified); + } + }; + + if let neotron_common_bios::FfiResult::Err(e) = + unsafe { (api.video_set_mode)(mode, buffer_ptr) } + { + osprintln!("Couldn't set mode {:?}: {:?}", mode, e); + return Err(SlideError::Unspecified); + } + + // Copy bitmap + let mut pixel_word = 0; + let mut offset_word = 0; + let mut left_in_word = 1 << px_per_word_shift; + let mut y = 0; + let mut x = 0; + // annoyingly bitmaps aren't always top-left to bottom-right. + for px in raw_bmp.pixels() { + if y != px.position.y || x != px.position.x { + // we assume discontinuities only happen at line breaks + y = px.position.y; + x = px.position.x; + offset_word = (((y * 640) + x) >> px_per_word_shift) as usize; + left_in_word = 1 << px_per_word_shift; + pixel_word = 0; + } + + pixel_word <<= bpp; + pixel_word |= px.color; + + left_in_word -= 1; + if left_in_word == 0 { + pixel_word = pixel_word.to_be(); + unsafe { + buffer_ptr.add(offset_word).write_volatile(pixel_word); + } + pixel_word = 0; + left_in_word = 1 << px_per_word_shift; + offset_word += 1; + } + + x += 1; + if x == 640 { + x = 0; + y += 1; + } + } + + // Set palette to correct colours now picture is drawn + for entry in 0..table.len() { + if let Some(rgb) = table.get(entry as u32) { + let rgb666 = neotron_common_bios::video::RGBColour::from_rgb(rgb.r(), rgb.g(), rgb.b()); + (api.video_set_palette)(entry as u8, rgb666); + } + } + + Ok(()) +} + // End of file diff --git a/neotron-os/src/lib.rs b/neotron-os/src/lib.rs index 69307c5..a63c2e4 100644 --- a/neotron-os/src/lib.rs +++ b/neotron-os/src/lib.rs @@ -62,10 +62,10 @@ static STD_INPUT: CsRefCell = CsRefCell::new(StdInput::new()); static FILESYSTEM: fs::Filesystem = fs::Filesystem::new(); #[cfg(romfs_enabled = "yes")] -static ROMFS: &'static [u8] = include_bytes!(env!("ROMFS_PATH")); +static ROMFS: &[u8] = include_bytes!(env!("ROMFS_PATH")); #[cfg(not(romfs_enabled = "yes"))] -static ROMFS: &'static [u8] = &[]; +static ROMFS: &[u8] = &[]; // =========================================================================== // Macros diff --git a/neotron-os/src/program.rs b/neotron-os/src/program.rs index 404b3ce..7cc1878 100644 --- a/neotron-os/src/program.rs +++ b/neotron-os/src/program.rs @@ -310,6 +310,7 @@ impl TransientProgramArea { // We support a maximum of four arguments. #[allow(clippy::get_first)] let ffi_args = [ + #[allow(clippy::get_first)] neotron_api::FfiString::new(args.get(0).unwrap_or(&"")), neotron_api::FfiString::new(args.get(1).unwrap_or(&"")), neotron_api::FfiString::new(args.get(2).unwrap_or(&"")), diff --git a/neotron-os/src/slide_bios.bmp b/neotron-os/src/slide_bios.bmp new file mode 100644 index 0000000..2b72a90 Binary files /dev/null and b/neotron-os/src/slide_bios.bmp differ diff --git a/neotron-os/src/slide_os.bmp b/neotron-os/src/slide_os.bmp new file mode 100644 index 0000000..36f9740 Binary files /dev/null and b/neotron-os/src/slide_os.bmp differ diff --git a/neotron-os/src/slide_oss.bmp b/neotron-os/src/slide_oss.bmp new file mode 100644 index 0000000..b42412b Binary files /dev/null and b/neotron-os/src/slide_oss.bmp differ diff --git a/neotron-os/src/slide_pi.bmp b/neotron-os/src/slide_pi.bmp new file mode 100644 index 0000000..e81f444 Binary files /dev/null and b/neotron-os/src/slide_pi.bmp differ diff --git a/neotron-os/src/slide_pico_audio.bmp b/neotron-os/src/slide_pico_audio.bmp new file mode 100644 index 0000000..8463739 Binary files /dev/null and b/neotron-os/src/slide_pico_audio.bmp differ diff --git a/neotron-os/src/slide_pico_vga.bmp b/neotron-os/src/slide_pico_vga.bmp new file mode 100644 index 0000000..9c803c0 Binary files /dev/null and b/neotron-os/src/slide_pico_vga.bmp differ diff --git a/neotron-os/src/slide_px3.bmp b/neotron-os/src/slide_px3.bmp new file mode 100644 index 0000000..d4f5611 Binary files /dev/null and b/neotron-os/src/slide_px3.bmp differ diff --git a/neotron-os/src/slide_sdk.bmp b/neotron-os/src/slide_sdk.bmp new file mode 100644 index 0000000..eeb66eb Binary files /dev/null and b/neotron-os/src/slide_sdk.bmp differ diff --git a/neotron-os/src/slide_stars.bmp b/neotron-os/src/slide_stars.bmp new file mode 100644 index 0000000..73e2d39 Binary files /dev/null and b/neotron-os/src/slide_stars.bmp differ diff --git a/neotron-os/src/slide_win30.bmp b/neotron-os/src/slide_win30.bmp new file mode 100644 index 0000000..6a66f60 Binary files /dev/null and b/neotron-os/src/slide_win30.bmp differ diff --git a/neotron-os/src/slide_win31.bmp b/neotron-os/src/slide_win31.bmp new file mode 100644 index 0000000..2f3bc7e Binary files /dev/null and b/neotron-os/src/slide_win31.bmp differ diff --git a/utilities/flames/src/lib.rs b/utilities/flames/src/lib.rs index 4cc4a63..0c9a7b9 100644 --- a/utilities/flames/src/lib.rs +++ b/utilities/flames/src/lib.rs @@ -136,7 +136,7 @@ impl App { /// Generates a number in the range [0, limit) fn random_up_to(&mut self, limit: usize) -> usize { - let buckets = ::core::usize::MAX / limit; + let buckets = usize::MAX / limit; let upper_edge = buckets * limit; loop { let attempt = self.random();