Compare commits
3 Commits
c2339138a8
...
92aea23e04
Author | SHA1 | Date |
---|---|---|
an | 92aea23e04 | |
an | 17b5456aca | |
an | e64f652281 |
|
@ -9,13 +9,7 @@ is derived from the Japanese transliteration of "Mariah," and is pronounced
|
||||||
The basis of this project is the Rust project `maraiah` which provides functions
|
The basis of this project is the Rust project `maraiah` which provides functions
|
||||||
and structures to build applications which work with Marathon's data.
|
and structures to build applications which work with Marathon's data.
|
||||||
|
|
||||||
Maraiah comes with a set of almost fully portable tools written in Rust,
|
See [the crate documentation](source/lib.rs) for more information.
|
||||||
including binary file reading, safe C-like `enum` reading, improved error
|
|
||||||
handling, FFI tools, fixed point numbers, and image and sound structures.
|
|
||||||
|
|
||||||
Maraiah also comes with APIs for working with various data formats, primarily
|
|
||||||
Marathon's. It also handles Macintosh PICT files, Portable PixMap, TARGA, RIFF
|
|
||||||
WAVE, and more.
|
|
||||||
|
|
||||||
## `maraiah-leela`
|
## `maraiah-leela`
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,9 @@ macro_rules! rd_impl {
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[macro_use] extern crate maraiah;
|
/// # #[macro_use] extern crate maraiah;
|
||||||
/// # use maraiah::err::*;
|
/// # use maraiah::err::*;
|
||||||
|
/// #
|
||||||
|
/// # fn main() -> ResultS<()>
|
||||||
|
/// # {
|
||||||
/// let buffer = &[4, 0, 2, 0, 0, 0, 6];
|
/// let buffer = &[4, 0, 2, 0, 0, 0, 6];
|
||||||
///
|
///
|
||||||
/// read_data! {
|
/// read_data! {
|
||||||
|
@ -176,6 +179,7 @@ macro_rules! rd_impl {
|
||||||
/// assert_eq!(six, 6_u8);
|
/// assert_eq!(six, 6_u8);
|
||||||
/// assert_eq!(byte, &[2, 0, 0, 0]);
|
/// assert_eq!(byte, &[2, 0, 0, 0]);
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! read_data {
|
macro_rules! read_data {
|
||||||
|
@ -185,20 +189,24 @@ macro_rules! read_data {
|
||||||
$($ex:ident$(::$exc:ident)*)*;)*
|
$($ex:ident$(::$exc:ident)*)*;)*
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
$crate::check_data!($at + $sz, $b);
|
$crate::bin::check_data($b, $at + $sz)?;
|
||||||
$($crate::rd_impl!($e, $b, $at, $n;
|
$($crate::rd_impl!($e, $b, $at, $n;
|
||||||
$($rn;)? $nam, $($ex$(::$exc)*,)* $t$(::$tc)*);)*
|
$($rn;)? $nam, $($ex$(::$exc)*,)* $t$(::$tc)*);)*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if there is enough data in `b`.
|
/// Checks if there is enough data in `b`.
|
||||||
#[macro_export]
|
///
|
||||||
macro_rules! check_data {
|
/// # Errors
|
||||||
($sz:expr, $b:expr) => {
|
///
|
||||||
if $b.len() < $sz {
|
/// Returns `Err` if `b.len()` is less than `sz`.
|
||||||
return Err(err_msg("not enough data"));
|
pub fn check_data(b: &[u8], sz: usize) -> ResultS<()>
|
||||||
}
|
{
|
||||||
};
|
if b.len() < sz {
|
||||||
|
Err(err_msg("not enough data"))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Casts a `u32` to a `usize`.
|
/// Casts a `u32` to a `usize`.
|
||||||
|
@ -417,7 +425,7 @@ pub fn rd_ofstable<T, F>(b: &[u8],
|
||||||
|
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
let ofs = usize_from_u32(u32b(&b[p..p + 4]));
|
let ofs = usize_from_u32(u32b(&b[p..p + 4]));
|
||||||
check_data!(ofs, b);
|
check_data(b, ofs)?;
|
||||||
v.push(read(&b[ofs..])?);
|
v.push(read(&b[ofs..])?);
|
||||||
p += 4;
|
p += 4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#![doc(hidden)]
|
#![doc(hidden)]
|
||||||
|
|
||||||
/// Creates an enumeration and function for converting a representation into
|
/// Creates an enumeration and function for converting a representation into the
|
||||||
/// the enumeration type.
|
/// enumeration type.
|
||||||
///
|
///
|
||||||
/// The syntax is similar to the `bitflags` macro, but each value has the
|
/// The syntax is similar to the `bitflags` macro, but each value has the syntax
|
||||||
/// syntax `value => enumeration`. `enum` is used instead of `struct`.
|
/// `value = enumeration`. `enum` is used instead of `struct`.
|
||||||
///
|
///
|
||||||
/// This will generate an `enum $t` as well as implement `TryFrom` on it which
|
/// This will generate an `enum $t` as well as implement `TryFrom` on it which
|
||||||
/// will return `Result<$t, ReprError>`.
|
/// will return `Result<$t, ReprError>`.
|
||||||
|
@ -39,7 +39,7 @@ macro_rules! c_enum
|
||||||
$(#[$outer:meta])*
|
$(#[$outer:meta])*
|
||||||
$vi:vis enum $t:ident: $ti:ident
|
$vi:vis enum $t:ident: $ti:ident
|
||||||
{
|
{
|
||||||
$($en:ident = $va:expr),+ $(,)?
|
$($(#[$vouter:meta])* $en:ident = $va:expr),+ $(,)?
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
$(#[$outer])*
|
$(#[$outer])*
|
||||||
|
@ -47,7 +47,7 @@ macro_rules! c_enum
|
||||||
#[repr($ti)]
|
#[repr($ti)]
|
||||||
$vi enum $t
|
$vi enum $t
|
||||||
{
|
{
|
||||||
$($en = $va,)+
|
$($(#[$vouter])* $en = $va,)+
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_qualifications)]
|
#[allow(unused_qualifications)]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! DEFLATE loader.
|
//! DEFLATE loader.
|
||||||
|
|
||||||
use crate::{bit::*, err::*};
|
use crate::{bin::check_data, bit::*, err::*};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
/// Loads a ZLIB file header.
|
/// Loads a ZLIB file header.
|
||||||
|
@ -76,7 +76,7 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS<usize>
|
||||||
|
|
||||||
p += 2 + xlen;
|
p += 2 + xlen;
|
||||||
|
|
||||||
check_data!(p, b);
|
check_data(b, p)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if fl & FNAME != 0 {
|
if fl & FNAME != 0 {
|
||||||
|
@ -90,7 +90,7 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS<usize>
|
||||||
if fl & FHCRC != 0 {
|
if fl & FHCRC != 0 {
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
check_data!(p, b);
|
check_data(b, p)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(p)
|
Ok(p)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#![doc(hidden)]
|
||||||
|
|
||||||
|
/// Macro-izes `#[doc = x]`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use maraiah::doc_comment;
|
||||||
|
///
|
||||||
|
/// doc_comment! {
|
||||||
|
/// concat!("Have a nice", " day", "!"),
|
||||||
|
/// const A: u32 = 5;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// assert_eq!(A, 5);
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! doc_comment {
|
||||||
|
($x:expr, $($tt:tt)*) => {#[doc = $x] $($tt)*}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
|
@ -1,11 +1,27 @@
|
||||||
//! Foreign function interface utilities.
|
//! Foreign function interface utilities.
|
||||||
|
|
||||||
use crate::err::*;
|
use crate::err::*;
|
||||||
pub use std::{ffi::*,
|
|
||||||
os::raw::*,
|
pub use std::{ffi::*, os::raw::*, ptr::{null, null_mut}};
|
||||||
ptr::{null, null_mut}};
|
|
||||||
|
|
||||||
/// Creates a C string from a literal.
|
/// Creates a C string from a literal.
|
||||||
|
///
|
||||||
|
/// This is done by concatenating a null byte with the string and converting it
|
||||||
|
/// to a pointer.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use maraiah::c_str;
|
||||||
|
///
|
||||||
|
/// let st = c_str!("test");
|
||||||
|
///
|
||||||
|
/// assert!(!st.is_null());
|
||||||
|
///
|
||||||
|
/// unsafe {
|
||||||
|
/// assert_eq!(std::slice::from_raw_parts(st, 5), &[116, 101, 115, 116, 0]);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! c_str {
|
macro_rules! c_str {
|
||||||
($s:expr) => {
|
($s:expr) => {
|
||||||
|
@ -13,9 +29,17 @@ macro_rules! c_str {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns [`null`] as a [`*const c_void`].
|
||||||
|
///
|
||||||
|
/// [`null`]: fn.null.html
|
||||||
|
/// [`*const c_void`]: enum.c_void.html
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn null_void() -> *const c_void {null()}
|
pub const fn null_void() -> *const c_void {null()}
|
||||||
|
|
||||||
|
/// Returns [`null_mut`] as a [`*mut c_void`].
|
||||||
|
///
|
||||||
|
/// [`null_mut`]: fn.null_mut.html
|
||||||
|
/// [`*mut c_void`]: enum.c_void.html
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn null_mut_void() -> *mut c_void {null_mut()}
|
pub const fn null_mut_void() -> *mut c_void {null_mut()}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
//! This is the base library for the Maraiah tool set. This library contains
|
||||||
|
//! functions and structures for reading many file formats, primarily those used
|
||||||
|
//! by Marathon, Marathon 2, and Marathon Infinity.
|
||||||
|
//!
|
||||||
|
//! Maraiah comes with a set of almost fully portable tools written in Rust,
|
||||||
|
//! including binary file reading, safe C-like `enum` reading, improved error
|
||||||
|
//! handling, FFI tools, fixed point numbers, and image and sound structures.
|
||||||
|
//!
|
||||||
|
//! Maraiah also comes with APIs for working with various data formats,
|
||||||
|
//! primarily Marathon's. It also handles Macintosh PICT files, Portable PixMap,
|
||||||
|
//! TARGA, RIFF WAVE, and more.
|
||||||
|
//!
|
||||||
|
//! # Features
|
||||||
|
//!
|
||||||
|
//! Maraiah supports serializing and deserializing through `serde` with the
|
||||||
|
//! `serde_obj` feature.
|
||||||
#![deny(anonymous_parameters)]
|
#![deny(anonymous_parameters)]
|
||||||
#![deny(bare_trait_objects)]
|
#![deny(bare_trait_objects)]
|
||||||
#![deny(elided_lifetimes_in_paths)]
|
#![deny(elided_lifetimes_in_paths)]
|
||||||
|
@ -47,12 +63,14 @@
|
||||||
#![deny(clippy::use_self)]
|
#![deny(clippy::use_self)]
|
||||||
#![deny(clippy::used_underscore_binding)]
|
#![deny(clippy::used_underscore_binding)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod doc;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod err;
|
pub mod err;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod cenum;
|
mod cenum;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod bin;
|
pub mod bin;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//! `iidx` chunk.
|
//! `iidx` chunk.
|
||||||
|
|
||||||
use crate::{bin::u16b, err::*};
|
use crate::{bin::{check_data, u16b}, err::*};
|
||||||
|
|
||||||
/// Reads an `iidx` chunk.
|
/// Reads an `iidx` chunk.
|
||||||
pub fn read(b: &[u8]) -> ResultS<(u16, usize)>
|
pub fn read(b: &[u8]) -> ResultS<(u16, usize)>
|
||||||
{
|
{
|
||||||
check_data!(2, b);
|
check_data(b, 2)?;
|
||||||
|
|
||||||
Ok((u16b(b), 2))
|
Ok((u16b(b), 2))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,51 @@
|
||||||
//! Meta-information of this crate.
|
//! Meta-information of this crate.
|
||||||
|
|
||||||
use crate::ffi;
|
|
||||||
|
|
||||||
macro_rules! meta_str {
|
macro_rules! meta_str {
|
||||||
($($name:ident = $cname:ident = $e:expr;)*) => {
|
($($(#[$outer:meta])* $name:ident = $cname:ident = $e:expr;)*) => {
|
||||||
$(
|
$(
|
||||||
pub const $name: &'static str = $e;
|
$(#[$outer])* pub const $name: &'static str = $e;
|
||||||
pub const $cname: ffi::NT = c_str!($e);
|
|
||||||
)*
|
)*
|
||||||
|
pub mod ffi
|
||||||
|
{
|
||||||
|
$(
|
||||||
|
doc_comment! {
|
||||||
|
concat!("FFI variant of [`",
|
||||||
|
stringify!($name),
|
||||||
|
"`]\n\n[`",
|
||||||
|
stringify!($name),
|
||||||
|
"`]: ../constant.",
|
||||||
|
stringify!($name),
|
||||||
|
".html"),
|
||||||
|
pub const $cname: crate::ffi::NT = c_str!($e);
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_str!(
|
meta_str!(
|
||||||
AUTHORS = C_AUTHORS = env!("CARGO_PKG_AUTHORS");
|
/// The authors of this crate, `:` separated.
|
||||||
DESCRIPTION = C_DESCRIPTION = env!("CARGO_PKG_DESCRIPTION");
|
AUTHORS = AUTHORS_C = env!("CARGO_PKG_AUTHORS");
|
||||||
HOMEPAGE = C_HOMEPAGE = env!("CARGO_PKG_HOMEPAGE");
|
/// The description of this crate.
|
||||||
LICENSE_TEXT = C_LICENSE_TEXT = include_str!("../LICENSE");
|
DESCRIPTION = DESCRIPTION_C = env!("CARGO_PKG_DESCRIPTION");
|
||||||
NAME = C_NAME = env!("CARGO_PKG_NAME");
|
/// The home page of this crate.
|
||||||
REPOSITORY = C_REPOSITORY = env!("CARGO_PKG_REPOSITORY");
|
HOMEPAGE = HOMEPAGE_C = env!("CARGO_PKG_HOMEPAGE");
|
||||||
VERSION = C_VERSION = env!("CARGO_PKG_VERSION");
|
/// The full license text of this crate.
|
||||||
VERSION_MAJOR = C_VERSION_MAJOR = env!("CARGO_PKG_VERSION_MAJOR");
|
LICENSE_TEXT = LICENSE_TEXT_C = include_str!("../LICENSE");
|
||||||
VERSION_MINOR = C_VERSION_MINOR = env!("CARGO_PKG_VERSION_MINOR");
|
/// The name of this crate.
|
||||||
VERSION_PATCH = C_VERSION_PATCH = env!("CARGO_PKG_VERSION_PATCH");
|
NAME = NAME_C = env!("CARGO_PKG_NAME");
|
||||||
VERSION_PRE = C_VERSION_PRE = env!("CARGO_PKG_VERSION_PRE");
|
/// The repository of this crate.
|
||||||
|
REPOSITORY = REPOSITORY_C = env!("CARGO_PKG_REPOSITORY");
|
||||||
|
/// The full version of this crate.
|
||||||
|
VERSION = VERSION_C = env!("CARGO_PKG_VERSION");
|
||||||
|
/// The major version of this crate.
|
||||||
|
VERSION_MAJOR = VERSION_MAJOR_C = env!("CARGO_PKG_VERSION_MAJOR");
|
||||||
|
/// The minor version of this crate.
|
||||||
|
VERSION_MINOR = VERSION_MINOR_C = env!("CARGO_PKG_VERSION_MINOR");
|
||||||
|
/// The patch version of this crate.
|
||||||
|
VERSION_PATCH = VERSION_PATCH_C = env!("CARGO_PKG_VERSION_PATCH");
|
||||||
|
/// The pre-release version of this crate.
|
||||||
|
VERSION_PRE = VERSION_PRE_C = env!("CARGO_PKG_VERSION_PRE");
|
||||||
);
|
);
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
"cppFile": "",
|
"cppFile": "",
|
||||||
"rust": {
|
"rust": {
|
||||||
"dir": "",
|
"dir": "",
|
||||||
"interfaceModule": "qintr",
|
"interfaceModule": "ffi",
|
||||||
"implementationModule": "qimpl"
|
"implementationModule": "gui"
|
||||||
},
|
},
|
||||||
"objects": {
|
"objects": {
|
||||||
"MapModel": {
|
"MapModel": {
|
||||||
|
|
|
@ -21,7 +21,7 @@ ProjectModel::ProjectModel(ProjectModel &&o) :
|
||||||
ProjectModel::~ProjectModel()
|
ProjectModel::~ProjectModel()
|
||||||
{
|
{
|
||||||
switch(modelType) {
|
switch(modelType) {
|
||||||
case Map: delete modelMap;
|
case Map: delete modelMap; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
//! GUI implementation.
|
||||||
|
|
||||||
|
mod ffi;
|
||||||
|
mod map;
|
||||||
|
|
||||||
|
pub use self::map::MapModel;
|
||||||
|
|
||||||
|
// EOF
|
|
@ -4,6 +4,6 @@
|
||||||
|
|
||||||
use maraiah::ffi as libc;
|
use maraiah::ffi as libc;
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/src/qintr.rs"));
|
include!(concat!(env!("OUT_DIR"), "/src/ffi.rs"));
|
||||||
|
|
||||||
// EOF
|
// EOF
|
|
@ -1,6 +1,6 @@
|
||||||
//! Map model.
|
//! Map model.
|
||||||
|
|
||||||
use crate::qintr::*;
|
use super::ffi::*;
|
||||||
//use memmap::Mmap;
|
//use memmap::Mmap;
|
||||||
use maraiah::map;
|
use maraiah::map;
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use maraiah::{err::*, ffi};
|
use maraiah::{err::*, ffi};
|
||||||
|
|
||||||
|
mod gui;
|
||||||
mod meta;
|
mod meta;
|
||||||
mod qimpl;
|
|
||||||
mod qintr;
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn main_cc(app_name: *mut ffi::c_char);
|
fn main_cc(app_name: *mut ffi::c_char);
|
||||||
|
|
|
@ -15,11 +15,11 @@ macro_rules! meta_str {
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_str!(
|
meta_str!(
|
||||||
tychoAuthors = meta::C_AUTHORS;
|
tychoAuthors = meta::ffi::AUTHORS_C;
|
||||||
tychoHomepage = meta::C_HOMEPAGE;
|
tychoHomepage = meta::ffi::HOMEPAGE_C;
|
||||||
tychoLicenseText = meta::C_LICENSE_TEXT;
|
tychoLicenseText = meta::ffi::LICENSE_TEXT_C;
|
||||||
tychoRepository = meta::C_REPOSITORY;
|
tychoRepository = meta::ffi::REPOSITORY_C;
|
||||||
tychoVersion = meta::C_VERSION;
|
tychoVersion = meta::ffi::VERSION_C;
|
||||||
);
|
);
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
//! Qt implementation.
|
|
||||||
|
|
||||||
mod map;
|
|
||||||
|
|
||||||
pub use self::map::*;
|
|
||||||
|
|
||||||
// EOF
|
|
Loading…
Reference in New Issue