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>>")
|
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()
|
endif()
|
||||||
|
|
||||||
|
set(ENV{VCPKG_ROOT} C:\\vcpkg)
|
||||||
|
|
||||||
project ("xna")
|
project ("xna")
|
||||||
|
|
||||||
# Include sub-projects.
|
# Include sub-projects.
|
||||||
|
@ -3,7 +3,43 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# Add source to this project's executable.
|
# 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)
|
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||||
set_property(TARGET xna PROPERTY CXX_STANDARD 20)
|
set_property(TARGET xna PROPERTY CXX_STANDARD 20)
|
||||||
@ -12,7 +48,6 @@ endif()
|
|||||||
# TODO: Add tests and install targets if needed.
|
# TODO: Add tests and install targets if needed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -- Biblioteca DirectxTK --
|
# -- Biblioteca DirectxTK --
|
||||||
# Url: https://github.com/microsoft/DirectXTK/wiki/DirectXTK
|
# Url: https://github.com/microsoft/DirectXTK/wiki/DirectXTK
|
||||||
#
|
#
|
||||||
@ -30,5 +65,14 @@ endif()
|
|||||||
# "CMAKE_TOOLCHAIN_FILE": "{VCPKG_DIR}\\scripts\\buildsystems\\vcpkg.cmake"
|
# "CMAKE_TOOLCHAIN_FILE": "{VCPKG_DIR}\\scripts\\buildsystems\\vcpkg.cmake"
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
|
# Instalaçao do libmspack
|
||||||
|
# $- vcpkg install libmspack
|
||||||
|
#
|
||||||
find_package(directxtk CONFIG REQUIRED)
|
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 "reader.hpp"
|
||||||
#include "manager.hpp"
|
#include "manager.hpp"
|
||||||
|
#include "lzx/decoderstream.hpp"
|
||||||
|
|
||||||
namespace xna {
|
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>();
|
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
|
#define XNA_CONTENT_READER_HPP
|
||||||
|
|
||||||
#include "../default.hpp"
|
#include "../default.hpp"
|
||||||
|
#include "../csharp/binary.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
class ContentReader {
|
class ContentReader : public BinaryReader{
|
||||||
public:
|
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:
|
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 "binary.hpp"
|
||||||
|
#include "../csharp/buffer.hpp"
|
||||||
|
|
||||||
namespace xna {
|
namespace xna {
|
||||||
Int BinaryReader::PeekChar(xna_error_ptr_arg)
|
Int BinaryReader::PeekChar(xna_error_ptr_arg)
|
||||||
@ -6,7 +7,7 @@ namespace xna {
|
|||||||
if (!stream) {
|
if (!stream) {
|
||||||
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto position = stream->Position();
|
const auto position = stream->Position();
|
||||||
const auto num = Read(err);
|
const auto num = Read(err);
|
||||||
@ -267,7 +268,7 @@ namespace xna {
|
|||||||
{
|
{
|
||||||
Int num1 = 0;
|
Int num1 = 0;
|
||||||
Long num2 = 0;
|
Long num2 = 0;
|
||||||
Long num3 = stream->Position();
|
Long num3 = stream->Position();
|
||||||
|
|
||||||
if (charBytes.empty())
|
if (charBytes.empty())
|
||||||
charBytes.resize(128);
|
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;
|
auto charCount = count;
|
||||||
|
|
||||||
@ -371,18 +372,18 @@ namespace xna {
|
|||||||
if (count1 > 128)
|
if (count1 > 128)
|
||||||
count1 = 128;
|
count1 = 128;
|
||||||
|
|
||||||
Int num = 0;
|
Int position = 0;
|
||||||
Int byteCount;
|
Int byteCount;
|
||||||
|
|
||||||
std::vector<Byte> numArray;
|
std::vector<Byte> numArray;
|
||||||
|
|
||||||
byteCount = stream->Read(charBytes, 0, count1);
|
byteCount = stream->Read(charBytes, 0, static_cast<Int>(count1), err);
|
||||||
numArray = charBytes;
|
numArray = charBytes;
|
||||||
|
|
||||||
if (byteCount == 0)
|
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);
|
xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -393,22 +394,28 @@ namespace xna {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto data = reinterpret_cast<char*>(charBytes.data());
|
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);
|
const auto chars = static_cast<Int>(result.size());
|
||||||
index += static_cast<Int>(chars);
|
|
||||||
|
charCount -= chars;
|
||||||
|
index += chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count - charCount;
|
return static_cast<Int>(count - charCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
Long BinaryWriter::Seek(Int offset, SeekOrigin origin, xna_error_ptr_arg)
|
Long BinaryWriter::Seek(Int offset, SeekOrigin origin, xna_error_ptr_arg)
|
||||||
{
|
{
|
||||||
if (!_stream) {
|
if (!_stream) {
|
||||||
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
||||||
return - 1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _stream->Seek(offset, origin);
|
return _stream->Seek(offset, origin);
|
||||||
@ -648,4 +655,55 @@ namespace xna {
|
|||||||
_buffer[7] = static_cast<Byte>(value >> 56);
|
_buffer[7] = static_cast<Byte>(value >> 56);
|
||||||
_stream->Write(_buffer, 0, 8);
|
_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 {
|
namespace xna {
|
||||||
class BinaryReader {
|
class BinaryReader {
|
||||||
public:
|
public:
|
||||||
BinaryReader(Stream* const& input) {
|
BinaryReader(sptr<Stream> const& input) {
|
||||||
stream = input;
|
stream = input;
|
||||||
buffer = std::vector<Byte>(bufferLength);
|
buffer = std::vector<Byte>(bufferLength);
|
||||||
}
|
}
|
||||||
@ -28,18 +28,14 @@ namespace xna {
|
|||||||
double ReadDouble(xna_error_nullarg);
|
double ReadDouble(xna_error_nullarg);
|
||||||
std::string ReadString(xna_error_nullarg);
|
std::string ReadString(xna_error_nullarg);
|
||||||
|
|
||||||
Int Read(std::vector<Char>& buffer, size_t index, size_t count, xna_error_nullarg) {
|
Int Read(std::vector<Char>& buffer, size_t index, size_t count, xna_error_nullarg);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Byte> ReadBytes(size_t count, xna_error_nullarg) {
|
std::vector<Byte> ReadBytes(size_t count, xna_error_nullarg);
|
||||||
return std::vector<Byte>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr int maxCharBytesSize = 128;
|
static constexpr int maxCharBytesSize = 128;
|
||||||
static constexpr int bufferLength = 16;
|
static constexpr int bufferLength = 16;
|
||||||
Stream* stream = nullptr;
|
sptr<Stream> stream = nullptr;
|
||||||
std::vector<Byte> charBytes;
|
std::vector<Byte> charBytes;
|
||||||
std::vector<Char> singleChar;
|
std::vector<Char> singleChar;
|
||||||
std::vector<Byte> buffer;
|
std::vector<Byte> buffer;
|
||||||
@ -51,34 +47,14 @@ namespace xna {
|
|||||||
|
|
||||||
void FillBuffer(Int numBytes, xna_error_nullarg);
|
void FillBuffer(Int numBytes, xna_error_nullarg);
|
||||||
|
|
||||||
Int Read7BitEncodedInt(xna_error_nullarg)
|
Int Read7BitEncodedInt(xna_error_nullarg);
|
||||||
{
|
|
||||||
Int num1 = 0;
|
|
||||||
Int num2 = 0;
|
|
||||||
|
|
||||||
while (num2 != 35) {
|
Int InternalReadChars(Char* buffer, size_t bufferSize, size_t index, size_t count, xna_error_nullarg);
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BinaryWriter {
|
class BinaryWriter {
|
||||||
public:
|
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);
|
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);
|
void Write(const char* _string, size_t stringLength, xna_error_nullarg);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Stream* _stream;
|
sptr<Stream> _stream = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Byte> _buffer;
|
std::vector<Byte> _buffer;
|
||||||
|
@ -8,12 +8,7 @@ namespace xna {
|
|||||||
class Buffer {
|
class Buffer {
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void BlockCopy(
|
static void BlockCopy(T const* src, rsize_t srcOffset, T* dst, rsize_t dstOffset, rsize_t byteCount) {
|
||||||
T const* src,
|
|
||||||
rsize_t srcOffset,
|
|
||||||
T* dst,
|
|
||||||
rsize_t dstOffset,
|
|
||||||
rsize_t byteCount) {
|
|
||||||
memmove_s(dst + dstOffset, byteCount, src + srcOffset, 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 {
|
namespace xna {
|
||||||
class Stream {
|
class Stream {
|
||||||
public:
|
public:
|
||||||
|
virtual ~Stream(){}
|
||||||
virtual Int Length() = 0;
|
virtual Int Length() = 0;
|
||||||
virtual Long Position() = 0;
|
virtual Long Position() = 0;
|
||||||
virtual void Close() = 0;
|
virtual void Close() = 0;
|
||||||
@ -47,13 +48,13 @@ namespace xna {
|
|||||||
_buffer = std::vector<Byte>();
|
_buffer = std::vector<Byte>();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Long Seek(Long offset, SeekOrigin const& origin, 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_ptr_arg) 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_ptr_arg) override;
|
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||||
virtual Int ReadByte(xna_error_ptr_arg) override;
|
virtual Int ReadByte(xna_error_nullarg) override;
|
||||||
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) 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_ptr_arg) override;
|
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||||
virtual void WriteByte(Byte value, xna_error_ptr_arg) override;
|
virtual void WriteByte(Byte value, xna_error_nullarg) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Int _position{ 0 };
|
Int _position{ 0 };
|
||||||
@ -108,13 +109,13 @@ namespace xna {
|
|||||||
_fstream.close();
|
_fstream.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Long Seek(Long offset, SeekOrigin const& origin, 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_ptr_arg) 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_ptr_arg) override;
|
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||||
virtual Int ReadByte(xna_error_ptr_arg) override;
|
virtual Int ReadByte(xna_error_nullarg) override;
|
||||||
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) 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_ptr_arg) override;
|
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) override;
|
||||||
virtual void WriteByte(Byte value, xna_error_ptr_arg) override;
|
virtual void WriteByte(Byte value, xna_error_nullarg) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::streampos _filesize{ 0 };
|
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 Stream;
|
||||||
class FileStream;
|
class FileStream;
|
||||||
class MemoryStream;
|
class MemoryStream;
|
||||||
|
class Object;
|
||||||
|
class Type;
|
||||||
|
|
||||||
//Content
|
//Content
|
||||||
class ContentManager;
|
class ContentManager;
|
||||||
class ContentReader;
|
class ContentReader;
|
||||||
|
class ContentTypeReader;
|
||||||
|
class ContentTypeReaderManager;
|
||||||
|
|
||||||
//Framework
|
//Framework
|
||||||
class BoundingBox;
|
class BoundingBox;
|
||||||
|
@ -18,7 +18,8 @@ namespace xna {
|
|||||||
contentManager = New<ContentManager>("Content");
|
contentManager = New<ContentManager>("Content");
|
||||||
//const auto s = contentManager->_path.string();
|
//const auto s = contentManager->_path.string();
|
||||||
// const auto current = std::filesystem::current_path();
|
// const auto current = std::filesystem::current_path();
|
||||||
auto s = contentManager->OpenStream("file");
|
//auto s = contentManager->OpenStream("file");
|
||||||
|
//DecompressStream::Decompress();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize() override {
|
void Initialize() override {
|
||||||
@ -30,7 +31,7 @@ namespace xna {
|
|||||||
spriteBatch = New<SpriteBatch>(*_graphicsDevice);
|
spriteBatch = New<SpriteBatch>(*_graphicsDevice);
|
||||||
|
|
||||||
XnaErrorCode err;
|
XnaErrorCode err;
|
||||||
texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err);
|
texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err);
|
||||||
|
|
||||||
Game::LoadContent();
|
Game::LoadContent();
|
||||||
}
|
}
|
||||||
|
@ -24,5 +24,6 @@
|
|||||||
#include "Windows.h"
|
#include "Windows.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "content/manager.hpp"
|
#include "content/manager.hpp"
|
||||||
|
#include "content/decstream.hpp"
|
||||||
|
|
||||||
// TODO: Reference additional headers your program requires here.
|
// TODO: Reference additional headers your program requires here.
|
||||||
|
@ -13,7 +13,8 @@ namespace xna {
|
|||||||
BAD_CAST,
|
BAD_CAST,
|
||||||
STREAM_ERROR,
|
STREAM_ERROR,
|
||||||
UNINTIALIZED_RESOURCE,
|
UNINTIALIZED_RESOURCE,
|
||||||
END_OF_FILE
|
END_OF_FILE,
|
||||||
|
BAD_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void xna_error_apply(XnaErrorCode* source, XnaErrorCode const& value) {
|
inline void xna_error_apply(XnaErrorCode* source, XnaErrorCode const& value) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user