Compare commits

...

16 Commits

68 changed files with 474 additions and 308 deletions

View File

@ -2414,8 +2414,9 @@ this actually hurts my head.
| `BecomeItem` | `16` |
| `Bloody` | `17` |
| `WanderHorz` | `18` |
| `UseLowGrav` | `19` |
| `PassMedia` | `20` |
| `WanderVert` | `19` |
| `UseLowGrav` | `20` |
| `PassMedia` | `21` |
### Monster Flags ###

View File

@ -235,7 +235,8 @@ macro_rules! read_data {
/// # Errors
///
/// 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 {
Err(err_msg("not enough data"))

View File

@ -16,8 +16,7 @@
/// use std::convert::TryFrom;
///
/// c_enum! {
/// enum MyEnum: u16
/// {
/// enum MyEnum: u16 {
/// Zero = 0,
/// One = 1,
/// Two = 2
@ -44,8 +43,7 @@ macro_rules! c_enum
$(#[$outer])*
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[repr($ti)]
$vi enum $t
{
$vi enum $t {
$($(#[$vouter])* $en = $va,)+
}
@ -59,7 +57,7 @@ macro_rules! c_enum
{
match n {
$($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;
c_enum! {
enum TestEnum: u16
{
enum TestEnum: u16 {
Zero = 0,
One = 1,
Two = 2,

View File

@ -413,12 +413,11 @@ impl HuffmanTable
code <<= 1;
}
Err(repr_error(code))
Err(ReprError::new("DEFLATE code", code).into())
}
}
struct HuffmanTable
{
struct HuffmanTable {
nums: [u16; 16],
syms: Vec<u16>,
}

View File

@ -15,9 +15,13 @@ macro_rules! ok {
macro_rules! flag_ok {
($t:ident$(::$tc:ident)*, $v:expr) => {
match $t$(::$tc)*::from_bits($v) {
Some(v) => Ok(v),
None => Err($crate::err::err_msg(concat!("bad ", stringify!($t)))),
{
let v = $v;
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.
///
/// # Examples
@ -40,33 +53,22 @@ macro_rules! bail {
/// ```
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
{
/// Creates a new `ReprError`.
/// Returns an `Error` with a message for representation errata.
///
/// # Examples
///
/// ```
/// use maraiah::err::ReprError;
/// use maraiah::err::repr_error;
///
/// let err = ReprError::new(7);
///
/// assert_eq!(format!("{}", err), "representation error (got 7)");
/// assert_eq!(format!("{}", repr_error("TypeName", 77)),
/// "bad TypeName (77)");
/// ```
#[inline]
pub fn new<T: Into<i64>>(n: T) -> Self {Self(n.into())}
pub fn new<T: Into<i64>>(t: &'static str, n: T) -> Self
{
Self(t, n.into())
}
}
impl Fail for ReprError {}
@ -76,7 +78,7 @@ impl fmt::Display for ReprError
{
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.
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct ReprError(i64);
pub struct ReprError(&'static str, i64);
#[derive(Debug)]
struct ErrMsg(&'static str);

View File

@ -85,8 +85,7 @@ impl Default for CStringVec
/// An owned null-terminated string vector.
#[derive(Debug)]
pub struct CStringVec
{
pub struct CStringVec {
sv: Vec<CString>,
cv: Vec<NT>,
}

View File

@ -15,7 +15,7 @@ pub fn validate_folder_path(p: &str) -> ResultS<()>
}
/// 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)?;

View File

@ -236,8 +236,7 @@ pub struct Color8(u8, u8, u8);
/// An RGB16 image.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Image16
{
pub struct Image16 {
w: usize,
h: usize,
@ -248,8 +247,7 @@ pub struct Image16
/// An RGB8 image.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Image8
{
pub struct Image8 {
w: usize,
h: usize,

View File

@ -54,8 +54,7 @@ pub fn read<'a>(b: &'a [u8],
Ok((&b[p..], Header{pitch, pack_t, depth, clut, rle}))
}
pub struct Header
{
pub struct Header {
pub pitch: usize,
pub pack_t: PackType,
pub depth: Depth,
@ -64,8 +63,7 @@ pub struct Header
}
c_enum! {
pub enum Depth: u16
{
pub enum Depth: u16 {
_1 = 1,
_2 = 2,
_4 = 4,
@ -76,8 +74,7 @@ c_enum! {
}
c_enum! {
pub enum PackType: u16
{
pub enum PackType: u16 {
Default = 0,
None = 1,
NoPad = 2,

View File

@ -1,6 +1,6 @@
//! 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`.
pub fn read(mut im: Image8,
@ -34,6 +34,8 @@ pub fn read(mut im: Image8,
d
};
check_data(&d, im.w())?;
p += pp;
for &idx in &d {

View File

@ -1,6 +1,6 @@
//! 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`.
pub fn read(mut im: Image8,
@ -26,6 +26,8 @@ pub fn read(mut im: Image8,
for _ in 0..im.h() {
let (d, pp) = rle::read::<u16>(&b[p..], hdr.pitch)?;
check_data(&d, im.w())?;
p += pp;
for &cr in &d {

View File

@ -1,6 +1,6 @@
//! 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`.
pub fn read(mut im: Image8,
@ -41,12 +41,14 @@ pub fn read(mut im: Image8,
for _ in 0..im.h() {
let (d, pp) = rle::read::<u8>(&b[p..], pitch)?;
check_data(&d, im.w() * 3)?;
p += pp;
for x in 0..im.w() {
let r = d[x + im.w()];
let g = d[x + im.w() * 2];
let b = d[x + im.w() * 3];
let r = d[x];
let g = d[x * 2];
let b = d[x * 3];
im.cr.push(Color8::new(r, g, b));
}
}

View File

@ -18,8 +18,7 @@ pub fn read(b: &[u8]) -> ResultS<(SoundAmbi, usize)>
/// An ambient sound definition.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SoundAmbi
{
pub struct SoundAmbi {
pub index: u16,
pub volume: u16,
}

View File

@ -24,8 +24,7 @@ pub fn read(b: &[u8]) -> ResultS<Attack>
/// The definition of a monster's attack.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Attack
{
pub struct Attack {
pub ptype: OptU16,
pub rep: u16,
pub error: Angle,

View File

@ -28,8 +28,7 @@ pub fn read(b: &[u8]) -> ResultS<(SoundRand, usize)>
/// A randomly played sound definition.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SoundRand
{
pub struct SoundRand {
pub flags: SoundRandFlags,
pub index: u16,
pub vol_nrm: u16,
@ -45,9 +44,9 @@ pub struct SoundRand
bitflags! {
/// Flags for `SoundRand`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct SoundRandFlags: u16
{
pub struct SoundRandFlags: u16 {
const NO_DIRECTION = 1;
const _2 = 2;
}
}

View File

@ -22,8 +22,7 @@ pub fn read(b: &[u8]) -> ResultS<Damage>
/// A damage definition.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Damage
{
pub struct Damage {
pub dtype: DamageType,
pub flags: DamageFlags,
pub dmg_base: u16,
@ -34,8 +33,7 @@ pub struct Damage
bitflags! {
/// The composite type of damage taken by something.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct DamageTypeFlags: u32
{
pub struct DamageTypeFlags: u32 {
const EXPLOSION = 1;
const ELECTRICAL_STAFF = 1 << 1;
const PROJECTILE = 1 << 2;
@ -66,8 +64,7 @@ bitflags! {
bitflags! {
/// Flags for `Damage`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct DamageFlags: u16
{
pub struct DamageFlags: u16 {
const ALIEN = 1;
}
}
@ -75,8 +72,7 @@ bitflags! {
c_enum! {
/// A named type of damage taken by something.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum DamageType: u16
{
pub enum DamageType: u16 {
Explosion = 0,
ElectricalStaff = 1,
Projectile = 2,

View File

@ -76,11 +76,92 @@ pub fn read_all(head: &head::Header,
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.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Default, Eq, PartialEq)]
pub struct EntryData
{
pub struct EntryData {
/** `EPNT` chunk data. */ pub epnt: Option<Vec<map::epnt::Endpoint>>,
/** `FXpx` chunk data. */ pub fxpx: Option<Vec<map::fxpx::Effect>>,
/** `LINS` chunk data. */ pub lins: Option<Vec<map::lins::Line>>,

View File

@ -8,18 +8,29 @@ use std::collections::BTreeMap;
pub fn read(map: &head::Map, i: usize) -> ResultS<(u16, Entry<'_>)>
{
let size = map.head().size_entry();
let b = map.dir();
let sta = size * i;
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 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 index = if map.head().old_wad() {i as u16} else {index};
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.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Entry<'a>
{
pub struct Entry<'a> {
/// The data in this `Entry`.
pub data: &'a [u8],

View File

@ -29,8 +29,7 @@ pub fn to_pnts(v: &[Endpoint]) -> Vec<pnts::Point>
/// A pre-processed point in world-space.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Endpoint
{
pub struct Endpoint {
pub flags: EndpointFlags,
pub hei_hi: Unit,
pub hei_lo: Unit,
@ -41,8 +40,7 @@ pub struct Endpoint
bitflags! {
/// Flags for `Endpoint`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct EndpointFlags: u16
{
pub struct EndpointFlags: u16 {
const SOLID = 1;
const SAME_HEIGHT = 1 << 1;
const TRANSPARENT = 1 << 2;

View File

@ -23,8 +23,7 @@ pub fn read(b: &[u8]) -> ResultS<(Effect, usize)>
/// An effect definition.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Effect
{
pub struct Effect {
pub collection: u16,
pub shape: u16,
pub pitch: Fixed,
@ -36,8 +35,7 @@ pub struct Effect
bitflags! {
/// Flags for an effect.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct EffectFlags: u16
{
pub struct EffectFlags: u16 {
const END_ON_LOOP = 1;
const END_ON_XFER_LOOP = 1 << 1;
const SOUND_ONLY = 1 << 2;

View File

@ -111,8 +111,7 @@ impl Map
/// A Map header.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Header
{
pub struct Header {
/// The original name of this file.
pub name: String,
@ -124,8 +123,7 @@ pub struct Header
/// A Map file.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Map
{
pub struct Map {
head: Header,
data: Vec<u8>,
dir_ofs: usize,
@ -135,8 +133,7 @@ pub struct Map
c_enum! {
/// The version of a Map file.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum Ver: u16
{
pub enum Ver: u16 {
Base = 0,
Dir = 1,
Over = 2,

View File

@ -24,8 +24,7 @@ pub fn read(b: &[u8]) -> ResultS<(Line, usize)>
/// A line segment.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Line
{
pub struct Line {
pub flags: LineFlags,
pub pnt_beg: u16,
pub pnt_end: u16,
@ -38,8 +37,7 @@ pub struct Line
bitflags! {
/// Flags for `Line`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct LineFlags: u16
{
pub struct LineFlags: u16 {
const TRANS_SIDE = 1 << 9;
const ELEV_VAR = 1 << 10;
const ELEVATION = 1 << 11;

View File

@ -73,8 +73,7 @@ pub fn read_old(b: &[u8]) -> ResultS<(Light, usize)>
/// A dynamic polygon light.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Light
{
pub struct Light {
pub ltype: LightType,
pub flags: LightFlags,
pub phase: i16,
@ -90,8 +89,7 @@ pub struct Light
bitflags! {
/// Flags for `Light`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct LightFlags: u16
{
pub struct LightFlags: u16 {
const INIT_ACTIVE = 1;
const SLAVE_VALUE = 1 << 1;
const STATELESS = 1 << 2;
@ -101,8 +99,7 @@ bitflags! {
c_enum! {
/// The type of a `Light`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum LightType: u16
{
pub enum LightType: u16 {
Normal = 0,
Strobe = 1,
Media = 2,

View File

@ -33,8 +33,7 @@ pub fn write(v: &LightFunc) -> Vec<u8>
/// A light function.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct LightFunc
{
pub struct LightFunc {
pub ftype: LightFuncType,
pub prd_nrm: u16,
pub prd_dta: u16,
@ -45,8 +44,7 @@ pub struct LightFunc
c_enum! {
/// The type of function for a `LightFunc`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum LightFuncType: u16
{
pub enum LightFuncType: u16 {
Constant = 0,
Linear = 1,
Smooth = 2,

View File

@ -13,7 +13,7 @@ pub fn read(b: &[u8]) -> ResultS<(Media, usize)>
read_data! {
endian: BIG, buf: b, size: 32, start: 0, data {
let mtype = u16[0] enum MediaType;
let flags = u16[2] flag MediaFlags;
let flags = u8[3] flag MediaFlags;
let control = u16[4];
let dir = Angle[6];
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.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Media
{
pub struct Media {
pub mtype: MediaType,
pub flags: MediaFlags,
pub control: u16,
@ -53,20 +52,19 @@ pub struct Media
c_enum! {
/// The liquid type of a `Media`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum MediaType: u16
{
pub enum MediaType: u16 {
Water = 0,
Lava = 1,
Goo = 2,
Sewage = 3,
Jjaro = 4,
}
}
bitflags! {
/// Flags for `Media`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct MediaFlags: u16
{
pub struct MediaFlags: u8 {
const OBSTRUCT = 1;
}
}

View File

@ -71,8 +71,7 @@ impl Default for Info
/// Static map information.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Info
{
pub struct Info {
pub texture_id: u16,
pub physics_id: u16,
pub skypict_id: u16,
@ -85,8 +84,7 @@ pub struct Info
bitflags! {
/// Static environment flags.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct EnvironmentFlags: u16
{
pub struct EnvironmentFlags: u16 {
const VACUUM = 1;
const MAGNETIC = 1 << 1;
const REBELLION = 1 << 2;
@ -104,8 +102,7 @@ bitflags! {
bitflags! {
/// Static entry point flags.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct EntryFlags: u32
{
pub struct EntryFlags: u32 {
const SOLO = 1;
const CO_OP = 1 << 1;
const CARNAGE = 1 << 2;
@ -120,8 +117,7 @@ bitflags! {
bitflags! {
/// Static mission flags.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct MissionFlags: u16
{
pub struct MissionFlags: u16 {
const EXTERMINATION = 1;
const EXPLORATION = 1 << 1;
const RETRIEVAL = 1 << 2;

View File

@ -86,8 +86,7 @@ pub fn read(b: &[u8]) -> ResultS<(Monster, usize)>
/// A monster definition.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Monster
{
pub struct Monster {
pub collection: u16,
pub vitality: u16,
pub dty_immune: damg::DamageTypeFlags,
@ -144,8 +143,7 @@ pub struct Monster
bitflags! {
/// Flags for a monster.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct MonsterFlags: u32
{
pub struct MonsterFlags: u32 {
const IGNORE_LOS = 1;
const FLYING = 1 << 1;
const ALIEN = 1 << 2;
@ -180,8 +178,7 @@ bitflags! {
bitflags! {
/// The composite type of a monster.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct MonsterClass: u32
{
pub struct MonsterClass: u32 {
const PLAYER = 1;
const CIVILIAN = 1 << 1;
const MADD = 1 << 2;

View File

@ -20,8 +20,7 @@ pub fn read(b: &[u8]) -> ResultS<(Note, usize)>
/// Overhead map annotations.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Note
{
pub struct Note {
pub pos: pnts::Point,
pub poly: u16,
pub text: String,

View File

@ -30,8 +30,7 @@ pub fn read(b: &[u8]) -> ResultS<(Object, usize)>
/// An object in the world.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Object
{
pub struct Object {
pub group: u16,
pub index: u16,
pub angle: Angle,
@ -46,8 +45,7 @@ pub struct Object
bitflags! {
/// Flags for `Object`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct ObjectFlags: u16
{
pub struct ObjectFlags: u16 {
const INVISIBLE = 1;
const CEILING = 1 << 1;
const BLIND = 1 << 2;

View File

@ -23,8 +23,7 @@ pub fn read(b: &[u8]) -> ResultS<(ObjectFreq, usize)>
/// The difficulty definition for various object types.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ObjectFreq
{
pub struct ObjectFreq {
pub flags: ObjectFreqFlags,
pub cnt_ini: u16,
pub cnt_min: u16,
@ -36,9 +35,12 @@ pub struct ObjectFreq
bitflags! {
/// Flags for `ObjectFreq`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct ObjectFreqFlags: u16
{
pub struct ObjectFreqFlags: u16 {
const RANDOM_LOCATION = 1;
const _3 = 1 << 3;
const _4 = 1 << 4;
const _5 = 1 << 5;
const _6 = 1 << 6;
}
}

View File

@ -25,8 +25,7 @@ pub fn read(b: &[u8]) -> ResultS<(Platform, usize)>
/// Extra information for polygons with platforms.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Platform
{
pub struct Platform {
pub ptype: u16,
pub speed: u16,
pub delay: u16,
@ -40,8 +39,7 @@ pub struct Platform
bitflags! {
/// Flags for `Platform`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct PlatformFlags: u32
{
pub struct PlatformFlags: u32 {
const INIT_ACTIVE = 1;
const INIT_EXTENDED = 1 << 1;
const STOP_AT_EACH_LEVEL = 1 << 2;

View File

@ -30,8 +30,7 @@ pub fn read(b: &[u8]) -> ResultS<(Point, usize)> {Ok((read_o(b)?, 4))}
/// A point in world-space.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub struct Point
{
pub struct Point {
pub x: Unit,
pub y: Unit,
}

View File

@ -94,7 +94,7 @@ impl PolygonType
21 => Ok(PolygonType::Glue),
22 => Ok(PolygonType::GlueTrigger(pdata)),
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),
14 => Ok(PolygonType::MustExplore),
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.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Polygon
{
pub struct Polygon {
pub ptype: PolygonType,
pub tex_flr: OptU16,
pub tex_cei: OptU16,
@ -154,8 +153,7 @@ pub struct Polygon
/// The action type of a `Polygon`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PolygonType
{
pub enum PolygonType {
Normal,
ImpassItem,
ImpassMons,
@ -185,8 +183,7 @@ pub enum PolygonType
bitflags! {
/// Flags for `Polygon`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct PolygonFlags: u16
{
pub struct PolygonFlags: u16 {
const DETACHED = 1 << 14;
}
}

View File

@ -38,8 +38,7 @@ pub fn read(b: &[u8]) -> ResultS<(Projectile, usize)>
/// A projectile definition.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Projectile
{
pub struct Projectile {
pub collection: OptU16,
pub shape: u16,
pub fxt_explode: OptU16,
@ -62,8 +61,7 @@ pub struct Projectile
bitflags! {
/// Flags for a projectile.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct ProjectileFlags: u32
{
pub struct ProjectileFlags: u32 {
const GUIDED = 1;
const STOP_ON_LOOP = 1 << 1;
const PERSISTENT = 1 << 2;
@ -83,8 +81,9 @@ bitflags! {
const BECOME_ITEM = 1 << 16;
const BLOODY = 1 << 17;
const WANDER_HORZ = 1 << 18;
const USE_LOW_GRAV = 1 << 19;
const PASS_MEDIA = 1 << 20;
const WANDER_VERT = 1 << 19;
const USE_LOW_GRAV = 1 << 20;
const PASS_MEDIA = 1 << 21;
}
}

View File

@ -45,8 +45,7 @@ pub fn read(b: &[u8]) -> ResultS<(Physics, usize)>
/// Static physics information.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Physics
{
pub struct Physics {
pub acc_ang: Fixed,
pub acc_cli: Fixed,
pub acc_grv: Fixed,

View File

@ -10,7 +10,7 @@ pub fn read(b: &[u8]) -> ResultS<(Side, usize)>
read_data! {
endian: BIG, buf: b, size: 64, start: 0, data {
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_sec = stex::read[10; 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.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Side
{
pub struct Side {
pub stype: SideType,
pub flags: SideFlags,
pub tex_pri: stex::SideTex,
@ -59,8 +58,7 @@ pub struct Side
bitflags! {
/// Flags for `Side`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct SideFlags: u16
{
pub struct SideFlags: u8 {
const STATUS = 1;
const PANEL = 1 << 1;
const REPAIR = 1 << 2;
@ -75,8 +73,7 @@ bitflags! {
c_enum! {
/// The texture type of a `Side`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum SideType: u16
{
pub enum SideType: u16 {
Full = 0,
High = 1,
Low = 2,

View File

@ -28,8 +28,7 @@ pub fn write(v: &SideTex) -> Vec<u8>
/// The texture of a side segment.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SideTex
{
pub struct SideTex {
pub offs: pnts::Point,
pub tex_id: OptU16,
}

View File

@ -46,8 +46,7 @@ pub fn read(b: &[u8]) -> ResultS<(Terminal, usize)>
/// A terminal definition, with collections of groups and faces.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Terminal
{
pub struct Terminal {
pub lines: u16,
pub groups: Vec<trmg::Group>,
pub faces: Vec<trmf::Face>,

View File

@ -36,8 +36,7 @@ pub fn read(b: &[u8]) -> ResultS<Trigger>
/// The definition of one of two triggers for a weapon.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Trigger
{
pub struct Trigger {
pub burst: u16,
pub dx: i16,
pub dz: i16,
@ -61,8 +60,7 @@ pub struct Trigger
c_enum! {
/// A bullet shell casing emitted by a weapon.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum CasingType: u16
{
pub enum CasingType: u16 {
Rifle = 0,
Pistol = 1,
PistolLeft = 2,

View File

@ -19,8 +19,7 @@ pub fn read(b: &[u8]) -> ResultS<(Face, usize)>
/// A text face.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Face
{
pub struct Face {
pub start: usize,
pub face: u16,
pub color: u16,

View File

@ -35,7 +35,7 @@ pub fn read(b: &[u8]) -> ResultS<(InterGroup, usize)>
14 => GroupType::Camera(pdata),
15 => GroupType::Static(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))
@ -48,8 +48,7 @@ impl Default for GroupType
/// Interim structure.
#[derive(Debug, Eq, PartialEq)]
pub struct InterGroup
{
pub struct InterGroup {
pub flags: GroupFlags,
pub ttype: GroupType,
pub lines: u16,
@ -60,8 +59,7 @@ pub struct InterGroup
/// A terminal command grouping.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Group
{
pub struct Group {
pub flags: GroupFlags,
pub ttype: GroupType,
pub lines: u16,
@ -71,8 +69,7 @@ pub struct Group
/// The command of a `Group`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum GroupType
{
pub enum GroupType {
Logon(u16),
Unfinished,
Success,
@ -95,8 +92,7 @@ pub enum GroupType
bitflags! {
/// Flags for `Group`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct GroupFlags: u16
{
pub struct GroupFlags: u16 {
/// Draws the picture on the right.
const DRAW_ON_RIGHT = 1;
/// Draws the picture in the center.

View File

@ -48,8 +48,7 @@ pub fn read(b: &[u8]) -> ResultS<(Weapon, usize)>
/// A weapon definition.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Weapon
{
pub struct Weapon {
pub amp_bob: Fixed,
pub amp_horz: Fixed,
pub collection: u16,
@ -80,8 +79,7 @@ pub struct Weapon
bitflags! {
/// Flags for a weapon.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct WeaponFlags: u16
{
pub struct WeaponFlags: u16 {
const AUTOMATIC = 1;
const REMOVE_AFTER_USE = 1 << 1;
const INSTANT_CASING = 1 << 2;
@ -99,8 +97,7 @@ bitflags! {
c_enum! {
/// The type of functionality a weapon provides.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum WeaponType: u16
{
pub enum WeaponType: u16 {
Melee = 0,
Normal = 1,
DualFunc = 2,

View File

@ -22,7 +22,7 @@ macro_rules! meta_str {
}
}
meta_str!(
meta_str! {
/// The authors of this crate, `:` separated.
authors = env!("CARGO_PKG_AUTHORS");
/// The description of this crate.
@ -45,6 +45,6 @@ meta_str!(
version_patch = env!("CARGO_PKG_VERSION_PATCH");
/// The pre-release version of this crate.
version_pre = env!("CARGO_PKG_VERSION_PRE");
);
}
// EOF

View File

@ -114,8 +114,7 @@ impl Image for ImageShp<'_, '_>
/// An unpacked Shape bitmap.
#[derive(Debug, Eq, PartialEq)]
pub struct Bitmap
{
pub struct Bitmap {
w: usize,
h: usize,
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
/// `Image` trait.
#[derive(Debug, Eq, PartialEq)]
pub struct ImageShp<'a, 'b>
{
pub struct ImageShp<'a, 'b> {
bmp: &'a Bitmap,
clut: &'b [clut::ColorShp],
}
bitflags! {
struct BmpFlags: u16
{
struct BmpFlags: u16 {
const TRANSPARENT = 1 << 14;
const COLUMN_MAJOR = 1 << 15;
}

View File

@ -93,8 +93,7 @@ impl Color for ColorShp
/// A color in a `Clut`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ColorShp
{
pub enum ColorShp {
/// A completely translucent color.
Translucent,

View File

@ -36,8 +36,7 @@ pub fn read(b: &[u8]) -> ResultS<Collection>
/// A collection of color tables, bitmaps, frames and sequences.
#[derive(Debug, Eq, PartialEq)]
pub struct Collection
{
pub struct Collection {
/// The type of collection this is.
pub ctyp: CollectionType,
@ -57,8 +56,7 @@ pub struct Collection
c_enum! {
/// The type of a collection.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum CollectionType: u16
{
pub enum CollectionType: u16 {
Unused = 0,
Wall = 1,
Object = 2,

View File

@ -26,8 +26,7 @@ pub fn read(b: &[u8]) -> ResultS<Frame>
/// A frame, also known as a low level shape.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Frame
{
pub struct Frame {
/// The flags for this frame.
pub flags: FrameFlags,
@ -59,8 +58,7 @@ pub struct Frame
bitflags! {
/// Flags for `Frame`.
#[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.
const OBSCURE = 1 << 13;
/// The bitmap will be flipped on the vertical axis.

View File

@ -32,8 +32,7 @@ pub fn read(b: &[u8]) -> ResultS<Sequence>
/// A sequence, also known as a high level shape.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Sequence
{
pub struct Sequence {
/// The display name for this sequence.
pub name: String,
@ -71,8 +70,7 @@ pub struct Sequence
c_enum! {
/// The type of or number of views for a sequence.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum ViewType: u16
{
pub enum ViewType: u16 {
Anim = 1,
Anim8from2 = 2,
Anim4from3 = 3,

View File

@ -43,8 +43,7 @@ pub fn read(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
/// A sound definition containing one, many or no sounds.
#[derive(Debug, Eq, PartialEq)]
pub struct SoundDef
{
pub struct SoundDef {
/// The volume type for this sound.
pub volume: Volume,
@ -67,8 +66,7 @@ pub struct SoundDef
bitflags! {
/// Flags for `SoundDef`.
#[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.
const NO_RESTART = 1;
/// The sound will not switch channels when trying to play over itself.
@ -89,8 +87,7 @@ bitflags! {
c_enum! {
/// The type of volume this sound has.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum Volume: u16
{
pub enum Volume: u16 {
Quiet = 0,
Normal = 1,
Loud = 2,

View File

@ -86,8 +86,7 @@ impl Sound for Sound16
/// A 16-bit PCM stream.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Sound16
{
pub struct Sound16 {
rate: u16,
lp_beg: usize,
lp_end: usize,

View File

@ -8,8 +8,7 @@ impl Default for TransferMode
c_enum! {
/// A rendering style for many things.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub enum TransferMode: u16
{
pub enum TransferMode: u16 {
Normal = 0,
FadeBlack = 1,
Invisibility = 2,
@ -32,6 +31,7 @@ c_enum! {
Wander = 19,
Wander2 = 20,
BigSky = 21,
None = 0xFFFF,
}
}

View File

@ -9,6 +9,7 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror")
find_package(
Qt5 5.6.0
@ -22,11 +23,14 @@ add_library(
SHARED
$ENV{OUT_DIR}/bindings.cc
$ENV{OUT_DIR}/bindings.h
cc_headers/mapmodel.h
cc_headers/mapprops.h
cc_headers/menu.h
cc_headers/project.h
cc_headers/tycho.h
cc_source/cc.cc
cc_source/main.cc
cc_source/mapmodel.cc
cc_source/mapprops.cc
cc_source/menu.cc
cc_source/project.cc
@ -60,6 +64,14 @@ target_link_libraries(
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)
## EOF

View File

@ -6,8 +6,8 @@
"implementationModule": "gui"
},
"objects": {
"MapModel": {
"type": "Tree",
"AbstractMapModel": {
"type": "List",
"functions": {
"open": {
"return": "bool",
@ -32,18 +32,22 @@
"isDirty": {
"return": "bool",
"mut": false
},
"propIcon": {
"return": "QString",
"mut": false,
"arguments": [{
"name": "index",
"type": "quint16"
}]
}
},
"properties": {
},
"itemProperties": {
"rowName": {
"propIndex": {
"type": "quint64",
"roles": [["display"]]
},
"someNumber": {
"type": "quint64",
"roles": [[], ["display"]]
}
}
}

View File

@ -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

View File

@ -19,6 +19,7 @@ public slots:
void mapNew();
void mapOpen();
void openAbout();
void openAboutQt();
void openMapProperties();
void updateActions();

View File

@ -4,6 +4,8 @@
#include "../ui/ui_project.h"
class MapModel;
class ProjectModel
{
public:

10
tycho/cc_source/cc.cc Normal file
View File

@ -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

View File

@ -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

View File

@ -2,12 +2,14 @@
#include "mapprops.h"
#include "menu.h"
#include "project.h"
#include "mapmodel.h"
#include "../ui/ui_about.h"
#include "../ui/ui_license.h"
#include <QCloseEvent>
#include <QFileDialog>
#include <QMdiSubWindow>
#include <QMessageBox>
#include <iostream>
Menu::Menu(QWidget *parent) :
@ -44,12 +46,17 @@ void Menu::mapOpen()
this,
tr("Open Map File"),
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)) {
addProject(proj.take());
if(proj->model.open(fname)) {
addProject(proj.take());
}
}
}
@ -77,6 +84,11 @@ void Menu::openAbout()
dlg.exec();
}
void Menu::openAboutQt()
{
QMessageBox::aboutQt(this);
}
void Menu::openLicense(QWidget *parent)
{
QDialog dlg{parent};

View File

@ -1,5 +1,6 @@
#include "tycho.h"
#include "project.h"
#include "mapmodel.h"
#include <QCloseEvent>
#include <QMessageBox>
@ -22,6 +23,7 @@ ProjectModel::~ProjectModel()
{
switch(modelType) {
case Map: delete modelMap; break;
case Invalid: break;
}
}
@ -34,8 +36,8 @@ QAbstractItemModel *ProjectModel::getAbstract() const
{
switch(modelType) {
case Map: return modelMap;
case Invalid: Q_UNREACHABLE();
}
Q_UNREACHABLE();
}
MapModel *ProjectModel::getMap() const
@ -47,6 +49,7 @@ bool ProjectModel::isDirty() const
{
switch(modelType) {
case Map: return modelMap->isDirty();
case Invalid: Q_UNREACHABLE();
}
Q_UNREACHABLE();
}
@ -55,6 +58,7 @@ bool ProjectModel::open(QString const &path)
{
switch(modelType) {
case Map: return modelMap->open(path);
case Invalid: Q_UNREACHABLE();
}
Q_UNREACHABLE();
}
@ -63,6 +67,7 @@ bool ProjectModel::saveAs(QString const &path) const
{
switch(modelType) {
case Map: return modelMap->saveAs(path);
case Invalid: Q_UNREACHABLE();
}
Q_UNREACHABLE();
}
@ -71,6 +76,7 @@ bool ProjectModel::save() const
{
switch(modelType) {
case Map: return modelMap->save();
case Invalid: Q_UNREACHABLE();
}
Q_UNREACHABLE();
}
@ -86,7 +92,7 @@ Project::Project(ProjectModel &&_model, QWidget *parent) :
setWidget(widget);
setAttribute(Qt::WA_DeleteOnClose);
treeView->setModel(model.getAbstract());
listView->setModel(model.getAbstract());
dbgPrintFunc();
}
@ -117,8 +123,7 @@ void Project::closeEvent(QCloseEvent *event)
event->ignore();
return;
default:
assert(true);
break;
Q_UNREACHABLE();
}
}

21
tycho/source/cc.rs Normal file
View File

@ -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

View File

@ -1,8 +1,8 @@
//! GUI implementation.
mod ffi;
mod map;
mod qobj;
pub use self::map::MapModel;
pub use self::map::AbstractMapModel;
// EOF

View File

@ -1,69 +1,63 @@
//! Map model.
use super::ffi::*;
use maraiah::map;
use memmap::Mmap;
use super::qobj::*;
use maraiah::{backtrace, err::*, map::{self, data::*}};
use crate::cc;
fn open_f(path: String) -> ResultS<map::Map>
impl AbstractMapModel
{
let fp = std::fs::File::open(path)?;
let mm = unsafe { Mmap::map(&fp) }?;
pub fn open_map(path: String) -> ResultS<EntryDataMap>
{
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.
fn new(emit: MapModelEmitter, model: MapModelTree) -> Self
/// Returns a new `AbstractMapModel` instance.
fn new(emit: AbstractMapModelEmitter, _: AbstractMapModelList) -> Self
{
if cfg!(debug_assertions) {
eprintln!("new MapModel");
eprintln!("new AbstractMapModel");
}
Self { emit,
model,
map: map::Map::default() }
Self{emit, map: EntryDataMap::default()}
}
/// 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 check_row(&self, index: usize, _row: usize) -> Option<usize> { None }
fn row_count(&self) -> usize {self.map.len()}
/// Returns the row `index` is in.
fn row(&self, index: usize) -> usize { index }
fn prop_index(&self, index: usize) -> u64 {(*self.get(index).0).into()}
/// Returns the number of rows in `index`.
fn row_count(&self, index: Option<usize>) -> usize
fn prop_icon(&self, index: u16) -> String
{
match index {
Some(_) => 0,
None => 7,
match self.get(index.into()).1.get_type() {
EntryType::Image => "image-x-generic".to_string(),
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`.
fn open(&mut self, path: String) -> bool
{
@ -71,11 +65,16 @@ impl MapModelTrait for MapModel
eprintln!("opening project: {}", &path);
}
if let Ok(map) = open_f(&mm) {
self.map = map;
true
} else {
false
match Self::open_map(path) {
Ok(map) => {
self.map = map;
true
}
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.
fn is_dirty(&self) -> bool { false }
fn is_dirty(&self) -> bool {false}
}
impl Drop for MapModel
impl Drop for AbstractMapModel
{
fn drop(&mut self)
{
if cfg!(debug_assertions) {
eprintln!("drop MapModel");
eprintln!("drop AbstractMapModel");
}
}
}
pub struct MapModel
{
emit: MapModelEmitter,
model: MapModelTree,
map: map::Map,
pub struct AbstractMapModel {
emit: AbstractMapModelEmitter,
map: EntryDataMap,
}
// EOF

View File

@ -1,5 +1,6 @@
use maraiah::{err::*, ffi};
mod cc;
mod gui;
mod meta;

View File

@ -14,12 +14,12 @@ macro_rules! meta_str {
}
}
meta_str!(
tychoAuthors = meta::ffi::AUTHORS_C;
tychoHomepage = meta::ffi::HOMEPAGE_C;
tychoLicenseText = meta::ffi::LICENSE_TEXT_C;
tychoRepository = meta::ffi::REPOSITORY_C;
tychoVersion = meta::ffi::VERSION_C;
);
meta_str! {
tychoAuthors = meta::ffi::authors();
tychoHomepage = meta::ffi::homepage();
tychoLicenseText = meta::ffi::license_text();
tychoRepository = meta::ffi::repository();
tychoVersion = meta::ffi::version();
}
// EOF

View File

@ -76,6 +76,7 @@
<string>&amp;Help</string>
</property>
<addaction name="actionAbout"/>
<addaction name="actionAboutQt"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
@ -135,12 +136,21 @@
<bool>false</bool>
</property>
<property name="icon">
<iconset theme="window-close"/>
<iconset theme="window-close">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Close</string>
</property>
</action>
<action name="actionAboutQt">
<property name="icon">
<iconset theme="help-about"/>
</property>
<property name="text">
<string>About Qt</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
@ -259,6 +269,22 @@
</hint>
</hints>
</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>
<slots>
<slot>openMapProperties()</slot>
@ -266,5 +292,6 @@
<slot>mapOpen()</slot>
<slot>openAbout()</slot>
<slot>updateActions()</slot>
<slot>openAboutQt()</slot>
</slots>
</ui>

View File

@ -15,7 +15,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeView" name="treeView">
<widget class="QListView" name="listView">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -31,6 +31,12 @@
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget>
</item>
</layout>