aboutsummaryrefslogtreecommitdiff
path: root/src/display/components.rs
blob: 1346f50fec71a9b3cfb465eb80e7de92b6785c78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use bevy::{
    ecs::{
        component::ComponentId,
        world::DeferredWorld,
    },
    prelude::*,
    render::render_resource::{
        Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
    },
};
use bevy_dither_post_process::components::DitherPostProcessSettings;
use bevy_headless_render::components::HeadlessRenderSource;

/// Marker component for terminal display
#[derive(Component, Debug)]
#[component(on_add = on_add_terminal_display)]
pub struct TerminalDisplay(pub u32);

fn on_add_terminal_display(mut world: DeferredWorld, entity: Entity, _id: ComponentId) {
    let asset_server = world.get_resource::<AssetServer>().unwrap();
    let dither_level = world.entity(entity).get::<TerminalDisplay>().unwrap().0;

    let terminal_size = crossterm::terminal::size().unwrap();
    let size = Extent3d {
        width: (terminal_size.0 as u32) * 2,
        height: (terminal_size.1 as u32) * 4,
        depth_or_array_layers: 1,
    };

    let mut image = Image {
        texture_descriptor: TextureDescriptor {
            label: None,
            size,
            dimension: TextureDimension::D2,
            format: TextureFormat::R8Unorm,
            mip_level_count: 1,
            sample_count: 1,
            usage: TextureUsages::TEXTURE_BINDING
                | TextureUsages::COPY_SRC
                | TextureUsages::RENDER_ATTACHMENT,
            view_formats: &[],
        },
        ..default()
    };

    image.resize(size);
    let image_handle = asset_server.add(image);

    let headless_render_source = HeadlessRenderSource::new(&asset_server, image_handle.clone());
    let post_process_settings = DitherPostProcessSettings::new(dither_level, &asset_server);
    world
        .commands()
        .entity(entity)
        .insert((headless_render_source, post_process_settings));
    if let Some(mut camera) =  world.entity_mut(entity).get_mut::<Camera>() {
        camera.target = image_handle.into();
    } else {
        world.commands().entity(entity).insert(Camera {
            target: image_handle.into(),
            ..Default::default()
        });
    }
}