engine/resources/
chunks.rs

1// SPDX-FileCopyrightText: 2024 Jens Pitkänen <jens.pitkanen@helsinki.fi>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5use core::ops::Range;
6
7use platform::{Platform, SpriteRef};
8
9use crate::resources::{CHUNK_SIZE, SPRITE_CHUNK_DIMENSIONS, SPRITE_CHUNK_FORMAT};
10
11/// Metadata for loading in a [`ChunkData`].
12#[derive(Debug, Clone)]
13pub struct ChunkDescriptor {
14    /// The range of bytes in the chunk data portion of the database this
15    /// sprite chunk can be loaded from.
16    pub source_bytes: Range<u64>,
17}
18
19/// Metadata for loading in a [`SpriteChunkData`].
20#[derive(Debug, Clone)]
21pub struct SpriteChunkDescriptor {
22    /// The width of the sprite the chunk contains.
23    pub region_width: u16,
24    /// The height of the sprite the chunk contains.
25    pub region_height: u16,
26    /// The range of bytes in the chunk data portion of the database this
27    /// sprite chunk can be loaded from.
28    pub source_bytes: Range<u64>,
29}
30
31/// Loaded memory for a single regular chunk. Contains [`CHUNK_SIZE`] bytes.
32#[repr(C, align(64))]
33pub struct ChunkData(pub [u8; CHUNK_SIZE as usize]);
34
35impl ChunkData {
36    /// Creates a zeroed-out [`ChunkData`].
37    pub const fn empty() -> ChunkData {
38        ChunkData([0; CHUNK_SIZE as usize])
39    }
40
41    /// Replaces the chunk contents with the given buffer, based on the
42    /// [`ChunkDescriptor`] metadata.
43    pub fn update(&mut self, descriptor: &ChunkDescriptor, buffer: &[u8]) {
44        let len = (descriptor.source_bytes.end - descriptor.source_bytes.start) as usize;
45        self.0[..len].copy_from_slice(buffer);
46    }
47}
48
49/// Loaded (video) memory for a single sprite chunk. Contains a reference to a
50/// loaded sprite, ready for drawing, with the size and format
51/// [`SPRITE_CHUNK_DIMENSIONS`] and [`SPRITE_CHUNK_FORMAT`].
52pub struct SpriteChunkData(pub SpriteRef);
53
54impl SpriteChunkData {
55    /// Creates a new sprite chunk from a newly created platform-dependent
56    /// sprite.
57    pub fn empty(platform: &dyn Platform) -> Option<SpriteChunkData> {
58        let (w, h) = SPRITE_CHUNK_DIMENSIONS;
59        let format = SPRITE_CHUNK_FORMAT;
60        Some(SpriteChunkData(platform.create_sprite(w, h, format)?))
61    }
62
63    /// Uploads the pixel data from the buffer into the sprite, based on the
64    /// [`SpriteChunkDescriptor`] metadata.
65    pub fn update(
66        &mut self,
67        descriptor: &SpriteChunkDescriptor,
68        buffer: &[u8],
69        platform: &dyn Platform,
70    ) {
71        platform.update_sprite(
72            self.0,
73            0,
74            0,
75            descriptor.region_width,
76            descriptor.region_height,
77            buffer,
78        );
79    }
80}