aboutsummaryrefslogtreecommitdiff
path: root/renderer/src/tee.rs
blob: d796f5e7af33505ccb8183c4d1d00a48531f66f4 (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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use std::{collections::BTreeMap, fs::File, io::Read};

use skia_safe::{
    canvas::SrcRectConstraint, utils::text_utils::Align, Canvas, Color4f, ColorSpace, Data, Font,
    Image, Paint, Point, Rect,
};
use twclient::world::{tee::Tee, World};

const TEE_COLL_RADIUS: f32 = 16.0;
const TEE_REND_RADIUS: f32 = 32.0;

pub struct TeeRenderer {
    skins: BTreeMap<String, Image>,
}

impl TeeRenderer {
    pub fn new() -> Self {
        Self {
            skins: BTreeMap::new(),
        }
    }

    pub fn draw(&mut self, world: &World, canvas: &mut Canvas) {
        for t in world.tees.inner.values() {
            canvas.save();
            canvas.translate((t.x as f32, t.y as f32));
            self.draw_tee(canvas, t);
            canvas.restore();
        }
    }

    pub fn draw_tee(&mut self, canvas: &mut Canvas, tee: &Tee) {
        let tee_paint = Paint::new(
            Color4f {
                a: 1.0,
                r: 1.0,
                g: 1.0,
                b: 1.0,
            },
            &ColorSpace::new_srgb(),
        );
        let name_paint = Paint::new(
            Color4f {
                a: 1.0,
                r: 1.0,
                g: 1.0,
                b: 0.0,
            },
            &ColorSpace::new_srgb(),
        );
        let skin_texture = self
            .skins
            .entry(tee.skin.clone())
            .or_insert_with(|| TeeRenderer::load_skin(tee.name.as_str()).unwrap());

        let origin = Point {
            x: tee.x as f32,
            y: tee.y as f32,
        };

        canvas.draw_image_rect(
            skin_texture,
            Some((
                &Rect {
                    top: 16.0,
                    left: 16.0,
                    right: 96.0,
                    bottom: 96.0,
                },
                SrcRectConstraint::Strict,
            )),
            Rect {
                top: -TEE_REND_RADIUS,
                left: -TEE_REND_RADIUS,
                right: TEE_REND_RADIUS,
                bottom: TEE_REND_RADIUS,
            },
            &tee_paint,
        );

        canvas.draw_str_align(
            tee.name.as_str(),
            (origin.x, origin.y - 20.0),
            &Font::default(),
            &name_paint,
            Align::Center,
        );
    }

    pub fn load_skin(_name: &str) -> Option<Image> {
        let path = "/usr/share/ddnet/data/skins/default.png";
        let mut file = File::open(path).unwrap();
        let mut data = Vec::new();
        file.read_to_end(&mut data).unwrap();
        let data = Data::new_copy(&data);
        Image::from_encoded(data)
    }
}