Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add factory for common image format #786

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/graphic/Fast3D/gfx_pc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#endif
#include "graphic/Fast3D/debug/GfxDebugger.h"
#include "libultraship/libultra/types.h"
//#include "libultraship/libultra/gs2dex.h"
// #include "libultraship/libultra/gs2dex.h"
#include <string>

#include "gfx_pc.h"
Expand Down Expand Up @@ -879,6 +879,19 @@ static void import_texture_ci8(int tile, bool importReplacement) {
gfx_rapi->upload_texture(tex_upload_buffer, width, height);
}

static void import_texture_img(int tile, bool importReplacement) {
const RawTexMetadata* metadata = &g_rdp.loaded_texture[g_rdp.texture_tile[tile].tmem_index].raw_tex_metadata;
const uint8_t* addr =
importReplacement && (metadata->resource != nullptr)
? masked_textures.find(gfx_get_base_texture_path(metadata->resource->GetInitData()->Path))
->second.replacementData
: g_rdp.loaded_texture[g_rdp.texture_tile[tile].tmem_index].addr;

uint16_t width = metadata->width;
uint16_t height = metadata->height;
gfx_rapi->upload_texture(addr, width, height);
}

static void import_texture_raw(int tile, bool importReplacement) {
const RawTexMetadata* metadata = &g_rdp.loaded_texture[g_rdp.texture_tile[tile].tmem_index].raw_tex_metadata;
const uint8_t* addr =
Expand Down Expand Up @@ -982,6 +995,11 @@ static void import_texture(int i, int tile, bool importReplacement) {
return;
}

if ((texFlags & TEX_FLAG_LOAD_AS_IMG) != 0) {
import_texture_img(tile, importReplacement);
return;
}

// if load as raw is set then we load_raw();
if ((texFlags & TEX_FLAG_LOAD_AS_RAW) != 0) {
import_texture_raw(tile, importReplacement);
Expand Down
1 change: 1 addition & 0 deletions src/resource/File.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Archive;

#define RESOURCE_FORMAT_BINARY 0
#define RESOURCE_FORMAT_XML 1
#define RESOURCE_FORMAT_IMG 2

struct ResourceInitData {
std::shared_ptr<Archive> Parent;
Expand Down
19 changes: 19 additions & 0 deletions src/resource/ResourceFactoryImg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "ResourceFactoryImg.h"
#include <variant>
#include "spdlog/spdlog.h"

namespace Ship {
bool ResourceFactoryImg::FileHasValidFormatAndReader(std::shared_ptr<File> file) {
if (file->InitData->Format != RESOURCE_FORMAT_IMG) {
SPDLOG_ERROR("resource file format does not match factory format.");
return false;
}

if (!std::holds_alternative<std::shared_ptr<BinaryReader>>(file->Reader)) {
SPDLOG_ERROR("Failed to load resource: File has Reader ({} - {})", file->InitData->Type, file->InitData->Path);
return false;
}

return true;
};
} // namespace Ship
10 changes: 10 additions & 0 deletions src/resource/ResourceFactoryImg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include "ResourceFactory.h"

namespace Ship {
class ResourceFactoryImg : public ResourceFactory {
protected:
bool FileHasValidFormatAndReader(std::shared_ptr<File> file) override;
};
} // namespace Ship
33 changes: 30 additions & 3 deletions src/resource/archive/Archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Context.h"
#include "resource/File.h"
#include "resource/ResourceLoader.h"
#include "resource/ResourceType.h"
#include "utils/binarytools/MemoryStream.h"
#include "utils/glob.h"
#include "utils/StrHash64.h"
Expand Down Expand Up @@ -142,8 +143,13 @@ std::shared_ptr<ResourceInitData> Archive::ReadResourceInitData(const std::strin

std::shared_ptr<ResourceInitData> Archive::ReadResourceInitDataLegacy(const std::string& filePath,
std::shared_ptr<File> fileToLoad) {
// Determine if file is binary or XML...
if (fileToLoad->Buffer->at(0) == '<') {
if (stbi_info_from_memory((const uint8_t*)fileToLoad->Buffer->data(), fileToLoad->Buffer->size(), nullptr, nullptr,
nullptr) != 0) {
auto stream = std::make_shared<MemoryStream>(fileToLoad->Buffer);
auto binaryReader = std::make_shared<BinaryReader>(stream);

return ReadResourceInitDataPng(filePath, binaryReader);
} else if (fileToLoad->Buffer->at(0) == '<') { // Determine if file is binary or XML...
// File is XML
// Read the xml document
auto stream = std::make_shared<MemoryStream>(fileToLoad->Buffer);
Expand Down Expand Up @@ -229,6 +235,7 @@ std::shared_ptr<File> Archive::LoadFile(const std::string& filePath, std::shared

switch (fileToLoad->InitData->Format) {
case RESOURCE_FORMAT_BINARY:
case RESOURCE_FORMAT_IMG:
fileToLoad->Reader = CreateBinaryReader(fileToLoad);
break;
case RESOURCE_FORMAT_XML:
Expand Down Expand Up @@ -264,7 +271,7 @@ std::shared_ptr<ResourceInitData> Archive::ReadResourceInitDataBinary(const std:
resourceInitData->Path = filePath;

if (headerReader == nullptr) {
SPDLOG_ERROR("Error reading OTR header from XML: No header buffer document for file {}", filePath);
SPDLOG_ERROR("Error reading OTR header from Binary: No header buffer document for file {}", filePath);
return resourceInitData;
}

Expand Down Expand Up @@ -320,4 +327,24 @@ std::shared_ptr<ResourceInitData> Archive::ReadResourceInitDataXml(const std::st
return resourceInitData;
}

std::shared_ptr<ResourceInitData> Archive::ReadResourceInitDataPng(const std::string& filePath,
std::shared_ptr<BinaryReader> headerReader) {
auto resourceInitData = CreateDefaultResourceInitData();
resourceInitData->Path = filePath;

if (headerReader == nullptr) {
SPDLOG_ERROR("Error reading OTR header from XML: No header buffer document for file {}", filePath);
return resourceInitData;
}

resourceInitData->IsCustom = true;
resourceInitData->Format = RESOURCE_FORMAT_IMG;
resourceInitData->Type =
Context::GetInstance()->GetResourceManager()->GetResourceLoader()->GetResourceType("Texture");
resourceInitData->ResourceVersion = 0;

headerReader->Seek(0, SeekOffsetType::Start);
return resourceInitData;
}

} // namespace Ship
2 changes: 2 additions & 0 deletions src/resource/archive/Archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class Archive : public std::enable_shared_from_this<Archive> {
std::shared_ptr<BinaryReader> headerReader);
static std::shared_ptr<ResourceInitData> ReadResourceInitDataXml(const std::string& filePath,
std::shared_ptr<tinyxml2::XMLDocument> document);
static std::shared_ptr<ResourceInitData> ReadResourceInitDataPng(const std::string& filePath,
std::shared_ptr<BinaryReader> headerReader);
std::shared_ptr<BinaryReader> CreateBinaryReader(std::shared_ptr<File> fileToLoad);
std::shared_ptr<tinyxml2::XMLDocument> CreateXMLReader(std::shared_ptr<File> fileToLoad);

Expand Down
40 changes: 40 additions & 0 deletions src/resource/factory/PngFactory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "resource/factory/PngFactory.h"
#include "resource/type/Texture.h"
#include "spdlog/spdlog.h"

#include <stb_image.h>

namespace Fast {

std::shared_ptr<Ship::IResource> ResourceFactoryImageTexture::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}

auto texture = std::make_shared<Texture>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);

auto callback = stbi_io_callbacks{ [](void* user, char* data, int size) {
auto reader = static_cast<Ship::BinaryReader*>(user);
reader->Read(data, size);
return size;
},
[](void* user, int size) {
auto reader = static_cast<Ship::BinaryReader*>(user);
reader->Seek(size, Ship::SeekOffsetType::Current);
},
[](void* user) { return 0; } };
int height, width = 0;

texture->ImageData = stbi_load_from_callbacks(&callback, reader.get(), &width, &height, nullptr, 4);

texture->Width = width;
texture->Height = height;
texture->Type = TextureType::RGBA32bpp;
texture->ImageDataSize = texture->Width * texture->Height * 4;
texture->Flags = TEX_FLAG_LOAD_AS_IMG;

return texture;
}

} // namespace Fast
11 changes: 11 additions & 0 deletions src/resource/factory/PngFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include "resource/Resource.h"
#include "resource/ResourceFactoryImg.h"

namespace Fast {
class ResourceFactoryImageTexture : public Ship::ResourceFactoryImg {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
} // namespace Fast
1 change: 1 addition & 0 deletions src/resource/type/Texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "resource/Resource.h"

#define TEX_FLAG_LOAD_AS_RAW (1 << 0)
#define TEX_FLAG_LOAD_AS_IMG (1 << 1)

namespace Fast {
enum class TextureType {
Expand Down
Loading