Support for loading TIM
This commit is contained in:
73
src/Library/src/File/Processor/TIM/simpletim_processor.cpp
Normal file
73
src/Library/src/File/Processor/TIM/simpletim_processor.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "tim_helper.hpp"
|
||||
#include <stdio.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace FileProcessor {
|
||||
using GPU::AreaU16;
|
||||
using GPU::PositionU16;
|
||||
using GPU::SizeU16;
|
||||
|
||||
namespace {
|
||||
struct SimpleTIMSize : private SimpleTIM {
|
||||
constexpr SimpleTIMSize() {
|
||||
}
|
||||
|
||||
constexpr uint16_t get_texture_width() const {
|
||||
return SimpleTIM::get_texture_x();
|
||||
}
|
||||
|
||||
constexpr uint16_t get_texture_height() const {
|
||||
return SimpleTIM::get_texture_y();
|
||||
}
|
||||
|
||||
constexpr SizeU16 get_texture_size() const {
|
||||
return {SimpleTIMSize::get_texture_width(), SimpleTIMSize::get_texture_height()};
|
||||
}
|
||||
|
||||
constexpr uint16_t get_clut_width() const {
|
||||
return SimpleTIM::get_clut_x();
|
||||
}
|
||||
|
||||
constexpr uint16_t get_clut_height() const {
|
||||
return SimpleTIM::get_clut_y();
|
||||
}
|
||||
|
||||
constexpr SizeU16 get_clut_size() const {
|
||||
return {SimpleTIMSize::get_clut_width(), SimpleTIMSize::get_clut_height()};
|
||||
}
|
||||
};
|
||||
|
||||
struct SimpleTIMState : public TIMFileProcessor::GenericTIM {
|
||||
// TODO: Create function???
|
||||
SimpleTIMState(const SimpleTIM& dst_info) {
|
||||
this->tex_area = AreaU16::create(dst_info.get_texture_position(), SizeU16::create(0, 0));
|
||||
this->clut_area = AreaU16::create(dst_info.get_clut_position(), SizeU16::create(0, 0));
|
||||
this->words_left = 0;
|
||||
}
|
||||
|
||||
virtual Progress parse_header(State::Configuration& config) override {
|
||||
if(config.data_bytes >= sizeof(SimpleTIMSize)) {
|
||||
// TODO: Return value???
|
||||
SimpleTIMSize size_info;
|
||||
Helper::simple_read(size_info, config);
|
||||
|
||||
this->clut_area.size = size_info.get_clut_size();
|
||||
this->tex_area.size = size_info.get_texture_size();
|
||||
return Progress::Done;
|
||||
}
|
||||
|
||||
return Progress::InProgress;
|
||||
}
|
||||
|
||||
virtual Progress pre_data_parsing(State::Configuration& config) {
|
||||
return Progress::Done;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
State create(const uint32_t* data_adr, const SimpleTIM& file) {
|
||||
using Callback = Progress(*)(State::Configuration& config, SimpleTIMState& simple_tim);
|
||||
return State::from(SimpleTIMState(file), data_adr, reinterpret_cast<Callback>(TIMFileProcessor::parse_header));
|
||||
}
|
||||
}
|
||||
}
|
67
src/Library/src/File/Processor/TIM/tim_helper.cpp
Normal file
67
src/Library/src/File/Processor/TIM/tim_helper.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "tim_helper.hpp"
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace TIMFileProcessor {
|
||||
namespace {
|
||||
void set_gpu_receive(const uint32_t* src, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
GPU::internal::DMA::Receive::prepare();
|
||||
GPU::internal::DMA::Receive::set_dst(PositionU16::create(x, y), SizeU16::create(w, h));
|
||||
GPU::internal::DMA::Receive::set_src(reinterpret_cast<const uintptr_t>(src));
|
||||
}
|
||||
|
||||
size_t set_gpu_receive_data(const uint32_t* src, const AreaU16& dst) {
|
||||
const auto width = dst.size.width;
|
||||
const auto height = dst.size.height;
|
||||
|
||||
set_gpu_receive(src, dst.position.x, dst.position.y, width, height);
|
||||
return (width*height)/2;
|
||||
}
|
||||
|
||||
Progress parse_data(State::Configuration& config, GenericTIM& generic_tim) {
|
||||
const auto [words_to_use, is_last] = Helper::DMA::WordsReady::calculate(config, generic_tim.words_left);
|
||||
const auto words_used = Helper::DMA::send_words<GPU::internal::DMA>(words_to_use, is_last);
|
||||
|
||||
generic_tim.words_left -= words_used;
|
||||
config.processed(words_used*sizeof(uint32_t));
|
||||
return is_last ? Progress::Done : Progress::InProgress;
|
||||
}
|
||||
|
||||
Progress switch_state_parse_data(State::Configuration& config, GenericTIM& generic_tim) {
|
||||
const auto result = generic_tim.pre_data_parsing(config);
|
||||
if(result == Progress::Done) {
|
||||
generic_tim.words_left = TIMFileProcessor::set_gpu_receive_data(reinterpret_cast<const uint32_t*>(config.data_adr), generic_tim.tex_area);
|
||||
return Helper::exchange_and_execute_process_function<TIMFileProcessor::GenericTIM>(TIMFileProcessor::parse_data, config, generic_tim);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Progress parse_clut(State::Configuration& config, GenericTIM& generic_tim) {
|
||||
if(const auto result = TIMFileProcessor::parse_data(config, generic_tim); result != Progress::Done) {
|
||||
return result;
|
||||
}
|
||||
|
||||
else {
|
||||
return switch_state_parse_data(config, generic_tim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Progress parse_header(State::Configuration& config, GenericTIM& generic_tim) {
|
||||
const auto result = generic_tim.parse_header(config);
|
||||
if(result == Progress::Done) {
|
||||
//Check if we have a clut to care about
|
||||
if(generic_tim.has_clut()) {
|
||||
//CLUTs are 16bit full color anyway
|
||||
generic_tim.words_left = TIMFileProcessor::set_gpu_receive_data(reinterpret_cast<const uint32_t*>(config.data_adr), generic_tim.clut_area);
|
||||
return Helper::exchange_and_execute_process_function(parse_clut, config, generic_tim);
|
||||
}
|
||||
|
||||
else {
|
||||
return switch_state_parse_data(config, generic_tim);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
26
src/Library/src/File/Processor/TIM/tim_helper.hpp
Normal file
26
src/Library/src/File/Processor/TIM/tim_helper.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "../../../../internal-include/GPU/gpu_internal.hpp"
|
||||
#include <PSX/File/file_processor_helper.hpp>
|
||||
#include <PSX/GPU/gpu_types.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace TIMFileProcessor {
|
||||
using namespace FileProcessor;
|
||||
using namespace GPU;
|
||||
|
||||
struct GenericTIM {
|
||||
AreaU16 clut_area;
|
||||
AreaU16 tex_area;
|
||||
size_t words_left; //32bit values
|
||||
|
||||
bool has_clut() const {
|
||||
return this->clut_area.size.width > 0;
|
||||
}
|
||||
|
||||
virtual Progress parse_header(State::Configuration& config) = 0;
|
||||
virtual Progress pre_data_parsing(State::Configuration& config) = 0;
|
||||
};
|
||||
|
||||
Progress parse_header(State::Configuration& config, GenericTIM& generic_tim);
|
||||
}
|
||||
}
|
54
src/Library/src/File/Processor/TIM/tim_processor.cpp
Normal file
54
src/Library/src/File/Processor/TIM/tim_processor.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "tim_helper.hpp"
|
||||
#include <stdio.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace FileProcessor {
|
||||
namespace {
|
||||
using GPU::AreaU16;
|
||||
|
||||
struct BlockInfo {
|
||||
uint32_t size;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
};
|
||||
|
||||
struct TIMState : public TIMFileProcessor::GenericTIM {
|
||||
// TODO: Create function???
|
||||
TIMState() {
|
||||
}
|
||||
|
||||
virtual Progress parse_header(State::Configuration& config) override {
|
||||
static constexpr auto HEADER_SIZE = 2*sizeof(uint32_t);
|
||||
|
||||
if(config.data_bytes >= (HEADER_SIZE + sizeof(BlockInfo))) {
|
||||
BlockInfo block_info;
|
||||
|
||||
config.processed(HEADER_SIZE);
|
||||
Helper::simple_read(block_info, config);
|
||||
this->clut_area = AreaU16::create(block_info.x, block_info.y, block_info.w, block_info.h);
|
||||
return Progress::Done;
|
||||
}
|
||||
return Progress::Error;
|
||||
}
|
||||
|
||||
virtual Progress pre_data_parsing(State::Configuration& config) {
|
||||
if(config.data_bytes >= sizeof(BlockInfo)) {
|
||||
BlockInfo block_info;
|
||||
|
||||
Helper::simple_read(block_info, config);
|
||||
this->tex_area = AreaU16::create(block_info.x, block_info.y, block_info.w, block_info.h);
|
||||
return Progress::Done;
|
||||
}
|
||||
return Progress::InProgress;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
State create(const uint32_t* data_adr, const TIM& file) {
|
||||
using Callback = Progress(*)(State::Configuration& config, TIMState& simple_tim);
|
||||
return State::from(TIMState(), data_adr, reinterpret_cast<Callback>(TIMFileProcessor::parse_header));
|
||||
}
|
||||
}
|
||||
}
|
@@ -43,6 +43,9 @@ namespace JabyEngine {
|
||||
case CDFileType::SimpleTIM:
|
||||
return FileProcessor::create(data_adr, file.payload.simple_tim);
|
||||
|
||||
case CDFileType::SonyTIM:
|
||||
return FileProcessor::create(data_adr, file.payload.tim);
|
||||
|
||||
case CDFileType::SonyVAG:
|
||||
return FileProcessor::create(data_adr, file.payload.vag);
|
||||
|
||||
|
@@ -1,113 +0,0 @@
|
||||
#include "../../../internal-include/GPU/gpu_internal.hpp"
|
||||
#include <PSX/File/file_processor_helper.hpp>
|
||||
#include <PSX/GPU/gpu_types.hpp>
|
||||
#include <stdio.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace FileProcessor {
|
||||
using GPU::AreaU16;
|
||||
using GPU::PositionU16;
|
||||
using GPU::SizeU16;
|
||||
|
||||
struct SimpleTIMSize : private SimpleTIM {
|
||||
constexpr SimpleTIMSize() {
|
||||
}
|
||||
|
||||
constexpr uint16_t get_texture_width() const {
|
||||
return SimpleTIM::get_texture_x();
|
||||
}
|
||||
|
||||
constexpr uint16_t get_texture_height() const {
|
||||
return SimpleTIM::get_texture_y();
|
||||
}
|
||||
|
||||
constexpr SizeU16 get_texture_size() const {
|
||||
return {SimpleTIMSize::get_texture_width(), SimpleTIMSize::get_texture_height()};
|
||||
}
|
||||
|
||||
constexpr uint16_t get_clut_width() const {
|
||||
return SimpleTIM::get_clut_x();
|
||||
}
|
||||
|
||||
constexpr uint16_t get_clut_height() const {
|
||||
return SimpleTIM::get_clut_y();
|
||||
}
|
||||
|
||||
constexpr SizeU16 get_clut_size() const {
|
||||
return {SimpleTIMSize::get_clut_width(), SimpleTIMSize::get_clut_height()};
|
||||
}
|
||||
};
|
||||
|
||||
struct SimpleTIMState {
|
||||
SimpleTIM dst_info;
|
||||
SimpleTIMSize size_info;
|
||||
size_t words_left; //32bit values
|
||||
|
||||
constexpr SimpleTIMState(const SimpleTIM& dst_info) : dst_info(dst_info), words_left(0) {
|
||||
}
|
||||
};
|
||||
|
||||
static void set_gpu_receive(const uint32_t* src, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
GPU::internal::DMA::Receive::prepare();
|
||||
GPU::internal::DMA::Receive::set_dst(PositionU16::create(x, y), SizeU16::create(w, h));
|
||||
GPU::internal::DMA::Receive::set_src(reinterpret_cast<const uintptr_t>(src));
|
||||
}
|
||||
|
||||
static size_t set_gpu_receive_data(const uint32_t* src, const AreaU16& dst) {
|
||||
const auto width = dst.size.width;
|
||||
const auto height = dst.size.height;
|
||||
|
||||
set_gpu_receive(src, dst.position.x, dst.position.y, width, height);
|
||||
return (width*height)/2;
|
||||
}
|
||||
|
||||
static Progress parse_data(State::Configuration& config, SimpleTIMState& state) {
|
||||
const auto [words_to_use, is_last] = Helper::DMA::WordsReady::calculate(config, state.words_left);
|
||||
const auto words_used = Helper::DMA::send_words<GPU::internal::DMA>(words_to_use, is_last);
|
||||
|
||||
state.words_left -= words_used;
|
||||
config.processed(words_used*sizeof(uint32_t));
|
||||
return is_last ? Progress::Done : Progress::InProgress;
|
||||
}
|
||||
|
||||
static Progress switch_state_parse_data(State::Configuration& config, SimpleTIMState& state) {
|
||||
state.words_left = set_gpu_receive_data(reinterpret_cast<const uint32_t*>(config.data_adr), {state.dst_info.get_texture_position(), state.size_info.get_texture_size()});
|
||||
return Helper::exchange_and_execute_process_function(parse_data, config, state);
|
||||
}
|
||||
|
||||
static Progress parse_clut(State::Configuration& config, SimpleTIMState& state) {
|
||||
if(const auto result = parse_data(config, state); result != Progress::Done) {
|
||||
return result;
|
||||
}
|
||||
|
||||
else {
|
||||
return switch_state_parse_data(config, state);
|
||||
}
|
||||
}
|
||||
|
||||
static Progress parse_header(State::Configuration& config, SimpleTIMState& state) {
|
||||
if(config.data_bytes >= sizeof(SimpleTIMSize)) {
|
||||
Helper::simple_read(state.size_info, config);
|
||||
|
||||
//Check if we have a clut to care about
|
||||
if(state.size_info.get_clut_width() > 0) {
|
||||
//CLUTs are 16bit full color anyway
|
||||
state.words_left = set_gpu_receive_data(reinterpret_cast<const uint32_t*>(config.data_adr), {state.dst_info.get_clut_position(), state.size_info.get_clut_size()});
|
||||
return Helper::exchange_and_execute_process_function(parse_clut, config, state);
|
||||
}
|
||||
|
||||
//We have direct data
|
||||
else {
|
||||
return switch_state_parse_data(config, state);
|
||||
}
|
||||
}
|
||||
|
||||
return Progress::InProgress;
|
||||
}
|
||||
|
||||
State create(const uint32_t* data_adr, const SimpleTIM& file) {
|
||||
return State::from(SimpleTIMState(file), data_adr, parse_header);
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef private
|
Reference in New Issue
Block a user