Skip to main content

SoftwareBackend

Struct SoftwareBackend 

Source
pub struct SoftwareBackend {
    pub cols: u16,
    pub rows: u16,
    pub scale: u8,
    pub tilesets: Vec<TilesetOptions>,
    /* private fields */
}
Expand description

Configuration and entry point for the software rendering backend.

Construct this via SoftwareBackendBuilder, then call into_renderer to obtain a SoftwareRenderer (which implements Backend for in-memory use, and retroglyph_window::Presenter for windowed use).

§Examples

Windowed mode (requires default-font feature; the loop comes from retroglyph-window):

use retroglyph_software::SoftwareBackendBuilder;
use retroglyph_window::winit::{WindowConfig, run_windowed};
use retroglyph_core::event::{Event, KeyCode};
use retroglyph_core::color::Style;
use std::time::Duration;

let renderer = SoftwareBackendBuilder::new()
    .grid_size(80, 25)
    .scale(2)
    .build()
    .expect("backend init failed")
    .into_renderer()
    .expect("renderer init failed");

let config = WindowConfig::fit(&renderer, "My Game", None, true);
run_windowed(config, renderer, move |term| {
    term.draw(|s| s.print((0, 0), "Hello from rg!", Style::default())).ok();

    if let Some(event) = term.poll(Duration::from_millis(16)) {
        match event {
            Event::Key(k) if k.code == KeyCode::Escape => std::process::exit(0),
            Event::Close => std::process::exit(0),
            _ => {}
        }
    }
}).expect("event loop failed");

Headless mode (useful for testing):

use retroglyph_software::{SoftwareBackendBuilder, SoftwareRenderer};
use retroglyph_core::color::Style;
use retroglyph_core::grid::Pos;
use retroglyph_core::backend::{DrawCell, Output};
use retroglyph_core::color::Color;

let opts = SoftwareBackendBuilder::new()
    .grid_size(1, 1)
    .scale(1)
    .build()
    .unwrap();

let mut renderer: SoftwareRenderer = opts.into_renderer().unwrap();

// Draw a red cell on layer 0.
use retroglyph_core::tile::Tile;
let tile = Tile::new(' ', Style::new().bg(Color::Rgb { r: 255, g: 0, b: 0 }));
renderer
    .draw_layers([DrawCell::on_layer(0, Pos::new(0, 0), &tile)].into_iter())
    .unwrap();

let pixels = renderer.pixels();
assert!(pixels.iter().all(|&p| p == 0x00FF_0000));

See the demo example for a complete runnable program.

Fields§

§cols: u16

Grid width in cells.

§rows: u16

Grid height in cells.

§scale: u8

Pixel-scale factor applied to each font pixel.

A scale of 2 renders each 1-bit font pixel as a 2×2 block, making the Unscii 16 font display at 16×32 pixels per cell. Default is 1.

§tilesets: Vec<TilesetOptions>

Registered tileset options, loaded at into_renderer time.

Implementations§

Source§

impl SoftwareBackend

Source

pub const fn fonts(&self) -> Option<&FontChain<'static>>

Returns the configured font chain, if any.

None only when default-font is disabled and no font was supplied via SoftwareBackendBuilder::font; in that case SoftwareBackendBuilder::build fails with SoftwareBackendError::NoFont before a SoftwareBackend can be constructed at all.

Source§

impl SoftwareBackend

Source

pub fn into_renderer(self) -> Result<SoftwareRenderer, SoftwareBackendError>

Builds a SoftwareRenderer from this configuration.

This does not block: it returns a SoftwareRenderer immediately. The renderer’s pixel buffer can be inspected via SoftwareRenderer::pixels for headless / pixel-level use, or the renderer can be handed to retroglyph_window::winit::run_windowed to drive a window. Flushing is a no-op (the buffer stays in memory).

§Examples
use retroglyph_core::backend::Output;
use retroglyph_core::tile::Tile;
use retroglyph_core::color::Style;
use retroglyph_core::grid::Pos;
use retroglyph_core::backend::DrawCell;
use retroglyph_core::color::Color;
use retroglyph_software::SoftwareBackendBuilder;

let mut renderer = SoftwareBackendBuilder::new()
    .grid_size(1, 1)
    .scale(1)
    .build()
    .unwrap()
    .into_renderer()
    .unwrap();

// Render a red cell on layer 0.
let tile = Tile::new(' ', Style::new().bg(Color::Rgb { r: 255, g: 0, b: 0 }));
renderer
    .draw_layers([DrawCell::on_layer(0, Pos::new(0, 0), &tile)].into_iter())
    .unwrap();

assert!(renderer.pixels().iter().all(|&p| p == 0x00FF_0000));
§Errors

Returns SoftwareBackendError::NoFont if no font is set, or SoftwareBackendError::MixedGlyphSizes if the font chain’s fonts disagree on their glyph size (both only reachable if SoftwareBackendBuilder::build was bypassed), SoftwareBackendError::ZeroScale if scale is 0 (likewise only reachable if build was bypassed, since a caller mutated the field after construction), SoftwareBackendError::ZeroGrid if cols or rows is 0, and SoftwareBackendError::Tileset if a registered tileset fails to load.

§Panics

Panics only on a u32-to-usize conversion that cannot fail on any target this crate supports (usize is at least 32 bits on every 32- and 64-bit platform), so this is not reachable in practice.

Trait Implementations§

Source§

impl Clone for SoftwareBackend

Source§

fn clone(&self) -> SoftwareBackend

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SoftwareBackend

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for SoftwareBackend

Source§

fn eq(&self, other: &SoftwareBackend) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for SoftwareBackend

Source§

impl StructuralPartialEq for SoftwareBackend

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,