1
0
mirror of https://github.com/ScrelliCopter/tmx2gba.git synced 2025-02-21 03:29:25 +11:00

Added object exporting & the ability to store arguments in a parameters file, woo!

I'll update the readme when I can be bothered.
This commit is contained in:
2016-04-04 02:51:24 +10:00
parent cacfa29501
commit 29b64fffaf
10 changed files with 439 additions and 128 deletions

3
.gitignore vendored
View File

@@ -43,3 +43,6 @@ editor.png
.vs/
*.opendb
gfx/
res/
*.tmx2gba
map/

View File

@@ -15,9 +15,10 @@
#ifndef XGETOPT_H
#define XGETOPT_H
extern int optind, opterr;
extern char *optarg;
extern int optind;
extern char *optarg, *next;
void getoptClear ();
int getopt(int argc, char *argv[], char *optstring);
#endif //XGETOPT_H

View File

@@ -146,11 +146,18 @@
///////////////////////////////////////////////////////////////////////////////
char *optarg; // global argument pointer
char *next;
int optind = 0; // global argv index
void getoptClear ()
{
optarg = nullptr;
next = nullptr;
optind = 0;
}
int getopt(int argc, char *argv[], char *optstring)
{
static char *next = nullptr;
if (optind == 0)
next = nullptr;

View File

@@ -22,47 +22,67 @@
#include "tmxreader.h"
#include "tmxlayer.h"
#include "tmxobject.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <map>
#include <string>
#include <cstdint>
#include <algorithm>
#include <XGetopt.h>
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::vector;
using std::map;
using std::ifstream;
using std::ofstream;
using std::stoi;
using std::min;
using std::max;
using std::ios;
static const std::string g_strUsage = "Usage: tmx2gba [-h] [-r offset] [-lyc name] [-p 0-15] <-i inpath> <-o outpath>\nRun 'tmx2gba -h' to view all available options.";
static const std::string g_strFullHelp = R"(Usage: tmx2gba [-h] [-r offset] [-lyc name] [-p 0-15] <-i inpath> <-o outpath>
-h ---------- Display this help & command info.
-l <name> --- Name of layer to use (default first layer in TMX).
-y <name> --- Layer for palette mappings.
-c <name> --- Output a separate 8bit collision map of the specified layer.
-r <offset> - Offset tile indices (default 0).
-p <0-15> --- Select which palette to use for 4-bit tilesets.
-i <path> --- Path to input TMX file.
-o <path> --- Path to output files.)";
static const string g_strUsage = "Usage: tmx2gba [-h] [-f file] [-r offset] [-lyc name] [-p 0-15] [-m name;id] <-i inpath> <-o outpath>";
static const string g_strHelpShort = "Run 'tmx2gba -h' to view all available options.";
static const string g_strHelpFull = R"(
-h ------------ Display this help & command info.
-l <name> ----- Name of layer to use (default first layer in TMX).
-y <name> ----- Layer for palette mappings.
-c <name> ----- Output a separate 8bit collision map of the specified layer.
-r <offset> --- Offset tile indices (default 0).
-p <0-15> ----- Select which palette to use for 4-bit tilesets.
-m <name;id> -- Map an object name to an ID, will enable object exports.
-i <path> ----- Path to input TMX file.
-o <path> ----- Path to output files.
-f <file> ----- Specify a file to use for flags, will override any options specified in the cmd line.)";
struct SParams
{
std::string inPath, outPath;
std::string layer, collisionlay, paletteLay;
bool help = false;
string inPath, outPath;
string layer, collisionlay, paletteLay;
string flagFile;
int offset = 0;
int palette = 0;
vector<string> objMappings;
bool objExport = false;
};
bool ParseArgs ( int argc, char** argv, SParams* params )
void ParseArgs ( int argc, char** argv, SParams* params )
{
char cOption;
while ( ( cOption = (char)getopt ( argc, argv, "hr:l:c:p:y:i:o:" ) ) > 0 )
getoptClear ();
while ( ( cOption = (char)getopt ( argc, argv, "hr:l:c:p:y:m:i:o:f:" ) ) > 0 )
{
switch ( cOption )
{
case ( 'h' ):
std::cout << g_strFullHelp << std::endl;
return 0;
params->help = true;
return;
case ( 'l' ):
params->layer = optarg;
@@ -77,11 +97,16 @@ bool ParseArgs ( int argc, char** argv, SParams* params )
break;
case ( 'r' ):
params->offset = std::stoi ( optarg );
params->offset = stoi ( optarg );
break;
case ( 'p' ):
params->palette = std::stoi ( optarg );
params->palette = stoi ( optarg );
break;
case ( 'm' ):
params->objExport = true;
params->objMappings.push_back ( optarg );
break;
case ( 'i' ):
@@ -92,28 +117,35 @@ bool ParseArgs ( int argc, char** argv, SParams* params )
params->outPath = optarg;
break;
case ( 'f' ):
params->flagFile = optarg;
break;
default:
break;
}
}
}
bool CheckArgs ( const SParams* params )
{
// Check my paranoia.
if ( params->inPath.empty () )
{
std::cerr << "No input file specified." << std::endl;
std::cout << g_strUsage << std::endl;
cerr << "No input file specified." << endl;
cout << g_strUsage << endl << g_strHelpShort << endl;
return false;
}
if ( params->outPath.empty () )
{
std::cerr << "No output file specified." << std::endl;
std::cout << g_strUsage << std::endl;
cerr << "No output file specified." << endl;
cout << g_strUsage << endl << g_strHelpShort << endl;
return false;
}
if ( params->palette < 0 || params->palette > 15 )
{
std::cerr << "Invalid palette index." << std::endl;
std::cout << g_strUsage << std::endl;
cerr << "Invalid palette index." << endl;
cout << g_strUsage << endl << g_strHelpShort << endl;
return false;
}
@@ -122,12 +154,12 @@ bool ParseArgs ( int argc, char** argv, SParams* params )
template <typename T>
void WriteArray ( std::ofstream& a_fout, const std::vector<T>& a_dat, int a_perCol = 16 )
void WriteArray ( ofstream& a_fout, const vector<T>& a_dat, int a_perCol = 16 )
{
const int w = sizeof(T) * 2;
int col = 0;
std::string datType = "ERR";
string datType = "ERR";
if ( sizeof(T) == 1 )
{
datType = ".byte";
@@ -143,8 +175,8 @@ void WriteArray ( std::ofstream& a_fout, const std::vector<T>& a_dat, int a_perC
datType = ".word";
}
a_fout.setf ( std::ios::hex, std::ios::basefield );
a_fout.setf ( std::ios::showbase );
a_fout.setf ( ios::hex, ios::basefield );
a_fout.setf ( ios::showbase );
size_t i = 0;
for ( T element : a_dat )
@@ -154,7 +186,6 @@ void WriteArray ( std::ofstream& a_fout, const std::vector<T>& a_dat, int a_perC
a_fout << "\t" << datType << " ";
}
//a_fout << "0x" << std::hex << std::setw ( w ) << std::setfill ( '0' ) << (int)element;
a_fout << std::hex << (int)element;
if ( i < a_dat.size () - 1 )
@@ -165,7 +196,7 @@ void WriteArray ( std::ofstream& a_fout, const std::vector<T>& a_dat, int a_perC
}
else
{
a_fout << "" << std::endl;
a_fout << "" << endl;
col = 0;
}
}
@@ -177,17 +208,119 @@ void WriteArray ( std::ofstream& a_fout, const std::vector<T>& a_dat, int a_perC
int main ( int argc, char** argv )
{
SParams params;
if ( !ParseArgs ( argc, argv, &params ) )
ParseArgs ( argc, argv, &params );
if ( params.help )
{
cout << g_strUsage << endl << g_strHelpFull << endl;
return 0;
}
if ( params.flagFile.length () != 0 )
{
ifstream paramFile ( params.flagFile );
if ( !paramFile.is_open () )
{
cerr << "Failed to open param file." << endl;
return -1;
}
vector<string> fileArgTokens;
fileArgTokens.push_back ( "auu~~" );
bool carry = false;
string token;
while ( !paramFile.eof () )
{
if ( carry )
{
string tmp;
paramFile >> tmp;
token += " ";
token += tmp;
}
else
{
token.clear ();
paramFile >> token;
}
if ( token == "" )
{
continue;
}
bool qFr = token[0] == '"';
bool qBk = token[token.length () - 1] == '"';
if ( qFr && qBk )
{
fileArgTokens.push_back ( token.substr ( 1, token.length () - 2 ) );
}
else
if ( qFr )
{
fileArgTokens.push_back ( token.substr ( 1, token.length () - 1 ) );
carry = true;
}
else
if ( qBk )
{
fileArgTokens.push_back ( token.substr ( 0, token.length () - 1 ) );
carry = false;
}
else
{
fileArgTokens.push_back ( token );
}
}
vector<const char*> fileArgs;
fileArgs.reserve ( fileArgTokens.size () );
for ( auto& token : fileArgTokens )
{
fileArgs.push_back ( token.c_str () );
}
ParseArgs ( fileArgs.size (), (char**)fileArgs.data (), &params );
}
if ( !CheckArgs ( &params ) )
{
return -1;
}
// Object mappings.
map<string, uint32_t> objMapping;
if ( params.objExport )
{
for ( auto token : params.objMappings )
{
int splitter = token.find_last_of ( ';' );
if ( splitter == -1 )
{
cerr << "Malformed mapping (missing a splitter)." << endl;
return -1;
}
try
{
string name = token.substr ( 0, splitter );
int id = stoi ( token.substr ( splitter + 1 ) );
objMapping[name] = id;
}
catch ( std::exception )
{
cerr << "Malformed mapping, make sure id is numeric." << endl;
}
}
}
// Open & read input file.
CTmxReader tmx;
std::ifstream fin ( params.inPath );
ifstream fin ( params.inPath );
if ( !fin.is_open () )
{
std::cerr << "Failed to open input file." << std::endl;
cerr << "Failed to open input file." << endl;
return -1;
}
tmx.Open ( fin );
@@ -195,7 +328,7 @@ int main ( int argc, char** argv )
// Get layers.
if ( tmx.GetLayerCount () == 0 )
{
std::cerr << "No layers found." << std::endl;
cerr << "No layers found." << endl;
return -1;
}
const CTmxLayer* pLayerGfx = params.layer.empty () ? tmx.GetLayer ( 0 ) : tmx.GetLayer ( params.layer );
@@ -204,46 +337,46 @@ int main ( int argc, char** argv )
if ( pLayerGfx == nullptr )
{
std::cerr << "Input layer not found." << std::endl;
cerr << "Input layer not found." << endl;
return -1;
}
// Open output files.
std::ofstream foutS ( params.outPath + ".s", std::ios::binary );
std::ofstream foutH ( params.outPath + ".h", std::ios::binary );
ofstream foutS ( params.outPath + ".s" );
ofstream foutH ( params.outPath + ".h" );
if ( !foutS.is_open () || !foutH.is_open () )
{
std::cerr << "Failed to create output file(s).";
cerr << "Failed to create output file(s).";
return -1;
}
int slashPos = std::max ( (int)params.outPath.find_last_of ( '/' ), (int)params.outPath.find_last_of ( '\\' ) );
std::string name = params.outPath;
int slashPos = max ( (int)params.outPath.find_last_of ( '/' ), (int)params.outPath.find_last_of ( '\\' ) );
string name = params.outPath;
if ( slashPos != -1 )
{
name = name.substr ( slashPos + 1 );
}
// Write header guards.
std::string guard = "__TMX2GBA_" + name + "__";
string guard = "__TMX2GBA_" + name + "__";
for ( auto& c: guard ) c = (char)toupper ( (int)c );
foutH << "#ifndef " << guard << std::endl;
foutH << "#define " << guard << std::endl;
foutH << std::endl;
foutH << "#define " << name << "Width " << tmx.GetWidth () << std::endl;
foutH << "#define " << name << "Height " << tmx.GetHeight () << std::endl;
foutH << std::endl;
foutH << "#ifndef " << guard << endl;
foutH << "#define " << guard << endl;
foutH << endl;
foutH << "#define " << name << "Width " << tmx.GetWidth () << endl;
foutH << "#define " << name << "Height " << tmx.GetHeight () << endl;
foutH << endl;
// Convert to GBA-friendly charmap data.
const uint32_t* pRead = pLayerGfx->GetData ();
const uint32_t* pPalRead = pLayerPal == nullptr ? nullptr : pLayerPal->GetData ();
std::vector<uint16_t> vucCharDat;
vector<uint16_t> vucCharDat;
vucCharDat.reserve ( pLayerGfx->GetWidth () * pLayerGfx->GetHeight () );
for ( size_t i = 0; i < size_t(pLayerGfx->GetWidth () * pLayerGfx->GetHeight ()); ++i )
{
uint32_t uiRead = (*pRead++);
uint16_t usTile = (uint16_t)std::max<int32_t> ( 0, tmx.LidFromGid ( uiRead & ~FLIP_MASK ) + params.offset );
uint16_t usTile = (uint16_t)max<int32_t> ( 0, tmx.LidFromGid ( uiRead & ~FLIP_MASK ) + params.offset );
uint8_t ucFlags = 0x0;
// Get flipped!
@@ -266,36 +399,25 @@ int main ( int argc, char** argv )
}
// Save out charmap.
foutH << "#define " << name << "TilesLen " << vucCharDat.size () * 2 << std::endl;
foutH << "extern const unsigned short " << name << "Tiles[" << vucCharDat.size () << "];" << std::endl;
foutH << std::endl;
foutH << "#define " << name << "TilesLen " << vucCharDat.size () * 2 << endl;
foutH << "extern const unsigned short " << name << "Tiles[" << vucCharDat.size () << "];" << endl;
foutH << endl;
foutS << "\t.section .rodata" << std::endl;
foutS << "\t.align 2" << std::endl;
foutS << "\t.global " << name << "Tiles" << std::endl;
foutS << "\t.hidden " << name << "Tiles" << std::endl;
foutS << name << "Tiles" << ":" << std::endl;
foutS << "\t.section .rodata" << endl;
foutS << "\t.align 2" << endl;
foutS << "\t.global " << name << "Tiles" << endl;
foutS << "\t.hidden " << name << "Tiles" << endl;
foutS << name << "Tiles" << ":" << endl;
WriteArray<uint16_t> ( foutS, vucCharDat );
foutS << std::endl;
/*
std::ofstream fout ( params.outPath, std::ios::binary );
if ( !fout.is_open () )
{
std::cerr << "Failed to create output file.";
return -1;
}
fout.write ( (const char*)vucCharDat.data (), vucCharDat.size () * sizeof(uint16_t) );
fout.close ();
*/
foutS << endl;
// Convert collision map & save it out.
if ( pLayerCls != nullptr )
{
std::vector<uint8_t> vucCollisionDat;
vector<uint8_t> vucCollisionDat;
vucCollisionDat.reserve ( pLayerCls->GetWidth () * pLayerCls->GetHeight () );
const uint32_t* pRead = pLayerCls->GetData ();
pRead = pLayerCls->GetData ();
for ( int i = 0; i < pLayerCls->GetWidth () * pLayerCls->GetHeight (); ++i )
{
uint8_t ucTile = (uint8_t)tmx.LidFromGid ( (*pRead++) & ~FLIP_MASK );
@@ -303,9 +425,9 @@ int main ( int argc, char** argv )
}
// Try to nicely append "_collision" to the output name.
std::string strPath;
string strPath;
size_t extPos = params.outPath.find_last_of ( '.' );
if ( extPos != std::string::npos )
if ( extPos != string::npos )
{
strPath = params.outPath.insert ( extPos, "_collision" );
}
@@ -315,30 +437,56 @@ int main ( int argc, char** argv )
}
// Save it out.
foutH << "#define " << name << "CollisionLen " << vucCollisionDat.size () << std::endl;
foutH << "extern const unsigned char " << name << "Collision[" << vucCollisionDat.size () << "];" << std::endl;
foutH << std::endl;
foutH << "#define " << name << "CollisionLen " << vucCollisionDat.size () << endl;
foutH << "extern const unsigned char " << name << "Collision[" << vucCollisionDat.size () << "];" << endl;
foutH << endl;
foutS << std::endl;
foutS << "\t.section .rodata" << std::endl;
foutS << "\t.align 2" << std::endl;
foutS << "\t.global " << name << "Collision" << std::endl;
foutS << "\t.hidden " << name << "Collision" << std::endl;
foutS << name << "Collision" << ":" << std::endl;
foutS << endl;
foutS << "\t.section .rodata" << endl;
foutS << "\t.align 2" << endl;
foutS << "\t.global " << name << "Collision" << endl;
foutS << "\t.hidden " << name << "Collision" << endl;
foutS << name << "Collision" << ":" << endl;
WriteArray<uint8_t> ( foutS, vucCollisionDat );
foutS << std::endl;
foutS << endl;
}
/*
fout.open ( strPath, std::ios::binary );
if ( fout.is_open () )
if ( params.objExport )
{
fout.write ( (const char*)vucCollisionDat.data (), vucCollisionDat.size () * sizeof(uint8_t) );
fout.close ();
}
*/
vector<uint32_t> objDat;
for ( int i = 0; i < tmx.GetObjectCount (); ++i )
{
auto obj = tmx.GetObject ( i );
auto it = objMapping.find ( obj->GetName () );
if ( it == objMapping.end () )
{
continue;
}
foutH << "#endif//" << guard << std::endl;
float x, y;
obj->GetPos ( &x, &y );
objDat.push_back ( it->second );
objDat.push_back ( (int)( x * 256.0f ) );
objDat.push_back ( (int)( y * 256.0f ) );
}
// Save it out.
foutH << "#define " << name << "ObjCount " << objDat.size () / 3 << endl;
foutH << "#define " << name << "ObjdatLen " << objDat.size () * sizeof(int) << endl;
foutH << "extern const unsigned int " << name << "Objdat[" << objDat.size () << "];" << endl;
foutH << endl;
foutS << endl;
foutS << "\t.section .rodata" << endl;
foutS << "\t.align 2" << endl;
foutS << "\t.global " << name << "Objdat" << endl;
foutS << "\t.hidden " << name << "Objdat" << endl;
foutS << name << "Objdat" << ":" << endl;
WriteArray<uint32_t> ( foutS, objDat );
foutS << endl;
}
foutH << "#endif//" << guard << endl;
foutH.close ();
foutS.close ();

61
src/tmxobject.cpp Normal file
View File

@@ -0,0 +1,61 @@
/* tmxobject.cpp
Copyright (C) 2015 Nicholas Curtis
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "tmxobject.h"
CTmxObject::CTmxObject () :
m_name ( "" ),
m_x ( 0.0f ), m_y ( 0.0f )
{
}
CTmxObject::CTmxObject ( const std::string& a_name, float a_x, float a_y ) :
m_name ( a_name ),
m_x ( a_x ), m_y ( a_y )
{
}
CTmxObject::~CTmxObject ()
{
}
const std::string& CTmxObject::GetName () const
{
return m_name;
}
void CTmxObject::GetPos ( float* a_outX, float* a_outY ) const
{
if ( a_outX != nullptr )
{
*a_outX = m_x;
}
if ( a_outY != nullptr )
{
*a_outY = m_y;
}
}

21
src/tmxobject.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef __TMXOBJECT_H__
#define __TMXOBJECT_H__
#include <string>
class CTmxObject
{
public:
CTmxObject ();
CTmxObject ( const std::string& a_name, float a_x, float a_y );
~CTmxObject ();
const std::string& GetName () const;
void GetPos ( float* a_outX, float* a_outY ) const;
private:
std::string m_name;
float m_x, m_y;
};
#endif//__TMXOBJECT_H__

View File

@@ -22,6 +22,7 @@
#include "tmxreader.h"
#include "tmxtileset.h"
#include "tmxobject.h"
#include "tmxlayer.h"
#include <cstdint>
#include <sstream>
@@ -39,18 +40,18 @@ CTmxReader::CTmxReader ()
CTmxReader::~CTmxReader ()
{
// Delete old tilesets.
for ( auto pTileset : m_vpTileset )
for ( auto pTileset : m_tileset )
{
delete pTileset;
}
m_vpTileset.clear ();
m_tileset.clear ();
// Delete old layers.
for ( auto pLay : m_vpLayers )
for ( auto pLay : m_layers )
{
delete pLay;
}
m_vpLayers.clear ();
m_layers.clear ();
}
@@ -104,7 +105,7 @@ void CTmxReader::ReadTileset ( rapidxml::xml_node<>* a_xNode )
uiFirstGid = std::stoul ( xAttrib->value () );
}
m_vpTileset.push_back ( new CTmxTileset ( szName, szSource, uiFirstGid ) );
m_tileset.push_back ( new CTmxTileset ( szName, szSource, uiFirstGid ) );
}
void CTmxReader::ReadLayer ( rapidxml::xml_node<>* a_xNode )
@@ -149,26 +150,65 @@ void CTmxReader::ReadLayer ( rapidxml::xml_node<>* a_xNode )
}
}
m_vpLayers.push_back ( new CTmxLayer ( iWidth, iHeight, szName, pTileDat ) );
m_layers.push_back ( new CTmxLayer ( iWidth, iHeight, szName, pTileDat ) );
}
void CTmxReader::ReadObjects ( rapidxml::xml_node<>* a_xNode )
{
for ( auto xNode = a_xNode->first_node (); xNode != nullptr; xNode = xNode->next_sibling () )
{
if ( strcmp ( xNode->name (), "object" ) != 0 )
{
continue;
}
rapidxml::xml_attribute<>* xAttrib;
const char* name = "";
float x = 0.0f;
float y = 0.0f;
// Read name.
xAttrib = xNode->first_attribute ( "name" );
if ( xAttrib != nullptr )
{
name = xAttrib->value ();
}
// Read X pos.
xAttrib = xNode->first_attribute ( "x" );
if ( xAttrib != nullptr )
{
x = std::stof ( xAttrib->value () );
}
// Read Y pos.
xAttrib = xNode->first_attribute ( "y" );
if ( xAttrib != nullptr )
{
y = std::stof ( xAttrib->value () );
}
m_objects.push_back ( new CTmxObject ( name, x, y ) );
}
}
void CTmxReader::Open ( std::istream& a_in )
{
// Delete old tilesets.
for ( auto pTileset : m_vpTileset )
for ( auto pTileset : m_tileset )
{
delete pTileset;
}
m_vpTileset.clear ();
m_tileset.clear ();
// Delete old layers.
for ( auto pLay : m_vpLayers )
for ( auto pLay : m_layers )
{
delete pLay;
}
m_vpLayers.clear ();
m_layers.clear ();
m_vuiGidTable.clear ();
m_gidTable.clear ();
// Read string into a buffer.
std::stringstream buf;
@@ -191,11 +231,11 @@ void CTmxReader::Open ( std::istream& a_in )
rapidxml::xml_attribute<>* xAttrib = nullptr;
if ( ( xAttrib = xMap->first_attribute ( "width" ) ) != nullptr )
{
m_iWidth = std::stoi ( xAttrib->value () );
m_width = std::stoi ( xAttrib->value () );
}
if ( ( xAttrib = xMap->first_attribute ( "height" ) ) != nullptr )
{
m_iHeight = std::stoi ( xAttrib->value () );
m_height = std::stoi ( xAttrib->value () );
}
// Read nodes.
@@ -211,36 +251,41 @@ void CTmxReader::Open ( std::istream& a_in )
{
ReadTileset ( xNode );
}
else
if ( strcmp ( xNode->name (), "objectgroup" ) == 0 )
{
ReadObjects ( xNode );
}
}
// Generate global id table.
for ( auto pTileset : m_vpTileset )
for ( auto pTileset : m_tileset )
{
m_vuiGidTable.push_back ( pTileset->GetFirstGid () );
m_gidTable.push_back ( pTileset->GetFirstGid () );
}
std::sort ( m_vuiGidTable.rbegin (), m_vuiGidTable.rend () );
std::sort ( m_gidTable.rbegin (), m_gidTable.rend () );
}
int CTmxReader::GetWidth () const
{
return m_iWidth;
return m_width;
}
int CTmxReader::GetHeight () const
{
return m_iHeight;
return m_height;
}
const CTmxLayer* CTmxReader::GetLayer ( int a_iId ) const
const CTmxLayer* CTmxReader::GetLayer ( int a_id ) const
{
return m_vpLayers[a_iId];
return m_layers[a_id];
}
const CTmxLayer* CTmxReader::GetLayer ( std::string a_strName ) const
{
for ( auto pLay : m_vpLayers )
for ( auto pLay : m_layers )
{
if ( pLay->GetName ().compare ( a_strName ) == 0 )
{
@@ -253,13 +298,24 @@ const CTmxLayer* CTmxReader::GetLayer ( std::string a_strName ) const
int CTmxReader::GetLayerCount () const
{
return m_vpLayers.size ();
return m_layers.size ();
}
const CTmxObject* CTmxReader::GetObject ( int a_id ) const
{
return m_objects[a_id];
}
int CTmxReader::GetObjectCount () const
{
return m_objects.size ();
}
uint32_t CTmxReader::LidFromGid ( uint32_t a_uiGid )
{
for ( uint32_t uiFirst : m_vuiGidTable )
for ( uint32_t uiFirst : m_gidTable )
{
if ( uiFirst <= a_uiGid )
{

View File

@@ -8,6 +8,7 @@
class CTmxTileset;
class CTmxLayer;
class CTmxObject;
namespace rapidxml { template<class Ch = char> class xml_node; }
class CTmxReader
@@ -21,21 +22,26 @@ public:
int GetWidth () const;
int GetHeight () const;
const CTmxLayer* GetLayer ( int a_iId ) const;
const CTmxLayer* GetLayer ( int a_id ) const;
const CTmxLayer* GetLayer ( std::string a_strName ) const;
int GetLayerCount () const;
uint32_t LidFromGid ( uint32_t a_uiGid );
const CTmxObject* GetObject ( int a_id ) const;
int GetObjectCount () const;
uint32_t LidFromGid ( uint32_t a_gid );
private:
bool DecodeMap ( uint32_t* a_pOut, size_t a_outSize, const std::string& a_strIn );
bool DecodeMap ( uint32_t* a_out, size_t a_outSize, const std::string& a_strIn );
void ReadTileset ( rapidxml::xml_node<>* a_xNode );
void ReadLayer ( rapidxml::xml_node<>* a_xNode );
void ReadObjects ( rapidxml::xml_node<>* a_xNode );
int m_iWidth, m_iHeight;
std::vector<CTmxTileset*> m_vpTileset;
std::vector<CTmxLayer*> m_vpLayers;
std::vector<uint32_t> m_vuiGidTable;
int m_width, m_height;
std::vector<CTmxTileset*> m_tileset;
std::vector<CTmxLayer*> m_layers;
std::vector<CTmxObject*> m_objects;
std::vector<uint32_t> m_gidTable;
};

View File

@@ -69,6 +69,7 @@
<ClCompile Include="src\base64.cpp" />
<ClCompile Include="src\tmx2gba.cpp" />
<ClCompile Include="src\tmxlayer.cpp" />
<ClCompile Include="src\tmxobject.cpp" />
<ClCompile Include="src\tmxreader.cpp" />
<ClCompile Include="src\XGetopt.cpp" />
<ClCompile Include="src\tmxtileset.cpp" />
@@ -82,6 +83,7 @@
<ClInclude Include="inc\rapidxml\rapidxml_utils.hpp" />
<ClInclude Include="inc\XGetopt.h" />
<ClInclude Include="src\tmxlayer.h" />
<ClInclude Include="src\tmxobject.h" />
<ClInclude Include="src\tmxreader.h" />
<ClInclude Include="src\tmxtileset.h" />
</ItemGroup>

View File

@@ -33,6 +33,9 @@
<ClCompile Include="src\tmxtileset.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\tmxobject.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="inc\base64.h">
@@ -65,5 +68,8 @@
<ClInclude Include="src\tmxtileset.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\tmxobject.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>