WIP in the direction of the graphics device

This commit is contained in:
Reid 'arrdem' McKenzie 2022-12-29 01:16:43 -07:00
parent 5152a5c47d
commit f52fe61359
5 changed files with 488 additions and 20 deletions

239
Cargo.lock generated
View file

@ -11,6 +11,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "autocfg"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
dependencies = [
"autocfg 1.1.0",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -23,12 +32,27 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[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 = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
dependencies = [
"bitflags",
]
[[package]]
name = "env_logger"
version = "0.8.4"
@ -39,6 +63,12 @@ dependencies = [
"regex",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "futures"
version = "0.3.25"
@ -140,7 +170,7 @@ version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"libc",
"wasi",
]
@ -163,7 +193,7 @@ version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
]
[[package]]
@ -178,6 +208,47 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b06910a54adb901a01dfd9c475e7959c41acd55a078101ec70fb180f01b7435f"
[[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.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg 1.1.0",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
dependencies = [
"autocfg 1.1.0",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg 1.1.0",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
@ -207,7 +278,7 @@ checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6"
dependencies = [
"env_logger",
"log",
"rand",
"rand 0.8.5",
]
[[package]]
@ -219,15 +290,59 @@ 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.8",
"libc",
"rand_chacha",
"rand_core 0.4.2",
"rand_hc",
"rand_isaac",
"rand_jitter",
"rand_os",
"rand_pcg",
"rand_xorshift",
"winapi",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
dependencies = [
"autocfg 0.1.8",
"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_core"
version = "0.6.4"
@ -237,6 +352,77 @@ dependencies = [
"getrandom",
]
[[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.8",
"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 = "regex"
version = "1.7.0"
@ -272,7 +458,7 @@ version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7229b505ae0706e64f37ffc54a9c163e11022a6636d58fe1f3f52018257ff9f7"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"proc-macro2",
"quote",
"rustc_version",
@ -291,25 +477,26 @@ dependencies = [
[[package]]
name = "sdl2"
version = "0.35.2"
version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7959277b623f1fb9e04aea73686c3ca52f01b2145f8ea16f4ff30d8b7623b1a"
checksum = "d051a07231e303f5f719da78cb6f7394f6d5b54f733aef5b0b447804a83edd7b"
dependencies = [
"bitflags",
"lazy_static",
"libc",
"num",
"rand 0.6.5",
"sdl2-sys",
]
[[package]]
name = "sdl2-sys"
version = "0.35.2"
version = "0.32.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3586be2cf6c0a8099a79a12b4084357aa9b3e0b0d7980e3b67aaf7a9d55f9f0"
checksum = "34e71125077d297d57e4c1acfe8981b5bdfbf5a20e7b589abfdcb33bf1127f86"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"version-compare",
]
[[package]]
@ -324,7 +511,7 @@ version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
dependencies = [
"autocfg",
"autocfg 1.1.0",
]
[[package]]
@ -354,14 +541,30 @@ dependencies = [
"sdl2",
]
[[package]]
name = "version-compare"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "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"

View file

@ -11,10 +11,15 @@ path = "src/bin/uxncli/main.rs"
name = "uxnsym"
path = "src/bin/uxnsym/main.rs"
[[bin]]
name = "uxnsdl2"
path = "src/bin/uxnsdl2/main.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
sdl2 = "0.35.2"
[dependencies.sdl2]
version = "0.32.1" # FIXME: Get upgraded
default-features = false
[dev-dependencies]
quickcheck = "1.0.3"

BIN
assets/bardo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

73
src/bin/uxnsdl2/main.rs Normal file
View file

@ -0,0 +1,73 @@
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use sdl2::rect::{Point, Rect};
use sdl2::render::WindowCanvas;
// "self" imports the "image" module itself as well as everything else we listed
use std::thread::sleep;
use std::time::Duration;
fn render(canvas: &mut WindowCanvas, color: Color) -> Result<(), String> {
canvas.set_draw_color(color);
canvas.clear();
canvas.set_draw_color(color);
// fills the canvas with the color we set in `set_draw_color`.
canvas.clear();
// change the color of our drawing with a gold-color ...
canvas.set_draw_color(Color::RGB(255, 210, 0));
// A draw a rectangle which almost fills our window with it!
canvas.fill_rect(Rect::new(10, 10, 780, 580))?;
canvas.draw_point(Point::new(5, 5))?;
canvas.present();
Ok(())
}
fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let window = video_subsystem
.window("rusty varvara [sdl2]", 800, 600)
.position_centered()
.build()
.expect("could not initialize video subsystem");
let mut canvas = window
.into_canvas()
.build()
.expect("could not make a canvas");
let mut event_pump = sdl_context.event_pump()?;
let mut i = 0;
'running: loop {
// Handle events
for event in event_pump.poll_iter() {
match event {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => {
break 'running;
}
_ => {}
}
}
// Update
i = (i + 1) % 255;
// Render
render(&mut canvas, Color::RGB(i, 64, 255 - i))?;
// Time management!
sleep(Duration::new(0, 1_000_000_000u32 / 60));
}
Ok(())
}

187
src/device/video_sdl2.rs Normal file
View file

@ -0,0 +1,187 @@
use crate::uxn::device::Device;
static blending: [[u8; 16]; 5] = [
[0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0],
[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3],
[1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1],
[2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2],
[1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0],
];
static palette_mono: [u32; 2] = [0x0f000000u32, 0x0fffffffu32];
struct Layer {
pixels: Vec<u8>,
changed: bool,
}
pub struct Sdl2VideoDevice {
vector: u16,
palette: [u32; 4],
pixels: &[u32],
width: u16,
height: u16,
fg: Layer,
bg: Layer,
mono: u8,
x_cur: u16, // x8, x9
y_cur: u16, // xa, xb
auto: bool, // x6
sprite_addr: u16, // xc, xd
}
impl Sdl2VideoDevice {
fn new() -> Sdl2VideoDevice {
unimplemented!();
}
fn clear(&mut self) {
for i in 0..self.width * self.height {
// FIXME: Is there some clear/set operation on vector? You can write your own seemingly, but it's this loop.
self.fg.pixels[i] = 0x00;
self.bg.pixels[i] = 0x00;
}
}
/**
* Update an entry in either the foreground or background buffers, marking the buffer as dirty.
*/
fn write_pixel(&mut self, layer: bool, x: u16, y: u16, color: u8) {
let layer = if layer { &mut self.fg } else { &mut self.bg };
if x < self.width && y < self.height {
let idx = x + (y * self.height) as usize;
if color != layer.pixes[idx] {
layer.pixels[idx] = color;
layer.changed |= true;
}
}
}
/**
* Roll through the pixels associated with a sprite, calling write_pixel for each one.
*/
fn write_sprite(
&mut self,
layer: bool,
x: u16,
y: u16,
sprite_ptr: (),
flipx: bool,
flipy: bool,
twobpp: bool,
) {
let mut v = h = opaque = blending[4][color];
for v in 0..8 {
let c: u8 = sprite[v] | (if twobpp { sprite[v + 8] } else { 0 }) << 8;
for h in 7..0 {
c = c >>= 1;
let ch = (c & 1) | ((c >> 7) & 2);
if (opaque || (ch != 0)) {
self.write_pixel(
layer,
x + (if flipx { 7 - h } else { h }),
y + (if flipy { 7 - v } else { v }),
blending[ch][color],
);
}
}
}
}
/**
* Compute a partial form of the palette.
* Note that redraw() does its own final palette computation.
* Not clear what parts of that live where why.
*/
fn set_palette(&mut self, colors: [u8; 6]) {
// TODO: What in the everliving fuck is this doing.
// Works in C's *u8 land, not clear it works in Rust.
let mut shift = 4;
for i in 0..4 {
let r = (colors[0 + i / 2] >> shift) & 0x0f;
let g = (colors[2 + i / 2] >> shift) & 0x0f;
let b = (colors[4 + i / 2] >> shift) & 0x0f;
self.palette[i] = 0x0f000000 | r << 16 | g << 8 | b;
self.palette[i] |= self.palette[i] << 4;
shift ^= 4;
}
// Both layers are now dirty
self.fg.changed |= true;
self.bg.changed |= true;
}
fn redraw(&mut self) {
let size = self.width * self.height;
let mut pallet = [0u32; 16];
for i in 0..16 {
let idx = if (i >> 2) != 0 { i >> 2 } else { i & 3 };
palette[i] = self.palette[idx];
}
if (self.mono) {
for i in i..size {
let idx = (if self.fg.pixels[i] != 0 {
self.fg.pixels[i]
} else {
self.bg.pixels[i]
}) & 0x1;
pixels[i] = palette_mono[idx];
}
} else {
for i in 0..size {
pixels[i] = palette[self.fg.pixels[i] << 2 | self.bg.pixels[i]];
}
}
self.fg.changed = false;
self.bg.changed = false;
}
}
impl Device for Sdl2VideoDevice {
fn dei1(&mut self, vm: &mut Uxn, port: u8) -> Result<u8, DeviceError> {
let slot = port & 0xF;
// FIXME: this is sorta copypasta, but LOTS of source byte order assumptions here.
match slot {
0x0 => Ok(self.vector >> 8),
0x1 => Ok(self.vector & 0xFF),
0x2 => Ok(self.width >> 8),
0x3 => Ok(self.width & 0xFF),
0x4 => Ok(self.height >> 8),
0x5 => Ok(self.height & 0xFF),
_ => Ok(0),
}
}
/**
* Callback used by UXN to do output through a "device".
*/
fn deo1(&mut self, vm: &mut Uxn, port: u8, val: u8) -> Result<(), DeviceError> {
let slot = port & 0xF;
match slot {
// Writing to the device vector
0x0 => self.vector = self.vector & 0x00FF | ((val as u16) << 8),
0x1 => self.vector = self.vector & 0xFF00 | (val as u16),
// Writing to the device width port.
// Note that the reference implementation triggers resizing on the lower byte
0x2 | 0x3 => (),
// Writing to the device height port
// Note that the reference implementation triggers resizing on the lower byte
0x4 | 0x5 => (),
// FIXME: Writing to all the settings words (auto, x, y, addr)
// Write a pixel word
0xe => (),
// Write a sprite word
0xf => (),
_ => (),
}
Ok()
}
}