summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am4
-rw-r--r--src/main.cpp12
-rw-r--r--src/map.cpp7
-rw-r--r--src/map.h5
-rw-r--r--src/resources/image.cpp2
-rw-r--r--src/resources/image.h2
-rw-r--r--src/resources/mapreader.cpp229
-rw-r--r--src/resources/mapreader.h57
-rw-r--r--src/resources/resourcemanager.cpp71
9 files changed, 343 insertions, 46 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7cdf49a9..f7a8cfbb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -78,6 +78,8 @@ tmw_SOURCES = graphic/graphic.cpp \
net/win2linux.h \
resources/image.cpp \
resources/image.h \
+ resources/mapreader.cpp \
+ resources/mapreader.h \
resources/resource.cpp \
resources/resource.h \
resources/resourcemanager.cpp \
@@ -105,5 +107,5 @@ INCLUDES= $(all_includes)
# the library search path.
tmw_LDFLAGS = $(all_libraries) $(LIBSDL_RPATH) -lguichan_sdl -lguichan `pkg-config --libs libxml-2.0`
tmw_CXXFLAGS = $(LIBSDL_CFLAGS) `pkg-config --cflags libxml-2.0`
-tmw_LDADD = $(LIBSDL_LIBS) -lguichan_opengl -lguichan -lGL
+tmw_LDADD = $(LIBSDL_LIBS) -lguichan_opengl -lguichan -lGL -lphysfs
tmw_TARGET = ../tmw
diff --git a/src/main.cpp b/src/main.cpp
index 82f669d7..256b2943 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -114,10 +114,6 @@ class InitWarningListener : public gcn::ActionListener {
*/
void init_engine()
{
- // Initialize libxml2 and check for potential ABI mismatches between
- // compiled version and the shared library actually used.
- LIBXML_TEST_VERSION
-
// Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
std::cerr << "Could not initialize SDL: " <<
@@ -324,9 +320,15 @@ void exit_engine()
/** Main */
int main(int argc, char *argv[])
{
- init_engine();
+ // Initialize libxml2 and check for potential ABI mismatches between
+ // compiled version and the shared library actually used.
+ LIBXML_TEST_VERSION;
+
+ // Initialize PhysicsFS
PHYSFS_init(argv[0]);
+ init_engine();
+
SDL_Event event;
while (state != EXIT)
diff --git a/src/map.cpp b/src/map.cpp
index 76fba34a..2c7524a4 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -94,6 +94,13 @@ Map::Map():
tiles = new Tile[width * height];
}
+Map::Map(int width, int height):
+ width(width), height(height),
+ onClosedList(1), onOpenList(2)
+{
+ tiles = new Tile[width * height];
+}
+
Map::~Map()
{
delete[] tiles;
diff --git a/src/map.h b/src/map.h
index 26f3ef78..957b3b0a 100644
--- a/src/map.h
+++ b/src/map.h
@@ -83,6 +83,11 @@ class Map
Map();
/**
+ * Constructor that takes initial map size as parameters.
+ */
+ Map(int width, int height);
+
+ /**
* Destructor.
*/
~Map();
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 3f2e9560..d30d6c92 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -198,7 +198,7 @@ Image* Image::load(const std::string &filePath, int flags)
#endif
}
-Image* Image::load(const char* buffer, const unsigned int bufferSize)
+Image* Image::load(const char* buffer, unsigned int bufferSize)
{
// Define our RWops structure
SDL_RWops* rw = NULL;
diff --git a/src/resources/image.h b/src/resources/image.h
index 031f6645..ed1e0905 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -77,7 +77,7 @@ class Image : public Resource
* @return <code>NULL</code> if the an error occurred, a
* valid pointer otherwise.
*/
- static Image *load(const char* buffer, const unsigned int bufferSize);
+ static Image *load(const char* buffer, unsigned int bufferSize);
/**
* Frees the resources created by SDL.
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
new file mode 100644
index 00000000..7e604b93
--- /dev/null
+++ b/src/resources/mapreader.cpp
@@ -0,0 +1,229 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#include "mapreader.h"
+#include "../log.h"
+
+#include <iostream>
+
+#define DEFAULT_TILE_WIDTH 32
+#define DEFAULT_TILE_HEIGHT 32
+
+
+Map *MapReader::readMap(const std::string &filename)
+{
+ std::cout << "Attempting to parse XML map data";
+
+ FILE* f = fopen(filename.c_str(), "rb");
+ char *map_string;
+
+ if (!f) {
+ error(std::string("Error: failed to open ") + filename);
+ }
+
+ // Get size of file
+ fseek(f, 0, SEEK_END);
+ long size = ftell(f);
+ rewind(f);
+
+ // Read file into character array
+ map_string = new char[size + 1];
+ fread(map_string, 1, size, f);
+ map_string[size] = '\0';
+
+ fclose(f);
+
+ xmlDocPtr doc = xmlReadMemory(map_string, size, NULL, NULL, 0);
+ delete[] map_string;
+
+ if (doc) {
+ std::cout << "Looking for root node";
+ xmlNodePtr node = xmlDocGetRootElement(doc);
+
+ if (!node || !xmlStrEqual(node->name, BAD_CAST "map")) {
+ log("Warning: No map file (%s)!", filename.c_str());
+ return NULL;
+ }
+
+ std::cout << "Loading map from XML tree";
+ return readMap(node, filename);
+ xmlFreeDoc(doc);
+ } else {
+ log("Error while parsing map file (%s)!", filename.c_str());
+ }
+
+ return NULL;
+}
+
+Map* MapReader::readMap(xmlNodePtr node, const std::string &path)
+{
+ xmlChar *prop;
+
+ prop = xmlGetProp(node, BAD_CAST "version");
+ xmlFree(prop);
+
+ int w = getProperty(node, "width", 0);
+ int h = getProperty(node, "height", 0);
+ int tilew = getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH);
+ int tileh = getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT);
+ int layerNr = 0;
+ Map* map = new Map(w, h);
+
+ for (node = node->xmlChildrenNode; node != NULL; node = node->next)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "tileset")) {
+ /*
+ Tileset* set = readTileset(node, path);
+ if (set) {
+ map->tilesets.push_back(set);
+ }
+ */
+ }
+ else if (xmlStrEqual(node->name, BAD_CAST "layer")) {
+ log("- Loading layer %d", layerNr);
+ readLayer(node, map, layerNr);
+ layerNr++;
+ }
+ /*
+ else if (xmlStrEqual(node->name, BAD_CAST "object")) {
+ int x = getProperty(node, "x", 0);
+ int y = getProperty(node, "y", 0);
+
+ // Spawn the object
+ prop = xmlGetProp(node, BAD_CAST "type");
+
+ log("- Adding %s at (%d, %d)", (char*)prop, x, y);
+ map->addObject(double(x) / tilew, double(y) / tileh, (char*)prop);
+ xmlFree(prop);
+ }
+ */
+ }
+
+ return map;
+}
+
+void MapReader::readLayer(xmlNodePtr node, Map *map, int layer)
+{
+ // Ignored layer attributes
+ //int w = getProperty(node, "width", 0); // Map width is used
+ //int h = getProperty(node, "height", 0); // Map height is used
+ //xmlChar *name = xmlGetProp(node, BAD_CAST "name");
+
+ node = node->xmlChildrenNode;
+ int x = 0;
+ int y = 0;
+
+ // Load the tile data
+ /*
+ while (node != NULL)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "tile") && y < h)
+ {
+ xmlChar *name = xmlGetProp(node, BAD_CAST "name");
+ int gid = getProperty(node, "gid", -1);
+
+ if (gid > -1) {
+ layer->setTile(Point(x, y), map->getTile(gid));
+ }
+ else {
+ layer->setTile(Point(x, y), NULL);
+ }
+
+ x++;
+ if (x == w) {x = 0; y++;}
+ }
+
+ if (xmlStrEqual(node->name, BAD_CAST "data")) {
+ node = node->xmlChildrenNode;
+ } else {
+ node = node->next;
+ }
+ }
+ */
+}
+
+/*
+Tileset* MapReader::readTileset(xmlNodePtr node, const std::string &path)
+{
+ Tileset* set = NULL;
+
+ xmlChar* prop = xmlGetProp(node, BAD_CAST "source");
+ if (prop) {
+ console.log(CON_LOG, CON_ALWAYS,
+ "Warning: External tilesets not supported yet.");
+ xmlFree(prop);
+ return NULL;
+ }
+
+ int firstgid = getProperty(node, "firstgid", 0);
+ int tw = getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH);
+ int th = getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT);
+ int ts = getProperty(node, "spacing", 0);
+ xmlChar* name = xmlGetProp(node, BAD_CAST "name");
+
+ node = node->xmlChildrenNode;
+
+ while (node != NULL) {
+ if (xmlStrEqual(node->name, BAD_CAST "image")) {
+ xmlChar* source = xmlGetProp(node, BAD_CAST "source");
+
+ if (source) {
+ char* srcname = get_filename((char*)source);
+ BITMAP* tilebmp = module->findBitmap(srcname);
+
+ if (tilebmp) {
+ set = new Tileset();
+ set->importTileBitmap(tilebmp, (char*)source, tw, th, ts);
+ set->setFirstGid(firstgid);
+ if (name) { set->setName((char*)name); }
+ xmlFree(source);
+ } else {
+ printf("Warning: Failed to load tileset %s (%s)\n",
+ srcname, (char*)name);
+ }
+ }
+
+ break;
+ }
+
+ node = node->next;
+ }
+
+ xmlFree(name);
+
+ return set;
+}
+*/
+
+int MapReader::getProperty(xmlNodePtr node, const char* name, int def)
+{
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+ if (prop) {
+ int val = atoi((char*)prop);
+ xmlFree(prop);
+ return val;
+ }
+ else {
+ return def;
+ }
+}
diff --git a/src/resources/mapreader.h b/src/resources/mapreader.h
new file mode 100644
index 00000000..cf34f96f
--- /dev/null
+++ b/src/resources/mapreader.h
@@ -0,0 +1,57 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#ifndef _INCLUDED_MAPREADER_H
+#define _INCLUDED_MAPREADER_H
+
+#include "../map.h"
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+/**
+ * Reader for XML map files (*.tmx)
+ */
+class MapReader
+{
+ public:
+ /**
+ * Read an XML map from a file.
+ */
+ static Map *readMap(const std::string &filename);
+
+ /**
+ * Read an XML map from a parsed XML tree. The path is used to find the
+ * location of referenced tileset images.
+ */
+ static Map *readMap(xmlNodePtr node, const std::string &path);
+
+ private:
+ /**
+ * Helper function that handler reading the map layers.
+ */
+ static void readLayer(xmlNodePtr node, Map *map, int layer);
+
+ static int getProperty(xmlNodePtr node, const char* name, int def);
+};
+
+#endif
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 1e4af1a2..13cbc4d6 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -33,7 +33,6 @@
#else
#include <unistd.h>
#include <dirent.h>
-
#endif
ResourceEntry::ResourceEntry():
@@ -108,24 +107,27 @@ Resource* ResourceManager::get(const E_RESOURCE_TYPE &type,
reinterpret_cast<Resource*>(Image::load(filePath, flags));
// If the object is invalid, try using PhysicsFS
- if(resource == NULL) {
- std::cout << "Check If Exists: " << filePath << std::endl;
+ if (resource == NULL) {
+ std::cout << "Check if exists: " << filePath << std::endl;
// If the file is in the PhysicsFS search path
- if(PHYSFS_exists(filePath.c_str()) != 0) {
+ if (PHYSFS_exists(filePath.c_str()) != 0) {
// Open the file for read
PHYSFS_file* imageFile = PHYSFS_openRead(filePath.c_str());
- std::cout << filePath << " - " << PHYSFS_fileLength(imageFile) << " bytes" << std::endl;
+ std::cout << filePath << " - " <<
+ PHYSFS_fileLength(imageFile) << " bytes" << std::endl;
// Read the file data into a buffer
char* buffer = new char[PHYSFS_fileLength(imageFile)];
- PHYSFS_read(imageFile, buffer, 1, PHYSFS_fileLength(imageFile));
+ PHYSFS_read(imageFile, buffer, 1,
+ PHYSFS_fileLength(imageFile));
// Cast the file to a valid resource
- resource = reinterpret_cast<Resource*>(Image::load(buffer, PHYSFS_fileLength(imageFile)));
+ resource = reinterpret_cast<Resource*>(Image::load(buffer,
+ PHYSFS_fileLength(imageFile)));
// Close the file
PHYSFS_close(imageFile);
- delete buffer;
+ delete[] buffer;
}
}
@@ -189,19 +191,21 @@ void ResourceManager::searchAndAddZipFiles()
struct _finddata_t findFileInfo;
// Find the first zipped file
- long handle = static_cast<long>(::_findfirst(searchString.c_str(), &findFileInfo));
- long file = handle;
+ long handle =
+ static_cast<long>(::_findfirst(searchString.c_str(), &findFileInfo));
+ long file = handle;
// Loop until all files we're searching for are found
while (file >= 0) {
// Define the file path string
- std::string filePath = std::string("data/") + std::string(findFileInfo.name);
+ std::string filePath = std::string("data/") +
+ std::string(findFileInfo.name);
+
+ std::cout << "Adding to PhysicsFS: " << findFileInfo.name << std::endl;
// Add the zip file to our PhysicsFS search path
PHYSFS_addToSearchPath(filePath.c_str(), 1);
- std::cout << "Add To PhysicsFS: " << findFileInfo.name << std::endl;
-
// Find the next file
file = ::_findnext(handle, &findFileInfo);
}
@@ -212,40 +216,31 @@ void ResourceManager::searchAndAddZipFiles()
// Retrieve the current path
char programPath[256];
getcwd(programPath, 256);
+ strncat(programPath, "/data", 256 - strlen(programPath) - 1);
// Create our directory structure
- DIR directory = opendir(programPath);
+ DIR *dir = opendir(programPath);
- // If the directory is invalid
- if (directory == NULL) {
- // Return from the function
+ // Return if the directory is invalid
+ if (dir == NULL) {
return;
}
- // Change the directory to the folder
- chdir(programPath);
+ struct dirent *direntry;
+ while ((direntry = readdir(dir)) != NULL) {
+ char *ext = strstr(direntry->d_name, ".zip");
+ if (ext != NULL && strcmp(ext, ".zip") == 0) {
+ // Define the file path string
+ std::string filePath = std::string(programPath) +
+ std::string("/") + std::string(direntry->d_name);
- // Create the find file data structure
- struct finddata_t* findFileInfo = &directory->dd_dta;
-
- // Find the first occurence of the requested file
- long handle = static_cast<long>(findfirst("*", "*.zip"));
- long file = handle;
-
- // Loop until all files we're searching for are found
- while (file >= 0) {
- // Define the file path string
- std::string filePath = std::string("data/") + std::string(findFileInfo->name);
+ std::cout << "Adding to PhysicsFS: " << filePath << std::endl;
- // Add the zip file to our PhysicsFS search path
- PHYSFS_addToSearchPath(filePath.c_str(), 1);
-
- // Find the next file
- file = findnext(handle, findFileInfo);
+ // Add the zip file to our PhysicsFS search path
+ PHYSFS_addToSearchPath(filePath.c_str(), 1);
+ }
}
- // Perform cleanup
- findclose(handle);
- closedir(directory);
+ closedir(dir);
#endif
}