Compare commits
16 Commits
ad792b99d3
...
e3c0b0dd7d
Author | SHA1 | Date |
---|---|---|
an | e3c0b0dd7d | |
an | 14c0ef8f2a | |
an | ab48d26711 | |
an | 501784e2fe | |
an | 80295108b7 | |
an | 9dcf487d18 | |
an | b16b2a7ff1 | |
an | 19cf86b8bc | |
an | 628494e8a4 | |
an | 14d9850653 | |
an | 8f1b043b93 | |
an | 54ab1f9153 | |
an | 5edec0bc88 | |
an | e6bc793861 | |
an | fcf467210e | |
an | 31c6701dd5 |
|
@ -2414,8 +2414,9 @@ this actually hurts my head.
|
||||||
| `BecomeItem` | `16` |
|
| `BecomeItem` | `16` |
|
||||||
| `Bloody` | `17` |
|
| `Bloody` | `17` |
|
||||||
| `WanderHorz` | `18` |
|
| `WanderHorz` | `18` |
|
||||||
| `UseLowGrav` | `19` |
|
| `WanderVert` | `19` |
|
||||||
| `PassMedia` | `20` |
|
| `UseLowGrav` | `20` |
|
||||||
|
| `PassMedia` | `21` |
|
||||||
|
|
||||||
### Monster Flags ###
|
### Monster Flags ###
|
||||||
|
|
||||||
|
|
|
@ -235,7 +235,8 @@ macro_rules! read_data {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns `Err` if `b.len()` is less than `sz`.
|
/// Returns `Err` if `b.len()` is less than `sz`.
|
||||||
pub fn check_data(b: &[u8], sz: usize) -> ResultS<()>
|
#[inline]
|
||||||
|
pub fn check_data<T>(b: &[T], sz: usize) -> ResultS<()>
|
||||||
{
|
{
|
||||||
if b.len() < sz {
|
if b.len() < sz {
|
||||||
Err(err_msg("not enough data"))
|
Err(err_msg("not enough data"))
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
/// use std::convert::TryFrom;
|
/// use std::convert::TryFrom;
|
||||||
///
|
///
|
||||||
/// c_enum! {
|
/// c_enum! {
|
||||||
/// enum MyEnum: u16
|
/// enum MyEnum: u16 {
|
||||||
/// {
|
|
||||||
/// Zero = 0,
|
/// Zero = 0,
|
||||||
/// One = 1,
|
/// One = 1,
|
||||||
/// Two = 2
|
/// Two = 2
|
||||||
|
@ -44,8 +43,7 @@ macro_rules! c_enum
|
||||||
$(#[$outer])*
|
$(#[$outer])*
|
||||||
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
#[repr($ti)]
|
#[repr($ti)]
|
||||||
$vi enum $t
|
$vi enum $t {
|
||||||
{
|
|
||||||
$($(#[$vouter])* $en = $va,)+
|
$($(#[$vouter])* $en = $va,)+
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +57,7 @@ macro_rules! c_enum
|
||||||
{
|
{
|
||||||
match n {
|
match n {
|
||||||
$($va => Ok($t::$en),)+
|
$($va => Ok($t::$en),)+
|
||||||
n => Err(Self::Error::new(n))
|
n => Err(Self::Error::new(stringify!($t), n))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,8 +71,7 @@ mod test
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
c_enum! {
|
c_enum! {
|
||||||
enum TestEnum: u16
|
enum TestEnum: u16 {
|
||||||
{
|
|
||||||
Zero = 0,
|
Zero = 0,
|
||||||
One = 1,
|
One = 1,
|
||||||
Two = 2,
|
Two = 2,
|
||||||
|
|
|
@ -413,12 +413,11 @@ impl HuffmanTable
|
||||||
code <<= 1;
|
code <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(repr_error(code))
|
Err(ReprError::new("DEFLATE code", code).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HuffmanTable
|
struct HuffmanTable {
|
||||||
{
|
|
||||||
nums: [u16; 16],
|
nums: [u16; 16],
|
||||||
syms: Vec<u16>,
|
syms: Vec<u16>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,13 @@ macro_rules! ok {
|
||||||
|
|
||||||
macro_rules! flag_ok {
|
macro_rules! flag_ok {
|
||||||
($t:ident$(::$tc:ident)*, $v:expr) => {
|
($t:ident$(::$tc:ident)*, $v:expr) => {
|
||||||
match $t$(::$tc)*::from_bits($v) {
|
{
|
||||||
Some(v) => Ok(v),
|
let v = $v;
|
||||||
None => Err($crate::err::err_msg(concat!("bad ", stringify!($t)))),
|
|
||||||
|
match $t$(::$tc)*::from_bits(v) {
|
||||||
|
Some(v) => Ok(v),
|
||||||
|
None => Err($crate::err::ReprError::new(stringify!($t), v)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -28,6 +32,15 @@ macro_rules! bail {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! backtrace {
|
||||||
|
($e:expr) => {
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
dbg!($e.backtrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns an `Error` with a static string.
|
/// Returns an `Error` with a static string.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -40,33 +53,22 @@ macro_rules! bail {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn err_msg(msg: &'static str) -> Error {ErrMsg(msg).into()}
|
pub fn err_msg(msg: &'static str) -> Error {ErrMsg(msg).into()}
|
||||||
|
|
||||||
/// Returns an `Error` from a `ReprError`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use maraiah::err::repr_error;
|
|
||||||
///
|
|
||||||
/// assert_eq!(format!("{}", repr_error(77)),
|
|
||||||
/// "representation error (got 77)");
|
|
||||||
/// ```
|
|
||||||
pub fn repr_error<T: Into<i64>>(n: T) -> Error {ReprError::new(n).into()}
|
|
||||||
|
|
||||||
impl ReprError
|
impl ReprError
|
||||||
{
|
{
|
||||||
/// Creates a new `ReprError`.
|
/// Returns an `Error` with a message for representation errata.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use maraiah::err::ReprError;
|
/// use maraiah::err::repr_error;
|
||||||
///
|
///
|
||||||
/// let err = ReprError::new(7);
|
/// assert_eq!(format!("{}", repr_error("TypeName", 77)),
|
||||||
///
|
/// "bad TypeName (77)");
|
||||||
/// assert_eq!(format!("{}", err), "representation error (got 7)");
|
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
pub fn new<T: Into<i64>>(t: &'static str, n: T) -> Self
|
||||||
pub fn new<T: Into<i64>>(n: T) -> Self {Self(n.into())}
|
{
|
||||||
|
Self(t, n.into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fail for ReprError {}
|
impl Fail for ReprError {}
|
||||||
|
@ -76,7 +78,7 @@ impl fmt::Display for ReprError
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||||
{
|
{
|
||||||
write!(f, "representation error (got {})", self.0)
|
write!(f, "bad {} ({})", self.0, self.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +92,7 @@ impl fmt::Display for ErrMsg
|
||||||
|
|
||||||
/// A representation error for an integer.
|
/// A representation error for an integer.
|
||||||
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
pub struct ReprError(i64);
|
pub struct ReprError(&'static str, i64);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ErrMsg(&'static str);
|
struct ErrMsg(&'static str);
|
||||||
|
|
|
@ -85,8 +85,7 @@ impl Default for CStringVec
|
||||||
|
|
||||||
/// An owned null-terminated string vector.
|
/// An owned null-terminated string vector.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CStringVec
|
pub struct CStringVec {
|
||||||
{
|
|
||||||
sv: Vec<CString>,
|
sv: Vec<CString>,
|
||||||
cv: Vec<NT>,
|
cv: Vec<NT>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub fn validate_folder_path(p: &str) -> ResultS<()>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens the file at `path` and skips past any macintosh headers.
|
/// Opens the file at `path` and skips past any macintosh headers.
|
||||||
pub fn open_mac_file<P: AsRef<Path>>(path: P) -> ResultS<fs::File>
|
pub fn open_mac<P: AsRef<Path>>(path: P) -> ResultS<fs::File>
|
||||||
{
|
{
|
||||||
let mut fp = fs::File::open(path)?;
|
let mut fp = fs::File::open(path)?;
|
||||||
|
|
||||||
|
|
|
@ -236,8 +236,7 @@ pub struct Color8(u8, u8, u8);
|
||||||
/// An RGB16 image.
|
/// An RGB16 image.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Image16
|
pub struct Image16 {
|
||||||
{
|
|
||||||
w: usize,
|
w: usize,
|
||||||
h: usize,
|
h: usize,
|
||||||
|
|
||||||
|
@ -248,8 +247,7 @@ pub struct Image16
|
||||||
/// An RGB8 image.
|
/// An RGB8 image.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Image8
|
pub struct Image8 {
|
||||||
{
|
|
||||||
w: usize,
|
w: usize,
|
||||||
h: usize,
|
h: usize,
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,7 @@ pub fn read<'a>(b: &'a [u8],
|
||||||
Ok((&b[p..], Header{pitch, pack_t, depth, clut, rle}))
|
Ok((&b[p..], Header{pitch, pack_t, depth, clut, rle}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Header
|
pub struct Header {
|
||||||
{
|
|
||||||
pub pitch: usize,
|
pub pitch: usize,
|
||||||
pub pack_t: PackType,
|
pub pack_t: PackType,
|
||||||
pub depth: Depth,
|
pub depth: Depth,
|
||||||
|
@ -64,8 +63,7 @@ pub struct Header
|
||||||
}
|
}
|
||||||
|
|
||||||
c_enum! {
|
c_enum! {
|
||||||
pub enum Depth: u16
|
pub enum Depth: u16 {
|
||||||
{
|
|
||||||
_1 = 1,
|
_1 = 1,
|
||||||
_2 = 2,
|
_2 = 2,
|
||||||
_4 = 4,
|
_4 = 4,
|
||||||
|
@ -76,8 +74,7 @@ c_enum! {
|
||||||
}
|
}
|
||||||
|
|
||||||
c_enum! {
|
c_enum! {
|
||||||
pub enum PackType: u16
|
pub enum PackType: u16 {
|
||||||
{
|
|
||||||
Default = 0,
|
Default = 0,
|
||||||
None = 1,
|
None = 1,
|
||||||
NoPad = 2,
|
NoPad = 2,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! QuickDraw PICT indexed `PixMap`s.
|
//! QuickDraw PICT indexed `PixMap`s.
|
||||||
|
|
||||||
use crate::{err::*, image::{*, pict::{pm, rle}}};
|
use crate::{bin::check_data, err::*, image::{*, pict::{pm, rle}}};
|
||||||
|
|
||||||
/// Reads an indexed `PixMap`.
|
/// Reads an indexed `PixMap`.
|
||||||
pub fn read(mut im: Image8,
|
pub fn read(mut im: Image8,
|
||||||
|
@ -34,6 +34,8 @@ pub fn read(mut im: Image8,
|
||||||
d
|
d
|
||||||
};
|
};
|
||||||
|
|
||||||
|
check_data(&d, im.w())?;
|
||||||
|
|
||||||
p += pp;
|
p += pp;
|
||||||
|
|
||||||
for &idx in &d {
|
for &idx in &d {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! QuickDraw PICT R5G5B5 `PixMap`s.
|
//! QuickDraw PICT R5G5B5 `PixMap`s.
|
||||||
|
|
||||||
use crate::{bin::u16b, err::*, image::{*, pict::{pm, rle}}};
|
use crate::{bin::{check_data, u16b}, err::*, image::{*, pict::{pm, rle}}};
|
||||||
|
|
||||||
/// Reads a R5G5B5 `PixMap`.
|
/// Reads a R5G5B5 `PixMap`.
|
||||||
pub fn read(mut im: Image8,
|
pub fn read(mut im: Image8,
|
||||||
|
@ -26,6 +26,8 @@ pub fn read(mut im: Image8,
|
||||||
for _ in 0..im.h() {
|
for _ in 0..im.h() {
|
||||||
let (d, pp) = rle::read::<u16>(&b[p..], hdr.pitch)?;
|
let (d, pp) = rle::read::<u16>(&b[p..], hdr.pitch)?;
|
||||||
|
|
||||||
|
check_data(&d, im.w())?;
|
||||||
|
|
||||||
p += pp;
|
p += pp;
|
||||||
|
|
||||||
for &cr in &d {
|
for &cr in &d {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! QuickDraw PICT RGB8 `PixMap`s.
|
//! QuickDraw PICT RGB8 `PixMap`s.
|
||||||
|
|
||||||
use crate::{err::*, image::{*, pict::{pm, rle}}};
|
use crate::{bin::check_data, err::*, image::{*, pict::{pm, rle}}};
|
||||||
|
|
||||||
/// Reads a RGB8 `PixMap`.
|
/// Reads a RGB8 `PixMap`.
|
||||||
pub fn read(mut im: Image8,
|
pub fn read(mut im: Image8,
|
||||||
|
@ -41,12 +41,14 @@ pub fn read(mut im: Image8,
|
||||||
for _ in 0..im.h() {
|
for _ in 0..im.h() {
|
||||||
let (d, pp) = rle::read::<u8>(&b[p..], pitch)?;
|
let (d, pp) = rle::read::<u8>(&b[p..], pitch)?;
|
||||||
|
|
||||||
|
check_data(&d, im.w() * 3)?;
|
||||||
|
|
||||||
p += pp;
|
p += pp;
|
||||||
|
|
||||||
for x in 0..im.w() {
|
for x in 0..im.w() {
|
||||||
let r = d[x + im.w()];
|
let r = d[x];
|
||||||
let g = d[x + im.w() * 2];
|
let g = d[x * 2];
|
||||||
let b = d[x + im.w() * 3];
|
let b = d[x * 3];
|
||||||
im.cr.push(Color8::new(r, g, b));
|
im.cr.push(Color8::new(r, g, b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,7 @@ pub fn read(b: &[u8]) -> ResultS<(SoundAmbi, usize)>
|
||||||
/// An ambient sound definition.
|
/// An ambient sound definition.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct SoundAmbi
|
pub struct SoundAmbi {
|
||||||
{
|
|
||||||
pub index: u16,
|
pub index: u16,
|
||||||
pub volume: u16,
|
pub volume: u16,
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,7 @@ pub fn read(b: &[u8]) -> ResultS<Attack>
|
||||||
/// The definition of a monster's attack.
|
/// The definition of a monster's attack.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Attack
|
pub struct Attack {
|
||||||
{
|
|
||||||
pub ptype: OptU16,
|
pub ptype: OptU16,
|
||||||
pub rep: u16,
|
pub rep: u16,
|
||||||
pub error: Angle,
|
pub error: Angle,
|
||||||
|
|
|
@ -28,8 +28,7 @@ pub fn read(b: &[u8]) -> ResultS<(SoundRand, usize)>
|
||||||
/// A randomly played sound definition.
|
/// A randomly played sound definition.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct SoundRand
|
pub struct SoundRand {
|
||||||
{
|
|
||||||
pub flags: SoundRandFlags,
|
pub flags: SoundRandFlags,
|
||||||
pub index: u16,
|
pub index: u16,
|
||||||
pub vol_nrm: u16,
|
pub vol_nrm: u16,
|
||||||
|
@ -45,9 +44,9 @@ pub struct SoundRand
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `SoundRand`.
|
/// Flags for `SoundRand`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct SoundRandFlags: u16
|
pub struct SoundRandFlags: u16 {
|
||||||
{
|
|
||||||
const NO_DIRECTION = 1;
|
const NO_DIRECTION = 1;
|
||||||
|
const _2 = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,7 @@ pub fn read(b: &[u8]) -> ResultS<Damage>
|
||||||
/// A damage definition.
|
/// A damage definition.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Damage
|
pub struct Damage {
|
||||||
{
|
|
||||||
pub dtype: DamageType,
|
pub dtype: DamageType,
|
||||||
pub flags: DamageFlags,
|
pub flags: DamageFlags,
|
||||||
pub dmg_base: u16,
|
pub dmg_base: u16,
|
||||||
|
@ -34,8 +33,7 @@ pub struct Damage
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// The composite type of damage taken by something.
|
/// The composite type of damage taken by something.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct DamageTypeFlags: u32
|
pub struct DamageTypeFlags: u32 {
|
||||||
{
|
|
||||||
const EXPLOSION = 1;
|
const EXPLOSION = 1;
|
||||||
const ELECTRICAL_STAFF = 1 << 1;
|
const ELECTRICAL_STAFF = 1 << 1;
|
||||||
const PROJECTILE = 1 << 2;
|
const PROJECTILE = 1 << 2;
|
||||||
|
@ -66,8 +64,7 @@ bitflags! {
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Damage`.
|
/// Flags for `Damage`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct DamageFlags: u16
|
pub struct DamageFlags: u16 {
|
||||||
{
|
|
||||||
const ALIEN = 1;
|
const ALIEN = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,8 +72,7 @@ bitflags! {
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// A named type of damage taken by something.
|
/// A named type of damage taken by something.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum DamageType: u16
|
pub enum DamageType: u16 {
|
||||||
{
|
|
||||||
Explosion = 0,
|
Explosion = 0,
|
||||||
ElectricalStaff = 1,
|
ElectricalStaff = 1,
|
||||||
Projectile = 2,
|
Projectile = 2,
|
||||||
|
|
|
@ -76,11 +76,92 @@ pub fn read_all(head: &head::Header,
|
||||||
Ok(data_map)
|
Ok(data_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EntryData
|
||||||
|
{
|
||||||
|
pub fn get_type(&self) -> EntryType
|
||||||
|
{
|
||||||
|
if self.has_minf() {
|
||||||
|
EntryType::Map
|
||||||
|
} else if self.has_fxpx() ||
|
||||||
|
self.has_mnpx() ||
|
||||||
|
self.has_prpx() ||
|
||||||
|
self.has_pxpx() ||
|
||||||
|
self.has_wppx() {
|
||||||
|
EntryType::Physics
|
||||||
|
} else if self.has_pict() {
|
||||||
|
EntryType::Image
|
||||||
|
} else {
|
||||||
|
EntryType::Other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_epnt(&self) -> bool {self.epnt.is_some()}
|
||||||
|
pub fn has_fxpx(&self) -> bool {self.fxpx.is_some()}
|
||||||
|
pub fn has_lins(&self) -> bool {self.lins.is_some()}
|
||||||
|
pub fn has_lite(&self) -> bool {self.lite.is_some()}
|
||||||
|
pub fn has_mnpx(&self) -> bool {self.mnpx.is_some()}
|
||||||
|
pub fn has_minf(&self) -> bool {self.minf.is_some()}
|
||||||
|
pub fn has_name(&self) -> bool {self.name.is_some()}
|
||||||
|
pub fn has_note(&self) -> bool {self.note.is_some()}
|
||||||
|
pub fn has_objs(&self) -> bool {self.objs.is_some()}
|
||||||
|
pub fn has_pict(&self) -> bool {self.pict.is_some()}
|
||||||
|
pub fn has_pnts(&self) -> bool {self.pnts.is_some()}
|
||||||
|
pub fn has_poly(&self) -> bool {self.poly.is_some()}
|
||||||
|
pub fn has_prpx(&self) -> bool {self.prpx.is_some()}
|
||||||
|
pub fn has_pxpx(&self) -> bool {self.pxpx.is_some()}
|
||||||
|
pub fn has_sids(&self) -> bool {self.sids.is_some()}
|
||||||
|
pub fn has_wppx(&self) -> bool {self.wppx.is_some()}
|
||||||
|
pub fn has_ambi(&self) -> bool {self.ambi.is_some()}
|
||||||
|
pub fn has_bonk(&self) -> bool {self.bonk.is_some()}
|
||||||
|
pub fn has_iidx(&self) -> bool {self.iidx.is_some()}
|
||||||
|
pub fn has_medi(&self) -> bool {self.medi.is_some()}
|
||||||
|
pub fn has_plac(&self) -> bool {self.plac.is_some()}
|
||||||
|
pub fn has_plat(&self) -> bool {self.plat.is_some()}
|
||||||
|
pub fn has_term(&self) -> bool {self.term.is_some()}
|
||||||
|
|
||||||
|
pub fn num_unknown(&self) -> usize {self.unkn.len()}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize
|
||||||
|
{
|
||||||
|
let ret = if self.has_epnt() {1} else {0} +
|
||||||
|
if self.has_fxpx() {1} else {0} +
|
||||||
|
if self.has_lins() {1} else {0} +
|
||||||
|
if self.has_lite() {1} else {0} +
|
||||||
|
if self.has_mnpx() {1} else {0} +
|
||||||
|
if self.has_minf() {1} else {0} +
|
||||||
|
if self.has_name() {1} else {0} +
|
||||||
|
if self.has_note() {1} else {0} +
|
||||||
|
if self.has_objs() {1} else {0} +
|
||||||
|
if self.has_pict() {1} else {0} +
|
||||||
|
if self.has_pnts() {1} else {0} +
|
||||||
|
if self.has_poly() {1} else {0} +
|
||||||
|
if self.has_prpx() {1} else {0} +
|
||||||
|
if self.has_pxpx() {1} else {0} +
|
||||||
|
if self.has_sids() {1} else {0} +
|
||||||
|
if self.has_wppx() {1} else {0} +
|
||||||
|
if self.has_ambi() {1} else {0} +
|
||||||
|
if self.has_bonk() {1} else {0} +
|
||||||
|
if self.has_iidx() {1} else {0} +
|
||||||
|
if self.has_medi() {1} else {0} +
|
||||||
|
if self.has_plac() {1} else {0} +
|
||||||
|
if self.has_plat() {1} else {0} +
|
||||||
|
self.num_unknown();
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The abstract type of an entry.
|
||||||
|
pub enum EntryType {
|
||||||
|
Other,
|
||||||
|
Map,
|
||||||
|
Image,
|
||||||
|
Physics,
|
||||||
|
}
|
||||||
|
|
||||||
/// The loaded data of a Map file entry.
|
/// The loaded data of a Map file entry.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Default, Eq, PartialEq)]
|
#[derive(Debug, Default, Eq, PartialEq)]
|
||||||
pub struct EntryData
|
pub struct EntryData {
|
||||||
{
|
|
||||||
/** `EPNT` chunk data. */ pub epnt: Option<Vec<map::epnt::Endpoint>>,
|
/** `EPNT` chunk data. */ pub epnt: Option<Vec<map::epnt::Endpoint>>,
|
||||||
/** `FXpx` chunk data. */ pub fxpx: Option<Vec<map::fxpx::Effect>>,
|
/** `FXpx` chunk data. */ pub fxpx: Option<Vec<map::fxpx::Effect>>,
|
||||||
/** `LINS` chunk data. */ pub lins: Option<Vec<map::lins::Line>>,
|
/** `LINS` chunk data. */ pub lins: Option<Vec<map::lins::Line>>,
|
||||||
|
|
|
@ -8,18 +8,29 @@ use std::collections::BTreeMap;
|
||||||
pub fn read(map: &head::Map, i: usize) -> ResultS<(u16, Entry<'_>)>
|
pub fn read(map: &head::Map, i: usize) -> ResultS<(u16, Entry<'_>)>
|
||||||
{
|
{
|
||||||
let size = map.head().size_entry();
|
let size = map.head().size_entry();
|
||||||
|
let b = map.dir();
|
||||||
|
let sta = size * i;
|
||||||
|
|
||||||
read_data! {
|
read_data! {
|
||||||
endian: BIG, buf: map.dir(), size: size, start: size * i, data {
|
endian: BIG, buf: b, size: size, start: sta, data {
|
||||||
let offset = u32[0] usize;
|
let offset = u32[0] usize;
|
||||||
let dsize = u32[4] usize;
|
let dsize = u32[4] usize;
|
||||||
let index = u16[8];
|
|
||||||
let app_data = u8[10; map.head().size_appl()];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (index, app_data) = if !map.head().old_wad() {
|
||||||
|
read_data! {
|
||||||
|
endian: BIG, buf: b, size: size, start: sta, data {
|
||||||
|
let index = u16[8];
|
||||||
|
let app_data = u8[10; map.head().size_appl()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(index, app_data)
|
||||||
|
} else {
|
||||||
|
(i as u16, &b[0..0])
|
||||||
|
};
|
||||||
|
|
||||||
let data = &map.data()[offset..offset + dsize];
|
let data = &map.data()[offset..offset + dsize];
|
||||||
let index = if map.head().old_wad() {i as u16} else {index};
|
|
||||||
|
|
||||||
Ok((index, Entry{data, app_data}))
|
Ok((index, Entry{data, app_data}))
|
||||||
}
|
}
|
||||||
|
@ -45,8 +56,7 @@ pub fn read_all(map: &head::Map) -> ResultS<EntryMap<'_>>
|
||||||
/// An entry containing chunked data and application-specific data.
|
/// An entry containing chunked data and application-specific data.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Entry<'a>
|
pub struct Entry<'a> {
|
||||||
{
|
|
||||||
/// The data in this `Entry`.
|
/// The data in this `Entry`.
|
||||||
pub data: &'a [u8],
|
pub data: &'a [u8],
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,7 @@ pub fn to_pnts(v: &[Endpoint]) -> Vec<pnts::Point>
|
||||||
/// A pre-processed point in world-space.
|
/// A pre-processed point in world-space.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Endpoint
|
pub struct Endpoint {
|
||||||
{
|
|
||||||
pub flags: EndpointFlags,
|
pub flags: EndpointFlags,
|
||||||
pub hei_hi: Unit,
|
pub hei_hi: Unit,
|
||||||
pub hei_lo: Unit,
|
pub hei_lo: Unit,
|
||||||
|
@ -41,8 +40,7 @@ pub struct Endpoint
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Endpoint`.
|
/// Flags for `Endpoint`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct EndpointFlags: u16
|
pub struct EndpointFlags: u16 {
|
||||||
{
|
|
||||||
const SOLID = 1;
|
const SOLID = 1;
|
||||||
const SAME_HEIGHT = 1 << 1;
|
const SAME_HEIGHT = 1 << 1;
|
||||||
const TRANSPARENT = 1 << 2;
|
const TRANSPARENT = 1 << 2;
|
||||||
|
|
|
@ -23,8 +23,7 @@ pub fn read(b: &[u8]) -> ResultS<(Effect, usize)>
|
||||||
/// An effect definition.
|
/// An effect definition.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Effect
|
pub struct Effect {
|
||||||
{
|
|
||||||
pub collection: u16,
|
pub collection: u16,
|
||||||
pub shape: u16,
|
pub shape: u16,
|
||||||
pub pitch: Fixed,
|
pub pitch: Fixed,
|
||||||
|
@ -36,8 +35,7 @@ pub struct Effect
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for an effect.
|
/// Flags for an effect.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct EffectFlags: u16
|
pub struct EffectFlags: u16 {
|
||||||
{
|
|
||||||
const END_ON_LOOP = 1;
|
const END_ON_LOOP = 1;
|
||||||
const END_ON_XFER_LOOP = 1 << 1;
|
const END_ON_XFER_LOOP = 1 << 1;
|
||||||
const SOUND_ONLY = 1 << 2;
|
const SOUND_ONLY = 1 << 2;
|
||||||
|
|
|
@ -111,8 +111,7 @@ impl Map
|
||||||
/// A Map header.
|
/// A Map header.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Header
|
pub struct Header {
|
||||||
{
|
|
||||||
/// The original name of this file.
|
/// The original name of this file.
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
|
@ -124,8 +123,7 @@ pub struct Header
|
||||||
/// A Map file.
|
/// A Map file.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Map
|
pub struct Map {
|
||||||
{
|
|
||||||
head: Header,
|
head: Header,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
dir_ofs: usize,
|
dir_ofs: usize,
|
||||||
|
@ -135,8 +133,7 @@ pub struct Map
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// The version of a Map file.
|
/// The version of a Map file.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum Ver: u16
|
pub enum Ver: u16 {
|
||||||
{
|
|
||||||
Base = 0,
|
Base = 0,
|
||||||
Dir = 1,
|
Dir = 1,
|
||||||
Over = 2,
|
Over = 2,
|
||||||
|
|
|
@ -24,8 +24,7 @@ pub fn read(b: &[u8]) -> ResultS<(Line, usize)>
|
||||||
/// A line segment.
|
/// A line segment.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Line
|
pub struct Line {
|
||||||
{
|
|
||||||
pub flags: LineFlags,
|
pub flags: LineFlags,
|
||||||
pub pnt_beg: u16,
|
pub pnt_beg: u16,
|
||||||
pub pnt_end: u16,
|
pub pnt_end: u16,
|
||||||
|
@ -38,8 +37,7 @@ pub struct Line
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Line`.
|
/// Flags for `Line`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct LineFlags: u16
|
pub struct LineFlags: u16 {
|
||||||
{
|
|
||||||
const TRANS_SIDE = 1 << 9;
|
const TRANS_SIDE = 1 << 9;
|
||||||
const ELEV_VAR = 1 << 10;
|
const ELEV_VAR = 1 << 10;
|
||||||
const ELEVATION = 1 << 11;
|
const ELEVATION = 1 << 11;
|
||||||
|
|
|
@ -73,8 +73,7 @@ pub fn read_old(b: &[u8]) -> ResultS<(Light, usize)>
|
||||||
/// A dynamic polygon light.
|
/// A dynamic polygon light.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Light
|
pub struct Light {
|
||||||
{
|
|
||||||
pub ltype: LightType,
|
pub ltype: LightType,
|
||||||
pub flags: LightFlags,
|
pub flags: LightFlags,
|
||||||
pub phase: i16,
|
pub phase: i16,
|
||||||
|
@ -90,8 +89,7 @@ pub struct Light
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Light`.
|
/// Flags for `Light`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct LightFlags: u16
|
pub struct LightFlags: u16 {
|
||||||
{
|
|
||||||
const INIT_ACTIVE = 1;
|
const INIT_ACTIVE = 1;
|
||||||
const SLAVE_VALUE = 1 << 1;
|
const SLAVE_VALUE = 1 << 1;
|
||||||
const STATELESS = 1 << 2;
|
const STATELESS = 1 << 2;
|
||||||
|
@ -101,8 +99,7 @@ bitflags! {
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// The type of a `Light`.
|
/// The type of a `Light`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum LightType: u16
|
pub enum LightType: u16 {
|
||||||
{
|
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
Strobe = 1,
|
Strobe = 1,
|
||||||
Media = 2,
|
Media = 2,
|
||||||
|
|
|
@ -33,8 +33,7 @@ pub fn write(v: &LightFunc) -> Vec<u8>
|
||||||
/// A light function.
|
/// A light function.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct LightFunc
|
pub struct LightFunc {
|
||||||
{
|
|
||||||
pub ftype: LightFuncType,
|
pub ftype: LightFuncType,
|
||||||
pub prd_nrm: u16,
|
pub prd_nrm: u16,
|
||||||
pub prd_dta: u16,
|
pub prd_dta: u16,
|
||||||
|
@ -45,8 +44,7 @@ pub struct LightFunc
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// The type of function for a `LightFunc`.
|
/// The type of function for a `LightFunc`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum LightFuncType: u16
|
pub enum LightFuncType: u16 {
|
||||||
{
|
|
||||||
Constant = 0,
|
Constant = 0,
|
||||||
Linear = 1,
|
Linear = 1,
|
||||||
Smooth = 2,
|
Smooth = 2,
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub fn read(b: &[u8]) -> ResultS<(Media, usize)>
|
||||||
read_data! {
|
read_data! {
|
||||||
endian: BIG, buf: b, size: 32, start: 0, data {
|
endian: BIG, buf: b, size: 32, start: 0, data {
|
||||||
let mtype = u16[0] enum MediaType;
|
let mtype = u16[0] enum MediaType;
|
||||||
let flags = u16[2] flag MediaFlags;
|
let flags = u8[3] flag MediaFlags;
|
||||||
let control = u16[4];
|
let control = u16[4];
|
||||||
let dir = Angle[6];
|
let dir = Angle[6];
|
||||||
let mag = Unit[8];
|
let mag = Unit[8];
|
||||||
|
@ -34,8 +34,7 @@ pub fn read(b: &[u8]) -> ResultS<(Media, usize)>
|
||||||
/// A media, as in a part of a polygon which goes up the middle of the wall.
|
/// A media, as in a part of a polygon which goes up the middle of the wall.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Media
|
pub struct Media {
|
||||||
{
|
|
||||||
pub mtype: MediaType,
|
pub mtype: MediaType,
|
||||||
pub flags: MediaFlags,
|
pub flags: MediaFlags,
|
||||||
pub control: u16,
|
pub control: u16,
|
||||||
|
@ -53,20 +52,19 @@ pub struct Media
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// The liquid type of a `Media`.
|
/// The liquid type of a `Media`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum MediaType: u16
|
pub enum MediaType: u16 {
|
||||||
{
|
|
||||||
Water = 0,
|
Water = 0,
|
||||||
Lava = 1,
|
Lava = 1,
|
||||||
Goo = 2,
|
Goo = 2,
|
||||||
Sewage = 3,
|
Sewage = 3,
|
||||||
|
Jjaro = 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Media`.
|
/// Flags for `Media`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct MediaFlags: u16
|
pub struct MediaFlags: u8 {
|
||||||
{
|
|
||||||
const OBSTRUCT = 1;
|
const OBSTRUCT = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,7 @@ impl Default for Info
|
||||||
/// Static map information.
|
/// Static map information.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Info
|
pub struct Info {
|
||||||
{
|
|
||||||
pub texture_id: u16,
|
pub texture_id: u16,
|
||||||
pub physics_id: u16,
|
pub physics_id: u16,
|
||||||
pub skypict_id: u16,
|
pub skypict_id: u16,
|
||||||
|
@ -85,8 +84,7 @@ pub struct Info
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Static environment flags.
|
/// Static environment flags.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct EnvironmentFlags: u16
|
pub struct EnvironmentFlags: u16 {
|
||||||
{
|
|
||||||
const VACUUM = 1;
|
const VACUUM = 1;
|
||||||
const MAGNETIC = 1 << 1;
|
const MAGNETIC = 1 << 1;
|
||||||
const REBELLION = 1 << 2;
|
const REBELLION = 1 << 2;
|
||||||
|
@ -104,8 +102,7 @@ bitflags! {
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Static entry point flags.
|
/// Static entry point flags.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct EntryFlags: u32
|
pub struct EntryFlags: u32 {
|
||||||
{
|
|
||||||
const SOLO = 1;
|
const SOLO = 1;
|
||||||
const CO_OP = 1 << 1;
|
const CO_OP = 1 << 1;
|
||||||
const CARNAGE = 1 << 2;
|
const CARNAGE = 1 << 2;
|
||||||
|
@ -120,8 +117,7 @@ bitflags! {
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Static mission flags.
|
/// Static mission flags.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct MissionFlags: u16
|
pub struct MissionFlags: u16 {
|
||||||
{
|
|
||||||
const EXTERMINATION = 1;
|
const EXTERMINATION = 1;
|
||||||
const EXPLORATION = 1 << 1;
|
const EXPLORATION = 1 << 1;
|
||||||
const RETRIEVAL = 1 << 2;
|
const RETRIEVAL = 1 << 2;
|
||||||
|
|
|
@ -86,8 +86,7 @@ pub fn read(b: &[u8]) -> ResultS<(Monster, usize)>
|
||||||
/// A monster definition.
|
/// A monster definition.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Monster
|
pub struct Monster {
|
||||||
{
|
|
||||||
pub collection: u16,
|
pub collection: u16,
|
||||||
pub vitality: u16,
|
pub vitality: u16,
|
||||||
pub dty_immune: damg::DamageTypeFlags,
|
pub dty_immune: damg::DamageTypeFlags,
|
||||||
|
@ -144,8 +143,7 @@ pub struct Monster
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for a monster.
|
/// Flags for a monster.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct MonsterFlags: u32
|
pub struct MonsterFlags: u32 {
|
||||||
{
|
|
||||||
const IGNORE_LOS = 1;
|
const IGNORE_LOS = 1;
|
||||||
const FLYING = 1 << 1;
|
const FLYING = 1 << 1;
|
||||||
const ALIEN = 1 << 2;
|
const ALIEN = 1 << 2;
|
||||||
|
@ -180,8 +178,7 @@ bitflags! {
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// The composite type of a monster.
|
/// The composite type of a monster.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct MonsterClass: u32
|
pub struct MonsterClass: u32 {
|
||||||
{
|
|
||||||
const PLAYER = 1;
|
const PLAYER = 1;
|
||||||
const CIVILIAN = 1 << 1;
|
const CIVILIAN = 1 << 1;
|
||||||
const MADD = 1 << 2;
|
const MADD = 1 << 2;
|
||||||
|
|
|
@ -20,8 +20,7 @@ pub fn read(b: &[u8]) -> ResultS<(Note, usize)>
|
||||||
/// Overhead map annotations.
|
/// Overhead map annotations.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Note
|
pub struct Note {
|
||||||
{
|
|
||||||
pub pos: pnts::Point,
|
pub pos: pnts::Point,
|
||||||
pub poly: u16,
|
pub poly: u16,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
|
|
|
@ -30,8 +30,7 @@ pub fn read(b: &[u8]) -> ResultS<(Object, usize)>
|
||||||
/// An object in the world.
|
/// An object in the world.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Object
|
pub struct Object {
|
||||||
{
|
|
||||||
pub group: u16,
|
pub group: u16,
|
||||||
pub index: u16,
|
pub index: u16,
|
||||||
pub angle: Angle,
|
pub angle: Angle,
|
||||||
|
@ -46,8 +45,7 @@ pub struct Object
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Object`.
|
/// Flags for `Object`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct ObjectFlags: u16
|
pub struct ObjectFlags: u16 {
|
||||||
{
|
|
||||||
const INVISIBLE = 1;
|
const INVISIBLE = 1;
|
||||||
const CEILING = 1 << 1;
|
const CEILING = 1 << 1;
|
||||||
const BLIND = 1 << 2;
|
const BLIND = 1 << 2;
|
||||||
|
|
|
@ -23,8 +23,7 @@ pub fn read(b: &[u8]) -> ResultS<(ObjectFreq, usize)>
|
||||||
/// The difficulty definition for various object types.
|
/// The difficulty definition for various object types.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct ObjectFreq
|
pub struct ObjectFreq {
|
||||||
{
|
|
||||||
pub flags: ObjectFreqFlags,
|
pub flags: ObjectFreqFlags,
|
||||||
pub cnt_ini: u16,
|
pub cnt_ini: u16,
|
||||||
pub cnt_min: u16,
|
pub cnt_min: u16,
|
||||||
|
@ -36,9 +35,12 @@ pub struct ObjectFreq
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `ObjectFreq`.
|
/// Flags for `ObjectFreq`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct ObjectFreqFlags: u16
|
pub struct ObjectFreqFlags: u16 {
|
||||||
{
|
|
||||||
const RANDOM_LOCATION = 1;
|
const RANDOM_LOCATION = 1;
|
||||||
|
const _3 = 1 << 3;
|
||||||
|
const _4 = 1 << 4;
|
||||||
|
const _5 = 1 << 5;
|
||||||
|
const _6 = 1 << 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,7 @@ pub fn read(b: &[u8]) -> ResultS<(Platform, usize)>
|
||||||
/// Extra information for polygons with platforms.
|
/// Extra information for polygons with platforms.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Platform
|
pub struct Platform {
|
||||||
{
|
|
||||||
pub ptype: u16,
|
pub ptype: u16,
|
||||||
pub speed: u16,
|
pub speed: u16,
|
||||||
pub delay: u16,
|
pub delay: u16,
|
||||||
|
@ -40,8 +39,7 @@ pub struct Platform
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Platform`.
|
/// Flags for `Platform`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct PlatformFlags: u32
|
pub struct PlatformFlags: u32 {
|
||||||
{
|
|
||||||
const INIT_ACTIVE = 1;
|
const INIT_ACTIVE = 1;
|
||||||
const INIT_EXTENDED = 1 << 1;
|
const INIT_EXTENDED = 1 << 1;
|
||||||
const STOP_AT_EACH_LEVEL = 1 << 2;
|
const STOP_AT_EACH_LEVEL = 1 << 2;
|
||||||
|
|
|
@ -30,8 +30,7 @@ pub fn read(b: &[u8]) -> ResultS<(Point, usize)> {Ok((read_o(b)?, 4))}
|
||||||
/// A point in world-space.
|
/// A point in world-space.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
|
||||||
pub struct Point
|
pub struct Point {
|
||||||
{
|
|
||||||
pub x: Unit,
|
pub x: Unit,
|
||||||
pub y: Unit,
|
pub y: Unit,
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ impl PolygonType
|
||||||
21 => Ok(PolygonType::Glue),
|
21 => Ok(PolygonType::Glue),
|
||||||
22 => Ok(PolygonType::GlueTrigger(pdata)),
|
22 => Ok(PolygonType::GlueTrigger(pdata)),
|
||||||
23 => Ok(PolygonType::GlueSuper),
|
23 => Ok(PolygonType::GlueSuper),
|
||||||
n => Err(ReprError::new(n)),
|
n => Err(ReprError::new("PolygonType", n)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ impl PolygonType
|
||||||
13 => Ok(PolygonType::GlueSuper),
|
13 => Ok(PolygonType::GlueSuper),
|
||||||
14 => Ok(PolygonType::MustExplore),
|
14 => Ok(PolygonType::MustExplore),
|
||||||
15 => Ok(PolygonType::AutoExit),
|
15 => Ok(PolygonType::AutoExit),
|
||||||
n => Err(ReprError::new(n)),
|
n => Err(ReprError::new("PolygonType", n)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,8 +131,7 @@ impl Default for PolygonType
|
||||||
/// A polygon segment.
|
/// A polygon segment.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||||
pub struct Polygon
|
pub struct Polygon {
|
||||||
{
|
|
||||||
pub ptype: PolygonType,
|
pub ptype: PolygonType,
|
||||||
pub tex_flr: OptU16,
|
pub tex_flr: OptU16,
|
||||||
pub tex_cei: OptU16,
|
pub tex_cei: OptU16,
|
||||||
|
@ -154,8 +153,7 @@ pub struct Polygon
|
||||||
/// The action type of a `Polygon`.
|
/// The action type of a `Polygon`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub enum PolygonType
|
pub enum PolygonType {
|
||||||
{
|
|
||||||
Normal,
|
Normal,
|
||||||
ImpassItem,
|
ImpassItem,
|
||||||
ImpassMons,
|
ImpassMons,
|
||||||
|
@ -185,8 +183,7 @@ pub enum PolygonType
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Polygon`.
|
/// Flags for `Polygon`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct PolygonFlags: u16
|
pub struct PolygonFlags: u16 {
|
||||||
{
|
|
||||||
const DETACHED = 1 << 14;
|
const DETACHED = 1 << 14;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,7 @@ pub fn read(b: &[u8]) -> ResultS<(Projectile, usize)>
|
||||||
/// A projectile definition.
|
/// A projectile definition.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Projectile
|
pub struct Projectile {
|
||||||
{
|
|
||||||
pub collection: OptU16,
|
pub collection: OptU16,
|
||||||
pub shape: u16,
|
pub shape: u16,
|
||||||
pub fxt_explode: OptU16,
|
pub fxt_explode: OptU16,
|
||||||
|
@ -62,8 +61,7 @@ pub struct Projectile
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for a projectile.
|
/// Flags for a projectile.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct ProjectileFlags: u32
|
pub struct ProjectileFlags: u32 {
|
||||||
{
|
|
||||||
const GUIDED = 1;
|
const GUIDED = 1;
|
||||||
const STOP_ON_LOOP = 1 << 1;
|
const STOP_ON_LOOP = 1 << 1;
|
||||||
const PERSISTENT = 1 << 2;
|
const PERSISTENT = 1 << 2;
|
||||||
|
@ -83,8 +81,9 @@ bitflags! {
|
||||||
const BECOME_ITEM = 1 << 16;
|
const BECOME_ITEM = 1 << 16;
|
||||||
const BLOODY = 1 << 17;
|
const BLOODY = 1 << 17;
|
||||||
const WANDER_HORZ = 1 << 18;
|
const WANDER_HORZ = 1 << 18;
|
||||||
const USE_LOW_GRAV = 1 << 19;
|
const WANDER_VERT = 1 << 19;
|
||||||
const PASS_MEDIA = 1 << 20;
|
const USE_LOW_GRAV = 1 << 20;
|
||||||
|
const PASS_MEDIA = 1 << 21;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,7 @@ pub fn read(b: &[u8]) -> ResultS<(Physics, usize)>
|
||||||
/// Static physics information.
|
/// Static physics information.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Physics
|
pub struct Physics {
|
||||||
{
|
|
||||||
pub acc_ang: Fixed,
|
pub acc_ang: Fixed,
|
||||||
pub acc_cli: Fixed,
|
pub acc_cli: Fixed,
|
||||||
pub acc_grv: Fixed,
|
pub acc_grv: Fixed,
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub fn read(b: &[u8]) -> ResultS<(Side, usize)>
|
||||||
read_data! {
|
read_data! {
|
||||||
endian: BIG, buf: b, size: 64, start: 0, data {
|
endian: BIG, buf: b, size: 64, start: 0, data {
|
||||||
let stype = u16[0] enum SideType;
|
let stype = u16[0] enum SideType;
|
||||||
let flags = u16[2] flag SideFlags;
|
let flags = u8[3] flag SideFlags;
|
||||||
let tex_pri = stex::read[4; 6];
|
let tex_pri = stex::read[4; 6];
|
||||||
let tex_sec = stex::read[10; 6];
|
let tex_sec = stex::read[10; 6];
|
||||||
let tex_tra = stex::read[16; 6];
|
let tex_tra = stex::read[16; 6];
|
||||||
|
@ -41,8 +41,7 @@ pub fn read_old(b: &[u8]) -> ResultS<(Side, usize)>
|
||||||
/// One side of a line segment.
|
/// One side of a line segment.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Side
|
pub struct Side {
|
||||||
{
|
|
||||||
pub stype: SideType,
|
pub stype: SideType,
|
||||||
pub flags: SideFlags,
|
pub flags: SideFlags,
|
||||||
pub tex_pri: stex::SideTex,
|
pub tex_pri: stex::SideTex,
|
||||||
|
@ -59,8 +58,7 @@ pub struct Side
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Side`.
|
/// Flags for `Side`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct SideFlags: u16
|
pub struct SideFlags: u8 {
|
||||||
{
|
|
||||||
const STATUS = 1;
|
const STATUS = 1;
|
||||||
const PANEL = 1 << 1;
|
const PANEL = 1 << 1;
|
||||||
const REPAIR = 1 << 2;
|
const REPAIR = 1 << 2;
|
||||||
|
@ -75,8 +73,7 @@ bitflags! {
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// The texture type of a `Side`.
|
/// The texture type of a `Side`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum SideType: u16
|
pub enum SideType: u16 {
|
||||||
{
|
|
||||||
Full = 0,
|
Full = 0,
|
||||||
High = 1,
|
High = 1,
|
||||||
Low = 2,
|
Low = 2,
|
||||||
|
|
|
@ -28,8 +28,7 @@ pub fn write(v: &SideTex) -> Vec<u8>
|
||||||
/// The texture of a side segment.
|
/// The texture of a side segment.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct SideTex
|
pub struct SideTex {
|
||||||
{
|
|
||||||
pub offs: pnts::Point,
|
pub offs: pnts::Point,
|
||||||
pub tex_id: OptU16,
|
pub tex_id: OptU16,
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,7 @@ pub fn read(b: &[u8]) -> ResultS<(Terminal, usize)>
|
||||||
/// A terminal definition, with collections of groups and faces.
|
/// A terminal definition, with collections of groups and faces.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Terminal
|
pub struct Terminal {
|
||||||
{
|
|
||||||
pub lines: u16,
|
pub lines: u16,
|
||||||
pub groups: Vec<trmg::Group>,
|
pub groups: Vec<trmg::Group>,
|
||||||
pub faces: Vec<trmf::Face>,
|
pub faces: Vec<trmf::Face>,
|
||||||
|
|
|
@ -36,8 +36,7 @@ pub fn read(b: &[u8]) -> ResultS<Trigger>
|
||||||
/// The definition of one of two triggers for a weapon.
|
/// The definition of one of two triggers for a weapon.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Trigger
|
pub struct Trigger {
|
||||||
{
|
|
||||||
pub burst: u16,
|
pub burst: u16,
|
||||||
pub dx: i16,
|
pub dx: i16,
|
||||||
pub dz: i16,
|
pub dz: i16,
|
||||||
|
@ -61,8 +60,7 @@ pub struct Trigger
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// A bullet shell casing emitted by a weapon.
|
/// A bullet shell casing emitted by a weapon.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum CasingType: u16
|
pub enum CasingType: u16 {
|
||||||
{
|
|
||||||
Rifle = 0,
|
Rifle = 0,
|
||||||
Pistol = 1,
|
Pistol = 1,
|
||||||
PistolLeft = 2,
|
PistolLeft = 2,
|
||||||
|
|
|
@ -19,8 +19,7 @@ pub fn read(b: &[u8]) -> ResultS<(Face, usize)>
|
||||||
/// A text face.
|
/// A text face.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Face
|
pub struct Face {
|
||||||
{
|
|
||||||
pub start: usize,
|
pub start: usize,
|
||||||
pub face: u16,
|
pub face: u16,
|
||||||
pub color: u16,
|
pub color: u16,
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub fn read(b: &[u8]) -> ResultS<(InterGroup, usize)>
|
||||||
14 => GroupType::Camera(pdata),
|
14 => GroupType::Camera(pdata),
|
||||||
15 => GroupType::Static(pdata),
|
15 => GroupType::Static(pdata),
|
||||||
16 => GroupType::Tag(pdata),
|
16 => GroupType::Tag(pdata),
|
||||||
n => return Err(ReprError::new(n).into()),
|
n => return Err(ReprError::new("GroupType", n).into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((InterGroup{flags, ttype, lines, beg, len}, 12))
|
Ok((InterGroup{flags, ttype, lines, beg, len}, 12))
|
||||||
|
@ -48,8 +48,7 @@ impl Default for GroupType
|
||||||
|
|
||||||
/// Interim structure.
|
/// Interim structure.
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct InterGroup
|
pub struct InterGroup {
|
||||||
{
|
|
||||||
pub flags: GroupFlags,
|
pub flags: GroupFlags,
|
||||||
pub ttype: GroupType,
|
pub ttype: GroupType,
|
||||||
pub lines: u16,
|
pub lines: u16,
|
||||||
|
@ -60,8 +59,7 @@ pub struct InterGroup
|
||||||
/// A terminal command grouping.
|
/// A terminal command grouping.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Group
|
pub struct Group {
|
||||||
{
|
|
||||||
pub flags: GroupFlags,
|
pub flags: GroupFlags,
|
||||||
pub ttype: GroupType,
|
pub ttype: GroupType,
|
||||||
pub lines: u16,
|
pub lines: u16,
|
||||||
|
@ -71,8 +69,7 @@ pub struct Group
|
||||||
/// The command of a `Group`.
|
/// The command of a `Group`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub enum GroupType
|
pub enum GroupType {
|
||||||
{
|
|
||||||
Logon(u16),
|
Logon(u16),
|
||||||
Unfinished,
|
Unfinished,
|
||||||
Success,
|
Success,
|
||||||
|
@ -95,8 +92,7 @@ pub enum GroupType
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Group`.
|
/// Flags for `Group`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct GroupFlags: u16
|
pub struct GroupFlags: u16 {
|
||||||
{
|
|
||||||
/// Draws the picture on the right.
|
/// Draws the picture on the right.
|
||||||
const DRAW_ON_RIGHT = 1;
|
const DRAW_ON_RIGHT = 1;
|
||||||
/// Draws the picture in the center.
|
/// Draws the picture in the center.
|
||||||
|
|
|
@ -48,8 +48,7 @@ pub fn read(b: &[u8]) -> ResultS<(Weapon, usize)>
|
||||||
/// A weapon definition.
|
/// A weapon definition.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Weapon
|
pub struct Weapon {
|
||||||
{
|
|
||||||
pub amp_bob: Fixed,
|
pub amp_bob: Fixed,
|
||||||
pub amp_horz: Fixed,
|
pub amp_horz: Fixed,
|
||||||
pub collection: u16,
|
pub collection: u16,
|
||||||
|
@ -80,8 +79,7 @@ pub struct Weapon
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for a weapon.
|
/// Flags for a weapon.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct WeaponFlags: u16
|
pub struct WeaponFlags: u16 {
|
||||||
{
|
|
||||||
const AUTOMATIC = 1;
|
const AUTOMATIC = 1;
|
||||||
const REMOVE_AFTER_USE = 1 << 1;
|
const REMOVE_AFTER_USE = 1 << 1;
|
||||||
const INSTANT_CASING = 1 << 2;
|
const INSTANT_CASING = 1 << 2;
|
||||||
|
@ -99,8 +97,7 @@ bitflags! {
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// The type of functionality a weapon provides.
|
/// The type of functionality a weapon provides.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum WeaponType: u16
|
pub enum WeaponType: u16 {
|
||||||
{
|
|
||||||
Melee = 0,
|
Melee = 0,
|
||||||
Normal = 1,
|
Normal = 1,
|
||||||
DualFunc = 2,
|
DualFunc = 2,
|
||||||
|
|
|
@ -22,7 +22,7 @@ macro_rules! meta_str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_str!(
|
meta_str! {
|
||||||
/// The authors of this crate, `:` separated.
|
/// The authors of this crate, `:` separated.
|
||||||
authors = env!("CARGO_PKG_AUTHORS");
|
authors = env!("CARGO_PKG_AUTHORS");
|
||||||
/// The description of this crate.
|
/// The description of this crate.
|
||||||
|
@ -45,6 +45,6 @@ meta_str!(
|
||||||
version_patch = env!("CARGO_PKG_VERSION_PATCH");
|
version_patch = env!("CARGO_PKG_VERSION_PATCH");
|
||||||
/// The pre-release version of this crate.
|
/// The pre-release version of this crate.
|
||||||
version_pre = env!("CARGO_PKG_VERSION_PRE");
|
version_pre = env!("CARGO_PKG_VERSION_PRE");
|
||||||
);
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -114,8 +114,7 @@ impl Image for ImageShp<'_, '_>
|
||||||
|
|
||||||
/// An unpacked Shape bitmap.
|
/// An unpacked Shape bitmap.
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Bitmap
|
pub struct Bitmap {
|
||||||
{
|
|
||||||
w: usize,
|
w: usize,
|
||||||
h: usize,
|
h: usize,
|
||||||
cr: Vec<u8>,
|
cr: Vec<u8>,
|
||||||
|
@ -126,15 +125,13 @@ pub struct Bitmap
|
||||||
/// An image from a Shape. This mainly just exists so that `Bitmap` can use the
|
/// An image from a Shape. This mainly just exists so that `Bitmap` can use the
|
||||||
/// `Image` trait.
|
/// `Image` trait.
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct ImageShp<'a, 'b>
|
pub struct ImageShp<'a, 'b> {
|
||||||
{
|
|
||||||
bmp: &'a Bitmap,
|
bmp: &'a Bitmap,
|
||||||
clut: &'b [clut::ColorShp],
|
clut: &'b [clut::ColorShp],
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
struct BmpFlags: u16
|
struct BmpFlags: u16 {
|
||||||
{
|
|
||||||
const TRANSPARENT = 1 << 14;
|
const TRANSPARENT = 1 << 14;
|
||||||
const COLUMN_MAJOR = 1 << 15;
|
const COLUMN_MAJOR = 1 << 15;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,8 +93,7 @@ impl Color for ColorShp
|
||||||
/// A color in a `Clut`.
|
/// A color in a `Clut`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum ColorShp
|
pub enum ColorShp {
|
||||||
{
|
|
||||||
/// A completely translucent color.
|
/// A completely translucent color.
|
||||||
Translucent,
|
Translucent,
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,7 @@ pub fn read(b: &[u8]) -> ResultS<Collection>
|
||||||
|
|
||||||
/// A collection of color tables, bitmaps, frames and sequences.
|
/// A collection of color tables, bitmaps, frames and sequences.
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Collection
|
pub struct Collection {
|
||||||
{
|
|
||||||
/// The type of collection this is.
|
/// The type of collection this is.
|
||||||
pub ctyp: CollectionType,
|
pub ctyp: CollectionType,
|
||||||
|
|
||||||
|
@ -57,8 +56,7 @@ pub struct Collection
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// The type of a collection.
|
/// The type of a collection.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum CollectionType: u16
|
pub enum CollectionType: u16 {
|
||||||
{
|
|
||||||
Unused = 0,
|
Unused = 0,
|
||||||
Wall = 1,
|
Wall = 1,
|
||||||
Object = 2,
|
Object = 2,
|
||||||
|
|
|
@ -26,8 +26,7 @@ pub fn read(b: &[u8]) -> ResultS<Frame>
|
||||||
/// A frame, also known as a low level shape.
|
/// A frame, also known as a low level shape.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Frame
|
pub struct Frame {
|
||||||
{
|
|
||||||
/// The flags for this frame.
|
/// The flags for this frame.
|
||||||
pub flags: FrameFlags,
|
pub flags: FrameFlags,
|
||||||
|
|
||||||
|
@ -59,8 +58,7 @@ pub struct Frame
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `Frame`.
|
/// Flags for `Frame`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct FrameFlags: u16
|
pub struct FrameFlags: u16 {
|
||||||
{
|
|
||||||
/// The player's torso will obscure the player's legs.
|
/// The player's torso will obscure the player's legs.
|
||||||
const OBSCURE = 1 << 13;
|
const OBSCURE = 1 << 13;
|
||||||
/// The bitmap will be flipped on the vertical axis.
|
/// The bitmap will be flipped on the vertical axis.
|
||||||
|
|
|
@ -32,8 +32,7 @@ pub fn read(b: &[u8]) -> ResultS<Sequence>
|
||||||
/// A sequence, also known as a high level shape.
|
/// A sequence, also known as a high level shape.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Sequence
|
pub struct Sequence {
|
||||||
{
|
|
||||||
/// The display name for this sequence.
|
/// The display name for this sequence.
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
|
@ -71,8 +70,7 @@ pub struct Sequence
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// The type of or number of views for a sequence.
|
/// The type of or number of views for a sequence.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum ViewType: u16
|
pub enum ViewType: u16 {
|
||||||
{
|
|
||||||
Anim = 1,
|
Anim = 1,
|
||||||
Anim8from2 = 2,
|
Anim8from2 = 2,
|
||||||
Anim4from3 = 3,
|
Anim4from3 = 3,
|
||||||
|
|
|
@ -43,8 +43,7 @@ pub fn read(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
|
||||||
|
|
||||||
/// A sound definition containing one, many or no sounds.
|
/// A sound definition containing one, many or no sounds.
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct SoundDef
|
pub struct SoundDef {
|
||||||
{
|
|
||||||
/// The volume type for this sound.
|
/// The volume type for this sound.
|
||||||
pub volume: Volume,
|
pub volume: Volume,
|
||||||
|
|
||||||
|
@ -67,8 +66,7 @@ pub struct SoundDef
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Flags for `SoundDef`.
|
/// Flags for `SoundDef`.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub struct SoundFlags: u16
|
pub struct SoundFlags: u16 {
|
||||||
{
|
|
||||||
/// The sound will not restart when trying to play over itself.
|
/// The sound will not restart when trying to play over itself.
|
||||||
const NO_RESTART = 1;
|
const NO_RESTART = 1;
|
||||||
/// The sound will not switch channels when trying to play over itself.
|
/// The sound will not switch channels when trying to play over itself.
|
||||||
|
@ -89,8 +87,7 @@ bitflags! {
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// The type of volume this sound has.
|
/// The type of volume this sound has.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum Volume: u16
|
pub enum Volume: u16 {
|
||||||
{
|
|
||||||
Quiet = 0,
|
Quiet = 0,
|
||||||
Normal = 1,
|
Normal = 1,
|
||||||
Loud = 2,
|
Loud = 2,
|
||||||
|
|
|
@ -86,8 +86,7 @@ impl Sound for Sound16
|
||||||
/// A 16-bit PCM stream.
|
/// A 16-bit PCM stream.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Sound16
|
pub struct Sound16 {
|
||||||
{
|
|
||||||
rate: u16,
|
rate: u16,
|
||||||
lp_beg: usize,
|
lp_beg: usize,
|
||||||
lp_end: usize,
|
lp_end: usize,
|
||||||
|
|
|
@ -8,8 +8,7 @@ impl Default for TransferMode
|
||||||
c_enum! {
|
c_enum! {
|
||||||
/// A rendering style for many things.
|
/// A rendering style for many things.
|
||||||
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
|
||||||
pub enum TransferMode: u16
|
pub enum TransferMode: u16 {
|
||||||
{
|
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
FadeBlack = 1,
|
FadeBlack = 1,
|
||||||
Invisibility = 2,
|
Invisibility = 2,
|
||||||
|
@ -32,6 +31,7 @@ c_enum! {
|
||||||
Wander = 19,
|
Wander = 19,
|
||||||
Wander2 = 20,
|
Wander2 = 20,
|
||||||
BigSky = 21,
|
BigSky = 21,
|
||||||
|
None = 0xFFFF,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror")
|
||||||
|
|
||||||
find_package(
|
find_package(
|
||||||
Qt5 5.6.0
|
Qt5 5.6.0
|
||||||
|
@ -22,11 +23,14 @@ add_library(
|
||||||
SHARED
|
SHARED
|
||||||
$ENV{OUT_DIR}/bindings.cc
|
$ENV{OUT_DIR}/bindings.cc
|
||||||
$ENV{OUT_DIR}/bindings.h
|
$ENV{OUT_DIR}/bindings.h
|
||||||
|
cc_headers/mapmodel.h
|
||||||
cc_headers/mapprops.h
|
cc_headers/mapprops.h
|
||||||
cc_headers/menu.h
|
cc_headers/menu.h
|
||||||
cc_headers/project.h
|
cc_headers/project.h
|
||||||
cc_headers/tycho.h
|
cc_headers/tycho.h
|
||||||
|
cc_source/cc.cc
|
||||||
cc_source/main.cc
|
cc_source/main.cc
|
||||||
|
cc_source/mapmodel.cc
|
||||||
cc_source/mapprops.cc
|
cc_source/mapprops.cc
|
||||||
cc_source/menu.cc
|
cc_source/menu.cc
|
||||||
cc_source/project.cc
|
cc_source/project.cc
|
||||||
|
@ -60,6 +64,14 @@ target_link_libraries(
|
||||||
Qt5::Widgets
|
Qt5::Widgets
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(
|
||||||
|
maraiah-tycho-hermes
|
||||||
|
PUBLIC
|
||||||
|
-DQT_DEPRECATED_WARNINGS
|
||||||
|
-DQT_STRICT_ITERATORS
|
||||||
|
-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT
|
||||||
|
)
|
||||||
|
|
||||||
install(TARGETS maraiah-tycho-hermes)
|
install(TARGETS maraiah-tycho-hermes)
|
||||||
|
|
||||||
## EOF
|
## EOF
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
"implementationModule": "gui"
|
"implementationModule": "gui"
|
||||||
},
|
},
|
||||||
"objects": {
|
"objects": {
|
||||||
"MapModel": {
|
"AbstractMapModel": {
|
||||||
"type": "Tree",
|
"type": "List",
|
||||||
"functions": {
|
"functions": {
|
||||||
"open": {
|
"open": {
|
||||||
"return": "bool",
|
"return": "bool",
|
||||||
|
@ -32,18 +32,22 @@
|
||||||
"isDirty": {
|
"isDirty": {
|
||||||
"return": "bool",
|
"return": "bool",
|
||||||
"mut": false
|
"mut": false
|
||||||
|
},
|
||||||
|
"propIcon": {
|
||||||
|
"return": "QString",
|
||||||
|
"mut": false,
|
||||||
|
"arguments": [{
|
||||||
|
"name": "index",
|
||||||
|
"type": "quint16"
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
},
|
},
|
||||||
"itemProperties": {
|
"itemProperties": {
|
||||||
"rowName": {
|
"propIndex": {
|
||||||
"type": "quint64",
|
"type": "quint64",
|
||||||
"roles": [["display"]]
|
"roles": [["display"]]
|
||||||
},
|
|
||||||
"someNumber": {
|
|
||||||
"type": "quint64",
|
|
||||||
"roles": [[], ["display"]]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "bindings.h"
|
||||||
|
|
||||||
|
class MapModel : public AbstractMapModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MapModel(QObject *parent = nullptr);
|
||||||
|
~MapModel();
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole)
|
||||||
|
const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// EOF
|
|
@ -19,6 +19,7 @@ public slots:
|
||||||
void mapNew();
|
void mapNew();
|
||||||
void mapOpen();
|
void mapOpen();
|
||||||
void openAbout();
|
void openAbout();
|
||||||
|
void openAboutQt();
|
||||||
void openMapProperties();
|
void openMapProperties();
|
||||||
void updateActions();
|
void updateActions();
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "../ui/ui_project.h"
|
#include "../ui/ui_project.h"
|
||||||
|
|
||||||
|
class MapModel;
|
||||||
|
|
||||||
class ProjectModel
|
class ProjectModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include "tycho.h"
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void critical_msg(char const *title, char const *msg) {
|
||||||
|
QMessageBox::critical(nullptr, QObject::tr(title), QObject::tr(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
|
@ -0,0 +1,28 @@
|
||||||
|
#include "tycho.h"
|
||||||
|
#include "mapmodel.h"
|
||||||
|
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
|
MapModel::MapModel(QObject *parent) :
|
||||||
|
AbstractMapModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MapModel::~MapModel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant MapModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
switch(role) {
|
||||||
|
case Qt::DecorationRole: {
|
||||||
|
auto name = propIcon(index.row());
|
||||||
|
auto icon = name.front() == ':' ? QIcon(name) : QIcon::fromTheme(name);
|
||||||
|
return QVariant::fromValue(icon);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return AbstractMapModel::data(index, role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
|
@ -2,12 +2,14 @@
|
||||||
#include "mapprops.h"
|
#include "mapprops.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
#include "mapmodel.h"
|
||||||
#include "../ui/ui_about.h"
|
#include "../ui/ui_about.h"
|
||||||
#include "../ui/ui_license.h"
|
#include "../ui/ui_license.h"
|
||||||
|
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMdiSubWindow>
|
#include <QMdiSubWindow>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
Menu::Menu(QWidget *parent) :
|
Menu::Menu(QWidget *parent) :
|
||||||
|
@ -44,12 +46,17 @@ void Menu::mapOpen()
|
||||||
this,
|
this,
|
||||||
tr("Open Map File"),
|
tr("Open Map File"),
|
||||||
QString(),
|
QString(),
|
||||||
tr("Marathon Map files (*.scen *.sceA Map)"));
|
tr("Marathon Map files (*.scen *.sceA Map);;"
|
||||||
|
"Marathon Physics files (*.phys *.phyA Physics);;"
|
||||||
|
"Aleph One Image files (*.imgA);;"
|
||||||
|
"All files (*)"));
|
||||||
|
|
||||||
QScopedPointer proj{new Project(new MapModel)};
|
if(!fname.isEmpty()) {
|
||||||
|
QScopedPointer proj{new Project(new MapModel)};
|
||||||
|
|
||||||
if(proj->model.open(fname)) {
|
if(proj->model.open(fname)) {
|
||||||
addProject(proj.take());
|
addProject(proj.take());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +84,11 @@ void Menu::openAbout()
|
||||||
dlg.exec();
|
dlg.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::openAboutQt()
|
||||||
|
{
|
||||||
|
QMessageBox::aboutQt(this);
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::openLicense(QWidget *parent)
|
void Menu::openLicense(QWidget *parent)
|
||||||
{
|
{
|
||||||
QDialog dlg{parent};
|
QDialog dlg{parent};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "tycho.h"
|
#include "tycho.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
#include "mapmodel.h"
|
||||||
|
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
@ -22,6 +23,7 @@ ProjectModel::~ProjectModel()
|
||||||
{
|
{
|
||||||
switch(modelType) {
|
switch(modelType) {
|
||||||
case Map: delete modelMap; break;
|
case Map: delete modelMap; break;
|
||||||
|
case Invalid: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +36,8 @@ QAbstractItemModel *ProjectModel::getAbstract() const
|
||||||
{
|
{
|
||||||
switch(modelType) {
|
switch(modelType) {
|
||||||
case Map: return modelMap;
|
case Map: return modelMap;
|
||||||
|
case Invalid: Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
Q_UNREACHABLE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapModel *ProjectModel::getMap() const
|
MapModel *ProjectModel::getMap() const
|
||||||
|
@ -47,6 +49,7 @@ bool ProjectModel::isDirty() const
|
||||||
{
|
{
|
||||||
switch(modelType) {
|
switch(modelType) {
|
||||||
case Map: return modelMap->isDirty();
|
case Map: return modelMap->isDirty();
|
||||||
|
case Invalid: Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -55,6 +58,7 @@ bool ProjectModel::open(QString const &path)
|
||||||
{
|
{
|
||||||
switch(modelType) {
|
switch(modelType) {
|
||||||
case Map: return modelMap->open(path);
|
case Map: return modelMap->open(path);
|
||||||
|
case Invalid: Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -63,6 +67,7 @@ bool ProjectModel::saveAs(QString const &path) const
|
||||||
{
|
{
|
||||||
switch(modelType) {
|
switch(modelType) {
|
||||||
case Map: return modelMap->saveAs(path);
|
case Map: return modelMap->saveAs(path);
|
||||||
|
case Invalid: Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -71,6 +76,7 @@ bool ProjectModel::save() const
|
||||||
{
|
{
|
||||||
switch(modelType) {
|
switch(modelType) {
|
||||||
case Map: return modelMap->save();
|
case Map: return modelMap->save();
|
||||||
|
case Invalid: Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -86,7 +92,7 @@ Project::Project(ProjectModel &&_model, QWidget *parent) :
|
||||||
setWidget(widget);
|
setWidget(widget);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
treeView->setModel(model.getAbstract());
|
listView->setModel(model.getAbstract());
|
||||||
|
|
||||||
dbgPrintFunc();
|
dbgPrintFunc();
|
||||||
}
|
}
|
||||||
|
@ -117,8 +123,7 @@ void Project::closeEvent(QCloseEvent *event)
|
||||||
event->ignore();
|
event->ignore();
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
assert(true);
|
Q_UNREACHABLE();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
//! C++ functions.
|
||||||
|
|
||||||
|
mod ffi {
|
||||||
|
extern "C" {
|
||||||
|
pub fn critical_msg(title: maraiah::ffi::NT, msg: maraiah::ffi::NT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn critical_msg<T, U>(title: T, msg: U)
|
||||||
|
where T: ToString,
|
||||||
|
U: ToString
|
||||||
|
{
|
||||||
|
let title = std::ffi::CString::new(title.to_string()).unwrap();
|
||||||
|
let msg = std::ffi::CString::new(msg.to_string()).unwrap();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
ffi::critical_msg(title.as_ptr(), msg.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
|
@ -1,8 +1,8 @@
|
||||||
//! GUI implementation.
|
//! GUI implementation.
|
||||||
|
|
||||||
mod ffi;
|
|
||||||
mod map;
|
mod map;
|
||||||
|
mod qobj;
|
||||||
|
|
||||||
pub use self::map::MapModel;
|
pub use self::map::AbstractMapModel;
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -1,69 +1,63 @@
|
||||||
//! Map model.
|
//! Map model.
|
||||||
|
|
||||||
use super::ffi::*;
|
use super::qobj::*;
|
||||||
use maraiah::map;
|
use maraiah::{backtrace, err::*, map::{self, data::*}};
|
||||||
use memmap::Mmap;
|
use crate::cc;
|
||||||
|
|
||||||
fn open_f(path: String) -> ResultS<map::Map>
|
impl AbstractMapModel
|
||||||
{
|
{
|
||||||
let fp = std::fs::File::open(path)?;
|
pub fn open_map(path: String) -> ResultS<EntryDataMap>
|
||||||
let mm = unsafe { Mmap::map(&fp) }?;
|
{
|
||||||
|
let mut fp = maraiah::file::open_mac(path)?;
|
||||||
|
|
||||||
map::read(&mm)
|
let map = map::head::read(&mut fp)?;
|
||||||
|
let ent = map::entr::read_all(&map)?;
|
||||||
|
|
||||||
|
map::data::read_all(map.head(), &ent)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, index: usize) -> (&u16, &EntryData)
|
||||||
|
{
|
||||||
|
self.map.iter().nth(index).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
pub fn get_mut(&mut self, index: usize) -> (&u16, &mut EntryData)
|
||||||
|
{
|
||||||
|
self.map.iter_mut().nth(index).unwrap()
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MapModelTrait for MapModel
|
impl AbstractMapModelTrait for AbstractMapModel
|
||||||
{
|
{
|
||||||
/// Returns a new `MapModel` instance.
|
/// Returns a new `AbstractMapModel` instance.
|
||||||
fn new(emit: MapModelEmitter, model: MapModelTree) -> Self
|
fn new(emit: AbstractMapModelEmitter, _: AbstractMapModelList) -> Self
|
||||||
{
|
{
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
eprintln!("new MapModel");
|
eprintln!("new AbstractMapModel");
|
||||||
}
|
}
|
||||||
|
|
||||||
Self { emit,
|
Self{emit, map: EntryDataMap::default()}
|
||||||
model,
|
|
||||||
map: map::Map::default() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the emitter of `self`.
|
/// Returns the emitter of `self`.
|
||||||
fn emit(&mut self) -> &mut MapModelEmitter { &mut self.emit }
|
fn emit(&mut self) -> &mut AbstractMapModelEmitter {&mut self.emit}
|
||||||
|
|
||||||
/// Checks if `row` exists in the leaf `index`.
|
fn row_count(&self) -> usize {self.map.len()}
|
||||||
fn check_row(&self, index: usize, _row: usize) -> Option<usize> { None }
|
|
||||||
|
|
||||||
/// Returns the row `index` is in.
|
fn prop_index(&self, index: usize) -> u64 {(*self.get(index).0).into()}
|
||||||
fn row(&self, index: usize) -> usize { index }
|
|
||||||
|
|
||||||
/// Returns the number of rows in `index`.
|
fn prop_icon(&self, index: u16) -> String
|
||||||
fn row_count(&self, index: Option<usize>) -> usize
|
|
||||||
{
|
{
|
||||||
match index {
|
match self.get(index.into()).1.get_type() {
|
||||||
Some(_) => 0,
|
EntryType::Image => "image-x-generic".to_string(),
|
||||||
None => 7,
|
EntryType::Map => ":/tycho/color/map.png".to_string(),
|
||||||
|
EntryType::Other => "image-missing".to_string(),
|
||||||
|
EntryType::Physics => "applications-system".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the leaf index of `row` in the leaf `index`.
|
|
||||||
fn index(&self, index: Option<usize>, row: usize) -> usize
|
|
||||||
{
|
|
||||||
match index {
|
|
||||||
Some(_) => unreachable!(),
|
|
||||||
None => row,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the parent index of the leaf `index`, if any.
|
|
||||||
fn parent(&self, _index: usize) -> Option<usize>
|
|
||||||
{
|
|
||||||
// no parents!
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn row_name(&self, row: usize) -> u64 { row as u64 + 1 }
|
|
||||||
|
|
||||||
fn some_number(&self, row: usize) -> u64 { 69420 }
|
|
||||||
|
|
||||||
/// Opens the map file at `path`.
|
/// Opens the map file at `path`.
|
||||||
fn open(&mut self, path: String) -> bool
|
fn open(&mut self, path: String) -> bool
|
||||||
{
|
{
|
||||||
|
@ -71,11 +65,16 @@ impl MapModelTrait for MapModel
|
||||||
eprintln!("opening project: {}", &path);
|
eprintln!("opening project: {}", &path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(map) = open_f(&mm) {
|
match Self::open_map(path) {
|
||||||
self.map = map;
|
Ok(map) => {
|
||||||
true
|
self.map = map;
|
||||||
} else {
|
true
|
||||||
false
|
}
|
||||||
|
Err(e) => {
|
||||||
|
backtrace!(e);
|
||||||
|
cc::critical_msg("Error opening map", e);
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,24 +99,22 @@ impl MapModelTrait for MapModel
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the file has been modified from its original state.
|
/// Returns `true` if the file has been modified from its original state.
|
||||||
fn is_dirty(&self) -> bool { false }
|
fn is_dirty(&self) -> bool {false}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for MapModel
|
impl Drop for AbstractMapModel
|
||||||
{
|
{
|
||||||
fn drop(&mut self)
|
fn drop(&mut self)
|
||||||
{
|
{
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
eprintln!("drop MapModel");
|
eprintln!("drop AbstractMapModel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MapModel
|
pub struct AbstractMapModel {
|
||||||
{
|
emit: AbstractMapModelEmitter,
|
||||||
emit: MapModelEmitter,
|
map: EntryDataMap,
|
||||||
model: MapModelTree,
|
|
||||||
map: map::Map,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use maraiah::{err::*, ffi};
|
use maraiah::{err::*, ffi};
|
||||||
|
|
||||||
|
mod cc;
|
||||||
mod gui;
|
mod gui;
|
||||||
mod meta;
|
mod meta;
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,12 @@ macro_rules! meta_str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_str!(
|
meta_str! {
|
||||||
tychoAuthors = meta::ffi::AUTHORS_C;
|
tychoAuthors = meta::ffi::authors();
|
||||||
tychoHomepage = meta::ffi::HOMEPAGE_C;
|
tychoHomepage = meta::ffi::homepage();
|
||||||
tychoLicenseText = meta::ffi::LICENSE_TEXT_C;
|
tychoLicenseText = meta::ffi::license_text();
|
||||||
tychoRepository = meta::ffi::REPOSITORY_C;
|
tychoRepository = meta::ffi::repository();
|
||||||
tychoVersion = meta::ffi::VERSION_C;
|
tychoVersion = meta::ffi::version();
|
||||||
);
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
<string>&Help</string>
|
<string>&Help</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionAbout"/>
|
<addaction name="actionAbout"/>
|
||||||
|
<addaction name="actionAboutQt"/>
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
<addaction name="menuEdit"/>
|
<addaction name="menuEdit"/>
|
||||||
|
@ -135,12 +136,21 @@
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="window-close"/>
|
<iconset theme="window-close">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Close</string>
|
<string>&Close</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionAboutQt">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="help-about"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>About Qt</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources>
|
<resources>
|
||||||
|
@ -259,6 +269,22 @@
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>actionAboutQt</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>Menu</receiver>
|
||||||
|
<slot>openAboutQt()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
<slots>
|
<slots>
|
||||||
<slot>openMapProperties()</slot>
|
<slot>openMapProperties()</slot>
|
||||||
|
@ -266,5 +292,6 @@
|
||||||
<slot>mapOpen()</slot>
|
<slot>mapOpen()</slot>
|
||||||
<slot>openAbout()</slot>
|
<slot>openAbout()</slot>
|
||||||
<slot>updateActions()</slot>
|
<slot>updateActions()</slot>
|
||||||
|
<slot>openAboutQt()</slot>
|
||||||
</slots>
|
</slots>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeView" name="treeView">
|
<widget class="QListView" name="listView">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -31,6 +31,12 @@
|
||||||
<property name="horizontalScrollBarPolicy">
|
<property name="horizontalScrollBarPolicy">
|
||||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="viewMode">
|
||||||
|
<enum>QListView::IconMode</enum>
|
||||||
|
</property>
|
||||||
|
<property name="uniformItemSizes">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
Loading…
Reference in New Issue