Integrate CircularBuffer as essential part of loading files from CD and dedicate file processing to the FileProcessor
This commit is contained in:
parent
7550795af4
commit
e9cc5f299a
|
@ -11,6 +11,10 @@ namespace JabyEngine {
|
||||||
Progress progress;
|
Progress progress;
|
||||||
size_t bytes_ready;
|
size_t bytes_ready;
|
||||||
|
|
||||||
|
constexpr operator bool() const {
|
||||||
|
return this->progress != Progress::Error;
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr Result new_error() {
|
static constexpr Result new_error() {
|
||||||
return {Progress::Error, 0};
|
return {Progress::Error, 0};
|
||||||
}
|
}
|
||||||
|
@ -27,6 +31,7 @@ namespace JabyEngine {
|
||||||
private:
|
private:
|
||||||
struct State {
|
struct State {
|
||||||
enum struct Step {
|
enum struct Step {
|
||||||
|
Disabled,
|
||||||
ReadToken,
|
ReadToken,
|
||||||
ObtainLiteralLength,
|
ObtainLiteralLength,
|
||||||
CopyLiterals,
|
CopyLiterals,
|
||||||
|
@ -35,12 +40,23 @@ namespace JabyEngine {
|
||||||
CopyMatch,
|
CopyMatch,
|
||||||
};
|
};
|
||||||
|
|
||||||
Step step = Step::ReadToken;
|
Step step = Step::Disabled;
|
||||||
size_t literal_length = 0;
|
size_t literal_length = 0;
|
||||||
size_t match_length = 0;
|
size_t match_length = 0;
|
||||||
uint16_t match_offset = 0xFFFF;
|
uint16_t match_offset = 0;
|
||||||
|
|
||||||
State() = default;
|
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:
|
private:
|
||||||
|
@ -56,7 +72,7 @@ namespace JabyEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(uint8_t* dst_adr);
|
void setup(uint8_t* dst_adr);
|
||||||
void reset();
|
void disable();
|
||||||
|
|
||||||
Result process(ArrayRange<const uint8_t> data, bool is_last);
|
Result process(ArrayRange<const uint8_t> data, bool is_last);
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,17 +25,15 @@ namespace JabyEngine {
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileProcessor::State file_pro_state;
|
FileProcessor::State file_state;
|
||||||
CircularBuffer<CD_IO::DataSector> circular_buffer;
|
CircularBuffer<CD_IO::DataSector> circular_buffer;
|
||||||
LZ4Decompressor lz4_decomp;
|
LZ4Decompressor lz4_decomp;
|
||||||
JobArray jobs;
|
JobArray jobs;
|
||||||
const AutoLBAEntry* lba = nullptr;
|
const AutoLBAEntry* lba = nullptr;
|
||||||
uint32_t*const tmp_area = nullptr; //< The start of the area to copy data to
|
uint32_t*const tmp_area = nullptr; //< The start of the area to copy data to for the file processor
|
||||||
uint32_t* dst_area = nullptr; //< Current target for copying the data
|
|
||||||
|
|
||||||
void start_cur_job();
|
void start_cur_job();
|
||||||
void reading_state(const CDFile& file);
|
bool process_data();
|
||||||
void done_state(const CDFile& file);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CDFileProcessor() = default;
|
CDFileProcessor() = default;
|
||||||
|
|
|
@ -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);
|
State create(const uint32_t* data_adr, const SimpleTIM& file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
#ifndef __JABYENGINE_FILE_TYPES_HPP__
|
#ifndef __JABYENGINE_FILE_TYPES_HPP__
|
||||||
#define __JABYENGINE_FILE_TYPES_HPP__
|
#define __JABYENGINE_FILE_TYPES_HPP__
|
||||||
|
#include "../Auxiliary/bits.hpp"
|
||||||
#include "../jabyengine_defines.h"
|
#include "../jabyengine_defines.h"
|
||||||
|
|
||||||
namespace JabyEngine {
|
namespace JabyEngine {
|
||||||
|
struct __no_align Nothing {
|
||||||
|
};
|
||||||
|
|
||||||
struct __no_align SimpleTIM {
|
struct __no_align SimpleTIM {
|
||||||
static constexpr auto TextureX = BitRange::from_to(0, 8);
|
static constexpr auto TextureX = BitRange::from_to(0, 8);
|
||||||
static constexpr auto TextureY = BitRange::from_to(9, 16);
|
static constexpr auto TextureY = BitRange::from_to(9, 16);
|
||||||
|
|
|
@ -24,11 +24,11 @@ namespace JabyEngine {
|
||||||
|
|
||||||
void LZ4Decompressor :: setup(uint8_t* dst_adr) {
|
void LZ4Decompressor :: setup(uint8_t* dst_adr) {
|
||||||
this->dst_adr = dst_adr;
|
this->dst_adr = dst_adr;
|
||||||
LZ4Decompressor::reset();
|
this->state.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LZ4Decompressor :: reset() {
|
void LZ4Decompressor :: disable() {
|
||||||
this->state = State();
|
this->state.disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
LZ4Decompressor::Result LZ4Decompressor :: process(ArrayRange<const uint8_t> data, bool is_last) {
|
LZ4Decompressor::Result LZ4Decompressor :: process(ArrayRange<const uint8_t> data, bool is_last) {
|
||||||
|
@ -36,6 +36,9 @@ namespace JabyEngine {
|
||||||
|
|
||||||
while(data) {
|
while(data) {
|
||||||
switch(this->state.step) {
|
switch(this->state.step) {
|
||||||
|
case State::Step::Disabled:
|
||||||
|
return Result::new_done(data.size);
|
||||||
|
|
||||||
case State::Step::ReadToken: {
|
case State::Step::ReadToken: {
|
||||||
const auto token = data.pop();
|
const auto token = data.pop();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace JabyEngine {
|
namespace JabyEngine {
|
||||||
|
static constexpr auto NormalCircularBufferSize = 5;
|
||||||
|
|
||||||
void CDFileProcessor :: start_cur_job() {
|
void CDFileProcessor :: start_cur_job() {
|
||||||
using CD::internal::FileInfo;
|
using CD::internal::FileInfo;
|
||||||
using CD::internal::SectorBufferAllocator;
|
using CD::internal::SectorBufferAllocator;
|
||||||
|
@ -11,13 +13,6 @@ namespace JabyEngine {
|
||||||
CDFileProcessor &self = *reinterpret_cast<CDFileProcessor*>(ctx);
|
CDFileProcessor &self = *reinterpret_cast<CDFileProcessor*>(ctx);
|
||||||
return self.circular_buffer.allocate();
|
return self.circular_buffer.allocate();
|
||||||
};
|
};
|
||||||
static const auto direct_copy_callback = [](void* ctx) -> CD_IO::DataSector* {
|
|
||||||
auto** data_sector = reinterpret_cast<CD_IO::DataSector**>(ctx);
|
|
||||||
auto* cur_sector = *data_sector;
|
|
||||||
|
|
||||||
data_sector += sizeof(CD_IO::DataSector);
|
|
||||||
return cur_sector;
|
|
||||||
};
|
|
||||||
|
|
||||||
switch(file.type) {
|
switch(file.type) {
|
||||||
case CDFileType::SimpleTIM:
|
case CDFileType::SimpleTIM:
|
||||||
|
@ -25,8 +20,11 @@ namespace JabyEngine {
|
||||||
return SectorBufferAllocator::invalid();
|
return SectorBufferAllocator::invalid();
|
||||||
|
|
||||||
case CDFileType::CopyTo:
|
case CDFileType::CopyTo:
|
||||||
this->dst_area = file.payload.copy_to.dst;
|
this->circular_buffer.setup(reinterpret_cast<CD_IO::DataSector*>(file.payload.copy_to.dst), 512);
|
||||||
return SectorBufferAllocator::create(&this->dst_area, direct_copy_callback);
|
this->lz4_decomp.disable();
|
||||||
|
|
||||||
|
this->file_state = FileProcessor::create(this->tmp_area, Nothing());
|
||||||
|
return SectorBufferAllocator::create(this, circular_buffer_callback);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return SectorBufferAllocator::invalid();
|
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);
|
printf(">>> CD needs to load LBA: %i -> %i\n", cur_lba.lba, cur_lba.size_words);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDFileProcessor :: reading_state(const CDFile& file) {
|
bool CDFileProcessor :: process_data() {
|
||||||
switch(file.type) {
|
while(this->circular_buffer.has_data()) {
|
||||||
case CDFileType::SimpleTIM:
|
ArrayRange<const uint8_t> cur_sector(reinterpret_cast<uint8_t*>(this->circular_buffer.get_next()->data), CD_IO::DataSector::SizeBytes);
|
||||||
printf("CDFileProcessor: SimpleTIM not supported yet\n");
|
|
||||||
break;
|
// 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:
|
if(result) {
|
||||||
default:
|
// Process the data in the tmp_area
|
||||||
break;
|
if(this->file_state.process(result.bytes_ready/sizeof(uint32_t)) == Progress::Error) {
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void CDFileProcessor :: done_state(const CDFile& file) {
|
|
||||||
switch(file.type) {
|
else {
|
||||||
case CDFileType::SimpleTIM:
|
return false;
|
||||||
printf("CDFileProcessor: SimpleTIM not supported yet\n");
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case CDFileType::CopyTo:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area) {
|
void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area) {
|
||||||
|
@ -71,33 +67,30 @@ namespace JabyEngine {
|
||||||
this->jobs = jobs;
|
this->jobs = jobs;
|
||||||
|
|
||||||
// Setsup the circular buffer and determines where to place the temp area in
|
// Setsup the circular buffer and determines where to place the temp area in
|
||||||
const_cast<uint32_t*&>(this->tmp_area) = reinterpret_cast<uint32_t*>(this->circular_buffer.setup(reinterpret_cast<CD_IO::DataSector*>(tmp_area), 5));
|
const_cast<uint32_t*&>(this->tmp_area) = reinterpret_cast<uint32_t*>(this->circular_buffer.setup(reinterpret_cast<CD_IO::DataSector*>(tmp_area), NormalCircularBufferSize));
|
||||||
CDFileProcessor::start_cur_job();
|
CDFileProcessor::start_cur_job();
|
||||||
}
|
}
|
||||||
|
|
||||||
Progress CDFileProcessor :: process() {
|
Progress CDFileProcessor :: process() {
|
||||||
const auto& cur_job = *this->jobs.files;
|
CDFileProcessor::process_data();
|
||||||
|
|
||||||
switch(CD::internal::read_current_state()) {
|
switch(CD::internal::read_current_state()) {
|
||||||
case CD::internal::State::Done:
|
case CD::internal::State::Done:
|
||||||
// We are done now!
|
/*
|
||||||
// The user decides if he wants the next value
|
We are done now!
|
||||||
CDFileProcessor::done_state(cur_job);
|
The user decides if he wants the next value
|
||||||
|
*/
|
||||||
return Progress::Done;
|
return Progress::Done;
|
||||||
|
|
||||||
case CD::internal::State::BufferFull:
|
case CD::internal::State::BufferFull:
|
||||||
// We have to process data and unpause the CD drive
|
/* We processd data and unpause the CD drive */
|
||||||
CDFileProcessor::reading_state(cur_job);
|
return CD::internal::continue_reading() ? Progress::InProgress : Progress::Error;
|
||||||
return CD::internal::continue_reading() ? CDFileProcessor::process() : Progress::Error;
|
|
||||||
|
|
||||||
case CD::internal::State::Reading:
|
case CD::internal::State::Reading:
|
||||||
// Do we have data? Use it!
|
|
||||||
CDFileProcessor::reading_state(cur_job);
|
|
||||||
return Progress::InProgress;
|
return Progress::InProgress;
|
||||||
|
|
||||||
case CD::internal::State::Error:
|
case CD::internal::State::Error:
|
||||||
default:
|
default:
|
||||||
// Error for real!
|
/* Error for real */
|
||||||
return Progress::Error;
|
return Progress::Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue