diff --git a/JACK_PLUGIN_TEST/src.cpp b/JACK_PLUGIN_TEST/src.cpp deleted file mode 100644 index 7d768ea..0000000 --- a/JACK_PLUGIN_TEST/src.cpp +++ /dev/null @@ -1,540 +0,0 @@ -#define _WIN32_WINNT 0x0501 -#define WINVER 0x0501 -#define NTDDI_VERSION 0x05010000 - -#define VC_EXTRALEAN -#define _ATL_XP_TARGETING -#define WIN32_LEAN_AND_MEAN -#define PSAPI_VERSION 1 - - -#include -#include -#include -#include -#include -#include - -const char* actionName = "About"; -const char* actionDescription = "UnrealMapDrawTool is a map painting tools. Download https://github.com/UnrealKaraulov/UnrealMapDrawTool Extension of maps: .umd. "; -const char* actionDirectory = "UnrealMapDrawTool"; -const char* actionFormatName = "UnrealMapDrawTool MAP"; -const char* actionFormat = ".umd"; - -enum cell_type :unsigned char -{ - cell_none = 0, - cell_brush, - cell_hostage, - cell_player_TT, - cell_player_CT, - cell_light, - cell_buyzone, - cell_bombzone, - cell_waterzone -}; - -struct cell -{ - unsigned char height; - unsigned char height_offset; - cell_type type; -}; - -std::vector cell_list; - -std::string GenerateCuboid(float x1, float y1, float z1, float x2, float y2, float z2, const char* texture = "AAATRIGGER") -{ - std::stringstream outcuboid; - - outcuboid << "{" << std::endl; - outcuboid << "( " << x2 << " " << y1 << " " << z2 << " ) ( " << x2 << " " << y1 << " " << z1 << " ) ( " << x2 << " " << y2 << " " << z2 << " ) " << texture << " [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1" << std::endl; - outcuboid << "( " << x1 << " " << y2 << " " << z2 << " ) ( " << x1 << " " << y2 << " " << z1 << " ) ( " << x1 << " " << y1 << " " << z2 << " ) " << texture << " [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1" << std::endl; - outcuboid << "( " << x2 << " " << y2 << " " << z2 << " ) ( " << x2 << " " << y2 << " " << z1 << " ) ( " << x1 << " " << y2 << " " << z2 << " ) " << texture << " [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1" << std::endl; - outcuboid << "( " << x1 << " " << y1 << " " << z2 << " ) ( " << x1 << " " << y1 << " " << z1 << " ) ( " << x2 << " " << y1 << " " << z2 << " ) " << texture << " [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1" << std::endl; - outcuboid << "( " << x1 << " " << y1 << " " << z1 << " ) ( " << x1 << " " << y2 << " " << z1 << " ) ( " << x2 << " " << y1 << " " << z1 << " ) " << texture << " [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1" << std::endl; - outcuboid << "( " << x2 << " " << y2 << " " << z2 << " ) ( " << x1 << " " << y2 << " " << z2 << " ) ( " << x2 << " " << y1 << " " << z2 << " ) " << texture << " [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1" << std::endl; - outcuboid << "}"; - - return outcuboid.str(); -} - - -std::string GenerateOriginString(float x, float y, float z) -{ - std::stringstream outcuboid; - outcuboid << "\"origin\" \"" << x << " " << y << " " << z << "\""; - return outcuboid.str(); -} - - -float GetMinZ_fromPercent(float z, float cell_height, float z_offset) -{ - return z + cell_height / 100.0f * z_offset; -} - -float GetMaxZ_fromPercent(float z, float cell_height, float z_offset, float z_height) -{ - return z + (cell_height / 100.0f * z_offset) + (cell_height / 100.0f * z_height); -} - -float GetHeight_fromPercent(float cell_height, float z_height) -{ - return cell_height / 100.0f * z_height; -} - -float GetHeightOffset_fromPercent(float cell_height, float z_offset) -{ - return cell_height / 100.0f * z_offset; -} - -bool UseSkyBorders = false; - -void GenerateUnrealMap(std::string fpath, float cell_size, float cell_height, float cell_x, float cell_y, int cell_levels, int cell_layers) -{ - int cur_item = 0; - - int x_min = 99999; - int x_max = -99999; - - int y_min = 99999; - int y_max = -99999; - - - // search mins/maxs - for (int lvl = 0; lvl < cell_levels; lvl++) - { - for (int layer = 0; layer < cell_layers; layer++) - { - for (int y = 0; y < cell_y; y++) - { - for (int x = 0; x < cell_x; x++) - { - cell cur_cell = cell_list[cur_item]; - - if (cur_cell.type != cell_type::cell_none) - { - if (x >= x_max) - x_max = x; - if (x <= x_min) - x_min = x; - - if (y >= y_max) - y_max = y; - if (y <= y_min) - y_min = y; - } - cur_item++; - } - } - } - } - - std::stringstream output_bruhes; - std::stringstream output_entities; - - int tmp_item = 0; - cur_item = 0; - - int cur_item_y_multiple = 1; - int cur_item_x_multiple = 1; - - bool one_Light_found = false; - - int lvl_save, layer_save, x_save, y_save; - - float item_z_offset = -(cell_height * cell_levels / 2.0f); - float item_x_offset = -(cell_size * (abs(x_min) + abs(x_max) + 1) / 2.0f); - float item_y_offset = cell_size * (abs(y_min) + abs(y_max) + 1) / 2.0f; - - - output_bruhes << - GenerateCuboid(item_x_offset, item_y_offset, - item_z_offset - cell_size, - -item_x_offset, - -item_y_offset, - item_z_offset, "CRETE4_FLR02"); - output_bruhes << std::endl; - - output_bruhes << - GenerateCuboid(item_x_offset, item_y_offset, - -item_z_offset, - -item_x_offset, - -item_y_offset, - -item_z_offset + cell_size, UseSkyBorders ? "SKY" : "CRETE4_WALL01C"); - output_bruhes << std::endl; - - output_bruhes << - GenerateCuboid(item_x_offset - cell_size, item_y_offset, - item_z_offset - cell_size, - item_x_offset, - -item_y_offset, - -item_z_offset + cell_size, UseSkyBorders ? "SKY" : "CRETE4_WALL01C"); - output_bruhes << std::endl; - - output_bruhes << - GenerateCuboid(-item_x_offset, item_y_offset, - item_z_offset - cell_size, - -item_x_offset + cell_size, - -item_y_offset, - -item_z_offset + cell_size, UseSkyBorders ? "SKY" : "CRETE4_WALL01C"); - output_bruhes << std::endl; - - output_bruhes << - GenerateCuboid(item_x_offset - cell_size, item_y_offset + cell_size, - item_z_offset - cell_size, - -item_x_offset + cell_size, - item_y_offset, - -item_z_offset + cell_size, UseSkyBorders ? "SKY" : "CRETE4_WALL01C"); - output_bruhes << std::endl; - - output_bruhes << - GenerateCuboid(item_x_offset - cell_size, -item_y_offset, - item_z_offset - cell_size, - -item_x_offset + cell_size, - -item_y_offset - cell_size, - -item_z_offset + cell_size, UseSkyBorders ? "SKY" : "CRETE4_WALL01C"); - output_bruhes << std::endl; - - - for (int lvl = 0; lvl < cell_levels; lvl++) - { - for (int layer = 0; layer < cell_layers; layer++) - { - for (int y = 0; y < cell_y; y++) - { - for (int x = 0; x < cell_x; x++) - { - cell cur_cell = cell_list[cur_item]; - - if (cur_cell.type != cell_type::cell_none) - { - tmp_item = cur_item; - lvl_save = lvl; - layer_save = layer; - x_save = x; - y_save = y; - - cur_item_y_multiple = 1; - cur_item_x_multiple = 1; - - // search X multiple - if (x + 1 < cell_x) - { - bool ignore_other = false; - x++; - tmp_item++; - for (; x < cell_x; x++) - { - cell next_cell = cell_list[tmp_item]; - if (!ignore_other && next_cell.type == cur_cell.type && - next_cell.height == cur_cell.height && - next_cell.height_offset == cur_cell.height_offset && (cur_cell.type == cell_type::cell_bombzone - || cur_cell.type == cell_type::cell_buyzone || cur_cell.type == cell_type::cell_brush - || cur_cell.type == cell_type::cell_waterzone)) - { - cur_item_x_multiple++; - cell_list[tmp_item].height = 0; - cell_list[tmp_item].height_offset = 0; - cell_list[tmp_item].type = cell_type::cell_none; - } - else - { - ignore_other = true; - } - tmp_item++; - } - } - - bool y_search = true; - while (y + 1 < cell_y && y_search) - { - std::vector items_for_erase; - y++; - for (x = 0; x < x_save; x++) - { - tmp_item++; - } - int tmp_x_multiple = 0; - - bool ignore_other = false; - for (; x < cell_x; x++) - { - cell next_cell = cell_list[tmp_item]; - if (tmp_x_multiple < cur_item_x_multiple && !ignore_other && next_cell.type == cur_cell.type && - next_cell.height == cur_cell.height && - next_cell.height_offset == cur_cell.height_offset && (cur_cell.type == cell_type::cell_bombzone - || cur_cell.type == cell_type::cell_buyzone || cur_cell.type == cell_type::cell_brush - || cur_cell.type == cell_type::cell_waterzone)) - { - tmp_x_multiple++; - items_for_erase.push_back(tmp_item); - } - else - { - ignore_other = true; - } - tmp_item++; - } - - - if (tmp_x_multiple == cur_item_x_multiple) - { - cur_item_y_multiple++; - for (int erase_cell_id : items_for_erase) - { - cell_list[erase_cell_id].height = 0; - cell_list[erase_cell_id].height_offset = 0; - cell_list[erase_cell_id].type = cell_type::cell_none; - } - } - else - break; - } - - lvl = lvl_save; - layer = layer_save; - x = x_save; - y = y_save; - - if (cur_cell.type == cell_type::cell_brush) - { - output_bruhes << - GenerateCuboid(item_x_offset + x * cell_size, item_y_offset - y * cell_size, - GetMinZ_fromPercent(item_z_offset, cell_height, (float)cur_cell.height_offset), - item_x_offset + x * cell_size + cell_size * cur_item_x_multiple, - item_y_offset - (y * cell_size + cell_size * cur_item_y_multiple), - GetMaxZ_fromPercent(item_z_offset, cell_height, (float)cur_cell.height_offset, (float)cur_cell.height), "TNNL_FLR7"); - output_bruhes << std::endl; - } - else - { - output_entities << "{" << std::endl; - if (cur_cell.type == cell_type::cell_player_CT - || cur_cell.type == cell_type::cell_player_TT - || cur_cell.type == cell_type::cell_hostage - || cur_cell.type == cell_type::cell_light) - { - if (cur_cell.type == cell_type::cell_player_CT) - output_entities << "\"classname\" \"info_player_start\"" << std::endl; - else if (cur_cell.type == cell_type::cell_player_TT) - output_entities << "\"classname\" \"info_player_deathmatch\"" << std::endl; - else if (cur_cell.type == cell_type::cell_light) - { - one_Light_found = true; - output_entities << "\"classname\" \"light\"" << std::endl; - output_entities << "\"_falloff\" \"0\"" << std::endl; - output_entities << "\"_fade\" \"1.0\"" << std::endl; - output_entities << "\"style\" \"0\"" << std::endl; - output_entities << "\"_light\" \"255 255 128 200\"" << std::endl; - } - else - output_entities << "\"classname\" \"hostage_entity\"" << std::endl; - output_entities << GenerateOriginString(item_x_offset + cell_size / 2.0f + cell_size * x, item_y_offset - cell_size / 2.0f - cell_size * y, - cur_cell.type == cell_type::cell_light && cur_cell.height_offset > 0 ? GetMinZ_fromPercent(item_z_offset, cell_height, (float)cur_cell.height_offset) : item_z_offset + cell_height / 2.0f); - output_entities << std::endl; - } - else if (cur_cell.type == cell_type::cell_buyzone || cur_cell.type == cell_type::cell_bombzone - || cur_cell.type == cell_type::cell_waterzone) - { - if (cur_cell.type == cell_type::cell_buyzone) - output_entities << "\"classname\" \"func_buyzone\"" << std::endl; - else if (cur_cell.type == cell_type::cell_waterzone) - { - output_entities << "\"classname\" \"func_water\"" << std::endl; - output_entities << "\"skin\" \"-3\"" << std::endl; - } - else - output_entities << "\"classname\" \"func_bomb_target\"" << std::endl; - output_entities << - GenerateCuboid(item_x_offset + x * cell_size, item_y_offset - y * cell_size, - GetMinZ_fromPercent(item_z_offset, cell_height, (float)cur_cell.height_offset), - item_x_offset + x * cell_size + cell_size * cur_item_x_multiple, - item_y_offset - (y * cell_size + cell_size * cur_item_y_multiple), - GetMaxZ_fromPercent(item_z_offset, cell_height, (float)cur_cell.height_offset, (float)cur_cell.height), cur_cell.type == cell_type::cell_waterzone ? "!WATER2B" : "AAATRIGGER"); - output_entities << std::endl; - } - output_entities << "}" << std::endl; - } - } - cur_item++; - } - } - } - - item_z_offset += cell_height; - } - - std::stringstream outputmap; - outputmap << "{" << std::endl; - outputmap << "\"classname\" \"worldspawn\"" << std::endl; - outputmap << "\"mapversion\" \"220\"" << std::endl; - outputmap << "\"startdark\" \"0\"" << std::endl; - if (!one_Light_found) - { - outputmap << "\"light\" \"1\"" << std::endl; - outputmap << "\"_minlight\" \"0.5\"" << std::endl; - } - outputmap << "\"MaxRange\" \"8096\"" << std::endl; - outputmap << "\"sounds\" \"1\"" << std::endl; - outputmap << "\"wad\" \"/valve/halflife.wad;/valve/liquids.wad\"" << std::endl; - outputmap << "\"_generator\" \"UnrealMapDrawTool\"" << std::endl; - outputmap << output_bruhes.str(); - outputmap << "}" << std::endl; - outputmap << output_entities.str(); - - std::ofstream outFile; - outFile.open(fpath, std::ios::out); - if (outFile.is_open()) - { - outFile << outputmap.rdbuf(); - outFile.close(); - } -} - -char cell_size[256] = "32"; -char cell_height[256] = "128"; -char cell_x[256] = "64"; -char cell_y[256] = "64"; -char cell_levels[256] = "2"; -char cell_layers[256] = "3"; - - -BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - return 1; -} - -BOOL CALLBACK PrintAboutForJack(HWND hwnd, LPARAM lParam) { - DWORD processId = 0; - GetWindowThreadProcessId(hwnd, &processId); - - DWORD targetProcessId = *reinterpret_cast(lParam); - - if (processId == targetProcessId) { - MessageBoxA(hwnd, actionDescription, "UnrealMapDrawTool .umd Import Plugin by Karaulov", 0); - return FALSE; - } - return TRUE; -} - - -__int64 dispatchFunc() -{ - DWORD processId = GetCurrentProcessId(); - EnumWindows(PrintAboutForJack, reinterpret_cast(&processId)); - return 0; -} - -#pragma pack(push, 1) - -struct JACK_ACTION -{ - const char* actionData[3]; - __int64 state; // 0 is item enabled // 2 is item disabled - __int64 flags; // - void* dispatch_func; - // UNUSED - __int64 reserved; - __int64 reserved2; -}; - -#pragma pack(pop) - -JACK_ACTION tmpJACK_ACTION{ {actionName,actionDescription,actionDirectory}, 0 , 0, (void*)dispatchFunc, 0,0 }; - -__int64 __fastcall vpEnumActions(void(__fastcall* jackAddAction)(JACK_ACTION*, unsigned char* qlib), unsigned char* qlib) -{ - jackAddAction(&tmpJACK_ACTION, qlib); - - return 1; -} - -__int64 __fastcall vpMain(void* unused, __int64 sdk_version) -{ - if (sdk_version != 100) - return 100LL; - setlocale(0, "C"); - return 0LL; -} - -bool __fastcall vpEnumImportFormats(__int64(__fastcall* jackAddImport)(int version, const char* name, const char* extension, unsigned char* qlib), unsigned char* qlib) -{ - return jackAddImport(0, actionFormatName, actionFormat, qlib) != 0; -} - -typedef __int64(__fastcall* pvpImport)(int version, const char* src, unsigned char* data); - -char newSrcName[2048]; - -__int64 __fastcall vpImport(int formatid, const char* src, unsigned char* data) -{ - HMODULE mdl = LoadLibraryA("vpHalfLifex64.dll"); - pvpImport imp = (pvpImport)GetProcAddress(mdl,"vpImport"); - - sprintf_s(newSrcName, 2048, "%s", src); - - newSrcName[strlen(src) - 1] = 'p'; - newSrcName[strlen(src) - 2] = 'a'; - newSrcName[strlen(src) - 3] = 'm'; - newSrcName[strlen(src) - 4] = '.'; - - - int tmp_int_value = 0; - std::ifstream tmpmap(src, std::ios::in | std::ios::binary); - if (tmpmap.is_open()) - { - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_x, sizeof(cell_x), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_y, sizeof(cell_y), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_size, sizeof(cell_size), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_height, sizeof(cell_height), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_levels, sizeof(cell_levels), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_layers, sizeof(cell_layers), "%d", tmp_int_value); - - cell tmpcell = cell(); - tmpcell.height = 0; - tmpcell.height_offset = 0; - tmpcell.type = cell_none; - cell_list.clear(); - - for (int lvl = 0; lvl < atoi(cell_levels); lvl++) - { - for (int layer = 0; layer < atoi(cell_layers); layer++) - { - for (int y = 0; y < atoi(cell_y); y++) - { - for (int x = 0; x < atoi(cell_x); x++) - { - tmpmap.read((char*)&tmpcell.height, 1); - tmpmap.read((char*)&tmpcell.height_offset, 1); - tmpmap.read((char*)&tmpcell.type, 1); - cell_list.push_back(tmpcell); - } - } - } - } - - - int skybool = UseSkyBorders ? 1 : 0; - tmpmap.read((char*)&skybool, 4); - - UseSkyBorders = skybool != 0; - - tmpmap.close(); - } - - GenerateUnrealMap(newSrcName, (float)atof(cell_size), (float)atof(cell_height), (float)atof(cell_x), (float)atof(cell_y), atoi(cell_levels), atoi(cell_layers)); - - __int64 retval = imp(2,newSrcName,data); - - DeleteFileA(newSrcName); - - return retval; -} - diff --git a/Release/DrawMap_x32.exe b/Release/DrawMap_x32.exe deleted file mode 100644 index 21cd6f5..0000000 Binary files a/Release/DrawMap_x32.exe and /dev/null differ diff --git a/Release/DrawMap_x64.exe b/Release/DrawMap_x64.exe deleted file mode 100644 index 7f37095..0000000 Binary files a/Release/DrawMap_x64.exe and /dev/null differ diff --git a/Release/test_map.umd b/Release/test_map.umd new file mode 100644 index 0000000..b643290 Binary files /dev/null and b/Release/test_map.umd differ diff --git a/Release/vpKarPlugx64.dll b/Release/vpKarPlugx64.dll new file mode 100644 index 0000000..5cf6eea Binary files /dev/null and b/Release/vpKarPlugx64.dll differ diff --git a/Release/vpKarPlugx64.exp b/Release/vpKarPlugx64.exp new file mode 100644 index 0000000..2a4022c Binary files /dev/null and b/Release/vpKarPlugx64.exp differ diff --git a/Release/vpKarPlugx64.lib b/Release/vpKarPlugx64.lib new file mode 100644 index 0000000..853f886 Binary files /dev/null and b/Release/vpKarPlugx64.lib differ diff --git a/src/ImFileDialog.cpp b/src/ImFileDialog.cpp index 073f307..b681216 100644 --- a/src/ImFileDialog.cpp +++ b/src/ImFileDialog.cpp @@ -1,7 +1,6 @@ #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS #endif -#define NOMINMAX #include "ImFileDialog.h" #include diff --git a/src/jack_api.def b/src/jack_api.def new file mode 100644 index 0000000..c84f5ec --- /dev/null +++ b/src/jack_api.def @@ -0,0 +1,6 @@ +LIBRARY vpKarPlugx64 +EXPORTS +vpMain +vpEnumActions +vpEnumImportFormats +vpImport \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 547f56c..6c27102 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,3 @@ -// Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline -// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) -// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. -// Read online: https://github.com/ocornut/imgui/tree/master/docs -#define GLEW_STATIC #include #include @@ -11,6 +6,9 @@ #include #include +#include + +#ifndef JACK_PLUGIN #include "font.h" #include "glew.h" @@ -22,15 +20,14 @@ #include "imgui_internal.h" #include "imstb_truetype.h" #include "ImFileDialog.h" +#endif #if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) #pragma comment(lib, "legacy_stdio_definitions") #endif - //#define RUSSIAN_LANGUAGE - static void glfw_error_callback(int error, const char* description) { std::cerr << "Glfw Error:" << error << "," << description << std::endl; @@ -58,7 +55,21 @@ struct cell std::vector cell_list; +bool cell_edit(cell& c, unsigned char new_height, unsigned char new_offset, cell_type new_type) +{ + if (c.height == new_height && c.height_offset == new_offset && c.type == new_type) + { + return false; + } + + c.height = new_height; + c.height_offset = new_offset; + c.type = new_type; + return true; +} + +#ifndef JACK_PLUGIN ImVec4 get_cell_color(cell_type c_type) { switch (c_type) @@ -98,7 +109,7 @@ ImVec4 get_cell_color(int id) cell_type c_type = cell_list[id].type; return get_cell_color(c_type); } - +#endif std::string GenerateCuboid(float x1, float y1, float z1, float x2, float y2, float z2, const char* texture = "AAATRIGGER") { std::stringstream outcuboid; @@ -144,8 +155,7 @@ float GetHeightOffset_fromPercent(float cell_height, float z_offset) bool UseSkyBorders = false; - -void GenerateUnrealMap(std::string fpath, float cell_size, float cell_height, float cell_x, float cell_y, int cell_levels, int cell_layers) +void GenerateUnrealMap(const std::string & fpath, float cell_size, float cell_height, float cell_x, float cell_y, int cell_levels, int cell_layers) { int cur_item = 0; @@ -496,6 +506,71 @@ const char* atoint_static(const char* s) return (const char*)&atoi_val; } + + +bool LoadMap(std::string path) +{ + int tmp_int_value = 0; + std::ifstream tmpmap(path, std::ios::in | std::ios::binary); + if (tmpmap && tmpmap.is_open()) + { + tmpmap.read((char*)&tmp_int_value, 4); + snprintf(cell_x, sizeof(cell_x), "%d", tmp_int_value); + tmpmap.read((char*)&tmp_int_value, 4); + snprintf(cell_y, sizeof(cell_y), "%d", tmp_int_value); + tmpmap.read((char*)&tmp_int_value, 4); + snprintf(cell_size, sizeof(cell_size), "%d", tmp_int_value); + tmpmap.read((char*)&tmp_int_value, 4); + snprintf(cell_height, sizeof(cell_height), "%d", tmp_int_value); + tmpmap.read((char*)&tmp_int_value, 4); + snprintf(cell_levels, sizeof(cell_levels), "%d", tmp_int_value); + tmpmap.read((char*)&tmp_int_value, 4); + snprintf(cell_layers, sizeof(cell_layers), "%d", tmp_int_value); + + cell tmpcell = cell(); + tmpcell.height = 0; + tmpcell.height_offset = 0; + tmpcell.type = cell_none; + cell_list.clear(); + + for (int lvl = 0; lvl < atoi(cell_levels); lvl++) + { + for (int layer = 0; layer < atoi(cell_layers); layer++) + { + for (int y = 0; y < atoi(cell_y); y++) + { + for (int x = 0; x < atoi(cell_x); x++) + { + tmpmap.read((char*)&tmpcell.height, 1); + tmpmap.read((char*)&tmpcell.height_offset, 1); + tmpmap.read((char*)&tmpcell.type, 1); + cell_list.push_back(tmpcell); + } + } + } + } + + + int skybool = UseSkyBorders ? 1 : 0; + tmpmap.read((char*)&skybool, 4); + + UseSkyBorders = skybool != 0; + + setup_end = true; + tmpmap.close(); + return true; + } + return false; +} + +#ifndef JACK_PLUGIN + + +bool AutoSave = false; +bool NeedSaveChanges = false; +std::string LastSaveString = { }; + + void DrawUnrealGUI() { @@ -619,55 +694,7 @@ void DrawUnrealGUI() if (ifd::FileDialog::Instance().IsDone("MapOpenDialog")) { if (ifd::FileDialog::Instance().HasResult()) { std::filesystem::path res = ifd::FileDialog::Instance().GetResult(); - int tmp_int_value = 0; - std::ifstream tmpmap(res.string(), std::ios::in | std::ios::binary); - if (tmpmap.is_open()) - { - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_x, sizeof(cell_x), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_y, sizeof(cell_y), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_size, sizeof(cell_size), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_height, sizeof(cell_height), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_levels, sizeof(cell_levels), "%d", tmp_int_value); - tmpmap.read((char*)&tmp_int_value, 4); - snprintf(cell_layers, sizeof(cell_layers), "%d", tmp_int_value); - - cell tmpcell = cell(); - tmpcell.height = 0; - tmpcell.height_offset = 0; - tmpcell.type = cell_none; - cell_list.clear(); - - for (int lvl = 0; lvl < atoi(cell_levels); lvl++) - { - for (int layer = 0; layer < atoi(cell_layers); layer++) - { - for (int y = 0; y < atoi(cell_y); y++) - { - for (int x = 0; x < atoi(cell_x); x++) - { - tmpmap.read((char*)&tmpcell.height, 1); - tmpmap.read((char*)&tmpcell.height_offset, 1); - tmpmap.read((char*)&tmpcell.type, 1); - cell_list.push_back(tmpcell); - } - } - } - } - - - int skybool = UseSkyBorders ? 1 : 0; - tmpmap.read((char*)&skybool, 4); - - UseSkyBorders = skybool != 0; - - setup_end = true; - tmpmap.close(); - } + LoadMap(res.string()); } ifd::FileDialog::Instance().Close(); } @@ -759,6 +786,24 @@ void DrawUnrealGUI() } ImGui::Checkbox("Skybox", &UseSkyBorders); + + ImGui::SameLine(); + + + if (LastSaveString.empty()) + { + ImGui::BeginDisabled(); + AutoSave = false; + } + + ImGui::Checkbox("Auto save", &AutoSave); + + + if (LastSaveString.empty()) + { + ImGui::EndDisabled(); + } + #ifdef RUSSIAN_LANGUAGE if (ImGui::Button("Залить весь слой")) #else @@ -795,6 +840,8 @@ void DrawUnrealGUI() } } } + + NeedSaveChanges = true; } ImGui::SameLine(); @@ -814,6 +861,7 @@ void DrawUnrealGUI() if (ifd::FileDialog::Instance().IsDone("MapGenDialog")) { if (ifd::FileDialog::Instance().HasResult()) { std::filesystem::path res = ifd::FileDialog::Instance().GetResult(); + std::vector tmp_cell_list = cell_list; GenerateUnrealMap(res.string(), (float)atof(cell_size), (float)atof(cell_height), (float)atof(cell_x), (float)atof(cell_y), atoi(cell_levels), atoi(cell_layers)); cell_list = tmp_cell_list; @@ -833,10 +881,17 @@ void DrawUnrealGUI() int cur_item = 0; - if (ifd::FileDialog::Instance().IsDone("MapSaveDialog")) { - if (ifd::FileDialog::Instance().HasResult()) { - std::filesystem::path res = ifd::FileDialog::Instance().GetResult(); - std::ofstream tmpmap(res.string(), std::ios::out | std::ios::binary); + if (ifd::FileDialog::Instance().IsDone("MapSaveDialog") || (NeedSaveChanges && !LastSaveString.empty())) { + if (ifd::FileDialog::Instance().HasResult() || (NeedSaveChanges && !LastSaveString.empty())) { + + if (!NeedSaveChanges) + { + std::filesystem::path res = ifd::FileDialog::Instance().GetResult(); + LastSaveString = res.string(); + } + NeedSaveChanges = false; + + std::ofstream tmpmap(LastSaveString, std::ios::out | std::ios::binary); if (tmpmap.is_open()) { tmpmap.write((const char*)atoint_static(cell_x), 4); @@ -960,8 +1015,13 @@ void DrawUnrealGUI() cell_list[cur_item].type == cell_type::cell_player_CT || cell_list[cur_item].type == cell_type::cell_player_TT) { - cell_list[cur_item].height = 100; - cell_list[cur_item].height_offset = 0; + if (cell_list[cur_item].height != 100 || cell_list[cur_item].height_offset != 0) + { + if (cell_edit(cell_list[cur_item],100,0, cell_list[cur_item].type)) + { + NeedSaveChanges = true; + } + } snprintf(tmplbl, sizeof(tmplbl), "##item%d", cur_item); } else if (cell_list[cur_item].type == cell_type::cell_light) @@ -993,7 +1053,7 @@ void DrawUnrealGUI() ImGui::Text("Размер %d", atoi(cell_size)); #else ImGui::Text("Type: %s", items[cell_list[cur_item].type]); - ImGui::Text("Pos %d/%d(%d/%d)", x + 1, y + 1, (x + 1)* atoi(cell_size), (y + 1)* atoi(cell_size)); + ImGui::Text("Pos %d/%d(%d/%d)", x + 1, y + 1, (x + 1) * atoi(cell_size), (y + 1) * atoi(cell_size)); ImGui::Text("Size %d units", atoi(cell_size)); #endif if (cell_list[cur_item].type == cell_type::cell_brush @@ -1019,22 +1079,25 @@ void DrawUnrealGUI() { if (c_type == cell_type::cell_none) { - cell_list[cur_item].type = cell_type::cell_none; - cell_list[cur_item].height = 0; - cell_list[cur_item].height_offset = 0; + if (cell_edit(cell_list[cur_item], 0, 0, cell_type::cell_none)) + { + NeedSaveChanges = true; + } } else { - cell_list[cur_item].type = c_type; - cell_list[cur_item].height = (unsigned char)atoi(cur_cell_height); - cell_list[cur_item].height_offset = (unsigned char)atoi(cur_cell_height_offset); + if (cell_edit(cell_list[cur_item], (unsigned char)atoi(cur_cell_height), (unsigned char)atoi(cur_cell_height_offset), c_type)) + { + NeedSaveChanges = true; + } } } else if (ImGui::IsMouseDown(ImGuiMouseButton_Right)) { - cell_list[cur_item].type = cell_type::cell_none; - cell_list[cur_item].height = 0; - cell_list[cur_item].height_offset = 0; + if (cell_edit(cell_list[cur_item], 0, 0, cell_type::cell_none)) + { + NeedSaveChanges = true; + } } } @@ -1043,12 +1106,22 @@ void DrawUnrealGUI() cell_list[cur_item].type = c_type; cell_list[cur_item].height = (unsigned char)atoi(cur_cell_height); cell_list[cur_item].height_offset = (unsigned char)atoi(cur_cell_height_offset); + + if (AutoSave) + { + NeedSaveChanges = true; + } } else if (clear_current_layer) { cell_list[cur_item].type = cell_type::cell_none; cell_list[cur_item].height = 0; cell_list[cur_item].height_offset = 0; + + if (AutoSave) + { + NeedSaveChanges = true; + } } if (x + 1 != atoi(cell_x)) @@ -1098,8 +1171,247 @@ void DrawUnrealGUI() ImGui::End(); } } +#endif + + +#ifdef JACK_PLUGIN + +#include + +const char* actionName = "About"; +const char* actionName2 = "Enable AutoReload"; +const char* actionDescription = "UnrealMapDrawTool is a map painting tools. Download https://github.com/UnrealKaraulov/UnrealMapDrawTool Extension of maps: .umd. "; +const char* actionDescription2 = "Auto reload .umd map when change!"; +const char* actionDirectory = "UnrealMapDrawTool"; +const char* actionFormatName = "UnrealMapDrawTool MAP"; +const char* actionFormat = ".umd"; + + +DWORD StartTicks = 0; +DWORD MainThread = 0; +HHOOK hhookSysMsg = 0; +bool AutoReload = false; + + +std::filesystem::file_time_type lastEditTime = {}; + + +std::filesystem::file_time_type GetLastEditTime(std::string path) +{ + return std::filesystem::last_write_time(path); +} + +std::string lastFilePath_umd; +std::string lastFilePath_map; + +typedef __int64(__fastcall* pvpImport)(int version, const char* src, unsigned char* data); + +unsigned char* importData = NULL; + +__int64 import_real() +{ + HMODULE mdl = LoadLibraryA("vpHalfLifex64.dll"); + + if (!mdl) + return 0; + + auto proc = GetProcAddress(mdl, "vpImport"); + if (!proc) + return 0; + + pvpImport imp = (pvpImport)proc; + + // Load .map + __int64 retval = imp(1, lastFilePath_map.c_str(), importData); + + DeleteFileA(lastFilePath_map.c_str()); + + return retval; +} + +LRESULT CALLBACK HookCallWndProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + if (nCode < HC_ACTION) + return CallNextHookEx(hhookSysMsg, nCode, wParam, lParam); + + if (GetCurrentThreadId() == MainThread && GetTickCount() - StartTicks > 500) + { + StartTicks = GetTickCount(); + if (AutoReload && lastFilePath_umd.size()) + { + if (GetLastEditTime(lastFilePath_umd) != lastEditTime) + { + lastEditTime = GetLastEditTime(lastFilePath_umd); + cell_list.clear(); + if (!LoadMap(lastFilePath_umd)) + { + lastFilePath_umd = std::string(); + } + else + { + GenerateUnrealMap(lastFilePath_map, (float)atof(cell_size), (float)atof(cell_height), (float)atof(cell_x), (float)atof(cell_y), atoi(cell_levels), atoi(cell_layers)); + cell_list.clear(); + + // Clear cache (but not hastable memory release) + *(__int64*)(importData + 0x18) = 0; + *(__int64*)(importData + 0x20) = 0; + *(__int64*)(importData + 0xC8) = 0; + + if (!import_real()) + { + lastFilePath_umd = std::string(); + } + } + } + } + } + return CallNextHookEx(hhookSysMsg, nCode, wParam, lParam); +} +BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + if (fdwReason == DLL_PROCESS_DETACH) + { + UnhookWindowsHookEx(hhookSysMsg); + } + else if (fdwReason == DLL_PROCESS_ATTACH) + { + MainThread = GetCurrentThreadId(); + hhookSysMsg = SetWindowsHookExW(WH_GETMESSAGE, HookCallWndProc, hinstDLL, GetCurrentThreadId()); + } + return 1; +} + +BOOL CALLBACK PrintAboutForJack(HWND hwnd, LPARAM lParam) { + DWORD processId = 0; + GetWindowThreadProcessId(hwnd, &processId); + + DWORD targetProcessId = *reinterpret_cast(lParam); + + if (processId == targetProcessId) { + MessageBoxA(hwnd, actionDescription, "UnrealMapDrawTool .umd Import Plugin by Karaulov", 0); + return FALSE; + } + return TRUE; +} + +__int64 dispatchFunc() +{ + DWORD processId = GetCurrentProcessId(); + EnumWindows(PrintAboutForJack, reinterpret_cast(&processId)); + return 0; +} + +#pragma pack(push, 1) + +struct JACK_ACTION +{ + const char* actionData[3]; + __int64 state; // + __int64 flags; // 0 is item enabled 1+ disabled + void* dispatch_func; + __int64 unknown; + __int64 id; + __int64 reserved; + __int64 reserved2; +}; + +#pragma pack(pop) + +JACK_ACTION tmpJACK_ACTION{ {actionName,actionDescription,actionDirectory}, 0 , 0, (void*)dispatchFunc, 0,0, 0,0 }; + +__int64 dispatchFunc2(); + +JACK_ACTION tmpJACK_ACTION2{ {actionName2,actionName2,actionDirectory}, 0 , 0, (void*)dispatchFunc2, 0, 5, 0,0 }; + +BOOL CALLBACK PrintUpdateStateForJack(HWND hwnd, LPARAM lParam) { + DWORD processId = 0; + GetWindowThreadProcessId(hwnd, &processId); + + DWORD targetProcessId = *reinterpret_cast(lParam); + + if (processId == targetProcessId) { + if (AutoReload) + { + MessageBoxA(hwnd, "Auto Reload enabled!", "UnrealMapDrawTool .umd Auto Reload enabled!", 0); + } + else + { + MessageBoxA(hwnd, "Auto Reload disabled!", "UnrealMapDrawTool .umd Auto Reload disabled!", 0); + } + return FALSE; + } + return TRUE; +} + +__int64 dispatchFunc2() +{ + AutoReload = !AutoReload; + + DWORD processId = GetCurrentProcessId(); + EnumWindows(PrintUpdateStateForJack, reinterpret_cast(&processId)); + return 0; +} + +typedef void(__fastcall* jackAddAction)(JACK_ACTION*, unsigned char* qlib); + +__int64 __fastcall vpEnumActions(jackAddAction addAction, unsigned char* qlib) +{ + addAction(&tmpJACK_ACTION, qlib); + addAction(&tmpJACK_ACTION2, qlib); + return 1; +} + +__int64 __fastcall vpMain(void* unused, __int64 sdk_version) +{ + if (sdk_version != 100) + return 100LL; + setlocale(0, "C"); + return 0LL; +} + +bool __fastcall vpEnumImportFormats(__int64(__fastcall* jackAddImport)(int version, const char* name, const char* extension, unsigned char* qlib), unsigned char* qlib) +{ + return jackAddImport(0, actionFormatName, actionFormat, qlib) != 0; +} + +__int64 __fastcall vpImport(int formatid, char* src, unsigned char* jack_data) +{ + char newSrcName[2048]; + sprintf_s(newSrcName, 2048, "%s", src); + + char address[2048]; + sprintf_s(address, 2048, "%p", jack_data); + MessageBoxA(0, address, address, 0); + + lastFilePath_umd = newSrcName; + + newSrcName[strlen(src) - 1] = 'p'; + newSrcName[strlen(src) - 2] = 'a'; + newSrcName[strlen(src) - 3] = 'm'; + newSrcName[strlen(src) - 4] = '.'; + + lastFilePath_map = newSrcName; + + cell_list.clear(); + + if (!LoadMap(lastFilePath_umd)) + { + lastFilePath_umd = std::string(); + return 0; + } + + GenerateUnrealMap(lastFilePath_map, (float)atof(cell_size), (float)atof(cell_height), (float)atof(cell_x), (float)atof(cell_y), atoi(cell_levels), atoi(cell_layers)); + cell_list.clear(); + + importData = jack_data; + return import_real(); +} + + +#endif +#ifndef JACK_PLUGIN int main(int, char**) { @@ -1185,12 +1497,12 @@ int main(int, char**) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, (fmt == 0) ? GL_BGRA : GL_RGBA, GL_UNSIGNED_BYTE, data); glBindTexture(GL_TEXTURE_2D, 0); return (void*)tex; - }; + }; ifd::FileDialog::Instance().DeleteTexture = [](void* tex) { GLuint texID = (GLuint)((uintptr_t)tex); glDeleteTextures(1, &texID); - }; + }; // Main loop while (!glfwWindowShouldClose(window)) @@ -1222,3 +1534,4 @@ int main(int, char**) return 0; } +#endif \ No newline at end of file diff --git a/vc_project/UnrealMapDrawTool.sln b/vc_project/UnrealMapDrawTool.sln index b496126..3ebdfc0 100644 --- a/vc_project/UnrealMapDrawTool.sln +++ b/vc_project/UnrealMapDrawTool.sln @@ -9,6 +9,8 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + JackPlugin|x64 = JackPlugin|x64 + JackPlugin|x86 = JackPlugin|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection @@ -17,6 +19,10 @@ Global {DCE3ED16-0878-433D-BF2C-40452C36B86D}.Debug|x64.Build.0 = Debug|x64 {DCE3ED16-0878-433D-BF2C-40452C36B86D}.Debug|x86.ActiveCfg = Debug|Win32 {DCE3ED16-0878-433D-BF2C-40452C36B86D}.Debug|x86.Build.0 = Debug|Win32 + {DCE3ED16-0878-433D-BF2C-40452C36B86D}.JackPlugin|x64.ActiveCfg = JackPlugin|x64 + {DCE3ED16-0878-433D-BF2C-40452C36B86D}.JackPlugin|x64.Build.0 = JackPlugin|x64 + {DCE3ED16-0878-433D-BF2C-40452C36B86D}.JackPlugin|x86.ActiveCfg = JackPlugin|Win32 + {DCE3ED16-0878-433D-BF2C-40452C36B86D}.JackPlugin|x86.Build.0 = JackPlugin|Win32 {DCE3ED16-0878-433D-BF2C-40452C36B86D}.Release|x64.ActiveCfg = Release|x64 {DCE3ED16-0878-433D-BF2C-40452C36B86D}.Release|x64.Build.0 = Release|x64 {DCE3ED16-0878-433D-BF2C-40452C36B86D}.Release|x86.ActiveCfg = Release|Win32 diff --git a/vc_project/UnrealMapDrawTool.vcxproj b/vc_project/UnrealMapDrawTool.vcxproj index 108e472..ab13172 100644 --- a/vc_project/UnrealMapDrawTool.vcxproj +++ b/vc_project/UnrealMapDrawTool.vcxproj @@ -5,6 +5,14 @@ Debug Win32 + + JackPlugin + Win32 + + + JackPlugin + x64 + Release Win32 @@ -32,6 +40,12 @@ v143 Unicode + + DynamicLibrary + true + v143 + Unicode + Application false @@ -45,6 +59,12 @@ v143 Unicode + + DynamicLibrary + true + v143 + Unicode + Application false @@ -60,12 +80,18 @@ + + + + + + @@ -75,11 +101,22 @@ DrawMap_x64d.exe $(VC_IncludePath);$(WindowsSDK_IncludePath);.\..\src; + + $(SolutionDir)\..\Release\ + vpKarPlugx64 + $(VC_IncludePath);$(WindowsSDK_IncludePath);.\..\src; + $(SolutionDir)\..\Release\ DrawMap_x32d.exe $(VC_IncludePath);$(WindowsSDK_IncludePath);.\..\src; + + $(SolutionDir)\..\Release\ + vpKarPlugx32 + $(VC_IncludePath);$(WindowsSDK_IncludePath);.\..\src; + $(Platform)\$(Configuration)\ + $(SolutionDir)\..\Release\ DrawMap_x32.exe @@ -94,7 +131,22 @@ Level3 true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _DEBUG;WIN32;NOMINMAX;_WIN32_WINNT=0x0501;WINVER=0x0501;NTDDI_VERSION=0x05010000;VC_EXTRALEAN;_ATL_XP_TARGETING;WIN32_LEAN_AND_MEAN;PSAPI_VERSION=1;GLEW_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDebug + stdcpplatest + + + Console + true + $(CoreLibraryDependencies);%(AdditionalDependencies);../src/glew32s.lib;../src/glfw3_32.lib;opengl32.lib + + + + + Level3 + true + _DEBUG;JACK_PLUGIN;WIN32;NOMINMAX;_WIN32_WINNT=0x0501;WINVER=0x0501;NTDDI_VERSION=0x05010000;VC_EXTRALEAN;_ATL_XP_TARGETING;WIN32_LEAN_AND_MEAN;PSAPI_VERSION=1;GLEW_STATIC;%(PreprocessorDefinitions) true MultiThreadedDebug stdcpplatest @@ -111,7 +163,7 @@ true true true - WIN32;NDEBUG;_WINDOWS;NOMINMAX;_WIN32_WINNT=0x0501;WINVER=0x0501;NTDDI_VERSION=0x05010000;VC_EXTRALEAN;_ATL_XP_TARGETING;WIN32_LEAN_AND_MEAN;PSAPI_VERSION=1;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;NOMINMAX;_WIN32_WINNT=0x0501;WINVER=0x0501;NTDDI_VERSION=0x05010000;VC_EXTRALEAN;_ATL_XP_TARGETING;WIN32_LEAN_AND_MEAN;PSAPI_VERSION=1;GLEW_STATIC;%(PreprocessorDefinitions) true MultiThreaded stdcpplatest @@ -129,7 +181,7 @@ Level3 true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _DEBUG;WIN32;NOMINMAX;_WIN32_WINNT=0x0501;WINVER=0x0501;NTDDI_VERSION=0x05010000;VC_EXTRALEAN;_ATL_XP_TARGETING;WIN32_LEAN_AND_MEAN;PSAPI_VERSION=1;GLEW_STATIC;%(PreprocessorDefinitions) true MultiThreadedDebug stdcpplatest @@ -140,13 +192,41 @@ $(CoreLibraryDependencies);%(AdditionalDependencies);../src/glew64s.lib;../src/glfw3.lib;opengl32.lib + + + Level3 + false + NDEBUG;JACK_PLUGIN;WIN32;NOMINMAX;_WIN32_WINNT=0x0501;WINVER=0x0501;NTDDI_VERSION=0x05010000;VC_EXTRALEAN;_ATL_XP_TARGETING;WIN32_LEAN_AND_MEAN;PSAPI_VERSION=1;GLEW_STATIC;%(PreprocessorDefinitions) + + + MultiThreaded + stdcpplatest + MaxSpeed + AnySuitable + true + Speed + true + true + + + Default + true + false + + + Console + true + $(CoreLibraryDependencies);%(AdditionalDependencies);../src/glew64s.lib;../src/glfw3.lib;opengl32.lib + ../src/jack_api.def + + Level3 true true true - WIN32;NDEBUG;_WINDOWS;NOMINMAX;_WIN32_WINNT=0x0501;WINVER=0x0501;NTDDI_VERSION=0x05010000;VC_EXTRALEAN;_ATL_XP_TARGETING;WIN32_LEAN_AND_MEAN;PSAPI_VERSION=1;%(PreprocessorDefinitions) + NDEBUG;WIN32;NOMINMAX;_WIN32_WINNT=0x0501;WINVER=0x0501;NTDDI_VERSION=0x05010000;VC_EXTRALEAN;_ATL_XP_TARGETING;WIN32_LEAN_AND_MEAN;PSAPI_VERSION=1;GLEW_STATIC;%(PreprocessorDefinitions) true MultiThreaded stdcpplatest @@ -171,6 +251,9 @@ + + + diff --git a/vc_project/UnrealMapDrawTool.vcxproj.filters b/vc_project/UnrealMapDrawTool.vcxproj.filters index 9116708..6574416 100644 --- a/vc_project/UnrealMapDrawTool.vcxproj.filters +++ b/vc_project/UnrealMapDrawTool.vcxproj.filters @@ -90,4 +90,9 @@ GLFW_SRC + + + IMGUI_SRC + + \ No newline at end of file