diff --git a/project/copy_res.bat b/build/backup/copy_res.bat similarity index 100% rename from project/copy_res.bat rename to build/backup/copy_res.bat diff --git a/project/copy_res.sh b/build/backup/copy_res.sh similarity index 100% rename from project/copy_res.sh rename to build/backup/copy_res.sh diff --git a/dl/CMakeLists.txt b/dl/CMakeLists.txt index 04ae6512..630f00db 100644 --- a/dl/CMakeLists.txt +++ b/dl/CMakeLists.txt @@ -215,17 +215,18 @@ if (CMAKE_SYSTEM_NAME MATCHES "Android") endif() # 创建软链接到项目根目录 -add_custom_command( - TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E create_symlink - ${CMAKE_BINARY_DIR}/compile_commands.json - ${CMAKE_SOURCE_DIR}/compile_commands.json - COMMENT "创建软链接:`compile_commands.json" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} -) +if(NOT MSVC) + add_custom_command( + TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink + ${CMAKE_BINARY_DIR}/compile_commands.json + ${CMAKE_SOURCE_DIR}/compile_commands.json + COMMENT "创建软链接:`compile_commands.json" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) +endif() # 安装(方便修改,可以直接使用头文件) - install(DIRECTORY "./" DESTINATION ${CMAKE_INSTALL_PREFIX}/include/dl/ FILES_MATCHING PATTERN "*.h") diff --git a/dl/io/dl_file.h b/dl/io/dl_file.h index eb6f78c4..8bd5011f 100644 --- a/dl/io/dl_file.h +++ b/dl/io/dl_file.h @@ -50,7 +50,7 @@ namespace dl::File void GetPathFileAll(std::string_view path, std::vector& ret, std::string_view regex = "", bool recursion = true); -//! 过滤规则,兼容大小写(传入需要填小写) +//! 过滤规则,不兼容大小写 struct SearchRule { std::vector _vecFmt; //!< 要求的格式 png @@ -72,7 +72,7 @@ void GetPathFileAll(std::string_view path, std::vector& ret, * @brief 获取文件夹当前内容 * @param[in] path 路径 * @param[out] ret 返回的目录 -* @param[in] regex 正则表达式,例如 .(png|jpg)$ +* @param[in] regex 正则表达式,例如 .(png|jpg|PNG)$ * @param[in] folder 是否包含目录 * @param[in] file 是否包含文件 * @note 排除特定文件写法:^(?!a.png$|b.jpg$).*.(png|jpg)$ diff --git a/dl/io/dl_json.cpp b/dl/io/dl_json.cpp index 71af35d9..a5918e69 100644 --- a/dl/io/dl_json.cpp +++ b/dl/io/dl_json.cpp @@ -45,6 +45,12 @@ json ParseString(std::string_view str) json ParseFile(std::string_view path_name, bool binary) { + if (!File::IsExist(path_name)) + { + if (g_bJsonLog) + log_warn("文件不存在:{}", path_name); + return {}; + } if (binary) { Buffer buf = File::GetBuffer(path_name); diff --git a/dl/io/dl_json.h b/dl/io/dl_json.h index 2d6ac749..a119c3af 100644 --- a/dl/io/dl_json.h +++ b/dl/io/dl_json.h @@ -62,7 +62,7 @@ json ParseString(std::string_view str); /** -* @brief 从json返回值,不存在则返回false,打印日志 +* @brief 从json返回子元素值,不存在则返回false,打印日志 */ template bool Get(const json& j, const std::string& name, T& t) @@ -90,7 +90,7 @@ bool Get(const json& j, const std::string& name, T& t) * @brief 从json返回值,不存在则返回false,打印日志 */ template -bool Get(const json& j, T& t) +bool Cast(const json& j, T& t) { try { diff --git a/dl/render/dl_factory.cpp b/dl/render/dl_factory.cpp index dd3d09f8..11d50e60 100644 --- a/dl/render/dl_factory.cpp +++ b/dl/render/dl_factory.cpp @@ -684,6 +684,21 @@ dl::gcAnimation Factory::CreateAnimation(std::string_view name, std::string_view ret->SetFrameTime(node._ftime); log_msg("创建动画:{}({}),{}", name, dir, ret->GetFrameCount()); } + else if (info._type == "packed") + { + std::string name_spr = name + "." + "__packed"; + unsigned count = node._count ? node._count : (unsigned)g_factory->GetSpriteSheetNum(name_spr); + unsigned beg = node._beg + (count + node._skip) * dir; + + for (unsigned i = beg; i < beg + count; ++i) + { + gcSprite spr = g_factory->CreateSprite(name_spr, i); + spr->DtQuadOffset(info._offset); + ret->PushBack(spr); + } + ret->SetFrameTime(node._ftime); + log_msg("创建动画:{}({}),{}", name, dir, ret->GetFrameCount()); + } else assert(0); return ret; @@ -943,6 +958,157 @@ void Factory::ExportTexture2D() } +bool Factory::CompressMir2Res(std::string_view path) +{ + if (!File::IsExist(path)) + { + log_err("目录不存在:{}", path); + return false; + } + + // 收集所有图片 + std::vector all_image_path; + File::GetPathContent(path, all_image_path, ".(png|PNG)$", false); + + // input + struct ImageNode + { + Image* _img; + int _index; // 旧index + }; + std::list all_image; + + for (auto& iter : all_image_path) + { + ImageNode node; + node._img = Img::Create(iter); + if (!node._img || node._img->size() <= 1) + { + delete node._img; + log_msg("跳过图像:{}", iter); + continue; + } + node._index = String::toInt(String::GetFileStem(iter), -1); + if (node._index == -1) + { + delete node._img; + log_msg("获取图标下标失败:{}", String::GetFileStem(iter)); + continue; + } + all_image.push_back(node); + } + + // output + struct SrpiteOut + { + RectU _rect = {}; + Point _anchor = {}; + size_t _newIndex = -1; + }; + // 旧index -> Out + std::unordered_map map_sprite_out; + + Image* img_big = Img::Create(SIZE_TEXTURE_2D_SIZE, ColorDef::NONE); + + // 合图 + TexturePack::Static pack; + pack.SetSize(SIZE_TEXTURE_2D_SIZE); + + // 获得大小 + auto fn_get_size = [](const ImageNode& node) { + return node._img->GetSize(); + }; + // 成功加入操作 + size_t index = 0; + auto fn_call_back = [&](const ImageNode& node, const PointU& lt) { + + RectU rect = createRectU(node._img->GetSize()); + Img::AddRect(img_big, node._img, rect, lt); + delete node._img; + + Align::OffsetRect(rect, lt); + SrpiteOut out; + out._rect = rect; + out._newIndex = index++; + map_sprite_out[node._index] = out; + }; + + // 直到全部添加 + pack.Calc(all_image, fn_get_size, fn_call_back); + assert(all_image.empty()); + + Img::Save(img_big, path + "__packed.png"); + delete img_big; + + // 精灵信息记录 + if (File::IsExist(path + "Placements/")) + { + // 收集所有图片 + std::vector all_txt_path; + File::GetPathContent(path + "Placements/", all_txt_path, ".txt", false); + + for (auto& iter : all_txt_path) + { + std::string str = File::GetString(iter); + Position pos = String::toPosition2(str, '\n'); + + int index = String::toInt(String::GetFileStem(iter), -1); + auto iter = map_sprite_out.find(index); + if (iter == map_sprite_out.end()) + { + log_warn("无效的旧下标:{}", index); + continue; + } + iter->second._anchor = toPoint(-pos); + } + } + // 保存精灵信息 + { + json j; + json j_arr = {}; + for (auto& iter : map_sprite_out) + { + SrpiteOut& spr = iter.second; + { + json j_spr; + j_spr["rect"] = spr._rect; + j_spr["anchor"] = spr._anchor; + j_arr[spr._newIndex] = j_spr; + } + } + j["packed"] = j_arr; + Json::SaveFile(j, path + "__packed.json"); + } + + // 更新动画信息 + { + json j = Json::ParseFile(path + "__animation_old.json"); + if (!j.is_null()) + { + AnimationInfo info = j; + info._skip = 0; + info._type = "packed"; + info._format = ""; + for (auto& iter : info._allAni) + { + AnimationInfo::Node& node = iter.second; + node._skip = 0; + auto iter1 = map_sprite_out.find(node._beg); + if (iter1 == map_sprite_out.end()) + { + log_warn("无效的beg值:{}", node._beg); + continue; + } + node._beg = (unsigned)iter1->second._newIndex; + } + j = info; + Json::SaveFile(j, path + "__animation.json"); + } + } + + return true; +} + void Factory::_render_sprite(Sprite* spr) { const SpriteID& id = g_factory->GetImp()->_idTrans; @@ -1585,17 +1751,43 @@ void Factory::_load_sprite_sub(std::string_view path, std::string_view name, std // 不同meta处理 bool read_meta = false; + if (!read_meta) + { + std::string file_name = String::GetFileStem(path_name); + if (file_name == "__packed") + { + std::string meta_name = path_name; + String::ReplaceExtension(meta_name, "json"); + + Json::DisableLog l; + json j = Json::ParseFile(meta_name); + if (!j.is_null()) + { + read_meta = true; + json j_arr = {}; + Json::Get(j, "packed", j_arr); + for (auto& iter : j_arr) + { + SheetNodeInfo node; + Point anchor; + Json::Get(iter, "anchor", anchor); + Json::Get(iter, "rect", node._rect); + node._anchor = dl::to_string(anchor); + vec_node.push_back(node); + } + } + } + } if(!read_meta) { // json meta std::string meta_name = path_name; String::ReplaceExtension(meta_name, "json"); - std::ifstream ifs = File::Get(meta_name); - if (ifs.is_open()) + Json::DisableLog l; + json j = Json::ParseFile(meta_name); + if (!j.is_null()) { read_meta = true; - json j = json::parse(ifs); - Json::DisableLog l; Json::Get(j, "anchor", sheet_info._anchor);// 公共锚点 Json::Get(j, "color", sheet_info._color);// 公共颜色 diff --git a/dl/render/dl_factory.h b/dl/render/dl_factory.h index 1c41e9dc..4d260547 100644 --- a/dl/render/dl_factory.h +++ b/dl/render/dl_factory.h @@ -462,6 +462,10 @@ public: * @brief 导出所有2d纹理 */ void ExportTexture2D(); + + //! 打包传奇补丁包(TODO 有问题不要使用) + bool CompressMir2Res(std::string_view path); + FactoryImp* GetImp() { return _imp; } void _render_sprite(Sprite* spr); diff --git a/dl/script/dl_lua_register.cpp b/dl/script/dl_lua_register.cpp index 7c1c94b2..816abec3 100644 --- a/dl/script/dl_lua_register.cpp +++ b/dl/script/dl_lua_register.cpp @@ -347,6 +347,7 @@ namespace dl luabridge::overload(&Factory::CreateSprite), luabridge::overload(&Factory::CreateSprite)) .addFunction("SetPath", &Factory::SetPath) + .addFunction("CompressMir2Res", &Factory::CompressMir2Res) .endClass(); auto result = luabridge::push(L, g_factory); diff --git a/project/dl_console/.gitignore b/project/dl_console/.gitignore new file mode 100644 index 00000000..b605e1d1 --- /dev/null +++ b/project/dl_console/.gitignore @@ -0,0 +1,11 @@ +/log +/*.ilk +/*.pdb +/*.exe +/memory_leak_report.txt +/vld.ini +/temp +/binary +/dl +/Microsoft.DTfW.DHL.manifest +/out diff --git a/project/dl_console/res/crashrpt_lang.ini b/project/dl_console/res/crashrpt_lang.ini index e2765304..fd3c6880 100644 Binary files a/project/dl_console/res/crashrpt_lang.ini and b/project/dl_console/res/crashrpt_lang.ini differ diff --git a/project/dl_console/res/打包Mir2资源.lua b/project/dl_console/res/打包Mir2资源.lua new file mode 100644 index 00000000..c5206ed9 --- /dev/null +++ b/project/dl_console/res/打包Mir2资源.lua @@ -0,0 +1,31 @@ +-- 你的资源根目录 +local rootPath = "D:/work/base_actor/image/ani/" + +-- 所有需要压缩的文件夹列表 +local folders = { + "刀盾兵重甲", + "双刀兵", + "大刀兵中甲", + "大锤兵", + "女琴师", + "弓箭手", + "弓箭手中甲", + "弓箭手轻甲", + "弓船", + "搬运工", + "标枪", + "树木倒塌", + "武将", + "祭司", + "蛮族侦察兵", + "蛮族步兵", + "酒者", + "黑骑士" +} + +-- 遍历并压缩 +for _, folder in ipairs(folders) do + local fullPath = rootPath .. folder + g_factory:CompressMir2Res(fullPath) + print("已压缩: " .. folder) +end \ No newline at end of file diff --git a/project/dl_editor b/project/dl_editor index 368d5511..c5c032a1 160000 --- a/project/dl_editor +++ b/project/dl_editor @@ -1 +1 @@ -Subproject commit 368d551155f8ee8a57f98ec3d95cefc7187eb999 +Subproject commit c5c032a16f0f117007316ac40c33edaf56be9086 diff --git a/project/dl_test/.gitignore b/project/dl_test/.gitignore new file mode 100644 index 00000000..b605e1d1 --- /dev/null +++ b/project/dl_test/.gitignore @@ -0,0 +1,11 @@ +/log +/*.ilk +/*.pdb +/*.exe +/memory_leak_report.txt +/vld.ini +/temp +/binary +/dl +/Microsoft.DTfW.DHL.manifest +/out diff --git a/project/dl_test/res/crashrpt_lang.ini b/project/dl_test/res/crashrpt_lang.ini index e2765304..fd3c6880 100644 Binary files a/project/dl_test/res/crashrpt_lang.ini and b/project/dl_test/res/crashrpt_lang.ini differ diff --git a/project/hs b/project/hs index 77903040..31b832dc 160000 --- a/project/hs +++ b/project/hs @@ -1 +1 @@ -Subproject commit 77903040cd36bad23fac2faf733291a06db7ba06 +Subproject commit 31b832dcb3f2326288ff62b596e569c7a88ad46c diff --git a/project/project.cmake b/project/project.cmake index 063db212..5554589c 100644 --- a/project/project.cmake +++ b/project/project.cmake @@ -95,53 +95,21 @@ set(DL_PATH_VLD ${CMAKE_SOURCE_DIR}/third/vld/bin/${ARCH}) # CrashRpt资源文件夹 set(DL_PATH_CR ${CMAKE_SOURCE_DIR}/third/CrashRpt/${ARCH}) - -## 复制资源 -#add_custom_command(TARGET ${PROJECT_NAME} -# PRE_BUILD -# COMMAND ${CMAKE_COMMAND} -E remove_directory ${PATH_OUT} -# COMMENT "清理资源完成") -#add_custom_command(TARGET ${PROJECT_NAME} -# POST_BUILD -# COMMAND ${CMAKE_COMMAND} -E copy_directory ${PATH_RES} ${PATH_OUT} -# COMMENT "复制资源完成") - -# 资源软链接 -# if (CMAKE_SYSTEM_NAME MATCHES "Windows") -# add_custom_command(TARGET ${PROJECT_NAME} -# PRE_BUILD -# COMMAND ${CMAKE_COMMAND} -E remove_directory ${PATH_OUT} -# COMMAND cmd /c ${CMAKE_SOURCE_DIR}/project/copy_res.bat ${PATH_RES} ${PATH_OUT} -# COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/project/template.gitignore ${PATH_OUT}/.gitignore) -# elseif(CMAKE_SYSTEM_NAME MATCHES "Android") -# add_custom_command(TARGET ${PROJECT_NAME} -# PRE_BUILD -# COMMAND ${CMAKE_COMMAND} -E remove_directory ${PATH_OUT} -# #COMMAND cmd /c ${CMAKE_SOURCE_DIR}/project/copy_res.bat ${PATH_RES} ${PATH_OUT} -# COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/project/template.gitignore ${PATH_OUT}/.gitignore) -# elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") -# add_custom_command(TARGET ${PROJECT_NAME} -# PRE_BUILD -# COMMAND ${CMAKE_COMMAND} -E remove_directory ${PATH_OUT} -# COMMAND bash ${CMAKE_SOURCE_DIR}/project/copy_res.sh ${PATH_RES} ${PATH_OUT} -# COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/project/template.gitignore ${PATH_OUT}/.gitignore) -# elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") -# add_custom_command(TARGET ${PROJECT_NAME} -# PRE_BUILD -# COMMAND ${CMAKE_COMMAND} -E remove_directory ${PATH_OUT} -# COMMAND bash ${CMAKE_SOURCE_DIR}/project/copy_res.sh ${PATH_RES} ${PATH_OUT} -# COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/project/template.gitignore ${PATH_OUT}/.gitignore) -# endif() - # 创建软链接、复制必要资源 add_custom_command( TARGET ${PROJECT_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E remove_directory ${PATH_OUT} COMMAND ${CMAKE_COMMAND} -E create_symlink ${PATH_RES} ${PATH_OUT} - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/project/template.gitignore ${PATH_OUT}/.gitignore COMMENT "创建资源软链接,并复制资源" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) +# 复制必要资源 +if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.gitignore") + add_custom_command( + TARGET ${PROJECT_NAME} PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/project/template.gitignore ${CMAKE_CURRENT_SOURCE_DIR}/.gitignore + COMMENT "复制.gitignore文件模板" + ) +endif() # 复制dl必要资源(重新生成代码的时候才会触发) if (USE_RENDER) @@ -156,9 +124,11 @@ if(MSVC) add_custom_command(TARGET ${PROJECT_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${DL_PATH_VLD} ${PATH_OUT}) - add_custom_command(TARGET ${PROJECT_NAME} - PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/third/vld/vld.ini ${PATH_OUT}) + if(NOT EXISTS "${PATH_OUT}/vld.ini") + add_custom_command(TARGET ${PROJECT_NAME} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/third/vld/vld.ini ${PATH_OUT}) + endif() endif() # 复制CrashRpt if (CMAKE_BUILD_TYPE MATCHES "Release")