From efab931113c36a94df6f12a842b8edb64b7c6455 Mon Sep 17 00:00:00 2001 From: Danilo Date: Wed, 1 May 2024 19:09:43 -0300 Subject: [PATCH 01/17] Arquivos Content --- CMakeLists.txt | 2 + framework/CMakeLists.txt | 50 +- framework/content/decstream.cpp | 111 ++++ framework/content/decstream.hpp | 60 +++ framework/content/lzx/decoder.cpp | 5 + framework/content/lzx/decoder.hpp | 649 ++++++++++++++++++++++++ framework/content/lzx/decoderstream.cpp | 40 ++ framework/content/lzx/decoderstream.hpp | 88 ++++ framework/content/reader.cpp | 51 +- framework/content/reader.hpp | 21 +- framework/content/typereadermanager.cpp | 137 +++++ framework/content/typereadermanager.hpp | 114 +++++ framework/csharp/binary.cpp | 84 ++- framework/csharp/binary.hpp | 40 +- framework/csharp/buffer.hpp | 7 +- framework/csharp/object.cpp | 13 + framework/csharp/object.hpp | 13 + framework/csharp/stream.hpp | 29 +- framework/csharp/type.hpp | 32 ++ framework/forward.hpp | 4 + framework/xna.cpp | 5 +- framework/xna.h | 1 + framework/xnaerror.hpp | 3 +- 23 files changed, 1484 insertions(+), 75 deletions(-) create mode 100644 framework/content/decstream.cpp create mode 100644 framework/content/decstream.hpp create mode 100644 framework/content/lzx/decoder.cpp create mode 100644 framework/content/lzx/decoder.hpp create mode 100644 framework/content/lzx/decoderstream.cpp create mode 100644 framework/content/lzx/decoderstream.hpp create mode 100644 framework/content/typereadermanager.cpp create mode 100644 framework/content/typereadermanager.hpp create mode 100644 framework/csharp/object.cpp create mode 100644 framework/csharp/object.hpp create mode 100644 framework/csharp/type.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f8c094..5f9f0f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,8 @@ if (POLICY CMP0141) set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") endif() +set(ENV{VCPKG_ROOT} C:\\vcpkg) + project ("xna") # Include sub-projects. diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index d127244..c84a1a2 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -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 +) diff --git a/framework/content/decstream.cpp b/framework/content/decstream.cpp new file mode 100644 index 0000000..7d96ba8 --- /dev/null +++ b/framework/content/decstream.cpp @@ -0,0 +1,111 @@ +#include "decstream.hpp" +#include + +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& 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 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& 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; + } + +} \ No newline at end of file diff --git a/framework/content/decstream.hpp b/framework/content/decstream.hpp new file mode 100644 index 0000000..20219ec --- /dev/null +++ b/framework/content/decstream.hpp @@ -0,0 +1,60 @@ +#ifndef XNA_CONTENT_DECOMPRESS_STREAM_HPP +#define XNA_CONTENT_DECOMPRESS_STREAM_HPP + +#include "../default.hpp" +#include "../csharp/stream.hpp" +#include + +namespace xna { + class DecompressStream : public Stream { + public: + DecompressStream(sptr const& baseStream, Int compressedTodo, Int decompressedTodo): + baseStream(baseStream), compressedTodo(compressedTodo), decompressedTodo(decompressedTodo){ + compressedBuffer = std::vector(CompressedBufferSize); + decompressedBuffer = std::vector(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& 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 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 baseStream = nullptr; + Int compressedTodo{ 0 }; + Int compressedSize{ 0 }; + Int compressedPosition{ 0 }; + std::vector compressedBuffer; + Int decompressedTodo{ 0 }; + Int decompressedSize{ 0 }; + Int decompressedPosition{ 0 }; + std::vector decompressedBuffer; + mscab_decompressor* decompressionContext = nullptr; + + private: + bool DecompressNextBuffer(); + void ReadNextBufferFromDisk(); + void ReadBufferFromDisk(std::vector& buffer, Int& bufferTodo, Int& bufferSize); + }; +} + +#endif \ No newline at end of file diff --git a/framework/content/lzx/decoder.cpp b/framework/content/lzx/decoder.cpp new file mode 100644 index 0000000..4639276 --- /dev/null +++ b/framework/content/lzx/decoder.cpp @@ -0,0 +1,5 @@ +#include "decoder.hpp" + +namespace xna { + +} \ No newline at end of file diff --git a/framework/content/lzx/decoder.hpp b/framework/content/lzx/decoder.hpp new file mode 100644 index 0000000..e93be4a --- /dev/null +++ b/framework/content/lzx/decoder.hpp @@ -0,0 +1,649 @@ +#ifndef XNA_CONTENT_LZX_LZXDECODE_HPP +#define XNA_CONTENT_LZX_LZXDECODE_HPP + +#include "../../default.hpp" +#include "../../csharp/stream.hpp" +#include + +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 PRETREE_table; + std::vector PRETREE_len; + std::vector MAINTREE_table; + std::vector MAINTREE_len; + std::vector LENGTH_table; + std::vector LENGTH_len; + std::vector ALIGNED_table; + std::vector ALIGNED_len; + + // NEEDED MEMBERS + // CAB actualsize + // CAB window + // CAB window_size + // CAB window_posn + Uint actual_size{ 0 }; + std::vector window; + Uint window_size{ 0 }; + Uint window_posn{ 0 }; + }; + + class BitBuffer { + public: + BitBuffer(sptr const& stream) : byteStream(stream) { + InitBitStream(); + } + + constexpr void InitBitStream() { + buffer = 0; + bitsleft = 0; + } + + void EnsureBits(Byte bits) { + while (bitsleft < bits) { + const auto lo = static_cast(byteStream->ReadByte()); + const auto hi = static_cast(byteStream->ReadByte()); + //int amount2shift = sizeofstatic_cast(*8 - 16 - bitsleft; + buffer |= static_cast(((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 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(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(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(j); + j += static_cast(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(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((1 << LzxConstants::PRETREE_TABLEBITS) + (LzxConstants::PRETREE_MAXSYMBOLS << 1)); + m_state.PRETREE_len = std::vector(LzxConstants::PRETREE_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY); + m_state.MAINTREE_table = std::vector((1 << LzxConstants::MAINTREE_TABLEBITS) + (LzxConstants::MAINTREE_MAXSYMBOLS << 1)); + m_state.MAINTREE_len = std::vector(LzxConstants::MAINTREE_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY); + m_state.LENGTH_table = std::vector((1 << LzxConstants::LENGTH_TABLEBITS) + (LzxConstants::LENGTH_MAXSYMBOLS << 1)); + m_state.LENGTH_len = std::vector(LzxConstants::LENGTH_MAXSYMBOLS + LzxConstants::LENTABLE_SAFETY); + m_state.ALIGNED_table = std::vector((1 << LzxConstants::ALIGNED_TABLEBITS) + (LzxConstants::ALIGNED_MAXSYMBOLS << 1)); + m_state.ALIGNED_len = std::vector(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& inData, Int inLen, sptr& 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((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(bitbuf.ReadBits(3)); + i = bitbuf.ReadBits(16); + j = bitbuf.ReadBits(8); + m_state.block_remaining = m_state.block_length = static_cast((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(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(inData->ReadByte()); + ml = static_cast(inData->ReadByte()); + mh = static_cast(inData->ReadByte()); + hi = static_cast(inData->ReadByte()); + R0 = static_cast(lo | ml << 8 | mh << 16 | hi << 24); + lo = static_cast(inData->ReadByte()); + ml = static_cast(inData->ReadByte()); + mh = static_cast(inData->ReadByte()); + hi = static_cast(inData->ReadByte()); + R1 = static_cast(lo | ml << 8 | mh << 16 | hi << 24); + lo = static_cast(inData->ReadByte()); + ml = static_cast(inData->ReadByte()); + mh = static_cast(inData->ReadByte()); + hi = static_cast(inData->ReadByte()); + R2 = static_cast(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(m_state.block_remaining)) > 0 && togo > 0) + { + if (this_run > togo) + this_run = togo; + + togo -= this_run; + m_state.block_remaining -= static_cast(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(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(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(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(bitbuf.ReadBits(static_cast(extra))); + match_offset = static_cast(position_base[match_offset]) - 2 + verbatim_bits; + } + else + { + match_offset = 1; + } + + /* update repeated offset LRU queue */ + R2 = R1; R1 = R0; R0 = static_cast(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(match_offset); + } + else /* match_offset == 2 */ + { + match_offset = (int)R2; + R2 = R0; R0 = static_cast(match_offset); + } + + rundest = (int)window_posn; + this_run -= match_length; + + /* copy any wrapped around source data */ + if (static_cast(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(copy_length); + while (copy_length-- > 0) window[rundest++] = window[runsrc++]; + runsrc = 0; + } + } + window_posn += static_cast(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(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(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(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(position_base[match_offset]) - 2; + if (extra > 3) + { + /* verbatim and aligned bits */ + extra -= 3; + verbatim_bits = static_cast(bitbuf.ReadBits(static_cast(extra))); + match_offset += (verbatim_bits << 3); + aligned_bits = static_cast(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(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(bitbuf.ReadBits(static_cast(extra))); + match_offset += verbatim_bits; + } + else /* extra == 0 */ + { + /* ??? */ + match_offset = 1; + } + + /* update repeated offset LRU queue */ + R2 = R1; R1 = R0; R0 = static_cast(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(match_offset); + } + else /* match_offset == 2 */ + { + match_offset = (int)R2; + R2 = R0; R0 = static_cast(match_offset); + } + + rundest = (int)window_posn; + this_run -= match_length; + + /* copy any wrapped around source data */ + if (static_cast(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(copy_length); + while (copy_length-- > 0) window[rundest++] = window[runsrc++]; + runsrc = 0; + } + } + window_posn += static_cast(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 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(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(window_posn); + + if (start_window_pos == 0) + start_window_pos = static_cast(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(m_state.intel_curpos); + + m_state.intel_curpos = static_cast(curpos) + outLen; + + while (outData->Position() < dataend) + { + if (outData->ReadByte() != 0xE8) { + curpos++; + continue; + } + } + } + + return -1; + } + + return 0; + } + + public: + inline static std::vector position_base; + inline static std::vector extra_bits; + + private: + LzxState m_state; + + Int MakeDecodeTable(Uint nsyms, Uint nbits, std::vector& length, std::vector& table) { + return 0; + } + void ReadLengths(std::vector const& lens, Uint first, Uint last, BitBuffer& bitbuf) {} + Uint ReadHuffSym(std::vector& table, std::vector& lengths, Uint nsyms, Uint nbits, BitBuffer& bitbuf) { + return 0; + } + }; +} + +#endif \ No newline at end of file diff --git a/framework/content/lzx/decoderstream.cpp b/framework/content/lzx/decoderstream.cpp new file mode 100644 index 0000000..b9276f9 --- /dev/null +++ b/framework/content/lzx/decoderstream.cpp @@ -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& 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 const& buffer, Int offset, Int count, xna_error_ptr_arg) + { + } + void LzxDecoderStream::WriteByte(Byte value, xna_error_ptr_arg) + { + } +} \ No newline at end of file diff --git a/framework/content/lzx/decoderstream.hpp b/framework/content/lzx/decoderstream.hpp new file mode 100644 index 0000000..eac4f41 --- /dev/null +++ b/framework/content/lzx/decoderstream.hpp @@ -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& input, Int decompressedSize, Int compressedSize) { + dec = New(16); + Decompress(input, decompressedSize, compressedSize); + } + + private: + void Decompress(sptr& 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(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(stream->ReadByte()); + frame_size = (hi << 8) | lo; + hi = static_cast(stream->ReadByte()); + lo = static_cast(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(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 dec = nullptr; + sptrdecompressedStream = 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& 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 const& buffer, Int offset, Int count, xna_error_nullarg) override; + void WriteByte(Byte value, xna_error_nullarg) override; + }; +} + +#endif \ No newline at end of file diff --git a/framework/content/reader.cpp b/framework/content/reader.cpp index c229138..160c74a 100644 --- a/framework/content/reader.cpp +++ b/framework/content/reader.cpp @@ -1,9 +1,58 @@ #include "reader.hpp" #include "manager.hpp" +#include "lzx/decoderstream.hpp" namespace xna { - sptr ContentReader::Create(ContentManager* contentManager, Stream& input, String const& assetName) + sptr ContentReader::Create(ContentManager* contentManager, Stream* input, String const& assetName) { return sptr(); } + + sptr ContentReader::PrepareStream(sptr& 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(input, compressedTodo, decompressedTodo); + + return reinterpret_pointer_cast(lzxStream); + } + + Int ContentReader::ReadHeader() { + return Int(); + } } diff --git a/framework/content/reader.hpp b/framework/content/reader.hpp index 7d00001..e7382c4 100644 --- a/framework/content/reader.hpp +++ b/framework/content/reader.hpp @@ -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 Create(ContentManager* contentManager, Stream& input, String const& assetName); + static sptr Create(ContentManager* contentManager, Stream* input, String const& assetName); + + template + sptr ReadAsset() { + return nullptr; + } private: - //ContentReader(ContentManager* contentManager, Stream& inut) + ContentReader(ContentManager* contentManager, sptrconst& input, String const& assetName) + : BinaryReader(input), _contentManager(contentManager), _assetName(assetName){} + + static sptr PrepareStream(sptr& input, String const* assetName, Int& graphicsProfile); + + Int ReadHeader(); + + private: + ContentManager* _contentManager = nullptr; + String _assetName; }; } diff --git a/framework/content/typereadermanager.cpp b/framework/content/typereadermanager.cpp new file mode 100644 index 0000000..f5148a5 --- /dev/null +++ b/framework/content/typereadermanager.cpp @@ -0,0 +1,137 @@ +#include "typereadermanager.hpp" +#include "reader.hpp" + +namespace xna { + std::vector ContentTypeReaderManager::ReadTypeManifest(Int typeCount, sptr& contentReader, xna_error_ptr_arg) + { + initMaps(); + + auto contentTypeReaderArray = std::vector(typeCount); + std::vector 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(); + } + + contentTypeReaderArray[index] = typeReader; + + if (!newTypeReaders.empty()) { + auto manager = std::shared_ptr(new ContentTypeReaderManager(contentReader)); + + for (size_t i = 0; i < newTypeReaders.size(); ++i) { + auto& contentTypeReader = newTypeReaders[i]; + contentTypeReader->Initialize(manager); + } + } + } + + return contentTypeReaderArray; + } + + sptr ContentTypeReaderManager::GetTypeReader(String const& targetType, sptr& contentReader, xna_error_ptr_arg) + { + if (targetType.empty()) + return nullptr; + + sptr 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) { + initMaps(); + } + + sptr ContentTypeReaderManager::GetTypeReader(String const& readerTypeName, sptr& contentReader, std::vector& newTypeReaders, xna_error_ptr_arg) + { + sptr 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, sptr& 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, sptr& 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>& 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>& dictionary, sptr& reader) { + std::map>::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(); + auto contentTypeReader = reinterpret_pointer_cast(typeReader); + + targetTypeToReader.insert({ typeReader->TargetType(), contentTypeReader}); + readerTypeToReader.insert({ typeReader->GetType(), contentTypeReader}); + } + } + + sptr ObjectReader::Read(ContentReader input, sptr existingInstance) + { + return nullptr; + } +} \ No newline at end of file diff --git a/framework/content/typereadermanager.hpp b/framework/content/typereadermanager.hpp new file mode 100644 index 0000000..3e92bdc --- /dev/null +++ b/framework/content/typereadermanager.hpp @@ -0,0 +1,114 @@ +#ifndef XNA_CONTENT_TYPEREADER_HPP +#define XNA_CONTENT_TYPEREADER_HPP + +#include "../default.hpp" +#include +#include + +namespace xna { + //ContentTypeReader + class ContentTypeReader { + public: + virtual Int TypeVersion() { return 0; } + virtual bool CanDeserializeIntoExistingObject() { return 0; } + virtual void Initialize(sptr& manager) {} + + constexpr String TargetType() { return _targetType; } + + virtual String GetType() { return "ContentTypeReader"; } + + protected: + ContentTypeReader(String targetType) : _targetType(targetType) { + } + + virtual sptr Read(ContentReader input, sptr existingInstance) = 0; + + private: + String _targetType = "contentTypeReader"; + }; + + //ContentTypeReaderActivador + class ContentTypeReaderActivador { + public: + using Activador = sptr(*)(); + + static sptr 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 activators = + std::map(); + + ContentTypeReaderActivador(); + ContentTypeReaderActivador(ContentTypeReaderActivador&&); + ContentTypeReaderActivador(ContentTypeReaderActivador&); + }; + + using PContentTypeReader = sptr; + + //ContentTypeReaderManager + class ContentTypeReaderManager { + public: + static std::vector ReadTypeManifest(Int typeCount, sptr& contentReader, xna_error_nullarg); + static sptr GetTypeReader(String const& targetType, sptr& contentReader, xna_error_nullarg); + + inline sptr 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); + static sptr GetTypeReader(String const& readerTypeName, sptr& contentReader, std::vector& newTypeReaders, xna_error_nullarg); + static bool InstantiateTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader); + static void AddTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader, xna_error_nullarg); + static void RollbackAddReaders(std::vector>& newTypeReaders); + static void RollbackAddReader(std::map>& dictionary, sptr& reader); + + + private: + sptr contentReader = nullptr; + + inline static std::map nameToReader = std::map(); + inline static std::map targetTypeToReader = std::map(); + inline static std::map readerTypeToReader = std::map(); + + static void initMaps(); + }; + + //ObjectReader + class ObjectReader : public ContentTypeReader { + public: + ObjectReader() : ContentTypeReader("object"){ + ContentTypeReaderActivador::SetActivador("object", []() -> sptr { + auto obj = New (); + return reinterpret_pointer_cast(obj); + }); + } + + // Inherited via ContentTypeReader + sptr Read(ContentReader input, sptr existingInstance) override; + + String GetType() override { + return "ObjectReader"; + } + }; +} + +#endif \ No newline at end of file diff --git a/framework/csharp/binary.cpp b/framework/csharp/binary.cpp index 20adc25..03c60ce 100644 --- a/framework/csharp/binary.cpp +++ b/framework/csharp/binary.cpp @@ -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 numArray; - byteCount = stream->Read(charBytes, 0, count1); + byteCount = stream->Read(charBytes, 0, static_cast(count1), err); numArray = charBytes; if (byteCount == 0) - return count - charCount; + return static_cast(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(charBytes.data()); - const auto result = std::string((data + num), (data + num) + byteCount); + auto pChars = reinterpret_cast(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(pChars); - charCount -= static_cast(chars); - index += static_cast(chars); + const auto chars = static_cast(result.size()); + + charCount -= chars; + index += chars; } - return count - charCount; + return static_cast(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(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(num3) & static_cast(SbyteMaxValue)) << num2; + num2 += 7; + + if ((static_cast(num3) & 128) == 0) + return num1; + } + + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return -1; + } + + Int BinaryReader::Read(std::vector& buffer, size_t index, size_t count, xna_error_ptr_arg) + { + return InternalReadChars(buffer.data(), buffer.size(), index, count, err); + } + + std::vector BinaryReader::ReadBytes(size_t count, xna_error_ptr_arg) + { + std::vector result(count); + Int numRead = 0; + + do { + const auto n = stream->Read(result, static_cast(numRead), static_cast(count), err); + + if (n == 0) + break; + + numRead += n; + count -= n; + } while (count > 0); + + if (numRead != result.size()) { + std::vector copy(numRead); + Buffer::BlockCopy(result.data(), 0, copy.data(), 0, numRead); + result = copy; + } + + return result; + } } \ No newline at end of file diff --git a/framework/csharp/binary.hpp b/framework/csharp/binary.hpp index a8ad428..b06249c 100644 --- a/framework/csharp/binary.hpp +++ b/framework/csharp/binary.hpp @@ -7,7 +7,7 @@ namespace xna { class BinaryReader { public: - BinaryReader(Stream* const& input) { + BinaryReader(sptr const& input) { stream = input; buffer = std::vector(bufferLength); } @@ -28,18 +28,14 @@ namespace xna { double ReadDouble(xna_error_nullarg); std::string ReadString(xna_error_nullarg); - Int Read(std::vector& buffer, size_t index, size_t count, xna_error_nullarg) { - return -1; - } + Int Read(std::vector& buffer, size_t index, size_t count, xna_error_nullarg); - std::vector ReadBytes(size_t count, xna_error_nullarg) { - return std::vector(); - } + std::vector ReadBytes(size_t count, xna_error_nullarg); private: static constexpr int maxCharBytesSize = 128; static constexpr int bufferLength = 16; - Stream* stream = nullptr; + sptr stream = nullptr; std::vector charBytes; std::vector singleChar; std::vector 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(num3) & static_cast(SbyteMaxValue)) << num2; - num2 += 7; - - if ((static_cast(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 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 = nullptr; private: std::vector _buffer; diff --git a/framework/csharp/buffer.hpp b/framework/csharp/buffer.hpp index 6c5775f..e2a8e75 100644 --- a/framework/csharp/buffer.hpp +++ b/framework/csharp/buffer.hpp @@ -8,12 +8,7 @@ namespace xna { class Buffer { public: template - 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); } diff --git a/framework/csharp/object.cpp b/framework/csharp/object.cpp new file mode 100644 index 0000000..067c9ce --- /dev/null +++ b/framework/csharp/object.cpp @@ -0,0 +1,13 @@ +#include "object.hpp" +#include "type.hpp" + +namespace xna { + sptr Object::GetType() + { + auto type = New(); + type->FullName = "Object"; + type->Namespace = "xna"; + type->IsClass = true; + return type; + } +} \ No newline at end of file diff --git a/framework/csharp/object.hpp b/framework/csharp/object.hpp new file mode 100644 index 0000000..a83503c --- /dev/null +++ b/framework/csharp/object.hpp @@ -0,0 +1,13 @@ +#ifndef XNA_CSHARP_OBJECT_HPP +#define XNA_CSHARP_OBJECT_HPP + +#include "../default.hpp" + +namespace xna { + class Object { + public: + virtual sptr GetType(); + }; +} + +#endif \ No newline at end of file diff --git a/framework/csharp/stream.hpp b/framework/csharp/stream.hpp index 4b3fad6..865eb73 100644 --- a/framework/csharp/stream.hpp +++ b/framework/csharp/stream.hpp @@ -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(); } - 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& 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 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& 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 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& 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 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& 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 const& buffer, Int offset, Int count, xna_error_nullarg) override; + virtual void WriteByte(Byte value, xna_error_nullarg) override; public: std::streampos _filesize{ 0 }; diff --git a/framework/csharp/type.hpp b/framework/csharp/type.hpp new file mode 100644 index 0000000..3fba755 --- /dev/null +++ b/framework/csharp/type.hpp @@ -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 + inline sptr typeof(T const& obj) { + auto obj = reinterpret_cast(&obj); + + if (!obj) + return nullptr; + + return obj->GetType(); + } +} + +#endif \ No newline at end of file diff --git a/framework/forward.hpp b/framework/forward.hpp index 4df05f8..e5d3eaf 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -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; diff --git a/framework/xna.cpp b/framework/xna.cpp index 615e12d..5cbd3f5 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -18,7 +18,8 @@ namespace xna { contentManager = New("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(*_graphicsDevice); XnaErrorCode err; - texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err); + texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err); Game::LoadContent(); } diff --git a/framework/xna.h b/framework/xna.h index e81e780..8d73ac0 100644 --- a/framework/xna.h +++ b/framework/xna.h @@ -24,5 +24,6 @@ #include "Windows.h" #include #include "content/manager.hpp" +#include "content/decstream.hpp" // TODO: Reference additional headers your program requires here. diff --git a/framework/xnaerror.hpp b/framework/xnaerror.hpp index bd0a11b..44b69d2 100644 --- a/framework/xnaerror.hpp +++ b/framework/xnaerror.hpp @@ -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) { From 956c9e6ebf0456cb7da983a20cb828b48cdd55f1 Mon Sep 17 00:00:00 2001 From: Danilo Date: Thu, 2 May 2024 10:52:08 -0300 Subject: [PATCH 02/17] Implementa ContentTypeReaderManager --- framework/CMakeLists.txt | 2 +- framework/content/reader.cpp | 3 +- framework/content/typereadermanager.cpp | 53 +++++---- framework/content/typereadermanager.hpp | 142 ++++++++++++++++++------ framework/csharp/binary.hpp | 1 + framework/csharp/object.cpp | 12 +- framework/csharp/object.hpp | 3 +- framework/csharp/type.cpp | 28 +++++ framework/csharp/type.hpp | 40 ++++++- framework/helpers.hpp | 7 ++ framework/xnaerror.hpp | 2 +- 11 files changed, 228 insertions(+), 65 deletions(-) create mode 100644 framework/csharp/type.cpp diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index c84a1a2..730b18d 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -39,7 +39,7 @@ add_executable (xna WIN32 "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") +"content/decstream.cpp" "content/lzx/decoder.cpp" "content/lzx/decoderstream.cpp" "content/typereadermanager.cpp" "csharp/object.cpp" "csharp/type.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/content/reader.cpp b/framework/content/reader.cpp index 160c74a..7f6a211 100644 --- a/framework/content/reader.cpp +++ b/framework/content/reader.cpp @@ -1,6 +1,7 @@ #include "reader.hpp" #include "manager.hpp" #include "lzx/decoderstream.hpp" +#include "typereadermanager.hpp" namespace xna { sptr ContentReader::Create(ContentManager* contentManager, Stream* input, String const& assetName) @@ -53,6 +54,6 @@ namespace xna { } Int ContentReader::ReadHeader() { - return Int(); + //typeReaders = ContentTypeReaderManager::ReadTypeManifest(this->Read7BitEncodedInt(), this); } } diff --git a/framework/content/typereadermanager.cpp b/framework/content/typereadermanager.cpp index f5148a5..636b7c5 100644 --- a/framework/content/typereadermanager.cpp +++ b/framework/content/typereadermanager.cpp @@ -34,10 +34,12 @@ namespace xna { return contentTypeReaderArray; } - sptr ContentTypeReaderManager::GetTypeReader(String const& targetType, sptr& contentReader, xna_error_ptr_arg) + sptr ContentTypeReaderManager::GetTypeReader(sptr const& targetType, sptr& contentReader, xna_error_ptr_arg) { - if (targetType.empty()) + if (!targetType) { + xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL); return nullptr; + } sptr typeReader = nullptr; @@ -57,10 +59,13 @@ namespace xna { { sptr reader = nullptr; - if (ContentTypeReaderManager::nameToReader.contains(readerTypeName) || !ContentTypeReaderManager::InstantiateTypeReader(readerTypeName, contentReader, reader)) { + if (ContentTypeReaderManager::nameToReader.contains(readerTypeName) || !ContentTypeReaderManager::InstantiateTypeReader(readerTypeName, contentReader, reader, err)) { return ContentTypeReaderManager::nameToReader[readerTypeName]; } + if (xna_error_haserros(err)) + return nullptr; + ContentTypeReaderManager::AddTypeReader(readerTypeName, contentReader, reader, err); if (xna_error_haserros(err)) return nullptr; @@ -70,15 +75,30 @@ namespace xna { return reader; } - bool ContentTypeReaderManager::InstantiateTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader) + bool ContentTypeReaderManager::InstantiateTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader, xna_error_ptr_arg) { - if (ContentTypeReaderManager::readerTypeToReader.contains(readerTypeName)) { - reader = ContentTypeReaderManager::readerTypeToReader[readerTypeName]; + sptr type = nullptr; + + std::map, sptr>::iterator it; + + for (it = readerTypeToReader.begin(); it != readerTypeToReader.end(); it++) { + if (it->first->FullName == readerTypeName) + type = it->first; + } + + if (!type) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return false; + } + + if (ContentTypeReaderManager::readerTypeToReader.contains(type)) { + reader = ContentTypeReaderManager::readerTypeToReader[type]; ContentTypeReaderManager::nameToReader.insert({ readerTypeName, reader }); return false; } - reader = ContentTypeReaderActivador::CreateInstance(readerTypeName); + reader = ContentTypeReaderActivador::CreateInstance(type, err); + return true; } void ContentTypeReaderManager::AddTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader, xna_error_ptr_arg) @@ -106,18 +126,7 @@ namespace xna { ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::targetTypeToReader, newTypeReader); ContentTypeReaderManager::RollbackAddReader(ContentTypeReaderManager::readerTypeToReader, newTypeReader); } - } - - void ContentTypeReaderManager::RollbackAddReader(std::map>& dictionary, sptr& reader) { - std::map>::iterator it; - - for (it = dictionary.begin(); it != dictionary.end(); it++) { - if (it->second == reader) { - dictionary.erase(it->first); - it = dictionary.begin(); - } - } - } + } void ContentTypeReaderManager::initMaps() { @@ -125,8 +134,10 @@ namespace xna { auto typeReader = New(); auto contentTypeReader = reinterpret_pointer_cast(typeReader); - targetTypeToReader.insert({ typeReader->TargetType(), contentTypeReader}); - readerTypeToReader.insert({ typeReader->GetType(), contentTypeReader}); + //targetTypeToReader.insert({ typeReader->TargetType(), contentTypeReader}); + //readerTypeToReader.insert({ typeReader->GetType(), contentTypeReader}); + targetTypeToReader.insert({ typeof(), contentTypeReader}); + readerTypeToReader.insert({ typeof(), contentTypeReader}); } } diff --git a/framework/content/typereadermanager.hpp b/framework/content/typereadermanager.hpp index 3e92bdc..784df69 100644 --- a/framework/content/typereadermanager.hpp +++ b/framework/content/typereadermanager.hpp @@ -1,56 +1,100 @@ #ifndef XNA_CONTENT_TYPEREADER_HPP #define XNA_CONTENT_TYPEREADER_HPP +#include "../csharp/type.hpp" #include "../default.hpp" -#include #include +#include namespace xna { - //ContentTypeReader - class ContentTypeReader { + //-------------------------------------------------------// + // ContentTypeReader // + //-------------------------------------------------------// + class ContentTypeReader : public Object { + public: + ContentTypeReader(){} + public: virtual Int TypeVersion() { return 0; } - virtual bool CanDeserializeIntoExistingObject() { return 0; } + virtual bool CanDeserializeIntoExistingObject() { return false; } virtual void Initialize(sptr& manager) {} - constexpr String TargetType() { return _targetType; } + sptr TargetType() { return _targetType; } - virtual String GetType() { return "ContentTypeReader"; } + virtual sptr GetType() const override { + auto type = New(); + type->FullName = "xna::ContentTypeReader"; + type->Namespace = "xna"; + type->IsClass = true; + return type; + } protected: - ContentTypeReader(String targetType) : _targetType(targetType) { + ContentTypeReader(sptr const& targetType) : _targetType(targetType) + { } virtual sptr Read(ContentReader input, sptr existingInstance) = 0; + public: + bool TargetIsValueType{ false }; + private: - String _targetType = "contentTypeReader"; + sptr _targetType = nullptr; }; - //ContentTypeReaderActivador + //-------------------------------------------------------// + // TypeComparator // + //-------------------------------------------------------// + struct TypeComparator + { + bool operator()(sptr t1, sptr t2) const + { + return t1->GetHashCode() < t2->GetHashCode(); + } + }; + + //-------------------------------------------------------// + // ContentTypeReaderActivador // + //-------------------------------------------------------// class ContentTypeReaderActivador { public: using Activador = sptr(*)(); - static sptr CreateInstance(String const& readerTypeName) { - if (!activators.contains(readerTypeName)) + static sptr CreateInstance(sptr const& type, xna_error_nullarg) { + if (!type) + { + xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL); + return nullptr; + } + + const auto hash = type->GetHashCode(); + + if (!activators.contains(hash)) return nullptr; - auto activador = activators[readerTypeName]; + auto activador = activators[hash]; if (!activador) return nullptr; return activador(); } - static void SetActivador(String const& readerTypeName, Activador activador) { - if (!activators.contains(readerTypeName)) - activators.insert({ readerTypeName, activador }); + static void SetActivador(sptr const& type, Activador activador, xna_error_nullarg) { + if (!type) { + xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL); + return; + } + + const auto hash = type->GetHashCode(); + + if (!activators.contains(hash)) + activators.insert({ hash, activador }); } private: - inline static std::map activators = - std::map(); + //inline static auto activators = std::map(); + inline static auto activators = std::map(); ContentTypeReaderActivador(); ContentTypeReaderActivador(ContentTypeReaderActivador&&); @@ -58,55 +102,87 @@ namespace xna { }; using PContentTypeReader = sptr; + using PType = sptr; - //ContentTypeReaderManager + //-------------------------------------------------------// + // ContentTypeReaderManager // + //-------------------------------------------------------// class ContentTypeReaderManager { public: static std::vector ReadTypeManifest(Int typeCount, sptr& contentReader, xna_error_nullarg); - static sptr GetTypeReader(String const& targetType, sptr& contentReader, xna_error_nullarg); + static sptr GetTypeReader(sptr const& targetType, sptr& contentReader, xna_error_nullarg); - inline sptr GetTypeReader(String const& targetType, xna_error_nullarg) { + inline sptr GetTypeReader(sptr const& targetType, xna_error_nullarg) { return ContentTypeReaderManager::GetTypeReader(targetType, this->contentReader, err); } - inline static bool ContainsTypeReader(String const& targetType) { + inline static bool ContainsTypeReader(sptr const& targetType) { return ContentTypeReaderManager::targetTypeToReader.contains(targetType); } private: ContentTypeReaderManager(sptr& contentReader); static sptr GetTypeReader(String const& readerTypeName, sptr& contentReader, std::vector& newTypeReaders, xna_error_nullarg); - static bool InstantiateTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader); + static bool InstantiateTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader, xna_error_nullarg); static void AddTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader, xna_error_nullarg); - static void RollbackAddReaders(std::vector>& newTypeReaders); - static void RollbackAddReader(std::map>& dictionary, sptr& reader); + static void RollbackAddReaders(std::vector>& newTypeReaders); + + static void RollbackAddReader(std::map& dictionary, sptr& reader) { + std::map>::iterator it; + + for (it = dictionary.begin(); it != dictionary.end(); it++) { + if (it->second == reader) { + dictionary.erase(it->first); + it = dictionary.begin(); + } + } + } + + static void RollbackAddReader(std::map& dictionary, sptr& reader) { + std::map>::iterator it; + + for (it = dictionary.begin(); it != dictionary.end(); it++) { + if (it->second == reader) { + dictionary.erase(it->first); + it = dictionary.begin(); + } + } + } private: sptr contentReader = nullptr; - inline static std::map nameToReader = std::map(); - inline static std::map targetTypeToReader = std::map(); - inline static std::map readerTypeToReader = std::map(); + inline static auto nameToReader = std::map(); + //inline static auto targetTypeToReader = std::map(); + //inline static auto readerTypeToReader = std::map(); + inline static auto targetTypeToReader = std::map(); + inline static auto readerTypeToReader = std::map(); static void initMaps(); }; - //ObjectReader + //-------------------------------------------------------// + // ObjectReader // + //-------------------------------------------------------// class ObjectReader : public ContentTypeReader { public: - ObjectReader() : ContentTypeReader("object"){ - ContentTypeReaderActivador::SetActivador("object", []() -> sptr { + ObjectReader() : ContentTypeReader(typeof(this)){ + ContentTypeReaderActivador::SetActivador(typeof(this), []() -> sptr { auto obj = New (); return reinterpret_pointer_cast(obj); }); } // Inherited via ContentTypeReader - sptr Read(ContentReader input, sptr existingInstance) override; + sptr Read(ContentReader input, sptr existingInstance) override; - String GetType() override { - return "ObjectReader"; + sptr GetType() const override{ + auto type = New(); + type->FullName = "xna::ObjectReader"; + type->Namespace = "xna"; + type->IsClass = true; + return type; } }; } diff --git a/framework/csharp/binary.hpp b/framework/csharp/binary.hpp index b06249c..9721817 100644 --- a/framework/csharp/binary.hpp +++ b/framework/csharp/binary.hpp @@ -43,6 +43,7 @@ namespace xna { bool m2BytesPerChar{ false }; + protected: Int InternalReadOneChar(xna_error_nullarg); void FillBuffer(Int numBytes, xna_error_nullarg); diff --git a/framework/csharp/object.cpp b/framework/csharp/object.cpp index 067c9ce..374dd51 100644 --- a/framework/csharp/object.cpp +++ b/framework/csharp/object.cpp @@ -2,12 +2,20 @@ #include "type.hpp" namespace xna { - sptr Object::GetType() + sptr Object::GetType() const { auto type = New(); - type->FullName = "Object"; + type->FullName = "xna::Object"; type->Namespace = "xna"; type->IsClass = true; return type; } + + size_t Object::GetHashCode() const + { + size_t seed = 0; + XnaHHashCombine(seed, this); + + return seed; + } } \ No newline at end of file diff --git a/framework/csharp/object.hpp b/framework/csharp/object.hpp index a83503c..9d30039 100644 --- a/framework/csharp/object.hpp +++ b/framework/csharp/object.hpp @@ -6,7 +6,8 @@ namespace xna { class Object { public: - virtual sptr GetType(); + virtual sptr GetType() const; + virtual size_t GetHashCode() const; }; } diff --git a/framework/csharp/type.cpp b/framework/csharp/type.cpp new file mode 100644 index 0000000..1f01559 --- /dev/null +++ b/framework/csharp/type.cpp @@ -0,0 +1,28 @@ +#include "type.hpp" + +namespace xna { + sptr Type::GetType() const + { + auto type = New(); + type->FullName = "xna::Type"; + type->Namespace = "xna"; + type->IsClass = true; + return type; + } + + size_t Type::GetHashCode() const + { + size_t seed = 0; + XnaHHashCombine(seed, Namespace); + XnaHHashCombine(seed, FullName); + XnaHHashCombine(seed, IsInterface); + XnaHHashCombine(seed, IsArray); + XnaHHashCombine(seed, IsPointer); + XnaHHashCombine(seed, IsClass); + XnaHHashCombine(seed, IsCOMObject); + XnaHHashCombine(seed, IsEnum); + XnaHHashCombine(seed, IsValueType); + + return seed; + } +} \ No newline at end of file diff --git a/framework/csharp/type.hpp b/framework/csharp/type.hpp index 3fba755..c75043e 100644 --- a/framework/csharp/type.hpp +++ b/framework/csharp/type.hpp @@ -5,7 +5,7 @@ #include "object.hpp" namespace xna { - class Type { + class Type : public Object { public: String Namespace; String FullName; @@ -16,13 +16,43 @@ namespace xna { bool IsCOMObject{ false }; bool IsEnum{ false }; bool IsValueType{ false }; - }; + + constexpr bool operator==(const Type& other) const + { + return Namespace == other.Namespace + && FullName == other.FullName + && IsInterface == other.IsInterface + && IsArray == other.IsArray + && IsPointer == other.IsPointer + && IsClass == other.IsClass + && IsCOMObject == other.IsCOMObject + && IsEnum == other.IsEnum + && IsValueType == other.IsValueType; + } + + virtual sptr GetType() const override; + virtual size_t GetHashCode() const; + + bool operator()(Type const& t1, Type const& t2) const { + return t1.GetHashCode() < t2.GetHashCode(); + } + }; template - inline sptr typeof(T const& obj) { - auto obj = reinterpret_cast(&obj); + inline sptr typeof() { + auto t = New(); + auto obj = reinterpret_pointer_cast(t); - if (!obj) + if (!obj) return nullptr; + + return obj->GetType(); + } + + template + inline sptr typeof(T const* object) { + auto obj = reinterpret_cast(object); + + if (!obj) return nullptr; return obj->GetType(); diff --git a/framework/helpers.hpp b/framework/helpers.hpp index aba54eb..afc396c 100644 --- a/framework/helpers.hpp +++ b/framework/helpers.hpp @@ -2,6 +2,7 @@ #define XNA_HELPERS_HPP #include +#include namespace xna { inline std::wstring XnaHToWString(const std::string& str) @@ -21,6 +22,12 @@ namespace xna { wcstombs_s(&size, &str[0], str.size() + 1, wstr.c_str(), wstr.size()); return str; } + + template + static constexpr void XnaHHashCombine(std::size_t& seed, const T& v) { + std::hash hasher; + seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } } #endif \ No newline at end of file diff --git a/framework/xnaerror.hpp b/framework/xnaerror.hpp index 44b69d2..a89e32c 100644 --- a/framework/xnaerror.hpp +++ b/framework/xnaerror.hpp @@ -23,7 +23,7 @@ namespace xna { } inline bool xna_error_haserros(XnaErrorCode* source) { - return source != nullptr; + return source != nullptr && *source != XnaErrorCode::NONE; } #define xna_error_nullarg XnaErrorCode* err = nullptr From acef4d97871591b3d30833fe855aa28572ee3b8b Mon Sep 17 00:00:00 2001 From: Danilo Date: Fri, 3 May 2024 11:49:01 -0300 Subject: [PATCH 03/17] =?UTF-8?q?Implementa=C3=A7=C3=B5es=20em=20ContentRe?= =?UTF-8?q?ader=20e=20Manager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/content/manager.hpp | 5 +- framework/content/reader.cpp | 97 ++++++++++++++++++++++++- framework/content/reader.hpp | 96 ++++++++++++++++++++++-- framework/content/typereadermanager.cpp | 12 +-- framework/content/typereadermanager.hpp | 52 ++++++------- framework/csharp/object.cpp | 9 --- framework/csharp/object.hpp | 1 - framework/csharp/type.cpp | 23 ++---- framework/csharp/type.hpp | 92 ++++++++++++++--------- 9 files changed, 275 insertions(+), 112 deletions(-) diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index 7dfe009..05db4f7 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -49,10 +49,13 @@ namespace xna { return obj2; } - public: + protected: template sptr ReadAsset(String const& assetName) { auto input = OpenStream(assetName); + auto contentReader = ContentReader::Create(this, input, assetName); + + return contentReader->ReadAsset(); } sptr OpenStream(String const& assetName) { diff --git a/framework/content/reader.cpp b/framework/content/reader.cpp index 7f6a211..e108343 100644 --- a/framework/content/reader.cpp +++ b/framework/content/reader.cpp @@ -4,12 +4,91 @@ #include "typereadermanager.hpp" namespace xna { - sptr ContentReader::Create(ContentManager* contentManager, Stream* input, String const& assetName) + sptr ContentReader::Create(ContentManager* contentManager, sptr& input, String const& assetName) { - return sptr(); + Int graphicsProfile = 0; + input = ContentReader::PrepareStream(input, assetName, graphicsProfile); + return std::shared_ptr(new ContentReader(contentManager, input, assetName, graphicsProfile)); } - sptr ContentReader::PrepareStream(sptr& input, String const* assetName, Int& graphicsProfile) + Vector2 ContentReader::ReadVector2() + { + Vector2 vector2; + vector2.X = ReadSingle(); + vector2.Y = ReadSingle(); + return vector2; + } + + Vector3 ContentReader::ReadVector3() + { + Vector3 vector3; + vector3.X = ReadSingle(); + vector3.Y = ReadSingle(); + vector3.Z = ReadSingle(); + return vector3; + } + + Vector4 ContentReader::ReadVector4() + { + Vector4 vector4; + vector4.X = ReadSingle(); + vector4.Y = ReadSingle(); + vector4.Z = ReadSingle(); + vector4.W = ReadSingle(); + return vector4; + } + + Matrix ContentReader::ReadMatrix() + { + Matrix matrix; + matrix.M11 = ReadSingle(); + matrix.M12 = ReadSingle(); + matrix.M13 = ReadSingle(); + matrix.M14 = ReadSingle(); + matrix.M21 = ReadSingle(); + matrix.M22 = ReadSingle(); + matrix.M23 = ReadSingle(); + matrix.M24 = ReadSingle(); + matrix.M31 = ReadSingle(); + matrix.M32 = ReadSingle(); + matrix.M33 = ReadSingle(); + matrix.M34 = ReadSingle(); + matrix.M41 = ReadSingle(); + matrix.M42 = ReadSingle(); + matrix.M43 = ReadSingle(); + matrix.M44 = ReadSingle(); + return matrix; + } + + Quaternion ContentReader::ReadQuaternion() + { + Quaternion quaternion; + quaternion.X = ReadSingle(); + quaternion.Y = ReadSingle(); + quaternion.Z = ReadSingle(); + quaternion.W = ReadSingle(); + return quaternion; + } + + Color ContentReader::ReadColor() + { + const auto packedValue = ReadUInt32(); + return Color(packedValue); + } + + float ContentReader::ReadSingle() + { + const auto int32 = ReadUInt32(); + return *(float*)&int32; + } + + double ContentReader::ReadDouble() + { + const auto int64 = ReadUInt64(); + return *(double*)&int64; + } + + sptr ContentReader::PrepareStream(sptr& input, String const& assetName, Int& graphicsProfile) { BinaryReader binaryReader = BinaryReader(input); @@ -54,6 +133,16 @@ namespace xna { } Int ContentReader::ReadHeader() { - //typeReaders = ContentTypeReaderManager::ReadTypeManifest(this->Read7BitEncodedInt(), this); + auto _this = shared_from_this(); + typeReaders = ContentTypeReaderManager::ReadTypeManifest(this->Read7BitEncodedInt(), _this); + auto length = this->Read7BitEncodedInt(); + + if (length > 0) + { + //TODO: length > 0 + } + + return length; + } } diff --git a/framework/content/reader.hpp b/framework/content/reader.hpp index e7382c4..0f8fc77 100644 --- a/framework/content/reader.hpp +++ b/framework/content/reader.hpp @@ -3,29 +3,111 @@ #include "../default.hpp" #include "../csharp/binary.hpp" +#include "../csharp/type.hpp" +#include "typereadermanager.hpp" +#include +#include "../common/vectors.hpp" +#include "../common/matrix.hpp" +#include "../common/quaternion.hpp" +#include "../common/color.hpp" namespace xna { - class ContentReader : public BinaryReader{ + class ContentReader : public BinaryReader, public std::enable_shared_from_this{ public: - static sptr Create(ContentManager* contentManager, Stream* input, String const& assetName); + static sptr Create(ContentManager* contentManager, sptr& input, String const& assetName); template - sptr ReadAsset() { - return nullptr; - } + sptr ReadAsset(); + + template + T ReadObject(); + + template + T ReadObject(T existingInstance); + + Vector2 ReadVector2(); + Vector3 ReadVector3(); + Vector4 ReadVector4(); + Matrix ReadMatrix(); + Quaternion ReadQuaternion(); + Color ReadColor(); + float ReadSingle(); + double ReadDouble(); private: - ContentReader(ContentManager* contentManager, sptrconst& input, String const& assetName) + ContentReader(ContentManager* contentManager, sptr& input, String const& assetName, Int graphicsProfile) : BinaryReader(input), _contentManager(contentManager), _assetName(assetName){} - static sptr PrepareStream(sptr& input, String const* assetName, Int& graphicsProfile); + static sptr PrepareStream(sptr& input, String const& assetName, Int& graphicsProfile); Int ReadHeader(); + template + T ReadObjectInternal(std::any& existingInstance, xna_error_nullarg); + + template + T InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg); + private: ContentManager* _contentManager = nullptr; String _assetName; + std::vector> typeReaders; + Int graphicsProfile{ 0 }; }; + + template + inline T ContentReader::ReadObjectInternal(std::any& existingInstance, xna_error_ptr_arg) + { + const auto num = Read7BitEncodedInt(); + + if (num == 0) { + return T(); + } + + const auto index = num - 1; + + if (index >= typeReaders.size()) { + xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE); + return T(); + } + + return InvokeReader(typeReaders[index], existingInstance); + } + + template + inline T ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_ptr_arg) + { + auto contentTypeReader = reinterpret_cast*>(&reader); + T objB = T(); + + if (contentTypeReader) { + T existingInstance1 = existingInstance.has_value() ? std::any_cast(existingInstance) : T(); + objB = contentTypeReader->Read(*this, existingInstance1); + } + + return T(); + } + + template + inline sptr ContentReader::ReadAsset() + { + const auto sharedResourceCount = ReadHeader(); + T obj = ReadObject(); + //this.ReadSharedResources(sharedResourceCount); + return obj; + } + + template + inline T ContentReader::ReadObject() + { + return ReadObjectInternal(nullptr); + } + + template + inline T ContentReader::ReadObject(T existingInstance) + { + return ReadObjectInternal(std::any(existingInstance)); + } } #endif \ No newline at end of file diff --git a/framework/content/typereadermanager.cpp b/framework/content/typereadermanager.cpp index 636b7c5..43c3f5b 100644 --- a/framework/content/typereadermanager.cpp +++ b/framework/content/typereadermanager.cpp @@ -82,7 +82,7 @@ namespace xna { std::map, sptr>::iterator it; for (it = readerTypeToReader.begin(); it != readerTypeToReader.end(); it++) { - if (it->first->FullName == readerTypeName) + if (it->first->FullName() == readerTypeName) type = it->first; } @@ -111,7 +111,8 @@ namespace xna { } ContentTypeReaderManager::targetTypeToReader.insert({ targetType, reader }); - ContentTypeReaderManager::readerTypeToReader.insert({ reader->GetType(), reader }); + //ContentTypeReaderManager::readerTypeToReader.insert({ reader->GetType(), reader }); + ContentTypeReaderManager::readerTypeToReader.insert({ typeof(*reader), reader}); ContentTypeReaderManager::nameToReader.insert({ readerTypeName, reader }); } @@ -139,10 +140,5 @@ namespace xna { targetTypeToReader.insert({ typeof(), contentTypeReader}); readerTypeToReader.insert({ typeof(), contentTypeReader}); } - } - - sptr ObjectReader::Read(ContentReader input, sptr existingInstance) - { - return nullptr; - } + } } \ No newline at end of file diff --git a/framework/content/typereadermanager.hpp b/framework/content/typereadermanager.hpp index 784df69..79a812f 100644 --- a/framework/content/typereadermanager.hpp +++ b/framework/content/typereadermanager.hpp @@ -5,42 +5,43 @@ #include "../default.hpp" #include #include +#include namespace xna { //-------------------------------------------------------// // ContentTypeReader // //-------------------------------------------------------// - class ContentTypeReader : public Object { - public: - ContentTypeReader(){} - + class ContentTypeReader { public: virtual Int TypeVersion() { return 0; } virtual bool CanDeserializeIntoExistingObject() { return false; } virtual void Initialize(sptr& manager) {} - sptr TargetType() { return _targetType; } - - virtual sptr GetType() const override { - auto type = New(); - type->FullName = "xna::ContentTypeReader"; - type->Namespace = "xna"; - type->IsClass = true; - return type; - } + sptr TargetType() { return _targetType; } + virtual std::any Read(ContentReader& input, std::any& existingInstance) = 0; protected: ContentTypeReader(sptr const& targetType) : _targetType(targetType) - { - } - - virtual sptr Read(ContentReader input, sptr existingInstance) = 0; + {} public: bool TargetIsValueType{ false }; private: sptr _targetType = nullptr; + }; + + template + class ContentTypeReaderT : public ContentTypeReader { + protected: + ContentTypeReaderT(sptr const& targetType) : ContentTypeReader(targetType){} + + public: + virtual std::any Read(ContentReader& input, std::any& existingInstance) override{ + return std::any(); + } + + virtual T Read(ContentReader& input, T existingInstance) = 0; }; //-------------------------------------------------------// @@ -165,24 +166,17 @@ namespace xna { //-------------------------------------------------------// // ObjectReader // //-------------------------------------------------------// - class ObjectReader : public ContentTypeReader { + class ObjectReader : public ContentTypeReaderT { public: - ObjectReader() : ContentTypeReader(typeof(this)){ + ObjectReader() : ContentTypeReaderT(typeof()) { ContentTypeReaderActivador::SetActivador(typeof(this), []() -> sptr { auto obj = New (); return reinterpret_pointer_cast(obj); }); - } + } - // Inherited via ContentTypeReader - sptr Read(ContentReader input, sptr existingInstance) override; - - sptr GetType() const override{ - auto type = New(); - type->FullName = "xna::ObjectReader"; - type->Namespace = "xna"; - type->IsClass = true; - return type; + virtual Object Read(ContentReader& input, Object existingInstance) override { + return Object(); } }; } diff --git a/framework/csharp/object.cpp b/framework/csharp/object.cpp index 374dd51..6b61c37 100644 --- a/framework/csharp/object.cpp +++ b/framework/csharp/object.cpp @@ -2,15 +2,6 @@ #include "type.hpp" namespace xna { - sptr Object::GetType() const - { - auto type = New(); - type->FullName = "xna::Object"; - type->Namespace = "xna"; - type->IsClass = true; - return type; - } - size_t Object::GetHashCode() const { size_t seed = 0; diff --git a/framework/csharp/object.hpp b/framework/csharp/object.hpp index 9d30039..6fedc8c 100644 --- a/framework/csharp/object.hpp +++ b/framework/csharp/object.hpp @@ -6,7 +6,6 @@ namespace xna { class Object { public: - virtual sptr GetType() const; virtual size_t GetHashCode() const; }; } diff --git a/framework/csharp/type.cpp b/framework/csharp/type.cpp index 1f01559..b4ceeec 100644 --- a/framework/csharp/type.cpp +++ b/framework/csharp/type.cpp @@ -1,27 +1,14 @@ #include "type.hpp" namespace xna { - sptr Type::GetType() const - { - auto type = New(); - type->FullName = "xna::Type"; - type->Namespace = "xna"; - type->IsClass = true; - return type; - } - size_t Type::GetHashCode() const { size_t seed = 0; - XnaHHashCombine(seed, Namespace); - XnaHHashCombine(seed, FullName); - XnaHHashCombine(seed, IsInterface); - XnaHHashCombine(seed, IsArray); - XnaHHashCombine(seed, IsPointer); - XnaHHashCombine(seed, IsClass); - XnaHHashCombine(seed, IsCOMObject); - XnaHHashCombine(seed, IsEnum); - XnaHHashCombine(seed, IsValueType); + XnaHHashCombine(seed, fullName); + XnaHHashCombine(seed, isClass); + XnaHHashCombine(seed, isEnum); + XnaHHashCombine(seed, isValueType); + XnaHHashCombine(seed, isPrimitive); return seed; } diff --git a/framework/csharp/type.hpp b/framework/csharp/type.hpp index c75043e..335296a 100644 --- a/framework/csharp/type.hpp +++ b/framework/csharp/type.hpp @@ -3,59 +3,81 @@ #include "../default.hpp" #include "object.hpp" +#include +#include namespace xna { class Type : public Object { 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 }; + constexpr String FullName() const { return fullName; } + constexpr bool IsClass() const { return isClass; } + constexpr bool IsEnum() const { return isEnum; } + constexpr bool IsValueType() const { return isValueType; } + constexpr bool IsPrimitive() const { return isPrimitive; } - constexpr bool operator==(const Type& other) const - { - return Namespace == other.Namespace - && FullName == other.FullName - && IsInterface == other.IsInterface - && IsArray == other.IsArray - && IsPointer == other.IsPointer - && IsClass == other.IsClass - && IsCOMObject == other.IsCOMObject - && IsEnum == other.IsEnum - && IsValueType == other.IsValueType; - } - - virtual sptr GetType() const override; virtual size_t GetHashCode() const; + constexpr bool operator==(const Type& other) const { + return + fullName == other.fullName + && isClass == other.isClass + && isEnum == other.isEnum + && isValueType == other.isValueType + && isPrimitive == other.isPrimitive; + } + bool operator()(Type const& t1, Type const& t2) const { return t1.GetHashCode() < t2.GetHashCode(); } - }; + + template + friend sptr typeof(); + + private: + String fullName; + bool isClass{ false }; + bool isEnum{ false }; + bool isValueType{ false }; + bool isPrimitive{ false }; + }; template inline sptr typeof() { - auto t = New(); - auto obj = reinterpret_pointer_cast(t); + if (std::is_arithmetic::value) { + auto primitiveType = New(); + primitiveType->fullName = typeid(T).name(); + primitiveType->isPrimitive = true; + primitiveType->isValueType = true; + return primitiveType; + } - if (!obj) return nullptr; - - return obj->GetType(); - } + if (std::is_enum::value) { + auto enumType = New(); + enumType->fullName = typeid(T).name(); + enumType->isValueType = true; + enumType->isEnum = true; + return enumType; + } + + if (std::is_class::value) { + auto classType = New(); + classType->fullName = typeid(T).name(); + classType->isClass = true; + + return classType; + } + + return nullptr; + } template inline sptr typeof(T const* object) { - auto obj = reinterpret_cast(object); + return typeof(); + } - if (!obj) - return nullptr; - - return obj->GetType(); + template + inline sptr typeof(T const& object) { + return typeof(); } } From 7ebfa86809201eb4867f43cfc695f91ad8cd966f Mon Sep 17 00:00:00 2001 From: Danilo Date: Sat, 4 May 2024 21:07:39 -0300 Subject: [PATCH 04/17] Implementa SetData de Texture2D --- framework/common/color.hpp | 4 + framework/csharp/buffer.hpp | 7 +- framework/graphics/rendertarget.hpp | 6 +- framework/graphics/texture.hpp | 6 +- framework/platform/device-dx.cpp | 7 +- framework/platform/game-dx.cpp | 32 ++++-- framework/platform/rendertarget-dx.cpp | 33 +++--- framework/platform/rendertarget-dx.hpp | 6 +- framework/platform/spritebatch-dx.cpp | 28 ++--- framework/platform/texture-dx.cpp | 57 ++++++++-- framework/platform/texture-dx.hpp | 137 ++++++++++++++++++++++--- framework/xna.cpp | 15 ++- framework/xnaerror.hpp | 3 +- 13 files changed, 259 insertions(+), 82 deletions(-) diff --git a/framework/common/color.hpp b/framework/common/color.hpp index a366598..40f52d1 100644 --- a/framework/common/color.hpp +++ b/framework/common/color.hpp @@ -189,6 +189,10 @@ namespace xna { return Color::Multiply(value, scale); } + constexpr operator Uint() const { + return _packedValue; + } + private: Uint _packedValue{ 0 }; diff --git a/framework/csharp/buffer.hpp b/framework/csharp/buffer.hpp index e2a8e75..9810c1f 100644 --- a/framework/csharp/buffer.hpp +++ b/framework/csharp/buffer.hpp @@ -10,7 +10,12 @@ namespace xna { template 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); - } + } + + template + static void BlockCopy(TSOURCE const* src, rsize_t srcOffset, TDEST* dst, rsize_t dstOffset, rsize_t byteCount) { + memmove_s(dst + dstOffset, byteCount, src + srcOffset, byteCount); + } private: constexpr Buffer() = default; diff --git a/framework/graphics/rendertarget.hpp b/framework/graphics/rendertarget.hpp index 1e8ca1c..90361db 100644 --- a/framework/graphics/rendertarget.hpp +++ b/framework/graphics/rendertarget.hpp @@ -1,7 +1,7 @@ #ifndef XNA_GRAPHICS_RENDERTARGET_HPP #define XNA_GRAPHICS_RENDERTARGET_HPP -#include "texture.hpp" +#include "../default.hpp" namespace xna { @@ -9,8 +9,8 @@ namespace xna { public: virtual ~IRenderTarget2D(){} - virtual bool Initialize(GraphicsDevice& device) = 0; - virtual bool Apply(GraphicsDevice& device) = 0; + virtual bool Initialize(xna_error_nullarg) = 0; + virtual bool Apply(xna_error_nullarg) = 0; }; } diff --git a/framework/graphics/texture.hpp b/framework/graphics/texture.hpp index bbf9bba..ec7dbf4 100644 --- a/framework/graphics/texture.hpp +++ b/framework/graphics/texture.hpp @@ -1,9 +1,7 @@ #ifndef XNA_GRAPHICS_TEXTURE_HPP #define XNA_GRAPHICS_TEXTURE_HPP -#include "../forward.hpp" -#include "../types.hpp" -#include "../enums.hpp" +#include "../default.hpp" namespace xna { class Texture { @@ -14,6 +12,8 @@ namespace xna { virtual ~ITexture2D(){} virtual Int Width() const = 0; virtual Int Height() const = 0; + virtual Rectangle Bounds() const = 0; + virtual bool Initialize(xna_error_nullarg) = 0; }; } diff --git a/framework/platform/device-dx.cpp b/framework/platform/device-dx.cpp index 86bd563..8e491dd 100644 --- a/framework/platform/device-dx.cpp +++ b/framework/platform/device-dx.cpp @@ -47,10 +47,11 @@ namespace xna { hr = _factory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER); if (FAILED(hr)) return false; - _renderTarget2D = New(); - if (!_renderTarget2D->Initialize(*this)) return false; + _renderTarget2D = New(this); + if (!_renderTarget2D->Initialize()) + return false; - _renderTarget2D->Apply(*this); + _renderTarget2D->Apply(); D3D11_VIEWPORT view{}; view.TopLeftX = _viewport.X; diff --git a/framework/platform/game-dx.cpp b/framework/platform/game-dx.cpp index 3121df2..d342ca3 100644 --- a/framework/platform/game-dx.cpp +++ b/framework/platform/game-dx.cpp @@ -42,19 +42,33 @@ namespace xna { Keyboard::Initialize(); Mouse::Initialize(); - //initialize é requisito para GamePad + ////initialize é requisito para GamePad + //Microsoft::WRL::Wrappers::RoInitializeWrapper initialize(RO_INIT_MULTITHREADED); + + //if (FAILED(initialize)) + // MessageBox(nullptr, "Ocorreu um erro ao executar Microsoft::WRL::Wrappers::RoInitializeWrapper. O GamePad não foi inicializado corretamente.", "XN65", MB_OK); + + //GamePad.Initialize(); + + ////CoInitializeEx é requisito para biblioteca DirectXTK + //const auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); + + //if (FAILED(hr)) + // MessageBox(nullptr, "Ocorreu um erro ao executar CoInitializeEx. O AudioEngine não foi inicializado corretamente.", "XN65", MB_OK); + +#if (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/) Microsoft::WRL::Wrappers::RoInitializeWrapper initialize(RO_INIT_MULTITHREADED); - if (FAILED(initialize)) - MessageBox(nullptr, "Ocorreu um erro ao executar Microsoft::WRL::Wrappers::RoInitializeWrapper. O GamePad não foi inicializado corretamente.", "XN65", MB_OK); - - GamePad.Initialize(); - - //CoInitializeEx é requisito para AudioEngine - const auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); + { + } +#else + HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); if (FAILED(hr)) - MessageBox(nullptr, "Ocorreu um erro ao executar CoInitializeEx. O AudioEngine não foi inicializado corretamente.", "XN65", MB_OK); + { + + } +#endif _audioEngine = New(); diff --git a/framework/platform/rendertarget-dx.cpp b/framework/platform/rendertarget-dx.cpp index 564a58d..32820ac 100644 --- a/framework/platform/rendertarget-dx.cpp +++ b/framework/platform/rendertarget-dx.cpp @@ -4,30 +4,39 @@ #include "device-dx.hpp" namespace xna { - bool RenderTarget2D::Initialize(GraphicsDevice& device) { - if (!device._device) + bool RenderTarget2D::Initialize(xna_error_ptr_arg) { + if (!m_device || !m_device->_device) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); return false; - - if (_texture2D) { - _texture2D->Release(); - _texture2D = nullptr; } - if (!device._swapChain->GetBackBuffer(_texture2D)) + if (dxTexture2D) { + dxTexture2D->Release(); + dxTexture2D = nullptr; + } + + if (!m_device->_swapChain->GetBackBuffer(dxTexture2D)) return false; - auto& dxdevice = device._device; + auto& dxdevice = m_device->_device; - const auto hr = dxdevice->CreateRenderTargetView(_texture2D, NULL, &_renderTargetView); + const auto hr = dxdevice->CreateRenderTargetView(dxTexture2D, NULL, &_renderTargetView); - if (FAILED(hr)) + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); return false; + } return true; } - bool RenderTarget2D::Apply(GraphicsDevice& device) { - auto& context = device._context; + bool RenderTarget2D::Apply(xna_error_ptr_arg) { + if (!m_device || !m_device->_context) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return false; + } + + auto& context = m_device->_context; context->OMSetRenderTargets(1, &_renderTargetView, nullptr); return true; } diff --git a/framework/platform/rendertarget-dx.hpp b/framework/platform/rendertarget-dx.hpp index 81493c3..d7430c0 100644 --- a/framework/platform/rendertarget-dx.hpp +++ b/framework/platform/rendertarget-dx.hpp @@ -9,6 +9,8 @@ namespace xna { class RenderTarget2D : public IRenderTarget2D, public Texture2D { public: + RenderTarget2D(GraphicsDevice* device) : Texture2D(device){} + virtual ~RenderTarget2D() override { if (_renderTargetView) { _renderTargetView->Release(); @@ -16,8 +18,8 @@ namespace xna { } } - virtual bool Initialize(GraphicsDevice& device) override; - virtual bool Apply(GraphicsDevice& device) override; + virtual bool Initialize(xna_error_nullarg) override; + virtual bool Apply(xna_error_nullarg) override; public: ID3D11RenderTargetView* _renderTargetView = nullptr; diff --git a/framework/platform/spritebatch-dx.cpp b/framework/platform/spritebatch-dx.cpp index f4d0fbb..e01457c 100644 --- a/framework/platform/spritebatch-dx.cpp +++ b/framework/platform/spritebatch-dx.cpp @@ -63,7 +63,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture._textureView) + if (!texture.dxShaderResourceView) return; const auto _position = XMFLOAT2(position.X, position.Y); @@ -71,7 +71,7 @@ namespace xna { XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W }; _dxspriteBatch->Draw( - texture._textureView, + texture.dxShaderResourceView, _position, _color ); @@ -81,7 +81,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture._textureView) + if (!texture.dxShaderResourceView) return; const auto _position = XMFLOAT2(position.X, position.Y); @@ -98,7 +98,7 @@ namespace xna { }; _dxspriteBatch->Draw( - texture._textureView, + texture.dxShaderResourceView, _position, sourceRectangle ? &_sourceRect : nullptr, _color); @@ -108,7 +108,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture._textureView) + if (!texture.dxShaderResourceView) return; const auto _position = XMFLOAT2(position.X, position.Y); @@ -128,7 +128,7 @@ namespace xna { const DxSpriteEffects _effects = static_cast(effects); _dxspriteBatch->Draw( - texture._textureView, + texture.dxShaderResourceView, _position, sourceRectangle ? &_sourceRect : nullptr, _color, @@ -143,7 +143,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture._textureView) + if (!texture.dxShaderResourceView) return; const auto _position = XMFLOAT2(position.X, position.Y); @@ -164,7 +164,7 @@ namespace xna { const XMFLOAT2 _scale = { scale.X, scale.Y }; _dxspriteBatch->Draw( - texture._textureView, + texture.dxShaderResourceView, _position, sourceRectangle ? &_sourceRect : nullptr, _color, @@ -179,7 +179,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture._textureView) + if (!texture.dxShaderResourceView) return; RECT _destinationRect{}; @@ -191,14 +191,14 @@ namespace xna { const auto v4 = color.ToVector4(); const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W }; - _dxspriteBatch->Draw(texture._textureView, _destinationRect, _color); + _dxspriteBatch->Draw(texture.dxShaderResourceView, _destinationRect, _color); } void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color) { if (!_dxspriteBatch) return; - if (!texture._textureView) + if (!texture.dxShaderResourceView) return; RECT _destinationRect{}; @@ -219,14 +219,14 @@ namespace xna { _sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height; }; - _dxspriteBatch->Draw(texture._textureView, _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color); + _dxspriteBatch->Draw(texture.dxShaderResourceView, _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color); } void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color, float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) { if (!_dxspriteBatch) return; - if (!texture._textureView) + if (!texture.dxShaderResourceView) return; RECT _destinationRect{}; @@ -251,7 +251,7 @@ namespace xna { const auto _effects = static_cast(effects); _dxspriteBatch->Draw( - texture._textureView, + texture.dxShaderResourceView, _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color, diff --git a/framework/platform/texture-dx.cpp b/framework/platform/texture-dx.cpp index 63757e1..8e2a5e0 100644 --- a/framework/platform/texture-dx.cpp +++ b/framework/platform/texture-dx.cpp @@ -3,13 +3,10 @@ #include "device-dx.hpp" #include "../helpers.hpp" -namespace xna { - Texture2D::Texture2D() { - } - +namespace xna { sptr Texture2D::FromStream(GraphicsDevice& device, String const& fileName, xna_error_ptr_arg) { - auto texture2d = New(); + auto texture2d = New(&device); ID3D11Resource* resource = nullptr; auto wstr = XnaHToWString(fileName); @@ -18,7 +15,7 @@ namespace xna { device._context, wstr.c_str(), &resource, - &texture2d->_textureView, + &texture2d->dxShaderResourceView, 0U); if (FAILED(result)) @@ -33,7 +30,7 @@ namespace xna { return nullptr; } - result = resource->QueryInterface(IID_ID3D11Texture2D, (void**)&texture2d->_texture2D); + result = resource->QueryInterface(IID_ID3D11Texture2D, (void**)&texture2d->dxTexture2D); if (FAILED(result)) { xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); @@ -47,12 +44,54 @@ namespace xna { } D3D11_TEXTURE2D_DESC desc; - texture2d->_texture2D->GetDesc(&desc); - texture2d->_description = desc; + texture2d->dxTexture2D->GetDesc(&desc); + texture2d->dxDescription = desc; resource->Release(); resource = nullptr; return texture2d; } + + bool Texture2D::Initialize(xna_error_ptr_arg) + { + if (dxTexture2D) { + xna_error_apply(err, XnaErrorCode::WARNING_INITIALIZED_RESOURCE); + return false; + } + + if (!m_device || !m_device->_device) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return false; + } + + auto hr = m_device->_device->CreateTexture2D(&dxDescription, nullptr, &dxTexture2D); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return false; + } + + ID3D11Resource* resource = nullptr; + hr = dxTexture2D->QueryInterface(IID_ID3D11Resource, (void**)&resource); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return false; + } + + hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDecription, &dxShaderResourceView); + + if (resource) { + resource->Release(); + resource = nullptr; + } + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return false; + } + + return true; + } } \ No newline at end of file diff --git a/framework/platform/texture-dx.hpp b/framework/platform/texture-dx.hpp index dbd5b16..1cbe9e0 100644 --- a/framework/platform/texture-dx.hpp +++ b/framework/platform/texture-dx.hpp @@ -1,44 +1,147 @@ #ifndef XNA_PLATFORM_TEXTURE_DX_HPP #define XNA_PLATFORM_TEXTURE_DX_HPP +#include "../common/rectangle.hpp" +#include "../csharp/buffer.hpp" #include "../graphics/texture.hpp" -#include "dxgi.h" -#include "d3d11.h" #include "../xnaerror.hpp" +#include "dxheaders.hpp" +#include +#include "../graphics/gresource.hpp" +#include "device-dx.hpp" +#include namespace xna { - class Texture2D : public ITexture2D { + class Texture2D : public ITexture2D, public GraphicsResource { public: - Texture2D(); + Texture2D(GraphicsDevice* device, size_t width, size_t height) : GraphicsResource(device) { + dxDescription.Width = static_cast(width); + dxDescription.Height = static_cast(height); + setDefaultDesc(); + } + + Texture2D(GraphicsDevice* device) : GraphicsResource(device) { + setDefaultDesc(); + } virtual ~Texture2D() override { - if (_texture2D) { - _texture2D->Release(); - _texture2D = nullptr; + if (dxTexture2D) { + dxTexture2D->Release(); + dxTexture2D = nullptr; } - if (_textureView) { - _textureView->Release(); - _textureView = nullptr; + if (dxShaderResourceView) { + dxShaderResourceView->Release(); + dxShaderResourceView = nullptr; } } virtual constexpr Int Width() const override { - return _description.Width; + return dxDescription.Width; } virtual constexpr Int Height() const override { - return _description.Height; + return dxDescription.Height; } - static sptr FromStream(GraphicsDevice& device, String const& fileName, xna_error_nullarg); + constexpr Rectangle Bounds() const override { + return { 0, 0, static_cast(dxDescription.Width), static_cast(dxDescription.Height) }; + } + + bool Initialize(xna_error_nullarg) override; + + template + void SetData(std::vector const& data, xna_error_ptr_arg); + + template + void SetData(std::vector const& data, size_t startIndex, size_t elementCount, xna_error_nullarg); + + static sptr FromStream(GraphicsDevice& device, String const& fileName, xna_error_nullarg); public: - ID3D11Texture2D* _texture2D{nullptr}; - ID3D11ShaderResourceView* _textureView{ nullptr }; - D3D11_TEXTURE2D_DESC _description{}; - + ID3D11Texture2D* dxTexture2D{ nullptr }; + ID3D11ShaderResourceView* dxShaderResourceView{ nullptr }; + D3D11_SUBRESOURCE_DATA dxSubResource{}; + D3D11_TEXTURE2D_DESC dxDescription{}; + D3D11_SHADER_RESOURCE_VIEW_DESC dxShaderDecription{}; + + private: + static constexpr int R8G8B8A8U_BYTE_SIZE = 4; + + void setDefaultDesc() { + dxDescription.MipLevels = 1; + dxDescription.ArraySize = 1; + dxDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + dxDescription.SampleDesc.Count = 1; + dxDescription.Usage = D3D11_USAGE_DEFAULT; + dxDescription.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + dxShaderDecription.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + dxShaderDecription.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + dxShaderDecription.Texture2D.MipLevels = dxDescription.MipLevels; + dxShaderDecription.Texture2D.MostDetailedMip = 0; + } }; + + template + inline void Texture2D::SetData(std::vector const& data, xna_error_ptr_arg) { + SetData(data, 0, data.size(), err); + } + + template + inline void Texture2D::SetData(std::vector const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg) { + if (!m_device || !m_device->_device || !m_device->_context) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return; + } + + std::vector finalData(elementCount); + auto finalDataIndex = 0; + + for (size_t i = startIndex; i < elementCount; ++i) { + finalData[finalDataIndex] = static_cast(data[i]); + ++finalDataIndex; + } + + if (!dxTexture2D) { + auto hr = m_device->_device->CreateTexture2D(&dxDescription, nullptr, &dxTexture2D); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return; + } + } + + ID3D11Resource* resource = nullptr; + auto hr = dxTexture2D->QueryInterface(IID_ID3D11Resource, (void**)&resource); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return; + } + + dxShaderDecription.Texture2D.MipLevels = dxDescription.MipLevels; + m_device->_context->UpdateSubresource(resource, 0, nullptr, finalData.data(), dxDescription.Width * R8G8B8A8U_BYTE_SIZE, 0); + + if (dxShaderResourceView) { + dxShaderResourceView->Release(); + dxShaderResourceView = nullptr; + } + + hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDecription, &dxShaderResourceView); + + if (resource) { + resource->Release(); + resource = nullptr; + } + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return; + } + + dxTexture2D->GetDesc(&dxDescription); + } } #endif \ No newline at end of file diff --git a/framework/xna.cpp b/framework/xna.cpp index 5cbd3f5..2746e92 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -14,12 +14,6 @@ namespace xna { graphics = New(_game); graphics->PreferredBackBufferWidth(1280); graphics->PreferredBackBufferHeight(720); - - contentManager = New("Content"); - //const auto s = contentManager->_path.string(); - // const auto current = std::filesystem::current_path(); - //auto s = contentManager->OpenStream("file"); - //DecompressStream::Decompress(); } void Initialize() override { @@ -30,8 +24,13 @@ namespace xna { void LoadContent() override { spriteBatch = New(*_graphicsDevice); - XnaErrorCode err; - texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err); + XnaErrorCode err{0}; + //texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err); + texture = New(_graphicsDevice.get(), 256, 256); + std::vector data(256 * 256, 4278190080U); + //std::vector data(256 * 256, 0xffffffff); + //std::vector data(256 * 256, 4278190080U); + texture->SetData(data, 0, data.size()); Game::LoadContent(); } diff --git a/framework/xnaerror.hpp b/framework/xnaerror.hpp index a89e32c..dcdf274 100644 --- a/framework/xnaerror.hpp +++ b/framework/xnaerror.hpp @@ -14,7 +14,8 @@ namespace xna { STREAM_ERROR, UNINTIALIZED_RESOURCE, END_OF_FILE, - BAD_TYPE + BAD_TYPE, + WARNING_INITIALIZED_RESOURCE }; inline void xna_error_apply(XnaErrorCode* source, XnaErrorCode const& value) { From 9b10adfc387f3048a3cc98fc25e824baaf92fb4f Mon Sep 17 00:00:00 2001 From: Danilo Date: Sun, 5 May 2024 15:50:17 -0300 Subject: [PATCH 05/17] =?UTF-8?q?Implementa=C3=A7=C3=B5es=20em=20Texture2D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/content/manager.hpp | 10 +- framework/content/reader.cpp | 24 ++ framework/content/reader.hpp | 16 +- framework/content/typereadermanager.hpp | 4 +- framework/csharp/binary.cpp | 5 + framework/csharp/binary.hpp | 1 + .../content-readers/texture2Dreader-dx.hpp | 28 +++ framework/platform/dxheaders.hpp | 24 ++ framework/platform/spritebatch-dx.cpp | 28 +-- framework/platform/texture-dx.cpp | 236 +++++++++++++++++- framework/platform/texture-dx.hpp | 115 ++------- framework/xna.cpp | 10 +- 12 files changed, 376 insertions(+), 125 deletions(-) create mode 100644 framework/platform/content-readers/texture2Dreader-dx.hpp diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index 05db4f7..d69dbf8 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -1,15 +1,18 @@ #ifndef XNA_CONTENT_MANAGER_HPP #define XNA_CONTENT_MANAGER_HPP +#include "../csharp/stream.hpp" #include "../default.hpp" +#include "reader.hpp" +#include #include #include -#include -#include "../csharp/stream.hpp" namespace xna { class ContentManager { public: + friend class ContentReader; + ContentManager(String const& rootDirectory) : _rootDirectory(rootDirectory), _path(rootDirectory){}; @@ -35,7 +38,7 @@ namespace xna { } template - sptr Load(String const& assetName) { + T Load(String const& assetName) { if (assetName.empty()) return nullptr; if (_loadedAssets.contains(assetName)) { @@ -69,6 +72,7 @@ namespace xna { std::filesystem::path _path; std::map> _loadedAssets; inline const static String contentExtension = ".xnb"; + std::vector byteBuffer; }; } diff --git a/framework/content/reader.cpp b/framework/content/reader.cpp index e108343..df63c50 100644 --- a/framework/content/reader.cpp +++ b/framework/content/reader.cpp @@ -2,6 +2,7 @@ #include "manager.hpp" #include "lzx/decoderstream.hpp" #include "typereadermanager.hpp" +#include "manager.hpp" namespace xna { sptr ContentReader::Create(ContentManager* contentManager, sptr& input, String const& assetName) @@ -88,6 +89,29 @@ namespace xna { return *(double*)&int64; } + std::vector ContentReader::ReadByteBuffer(size_t size, xna_error_ptr_arg) + { + std::vector& buffer = _contentManager->byteBuffer; + + if (buffer.empty() || buffer.size() < size) + { + buffer = std::vector(size); + //_contentManager->byteBuffer = buffer; + } + + Int num = 0; + for (size_t index = 0; index < size; index += num) + { + num = Read(buffer, index, size - index); + if (num == 0) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return std::vector(); + } + } + + return buffer; + } + sptr ContentReader::PrepareStream(sptr& input, String const& assetName, Int& graphicsProfile) { BinaryReader binaryReader = BinaryReader(input); diff --git a/framework/content/reader.hpp b/framework/content/reader.hpp index 0f8fc77..c521be1 100644 --- a/framework/content/reader.hpp +++ b/framework/content/reader.hpp @@ -1,15 +1,15 @@ #ifndef XNA_CONTENT_READER_HPP #define XNA_CONTENT_READER_HPP -#include "../default.hpp" -#include "../csharp/binary.hpp" -#include "../csharp/type.hpp" -#include "typereadermanager.hpp" -#include -#include "../common/vectors.hpp" +#include "../common/color.hpp" #include "../common/matrix.hpp" #include "../common/quaternion.hpp" -#include "../common/color.hpp" +#include "../common/vectors.hpp" +#include "../csharp/binary.hpp" +#include "../csharp/type.hpp" +#include "../default.hpp" +#include "typereadermanager.hpp" +#include namespace xna { class ContentReader : public BinaryReader, public std::enable_shared_from_this{ @@ -34,6 +34,8 @@ namespace xna { float ReadSingle(); double ReadDouble(); + std::vector ReadByteBuffer(size_t size, xna_error_nullarg); + private: ContentReader(ContentManager* contentManager, sptr& input, String const& assetName, Int graphicsProfile) : BinaryReader(input), _contentManager(contentManager), _assetName(assetName){} diff --git a/framework/content/typereadermanager.hpp b/framework/content/typereadermanager.hpp index 79a812f..9bab3c2 100644 --- a/framework/content/typereadermanager.hpp +++ b/framework/content/typereadermanager.hpp @@ -41,7 +41,7 @@ namespace xna { return std::any(); } - virtual T Read(ContentReader& input, T existingInstance) = 0; + virtual T Read(ContentReader& input, T& existingInstance) = 0; }; //-------------------------------------------------------// @@ -175,7 +175,7 @@ namespace xna { }); } - virtual Object Read(ContentReader& input, Object existingInstance) override { + virtual Object Read(ContentReader& input, Object& existingInstance) override { return Object(); } }; diff --git a/framework/csharp/binary.cpp b/framework/csharp/binary.cpp index 03c60ce..fffdee9 100644 --- a/framework/csharp/binary.cpp +++ b/framework/csharp/binary.cpp @@ -683,6 +683,11 @@ namespace xna { return InternalReadChars(buffer.data(), buffer.size(), index, count, err); } + Int BinaryReader::Read(std::vector& buffer, size_t index, size_t count, xna_error_ptr_arg) + { + auto data = reinterpret_cast(buffer.data()); + return InternalReadChars(data, buffer.size(), index, count, err); + } std::vector BinaryReader::ReadBytes(size_t count, xna_error_ptr_arg) { std::vector result(count); diff --git a/framework/csharp/binary.hpp b/framework/csharp/binary.hpp index 9721817..1c9cea3 100644 --- a/framework/csharp/binary.hpp +++ b/framework/csharp/binary.hpp @@ -29,6 +29,7 @@ namespace xna { std::string ReadString(xna_error_nullarg); Int Read(std::vector& buffer, size_t index, size_t count, xna_error_nullarg); + Int Read(std::vector& buffer, size_t index, size_t count, xna_error_nullarg); std::vector ReadBytes(size_t count, xna_error_nullarg); diff --git a/framework/platform/content-readers/texture2Dreader-dx.hpp b/framework/platform/content-readers/texture2Dreader-dx.hpp new file mode 100644 index 0000000..ca930a3 --- /dev/null +++ b/framework/platform/content-readers/texture2Dreader-dx.hpp @@ -0,0 +1,28 @@ +#ifndef XNA_PLATFORM_CONTENTREADERS_TEXTURE2D_HPP +#define XNA_PLATFORM_CONTENTREADERS_TEXTURE2D_HPP + +#include "../../content/reader.hpp" +#include "../texture-dx.hpp" + +namespace xna { + class Texture2DReader : public ContentTypeReaderT { + Texture2D Read(ContentReader& input, Texture2D& existingInstance) override{ + const auto format = static_cast(input.ReadInt32()); + const auto width = input.ReadInt32(); + const auto height = input.ReadInt32(); + const auto mipMaps = input.ReadInt32(); + auto texture2D = Texture2D(nullptr, width, height, mipMaps, format); + + for (size_t level = 0; level < mipMaps; ++level) { + auto elementCount = input.ReadInt32(); + std::vector data = input.ReadByteBuffer(elementCount); + + texture2D.SetData(level, nullptr, data, 0, elementCount); + } + + return texture2D; + } + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/dxheaders.hpp b/framework/platform/dxheaders.hpp index a2fc464..c08436a 100644 --- a/framework/platform/dxheaders.hpp +++ b/framework/platform/dxheaders.hpp @@ -1,9 +1,33 @@ +//DirectX #include "dxgi.h" #include "d3d11.h" #include #include +//HSLS #include +//DirectXTK #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//Windows #define NOMINMAX #include #include diff --git a/framework/platform/spritebatch-dx.cpp b/framework/platform/spritebatch-dx.cpp index e01457c..0345150 100644 --- a/framework/platform/spritebatch-dx.cpp +++ b/framework/platform/spritebatch-dx.cpp @@ -63,7 +63,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture.dxShaderResourceView) + if (!texture.dxShaderResource) return; const auto _position = XMFLOAT2(position.X, position.Y); @@ -71,7 +71,7 @@ namespace xna { XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W }; _dxspriteBatch->Draw( - texture.dxShaderResourceView, + texture.dxShaderResource, _position, _color ); @@ -81,7 +81,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture.dxShaderResourceView) + if (!texture.dxShaderResource) return; const auto _position = XMFLOAT2(position.X, position.Y); @@ -98,7 +98,7 @@ namespace xna { }; _dxspriteBatch->Draw( - texture.dxShaderResourceView, + texture.dxShaderResource, _position, sourceRectangle ? &_sourceRect : nullptr, _color); @@ -108,7 +108,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture.dxShaderResourceView) + if (!texture.dxShaderResource) return; const auto _position = XMFLOAT2(position.X, position.Y); @@ -128,7 +128,7 @@ namespace xna { const DxSpriteEffects _effects = static_cast(effects); _dxspriteBatch->Draw( - texture.dxShaderResourceView, + texture.dxShaderResource, _position, sourceRectangle ? &_sourceRect : nullptr, _color, @@ -143,7 +143,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture.dxShaderResourceView) + if (!texture.dxShaderResource) return; const auto _position = XMFLOAT2(position.X, position.Y); @@ -164,7 +164,7 @@ namespace xna { const XMFLOAT2 _scale = { scale.X, scale.Y }; _dxspriteBatch->Draw( - texture.dxShaderResourceView, + texture.dxShaderResource, _position, sourceRectangle ? &_sourceRect : nullptr, _color, @@ -179,7 +179,7 @@ namespace xna { if (!_dxspriteBatch) return; - if (!texture.dxShaderResourceView) + if (!texture.dxShaderResource) return; RECT _destinationRect{}; @@ -191,14 +191,14 @@ namespace xna { const auto v4 = color.ToVector4(); const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W }; - _dxspriteBatch->Draw(texture.dxShaderResourceView, _destinationRect, _color); + _dxspriteBatch->Draw(texture.dxShaderResource, _destinationRect, _color); } void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color) { if (!_dxspriteBatch) return; - if (!texture.dxShaderResourceView) + if (!texture.dxShaderResource) return; RECT _destinationRect{}; @@ -219,14 +219,14 @@ namespace xna { _sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height; }; - _dxspriteBatch->Draw(texture.dxShaderResourceView, _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color); + _dxspriteBatch->Draw(texture.dxShaderResource, _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color); } void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color, float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) { if (!_dxspriteBatch) return; - if (!texture.dxShaderResourceView) + if (!texture.dxShaderResource) return; RECT _destinationRect{}; @@ -251,7 +251,7 @@ namespace xna { const auto _effects = static_cast(effects); _dxspriteBatch->Draw( - texture.dxShaderResourceView, + texture.dxShaderResource, _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color, diff --git a/framework/platform/texture-dx.cpp b/framework/platform/texture-dx.cpp index 8e2a5e0..e5b602d 100644 --- a/framework/platform/texture-dx.cpp +++ b/framework/platform/texture-dx.cpp @@ -1,7 +1,6 @@ #include "texture-dx.hpp" -#include "WICTextureLoader.h" #include "device-dx.hpp" -#include "../helpers.hpp" +#include "adapter-dx.hpp" namespace xna { sptr Texture2D::FromStream(GraphicsDevice& device, String const& fileName, xna_error_ptr_arg) @@ -15,7 +14,7 @@ namespace xna { device._context, wstr.c_str(), &resource, - &texture2d->dxShaderResourceView, + &texture2d->dxShaderResource, 0U); if (FAILED(result)) @@ -80,7 +79,7 @@ namespace xna { return false; } - hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDecription, &dxShaderResourceView); + hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDescription, &dxShaderResource); if (resource) { resource->Release(); @@ -94,4 +93,233 @@ namespace xna { return true; } + + Texture2D::Texture2D(GraphicsDevice* device, size_t width, size_t height) : GraphicsResource(device) { + setDefaultDesc(); + dxDescription.Width = static_cast(width); + dxDescription.Height = static_cast(height); + } + + Texture2D::Texture2D(GraphicsDevice* device) : GraphicsResource(device) { + setDefaultDesc(); + } + + Texture2D::Texture2D(GraphicsDevice* device, size_t width, size_t height, size_t mipMap, SurfaceFormat format) : GraphicsResource(device) + { + setDefaultDesc(); + dxDescription.Width = static_cast(width); + dxDescription.Height = static_cast(height); + dxDescription.MipLevels = static_cast(mipMap); + dxDescription.Format = GraphicsAdapter::ConvertSurfaceToDXGIFORMAT(format); + } + + void Texture2D::SetData(std::vector const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg) + { + if (!m_device || !m_device->_device || !m_device->_context) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return; + } + + internalSetData(data.data(), err); + } + + void Texture2D::SetData(std::vector const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg) + { + if (!m_device || !m_device->_device || !m_device->_context) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return; + } + + std::vector finalData(elementCount / 4); + auto fIndex = 0; + + for (size_t i = startIndex; i < elementCount; ++i) { + const auto& r = data[i]; + const auto& g = data[++i]; + const auto& b = data[++i]; + const auto& a = data[++i]; + finalData[fIndex] = Color(r, g, b, a); + ++fIndex; + } + + internalSetData(finalData.data(), err); + } + + void Texture2D::SetData(Int level, Rectangle* rect, std::vector const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg) + { + if (!m_device || !m_device->_device || !m_device->_context) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return; + } + + std::vector finalData(elementCount / 4); + auto fIndex = 0; + + for (size_t i = startIndex; i < elementCount; ++i) { + const auto& r = data[i]; + const auto& g = data[++i]; + const auto& b = data[++i]; + const auto& a = data[++i]; + finalData[fIndex] = Color(r, g, b, a); + ++fIndex; + } + + if (!dxTexture2D) { + auto hr = m_device->_device->CreateTexture2D(&dxDescription, nullptr, &dxTexture2D); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return; + } + } + + ID3D11Resource* resource = nullptr; + auto hr = dxTexture2D->QueryInterface(IID_ID3D11Resource, (void**)&resource); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return; + } + + D3D11_BOX box{}; + + if (rect) { + box.left = rect->X; + box.right = rect->X + rect->Width; + box.top = rect->Y; + box.bottom = rect->Y + rect->Height; + box.back = level; + box.front = 0; + } + + m_device->_context->UpdateSubresource(resource, 0, rect ? &box : nullptr, finalData.data(), dxDescription.Width * R8G8B8A8U_BYTE_SIZE, 0); + + if (dxShaderResource) { + dxShaderResource->Release(); + dxShaderResource = nullptr; + } + + dxShaderDescription.Texture2D.MipLevels = dxDescription.MipLevels; + hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDescription, &dxShaderResource); + + if (resource) { + resource->Release(); + resource = nullptr; + } + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return; + } + + dxTexture2D->GetDesc(&dxDescription); + } + + void Texture2D::SetData(std::vector const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg) + { + if (!m_device || !m_device->_device || !m_device->_context) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return; + } + + std::vector finalData(elementCount); + auto finalDataIndex = 0; + + for (size_t i = startIndex; i < elementCount; ++i) { + finalData[finalDataIndex] = static_cast(data[i]); + ++finalDataIndex; + } + + internalSetData(finalData.data(), err); + } + + sptr Texture2D::FromMemory(GraphicsDevice& device, std::vector const& data, xna_error_ptr_arg) + { + auto texture2d = New(&device); + ID3D11Resource* resource = nullptr; + + auto hr = DirectX::CreateWICTextureFromMemory( + device._device, + device._context, + data.data(), + data.size(), + &resource, + &texture2d->dxShaderResource); + + if (FAILED(hr)) + { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + + if (resource) { + resource->Release(); + resource = nullptr; + } + + return nullptr; + } + + hr = resource->QueryInterface(IID_ID3D11Texture2D, (void**)&texture2d->dxTexture2D); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + + if (resource) { + resource->Release(); + resource = nullptr; + } + + return nullptr; + } + + D3D11_TEXTURE2D_DESC desc; + texture2d->dxTexture2D->GetDesc(&desc); + texture2d->dxDescription = desc; + + resource->Release(); + resource = nullptr; + + return texture2d; + } + + void Texture2D::internalSetData(UINT const* data, xna_error_ptr_arg) + { + if (!dxTexture2D) { + auto hr = m_device->_device->CreateTexture2D(&dxDescription, nullptr, &dxTexture2D); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return; + } + } + + ID3D11Resource* resource = nullptr; + auto hr = dxTexture2D->QueryInterface(IID_ID3D11Resource, (void**)&resource); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return; + } + + m_device->_context->UpdateSubresource(resource, 0, nullptr, data, dxDescription.Width * R8G8B8A8U_BYTE_SIZE, 0); + + if (dxShaderResource) { + dxShaderResource->Release(); + dxShaderResource = nullptr; + } + + dxShaderDescription.Texture2D.MipLevels = dxDescription.MipLevels; + hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDescription, &dxShaderResource); + + if (resource) { + resource->Release(); + resource = nullptr; + } + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return; + } + + dxTexture2D->GetDesc(&dxDescription); + } } \ No newline at end of file diff --git a/framework/platform/texture-dx.hpp b/framework/platform/texture-dx.hpp index 1cbe9e0..faccacf 100644 --- a/framework/platform/texture-dx.hpp +++ b/framework/platform/texture-dx.hpp @@ -2,27 +2,17 @@ #define XNA_PLATFORM_TEXTURE_DX_HPP #include "../common/rectangle.hpp" -#include "../csharp/buffer.hpp" -#include "../graphics/texture.hpp" -#include "../xnaerror.hpp" -#include "dxheaders.hpp" -#include #include "../graphics/gresource.hpp" +#include "../graphics/texture.hpp" +#include "dxheaders.hpp" #include "device-dx.hpp" -#include namespace xna { class Texture2D : public ITexture2D, public GraphicsResource { public: - Texture2D(GraphicsDevice* device, size_t width, size_t height) : GraphicsResource(device) { - dxDescription.Width = static_cast(width); - dxDescription.Height = static_cast(height); - setDefaultDesc(); - } - - Texture2D(GraphicsDevice* device) : GraphicsResource(device) { - setDefaultDesc(); - } + Texture2D(GraphicsDevice* device); + Texture2D(GraphicsDevice* device, size_t width, size_t height); + Texture2D(GraphicsDevice* device, size_t width, size_t height, size_t mipMap, SurfaceFormat format); virtual ~Texture2D() override { if (dxTexture2D) { @@ -30,9 +20,9 @@ namespace xna { dxTexture2D = nullptr; } - if (dxShaderResourceView) { - dxShaderResourceView->Release(); - dxShaderResourceView = nullptr; + if (dxShaderResource) { + dxShaderResource->Release(); + dxShaderResource = nullptr; } } @@ -48,22 +38,23 @@ namespace xna { return { 0, 0, static_cast(dxDescription.Width), static_cast(dxDescription.Height) }; } - bool Initialize(xna_error_nullarg) override; - - template - void SetData(std::vector const& data, xna_error_ptr_arg); - - template - void SetData(std::vector const& data, size_t startIndex, size_t elementCount, xna_error_nullarg); + bool Initialize(xna_error_nullarg) override; + + void SetData(std::vector const& data, size_t startIndex = 0, size_t elementCount = 0, xna_error_nullarg); + void SetData(std::vector const& data, size_t startIndex = 0, size_t elementCount = 0, xna_error_nullarg); + void SetData(std::vector const& data, size_t startIndex = 0, size_t elementCount = 0, xna_error_nullarg); + + void SetData(Int level, Rectangle* rect, std::vector const& data, size_t startIndex, size_t elementCount, xna_error_nullarg); static sptr FromStream(GraphicsDevice& device, String const& fileName, xna_error_nullarg); + static sptr FromMemory(GraphicsDevice& device, std::vector const& data, xna_error_nullarg); public: ID3D11Texture2D* dxTexture2D{ nullptr }; - ID3D11ShaderResourceView* dxShaderResourceView{ nullptr }; + ID3D11ShaderResourceView* dxShaderResource{ nullptr }; D3D11_SUBRESOURCE_DATA dxSubResource{}; D3D11_TEXTURE2D_DESC dxDescription{}; - D3D11_SHADER_RESOURCE_VIEW_DESC dxShaderDecription{}; + D3D11_SHADER_RESOURCE_VIEW_DESC dxShaderDescription{}; private: static constexpr int R8G8B8A8U_BYTE_SIZE = 4; @@ -76,72 +67,14 @@ namespace xna { dxDescription.Usage = D3D11_USAGE_DEFAULT; dxDescription.BindFlags = D3D11_BIND_SHADER_RESOURCE; - dxShaderDecription.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - dxShaderDecription.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - dxShaderDecription.Texture2D.MipLevels = dxDescription.MipLevels; - dxShaderDecription.Texture2D.MostDetailedMip = 0; - } - }; - - template - inline void Texture2D::SetData(std::vector const& data, xna_error_ptr_arg) { - SetData(data, 0, data.size(), err); - } - - template - inline void Texture2D::SetData(std::vector const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg) { - if (!m_device || !m_device->_device || !m_device->_context) { - xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); - return; + dxShaderDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + dxShaderDescription.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + dxShaderDescription.Texture2D.MipLevels = dxDescription.MipLevels; + dxShaderDescription.Texture2D.MostDetailedMip = 0; } - std::vector finalData(elementCount); - auto finalDataIndex = 0; - - for (size_t i = startIndex; i < elementCount; ++i) { - finalData[finalDataIndex] = static_cast(data[i]); - ++finalDataIndex; - } - - if (!dxTexture2D) { - auto hr = m_device->_device->CreateTexture2D(&dxDescription, nullptr, &dxTexture2D); - - if (FAILED(hr)) { - xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); - return; - } - } - - ID3D11Resource* resource = nullptr; - auto hr = dxTexture2D->QueryInterface(IID_ID3D11Resource, (void**)&resource); - - if (FAILED(hr)) { - xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); - return; - } - - dxShaderDecription.Texture2D.MipLevels = dxDescription.MipLevels; - m_device->_context->UpdateSubresource(resource, 0, nullptr, finalData.data(), dxDescription.Width * R8G8B8A8U_BYTE_SIZE, 0); - - if (dxShaderResourceView) { - dxShaderResourceView->Release(); - dxShaderResourceView = nullptr; - } - - hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDecription, &dxShaderResourceView); - - if (resource) { - resource->Release(); - resource = nullptr; - } - - if (FAILED(hr)) { - xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); - return; - } - - dxTexture2D->GetDesc(&dxDescription); - } + void internalSetData(UINT const* data, xna_error_nullarg); + }; } #endif \ No newline at end of file diff --git a/framework/xna.cpp b/framework/xna.cpp index 2746e92..db6b1ad 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -14,6 +14,7 @@ namespace xna { graphics = New(_game); graphics->PreferredBackBufferWidth(1280); graphics->PreferredBackBufferHeight(720); + contentManager = New("Content"); } void Initialize() override { @@ -26,11 +27,12 @@ namespace xna { XnaErrorCode err{0}; //texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err); - texture = New(_graphicsDevice.get(), 256, 256); - std::vector data(256 * 256, 4278190080U); + //texture = New(_graphicsDevice.get(), 256, 256); + //std::vector data(256 * 256, 4278190080U); //std::vector data(256 * 256, 0xffffffff); //std::vector data(256 * 256, 4278190080U); - texture->SetData(data, 0, data.size()); + //texture->SetData(data, 0, data.size()); + //Texture2D tx = contentManager->Load("Idle"); Game::LoadContent(); } @@ -46,7 +48,7 @@ namespace xna { _graphicsDevice->Clear(Colors::CornflowerBlue); spriteBatch->Begin(); - spriteBatch->Draw(*texture, position, Colors::White); + //spriteBatch->Draw(*texture, position, Colors::White); spriteBatch->End(); Game::Draw(gameTime); From b194a27dadec211dc94b2cd8d36c975843ff6135 Mon Sep 17 00:00:00 2001 From: Danilo Date: Mon, 6 May 2024 09:58:40 -0300 Subject: [PATCH 06/17] =?UTF-8?q?Implementa=C3=A7=C3=B5es=20em=20Content?= =?UTF-8?q?=20e=20Texture2D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/CMakeLists.txt | 2 +- framework/content/manager.hpp | 11 +++--- framework/content/reader.cpp | 9 ++--- framework/content/reader.hpp | 36 +++++++++++-------- framework/content/typereadermanager.cpp | 21 ++++++----- framework/csharp/binary.cpp | 2 +- framework/csharp/type.cpp | 2 +- framework/csharp/type.hpp | 6 +++- framework/platform/adapter-dx.hpp | 3 +- .../content-readers/texture2Dreader-dx.hpp | 7 ++-- framework/platform/game-dx.cpp | 3 +- framework/platform/init-dx.cpp | 30 ++++++++++++++++ framework/platform/init-dx.hpp | 18 ++++++++++ framework/platform/texture-dx.hpp | 4 +++ framework/types.hpp | 1 + framework/xna.cpp | 10 ++++-- framework/xna.h | 1 + 17 files changed, 123 insertions(+), 43 deletions(-) create mode 100644 framework/platform/init-dx.cpp create mode 100644 framework/platform/init-dx.hpp diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 730b18d..6aa384a 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -39,7 +39,7 @@ add_executable (xna WIN32 "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" "csharp/type.cpp") +"content/decstream.cpp" "content/lzx/decoder.cpp" "content/lzx/decoderstream.cpp" "content/typereadermanager.cpp" "csharp/object.cpp" "csharp/type.cpp" "platform/init-dx.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index d69dbf8..dfbf2a8 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -42,19 +42,20 @@ namespace xna { if (assetName.empty()) return nullptr; if (_loadedAssets.contains(assetName)) { - const auto& ptr = _loadedAssets[assetName]; - const auto obj1 = reinterpret_pointer_cast(ptr); + auto& ptr = _loadedAssets[assetName]; + auto obj1 = reinterpret_pointer_cast(ptr); - return obj1; + return *obj1; } - const auto obj2 = ReadAsset(assetName); + auto obj2 = ReadAsset(assetName); + //auto obj3 = reinterpret_pointer_cast(obj2); return obj2; } protected: template - sptr ReadAsset(String const& assetName) { + T ReadAsset(String const& assetName) { auto input = OpenStream(assetName); auto contentReader = ContentReader::Create(this, input, assetName); diff --git a/framework/content/reader.cpp b/framework/content/reader.cpp index df63c50..69cded6 100644 --- a/framework/content/reader.cpp +++ b/framework/content/reader.cpp @@ -120,20 +120,21 @@ namespace xna { return nullptr; Int num1 = 0; - if (binaryReader.ReadByte() == 'w') + auto _byte = binaryReader.ReadByte(); //desfazer + if (_byte == 'w') num1 = binaryReader.ReadUInt16(); else return nullptr; - graphicsProfile = (num1 & 32512) >> 8; + graphicsProfile = (num1 & XnbVersionProfileMask) >> XnbVersionProfileShift; bool flag = false; switch (num1 & -32513) { - case 5: + case XnbVersion: flag = false; break; - case 32773: + case XnbCompressedVersion: flag = true; break; default: diff --git a/framework/content/reader.hpp b/framework/content/reader.hpp index c521be1..5ae62c7 100644 --- a/framework/content/reader.hpp +++ b/framework/content/reader.hpp @@ -12,13 +12,13 @@ #include namespace xna { - class ContentReader : public BinaryReader, public std::enable_shared_from_this{ + class ContentReader : public BinaryReader, public std::enable_shared_from_this { public: static sptr Create(ContentManager* contentManager, sptr& input, String const& assetName); - + template - sptr ReadAsset(); - + T ReadAsset(); + template T ReadObject(); @@ -38,7 +38,7 @@ namespace xna { private: ContentReader(ContentManager* contentManager, sptr& input, String const& assetName, Int graphicsProfile) - : BinaryReader(input), _contentManager(contentManager), _assetName(assetName){} + : BinaryReader(input), _contentManager(contentManager), _assetName(assetName) {} static sptr PrepareStream(sptr& input, String const& assetName, Int& graphicsProfile); @@ -46,7 +46,7 @@ namespace xna { template T ReadObjectInternal(std::any& existingInstance, xna_error_nullarg); - + template T InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg); @@ -55,6 +55,11 @@ namespace xna { String _assetName; std::vector> typeReaders; Int graphicsProfile{ 0 }; + + static constexpr Ushort XnbVersionProfileMask = 32512; + static constexpr Ushort XnbCompressedVersion = 32773; + static constexpr Ushort XnbVersion = 5; + static constexpr Int XnbVersionProfileShift = 8; }; template @@ -65,7 +70,7 @@ namespace xna { if (num == 0) { return T(); } - + const auto index = num - 1; if (index >= typeReaders.size()) { @@ -73,9 +78,10 @@ namespace xna { return T(); } - return InvokeReader(typeReaders[index], existingInstance); + auto reader = typeReaders[index]; + return InvokeReader(*reader, existingInstance, err); } - + template inline T ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_ptr_arg) { @@ -85,13 +91,14 @@ namespace xna { if (contentTypeReader) { T existingInstance1 = existingInstance.has_value() ? std::any_cast(existingInstance) : T(); objB = contentTypeReader->Read(*this, existingInstance1); + return objB; } return T(); } - - template - inline sptr ContentReader::ReadAsset() + + template + inline T ContentReader::ReadAsset() { const auto sharedResourceCount = ReadHeader(); T obj = ReadObject(); @@ -102,14 +109,15 @@ namespace xna { template inline T ContentReader::ReadObject() { - return ReadObjectInternal(nullptr); + auto a = std::any(); + return ReadObjectInternal(a); } template inline T ContentReader::ReadObject(T existingInstance) { return ReadObjectInternal(std::any(existingInstance)); - } + } } #endif \ No newline at end of file diff --git a/framework/content/typereadermanager.cpp b/framework/content/typereadermanager.cpp index 43c3f5b..25be7dd 100644 --- a/framework/content/typereadermanager.cpp +++ b/framework/content/typereadermanager.cpp @@ -11,7 +11,11 @@ namespace xna { for (size_t index = 0; index < typeCount; ++index) { - auto typeReader = ContentTypeReaderManager::GetTypeReader(contentReader->ReadString(), contentReader, newTypeReaders); + const auto readerTypeName = contentReader->ReadString(); + const auto xnaType = readerTypeName.substr(0, readerTypeName.find(",")); + + + auto typeReader = ContentTypeReaderManager::GetTypeReader(xnaType.empty() ? readerTypeName : xnaType, contentReader, newTypeReaders); if (contentReader->ReadInt32() != typeReader->TypeVersion()) { xna_error_apply(err, XnaErrorCode::BAD_TYPE); @@ -59,9 +63,12 @@ namespace xna { { sptr reader = nullptr; - if (ContentTypeReaderManager::nameToReader.contains(readerTypeName) || !ContentTypeReaderManager::InstantiateTypeReader(readerTypeName, contentReader, reader, err)) { + if (ContentTypeReaderManager::nameToReader.contains(readerTypeName)) { return ContentTypeReaderManager::nameToReader[readerTypeName]; - } + } + else if (!ContentTypeReaderManager::InstantiateTypeReader(readerTypeName, contentReader, reader, err)) { + return reader; + } if (xna_error_haserros(err)) return nullptr; @@ -79,12 +86,8 @@ namespace xna { { sptr type = nullptr; - std::map, sptr>::iterator it; - - for (it = readerTypeToReader.begin(); it != readerTypeToReader.end(); it++) { - if (it->first->FullName() == readerTypeName) - type = it->first; - } + if (Type::NameOfRegisteredTypes.contains(readerTypeName)) + type = Type::NameOfRegisteredTypes[readerTypeName]; if (!type) { xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); diff --git a/framework/csharp/binary.cpp b/framework/csharp/binary.cpp index fffdee9..b419b2a 100644 --- a/framework/csharp/binary.cpp +++ b/framework/csharp/binary.cpp @@ -261,7 +261,7 @@ namespace xna { } while (num < val1); - return empty; + return sb; } Int BinaryReader::InternalReadOneChar(xna_error_ptr_arg) diff --git a/framework/csharp/type.cpp b/framework/csharp/type.cpp index b4ceeec..28e0123 100644 --- a/framework/csharp/type.cpp +++ b/framework/csharp/type.cpp @@ -11,5 +11,5 @@ namespace xna { XnaHHashCombine(seed, isPrimitive); return seed; - } + } } \ No newline at end of file diff --git a/framework/csharp/type.hpp b/framework/csharp/type.hpp index 335296a..a2ff3cd 100644 --- a/framework/csharp/type.hpp +++ b/framework/csharp/type.hpp @@ -5,6 +5,7 @@ #include "object.hpp" #include #include +#include namespace xna { class Type : public Object { @@ -33,12 +34,15 @@ namespace xna { template friend sptr typeof(); + public: + inline static auto NameOfRegisteredTypes = std::map>(); + private: String fullName; bool isClass{ false }; bool isEnum{ false }; bool isValueType{ false }; - bool isPrimitive{ false }; + bool isPrimitive{ false }; }; template diff --git a/framework/platform/adapter-dx.hpp b/framework/platform/adapter-dx.hpp index 0e32cbc..099fc78 100644 --- a/framework/platform/adapter-dx.hpp +++ b/framework/platform/adapter-dx.hpp @@ -45,7 +45,7 @@ namespace xna { switch (format) { case SurfaceFormat::Color://21 - return DXGI_FORMAT_B8G8R8A8_UNORM; + return DXGI_FORMAT_R8G8B8A8_UNORM; case SurfaceFormat::Bgr565: //23 return DXGI_FORMAT_B5G6R5_UNORM; case SurfaceFormat::Bgra5551://25 @@ -92,6 +92,7 @@ namespace xna { static constexpr SurfaceFormat ConvertDXGIFORMATToSurface(DXGI_FORMAT format) { switch (format) { + case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM: return SurfaceFormat::Color; case DXGI_FORMAT_B5G6R5_UNORM: diff --git a/framework/platform/content-readers/texture2Dreader-dx.hpp b/framework/platform/content-readers/texture2Dreader-dx.hpp index ca930a3..7ea9a05 100644 --- a/framework/platform/content-readers/texture2Dreader-dx.hpp +++ b/framework/platform/content-readers/texture2Dreader-dx.hpp @@ -6,19 +6,22 @@ namespace xna { class Texture2DReader : public ContentTypeReaderT { + public: + Texture2DReader() : ContentTypeReaderT(typeof()){} + Texture2D Read(ContentReader& input, Texture2D& existingInstance) override{ const auto format = static_cast(input.ReadInt32()); const auto width = input.ReadInt32(); const auto height = input.ReadInt32(); const auto mipMaps = input.ReadInt32(); auto texture2D = Texture2D(nullptr, width, height, mipMaps, format); - + for (size_t level = 0; level < mipMaps; ++level) { auto elementCount = input.ReadInt32(); std::vector data = input.ReadByteBuffer(elementCount); texture2D.SetData(level, nullptr, data, 0, elementCount); - } + } return texture2D; } diff --git a/framework/platform/game-dx.cpp b/framework/platform/game-dx.cpp index d342ca3..365726f 100644 --- a/framework/platform/game-dx.cpp +++ b/framework/platform/game-dx.cpp @@ -9,6 +9,7 @@ #include "mouse-dx.hpp" #include "window-dx.hpp" #include +#include "../csharp/type.hpp" namespace xna { Game::Game() { @@ -156,5 +157,5 @@ namespace xna { }); Draw(_currentGameTime); - } + } } diff --git a/framework/platform/init-dx.cpp b/framework/platform/init-dx.cpp new file mode 100644 index 0000000..c822e88 --- /dev/null +++ b/framework/platform/init-dx.cpp @@ -0,0 +1,30 @@ +#include "init-dx.hpp" +#include "../csharp/type.hpp" +#include "texture-dx.hpp" +#include "content-readers/texture2Dreader-dx.hpp" +#include "../content/typereadermanager.hpp" + +namespace xna { + void InitPlatform::InitRegisteredTypes() + { + Type::NameOfRegisteredTypes.insert({ "Texture2D", typeof() }); + + //Texture2DReader + Type::NameOfRegisteredTypes.insert({ "Texture2DReader", typeof() }); + Type::NameOfRegisteredTypes.insert({ "xna::Texture2DReader", typeof() }); + Type::NameOfRegisteredTypes.insert({ "Microsoft.Xna.Framework.Content.Texture2DReader", typeof() }); + } + + void InitPlatform::InitActivadors() + { + ContentTypeReaderActivador::SetActivador(typeof(), []() -> sptr { + auto obj = New (); + return reinterpret_pointer_cast(obj); + }); + + ContentTypeReaderActivador::SetActivador(typeof(), []() -> sptr { + auto obj = New (); + return reinterpret_pointer_cast(obj); + }); + } +} \ No newline at end of file diff --git a/framework/platform/init-dx.hpp b/framework/platform/init-dx.hpp new file mode 100644 index 0000000..eab6abf --- /dev/null +++ b/framework/platform/init-dx.hpp @@ -0,0 +1,18 @@ +#ifndef XNA_PLATFORM_INIT_HPP +#define XNA_PLATFORM_INIT_HPP + +#include "../default.hpp" + +namespace xna { + struct InitPlatform { + static void Init() { + InitRegisteredTypes(); + InitActivadors(); + } + + static void InitRegisteredTypes(); + static void InitActivadors(); + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/texture-dx.hpp b/framework/platform/texture-dx.hpp index faccacf..60f8fe4 100644 --- a/framework/platform/texture-dx.hpp +++ b/framework/platform/texture-dx.hpp @@ -10,6 +10,10 @@ namespace xna { class Texture2D : public ITexture2D, public GraphicsResource { public: + Texture2D() : GraphicsResource(nullptr){ + setDefaultDesc(); + } + Texture2D(GraphicsDevice* device); Texture2D(GraphicsDevice* device, size_t width, size_t height); Texture2D(GraphicsDevice* device, size_t width, size_t height, size_t mipMap, SurfaceFormat format); diff --git a/framework/types.hpp b/framework/types.hpp index c37d8a0..c647ee4 100644 --- a/framework/types.hpp +++ b/framework/types.hpp @@ -44,6 +44,7 @@ namespace xna { constexpr double DoubleMinValue = std::numeric_limits::min(); using String = std::string; + using WString = std::wstring; template using sptr = std::shared_ptr; diff --git a/framework/xna.cpp b/framework/xna.cpp index db6b1ad..371475a 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -32,7 +32,9 @@ namespace xna { //std::vector data(256 * 256, 0xffffffff); //std::vector data(256 * 256, 4278190080U); //texture->SetData(data, 0, data.size()); - //Texture2D tx = contentManager->Load("Idle"); + tx = contentManager->Load("Idle"); + tx.Bind(_graphicsDevice.get()); + tx.Initialize(&err); Game::LoadContent(); } @@ -48,7 +50,7 @@ namespace xna { _graphicsDevice->Clear(Colors::CornflowerBlue); spriteBatch->Begin(); - //spriteBatch->Draw(*texture, position, Colors::White); + spriteBatch->Draw(tx, position, Colors::White); spriteBatch->End(); Game::Draw(gameTime); @@ -65,12 +67,14 @@ namespace xna { float vel = 1; int var = 0; sptr contentManager; + Texture2D tx; }; } int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { - + xna::InitPlatform::Init(); + auto game = xna::Game1(); const auto result = game.Run(); return result; diff --git a/framework/xna.h b/framework/xna.h index 8d73ac0..cd43145 100644 --- a/framework/xna.h +++ b/framework/xna.h @@ -25,5 +25,6 @@ #include #include "content/manager.hpp" #include "content/decstream.hpp" +#include "platform/init-dx.hpp" // TODO: Reference additional headers your program requires here. From 319b545a03ef76f40ab6d5dfc0fa577989770097 Mon Sep 17 00:00:00 2001 From: Danilo Date: Mon, 6 May 2024 10:32:17 -0300 Subject: [PATCH 07/17] Implementa GameServices --- framework/CMakeLists.txt | 2 +- framework/content/manager.hpp | 9 ++++++++- framework/csharp/service.hpp | 15 +++++++++++++++ framework/forward.hpp | 1 + framework/game/game.hpp | 8 ++++---- framework/game/servicecontainer.cpp | 18 ++++++++++++++++++ framework/game/servicecontainer.hpp | 13 ++++++++++--- framework/platform/game-dx.cpp | 2 ++ framework/platform/game-dx.hpp | 15 +++++++++++++-- framework/xna.cpp | 7 +++---- 10 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 framework/csharp/service.hpp create mode 100644 framework/game/servicecontainer.cpp diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 6aa384a..8307a7f 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -39,7 +39,7 @@ add_executable (xna WIN32 "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" "csharp/type.cpp" "platform/init-dx.cpp") +"content/decstream.cpp" "content/lzx/decoder.cpp" "content/lzx/decoderstream.cpp" "content/typereadermanager.cpp" "csharp/object.cpp" "csharp/type.cpp" "platform/init-dx.cpp" "game/servicecontainer.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index dfbf2a8..6c4e250 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -7,20 +7,26 @@ #include #include #include +#include "../game/servicecontainer.hpp" namespace xna { class ContentManager { public: friend class ContentReader; - ContentManager(String const& rootDirectory) : + ContentManager(String const& rootDirectory, sptr const& services) : _rootDirectory(rootDirectory), + _services(services), _path(rootDirectory){}; virtual ~ContentManager(){ Unload(); } + sptr Services() { + return _services; + } + constexpr String RootDirectory() const { return _rootDirectory; } @@ -74,6 +80,7 @@ namespace xna { std::map> _loadedAssets; inline const static String contentExtension = ".xnb"; std::vector byteBuffer; + sptr _services = nullptr; }; } diff --git a/framework/csharp/service.hpp b/framework/csharp/service.hpp new file mode 100644 index 0000000..b7a9cb8 --- /dev/null +++ b/framework/csharp/service.hpp @@ -0,0 +1,15 @@ +#ifndef XNA_CSHARP_SERVICE_HPP +#define XNA_CSHARP_SERVICE_HPP + +#include "../default.hpp" +#include "type.hpp" +#include + +namespace xna { + class IServiceProvider { + public: + virtual std::any GetService(Type& serviceType) = 0; + }; +} + +#endif \ No newline at end of file diff --git a/framework/forward.hpp b/framework/forward.hpp index e5d3eaf..dd6f930 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -53,6 +53,7 @@ namespace xna { class GraphicsDeviceManager; class IGameTime; class IGameComponent; + class GameServiceContainer; //Graphics class BlendState; diff --git a/framework/game/game.hpp b/framework/game/game.hpp index 936335a..d57154e 100644 --- a/framework/game/game.hpp +++ b/framework/game/game.hpp @@ -1,12 +1,11 @@ #ifndef XNA_GAME_GAME_HPP #define XNA_GAME_GAME_HPP -#include "../enums.hpp" -#include "../forward.hpp" -#include "../types.hpp" +#include "../default.hpp" #include "time.hpp" #include "window.hpp" -#include "../game/component.hpp" +#include "component.hpp" +#include "servicecontainer.hpp" namespace xna { class IGame { @@ -18,6 +17,7 @@ namespace xna { virtual sptr Window() = 0; virtual sptr GetGraphicsDevice() = 0; virtual sptr Components() = 0; + virtual sptr Services() = 0; protected: virtual void Draw(GameTime const& gameTime) = 0; diff --git a/framework/game/servicecontainer.cpp b/framework/game/servicecontainer.cpp new file mode 100644 index 0000000..20c2689 --- /dev/null +++ b/framework/game/servicecontainer.cpp @@ -0,0 +1,18 @@ +#include "servicecontainer.hpp" + +namespace xna { + void GameServiceContainer::AddService(Type& type, std::any& provider) + { + auto hashCode = type.GetHashCode(); + services.insert({ hashCode, provider }); + } + + std::any GameServiceContainer::GetService(Type& serviceType) + { + auto hashCode = serviceType.GetHashCode(); + + return services.contains(hashCode) + ? services[hashCode] + : std::any(); + } +} \ No newline at end of file diff --git a/framework/game/servicecontainer.hpp b/framework/game/servicecontainer.hpp index 2ce68aa..69255d0 100644 --- a/framework/game/servicecontainer.hpp +++ b/framework/game/servicecontainer.hpp @@ -2,12 +2,19 @@ #define XNA_GAME_SERVICECONTAINER_HPP #include "../default.hpp" +#include "../csharp/service.hpp" +#include namespace xna { - class IServiceProvider { - }; + class GameServiceContainer : public IServiceProvider { + public: + void AddService(Type& type, std::any& provider); - class GameServiceContainer { + // Inherited via IServiceProvider + std::any GetService(Type& serviceType) override; + + private: + std::map services; }; } diff --git a/framework/platform/game-dx.cpp b/framework/platform/game-dx.cpp index 365726f..5aff1c0 100644 --- a/framework/platform/game-dx.cpp +++ b/framework/platform/game-dx.cpp @@ -13,6 +13,8 @@ namespace xna { Game::Game() { + _services = New(); + _gameWindow = New(); _gameWindow->Color(255, 155, 55); _gameWindow->Title("XN65"); diff --git a/framework/platform/game-dx.hpp b/framework/platform/game-dx.hpp index b1b42c0..93549be 100644 --- a/framework/platform/game-dx.hpp +++ b/framework/platform/game-dx.hpp @@ -5,6 +5,7 @@ #include "../game/game.hpp" #include "dxheaders.hpp" #include "dx/StepTimer.hpp" +#include "../content/manager.hpp" namespace xna { class Game : public IGame { @@ -30,6 +31,14 @@ namespace xna { return _gameComponents; } + sptr Services() override { + return _services; + } + + sptr Content() { + return contentManager; + } + constexpr void EnableGameComponents(bool value) { _enabledGameComponents = value; } @@ -52,14 +61,16 @@ namespace xna { GameTime _currentGameTime{}; DX::StepTimer _stepTimer; - + sptr contentManager; + sptr _services = nullptr; + private: int startLoop(); void step(); sptr _gameComponents = nullptr; std::vector> _drawableGameComponents; size_t _drawableGameComponentsCount{ 0 }; - bool _enabledGameComponents{ false }; + bool _enabledGameComponents{ false }; }; } diff --git a/framework/xna.cpp b/framework/xna.cpp index 371475a..3db47bb 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -9,12 +9,12 @@ using namespace xna; namespace xna { class Game1 : public Game { public: - Game1() { + Game1() : Game() { auto _game = reinterpret_cast(this); graphics = New(_game); graphics->PreferredBackBufferWidth(1280); graphics->PreferredBackBufferHeight(720); - contentManager = New("Content"); + contentManager = New("Content", _services); } void Initialize() override { @@ -65,8 +65,7 @@ namespace xna { MouseState currentState{}; MouseState oldState{}; float vel = 1; - int var = 0; - sptr contentManager; + int var = 0; Texture2D tx; }; } From d3ceb91ca106e3e3faf357e27991fc05097cb396 Mon Sep 17 00:00:00 2001 From: Danilo Date: Mon, 6 May 2024 11:35:27 -0300 Subject: [PATCH 08/17] =?UTF-8?q?Implementa=C3=A7=C3=B5es=20em=20Content?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/content/manager.hpp | 18 +++++----- framework/content/reader.hpp | 34 +++++++++---------- framework/content/typereadermanager.hpp | 6 ++-- .../content-readers/texture2Dreader-dx.hpp | 12 +++++-- framework/xna.cpp | 21 +++++------- framework/xna.h | 1 + 6 files changed, 48 insertions(+), 44 deletions(-) diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index 6c4e250..49ce509 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -15,15 +15,16 @@ namespace xna { friend class ContentReader; ContentManager(String const& rootDirectory, sptr const& services) : - _rootDirectory(rootDirectory), - _services(services), - _path(rootDirectory){}; + _rootDirectory(rootDirectory), + _path(rootDirectory){ + _services = services; + }; virtual ~ContentManager(){ Unload(); } - sptr Services() { + static sptr Services() { return _services; } @@ -44,14 +45,14 @@ namespace xna { } template - T Load(String const& assetName) { + sptr Load(String const& assetName) { if (assetName.empty()) return nullptr; if (_loadedAssets.contains(assetName)) { auto& ptr = _loadedAssets[assetName]; auto obj1 = reinterpret_pointer_cast(ptr); - return *obj1; + return obj1; } auto obj2 = ReadAsset(assetName); @@ -61,7 +62,7 @@ namespace xna { protected: template - T ReadAsset(String const& assetName) { + sptr ReadAsset(String const& assetName) { auto input = OpenStream(assetName); auto contentReader = ContentReader::Create(this, input, assetName); @@ -80,7 +81,8 @@ namespace xna { std::map> _loadedAssets; inline const static String contentExtension = ".xnb"; std::vector byteBuffer; - sptr _services = nullptr; + + inline static sptr _services = nullptr; }; } diff --git a/framework/content/reader.hpp b/framework/content/reader.hpp index 5ae62c7..8804308 100644 --- a/framework/content/reader.hpp +++ b/framework/content/reader.hpp @@ -17,13 +17,13 @@ namespace xna { static sptr Create(ContentManager* contentManager, sptr& input, String const& assetName); template - T ReadAsset(); + sptr ReadAsset(); template - T ReadObject(); + sptr ReadObject(); template - T ReadObject(T existingInstance); + sptr ReadObject(T existingInstance); Vector2 ReadVector2(); Vector3 ReadVector3(); @@ -45,10 +45,10 @@ namespace xna { Int ReadHeader(); template - T ReadObjectInternal(std::any& existingInstance, xna_error_nullarg); + sptr ReadObjectInternal(std::any& existingInstance, xna_error_nullarg); template - T InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg); + sptr InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg); private: ContentManager* _contentManager = nullptr; @@ -63,19 +63,19 @@ namespace xna { }; template - inline T ContentReader::ReadObjectInternal(std::any& existingInstance, xna_error_ptr_arg) + inline sptr ContentReader::ReadObjectInternal(std::any& existingInstance, xna_error_ptr_arg) { const auto num = Read7BitEncodedInt(); if (num == 0) { - return T(); + return New(); } const auto index = num - 1; if (index >= typeReaders.size()) { xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE); - return T(); + return New(); } auto reader = typeReaders[index]; @@ -83,38 +83,38 @@ namespace xna { } template - inline T ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_ptr_arg) + inline sptr ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_ptr_arg) { auto contentTypeReader = reinterpret_cast*>(&reader); - T objB = T(); + sptr objB = nullptr; if (contentTypeReader) { - T existingInstance1 = existingInstance.has_value() ? std::any_cast(existingInstance) : T(); - objB = contentTypeReader->Read(*this, existingInstance1); + auto existingInstance1 = existingInstance.has_value() ? std::any_cast>(existingInstance) : nullptr; + objB = contentTypeReader->Read(*this, *existingInstance1); return objB; } - return T(); + return New(); } template - inline T ContentReader::ReadAsset() + inline sptr ContentReader::ReadAsset() { const auto sharedResourceCount = ReadHeader(); - T obj = ReadObject(); + auto obj = ReadObject(); //this.ReadSharedResources(sharedResourceCount); return obj; } template - inline T ContentReader::ReadObject() + inline sptr ContentReader::ReadObject() { auto a = std::any(); return ReadObjectInternal(a); } template - inline T ContentReader::ReadObject(T existingInstance) + inline sptr ContentReader::ReadObject(T existingInstance) { return ReadObjectInternal(std::any(existingInstance)); } diff --git a/framework/content/typereadermanager.hpp b/framework/content/typereadermanager.hpp index 9bab3c2..12342a9 100644 --- a/framework/content/typereadermanager.hpp +++ b/framework/content/typereadermanager.hpp @@ -41,7 +41,7 @@ namespace xna { return std::any(); } - virtual T Read(ContentReader& input, T& existingInstance) = 0; + virtual sptr Read(ContentReader& input, T& existingInstance) = 0; }; //-------------------------------------------------------// @@ -175,8 +175,8 @@ namespace xna { }); } - virtual Object Read(ContentReader& input, Object& existingInstance) override { - return Object(); + virtual sptr Read(ContentReader& input, Object& existingInstance) override { + return nullptr; } }; } diff --git a/framework/platform/content-readers/texture2Dreader-dx.hpp b/framework/platform/content-readers/texture2Dreader-dx.hpp index 7ea9a05..1ae47ff 100644 --- a/framework/platform/content-readers/texture2Dreader-dx.hpp +++ b/framework/platform/content-readers/texture2Dreader-dx.hpp @@ -3,24 +3,30 @@ #include "../../content/reader.hpp" #include "../texture-dx.hpp" +#include "../../content/manager.hpp" +#include "../../csharp/type.hpp" namespace xna { class Texture2DReader : public ContentTypeReaderT { public: Texture2DReader() : ContentTypeReaderT(typeof()){} - Texture2D Read(ContentReader& input, Texture2D& existingInstance) override{ + sptr Read(ContentReader& input, Texture2D& existingInstance) override{ const auto format = static_cast(input.ReadInt32()); const auto width = input.ReadInt32(); const auto height = input.ReadInt32(); const auto mipMaps = input.ReadInt32(); - auto texture2D = Texture2D(nullptr, width, height, mipMaps, format); + + auto a_device = ContentManager::Services()->GetService(*typeof()); + auto device = std::any_cast>(a_device); + + auto texture2D = New(device.get(), width, height, mipMaps, format); for (size_t level = 0; level < mipMaps; ++level) { auto elementCount = input.ReadInt32(); std::vector data = input.ReadByteBuffer(elementCount); - texture2D.SetData(level, nullptr, data, 0, elementCount); + texture2D->SetData(level, nullptr, data, 0, elementCount); } return texture2D; diff --git a/framework/xna.cpp b/framework/xna.cpp index 3db47bb..571e62d 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -19,23 +19,18 @@ namespace xna { void Initialize() override { graphics->Initialize(); + + std::any device = _graphicsDevice; + _services->AddService(*typeof(), device); + Game::Initialize(); } void LoadContent() override { spriteBatch = New(*_graphicsDevice); - XnaErrorCode err{0}; - //texture = Texture2D::FromStream(*_graphicsDevice, "D:\\sprite.jpg", &err); - //texture = New(_graphicsDevice.get(), 256, 256); - //std::vector data(256 * 256, 4278190080U); - //std::vector data(256 * 256, 0xffffffff); - //std::vector data(256 * 256, 4278190080U); - //texture->SetData(data, 0, data.size()); - tx = contentManager->Load("Idle"); - tx.Bind(_graphicsDevice.get()); - tx.Initialize(&err); - + XnaErrorCode err{0}; + texture = contentManager->Load("Idle"); Game::LoadContent(); } @@ -50,7 +45,7 @@ namespace xna { _graphicsDevice->Clear(Colors::CornflowerBlue); spriteBatch->Begin(); - spriteBatch->Draw(tx, position, Colors::White); + spriteBatch->Draw(*texture, position, Colors::White); spriteBatch->End(); Game::Draw(gameTime); @@ -66,7 +61,7 @@ namespace xna { MouseState oldState{}; float vel = 1; int var = 0; - Texture2D tx; + //Texture2D tx; }; } diff --git a/framework/xna.h b/framework/xna.h index cd43145..eac110e 100644 --- a/framework/xna.h +++ b/framework/xna.h @@ -26,5 +26,6 @@ #include "content/manager.hpp" #include "content/decstream.hpp" #include "platform/init-dx.hpp" +#include "csharp/type.hpp" // TODO: Reference additional headers your program requires here. From da53a0a272b67f86610a92fc8fbcff1c196ecf52 Mon Sep 17 00:00:00 2001 From: Danilo Date: Mon, 6 May 2024 14:54:13 -0300 Subject: [PATCH 09/17] Limpeza em Game --- framework/content/manager.hpp | 9 ++- framework/game/game.hpp | 4 +- framework/platform/game-dx.cpp | 36 ++++-------- framework/platform/game-dx.hpp | 74 ++++++++---------------- framework/platform/gdevicemanager-dx.cpp | 6 +- framework/xna.cpp | 27 +++------ 6 files changed, 50 insertions(+), 106 deletions(-) diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index 49ce509..45ce5f1 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -15,8 +15,7 @@ namespace xna { friend class ContentReader; ContentManager(String const& rootDirectory, sptr const& services) : - _rootDirectory(rootDirectory), - _path(rootDirectory){ + _rootDirectory(rootDirectory){ _services = services; }; @@ -34,7 +33,6 @@ namespace xna { void RootDirectory(String const& value) { _rootDirectory = value; - _path = value; } virtual void Unload() { @@ -56,7 +54,9 @@ namespace xna { } auto obj2 = ReadAsset(assetName); - //auto obj3 = reinterpret_pointer_cast(obj2); + //auto voidAsset = reinterpret_pointer_cast(obj2); + _loadedAssets.insert({ assetName , obj2 }); + return obj2; } @@ -77,7 +77,6 @@ namespace xna { private: String _rootDirectory; - std::filesystem::path _path; std::map> _loadedAssets; inline const static String contentExtension = ".xnb"; std::vector byteBuffer; diff --git a/framework/game/game.hpp b/framework/game/game.hpp index d57154e..3656808 100644 --- a/framework/game/game.hpp +++ b/framework/game/game.hpp @@ -3,21 +3,19 @@ #include "../default.hpp" #include "time.hpp" -#include "window.hpp" #include "component.hpp" #include "servicecontainer.hpp" namespace xna { class IGame { public: - virtual ~IGame(){} - virtual void Exit() = 0; virtual int Run() = 0; virtual sptr Window() = 0; virtual sptr GetGraphicsDevice() = 0; virtual sptr Components() = 0; virtual sptr Services() = 0; + virtual sptr Content() = 0; protected: virtual void Draw(GameTime const& gameTime) = 0; diff --git a/framework/platform/game-dx.cpp b/framework/platform/game-dx.cpp index 5aff1c0..de5ff30 100644 --- a/framework/platform/game-dx.cpp +++ b/framework/platform/game-dx.cpp @@ -1,4 +1,4 @@ -#define NOMINMAX +#include "../csharp/type.hpp" #include "../game/time.hpp" #include "audioengine-dx.hpp" #include "device-dx.hpp" @@ -8,15 +8,14 @@ #include "keyboard-dx.hpp" #include "mouse-dx.hpp" #include "window-dx.hpp" -#include -#include "../csharp/type.hpp" namespace xna { Game::Game() { - _services = New(); + services = New(); + _contentManager = New("", services); _gameWindow = New(); - _gameWindow->Color(255, 155, 55); + _gameWindow->Color(146, 150, 154); _gameWindow->Title("XN65"); _gameWindow->Size( GraphicsDeviceManager::DefaultBackBufferWidth, @@ -25,15 +24,14 @@ namespace xna { _gameComponents = New(); } - void Game::Exit() - { + void Game::Exit() { _gameWindow->Close(); } int Game::Run() { Initialize(); - if (_graphicsDevice == nullptr) { + if (graphicsDevice == nullptr) { MessageBox(nullptr, "O dispositivo gráfico não foi inicializado corretamente", "XN65", MB_OK); return EXIT_FAILURE; } @@ -43,33 +41,19 @@ namespace xna { void Game::Initialize() { Keyboard::Initialize(); - Mouse::Initialize(); - - ////initialize é requisito para GamePad - //Microsoft::WRL::Wrappers::RoInitializeWrapper initialize(RO_INIT_MULTITHREADED); - - //if (FAILED(initialize)) - // MessageBox(nullptr, "Ocorreu um erro ao executar Microsoft::WRL::Wrappers::RoInitializeWrapper. O GamePad não foi inicializado corretamente.", "XN65", MB_OK); - - //GamePad.Initialize(); - - ////CoInitializeEx é requisito para biblioteca DirectXTK - //const auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); - - //if (FAILED(hr)) - // MessageBox(nullptr, "Ocorreu um erro ao executar CoInitializeEx. O AudioEngine não foi inicializado corretamente.", "XN65", MB_OK); + Mouse::Initialize(); #if (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/) Microsoft::WRL::Wrappers::RoInitializeWrapper initialize(RO_INIT_MULTITHREADED); if (FAILED(initialize)) { - + MessageBox(nullptr, "Ocorreu um erro ao chamar Microsoft::WRL::Wrappers::RoInitializeWrapper.", "XN65", MB_OK); } #else HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); if (FAILED(hr)) { - + MessageBox(nullptr, "Ocorreu um erro ao chamar CoInitializeEx.", "XN65", MB_OK); } #endif @@ -101,7 +85,7 @@ namespace xna { _drawableGameComponents.clear(); } - _graphicsDevice->Present(); + graphicsDevice->Present(); } void Game::Update(GameTime const& gameTime) { diff --git a/framework/platform/game-dx.hpp b/framework/platform/game-dx.hpp index 93549be..66ffef0 100644 --- a/framework/platform/game-dx.hpp +++ b/framework/platform/game-dx.hpp @@ -1,76 +1,52 @@ #ifndef XNA_PLATFORM_GAME_DX_HPP #define XNA_PLATFORM_GAME_DX_HPP +#include "../content/manager.hpp" #include "../default.hpp" #include "../game/game.hpp" -#include "dxheaders.hpp" #include "dx/StepTimer.hpp" -#include "../content/manager.hpp" +#include "dxheaders.hpp" namespace xna { class Game : public IGame { public: - Game(); + Game(); - virtual ~Game() override { - } - - virtual void Exit() override; - - virtual int Run() override; + void Exit() override; + int Run() override; - virtual sptr Window() override { - return _gameWindow; - } - - virtual sptr GetGraphicsDevice() override { - return _graphicsDevice; - } - - sptr Components() override { - return _gameComponents; - } - - sptr Services() override { - return _services; - } - - sptr Content() { - return contentManager; - } - - constexpr void EnableGameComponents(bool value) { - _enabledGameComponents = value; - } + inline sptr Window() override { return _gameWindow; } + inline sptr GetGraphicsDevice() override { return graphicsDevice; } + inline sptr Components() override { return _gameComponents; } + inline sptr Services() override { return services; } + inline sptr Content() override { return _contentManager; } + constexpr void EnableGameComponents(bool value) { _enabledGameComponents = value; } protected: - virtual void Draw(GameTime const& gameTime) override; - + virtual void Draw(GameTime const& gameTime) override; virtual void Initialize() override; - - virtual void LoadContent() override{} - + virtual void LoadContent() override{} virtual void Update(GameTime const& gameTime) override; public: - sptr _graphicsDevice{ nullptr }; + sptr graphicsDevice = nullptr; - protected: - sptr _gameWindow{ nullptr }; - sptr _audioEngine = nullptr; - - GameTime _currentGameTime{}; - DX::StepTimer _stepTimer; - sptr contentManager; - sptr _services = nullptr; + protected: + sptr services = nullptr; - private: - int startLoop(); - void step(); + private: sptr _gameComponents = nullptr; + sptr _gameWindow{ nullptr }; + sptr _audioEngine = nullptr; + sptr _contentManager; std::vector> _drawableGameComponents; size_t _drawableGameComponentsCount{ 0 }; bool _enabledGameComponents{ false }; + GameTime _currentGameTime{}; + DX::StepTimer _stepTimer{}; + + int startLoop(); + void step(); }; } diff --git a/framework/platform/gdevicemanager-dx.cpp b/framework/platform/gdevicemanager-dx.cpp index d656c69..8226f68 100644 --- a/framework/platform/gdevicemanager-dx.cpp +++ b/framework/platform/gdevicemanager-dx.cpp @@ -33,10 +33,10 @@ namespace xna { } bool GraphicsDeviceManager::ToggleFullScreen() { - if (!_game || !_game->_graphicsDevice || !_game->_graphicsDevice->_swapChain) + if (!_game || !_game->graphicsDevice || !_game->graphicsDevice->_swapChain) return false; - auto& swap = _game->_graphicsDevice->_swapChain; + auto& swap = _game->graphicsDevice->_swapChain; BOOL state = false; auto hr = swap->dxSwapChain->GetFullscreenState(&state, nullptr); @@ -110,7 +110,7 @@ namespace xna { return false; } - _game->_graphicsDevice = _device; + _game->graphicsDevice = _device; return true; } diff --git a/framework/xna.cpp b/framework/xna.cpp index 571e62d..8107cf6 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -12,25 +12,22 @@ namespace xna { Game1() : Game() { auto _game = reinterpret_cast(this); graphics = New(_game); - graphics->PreferredBackBufferWidth(1280); - graphics->PreferredBackBufferHeight(720); - contentManager = New("Content", _services); + + Content()->RootDirectory("Content"); } void Initialize() override { graphics->Initialize(); - std::any device = _graphicsDevice; - _services->AddService(*typeof(), device); + std::any device = graphicsDevice; + services->AddService(*typeof(), device); Game::Initialize(); } void LoadContent() override { - spriteBatch = New(*_graphicsDevice); + spriteBatch = New(*graphicsDevice); - XnaErrorCode err{0}; - texture = contentManager->Load("Idle"); Game::LoadContent(); } @@ -42,11 +39,9 @@ namespace xna { } void Draw(GameTime const& gameTime) override { - _graphicsDevice->Clear(Colors::CornflowerBlue); + graphicsDevice->Clear(Colors::CornflowerBlue); - spriteBatch->Begin(); - spriteBatch->Draw(*texture, position, Colors::White); - spriteBatch->End(); + Game::Draw(gameTime); } @@ -54,14 +49,6 @@ namespace xna { private: sptr graphics = nullptr; sptr spriteBatch = nullptr; - sptr texture = nullptr; //200x200 - Vector2 position{}; - std::vector points; - MouseState currentState{}; - MouseState oldState{}; - float vel = 1; - int var = 0; - //Texture2D tx; }; } From c6797f4d9329584f3811c7e44b95903f38c37069 Mon Sep 17 00:00:00 2001 From: Danilo Date: Mon, 6 May 2024 15:57:09 -0300 Subject: [PATCH 10/17] =?UTF-8?q?Corre=C3=A7=C3=B5es=20em=20GraphicsResour?= =?UTF-8?q?ce?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/graphics/gresource.hpp | 6 +++--- framework/platform/blendstate-dx.hpp | 2 +- .../platform/content-readers/texture2Dreader-dx.hpp | 2 +- framework/platform/depthstencilstate-dx.hpp | 2 +- framework/platform/device-dx.cpp | 8 +++++--- framework/platform/device-dx.hpp | 2 +- framework/platform/rasterizerstate-dx.hpp | 2 +- framework/platform/rendertarget-dx.hpp | 2 +- framework/platform/samplerstate-dx.hpp | 2 +- framework/platform/shader-dx.hpp | 6 +++--- framework/platform/swapchain-dx.hpp | 2 +- framework/platform/texture-dx.cpp | 12 +++++++----- framework/platform/texture-dx.hpp | 6 +++--- 13 files changed, 29 insertions(+), 25 deletions(-) diff --git a/framework/graphics/gresource.hpp b/framework/graphics/gresource.hpp index 74381fe..59e441d 100644 --- a/framework/graphics/gresource.hpp +++ b/framework/graphics/gresource.hpp @@ -6,11 +6,11 @@ namespace xna { class GraphicsResource { public: - GraphicsResource(GraphicsDevice* device) : m_device(device){} + GraphicsResource(sptr const& device) : m_device(device){} virtual ~GraphicsResource(){} - virtual bool Bind(GraphicsDevice* device) { + virtual bool Bind(sptr const& device) { if (device == m_device) return false; @@ -20,7 +20,7 @@ namespace xna { } protected: - GraphicsDevice* m_device = nullptr; + sptr m_device = nullptr; }; } diff --git a/framework/platform/blendstate-dx.hpp b/framework/platform/blendstate-dx.hpp index fcd3e99..1941daa 100644 --- a/framework/platform/blendstate-dx.hpp +++ b/framework/platform/blendstate-dx.hpp @@ -21,7 +21,7 @@ namespace xna { class BlendState : public IBlendState, public GraphicsResource { public: - BlendState(GraphicsDevice* device) : GraphicsResource(device) {}; + BlendState(sptr const& device) : GraphicsResource(device) {}; virtual ~BlendState() override { if (dxBlendState) { diff --git a/framework/platform/content-readers/texture2Dreader-dx.hpp b/framework/platform/content-readers/texture2Dreader-dx.hpp index 1ae47ff..02dbedf 100644 --- a/framework/platform/content-readers/texture2Dreader-dx.hpp +++ b/framework/platform/content-readers/texture2Dreader-dx.hpp @@ -20,7 +20,7 @@ namespace xna { auto a_device = ContentManager::Services()->GetService(*typeof()); auto device = std::any_cast>(a_device); - auto texture2D = New(device.get(), width, height, mipMaps, format); + auto texture2D = New(device, width, height, mipMaps, format); for (size_t level = 0; level < mipMaps; ++level) { auto elementCount = input.ReadInt32(); diff --git a/framework/platform/depthstencilstate-dx.hpp b/framework/platform/depthstencilstate-dx.hpp index 4126faa..76b16e4 100644 --- a/framework/platform/depthstencilstate-dx.hpp +++ b/framework/platform/depthstencilstate-dx.hpp @@ -8,7 +8,7 @@ namespace xna { class DepthStencilState : public IDepthStencilState, public GraphicsResource { public: - DepthStencilState(GraphicsDevice* device) : GraphicsResource(device) { + DepthStencilState(sptr const& device) : GraphicsResource(device) { dxDescription = defaultDesc(); } diff --git a/framework/platform/device-dx.cpp b/framework/platform/device-dx.cpp index 8e491dd..d068eb0 100644 --- a/framework/platform/device-dx.cpp +++ b/framework/platform/device-dx.cpp @@ -22,6 +22,8 @@ namespace xna { bool GraphicsDevice::Initialize(GameWindow& gameWindow) { reset(); + + auto _this = shared_from_this(); if (!createDevice()) return false; @@ -41,13 +43,13 @@ namespace xna { _backgroundColor[2] = GetBValue(color) / 255.0f; _backgroundColor[3] = 1.0f; - _swapChain = New(this); + _swapChain = New(_this); _swapChain->Initialize(); hr = _factory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER); if (FAILED(hr)) return false; - _renderTarget2D = New(this); + _renderTarget2D = New(_this); if (!_renderTarget2D->Initialize()) return false; @@ -64,7 +66,7 @@ namespace xna { _context->RSSetViewports(1, &view); _blendState = BlendState::NonPremultiplied(); - _blendState->Bind(this); + _blendState->Bind(_this); _blendState->Apply(); return true; diff --git a/framework/platform/device-dx.hpp b/framework/platform/device-dx.hpp index 07e013a..c9a6a4e 100644 --- a/framework/platform/device-dx.hpp +++ b/framework/platform/device-dx.hpp @@ -14,7 +14,7 @@ #include "presentparameters-dx.hpp" namespace xna { - class GraphicsDevice : public IGraphicsDevice { + class GraphicsDevice : public IGraphicsDevice, public std::enable_shared_from_this { public: GraphicsDevice(); GraphicsDevice(GraphicsDeviceInformation const& info); diff --git a/framework/platform/rasterizerstate-dx.hpp b/framework/platform/rasterizerstate-dx.hpp index 33f088e..3b46701 100644 --- a/framework/platform/rasterizerstate-dx.hpp +++ b/framework/platform/rasterizerstate-dx.hpp @@ -8,7 +8,7 @@ namespace xna { class RasterizerState : public IRasterizerState, public GraphicsResource { public: - RasterizerState(GraphicsDevice* device) : GraphicsResource(device){} + RasterizerState(sptr const& device) : GraphicsResource(device){} virtual ~RasterizerState() override { if (dxRasterizerState) { diff --git a/framework/platform/rendertarget-dx.hpp b/framework/platform/rendertarget-dx.hpp index d7430c0..0ed0667 100644 --- a/framework/platform/rendertarget-dx.hpp +++ b/framework/platform/rendertarget-dx.hpp @@ -9,7 +9,7 @@ namespace xna { class RenderTarget2D : public IRenderTarget2D, public Texture2D { public: - RenderTarget2D(GraphicsDevice* device) : Texture2D(device){} + RenderTarget2D(sptr const& device) : Texture2D(device){} virtual ~RenderTarget2D() override { if (_renderTargetView) { diff --git a/framework/platform/samplerstate-dx.hpp b/framework/platform/samplerstate-dx.hpp index 9e93f38..2b2dfe7 100644 --- a/framework/platform/samplerstate-dx.hpp +++ b/framework/platform/samplerstate-dx.hpp @@ -8,7 +8,7 @@ namespace xna { class SamplerState : public ISamplerState, public GraphicsResource { public: - SamplerState(GraphicsDevice* device) : GraphicsResource(device) { + SamplerState(sptr const& device) : GraphicsResource(device) { _description.MaxAnisotropy = 4; } diff --git a/framework/platform/shader-dx.hpp b/framework/platform/shader-dx.hpp index c0842e0..e7938f7 100644 --- a/framework/platform/shader-dx.hpp +++ b/framework/platform/shader-dx.hpp @@ -8,7 +8,7 @@ namespace xna { class Shader : public IShader, public GraphicsResource { public: - Shader(GraphicsDevice* device) : GraphicsResource(device){} + Shader(sptr const& device) : GraphicsResource(device){} virtual ~Shader() override {} @@ -19,7 +19,7 @@ namespace xna { class VertexShader : public Shader { public: - VertexShader(GraphicsDevice* device) : Shader(device){} + VertexShader(sptr const& device) : Shader(device){} virtual ~VertexShader() override { if (_vertexShader) { @@ -36,7 +36,7 @@ namespace xna { class PixelShader : public Shader { public: - PixelShader(GraphicsDevice* device) : Shader(device) {} + PixelShader(sptr const& device) : Shader(device) {} virtual ~PixelShader() override { if (_pixelShader) { diff --git a/framework/platform/swapchain-dx.hpp b/framework/platform/swapchain-dx.hpp index 9a12b0b..a229f76 100644 --- a/framework/platform/swapchain-dx.hpp +++ b/framework/platform/swapchain-dx.hpp @@ -9,7 +9,7 @@ namespace xna { class SwapChain : public ISwapChain, public GraphicsResource { public: - SwapChain(GraphicsDevice* device): GraphicsResource(device){} + SwapChain(sptr const& device): GraphicsResource(device){} virtual ~SwapChain() override { if (dxSwapChain) { diff --git a/framework/platform/texture-dx.cpp b/framework/platform/texture-dx.cpp index e5b602d..ff3c847 100644 --- a/framework/platform/texture-dx.cpp +++ b/framework/platform/texture-dx.cpp @@ -5,7 +5,8 @@ namespace xna { sptr Texture2D::FromStream(GraphicsDevice& device, String const& fileName, xna_error_ptr_arg) { - auto texture2d = New(&device); + auto _this = device.shared_from_this(); + auto texture2d = New(_this); ID3D11Resource* resource = nullptr; auto wstr = XnaHToWString(fileName); @@ -94,17 +95,17 @@ namespace xna { return true; } - Texture2D::Texture2D(GraphicsDevice* device, size_t width, size_t height) : GraphicsResource(device) { + Texture2D::Texture2D(sptr const& device, size_t width, size_t height) : GraphicsResource(device) { setDefaultDesc(); dxDescription.Width = static_cast(width); dxDescription.Height = static_cast(height); } - Texture2D::Texture2D(GraphicsDevice* device) : GraphicsResource(device) { + Texture2D::Texture2D(sptr const& device) : GraphicsResource(device) { setDefaultDesc(); } - Texture2D::Texture2D(GraphicsDevice* device, size_t width, size_t height, size_t mipMap, SurfaceFormat format) : GraphicsResource(device) + Texture2D::Texture2D(sptr const& device, size_t width, size_t height, size_t mipMap, SurfaceFormat format) : GraphicsResource(device) { setDefaultDesc(); dxDescription.Width = static_cast(width); @@ -235,7 +236,8 @@ namespace xna { sptr Texture2D::FromMemory(GraphicsDevice& device, std::vector const& data, xna_error_ptr_arg) { - auto texture2d = New(&device); + auto _this = device.shared_from_this(); + auto texture2d = New(_this); ID3D11Resource* resource = nullptr; auto hr = DirectX::CreateWICTextureFromMemory( diff --git a/framework/platform/texture-dx.hpp b/framework/platform/texture-dx.hpp index 60f8fe4..8bfb433 100644 --- a/framework/platform/texture-dx.hpp +++ b/framework/platform/texture-dx.hpp @@ -14,9 +14,9 @@ namespace xna { setDefaultDesc(); } - Texture2D(GraphicsDevice* device); - Texture2D(GraphicsDevice* device, size_t width, size_t height); - Texture2D(GraphicsDevice* device, size_t width, size_t height, size_t mipMap, SurfaceFormat format); + Texture2D(sptr const& device); + Texture2D(sptr const& device, size_t width, size_t height); + Texture2D(sptr const& device, size_t width, size_t height, size_t mipMap, SurfaceFormat format); virtual ~Texture2D() override { if (dxTexture2D) { From 6b37ede7200ba603257aa2e16f0acdf9c4b0098f Mon Sep 17 00:00:00 2001 From: Danilo Date: Tue, 7 May 2024 17:27:04 -0300 Subject: [PATCH 11/17] Implementa Vetores --- framework/common/matrix.hpp | 41 +++ framework/common/quaternion.hpp | 49 +++ framework/common/rectangle.hpp | 99 +++++- framework/common/vectors.cpp | 291 +++++++++++++++-- framework/common/vectors.hpp | 298 +++++++++++++++++- framework/content/defaultreaders.hpp | 38 +++ framework/content/reader.hpp | 31 +- framework/content/typereadermanager.hpp | 2 +- .../content-readers/texture2Dreader-dx.hpp | 11 +- 9 files changed, 813 insertions(+), 47 deletions(-) create mode 100644 framework/content/defaultreaders.hpp diff --git a/framework/common/matrix.hpp b/framework/common/matrix.hpp index 3a2959c..3da4588 100644 --- a/framework/common/matrix.hpp +++ b/framework/common/matrix.hpp @@ -623,6 +623,47 @@ namespace xna { vector3.Z = num3; return vector3; } + + constexpr Vector4 Vector4::Transform(Vector2 const& position, Matrix const& matrix) + { + const auto num1 = (position.X * matrix.M11 + position.Y * matrix.M21) + matrix.M41; + const auto num2 = (position.X * matrix.M12 + position.Y * matrix.M22) + matrix.M42; + const auto num3 = (position.X * matrix.M13 + position.Y * matrix.M23) + matrix.M43; + const auto num4 = (position.X * matrix.M14 + position.Y * matrix.M24) + matrix.M44; + Vector4 vector4; + vector4.X = num1; + vector4.Y = num2; + vector4.Z = num3; + vector4.W = num4; + return vector4; + } + + constexpr Vector4 Vector4::Transform(Vector3 const& position, Matrix const& matrix) + { + const auto num1 = (position.X * matrix.M11 + position.Y * matrix.M21 + position.Z * matrix.M31) + matrix.M41; + const auto num2 = (position.X * matrix.M12 + position.Y * matrix.M22 + position.Z * matrix.M32) + matrix.M42; + const auto num3 = (position.X * matrix.M13 + position.Y * matrix.M23 + position.Z * matrix.M33) + matrix.M43; + const auto num4 = (position.X * matrix.M14 + position.Y * matrix.M24 + position.Z * matrix.M34) + matrix.M44; + Vector4 vector4; + vector4.X = num1; + vector4.Y = num2; + vector4.Z = num3; + vector4.W = num4; + return vector4; + } + + constexpr Vector4 Vector4::Transform(Vector4 const& vector, Matrix const& matrix) { + const auto num1 = (vector.X * matrix.M11 + vector.Y * matrix.M21 + vector.Z * matrix.M31 + vector.W * matrix.M41); + const auto num2 = (vector.X * matrix.M12 + vector.Y * matrix.M22 + vector.Z * matrix.M32 + vector.W * matrix.M42); + const auto num3 = (vector.X * matrix.M13 + vector.Y * matrix.M23 + vector.Z * matrix.M33 + vector.W * matrix.M43); + const auto num4 = (vector.X * matrix.M14 + vector.Y * matrix.M24 + vector.Z * matrix.M34 + vector.W * matrix.M44); + Vector4 vector4; + vector4.X = num1; + vector4.Y = num2; + vector4.Z = num3; + vector4.W = num4; + return vector4; + } } #endif \ No newline at end of file diff --git a/framework/common/quaternion.hpp b/framework/common/quaternion.hpp index 87372d7..d7adeba 100644 --- a/framework/common/quaternion.hpp +++ b/framework/common/quaternion.hpp @@ -57,6 +57,55 @@ namespace xna { vector3.Z = num15; return vector3; } + + constexpr Vector4 Vector4::Transform(Vector2 const& value, Quaternion const& rotation) + { + const auto num1 = rotation.X + rotation.X; + const auto num2 = rotation.Y + rotation.Y; + const auto num3 = rotation.Z + rotation.Z; + const auto num4 = rotation.W * num1; + const auto num5 = rotation.W * num2; + const auto num6 = rotation.W * num3; + const auto num7 = rotation.X * num1; + const auto num8 = rotation.X * num2; + const auto num9 = rotation.X * num3; + const auto num10 = rotation.Y * num2; + const auto num11 = rotation.Y * num3; + const auto num12 = rotation.Z * num3; + const auto num13 = (value.X * (1.0F - num10 - num12) + value.Y * (num8 - num6)); + const auto num14 = (value.X * (num8 + num6) + value.Y * (1.0F - num7 - num12)); + const auto num15 = (value.X * (num9 - num5) + value.Y * (num11 + num4)); + Vector4 vector4; + vector4.X = num13; + vector4.Y = num14; + vector4.Z = num15; + vector4.W = 1.0f; + return vector4; + } + + constexpr Vector4 Vector4::Transform(Vector3 const& value, Quaternion const& rotation) { + const auto num1 = rotation.X + rotation.X; + const auto num2 = rotation.Y + rotation.Y; + const auto num3 = rotation.Z + rotation.Z; + const auto num4 = rotation.W * num1; + const auto num5 = rotation.W * num2; + const auto num6 = rotation.W * num3; + const auto num7 = rotation.X * num1; + const auto num8 = rotation.X * num2; + const auto num9 = rotation.X * num3; + const auto num10 = rotation.Y * num2; + const auto num11 = rotation.Y * num3; + const auto num12 = rotation.Z * num3; + const auto num13 = (value.X * (1.0F - num10 - num12) + value.Y * (num8 - num6) + value.Z * (num9 + num5)); + const auto num14 = (value.X * (num8 + num6) + value.Y * (1.0F - num7 - num12) + value.Z * (num11 - num4)); + const auto num15 = (value.X * (num9 - num5) + value.Y * (num11 + num4) + value.Z * (1.0F - num7 - num10)); + Vector4 vector4; + vector4.X = num13; + vector4.Y = num14; + vector4.Z = num15; + vector4.W = 1.0f; + return vector4; + } } #endif \ No newline at end of file diff --git a/framework/common/rectangle.hpp b/framework/common/rectangle.hpp index c454bc8..ed14fdc 100644 --- a/framework/common/rectangle.hpp +++ b/framework/common/rectangle.hpp @@ -2,18 +2,113 @@ #define XNA_COMMON_RECTANGLE_HPP #include "../types.hpp" +#include "point.hpp" namespace xna { struct Rectangle { - Int Height{ 0 }; - Int Width{ 0 }; Int X{ 0 }; Int Y{ 0 }; + Int Width{ 0 }; + Int Height{ 0 }; constexpr Rectangle() = default; constexpr Rectangle(const Int& X, const Int& Y, const Int& Width, const Int& Height): X(X), Y(Y), Width(Width), Height(Height) {} + + constexpr bool operator==(const Rectangle& other) const { + return Height == other.Height && Width == other.Width && X == other.X && Y == other.Y; + } + + constexpr Int Left() const { return X; } + constexpr Int Right() const { return X + Width; } + constexpr Int Top() const { return Y; } + constexpr Int Bottom() const { return Y + Height; } + + constexpr Point Location() const { return { X, Y }; } + constexpr void Location(Point const& p) { + X = p.X; + Y = p.Y; + } + + constexpr Point Center() const { return { X + Width / 2, Y + Height / 2 }; } + + constexpr static Rectangle Empty() { return {}; } + + constexpr bool IsEmpty() const { return Width == 0 && Height == 0 && X == 0 && Y == 0; } + + constexpr void Offset(Point const& amount) { + X += amount.X; + Y += amount.Y; + } + + constexpr void Offset(Int x, Int y) { + X += x; + Y += y; + } + + constexpr void Inflate(Int horizontalAmount, Int verticalAmount) { + X -= horizontalAmount; + Y -= verticalAmount; + Width += horizontalAmount * 2; + Height += verticalAmount * 2; + } + + constexpr bool Contains(Int x, Int y) const { + return X <= x && x < X + Width && Y <= y && y < Y + Height; + } + + constexpr bool Contains(Point const& value) const { + return X <= value.X && value.X < X + Width && Y <= value.Y && value.Y < Y + Height; + } + + constexpr bool Contains(Rectangle const& value) const { + return X <= value.X && value.X + value.Width <= X + Width && Y <= value.Y && value.Y + value.Height <= Y + Height; + } + + constexpr bool Intersects(Rectangle const& value) const { + return value.X < X + Width && X < value.X + value.Width && value.Y < Y + Height && Y < value.Y + value.Height; + } + + constexpr static Rectangle Intersect(Rectangle const& value1, Rectangle const& value2) { + const auto left1 = value1.Left(); + const auto left2 = value2.Left(); + const auto bottom1 = value1.Bottom(); + const auto bottom2 = value2.Bottom(); + const auto maxX = value1.X > value2.X ? value1.X : value2.X; + const auto maxY = value1.Y > value2.Y ? value1.Y : value2.Y; + const auto maxl = left1 < left2 ? left1 : left2; + const auto maxb = bottom1 < bottom2 ? bottom1 : bottom2; + + Rectangle rectangle{}; + + if (maxl > maxX && maxb > maxY) { + rectangle.X = maxX; + rectangle.Y = maxY; + rectangle.Width = maxl - maxX; + rectangle.Height = maxb - maxY; + } + + return rectangle; + } + + constexpr static Rectangle Union(Rectangle const& value1, Rectangle const& value2) { + const auto left1 = value1.Left(); + const auto left2 = value2.Left(); + const auto bottom1 = value1.Bottom(); + const auto bottom2 = value2.Bottom(); + const auto minX = value1.X < value2.X ? value1.X : value2.X; + const auto miny = value1.Y < value2.Y ? value1.Y : value2.Y; + const auto maxl = left1 > left2 ? left1 : left2; + const auto maxb = bottom1 > bottom2 ? bottom1 : bottom2; + + Rectangle rectangle; + rectangle.X = minX; + rectangle.Y = miny; + rectangle.Width = maxl - minX; + rectangle.Height = maxb - miny; + return rectangle; + } }; } diff --git a/framework/common/vectors.cpp b/framework/common/vectors.cpp index eb7dc6c..67c4034 100644 --- a/framework/common/vectors.cpp +++ b/framework/common/vectors.cpp @@ -17,6 +17,14 @@ namespace xna { return true; } + bool Vector2::Transform(std::vector sourceArray, Matrix const& matrix, std::vector& destinationArray) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size()); + } + bool Vector2::Transform(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length) { if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength @@ -32,6 +40,14 @@ namespace xna { return true; } + bool Vector2::Transform(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length); + } + bool Vector2::TransformNormal(Vector2 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength) { if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength) return false; @@ -44,6 +60,14 @@ namespace xna { return true; } + + bool Vector2::TransformNormal(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return TransformNormal(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size()); + } bool Vector2::TransformNormal(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length) { if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength @@ -60,6 +84,14 @@ namespace xna { return true; } + bool Vector2::TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return TransformNormal(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length); + } + bool Vector2::Transform(Vector2 const* sourceArray, size_t sourceArrayLength, Quaternion const& rotation, Vector2* destinationArray, size_t destinationArrayLength) { if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength) return false; @@ -86,6 +118,14 @@ namespace xna { return true; } + bool Vector2::Transform(std::vector const& sourceArray, Quaternion const& rotation, std::vector& destinationArray) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), rotation, destinationArray.data(), destinationArray.size()); + } + bool Vector2::Transform(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Quaternion const& rotation, Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length) { if (!sourceArray || !destinationArray || destinationArrayLength < sourceArrayLength @@ -117,30 +157,20 @@ namespace xna { return true; } - void Vector3::Normalize() { - const auto num = 1.0f / std::sqrt(X * X + Y * Y + Z * Z); - X *= num; - Y *= num; - Z *= num; - } - - Vector3 Vector3::Normalize(Vector3 const& value) { - const auto num = 1.0f / std::sqrt(value.X * value.X + value.Y * value.Y + value.Z * value.Z); - - Vector3 vector3; - vector3.X = value.X * num; - vector3.Y = value.Y * num; - vector3.Z = value.Z * num; - - return vector3; - } - - bool xna::Vector3::Transform(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray) + bool Vector2::Transform(std::vector const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector& destinationArray, size_t destinationIndex, size_t length) { - if (destinationArray.size() < sourceArray.size()) + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, rotation, destinationArray.data(), destinationArray.size(), destinationIndex, length); + } + + bool Vector3::Transform(Vector3 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength) + { + if (!sourceArray || !destinationArray || destinationLength < sourceArrayLength) return false; - for (size_t index = 0; index < sourceArray.size(); ++index) + for (size_t index = 0; index < sourceArrayLength; ++index) { const auto& source = sourceArray[index]; destinationArray[index].X = (source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31) + matrix.M41; @@ -151,9 +181,17 @@ namespace xna { return true; } - bool Vector3::Transform(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length) + bool Vector3::Transform(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray) { - if (sourceArray.size() < sourceIndex + length || destinationArray.size() < destinationIndex + length) + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size()); + } + + bool Vector3::Transform(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length) + { + if (!sourceArray || !destinationArray || sourceArrayLength < sourceIndex + length || destinationLength < destinationIndex + length) return false; for (size_t index = 0; index < length; ++index) @@ -161,18 +199,26 @@ namespace xna { const auto& source = sourceArray[sourceIndex + index]; destinationArray[destinationIndex + index].X = (source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31) + matrix.M41; destinationArray[destinationIndex + index].Y = (source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32) + matrix.M42; - destinationArray[destinationIndex + index].Z = (source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33) + matrix.M43; + destinationArray[destinationIndex + index].Z = (source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33) + matrix.M43; } return true; } - bool Vector3::TransformNormal(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray) + bool Vector3::Transform(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length) { - if (destinationArray.size() < sourceArray.size()) + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length); + } + + bool Vector3::TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector3* destinationArray, size_t destionationArrayLength) + { + if (!sourceArray || !destinationArray || sourceArrayLength < destionationArrayLength) return false; - for (size_t index = 0; index < sourceArray.size(); ++index) + for (size_t index = 0; index < sourceArrayLength; ++index) { const auto& source = sourceArray[index]; destinationArray[index].X = source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31; @@ -183,9 +229,17 @@ namespace xna { return true; } - bool Vector3::TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length) + bool Vector3::TransformNormal(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray) { - if (sourceArray.size() < sourceIndex + length || destinationArray.size() < destinationIndex + length) + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return TransformNormal(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size()); + } + + bool Vector3::TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length) + { + if (!sourceArray || !destinationArray || sourceArrayLength < sourceIndex + length || destinationLength < destinationIndex + length) return false; for (size_t index = 0; index < length; ++index) { @@ -198,9 +252,17 @@ namespace xna { return true; } - bool Vector3::TransformNormal(std::vector const& sourceArray, Quaternion const& rotation, std::vector& destinationArray) + bool Vector3::TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length) { - if (destinationArray.size() < sourceArray.size()) + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return TransformNormal(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length); + } + + bool Vector3::TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, Quaternion const& rotation, Vector3* destinationArray, size_t destinationLength) + { + if (!sourceArray || !destinationArray || destinationLength < sourceArrayLength) return false; const auto num1 = rotation.X + rotation.X; @@ -225,7 +287,7 @@ namespace xna { const auto num20 = num11 + num4; const auto num21 = 1.0f - num7 - num10; - for (size_t index = 0; index < sourceArray.size(); ++index) + for (size_t index = 0; index < sourceArrayLength; ++index) { const auto& source = sourceArray[index]; destinationArray[index].X = source.X * num13 + source.Y * num14 + source.Z * num15; @@ -236,11 +298,19 @@ namespace xna { return true; } - bool Vector3::TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector& destinationArray, size_t destinationIndex, size_t length) + bool Vector3::TransformNormal(std::vector const& sourceArray, Quaternion const& rotation, std::vector& destinationArray) { - if (sourceArray.size() < sourceIndex + length || destinationArray.size() < destinationIndex + length) + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return TransformNormal(sourceArray.data(), sourceArray.size(), rotation, destinationArray.data(), destinationArray.size()); + } + + bool Vector3::TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Quaternion const& rotation, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length) + { + if (!sourceArray || !destinationArray || sourceArrayLength < sourceIndex + length || destinationLength < destinationIndex + length) return false; - + const auto num1 = rotation.X + rotation.X; const auto num2 = rotation.Y + rotation.Y; const auto num3 = rotation.Z + rotation.Z; @@ -273,4 +343,155 @@ namespace xna { return true; } + + bool Vector3::TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector& destinationArray, size_t destinationIndex, size_t length) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return TransformNormal(sourceArray.data(), sourceArray.size(), sourceIndex, rotation, destinationArray.data(), destinationArray.size(), destinationIndex, length); + } + + bool Vector4::Transform(Vector4 const* sourceArray, size_t sourceLength, Matrix const& matrix, Vector4* destinationArray, size_t destinationLength) + { + if (!sourceArray || !destinationArray || destinationLength < sourceLength) + return false; + + for (size_t index = 0; index < sourceLength; ++index) + { + const auto& source = sourceArray[index]; + destinationArray[index].X = source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31 + source.W * matrix.M41; + destinationArray[index].Y = source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32 + source.W * matrix.M42; + destinationArray[index].Z = source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33 + source.W * matrix.M43; + destinationArray[index].W = source.X * matrix.M14 + source.Y * matrix.M24 + source.Z * matrix.M34 + source.W * matrix.M44; + } + + return true; + } + + bool Vector4::Transform(std::vector const& sourceArray, size_t sourceLength, Matrix const& matrix, std::vector& destinationArray) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), matrix, destinationArray.data(), destinationArray.size()); + } + + bool Vector4::Transform(Vector4 const* sourceArray, size_t sourceLength, size_t sourceIndex, Matrix const& matrix, Vector4* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length) + { + if (!sourceArray || !destinationArray || sourceLength < sourceIndex + length || destinationLength < destinationIndex + length) + return false; + + for (size_t i = 0; i < length; ++i) + { + const auto& source = sourceArray[sourceIndex + i]; + destinationArray[destinationIndex].X = source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31 + source.W * matrix.M41; + destinationArray[destinationIndex].Y = source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32 + source.W * matrix.M42; + destinationArray[destinationIndex].Z = source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33 + source.W * matrix.M43; + destinationArray[destinationIndex].W = source.X * matrix.M14 + source.Y * matrix.M24 + source.Z * matrix.M34 + source.W * matrix.M44; + } + + return true; + } + + bool Vector4::Transform(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, matrix, destinationArray.data(), destinationArray.size(), destinationIndex, length); + } + + bool Vector4::Transform(Vector4 const* sourceArray, size_t sourceLength, Quaternion const& rotation, Vector4* destinationArray, size_t destinationLength) + { + if (!sourceArray || !destinationArray || destinationLength < sourceLength) + return false; + + const auto num1 = rotation.X + rotation.X; + const auto num2 = rotation.Y + rotation.Y; + const auto num3 = rotation.Z + rotation.Z; + const auto num4 = rotation.W * num1; + const auto num5 = rotation.W * num2; + const auto num6 = rotation.W * num3; + const auto num7 = rotation.X * num1; + const auto num8 = rotation.X * num2; + const auto num9 = rotation.X * num3; + const auto num10 = rotation.Y * num2; + const auto num11 = rotation.Y * num3; + const auto num12 = rotation.Z * num3; + const auto num13 = 1.0f - num10 - num12; + const auto num14 = num8 - num6; + const auto num15 = num9 + num5; + const auto num16 = num8 + num6; + const auto num17 = 1.0f - num7 - num12; + const auto num18 = num11 - num4; + const auto num19 = num9 - num5; + const auto num20 = num11 + num4; + const auto num21 = 1.0f - num7 - num10; + + for (size_t index = 0; index < sourceLength; ++index) + { + const auto& source = sourceArray[index]; + destinationArray[index].X = source.Z * num13 + source.Y * num14 + source.Z * num15; + destinationArray[index].Y = source.Z * num16 + source.Y * num17 + source.Z * num18; + destinationArray[index].Z = source.Z * num19 + source.Y * num20 + source.Z * num21; + destinationArray[index].W = sourceArray[index].W; + } + + return true; + } + + bool Vector4::Transform(std::vector const& sourceArray, Quaternion const& rotation, std::vector& destinationArray) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), rotation, destinationArray.data(), destinationArray.size()); + } + + bool Vector4::Transform(Vector4 const* sourceArray, size_t sourceLength, size_t sourceIndex, Quaternion const& rotation, Vector4* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length) + { + if (!sourceArray || !destinationArray || sourceLength < sourceIndex + length || destinationLength < destinationIndex + length) + return false; + + const auto num1 = rotation.X + rotation.X; + const auto num2 = rotation.Y + rotation.Y; + const auto num3 = rotation.Z + rotation.Z; + const auto num4 = rotation.W * num1; + const auto num5 = rotation.W * num2; + const auto num6 = rotation.W * num3; + const auto num7 = rotation.X * num1; + const auto num8 = rotation.X * num2; + const auto num9 = rotation.X * num3; + const auto num10 = rotation.Y * num2; + const auto num11 = rotation.Y * num3; + const auto num12 = rotation.Z * num3; + const auto num13 = 1.0f - num10 - num12; + const auto num14 = num8 - num6; + const auto num15 = num9 + num5; + const auto num16 = num8 + num6; + const auto num17 = 1.0f - num7 - num12; + const auto num18 = num11 - num4; + const auto num19 = num9 - num5; + const auto num20 = num11 + num4; + const auto num21 = 1.0f - num7 - num10; + + for (size_t i = 0; i < length; ++i) + { + const auto& source = sourceArray[sourceIndex + i]; + destinationArray[destinationIndex].X = source.X * num13 + source.Y * num14 + source.Z * num15; + destinationArray[destinationIndex].Y = source.X * num16 + source.Y * num17 + source.Z * num18; + destinationArray[destinationIndex].Z = source.X * num19 + source.Y * num20 + source.Z * num21; + destinationArray[destinationIndex].W = source.W; + } + + return true; + } + bool Vector4::Transform(std::vector const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector& destinationArray, size_t destinationIndex, size_t length) + { + if (destinationArray.empty()) + destinationArray.resize(sourceArray.size()); + + return Transform(sourceArray.data(), sourceArray.size(), sourceIndex, rotation, destinationArray.data(), destinationArray.size(), destinationIndex, length); + } } \ No newline at end of file diff --git a/framework/common/vectors.hpp b/framework/common/vectors.hpp index 5587285..20a3abb 100644 --- a/framework/common/vectors.hpp +++ b/framework/common/vectors.hpp @@ -53,8 +53,9 @@ namespace xna { } static inline Vector2 Normalize(Vector2 const& value) { - const auto normal = 1.0F / value.Length(); - return { value.X * normal, value.Y * normal }; + auto v = value; + v.Normalize(); + return v; } static constexpr Vector2 Reflect(Vector2 const& vector, Vector2 const& normal) { @@ -136,14 +137,20 @@ namespace xna { static constexpr Vector2 TransformNormal(Vector2 const& normal, Matrix const& matrix); static constexpr Vector2 Transform(Vector2 const& value, Quaternion const& rotation); static bool Transform(Vector2 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength); + static bool Transform(std::vector sourceArray, Matrix const& matrix, std::vector& destinationArray); static bool Transform(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length); + static bool Transform(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length); static bool TransformNormal(Vector2 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength); + static bool TransformNormal(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray); static bool TransformNormal(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length); + static bool TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length); static bool Transform(Vector2 const* sourceArray, size_t sourceArrayLength, Quaternion const& rotation, Vector2* destinationArray, size_t destinationArrayLength); + static bool Transform(std::vector const& sourceArray, Quaternion const& rotation, std::vector& destinationArray); static bool Transform(Vector2 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Quaternion const& rotation, Vector2* destinationArray, size_t destinationArrayLength, size_t destinationIndex, size_t length); + static bool Transform(std::vector const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector& destinationArray, size_t destinationIndex, size_t length); static constexpr Vector2 Negate(Vector2 const& value) { return { -value.X, -value.Y }; @@ -260,8 +267,18 @@ namespace xna { return vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z; } - void Normalize(); - static Vector3 Normalize(Vector3 const& value); + inline void Normalize() { + const auto num = 1.0f / Length(); + X *= num; + Y *= num; + Z *= num; + } + + static Vector3 Normalize(Vector3 const& value) { + auto v = value; + v.Normalize(); + return v; + } static constexpr Vector3 Cross(Vector3 const& vector1, Vector3 const& vector2) { Vector3 vector3; @@ -364,11 +381,17 @@ namespace xna { static constexpr Vector3 Transform(Vector3 const& position, Matrix const& matrix); static constexpr Vector3 TransformNormal(Vector3 const& normal, Matrix const& matrix); static constexpr Vector3 Transform(Vector3 const& value, Quaternion const& rotation); + static bool Transform(Vector3 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength); static bool Transform(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray); + static bool Transform(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length); static bool Transform(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length); + static bool TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, Matrix const& matrix, Vector3* destinationArray, size_t destionationArrayLength); static bool TransformNormal(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray); + static bool TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Matrix const& matrix, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length); static bool TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length); + static bool TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, Quaternion const& rotation,Vector3* destinationArray, size_t destinationLength); static bool TransformNormal(std::vector const& sourceArray, Quaternion const& rotation, std::vector& destinationArray); + static bool TransformNormal(Vector3 const* sourceArray, size_t sourceArrayLength, size_t sourceIndex, Quaternion const& rotation, Vector3* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length); static bool TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector& destinationArray, size_t destinationIndex, size_t length); static constexpr Vector3 Negate(Vector3 const& value) @@ -474,12 +497,279 @@ namespace xna { constexpr Vector4() = default; + constexpr Vector4(float value): + X(value), Y(value), Z(value), W(value){} + constexpr Vector4(float X, float Y, float Z, float W) : X(X), Y(Y), Z(Z), W(W) { } + constexpr Vector4(Vector2 value, float Z, float W) + : X(value.X), Y(value.Y), Z(Z), W(W) { } + + constexpr Vector4(Vector3 value, float W) + : X(value.X), Y(value.Y), Z(value.Z), W(W) { } + constexpr bool operator==(const Vector4& other) const { return X == other.X && Y == other.Y && Z == other.Z && W == other.W; } + + static Vector4 Zero() { return {}; } + static Vector4 One() { return { 1 }; } + static Vector4 UnitX() { return { 1,0,0,0 }; } + static Vector4 UnitY() { return { 0,1,0,0 }; } + static Vector4 UnitZ() { return { 0,0,1,0 }; } + static Vector4 UnitW() { return { 0,0,0,1 }; } + + float Length() const { + return sqrt(LengthSquared()); + } + + constexpr float LengthSquared() const { + return (X * X + Y * Y + Z * Z + W * W); + } + + inline static float Distance(Vector4 const& value1, Vector4 const& value2) { + return sqrt(DistanceSquared(value1, value2)); + } + + static constexpr float DistanceSquared(Vector4 const& value1, Vector4 const& value2) { + const auto num1 = value1.X - value2.X; + const auto num2 = value1.Y - value2.Y; + const auto num3 = value1.Z - value2.Z; + const auto num4 = value1.W - value2.W; + return num1 * num1 + num2 * num2 + num3 * num3 + num4 * num4; + } + + static constexpr float Dot(Vector4 const& vector1, Vector4 const& vector2) { + return vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z + vector1.W * vector2.W; + } + + void Normalize() { + const auto num = 1.0f / Length(); + X *= num; + Y *= num; + Z *= num; + W *= num; + } + + inline static Vector4 Normalize(Vector4 const& vector) { + auto v = vector; + v.Normalize(); + return v; + } + + static constexpr Vector4 Min(Vector4 const& value1, Vector4 const& value2) { + Vector4 vector4; + vector4.X = value1.X < value2.X ? value1.X : value2.X; + vector4.Y = value1.Y < value2.Y ? value1.Y : value2.Y; + vector4.Z = value1.Z < value2.Z ? value1.Z : value2.Z; + vector4.W = value1.W < value2.W ? value1.W : value2.W; + return vector4; + } + + static constexpr Vector4 Max(Vector4 const& value1, Vector4 const& value2) { + Vector4 vector4; + vector4.X = value1.X > value2.X ? value1.X : value2.X; + vector4.Y = value1.Y > value2.Y ? value1.Y : value2.Y; + vector4.Z = value1.Z > value2.Z ? value1.Z : value2.Z; + vector4.W = value1.W > value2.W ? value1.W : value2.W; + return vector4; + } + + static Vector4 Clamp(Vector4 const& value1, Vector4 const& min, Vector4 const& max) { + const auto x = value1.X; + const auto num1 = x > max.X ? max.X : x; + const auto num2 = num1 < min.X ? min.X : num1; + const auto y = value1.Y; + const auto num3 = y > max.Y ? max.Y : y; + const auto num4 = num3 < min.Y ? min.Y : num3; + const auto z = value1.Z; + const auto num5 = z > max.Z ? max.Z : z; + const auto num6 = num5 < min.Z ? min.Z : num5; + const auto w = value1.W; + const auto num7 = w > max.W ? max.W : w; + const auto num8 = num7 < min.W ? min.W : num7; + Vector4 vector4; + vector4.X = num2; + vector4.Y = num4; + vector4.Z = num6; + vector4.W = num8; + return vector4; + } + + static Vector4 Lerp(Vector4 const& value1, Vector4 const& value2, float amount) { + Vector4 vector4; + vector4.X = value1.X + (value2.X - value1.X) * amount; + vector4.Y = value1.Y + (value2.Y - value1.Y) * amount; + vector4.Z = value1.Z + (value2.Z - value1.Z) * amount; + vector4.W = value1.W + (value2.W - value1.W) * amount; + return vector4; + } + + static Vector4 Barycentric(Vector4 const& value1, Vector4 const& value2, Vector4 const& value3, float amount1, float amount2) { + Vector4 vector4; + vector4.X = value1.X + amount1 * (value2.X - value1.X) + amount2 * (value3.X - value1.X); + vector4.Y = value1.Y + amount1 * (value2.Y - value1.Y) + amount2 * (value3.Y - value1.Y); + vector4.Z = value1.Z + amount1 * (value2.Z - value1.Z) + amount2 * (value3.Z - value1.Z); + vector4.W = value1.W + amount1 * (value2.W - value1.W) + amount2 * (value3.W - value1.W); + return vector4; + } + + static Vector4 SmoothStep(Vector4 const& value1, Vector4 const& value2, float amount) { + amount = amount > 1.0F ? 1.0f : (amount < 0.0F ? 0.0f : amount); + amount = (amount * amount * (3.0F - 2.0F * amount)); + Vector4 vector4; + vector4.X = value1.X + (value2.X - value1.X) * amount; + vector4.Y = value1.Y + (value2.Y - value1.Y) * amount; + vector4.Z = value1.Z + (value2.Z - value1.Z) * amount; + vector4.W = value1.W + (value2.W - value1.W) * amount; + return vector4; + } + + static Vector4 CatmullRom(Vector4 const& value1, Vector4 const& value2, Vector4 const& value3, Vector4 const& value4, float amount) { + const auto num1 = amount * amount; + const auto num2 = amount * num1; + Vector4 vector4; + vector4.X = 0.5F * (2.0f * value2.X + (-value1.X + value3.X) * amount + (2.0F * value1.X - 5.0f * value2.X + 4.0f * value3.X - value4.X) * num1 + (-value1.X + 3.0f * value2.X - 3.0f * value3.X + value4.X) * num2); + vector4.Y = 0.5F * (2.0f * value2.Y + (-value1.Y + value3.Y) * amount + (2.0F * value1.Y - 5.0f * value2.Y + 4.0f * value3.Y - value4.Y) * num1 + (-value1.Y + 3.0f * value2.Y - 3.0f * value3.Y + value4.Y) * num2); + vector4.Z = 0.5F * (2.0f * value2.Z + (-value1.Z + value3.Z) * amount + (2.0F * value1.Z - 5.0f * value2.Z + 4.0f * value3.Z - value4.Z) * num1 + (-value1.Z + 3.0f * value2.Z - 3.0f * value3.Z + value4.Z) * num2); + vector4.W = 0.5F * (2.0f * value2.W + (-value1.W + value3.W) * amount + (2.0F * value1.W - 5.0f * value2.W + 4.0f * value3.W - value4.W) * num1 + (-value1.W + 3.0f * value2.W - 3.0f * value3.W + value4.W) * num2); + return vector4; + } + + static Vector4 Hermite(Vector4 const& value1, Vector4 const& tangent1, Vector4 const& value2, Vector4 const& tangent2, float amount) { + const auto num1 = amount * amount; + const auto num2 = amount * num1; + const auto num3 = (2.0F * num2 - 3.0F * num1 + 1.0F); + const auto num4 = (-2.0F * num2 + 3.0F * num1); + const auto num5 = num2 - 2.0f * num1 + amount; + const auto num6 = num2 - num1; + Vector4 vector4; + vector4.X = (value1.X * num3 + value2.X * num4 + tangent1.X * num5 + tangent2.X * num6); + vector4.Y = (value1.Y * num3 + value2.Y * num4 + tangent1.Y * num5 + tangent2.Y * num6); + vector4.Z = (value1.Z * num3 + value2.Z * num4 + tangent1.Z * num5 + tangent2.Z * num6); + vector4.W = (value1.W * num3 + value2.W * num4 + tangent1.W * num5 + tangent2.W * num6); + return vector4; + } + + static constexpr Vector4 Transform(Vector2 const& position, Matrix const& matrix); + static constexpr Vector4 Transform(Vector3 const& position, Matrix const& matrix); + static constexpr Vector4 Transform(Vector4 const& vector, Matrix const& matrix); + static constexpr Vector4 Transform(Vector2 const& value, Quaternion const& rotation); + static constexpr Vector4 Transform(Vector3 const& value, Quaternion const& rotation); + static bool Transform(Vector4 const* sourceArray, size_t sourceLength, Matrix const& matrix, Vector4* destinationArray, size_t destinationLength); + static bool Transform(std::vector const& sourceArray, size_t sourceLength, Matrix const& matrix, std::vector& destinationArray); + static bool Transform(Vector4 const* sourceArray, size_t sourceLength, size_t sourceIndex, Matrix const& matrix, Vector4* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length); + static bool Transform(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length); + static bool Transform(Vector4 const* sourceArray, size_t sourceLength, Quaternion const& rotation, Vector4* destinationArray, size_t destinationLength); + static bool Transform(std::vector const& sourceArray, Quaternion const& rotation, std::vector& destinationArray); + static bool Transform(Vector4 const* sourceArray, size_t sourceLength, size_t sourceIndex, Quaternion const& rotation, Vector4* destinationArray, size_t destinationLength, size_t destinationIndex, size_t length); + static bool Transform(std::vector const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector& destinationArray, size_t destinationIndex, size_t length); + + static constexpr Vector4 Negate(Vector4 const& value) { + Vector4 vector4; + vector4.X = -value.X; + vector4.Y = -value.Y; + vector4.Z = -value.Z; + vector4.W = -value.W; + return vector4; + } + + static constexpr Vector4 Add(Vector4 const& value1, Vector4 const& value2) { + Vector4 vector4; + vector4.X = value1.X + value2.X; + vector4.Y = value1.Y + value2.Y; + vector4.Z = value1.Z + value2.Z; + vector4.W = value1.W + value2.W; + return vector4; + } + + static constexpr Vector4 Subtract(Vector4 const& value1, Vector4 const& value2) { + Vector4 vector4; + vector4.X = value1.X - value2.X; + vector4.Y = value1.Y - value2.Y; + vector4.Z = value1.Z - value2.Z; + vector4.W = value1.W - value2.W; + return vector4; + } + + static constexpr Vector4 Multiply(Vector4 const& value1, Vector4 const& value2) + { + Vector4 vector4; + vector4.X = value1.X * value2.X; + vector4.Y = value1.Y * value2.Y; + vector4.Z = value1.Z * value2.Z; + vector4.W = value1.W * value2.W; + return vector4; + } + + + static constexpr Vector4 Multiply(Vector4 const& value1, float scaleFactor) + { + Vector4 vector4; + vector4.X = value1.X * scaleFactor; + vector4.Y = value1.Y * scaleFactor; + vector4.Z = value1.Z * scaleFactor; + vector4.W = value1.W * scaleFactor; + return vector4; + } + + static constexpr Vector4 Divide(Vector4 const& value1, Vector4 const& value2) + { + Vector4 vector4; + vector4.X = value1.X / value2.X; + vector4.Y = value1.Y / value2.Y; + vector4.Z = value1.Z / value2.Z; + vector4.W = value1.W / value2.W; + return vector4; + } + + static constexpr Vector4 Divide(Vector4 const& value1, float divider) + { + float num = 1.0f / divider; + Vector4 vector4; + vector4.X = value1.X * num; + vector4.Y = value1.Y * num; + vector4.Z = value1.Z * num; + vector4.W = value1.W * num; + return vector4; + } + + constexpr Vector4 operator-() const { + return Vector4::Negate(*this); + } + + friend constexpr Vector4 operator+(Vector4 const& value1, Vector4 const& value2) { + return Vector4::Add(value1, value2); + } + + friend constexpr Vector4 operator-(Vector4 const& value1, Vector4 const& value2) { + return Vector4::Subtract(value1, value2); + } + + friend constexpr Vector4 operator*(Vector4 const& value1, Vector4 const& value2) { + return Vector4::Multiply(value1, value2); + } + + friend constexpr Vector4 operator*(Vector4 const& value, float factor) { + return Vector4::Multiply(value, factor); + } + + friend constexpr Vector4 operator*(float factor, Vector4 const& value) { + return Vector4::Multiply(value, factor); + } + + friend constexpr Vector4 operator/(Vector4 const& value1, Vector4 const& value2) { + return Vector4::Divide(value1, value2); + } + + friend constexpr Vector4 operator/(Vector4 const& value, float divider) { + return Vector4::Divide(value, divider); + } + + friend constexpr Vector4 operator/(float divider, Vector4 const& value) { + return Vector4::Divide(value, divider); + } }; } diff --git a/framework/content/defaultreaders.hpp b/framework/content/defaultreaders.hpp new file mode 100644 index 0000000..9684f5b --- /dev/null +++ b/framework/content/defaultreaders.hpp @@ -0,0 +1,38 @@ +#ifndef XNA_CONTENT_DEFAULTREADERS_ARRAY_HPP +#define XNA_CONTENT_DEFAULTREADERS_ARRAY_HPP + +#include "reader.hpp" +#include "../default.hpp" + +namespace xna { + template + class ArrayReader : public ContentTypeReaderT> { + public: + void Initialize(sptr const& manager) { + elementReader = manager->GetTypeReader(typeof()); + } + + sptr> Read(ContentReader& input, std::vector& existingInstance) override { + const auto length = input.ReadInt32(); + std::vector objArray(length); + + for (size_t index = 0; index < length; ++index) + objArray[index] = input.ReadObject(elementReader); + + return objArray; + } + + private: + sptr elementReader = nullptr; + }; + + class BooleanReader : public ContentTypeReaderT { + sptr Read(ContentReader& input, bool& existingInstance) override { + auto value = input.ReadBoolean(); + auto b = New(value); + return b; + } + }; +} + +#endif \ No newline at end of file diff --git a/framework/content/reader.hpp b/framework/content/reader.hpp index 8804308..5a8e402 100644 --- a/framework/content/reader.hpp +++ b/framework/content/reader.hpp @@ -25,6 +25,12 @@ namespace xna { template sptr ReadObject(T existingInstance); + template + sptr ReadObject(ContentTypeReader& typeReader); + + template + sptr ReadObject(ContentTypeReader& typeReader, T existingInstance); + Vector2 ReadVector2(); Vector3 ReadVector3(); Vector4 ReadVector4(); @@ -46,6 +52,9 @@ namespace xna { template sptr ReadObjectInternal(std::any& existingInstance, xna_error_nullarg); + + template + sptr ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_nullarg); template sptr InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg); @@ -102,7 +111,6 @@ namespace xna { { const auto sharedResourceCount = ReadHeader(); auto obj = ReadObject(); - //this.ReadSharedResources(sharedResourceCount); return obj; } @@ -118,6 +126,27 @@ namespace xna { { return ReadObjectInternal(std::any(existingInstance)); } + + template + inline sptr ContentReader::ReadObject(ContentTypeReader& typeReader) + { + auto obj = std::any(); + return ReadObjectInternal(typeReader, obj); + } + + template + inline sptr ContentReader::ReadObject(ContentTypeReader& typeReader, T existingInstance) + { + return ReadObjectInternal(typeReader, std::any(existingInstance)); + } + + template + inline sptr ContentReader::ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_ptr_arg) + { + return typeReader.TargetIsValueType + ? InvokeReader(typeReader, existingInstance, err) + : ReadObjectInternal(existingInstance, err); + } } #endif \ No newline at end of file diff --git a/framework/content/typereadermanager.hpp b/framework/content/typereadermanager.hpp index 12342a9..d9f230a 100644 --- a/framework/content/typereadermanager.hpp +++ b/framework/content/typereadermanager.hpp @@ -15,7 +15,7 @@ namespace xna { public: virtual Int TypeVersion() { return 0; } virtual bool CanDeserializeIntoExistingObject() { return false; } - virtual void Initialize(sptr& manager) {} + virtual void Initialize(sptr const& manager) {} sptr TargetType() { return _targetType; } virtual std::any Read(ContentReader& input, std::any& existingInstance) = 0; diff --git a/framework/platform/content-readers/texture2Dreader-dx.hpp b/framework/platform/content-readers/texture2Dreader-dx.hpp index 02dbedf..7ad93f7 100644 --- a/framework/platform/content-readers/texture2Dreader-dx.hpp +++ b/framework/platform/content-readers/texture2Dreader-dx.hpp @@ -1,10 +1,10 @@ #ifndef XNA_PLATFORM_CONTENTREADERS_TEXTURE2D_HPP #define XNA_PLATFORM_CONTENTREADERS_TEXTURE2D_HPP -#include "../../content/reader.hpp" -#include "../texture-dx.hpp" #include "../../content/manager.hpp" +#include "../../content/reader.hpp" #include "../../csharp/type.hpp" +#include "../texture-dx.hpp" namespace xna { class Texture2DReader : public ContentTypeReaderT { @@ -18,7 +18,10 @@ namespace xna { const auto mipMaps = input.ReadInt32(); auto a_device = ContentManager::Services()->GetService(*typeof()); - auto device = std::any_cast>(a_device); + sptr device = nullptr; + + if(a_device.has_value()) + device = std::any_cast>(a_device); auto texture2D = New(device, width, height, mipMaps, format); @@ -26,7 +29,7 @@ namespace xna { auto elementCount = input.ReadInt32(); std::vector data = input.ReadByteBuffer(elementCount); - texture2D->SetData(level, nullptr, data, 0, elementCount); + texture2D->SetData(static_cast(level), nullptr, data, 0, elementCount); } return texture2D; From a7839de84f314bd6342d1c4021fab67993736981 Mon Sep 17 00:00:00 2001 From: Danilo Date: Wed, 8 May 2024 09:16:17 -0300 Subject: [PATCH 12/17] Implementa MathHelper --- framework/CMakeLists.txt | 2 +- framework/common/color.cpp | 5 +++++ framework/common/math.hpp | 45 +++++++++++++++++++++++++++++++++++-- framework/common/matrix.cpp | 2 +- 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 framework/common/color.cpp diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 8307a7f..1170c0e 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -39,7 +39,7 @@ add_executable (xna WIN32 "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" "csharp/type.cpp" "platform/init-dx.cpp" "game/servicecontainer.cpp") +"content/decstream.cpp" "content/lzx/decoder.cpp" "content/lzx/decoderstream.cpp" "content/typereadermanager.cpp" "csharp/object.cpp" "csharp/type.cpp" "platform/init-dx.cpp" "game/servicecontainer.cpp" "common/color.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/common/color.cpp b/framework/common/color.cpp new file mode 100644 index 0000000..c25e283 --- /dev/null +++ b/framework/common/color.cpp @@ -0,0 +1,5 @@ +#include "color.hpp" + +namespace xna { + +} \ No newline at end of file diff --git a/framework/common/math.hpp b/framework/common/math.hpp index a417d1f..452d28d 100644 --- a/framework/common/math.hpp +++ b/framework/common/math.hpp @@ -2,6 +2,7 @@ #define XNA_COMMON_MATH_HPP #include +#include namespace xna { struct MathHelper { @@ -9,9 +10,49 @@ namespace xna { static constexpr double PI = 3.1415926535897931; static constexpr double TAU = 6.2831853071795862; static constexpr double EPSILON = std::numeric_limits::epsilon(); - }; - using Math = MathHelper; + static constexpr float ToRadians(float degrees) { return degrees * (static_cast(PI) / 180.0f); } + static constexpr float ToDegrees(float radians) { return radians * 57.2957764F; } + static float Distance(float value1, float value2) { return std::abs(value1 - value2); } + static float Min(float value1, float value2) { return (std::min)(value1, value2); } + static float Max(float value1, float value2) { return (std::max)(value1, value2); } + + static constexpr float Clamp(float value, float min, float max) { + value = value > max ? max : value; + value = value < min ? min : value; + return value; + } + + static constexpr float Lerp(float value1, float value2, float amount) { + return value1 + (value2 - value1) * amount; + } + + static constexpr float Barycentric(float value1, float value2, float value3, float amount1, float amount2) { + return value1 + amount1 * (value2 - value1) + amount2 * (value3 - value1); + } + + static constexpr float SmoothStep(float value1, float value2, float amount) { + const auto num = Clamp(amount, 0.0f, 1.0f); + return Lerp(value1, value2, (num * num * (3.0F - 2.0F * num))); + } + + static float CatmullRom(float value1, float value2, float value3, float value4, float amount) { + const auto num1 = amount * amount; + const auto num2 = amount * num1; + return (0.5F * (2.0F * value2 + (-value1 + value3) * amount + (2.0F * value1 - 5.0F * value2 + 4.0F * value3 - value4) * num1 + (-value1 + 3.0F * value2 - 3.0F * value3 + value4) * num2)); + } + + static float Hermite(float value1, float tangent1, float value2, float tangent2, float amount) { + const auto num1 = amount; + const auto num2 = num1 * num1; + const auto num3 = num1 * num2; + const auto num4 = (2.0F * num3 - 3.0F * num2 + 1.0F); + const auto num5 = (-2.0F * num3 + 3.0F * num2); + const auto num6 = num3 - 2.0f * num2 + num1; + const auto num7 = num3 - num2; + return value1 * num4 + value2 * num5 + tangent1 * num6 + tangent2 * num7; + } + }; } #endif \ No newline at end of file diff --git a/framework/common/matrix.cpp b/framework/common/matrix.cpp index b2bcf1f..bcd2621 100644 --- a/framework/common/matrix.cpp +++ b/framework/common/matrix.cpp @@ -212,7 +212,7 @@ namespace xna { } Matrix Matrix::CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance) { - if (fieldOfView <= 0.0 || fieldOfView >= Math::PI || nearPlaneDistance <= 0.0 || farPlaneDistance <= 0.0 || nearPlaneDistance >= farPlaneDistance) { + if (fieldOfView <= 0.0 || fieldOfView >= MathHelper::PI || nearPlaneDistance <= 0.0 || farPlaneDistance <= 0.0 || nearPlaneDistance >= farPlaneDistance) { return Matrix(); } From 0c5d3af199e7485149179e2e9941b5903236a21c Mon Sep 17 00:00:00 2001 From: Danilo Date: Wed, 8 May 2024 10:51:49 -0300 Subject: [PATCH 13/17] =?UTF-8?q?Modifica=C3=A7=C3=B5es=20em=20Content.Loa?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/content/defaultreaders.hpp | 4 +- framework/content/manager.hpp | 12 ++--- framework/content/reader.hpp | 45 ++++++++++--------- framework/content/typereadermanager.hpp | 6 +-- framework/forward.hpp | 3 ++ .../content-readers/texture2Dreader-dx.hpp | 4 +- framework/platform/init-dx.cpp | 8 ++-- framework/xna.cpp | 10 ++++- 8 files changed, 51 insertions(+), 41 deletions(-) diff --git a/framework/content/defaultreaders.hpp b/framework/content/defaultreaders.hpp index 9684f5b..7579941 100644 --- a/framework/content/defaultreaders.hpp +++ b/framework/content/defaultreaders.hpp @@ -12,7 +12,7 @@ namespace xna { elementReader = manager->GetTypeReader(typeof()); } - sptr> Read(ContentReader& input, std::vector& existingInstance) override { + std::vector Read(ContentReader& input, std::vector& existingInstance) override { const auto length = input.ReadInt32(); std::vector objArray(length); @@ -27,7 +27,7 @@ namespace xna { }; class BooleanReader : public ContentTypeReaderT { - sptr Read(ContentReader& input, bool& existingInstance) override { + bool Read(ContentReader& input, bool& existingInstance) override { auto value = input.ReadBoolean(); auto b = New(value); return b; diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index 45ce5f1..b70a927 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -43,26 +43,26 @@ namespace xna { } template - sptr Load(String const& assetName) { - if (assetName.empty()) return nullptr; + T Load(String const& assetName) { + if (assetName.empty()) return T(); - if (_loadedAssets.contains(assetName)) { + /*if (_loadedAssets.contains(assetName)) { auto& ptr = _loadedAssets[assetName]; auto obj1 = reinterpret_pointer_cast(ptr); return obj1; - } + }*/ auto obj2 = ReadAsset(assetName); //auto voidAsset = reinterpret_pointer_cast(obj2); - _loadedAssets.insert({ assetName , obj2 }); + //_loadedAssets.insert({ assetName , obj2 }); return obj2; } protected: template - sptr ReadAsset(String const& assetName) { + T ReadAsset(String const& assetName) { auto input = OpenStream(assetName); auto contentReader = ContentReader::Create(this, input, assetName); diff --git a/framework/content/reader.hpp b/framework/content/reader.hpp index 5a8e402..f953d5f 100644 --- a/framework/content/reader.hpp +++ b/framework/content/reader.hpp @@ -17,19 +17,19 @@ namespace xna { static sptr Create(ContentManager* contentManager, sptr& input, String const& assetName); template - sptr ReadAsset(); + T ReadAsset(); template - sptr ReadObject(); + T ReadObject(); template - sptr ReadObject(T existingInstance); + T ReadObject(T existingInstance); template - sptr ReadObject(ContentTypeReader& typeReader); + T ReadObject(ContentTypeReader& typeReader); template - sptr ReadObject(ContentTypeReader& typeReader, T existingInstance); + T ReadObject(ContentTypeReader& typeReader, T existingInstance); Vector2 ReadVector2(); Vector3 ReadVector3(); @@ -51,13 +51,13 @@ namespace xna { Int ReadHeader(); template - sptr ReadObjectInternal(std::any& existingInstance, xna_error_nullarg); + T ReadObjectInternal(std::any& existingInstance, xna_error_nullarg); template - sptr ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_nullarg); + T ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_nullarg); template - sptr InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg); + T InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg); private: ContentManager* _contentManager = nullptr; @@ -72,19 +72,20 @@ namespace xna { }; template - inline sptr ContentReader::ReadObjectInternal(std::any& existingInstance, xna_error_ptr_arg) + inline T ContentReader::ReadObjectInternal(std::any& existingInstance, xna_error_ptr_arg) { const auto num = Read7BitEncodedInt(); if (num == 0) { - return New(); + return T(); } const auto index = num - 1; if (index >= typeReaders.size()) { xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE); - return New(); + + return T(); } auto reader = typeReaders[index]; @@ -92,22 +93,22 @@ namespace xna { } template - inline sptr ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_ptr_arg) + inline T ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_ptr_arg) { auto contentTypeReader = reinterpret_cast*>(&reader); - sptr objB = nullptr; + T objB; if (contentTypeReader) { - auto existingInstance1 = existingInstance.has_value() ? std::any_cast>(existingInstance) : nullptr; - objB = contentTypeReader->Read(*this, *existingInstance1); + auto existingInstance1 = existingInstance.has_value() ? std::any_cast(existingInstance) : T(); + objB = contentTypeReader->Read(*this, existingInstance1); return objB; } - return New(); + return T(); } template - inline sptr ContentReader::ReadAsset() + inline T ContentReader::ReadAsset() { const auto sharedResourceCount = ReadHeader(); auto obj = ReadObject(); @@ -115,33 +116,33 @@ namespace xna { } template - inline sptr ContentReader::ReadObject() + inline T ContentReader::ReadObject() { auto a = std::any(); return ReadObjectInternal(a); } template - inline sptr ContentReader::ReadObject(T existingInstance) + inline T ContentReader::ReadObject(T existingInstance) { return ReadObjectInternal(std::any(existingInstance)); } template - inline sptr ContentReader::ReadObject(ContentTypeReader& typeReader) + inline T ContentReader::ReadObject(ContentTypeReader& typeReader) { auto obj = std::any(); return ReadObjectInternal(typeReader, obj); } template - inline sptr ContentReader::ReadObject(ContentTypeReader& typeReader, T existingInstance) + inline T ContentReader::ReadObject(ContentTypeReader& typeReader, T existingInstance) { return ReadObjectInternal(typeReader, std::any(existingInstance)); } template - inline sptr ContentReader::ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_ptr_arg) + inline T ContentReader::ReadObjectInternal(ContentTypeReader& typeReader, std::any& existingInstance, xna_error_ptr_arg) { return typeReader.TargetIsValueType ? InvokeReader(typeReader, existingInstance, err) diff --git a/framework/content/typereadermanager.hpp b/framework/content/typereadermanager.hpp index d9f230a..fcf5553 100644 --- a/framework/content/typereadermanager.hpp +++ b/framework/content/typereadermanager.hpp @@ -41,7 +41,7 @@ namespace xna { return std::any(); } - virtual sptr Read(ContentReader& input, T& existingInstance) = 0; + virtual T Read(ContentReader& input, T& existingInstance) = 0; }; //-------------------------------------------------------// @@ -175,8 +175,8 @@ namespace xna { }); } - virtual sptr Read(ContentReader& input, Object& existingInstance) override { - return nullptr; + virtual Object Read(ContentReader& input, Object& existingInstance) override { + return Object(); } }; } diff --git a/framework/forward.hpp b/framework/forward.hpp index dd6f930..3085424 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -88,6 +88,9 @@ namespace xna { struct GamePadState; struct KeyboardState; struct MouseState; + + //Pointer + using PTexture2D = std::shared_ptr; } #endif \ No newline at end of file diff --git a/framework/platform/content-readers/texture2Dreader-dx.hpp b/framework/platform/content-readers/texture2Dreader-dx.hpp index 7ad93f7..7bff5bc 100644 --- a/framework/platform/content-readers/texture2Dreader-dx.hpp +++ b/framework/platform/content-readers/texture2Dreader-dx.hpp @@ -7,11 +7,11 @@ #include "../texture-dx.hpp" namespace xna { - class Texture2DReader : public ContentTypeReaderT { + class Texture2DReader : public ContentTypeReaderT { public: Texture2DReader() : ContentTypeReaderT(typeof()){} - sptr Read(ContentReader& input, Texture2D& existingInstance) override{ + PTexture2D Read(ContentReader& input, PTexture2D& existingInstance) override{ const auto format = static_cast(input.ReadInt32()); const auto width = input.ReadInt32(); const auto height = input.ReadInt32(); diff --git a/framework/platform/init-dx.cpp b/framework/platform/init-dx.cpp index c822e88..1634626 100644 --- a/framework/platform/init-dx.cpp +++ b/framework/platform/init-dx.cpp @@ -10,9 +10,9 @@ namespace xna { Type::NameOfRegisteredTypes.insert({ "Texture2D", typeof() }); //Texture2DReader - Type::NameOfRegisteredTypes.insert({ "Texture2DReader", typeof() }); - Type::NameOfRegisteredTypes.insert({ "xna::Texture2DReader", typeof() }); - Type::NameOfRegisteredTypes.insert({ "Microsoft.Xna.Framework.Content.Texture2DReader", typeof() }); + const auto textureReader = typeof(); + Type::NameOfRegisteredTypes.insert({ "xna::Texture2DReader", textureReader }); + Type::NameOfRegisteredTypes.insert({ "Microsoft.Xna.Framework.Content.Texture2DReader", textureReader }); } void InitPlatform::InitActivadors() @@ -25,6 +25,6 @@ namespace xna { ContentTypeReaderActivador::SetActivador(typeof(), []() -> sptr { auto obj = New (); return reinterpret_pointer_cast(obj); - }); + }); } } \ No newline at end of file diff --git a/framework/xna.cpp b/framework/xna.cpp index 8107cf6..7f12728 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -28,6 +28,9 @@ namespace xna { void LoadContent() override { spriteBatch = New(*graphicsDevice); + texture = Content()->Load("idle"); + //Texture2D texture = Content()->Load("idle"); + Game::LoadContent(); } @@ -39,9 +42,11 @@ namespace xna { } void Draw(GameTime const& gameTime) override { - graphicsDevice->Clear(Colors::CornflowerBlue); + graphicsDevice->Clear(Colors::CornflowerBlue); - + spriteBatch->Begin(); + spriteBatch->Draw(*texture, Vector2(10, 10), Colors::White); + spriteBatch->End(); Game::Draw(gameTime); } @@ -49,6 +54,7 @@ namespace xna { private: sptr graphics = nullptr; sptr spriteBatch = nullptr; + PTexture2D texture = nullptr; }; } From 77c6c401155541db6d906509d42404750e5ebaa8 Mon Sep 17 00:00:00 2001 From: Danilo Date: Wed, 8 May 2024 11:07:00 -0300 Subject: [PATCH 14/17] Finaliza LzxDecoder --- framework/content/lzx/decoder.hpp | 142 +++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 2 deletions(-) diff --git a/framework/content/lzx/decoder.hpp b/framework/content/lzx/decoder.hpp index e93be4a..5c44679 100644 --- a/framework/content/lzx/decoder.hpp +++ b/framework/content/lzx/decoder.hpp @@ -637,11 +637,149 @@ namespace xna { LzxState m_state; Int MakeDecodeTable(Uint nsyms, Uint nbits, std::vector& length, std::vector& table) { + Ushort sym = 0; + Uint leaf = 0; + Byte bit_num = 1; + Uint fill; + Uint pos = 0; /* the current position in the decode table */ + Uint table_mask = static_cast(1 << static_cast(nbits)); + Uint bit_mask = table_mask >> 1; /* don't do 0 length codes */ + Uint next_symbol = bit_mask; /* base of allocation for long codes */ + + /* fill entries for codes short enough for a direct mapping */ + while (bit_num <= nbits) + { + for (sym = 0; sym < nsyms; sym++) + { + if (length[sym] == bit_num) + { + leaf = pos; + + if ((pos += bit_mask) > table_mask) return 1; /* table overrun */ + + /* fill all possible lookups of this symbol with the symbol itself */ + fill = bit_mask; + while (fill-- > 0) table[leaf++] = sym; + } + } + bit_mask >>= 1; + bit_num++; + } + + /* if there are any codes longer than nbits */ + if (pos != table_mask) + { + /* clear the remainder of the table */ + for (sym = static_cast(pos); + sym < table_mask; sym++) table[sym] = 0; + + /* give ourselves room for codes to grow by up to 16 more bits */ + pos <<= 16; + table_mask <<= 16; + bit_mask = 1 << 15; + + while (bit_num <= 16) + { + for (sym = 0; sym < nsyms; sym++) + { + if (length[sym] == bit_num) + { + leaf = pos >> 16; + for (fill = 0; fill < bit_num - nbits; fill++) + { + /* if this path hasn't been taken yet, 'allocate' two entries */ + if (table[leaf] == 0) + { + table[(next_symbol << 1)] = 0; + table[(next_symbol << 1) + 1] = 0; + table[leaf] = static_cast(next_symbol++); + } + /* follow the path and select either left or right for next bit */ + leaf = static_cast(table[leaf] << 1); + if (((pos >> static_cast(15 - fill)) & 1) == 1) leaf++; + } + table[leaf] = sym; + + if ((pos += bit_mask) > table_mask) return 1; + } + } + bit_mask >>= 1; + bit_num++; + } + } + + /* full talbe? */ + if (pos == table_mask) return 0; + + /* either erroneous table, or all elements are 0 - let's find out. */ + for (sym = 0; sym < nsyms; sym++) if (length[sym] != 0) return 1; return 0; } - void ReadLengths(std::vector const& lens, Uint first, Uint last, BitBuffer& bitbuf) {} + void ReadLengths(std::vector& lens, Uint first, Uint last, BitBuffer& bitbuf) { + Uint x = 0; + Uint y = 0; + Int z = 0; + + // hufftbl pointer here? + + for (x = 0; x < 20; x++) + { + y = bitbuf.ReadBits(4); + m_state.PRETREE_len[x] = static_cast(y); + } + + MakeDecodeTable(LzxConstants::PRETREE_MAXSYMBOLS, LzxConstants::PRETREE_TABLEBITS, + m_state.PRETREE_len, m_state.PRETREE_table); + + for (x = first; x < last;) + { + z = (int)ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len, + LzxConstants::PRETREE_MAXSYMBOLS, LzxConstants::PRETREE_TABLEBITS, bitbuf); + if (z == 17) + { + y = bitbuf.ReadBits(4); y += 4; + while (y-- != 0) lens[x++] = 0; + } + else if (z == 18) + { + y = bitbuf.ReadBits(5); y += 20; + while (y-- != 0) lens[x++] = 0; + } + else if (z == 19) + { + y = bitbuf.ReadBits(1); y += 4; + z = static_cast(ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len, + LzxConstants::PRETREE_MAXSYMBOLS, LzxConstants::PRETREE_TABLEBITS, bitbuf)); + z = lens[x] - z; if (z < 0) z += 17; + while (y-- != 0) lens[x++] = static_cast(z); + } + else + { + z = lens[x] - z; if (z < 0) z += 17; + lens[x++] = static_cast(z); + } + } + } + Uint ReadHuffSym(std::vector& table, std::vector& lengths, Uint nsyms, Uint nbits, BitBuffer& bitbuf) { - return 0; + Uint i = 0; + Uint j = 0; + + bitbuf.EnsureBits(16); + + if ((i = table[bitbuf.PeekBits(static_cast(nbits))]) >= nsyms) + { + j = static_cast(1 << static_cast((sizeof(Uint) * 8) - nbits)); + do + { + j >>= 1; i <<= 1; i |= (bitbuf.GetBuffer() & j) != 0 ? static_cast(1) : 0; + if (j == 0) return 0; // TODO throw proper exception + } while ((i = table[i]) >= nsyms); + } + j = lengths[i]; + bitbuf.RemoveBits(static_cast(j)); + + return i; } }; } From caa9958e9e13bcbddf3f8a435a74669ecf3a0b56 Mon Sep 17 00:00:00 2001 From: Danilo Date: Wed, 8 May 2024 20:42:15 -0300 Subject: [PATCH 15/17] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20em=20init-dx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/content/defaultreaders.hpp | 223 ++++++++++++++++++++++-- framework/content/manager.hpp | 33 +--- framework/content/typereadermanager.cpp | 1 + framework/content/typereadermanager.hpp | 33 +--- framework/csharp/stream.hpp | 4 +- framework/platform/init-dx.cpp | 64 +++++-- framework/platform/init-dx.hpp | 18 ++ framework/xna.cpp | 3 +- 8 files changed, 283 insertions(+), 96 deletions(-) diff --git a/framework/content/defaultreaders.hpp b/framework/content/defaultreaders.hpp index 7579941..376bb58 100644 --- a/framework/content/defaultreaders.hpp +++ b/framework/content/defaultreaders.hpp @@ -3,36 +3,221 @@ #include "reader.hpp" #include "../default.hpp" +#include "../common/color.hpp" +#include "../common/matrix.hpp" +#include "../common/point.hpp" +#include "../common/rectangle.hpp" +#include "../csharp/timespan.hpp" namespace xna { - template - class ArrayReader : public ContentTypeReaderT> { + class ObjectReader : public ContentTypeReaderT { public: - void Initialize(sptr const& manager) { - elementReader = manager->GetTypeReader(typeof()); + ObjectReader() : ContentTypeReaderT(typeof()) {} + + virtual Object Read(ContentReader& input, Object& existingInstance) override { + return Object(); } - - std::vector Read(ContentReader& input, std::vector& existingInstance) override { - const auto length = input.ReadInt32(); - std::vector objArray(length); - - for (size_t index = 0; index < length; ++index) - objArray[index] = input.ReadObject(elementReader); - - return objArray; - } - - private: - sptr elementReader = nullptr; }; class BooleanReader : public ContentTypeReaderT { + public: + BooleanReader() : ContentTypeReaderT(typeof()) {} + bool Read(ContentReader& input, bool& existingInstance) override { - auto value = input.ReadBoolean(); - auto b = New(value); + return input.ReadBoolean(); + } + }; + + class ByteReader : public ContentTypeReaderT { + public: + ByteReader() : ContentTypeReaderT(typeof()) {} + + Byte Read(ContentReader& input, Byte& existingInstance) override { + const auto b = input.ReadByte(); return b; } }; + + class CharReader : public ContentTypeReaderT { + public: + CharReader() : ContentTypeReaderT(typeof()) {} + + Char Read(ContentReader& input, Char& existingInstance) override { + const auto b = input.ReadChar(); + return b; + } + }; + + class ColorReader : public ContentTypeReaderT { + public: + ColorReader() : ContentTypeReaderT(typeof()) {} + + Color Read(ContentReader& input, Color& existingInstance) override { + const auto i = input.ReadUInt32(); + return { i }; + } + }; + + class DoubleReader : public ContentTypeReaderT { + public: + DoubleReader() : ContentTypeReaderT(typeof()) {} + + double Read(ContentReader& input, double& existingInstance) override { + return input.ReadDouble(); + } + }; + + class Int16Reader : public ContentTypeReaderT { + public: + Int16Reader() : ContentTypeReaderT(typeof()) {} + + Short Read(ContentReader& input, Short& existingInstance) override { + return input.ReadInt16(); + } + }; + + class Int32Reader : public ContentTypeReaderT { + public: + Int32Reader() : ContentTypeReaderT(typeof()) {} + + Int Read(ContentReader& input, Int& existingInstance) override { + return input.ReadInt32(); + } + }; + + class Int64Reader : public ContentTypeReaderT { + public: + Int64Reader() : ContentTypeReaderT(typeof()) {} + + Long Read(ContentReader& input, Long& existingInstance) override { + return input.ReadInt64(); + } + }; + + class MatrixReader : public ContentTypeReaderT { + public: + MatrixReader() : ContentTypeReaderT(typeof()) {} + + Matrix Read(ContentReader& input, Matrix& existingInstance) override { + return input.ReadMatrix(); + } + }; + + class PointReader : public ContentTypeReaderT { + public: + PointReader() : ContentTypeReaderT(typeof()) {} + + Point Read(ContentReader& input, Point& existingInstance) override { + Point point; + point.X = input.ReadInt32(); + point.Y = input.ReadInt32(); + return point; + } + }; + + class QuaternionReader : public ContentTypeReaderT { + public: + QuaternionReader() : ContentTypeReaderT(typeof()) {} + + Quaternion Read(ContentReader& input, Quaternion& existingInstance) override { + return input.ReadQuaternion(); + } + }; + + class RectangleReader : public ContentTypeReaderT { + public: + RectangleReader() : ContentTypeReaderT(typeof()) {} + + Rectangle Read(ContentReader& input, Rectangle& existingInstance) override { + Rectangle rectangle; + rectangle.X = input.ReadInt32(); + rectangle.Y = input.ReadInt32(); + rectangle.Width = input.ReadInt32(); + rectangle.Height = input.ReadInt32(); + return rectangle; + } + }; + + class SByteReader : public ContentTypeReaderT { + public: + SByteReader() : ContentTypeReaderT(typeof()) {} + + Sbyte Read(ContentReader& input, Sbyte& existingInstance) override { + return input.ReadSByte(); + } + }; + + class SingleReader : public ContentTypeReaderT { + public: + SingleReader() : ContentTypeReaderT(typeof()) {} + + float Read(ContentReader& input, float& existingInstance) override { + return input.ReadSingle(); + } + }; + + class TimeSpanReader : public ContentTypeReaderT { + public: + TimeSpanReader() : ContentTypeReaderT(typeof()) {} + + TimeSpan Read(ContentReader& input, TimeSpan& existingInstance) override { + return TimeSpan::FromTicks(input.ReadInt64()); + } + }; + + class UInt16Reader : public ContentTypeReaderT { + public: + UInt16Reader() : ContentTypeReaderT(typeof()) {} + + Ushort Read(ContentReader& input, Ushort& existingInstance) override { + return input.ReadUInt16(); + } + }; + + class UInt32Reader : public ContentTypeReaderT { + public: + UInt32Reader() : ContentTypeReaderT(typeof()) {} + + Uint Read(ContentReader& input, Uint& existingInstance) override { + return input.ReadUInt32(); + } + }; + + class UInt64Reader : public ContentTypeReaderT { + public: + UInt64Reader() : ContentTypeReaderT(typeof()) {} + + Ulong Read(ContentReader& input, Ulong& existingInstance) override { + return input.ReadUInt64(); + } + }; + + class Vector2Reader : public ContentTypeReaderT { + public: + Vector2Reader() : ContentTypeReaderT(typeof()) {} + + Vector2 Read(ContentReader& input, Vector2& existingInstance) override { + return input.ReadVector2(); + } + }; + + class Vector3Reader : public ContentTypeReaderT { + public: + Vector3Reader() : ContentTypeReaderT(typeof()) {} + + Vector3 Read(ContentReader& input, Vector3& existingInstance) override { + return input.ReadVector3(); + } + }; + + class Vector4Reader : public ContentTypeReaderT { + public: + Vector4Reader() : ContentTypeReaderT(typeof()) {} + + Vector4 Read(ContentReader& input, Vector4& existingInstance) override { + return input.ReadVector4(); + } + }; } #endif \ No newline at end of file diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index b70a927..fd88fc6 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -3,11 +3,11 @@ #include "../csharp/stream.hpp" #include "../default.hpp" +#include "../game/servicecontainer.hpp" #include "reader.hpp" #include #include #include -#include "../game/servicecontainer.hpp" namespace xna { class ContentManager { @@ -17,11 +17,7 @@ namespace xna { ContentManager(String const& rootDirectory, sptr const& services) : _rootDirectory(rootDirectory){ _services = services; - }; - - virtual ~ContentManager(){ - Unload(); - } + }; static sptr Services() { return _services; @@ -35,30 +31,14 @@ namespace xna { _rootDirectory = value; } - virtual void Unload() { - if (_loadedAssets.empty()) - return; - - _loadedAssets.clear(); - } - template T Load(String const& assetName) { - if (assetName.empty()) return T(); - - /*if (_loadedAssets.contains(assetName)) { - auto& ptr = _loadedAssets[assetName]; - auto obj1 = reinterpret_pointer_cast(ptr); - - return obj1; - }*/ + if (assetName.empty()) return T(); auto obj2 = ReadAsset(assetName); - //auto voidAsset = reinterpret_pointer_cast(obj2); - //_loadedAssets.insert({ assetName , obj2 }); return obj2; - } + } protected: template @@ -76,11 +56,10 @@ namespace xna { } private: - String _rootDirectory; - std::map> _loadedAssets; - inline const static String contentExtension = ".xnb"; + String _rootDirectory; std::vector byteBuffer; + inline const static String contentExtension = ".xnb"; inline static sptr _services = nullptr; }; } diff --git a/framework/content/typereadermanager.cpp b/framework/content/typereadermanager.cpp index 25be7dd..488f5da 100644 --- a/framework/content/typereadermanager.cpp +++ b/framework/content/typereadermanager.cpp @@ -1,5 +1,6 @@ #include "typereadermanager.hpp" #include "reader.hpp" +#include "defaultreaders.hpp" namespace xna { std::vector ContentTypeReaderManager::ReadTypeManifest(Int typeCount, sptr& contentReader, xna_error_ptr_arg) diff --git a/framework/content/typereadermanager.hpp b/framework/content/typereadermanager.hpp index fcf5553..3da2683 100644 --- a/framework/content/typereadermanager.hpp +++ b/framework/content/typereadermanager.hpp @@ -42,18 +42,7 @@ namespace xna { } virtual T Read(ContentReader& input, T& existingInstance) = 0; - }; - - //-------------------------------------------------------// - // TypeComparator // - //-------------------------------------------------------// - struct TypeComparator - { - bool operator()(sptr t1, sptr t2) const - { - return t1->GetHashCode() < t2->GetHashCode(); - } - }; + }; //-------------------------------------------------------// // ContentTypeReaderActivador // @@ -94,7 +83,6 @@ namespace xna { } private: - //inline static auto activators = std::map(); inline static auto activators = std::map(); ContentTypeReaderActivador(); @@ -155,30 +143,11 @@ namespace xna { sptr contentReader = nullptr; inline static auto nameToReader = std::map(); - //inline static auto targetTypeToReader = std::map(); - //inline static auto readerTypeToReader = std::map(); inline static auto targetTypeToReader = std::map(); inline static auto readerTypeToReader = std::map(); static void initMaps(); }; - - //-------------------------------------------------------// - // ObjectReader // - //-------------------------------------------------------// - class ObjectReader : public ContentTypeReaderT { - public: - ObjectReader() : ContentTypeReaderT(typeof()) { - ContentTypeReaderActivador::SetActivador(typeof(this), []() -> sptr { - auto obj = New (); - return reinterpret_pointer_cast(obj); - }); - } - - virtual Object Read(ContentReader& input, Object& existingInstance) override { - return Object(); - } - }; } #endif \ No newline at end of file diff --git a/framework/csharp/stream.hpp b/framework/csharp/stream.hpp index 865eb73..bdf28a9 100644 --- a/framework/csharp/stream.hpp +++ b/framework/csharp/stream.hpp @@ -118,8 +118,10 @@ namespace xna { virtual void WriteByte(Byte value, xna_error_nullarg) override; public: - std::streampos _filesize{ 0 }; std::fstream _fstream; + + private: + std::streampos _filesize{ 0 }; bool _closed{ false }; Int endOfFile() { diff --git a/framework/platform/init-dx.cpp b/framework/platform/init-dx.cpp index 1634626..077d162 100644 --- a/framework/platform/init-dx.cpp +++ b/framework/platform/init-dx.cpp @@ -3,28 +3,62 @@ #include "texture-dx.hpp" #include "content-readers/texture2Dreader-dx.hpp" #include "../content/typereadermanager.hpp" +#include "../content/defaultreaders.hpp" namespace xna { + + void InitPlatform::InitRegisteredTypes() { - Type::NameOfRegisteredTypes.insert({ "Texture2D", typeof() }); - - //Texture2DReader - const auto textureReader = typeof(); - Type::NameOfRegisteredTypes.insert({ "xna::Texture2DReader", textureReader }); - Type::NameOfRegisteredTypes.insert({ "Microsoft.Xna.Framework.Content.Texture2DReader", textureReader }); + insertRegisteredReader("ObjecReader"); + insertRegisteredReader("BooleanReader"); + insertRegisteredReader("ByteReader"); + insertRegisteredReader("CharReader"); + insertRegisteredReader("ColorReader"); + insertRegisteredReader("DoubleReader"); + insertRegisteredReader("Int16Reader"); + insertRegisteredReader("Int32Reader"); + insertRegisteredReader("Int64Reader"); + insertRegisteredReader("MatrixReader"); + insertRegisteredReader("PointReader"); + insertRegisteredReader("QuaternionReader"); + insertRegisteredReader("RectangleReader"); + insertRegisteredReader("SByteReader"); + insertRegisteredReader("SingleReader"); + insertRegisteredReader("TimeSpanReader"); + insertRegisteredReader("UInt16Reader"); + insertRegisteredReader("UInt32Reader"); + insertRegisteredReader("UInt64Reader"); + insertRegisteredReader("Vector2Reader"); + insertRegisteredReader("Vector3Reader"); + insertRegisteredReader("Vector4Reader"); + insertRegisteredReader("Texture2DReader"); } void InitPlatform::InitActivadors() { - ContentTypeReaderActivador::SetActivador(typeof(), []() -> sptr { - auto obj = New (); - return reinterpret_pointer_cast(obj); - }); - - ContentTypeReaderActivador::SetActivador(typeof(), []() -> sptr { - auto obj = New (); - return reinterpret_pointer_cast(obj); - }); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); + insertActivadorReader(); } } \ No newline at end of file diff --git a/framework/platform/init-dx.hpp b/framework/platform/init-dx.hpp index eab6abf..29cacb7 100644 --- a/framework/platform/init-dx.hpp +++ b/framework/platform/init-dx.hpp @@ -2,6 +2,8 @@ #define XNA_PLATFORM_INIT_HPP #include "../default.hpp" +#include "../csharp/type.hpp" +#include "../content/typereadermanager.hpp" namespace xna { struct InitPlatform { @@ -12,6 +14,22 @@ namespace xna { static void InitRegisteredTypes(); static void InitActivadors(); + + private: + template + static void insertRegisteredReader(String const& readerName) { + const auto reader = typeof(); + Type::NameOfRegisteredTypes.insert({ "xna::" + readerName, reader }); + Type::NameOfRegisteredTypes.insert({ "Microsoft.Xna.Framework.Content." + readerName, reader }); + } + + template + static void insertActivadorReader() { + ContentTypeReaderActivador::SetActivador(typeof(), []() -> sptr { + auto obj = New (); + return reinterpret_pointer_cast(obj); + }); + } }; } diff --git a/framework/xna.cpp b/framework/xna.cpp index 7f12728..f7e5296 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -28,8 +28,7 @@ namespace xna { void LoadContent() override { spriteBatch = New(*graphicsDevice); - texture = Content()->Load("idle"); - //Texture2D texture = Content()->Load("idle"); + texture = Content()->Load("idlse"); Game::LoadContent(); } From 676df7e1502c20fb657623fc9af24d8cfdca7442 Mon Sep 17 00:00:00 2001 From: Danilo Date: Thu, 9 May 2024 09:13:26 -0300 Subject: [PATCH 16/17] =?UTF-8?q?Implementa=C3=A7=C3=B5es=20em=20Content?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/content/lzx/decoderstream.hpp | 1 + framework/content/manager.hpp | 7 ++- framework/csharp/stream.cpp | 4 +- framework/csharp/stream.hpp | 70 ++++++++++++++++++++++++- framework/enums.hpp | 9 ++++ framework/xna.cpp | 2 +- 6 files changed, 87 insertions(+), 6 deletions(-) diff --git a/framework/content/lzx/decoderstream.hpp b/framework/content/lzx/decoderstream.hpp index eac4f41..882a5bf 100644 --- a/framework/content/lzx/decoderstream.hpp +++ b/framework/content/lzx/decoderstream.hpp @@ -82,6 +82,7 @@ namespace xna { void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) override; void Write(std::vector const& buffer, Int offset, Int count, xna_error_nullarg) override; void WriteByte(Byte value, xna_error_nullarg) override; + virtual constexpr bool IsClosed() override { return false; } }; } diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index fd88fc6..a1a6ff7 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -44,6 +44,10 @@ namespace xna { template T ReadAsset(String const& assetName) { auto input = OpenStream(assetName); + + if (input->IsClosed()) + return T(); + auto contentReader = ContentReader::Create(this, input, assetName); return contentReader->ReadAsset(); @@ -51,7 +55,8 @@ namespace xna { sptr OpenStream(String const& assetName) { String filePath = _rootDirectory + "\\" + assetName + contentExtension; - const auto stream = New(filePath); + const auto stream = New(filePath, FileMode::Open); + //const auto stream = New(filePath); return reinterpret_pointer_cast(stream); } diff --git a/framework/csharp/stream.cpp b/framework/csharp/stream.cpp index 67089dc..39277df 100644 --- a/framework/csharp/stream.cpp +++ b/framework/csharp/stream.cpp @@ -165,7 +165,7 @@ namespace xna { return -1; } - if (_closed) + if (_closed || _truncated) return 0; auto _buff = reinterpret_cast(buffer); @@ -184,7 +184,7 @@ namespace xna { } Int FileStream::ReadByte(xna_error_ptr_arg){ - if (_closed) + if (_closed || _truncated) return 0; char c = 0; diff --git a/framework/csharp/stream.hpp b/framework/csharp/stream.hpp index bdf28a9..d41b8df 100644 --- a/framework/csharp/stream.hpp +++ b/framework/csharp/stream.hpp @@ -14,6 +14,7 @@ namespace xna { virtual Int Length() = 0; virtual Long Position() = 0; virtual void Close() = 0; + virtual bool IsClosed() = 0; virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) = 0; virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) = 0; virtual Int Read(std::vector& buffer, Int offset, Int count, xna_error_nullarg) = 0; @@ -48,6 +49,10 @@ namespace xna { _buffer = std::vector(); } + virtual constexpr bool IsClosed() override { + return _closed; + } + 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& buffer, Int offset, Int count, xna_error_nullarg) override; @@ -66,7 +71,63 @@ namespace xna { class FileStream : public Stream { public: - FileStream(std::string const& path){ + FileStream(String const& path, FileMode fileMode) { + int flags = std::fstream::in + | std::fstream::out + | std::fstream::binary; + + const auto exists = std::filesystem::exists(path); + + switch (fileMode) + { + //Especifica se deve abrir um arquivo existente. + case FileMode::Open: + if (!exists) { + _closed = true; + return; + } + break; + //Especifica que se deve abrir um arquivo, se existir; + // caso contrário, um novo arquivo deverá ser criado. + case FileMode::OpenOrCreate: + case FileMode::Create: + if (!exists) + flags |= std::fstream::trunc; + break; + //Especifica que o sistema operacional deve criar um novo arquivo. + //Se o arquivo já existir, não abre o arquivo. + case FileMode::CreateNew: + if (!exists) + flags |= std::fstream::trunc; + else + return; + break; + //Abre o arquivo, se existir, e busca o final do arquivo ou cria um novo arquivo. + case FileMode::Append: + if (!exists) + flags |= std::fstream::trunc; + else + flags |= std::fstream::app; + break; + //Especifica que se deve abrir um arquivo existente. + //Quando o arquivo for aberto, ele deverá ser truncado + //para que seu tamanho seja zero bytes. + //Tentativa de ler um arquivo truncado retornará 0; + case FileMode::Truncate: + flags |= std::fstream::trunc; + _truncated = true; + break; + default: + break; + } + + _fstream.open(path.c_str(), flags); + + if (!_fstream.good()) + _closed = true; + } + + FileStream(String const& path){ int flags = std::fstream::in | std::fstream::out | std::fstream::binary; @@ -79,7 +140,7 @@ namespace xna { _fstream.open(path.c_str(), flags); - if (!_fstream.is_open()) + if (!_fstream.good()) _closed = true; } @@ -109,6 +170,10 @@ namespace xna { _fstream.close(); } + virtual constexpr bool IsClosed() override { + return _closed; + } + 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& buffer, Int offset, Int count, xna_error_nullarg) override; @@ -123,6 +188,7 @@ namespace xna { private: std::streampos _filesize{ 0 }; bool _closed{ false }; + bool _truncated{ false }; Int endOfFile() { if (_closed) diff --git a/framework/enums.hpp b/framework/enums.hpp index 0e2fa74..62ba815 100644 --- a/framework/enums.hpp +++ b/framework/enums.hpp @@ -165,6 +165,15 @@ namespace xna { Stretched = 2 }; + enum class FileMode { + CreateNew, + Create, + Append, + Open, + OpenOrCreate, + Truncate + }; + enum class FillMode { WireFrame, diff --git a/framework/xna.cpp b/framework/xna.cpp index f7e5296..86e6e80 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -28,7 +28,7 @@ namespace xna { void LoadContent() override { spriteBatch = New(*graphicsDevice); - texture = Content()->Load("idlse"); + texture = Content()->Load("idle"); Game::LoadContent(); } From dfa592ef5e216aa7b4a8c942d47d2a1741071e8a Mon Sep 17 00:00:00 2001 From: Danilo Date: Thu, 9 May 2024 09:15:18 -0300 Subject: [PATCH 17/17] Remove DecompressStream --- framework/CMakeLists.txt | 2 +- framework/content/decstream.cpp | 111 -------------------------------- framework/content/decstream.hpp | 60 ----------------- framework/xna.h | 1 - 4 files changed, 1 insertion(+), 173 deletions(-) delete mode 100644 framework/content/decstream.cpp delete mode 100644 framework/content/decstream.hpp diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 1170c0e..5eb9432 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -39,7 +39,7 @@ add_executable (xna WIN32 "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" "csharp/type.cpp" "platform/init-dx.cpp" "game/servicecontainer.cpp" "common/color.cpp") + "content/lzx/decoder.cpp" "content/lzx/decoderstream.cpp" "content/typereadermanager.cpp" "csharp/object.cpp" "csharp/type.cpp" "platform/init-dx.cpp" "game/servicecontainer.cpp" "common/color.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/content/decstream.cpp b/framework/content/decstream.cpp deleted file mode 100644 index 7d96ba8..0000000 --- a/framework/content/decstream.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "decstream.hpp" -#include - -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& 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 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& 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; - } - -} \ No newline at end of file diff --git a/framework/content/decstream.hpp b/framework/content/decstream.hpp deleted file mode 100644 index 20219ec..0000000 --- a/framework/content/decstream.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef XNA_CONTENT_DECOMPRESS_STREAM_HPP -#define XNA_CONTENT_DECOMPRESS_STREAM_HPP - -#include "../default.hpp" -#include "../csharp/stream.hpp" -#include - -namespace xna { - class DecompressStream : public Stream { - public: - DecompressStream(sptr const& baseStream, Int compressedTodo, Int decompressedTodo): - baseStream(baseStream), compressedTodo(compressedTodo), decompressedTodo(decompressedTodo){ - compressedBuffer = std::vector(CompressedBufferSize); - decompressedBuffer = std::vector(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& 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 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 baseStream = nullptr; - Int compressedTodo{ 0 }; - Int compressedSize{ 0 }; - Int compressedPosition{ 0 }; - std::vector compressedBuffer; - Int decompressedTodo{ 0 }; - Int decompressedSize{ 0 }; - Int decompressedPosition{ 0 }; - std::vector decompressedBuffer; - mscab_decompressor* decompressionContext = nullptr; - - private: - bool DecompressNextBuffer(); - void ReadNextBufferFromDisk(); - void ReadBufferFromDisk(std::vector& buffer, Int& bufferTodo, Int& bufferSize); - }; -} - -#endif \ No newline at end of file diff --git a/framework/xna.h b/framework/xna.h index eac110e..1a82cc9 100644 --- a/framework/xna.h +++ b/framework/xna.h @@ -24,7 +24,6 @@ #include "Windows.h" #include #include "content/manager.hpp" -#include "content/decstream.hpp" #include "platform/init-dx.hpp" #include "csharp/type.hpp"