Map Preloader progress
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 7m0s

This commit is contained in:
sigonasr2 2026-02-17 15:11:59 -06:00
parent 7ee04a54ee
commit ee625f23b5
3 changed files with 190 additions and 46 deletions

View File

@ -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==' '&&quotationMarkCount%2==0){
valid=true;
break;
}
data+=character;
if(pastEquals&&quotationMarkCount%2==0){
valid=true;
break;
}
if(character=='='&&quotationMarkCount%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";
}
};

View File

@ -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;
}

View File

@ -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[]){