Compare commits

...

8 Commits

21 changed files with 323 additions and 86 deletions

View File

@ -1,7 +1,7 @@
[package] [package]
name = "maraiah" name = "maraiah"
version = "0.1.0" version = "0.1.0"
authors = ["Alison Watson <marrub@greyserv.net>"] authors = ["Alison Watson <marrub@greyserv.net>", "Tae Matous"]
description = "Marathon editing tools." description = "Marathon editing tools."
homepage = "https://greyserv.net/maraiah/" homepage = "https://greyserv.net/maraiah/"
repository = "http://git.greyserv.net/marrub/Maraiah" repository = "http://git.greyserv.net/marrub/Maraiah"

12
LICENSE
View File

@ -1,10 +1,10 @@
Some of the data contained in tests/data and benches/data is Some of the data contained in tests/data and benches/data is Copyright © Bungie
Copyright © Bungie Software. I do not own them, but am permitted to Software. I do not own them, but am permitted to redistribute them. Everything
redistribute them. Everything else is public domain, as stated: else is public domain, as stated:
To the extent possible under law, I, Alison Watson, have waived all To the extent possible under law, I, Alison Watson, and all other contributors
copyright and related or neighboring rights to this Document as described by to Maraiah, have waived all copyright and related or neighboring rights to this
the Creative Commons Zero license as follows: Document as described by the Creative Commons Zero license as follows:
Creative Commons Legal Code Creative Commons Legal Code

View File

@ -64,6 +64,7 @@ pub mod fixed;
pub mod image; pub mod image;
pub mod machdr; pub mod machdr;
pub mod map; pub mod map;
pub mod meta;
pub mod shp; pub mod shp;
pub mod snd; pub mod snd;
pub mod sound; pub mod sound;

View File

@ -96,7 +96,7 @@ pub enum Chunk
/** `LINS` chunks. */ Lins(Vec<map::lins::Line>), /** `LINS` chunks. */ Lins(Vec<map::lins::Line>),
/** `LITE` chunks. */ Lite(Vec<map::lite::Light>), /** `LITE` chunks. */ Lite(Vec<map::lite::Light>),
/** `MNpx` chunks. */ Mnpx(Vec<map::mnpx::Monster>), /** `MNpx` chunks. */ Mnpx(Vec<map::mnpx::Monster>),
/** `Minf` chunks. */ Minf(map::minf::Minf), /** `Minf` chunks. */ Minf(map::minf::Info),
/** `NAME` chunks. */ Name(Vec<String>), /** `NAME` chunks. */ Name(Vec<String>),
/** `NOTE` chunks. */ Note(Vec<map::note::Note>), /** `NOTE` chunks. */ Note(Vec<map::note::Note>),
/** `OBJS` chunks. */ Objs(Vec<map::objs::Object>), /** `OBJS` chunks. */ Objs(Vec<map::objs::Object>),

View File

