Support for loading TIM
This commit is contained in:
parent
c3cc4a729d
commit
c66b68a0e8
|
@ -32,5 +32,7 @@ namespace FontCycler {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ScreenCenter {
|
namespace ScreenCenter {
|
||||||
|
extern const volatile JabyEngine::AutoLBAEntry lba[];
|
||||||
|
extern JabyEngine::CDFile Assets[1];
|
||||||
void main();
|
void main();
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
#include "include/frame.hpp"
|
#include "include/frame.hpp"
|
||||||
#include <FontWriter/fonts.hpp>
|
#include <FontWriter/fonts.hpp>
|
||||||
#include <PSX/GPU/gpu.hpp>
|
#include <PSX/GPU/gpu.hpp>
|
||||||
|
#include <PSX/GPU/make_gpu_primitives.hpp>
|
||||||
#include <PSX/Periphery/periphery.hpp>
|
#include <PSX/Periphery/periphery.hpp>
|
||||||
#include <PSX/Timer/frame_timer.hpp>
|
#include <PSX/Timer/frame_timer.hpp>
|
||||||
|
|
||||||
|
@ -76,6 +77,13 @@ namespace ScreenCenter {
|
||||||
Formular{.name = PSYQ::Name, .function = PSYQ::set_offset}
|
Formular{.name = PSYQ::Name, .function = PSYQ::set_offset}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr const auto background_img = Make::POLY_FT4(
|
||||||
|
Make::AreaI16(Make::PositionI16((GPU::Display::Width - 256)/2, (GPU::Display::Height - 240)/2), Make::SizeI16(256, 240)),
|
||||||
|
Make::PageOffset(0, 0),
|
||||||
|
Make::TPage(Make::PositionU16(384, 256), GPU::SemiTransparency::B_Half_add_F_Half, GPU::TextureColorMode::clut4),
|
||||||
|
Make::PageClut(Make::PositionU16(384, 255))
|
||||||
|
);
|
||||||
|
|
||||||
static auto frame = Frame::create();
|
static auto frame = Frame::create();
|
||||||
|
|
||||||
static ButtonPulser button_pulse[4];
|
static ButtonPulser button_pulse[4];
|
||||||
|
@ -182,6 +190,7 @@ namespace ScreenCenter {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render() {
|
static void render() {
|
||||||
|
GPU::render(background_img);
|
||||||
frame.render();
|
frame.render();
|
||||||
Shared::back_menu.render();
|
Shared::back_menu.render();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include <PSX/File/Processor/cd_file_processor.hpp>
|
||||||
|
#include <PSX/AutoLBA/auto_lba_declaration.hpp>
|
||||||
|
|
||||||
|
namespace ScreenCenter {
|
||||||
|
using namespace JabyEngine;
|
||||||
|
|
||||||
|
enum LBA {
|
||||||
|
__jabyengine_start_lba_request
|
||||||
|
__jabyengine_request_lba_for(BG_IMAGE, "ASSETS/SAND.TIM"),
|
||||||
|
__jabyengine_end_lba_request
|
||||||
|
};
|
||||||
|
__declare_lba_header(LBA);
|
||||||
|
|
||||||
|
CDFile Assets[1] = {
|
||||||
|
CDFileBuilder::sony_tim(LBA::BG_IMAGE, TIM::create())
|
||||||
|
};
|
||||||
|
}
|
|
@ -121,7 +121,7 @@ namespace Assets {
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_screen_center() {
|
void load_screen_center() {
|
||||||
load(CDFileBuilder::overlay(LBA::SCREEN_CENT_OVL, &__screen_center_start));
|
load(CDFileBuilder::overlay(LBA::SCREEN_CENT_OVL, &__screen_center_start), ScreenCenter::lba, ScreenCenter::Assets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -1,10 +1,6 @@
|
||||||
include $(JABY_ENGINE_DIR)/mkfile/common/ExportPath.mk
|
include $(JABY_ENGINE_DIR)/mkfile/common/ExportPath.mk
|
||||||
include $(JABY_ENGINE_DIR)/mkfile/common/RebuildTarget.mk
|
include $(JABY_ENGINE_DIR)/mkfile/common/RebuildTarget.mk
|
||||||
|
|
||||||
define wuff
|
|
||||||
$1_FLAGS = $2
|
|
||||||
endef
|
|
||||||
|
|
||||||
OUTPUT_DIR = bin
|
OUTPUT_DIR = bin
|
||||||
CLUT_4_COLOR_TRANS_FLAGS = simple-tim clut4 --color-trans
|
CLUT_4_COLOR_TRANS_FLAGS = simple-tim clut4 --color-trans
|
||||||
|
|
||||||
|
@ -38,6 +34,9 @@ JabyStar_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
|
||||||
INPUT += $(OUTPUT_DIR)/JabyTails.img
|
INPUT += $(OUTPUT_DIR)/JabyTails.img
|
||||||
JabyTails_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
|
JabyTails_FLAGS = $(CLUT_4_COLOR_TRANS_FLAGS)
|
||||||
|
|
||||||
|
INPUT += $(OUTPUT_DIR)/IMG_6921.tim
|
||||||
|
IMG_6921_TIM_FLAGS = tim clut4 --clut-pos {384,255} --tex-pos {384,256}
|
||||||
|
|
||||||
$(OUTPUT_DIR)/fox.xa: audio/temp/fox.wav
|
$(OUTPUT_DIR)/fox.xa: audio/temp/fox.wav
|
||||||
@mkdir -p $(OUTPUT_DIR)
|
@mkdir -p $(OUTPUT_DIR)
|
||||||
psxfileconv $< -o $@ xa
|
psxfileconv $< -o $@ xa
|
||||||
|
@ -54,6 +53,10 @@ $(OUTPUT_DIR)/%.img: %.png
|
||||||
@mkdir -p $(OUTPUT_DIR)
|
@mkdir -p $(OUTPUT_DIR)
|
||||||
psxfileconv --lz4 $< -o $@ $($*_FLAGS)
|
psxfileconv --lz4 $< -o $@ $($*_FLAGS)
|
||||||
|
|
||||||
|
$(OUTPUT_DIR)/%.tim: %.png
|
||||||
|
@mkdir -p $(OUTPUT_DIR)
|
||||||
|
psxfileconv $< -o $@ $($*_TIM_FLAGS)
|
||||||
|
|
||||||
all: $(INPUT)
|
all: $(INPUT)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<Overlay name = "GTO.BIN" lba_source = "../application/src/Overlay/GPUTest/gpu_test_assets.cpp" >../application/bin/%PSX_TV_FORMAT%/PSX-release/Overlay.gpu_tests</Overlay>
|
<Overlay name = "GTO.BIN" lba_source = "../application/src/Overlay/GPUTest/gpu_test_assets.cpp" >../application/bin/%PSX_TV_FORMAT%/PSX-release/Overlay.gpu_tests</Overlay>
|
||||||
<Overlay name = "GTE.BIN" lba_source = "../application/src/Overlay/GTETest/gte_test_assets.cpp" >../application/bin/%PSX_TV_FORMAT%/PSX-release/Overlay.gte_tests</Overlay>
|
<Overlay name = "GTE.BIN" lba_source = "../application/src/Overlay/GTETest/gte_test_assets.cpp" >../application/bin/%PSX_TV_FORMAT%/PSX-release/Overlay.gte_tests</Overlay>
|
||||||
<Overlay name = "FCO.BIN" lba_source = "" >../application/bin/%PSX_TV_FORMAT%/PSX-release/Overlay.font_cycler</Overlay>
|
<Overlay name = "FCO.BIN" lba_source = "" >../application/bin/%PSX_TV_FORMAT%/PSX-release/Overlay.font_cycler</Overlay>
|
||||||
<Overlay name = "SCO.BIN" lba_source = "" >../application/bin/%PSX_TV_FORMAT%/PSX-release/Overlay.screen_center</Overlay>
|
<Overlay name = "SCO.BIN" lba_source = "../application/src/Overlay/ScreenCenter/screen_center_assets.cpp" >../application/bin/%PSX_TV_FORMAT%/PSX-release/Overlay.screen_center</Overlay>
|
||||||
|
|
||||||
<Directory name = "ASSETS" hidden = "true">
|
<Directory name = "ASSETS" hidden = "true">
|
||||||
<Directory name = "MAIN">
|
<Directory name = "MAIN">
|
||||||
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
<File name = "TEX.IMG" lz4 = "already">../assets/bin/TexturePage.img</File>
|
<File name = "TEX.IMG" lz4 = "already">../assets/bin/TexturePage.img</File>
|
||||||
<File name = "ICON.IMG" lz4 = "already">../assets/bin/IconTexture.img</File>
|
<File name = "ICON.IMG" lz4 = "already">../assets/bin/IconTexture.img</File>
|
||||||
|
<File name = "SAND.TIM" lz4 = "none">../assets/bin/IMG_6921.tim</File>
|
||||||
</Directory>
|
</Directory>
|
||||||
<Directory name = "XAAUDIO" hidden = "true">
|
<Directory name = "XAAUDIO" hidden = "true">
|
||||||
<InterleavedFile name = "MIX.XA">
|
<InterleavedFile name = "MIX.XA">
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace JabyEngine {
|
||||||
class State {
|
class State {
|
||||||
public:
|
public:
|
||||||
struct Reserved {
|
struct Reserved {
|
||||||
uint32_t reserved[4];
|
uint32_t reserved[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Configuration;
|
struct Configuration;
|
||||||
|
@ -17,6 +17,7 @@ namespace JabyEngine {
|
||||||
|
|
||||||
typedef GenericProcessRoutine<Reserved> ProcessRoutine;
|
typedef GenericProcessRoutine<Reserved> ProcessRoutine;
|
||||||
|
|
||||||
|
// TODO: Better name!!!!
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
ProcessRoutine process_routine = nullptr;
|
ProcessRoutine process_routine = nullptr;
|
||||||
const uint8_t* data_adr = nullptr;
|
const uint8_t* data_adr = nullptr;
|
||||||
|
@ -52,6 +53,7 @@ namespace JabyEngine {
|
||||||
// The nothing state
|
// The nothing state
|
||||||
State create(const uint32_t* data_adr, const Nothing& nothing);
|
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);
|
||||||
|
State create(const uint32_t* data_adr, const TIM& file);
|
||||||
State create(const uint32_t* data_adr, const VAG& file);
|
State create(const uint32_t* data_adr, const VAG& file);
|
||||||
|
|
||||||
State create_custom(const uint32_t* data_adr, const CDFileType_t& file_type, const CDFile::Payload& payload);
|
State create_custom(const uint32_t* data_adr, const CDFileType_t& file_type, const CDFile::Payload& payload);
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace JabyEngine {
|
||||||
enum struct CDFileType : CDFileType_t {
|
enum struct CDFileType : CDFileType_t {
|
||||||
CopyTo = 0,
|
CopyTo = 0,
|
||||||
SimpleTIM,
|
SimpleTIM,
|
||||||
|
SonyTIM,
|
||||||
SonyVAG,
|
SonyVAG,
|
||||||
Custom,
|
Custom,
|
||||||
};
|
};
|
||||||
|
@ -20,6 +21,7 @@ namespace JabyEngine {
|
||||||
RawPayload_t raw;
|
RawPayload_t raw;
|
||||||
CopyTo copy_to;
|
CopyTo copy_to;
|
||||||
SimpleTIM simple_tim;
|
SimpleTIM simple_tim;
|
||||||
|
TIM tim;
|
||||||
VAG vag;
|
VAG vag;
|
||||||
Overlay overlay;
|
Overlay overlay;
|
||||||
};
|
};
|
||||||
|
@ -49,6 +51,10 @@ namespace JabyEngine {
|
||||||
return CDFile{.rel_lba_idx = rel_lba_idx, .type = CDFileType::SimpleTIM, .payload = {.simple_tim = simple_tim}};
|
return CDFile{.rel_lba_idx = rel_lba_idx, .type = CDFileType::SimpleTIM, .payload = {.simple_tim = simple_tim}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr CDFile sony_tim(uint8_t rel_lba_idx, TIM tim) {
|
||||||
|
return CDFile{.rel_lba_idx = rel_lba_idx, .type = CDFileType::SonyTIM, .payload = {.tim = tim}};
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr CDFile sony_vag(uint8_t lba_idx, VAG vag) {
|
static constexpr CDFile sony_vag(uint8_t lba_idx, VAG vag) {
|
||||||
return CDFile{.rel_lba_idx = lba_idx, .type = CDFileType::SonyVAG, .payload = {.vag = vag}};
|
return CDFile{.rel_lba_idx = lba_idx, .type = CDFileType::SonyVAG, .payload = {.vag = vag}};
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,14 @@ namespace JabyEngine {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TIM {
|
||||||
|
uint32_t zero;
|
||||||
|
|
||||||
|
static constexpr TIM create() {
|
||||||
|
return TIM{.zero = 0};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct VAG {
|
struct VAG {
|
||||||
uint8_t voice_number;
|
uint8_t voice_number;
|
||||||
SPU::SimpleVolume inital_stereo_vol;
|
SPU::SimpleVolume inital_stereo_vol;
|
||||||
|
|
|
@ -293,9 +293,9 @@ namespace JabyEngine {
|
||||||
static constexpr POLY_FT4 create(const AreaI16& area, const PageOffset& tex_offset, TPage tpage, PageClut clut, Color24 color = Color24::Grey()) {
|
static constexpr POLY_FT4 create(const AreaI16& area, const PageOffset& tex_offset, TPage tpage, PageClut clut, Color24 color = Color24::Grey()) {
|
||||||
return POLY_FT4::create({
|
return POLY_FT4::create({
|
||||||
{POLY_FT4::vertex0_from(area), tex_offset},
|
{POLY_FT4::vertex0_from(area), tex_offset},
|
||||||
{POLY_FT4::vertex1_from(area), tex_offset.move(area.size.width, 0)},
|
{POLY_FT4::vertex1_from(area), tex_offset.move(area.size.width - 1, 0)},
|
||||||
{POLY_FT4::vertex2_from(area), tex_offset.move(0, area.size.height)},
|
{POLY_FT4::vertex2_from(area), tex_offset.move(0, area.size.height - 1)},
|
||||||
{POLY_FT4::vertex3_from(area), tex_offset.move(area.size.width, area.size.height)}
|
{POLY_FT4::vertex3_from(area), tex_offset.move(area.size.width - 1, area.size.height - 1)}
|
||||||
}, tpage, clut, color);
|
}, tpage, clut, color);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -250,7 +250,7 @@ namespace JabyEngine {
|
||||||
return creator_template<GPU::POLY_FT4>(vertices_ex, tpage, clut, color);
|
return creator_template<GPU::POLY_FT4>(vertices_ex, tpage, clut, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color) {
|
static constexpr GPU::POLY_FT4 POLY_FT4(const GPU::AreaI16& area, const GPU::PageOffset& tex_offset, GPU::TPage tpage, GPU::PageClut clut, GPU::Color24 color = GPU::Color24::Grey()) {
|
||||||
return creator_template<GPU::POLY_FT4>(area, tex_offset, tpage, clut, color);
|
return creator_template<GPU::POLY_FT4>(area, tex_offset, tpage, clut, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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:
|
case CDFileType::SimpleTIM:
|
||||||
return FileProcessor::create(data_adr, file.payload.simple_tim);
|
return FileProcessor::create(data_adr, file.payload.simple_tim);
|
||||||
|
|
||||||
|
case CDFileType::SonyTIM:
|
||||||
|
return FileProcessor::create(data_adr, file.payload.tim);
|
||||||
|
|
||||||
case CDFileType::SonyVAG:
|
case CDFileType::SonyVAG:
|
||||||
return FileProcessor::create(data_adr, file.payload.vag);
|
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
|
|
Loading…
Reference in New Issue