1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

Arquivos Content

This commit is contained in:
Danilo 2024-05-01 19:09:43 -03:00
parent dba5482e46
commit efab931113
23 changed files with 1484 additions and 75 deletions

View File

@ -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.

View File

@ -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
)

View 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;
}
}

View 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

View File

@ -0,0 +1,5 @@
#include "decoder.hpp"
namespace xna {
}

View 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

View 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)
{
}
}

View 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

View File

@ -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();
}
}

View File

@ -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;
};
}

View 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;
}
}

View 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

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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);
}

View 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;
}
}

View 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

View File

@ -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
View 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

View File

@ -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;

View File

@ -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();
}

View File

@ -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.

View File

@ -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) {