@ -1,10 +1,10 @@
//! `Minf` type. //! `Info` type.
use crate::{err::*, text::*}; use crate::{err::*, text::*};
use bitflags::bitflags; use bitflags::bitflags;
/// Reads a `Minf` chunk. /// Reads a `Minf` chunk.
pub fn read(b: &[u8]) -> ResultS<Minf> pub fn read(b: &[u8]) -> ResultS<Info>
{ {
read_data! { read_data! {
endian: BIG, buf: b, size: 88, start: 0, data { endian: BIG, buf: b, size: 88, start: 0, data {
@ -18,12 +18,12 @@ pub fn read(b: &[u8]) -> ResultS<Minf>
} }
} }
Ok(Minf{texture_id, physics_id, skypict_id, miss_flags, envi_flags, Ok(Info{texture_id, physics_id, skypict_id, miss_flags, envi_flags,
entr_flags, level_name}) entr_flags, level_name})
} }
/// Writes a `Minf` chunk. /// Writes a `Minf` chunk.
pub fn write(v: &Minf) -> Vec<u8> pub fn write(v: &Info) -> Vec<u8>
{ {
let mut o = Vec::with_capacity(4); let mut o = Vec::with_capacity(4);
o.extend(&v.texture_id.to_be_bytes()); o.extend(&v.texture_id.to_be_bytes());
@ -37,7 +37,7 @@ pub fn write(v: &Minf) -> Vec<u8>
} }
/// Reads an old `Minf` chunk. /// Reads an old `Minf` chunk.
pub fn read_old(b: &[u8]) -> ResultS<Minf> pub fn read_old(b: &[u8]) -> ResultS<Info>
{ {
let minf = read(b)?; let minf = read(b)?;
@ -51,10 +51,10 @@ pub fn read_old(b: &[u8]) -> ResultS<Minf>
entr_flags.insert(EntFlags::CO_OP) entr_flags.insert(EntFlags::CO_OP)
} }
Ok(Minf{entr_flags, ..minf}) Ok(Info{entr_flags, ..minf})
} }
impl Default for Minf impl Default for Info
{ {
fn default() -> Self fn default() -> Self
{ {
@ -71,7 +71,7 @@ impl Default for Minf
/// 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 Minf pub struct Info
{ {
pub texture_id: u16, pub texture_id: u16,
pub physics_id: u16, pub physics_id: u16,

28
source/meta.rs Normal file
View File

@ -0,0 +1,28 @@
//! Meta-information of this crate.
use crate::ffi;
macro_rules! meta_str {
($($name:ident = $cname:ident = $e:expr;)*) => {
$(
pub const $name: &'static str = $e;
pub const $cname: ffi::NT = c_str!($e);
)*
}
}
meta_str!(
AUTHORS = C_AUTHORS = env!("CARGO_PKG_AUTHORS");
DESCRIPTION = C_DESCRIPTION = env!("CARGO_PKG_DESCRIPTION");
HOMEPAGE = C_HOMEPAGE = env!("CARGO_PKG_HOMEPAGE");
LICENSE_TEXT = C_LICENSE_TEXT = include_str!("../LICENSE");
NAME = C_NAME = env!("CARGO_PKG_NAME");
REPOSITORY = C_REPOSITORY = env!("CARGO_PKG_REPOSITORY");
VERSION = C_VERSION = env!("CARGO_PKG_VERSION");
VERSION_MAJOR = C_VERSION_MAJOR = env!("CARGO_PKG_VERSION_MAJOR");
VERSION_MINOR = C_VERSION_MINOR = env!("CARGO_PKG_VERSION_MINOR");
VERSION_PATCH = C_VERSION_PATCH = env!("CARGO_PKG_VERSION_PATCH");
VERSION_PRE = C_VERSION_PRE = env!("CARGO_PKG_VERSION_PRE");
);
// EOF

View File

@ -33,10 +33,12 @@ add_library(
cc_source/projectview.cc cc_source/projectview.cc
resources/resources.qrc resources/resources.qrc
ui/about.ui ui/about.ui
ui/license.ui
ui/mapprops.ui ui/mapprops.ui
ui/mapview.ui ui/mapview.ui
ui/menu.ui ui/menu.ui
ui/points.ui ui/points.ui
ui/projectview.ui
) )
set_target_properties( set_target_properties(
@ -53,13 +55,6 @@ target_include_directories(
$ENV{OUT_DIR} $ENV{OUT_DIR}
) )
target_compile_definitions(
maraiah-tycho-hermes
PUBLIC
-DTYCHO_VERSION=\"$ENV{CARGO_PKG_VERSION}\"
-DTYCHO_AUTHORS=\"$ENV{CARGO_PKG_AUTHORS}\"
)
target_link_libraries( target_link_libraries(
maraiah-tycho-hermes maraiah-tycho-hermes
Qt5::Core Qt5::Core

View File

@ -1,10 +1,8 @@
[package] [package]
name = "maraiah-tycho" name = "maraiah-tycho"
version = "0.1.0" version = "0.0.0"
authors = ["Alison Watson <marrub@greyserv.net>", "Tae Matous"] edition = "2018"
description = "Tycho map editor." build = "build.rs"
edition = "2018"
build = "build.rs"
[dependencies] [dependencies]
maraiah = {path = "../.."} maraiah = {path = "../.."}
@ -12,6 +10,7 @@ memmap = "0.7"
[build-dependencies] [build-dependencies]
cmake = "0.1" cmake = "0.1"
maraiah = {path = "../.."}
rust_qt_binding_generator = "0.3" rust_qt_binding_generator = "0.3"
[[bin]] [[bin]]

View File

@ -28,11 +28,12 @@ public slots:
protected: protected:
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
void openLicense(QWidget *parent);
private: private:
ProjectView *activeProject() const; ProjectView *activeProject() const;
QMdiSubWindow *activeSubWindow() const; QMdiSubWindow *activeSubWindow() const;
void addProject(ProjectView *proj); void addProject(ProjectView *view);
QSharedPointer<Ui::Menu> ui; QSharedPointer<Ui::Menu> ui;
}; };

View File

@ -20,4 +20,12 @@ constexpr std::uint32_t fourCC(std::uint8_t a,
return (a << 24) | (b << 16) | (c << 8) | d; return (a << 24) | (b << 16) | (c << 8) | d;
} }
extern "C" {
char const *tychoAuthors();
char const *tychoHomepage();
char const *tychoLicenseText();
char const *tychoRepository();
char const *tychoVersion();
}
// EOF // EOF

View File

@ -4,6 +4,7 @@
#include "project.h" #include "project.h"
#include "../ui/ui_menu.h" #include "../ui/ui_menu.h"
#include "../ui/ui_about.h" #include "../ui/ui_about.h"
#include "../ui/ui_license.h"
#include <QCloseEvent> #include <QCloseEvent>
#include <QFileDialog> #include <QFileDialog>
@ -16,11 +17,12 @@ Menu::Menu(QWidget *parent) :
{ {
ui->setupUi(this); ui->setupUi(this);
ui->actionOpen->setShortcut(QKeySequence(QKeySequence::Open));
ui->actionNew->setShortcut(QKeySequence(QKeySequence::New));
ui->actionQuit->setShortcut(QKeySequence(QKeySequence::Quit));
ui->actionAbout->setShortcut(QKeySequence(QKeySequence::HelpContents)); ui->actionAbout->setShortcut(QKeySequence(QKeySequence::HelpContents));
ui->actionClose->setShortcut(QKeySequence(QKeySequence::Close));
ui->actionMapProps->setShortcut(QKeySequence(tr("Ctrl+P"))); ui->actionMapProps->setShortcut(QKeySequence(tr("Ctrl+P")));
ui->actionNew->setShortcut(QKeySequence(QKeySequence::New));
ui->actionOpen->setShortcut(QKeySequence(QKeySequence::Open));
ui->actionQuit->setShortcut(QKeySequence(QKeySequence::Quit));
dbgPrintFunc(); dbgPrintFunc();
} }
@ -56,11 +58,40 @@ void Menu::mapOpen()
void Menu::openAbout() void Menu::openAbout()
{ {
QDialog dlg{this}; QDialog dlg{this};
Ui::About about{}; Ui::About ui{};
about.setupUi(&dlg); ui.setupUi(&dlg);
about.labelVer->setText(tr(TYCHO_VERSION));
about.labelAuthors->setText(tr(TYCHO_AUTHORS).replace(':', '\n')); auto text = ui.labelText->text();
text.replace("AUTHORS",
tr(tychoAuthors()).replace(':', ", ").toHtmlEscaped());
text.replace("HOMEPAGE", tr(tychoHomepage()));
text.replace("REPOSITORY", tr(tychoRepository()));
text.replace("VERSION", tr(tychoVersion()));
ui.labelText->setText(text);
connect(ui.btnLicense, &QPushButton::clicked, this, [&](){
openLicense(&dlg);
});
dlg.exec();
}
void Menu::openLicense(QWidget *parent)
{
QDialog dlg{parent};
Ui::License ui{};
ui.setupUi(&dlg);
ui.text->setPlainText(tychoLicenseText());
connect(ui.btnCopy, &QPushButton::clicked, this, [&]() {
ui.text->selectAll();
ui.text->copy();
});
dlg.exec(); dlg.exec();
} }
@ -80,7 +111,10 @@ void Menu::updateActions()
auto view = activeProject(); auto view = activeProject();
bool active = view != nullptr; bool active = view != nullptr;
ui->actionClose->setEnabled(active);
ui->actionMapProps->setEnabled(active); ui->actionMapProps->setEnabled(active);
dbgPrintFunc();
} }
void Menu::closeEvent(QCloseEvent *event) void Menu::closeEvent(QCloseEvent *event)
@ -97,8 +131,7 @@ void Menu::closeEvent(QCloseEvent *event)
ProjectView *Menu::activeProject() const ProjectView *Menu::activeProject() const
{ {
auto win = activeSubWindow(); return qobject_cast<ProjectView *>(activeSubWindow());
return win ? qobject_cast<ProjectView *>(win->widget()) : nullptr;
} }
QMdiSubWindow *Menu::activeSubWindow() const QMdiSubWindow *Menu::activeSubWindow() const

View File

@ -13,7 +13,7 @@ ProjectModel::~ProjectModel()
bool ProjectModel::isDirty() const bool ProjectModel::isDirty() const
{ {
return true; return false;
} }
bool ProjectModel::open(const QString &fname) bool ProjectModel::open(const QString &fname)

View File

@ -11,8 +11,11 @@ ProjectView::ProjectView(QWidget *parent) :
proj(new ProjectModel) proj(new ProjectModel)
{ {
auto widget = new QWidget(this); auto widget = new QWidget(this);
ui->setupUi(widget); ui->setupUi(widget);
setWidget(widget); setWidget(widget);
setAttribute(Qt::WA_DeleteOnClose);
dbgPrintFunc(); dbgPrintFunc();
} }

View File

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

View File

@ -0,0 +1,25 @@
//! Meta-information exposing functions.
use maraiah::{ffi, meta};
macro_rules! meta_str {
($($name:ident = $e:expr;)*) => {
$(
#[no_mangle]
pub extern "C" fn $name() -> ffi::NT
{
$e
}
)*
}
}
meta_str!(
tychoAuthors = meta::C_AUTHORS;
tychoHomepage = meta::C_HOMEPAGE;
tychoLicenseText = meta::C_LICENSE_TEXT;
tychoRepository = meta::C_REPOSITORY;
tychoVersion = meta::C_VERSION;
);
// EOF

View File

@ -1,3 +1,5 @@
//! Qt implementation.
mod project; mod project;
pub use self::project::*; pub use self::project::*;

View File

@ -1,3 +1,4 @@
//! Qt interface.
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(dead_code)] #![allow(dead_code)]

View File

@ -9,19 +9,22 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>669</width> <width>675</width>
<height>281</height> <height>305</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>About Tycho</string> <string>About Tycho</string>
</property> </property>
<property name="windowIcon">
<iconset theme="dialog-information"/>
</property>
<property name="modal"> <property name="modal">
<bool>true</bool> <bool>true</bool>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="labelImage">
<property name="text"> <property name="text">
<string>&lt;img src=&quot;qrc:///tycho/misc/tycho2.png&quot;/&gt;</string> <string>&lt;img src=&quot;qrc:///tycho/misc/tycho2.png&quot;/&gt;</string>
</property> </property>
@ -30,47 +33,64 @@
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="labelText">
<property name="text"> <property name="text">
<string>&lt;h1&gt;Tycho&lt;/h1&gt;</string> <string>&lt;h1&gt;Tycho&lt;/h1&gt;
&lt;h4&gt;VERSION&lt;/h4&gt;
&lt;p&gt;Tycho is a map editor for Marathon 2 and Marathon Infinity.&lt;/p&gt;
&lt;p&gt;Marathon is Copyright © Bungie Software.&lt;/p&gt;
&lt;p&gt;Tycho is public domain software under the CC0 license.&lt;/p&gt;
&lt;p&gt;Home: &lt;a href=&quot;HOMEPAGE&quot;&gt;HOMEPAGE&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Source code: &lt;a href=&quot;REPOSITORY&quot;&gt;REPOSITORY&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Made by AUTHORS&lt;/p&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="labelVer"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="text"> <item>
<string>VERSION NUMBER</string> <spacer name="horizontalSpacer">
</property> <property name="orientation">
</widget> <enum>Qt::Horizontal</enum>
</item> </property>
<item> <property name="sizeHint" stdset="0">
<widget class="QLabel" name="label_4"> <size>
<property name="text"> <width>40</width>
<string>Tycho is a map editor for Marathon 2 and Marathon Infinity.</string> <height>20</height>
</property> </size>
</widget> </property>
</item> </spacer>
<item> </item>
<widget class="QLabel" name="label_5"> <item>
<property name="text"> <widget class="QPushButton" name="btnLicense">
<string>Marathon is Copyright © Bungie Software. <property name="text">
Tycho is public domain software under the CC0 license.</string> <string>License Info</string>
</property> </property>
</widget> <property name="icon">
</item> <iconset theme="help-about"/>
<item> </property>
<widget class="QLabel" name="labelAuthors"> </widget>
<property name="text"> </item>
<string>AUTHORS</string> <item>
</property> <widget class="QPushButton" name="btnClose">
</widget> <property name="text">
</item> <string>Close</string>
<item> </property>
<widget class="QDialogButtonBox" name="buttonBox"> <property name="icon">
<property name="standardButtons"> <iconset theme="window-close"/>
<set>QDialogButtonBox::Close</set> </property>
</property> </widget>
</widget> </item>
</layout>
</item> </item>
</layout> </layout>
</item> </item>
@ -81,18 +101,18 @@ Tycho is public domain software under the CC0 license.</string>
</resources> </resources>
<connections> <connections>
<connection> <connection>
<sender>buttonBox</sender> <sender>btnClose</sender>
<signal>rejected()</signal> <signal>clicked()</signal>
<receiver>About</receiver> <receiver>About</receiver>
<slot>reject()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>479</x> <x>622</x>
<y>256</y> <y>256</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>334</x> <x>337</x>
<y>140</y> <y>143</y>
</hint> </hint>
</hints> </hints>
</connection> </connection>

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>License</class>
<widget class="QDialog" name="License">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPlainTextEdit" name="text">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="backgroundVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnCopy">
<property name="text">
<string>Copy</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnClose">
<property name="text">
<string>Close</string>
</property>
<property name="icon">
<iconset theme="window-close"/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>btnClose</sender>
<signal>clicked()</signal>
<receiver>License</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>548</x>
<y>374</y>
</hint>
<hint type="destinationlabel">
<x>299</x>
<y>199</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -61,6 +61,8 @@
<addaction name="actionNew"/> <addaction name="actionNew"/>
<addaction name="actionOpen"/> <addaction name="actionOpen"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionClose"/>
<addaction name="separator"/>
<addaction name="actionQuit"/> <addaction name="actionQuit"/>
</widget> </widget>
<widget class="QMenu" name="menuEdit"> <widget class="QMenu" name="menuEdit">
@ -128,6 +130,17 @@
<string>&amp;About Tycho</string> <string>&amp;About Tycho</string>
</property> </property>
</action> </action>
<action name="actionClose">
<property name="enabled">
<bool>false</bool>
</property>
<property name="icon">
<iconset theme="window-close"/>
</property>
<property name="text">
<string>&amp;Close</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources>
@ -230,6 +243,22 @@
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>actionClose</sender>
<signal>triggered()</signal>
<receiver>mdiArea</receiver>
<slot>closeActiveSubWindow()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>301</y>
</hint>
</hints>
</connection>
</connections> </connections>
<slots> <slots>
<slot>openMapProperties()</slot> <slot>openMapProperties()</slot>

View File

@ -1,4 +1,4 @@
map::minf::Minf{ map::minf::Info{
texture_id: 0, texture_id: 0,
physics_id: 1, physics_id: 1,
skypict_id: 1, skypict_id: 1,