ra2_pal/
lib.rs

1#![deny(missing_debug_implementations, missing_copy_implementations)]
2#![warn(missing_docs, rustdoc::missing_crate_level_docs)]
3#![doc = include_str!("../readme.md")]
4#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/208321371")]
5#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/208321371")]
6
7//! RA2 MIX file format library
8//!
9//! This library provides functionality for reading and writing Red Alert 2 MIX files.
10//! It supports both encrypted and unencrypted MIX files, and can extract files from MIX archives.
11
12mod colors;
13mod reader;
14
15pub use crate::colors::Ra2Color;
16use ra2_types::Ra2Error;
17use serde::Serialize;
18use std::path::Path;
19
20/// `PAL` files contain color palettes for various objects in the game.
21#[repr(C)]
22#[derive(Debug, Copy, Clone, Serialize)]
23pub struct Palette {
24    /// The 256 colors in palette
25    #[serde(serialize_with = "<[_]>::serialize")]
26    pub colors: [Ra2Color; 256],
27}
28
29impl Palette {
30    pub fn load(path: &Path) -> Result<Self, Ra2Error> {
31        let bytes = std::fs::read(path)?;
32        Self::decode(&bytes)
33    }
34    /// 从字节数组创建 PalFile 实例
35    pub fn decode(bytes: &[u8]) -> Result<Self, Ra2Error> {
36        if bytes.len() != 256 * 3 {
37            return Err(Ra2Error::InvalidFormat {
38                message: "字节数组长度不正确,PAL 文件应为 256 * 3 字节".to_string()
39            });
40        }
41
42        let mut colors: [Ra2Color; 256] = [Ra2Color { red: 0, green: 0, blue: 0 }; 256];
43
44        for i in 0..256 {
45            colors[i].red = bytes[i * 3];
46            colors[i].green = bytes[i * 3 + 1];
47            colors[i].blue = bytes[i * 3 + 2];
48        }
49
50        Ok(Palette { colors })
51    }
52
53    /// 获取指定索引的颜色
54    pub fn get_color(&self, index: u8) -> Result<Ra2Color, Ra2Error> {
55        match self.colors.get(index as usize) {
56            Some(s) => Ok(*s),
57            None => Err(Ra2Error::InvalidFormat { message: "超出范围".to_string() }),
58        }
59    }
60}