more rendering improvements
This commit is contained in:
@@ -439,8 +439,8 @@ TARGET_LINK_LIBRARIES (noggit
|
||||
set_property(TARGET noggit PROPERTY AUTOMOC ON)
|
||||
|
||||
if(APPLE)
|
||||
target_include_directories(noggit PRIVATE /usr/local/Cellar/llvm/12.0.0/include/c++/v1/)
|
||||
target_link_libraries(noggit /usr/local/Cellar/llvm/12.0.0/lib/libc++.1.0.dylib)
|
||||
target_include_directories(noggit PRIVATE /usr/local/Cellar/llvm/12.0.1/include/c++/v1/)
|
||||
target_link_libraries(noggit /usr/local/Cellar/llvm/12.0.1/lib/libc++.1.0.dylib)
|
||||
endif()
|
||||
|
||||
set (_noggit_revision_output_dir "${CMAKE_BINARY_DIR}/revision_output")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
#version 330 core
|
||||
#version 410 core
|
||||
|
||||
in vec3 position;
|
||||
in vec3 normal;
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "MakeshiftCommon.inl"
|
||||
|
||||
using namespace noggit::Recovery;
|
||||
|
||||
ChunkHeader::ChunkHeader
|
||||
(
|
||||
char const* magic,
|
||||
std::uint32_t size
|
||||
)
|
||||
: size{size}
|
||||
{
|
||||
assert(std::strlen(magic) == 4);
|
||||
std::copy(magic, magic + 4, reinterpret_cast<char*>(&this->magic));
|
||||
}
|
||||
|
||||
Buffer::Buffer ( )
|
||||
: _pos{}
|
||||
{ }
|
||||
|
||||
Buffer::Buffer ( std::string_view file )
|
||||
: _pos{}
|
||||
{
|
||||
if
|
||||
(
|
||||
std::ifstream f{file.data(), std::ios::binary}
|
||||
;
|
||||
f
|
||||
)
|
||||
{
|
||||
f.exceptions(std::ios::badbit);
|
||||
f.seekg(0, std::ios::end);
|
||||
_data.resize(static_cast<std::size_t>(f.tellg()) + 1);
|
||||
f.seekg(0);
|
||||
f.read(_data.data(), _data.size());
|
||||
}
|
||||
else
|
||||
std::cerr << "E: Unable to open '" << file << "' for reading.\n";
|
||||
}
|
||||
|
||||
auto Buffer::save ( std::string_view file )
|
||||
-> void
|
||||
{
|
||||
if
|
||||
(
|
||||
std::ofstream f(file.data(), std::ios::binary | std::ios::trunc)
|
||||
;
|
||||
f
|
||||
)
|
||||
{
|
||||
f.exceptions(std::ios::badbit);
|
||||
f.write(_data.data(), _data.size());
|
||||
}
|
||||
else
|
||||
std::cerr << "E: Unable to open '" << file << "' for writing.\n";
|
||||
}
|
||||
|
||||
auto Buffer::read
|
||||
(
|
||||
void* ptr,
|
||||
std::size_t amount
|
||||
)
|
||||
-> void
|
||||
{
|
||||
assert(_pos + amount < _data.size());
|
||||
std::copy(_data.data() + _pos, _data.data() + _pos + amount
|
||||
, static_cast<char*>(ptr));
|
||||
_pos += amount;
|
||||
}
|
||||
|
||||
auto Buffer::append
|
||||
(
|
||||
void const* mem,
|
||||
std::size_t size
|
||||
)
|
||||
-> void
|
||||
{
|
||||
std::size_t const pos{_pos};
|
||||
_extend(size);
|
||||
char const* const begin{static_cast<char const*>(mem)};
|
||||
std::copy(begin, begin + size, _data.data() + pos);
|
||||
}
|
||||
|
||||
auto Buffer::extend ( std::size_t amount )
|
||||
-> void
|
||||
{ _extend(amount); }
|
||||
|
||||
auto Buffer::getPos ( ) const
|
||||
-> std::size_t
|
||||
{ return _pos; }
|
||||
|
||||
auto Buffer::getData ( ) const
|
||||
-> std::vector<char> const&
|
||||
{ return _data; }
|
||||
|
||||
auto Buffer::_tether
|
||||
(
|
||||
CommonAnchor* who,
|
||||
void const* ptr
|
||||
)
|
||||
-> void
|
||||
{
|
||||
assert(_anchors.find(who) == _anchors.cend());
|
||||
assert(ptr >= _data.data() && ptr <= _data.data() + _data.size());
|
||||
_anchors.emplace(who, static_cast<char const*>(ptr) - _data.data());
|
||||
}
|
||||
|
||||
auto Buffer::_copyTether
|
||||
(
|
||||
CommonAnchor const& from,
|
||||
CommonAnchor* to
|
||||
)
|
||||
-> void
|
||||
{
|
||||
auto itr{_anchors.find(const_cast<CommonAnchor*>(&from))};
|
||||
assert(itr != _anchors.end());
|
||||
_anchors.emplace(to, itr->second);
|
||||
to->_setPtr(_data.data() + itr->second);
|
||||
}
|
||||
|
||||
auto Buffer::_untether ( CommonAnchor* who )
|
||||
-> void
|
||||
{
|
||||
assert(_anchors.find(who) != _anchors.cend());
|
||||
_anchors.erase(who);
|
||||
}
|
||||
|
||||
auto Buffer::_extend ( std::size_t amount )
|
||||
-> void
|
||||
{
|
||||
std::size_t const req{_pos + amount};
|
||||
|
||||
if(req > _data.size())
|
||||
{
|
||||
_data.resize(req);
|
||||
|
||||
for(auto& entry : _anchors)
|
||||
entry.first->_setPtr(_data.data() + entry.second);
|
||||
}
|
||||
|
||||
_pos = req;
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
#ifndef NOGGIT_SRC_NOGGIT_MAKESHIFTCOMMON_HPP
|
||||
#define NOGGIT_SRC_NOGGIT_MAKESHIFTCOMMON_HPP
|
||||
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace noggit::Recovery
|
||||
{
|
||||
struct ChunkHeader
|
||||
{
|
||||
ChunkHeader
|
||||
(
|
||||
char const* magic,
|
||||
std::uint32_t size = 0
|
||||
);
|
||||
|
||||
std::uint32_t magic;
|
||||
std::uint32_t size;
|
||||
};
|
||||
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
enum struct SeekMode : bool
|
||||
{
|
||||
Absolute,
|
||||
Relative
|
||||
};
|
||||
|
||||
class CommonAnchor
|
||||
{
|
||||
protected:
|
||||
friend Buffer;
|
||||
|
||||
virtual
|
||||
auto _setPtr ( void* ptr )
|
||||
-> void = 0;
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Ty,
|
||||
SeekMode mode = SeekMode::Absolute
|
||||
>
|
||||
struct Offset
|
||||
{ std::size_t offset; };
|
||||
|
||||
template < typename This >
|
||||
class Anchor : protected CommonAnchor
|
||||
{
|
||||
public:
|
||||
template < std::convertible_to<This> Other >
|
||||
Anchor ( Anchor<Other> const& other );
|
||||
Anchor ( Anchor<This>&& other )
|
||||
= delete;
|
||||
~Anchor ( );
|
||||
template < std::convertible_to<This> Other >
|
||||
auto operator = ( Anchor<Other> const& other )
|
||||
-> Anchor<This>&;
|
||||
auto operator = ( Anchor<This>&& other )
|
||||
-> Anchor& = delete;
|
||||
auto operator * ( )
|
||||
-> This&;
|
||||
auto operator * ( ) const
|
||||
-> This const&;
|
||||
auto operator [] ( std::size_t idx )
|
||||
-> This&;
|
||||
auto operator [] ( std::size_t idx ) const
|
||||
-> This const&;
|
||||
auto operator -> ( )
|
||||
-> This*;
|
||||
auto operator -> ( ) const
|
||||
-> This const*;
|
||||
operator This* ( );
|
||||
operator This const* ( ) const;
|
||||
protected:
|
||||
template
|
||||
<
|
||||
typename Ty,
|
||||
Buffer::SeekMode mode
|
||||
>
|
||||
friend constexpr
|
||||
auto operator +
|
||||
(
|
||||
Buffer& buf,
|
||||
Buffer::Offset<Ty, mode> offset
|
||||
)
|
||||
-> Buffer::Anchor<Ty>;
|
||||
|
||||
explicit constexpr
|
||||
Anchor
|
||||
(
|
||||
This* ptr,
|
||||
Buffer* buf
|
||||
);
|
||||
auto _setPtr ( void* ptr )
|
||||
-> void override;
|
||||
|
||||
This* _ptr;
|
||||
Buffer* _buf;
|
||||
};
|
||||
|
||||
Buffer ( );
|
||||
explicit
|
||||
Buffer ( std::string_view file );
|
||||
auto save ( std::string_view file )
|
||||
-> void;
|
||||
template < SeekMode mode = SeekMode::Absolute >
|
||||
auto seek ( std::size_t val )
|
||||
-> std::size_t;
|
||||
template < typename Ty >
|
||||
auto read ( Ty* ptr )
|
||||
-> void;
|
||||
template < typename Ty >
|
||||
auto read ( Ty const* ptr )
|
||||
-> void = delete;
|
||||
auto read
|
||||
(
|
||||
void* ptr,
|
||||
std::size_t amount
|
||||
)
|
||||
-> void;
|
||||
template < typename Ty >
|
||||
auto append ( Ty const& val )
|
||||
-> void;
|
||||
auto append
|
||||
(
|
||||
void const* mem,
|
||||
std::size_t size
|
||||
)
|
||||
-> void;
|
||||
auto extend ( std::size_t amount )
|
||||
-> void;
|
||||
auto getPos ( ) const
|
||||
-> std::size_t;
|
||||
auto getData ( ) const
|
||||
-> std::vector<char> const&;
|
||||
/*template < typename Ty >
|
||||
constexpr
|
||||
operator Anchor<Ty> ( );*/
|
||||
template < typename Ty >
|
||||
constexpr
|
||||
operator Anchor<Ty>()
|
||||
{
|
||||
return *this + Offset<Ty>{_pos};
|
||||
}
|
||||
protected:
|
||||
template < typename Ty >
|
||||
friend class Anchor;
|
||||
template
|
||||
<
|
||||
typename Ty,
|
||||
Buffer::SeekMode mode
|
||||
>
|
||||
friend constexpr
|
||||
auto operator +
|
||||
(
|
||||
Buffer& buf,
|
||||
Buffer::Offset<Ty, mode> offset
|
||||
)
|
||||
-> Buffer::Anchor<Ty>;
|
||||
|
||||
auto _tether
|
||||
(
|
||||
CommonAnchor* who,
|
||||
void const* ptr
|
||||
)
|
||||
-> void;
|
||||
auto _copyTether
|
||||
(
|
||||
CommonAnchor const& from,
|
||||
CommonAnchor* to
|
||||
)
|
||||
-> void;
|
||||
auto _untether ( CommonAnchor* who )
|
||||
-> void;
|
||||
auto _extend ( std::size_t amount )
|
||||
-> void;
|
||||
std::size_t _pos;
|
||||
std::vector<char> _data;
|
||||
std::unordered_map<CommonAnchor*, std::size_t> _anchors;
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Ty,
|
||||
Buffer::SeekMode mode
|
||||
>
|
||||
constexpr
|
||||
auto operator +
|
||||
(
|
||||
Buffer& buf,
|
||||
Buffer::Offset<Ty, mode> offset
|
||||
)
|
||||
-> Buffer::Anchor<Ty>;
|
||||
}
|
||||
|
||||
#endif //NOGGIT_SRC_NOGGIT_MAKESHIFTCOMMON_HPP
|
||||
@@ -1,147 +0,0 @@
|
||||
#ifndef NOGGIT_SRC_NOGGIT_MAKESHIFTCOMMON_INL
|
||||
#define NOGGIT_SRC_NOGGIT_MAKESHIFTCOMMON_INL
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include "MakeshiftCommon.hpp"
|
||||
|
||||
namespace noggit::Recovery
|
||||
{
|
||||
template < typename This >
|
||||
template < std::convertible_to<This> Other >
|
||||
Buffer::Anchor<This>::Anchor ( Anchor<Other> const& other )
|
||||
: _buf{other._buf}
|
||||
{ _buf->_copyTether(other, this); }
|
||||
|
||||
template < typename This >
|
||||
Buffer::Anchor<This>::~Anchor ( )
|
||||
{ _buf->_untether(this); }
|
||||
|
||||
template < typename This >
|
||||
template < std::convertible_to<This> Other >
|
||||
auto Buffer::Anchor<This>::operator = ( Anchor<Other> const& other )
|
||||
-> Anchor<This>&
|
||||
{
|
||||
_buf->_untether(this);
|
||||
_buf = other._buf;
|
||||
_buf->_copyTether(other, this);
|
||||
}
|
||||
|
||||
template < typename This >
|
||||
auto Buffer::Anchor<This>::operator * ( )
|
||||
-> This&
|
||||
{ return *_ptr; }
|
||||
|
||||
template < typename This >
|
||||
auto Buffer::Anchor<This>::operator * ( ) const
|
||||
-> This const&
|
||||
{ return *_ptr; }
|
||||
|
||||
template < typename This >
|
||||
auto Buffer::Anchor<This>::operator [] ( std::size_t idx )
|
||||
-> This&
|
||||
{ return _ptr[idx]; }
|
||||
|
||||
template < typename This >
|
||||
auto Buffer::Anchor<This>::operator [] ( std::size_t idx ) const
|
||||
-> This const&
|
||||
{ return _ptr[idx]; }
|
||||
|
||||
template < typename This >
|
||||
auto Buffer::Anchor<This>::operator -> ( )
|
||||
-> This*
|
||||
{ return _ptr; }
|
||||
|
||||
template < typename This >
|
||||
auto Buffer::Anchor<This>::operator -> ( ) const
|
||||
-> This const*
|
||||
{ return _ptr; }
|
||||
|
||||
template < typename This >
|
||||
Buffer::Anchor<This>::operator This* ( )
|
||||
{ return _ptr; }
|
||||
|
||||
template < typename This >
|
||||
Buffer::Anchor<This>::operator This const* ( ) const
|
||||
{ return _ptr; }
|
||||
|
||||
template < typename This >
|
||||
constexpr
|
||||
Buffer::Anchor<This>::Anchor
|
||||
(
|
||||
This* ptr,
|
||||
Buffer* buf
|
||||
)
|
||||
: _ptr{ptr}, _buf{buf}
|
||||
{ _buf->_tether(this, _ptr); }
|
||||
|
||||
template < typename This >
|
||||
auto Buffer::Anchor<This>::_setPtr ( void* ptr )
|
||||
-> void
|
||||
{
|
||||
_ptr = reinterpret_cast<std::remove_cv_t<This>*>(ptr);
|
||||
}
|
||||
|
||||
template < Buffer::SeekMode mode >
|
||||
auto Buffer::seek ( std::size_t val )
|
||||
-> std::size_t
|
||||
{
|
||||
if constexpr(mode == SeekMode::Absolute)
|
||||
_pos = val;
|
||||
else
|
||||
_pos += val;
|
||||
|
||||
return _pos;
|
||||
}
|
||||
|
||||
template < typename Ty >
|
||||
auto Buffer::read ( Ty* ptr )
|
||||
-> void
|
||||
{
|
||||
assert(_pos + sizeof(Ty) < _data.size());
|
||||
std::copy(_data.data() + _pos, _data.data() + _pos + sizeof(Ty)
|
||||
, reinterpret_cast<char*>(ptr));
|
||||
_pos += sizeof(Ty);
|
||||
}
|
||||
|
||||
template < typename Ty >
|
||||
auto Buffer::append ( Ty const& val )
|
||||
-> void
|
||||
{ append(&val, sizeof(Ty)); }
|
||||
|
||||
/*template < typename Ty >
|
||||
constexpr
|
||||
Buffer::operator Anchor<Ty> ( )
|
||||
{ return *this + Offset<Ty>{_pos}; }*/
|
||||
|
||||
template
|
||||
<
|
||||
typename Ty,
|
||||
Buffer::SeekMode mode
|
||||
>
|
||||
constexpr
|
||||
auto operator +
|
||||
(
|
||||
Buffer& buf,
|
||||
Buffer::Offset<Ty, mode> offset
|
||||
)
|
||||
-> Buffer::Anchor<Ty>
|
||||
{
|
||||
typedef std::remove_cv_t<Ty> NonCV;
|
||||
|
||||
if constexpr(mode == Buffer::SeekMode::Relative)
|
||||
return Buffer::Anchor<Ty>
|
||||
{
|
||||
reinterpret_cast<NonCV*>(buf._data.data() + buf._pos + offset.offset),
|
||||
&buf
|
||||
};
|
||||
|
||||
return Buffer::Anchor<Ty>
|
||||
{
|
||||
reinterpret_cast<NonCV*>(buf._data.data() + offset.offset),
|
||||
&buf
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //NOGGIT_SRC_NOGGIT_MAKESHIFTCOMMON_INL
|
||||
@@ -1,309 +0,0 @@
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "MapHeaders.h"
|
||||
#include "MPQ.h"
|
||||
#include "MakeshiftCommon.inl"
|
||||
#include "MakeshiftMt.hpp"
|
||||
|
||||
using namespace noggit::Recovery;
|
||||
|
||||
MakeshiftMt::MakeshiftMt
|
||||
(
|
||||
std::string_view file,
|
||||
std::vector<std::string_view> const& models,
|
||||
std::vector<std::string_view> const& wmos
|
||||
)
|
||||
: _file{file}
|
||||
, _defectiveModelNames{models}, _defectiveWmoNames{wmos}
|
||||
{
|
||||
std::uint32_t lMCNKOffsets[256];
|
||||
std::uint32_t fourcc;
|
||||
std::uint32_t size;
|
||||
MHDR Header;
|
||||
std::uint32_t version;
|
||||
Buffer buf{file};
|
||||
buf.read(&fourcc);
|
||||
buf.seek<Buffer::SeekMode::Relative>(4);
|
||||
buf.read(&version);
|
||||
assert(fourcc == 'MVER' && version == 18);
|
||||
buf.read(&fourcc);
|
||||
buf.seek<Buffer::SeekMode::Relative>(4);
|
||||
assert(fourcc == 'MHDR');
|
||||
buf.read(&Header);
|
||||
_flags = Header.flags;
|
||||
buf.seek(Header.mcin + 0x14);
|
||||
buf.read(&fourcc);
|
||||
buf.seek<Buffer::SeekMode::Relative>(4);
|
||||
assert(fourcc == 'MCIN');
|
||||
|
||||
for(int i = 0; i < 256; ++i)
|
||||
{
|
||||
buf.read(&lMCNKOffsets[i]);
|
||||
buf.seek<Buffer::SeekMode::Relative>(0xC);
|
||||
}
|
||||
|
||||
buf.seek(Header.mtex + 0x14);
|
||||
buf.read(&fourcc);
|
||||
buf.read(&size);
|
||||
assert(fourcc == 'MTEX');
|
||||
_mtex.resize(size);
|
||||
buf.read(_mtex.data(), size);
|
||||
|
||||
buf.seek(Header.mmdx + 0x14);
|
||||
buf.read(&fourcc);
|
||||
buf.read(&size);
|
||||
assert(fourcc == 'MMDX');
|
||||
|
||||
{
|
||||
char const* lCurPos{Buffer::Anchor<char const>{buf}};
|
||||
char const* const lEnd{lCurPos + size};
|
||||
|
||||
while(lCurPos < lEnd)
|
||||
{
|
||||
_modelNames.emplace_back(lCurPos);
|
||||
lCurPos += std::strlen(lCurPos) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
buf.seek(Header.mwmo + 0x14);
|
||||
buf.read(&fourcc);
|
||||
buf.read(&size);
|
||||
assert(fourcc == 'MWMO');
|
||||
|
||||
{
|
||||
char const* lCurPos{Buffer::Anchor<char const>{buf}};
|
||||
char const* const lEnd{lCurPos + size};
|
||||
|
||||
while(lCurPos < lEnd)
|
||||
{
|
||||
_wmoNames.emplace_back(lCurPos);
|
||||
lCurPos += std::strlen(lCurPos) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
buf.seek(Header.mddf + 0x14);
|
||||
buf.read(&fourcc);
|
||||
buf.read(&size);
|
||||
assert(fourcc == 'MDDF');
|
||||
ENTRY_MDDF const* const mddf_ptr{Buffer::Anchor<ENTRY_MDDF const>{buf}};
|
||||
|
||||
for(unsigned i{}; i < size / sizeof(ENTRY_MDDF); ++i)
|
||||
_models.push_back(mddf_ptr[i]);
|
||||
|
||||
buf.seek(Header.modf + 0x14);
|
||||
buf.read(&fourcc);
|
||||
buf.read(&size);
|
||||
assert(fourcc == 'MODF');
|
||||
ENTRY_MODF const* const modf_ptr{Buffer::Anchor<ENTRY_MODF const>{buf}};
|
||||
|
||||
for(unsigned i{}; i < size / sizeof(ENTRY_MODF); ++i)
|
||||
_wmos.push_back(modf_ptr[i]);
|
||||
|
||||
if(Header.mh2o)
|
||||
{
|
||||
buf.seek(Header.mh2o + 0x14);
|
||||
buf.read(&fourcc, 4);
|
||||
buf.read(&size, 4);
|
||||
assert(fourcc == 'MH2O');
|
||||
_mh2o.resize(size);
|
||||
buf.read(_mh2o.data(), size);
|
||||
}
|
||||
|
||||
if (_flags & 1)
|
||||
{
|
||||
buf.seek(Header.mfbo + 0x14);
|
||||
buf.read(&fourcc, 4);
|
||||
buf.read(&size, 4);
|
||||
assert(fourcc == 'MFBO' && size == 2 * 2 * 9);
|
||||
buf.read(_mfbo.data(), 2 * 2 * 9);
|
||||
}
|
||||
|
||||
for(auto itr{_mcnks.begin()}; itr != _mcnks.end(); ++itr)
|
||||
{
|
||||
buf.seek(lMCNKOffsets[std::distance(_mcnks.begin(), itr)] + 4);
|
||||
buf.read(&size, 4);
|
||||
itr->resize(size);
|
||||
buf.read(itr->data(), size);
|
||||
}
|
||||
}
|
||||
|
||||
auto MakeshiftMt::save ( )
|
||||
-> std::pair<std::size_t, std::size_t>
|
||||
{
|
||||
Buffer buf;
|
||||
buf.append(ChunkHeader{"REVM", 4});
|
||||
buf.append(18u);
|
||||
buf.append(ChunkHeader{"RDHM", 0x40});
|
||||
Buffer::Anchor<MHDR> mhdr{buf};
|
||||
buf.append(MHDR{.flags{_flags}});
|
||||
mhdr->mcin = buf.getPos() - 0x14;
|
||||
buf.append(ChunkHeader{"NICM", 256 * 0x10});
|
||||
Buffer::Anchor<std::uint32_t> mcin{buf};
|
||||
buf.extend(16 * 16 * 0x10);
|
||||
mhdr->mtex = buf.getPos() - 0x14;
|
||||
buf.append(ChunkHeader("XETM", _mtex.size()));
|
||||
buf.append(_mtex.data(), _mtex.size());
|
||||
std::vector<std::string_view> modelNames;
|
||||
std::vector<std::string_view> wmoNames;
|
||||
std::unordered_map<ENTRY_MDDF const*, std::uint32_t> modelNameMapping;
|
||||
std::unordered_map<ENTRY_MODF const*, std::uint32_t> wmoNameMapping;
|
||||
static constexpr
|
||||
auto prepare
|
||||
{
|
||||
[ ]
|
||||
< typename Chunk >
|
||||
(
|
||||
std::vector<Chunk> const& instances,
|
||||
std::vector<std::string> const& names,
|
||||
std::vector<std::string_view> const& defectiveNames,
|
||||
std::vector<std::string_view>* targetNames,
|
||||
std::unordered_map<Chunk const*, std::uint32_t>* targetInstances
|
||||
)
|
||||
-> void
|
||||
{
|
||||
std::unordered_map<std::uint32_t, std::uint32_t> nidMapping;
|
||||
|
||||
for(auto const& instance : instances)
|
||||
if
|
||||
(
|
||||
std::string_view const curName{names[instance.nameID]}
|
||||
; std::find(defectiveNames.cbegin(), defectiveNames.cend(), curName)
|
||||
== defectiveNames.cend()
|
||||
)
|
||||
targetInstances->emplace
|
||||
(
|
||||
&instance,
|
||||
nidMapping.find(instance.nameID) == nidMapping.cend()
|
||||
?
|
||||
(
|
||||
targetNames->push_back(curName)
|
||||
, nidMapping.emplace
|
||||
(
|
||||
instance.nameID,
|
||||
targetNames->size() - 1
|
||||
).first->second
|
||||
)
|
||||
: nidMapping.at(instance.nameID)
|
||||
);
|
||||
}
|
||||
};
|
||||
prepare(_models, _modelNames, _defectiveModelNames, &modelNames
|
||||
, &modelNameMapping);
|
||||
prepare(_wmos, _wmoNames, _defectiveWmoNames, &wmoNames
|
||||
, &wmoNameMapping);
|
||||
std::pair<std::size_t, std::size_t> const result
|
||||
{
|
||||
_models.size() - modelNameMapping.size(),
|
||||
_wmos.size() - wmoNameMapping.size()
|
||||
};
|
||||
std::cout << "I: Removed '" << result.first << "' defective models.\n";
|
||||
std::cout << "I: Removed '" << result.second << "' defective objects.\n";
|
||||
static constexpr
|
||||
auto writeNames
|
||||
{
|
||||
[ ]
|
||||
(
|
||||
char const* namesChunk,
|
||||
char const* idsChunk,
|
||||
std::uint32_t* namesPos,
|
||||
Buffer::Anchor<std::uint32_t> idsPos,
|
||||
std::vector<std::string_view> const& names,
|
||||
Buffer* buf
|
||||
)
|
||||
-> void
|
||||
{
|
||||
*namesPos = buf->getPos() - 0x14;
|
||||
Buffer::Anchor<ChunkHeader> header{*buf};
|
||||
buf->append(ChunkHeader{namesChunk});
|
||||
std::vector<std::uint32_t> offsets(names.size());
|
||||
|
||||
for(auto itr{names.cbegin()}; itr != names.cend(); ++itr)
|
||||
{
|
||||
offsets[std::distance(names.cbegin(), itr)] = header->size;
|
||||
std::size_t const size{itr->length() + 1};
|
||||
buf->append(itr->data(), size);
|
||||
header->size += size;
|
||||
}
|
||||
|
||||
*idsPos = buf->getPos() - 0x14;
|
||||
size_t const size{4 * offsets.size()};
|
||||
buf->append(ChunkHeader(idsChunk, size));
|
||||
buf->append(offsets.data(), size);
|
||||
}
|
||||
};
|
||||
writeNames
|
||||
(
|
||||
"XDMM",
|
||||
"DIMM",
|
||||
&mhdr->mmdx,
|
||||
buf + Buffer::Offset<std::uint32_t>{0x24},
|
||||
modelNames,
|
||||
&buf
|
||||
);
|
||||
writeNames
|
||||
(
|
||||
"OMWM",
|
||||
"DIWM",
|
||||
&mhdr->mwmo,
|
||||
buf + Buffer::Offset<std::uint32_t>{0x2C},
|
||||
wmoNames,
|
||||
&buf
|
||||
);
|
||||
static constexpr
|
||||
auto writeMapping
|
||||
{
|
||||
[ ]
|
||||
< typename Chunk >
|
||||
(
|
||||
char const* magic,
|
||||
std::uint32_t* pos,
|
||||
std::unordered_map<Chunk const*, std::uint32_t> const& mapping,
|
||||
Buffer* buf
|
||||
)
|
||||
-> void
|
||||
{
|
||||
*pos = buf->getPos() - 0x14;
|
||||
buf->append(ChunkHeader(magic, mapping.size() * sizeof(Chunk)));
|
||||
|
||||
for(auto entry : mapping)
|
||||
{
|
||||
Chunk chunk{*entry.first};
|
||||
chunk.nameID = entry.second;
|
||||
buf->append(chunk);
|
||||
}
|
||||
}
|
||||
};
|
||||
writeMapping("FDDM", &mhdr->mddf, modelNameMapping, &buf);
|
||||
writeMapping("FDOM", &mhdr->modf, wmoNameMapping, &buf);
|
||||
|
||||
if(!_mh2o.empty())
|
||||
{
|
||||
mhdr->mh2o = buf.getPos() - 0x14;
|
||||
buf.append(ChunkHeader("O2HM", _mh2o.size()));
|
||||
buf.append(_mh2o.data(), _mh2o.size());
|
||||
}
|
||||
else
|
||||
mhdr->mh2o = 0;
|
||||
|
||||
for(auto itr{_mcnks.cbegin()}; itr != _mcnks.cend(); ++itr)
|
||||
{
|
||||
mcin[static_cast<std::size_t>(std::distance(_mcnks.cbegin(), itr) * 4)]
|
||||
= buf.getPos();
|
||||
buf.append(ChunkHeader("KNCM", itr->size()));
|
||||
buf.append(itr->data(), itr->size());
|
||||
}
|
||||
|
||||
if(_flags & 1u)
|
||||
{
|
||||
mhdr->mfbo = buf.getPos() - 0x14;
|
||||
buf.append(ChunkHeader{"OBFM", 2 * 2 * 9});
|
||||
buf.append(_mfbo.data(), 2 * 2 * 9);
|
||||
}
|
||||
else
|
||||
mhdr->mfbo = 0;
|
||||
|
||||
buf.save(_file);
|
||||
return result;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef NOGGIT_SRC_NOGGIT_MAKESHIFTMT_HPP
|
||||
#define NOGGIT_SRC_NOGGIT_MAKESHIFTMT_HPP
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <math/vector_3d.hpp>
|
||||
|
||||
namespace noggit::Recovery
|
||||
{
|
||||
class MakeshiftMt
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
MakeshiftMt
|
||||
(
|
||||
std::string_view file,
|
||||
std::vector<std::string_view> const& models,
|
||||
std::vector<std::string_view> const& wmos
|
||||
);
|
||||
auto save ( )
|
||||
-> std::pair<std::size_t, std::size_t>;
|
||||
private:
|
||||
std::string_view _file;
|
||||
std::uint32_t _flags;
|
||||
std::vector<std::string_view> const& _defectiveModelNames;
|
||||
std::vector<std::string_view> const& _defectiveWmoNames;
|
||||
std::vector<std::string> _modelNames;
|
||||
std::vector<std::string> _wmoNames;
|
||||
std::vector<ENTRY_MDDF> _models;
|
||||
std::vector<ENTRY_MODF> _wmos;
|
||||
std::vector<char> _mtex;
|
||||
std::array<char, 2 * 2 * 9> _mfbo;
|
||||
std::vector<char> _mh2o;
|
||||
std::array<std::vector<char>, 256> _mcnks;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //NOGGIT_SRC_NOGGIT_MAKESHIFTMT_HPP
|
||||
@@ -652,12 +652,12 @@ void MapChunk::draw ( math::frustum const& frustum
|
||||
opengl::texture::set_active_texture(5);
|
||||
shadow.bind();
|
||||
|
||||
mcnk_shader.uniform_cached("layer_count", (int)texture_set->num());
|
||||
mcnk_shader.uniform_cached("cant_paint", (int)cantPaint);
|
||||
mcnk_shader.uniform("layer_count", (int)texture_set->num());
|
||||
mcnk_shader.uniform("cant_paint", (int)cantPaint);
|
||||
|
||||
if (draw_chunk_flag_overlay)
|
||||
{
|
||||
mcnk_shader.uniform_cached ("draw_impassible_flag", (int)header_flags.flags.impass);
|
||||
mcnk_shader.uniform ("draw_impassible_flag", (int)header_flags.flags.impass);
|
||||
}
|
||||
|
||||
if (draw_areaid_overlay)
|
||||
|
||||
@@ -2428,6 +2428,7 @@ MapView::MapView( math::degrees camera_yaw0
|
||||
setMouseTracking (true);
|
||||
setMinimumHeight(200);
|
||||
setMaximumHeight(10000);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||
|
||||
_context = noggit::NoggitRenderContext::MAP_VIEW;
|
||||
_transform_gizmo.setWorld(_world.get());
|
||||
@@ -2482,7 +2483,7 @@ MapView::MapView( math::degrees camera_yaw0
|
||||
|
||||
_startup_time.start();
|
||||
_update_every_event_loop.start (0);
|
||||
connect (&_update_every_event_loop, &QTimer::timeout, [this] { update(); });
|
||||
connect(&_update_every_event_loop, &QTimer::timeout,this, QOverload<>::of(&QOpenGLWidget::update));
|
||||
createGUI();
|
||||
}
|
||||
|
||||
@@ -3774,7 +3775,7 @@ selection_result MapView::intersect_result(bool terrain_only)
|
||||
}
|
||||
);
|
||||
|
||||
return results;
|
||||
return std::move(results);
|
||||
}
|
||||
|
||||
void MapView::doSelection (bool selectTerrainOnly, bool mouseMove)
|
||||
|
||||
@@ -1109,7 +1109,7 @@ void World::draw ( math::matrix_4x4 const& model_view
|
||||
// the flag stays on if the last chunk drawn before leaving the editing tool has it
|
||||
if (!draw_chunk_flag_overlay)
|
||||
{
|
||||
mcnk_shader.uniform_cached("draw_impassible_flag", 0);
|
||||
mcnk_shader.uniform("draw_impassible_flag", 0);
|
||||
}
|
||||
|
||||
mcnk_shader.uniform ("camera", camera_pos);
|
||||
@@ -1117,16 +1117,16 @@ void World::draw ( math::matrix_4x4 const& model_view
|
||||
|
||||
if (cursor_type != CursorType::NONE)
|
||||
{
|
||||
mcnk_shader.uniform_cached("draw_cursor_circle", static_cast<int>(cursor_type));
|
||||
mcnk_shader.uniform("draw_cursor_circle", static_cast<int>(cursor_type));
|
||||
mcnk_shader.uniform ("cursor_position", cursor_pos);
|
||||
mcnk_shader.uniform("cursorRotation", cursorRotation);
|
||||
mcnk_shader.uniform_cached ("outer_cursor_radius", brush_radius);
|
||||
mcnk_shader.uniform ("outer_cursor_radius", brush_radius);
|
||||
mcnk_shader.uniform ("inner_cursor_ratio", inner_radius_ratio);
|
||||
mcnk_shader.uniform ("cursor_color", cursor_color);
|
||||
}
|
||||
else
|
||||
{
|
||||
mcnk_shader.uniform_cached("draw_cursor_circle", 0);
|
||||
mcnk_shader.uniform("draw_cursor_circle", 0);
|
||||
}
|
||||
|
||||
mcnk_shader.uniform("tex_anim_0", math::vector_2d());
|
||||
@@ -1557,7 +1557,7 @@ selection_result World::intersect ( math::matrix_4x4 const& model_view
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
return std::move(results);
|
||||
}
|
||||
|
||||
void World::update_models_emitters(float dt)
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QSplashScreen>
|
||||
#include <QStyleFactory>
|
||||
#include "MakeshiftMt.hpp"
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
@@ -272,8 +271,9 @@ Noggit::Noggit(int argc, char *argv[])
|
||||
format.setVersion(4, 1);
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
//format.setOption(QSurfaceFormat::ResetNotification, true);
|
||||
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
|
||||
format.setSwapBehavior(QSurfaceFormat::TripleBuffer);
|
||||
format.setSwapInterval(settings.value ("vsync", 0).toInt());
|
||||
format.setRenderableType(QSurfaceFormat::OpenGL);
|
||||
|
||||
|
||||
if (doAntiAliasing)
|
||||
@@ -376,135 +376,6 @@ auto convert
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* command-line mode */
|
||||
if(argc > 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string rootStr;
|
||||
[[likely]]
|
||||
if
|
||||
(
|
||||
std::filesystem::path const root
|
||||
{std::filesystem::canonical(argv[1])}
|
||||
;
|
||||
std::filesystem::is_directory(root)
|
||||
)
|
||||
{
|
||||
std::vector<std::string_view> models;
|
||||
std::vector<std::string_view> wmos;
|
||||
convert(root.c_str(), &rootStr);
|
||||
|
||||
for(std::size_t i{2}; i < argc; ++i)
|
||||
{
|
||||
std::string_view const obj{argv[i]};
|
||||
|
||||
if(obj.ends_with(".m2") || obj.ends_with(".mdx"))
|
||||
models.emplace_back(obj);
|
||||
else if(obj.ends_with(".wmo"))
|
||||
wmos.emplace_back(obj);
|
||||
else
|
||||
{
|
||||
std::cerr << "E: Unknown object encountered with name '" << obj
|
||||
<< "'.\n";
|
||||
throw true;
|
||||
}
|
||||
|
||||
std::transform
|
||||
(
|
||||
argv[i],
|
||||
argv[i] + std::strlen(argv[i]),
|
||||
argv[i],
|
||||
[ ]
|
||||
( char c )
|
||||
constexpr
|
||||
-> char
|
||||
{ return c == '/' ? '\\' : std::toupper(c); }
|
||||
);
|
||||
}
|
||||
|
||||
std::cout << "I: Argument acquisition succeeded.\nI: Map root '"
|
||||
<< rootStr << "'.\n";
|
||||
|
||||
for(auto itr{models.cbegin()}; itr != models.cend(); ++itr)
|
||||
std::cout << "I: Defective model '"
|
||||
<< std::distance(models.cbegin(), itr) + 1
|
||||
<< "' with relative path '" << *itr << "'.\n";
|
||||
|
||||
for(auto itr{wmos.cbegin()}; itr != wmos.cend(); ++itr)
|
||||
std::cout << "I: Defective WMO '"
|
||||
<< std::distance(wmos.cbegin(), itr) + 1
|
||||
<< "' with relative path '" << *itr << "'.\n";
|
||||
|
||||
std::cout << "I: Repacking map...\n";
|
||||
std::size_t nTotModels{}, nTotObjects{}, nTiles{};
|
||||
std::string buf;
|
||||
|
||||
for(auto const& entry : std::filesystem::directory_iterator{root})
|
||||
if
|
||||
(
|
||||
std::string_view const path{convert(entry.path().c_str(), &buf)}
|
||||
;
|
||||
entry.is_regular_file()
|
||||
&&
|
||||
path.ends_with(".adt")
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::cout << "I: Reading tile '" << path << "'...\n";
|
||||
noggit::Recovery::MakeshiftMt mt{path, models, wmos};
|
||||
std::cout << "I: Writing tile '" << path << "'...\n";
|
||||
auto const [nModels, nObjects]{mt.save()};
|
||||
nTotModels += nModels;
|
||||
nTotObjects += nObjects;
|
||||
++nTiles;
|
||||
}
|
||||
catch ( std::ios::failure const& e )
|
||||
{
|
||||
std::cerr << "E: File operation failed on '" << path
|
||||
<< "' due to '" << e.what()
|
||||
<< "'. This file is not going to be processed.\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cout << "I: Skipping unrecognized filesystem entity '"
|
||||
<< path << "'.\n";
|
||||
|
||||
if(nTiles)
|
||||
std::cout << "I: Done repacking map of '" << nTiles
|
||||
<< "' tiles with '" << nTotModels
|
||||
<< "' defective model and '" << nTotObjects
|
||||
<< "' defective object deletions in total.\n";
|
||||
else
|
||||
std::cout
|
||||
<< "I: No repacking took place since no tiles were found.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "E: '" << rootStr << "' is not a directory.\n";
|
||||
throw true;
|
||||
}
|
||||
}
|
||||
catch ( std::filesystem::filesystem_error const& e )
|
||||
{
|
||||
std::string buf;
|
||||
std::cerr << "E: Failed to process path '"
|
||||
<< convert(e.path1().c_str(), &buf) << "' due to '" << e.what()
|
||||
<< "'.\n";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
noggit::RegisterErrorHandlers();
|
||||
std::set_terminate (noggit_terminate_handler);
|
||||
|
||||
|
||||
@@ -173,6 +173,10 @@ namespace opengl
|
||||
|
||||
gl.uniform1i (loc, value);
|
||||
}
|
||||
void use_program::uniform (GLint pos, GLint value)
|
||||
{
|
||||
gl.uniform1i (pos, value);
|
||||
}
|
||||
void use_program::uniform (std::string const& name, GLfloat value)
|
||||
{
|
||||
GLuint loc = uniform_location (name);
|
||||
@@ -181,6 +185,10 @@ namespace opengl
|
||||
|
||||
gl.uniform1f (loc, value);
|
||||
}
|
||||
void use_program::uniform (GLint pos, GLfloat value)
|
||||
{
|
||||
gl.uniform1f (pos, value);
|
||||
}
|
||||
void use_program::uniform (std::string const& name, bool value)
|
||||
{
|
||||
GLuint loc = uniform_location (name);
|
||||
@@ -189,6 +197,10 @@ namespace opengl
|
||||
|
||||
gl.uniform1i (loc, static_cast<int>(value));
|
||||
}
|
||||
void use_program::uniform (GLint pos, bool value)
|
||||
{
|
||||
gl.uniform1i (pos, static_cast<int>(value));
|
||||
}
|
||||
void use_program::uniform_cached(std::string const& name, GLint value)
|
||||
{
|
||||
GLuint loc = uniform_location (name);
|
||||
@@ -244,6 +256,10 @@ namespace opengl
|
||||
|
||||
gl.uniform1iv (loc, value.size(), value.data());
|
||||
}
|
||||
void use_program::uniform (GLint pos, std::vector<int> const& value)
|
||||
{
|
||||
gl.uniform1iv (pos, value.size(), value.data());
|
||||
}
|
||||
void use_program::uniform (std::string const& name, std::vector<math::vector_3d> const& value)
|
||||
{
|
||||
GLuint loc = uniform_location (name);
|
||||
@@ -252,6 +268,10 @@ namespace opengl
|
||||
|
||||
gl.uniform3fv (loc, value.size(), reinterpret_cast<const GLfloat*>(value.data()));
|
||||
}
|
||||
void use_program::uniform (GLint pos, std::vector<math::vector_3d> const& value)
|
||||
{
|
||||
gl.uniform3fv (pos, value.size(), reinterpret_cast<const GLfloat*>(value.data()));
|
||||
}
|
||||
void use_program::uniform (std::string const& name, math::vector_2d const& value)
|
||||
{
|
||||
GLuint loc = uniform_location (name);
|
||||
@@ -260,6 +280,10 @@ namespace opengl
|
||||
|
||||
gl.uniform2fv (loc, 1, value);
|
||||
}
|
||||
void use_program::uniform (GLint pos, math::vector_2d const& value)
|
||||
{
|
||||
gl.uniform2fv (pos, 1, value);
|
||||
}
|
||||
void use_program::uniform (std::string const& name, math::vector_3d const& value)
|
||||
{
|
||||
GLuint loc = uniform_location (name);
|
||||
@@ -268,6 +292,10 @@ namespace opengl
|
||||
|
||||
gl.uniform3fv (loc, 1, value);
|
||||
}
|
||||
void use_program::uniform (GLint pos, math::vector_3d const& value)
|
||||
{
|
||||
gl.uniform3fv (pos, 1, value);
|
||||
}
|
||||
void use_program::uniform (std::string const& name, math::vector_4d const& value)
|
||||
{
|
||||
GLuint loc = uniform_location (name);
|
||||
@@ -276,6 +304,10 @@ namespace opengl
|
||||
|
||||
gl.uniform4fv (loc, 1, value);
|
||||
}
|
||||
void use_program::uniform (GLint pos, math::vector_4d const& value)
|
||||
{
|
||||
gl.uniform4fv (pos, 1, value);
|
||||
}
|
||||
void use_program::uniform (std::string const& name, math::matrix_4x4 const& value)
|
||||
{
|
||||
GLuint loc = uniform_location (name);
|
||||
@@ -284,6 +316,10 @@ namespace opengl
|
||||
|
||||
gl.uniformMatrix4fv (loc, 1, GL_FALSE, value);
|
||||
}
|
||||
void use_program::uniform (GLint pos, math::matrix_4x4 const& value)
|
||||
{
|
||||
gl.uniformMatrix4fv(pos, 1, GL_FALSE, value);
|
||||
}
|
||||
|
||||
void use_program::sampler (std::string const& name, GLenum texture_slot, texture* tex)
|
||||
{
|
||||
|
||||
@@ -91,14 +91,23 @@ namespace opengl
|
||||
|
||||
void bind_uniform_block(std::string const& name, unsigned);
|
||||
void uniform (std::string const& name, std::vector<int> const&);
|
||||
void uniform (GLint pos, std::vector<int> const&);
|
||||
void uniform (std::string const& name, GLint);
|
||||
void uniform (GLint pos, GLint);
|
||||
void uniform (std::string const& name, GLfloat);
|
||||
void uniform (GLint pos, GLfloat);
|
||||
void uniform (std::string const& name, bool);
|
||||
void uniform (GLint pos, bool);
|
||||
void uniform (std::string const& name, std::vector<math::vector_3d> const& value);
|
||||
void uniform (GLint pos, std::vector<math::vector_3d> const& value);
|
||||
void uniform (std::string const& name, math::vector_2d const&);
|
||||
void uniform (GLint pos, math::vector_2d const&);
|
||||
void uniform (std::string const& name, math::vector_3d const&);
|
||||
void uniform (GLint pos, math::vector_3d const&);
|
||||
void uniform (std::string const& name, math::vector_4d const&);
|
||||
void uniform (GLint pos, math::vector_4d const&);
|
||||
void uniform (std::string const& name, math::matrix_4x4 const&);
|
||||
void uniform (GLint pos, math::matrix_4x4 const&);
|
||||
template<typename T> void uniform (std::string const&, T) = delete;
|
||||
|
||||
void uniform_cached (std::string const& name, GLint);
|
||||
|
||||
@@ -48,4 +48,5 @@ namespace opengl
|
||||
float wireframe_width;
|
||||
math::vector_4d wireframe_color;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user