diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..6b7bc6a --- /dev/null +++ b/.clang-format @@ -0,0 +1,321 @@ +--- +Language: Cpp +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: true + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseArrows: false + AlignCaseColons: false +AlignConsecutiveTableGenBreakingDAGArgColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveTableGenCondOperatorColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveTableGenDefinitionColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Never +AllowShortCaseExpressionOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AllowShortNamespacesOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: BinPack +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakAfterReturnType: None +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakBinaryOperations: Never +BreakConstructorInitializers: BeforeColon +BreakFunctionDefinitionParameters: false +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +BreakTemplateDeclarations: Yes +ColumnLimit: 80 +CommentPragmas: "^ IWYU pragma:" +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: "^<.*" + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: ".*" + Priority: 3 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: "([-_](test|unittest))?$" +IncludeIsMainSourceRegex: "" +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: true +IndentExportBlock: true +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLines: + AtEndOfFile: false + AtStartOfBlock: false + AtStartOfFile: true +KeepFormFeed: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: "" +MacroBlockEnd: "" +MainIncludeChar: Quote +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: NextLine +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakBeforeMemberAccess: 150 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - "c++" + - "C++" + CanonicalDelimiter: "" + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: pb + BasedOnStyle: google +ReferenceAlignment: Pointer +ReflowComments: Always +RemoveBracesLLVM: false +RemoveEmptyLinesInUnwrappedLines: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + ExceptDoubleParentheses: false + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Auto +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TableGenBreakInsideDAGArg: DontBreak +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +WrapNamespaceBodyWithEmptyLines: Leave +... diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e2a0c3..242b7d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,18 +29,13 @@ add_library(ctrff STATIC source/binutil.cpp source/helper.cpp source/lz11.cpp + source/pica.cpp source/smdh.cpp ) target_include_directories(ctrff PUBLIC include) if(${CTRFF_DESKTOP}) - add_subdirectory(vendor/palladium) - add_executable(ctrff-cli tool/main.cpp) - target_include_directories(ctrff-cli PUBLIC include vendor/stb vendor/cli-fancy/include) - target_link_libraries(ctrff-cli PUBLIC ctrff palladium) - add_executable(test tool/test.cpp) - target_include_directories(test PUBLIC include vendor/stb vendor/cli-fancy/include) - target_link_libraries(test PUBLIC ctrff) + add_subdirectory(tools) endif() install(TARGETS ctrff) diff --git a/include/ctrff.hpp b/include/ctrff.hpp index cac186f..4f1e3b7 100644 --- a/include/ctrff.hpp +++ b/include/ctrff.hpp @@ -6,4 +6,5 @@ #include #include #include +#include #include \ No newline at end of file diff --git a/include/ctrff/bclim.hpp b/include/ctrff/bclim.hpp index b7db170..8055e46 100644 --- a/include/ctrff/bclim.hpp +++ b/include/ctrff/bclim.hpp @@ -9,24 +9,24 @@ namespace ctrff { class CTRFF_API BCLIM : public BinFile { public: - BCLIM() {} + BCLIM() : pCurrent(Header::Default()), pImag(ImagHeader::Default()) {} ~BCLIM() {} enum Format : u32 { - L8, + L8, // tested A8, // tested LA4, LA8, HILO8, RGB565, // tested - RGB888, + RGB888, // tested RGBA5551, RGBA4444, RGBA8888, // tested ETC1, ETC1A4, - L4, - A4, + L4, // tested + A4, // tested }; struct Header { diff --git a/include/ctrff/helper.hpp b/include/ctrff/helper.hpp index 2e2d686..727bd56 100644 --- a/include/ctrff/helper.hpp +++ b/include/ctrff/helper.hpp @@ -5,7 +5,7 @@ namespace ctrff { CTRFF_API void String2U16(ctrff::u16 *res, const std::string &src, size_t max); CTRFF_API std::string U16toU8(ctrff::u16 *in, size_t max); -CTRFF_API void RGB565toRGBA(std::vector &img, ctrff::u16 *icon, +CTRFF_API void RGB565toRGBA(std::vector &img, const ctrff::u16 *icon, const int &w, const int &h); // Image can only be rgba8888 CTRFF_API void RGBA2RGB565(ctrff::u16 *out, const std::vector &img, diff --git a/include/ctrff/pica.hpp b/include/ctrff/pica.hpp new file mode 100644 index 0000000..d1a5cfc --- /dev/null +++ b/include/ctrff/pica.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include + +/** + * 3ds GPU Stuff + */ + +namespace ctrff { +namespace Pica { +enum Color : u32 { + L8, // tested + A8, // tested + LA4, + LA8, + HILO8, + RGB565, // tested + RGB888, // tested + RGBA5551, + RGBA4444, + RGBA8888, // tested + ETC1, + ETC1A4, + L4, // tested + A4, // tested +}; +CTRFF_API void EncodeImage(std::vector& ret, + std::vector rgba, int w, int h, + Color dst); +CTRFF_API void DecodeImage(std::vector& ret, + std::vector pixels, int w, int h, + Color src); +} // namespace Pica +} // namespace ctrff \ No newline at end of file diff --git a/source/helper.cpp b/source/helper.cpp index d6fc264..dbdd816 100644 --- a/source/helper.cpp +++ b/source/helper.cpp @@ -28,7 +28,7 @@ CTRFF_API ctrff::u32 ctrff::TileIndex(const int &x, const int &y, // TODO: Fix colors CTRFF_API void ctrff::RGB565toRGBA(std::vector &img, - ctrff::u16 *icon, const int &w, + const ctrff::u16 *icon, const int &w, const int &h) { if (img.size() != (w * h * 4)) { img.clear(); diff --git a/source/pica.cpp b/source/pica.cpp new file mode 100644 index 0000000..8e9716e --- /dev/null +++ b/source/pica.cpp @@ -0,0 +1,197 @@ +#include +#include + +namespace ctrff { +namespace Pica { +CTRFF_API void EncodeImage(std::vector& ret, + std::vector rgba, int w, int h, + Color dst_color) { + // Only used in rgb/rgba + int bpp = dst_color == RGBA8888 ? 4 : 3; + switch (dst_color) { + case RGB565: + ret.resize(w * h * 2); + ctrff::RGBA2RGB565(reinterpret_cast(ret.data()), rgba, w, h); + break; + case RGB888: + case RGBA8888: + ret.resize(w * h * bpp); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int src = (y * w + x) * 4; // basic rgba indexing btw + int dst = ctrff::TileIndex(x, y, w) * bpp; + for (int i = 0; i < bpp; i++) { + ret[dst + bpp - 1 - i] = rgba[src + i]; + } + } + } + break; + case A8: + ret.resize(w * h); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int src = (y * w + x) * 4; // basic rgba indexing btw + int dst = ctrff::TileIndex(x, y, w); + ret[dst] = rgba[src + 3]; // extract alpha only + } + } + break; + case A4: + ret.resize((w * h) >> 1); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int src = (y * w + x) * 4; // basic rgba indexing btw + int dst = ctrff::TileIndex(x, y, w); + ctrff::u8 tmp = rgba[src + 3] >> 4; + int a4pos = dst >> 1; + if ((dst & 1) == 0) { + ret[a4pos] = (tmp << 4) | (ret[a4pos] & 0x0f); + } else { + ret[a4pos] = (ret[a4pos] & 0xf0) | tmp; + } + } + } + break; + case L8: + ret.resize(w * h); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int src = (y * w + x) * 4; // basic rgba indexing btw + int dst = ctrff::TileIndex(x, y, w); + // Basic luminance calculation (already used in renderd7) + ret[dst] = + (rgba[src + 0] * 77 + rgba[src + 1] * 150 + rgba[src + 2] * 29) >> + 8; + } + } + break; + case L4: + ret.resize((w * h) >> 1); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int src = (y * w + x) * 4; // basic rgba indexing btw + int dst = ctrff::TileIndex(x, y, w); + // Basically same as a4 just with the luminance calculation func + ctrff::u8 tmp = ((rgba[src + 0] * 77 + rgba[src + 1] * 150 + + rgba[src + 2] * 29) >> + 8) >> + 4; + int a4pos = dst >> 1; + if ((dst & 1) == 0) { + ret[a4pos] = (tmp << 4) | (ret[a4pos] & 0x0f); + } else { + ret[a4pos] = (ret[a4pos] & 0xf0) | tmp; + } + } + } + break; + + default: + throw std::runtime_error("[ctrff] Pica: Unsupported Color format: " + + std::to_string((int)dst_color)); + break; + } +} + +CTRFF_API void DecodeImage(std::vector& ret, + std::vector pixels, int w, int h, + Color src_color) { + switch (src_color) { + case RGB565: + ret.resize(w * h * 4); + ctrff::RGB565toRGBA( + ret, reinterpret_cast(pixels.data()), w, h); + break; + case RGB888: + case RGBA8888: + ret.resize(w * h * 4); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int bpp = src_color == RGBA8888 ? 4 : 3; + int src = ctrff::TileIndex(x, y, w) * bpp; + int dst = (y * w + x) * 4; // basic rgba indexing btw + for (int i = 0; i < bpp; i++) { + ret[dst + i] = pixels[src + bpp - 1 - i]; + } + if (src_color == RGB888) { + ret[dst + 3] = 255; + } + } + } + break; + case A8: + ret.resize(w * h * 4); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int src = ctrff::TileIndex(x, y, w); + int dst = (y * w + x) * 4; + ret[dst + 0] = 255; + ret[dst + 1] = 255; + ret[dst + 2] = 255; + ret[dst + 3] = pixels[src]; + } + } + break; + case A4: // most hated by me (tobid7) + ret.resize(w * h * 4); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int src = ctrff::TileIndex(x, y, w); + int dst = (y * w + x) * 4; + /** + * Basically checking by %2 aka &1 if we have a high or low nibble + * by this we either extract the high or low one and multiply + * by 17 aka 0x11 to get the resulting A8 Value + */ + ctrff::u8 a4 = src & 1 ? ((pixels[src >> 1] >> 4) & 0xf) * 0x11 + : (pixels[src >> 1] & 0xf) * 0x11; + ret[dst + 0] = 255; + ret[dst + 1] = 255; + ret[dst + 2] = 255; + ret[dst + 3] = a4; + } + } + break; + case L4: // most hated by me (tobid7) + ret.resize(w * h * 4); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int src = ctrff::TileIndex(x, y, w); + int dst = (y * w + x) * 4; + /** + * Same as A4 + * Basically checking by %2 aka &1 if we have a high or low nibble + * by this we either extract the high or low one and multiply + * by 17 aka 0x11 to get the resulting A8 Value + */ + ctrff::u8 a4 = src & 1 ? ((ret[src >> 1] >> 4) & 0xf) * 0x11 + : (ret[src >> 1] & 0xf) * 0x11; + pixels[dst + 0] = a4; + pixels[dst + 1] = a4; + pixels[dst + 2] = a4; + pixels[dst + 3] = 255; + } + } + break; + case L8: + ret.resize(w * h * 4); + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int src = ctrff::TileIndex(x, y, w); + int dst = (y * w + x) * 4; + ret[dst + 0] = pixels[src]; + ret[dst + 1] = pixels[src]; + ret[dst + 2] = pixels[src]; + ret[dst + 3] = 255; + } + } + break; + + default: + throw std::runtime_error("[ctrff] Pica: Unsupported Color format: " + + std::to_string((int)src_color)); + break; + } +} +} // namespace Pica +} // namespace ctrff \ No newline at end of file diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 0000000..fb87720 --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.22) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/palladium palladium) + +add_subdirectory(ctrff) diff --git a/tools/ctrff/CMakeLists.txt b/tools/ctrff/CMakeLists.txt new file mode 100644 index 0000000..9cbd148 --- /dev/null +++ b/tools/ctrff/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.22) + +project(ctrff-cli) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED true) + +add_executable(ctrff-cli source/main.cpp) +target_include_directories(ctrff-cli PUBLIC include + ${CMAKE_CURRENT_SOURCE_DIR}/../../vendor/stb + ${CMAKE_CURRENT_SOURCE_DIR}/../../vendor/cli-fancy/include +) +target_link_libraries(ctrff-cli PUBLIC ctrff palladium) + +add_executable(test source/test.cpp) +target_include_directories(test PUBLIC include + ${CMAKE_CURRENT_SOURCE_DIR}/../../vendor/stb + ${CMAKE_CURRENT_SOURCE_DIR}/../../vendor/cli-fancy/include +) +target_link_libraries(test PUBLIC ctrff) + +install(TARGETS ctrff-cli) diff --git a/tool/main.cpp b/tools/ctrff/source/main.cpp similarity index 91% rename from tool/main.cpp rename to tools/ctrff/source/main.cpp index d0ed391..c97ff15 100644 --- a/tool/main.cpp +++ b/tools/ctrff/source/main.cpp @@ -10,7 +10,6 @@ #include /** Import palladium stb image */ -#define STB_IMAGE_IMPLEMENTATION #include #define STB_IMAGE_WRITE_IMPLEMENTATION #include @@ -432,7 +431,12 @@ void LZ11Compress(const cf7::command::ArgumentList &data) { std::make_pair(i, cf7::col(255, 210, 0)), std::make_pair(FormatBytes(buf.size()), cf7::col(255, 255, 0)), }); - auto res = ctrff::LZ11::Compress(buf); + std::vector res; + if (buf[0] == 0x11) { + res = ctrff::LZ11::Decompress(buf); + } else { + res = ctrff::LZ11::Compress(buf); + } cf7::PrintFancy({ std::make_pair("Output", cf7::col(255, 165, 0)), std::make_pair(o, cf7::col(255, 210, 0)), @@ -451,61 +455,41 @@ void BCLIMMaker(const cf7::command::ArgumentList &data) { std::cout << "[ctrff] BCLIM: Error, no input or output" << std::endl; return; } - if (f.empty() || (f.compare("rgba32") != 0 && f.compare("a8") != 0 && - f.compare("rgb565") != 0)) { - f = "a8"; - } - int w = 0, h = 0, c = 0; - auto ret = stbi_load(i.c_str(), &w, &h, &c, 4); - if (!ret) { + PD::Image::Ref img = PD::Image::New(); + img->Load(i); + if (img->GetBuffer().empty()) { std::cout << "[ctrff] BCLIM: Failed to load image " + i << std::endl; return; } - if (!PD::BitUtil::IsSingleBit(w) || !PD::BitUtil::IsSingleBit(h)) { + if (!PD::BitUtil::IsSingleBit(img->Width()) || + !PD::BitUtil::IsSingleBit(img->Height())) { std::cout << "[ctrff] BCLIM: Image with and height must be a power of 8!"; return; } - size_t size = w * h; - if (f == "rgba32") { - size *= 4; + img->Convert(img, img->RGBA); + std::vector res; + ctrff::Pica::Color fmt = ctrff::Pica::A8; + if (f == "a4") { + fmt = ctrff::Pica::A4; + } else if (f == "l4") { + fmt = ctrff::Pica::L4; + } else if (f == "a8") { + fmt = ctrff::Pica::L8; + } else if (f == "l8") { + fmt = ctrff::Pica::L8; } else if (f == "rgb565") { - size *= 2; - } - std::vector res(size); - if (f == "rgba32" || f == "a8") { - for (int x = 0; x < w; x++) { - for (int y = 0; y < h; y++) { - int src = (y * w + x) * 4; - int dst = ctrff::TileIndex(x, y, w); - if (f == "rgba32") { - dst *= 4; - res[dst + 3] = ret[src + 0]; - res[dst + 2] = ret[src + 1]; - res[dst + 1] = ret[src + 2]; - res[dst + 0] = ret[src + 3]; - } else { - res[dst] = ret[src + 3]; - } - } - } - } else if (f == "rgb565") { - std::vector res16(w * h); - ctrff::RGBA2RGB565(res16.data(), - std::vector(ret, ret + (w * h * 4)), w, h); - for (int i = 0; i < res16.size(); i++) { - int pos = i * 2; - res[pos] = (ctrff::u8)(res16[i] & 0xff); - res[pos + 1] = (ctrff::u8)((res16[i] >> 8) & 0xff); - } + fmt = ctrff::Pica::RGB565; + } else if (f == "rgb888") { + fmt = ctrff::Pica::RGB888; + } else if (f == "rgba8888") { + fmt = ctrff::Pica::RGBA8888; } + ctrff::Pica::EncodeImage(res, img->GetBuffer(), img->Width(), img->Height(), + fmt); + ctrff::BCLIM file; - ctrff::BCLIM::Format fmt = ctrff::BCLIM::A8; - if (f == "rgba32") { - fmt = ctrff::BCLIM::RGBA8888; - } else if (f == "rgb565") { - fmt = ctrff::BCLIM::RGB565; - } - file.CreateByImage(res, w, h, fmt); + ctrff::BCLIM::Format _fmt = (ctrff::BCLIM::Format)fmt; + file.CreateByImage(res, img->Width(), img->Height(), _fmt); file.Save(o); std::cout << "File " + o + " created" << std::endl; } @@ -556,7 +540,7 @@ int main(int argc, char *argv[]) { "Output icon path!", false)) .SetFunction(Read3DSX)); mgr.AddCommand( - cf7::command("lz11", "Creates a LZ11 Compressed File") + cf7::command("lz11", "Compress/Decompress a file with LZ11") .AddSubEntry(cf7::command::sub("i", "input", "Input file path", true)) .AddSubEntry( cf7::command::sub("o", "output", "Output file path", true)) @@ -570,8 +554,9 @@ int main(int argc, char *argv[]) { .AddSubEntry(cf7::command::sub("i", "input", "Input png|bmp", true)) .AddSubEntry(cf7::command::sub("o", "output", "Output path of .bclim file", true)) - .AddSubEntry(cf7::command::sub("f", "format", - "Image format rgba32|rgb565|a8", true)) + .AddSubEntry(cf7::command::sub( + "f", "format", "Image format rgba8888|rgb888|rgb565|a8|l8|a4|l4", + false)) .SetFunction(BCLIMMaker)); mgr.Execute(); return 0; diff --git a/tool/test.cpp b/tools/ctrff/source/test.cpp similarity index 100% rename from tool/test.cpp rename to tools/ctrff/source/test.cpp diff --git a/vendor/palladium b/vendor/palladium index 3575a67..eb5d5f9 160000 --- a/vendor/palladium +++ b/vendor/palladium @@ -1 +1 @@ -Subproject commit 3575a6787d85115ab88e4f159d0bba9cfbba5ad8 +Subproject commit eb5d5f99743bccfa42d589a9e078c0e2cbecbaa0