From a70e604c624bb9626b0be7314dc9c9e0bc69f7b5 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sun, 17 Mar 2024 19:19:08 -0500 Subject: [PATCH] Add in missing parsing features for TSX reading so that we have all the information we need to recreate the file. --- TiledCollisionEditor/Error.h | 116 ++++++++++++++++++ TiledCollisionEditor/TSXParser.h | 81 ++++++++++-- .../TiledCollisionEditor.vcxproj | 4 + .../TiledCollisionEditor.vcxproj.filters | 3 + TiledCollisionEditor/Tiles/Basic Tileset.tsx | 6 + TiledCollisionEditor/Tileset.h | 1 + TiledCollisionEditor/main.cpp | 5 +- assets/Tiles/Basic Tileset.tsx | 22 ++++ 8 files changed, 229 insertions(+), 9 deletions(-) create mode 100644 TiledCollisionEditor/Error.h diff --git a/TiledCollisionEditor/Error.h b/TiledCollisionEditor/Error.h new file mode 100644 index 0000000..7a5baf9 --- /dev/null +++ b/TiledCollisionEditor/Error.h @@ -0,0 +1,116 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions or derivations of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce the above +copyright notice. This list of conditions and the following disclaimer must be +reproduced in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +Portions of this software are copyright © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#pragma once +#include +#include +#include +#include +#include +#include + +#ifdef _DEBUG +#ifndef __EMSCRIPTEN__ +#ifndef __linux__ + #define NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) + // Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the + // allocations to be of _CLIENT_BLOCK type +#else + #define NEW new +#endif +#else + #define NEW new +#endif +#else + #define NEW new +#endif + +#undef ERR //Stupid Windows + +#ifndef __EMSCRIPTEN__ + //WARNING! err accepts a stream of data using << operators. If you want to concatenate strings via the + operator, you must wrap the entire operation in () + #define ERR(err) { \ + std::stringstream errStream; \ + errStream< +type DYNAMIC_CAST(auto variable){ + type pointer=dynamic_cast(variable); + if(pointer==nullptr)ERR("Could not dynamic cast to type "< +std::shared_ptrDYNAMIC_POINTER_CAST(const std::shared_ptr&variable){ + std::shared_ptr newVariable=dynamic_pointer_cast(variable); + if(!newVariable)ERR("Could not dynamic cast to pointer type "< +std::shared_ptrDYNAMIC_POINTER_CAST(const std::weak_ptr&variable){ + std::shared_ptr newVariable=dynamic_pointer_cast(variable.lock()); + if(!newVariable)ERR("Could not dynamic cast to pointer type "<tags; + }; + + enum NextObjectType{ + OBJECT, + PERSPECTIVEOBJECT, + NONOBJECT, + }; + Tileset parsedTilesetInfo; + std::vectororiginalData; + std::vectornonObjects; int previousTagID; + std::string currentObj; + NextObjectType nextObjType; inline void ParseTag(std::string tag){ XMLTag newTag; //First character is a '<' so we discard it. @@ -99,27 +116,77 @@ class TSXParser{ } } } - + //objectgroup + //object + //polygon if (newTag.tag=="tileset") { + parsedTilesetInfo.name=newTag.data["name"]; parsedTilesetInfo.tilecount=stoi(newTag.data["tilecount"]); parsedTilesetInfo.tilewidth=stoi(newTag.data["tilewidth"]); parsedTilesetInfo.tileheight=stoi(newTag.data["tileheight"]); parsedTilesetInfo.columns=stoi(newTag.data["columns"]); - } else + }else if (newTag.tag=="image") { parsedTilesetInfo.ImageData=newTag; parsedTilesetInfo.filename=newTag.GetString("source"); parsedTilesetInfo.imagewidth=newTag.GetInteger("width"); parsedTilesetInfo.imageheight=newTag.GetInteger("height"); - } else + }else if (newTag.tag=="property"){ - if(newTag.data["name"]=="Name"){ - std::string objectName=newTag.data["value"]; - parsedTilesetInfo.objects[objectName].AddTile(parsedTilesetInfo,previousTagID); + if(nextObjType!=NONOBJECT){ + if(newTag.data["name"]=="Name"){ + std::string objectName=newTag.data["value"]; + currentObj=objectName; + parsedTilesetInfo.objects[objectName].AddTile(parsedTilesetInfo,previousTagID); + parsedTilesetInfo.objects[objectName].perspectiveObj=nextObjType==PERSPECTIVEOBJECT; + } + }else{ + nonObjects.back().tags.push_back(newTag); + } + }else + if (newTag.tag=="object"){ + if(newTag.GetInteger("x")!=0||newTag.GetInteger("y")!=0){ + ERR(std::format("WARNING! The collision for {} was not properly made inside of this editor, but in Tiled!\n\nTHIS IS NOT ALLOWED!\n\nPlease delete the collision for {} to modify it here (Tileset ID: {}) \n\nCollision X:{} Collision Y:{}",currentObj,currentObj,previousTagID,newTag.GetInteger("x"),newTag.GetInteger("y"))); } - } else + }else + if (newTag.tag=="polygon"){ + int pointCount=0; + size_t parseMarker=0; + bool findComma=true; + vf2d collision; + Quadrilateral collisionQuad; + const std::string points=newTag.GetString("points"); + while(parseMarker3)ERR("WARNING! Trying to parse a shape that has more than 4 sides!"); + collisionQuad[pointCount++]=collision; + } + if(parseMarker==std::string::npos)break; + parseMarker++; //Ignore the symbol + findComma=!findComma; + } + if(pointCount<3)ERR("WARNING! Trying to parse a shape that has less than 4 sides!"); + parsedTilesetInfo.objects[currentObj].collisionTiles.push_back(collisionQuad); + }else if (newTag.tag=="tile"){ + if(newTag.data["type"]=="Object"){ + nextObjType=OBJECT; + }else + if(newTag.data["type"]=="PerspectiveObject"){ + nextObjType=PERSPECTIVEOBJECT; + }else{ + nextObjType=NONOBJECT; + nonObjects.push_back({}); + nonObjects.back().tags.push_back(newTag); + } previousTagID=newTag.GetInteger("id"); + }else + { + originalData.push_back(newTag); } }; public: diff --git a/TiledCollisionEditor/TiledCollisionEditor.vcxproj b/TiledCollisionEditor/TiledCollisionEditor.vcxproj index 5112476..e1526d1 100644 --- a/TiledCollisionEditor/TiledCollisionEditor.vcxproj +++ b/TiledCollisionEditor/TiledCollisionEditor.vcxproj @@ -129,6 +129,10 @@ + + + + diff --git a/TiledCollisionEditor/TiledCollisionEditor.vcxproj.filters b/TiledCollisionEditor/TiledCollisionEditor.vcxproj.filters index 64aac0f..7eabeed 100644 --- a/TiledCollisionEditor/TiledCollisionEditor.vcxproj.filters +++ b/TiledCollisionEditor/TiledCollisionEditor.vcxproj.filters @@ -48,6 +48,9 @@ Header Files + + Header Files + diff --git a/TiledCollisionEditor/Tiles/Basic Tileset.tsx b/TiledCollisionEditor/Tiles/Basic Tileset.tsx index b0d0850..6720585 100644 --- a/TiledCollisionEditor/Tiles/Basic Tileset.tsx +++ b/TiledCollisionEditor/Tiles/Basic Tileset.tsx @@ -722,6 +722,12 @@ + + + + + + diff --git a/TiledCollisionEditor/Tileset.h b/TiledCollisionEditor/Tileset.h index 7510c68..80e4290 100644 --- a/TiledCollisionEditor/Tileset.h +++ b/TiledCollisionEditor/Tileset.h @@ -43,6 +43,7 @@ All rights reserved. struct Tileset{ std::string filename; + std::string name; std::unordered_mapobjects; XMLTag ImageData; int tilecount=0; diff --git a/TiledCollisionEditor/main.cpp b/TiledCollisionEditor/main.cpp index 5780932..a5059d6 100644 --- a/TiledCollisionEditor/main.cpp +++ b/TiledCollisionEditor/main.cpp @@ -44,7 +44,7 @@ public: ImageCheckBox*createNewButton=nullptr; ImageCheckBox*editButton=nullptr; - + TSXParser parsedMap{""}; public: bool OnUserCreate() override { @@ -61,7 +61,8 @@ public: editButtonImg.Load("EditButton.png"); std::string tilesetFilename=TILESET_DIR+"Basic Tileset.tsx"; - Tileset&tileset=tilesets[tilesetFilename]=TSXParser{tilesetFilename}.GetData(); + parsedMap={tilesetFilename}; + Tileset&tileset=tilesets[tilesetFilename]=parsedMap.GetData(); Renderable&tilesetImg=images[tilesetFilename]; tilesetImg.Load(TILESET_DIR+tileset.filename); diff --git a/assets/Tiles/Basic Tileset.tsx b/assets/Tiles/Basic Tileset.tsx index b0d0850..70344a9 100644 --- a/assets/Tiles/Basic Tileset.tsx +++ b/assets/Tiles/Basic Tileset.tsx @@ -6,6 +6,11 @@ + + + + + @@ -16,6 +21,17 @@ + + + + + + + + + + + @@ -722,6 +738,12 @@ + + + + + +