From 765b823365b75b3281ae1c806734127aa0557716 Mon Sep 17 00:00:00 2001 From: lifning <> Date: Sat, 16 Oct 2021 02:29:48 -0700 Subject: [PATCH] initial commit: draw a font (ui eventually) layer above the gameplay --- .gitignore | 2 + Cargo.lock | 617 +++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 18 ++ src/lifont.png | Bin 0 -> 42352 bytes src/main.rs | 131 +++++++++++ 5 files changed, 768 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/lifont.png create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d81f12e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/.idea diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ecf8638 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,617 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cc" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg 1.0.1", + "cfg-if 0.1.10", + "lazy_static", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ferretro_base" +version = "0.1.0" +dependencies = [ + "cc", + "libloading", + "libretro-sys", + "num_enum", +] + +[[package]] +name = "ferretro_components" +version = "0.1.0" +dependencies = [ + "cc", + "crossbeam-channel", + "ferretro_base", + "gl", + "libloading", + "num_enum", + "sdl2", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "gl" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94edab108827d67608095e269cf862e60d920f144a5026d3dbcfd8b877fb404" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" + +[[package]] +name = "libloading" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" +dependencies = [ + "cc", + "winapi", +] + +[[package]] +name = "libretro-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "207b060b02cecbcee6df3d0f5ed38691d5c4df1379dd1acd5c49c9b25d20b439" +dependencies = [ + "libc", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "num" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +dependencies = [ + "num-integer", + "num-iter", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg 1.0.1", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg 1.0.1", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg 1.0.1", +] + +[[package]] +name = "num_enum" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4" +dependencies = [ + "derivative", + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha", + "rand_core 0.4.2", + "rand_hc", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "sdl2" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d051a07231e303f5f719da78cb6f7394f6d5b54f733aef5b0b447804a83edd7b" +dependencies = [ + "bitflags", + "lazy_static", + "libc", + "num", + "rand", + "sdl2-sys", +] + +[[package]] +name = "sdl2-sys" +version = "0.32.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34e71125077d297d57e4c1acfe8981b5bdfbf5a20e7b589abfdcb33bf1127f86" +dependencies = [ + "cfg-if 0.1.10", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "structopt" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[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 = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + +[[package]] +name = "zretro" +version = "0.1.0" +dependencies = [ + "ferretro_components", + "sdl2", + "structopt", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..4625695 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "zretro" +version = "0.1.0" +authors = ["lifning"] +edition = "2018" + +[patch.'https://git.vvn.space/cinnabon/rustro'] +ferretro_base = { path = "../ferretro/ferretro_base" } +ferretro_components = { path = "../ferretro/ferretro_components" } + +[dependencies.ferretro_components] +git = "https://git.vvn.space/cinnabon/rustro" +branch = "matriarch" +features = ["sdl2_comp"] + +[dependencies] +sdl2 = { version = "0.32", features = ["image"] } +structopt = "0.3" diff --git a/src/lifont.png b/src/lifont.png new file mode 100644 index 0000000000000000000000000000000000000000..02e4460766cca5c857465cfacf46cdb91cea7462 GIT binary patch literal 42352 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 = std::result::Result>; + +#[derive(StructOpt)] +struct Opt { + /// Core module to use. + #[structopt(short, long, parse(from_os_str))] + core: PathBuf, + /// ROM to load using the core. + #[structopt(short, long, parse(from_os_str))] + rom: PathBuf, + /// System directory, often containing BIOS files + #[structopt(short, long, parse(from_os_str))] + system: Option, +} + +struct Zretro { + emu: Pin>, + canvas: WindowCanvas, + font: Surface<'static>, + sdl2surf_comp: Rc>, +} + +const FONT_PNG: &'static [u8] = include_bytes!("lifont.png"); + +impl Zretro { + fn new(opt: Opt) -> Result { + let mut emu = RetroComponentBase::new(&opt.core); + + let geometry = emu.libretro_core().get_system_av_info().geometry; + let sys_info = emu.libretro_core().get_system_info(); + let title = format!( + "zretro - {}", + unsafe { CStr::from_ptr(sys_info.library_name) }.to_string_lossy() + ); + + let mut sdl_context = sdl2::init()?; + + let window = sdl_context + .video()? + .window(title.as_str(), geometry.base_width, geometry.base_height) + .borderless() + .build()?; + let mut canvas = window.into_canvas().build()?; + + let sdl2surf_comp = Rc::new(RefCell::new( + Sdl2SurfaceComponent::new(emu.libretro_core())? + )); + emu.register_component(sdl2surf_comp.clone()); + + let sdl2_audio = SimpleSdl2AudioComponent::new(&mut sdl_context, emu.libretro_core()); + emu.register_component(sdl2_audio); + + let sleep_fps = SleepFramerateLimitComponent::new(emu.libretro_core()); + emu.register_component(sleep_fps); + + emu.register_component(PathBufComponent { + sys_path: opt.system.clone(), + libretro_path: Some(opt.core.to_path_buf()), + core_assets_path: None, + save_path: Some(std::env::temp_dir()), + }); + + emu.init().unwrap(); + emu.load_game(&opt.rom).unwrap(); + + let rwops = sdl2::rwops::RWops::from_bytes(FONT_PNG)?; + let font_shortlived = rwops.load_png()?; + // there's a nonsemantic inheritance of lifetime from ImageRWops::load_png. TODO: pr + let font = unsafe { + let ptr = font_shortlived.raw(); + std::mem::forget(font_shortlived); + Surface::from_ll(ptr) + }; + + Ok(Zretro { + emu, + canvas, + font, + sdl2surf_comp, + }) + } + + fn run(&mut self) -> Result<()> { + let tc = self.canvas.texture_creator(); + let font_tx = tc.create_texture_from_surface(&self.font)?; + let mut font_rect = self.font.rect(); + font_rect.set_height(64); + while let ControlFlow::Continue = self.emu.run() { + let ref_mut = RefCell::try_borrow_mut(&self.sdl2surf_comp)?; + let mut surface = ref_mut.surface(); + + let texture = tc.create_texture_from_surface(surface)?; + + self.canvas.clear(); + self.canvas.copy(&texture, None, None)?; + self.canvas.copy(&font_tx, font_rect, font_rect)?; + self.canvas.present(); + } + Ok(()) + } +} + +fn main() -> Result<()> { + let opt: Opt = Opt::from_args(); + let mut frontend = Zretro::new(opt)?; + frontend.run()?; + Ok(()) +}