Map Preloader progress
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 7m0s
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 7m0s
This commit is contained in:
parent
7ee04a54ee
commit
ee625f23b5
@ -1,7 +1,8 @@
|
||||
#include <strstream>
|
||||
#include<strstream>
|
||||
#include<unordered_map>
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<string>
|
||||
|
||||
struct XMLTag{
|
||||
std::string tag;
|
||||
@ -61,7 +62,7 @@ struct LayerTag{
|
||||
|
||||
struct Map{
|
||||
XMLTag MapData;
|
||||
XMLTag TilesetData;
|
||||
std::vector<TilesetTag>TilesetData;
|
||||
std::vector<LayerTag> LayerData;
|
||||
std::string FormatLayerData(std::ostream& os, std::vector<LayerTag>tiles) {
|
||||
std::string displayStr;
|
||||
@ -70,13 +71,6 @@ struct Map{
|
||||
}
|
||||
return displayStr;
|
||||
}
|
||||
friend std::ostream& operator << (std::ostream& os, Map& rhs) {
|
||||
os <<
|
||||
rhs.MapData <<"\n"<<
|
||||
rhs.TilesetData <<"\n"<<
|
||||
rhs.FormatLayerData(os,rhs.LayerData) <<"\n";
|
||||
|
||||
return os; }
|
||||
};
|
||||
|
||||
class TMXParser{
|
||||
@ -92,35 +86,68 @@ class TMXParser{
|
||||
Map parsedMapInfo;
|
||||
|
||||
void ParseTag(std::string tag) {
|
||||
XMLTag newTag;
|
||||
//First character is a '<' so we discard it.
|
||||
tag.erase(0,1); tag.erase(tag.length()-1,1); //Erase the first and last characters in the tag. Now parse by spaces.
|
||||
std::stringstream s(tag); //Turn it into a string stream to now parse into individual whitespaces.
|
||||
std::string data;
|
||||
while (s.good()) {
|
||||
s>>data;
|
||||
if (newTag.tag.length()==0) { //Tag's empty, so first line is the tag.
|
||||
newTag.tag=data;
|
||||
std::cout<<"Tag: "<<newTag.tag<<"\n";
|
||||
} else {
|
||||
std::string key = data.substr(0,data.find("="));
|
||||
std::string value = data.substr(data.find("=")+1,std::string::npos);
|
||||
auto ReadNextTag=[&](){
|
||||
XMLTag newTag;
|
||||
//First character is a '<' so we discard it.
|
||||
tag.erase(0,1); tag.erase(tag.length()-1,1); //Erase the first and last characters in the tag. Now parse by spaces.
|
||||
std::stringstream s(tag); //Turn it into a string stream to now parse into individual whitespaces.
|
||||
std::string data;
|
||||
while (s.good()) {
|
||||
int quotationMarkCount=0;
|
||||
bool pastEquals=false;
|
||||
data="";
|
||||
bool valid=false;
|
||||
while(s.good()){
|
||||
int character=s.get();
|
||||
if(character=='"'){
|
||||
quotationMarkCount++;
|
||||
}
|
||||
if(character==' '&"ationMarkCount%2==0){
|
||||
valid=true;
|
||||
break;
|
||||
}
|
||||
data+=character;
|
||||
if(pastEquals&"ationMarkCount%2==0){
|
||||
valid=true;
|
||||
break;
|
||||
}
|
||||
if(character=='='&"ationMarkCount%2==0){
|
||||
pastEquals=true;
|
||||
}
|
||||
}
|
||||
if(valid&&data.length()>0){
|
||||
if (newTag.tag.length()==0) { //Tag's empty, so first line is the tag.
|
||||
newTag.tag=data;
|
||||
}else{
|
||||
std::string key = data.substr(0,data.find("="));
|
||||
std::string value = data.substr(data.find("=")+1,std::string::npos);
|
||||
|
||||
//Strip Quotation marks.
|
||||
value = value.substr(1,std::string::npos);
|
||||
value = value.substr(0,value.length()-1);
|
||||
//Strip Quotation marks.
|
||||
value = value.substr(1,std::string::npos);
|
||||
value = value.substr(0,value.length()-1);
|
||||
|
||||
newTag.data[key]=value;
|
||||
std::cout<<" "<<key<<":"<<newTag.data[key]<<"\n";
|
||||
}
|
||||
}
|
||||
newTag.data[key]=value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newTag;
|
||||
};
|
||||
|
||||
XMLTag newTag{ReadNextTag()};
|
||||
|
||||
if (newTag.tag=="map") {
|
||||
parsedMapInfo.MapData=newTag;
|
||||
} else
|
||||
if (newTag.tag=="tileset") {
|
||||
parsedMapInfo.TilesetData=newTag;
|
||||
} else
|
||||
if (newTag.tag=="tileset"){
|
||||
TilesetTag tilesetTag;
|
||||
tilesetTag.data=newTag.data;
|
||||
tilesetTag.tag=newTag.tag;
|
||||
tilesetTag.firstgid=std::stoi(tilesetTag.data.at("firstgid"));
|
||||
const size_t slashMarkerSourceDir = tilesetTag.data.at("source").find_last_of('/');
|
||||
const std::string baseSourceDir=tilesetTag.data.at("source").substr(slashMarkerSourceDir+1);
|
||||
tilesetTag.baseSourceDir="assets/maps/"+baseSourceDir;
|
||||
parsedMapInfo.TilesetData.emplace_back(tilesetTag);
|
||||
}else
|
||||
if (newTag.tag=="layer") {
|
||||
LayerTag l = {newTag};
|
||||
parsedMapInfo.LayerData.push_back(l);
|
||||
@ -167,6 +194,5 @@ class TMXParser{
|
||||
}
|
||||
}
|
||||
|
||||
std::cout<<"Parsed Map Data:\n"<<parsedMapInfo<<"\n";
|
||||
}
|
||||
};
|
||||
@ -57,18 +57,6 @@ struct TileCollisionData{
|
||||
geom2d::rect<float>collision;
|
||||
};
|
||||
|
||||
struct TilesetData{
|
||||
int tilewidth=0,tileheight=0;
|
||||
bool isTerrain=false;
|
||||
std::unordered_map<int,ForegroundTileTag>foregroundTiles;
|
||||
std::unordered_map<int,ForegroundTileTag>upperForegroundTiles;
|
||||
std::unordered_map<int,TileCollisionData>collision;
|
||||
std::unordered_map<int,XMLTag>staircaseTiles;
|
||||
std::unordered_map<int,std::vector<int>>animationData;
|
||||
std::unordered_map<int,vi2d>tileRepeatData;
|
||||
std::set<int>reflectiveData;
|
||||
};
|
||||
|
||||
struct TilesheetData{
|
||||
std::string tilesetName;
|
||||
int firstgid;
|
||||
@ -150,7 +138,6 @@ class TSXParser{
|
||||
|
||||
#ifdef TSX_PARSER_SETUP
|
||||
#undef TSX_PARSER_SETUP
|
||||
extern bool _DEBUG_MAP_LOAD_INFO;
|
||||
Tileset&TSXParser::GetData() {
|
||||
return parsedTilesetInfo;
|
||||
}
|
||||
|
||||
@ -4,9 +4,140 @@
|
||||
#include<filesystem>
|
||||
#include"TSXParser.h"
|
||||
#include"olcUTIL_DataFile.h"
|
||||
#include<queue>
|
||||
|
||||
std::unordered_map<std::string,TSXParser>MAP_TILESETS;
|
||||
|
||||
|
||||
const TilesheetData GetTileSheet(TMXParser&map,int tileID){
|
||||
using BaseSourceDir=std::string;
|
||||
const std::vector<TilesetTag>&tileData=map.GetData().TilesetData;
|
||||
if(tileData.size()==1){
|
||||
return {tileData[0].tilesetFilename,1};
|
||||
}else{
|
||||
for (int i=1;i<tileData.size();i++){
|
||||
if(tileID%1000000>=tileData[i].firstgid-1)continue;
|
||||
if(tileID!=-1){
|
||||
return {tileData[i-1].tilesetFilename,tileData[i-1].firstgid};
|
||||
}else{
|
||||
return {tileData[i-1].tilesetFilename,tileData[i-1].firstgid};
|
||||
}
|
||||
}
|
||||
}
|
||||
return {tileData[tileData.size()-1].tilesetFilename,tileData[tileData.size()-1].firstgid};
|
||||
}
|
||||
|
||||
void SetupForegroundFadeGroups(TMXParser&map){
|
||||
std::set<vi2d>foregroundTilesAdded,upperForegroundTilesAdded;
|
||||
|
||||
auto GetCurrentMapData=[&map](){return map.GetData().MapData;};
|
||||
|
||||
for(int x=0;x<GetCurrentMapData().GetInteger("width");x++){
|
||||
for(int y=0;y<GetCurrentMapData().GetInteger("height");y++){
|
||||
int layerID=0;
|
||||
for(LayerTag&layer:map.GetData().LayerData){
|
||||
int tileID=layer.tiles[y][x]-1;
|
||||
if(tileID!=-1){
|
||||
TilesheetData tileSheet=GetTileSheet(map,tileID);
|
||||
const Tileset tilesetData{MAP_TILESETS.at(tileSheet.tilesetName).GetData()};
|
||||
int tileSheetWidth=tilesetData.imagewidth;
|
||||
int tileSheetHeight=tilesetData.imageheight;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int realTileSheetIndex=(tileID%1000000)-(tileSheet.firstgid-1);
|
||||
int tileSheetX=realTileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=realTileSheetIndex/tileSheetWidth;
|
||||
int checkTileIndex=tileID;
|
||||
int checkTileID=tileSheetIndex;
|
||||
#pragma region TileGroupShenanigans
|
||||
auto SetupTileGroups=[&](std::function<bool(TilesheetData,int)>IsForeground,TileRenderData tile,std::set<vi2d>&foregroundTilesIncluded,std::vector<TileGroup>&groups){
|
||||
if(foregroundTilesIncluded.find({x,y})==foregroundTilesIncluded.end()&&IsForeground(tileSheet,tileSheetIndex)){
|
||||
std::queue<vi2d>tileGroupChecks;
|
||||
TileGroup group;
|
||||
foregroundTilesIncluded.insert({x,y});
|
||||
group.InsertTile(tile);
|
||||
if(x>0&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{-1,0})==foregroundTilesIncluded.end())tileGroupChecks.push({x-1,y});
|
||||
if(x<GetCurrentMapData().GetInteger("width")-1&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{1,0})==foregroundTilesIncluded.end())tileGroupChecks.push({x+1,y});
|
||||
if(y>0&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{0,-1})==foregroundTilesIncluded.end())tileGroupChecks.push({x,y-1});
|
||||
if(y<GetCurrentMapData().GetInteger("height")-1&&foregroundTilesIncluded.find(vi2d{x,y}+vi2d{0,1})==foregroundTilesIncluded.end())tileGroupChecks.push({x,y+1});
|
||||
auto IterateThroughOtherLayers=[&](vi2d pos,bool loopAll=false){
|
||||
int layer2ID=0;
|
||||
bool hadForeground=false;
|
||||
for(LayerTag&layer2:map.GetData().LayerData){
|
||||
if(!loopAll&&&layer==&layer2){layer2ID++;continue;};
|
||||
int tileID=layer2.tiles[pos.y][pos.x]-1;
|
||||
TilesheetData tileSheet=GetTileSheet(map,tileID%1000000);
|
||||
const Tileset tilesetData{MAP_TILESETS.at(tileSheet.tilesetName).GetData()};
|
||||
int tileSheetWidth=tilesetData.imagewidth;
|
||||
int tileSheetHeight=tilesetData.imageheight;
|
||||
int tileSheetIndex=tileID-(tileSheet.firstgid-1);
|
||||
int realTileSheetIndex=(tileID%1000000)-(tileSheet.firstgid-1);
|
||||
int tileSheetX=realTileSheetIndex%tileSheetWidth;
|
||||
int tileSheetY=realTileSheetIndex/tileSheetWidth;
|
||||
//TilesheetData tileSheet;
|
||||
//vf2d pos;
|
||||
//vi2d tileSheetPos;
|
||||
//int tileID;
|
||||
//int layerID;
|
||||
TileRenderData tile{tileSheet,vi2d{pos.x,pos.y}*GetCurrentMapData().GetInteger("width"),vi2d{tileSheetX,tileSheetY}*GetCurrentMapData().GetInteger("width"),realTileSheetIndex,layer2ID};
|
||||
if(IsForeground(tileSheet,tileSheetIndex)){
|
||||
foregroundTilesIncluded.insert({pos.x,pos.y});
|
||||
group.InsertTile(tile);
|
||||
hadForeground=true;
|
||||
}
|
||||
layer2ID++;
|
||||
}
|
||||
return hadForeground;
|
||||
};
|
||||
IterateThroughOtherLayers({x,y});
|
||||
while(!tileGroupChecks.empty()){
|
||||
vi2d&pos=tileGroupChecks.front();
|
||||
if(IterateThroughOtherLayers(pos,true)){
|
||||
foregroundTilesIncluded.insert({pos.x,pos.y}); //Regardless of if we found a foreground tile or not, we need to add this to not get stuck in an infinite loop.
|
||||
vi2d targetPos=pos+vi2d{-1,0};
|
||||
if(pos.x>0&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||||
targetPos=pos+vi2d{1,0};
|
||||
if(pos.x<GetCurrentMapData().GetInteger("width")-1&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||||
targetPos=pos+vi2d{0,-1};
|
||||
if(pos.y>0&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||||
targetPos=pos+vi2d{0,1};
|
||||
if(pos.y<GetCurrentMapData().GetInteger("height")-1&&foregroundTilesIncluded.find(targetPos)==foregroundTilesIncluded.end()){tileGroupChecks.push(targetPos);foregroundTilesIncluded.insert(targetPos);}
|
||||
}
|
||||
tileGroupChecks.pop();
|
||||
}
|
||||
groups.push_back(group);
|
||||
}
|
||||
};
|
||||
tileID){return IsUpperForegroundTile(tileID);},tile,upperForegroundTilesAdded,upperForegroundTileGroups);
|
||||
#pragma endregion
|
||||
}
|
||||
layerID++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(TileGroup&group:foregroundTileGroups){
|
||||
std::sort(group.GetTiles().begin(),group.GetTiles().end(),[](TileRenderData&t1,TileRenderData&t2){return t1.layerID<t2.layerID;});
|
||||
}
|
||||
for(TileGroup&group:upperForegroundTileGroups){
|
||||
std::sort(group.GetTiles().begin(),group.GetTiles().end(),[](TileRenderData&t1,TileRenderData&t2){return t1.layerID<t2.layerID;});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LoadTilesets(TMXParser&map){
|
||||
for(XMLTag&tag:map.GetData().TilesetData){
|
||||
size_t slashMarkerSourceDir = tag.data["source"].find_last_of('/');
|
||||
std::string tilesetFilename=tag.data["source"].substr(slashMarkerSourceDir+1);
|
||||
const std::string BASE_DIR{std::format("..\\\\..\\\\Adventures in Lestoria\\\\assets\\\\maps/{}",tag.data["source"],tilesetFilename)};
|
||||
if(MAP_TILESETS.find(BASE_DIR)==MAP_TILESETS.end())auto&[key,tileset]=*(MAP_TILESETS.insert({BASE_DIR,TSXParser{BASE_DIR}}).first);
|
||||
}
|
||||
}
|
||||
|
||||
void GeneratePreloadFile(const std::string&file){
|
||||
TMXParser map{file};
|
||||
|
||||
LoadTilesets(map);
|
||||
|
||||
SetupForegroundFadeGroups(map);
|
||||
}
|
||||
|
||||
int main(int arg_count,char*args[]){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user