From 4553dbef6ea441112cf73a0f3e2caf820f890cad Mon Sep 17 00:00:00 2001 From: Jaby Date: Sat, 1 Apr 2023 11:20:56 +0200 Subject: [PATCH] Integrate CircularBuffer as essential part of loading files from CD and dedicate file processing to the FileProcessor --- include/PSX/Auxiliary/lz4_decompressor.hpp | 22 +++++- .../PSX/File/Processor/cd_file_processor.hpp | 10 +-- include/PSX/File/Processor/file_processor.hpp | 2 + include/PSX/File/file_types.hpp | 4 + .../src/Auxiliary/lz4_decompressor.cpp | 9 ++- .../src/File/Processor/cd_file_processor.cpp | 75 +++++++++---------- .../src/File/Processor/nothing_processor.cpp | 16 ++++ 7 files changed, 85 insertions(+), 53 deletions(-) create mode 100644 src/Library/src/File/Processor/nothing_processor.cpp diff --git a/include/PSX/Auxiliary/lz4_decompressor.hpp b/include/PSX/Auxiliary/lz4_decompressor.hpp index e8343cc9..0ebd7b90 100644 --- a/include/PSX/Auxiliary/lz4_decompressor.hpp +++ b/include/PSX/Auxiliary/lz4_decompressor.hpp @@ -11,6 +11,10 @@ namespace JabyEngine { Progress progress; size_t bytes_ready; + constexpr operator bool() const { + return this->progress != Progress::Error; + } + static constexpr Result new_error() { return {Progress::Error, 0}; } @@ -27,6 +31,7 @@ namespace JabyEngine { private: struct State { enum struct Step { + Disabled, ReadToken, ObtainLiteralLength, CopyLiterals, @@ -35,12 +40,23 @@ namespace JabyEngine { CopyMatch, }; - Step step = Step::ReadToken; + Step step = Step::Disabled; size_t literal_length = 0; size_t match_length = 0; - uint16_t match_offset = 0xFFFF; + uint16_t match_offset = 0; State() = default; + + void enable() { + this->step = Step::ReadToken; + this->literal_length = 0; + this->match_length = 0; + this->match_offset = 0xFFFF; + } + + void disable() { + this->step = Step::Disabled; + } }; private: @@ -56,7 +72,7 @@ namespace JabyEngine { } void setup(uint8_t* dst_adr); - void reset(); + void disable(); Result process(ArrayRange data, bool is_last); }; diff --git a/include/PSX/File/Processor/cd_file_processor.hpp b/include/PSX/File/Processor/cd_file_processor.hpp index f6ca1c67..58b08920 100644 --- a/include/PSX/File/Processor/cd_file_processor.hpp +++ b/include/PSX/File/Processor/cd_file_processor.hpp @@ -25,17 +25,15 @@ namespace JabyEngine { }; private: - FileProcessor::State file_pro_state; + FileProcessor::State file_state; CircularBuffer circular_buffer; LZ4Decompressor lz4_decomp; JobArray jobs; const AutoLBAEntry* lba = nullptr; - uint32_t*const tmp_area = nullptr; //< The start of the area to copy data to - uint32_t* dst_area = nullptr; //< Current target for copying the data + uint32_t*const tmp_area = nullptr; //< The start of the area to copy data to for the file processor - void start_cur_job(); - void reading_state(const CDFile& file); - void done_state(const CDFile& file); + void start_cur_job(); + bool process_data(); public: CDFileProcessor() = default; diff --git a/include/PSX/File/Processor/file_processor.hpp b/include/PSX/File/Processor/file_processor.hpp index bdfba65f..fe3e3e9d 100644 --- a/include/PSX/File/Processor/file_processor.hpp +++ b/include/PSX/File/Processor/file_processor.hpp @@ -51,6 +51,8 @@ namespace JabyEngine { } }; + // The nothing state + State create(const uint32_t* data_adr, const Nothing& nothing); State create(const uint32_t* data_adr, const SimpleTIM& file); } } diff --git a/include/PSX/File/file_types.hpp b/include/PSX/File/file_types.hpp index 21f428b6..fe55228b 100644 --- a/include/PSX/File/file_types.hpp +++ b/include/PSX/File/file_types.hpp @@ -1,8 +1,12 @@ #ifndef __JABYENGINE_FILE_TYPES_HPP__ #define __JABYENGINE_FILE_TYPES_HPP__ +#include "../Auxiliary/bits.hpp" #include "../jabyengine_defines.h" namespace JabyEngine { + struct __no_align Nothing { + }; + struct __no_align SimpleTIM { static constexpr auto TextureX = BitRange::from_to(0, 8); static constexpr auto TextureY = BitRange::from_to(9, 16); diff --git a/src/Library/src/Auxiliary/lz4_decompressor.cpp b/src/Library/src/Auxiliary/lz4_decompressor.cpp index 3422a6ab..203693a9 100644 --- a/src/Library/src/Auxiliary/lz4_decompressor.cpp +++ b/src/Library/src/Auxiliary/lz4_decompressor.cpp @@ -24,11 +24,11 @@ namespace JabyEngine { void LZ4Decompressor :: setup(uint8_t* dst_adr) { this->dst_adr = dst_adr; - LZ4Decompressor::reset(); + this->state.enable(); } - void LZ4Decompressor :: reset() { - this->state = State(); + void LZ4Decompressor :: disable() { + this->state.disable(); } LZ4Decompressor::Result LZ4Decompressor :: process(ArrayRange data, bool is_last) { @@ -36,6 +36,9 @@ namespace JabyEngine { while(data) { switch(this->state.step) { + case State::Step::Disabled: + return Result::new_done(data.size); + case State::Step::ReadToken: { const auto token = data.pop(); diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 01a198df..3bd92faa 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -3,6 +3,8 @@ #include namespace JabyEngine { + static constexpr auto NormalCircularBufferSize = 5; + void CDFileProcessor :: start_cur_job() { using CD::internal::FileInfo; using CD::internal::SectorBufferAllocator; @@ -11,13 +13,6 @@ namespace JabyEngine { CDFileProcessor &self = *reinterpret_cast(ctx); return self.circular_buffer.allocate(); }; - static const auto direct_copy_callback = [](void* ctx) -> CD_IO::DataSector* { - auto** data_sector = reinterpret_cast(ctx); - auto* cur_sector = *data_sector; - - data_sector += sizeof(CD_IO::DataSector); - return cur_sector; - }; switch(file.type) { case CDFileType::SimpleTIM: @@ -25,8 +20,11 @@ namespace JabyEngine { return SectorBufferAllocator::invalid(); case CDFileType::CopyTo: - this->dst_area = file.payload.copy_to.dst; - return SectorBufferAllocator::create(&this->dst_area, direct_copy_callback); + this->circular_buffer.setup(reinterpret_cast(file.payload.copy_to.dst), 512); + this->lz4_decomp.disable(); + + this->file_state = FileProcessor::create(this->tmp_area, Nothing()); + return SectorBufferAllocator::create(this, circular_buffer_callback); default: return SectorBufferAllocator::invalid(); @@ -42,28 +40,26 @@ namespace JabyEngine { printf(">>> CD needs to load LBA: %i -> %i\n", cur_lba.lba, cur_lba.size_words); } - void CDFileProcessor :: reading_state(const CDFile& file) { - switch(file.type) { - case CDFileType::SimpleTIM: - printf("CDFileProcessor: SimpleTIM not supported yet\n"); - break; + bool CDFileProcessor :: process_data() { + while(this->circular_buffer.has_data()) { + ArrayRange cur_sector(reinterpret_cast(this->circular_buffer.get_next()->data), CD_IO::DataSector::SizeBytes); + + // v We can not know if there will be more data or not - but it also doesn't matter much for us + const auto result = this->lz4_decomp.process(cur_sector, false); + this->circular_buffer.pop(); - case CDFileType::CopyTo: - default: - break; - } - } - - void CDFileProcessor :: done_state(const CDFile& file) { - switch(file.type) { - case CDFileType::SimpleTIM: - printf("CDFileProcessor: SimpleTIM not supported yet\n"); - break; - - case CDFileType::CopyTo: - default: - break; + if(result) { + // Process the data in the tmp_area + if(this->file_state.process(result.bytes_ready/sizeof(uint32_t)) == Progress::Error) { + return false; + } + } + + else { + return false; + } } + return true; } void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area) { @@ -71,33 +67,30 @@ namespace JabyEngine { this->jobs = jobs; // Setsup the circular buffer and determines where to place the temp area in - const_cast(this->tmp_area) = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(tmp_area), 5)); + const_cast(this->tmp_area) = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(tmp_area), NormalCircularBufferSize)); CDFileProcessor::start_cur_job(); } Progress CDFileProcessor :: process() { - const auto& cur_job = *this->jobs.files; - + CDFileProcessor::process_data(); switch(CD::internal::read_current_state()) { case CD::internal::State::Done: - // We are done now! - // The user decides if he wants the next value - CDFileProcessor::done_state(cur_job); + /* + We are done now! + The user decides if he wants the next value + */ return Progress::Done; case CD::internal::State::BufferFull: - // We have to process data and unpause the CD drive - CDFileProcessor::reading_state(cur_job); - return CD::internal::continue_reading() ? CDFileProcessor::process() : Progress::Error; + /* We processd data and unpause the CD drive */ + return CD::internal::continue_reading() ? Progress::InProgress : Progress::Error; case CD::internal::State::Reading: - // Do we have data? Use it! - CDFileProcessor::reading_state(cur_job); return Progress::InProgress; case CD::internal::State::Error: default: - // Error for real! + /* Error for real */ return Progress::Error; } } diff --git a/src/Library/src/File/Processor/nothing_processor.cpp b/src/Library/src/File/Processor/nothing_processor.cpp new file mode 100644 index 00000000..b76e5e2c --- /dev/null +++ b/src/Library/src/File/Processor/nothing_processor.cpp @@ -0,0 +1,16 @@ +#include "simplehelper.hpp" + +namespace JabyEngine { + namespace FileProcessor { + struct NothingState { + }; + + static Progress parse_nothing(State::Configuration& config, NothingState& state) { + return Progress::Done; + } + + State create(const uint32_t* data_adr, const Nothing& nothing) { + return State::from(NothingState(), data_adr, parse_nothing); + } + } +} \ No newline at end of file