diff --git a/.gitmodules b/.gitmodules index 65807e1..876e2bd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "external/lua"] path = external/lua url = https://github.com/walterschell/Lua.git -[submodule "external/pugixml"] - path = external/pugixml - url = https://github.com/zeux/pugixml.git [submodule "external/freetype"] path = external/freetype url = https://gitlab.freedesktop.org/freetype/freetype.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 1adfab1..5d55687 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,10 +122,6 @@ if(NOT EXISTS "${PROJECT_SOURCE_DIR}/external/lua/CMakeLists.txt") message(FATAL_ERROR "LUA submodule was not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.") endif() -if(NOT EXISTS "${PROJECT_SOURCE_DIR}/external/pugixml/CMakeLists.txt") - message(FATAL_ERROR "PUGIXML submodule was not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.") -endif() - if(NOT EXISTS "${PROJECT_SOURCE_DIR}/external/freetype/CMakeLists.txt") message(FATAL_ERROR "FREETYPE submodule was not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.") endif() @@ -149,9 +145,6 @@ add_subdirectory(external/dearimgui) # add lua -- https://github.com/walterschell/Lua add_subdirectory(external/lua) -# add pugixml -add_subdirectory(external/pugixml) - # add freetype add_subdirectory(external/freetype) @@ -192,7 +185,7 @@ target_link_directories(${PROJECT_NAME} PRIVATE external/box2d/bin ) -target_link_libraries(${PROJECT_NAME} box2d glfw glad glm dearimgui lua_static pugixml freetype testbed) +target_link_libraries(${PROJECT_NAME} box2d glfw glad glm dearimgui lua_static freetype testbed) if (NOT NO_EDITOR) target_link_libraries(${PROJECT_NAME} editor) diff --git a/docs/tasks/Bugs.todo b/docs/tasks/Bugs.todo index 1e16286..5c3adf0 100644 --- a/docs/tasks/Bugs.todo +++ b/docs/tasks/Bugs.todo @@ -1,5 +1,6 @@ High Importance: + ☐ Editor does not get absolute paths from the file browser - replace with NFD dialogs @critical ✔ The Map Editor does not get the tile maps when a project is opened @high @done (3/3/2022, 2:47:41 PM) ✔ Tile Set IDs (as opposed to the Asset ID) is not saved or loaded yet @high @done (3/11/2022, 2:10:30 PM) ✔ Had to flip the V component of the UVs for the sprite vertices. This fixes the partial image drawing but will need to be accounted for in other places in the editor. @done (3/14/2022, 1:46:48 PM) diff --git a/docs/tasks/core.todo b/docs/tasks/core.todo index 8fd1748..6da2e26 100644 --- a/docs/tasks/core.todo +++ b/docs/tasks/core.todo @@ -7,9 +7,10 @@ Build System: ✔ Modify .sh scripts to recognize the noeditor flag @done (1/25/2022, 3:59:23 PM) Core: + Add custom (64 bit?) UUID generator (based on Chreno's UUIDs: ) ✔ Add Terminal subsystem to allow for printing colored text in a cross-platform way @done(22-05-16 18:05) ✔ Create a LogListener that uses the colored text (replace the current stdout listener) @done(22-05-16 18:23) - ☐ Replace XML with JSON (https://github.com/nlohmann/json) @high + ✔ Replace XML with JSON (https://github.com/nlohmann/json) @high @done(22-05-19 15:35) ✔ Move internal libs back into the core and refactor @high @done(22-05-17 14:27) ✔ Utils @done(22-05-13 17:29) ✔ assets @done(22-05-17 14:27) diff --git a/docs/tasks/editor.todo b/docs/tasks/editor.todo index b65d700..12b7e92 100644 --- a/docs/tasks/editor.todo +++ b/docs/tasks/editor.todo @@ -1,5 +1,7 @@ Editor: + ☐ Asset Location MUST be relative to the project root directory @critical + ☐ Switch to NFD dialogs ✔ Come up with project directory structure @done (9/17/2021, 6:46:44 PM) ✔ Make the editor a separate module @high @done (11/1/2021, 2:24:35 PM) ✔ Implement Run Mode interface class @high @done (2/8/2022, 4:05:17 PM) diff --git a/external/pugixml b/external/pugixml deleted file mode 160000 index 9e382f9..0000000 --- a/external/pugixml +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9e382f98076e57581fcc61323728443374889646 diff --git a/src/core/state.cpp b/src/core/state.cpp index cc3d81a..7cdbc5c 100644 --- a/src/core/state.cpp +++ b/src/core/state.cpp @@ -257,6 +257,9 @@ namespace lunarium auto& s = j["State"]; s["DataDirectory"] = DataDirectory; + const char* modes[] = { "game", "editor", "test" }; + s["Mode"] = modes[Mode]; + auto& d = s["Display"]; const char* names[] = { "opengl", "vulkan", "unknown" }; d["FullScreenResolution"]["Width"] = Display.FullScreenResolution.Width; diff --git a/src/gui/file_browser.cpp b/src/gui/file_browser.cpp index f8122a3..065986b 100644 --- a/src/gui/file_browser.cpp +++ b/src/gui/file_browser.cpp @@ -102,8 +102,8 @@ namespace lunarium if (ImGui::InputText("selection", mInputBuffer, mBufferSize)) { - // mInputSelection = mCurrentDirectory / mInputBuffer; - mInputSelection = mInputBuffer; + mInputSelection = mCurrentDirectory / mInputBuffer; + //mInputSelection = mInputBuffer; mpSelectedItem = &mInputSelection; } diff --git a/src/run_modes/editor/CMakeLists.txt b/src/run_modes/editor/CMakeLists.txt index 03f807b..8e66c01 100644 --- a/src/run_modes/editor/CMakeLists.txt +++ b/src/run_modes/editor/CMakeLists.txt @@ -31,6 +31,5 @@ target_include_directories(editor PUBLIC ../../../external/glad/include PUBLIC ../../../external/glfw/include PUBLIC ../../../external/box2d/include - PUBLIC ../../../external/pugixml/src PUBLIC ../../../external/ ) \ No newline at end of file diff --git a/src/run_modes/editor/contents/content_manager.cpp b/src/run_modes/editor/contents/content_manager.cpp index 2568660..b971741 100644 --- a/src/run_modes/editor/contents/content_manager.cpp +++ b/src/run_modes/editor/contents/content_manager.cpp @@ -9,10 +9,11 @@ ******************************************************************************/ #include "content_manager.h" -#include -#include "../project.h" -#include +#include #include "editor_asset.h" +#include "../project.h" +#include +#include // Asset types #include "tile_set.h" @@ -52,7 +53,7 @@ namespace lunarium { namespace editor mpProject = project; std::filesystem::path root = mpProject->GetRootDirectory(); - mContentFile = root / "contents/content_meta.xml"; + mContentFile = root / "contents/content_meta.json"; // If this is a new project being generated just create a base contents file if (!std::filesystem::exists(mContentFile)) @@ -72,72 +73,93 @@ namespace lunarium { namespace editor return Save(); } - // Load the file - pugi::xml_document doc; - pugi::xml_parse_result result = doc.load_file(mContentFile.string().c_str()); - if (result.status != pugi::xml_parse_status::status_ok) + std::ifstream ifs = std::ifstream(mContentFile.string().c_str()); + if (!ifs.is_open()) { - return OpRes::Fail("Could not open contents file: %s, %s", mContentFile.string().c_str(), result.description()); + return OpRes::Fail("Could not open contents file: %s", mContentFile.string().c_str()); } - pugi::xml_node proj_node = doc.child("Project"); - if (!proj_node) + nlohmann::json j; + ifs >> j; + ifs.close(); + + auto p = j["Project"]; + + if (p.is_null()) { - return OpRes::Fail("content_meta.xml missing Project root node"); + return OpRes::Fail("content_meta.json missing Project element"); } - // Get ID - pugi::xml_node ID = proj_node.child("NextID"); - - if (!ID) + if (p["NextID"].is_null()) { return OpRes::Fail("content_meta.xml missing NextID node"); } - mNextID = ID.attribute("ID").as_ullong(); + mNextID = p["NextID"].get(); - pugi::xml_node contents = proj_node.child("Contents"); + auto c = p["Contents"]; - if (!contents) + if (c.is_null()) { return OpRes::Fail("content_meta.xml missing Contents node"); } + + // ARRAY EXAMPLE + /* + std::string raw = "{\"Contents\" : [ { \"Name\" : \"first\", \"ID\" : 1 }, { \"Name\" : \"second\", \"ID\" : 2 }]}"; + + auto j = nlohmann::json::parse(raw); + + for (auto it = j["Contents"].begin(); it != j["Contents"].end(); ++it) + { + std::cout << (*it)["ID"] << " - " << (*it)["Name"] << "\n"; + } - // Iterate through content - for (pugi::xml_node asset = contents.child("Asset"); asset; asset = asset.next_sibling("Asset")) + nlohmann::json oj; + oj["Contents"].push_back({ {"Name", "first"}, {"ID", 1} }); + oj["Contents"].push_back({ {"Name", "second"}, { "ID", 2 } }); + + std::cout << "\n" << std::setw(4) << oj; + */ + /////////////////////////////////// + + for (auto it = c.begin(); it != c.end(); ++it) { + auto& asset = (*it); if (!IsValidAsset(asset)) { - return OpRes::Fail("Invalid asset node in content_meta.xml"); + return OpRes::Fail("Invalid asset node in content_meta.json"); } // Load Type - AssetType type = (AssetType)asset.attribute("Type").as_int(); + AssetType type = (AssetType)asset["Type"].get(); EditorAsset* pAsset = CreateAsset(type); - pAsset->mAssetDir = mpProject->GetAssetDirectory(); - + if (!pAsset) { return OpRes::Fail("Could not create Editor Asset. Unknown type: %n", (int)type); } + pAsset->mAssetDir = mpProject->GetAssetDirectory(); // Load ID - pAsset->mID = (uint64_t)asset.attribute("ID").as_ullong(); + pAsset->mID = asset["ID"].get(); // Load Location - pAsset->mLocation = std::filesystem::path(asset.attribute("Location").as_string()); + pAsset->mLocation = std::filesystem::path(asset["Location"].get()); // Load type specific data - if (Failed(pAsset->LoadFromXML(asset).LogIfFailed(Editor::LogCat))) + if (Failed(pAsset->LoadFromJSON(asset).LogIfFailed(Editor::LogCat).LogIfFailed(Editor::LogCat))) { return OpRes::Fail("Could not load asset type specific data for asset with ID: %llu, File: %s", pAsset->GetID(), pAsset->GetFileLocation().filename().string().c_str()); } // Store asset - if (mAssets.find(pAsset->mID) != mAssets.end()) + auto iter = mAssets.find(pAsset->mID); + if (iter != mAssets.end()) { - return OpRes::Fail("Asset ID collision, ID: %llu, File: %s", + return OpRes::Fail("Asset ID collision, First asset: ID: %llu, File: %s, Second asset: ID: %llu, File: %s", + iter->second->GetID(), iter->second->GetFileLocation().filename().string().c_str(), pAsset->GetID(), pAsset->GetFileLocation().filename().string().c_str()); } @@ -154,35 +176,43 @@ namespace lunarium { namespace editor return OpRes::Fail("ConentManager::Save failed: no project set"); } + nlohmann::json oj; + auto& p = oj["Project"]; + // Save header info - pugi::xml_document doc; - pugi::xml_node proj_node = doc.append_child("Project"); - proj_node.append_attribute("Name").set_value(mpProject->GetName().c_str()); - proj_node.append_child("NextID").append_attribute("ID").set_value(mNextID); - // pugi::xml_node proj_node = doc.append_child("Contents"); + p["Name"] = mpProject->GetName(); + p["NextID"] = mNextID; // Save all assets - pugi::xml_node contents = proj_node.append_child("Contents"); + auto& c = p["Contents"]; for (auto iter = mAssets.begin(); iter != mAssets.end(); iter++) { EditorAsset* pAsset = iter->second; - pugi::xml_node asset = contents.append_child("Asset"); + nlohmann::json asset; + + asset["Type"] = (i32)pAsset->GetType(); + asset["ID"] = pAsset->GetID(); - asset.append_attribute("Type").set_value((int)pAsset->GetType()); - asset.append_attribute("ID").set_value(pAsset->GetID()); - asset.append_attribute("Location").set_value(pAsset->GetFileLocation().string().c_str()); + // TODO: This needs to be a relative path! (Relative to the project root) + asset["Location"] = pAsset->GetFileLocation().string().c_str(); - if (Failed(pAsset->SaveToXML(asset).LogIfFailed(Editor::LogCat))) + if (Failed(pAsset->SaveToJSON(asset).LogIfFailed(Editor::LogCat).LogIfFailed(Editor::LogCat))) { return OpRes::Fail("Could not save asset meta data for file: %s", pAsset->GetFileLocation().string().c_str()); } + + c.push_back(asset); } - if (!doc.save_file(mContentFile.string().c_str())) + std::ofstream ofs = std::ofstream(mContentFile.string().c_str()); + if (!ofs.is_open()) { - return OpRes::Fail("ContentManager could not save file: %s", mContentFile.string().c_str()); + return OpRes::Fail("ContentManager could not save file: %s - could not open file", mContentFile.string().c_str()); } + ofs << std::setw(4) << oj; + ofs.close(); + return OpRes::OK(); } @@ -254,11 +284,13 @@ namespace lunarium { namespace editor return OpRes::Fail("Could not copy asset file from: %s to: %s", file.string().c_str(), to_location.string().c_str()); } + + EditorAsset* pAsset = CreateAsset(type); pAsset->mAssetDir = mpProject->GetAssetDirectory(); pAsset->mID = mNextID; mNextID++; - pAsset->mLocation = to_location; + pAsset->mLocation = mpProject->MakeRelativeToRoot(to_location); if (Failed(pAsset->LoadRawFile().LogIfFailed(Editor::LogCat))) { delete pAsset; @@ -283,11 +315,14 @@ namespace lunarium { namespace editor mAssets.erase(iter); } - bool ContentManager::IsValidAsset(pugi::xml_node& node) + bool ContentManager::IsValidAsset(nlohmann::json& node) { - if (!node.attribute("ID")) { return false; } - if (!node.attribute("Type")) { return false; } - if (!node.attribute("Location")) { return false; } + if (node.is_null()) { return false; } + if (node["ID"].is_null()) { return false; } + if (!node["ID"].is_number_unsigned()) { return false; } + if (node["Type"].is_null()) { return false; } + if (!node["Type"].is_number()) { return false; } + if (node["Location"].is_null()) { return false; } return true; } diff --git a/src/run_modes/editor/contents/content_manager.h b/src/run_modes/editor/contents/content_manager.h index 693c74b..9e3bdde 100644 --- a/src/run_modes/editor/contents/content_manager.h +++ b/src/run_modes/editor/contents/content_manager.h @@ -17,8 +17,7 @@ #include #include #include - -namespace pugi { class xml_node; } +#include namespace lunarium { namespace editor { @@ -63,7 +62,7 @@ namespace lunarium { namespace editor ContentManager& operator=(const ContentManager&) = delete; private: // Helpers - [[nodiscard]] bool IsValidAsset(pugi::xml_node& node); + [[nodiscard]] bool IsValidAsset(nlohmann::json& node); [[nodiscord]] EditorAsset* CreateAsset(AssetType type); void FreeAssets(); diff --git a/src/run_modes/editor/contents/editor_asset.h b/src/run_modes/editor/contents/editor_asset.h index a1c8fab..65c85bd 100644 --- a/src/run_modes/editor/contents/editor_asset.h +++ b/src/run_modes/editor/contents/editor_asset.h @@ -28,8 +28,8 @@ namespace lunarium { namespace editor std::filesystem::path GetFileLocation(); [[nodiscard]] virtual OpRes LoadRawFile() = 0; - [[nodiscard]] virtual OpRes LoadFromXML(pugi::xml_node& node) = 0; - [[nodiscard]] virtual OpRes SaveToXML(pugi::xml_node& node) = 0; + [[nodiscard]] virtual OpRes LoadFromJSON(nlohmann::json& node) = 0; + [[nodiscard]] virtual OpRes SaveToJSON(nlohmann::json& node) = 0; private: friend class ContentManager; @@ -40,6 +40,8 @@ namespace lunarium { namespace editor protected: std::filesystem::path mAssetDir; + + [[nodiscord]] virtual bool IsValidNode(nlohmann::json& node) = 0; }; }} diff --git a/src/run_modes/editor/contents/tile_set.cpp b/src/run_modes/editor/contents/tile_set.cpp index 73ecf24..bf116d3 100644 --- a/src/run_modes/editor/contents/tile_set.cpp +++ b/src/run_modes/editor/contents/tile_set.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include namespace lunarium { namespace editor { @@ -37,7 +37,7 @@ namespace lunarium { namespace editor return OpRes::OK(); } - OpRes TileSet::LoadFromXML(pugi::xml_node& node) + OpRes TileSet::LoadFromJSON(nlohmann::json& node) { // Load Image mSetImage = FileLoaders::LoadImage(mAssetDir / GetFileLocation()); @@ -46,26 +46,51 @@ namespace lunarium { namespace editor return OpRes::Fail("Could not load image file: %s", GetFileLocation().string().c_str()); } - mTileSetID = node.attribute("TileSetID").as_int(); - mTileSize.Width = node.attribute("TileSizeWidth").as_int(); - mTileSize.Height = node.attribute("TileSizeHeight").as_int(); - mNumTiles.Width = node.attribute("NumTilesCol").as_int(); - mNumTiles.Height = node.attribute("NumTilesRow").as_int(); + if (!IsValidNode(node)) + { + return OpRes::Fail("Asset node is invalid"); + } + + mTileSetID = node["TileSetID"].get(); + mTileSize.Width = node["TileSizeWidth"].get(); + mTileSize.Height = node["TileSizeHeight"].get(); + mNumTiles.Width = node["NumTilesCol"].get(); + mNumTiles.Height = node["NumTilesRow"].get(); return OpRes::OK(); } - OpRes TileSet::SaveToXML(pugi::xml_node& node) + OpRes TileSet::SaveToJSON(nlohmann::json& node) { - node.append_attribute("TileSetID").set_value(mTileSetID); - node.append_attribute("TileSizeWidth").set_value(mTileSize.Width); - node.append_attribute("TileSizeHeight").set_value(mTileSize.Height); - node.append_attribute("NumTilesCol").set_value(mNumTiles.Width); - node.append_attribute("NumTilesRow").set_value(mNumTiles.Height); + node["TileSetID"] = mTileSetID; + node["TileSizeWidth"] = mTileSize.Width; + node["TileSizeHeight"] = mTileSize.Height; + node["NumTilesCol"] = mNumTiles.Width; + node["NumTilesRow"] = mNumTiles.Height; return OpRes::OK(); } + bool TileSet::IsValidNode(nlohmann::json& node) + { + if (node["TileSetID"].is_null()) { return false; } + if (!node["TileSetID"].is_number()) { return false; } + + if (node["TileSizeWidth"].is_null()) { return false; } + if (!node["TileSizeWidth"].is_number()) { return false; } + + if (node["TileSizeHeight"].is_null()) { return false; } + if (!node["TileSizeHeight"].is_number()) { return false; } + + if (node["NumTilesCol"].is_null()) { return false; } + if (!node["NumTilesCol"].is_number()) { return false; } + + if (node["NumTilesRow"].is_null()) { return false; } + if (!node["NumTilesRow"].is_number()) { return false; } + + return true; + } + void TileSet::SetTileSetID(int id) { mTileSetID = id; diff --git a/src/run_modes/editor/contents/tile_set.h b/src/run_modes/editor/contents/tile_set.h index dbb6fe0..c893687 100644 --- a/src/run_modes/editor/contents/tile_set.h +++ b/src/run_modes/editor/contents/tile_set.h @@ -24,8 +24,8 @@ namespace lunarium { namespace editor // Load the raw asset file from the internal location OpRes LoadRawFile(); - OpRes LoadFromXML(pugi::xml_node& node); - OpRes SaveToXML(pugi::xml_node& node); + OpRes LoadFromJSON(nlohmann::json& node); + OpRes SaveToJSON(nlohmann::json& node); void SetTileSetID(int id); int GetTileSetID() const; @@ -45,6 +45,10 @@ namespace lunarium { namespace editor Sizei mNumTiles; int mTileSetID; + + private: + [[nodiscord]] virtual bool IsValidNode(nlohmann::json& node); + }; }} diff --git a/src/run_modes/editor/project.cpp b/src/run_modes/editor/project.cpp index 25fa2ac..7605a3a 100644 --- a/src/run_modes/editor/project.cpp +++ b/src/run_modes/editor/project.cpp @@ -8,8 +8,10 @@ #include "project.h" #include +#include #include "contents/content_manager.h" -#include +#include +#include namespace lunarium { namespace editor { @@ -39,13 +41,19 @@ namespace lunarium { namespace editor std::filesystem::path proj_doc = mLocation; proj_doc /= std::filesystem::path(mName + ".lproj"); - - pugi::xml_document doc; - pugi::xml_node proj_node = doc.append_child("Lunarium_Project"); - proj_node.append_attribute("name").set_value(mName.c_str()); - //pugi::xml_node name_node = proj_node.append_child("Name"); - doc.save_file(proj_doc.string().c_str()); + nlohmann::json j; + auto& p = j["Project"]; + p["Name"] = mName; + std::ofstream ofs = std::ofstream(proj_doc.c_str()); + if (!ofs.is_open()) + { + return OpRes::Fail("Failed to create project file"); + } + + ofs << std::setw(4) << j; + ofs.close(); + std::filesystem::create_directory(mLocation / std::filesystem::path("engine")); std::filesystem::create_directory(mLocation / std::filesystem::path("contents")); std::filesystem::create_directory(mLocation / std::filesystem::path("contents/assets")); @@ -116,5 +124,53 @@ namespace lunarium { namespace editor { return GetContentDirectory() / "assets"; } + + std::filesystem::path Project::MakeRelativeToRoot(std::filesystem::path abs_path) const + { + /* // HOW TO GET THE PATH RELATIVE TO THE PROJECT ROOT + std::filesystem::path p = "D:\\Projects\\lunarium\\test2\\contents\\assets\\LinkToThePast1_sized.png"; + + std::cout << "\nFull Path: " << p; + std::cout << "\nRelative path: " << p.relative_path(); + + std::filesystem::path proj = "D:\\Projects\\lunarium\\test2"; + std::filesystem::path new_path = proj.filename(); + for (auto iter = p.begin(); iter != p.end(); iter++) + { + std::cout << "\n" << (*iter); + if (proj.string().find((*iter).string()) == std::string::npos) + { + new_path /= (*iter); + } + + } + + std::cout << "\nNew Path: " << new_path; // new_path is what should be used as the location of the asset! + */ + + // Validate the passed in path + if (!abs_path.is_absolute()) + { + if (abs_path.filename() == std::filesystem::path(*mLocation.begin())) + { + // This path is already relative to the project root + return abs_path; + } + + Logger::Warn(Editor::LogCat, "Relative path passed into Project::MakeRelativeToRoot: %s", abs_path.string().c_str()); + return ""; + } + + std::filesystem::path new_path = mLocation.filename(); + for (auto iter = abs_path.begin(); iter != abs_path.end(); iter++) + { + if (mLocation.string().find((*iter).string()) == std::string::npos) + { + new_path /= (*iter); + } + } + + return new_path; + } }} \ No newline at end of file diff --git a/src/run_modes/editor/project.h b/src/run_modes/editor/project.h index 9cf39c8..243e2c6 100644 --- a/src/run_modes/editor/project.h +++ b/src/run_modes/editor/project.h @@ -39,6 +39,9 @@ namespace lunarium { namespace editor std::filesystem::path GetContentDirectory() const; std::filesystem::path GetAssetDirectory() const; + // Convert an absolute path to a path relative to the project root + std::filesystem::path MakeRelativeToRoot(std::filesystem::path) const; + private: bool mIsLoaded; std::string mName; diff --git a/test2/contents/content_meta.xml b/test2/contents/content_meta.xml index d114216..8522427 100644 --- a/test2/contents/content_meta.xml +++ b/test2/contents/content_meta.xml @@ -5,3 +5,20 @@ +{ + "Project" : { + "Name" = "test2.lproj", + "NextID" = 1, + "Contents" : [ + { + "Type" = 1, + "ID" = 0, + "Location" = "D:\Projects\lunarium\build\Debug\test2\contents\assets\LinkToThePast1_sized.png", + "TileSizeWidth" = 16, + "TileSizeHeight" = 16, + "NumTilesCol" = 64, + "NumTilesRow" = 64 + }, + ] + } +} \ No newline at end of file diff --git a/test2/test2.lproj b/test2/test2.lproj index 2364404..2cf4c7e 100644 --- a/test2/test2.lproj +++ b/test2/test2.lproj @@ -1,2 +1,6 @@ - - +{ + "Project" : { + "Name" : "test2" + } +} +