diff --git a/.github/workflows/branch-build.yml b/.github/workflows/branch-build.yml index fc60f55..a303edf 100644 --- a/.github/workflows/branch-build.yml +++ b/.github/workflows/branch-build.yml @@ -11,14 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Dependencies - run: | - sudo apt update && sudo apt install -y gcc-12 g++-12 make ragel lemon cmake + run: sudo apt update && sudo apt install -y gcc-12 g++-12 make ragel lemon cmake - name: Checkout Repository uses: actions/checkout@v3 - name: Configure CMake - run: CC=gcc-12 CXX=g++-12 cmake -B ${{github.workspace}}/build + run: CC=gcc-12 CXX=g++-12 cmake -DDISABLE_CLANG_TIDY=YES -B ${{github.workspace}}/build - name: Build run: cmake --build ${{github.workspace}}/build diff --git a/.github/workflows/master-release.yml b/.github/workflows/master-release.yml index b6bf53c..a94a596 100644 --- a/.github/workflows/master-release.yml +++ b/.github/workflows/master-release.yml @@ -27,7 +27,7 @@ jobs: - run: git fetch --tags - name: Configure CMake - run: CC=gcc-12 CXX=g++-12 cmake -B ${{github.workspace}}/build + run: CC=gcc-12 CXX=g++-12 cmake -DDISABLE_CLANG_TIDY=YES -B ${{github.workspace}}/build - name: Build run: cmake --build ${{github.workspace}}/build diff --git a/CMakeLists.txt b/CMakeLists.txt index 945fb1b..b974f1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,15 @@ project(gifscript CXX) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}) +# Using CMAKE_CXX_STANDARD doesn't work for GCC... +# This also doesn't work for Clang 14... +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CPP_23_ARG "-std=c++2b") +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CPP_23_ARG "-std=c++23") +endif() find_package(RAGEL REQUIRED) @@ -25,6 +31,12 @@ FetchContent_Declare(fmt ) FetchContent_MakeAvailable(fmt) +if(NOT WIN32) +find_program(CLANG_TIDY_EXE NAMES "clang-tidy") + if(CLANG_TIDY_EXE AND NOT DISABLE_CLANG_TIDY AND NOT WIN32) + set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=-*,readability-*,modernize-*,performance-*,portability-*,bugprone-*,clang-analyzer-*) + endif() +endif() RAGEL_TARGET(gifscript ${CMAKE_SOURCE_DIR}/gifscript.rl @@ -32,6 +44,12 @@ RAGEL_TARGET(gifscript COMPILE_FLAGS -G2 ) +set(GENERATED_SOURCES + parser.h + parser.c + ${RAGEL_gifscript_OUTPUTS} +) + set(BACKEND_SOURCES backend/backend.hpp backend/c_code.cpp @@ -41,16 +59,17 @@ set(BACKEND_SOURCES set(CORE_SOURCES version.h logger.h - parser.h - parser.c machine.h machine.cpp registers.h registers.cpp - ${RAGEL_gifscript_OUTPUTS} ) -add_executable(gifscript ${BACKEND_SOURCES} ${CORE_SOURCES}) +add_executable(gifscript ${BACKEND_SOURCES} ${CORE_SOURCES} ${GENERATED_SOURCES}) + +set_source_files_properties(${GENERATED_SOURCES} PROPERTIES + SKIP_LINTING ON + ) if(WIN32) target_compile_options(gifscript PRIVATE /std:c++latest) @@ -63,7 +82,7 @@ else() ) string(CONCAT GIT_VERSION "\"" ${GIT_VERSION} "\"") message("git version: ${GIT_VERSION}") - target_compile_options(gifscript PRIVATE -DGIT_VERSION=${GIT_VERSION} -std=c++23 -Wall -Werror -Wno-unused-const-variable) + target_compile_options(gifscript PRIVATE -DGIT_VERSION=${GIT_VERSION} -Wall -Werror -Wno-unused-const-variable ${CPP_23_ARG}) endif() target_include_directories(gifscript PRIVATE ${CMAKE_SOURCE_DIR}) diff --git a/backend/c_code.cpp b/backend/c_code.cpp index dda473c..0e4b4d6 100644 --- a/backend/c_code.cpp +++ b/backend/c_code.cpp @@ -4,12 +4,7 @@ #include #include "logger.h" - -c_code_backend::c_code_backend() noexcept -{ -} - -bool c_code_backend::arg_parse(int argc, char** argv) +auto c_code_backend::arg_parse(int argc, char** argv) -> bool { for(int i = 0; i < argc; i++) { @@ -81,14 +76,15 @@ void c_code_backend::emit(GIFBlock& block) } } + const size_t bytes_per_register = 16; std::string buffer = fmt::format("u64 {1}_data_size = {0};\n" "u64 {1}_data[] __attribute__((aligned(16))) = {{\n\t" "GIF_SET_TAG({2},1,{3},{4},0,1),GIF_REG_AD,\n\t", - (block.registers.size() + 1) * 16, block.name, block.registers.size(), block.prim ? 1 : 0, block.prim ? prim_str : "0"); + (block.registers.size() + 1) * bytes_per_register, block.name, block.registers.size(), block.prim ? 1 : 0, block.prim ? prim_str : "0"); fmt::print("Emitting block: {}\n", block.name); for(const auto& reg : block.registers) { - buffer += dispatch_table[reg->GetID()](this, *reg); + buffer += dispatch_table[static_cast(reg->GetID())](this, *reg); buffer += "\n\t"; } @@ -105,11 +101,12 @@ void c_code_backend::emit(GIFBlock& block) else { file = fopen(output.c_str(), "w"); - if(file == nullptr) - { - logger::error("Failed to open file: %s\n", output.cbegin()); - return; - } + } + + if(file == nullptr) + { + logger::error("Failed to open file: %s\n", output.cbegin()); + return; } const std::string prologue = "#include \n#include \n#include \n"; fwrite(prologue.c_str(), 1, prologue.size(), file); @@ -118,10 +115,9 @@ void c_code_backend::emit(GIFBlock& block) fwrite(buffer.c_str(), 1, buffer.size(), file); } - -std::string c_code_backend::emit_primitive(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_primitive(c_code_backend* inst, const GifRegister& reg) -> std::string { - const PRIM& prim = dynamic_cast(reg); + const auto& prim = dynamic_cast(reg); if(inst->emit_mode == EmitMode::USE_DEFS) { return fmt::format("GS_SET_PRIM({},{},{},{},0,{},GS_ENABLE,0,0),GS_REG_PRIM,", @@ -131,20 +127,18 @@ std::string c_code_backend::emit_primitive(c_code_backend* inst, const GifRegist prim.IsFogging() ? "GS_ENABLE" : "GS_DISABLE", prim.IsAA1() ? "GS_ENABLE" : "GS_DISABLE"); } - else - { - return fmt::format("GS_SET_PRIM({},{:d},{:d},{:d},0,{:d},1,0,0),0x00,", - static_cast(prim.GetType()), - prim.IsGouraud(), - prim.IsTextured(), - prim.IsFogging(), - prim.IsAA1()); - } + + return fmt::format("GS_SET_PRIM({},{:d},{:d},{:d},0,{:d},1,0,0),0x00,", + static_cast(prim.GetType()), + prim.IsGouraud(), + prim.IsTextured(), + prim.IsFogging(), + prim.IsAA1()); } -std::string c_code_backend::emit_rgbaq(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_rgbaq(c_code_backend* inst, const GifRegister& reg) -> std::string { - const RGBAQ& rgbaq = dynamic_cast(reg); + const auto& rgbaq = dynamic_cast(reg); auto val = rgbaq.GetValue(); @@ -152,19 +146,19 @@ std::string c_code_backend::emit_rgbaq(c_code_backend* inst, const GifRegister& val.x, val.y, val.z, val.w, 0, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_RGBAQ" : "0x01"); } -std::string c_code_backend::emit_uv(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_uv(c_code_backend* inst, const GifRegister& reg) -> std::string { - const UV& uv = dynamic_cast(reg); + const auto& uv_reg = dynamic_cast(reg); - auto val = uv.GetValue(); + auto val = uv_reg.GetValue(); return fmt::format("GS_SET_UV({}<<4,{}<<4),{},", val.x, val.y, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_UV" : "0x03"); } -std::string c_code_backend::emit_xyz2(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_xyz2(c_code_backend* inst, const GifRegister& reg) -> std::string { - const XYZ2& xyz2 = dynamic_cast(reg); + const auto& xyz2 = dynamic_cast(reg); auto val = xyz2.GetValue(); @@ -172,9 +166,9 @@ std::string c_code_backend::emit_xyz2(c_code_backend* inst, const GifRegister& r val.x, val.y, val.z, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_XYZ2" : "0x05"); } -std::string c_code_backend::emit_tex0(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_tex0(c_code_backend* inst, const GifRegister& reg) -> std::string { - const TEX0& tex0 = dynamic_cast(reg); + const auto& tex0 = dynamic_cast(reg); if(inst->emit_mode == EmitMode::USE_DEFS) { @@ -197,17 +191,15 @@ std::string c_code_backend::emit_tex0(c_code_backend* inst, const GifRegister& r tex0.GetTBP(), tex0.GetTBW(), PSM_STR, tex0.GetTW(), tex0.GetTH(), tex0.GetTCC(), static_cast(tex0.GetTFX())); } - else - { - return fmt::format("GS_SET_TEX0(0x{:02x},0x{:02x},{},{:02x},{:02x},{:d},{},0,0,0,0,0),0x06,", - tex0.GetTBP(), tex0.GetTBW(), static_cast(tex0.GetPSM()), - tex0.GetTW(), tex0.GetTH(), tex0.GetTCC(), static_cast(tex0.GetTFX())); - } + + return fmt::format("GS_SET_TEX0(0x{:02x},0x{:02x},{},{:02x},{:02x},{:d},{},0,0,0,0,0),0x06,", + tex0.GetTBP(), tex0.GetTBW(), static_cast(tex0.GetPSM()), + tex0.GetTW(), tex0.GetTH(), tex0.GetTCC(), static_cast(tex0.GetTFX())); } -std::string c_code_backend::emit_fog(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_fog(c_code_backend* inst, const GifRegister& reg) -> std::string { - const FOG& fog = dynamic_cast(reg); + const auto& fog = dynamic_cast(reg); auto val = fog.GetValue(); @@ -215,9 +207,9 @@ std::string c_code_backend::emit_fog(c_code_backend* inst, const GifRegister& re val, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_FOG" : "0x0A"); } -std::string c_code_backend::emit_fogcol(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_fogcol(c_code_backend* inst, const GifRegister& reg) -> std::string { - const FOGCOL& fogcol = dynamic_cast(reg); + const auto& fogcol = dynamic_cast(reg); auto val = fogcol.GetValue(); @@ -225,9 +217,9 @@ std::string c_code_backend::emit_fogcol(c_code_backend* inst, const GifRegister& val.x, val.y, val.z, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_FOGCOL" : "0x3D"); } -std::string c_code_backend::emit_scissor(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_scissor(c_code_backend* inst, const GifRegister& reg) -> std::string { - const SCISSOR& scissor = dynamic_cast(reg); + const auto& scissor = dynamic_cast(reg); auto val = scissor.GetValue(); @@ -235,9 +227,9 @@ std::string c_code_backend::emit_scissor(c_code_backend* inst, const GifRegister val.x, val.y, val.z, val.w, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_SCISSOR" : "0x40"); } -std::string c_code_backend::emit_signal(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_signal(c_code_backend* inst, const GifRegister& reg) -> std::string { - const SIGNAL& signal = dynamic_cast(reg); + const auto& signal = dynamic_cast(reg); auto val = signal.GetValue(); @@ -245,24 +237,22 @@ std::string c_code_backend::emit_signal(c_code_backend* inst, const GifRegister& val.x, val.y, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_SIGNAL" : "0x60"); } -std::string c_code_backend::emit_finish(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_finish(c_code_backend* inst, const GifRegister& reg) -> std::string { - const FINISH& finish = dynamic_cast(reg); + const auto& finish = dynamic_cast(reg); auto val = finish.GetValue(); if(inst->emit_mode == EmitMode::USE_DEFS) { return fmt::format("GS_SET_FINISH({}),GS_REG_FINISH,", val); } - else - { - return fmt::format("0x{:x},{},", val, "0x61"); - } + + return fmt::format("0x{:x},{},", val, "0x61"); } -std::string c_code_backend::emit_label(c_code_backend* inst, const GifRegister& reg) +auto c_code_backend::emit_label(c_code_backend* inst, const GifRegister& reg) -> std::string { - const LABEL& label = dynamic_cast(reg); + const auto& label = dynamic_cast(reg); auto val = label.GetValue(); diff --git a/backend/c_code.h b/backend/c_code.h index eeb757c..95c7038 100644 --- a/backend/c_code.h +++ b/backend/c_code.h @@ -19,7 +19,7 @@ class c_code_backend : public Backend }; public: - c_code_backend() noexcept; + c_code_backend() = default; ~c_code_backend(); bool arg_parse(int argc, char** argv) override; diff --git a/gifscript.rl b/gifscript.rl index d075d6d..2315ade 100644 --- a/gifscript.rl +++ b/gifscript.rl @@ -1,7 +1,7 @@ #include "version.h" -#include -#include +#include +#include #include #include #include diff --git a/machine.cpp b/machine.cpp index 1bd1f58..ae55a1a 100644 --- a/machine.cpp +++ b/machine.cpp @@ -7,7 +7,7 @@ Machine machine; -bool Machine::TryStartBlock(const std::string& name) +auto Machine::TryStartBlock(const std::string& name) -> bool { if(HasCurrentBlock()) [[unlikely]] { @@ -35,14 +35,14 @@ bool Machine::TryStartBlock(const std::string& name) return false; } - blocks.push_back(GIFBlock(name)); + blocks.emplace_back(name); // Questionable usage of end and iterators here... currentBlockIt = --blocks.end(); return true; } } -bool Machine::TryStartMacro(const std::string& name) +auto Machine::TryStartMacro(const std::string& name) -> bool { if(HasCurrentMacro()) [[unlikely]] { @@ -76,7 +76,7 @@ bool Machine::TryStartMacro(const std::string& name) } } -bool Machine::TryEndBlockMacro() +auto Machine::TryEndBlockMacro() -> bool { if(HasCurrentBlock()) { @@ -85,96 +85,90 @@ bool Machine::TryEndBlockMacro() currentBlockIt = blocks.end(); return true; } - else if(HasCurrentMacro()) + + if(HasCurrentMacro()) { currentMacroIt = macros.end(); return true; } - else [[unlikely]] - { - logger::error("No block to end\n"); - return false; - } + + [[unlikely]] logger::error("No block to end\n"); + return false; } -bool Machine::TryInsertMacro(const std::string& name) +auto Machine::TryInsertMacro(const std::string& name) -> bool { if(!HasCurrentBlockOrMacro()) [[unlikely]] { logger::error("No block or macro to insert macro into\n"); return false; } - else - { - const auto& macro = macros.find(name); - if(macro != macros.end()) - { - for(const auto& reg : macro->second.registers) - { - CurrentBlockMacro().registers.push_back(reg->Clone()); - } - return true; - } - else + const auto& macro = macros.find(name); + if(macro != macros.end()) + { + for(const auto& reg : macro->second.registers) { - logger::error("Macro with name %s does not exist\n", name.c_str()); - return false; + CurrentBlockMacro().registers.push_back(reg->Clone()); } + + return true; } + + [[unlikely]] logger::error("Macro with name %s does not exist\n", name.c_str()); + return false; } -bool Machine::TryInsertMacro(const std::string& name, Vec2 v) +auto Machine::TryInsertMacro(const std::string& name, Vec2 xyOffset) -> bool { if(!HasCurrentBlockOrMacro()) [[unlikely]] { logger::error("No block or macro to insert macro into\n"); return false; } - else + + const auto& macro = macros.find(name); + if(macro != macros.end()) [[likely]] { - const auto& macro = macros.find(name); - if(macro != macros.end()) + GIFBlock tmpMacro = macro->second; + for(const auto& reg : tmpMacro.registers) { - GIFBlock tmpMacro = macro->second; - - for(const auto& reg : tmpMacro.registers) + if(reg->GetID() == GifRegisterID::PRIM) { - if(reg->GetID() == 0x05) - { - // Copies the register - XYZ2 xyz2 = dynamic_cast(*reg); - - xyz2.value->x += v.x; - xyz2.value->y += v.y; - CurrentBlockMacro().registers.push_back(std::make_unique(xyz2)); - } - else + // Copies the register + XYZ2 xyz2 = dynamic_cast(*reg); + if(!xyz2.value.has_value()) { - CurrentBlockMacro().registers.push_back(reg->Clone()); + std::unreachable(); } + + xyz2.value->x += xyOffset.x; + xyz2.value->y += xyOffset.y; + CurrentBlockMacro().registers.push_back(std::make_unique(xyz2)); + } + else + { + CurrentBlockMacro().registers.push_back(reg->Clone()); } - return true; - } - else - { - logger::error("Macro with name %s does not exist\n", name.c_str()); - return false; } + return true; } + + [[unlikely]] logger::error("Macro with name %s does not exist\n", name.c_str()); + return false; } -bool Machine::TrySetRegister(std::unique_ptr reg) +auto Machine::TrySetRegister(std::unique_ptr reg) -> bool { - if(!HasCurrentBlockOrMacro()) [[unlikely]] + if(!HasCurrentBlockOrMacro()) { logger::error("Not in current block"); } - else if(CurrentBlockMacro().HasRegister() && !CurrentBlockMacro().CurrentRegister().Ready()) [[unlikely]] + else if(CurrentBlockMacro().HasRegister() && !CurrentBlockMacro().CurrentRegister().Ready()) { logger::error("Current register is not fulfilled"); } - else + else [[likely]] { CurrentBlockMacro().registers.emplace_back(std::move(reg)); return true; @@ -182,73 +176,63 @@ bool Machine::TrySetRegister(std::unique_ptr reg) return false; } -bool Machine::TryPushReg(int32_t i) +auto Machine::TryPushReg(int32_t value) -> bool { - if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) + if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) [[likely]] { - CurrentBlockMacro().CurrentRegister().Push(i); + CurrentBlockMacro().CurrentRegister().Push(value); return true; } - else [[unlikely]] - { - logger::error("There is no block, macro or register to push a integer to."); - return false; - } + + logger::error("There is no block, macro or register to push a integer to."); + return false; } -bool Machine::TryPushReg(Vec2 v2) +auto Machine::TryPushReg(Vec2 value) -> bool { - if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) + if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) [[likely]] { - CurrentBlockMacro().CurrentRegister().Push(v2); + CurrentBlockMacro().CurrentRegister().Push(value); return true; } - else [[unlikely]] - { - logger::error("There is no block, macro or register to push a Vec2 to."); - return false; - } + + logger::error("There is no block, macro or register to push a Vec2 to."); + return false; } -bool Machine::TryPushReg(Vec3 v3) +auto Machine::TryPushReg(Vec3 value) -> bool { - if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) + if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) [[likely]] { - CurrentBlockMacro().CurrentRegister().Push(v3); + CurrentBlockMacro().CurrentRegister().Push(value); return true; } - else [[unlikely]] - { - logger::error("There is no block, macro or register to push a Vec3 to."); - return false; - } + + logger::error("There is no block, macro or register to push a Vec3 to."); + return false; } -bool Machine::TryPushReg(Vec4 v4) +auto Machine::TryPushReg(Vec4 value) -> bool { - if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) + if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) [[likely]] { - CurrentBlockMacro().CurrentRegister().Push(v4); + CurrentBlockMacro().CurrentRegister().Push(value); return true; } - else [[unlikely]] - { - logger::error("There is no block, macro or register to push a Vec4 to."); - return false; - } + + logger::error("There is no block, macro or register to push a Vec4 to."); + return false; } -bool Machine::TryApplyModifier(RegModifier mod) +auto Machine::TryApplyModifier(RegModifier mod) -> bool { - if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) + if(HasCurrentBlockOrMacro() && CurrentBlockMacro().HasRegister()) [[likely]] { return CurrentBlockMacro().CurrentRegister().ApplyModifier(mod); } - else [[unlikely]] - { - logger::error("There is no block or register to apply a modifier to."); - return false; - } + + logger::error("There is no block or register to apply a modifier to."); + return false; } // First pass, doesn't know anything about the output format @@ -258,7 +242,7 @@ void Machine::FirstPassOptimize() // Dead store Elimination if(OptimizeConfig[DEAD_STORE_ELIMINATION]) { - std::list>::iterator lastRegIt = CurrentBlock().registers.end(); + auto lastRegIt = CurrentBlock().registers.end(); for(auto regIt = CurrentBlock().registers.begin(); regIt != CurrentBlock().registers.end(); regIt++) { @@ -272,7 +256,6 @@ void Machine::FirstPassOptimize() { logger::info("Dead store elimination: %s", lastRegIt->operator->()->GetName().cbegin()); CurrentBlock().registers.remove(*lastRegIt); - // Set lastReg to this register iterator lastRegIt = regIt; } else @@ -292,7 +275,7 @@ void Machine::FirstPassOptimize() { for(const auto& reg : CurrentBlock().registers) { - if(reg->GetID() == 0) + if(reg->GetID() == GifRegisterID::PRIM) { logger::info("Packing Prim into GIFTAG"); CurrentBlock().prim = reg->Clone(); diff --git a/machine.h b/machine.h index bc60f6e..9be1ce0 100644 --- a/machine.h +++ b/machine.h @@ -64,17 +64,17 @@ class Machine } void SetBackend(Backend* backend) noexcept { this->backend = backend; }; - bool TryStartBlock(const std::string& name); - bool TryStartMacro(const std::string& name); + bool TryStartBlock(const std::string&); + bool TryStartMacro(const std::string&); bool TryEndBlockMacro(); - bool TryInsertMacro(const std::string& name); - bool TryInsertMacro(const std::string& name, Vec2 v); + bool TryInsertMacro(const std::string&); + bool TryInsertMacro(const std::string&, Vec2); bool TrySetRegister(std::unique_ptr reg); - bool TryPushReg(int32_t i); - bool TryPushReg(Vec2 v); - bool TryPushReg(Vec3 v3); - bool TryPushReg(Vec4 v4); - bool TryApplyModifier(RegModifier mod); + bool TryPushReg(int32_t); + bool TryPushReg(Vec2); + bool TryPushReg(Vec3); + bool TryPushReg(Vec4); + bool TryApplyModifier(RegModifier); void DisableOptimization(Optimization op) { diff --git a/registers.cpp b/registers.cpp index a4b15e1..332b383 100644 --- a/registers.cpp +++ b/registers.cpp @@ -1,6 +1,7 @@ #include "registers.h" +#include -std::unique_ptr GenReg(GifRegisters reg) +auto GenReg(GifRegisters reg) -> std::unique_ptr { switch(reg) { @@ -26,6 +27,8 @@ std::unique_ptr GenReg(GifRegisters reg) return std::make_unique(); case GifRegisters::LABEL: return std::make_unique