mirror of
https://github.com/borgesdan/xn65
synced 2024-12-29 21:54:47 +01:00
Arquivos Content
This commit is contained in:
parent
dba5482e46
commit
efab931113
@ -9,6 +9,8 @@ if (POLICY CMP0141)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
|
||||
endif()
|
||||
|
||||
set(ENV{VCPKG_ROOT} C:\\vcpkg)
|
||||
|
||||
project ("xna")
|
||||
|
||||
# Include sub-projects.
|
||||
|
@ -3,7 +3,43 @@
|
||||
#
|
||||
|
||||
# Add source to this project's executable.
|
||||
add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp" "csharp/stream.cpp" "platform/gdevicemanager-dx.cpp" "platform/vertexinput-dx.cpp" "platform/shader-dx.cpp" "platform/rasterizerstate-dx.cpp" "platform/vertexbuffer-dx.cpp" "platform/indexbuffer-dx.cpp" "common/matrix.cpp" "platform/constbuffer-dx.cpp" "platform/databuffer-dx.cpp" "platform/samplerstate-dx.cpp" "platform/spritebatch-dx.cpp" "platform/spritefont-dx.cpp" "platform/depthstencilstate-dx.cpp" "platform/keyboard-dx.cpp" "platform/mouse-dx.cpp" "platform/gamepad-dx.cpp" "common/vectors.cpp" "platform/soundeffect-dx.cpp" "platform/displaymode-dx.cpp" "platform/presentparameters-dx.cpp" "game/component.cpp" "content/manager.cpp" "content/reader.cpp" "csharp/binary.cpp")
|
||||
add_executable (xna WIN32
|
||||
"xna.cpp"
|
||||
"platform/window-dx.cpp"
|
||||
"platform/device-dx.cpp"
|
||||
"platform/adapter-dx.cpp"
|
||||
"platform/swapchain-dx.cpp"
|
||||
"platform/rendertarget-dx.cpp"
|
||||
"platform/texture-dx.cpp"
|
||||
"platform/blendstate-dx.cpp"
|
||||
"platform/game-dx.cpp"
|
||||
"platform/clock-dx.cpp"
|
||||
"csharp/stream.cpp"
|
||||
"platform/gdevicemanager-dx.cpp"
|
||||
"platform/vertexinput-dx.cpp"
|
||||
"platform/shader-dx.cpp"
|
||||
"platform/rasterizerstate-dx.cpp"
|
||||
"platform/vertexbuffer-dx.cpp"
|
||||
"platform/indexbuffer-dx.cpp"
|
||||
"common/matrix.cpp"
|
||||
"platform/constbuffer-dx.cpp"
|
||||
"platform/databuffer-dx.cpp"
|
||||
"platform/samplerstate-dx.cpp"
|
||||
"platform/spritebatch-dx.cpp"
|
||||
"platform/spritefont-dx.cpp"
|
||||
"platform/depthstencilstate-dx.cpp"
|
||||
"platform/keyboard-dx.cpp"
|
||||
"platform/mouse-dx.cpp"
|
||||
"platform/gamepad-dx.cpp"
|
||||
"common/vectors.cpp"
|
||||
"platform/soundeffect-dx.cpp"
|
||||
"platform/displaymode-dx.cpp"
|
||||
"platform/presentparameters-dx.cpp"
|
||||
"game/component.cpp"
|
||||
"content/manager.cpp"
|
||||
"content/reader.cpp"
|
||||
"csharp/binary.cpp"
|
||||
"content/decstream.cpp" "content/lzx/decoder.cpp" "content/lzx/decoderstream.cpp" "content/typereadermanager.cpp" "csharp/object.cpp")
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET xna PROPERTY CXX_STANDARD 20)
|
||||
@ -12,7 +48,6 @@ endif()
|
||||
# TODO: Add tests and install targets if needed.
|
||||
|
||||
|
||||
|
||||
# -- Biblioteca DirectxTK --
|
||||
# Url: https://github.com/microsoft/DirectXTK/wiki/DirectXTK
|
||||
#
|
||||
@ -30,5 +65,14 @@ endif()
|
||||
# "CMAKE_TOOLCHAIN_FILE": "{VCPKG_DIR}\\scripts\\buildsystems\\vcpkg.cmake"
|
||||
# }
|
||||
#
|
||||
# Instalaçao do libmspack
|
||||
# $- vcpkg install libmspack
|
||||
#
|
||||
find_package(directxtk CONFIG REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} D3d11.lib dxgi.lib dxguid.lib d3dcompiler.lib Microsoft::DirectXTK)
|
||||
|
||||
include_directories($ENV{VCPKG_ROOT}\\packages\\libmspack_x64-windows\\include)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
D3d11.lib dxgi.lib dxguid.lib d3dcompiler.lib Microsoft::DirectXTK
|
||||
$ENV{VCPKG_ROOT}\\packages\\libmspack_x64-windows\\lib\\libmspack.lib
|
||||
)
|
||||
|
111
framework/content/decstream.cpp
Normal file
111
framework/content/decstream.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "decstream.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace xna {
|
||||
void DecompressStream::Decompress()
|
||||
{
|
||||
String filename = "C:\\Users\\Danilo Borges\\Documents\\xna\\projeto-final\\Game9\\bin\\Debug\\netcoreapp3.1\\Content\\Sprites\\MonsterA\\idle.xnb";
|
||||
|
||||
|
||||
}
|
||||
|
||||
Int DecompressStream::Length()
|
||||
{
|
||||
return Int();
|
||||
}
|
||||
|
||||
Long DecompressStream::Position()
|
||||
{
|
||||
return Long();
|
||||
}
|
||||
|
||||
void DecompressStream::Close()
|
||||
{
|
||||
}
|
||||
|
||||
Long DecompressStream::Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg)
|
||||
{
|
||||
return Long();
|
||||
}
|
||||
|
||||
Int DecompressStream::Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg)
|
||||
{
|
||||
return Int();
|
||||
}
|
||||
|
||||
Int DecompressStream::Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg)
|
||||
{
|
||||
return Int();
|
||||
}
|
||||
|
||||
Int DecompressStream::ReadByte(xna_error_ptr_arg)
|
||||
{
|
||||
return Int();
|
||||
}
|
||||
|
||||
void DecompressStream::Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg)
|
||||
{
|
||||
}
|
||||
|
||||
void DecompressStream::Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg)
|
||||
{
|
||||
}
|
||||
|
||||
void DecompressStream::WriteByte(Byte value, xna_error_ptr_arg)
|
||||
{
|
||||
}
|
||||
|
||||
bool DecompressStream::DecompressNextBuffer()
|
||||
{
|
||||
if (decompressedTodo <= 0)
|
||||
return false;
|
||||
|
||||
do {
|
||||
if (compressedPosition >= compressedSize)
|
||||
ReadNextBufferFromDisk();
|
||||
|
||||
auto sourceSize = compressedSize - compressedPosition;
|
||||
auto outputSize = 65536;
|
||||
|
||||
//TODO
|
||||
|
||||
if (outputSize == 0 && sourceSize == 0)
|
||||
return false;
|
||||
|
||||
compressedPosition += sourceSize;
|
||||
decompressedTodo -= outputSize;
|
||||
decompressedSize = outputSize;
|
||||
decompressedPosition = 0;
|
||||
|
||||
} while (decompressedSize == 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DecompressStream::ReadNextBufferFromDisk()
|
||||
{
|
||||
if (compressedTodo <= 0)
|
||||
return;
|
||||
|
||||
ReadBufferFromDisk(compressedBuffer, compressedTodo, compressedSize);
|
||||
compressedPosition = 0;
|
||||
}
|
||||
|
||||
void DecompressStream::ReadBufferFromDisk(std::vector<Byte>& buffer, Int& bufferTodo, Int& bufferSize)
|
||||
{
|
||||
Int num1 = 65536;
|
||||
if (num1 > bufferTodo)
|
||||
num1 = bufferTodo;
|
||||
|
||||
Int num2 = 0;
|
||||
for (int offset = 0; offset < num1; offset += num2) {
|
||||
num2 = baseStream->Read(buffer, offset, num1 - offset);
|
||||
|
||||
if (num2 == 0) return;
|
||||
}
|
||||
|
||||
bufferTodo -= num1;
|
||||
bufferSize = num1;
|
||||
}
|
||||
|
||||
}
|
60
framework/content/decstream.hpp
Normal file
60
framework/content/decstream.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef XNA_CONTENT_DECOMPRESS_STREAM_HPP
|
||||
#define XNA_CONTENT_DECOMPRESS_STREAM_HPP
|
||||
|
||||
#include "../default.hpp"
|
||||
#include "../csharp/stream.hpp"
|
||||
#include <mspack.h>
|
||||
|
||||
namespace xna {
|
||||
class DecompressStream : public Stream {
|
||||
public:
|
||||
DecompressStream(sptr<Stream> const& baseStream, Int compressedTodo, Int decompressedTodo):
|
||||
baseStream(baseStream), compressedTodo(compressedTodo), decompressedTodo(decompressedTodo){
|
||||
compressedBuffer = std::vector<Byte>(CompressedBufferSize);
|
||||
decompressedBuffer = std::vector<Byte>(DecompressedBufferSize);
|
||||
decompressionContext = mspack_create_cab_decompressor(nullptr);
|
||||
}
|
||||
|
||||
virtual ~DecompressStream() {
|
||||
if (decompressionContext) {
|
||||
mspack_destroy_cab_decompressor(decompressionContext);
|
||||
}
|
||||
}
|
||||
|
||||
void Decompress();
|
||||
|
||||
public:
|
||||
// Inherited via Stream
|
||||
Int Length() override;
|
||||
Long Position() override;
|
||||
void Close() override;
|
||||
Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) override;
|
||||
Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
|
||||
Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||
Int ReadByte(xna_error_nullarg) override;
|
||||
void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
|
||||
void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||
void WriteByte(Byte value, xna_error_nullarg) override;
|
||||
|
||||
private:
|
||||
static constexpr int CompressedBufferSize = 65536;
|
||||
static constexpr int DecompressedBufferSize = 65536;
|
||||
sptr<Stream> baseStream = nullptr;
|
||||
Int compressedTodo{ 0 };
|
||||
Int compressedSize{ 0 };
|
||||
Int compressedPosition{ 0 };
|
||||
std::vector<Byte> compressedBuffer;
|
||||
Int decompressedTodo{ 0 };
|
||||
Int decompressedSize{ 0 };
|
||||
Int decompressedPosition{ 0 };
|
||||
std::vector<Byte> decompressedBuffer;
|
||||
mscab_decompressor* decompressionContext = nullptr;
|
||||
|
||||
private:
|
||||
bool DecompressNextBuffer();
|
||||
void ReadNextBufferFromDisk();
|
||||
void ReadBufferFromDisk(std::vector<Byte>& buffer, Int& bufferTodo, Int& bufferSize);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
5
framework/content/lzx/decoder.cpp
Normal file
5
framework/content/lzx/decoder.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "decoder.hpp"
|
||||
|
||||
namespace xna {
|
||||
|
||||
}
|
649
framework/content/lzx/decoder.hpp
Normal file
649
framework/content/lzx/decoder.hpp
Normal file
@ -0,0 +1,649 @@
|
||||
#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) {
|
||||
return 0;
|
||||
}
|
||||
void ReadLengths(std::vector<Byte> const& lens, Uint first, Uint last, BitBuffer& bitbuf) {}
|
||||
Uint ReadHuffSym(std::vector<Ushort>& table, std::vector<Byte>& lengths, Uint nsyms, Uint nbits, BitBuffer& bitbuf) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
40
framework/content/lzx/decoderstream.cpp
Normal file
40
framework/content/lzx/decoderstream.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "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, xna_error_ptr_arg)
|
||||
{
|
||||
return Long();
|
||||
}
|
||||
Int LzxDecoderStream::Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg)
|
||||
{
|
||||
return decompressedStream->Read(buffer, bufferLength, offset, count, err);
|
||||
}
|
||||
Int LzxDecoderStream::Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg)
|
||||
{
|
||||
return decompressedStream->Read(buffer, offset, count, err);
|
||||
}
|
||||
Int LzxDecoderStream::ReadByte(xna_error_ptr_arg)
|
||||
{
|
||||
return Int();
|
||||
}
|
||||
void LzxDecoderStream::Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg)
|
||||
{
|
||||
}
|
||||
void LzxDecoderStream::Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg)
|
||||
{
|
||||
}
|
||||
void LzxDecoderStream::WriteByte(Byte value, xna_error_ptr_arg)
|
||||
{
|
||||
}
|
||||
}
|
88
framework/content/lzx/decoderstream.hpp
Normal file
88
framework/content/lzx/decoderstream.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
#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, xna_error_nullarg) override;
|
||||
Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
|
||||
Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||
Int ReadByte(xna_error_nullarg) override;
|
||||
void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
|
||||
void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||
void WriteByte(Byte value, xna_error_nullarg) override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,9 +1,58 @@
|
||||
#include "reader.hpp"
|
||||
#include "manager.hpp"
|
||||
#include "lzx/decoderstream.hpp"
|
||||
|
||||
namespace xna {
|
||||
sptr<ContentReader> ContentReader::Create(ContentManager* contentManager, Stream& input, String const& assetName)
|
||||
sptr<ContentReader> ContentReader::Create(ContentManager* contentManager, Stream* input, String const& assetName)
|
||||
{
|
||||
return sptr<ContentReader>();
|
||||
}
|
||||
|
||||
sptr<Stream> ContentReader::PrepareStream(sptr<Stream>& input, String const* assetName, Int& graphicsProfile)
|
||||
{
|
||||
BinaryReader binaryReader = BinaryReader(input);
|
||||
|
||||
if (binaryReader.ReadByte() != 'X' || binaryReader.ReadByte() != 'N' || binaryReader.ReadByte() != 'B')
|
||||
return nullptr;
|
||||
|
||||
Int num1 = 0;
|
||||
if (binaryReader.ReadByte() == 'w')
|
||||
num1 = binaryReader.ReadUInt16();
|
||||
else
|
||||
return nullptr;
|
||||
|
||||
graphicsProfile = (num1 & 32512) >> 8;
|
||||
bool flag = false;
|
||||
|
||||
switch (num1 & -32513)
|
||||
{
|
||||
case 5:
|
||||
flag = false;
|
||||
break;
|
||||
case 32773:
|
||||
flag = true;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto num2 = binaryReader.ReadInt32();
|
||||
|
||||
if ((num2 - 10) > input->Length() - input->Position())
|
||||
return nullptr;
|
||||
|
||||
if (!flag)
|
||||
return input;
|
||||
|
||||
const Int compressedTodo = num2 - 14;
|
||||
const auto decompressedTodo = binaryReader.ReadInt32();
|
||||
|
||||
auto lzxStream = New<LzxDecoderStream>(input, compressedTodo, decompressedTodo);
|
||||
|
||||
return reinterpret_pointer_cast<Stream>(lzxStream);
|
||||
}
|
||||
|
||||
Int ContentReader::ReadHeader() {
|
||||
return Int();
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,29 @@
|
||||
#define XNA_CONTENT_READER_HPP
|
||||
|
||||
#include "../default.hpp"
|
||||
#include "../csharp/binary.hpp"
|
||||
|
||||
namespace xna {
|
||||
class ContentReader {
|
||||
class ContentReader : public BinaryReader{
|
||||
public:
|
||||
static sptr<ContentReader> Create(ContentManager* contentManager, Stream& input, String const& assetName);
|
||||
static sptr<ContentReader> Create(ContentManager* contentManager, Stream* input, String const& assetName);
|
||||
|
||||
template <typename T>
|
||||
sptr<T> ReadAsset() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
//ContentReader(ContentManager* contentManager, Stream& inut)
|
||||
ContentReader(ContentManager* contentManager, sptr<Stream>const& input, String const& assetName)
|
||||
: BinaryReader(input), _contentManager(contentManager), _assetName(assetName){}
|
||||
|
||||
static sptr<Stream> PrepareStream(sptr<Stream>& input, String const* assetName, Int& graphicsProfile);
|
||||
|
||||
Int ReadHeader();
|
||||
|
||||
private:
|
||||
ContentManager* _contentManager = nullptr;
|
||||
String _assetName;
|
||||
};
|
||||
}
|
||||
|
||||
|
137
framework/content/typereadermanager.cpp
Normal file
137
framework/content/typereadermanager.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
#include "typereadermanager.hpp"
|
||||
#include "reader.hpp"
|
||||
|
||||
namespace xna {
|
||||
std::vector<PContentTypeReader> ContentTypeReaderManager::ReadTypeManifest(Int typeCount, sptr<ContentReader>& contentReader, xna_error_ptr_arg)
|
||||
{
|
||||
initMaps();
|
||||
|
||||
auto contentTypeReaderArray = std::vector<PContentTypeReader>(typeCount);
|
||||
std::vector<PContentTypeReader> newTypeReaders;
|
||||
|
||||
for (size_t index = 0; index < typeCount; ++index)
|
||||
{
|
||||
auto typeReader = ContentTypeReaderManager::GetTypeReader(contentReader->ReadString(), contentReader, newTypeReaders);
|
||||
|
||||
if (contentReader->ReadInt32() != typeReader->TypeVersion()) {
|
||||
xna_error_apply(err, XnaErrorCode::BAD_TYPE);
|
||||
ContentTypeReaderManager::RollbackAddReaders(newTypeReaders);
|
||||
return std::vector<PContentTypeReader>();
|
||||
}
|
||||
|
||||
contentTypeReaderArray[index] = typeReader;
|
||||
|
||||
if (!newTypeReaders.empty()) {
|
||||
auto manager = std::shared_ptr<ContentTypeReaderManager>(new ContentTypeReaderManager(contentReader));
|
||||
|
||||
for (size_t i = 0; i < newTypeReaders.size(); ++i) {
|
||||
auto& contentTypeReader = newTypeReaders[i];
|
||||
contentTypeReader->Initialize(manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return contentTypeReaderArray;
|
||||
}
|
||||
|
||||
sptr<ContentTypeReader> ContentTypeReaderManager::GetTypeReader(String const& targetType, sptr<ContentReader>& contentReader, xna_error_ptr_arg)
|
||||
{
|
||||
if (targetType.empty())
|
||||
return nullptr;
|
||||
|
||||
sptr<ContentTypeReader> typeReader = nullptr;
|
||||
|
||||
if (!ContentTypeReaderManager::targetTypeToReader.contains(targetType)) {
|
||||
xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ContentTypeReaderManager::targetTypeToReader[targetType];
|
||||
}
|
||||
|
||||
ContentTypeReaderManager::ContentTypeReaderManager(sptr<ContentReader>& contentReader) {
|
||||
initMaps();
|
||||
}
|
||||
|
||||
sptr<ContentTypeReader> ContentTypeReaderManager::GetTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, std::vector<PContentTypeReader>& newTypeReaders, xna_error_ptr_arg)
|
||||
{
|
||||
sptr<ContentTypeReader> reader = nullptr;
|
||||
|
||||
if (ContentTypeReaderManager::nameToReader.contains(readerTypeName) || !ContentTypeReaderManager::InstantiateTypeReader(readerTypeName, contentReader, reader)) {
|
||||
return ContentTypeReaderManager::nameToReader[readerTypeName];
|
||||
}
|
||||
|
||||
ContentTypeReaderManager::AddTypeReader(readerTypeName, contentReader, reader, err);
|
||||
|
||||
if (xna_error_haserros(err)) return nullptr;
|
||||
|
||||
newTypeReaders.push_back(reader);
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
bool ContentTypeReaderManager::InstantiateTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader)
|
||||
{
|
||||
if (ContentTypeReaderManager::readerTypeToReader.contains(readerTypeName)) {
|
||||
reader = ContentTypeReaderManager::readerTypeToReader[readerTypeName];
|
||||
ContentTypeReaderManager::nameToReader.insert({ readerTypeName, reader });
|
||||
return false;
|
||||
}
|
||||
|
||||
reader = ContentTypeReaderActivador::CreateInstance(readerTypeName);
|
||||
}
|
||||
|
||||
void ContentTypeReaderManager::AddTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_ptr_arg)
|
||||
{
|
||||
auto targetType = reader->TargetType();
|
||||
|
||||
if (ContentTypeReaderManager::targetTypeToReader.contains(targetType)) {
|
||||
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
ContentTypeReaderManager::targetTypeToReader.insert({ targetType, reader });
|
||||
ContentTypeReaderManager::readerTypeToReader.insert({ reader->GetType(), reader });
|
||||
ContentTypeReaderManager::nameToReader.insert({ readerTypeName, reader });
|
||||
}
|
||||
|
||||
void ContentTypeReaderManager::RollbackAddReaders(std::vector<sptr<ContentTypeReader>>& newTypeReaders)
|
||||
{
|
||||
if (newTypeReaders.empty())
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < newTypeReaders.size(); ++i) {
|
||||
auto newTypeReader = newTypeReaders[i];
|
||||
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::nameToReader, newTypeReader);
|
||||
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::targetTypeToReader, newTypeReader);
|
||||
ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::readerTypeToReader, newTypeReader);
|
||||
}
|
||||
}
|
||||
|
||||
void ContentTypeReaderManager::RollbackAddReader(std::map<String, sptr<ContentTypeReader>>& 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::initMaps()
|
||||
{
|
||||
if (targetTypeToReader.empty() && readerTypeToReader.empty()) {
|
||||
auto typeReader = New<ObjectReader>();
|
||||
auto contentTypeReader = reinterpret_pointer_cast<ContentTypeReader>(typeReader);
|
||||
|
||||
targetTypeToReader.insert({ typeReader->TargetType(), contentTypeReader});
|
||||
readerTypeToReader.insert({ typeReader->GetType(), contentTypeReader});
|
||||
}
|
||||
}
|
||||
|
||||
sptr<void> ObjectReader::Read(ContentReader input, sptr<void> existingInstance)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
114
framework/content/typereadermanager.hpp
Normal file
114
framework/content/typereadermanager.hpp
Normal file
@ -0,0 +1,114 @@
|
||||
#ifndef XNA_CONTENT_TYPEREADER_HPP
|
||||
#define XNA_CONTENT_TYPEREADER_HPP
|
||||
|
||||
#include "../default.hpp"
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
namespace xna {
|
||||
//ContentTypeReader
|
||||
class ContentTypeReader {
|
||||
public:
|
||||
virtual Int TypeVersion() { return 0; }
|
||||
virtual bool CanDeserializeIntoExistingObject() { return 0; }
|
||||
virtual void Initialize(sptr<ContentTypeReaderManager>& manager) {}
|
||||
|
||||
constexpr String TargetType() { return _targetType; }
|
||||
|
||||
virtual String GetType() { return "ContentTypeReader"; }
|
||||
|
||||
protected:
|
||||
ContentTypeReader(String targetType) : _targetType(targetType) {
|
||||
}
|
||||
|
||||
virtual sptr<void> Read(ContentReader input, sptr<void> existingInstance) = 0;
|
||||
|
||||
private:
|
||||
String _targetType = "contentTypeReader";
|
||||
};
|
||||
|
||||
//ContentTypeReaderActivador
|
||||
class ContentTypeReaderActivador {
|
||||
public:
|
||||
using Activador = sptr<ContentTypeReader>(*)();
|
||||
|
||||
static sptr<ContentTypeReader> CreateInstance(String const& readerTypeName) {
|
||||
if (!activators.contains(readerTypeName))
|
||||
return nullptr;
|
||||
|
||||
auto activador = activators[readerTypeName];
|
||||
|
||||
if (!activador) return nullptr;
|
||||
|
||||
return activador();
|
||||
}
|
||||
|
||||
static void SetActivador(String const& readerTypeName, Activador activador) {
|
||||
if (!activators.contains(readerTypeName))
|
||||
activators.insert({ readerTypeName, activador });
|
||||
}
|
||||
|
||||
private:
|
||||
inline static std::map<String, Activador> activators =
|
||||
std::map<String, Activador>();
|
||||
|
||||
ContentTypeReaderActivador();
|
||||
ContentTypeReaderActivador(ContentTypeReaderActivador&&);
|
||||
ContentTypeReaderActivador(ContentTypeReaderActivador&);
|
||||
};
|
||||
|
||||
using PContentTypeReader = sptr<ContentTypeReader>;
|
||||
|
||||
//ContentTypeReaderManager
|
||||
class ContentTypeReaderManager {
|
||||
public:
|
||||
static std::vector<PContentTypeReader> ReadTypeManifest(Int typeCount, sptr<ContentReader>& contentReader, xna_error_nullarg);
|
||||
static sptr<ContentTypeReader> GetTypeReader(String const& targetType, sptr<ContentReader>& contentReader, xna_error_nullarg);
|
||||
|
||||
inline sptr<ContentTypeReader> GetTypeReader(String const& targetType, xna_error_nullarg) {
|
||||
return ContentTypeReaderManager::GetTypeReader(targetType, this->contentReader, err);
|
||||
}
|
||||
|
||||
inline static bool ContainsTypeReader(String const& targetType) {
|
||||
return ContentTypeReaderManager::targetTypeToReader.contains(targetType);
|
||||
}
|
||||
|
||||
private:
|
||||
ContentTypeReaderManager(sptr<ContentReader>& contentReader);
|
||||
static sptr<ContentTypeReader> GetTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, std::vector<PContentTypeReader>& newTypeReaders, 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 RollbackAddReaders(std::vector<sptr<ContentTypeReader>>& newTypeReaders);
|
||||
static void RollbackAddReader(std::map<String, sptr<ContentTypeReader>>& dictionary, sptr<ContentTypeReader>& reader);
|
||||
|
||||
|
||||
private:
|
||||
sptr<ContentReader> contentReader = nullptr;
|
||||
|
||||
inline static std::map<String, PContentTypeReader> nameToReader = std::map<String, PContentTypeReader>();
|
||||
inline static std::map<String, PContentTypeReader> targetTypeToReader = std::map<String, PContentTypeReader>();
|
||||
inline static std::map<String, PContentTypeReader> readerTypeToReader = std::map<String, PContentTypeReader>();
|
||||
|
||||
static void initMaps();
|
||||
};
|
||||
|
||||
//ObjectReader
|
||||
class ObjectReader : public ContentTypeReader {
|
||||
public:
|
||||
ObjectReader() : ContentTypeReader("object"){
|
||||
ContentTypeReaderActivador::SetActivador("object", []() -> sptr<ContentTypeReader> {
|
||||
auto obj = New <ObjectReader>();
|
||||
return reinterpret_pointer_cast<ContentTypeReader>(obj);
|
||||
});
|
||||
}
|
||||
|
||||
// Inherited via ContentTypeReader
|
||||
sptr<void> Read(ContentReader input, sptr<void> existingInstance) override;
|
||||
|
||||
String GetType() override {
|
||||
return "ObjectReader";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,4 +1,5 @@
|
||||
#include "binary.hpp"
|
||||
#include "../csharp/buffer.hpp"
|
||||
|
||||
namespace xna {
|
||||
Int BinaryReader::PeekChar(xna_error_ptr_arg)
|
||||
@ -6,7 +7,7 @@ namespace xna {
|
||||
if (!stream) {
|
||||
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const auto position = stream->Position();
|
||||
const auto num = Read(err);
|
||||
@ -267,7 +268,7 @@ namespace xna {
|
||||
{
|
||||
Int num1 = 0;
|
||||
Long num2 = 0;
|
||||
Long num3 = stream->Position();
|
||||
Long num3 = stream->Position();
|
||||
|
||||
if (charBytes.empty())
|
||||
charBytes.resize(128);
|
||||
@ -352,7 +353,7 @@ namespace xna {
|
||||
}
|
||||
}
|
||||
|
||||
Int BinaryReader::InternalReadChars(char* buffer, size_t bufferSize, Int index, Int count, xna_error_ptr_arg)
|
||||
Int BinaryReader::InternalReadChars(Char* buffer, size_t bufferSize, size_t index, size_t count, xna_error_ptr_arg)
|
||||
{
|
||||
auto charCount = count;
|
||||
|
||||
@ -371,18 +372,18 @@ namespace xna {
|
||||
if (count1 > 128)
|
||||
count1 = 128;
|
||||
|
||||
Int num = 0;
|
||||
Int position = 0;
|
||||
Int byteCount;
|
||||
|
||||
std::vector<Byte> numArray;
|
||||
|
||||
byteCount = stream->Read(charBytes, 0, count1);
|
||||
byteCount = stream->Read(charBytes, 0, static_cast<Int>(count1), err);
|
||||
numArray = charBytes;
|
||||
|
||||
if (byteCount == 0)
|
||||
return count - charCount;
|
||||
return static_cast<Int>(count - charCount);
|
||||
|
||||
if (num < 0 || byteCount < 0 || (num + byteCount) > numArray.size()) {
|
||||
if (position < 0 || byteCount < 0 || (position + byteCount) > numArray.size()) {
|
||||
xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE);
|
||||
return -1;
|
||||
}
|
||||
@ -393,22 +394,28 @@ namespace xna {
|
||||
}
|
||||
|
||||
auto data = reinterpret_cast<char*>(charBytes.data());
|
||||
const auto result = std::string((data + num), (data + num) + byteCount);
|
||||
auto pChars = reinterpret_cast<char*>(buffer);
|
||||
|
||||
//const auto result = std::string((data + position), (pChars + index) + byteCount);
|
||||
const auto result = std::string((data + position), (data + position) + byteCount);
|
||||
Buffer::BlockCopy(result.c_str(), position, pChars, index, byteCount);
|
||||
|
||||
const auto chars = result.size();
|
||||
buffer = reinterpret_cast<Char*>(pChars);
|
||||
|
||||
charCount -= static_cast<Int>(chars);
|
||||
index += static_cast<Int>(chars);
|
||||
const auto chars = static_cast<Int>(result.size());
|
||||
|
||||
charCount -= chars;
|
||||
index += chars;
|
||||
}
|
||||
|
||||
return count - charCount;
|
||||
return static_cast<Int>(count - charCount);
|
||||
}
|
||||
|
||||
Long BinaryWriter::Seek(Int offset, SeekOrigin origin, xna_error_ptr_arg)
|
||||
{
|
||||
if (!_stream) {
|
||||
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
||||
return - 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _stream->Seek(offset, origin);
|
||||
@ -648,4 +655,55 @@ namespace xna {
|
||||
_buffer[7] = static_cast<Byte>(value >> 56);
|
||||
_stream->Write(_buffer, 0, 8);
|
||||
}
|
||||
|
||||
Int BinaryReader::Read7BitEncodedInt(xna_error_ptr_arg)
|
||||
{
|
||||
Int num1 = 0;
|
||||
Int num2 = 0;
|
||||
|
||||
while (num2 != 35) {
|
||||
auto num3 = ReadByte(err);
|
||||
|
||||
if (xna_error_haserros(err))
|
||||
return -1;
|
||||
|
||||
num1 |= (static_cast<Int>(num3) & static_cast<Int>(SbyteMaxValue)) << num2;
|
||||
num2 += 7;
|
||||
|
||||
if ((static_cast<Int>(num3) & 128) == 0)
|
||||
return num1;
|
||||
}
|
||||
|
||||
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Int BinaryReader::Read(std::vector<Char>& buffer, size_t index, size_t count, xna_error_ptr_arg)
|
||||
{
|
||||
return InternalReadChars(buffer.data(), buffer.size(), index, count, err);
|
||||
}
|
||||
|
||||
std::vector<Byte> BinaryReader::ReadBytes(size_t count, xna_error_ptr_arg)
|
||||
{
|
||||
std::vector<Byte> result(count);
|
||||
Int numRead = 0;
|
||||
|
||||
do {
|
||||
const auto n = stream->Read(result, static_cast<Int>(numRead), static_cast<Int>(count), err);
|
||||
|
||||
if (n == 0)
|
||||
break;
|
||||
|
||||
numRead += n;
|
||||
count -= n;
|
||||
} while (count > 0);
|
||||
|
||||
if (numRead != result.size()) {
|
||||
std::vector<Byte> copy(numRead);
|
||||
Buffer::BlockCopy(result.data(), 0, copy.data(), 0, numRead);
|
||||
result = copy;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
namespace xna {
|
||||
class BinaryReader {
|
||||
public:
|
||||
BinaryReader(Stream* const& input) {
|
||||
BinaryReader(sptr<Stream> const& input) {
|
||||
stream = input;
|
||||
buffer = std::vector<Byte>(bufferLength);
|
||||
}
|
||||
@ -28,18 +28,14 @@ namespace xna {
|
||||
double ReadDouble(xna_error_nullarg);
|
||||
std::string ReadString(xna_error_nullarg);
|
||||
|
||||
Int Read(std::vector<Char>& buffer, size_t index, size_t count, xna_error_nullarg) {
|
||||
return -1;
|
||||
}
|
||||
Int Read(std::vector<Char>& buffer, size_t index, size_t count, xna_error_nullarg);
|
||||
|
||||
std::vector<Byte> ReadBytes(size_t count, xna_error_nullarg) {
|
||||
return std::vector<Byte>();
|
||||
}
|
||||
std::vector<Byte> ReadBytes(size_t count, xna_error_nullarg);
|
||||
|
||||
private:
|
||||
static constexpr int maxCharBytesSize = 128;
|
||||
static constexpr int bufferLength = 16;
|
||||
Stream* stream = nullptr;
|
||||
sptr<Stream> stream = nullptr;
|
||||
std::vector<Byte> charBytes;
|
||||
std::vector<Char> singleChar;
|
||||
std::vector<Byte> buffer;
|
||||
@ -51,34 +47,14 @@ namespace xna {
|
||||
|
||||
void FillBuffer(Int numBytes, xna_error_nullarg);
|
||||
|
||||
Int Read7BitEncodedInt(xna_error_nullarg)
|
||||
{
|
||||
Int num1 = 0;
|
||||
Int num2 = 0;
|
||||
Int Read7BitEncodedInt(xna_error_nullarg);
|
||||
|
||||
while (num2 != 35) {
|
||||
auto num3 = ReadByte(err);
|
||||
|
||||
if (xna_error_haserros(err))
|
||||
return -1;
|
||||
|
||||
num1 |= (static_cast<Int>(num3) & static_cast<Int>(SbyteMaxValue)) << num2;
|
||||
num2 += 7;
|
||||
|
||||
if ((static_cast<Int>(num3) & 128) == 0)
|
||||
return num1;
|
||||
}
|
||||
|
||||
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Int InternalReadChars(char* buffer, size_t bufferSize, Int index, Int count, xna_error_nullarg);
|
||||
Int InternalReadChars(Char* buffer, size_t bufferSize, size_t index, size_t count, xna_error_nullarg);
|
||||
};
|
||||
|
||||
class BinaryWriter {
|
||||
public:
|
||||
BinaryWriter(Stream* stream) : _stream(stream), _buffer(16) {
|
||||
BinaryWriter(sptr<Stream> const& stream) : _stream(stream), _buffer(16) {
|
||||
}
|
||||
|
||||
Long Seek(Int offset, SeekOrigin origin, xna_error_nullarg);
|
||||
@ -103,7 +79,7 @@ namespace xna {
|
||||
void Write(const char* _string, size_t stringLength, xna_error_nullarg);
|
||||
|
||||
public:
|
||||
Stream* _stream;
|
||||
sptr<Stream> _stream = nullptr;
|
||||
|
||||
private:
|
||||
std::vector<Byte> _buffer;
|
||||
|
@ -8,12 +8,7 @@ namespace xna {
|
||||
class Buffer {
|
||||
public:
|
||||
template <typename T>
|
||||
static void BlockCopy(
|
||||
T const* src,
|
||||
rsize_t srcOffset,
|
||||
T* dst,
|
||||
rsize_t dstOffset,
|
||||
rsize_t byteCount) {
|
||||
static void BlockCopy(T const* src, rsize_t srcOffset, T* dst, rsize_t dstOffset, rsize_t byteCount) {
|
||||
memmove_s(dst + dstOffset, byteCount, src + srcOffset, byteCount);
|
||||
}
|
||||
|
||||
|
13
framework/csharp/object.cpp
Normal file
13
framework/csharp/object.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "object.hpp"
|
||||
#include "type.hpp"
|
||||
|
||||
namespace xna {
|
||||
sptr<Type> Object::GetType()
|
||||
{
|
||||
auto type = New<Type>();
|
||||
type->FullName = "Object";
|
||||
type->Namespace = "xna";
|
||||
type->IsClass = true;
|
||||
return type;
|
||||
}
|
||||
}
|
13
framework/csharp/object.hpp
Normal file
13
framework/csharp/object.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef XNA_CSHARP_OBJECT_HPP
|
||||
#define XNA_CSHARP_OBJECT_HPP
|
||||
|
||||
#include "../default.hpp"
|
||||
|
||||
namespace xna {
|
||||
class Object {
|
||||
public:
|
||||
virtual sptr<Type> GetType();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -10,6 +10,7 @@
|
||||
namespace xna {
|
||||
class Stream {
|
||||
public:
|
||||
virtual ~Stream(){}
|
||||
virtual Int Length() = 0;
|
||||
virtual Long Position() = 0;
|
||||
virtual void Close() = 0;
|
||||
@ -47,13 +48,13 @@ namespace xna {
|
||||
_buffer = std::vector<Byte>();
|
||||
}
|
||||
|
||||
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg) override;
|
||||
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
|
||||
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg) override;
|
||||
virtual Int ReadByte(xna_error_ptr_arg) override;
|
||||
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
|
||||
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg) override;
|
||||
virtual void WriteByte(Byte value, xna_error_ptr_arg) override;
|
||||
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) override;
|
||||
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
|
||||
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||
virtual Int ReadByte(xna_error_nullarg) override;
|
||||
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
|
||||
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||
virtual void WriteByte(Byte value, xna_error_nullarg) override;
|
||||
|
||||
public:
|
||||
Int _position{ 0 };
|
||||
@ -108,13 +109,13 @@ namespace xna {
|
||||
_fstream.close();
|
||||
}
|
||||
|
||||
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg) override;
|
||||
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
|
||||
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg) override;
|
||||
virtual Int ReadByte(xna_error_ptr_arg) override;
|
||||
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
|
||||
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg) override;
|
||||
virtual void WriteByte(Byte value, xna_error_ptr_arg) override;
|
||||
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) override;
|
||||
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
|
||||
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||
virtual Int ReadByte(xna_error_nullarg) override;
|
||||
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override;
|
||||
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||
virtual void WriteByte(Byte value, xna_error_nullarg) override;
|
||||
|
||||
public:
|
||||
std::streampos _filesize{ 0 };
|
||||
|
32
framework/csharp/type.hpp
Normal file
32
framework/csharp/type.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef XNA_CSHARP_TYPE_HPP
|
||||
#define XNA_CSHARP_TYPE_HPP
|
||||
|
||||
#include "../default.hpp"
|
||||
#include "object.hpp"
|
||||
|
||||
namespace xna {
|
||||
class Type {
|
||||
public:
|
||||
String Namespace;
|
||||
String FullName;
|
||||
bool IsInterface{ false };
|
||||
bool IsArray{ false };
|
||||
bool IsPointer{ false };
|
||||
bool IsClass{ false };
|
||||
bool IsCOMObject{ false };
|
||||
bool IsEnum{ false };
|
||||
bool IsValueType{ false };
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline sptr<Type> typeof(T const& obj) {
|
||||
auto obj = reinterpret_cast<Object*>(&obj);
|
||||
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
return obj->GetType();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -15,10 +15,14 @@ namespace xna {
|
||||
class Stream;
|
||||
class FileStream;
|
||||
class MemoryStream;
|
||||
class Object;
|
||||
class Type;
|
||||
|
||||
//Content
|
||||
class ContentManager;
|
||||
class ContentReader;
|
||||
class ContentTypeReader;
|
||||
class ContentTypeReaderManager;
|
||||
|
||||
//Framework
|
||||
class BoundingBox;
|
||||
|
@ -18,7 +18,8 @@ namespace xna {
|
||||
contentManager = New<ContentManager>("Content");
|
||||
//const auto s = contentManager->_path.string();
|
||||
// const auto current = std::filesystem::current_path();
|
||||
auto s = contentManager->OpenStream("file");
|
||||
//auto s = contentManager->OpenStream("file");
|
||||
//DecompressStream::Decompress();
|
||||
}
|
||||
|
||||
void Initialize() override {
|
||||
@ -30,7 +31,7 @@ namespace xna {
|
||||
spriteBatch = New<SpriteBatch>(*_graphicsDevice);
|
||||
|
||||
XnaErrorCode err;
|
||||
texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err);
|
||||
texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err);
|
||||
|
||||
Game::LoadContent();
|
||||
}
|
||||
|
@ -24,5 +24,6 @@
|
||||
#include "Windows.h"
|
||||
#include <iostream>
|
||||
#include "content/manager.hpp"
|
||||
#include "content/decstream.hpp"
|
||||
|
||||
// TODO: Reference additional headers your program requires here.
|
||||
|
@ -13,7 +13,8 @@ namespace xna {
|
||||
BAD_CAST,
|
||||
STREAM_ERROR,
|
||||
UNINTIALIZED_RESOURCE,
|
||||
END_OF_FILE
|
||||
END_OF_FILE,
|
||||
BAD_TYPE
|
||||
};
|
||||
|
||||
inline void xna_error_apply(XnaErrorCode* source, XnaErrorCode const& value) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user