mirror of
https://github.com/borgesdan/xn65
synced 2024-12-29 21:54:47 +01:00
commit
9faca789fe
@ -10,11 +10,13 @@ if (POLICY CMP0141)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# CMAKE_TOOLCHAIN_FILE
|
# CMAKE_TOOLCHAIN_FILE
|
||||||
include("C:/vcpkg/scripts/buildsystems/vcpkg.cmake")
|
set(PROJECT_VCPKG_DIRECTORY "C:/vcpkg")
|
||||||
|
set(PROJECT_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/inc")
|
||||||
|
include("${PROJECT_VCPKG_DIRECTORY}/scripts/buildsystems/vcpkg.cmake")
|
||||||
project ("xna")
|
project ("xna")
|
||||||
|
|
||||||
# Include sub-projects.
|
# Include sub-projects.
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
|
include_directories(${PROJECT_INCLUDE_DIR})
|
||||||
add_subdirectory ("framework")
|
add_subdirectory ("framework")
|
||||||
add_subdirectory ("samples")
|
add_subdirectory ("samples")
|
||||||
|
|
||||||
|
@ -4,14 +4,13 @@
|
|||||||
|
|
||||||
# Add source to this project's executable.
|
# Add source to this project's executable.
|
||||||
add_library (Xn65 STATIC
|
add_library (Xn65 STATIC
|
||||||
"../samples/01_blank/xna.cpp"
|
|
||||||
"csharp/stream.cpp"
|
"csharp/stream.cpp"
|
||||||
"game/component.cpp"
|
"game/component.cpp"
|
||||||
"content/manager.cpp"
|
"content/manager.cpp"
|
||||||
"content/reader.cpp"
|
"content/reader.cpp"
|
||||||
"csharp/binary.cpp"
|
"csharp/binary.cpp"
|
||||||
"content/lzx/decoder.cpp"
|
"content/lzx/decoder.cpp"
|
||||||
"content/lzx/decoderstream.cpp"
|
|
||||||
"content/typereadermanager.cpp"
|
"content/typereadermanager.cpp"
|
||||||
"csharp/object.cpp"
|
"csharp/object.cpp"
|
||||||
"csharp/type.cpp"
|
"csharp/type.cpp"
|
||||||
@ -52,4 +51,7 @@ endif()
|
|||||||
|
|
||||||
find_package(directxtk CONFIG REQUIRED)
|
find_package(directxtk CONFIG REQUIRED)
|
||||||
|
|
||||||
target_link_libraries(Xn65 D3d11.lib dxgi.lib dxguid.lib d3dcompiler.lib Microsoft::DirectXTK)
|
target_link_libraries(
|
||||||
|
Xn65 D3d11.lib dxgi.lib dxguid.lib d3dcompiler.lib Microsoft::DirectXTK
|
||||||
|
"${PROJECT_INCLUDE_DIR}/libmspack/mspack.lib"
|
||||||
|
)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "common/collision.hpp"
|
#include "xna/common/collision.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
Plane::Plane(Vector3 const& point1, Vector3 const& point2, Vector3 const& point3) {
|
Plane::Plane(Vector3 const& point1, Vector3 const& point2, Vector3 const& point3) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "common/color.hpp"
|
#include "xna/common/color.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
Color::Color(float r, float g, float b, float a) :
|
Color::Color(float r, float g, float b, float a) :
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "common/gjk.hpp"
|
#include "xna/common/gjk.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
Vector3 Gjk::ComputeClosestPoint() {
|
Vector3 Gjk::ComputeClosestPoint() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "common/numerics.hpp"
|
#include "xna/common/numerics.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
bool Vector2::Transform(Vector2 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength) {
|
bool Vector2::Transform(Vector2 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "common/packedvalue.hpp"
|
#include "xna/common/packedvalue.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
Uint PackUtils::PackUnsigned(float bitmask, float value) {
|
Uint PackUtils::PackUnsigned(float bitmask, float value) {
|
||||||
|
@ -1,5 +1,45 @@
|
|||||||
#include "content/lzx/decoder.hpp"
|
#include "xna/content/lzx/decoder.hpp"
|
||||||
|
#include "libmspack/mspack.h"
|
||||||
|
#include "libmspack/lzx.h"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
|
LzxDecoder::LzxDecoder(int window) {
|
||||||
|
if (window < 15 || window > 21)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window_bits = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LzxDecoder::Decompress(Stream* inData, int inLen, Stream* outData, int outLen) {
|
||||||
|
auto input = reinterpret_cast<mspack_file*>(inData->Data());
|
||||||
|
auto output = reinterpret_cast<mspack_file*>(outData->Data());
|
||||||
|
|
||||||
|
auto lzxstream = lzxd_init(
|
||||||
|
//struct mspack_system* system,
|
||||||
|
nullptr,
|
||||||
|
//struct mspack_file* input,
|
||||||
|
input + inData->Position(),
|
||||||
|
//struct mspack_file* output,
|
||||||
|
output + outData->Position(),
|
||||||
|
//int window_bits,
|
||||||
|
window_bits,
|
||||||
|
//int reset_interval,
|
||||||
|
0,
|
||||||
|
//int input_buffer_size,
|
||||||
|
inLen,
|
||||||
|
//off_t output_length,
|
||||||
|
outLen,
|
||||||
|
//char is_delta
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
auto result = lzxd_decompress(
|
||||||
|
//struct lzxd_stream* lzx,
|
||||||
|
lzxstream,
|
||||||
|
//off_t out_bytes
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,40 +0,0 @@
|
|||||||
#include "content/lzx/decoderstream.hpp"
|
|
||||||
|
|
||||||
namespace xna {
|
|
||||||
Int LzxDecoderStream::Length()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Long LzxDecoderStream::Position()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
void LzxDecoderStream::Close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
Long LzxDecoderStream::Seek(Long offset, SeekOrigin const& origin)
|
|
||||||
{
|
|
||||||
return Long();
|
|
||||||
}
|
|
||||||
Int LzxDecoderStream::Read(Byte* buffer, Int bufferLength, Int offset, Int count)
|
|
||||||
{
|
|
||||||
return decompressedStream->Read(buffer, bufferLength, offset, count);
|
|
||||||
}
|
|
||||||
Int LzxDecoderStream::Read(std::vector<Byte>& buffer, Int offset, Int count)
|
|
||||||
{
|
|
||||||
return decompressedStream->Read(buffer, offset, count);
|
|
||||||
}
|
|
||||||
Int LzxDecoderStream::ReadByte()
|
|
||||||
{
|
|
||||||
return Int();
|
|
||||||
}
|
|
||||||
void LzxDecoderStream::Write(Byte const* buffer, Int bufferLength, Int offset, Int count)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void LzxDecoderStream::Write(std::vector<Byte> const& buffer, Int offset, Int count)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void LzxDecoderStream::WriteByte(Byte value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +1,13 @@
|
|||||||
#include "content/manager.hpp"
|
#include "xna/content/manager.hpp"
|
||||||
|
|
||||||
|
namespace xna {
|
||||||
|
sptr<Stream> ContentManager::OpenStream(String const& assetName) const {
|
||||||
|
const String filePath = _rootDirectory + "\\" + assetName + contentExtension;
|
||||||
|
const auto stream = New<FileStream>(filePath, FileMode::Open);
|
||||||
|
|
||||||
|
if (stream->IsClosed())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return reinterpret_pointer_cast<Stream>(stream);
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,19 @@
|
|||||||
#include "content/reader.hpp"
|
#include "xna/content/reader.hpp"
|
||||||
#include "content/manager.hpp"
|
#include "xna/content/manager.hpp"
|
||||||
#include "content/lzx/decoderstream.hpp"
|
#include "xna/content/typereadermanager.hpp"
|
||||||
#include "content/typereadermanager.hpp"
|
|
||||||
#include "content/manager.hpp"
|
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
sptr<ContentReader> ContentReader::Create(ContentManager* contentManager, sptr<Stream>& input, String const& assetName)
|
sptr<ContentReader> ContentReader::Create(sptr<xna::ContentManager> const& contentManager, sptr<Stream>& input, String const& assetName)
|
||||||
{
|
{
|
||||||
Int graphicsProfile = 0;
|
Int graphicsProfile = 0;
|
||||||
input = ContentReader::PrepareStream(input, assetName, graphicsProfile);
|
input = ContentReader::PrepareStream(input, assetName, graphicsProfile);
|
||||||
return std::shared_ptr<ContentReader>(new ContentReader(contentManager, input, assetName, graphicsProfile));
|
return std::shared_ptr<ContentReader>(new ContentReader(contentManager, input, assetName, graphicsProfile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sptr<ContentManager> ContentReader::ContentManager() const {
|
||||||
|
return _contentManager;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 ContentReader::ReadVector2()
|
Vector2 ContentReader::ReadVector2()
|
||||||
{
|
{
|
||||||
Vector2 vector2;
|
Vector2 vector2;
|
||||||
@ -89,27 +91,23 @@ namespace xna {
|
|||||||
return *(double*)&int64;
|
return *(double*)&int64;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Byte> ContentReader::ReadByteBuffer(size_t size, xna_error_ptr_arg)
|
std::vector<Byte> ContentReader::ReadByteBuffer(size_t size)
|
||||||
{
|
{
|
||||||
std::vector<Byte>& buffer = _contentManager->byteBuffer;
|
if (byteBuffer.empty() || byteBuffer.size() < size)
|
||||||
|
|
||||||
if (buffer.empty() || buffer.size() < size)
|
|
||||||
{
|
{
|
||||||
buffer = std::vector<Byte>(size);
|
byteBuffer.resize(size);
|
||||||
//_contentManager->byteBuffer = buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Int num = 0;
|
Int num = 0;
|
||||||
for (size_t index = 0; index < size; index += num)
|
for (size_t index = 0; index < size; index += num)
|
||||||
{
|
{
|
||||||
num = Read(buffer, index, size - index);
|
num = Read(byteBuffer, index, size - index);
|
||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
|
throw std::runtime_error("ContentReader::ReadByteBuffer: Bad xbn.");
|
||||||
return std::vector<Byte>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return byteBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
sptr<Stream> ContentReader::PrepareStream(sptr<Stream>& input, String const& assetName, Int& graphicsProfile)
|
sptr<Stream> ContentReader::PrepareStream(sptr<Stream>& input, String const& assetName, Int& graphicsProfile)
|
||||||
@ -117,15 +115,16 @@ namespace xna {
|
|||||||
BinaryReader binaryReader = BinaryReader(input);
|
BinaryReader binaryReader = BinaryReader(input);
|
||||||
|
|
||||||
if (binaryReader.ReadByte() != 'X' || binaryReader.ReadByte() != 'N' || binaryReader.ReadByte() != 'B')
|
if (binaryReader.ReadByte() != 'X' || binaryReader.ReadByte() != 'N' || binaryReader.ReadByte() != 'B')
|
||||||
return nullptr;
|
throw std::runtime_error("ContentReader::PrepareStream: Bad xbn platform.");
|
||||||
|
|
||||||
Int num1 = 0;
|
Int num1 = 0;
|
||||||
auto _byte = binaryReader.ReadByte(); //desfazer
|
auto wbyte = binaryReader.ReadByte();
|
||||||
if (_byte == 'w')
|
|
||||||
num1 = binaryReader.ReadUInt16();
|
if(wbyte != 'w')
|
||||||
else
|
|
||||||
throw std::runtime_error("ContentReader::PrepareStream: Bad xbn file.");
|
throw std::runtime_error("ContentReader::PrepareStream: Bad xbn file.");
|
||||||
|
|
||||||
|
num1 = binaryReader.ReadUInt16();
|
||||||
|
|
||||||
graphicsProfile = (num1 & XnbVersionProfileMask) >> XnbVersionProfileShift;
|
graphicsProfile = (num1 & XnbVersionProfileMask) >> XnbVersionProfileShift;
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
|
|
||||||
@ -138,13 +137,13 @@ namespace xna {
|
|||||||
flag = true;
|
flag = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
throw std::runtime_error("ContentReader::PrepareStream: Bad xbn version.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto num2 = binaryReader.ReadInt32();
|
const auto num2 = binaryReader.ReadInt32();
|
||||||
|
|
||||||
if ((num2 - 10) > input->Length() - input->Position())
|
if ((static_cast<Long>(num2) - 10) > input->Length() - input->Position())
|
||||||
return nullptr;
|
throw std::runtime_error("ContentReader::PrepareStream: Bad xbn size.");
|
||||||
|
|
||||||
if (!flag)
|
if (!flag)
|
||||||
return input;
|
return input;
|
||||||
@ -152,20 +151,13 @@ namespace xna {
|
|||||||
const Int compressedTodo = num2 - 14;
|
const Int compressedTodo = num2 - 14;
|
||||||
const auto decompressedTodo = binaryReader.ReadInt32();
|
const auto decompressedTodo = binaryReader.ReadInt32();
|
||||||
|
|
||||||
auto lzxStream = New<LzxDecoderStream>(input, compressedTodo, decompressedTodo);
|
throw std::runtime_error("ContentReader::PrepareStream: LzxDecoder not implemented.");
|
||||||
|
|
||||||
return reinterpret_pointer_cast<Stream>(lzxStream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Int ContentReader::ReadHeader() {
|
Int ContentReader::ReadHeader() {
|
||||||
auto _this = shared_from_this();
|
auto _this = shared_from_this();
|
||||||
typeReaders = ContentTypeReaderManager::ReadTypeManifest(this->Read7BitEncodedInt(), _this);
|
typeReaders = ContentTypeReaderManager::ReadTypeManifest(this->Read7BitEncodedInt(), _this);
|
||||||
auto length = this->Read7BitEncodedInt();
|
auto length = this->Read7BitEncodedInt();
|
||||||
|
|
||||||
if (length > 0)
|
|
||||||
{
|
|
||||||
//TODO: length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
|
|
||||||
|
@ -1,9 +1,39 @@
|
|||||||
#include "content/typereadermanager.hpp"
|
#include "xna/content/typereadermanager.hpp"
|
||||||
#include "content/reader.hpp"
|
#include "xna/content/reader.hpp"
|
||||||
#include "content/readers/default.hpp"
|
#include "xna/content/readers/default.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
std::vector<PContentTypeReader> ContentTypeReaderManager::ReadTypeManifest(Int typeCount, sptr<ContentReader>& contentReader, xna_error_ptr_arg)
|
|
||||||
|
sptr<ContentTypeReader> ContentTypeReaderActivador::CreateInstance(sptr<Type> const& type) {
|
||||||
|
if (!type)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("ContentTypeReaderActivador: type is null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto hash = type->GetHashCode();
|
||||||
|
|
||||||
|
if (!activators.contains(hash))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto activador = activators[hash];
|
||||||
|
|
||||||
|
if (!activador) return nullptr;
|
||||||
|
|
||||||
|
return activador();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentTypeReaderActivador::SetActivador(sptr<Type> const& type, Activador activador) {
|
||||||
|
if (!type) {
|
||||||
|
throw std::invalid_argument("ContentTypeReaderActivador: type is null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto hash = type->GetHashCode();
|
||||||
|
|
||||||
|
if (!activators.contains(hash))
|
||||||
|
activators.insert({ hash, activador });
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PContentTypeReader> ContentTypeReaderManager::ReadTypeManifest(Int typeCount, sptr<ContentReader>& contentReader)
|
||||||
{
|
{
|
||||||
initMaps();
|
initMaps();
|
||||||
|
|
||||||
@ -18,8 +48,7 @@ namespace xna {
|
|||||||
|
|
||||||
auto typeReader = ContentTypeReaderManager::GetTypeReader(xnaType.empty() ? readerTypeName : xnaType, contentReader, newTypeReaders);
|
auto typeReader = ContentTypeReaderManager::GetTypeReader(xnaType.empty() ? readerTypeName : xnaType, contentReader, newTypeReaders);
|
||||||
|
|
||||||
if (contentReader->ReadInt32() != typeReader->TypeVersion()) {
|
if (contentReader->ReadInt32() != typeReader->TypeVersion()) {
|
||||||
xna_error_apply(err, XnaErrorCode::BAD_TYPE);
|
|
||||||
ContentTypeReaderManager::RollbackAddReaders(newTypeReaders);
|
ContentTypeReaderManager::RollbackAddReaders(newTypeReaders);
|
||||||
return std::vector<PContentTypeReader>();
|
return std::vector<PContentTypeReader>();
|
||||||
}
|
}
|
||||||
@ -39,11 +68,10 @@ namespace xna {
|
|||||||
return contentTypeReaderArray;
|
return contentTypeReaderArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
sptr<ContentTypeReader> ContentTypeReaderManager::GetTypeReader(sptr<Type> const& targetType, sptr<ContentReader>& contentReader, xna_error_ptr_arg)
|
sptr<ContentTypeReader> ContentTypeReaderManager::GetTypeReader(sptr<Type> const& targetType)
|
||||||
{
|
{
|
||||||
if (!targetType) {
|
if (!targetType) {
|
||||||
xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL);
|
throw std::invalid_argument("ContentTypeReaderManager::GetTypeReader: targetType is null.");
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& item : ContentTypeReaderManager::targetTypeToReader) {
|
for (auto const& item : ContentTypeReaderManager::targetTypeToReader) {
|
||||||
@ -61,30 +89,25 @@ namespace xna {
|
|||||||
initMaps();
|
initMaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
sptr<ContentTypeReader> ContentTypeReaderManager::GetTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, std::vector<PContentTypeReader>& newTypeReaders, xna_error_ptr_arg)
|
sptr<ContentTypeReader> ContentTypeReaderManager::GetTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, std::vector<PContentTypeReader>& newTypeReaders)
|
||||||
{
|
{
|
||||||
sptr<ContentTypeReader> reader = nullptr;
|
sptr<ContentTypeReader> reader = nullptr;
|
||||||
|
|
||||||
if (ContentTypeReaderManager::nameToReader.contains(readerTypeName)) {
|
if (ContentTypeReaderManager::nameToReader.contains(readerTypeName)) {
|
||||||
return ContentTypeReaderManager::nameToReader[readerTypeName];
|
return ContentTypeReaderManager::nameToReader[readerTypeName];
|
||||||
}
|
}
|
||||||
else if (!ContentTypeReaderManager::InstantiateTypeReader(readerTypeName, contentReader, reader, err)) {
|
else if (!ContentTypeReaderManager::InstantiateTypeReader(readerTypeName, contentReader, reader)) {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xna_error_haserros(err))
|
ContentTypeReaderManager::AddTypeReader(readerTypeName, contentReader, reader);
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
ContentTypeReaderManager::AddTypeReader(readerTypeName, contentReader, reader, err);
|
|
||||||
|
|
||||||
if (xna_error_haserros(err)) return nullptr;
|
|
||||||
|
|
||||||
newTypeReaders.push_back(reader);
|
newTypeReaders.push_back(reader);
|
||||||
|
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContentTypeReaderManager::InstantiateTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_ptr_arg)
|
bool ContentTypeReaderManager::InstantiateTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader)
|
||||||
{
|
{
|
||||||
sptr<Type> type = nullptr;
|
sptr<Type> type = nullptr;
|
||||||
|
|
||||||
@ -92,8 +115,7 @@ namespace xna {
|
|||||||
type = Type::NameOfRegisteredTypes[readerTypeName];
|
type = Type::NameOfRegisteredTypes[readerTypeName];
|
||||||
|
|
||||||
if (!type) {
|
if (!type) {
|
||||||
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
throw std::runtime_error("ContentTypeReaderManager::InstantiateTypeReader: registered type is null.");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ContentTypeReaderManager::readerTypeToReader.contains(type)) {
|
if (ContentTypeReaderManager::readerTypeToReader.contains(type)) {
|
||||||
@ -102,16 +124,15 @@ namespace xna {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
reader = ContentTypeReaderActivador::CreateInstance(type, err);
|
reader = ContentTypeReaderActivador::CreateInstance(type);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentTypeReaderManager::AddTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_ptr_arg)
|
void ContentTypeReaderManager::AddTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader)
|
||||||
{
|
{
|
||||||
auto targetType = reader->TargetType();
|
auto targetType = reader->TargetType();
|
||||||
|
|
||||||
if (ContentTypeReaderManager::targetTypeToReader.contains(targetType)) {
|
if (ContentTypeReaderManager::targetTypeToReader.contains(targetType)) {
|
||||||
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +147,7 @@ namespace xna {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (size_t i = 0; i < newTypeReaders.size(); ++i) {
|
for (size_t i = 0; i < newTypeReaders.size(); ++i) {
|
||||||
auto newTypeReader = newTypeReaders[i];
|
auto& newTypeReader = newTypeReaders[i];
|
||||||
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::nameToReader, newTypeReader);
|
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::nameToReader, newTypeReader);
|
||||||
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::targetTypeToReader, newTypeReader);
|
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::targetTypeToReader, newTypeReader);
|
||||||
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::readerTypeToReader, newTypeReader);
|
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::readerTypeToReader, newTypeReader);
|
||||||
@ -143,4 +164,26 @@ namespace xna {
|
|||||||
readerTypeToReader.insert({ typeof<ObjectReader>(), contentTypeReader});
|
readerTypeToReader.insert({ typeof<ObjectReader>(), contentTypeReader});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContentTypeReaderManager::RollbackAddReader(std::map<String, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader) {
|
||||||
|
std::map<String, sptr<ContentTypeReader>>::iterator it;
|
||||||
|
|
||||||
|
for (it = dictionary.begin(); it != dictionary.end(); it++) {
|
||||||
|
if (it->second == reader) {
|
||||||
|
dictionary.erase(it->first);
|
||||||
|
it = dictionary.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentTypeReaderManager::RollbackAddReader(std::map<PType, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader) {
|
||||||
|
std::map<PType, sptr<ContentTypeReader>>::iterator it;
|
||||||
|
|
||||||
|
for (it = dictionary.begin(); it != dictionary.end(); it++) {
|
||||||
|
if (it->second == reader) {
|
||||||
|
dictionary.erase(it->first);
|
||||||
|
it = dictionary.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
#include "csharp/binary.hpp"
|
#include "xna/csharp/binary.hpp"
|
||||||
#include "csharp/buffer.hpp"
|
#include "xna/csharp/buffer.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
Int BinaryReader::PeekChar()
|
Int BinaryReader::PeekChar()
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include "csharp/object.hpp"
|
#include "xna/csharp/object.hpp"
|
||||||
#include "csharp/type.hpp"
|
#include "xna/csharp/type.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
size_t Object::GetHashCode() const
|
size_t Object::GetHashCode() const
|
||||||
{
|
{
|
||||||
size_t seed = 0;
|
size_t seed = 0;
|
||||||
XnaHHashCombine(seed, this);
|
XnaHelper::HashCombine(seed, this);
|
||||||
|
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "csharp/stream.hpp"
|
#include "xna/csharp/stream.hpp"
|
||||||
#include "csharp/buffer.hpp"
|
#include "xna/csharp/buffer.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
Long MemoryStream::Seek(Long offset, SeekOrigin const& origin) {
|
Long MemoryStream::Seek(Long offset, SeekOrigin const& origin) {
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#include "csharp/type.hpp"
|
#include "xna/csharp/type.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
size_t Type::GetHashCode() const
|
size_t Type::GetHashCode() const
|
||||||
{
|
{
|
||||||
size_t seed = 0;
|
size_t seed = 0;
|
||||||
XnaHHashCombine(seed, fullName);
|
XnaHelper::HashCombine(seed, fullName);
|
||||||
XnaHHashCombine(seed, isClass);
|
XnaHelper::HashCombine(seed, isClass);
|
||||||
XnaHHashCombine(seed, isEnum);
|
XnaHelper::HashCombine(seed, isEnum);
|
||||||
XnaHHashCombine(seed, isValueType);
|
XnaHelper::HashCombine(seed, isValueType);
|
||||||
XnaHHashCombine(seed, isPrimitive);
|
XnaHelper::HashCombine(seed, isPrimitive);
|
||||||
|
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "game/component.hpp"
|
#include "xna/game/component.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
sptr<IGameComponent> GameComponentCollection::operator[](size_t index) const
|
sptr<IGameComponent> GameComponentCollection::operator[](size_t index) const
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "game/servicecontainer.hpp"
|
#include "xna/game/servicecontainer.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
void GameServiceContainer::AddService(Type& type, std::any& provider)
|
void GameServiceContainer::AddService(Type& type, std::any& provider)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include "graphics/adapter.hpp"
|
#include "xna/graphics/adapter.hpp"
|
||||||
#include "graphics/displaymode.hpp"
|
#include "xna/graphics/displaymode.hpp"
|
||||||
#include "platform-dx/headers.hpp"
|
#include "xna/platform-dx/headers.hpp"
|
||||||
#include "platform-dx/helpers.hpp"
|
#include "xna/platform-dx/helpers.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "game/gdevicemanager.hpp"
|
#include "xna/game/gdevicemanager.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
static size_t getDisplayModesCount(IDXGIAdapter* adapter);
|
static size_t getDisplayModesCount(IDXGIAdapter* adapter);
|
||||||
@ -89,7 +89,7 @@ namespace xna {
|
|||||||
|
|
||||||
DXGI_ADAPTER_DESC1 desc;
|
DXGI_ADAPTER_DESC1 desc;
|
||||||
impl->dxadapter->GetDesc1(&desc);
|
impl->dxadapter->GetDesc1(&desc);
|
||||||
String description = XnaHToString(desc.Description);
|
String description = XnaHelper::ToString(desc.Description);
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ namespace xna {
|
|||||||
|
|
||||||
if (impl->dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
|
if (impl->dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
|
||||||
pOutput->GetDesc(&outputDesc);
|
pOutput->GetDesc(&outputDesc);
|
||||||
String deviceName = XnaHToString(outputDesc.DeviceName);
|
String deviceName = XnaHelper::ToString(outputDesc.DeviceName);
|
||||||
|
|
||||||
pOutput->Release();
|
pOutput->Release();
|
||||||
pOutput = nullptr;
|
pOutput = nullptr;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
void AudioEngine::Initialize() {
|
void AudioEngine::Initialize() {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include "graphics/blendstate.hpp"
|
#include "xna/graphics/blendstate.hpp"
|
||||||
#include "graphics/gresource.hpp"
|
#include "xna/graphics/gresource.hpp"
|
||||||
#include "platform-dx/headers.hpp"
|
#include "xna/platform-dx/headers.hpp"
|
||||||
#include "platform-dx/helpers.hpp"
|
#include "xna/platform-dx/helpers.hpp"
|
||||||
#include "graphics/blendstate.hpp"
|
#include "xna/graphics/blendstate.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
BlendState::BlendState() : GraphicsResource(nullptr) {
|
BlendState::BlendState() : GraphicsResource(nullptr) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "graphics/buffer.hpp"
|
#include "xna/graphics/buffer.hpp"
|
||||||
#include "common/numerics.hpp"
|
#include "xna/common/numerics.hpp"
|
||||||
#include "platform-dx/headers.hpp"
|
#include "xna/platform-dx/headers.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
ConstantBuffer::ConstantBuffer() : GraphicsResource(nullptr){
|
ConstantBuffer::ConstantBuffer() : GraphicsResource(nullptr){
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "graphics/depthstencilstate.hpp"
|
#include "xna/graphics/depthstencilstate.hpp"
|
||||||
#include "platform-dx/headers.hpp"
|
#include "xna/platform-dx/headers.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
static D3D11_DEPTH_STENCIL_DESC defaultDesc() {
|
static D3D11_DEPTH_STENCIL_DESC defaultDesc() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "game/gdevicemanager.hpp"
|
#include "xna/game/gdevicemanager.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
void reset(GraphicsDevice::PlatformImplementation& impl)
|
void reset(GraphicsDevice::PlatformImplementation& impl)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "graphics/displaymode.hpp"
|
#include "xna/graphics/displaymode.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
DisplayMode::DisplayMode() {
|
DisplayMode::DisplayMode() {
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
#include "csharp/type.hpp"
|
#include "xna/csharp/type.hpp"
|
||||||
#include "game/time.hpp"
|
#include "xna/game/time.hpp"
|
||||||
#include "game/component.hpp"
|
#include "xna/game/component.hpp"
|
||||||
#include "game/servicecontainer.hpp"
|
#include "xna/game/servicecontainer.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "game/gdevicemanager.hpp"
|
#include "xna/game/gdevicemanager.hpp"
|
||||||
#include "content/manager.hpp"
|
#include "xna/content/manager.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
Game::Game() {
|
Game::Game() {
|
||||||
impl = unew<PlatformImplementation>();
|
impl = unew<PlatformImplementation>();
|
||||||
services = New<GameServiceContainer>();
|
services = New<GameServiceContainer>();
|
||||||
auto iservice = reinterpret_pointer_cast<IServiceProvider>(services);
|
auto iservice = reinterpret_pointer_cast<IServiceProvider>(services);
|
||||||
_contentManager = New<ContentManager>("", services);
|
_contentManager = New<ContentManager>(services, "");
|
||||||
|
_contentManager->_gameServices = iservice;
|
||||||
|
|
||||||
_gameWindow = New<GameWindow>();
|
_gameWindow = New<GameWindow>();
|
||||||
_gameWindow->impl->Color(146, 150, 154);
|
_gameWindow->impl->Color(146, 150, 154);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "input/gamepad.hpp"
|
#include "xna/input/gamepad.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
void GamePad::Initialize() {
|
void GamePad::Initialize() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "game/gdevicemanager.hpp"
|
#include "xna/game/gdevicemanager.hpp"
|
||||||
#include "graphics/presentparams.hpp"
|
#include "xna/graphics/presentparams.hpp"
|
||||||
#include "graphics/swapchain.hpp"
|
#include "xna/graphics/swapchain.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
GraphicsDeviceManager::GraphicsDeviceManager(sptr<Game> const& game) : _game(game)
|
GraphicsDeviceManager::GraphicsDeviceManager(sptr<Game> const& game) : _game(game)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#include "platform-dx/init.hpp"
|
#include "xna/platform-dx/init.hpp"
|
||||||
#include "csharp/type.hpp"
|
#include "xna/csharp/type.hpp"
|
||||||
#include "content/readers/graphics.hpp"
|
#include "xna/content/readers/graphics.hpp"
|
||||||
#include "content/readers/audio.hpp"
|
#include "xna/content/readers/audio.hpp"
|
||||||
#include "content/typereadermanager.hpp"
|
#include "xna/content/typereadermanager.hpp"
|
||||||
#include "content/readers/default.hpp"
|
#include "xna/content/readers/default.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
void Platform::Init() {
|
void Platform::Init() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "input/keyboard.hpp"
|
#include "xna/input/keyboard.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
KeyboardState Keyboard::GetState() {
|
KeyboardState Keyboard::GetState() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "input/mouse.hpp"
|
#include "xna/input/mouse.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
MouseState Mouse::GetState() {
|
MouseState Mouse::GetState() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "graphics/rasterizerstate.hpp"
|
#include "xna/graphics/rasterizerstate.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
RenderTarget2D::RenderTarget2D() : Texture2D() {
|
RenderTarget2D::RenderTarget2D() : Texture2D() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "graphics/samplerstate.hpp"
|
#include "xna/graphics/samplerstate.hpp"
|
||||||
#include "graphics/samplerstate.hpp"
|
#include "xna/graphics/samplerstate.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "platform-dx/helpers.hpp"
|
#include "xna/platform-dx/helpers.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
SamplerState::SamplerState() : GraphicsResource(nullptr) {
|
SamplerState::SamplerState() : GraphicsResource(nullptr) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "graphics/buffer.hpp"
|
#include "xna/graphics/buffer.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "graphics/shader.hpp"
|
#include "xna/graphics/shader.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
static HRESULT shaderCompileFromFile(_In_ LPCWSTR srcFile, _In_ LPCSTR entryPoint, _In_ LPCSTR profile, _Outptr_ ID3DBlob** blob)
|
static HRESULT shaderCompileFromFile(_In_ LPCWSTR srcFile, _In_ LPCSTR entryPoint, _In_ LPCSTR profile, _Outptr_ ID3DBlob** blob)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "csharp/stream.hpp"
|
#include "xna/csharp/stream.hpp"
|
||||||
|
|
||||||
using DxSoundEffect = DirectX::SoundEffect;
|
using DxSoundEffect = DirectX::SoundEffect;
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ namespace xna {
|
|||||||
if (!AudioEngine::impl || !AudioEngine::impl->_dxAudioEngine)
|
if (!AudioEngine::impl || !AudioEngine::impl->_dxAudioEngine)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto file = XnaHToWString(fileName);
|
const auto file = XnaHelper::ToWString(fileName);
|
||||||
impl->_dxSoundEffect = unew<DxSoundEffect>(AudioEngine::impl->_dxAudioEngine.get(), file.c_str());
|
impl->_dxSoundEffect = unew<DxSoundEffect>(AudioEngine::impl->_dxAudioEngine.get(), file.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include "graphics/rasterizerstate.hpp"
|
#include "xna/graphics/rasterizerstate.hpp"
|
||||||
#include "graphics/samplerstate.hpp"
|
#include "xna/graphics/samplerstate.hpp"
|
||||||
#include "common/color.hpp"
|
#include "xna/common/color.hpp"
|
||||||
#include "common/numerics.hpp"
|
#include "xna/common/numerics.hpp"
|
||||||
#include "graphics/sprite.hpp"
|
#include "xna/graphics/sprite.hpp"
|
||||||
#include "graphics/viewport.hpp"
|
#include "xna/graphics/viewport.hpp"
|
||||||
#include "graphics/blendstate.hpp"
|
#include "xna/graphics/blendstate.hpp"
|
||||||
#include "graphics/depthstencilstate.hpp"
|
#include "xna/graphics/depthstencilstate.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
using DxSpriteBatch = DirectX::SpriteBatch;
|
using DxSpriteBatch = DirectX::SpriteBatch;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "platform-dx/helpers.hpp"
|
#include "xna/platform-dx/helpers.hpp"
|
||||||
#include "graphics/adapter.hpp"
|
#include "xna/graphics/adapter.hpp"
|
||||||
#include "graphics/swapchain.hpp"
|
#include "xna/graphics/swapchain.hpp"
|
||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "graphics/device.hpp"
|
#include "xna/graphics/device.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
SwapChain::SwapChain() : GraphicsResource(nullptr) {
|
SwapChain::SwapChain() : GraphicsResource(nullptr) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
#include "platform-dx/helpers.hpp"
|
#include "xna/platform-dx/helpers.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
Texture2D::~Texture2D() {
|
Texture2D::~Texture2D() {
|
||||||
@ -11,7 +11,7 @@ namespace xna {
|
|||||||
auto _this = device.shared_from_this();
|
auto _this = device.shared_from_this();
|
||||||
auto texture2d = New<Texture2D>(_this);
|
auto texture2d = New<Texture2D>(_this);
|
||||||
ID3D11Resource* resource = nullptr;
|
ID3D11Resource* resource = nullptr;
|
||||||
auto wstr = XnaHToWString(fileName);
|
auto wstr = XnaHelper::ToWString(fileName);
|
||||||
|
|
||||||
HRESULT result = DirectX::CreateWICTextureFromFile(
|
HRESULT result = DirectX::CreateWICTextureFromFile(
|
||||||
device.impl->_device,
|
device.impl->_device,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "platform-dx/implementations.hpp"
|
#include "xna/platform-dx/implementations.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
GameWindow::GameWindow() {
|
GameWindow::GameWindow() {
|
||||||
|
@ -1,787 +0,0 @@
|
|||||||
#ifndef XNA_CONTENT_LZX_LZXDECODE_HPP
|
|
||||||
#define XNA_CONTENT_LZX_LZXDECODE_HPP
|
|
||||||
|
|
||||||
#include "../../default.hpp"
|
|
||||||
#include "../../csharp/stream.hpp"
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace xna {
|
|
||||||
struct LzxConstants {
|
|
||||||
static constexpr Ushort MIN_MATCH = 2;
|
|
||||||
static constexpr Ushort MAX_MATCH = 257;
|
|
||||||
static constexpr Ushort NUM_CHARS = 256;
|
|
||||||
|
|
||||||
enum class BLOCKTYPE {
|
|
||||||
INVALID = 0,
|
|
||||||
VERBATIM = 1,
|
|
||||||
ALIGNED = 2,
|
|
||||||
UNCOMPRESSED = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr Ushort PRETREE_NUM_ELEMENTS = 20;
|
|
||||||
static constexpr Ushort ALIGNED_NUM_ELEMENTS = 8;
|
|
||||||
static constexpr Ushort NUM_PRIMARY_LENGTHS = 7;
|
|
||||||
static constexpr Ushort NUM_SECONDARY_LENGTHS = 249;
|
|
||||||
|
|
||||||
static constexpr Ushort PRETREE_MAXSYMBOLS = PRETREE_NUM_ELEMENTS;
|
|
||||||
static constexpr Ushort PRETREE_TABLEBITS = 6;
|
|
||||||
static constexpr Ushort MAINTREE_MAXSYMBOLS = NUM_CHARS + 50 * 8;
|
|
||||||
static constexpr Ushort MAINTREE_TABLEBITS = 12;
|
|
||||||
static constexpr Ushort LENGTH_MAXSYMBOLS = NUM_SECONDARY_LENGTHS + 1;
|
|
||||||
static constexpr Ushort LENGTH_TABLEBITS = 12;
|
|
||||||
static constexpr Ushort ALIGNED_MAXSYMBOLS = ALIGNED_NUM_ELEMENTS;
|
|
||||||
static constexpr Ushort ALIGNED_TABLEBITS = 7;
|
|
||||||
|
|
||||||
static constexpr Ushort LENTABLE_SAFETY = 64;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LzxState {
|
|
||||||
Uint R0{ 1 }, R1{ 1 }, R2{ 1 }; /* for the LRU offset system */
|
|
||||||
Ushort main_elements{ 0 }; /* number of main tree elements */
|
|
||||||
Int header_read{ 0 }; /* have we started decoding at all yet? */
|
|
||||||
LzxConstants::BLOCKTYPE block_type{ LzxConstants::BLOCKTYPE::INVALID }; /* type of this block */
|
|
||||||
Uint block_length{ 0 }; /* uncompressed length of this block */
|
|
||||||
Uint block_remaining{ 0 }; /* uncompressed bytes still left to decode */
|
|
||||||
Uint frames_read{ 0 }; /* the number of CFDATA blocks processed */
|
|
||||||
Int intel_filesize{ 0 }; /* magic header value used for transform */
|
|
||||||
Int intel_curpos{ 0 }; /* current offset in transform space */
|
|
||||||
Int intel_started{ 0 }; /* have we seen any translateable data yet? */
|
|
||||||
|
|
||||||
std::vector<Ushort> PRETREE_table;
|
|
||||||
std::vector<Byte> PRETREE_len;
|
|
||||||
std::vector<Ushort> MAINTREE_table;
|
|
||||||
std::vector<Byte> MAINTREE_len;
|
|
||||||
std::vector<Ushort> LENGTH_table;
|
|
||||||
std::vector<Byte> LENGTH_len;
|
|
||||||
std::vector<Ushort> ALIGNED_table;
|
|
||||||
std::vector<Byte> ALIGNED_len;
|
|
||||||
|
|
||||||
// NEEDED MEMBERS
|
|
||||||
// CAB actualsize
|
|
||||||
// CAB window
|
|
||||||
// CAB window_size
|
|
||||||
// CAB window_posn
|
|
||||||
Uint actual_size{ 0 };
|
|
||||||
std::vector<Byte> window;
|
|
||||||
Uint window_size{ 0 };
|
|
||||||
Uint window_posn{ 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
class BitBuffer {
|
|
||||||
public:
|
|
||||||
BitBuffer(sptr<Stream> const& stream) : byteStream(stream) {
|
|
||||||
InitBitStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr void InitBitStream() {
|
|
||||||
buffer = 0;
|
|
||||||
bitsleft = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnsureBits(Byte bits) {
|
|
||||||
while (bitsleft < bits) {
|
|
||||||
const auto lo = static_cast<Byte>(byteStream->ReadByte());
|
|
||||||
const auto hi = static_cast<Byte>(byteStream->ReadByte());
|
|
||||||
//int amount2shift = sizeofstatic_cast<Uint>(*8 - 16 - bitsleft;
|
|
||||||
buffer |= static_cast<Uint>(((hi << 8) | lo) << (sizeof(Uint) * 8 - 16 - bitsleft));
|
|
||||||
bitsleft += 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr Uint PeekBits(Byte bits) const
|
|
||||||
{
|
|
||||||
return (buffer >> ((sizeof(Uint) * 8) - bits));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr void RemoveBits(Byte bits) {
|
|
||||||
buffer <<= bits;
|
|
||||||
bitsleft -= bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint ReadBits(Byte bits)
|
|
||||||
{
|
|
||||||
Uint ret = 0;
|
|
||||||
|
|
||||||
if (bits > 0)
|
|
||||||
{
|
|
||||||
EnsureBits(bits);
|
|
||||||
ret = PeekBits(bits);
|
|
||||||
RemoveBits(bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr Uint GetBuffer() const {
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr Byte GetBitsLeft() const {
|
|
||||||
return bitsleft;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Uint buffer{ 0 };
|
|
||||||
Byte bitsleft{ 0 };
|
|
||||||
sptr<Stream> byteStream = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LzxDecoder {
|
|
||||||
public:
|
|
||||||
LzxDecoder(Int window) {
|
|
||||||
Uint wndsize = (Uint)(1 << window);
|
|
||||||
Int posn_slots = 0;
|
|
||||||
|
|
||||||
// setup proper exception
|
|
||||||
if (window < 15 || window > 21)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// let's initialise our state
|
|
||||||
m_state.window = std::vector<Byte>(wndsize, 0xDC);
|
|
||||||
|
|
||||||
m_state.actual_size = wndsize;
|
|
||||||
m_state.window_size = wndsize;
|
|
||||||
|
|
||||||
/* initialize static tables */
|
|
||||||
|
|
||||||
if (extra_bits.empty()) {
|
|
||||||
extra_bits.resize(52);
|
|
||||||
|
|
||||||
for (size_t i = 0, j = 0; i <= 50; i += 2) {
|
|
||||||
extra_bits[i] = extra_bits[i + 1] = static_cast<Byte>(j);
|
|
||||||
|
|
||||||
if ((i != 0) && (j < 17))
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position_base.empty()) {
|
|
||||||
position_base.resize(51);
|
|
||||||
|
|
||||||
for (size_t i = 0, j = 0; i <= 50; i++) {
|
|
||||||
position_base[i] = static_cast<Uint>(j);
|
|
||||||
j += static_cast<size_t>(1) << extra_bits[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate required position slots */
|
|
||||||
if (window == 20)
|
|
||||||
posn_slots = 42;
|
|
||||||
else if (window == 21)
|
|
||||||
posn_slots = 50;
|
|
||||||
else
|
|
||||||
posn_slots = window << 1;
|
|
||||||
|
|
||||||
m_state.main_elements = static_cast<Ushort>(LzxConstants::NUM_CHARS + (posn_slots << 3));
|
|
||||||
|
|
||||||
// yo dawg i herd u liek arrays so we put arrays in ur arrays so u can array while u array
|
|
||||||
m_state.PRETREE_table = std::vector<Ushort>((1 << LzxConstants::PRETREE_TABLEBITS) + (LzxConstants::PRETREE_MAXSYMBOLS << 1));
|
|
||||||
m_state.PRETREE_len = std::vector<Byte>(LzxConstants::PRETREE_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY);
|
|
||||||
m_state.MAINTREE_table = std::vector<Ushort>((1 << LzxConstants::MAINTREE_TABLEBITS) + (LzxConstants::MAINTREE_MAXSYMBOLS << 1));
|
|
||||||
m_state.MAINTREE_len = std::vector<Byte>(LzxConstants::MAINTREE_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY);
|
|
||||||
m_state.LENGTH_table = std::vector<Ushort>((1 << LzxConstants::LENGTH_TABLEBITS) + (LzxConstants::LENGTH_MAXSYMBOLS << 1));
|
|
||||||
m_state.LENGTH_len = std::vector<Byte>(LzxConstants::LENGTH_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY);
|
|
||||||
m_state.ALIGNED_table = std::vector<Ushort>((1 << LzxConstants::ALIGNED_TABLEBITS) + (LzxConstants::ALIGNED_MAXSYMBOLS << 1));
|
|
||||||
m_state.ALIGNED_len = std::vector<Byte>(LzxConstants::ALIGNED_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY);
|
|
||||||
|
|
||||||
/* initialise tables to 0 (because deltas will be applied to them) */
|
|
||||||
for (size_t i = 0; i < LzxConstants::MAINTREE_MAXSYMBOLS; i++)
|
|
||||||
m_state.MAINTREE_len[i] = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < LzxConstants::LENGTH_MAXSYMBOLS; i++)
|
|
||||||
m_state.LENGTH_len[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Int Decompress(sptr<Stream>& inData, Int inLen, sptr<Stream>& outData, Int outLen) {
|
|
||||||
BitBuffer bitbuf(inData);
|
|
||||||
|
|
||||||
auto startpos = inData->Position();
|
|
||||||
auto endpos = inData->Position() + inLen;
|
|
||||||
|
|
||||||
auto& window = m_state.window;
|
|
||||||
|
|
||||||
Uint window_posn = m_state.window_posn;
|
|
||||||
Uint window_size = m_state.window_size;
|
|
||||||
Uint R0 = m_state.R0;
|
|
||||||
Uint R1 = m_state.R1;
|
|
||||||
Uint R2 = m_state.R2;
|
|
||||||
Uint i = 0;
|
|
||||||
Uint j = 0;
|
|
||||||
|
|
||||||
Int togo = outLen;
|
|
||||||
Int this_run = 0;
|
|
||||||
Int main_element = 0;
|
|
||||||
Int match_length = 0;
|
|
||||||
Int match_offset = 0;
|
|
||||||
Int length_footer = 0;
|
|
||||||
Int extra = 0;
|
|
||||||
Int verbatim_bits = 0;
|
|
||||||
Int rundest = 0;
|
|
||||||
Int runsrc = 0;
|
|
||||||
Int copy_length = 0;
|
|
||||||
Int aligned_bits = 0;
|
|
||||||
|
|
||||||
bitbuf.InitBitStream();
|
|
||||||
|
|
||||||
/* read header if necessary */
|
|
||||||
if (m_state.header_read == 0)
|
|
||||||
{
|
|
||||||
const auto intel = bitbuf.ReadBits(1);
|
|
||||||
if (intel != 0)
|
|
||||||
{
|
|
||||||
// read the filesize
|
|
||||||
i = bitbuf.ReadBits(16);
|
|
||||||
j = bitbuf.ReadBits(16);
|
|
||||||
m_state.intel_filesize = static_cast<Int>((i << 16) | j);
|
|
||||||
}
|
|
||||||
m_state.header_read = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (togo > 0)
|
|
||||||
{
|
|
||||||
/* last block finished, new block expected */
|
|
||||||
if (m_state.block_remaining == 0)
|
|
||||||
{
|
|
||||||
// TODO may screw something up here
|
|
||||||
if (m_state.block_type == LzxConstants::BLOCKTYPE::UNCOMPRESSED) {
|
|
||||||
if ((m_state.block_length & 1) == 1)
|
|
||||||
inData->ReadByte(); /* realign bitstream to word */
|
|
||||||
|
|
||||||
bitbuf.InitBitStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_state.block_type = static_cast<LzxConstants::BLOCKTYPE>(bitbuf.ReadBits(3));
|
|
||||||
i = bitbuf.ReadBits(16);
|
|
||||||
j = bitbuf.ReadBits(8);
|
|
||||||
m_state.block_remaining = m_state.block_length = static_cast<Uint>((i << 8) | j);
|
|
||||||
|
|
||||||
switch (m_state.block_type) {
|
|
||||||
case LzxConstants::BLOCKTYPE::ALIGNED: {
|
|
||||||
for (i = 0, j = 0; i < 8; i++) {
|
|
||||||
j = bitbuf.ReadBits(3);
|
|
||||||
m_state.ALIGNED_len[i] = static_cast<Byte>(j);
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeDecodeTable(LzxConstants::ALIGNED_MAXSYMBOLS, LzxConstants::ALIGNED_TABLEBITS,
|
|
||||||
m_state.ALIGNED_len, m_state.ALIGNED_table);
|
|
||||||
|
|
||||||
//O mesmo que verbatim
|
|
||||||
ReadLengths(m_state.MAINTREE_len, 0, 256, bitbuf);
|
|
||||||
ReadLengths(m_state.MAINTREE_len, 256, m_state.main_elements, bitbuf);
|
|
||||||
MakeDecodeTable(LzxConstants::MAINTREE_MAXSYMBOLS, LzxConstants::MAINTREE_TABLEBITS,
|
|
||||||
m_state.MAINTREE_len, m_state.MAINTREE_table);
|
|
||||||
|
|
||||||
if (m_state.MAINTREE_len[0xE8] != 0)
|
|
||||||
m_state.intel_started = 1;
|
|
||||||
|
|
||||||
ReadLengths(m_state.LENGTH_len, 0, LzxConstants::NUM_SECONDARY_LENGTHS, bitbuf);
|
|
||||||
MakeDecodeTable(LzxConstants::LENGTH_MAXSYMBOLS, LzxConstants::LENGTH_TABLEBITS,
|
|
||||||
m_state.LENGTH_len, m_state.LENGTH_table);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LzxConstants::BLOCKTYPE::VERBATIM: {
|
|
||||||
ReadLengths(m_state.MAINTREE_len, 0, 256, bitbuf);
|
|
||||||
ReadLengths(m_state.MAINTREE_len, 256, m_state.main_elements, bitbuf);
|
|
||||||
MakeDecodeTable(LzxConstants::MAINTREE_MAXSYMBOLS, LzxConstants::MAINTREE_TABLEBITS,
|
|
||||||
m_state.MAINTREE_len, m_state.MAINTREE_table);
|
|
||||||
|
|
||||||
if (m_state.MAINTREE_len[0xE8] != 0)
|
|
||||||
m_state.intel_started = 1;
|
|
||||||
|
|
||||||
ReadLengths(m_state.LENGTH_len, 0, LzxConstants::NUM_SECONDARY_LENGTHS, bitbuf);
|
|
||||||
MakeDecodeTable(LzxConstants::LENGTH_MAXSYMBOLS, LzxConstants::LENGTH_TABLEBITS,
|
|
||||||
m_state.LENGTH_len, m_state.LENGTH_table);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LzxConstants::BLOCKTYPE::UNCOMPRESSED: {
|
|
||||||
m_state.intel_started = 1; /* because we can't assume otherwise */
|
|
||||||
bitbuf.EnsureBits(16); /* get up to 16 pad bits into the buffer */
|
|
||||||
|
|
||||||
if (bitbuf.GetBitsLeft() > 16)
|
|
||||||
inData->Seek(-2, SeekOrigin::Current); /* and align the bitstream! */
|
|
||||||
|
|
||||||
Byte hi = 0;
|
|
||||||
Byte mh = 0;
|
|
||||||
Byte ml = 0;
|
|
||||||
Byte lo = 0;
|
|
||||||
|
|
||||||
lo = static_cast<Byte>(inData->ReadByte());
|
|
||||||
ml = static_cast<Byte>(inData->ReadByte());
|
|
||||||
mh = static_cast<Byte>(inData->ReadByte());
|
|
||||||
hi = static_cast<Byte>(inData->ReadByte());
|
|
||||||
R0 = static_cast<Uint>(lo | ml << 8 | mh << 16 | hi << 24);
|
|
||||||
lo = static_cast<Byte>(inData->ReadByte());
|
|
||||||
ml = static_cast<Byte>(inData->ReadByte());
|
|
||||||
mh = static_cast<Byte>(inData->ReadByte());
|
|
||||||
hi = static_cast<Byte>(inData->ReadByte());
|
|
||||||
R1 = static_cast<Uint>(lo | ml << 8 | mh << 16 | hi << 24);
|
|
||||||
lo = static_cast<Byte>(inData->ReadByte());
|
|
||||||
ml = static_cast<Byte>(inData->ReadByte());
|
|
||||||
mh = static_cast<Byte>(inData->ReadByte());
|
|
||||||
hi = static_cast<Byte>(inData->ReadByte());
|
|
||||||
R2 = static_cast<Uint>(lo | ml << 8 | mh << 16 | hi << 24);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return -1; // TODO throw proper exception
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* buffer exhaustion check */
|
|
||||||
if (inData->Position() > (startpos + inLen))
|
|
||||||
{
|
|
||||||
/* it's possible to have a file where the next run is less than
|
|
||||||
* 16 bits in size. In this case, the READ_HUFFSYM() macro used
|
|
||||||
* in building the tables will exhaust the buffer, so we should
|
|
||||||
* allow for this, but not allow those accidentally read bits to
|
|
||||||
* be used (so we check that there are at least 16 bits
|
|
||||||
* remaining - in this boundary case they aren't really part of
|
|
||||||
* the compressed data)
|
|
||||||
*/
|
|
||||||
//Debug.WriteLine("WTF");
|
|
||||||
|
|
||||||
if (inData->Position() > (startpos + inLen + 2) || bitbuf.GetBitsLeft() < 16)
|
|
||||||
return -1; //TODO throw proper exception
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((this_run = static_cast<Int>(m_state.block_remaining)) > 0 && togo > 0)
|
|
||||||
{
|
|
||||||
if (this_run > togo)
|
|
||||||
this_run = togo;
|
|
||||||
|
|
||||||
togo -= this_run;
|
|
||||||
m_state.block_remaining -= static_cast<Uint>(this_run);
|
|
||||||
|
|
||||||
/* apply 2^x-1 mask */
|
|
||||||
window_posn &= window_size - 1;
|
|
||||||
/* runs can't straddle the window wraparound */
|
|
||||||
if ((window_posn + this_run) > window_size)
|
|
||||||
return -1; //TODO throw proper exception
|
|
||||||
|
|
||||||
switch (m_state.block_type)
|
|
||||||
{
|
|
||||||
case LzxConstants::BLOCKTYPE::VERBATIM: {
|
|
||||||
while (this_run > 0)
|
|
||||||
{
|
|
||||||
main_element = static_cast<Int>(ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len,
|
|
||||||
LzxConstants::MAINTREE_MAXSYMBOLS, LzxConstants::MAINTREE_TABLEBITS,
|
|
||||||
bitbuf));
|
|
||||||
|
|
||||||
if (main_element < LzxConstants::NUM_CHARS)
|
|
||||||
{
|
|
||||||
/* literal: 0 to NUM_CHARS-1 */
|
|
||||||
window[window_posn++] = static_cast<Byte>(main_element);
|
|
||||||
this_run--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
|
|
||||||
main_element -= LzxConstants::NUM_CHARS;
|
|
||||||
|
|
||||||
match_length = main_element & LzxConstants::NUM_PRIMARY_LENGTHS;
|
|
||||||
if (match_length == LzxConstants::NUM_PRIMARY_LENGTHS)
|
|
||||||
{
|
|
||||||
length_footer = static_cast<Int>(ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len,
|
|
||||||
LzxConstants::LENGTH_MAXSYMBOLS, LzxConstants::LENGTH_TABLEBITS,
|
|
||||||
bitbuf));
|
|
||||||
match_length += length_footer;
|
|
||||||
}
|
|
||||||
match_length += LzxConstants::MIN_MATCH;
|
|
||||||
|
|
||||||
match_offset = main_element >> 3;
|
|
||||||
|
|
||||||
if (match_offset > 2)
|
|
||||||
{
|
|
||||||
/* not repeated offset */
|
|
||||||
if (match_offset != 3)
|
|
||||||
{
|
|
||||||
extra = extra_bits[match_offset];
|
|
||||||
verbatim_bits = static_cast<Int>(bitbuf.ReadBits(static_cast<Int>(extra)));
|
|
||||||
match_offset = static_cast<Int>(position_base[match_offset]) - 2 + verbatim_bits;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
match_offset = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update repeated offset LRU queue */
|
|
||||||
R2 = R1; R1 = R0; R0 = static_cast<Uint>(match_offset);
|
|
||||||
}
|
|
||||||
else if (match_offset == 0)
|
|
||||||
{
|
|
||||||
match_offset = (int)R0;
|
|
||||||
}
|
|
||||||
else if (match_offset == 1)
|
|
||||||
{
|
|
||||||
match_offset = (int)R1;
|
|
||||||
R1 = R0; R0 = static_cast<Uint>(match_offset);
|
|
||||||
}
|
|
||||||
else /* match_offset == 2 */
|
|
||||||
{
|
|
||||||
match_offset = (int)R2;
|
|
||||||
R2 = R0; R0 = static_cast<Uint>(match_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
rundest = (int)window_posn;
|
|
||||||
this_run -= match_length;
|
|
||||||
|
|
||||||
/* copy any wrapped around source data */
|
|
||||||
if (static_cast<Int>(window_posn) >= match_offset)
|
|
||||||
{
|
|
||||||
/* no wrap */
|
|
||||||
runsrc = rundest - match_offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
runsrc = rundest + ((int)window_size - match_offset);
|
|
||||||
copy_length = match_offset - (int)window_posn;
|
|
||||||
if (copy_length < match_length)
|
|
||||||
{
|
|
||||||
match_length -= copy_length;
|
|
||||||
window_posn += static_cast<Uint>(copy_length);
|
|
||||||
while (copy_length-- > 0) window[rundest++] = window[runsrc++];
|
|
||||||
runsrc = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window_posn += static_cast<Uint>(match_length);
|
|
||||||
|
|
||||||
/* copy match data - no worries about destination wraps */
|
|
||||||
while (match_length-- > 0) window[rundest++] = window[runsrc++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LzxConstants::BLOCKTYPE::ALIGNED: {
|
|
||||||
while (this_run > 0)
|
|
||||||
{
|
|
||||||
main_element = static_cast<Int>(ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len,
|
|
||||||
LzxConstants::MAINTREE_MAXSYMBOLS, LzxConstants::MAINTREE_TABLEBITS,
|
|
||||||
bitbuf));
|
|
||||||
|
|
||||||
if (main_element < LzxConstants::NUM_CHARS)
|
|
||||||
{
|
|
||||||
/* literal 0 to NUM_CHARS-1 */
|
|
||||||
window[window_posn++] = static_cast<Byte>(main_element);
|
|
||||||
this_run--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
|
|
||||||
main_element -= LzxConstants::NUM_CHARS;
|
|
||||||
|
|
||||||
match_length = main_element & LzxConstants::NUM_PRIMARY_LENGTHS;
|
|
||||||
if (match_length == LzxConstants::NUM_PRIMARY_LENGTHS)
|
|
||||||
{
|
|
||||||
length_footer = static_cast<Int>(ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len,
|
|
||||||
LzxConstants::LENGTH_MAXSYMBOLS, LzxConstants::LENGTH_TABLEBITS,
|
|
||||||
bitbuf));
|
|
||||||
match_length += length_footer;
|
|
||||||
}
|
|
||||||
match_length += LzxConstants::MIN_MATCH;
|
|
||||||
|
|
||||||
match_offset = main_element >> 3;
|
|
||||||
|
|
||||||
if (match_offset > 2)
|
|
||||||
{
|
|
||||||
/* not repeated offset */
|
|
||||||
extra = extra_bits[match_offset];
|
|
||||||
match_offset = static_cast<Int>(position_base[match_offset]) - 2;
|
|
||||||
if (extra > 3)
|
|
||||||
{
|
|
||||||
/* verbatim and aligned bits */
|
|
||||||
extra -= 3;
|
|
||||||
verbatim_bits = static_cast<Int>(bitbuf.ReadBits(static_cast<Byte>(extra)));
|
|
||||||
match_offset += (verbatim_bits << 3);
|
|
||||||
aligned_bits = static_cast<Int>(ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len,
|
|
||||||
LzxConstants::ALIGNED_MAXSYMBOLS, LzxConstants::ALIGNED_TABLEBITS,
|
|
||||||
bitbuf));
|
|
||||||
match_offset += aligned_bits;
|
|
||||||
}
|
|
||||||
else if (extra == 3)
|
|
||||||
{
|
|
||||||
/* aligned bits only */
|
|
||||||
aligned_bits = static_cast<Int>(ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len,
|
|
||||||
LzxConstants::ALIGNED_MAXSYMBOLS, LzxConstants::ALIGNED_TABLEBITS,
|
|
||||||
bitbuf));
|
|
||||||
match_offset += aligned_bits;
|
|
||||||
}
|
|
||||||
else if (extra > 0) /* extra==1, extra==2 */
|
|
||||||
{
|
|
||||||
/* verbatim bits only */
|
|
||||||
verbatim_bits = static_cast<Int>(bitbuf.ReadBits(static_cast<Byte>(extra)));
|
|
||||||
match_offset += verbatim_bits;
|
|
||||||
}
|
|
||||||
else /* extra == 0 */
|
|
||||||
{
|
|
||||||
/* ??? */
|
|
||||||
match_offset = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update repeated offset LRU queue */
|
|
||||||
R2 = R1; R1 = R0; R0 = static_cast<Uint>(match_offset);
|
|
||||||
}
|
|
||||||
else if (match_offset == 0)
|
|
||||||
{
|
|
||||||
match_offset = (int)R0;
|
|
||||||
}
|
|
||||||
else if (match_offset == 1)
|
|
||||||
{
|
|
||||||
match_offset = (int)R1;
|
|
||||||
R1 = R0; R0 = static_cast<Uint>(match_offset);
|
|
||||||
}
|
|
||||||
else /* match_offset == 2 */
|
|
||||||
{
|
|
||||||
match_offset = (int)R2;
|
|
||||||
R2 = R0; R0 = static_cast<Uint>(match_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
rundest = (int)window_posn;
|
|
||||||
this_run -= match_length;
|
|
||||||
|
|
||||||
/* copy any wrapped around source data */
|
|
||||||
if (static_cast<Int>(window_posn) >= match_offset)
|
|
||||||
{
|
|
||||||
/* no wrap */
|
|
||||||
runsrc = rundest - match_offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
runsrc = rundest + ((int)window_size - match_offset);
|
|
||||||
copy_length = match_offset - (int)window_posn;
|
|
||||||
if (copy_length < match_length)
|
|
||||||
{
|
|
||||||
match_length -= copy_length;
|
|
||||||
window_posn += static_cast<Uint>(copy_length);
|
|
||||||
while (copy_length-- > 0) window[rundest++] = window[runsrc++];
|
|
||||||
runsrc = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window_posn += static_cast<Uint>(match_length);
|
|
||||||
|
|
||||||
/* copy match data - no worries about destination wraps */
|
|
||||||
while (match_length-- > 0) window[rundest++] = window[runsrc++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LzxConstants::BLOCKTYPE::UNCOMPRESSED: {
|
|
||||||
if ((inData->Position() + this_run) > endpos) return -1; //TODO throw proper exception
|
|
||||||
std::vector<Byte> temp_buffer(this_run);
|
|
||||||
inData->Read(temp_buffer, 0, this_run);
|
|
||||||
|
|
||||||
for (size_t offset = 0; offset < temp_buffer.size(); ++offset)
|
|
||||||
window[window_posn + offset] = temp_buffer[offset];
|
|
||||||
|
|
||||||
window_posn += static_cast<Uint>(this_run);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return -1; //TODO throw proper exception
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (togo != 0)
|
|
||||||
return -1; //TODO throw proper exception
|
|
||||||
|
|
||||||
Int start_window_pos = static_cast<Int>(window_posn);
|
|
||||||
|
|
||||||
if (start_window_pos == 0)
|
|
||||||
start_window_pos = static_cast<Int>(window_size);
|
|
||||||
|
|
||||||
start_window_pos -= outLen;
|
|
||||||
outData->Write(window, start_window_pos, outLen);
|
|
||||||
|
|
||||||
m_state.window_posn = window_posn;
|
|
||||||
m_state.R0 = R0;
|
|
||||||
m_state.R1 = R1;
|
|
||||||
m_state.R2 = R2;
|
|
||||||
|
|
||||||
// TODO finish intel E8 decoding
|
|
||||||
/* intel E8 decoding */
|
|
||||||
if ((m_state.frames_read++ < 32768) && m_state.intel_filesize != 0)
|
|
||||||
{
|
|
||||||
if (outLen <= 6 || m_state.intel_started == 0)
|
|
||||||
{
|
|
||||||
m_state.intel_curpos += outLen;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Int dataend = outLen - 10;
|
|
||||||
auto curpos = static_cast<Uint>(m_state.intel_curpos);
|
|
||||||
|
|
||||||
m_state.intel_curpos = static_cast<Int>(curpos) + outLen;
|
|
||||||
|
|
||||||
while (outData->Position() < dataend)
|
|
||||||
{
|
|
||||||
if (outData->ReadByte() != 0xE8) {
|
|
||||||
curpos++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
inline static std::vector<Uint> position_base;
|
|
||||||
inline static std::vector<Byte> extra_bits;
|
|
||||||
|
|
||||||
private:
|
|
||||||
LzxState m_state;
|
|
||||||
|
|
||||||
Int MakeDecodeTable(Uint nsyms, Uint nbits, std::vector<Byte>& length, std::vector<Ushort>& table) {
|
|
||||||
Ushort sym = 0;
|
|
||||||
Uint leaf = 0;
|
|
||||||
Byte bit_num = 1;
|
|
||||||
Uint fill;
|
|
||||||
Uint pos = 0; /* the current position in the decode table */
|
|
||||||
Uint table_mask = static_cast<Uint>(1 << static_cast<Int>(nbits));
|
|
||||||
Uint bit_mask = table_mask >> 1; /* don't do 0 length codes */
|
|
||||||
Uint next_symbol = bit_mask; /* base of allocation for long codes */
|
|
||||||
|
|
||||||
/* fill entries for codes short enough for a direct mapping */
|
|
||||||
while (bit_num <= nbits)
|
|
||||||
{
|
|
||||||
for (sym = 0; sym < nsyms; sym++)
|
|
||||||
{
|
|
||||||
if (length[sym] == bit_num)
|
|
||||||
{
|
|
||||||
leaf = pos;
|
|
||||||
|
|
||||||
if ((pos += bit_mask) > table_mask) return 1; /* table overrun */
|
|
||||||
|
|
||||||
/* fill all possible lookups of this symbol with the symbol itself */
|
|
||||||
fill = bit_mask;
|
|
||||||
while (fill-- > 0) table[leaf++] = sym;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bit_mask >>= 1;
|
|
||||||
bit_num++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if there are any codes longer than nbits */
|
|
||||||
if (pos != table_mask)
|
|
||||||
{
|
|
||||||
/* clear the remainder of the table */
|
|
||||||
for (sym = static_cast<Ushort>(pos);
|
|
||||||
sym < table_mask; sym++) table[sym] = 0;
|
|
||||||
|
|
||||||
/* give ourselves room for codes to grow by up to 16 more bits */
|
|
||||||
pos <<= 16;
|
|
||||||
table_mask <<= 16;
|
|
||||||
bit_mask = 1 << 15;
|
|
||||||
|
|
||||||
while (bit_num <= 16)
|
|
||||||
{
|
|
||||||
for (sym = 0; sym < nsyms; sym++)
|
|
||||||
{
|
|
||||||
if (length[sym] == bit_num)
|
|
||||||
{
|
|
||||||
leaf = pos >> 16;
|
|
||||||
for (fill = 0; fill < bit_num - nbits; fill++)
|
|
||||||
{
|
|
||||||
/* if this path hasn't been taken yet, 'allocate' two entries */
|
|
||||||
if (table[leaf] == 0)
|
|
||||||
{
|
|
||||||
table[(next_symbol << 1)] = 0;
|
|
||||||
table[(next_symbol << 1) + 1] = 0;
|
|
||||||
table[leaf] = static_cast<Ushort>(next_symbol++);
|
|
||||||
}
|
|
||||||
/* follow the path and select either left or right for next bit */
|
|
||||||
leaf = static_cast<Uint>(table[leaf] << 1);
|
|
||||||
if (((pos >> static_cast<Int>(15 - fill)) & 1) == 1) leaf++;
|
|
||||||
}
|
|
||||||
table[leaf] = sym;
|
|
||||||
|
|
||||||
if ((pos += bit_mask) > table_mask) return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bit_mask >>= 1;
|
|
||||||
bit_num++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* full talbe? */
|
|
||||||
if (pos == table_mask) return 0;
|
|
||||||
|
|
||||||
/* either erroneous table, or all elements are 0 - let's find out. */
|
|
||||||
for (sym = 0; sym < nsyms; sym++) if (length[sym] != 0) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
void ReadLengths(std::vector<Byte>& lens, Uint first, Uint last, BitBuffer& bitbuf) {
|
|
||||||
Uint x = 0;
|
|
||||||
Uint y = 0;
|
|
||||||
Int z = 0;
|
|
||||||
|
|
||||||
// hufftbl pointer here?
|
|
||||||
|
|
||||||
for (x = 0; x < 20; x++)
|
|
||||||
{
|
|
||||||
y = bitbuf.ReadBits(4);
|
|
||||||
m_state.PRETREE_len[x] = static_cast<Byte>(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeDecodeTable(LzxConstants::PRETREE_MAXSYMBOLS, LzxConstants::PRETREE_TABLEBITS,
|
|
||||||
m_state.PRETREE_len, m_state.PRETREE_table);
|
|
||||||
|
|
||||||
for (x = first; x < last;)
|
|
||||||
{
|
|
||||||
z = (int)ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len,
|
|
||||||
LzxConstants::PRETREE_MAXSYMBOLS, LzxConstants::PRETREE_TABLEBITS, bitbuf);
|
|
||||||
if (z == 17)
|
|
||||||
{
|
|
||||||
y = bitbuf.ReadBits(4); y += 4;
|
|
||||||
while (y-- != 0) lens[x++] = 0;
|
|
||||||
}
|
|
||||||
else if (z == 18)
|
|
||||||
{
|
|
||||||
y = bitbuf.ReadBits(5); y += 20;
|
|
||||||
while (y-- != 0) lens[x++] = 0;
|
|
||||||
}
|
|
||||||
else if (z == 19)
|
|
||||||
{
|
|
||||||
y = bitbuf.ReadBits(1); y += 4;
|
|
||||||
z = static_cast<Int>(ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len,
|
|
||||||
LzxConstants::PRETREE_MAXSYMBOLS, LzxConstants::PRETREE_TABLEBITS, bitbuf));
|
|
||||||
z = lens[x] - z; if (z < 0) z += 17;
|
|
||||||
while (y-- != 0) lens[x++] = static_cast<Byte>(z);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
z = lens[x] - z; if (z < 0) z += 17;
|
|
||||||
lens[x++] = static_cast<Byte>(z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint ReadHuffSym(std::vector<Ushort>& table, std::vector<Byte>& lengths, Uint nsyms, Uint nbits, BitBuffer& bitbuf) {
|
|
||||||
Uint i = 0;
|
|
||||||
Uint j = 0;
|
|
||||||
|
|
||||||
bitbuf.EnsureBits(16);
|
|
||||||
|
|
||||||
if ((i = table[bitbuf.PeekBits(static_cast<Byte>(nbits))]) >= nsyms)
|
|
||||||
{
|
|
||||||
j = static_cast<Uint>(1 << static_cast<Int>((sizeof(Uint) * 8) - nbits));
|
|
||||||
do
|
|
||||||
{
|
|
||||||
j >>= 1; i <<= 1; i |= (bitbuf.GetBuffer() & j) != 0 ? static_cast<Uint>(1) : 0;
|
|
||||||
if (j == 0) return 0; // TODO throw proper exception
|
|
||||||
} while ((i = table[i]) >= nsyms);
|
|
||||||
}
|
|
||||||
j = lengths[i];
|
|
||||||
bitbuf.RemoveBits(static_cast<Byte>(j));
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,89 +0,0 @@
|
|||||||
#ifndef XNA_CONTENT_LZX_DECODERSTREAM_HPP
|
|
||||||
#define XNA_CONTENT_LZX_DECODERSTREAM_HPP
|
|
||||||
|
|
||||||
#include "decoder.hpp"
|
|
||||||
|
|
||||||
namespace xna {
|
|
||||||
class LzxDecoderStream : public Stream {
|
|
||||||
public:
|
|
||||||
LzxDecoderStream(sptr<Stream>& input, Int decompressedSize, Int compressedSize) {
|
|
||||||
dec = New<LzxDecoder>(16);
|
|
||||||
Decompress(input, decompressedSize, compressedSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Decompress(sptr<Stream>& stream, Int decompressedSize, Int compressedSize) {
|
|
||||||
//thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
|
|
||||||
// default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
|
|
||||||
decompressedStream = New<MemoryStream>(decompressedSize);
|
|
||||||
auto startPos = stream->Position();
|
|
||||||
auto pos = startPos;
|
|
||||||
|
|
||||||
while (pos - startPos < compressedSize)
|
|
||||||
{
|
|
||||||
// the compressed stream is seperated into blocks that will decompress
|
|
||||||
// into 32Kb or some other size if specified.
|
|
||||||
// normal, 32Kb output blocks will have a short indicating the size
|
|
||||||
// of the block before the block starts
|
|
||||||
// blocks that have a defined output will be preceded by a byte of value
|
|
||||||
// 0xFF (255), then a short indicating the output size and another
|
|
||||||
// for the block size
|
|
||||||
// all shorts for these cases are encoded in big endian order
|
|
||||||
Int hi = stream->ReadByte();
|
|
||||||
Int lo = stream->ReadByte();
|
|
||||||
Int block_size = (hi << 8) | lo;
|
|
||||||
Int frame_size = 0x8000; // frame size is 32Kb by default
|
|
||||||
// does this block define a frame size?
|
|
||||||
|
|
||||||
if (hi == 0xFF) {
|
|
||||||
hi = lo;
|
|
||||||
lo = static_cast<Byte>(stream->ReadByte());
|
|
||||||
frame_size = (hi << 8) | lo;
|
|
||||||
hi = static_cast<Byte>(stream->ReadByte());
|
|
||||||
lo = static_cast<Byte>(stream->ReadByte());
|
|
||||||
block_size = (hi << 8) | lo;
|
|
||||||
pos += 5;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pos += 2;
|
|
||||||
|
|
||||||
// either says there is nothing to decode
|
|
||||||
if (block_size == 0 || frame_size == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
auto decompressed = reinterpret_pointer_cast<Stream>(decompressedStream);
|
|
||||||
dec->Decompress(stream, block_size, decompressed, frame_size);
|
|
||||||
pos += block_size;
|
|
||||||
|
|
||||||
// reset the position of the input just incase the bit buffer
|
|
||||||
// read in some unused bytes
|
|
||||||
stream->Seek(pos, SeekOrigin::Begin);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decompressedStream->Position() != decompressedSize)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
decompressedStream->Seek(0, SeekOrigin::Begin);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
sptr<LzxDecoder> dec = nullptr;
|
|
||||||
sptr<MemoryStream>decompressedStream = nullptr;
|
|
||||||
|
|
||||||
// Inherited via Stream
|
|
||||||
Int Length() override;
|
|
||||||
Long Position() override;
|
|
||||||
void Close() override;
|
|
||||||
Long Seek(Long offset, SeekOrigin const& origin) override;
|
|
||||||
Int Read(Byte* buffer, Int bufferLength, Int offset, Int count) override;
|
|
||||||
Int Read(std::vector<Byte>& buffer, Int offset, Int count) override;
|
|
||||||
Int ReadByte() override;
|
|
||||||
void Write(Byte const* buffer, Int bufferLength, Int offset, Int count) override;
|
|
||||||
void Write(std::vector<Byte> const& buffer, Int offset, Int count) override;
|
|
||||||
void WriteByte(Byte value) override;
|
|
||||||
virtual constexpr bool IsClosed() override { return false; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,72 +0,0 @@
|
|||||||
#ifndef XNA_CONTENT_MANAGER_HPP
|
|
||||||
#define XNA_CONTENT_MANAGER_HPP
|
|
||||||
|
|
||||||
#include "../csharp/stream.hpp"
|
|
||||||
#include "../default.hpp"
|
|
||||||
#include "../game/servicecontainer.hpp"
|
|
||||||
#include "reader.hpp"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace xna {
|
|
||||||
class ContentManager {
|
|
||||||
public:
|
|
||||||
friend class ContentReader;
|
|
||||||
|
|
||||||
ContentManager(String const& rootDirectory, sptr<IServiceProvider> const& services) :
|
|
||||||
_rootDirectory(rootDirectory){
|
|
||||||
_services = services;
|
|
||||||
};
|
|
||||||
|
|
||||||
static sptr<IServiceProvider> Services() {
|
|
||||||
return _services;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr String RootDirectory() const {
|
|
||||||
return _rootDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RootDirectory(String const& value) {
|
|
||||||
_rootDirectory = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T Load(String const& assetName) {
|
|
||||||
if (assetName.empty()) return T();
|
|
||||||
|
|
||||||
auto obj2 = ReadAsset<T>(assetName);
|
|
||||||
|
|
||||||
return obj2;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
template <typename T>
|
|
||||||
T ReadAsset(String const& assetName) {
|
|
||||||
auto input = OpenStream(assetName);
|
|
||||||
|
|
||||||
if (input->IsClosed())
|
|
||||||
return T();
|
|
||||||
|
|
||||||
auto contentReader = ContentReader::Create(this, input, assetName);
|
|
||||||
|
|
||||||
return contentReader->ReadAsset<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
sptr<Stream> OpenStream(String const& assetName) {
|
|
||||||
String filePath = _rootDirectory + "\\" + assetName + contentExtension;
|
|
||||||
const auto stream = New<FileStream>(filePath, FileMode::Open);
|
|
||||||
//const auto stream = New<FileStream>(filePath);
|
|
||||||
return reinterpret_pointer_cast<Stream>(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
String _rootDirectory;
|
|
||||||
std::vector<Byte> byteBuffer;
|
|
||||||
|
|
||||||
inline const static String contentExtension = ".xnb";
|
|
||||||
inline static sptr<IServiceProvider> _services = nullptr;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,169 +0,0 @@
|
|||||||
#ifndef XNA_CONTENT_READER_HPP
|
|
||||||
#define XNA_CONTENT_READER_HPP
|
|
||||||
|
|
||||||
#include "../common/color.hpp"
|
|
||||||
#include "../common/numerics.hpp"
|
|
||||||
#include "../csharp/binary.hpp"
|
|
||||||
#include "../csharp/type.hpp"
|
|
||||||
#include "../default.hpp"
|
|
||||||
#include "typereadermanager.hpp"
|
|
||||||
#include <any>
|
|
||||||
|
|
||||||
namespace xna {
|
|
||||||
class ContentReader : public BinaryReader, public std::enable_shared_from_this<ContentReader> {
|
|
||||||
public:
|
|
||||||
static sptr<ContentReader> Create(ContentManager* contentManager, sptr<Stream>& input, String const& assetName);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T ReadAsset();
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T ReadObject();
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T ReadObject(T existingInstance);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T ReadObject(ContentTypeReader& typeReader);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T ReadObject(ContentTypeReader& typeReader, T existingInstance);
|
|
||||||
|
|
||||||
Vector2 ReadVector2();
|
|
||||||
Vector3 ReadVector3();
|
|
||||||
Vector4 ReadVector4();
|
|
||||||
Matrix ReadMatrix();
|
|
||||||
Quaternion ReadQuaternion();
|
|
||||||
Color ReadColor();
|
|
||||||
float ReadSingle();
|
|
||||||
double ReadDouble();
|
|
||||||
|
|
||||||
std::vector<Byte> ReadByteBuffer(size_t size, xna_error_nullarg);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ContentReader(ContentManager* contentManager, sptr<Stream>& input, String const& assetName, Int graphicsProfile)
|
|
||||||
: BinaryReader(input), _contentManager(contentManager), _assetName(assetName) {}
|
|
||||||
|
|
||||||
static sptr<Stream> PrepareStream(sptr<Stream>& input, String const& assetName, Int& graphicsProfile);
|
|
||||||
|
|
||||||
Int ReadHeader();
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T ReadObjectInternal(std::any& existingInstance, xna_error_nullarg);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_nullarg);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ContentManager* _contentManager = nullptr;
|
|
||||||
String _assetName;
|
|
||||||
std::vector<sptr<ContentTypeReader>> typeReaders;
|
|
||||||
Int graphicsProfile{ 0 };
|
|
||||||
|
|
||||||
static constexpr Ushort XnbVersionProfileMask = 32512;
|
|
||||||
static constexpr Ushort XnbCompressedVersion = 32773;
|
|
||||||
static constexpr Ushort XnbVersion = 5;
|
|
||||||
static constexpr Int XnbVersionProfileShift = 8;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T ContentReader::ReadObjectInternal(std::any& existingInstance, xna_error_ptr_arg)
|
|
||||||
{
|
|
||||||
const auto num = Read7BitEncodedInt();
|
|
||||||
|
|
||||||
if (num == 0) {
|
|
||||||
return T();
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto index = num - 1;
|
|
||||||
|
|
||||||
if (index >= typeReaders.size()) {
|
|
||||||
xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE);
|
|
||||||
|
|
||||||
return T();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto reader = typeReaders[index];
|
|
||||||
|
|
||||||
//Verificação necessária pois a depender da situação é encontrado um reader errado
|
|
||||||
/*auto typeT = typeof<T>();
|
|
||||||
auto typeThash = typeT->GetHashCode();
|
|
||||||
auto readerType = reader->TargetType();
|
|
||||||
|
|
||||||
if (readerType->GetHashCode() != typeThash) {
|
|
||||||
for (auto const& item : typeReaders) {
|
|
||||||
if (item->TargetType()->GetHashCode() == typeThash) {
|
|
||||||
reader = item;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(reader->TargetType()->GetHashCode() != typeThash)
|
|
||||||
throw std::runtime_error("ContentReader::ReadObjectInternal: wrong reader!");
|
|
||||||
} */
|
|
||||||
|
|
||||||
return InvokeReader<T>(*reader, existingInstance, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_ptr_arg)
|
|
||||||
{
|
|
||||||
auto contentTypeReader = reinterpret_cast<ContentTypeReaderT<T>*>(&reader);
|
|
||||||
T objB;
|
|
||||||
|
|
||||||
if (contentTypeReader) {
|
|
||||||
auto existingInstance1 = existingInstance.has_value() ? std::any_cast<T>(existingInstance) : T();
|
|
||||||
objB = contentTypeReader->Read(*this, existingInstance1);
|
|
||||||
return objB;
|
|
||||||
}
|
|
||||||
|
|
||||||
return T();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T ContentReader::ReadAsset()
|
|
||||||
{
|
|
||||||
const auto sharedResourceCount = ReadHeader();
|
|
||||||
auto obj = ReadObject<T>();
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T ContentReader::ReadObject()
|
|
||||||
{
|
|
||||||
auto a = std::any();
|
|
||||||
return ReadObjectInternal<T>(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T ContentReader::ReadObject(T existingInstance)
|
|
||||||
{
|
|
||||||
return ReadObjectInternal<T>(std::any(existingInstance));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T ContentReader::ReadObject(ContentTypeReader& typeReader)
|
|
||||||
{
|
|
||||||
auto obj = std::any();
|
|
||||||
return ReadObjectInternal<T>(typeReader, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T ContentReader::ReadObject(ContentTypeReader& typeReader, T existingInstance)
|
|
||||||
{
|
|
||||||
return ReadObjectInternal<T>(typeReader, std::any(existingInstance));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T ContentReader::ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_ptr_arg)
|
|
||||||
{
|
|
||||||
return typeReader.TargetIsValueType
|
|
||||||
? InvokeReader<T>(typeReader, existingInstance, err)
|
|
||||||
: ReadObjectInternal<T>(existingInstance, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,33 +0,0 @@
|
|||||||
#ifndef XNA_HELPERS_HPP
|
|
||||||
#define XNA_HELPERS_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace xna {
|
|
||||||
inline std::wstring XnaHToWString(const std::string& str)
|
|
||||||
{
|
|
||||||
std::wstring wstr;
|
|
||||||
size_t size;
|
|
||||||
wstr.resize(str.length());
|
|
||||||
mbstowcs_s(&size, &wstr[0], wstr.size() + 1, str.c_str(), str.size());
|
|
||||||
return wstr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string XnaHToString(const std::wstring& wstr)
|
|
||||||
{
|
|
||||||
std::string str;
|
|
||||||
size_t size;
|
|
||||||
str.resize(wstr.length());
|
|
||||||
wcstombs_s(&size, &str[0], str.size() + 1, wstr.c_str(), wstr.size());
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static constexpr void XnaHHashCombine(std::size_t& seed, const T& v) {
|
|
||||||
std::hash<T> hasher;
|
|
||||||
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
222
inc/libmspack/lzx.h
Normal file
222
inc/libmspack/lzx.h
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/* This file is part of libmspack.
|
||||||
|
* (C) 2003-2013 Stuart Caie.
|
||||||
|
*
|
||||||
|
* The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
|
||||||
|
* by Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* libmspack is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
||||||
|
*
|
||||||
|
* For further details, see the file COPYING.LIB distributed with libmspack
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifndef MSPACK_LZX_H
|
||||||
|
#define MSPACK_LZX_H 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* LZX compression / decompression definitions */
|
||||||
|
|
||||||
|
/* some constants defined by the LZX specification */
|
||||||
|
#define LZX_MIN_MATCH (2)
|
||||||
|
#define LZX_MAX_MATCH (257)
|
||||||
|
#define LZX_NUM_CHARS (256)
|
||||||
|
#define LZX_BLOCKTYPE_INVALID (0) /* also blocktypes 4-7 invalid */
|
||||||
|
#define LZX_BLOCKTYPE_VERBATIM (1)
|
||||||
|
#define LZX_BLOCKTYPE_ALIGNED (2)
|
||||||
|
#define LZX_BLOCKTYPE_UNCOMPRESSED (3)
|
||||||
|
#define LZX_PRETREE_NUM_ELEMENTS (20)
|
||||||
|
#define LZX_ALIGNED_NUM_ELEMENTS (8) /* aligned offset tree #elements */
|
||||||
|
#define LZX_NUM_PRIMARY_LENGTHS (7) /* this one missing from spec! */
|
||||||
|
#define LZX_NUM_SECONDARY_LENGTHS (249) /* length tree #elements */
|
||||||
|
|
||||||
|
/* LZX huffman defines: tweak tablebits as desired */
|
||||||
|
#define LZX_PRETREE_MAXSYMBOLS (LZX_PRETREE_NUM_ELEMENTS)
|
||||||
|
#define LZX_PRETREE_TABLEBITS (6)
|
||||||
|
#define LZX_MAINTREE_MAXSYMBOLS (LZX_NUM_CHARS + 290*8)
|
||||||
|
#define LZX_MAINTREE_TABLEBITS (12)
|
||||||
|
#define LZX_LENGTH_MAXSYMBOLS (LZX_NUM_SECONDARY_LENGTHS+1)
|
||||||
|
#define LZX_LENGTH_TABLEBITS (12)
|
||||||
|
#define LZX_ALIGNED_MAXSYMBOLS (LZX_ALIGNED_NUM_ELEMENTS)
|
||||||
|
#define LZX_ALIGNED_TABLEBITS (7)
|
||||||
|
#define LZX_LENTABLE_SAFETY (64) /* table decoding overruns are allowed */
|
||||||
|
|
||||||
|
#define LZX_FRAME_SIZE (32768) /* the size of a frame in LZX */
|
||||||
|
|
||||||
|
struct lzxd_stream {
|
||||||
|
struct mspack_system *sys; /* I/O routines */
|
||||||
|
struct mspack_file *input; /* input file handle */
|
||||||
|
struct mspack_file *output; /* output file handle */
|
||||||
|
|
||||||
|
off_t offset; /* number of bytes actually output */
|
||||||
|
off_t length; /* overall decompressed length of stream */
|
||||||
|
|
||||||
|
unsigned char *window; /* decoding window */
|
||||||
|
unsigned int window_size; /* window size */
|
||||||
|
unsigned int ref_data_size; /* LZX DELTA reference data size */
|
||||||
|
unsigned int num_offsets; /* number of match_offset entries in table */
|
||||||
|
unsigned int window_posn; /* decompression offset within window */
|
||||||
|
unsigned int frame_posn; /* current frame offset within in window */
|
||||||
|
unsigned int frame; /* the number of 32kb frames processed */
|
||||||
|
unsigned int reset_interval; /* which frame do we reset the compressor? */
|
||||||
|
|
||||||
|
unsigned int R0, R1, R2; /* for the LRU offset system */
|
||||||
|
unsigned int block_length; /* uncompressed length of this LZX block */
|
||||||
|
unsigned int block_remaining; /* uncompressed bytes still left to decode */
|
||||||
|
|
||||||
|
signed int intel_filesize; /* magic header value used for transform */
|
||||||
|
|
||||||
|
unsigned char intel_started; /* has intel E8 decoding started? */
|
||||||
|
unsigned char block_type; /* type of the current block */
|
||||||
|
unsigned char header_read; /* have we started decoding at all yet? */
|
||||||
|
unsigned char input_end; /* have we reached the end of input? */
|
||||||
|
unsigned char is_delta; /* does stream follow LZX DELTA spec? */
|
||||||
|
|
||||||
|
int error;
|
||||||
|
|
||||||
|
/* I/O buffering */
|
||||||
|
unsigned char *inbuf, *i_ptr, *i_end, *o_ptr, *o_end;
|
||||||
|
unsigned int bit_buffer, bits_left, inbuf_size;
|
||||||
|
|
||||||
|
/* huffman code lengths */
|
||||||
|
unsigned char PRETREE_len [LZX_PRETREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY];
|
||||||
|
unsigned char MAINTREE_len [LZX_MAINTREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY];
|
||||||
|
unsigned char LENGTH_len [LZX_LENGTH_MAXSYMBOLS + LZX_LENTABLE_SAFETY];
|
||||||
|
unsigned char ALIGNED_len [LZX_ALIGNED_MAXSYMBOLS + LZX_LENTABLE_SAFETY];
|
||||||
|
|
||||||
|
/* huffman decoding tables */
|
||||||
|
unsigned short PRETREE_table [(1 << LZX_PRETREE_TABLEBITS) +
|
||||||
|
(LZX_PRETREE_MAXSYMBOLS * 2)];
|
||||||
|
unsigned short MAINTREE_table[(1 << LZX_MAINTREE_TABLEBITS) +
|
||||||
|
(LZX_MAINTREE_MAXSYMBOLS * 2)];
|
||||||
|
unsigned short LENGTH_table [(1 << LZX_LENGTH_TABLEBITS) +
|
||||||
|
(LZX_LENGTH_MAXSYMBOLS * 2)];
|
||||||
|
unsigned short ALIGNED_table [(1 << LZX_ALIGNED_TABLEBITS) +
|
||||||
|
(LZX_ALIGNED_MAXSYMBOLS * 2)];
|
||||||
|
unsigned char LENGTH_empty;
|
||||||
|
|
||||||
|
/* this is used purely for doing the intel E8 transform */
|
||||||
|
unsigned char e8_buf[LZX_FRAME_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates and initialises LZX decompression state for decoding an LZX
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* This routine uses system->alloc() to allocate memory. If memory
|
||||||
|
* allocation fails, or the parameters to this function are invalid,
|
||||||
|
* NULL is returned.
|
||||||
|
*
|
||||||
|
* @param system an mspack_system structure used to read from
|
||||||
|
* the input stream and write to the output
|
||||||
|
* stream, also to allocate and free memory.
|
||||||
|
* @param input an input stream with the LZX data.
|
||||||
|
* @param output an output stream to write the decoded data to.
|
||||||
|
* @param window_bits the size of the decoding window, which must be
|
||||||
|
* between 15 and 21 inclusive for regular LZX
|
||||||
|
* data, or between 17 and 25 inclusive for
|
||||||
|
* LZX DELTA data.
|
||||||
|
* @param reset_interval the interval at which the LZX bitstream is
|
||||||
|
* reset, in multiples of LZX frames (32678
|
||||||
|
* bytes), e.g. a value of 2 indicates the input
|
||||||
|
* stream resets after every 65536 output bytes.
|
||||||
|
* A value of 0 indicates that the bitstream never
|
||||||
|
* resets, such as in CAB LZX streams.
|
||||||
|
* @param input_buffer_size the number of bytes to use as an input
|
||||||
|
* bitstream buffer.
|
||||||
|
* @param output_length the length in bytes of the entirely
|
||||||
|
* decompressed output stream, if known in
|
||||||
|
* advance. It is used to correctly perform the
|
||||||
|
* Intel E8 transformation, which must stop 6
|
||||||
|
* bytes before the very end of the
|
||||||
|
* decompressed stream. It is not otherwise used
|
||||||
|
* or adhered to. If the full decompressed
|
||||||
|
* length is known in advance, set it here.
|
||||||
|
* If it is NOT known, use the value 0, and call
|
||||||
|
* lzxd_set_output_length() once it is
|
||||||
|
* known. If never set, 4 of the final 6 bytes
|
||||||
|
* of the output stream may be incorrect.
|
||||||
|
* @param is_delta should be zero for all regular LZX data,
|
||||||
|
* non-zero for LZX DELTA encoded data.
|
||||||
|
* @return a pointer to an initialised lzxd_stream structure, or NULL if
|
||||||
|
* there was not enough memory or parameters to the function were wrong.
|
||||||
|
*/
|
||||||
|
extern struct lzxd_stream *lzxd_init(struct mspack_system *system,
|
||||||
|
struct mspack_file *input,
|
||||||
|
struct mspack_file *output,
|
||||||
|
int window_bits,
|
||||||
|
int reset_interval,
|
||||||
|
int input_buffer_size,
|
||||||
|
off_t output_length,
|
||||||
|
char is_delta);
|
||||||
|
|
||||||
|
/* see description of output_length in lzxd_init() */
|
||||||
|
extern void lzxd_set_output_length(struct lzxd_stream *lzx,
|
||||||
|
off_t output_length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads LZX DELTA reference data into the window and allows
|
||||||
|
* lzxd_decompress() to reference it.
|
||||||
|
*
|
||||||
|
* Call this before the first call to lzxd_decompress().
|
||||||
|
|
||||||
|
* @param lzx the LZX stream to apply this reference data to
|
||||||
|
* @param system an mspack_system implementation to use with the
|
||||||
|
* input param. Only read() will be called.
|
||||||
|
* @param input an input file handle to read reference data using
|
||||||
|
* system->read().
|
||||||
|
* @param length the length of the reference data. Cannot be longer
|
||||||
|
* than the LZX window size.
|
||||||
|
* @return an error code, or MSPACK_ERR_OK if successful
|
||||||
|
*/
|
||||||
|
extern int lzxd_set_reference_data(struct lzxd_stream *lzx,
|
||||||
|
struct mspack_system *system,
|
||||||
|
struct mspack_file *input,
|
||||||
|
unsigned int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decompresses entire or partial LZX streams.
|
||||||
|
*
|
||||||
|
* The number of bytes of data that should be decompressed is given as the
|
||||||
|
* out_bytes parameter. If more bytes are decoded than are needed, they
|
||||||
|
* will be kept over for a later invocation.
|
||||||
|
*
|
||||||
|
* The output bytes will be passed to the system->write() function given in
|
||||||
|
* lzxd_init(), using the output file handle given in lzxd_init(). More than
|
||||||
|
* one call may be made to system->write().
|
||||||
|
|
||||||
|
* Input bytes will be read in as necessary using the system->read()
|
||||||
|
* function given in lzxd_init(), using the input file handle given in
|
||||||
|
* lzxd_init(). This will continue until system->read() returns 0 bytes,
|
||||||
|
* or an error. Errors will be passed out of the function as
|
||||||
|
* MSPACK_ERR_READ errors. Input streams should convey an "end of input
|
||||||
|
* stream" by refusing to supply all the bytes that LZX asks for when they
|
||||||
|
* reach the end of the stream, rather than return an error code.
|
||||||
|
*
|
||||||
|
* If any error code other than MSPACK_ERR_OK is returned, the stream
|
||||||
|
* should be considered unusable and lzxd_decompress() should not be
|
||||||
|
* called again on this stream.
|
||||||
|
*
|
||||||
|
* @param lzx LZX decompression state, as allocated by lzxd_init().
|
||||||
|
* @param out_bytes the number of bytes of data to decompress.
|
||||||
|
* @return an error code, or MSPACK_ERR_OK if successful
|
||||||
|
*/
|
||||||
|
extern int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees all state associated with an LZX data stream. This will call
|
||||||
|
* system->free() using the system pointer given in lzxd_init().
|
||||||
|
*
|
||||||
|
* @param lzx LZX decompression state to free.
|
||||||
|
*/
|
||||||
|
void lzxd_free(struct lzxd_stream *lzx);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
2385
inc/libmspack/mspack.h
Normal file
2385
inc/libmspack/mspack.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
inc/libmspack/mspack.lib
Normal file
BIN
inc/libmspack/mspack.lib
Normal file
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
#ifndef XNA_COMMON_SHAPES_HPP
|
#ifndef XNA_COMMON_SHAPES_HPP
|
||||||
#define XNA_COMMON_SHAPES_HPP
|
#define XNA_COMMON_SHAPES_HPP
|
||||||
|
|
||||||
#include "default.hpp"
|
#include "../default.hpp"
|
||||||
#include "numerics.hpp"
|
#include "numerics.hpp"
|
||||||
#include "gjk.hpp"
|
#include "gjk.hpp"
|
||||||
#include <optional>
|
#include <optional>
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef XNA_COMMON_GDK_HPP
|
#ifndef XNA_COMMON_GDK_HPP
|
||||||
#define XNA_COMMON_GDK_HPP
|
#define XNA_COMMON_GDK_HPP
|
||||||
|
|
||||||
#include "default.hpp"
|
#include "../default.hpp"
|
||||||
#include "numerics.hpp"
|
#include "numerics.hpp"
|
||||||
#include "math.hpp"
|
#include "math.hpp"
|
||||||
|
|
16
inc/xna/content/lzx/decoder.hpp
Normal file
16
inc/xna/content/lzx/decoder.hpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef XNA_CONTENT_LZX_LZXDECODE_HPP
|
||||||
|
#define XNA_CONTENT_LZX_LZXDECODE_HPP
|
||||||
|
|
||||||
|
#include "../../default.hpp"
|
||||||
|
#include "../../csharp/stream.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace xna {
|
||||||
|
struct LzxDecoder {
|
||||||
|
LzxDecoder(int window);
|
||||||
|
int Decompress(Stream* inData, int inLen, Stream* outData, int outLen);
|
||||||
|
int window_bits = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
107
inc/xna/content/manager.hpp
Normal file
107
inc/xna/content/manager.hpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#ifndef XNA_CONTENT_MANAGER_HPP
|
||||||
|
#define XNA_CONTENT_MANAGER_HPP
|
||||||
|
|
||||||
|
#include "../csharp/service.hpp"
|
||||||
|
#include "../csharp/stream.hpp"
|
||||||
|
#include "../default.hpp"
|
||||||
|
#include "reader.hpp"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace xna {
|
||||||
|
//The run-time component which loads managed objects from the binary files produced by the design time content pipeline.
|
||||||
|
class ContentManager : public std::enable_shared_from_this<ContentManager> {
|
||||||
|
public:
|
||||||
|
ContentManager(sptr<IServiceProvider> const& services) :
|
||||||
|
_rootDirectory("") {
|
||||||
|
_services = services;
|
||||||
|
};
|
||||||
|
|
||||||
|
ContentManager(sptr<IServiceProvider> const& services, String const& rootDirectory) :
|
||||||
|
_rootDirectory(rootDirectory){
|
||||||
|
_services = services;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Gets the service provider associated with the ContentManager.
|
||||||
|
sptr<IServiceProvider> ServiceProvider() const {
|
||||||
|
return _services;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets or sets the root directory associated with this ContentManager.
|
||||||
|
constexpr String RootDirectory() const {
|
||||||
|
return _rootDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets or sets the root directory associated with this ContentManager.
|
||||||
|
void RootDirectory(String const& value) {
|
||||||
|
_rootDirectory = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Loads an asset that has been processed by the Content Pipeline.
|
||||||
|
template <typename T>
|
||||||
|
auto Load(String const& assetName) {
|
||||||
|
if (assetName.empty()) {
|
||||||
|
return XnaHelper::ReturnDefaultOrNull<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (XnaHelper::is_shared_ptr<T>::value) {
|
||||||
|
|
||||||
|
if (_loadedAssets.contains(assetName)) {
|
||||||
|
auto& voidAsset = _loadedAssets[assetName];
|
||||||
|
using TYPE = T::element_type;
|
||||||
|
auto asset = reinterpret_pointer_cast<TYPE>(voidAsset);
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto obj2 = ReadAsset<T>(assetName);
|
||||||
|
|
||||||
|
if constexpr (XnaHelper::is_shared_ptr<T>::value) {
|
||||||
|
|
||||||
|
if(obj2)
|
||||||
|
_loadedAssets.emplace( assetName, obj2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Disposes all data that was loaded by this ContentManager.
|
||||||
|
void Unload() {
|
||||||
|
_loadedAssets.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets the service provider associated with the main Game.
|
||||||
|
static sptr<IServiceProvider> GameServiceProvider() {
|
||||||
|
return _gameServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template <typename T>
|
||||||
|
auto ReadAsset(String const& assetName) {
|
||||||
|
auto input = OpenStream(assetName);
|
||||||
|
|
||||||
|
if (!input)
|
||||||
|
return XnaHelper::ReturnDefaultOrNull<T>();
|
||||||
|
|
||||||
|
const auto _this = shared_from_this();
|
||||||
|
auto contentReader = ContentReader::Create(_this, input, assetName);
|
||||||
|
|
||||||
|
auto asset = contentReader->ReadAsset<T>();
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
sptr<Stream> OpenStream(String const& assetName) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class ContentReader;
|
||||||
|
friend class Game;
|
||||||
|
|
||||||
|
String _rootDirectory;
|
||||||
|
sptr<IServiceProvider> _services = nullptr;
|
||||||
|
std::map<String, sptr<void>> _loadedAssets;
|
||||||
|
|
||||||
|
inline static sptr<IServiceProvider> _gameServices = nullptr;
|
||||||
|
inline const static String contentExtension = ".xnb";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
176
inc/xna/content/reader.hpp
Normal file
176
inc/xna/content/reader.hpp
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
#ifndef XNA_CONTENT_READER_HPP
|
||||||
|
#define XNA_CONTENT_READER_HPP
|
||||||
|
|
||||||
|
#include "../common/color.hpp"
|
||||||
|
#include "../common/numerics.hpp"
|
||||||
|
#include "../csharp/binary.hpp"
|
||||||
|
#include "../csharp/type.hpp"
|
||||||
|
#include "../default.hpp"
|
||||||
|
#include "typereadermanager.hpp"
|
||||||
|
#include <any>
|
||||||
|
|
||||||
|
namespace xna {
|
||||||
|
//A worker object that implements most of ContentManager.Load.
|
||||||
|
class ContentReader : public BinaryReader, public std::enable_shared_from_this<ContentReader> {
|
||||||
|
public:
|
||||||
|
static sptr<ContentReader> Create(sptr<ContentManager> const& contentManager, sptr<Stream>& input, String const& assetName);
|
||||||
|
|
||||||
|
// Reads a single object from the current stream.
|
||||||
|
template <typename T>
|
||||||
|
auto ReadObject();
|
||||||
|
|
||||||
|
// Reads a single object from the current stream.
|
||||||
|
template <typename T>
|
||||||
|
auto ReadObject(T existingInstance);
|
||||||
|
|
||||||
|
// Reads a single object from the current stream.
|
||||||
|
template <typename T>
|
||||||
|
auto ReadObject(ContentTypeReader& typeReader);
|
||||||
|
|
||||||
|
// Reads a single object from the current stream.
|
||||||
|
template <typename T>
|
||||||
|
auto ReadObject(ContentTypeReader& typeReader, T existingInstance);
|
||||||
|
|
||||||
|
//Reads a Vector2 value from the current stream.
|
||||||
|
Vector2 ReadVector2();
|
||||||
|
//Reads a Vector3 value from the current stream.
|
||||||
|
Vector3 ReadVector3();
|
||||||
|
//Reads a Vector4 value from the current stream.
|
||||||
|
Vector4 ReadVector4();
|
||||||
|
//Reads a Matrix value from the currently open stream.
|
||||||
|
Matrix ReadMatrix();
|
||||||
|
//Reads a Quaternion value from the current stream.
|
||||||
|
Quaternion ReadQuaternion();
|
||||||
|
//Reads a Color value from the currently open stream.
|
||||||
|
Color ReadColor();
|
||||||
|
//Reads a float value from the currently open stream.
|
||||||
|
float ReadSingle();
|
||||||
|
//Reads a double value from the currently open stream.
|
||||||
|
double ReadDouble();
|
||||||
|
|
||||||
|
//Gets the name of the asset currently being read by this ContentReader.
|
||||||
|
constexpr String AssetName() const {
|
||||||
|
return _assetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets the ContentManager associated with the ContentReader.
|
||||||
|
sptr<xna::ContentManager> ContentManager() const;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal methods
|
||||||
|
//
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto ReadAsset();
|
||||||
|
|
||||||
|
std::vector<Byte> ReadByteBuffer(size_t size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ContentReader(sptr<xna::ContentManager> const& contentManager, sptr<Stream>& input, String const& assetName, Int graphicsProfile)
|
||||||
|
: BinaryReader(input), _contentManager(contentManager), _assetName(assetName) {}
|
||||||
|
|
||||||
|
static sptr<Stream> PrepareStream(sptr<Stream>& input, String const& assetName, Int& graphicsProfile);
|
||||||
|
|
||||||
|
Int ReadHeader();
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto ReadObjectInternal(std::any& existingInstance);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto InvokeReader(ContentTypeReader& reader, std::any& existingInstance);
|
||||||
|
|
||||||
|
private:
|
||||||
|
sptr<xna::ContentManager> _contentManager = nullptr;
|
||||||
|
String _assetName;
|
||||||
|
std::vector<sptr<ContentTypeReader>> typeReaders;
|
||||||
|
Int graphicsProfile{ 0 };
|
||||||
|
std::vector<Byte> byteBuffer;
|
||||||
|
|
||||||
|
static constexpr Ushort XnbVersionProfileMask = 32512;
|
||||||
|
static constexpr Ushort XnbCompressedVersion = 32773;
|
||||||
|
static constexpr Ushort XnbVersion = 5;
|
||||||
|
static constexpr Int XnbVersionProfileShift = 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline auto ContentReader::ReadObjectInternal(std::any& existingInstance)
|
||||||
|
{
|
||||||
|
const auto num = Read7BitEncodedInt();
|
||||||
|
|
||||||
|
if (num == 0) {
|
||||||
|
XnaHelper::ReturnDefaultOrNull<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto index = num - 1;
|
||||||
|
|
||||||
|
if (index >= typeReaders.size()) {
|
||||||
|
throw std::runtime_error("ContentReader::ReadObjectInternal: Bad xbn.");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto reader = typeReaders[index];
|
||||||
|
|
||||||
|
return InvokeReader<T>(*reader, existingInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline auto ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance)
|
||||||
|
{
|
||||||
|
auto contentTypeReader = reinterpret_cast<ContentTypeReaderT<T>*>(&reader);
|
||||||
|
T objB;
|
||||||
|
|
||||||
|
if (contentTypeReader) {
|
||||||
|
auto existingInstance1 = existingInstance.has_value() ? std::any_cast<T>(existingInstance) : T();
|
||||||
|
objB = contentTypeReader->Read(*this, existingInstance1);
|
||||||
|
return objB;
|
||||||
|
}
|
||||||
|
|
||||||
|
return XnaHelper::ReturnDefaultOrNull<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline auto ContentReader::ReadAsset()
|
||||||
|
{
|
||||||
|
const auto sharedResourceCount = ReadHeader();
|
||||||
|
auto obj = ReadObject<T>();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline auto ContentReader::ReadObject()
|
||||||
|
{
|
||||||
|
auto a = std::any();
|
||||||
|
return ReadObjectInternal<T>(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline auto ContentReader::ReadObject(T existingInstance)
|
||||||
|
{
|
||||||
|
return ReadObjectInternal<T>(std::any(existingInstance));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline auto ContentReader::ReadObject(ContentTypeReader& typeReader)
|
||||||
|
{
|
||||||
|
auto obj = std::any();
|
||||||
|
return ReadObjectInternal<T>(typeReader, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline auto ContentReader::ReadObject(ContentTypeReader& typeReader, T existingInstance)
|
||||||
|
{
|
||||||
|
return ReadObjectInternal<T>(typeReader, std::any(existingInstance));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline auto ContentReader::ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance)
|
||||||
|
{
|
||||||
|
return typeReader.TargetIsValueType
|
||||||
|
? InvokeReader<T>(typeReader, existingInstance)
|
||||||
|
: ReadObjectInternal<T>(existingInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,11 +1,11 @@
|
|||||||
#ifndef XNA_CONTENT_READERS_AUDIO_HPP
|
#ifndef XNA_CONTENT_READERS_AUDIO_HPP
|
||||||
#define XNA_CONTENT_READERS_AUDIO_HPP
|
#define XNA_CONTENT_READERS_AUDIO_HPP
|
||||||
|
|
||||||
#include "content/manager.hpp"
|
#include "../../audio/soundeffect.hpp"
|
||||||
#include "content/reader.hpp"
|
#include "../../csharp/timespan.hpp"
|
||||||
#include "csharp/type.hpp"
|
#include "../../csharp/type.hpp"
|
||||||
#include "audio/soundeffect.hpp"
|
#include "../manager.hpp"
|
||||||
#include "csharp/timespan.hpp"
|
#include "../reader.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
class SoundEffectReader : public ContentTypeReaderT<PSoundEffect> {
|
class SoundEffectReader : public ContentTypeReaderT<PSoundEffect> {
|
||||||
@ -16,12 +16,12 @@ namespace xna {
|
|||||||
|
|
||||||
PSoundEffect Read(ContentReader& input, PSoundEffect& existingInstance) override {
|
PSoundEffect Read(ContentReader& input, PSoundEffect& existingInstance) override {
|
||||||
const auto count1 = input.ReadInt32();
|
const auto count1 = input.ReadInt32();
|
||||||
auto format = input.ReadBytes(count1);
|
const auto format = input.ReadBytes(count1);
|
||||||
auto count2 = input.ReadInt32();
|
const auto count2 = input.ReadInt32();
|
||||||
auto data = input.ReadBytes(count2);
|
const auto data = input.ReadBytes(count2);
|
||||||
auto loopStart = input.ReadInt32();
|
const auto loopStart = input.ReadInt32();
|
||||||
auto loopLength = input.ReadInt32();
|
const auto loopLength = input.ReadInt32();
|
||||||
auto num = input.ReadInt32();
|
const auto num = input.ReadInt32();
|
||||||
|
|
||||||
auto sf = snew<SoundEffect>(format, data, loopStart, loopLength, TimeSpan::FromMilliseconds((double)num));
|
auto sf = snew<SoundEffect>(format, data, loopStart, loopLength, TimeSpan::FromMilliseconds((double)num));
|
||||||
return sf;
|
return sf;
|
@ -1,11 +1,11 @@
|
|||||||
#ifndef XNA_CONTENT_READERS_DEFAULT_HPP
|
#ifndef XNA_CONTENT_READERS_DEFAULT_HPP
|
||||||
#define XNA_CONTENT_READERS_DEFAULT_HPP
|
#define XNA_CONTENT_READERS_DEFAULT_HPP
|
||||||
|
|
||||||
#include "content/reader.hpp"
|
#include "../../common/color.hpp"
|
||||||
#include "default.hpp"
|
#include "../../common/numerics.hpp"
|
||||||
#include "common/color.hpp"
|
#include "../../csharp/timespan.hpp"
|
||||||
#include "common/numerics.hpp"
|
#include "../../default.hpp"
|
||||||
#include "csharp/timespan.hpp"
|
#include "../reader.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
class ObjectReader : public ContentTypeReaderT<Object> {
|
class ObjectReader : public ContentTypeReaderT<Object> {
|
@ -1,13 +1,13 @@
|
|||||||
#ifndef XNA_CONTENT_READERS_GRAPHICS_HPP
|
#ifndef XNA_CONTENT_READERS_GRAPHICS_HPP
|
||||||
#define XNA_CONTENT_READERS_GRAPHICS_HPP
|
#define XNA_CONTENT_READERS_GRAPHICS_HPP
|
||||||
|
|
||||||
#include "content/manager.hpp"
|
#include "../../common/numerics.hpp"
|
||||||
#include "content/reader.hpp"
|
#include "../../csharp/timespan.hpp"
|
||||||
#include "csharp/type.hpp"
|
#include "../../csharp/type.hpp"
|
||||||
#include "graphics/texture.hpp"
|
#include "../../graphics/sprite.hpp"
|
||||||
#include "common/numerics.hpp"
|
#include "../../graphics/texture.hpp"
|
||||||
#include "csharp/timespan.hpp"
|
#include "../manager.hpp"
|
||||||
#include "graphics/sprite.hpp"
|
#include "../reader.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
class Texture2DReader : public ContentTypeReaderT<PTexture2D> {
|
class Texture2DReader : public ContentTypeReaderT<PTexture2D> {
|
||||||
@ -22,7 +22,7 @@ namespace xna {
|
|||||||
const auto height = input.ReadInt32();
|
const auto height = input.ReadInt32();
|
||||||
const auto mipMaps = input.ReadInt32();
|
const auto mipMaps = input.ReadInt32();
|
||||||
|
|
||||||
auto a_device = ContentManager::Services()->GetService(*typeof<GraphicsDevice>());
|
auto a_device = ContentManager::GameServiceProvider()->GetService(*typeof<GraphicsDevice>());
|
||||||
sptr<GraphicsDevice> device = nullptr;
|
sptr<GraphicsDevice> device = nullptr;
|
||||||
|
|
||||||
if (a_device.has_value())
|
if (a_device.has_value())
|
||||||
@ -48,13 +48,13 @@ namespace xna {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PSpriteFont Read(ContentReader& input, PSpriteFont& existingInstance) override {
|
PSpriteFont Read(ContentReader& input, PSpriteFont& existingInstance) override {
|
||||||
auto texture = input.ReadObject<PTexture2D>();
|
const auto texture = input.ReadObject<PTexture2D>();
|
||||||
auto glyphs = input.ReadObject<std::vector<Rectangle>>();
|
const auto glyphs = input.ReadObject<std::vector<Rectangle>>();
|
||||||
auto cropping = input.ReadObject<std::vector<Rectangle>>();
|
const auto cropping = input.ReadObject<std::vector<Rectangle>>();
|
||||||
auto charMap = input.ReadObject<std::vector<Char>>();
|
const auto charMap = input.ReadObject<std::vector<Char>>();
|
||||||
auto lineSpacing = input.ReadInt32();
|
const auto lineSpacing = input.ReadInt32();
|
||||||
auto spacing = input.ReadSingle();
|
const auto spacing = input.ReadSingle();
|
||||||
auto kerning = input.ReadObject<std::vector<Vector3>>();
|
const auto kerning = input.ReadObject<std::vector<Vector3>>();
|
||||||
std::optional<Char> defaultCharacter;
|
std::optional<Char> defaultCharacter;
|
||||||
|
|
||||||
if (input.ReadBoolean())
|
if (input.ReadBoolean())
|
@ -11,47 +11,59 @@ namespace xna {
|
|||||||
//-------------------------------------------------------//
|
//-------------------------------------------------------//
|
||||||
// ContentTypeReader //
|
// ContentTypeReader //
|
||||||
//-------------------------------------------------------//
|
//-------------------------------------------------------//
|
||||||
|
|
||||||
|
//Worker for reading a specific managed type from a binary format.
|
||||||
class ContentTypeReader {
|
class ContentTypeReader {
|
||||||
public:
|
public:
|
||||||
virtual Int TypeVersion() { return 0; }
|
virtual Int TypeVersion() { return 0; }
|
||||||
virtual bool CanDeserializeIntoExistingObject() { return false; }
|
virtual bool CanDeserializeIntoExistingObject() { return false; }
|
||||||
|
|
||||||
|
//Retrieves and caches nested type readers. Called by the framework at creation time.
|
||||||
virtual void Initialize(sptr<ContentTypeReaderManager> const& manager) {}
|
virtual void Initialize(sptr<ContentTypeReaderManager> const& manager) {}
|
||||||
|
|
||||||
sptr<Type> TargetType() { return _targetType; }
|
//Gets the type handled by this reader component.
|
||||||
|
sptr<Type> TargetType() { return _targetType; }
|
||||||
|
|
||||||
|
//Reads a strongly typed object from the current stream.
|
||||||
virtual std::any Read(ContentReader& input, std::any& existingInstance) = 0;
|
virtual std::any Read(ContentReader& input, std::any& existingInstance) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ContentTypeReader(sptr<Type> const& targetType) : _targetType(targetType)
|
ContentTypeReader(sptr<Type> const& targetType) : _targetType(targetType)
|
||||||
{
|
{
|
||||||
//TargetIsValueType = targetType->IsValueType();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//Vamos admitir que primariamente o alvo é tipo valor
|
//Let's admit that the target is primarily of type value, if not it must be manually set to false
|
||||||
//caso não seja deve ser setado manualmente para falso
|
|
||||||
bool TargetIsValueType{ true };
|
bool TargetIsValueType{ true };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sptr<Type> _targetType = nullptr;
|
sptr<Type> _targetType = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Worker for reading a specific managed type from a binary format.
|
||||||
|
//Derive from this class to add new data types to the content pipeline system.
|
||||||
template <class T>
|
template <class T>
|
||||||
class ContentTypeReaderT : public ContentTypeReader {
|
class ContentTypeReaderT : public ContentTypeReader {
|
||||||
public:
|
public:
|
||||||
//Por algum motivo ListReader<T> necessita de um construtor padrão
|
//For some reason ListReader<T> needs a default constructor
|
||||||
ContentTypeReaderT() : ContentTypeReader(typeof<T>()) {
|
ContentTypeReaderT() : ContentTypeReader(typeof<T>()) {}
|
||||||
auto a = T();
|
|
||||||
}
|
|
||||||
protected:
|
protected:
|
||||||
ContentTypeReaderT(sptr<Type> const& targetType) : ContentTypeReader(targetType){}
|
ContentTypeReaderT(sptr<Type> const& targetType) : ContentTypeReader(targetType) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual std::any Read(ContentReader& input, std::any& existingInstance) override{
|
//Reads a strongly typed object from the current stream.
|
||||||
return std::any();
|
std::any Read(ContentReader& input, std::any& existingInstance) override {
|
||||||
|
if (existingInstance.has_value() && !(existingInstance.type() == typeid(T)))
|
||||||
|
throw std::runtime_error("ContentTypeReader<T>::Read: bad xbn, wrong type.");
|
||||||
|
|
||||||
|
auto existingInstance1 = XnaHelper::ReturnDefaultOrNull<T>();
|
||||||
|
auto obj = Read(input, existingInstance1);
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Reads a strongly typed object from the current stream.
|
||||||
virtual T Read(ContentReader& input, T& existingInstance) = 0;
|
virtual T Read(ContentReader& input, T& existingInstance) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//-------------------------------------------------------//
|
//-------------------------------------------------------//
|
||||||
// ContentTypeReaderActivador //
|
// ContentTypeReaderActivador //
|
||||||
@ -60,36 +72,8 @@ namespace xna {
|
|||||||
public:
|
public:
|
||||||
using Activador = sptr<ContentTypeReader>(*)();
|
using Activador = sptr<ContentTypeReader>(*)();
|
||||||
|
|
||||||
static sptr<ContentTypeReader> CreateInstance(sptr<Type> const& type, xna_error_nullarg) {
|
static sptr<ContentTypeReader> CreateInstance(sptr<Type> const& type);
|
||||||
if (!type)
|
static void SetActivador(sptr<Type> const& type, Activador activador);
|
||||||
{
|
|
||||||
xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto hash = type->GetHashCode();
|
|
||||||
|
|
||||||
if (!activators.contains(hash))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
auto activador = activators[hash];
|
|
||||||
|
|
||||||
if (!activador) return nullptr;
|
|
||||||
|
|
||||||
return activador();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetActivador(sptr<Type> const& type, Activador activador, xna_error_nullarg) {
|
|
||||||
if (!type) {
|
|
||||||
xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto hash = type->GetHashCode();
|
|
||||||
|
|
||||||
if (!activators.contains(hash))
|
|
||||||
activators.insert({ hash, activador });
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static auto activators = std::map<size_t, Activador>();
|
inline static auto activators = std::map<size_t, Activador>();
|
||||||
@ -105,14 +89,14 @@ namespace xna {
|
|||||||
//-------------------------------------------------------//
|
//-------------------------------------------------------//
|
||||||
// ContentTypeReaderManager //
|
// ContentTypeReaderManager //
|
||||||
//-------------------------------------------------------//
|
//-------------------------------------------------------//
|
||||||
|
|
||||||
|
//A manager that constructs and keeps track of type reader objects.
|
||||||
class ContentTypeReaderManager {
|
class ContentTypeReaderManager {
|
||||||
public:
|
public:
|
||||||
static std::vector<PContentTypeReader> ReadTypeManifest(Int typeCount, sptr<ContentReader>& contentReader, xna_error_nullarg);
|
static std::vector<PContentTypeReader> ReadTypeManifest(Int typeCount, sptr<ContentReader>& contentReader);
|
||||||
static sptr<ContentTypeReader> GetTypeReader(sptr<Type> const& targetType, sptr<ContentReader>& contentReader, xna_error_nullarg);
|
|
||||||
|
|
||||||
inline sptr<ContentTypeReader> GetTypeReader(sptr<Type> const& targetType, xna_error_nullarg) {
|
//Looks up a reader for the specified type.
|
||||||
return ContentTypeReaderManager::GetTypeReader(targetType, this->contentReader, err);
|
static sptr<ContentTypeReader> GetTypeReader(sptr<Type> const& targetType);
|
||||||
}
|
|
||||||
|
|
||||||
inline static bool ContainsTypeReader(sptr<Type> const& targetType) {
|
inline static bool ContainsTypeReader(sptr<Type> const& targetType) {
|
||||||
return ContentTypeReaderManager::targetTypeToReader.contains(targetType);
|
return ContentTypeReaderManager::targetTypeToReader.contains(targetType);
|
||||||
@ -120,33 +104,13 @@ namespace xna {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ContentTypeReaderManager(sptr<ContentReader>& contentReader);
|
ContentTypeReaderManager(sptr<ContentReader>& contentReader);
|
||||||
static sptr<ContentTypeReader> GetTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, std::vector<PContentTypeReader>& newTypeReaders, xna_error_nullarg);
|
static sptr<ContentTypeReader> GetTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, std::vector<PContentTypeReader>& newTypeReaders);
|
||||||
static bool InstantiateTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_nullarg);
|
static bool InstantiateTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader);
|
||||||
static void AddTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_nullarg);
|
static void AddTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader);
|
||||||
static void RollbackAddReaders(std::vector<sptr<ContentTypeReader>>& newTypeReaders);
|
static void RollbackAddReaders(std::vector<sptr<ContentTypeReader>>& newTypeReaders);
|
||||||
|
|
||||||
static void RollbackAddReader(std::map<String, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader) {
|
|
||||||
std::map<String, sptr<ContentTypeReader>>::iterator it;
|
|
||||||
|
|
||||||
for (it = dictionary.begin(); it != dictionary.end(); it++) {
|
static void RollbackAddReader(std::map<String, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader);
|
||||||
if (it->second == reader) {
|
static void RollbackAddReader(std::map<PType, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader);
|
||||||
dictionary.erase(it->first);
|
|
||||||
it = dictionary.begin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RollbackAddReader(std::map<PType, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader) {
|
|
||||||
std::map<PType, sptr<ContentTypeReader>>::iterator it;
|
|
||||||
|
|
||||||
for (it = dictionary.begin(); it != dictionary.end(); it++) {
|
|
||||||
if (it->second == reader) {
|
|
||||||
dictionary.erase(it->first);
|
|
||||||
it = dictionary.begin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sptr<ContentReader> contentReader = nullptr;
|
sptr<ContentReader> contentReader = nullptr;
|
||||||
@ -154,7 +118,7 @@ namespace xna {
|
|||||||
inline static auto nameToReader = std::map<String, PContentTypeReader>();
|
inline static auto nameToReader = std::map<String, PContentTypeReader>();
|
||||||
inline static auto targetTypeToReader = std::map<PType, PContentTypeReader>();
|
inline static auto targetTypeToReader = std::map<PType, PContentTypeReader>();
|
||||||
inline static auto readerTypeToReader = std::map<PType, PContentTypeReader>();
|
inline static auto readerTypeToReader = std::map<PType, PContentTypeReader>();
|
||||||
|
|
||||||
static void initMaps();
|
static void initMaps();
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -40,6 +40,8 @@ namespace xna {
|
|||||||
|
|
||||||
//Writes a byte to the current position in the stream and advances the position within the stream by one byte.
|
//Writes a byte to the current position in the stream and advances the position within the stream by one byte.
|
||||||
virtual void WriteByte(Byte value) = 0;
|
virtual void WriteByte(Byte value) = 0;
|
||||||
|
|
||||||
|
virtual void* Data() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//A simplified port of the System.IO.MemoryStream.
|
//A simplified port of the System.IO.MemoryStream.
|
||||||
@ -83,6 +85,10 @@ namespace xna {
|
|||||||
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count) override;
|
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count) override;
|
||||||
virtual void WriteByte(Byte value) override;
|
virtual void WriteByte(Byte value) override;
|
||||||
|
|
||||||
|
virtual void* Data() override {
|
||||||
|
return _buffer.data();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<Byte> _buffer;
|
std::vector<Byte> _buffer;
|
||||||
private:
|
private:
|
||||||
@ -124,6 +130,10 @@ namespace xna {
|
|||||||
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count) override;
|
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count) override;
|
||||||
virtual void WriteByte(Byte value) override;
|
virtual void WriteByte(Byte value) override;
|
||||||
|
|
||||||
|
virtual void* Data() override {
|
||||||
|
return _fstream.rdbuf();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::fstream _fstream;
|
std::fstream _fstream;
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
#define XNA_GAME_GAME_HPP
|
#define XNA_GAME_GAME_HPP
|
||||||
|
|
||||||
#include "../default.hpp"
|
#include "../default.hpp"
|
||||||
#include "game/time.hpp"
|
#include "time.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
class Game : public std::enable_shared_from_this<Game> {
|
class Game : public std::enable_shared_from_this<Game> {
|
@ -2,8 +2,8 @@
|
|||||||
#define XNA_GRAPHICS_SPRITE_HPP
|
#define XNA_GRAPHICS_SPRITE_HPP
|
||||||
|
|
||||||
#include "../default.hpp"
|
#include "../default.hpp"
|
||||||
#include "common/numerics.hpp"
|
#include "../common/numerics.hpp"
|
||||||
#include "common/color.hpp"
|
#include "../common/color.hpp"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef XNA_GRAPHICS_VIEWPORT
|
#ifndef XNA_GRAPHICS_VIEWPORT
|
||||||
#define XNA_GRAPHICS_VIEWPORT
|
#define XNA_GRAPHICS_VIEWPORT
|
||||||
|
|
||||||
#include "common/numerics.hpp"
|
#include "../common/numerics.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
struct Viewport {
|
struct Viewport {
|
49
inc/xna/helpers.hpp
Normal file
49
inc/xna/helpers.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef XNA_HELPERS_HPP
|
||||||
|
#define XNA_HELPERS_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace xna {
|
||||||
|
struct XnaHelper {
|
||||||
|
template<typename T> struct is_shared_ptr : std::false_type {};
|
||||||
|
template<typename T> struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
|
||||||
|
|
||||||
|
static inline std::wstring ToWString(const std::string& str)
|
||||||
|
{
|
||||||
|
std::wstring wstr;
|
||||||
|
size_t size;
|
||||||
|
wstr.resize(str.length());
|
||||||
|
mbstowcs_s(&size, &wstr[0], wstr.size() + 1, str.c_str(), str.size());
|
||||||
|
return wstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::string ToString(const std::wstring& wstr)
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
size_t size;
|
||||||
|
str.resize(wstr.length());
|
||||||
|
wcstombs_s(&size, &str[0], str.size() + 1, wstr.c_str(), wstr.size());
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static constexpr void HashCombine(std::size_t& seed, const T& v) {
|
||||||
|
std::hash<T> hasher;
|
||||||
|
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline auto ReturnDefaultOrNull() {
|
||||||
|
if constexpr (is_shared_ptr<T>::value)
|
||||||
|
return (T)nullptr;
|
||||||
|
else if (std::is_default_constructible<T>::value)
|
||||||
|
return T();
|
||||||
|
else
|
||||||
|
throw std::runtime_error("Unable to build object");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user