quake3_qvm/
lib.rs

1#![warn(missing_docs)]
2
3//! A library to handle Quake 3 virtual machines.
4
5// Both `nom` and `error_chain` can recurse deeply
6#![recursion_limit="1024"]
7
8#[macro_use]
9extern crate error_chain;
10#[macro_use]
11extern crate nom;
12
13pub mod errors;
14pub mod bytecode;
15pub mod opcodes;
16pub mod parser;
17
18pub use bytecode::Instruction;
19
20use errors::*;
21
22const VM_MAGIC: [u8; 4] = [0x44, 0x14, 0x72, 0x12];
23
24/// A Quake 3 virtual machine image.
25///
26/// A VM consists of instructions and data, where data is separated into
27///
28/// * word-sized data
29/// * byte-sized data (LIT)
30/// * uninitialized data (BSS)
31#[derive(Debug,PartialEq)]
32pub struct QVM {
33    code: Vec<Instruction>,
34    data: Vec<u32>,
35    lit: Vec<u8>,
36    bss_length: u32,
37}
38
39impl QVM {
40    // TODO: Validate instructions; addresses might be out of bounds etc.
41    /// Creates a new VM instance.
42    ///
43    /// # Errors
44    /// lorem ipsum
45    pub fn new(code: Vec<Instruction>,
46               data: Vec<u32>,
47               lit: Vec<u8>,
48               bss_length: u32)
49               -> Result<QVM> {
50        Ok(QVM {
51               code: code,
52               data: data,
53               lit: lit,
54               bss_length: bss_length,
55           })
56    }
57
58    /// Returns the instructions of the code segment.
59    pub fn instructions(&self) -> &Vec<Instruction> {
60        &self.code
61    }
62
63    /// Returns the word-sized data of the data segment.
64    pub fn data(&self) -> &Vec<u32> {
65        &self.data
66    }
67
68    /// Returns the byte-sized data of the LIT segment.
69    pub fn lit(&self) -> &Vec<u8> {
70        &self.lit
71    }
72
73    /// Returns the length of the uninitialized BSS segment.
74    pub fn bss_length(&self) -> u32 {
75        self.bss_length
76    }
77}
78
79/// The different segments/sections in a QVM file.
80///
81/// See ioquake3's `segmentName_t` in `tools/asm/q3asm.c`
82// These should match the names in ioquake3
83#[allow(non_camel_case_types)]
84#[derive(Debug, Clone, Copy)]
85pub enum Segment {
86    /// The code segment, consisting of instructions.
87    CODE,
88    /// The data segment, consisting of word-sized data.
89    DATA,
90    /// The LIT segment, consisting of byte-sized data.
91    LIT,
92    /// The BSS pseudo-segment, consisting of uninitialized data.
93    BSS,
94    /// The jump table targets pseudo-segment, consisting of jump label addresses.
95    JTRG,
96}