[Moeng-cvs] BBRpg/src/shared base64.cpp, NONE, 1.1 base64.h, NONE, 1.1 inflate.cpp, NONE, 1.1 infla
Status: Alpha
Brought to you by:
b_lindeijer
From: Bjørn L. <b_l...@us...> - 2007-02-13 01:49:26
|
Update of /cvsroot/moeng/BBRpg/src/shared In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv27860/src/shared Modified Files: console.cpp console.h module.cpp module.h object.cpp tiled_map.cpp tiled_map.h Added Files: base64.cpp base64.h inflate.cpp inflate.h map_reader.cpp map_reader.h Log Message: Added support for loading current Tiled maps to this old engine version. Index: module.h =================================================================== RCS file: /cvsroot/moeng/BBRpg/src/shared/module.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- module.h 23 Oct 2004 11:54:19 -0000 1.3 +++ module.h 13 Feb 2007 01:49:22 -0000 1.4 @@ -41,12 +41,12 @@ private: char* makeFilename(const char *name, const char *subdir); char* addMagic(const char *file); - + DATAFILE *script_data; char *path; char *datafile_name; int loadLevel; - + map<std::string, BITMAP*> bitmaps; map<std::string, MIDI*> midis; map<std::string, SAMPLE*> samples; Index: module.cpp =================================================================== RCS file: /cvsroot/moeng/BBRpg/src/shared/module.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- module.cpp 23 Oct 2004 11:54:19 -0000 1.3 +++ module.cpp 13 Feb 2007 01:49:22 -0000 1.4 @@ -23,6 +23,7 @@ #include "module.h" #include "../common.h" #include "../script.h" +#include "map_reader.h" Module::Module(const char *name) @@ -30,7 +31,7 @@ // Remember the path to be able to load from files later path = new char[strlen(name) + 1]; strcpy(path, name); - + // Open the datafile datafile_name = new char[strlen(name) + 1 + 4]; sprintf(datafile_name, "%s.dat", name); @@ -73,7 +74,7 @@ else { console.log(CON_LOG, CON_ALWAYS, "%sX \"%s\" not found!", spaces, name.c_str()); } - + delete[] spaces; } @@ -113,7 +114,7 @@ } temp++; } - + // Unload the datafile unload_datafile_object(script_data); script_data = NULL; @@ -140,6 +141,9 @@ char *filename = makeFilename(name.c_str(), "/maps"); console.log(CON_LOG, CON_ALWAYS, "Loading map \"%s\"...", filename); + mmap = MapReader::readMap(filename); + + /* if (exists(filename)) { mmap = new SquareMap(TILES_W, TILES_H); if (mmap) { @@ -162,6 +166,7 @@ unload_datafile_object(df); } } + */ delete[] filename; return mmap; @@ -177,7 +182,7 @@ } else { char *filename = makeFilename(name.c_str(), "/bitmaps"); - + // Attempt to load from disk, and otherwise from the datafile if (exists(filename)) { bitmap = load_bitmap(filename, NULL); Index: tiled_map.h =================================================================== RCS file: /cvsroot/moeng/BBRpg/src/shared/tiled_map.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- tiled_map.h 8 Feb 2007 17:51:50 -0000 1.8 +++ tiled_map.h 13 Feb 2007 01:49:22 -0000 1.9 @@ -15,14 +15,13 @@ #include <map> #include <list> #include <vector> +#include <string> #include <allegro.h> #include <libxml/xmlwriter.h> #include <libxml/tree.h> -using namespace std; - class Object; - +class Tileset; #define TILES_W 24 #define TILES_H 24 @@ -84,17 +83,24 @@ class TileType { public: - TileType(BITMAP *tileBitmap, const char *tileName); + TileType(BITMAP *tileBitmap, const char *tileName, int id = 0); ~TileType(); + void + setTileset(Tileset* set) { mTileset = set; } + BITMAP* getBitmap() {return bitmap;} char* getName() {return name;} int getColor() {return color;} + int getId() const { return mId; } + protected: BITMAP* bitmap; char* name; int color; + Tileset* mTileset; + int mId; }; @@ -123,9 +129,9 @@ int tile_w, int tile_h, int tile_spacing, int tiles_in_row); TileType* getTileType(const char *tileName); - vector<TileType*> generateTileArray(); + std::vector<TileType*> generateTileArray(); protected: - map<const char*, TileType*, ltstr> tileTypes; + std::map<const char*, TileType*, ltstr> tileTypes; }; @@ -138,7 +144,6 @@ void saveTo(PACKFILE *file); void saveTo(xmlTextWriterPtr writer); void loadFrom(PACKFILE *file, TileRepository *tileRepository); - void loadFrom(xmlNodePtr reader, TileRepository *tileRepository); void setType(TileType* tileType); TileType* getType() {return tileType;} @@ -149,6 +154,61 @@ }; +/** + * Tileset class. + */ +class Tileset +{ + public: + /** + * Constructor. + */ + Tileset(); + + void + importTileBitmap(BITMAP *tileBitmap, + const std::string &imgSource, + int tw, int th, int ts); + + TileType* + getTile(int id); + + void + setFirstGid(int gid) { firstgid = gid; } + + void + setName(const std::string &name) { mName = name; } + + int + getFirstGid() const { return firstgid; } + + int + getNumTiles() const { return tiles.size(); } + + int + getTileWidth() const { return tileWidth; } + + int + getTileHeight() const { return tileHeight; } + + int + getTileSpacing() const { return tileSpacing; } + + const std::string& + getName() const { return mName; } + + const std::string& + getImgSource() const { return mImgSource; } + + protected: + std::string mName; + std::string mImgSource; + int tileWidth, tileHeight, tileSpacing; + int firstgid; + std::vector<TileType*> tiles; +}; + + // Entity sorting helper class =============================================== class EntityP { @@ -172,7 +232,6 @@ void saveTo(PACKFILE* file); void saveTo(xmlTextWriterPtr writer); void loadFrom(PACKFILE* file, TileRepository *tileRepository); - void loadFrom(xmlNodePtr reader, TileRepository *tileRepository); int getWidth() { return width; } int getHeight() { return height; } @@ -183,6 +242,7 @@ float getOpacity(); Tile* getTile(const Point &tileCoords); + void setTile(const Point &tileCoords, TileType*); private: int width, height; @@ -207,14 +267,15 @@ void saveTo(xmlTextWriterPtr writer); int loadMap(const char* filename); void loadFrom(PACKFILE* file, TileRepository *tileRepository); - void loadFrom(xmlNodePtr reader, TileRepository *tileRepository); int getWidth() {return width;} int getHeight() {return height;} // Tile and entity methods //Tile* getTile(Point tileCoords); - TiledMapLayer* getLayer(int i); + TiledMapLayer* getLayer(unsigned int i); + TiledMapLayer* getLayer(const char *name); + void deleteLayers(); // Drawing the map virtual void setCamera(Point cameraCoords, Rectangle screenRect, @@ -234,6 +295,10 @@ void addReference(Object* obj); void removeObjects(); + // Tileset methods + Tileset* getTileset(const char* name) const; + TileType* getTile(int gid) const; + // Coordinate space converters virtual Point screenToTile(Point screenCoords); virtual Point tileToScreen(Point tileCoords); @@ -245,12 +310,13 @@ virtual Point getMapSize() = 0; // The layers - TiledMapLayer *mapLayers[2]; - int nrLayers; + std::vector<TiledMapLayer*> mapLayers; // Entity list - list<Object*> objects; + std::list<Object*> objects; + // Tileset list + std::list<Tileset*> tilesets; int width, height; protected: --- NEW FILE: inflate.h --- /* * The Mana World * Copyright 2006 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: inflate.h,v 1.1 2007/02/13 01:49:22 b_lindeijer Exp $ */ #ifndef _RAGE_INFLATE_H_ #define _RAGE_INFLATE_H_ /** * Inflates either zlib or gzip deflated memory. The inflated memory is * expected to be freed by the caller. Returns <code>true</code> if the * inflation was sucessful. */ bool inflateMemory(unsigned char *in, unsigned int inLength, unsigned char *&out, unsigned int &outLength); #endif --- NEW FILE: map_reader.cpp --- /* * RAGE - Role & Adventure Games Engine * Website: http://alternativegamers.com/ * Copyright 2005 Ramine Darabiha * * This file is part of RAGE. * * RAGE 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. * * RAGE 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 RAGE; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: map_reader.cpp,v 1.1 2007/02/13 01:49:22 b_lindeijer Exp $ */ #include "map_reader.h" #include "base64.h" #include "console.h" #include "../common.h" #include "inflate.h" #include "module.h" #include "object.h" #include "tiled_map.h" TiledMap* MapReader::readMap(const char *filename) { console.log(CON_LOG, CON_VDEBUG, "- Attempting to parse XML map data"); FILE* f = fopen(filename, "rb"); char *map_string; if (!f) { console.log(CON_QUIT, CON_ALWAYS, "Error: %s 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) { console.log(CON_LOG, CON_VDEBUG, "- Looking for root node"); xmlNodePtr node = xmlDocGetRootElement(doc); if (!node || !xmlStrEqual(node->name, BAD_CAST "map")) { console.log(CON_LOG, CON_ALWAYS, "Warning, no map file (%s)!", filename); return NULL; } console.log(CON_LOG, CON_VDEBUG, "- Loading map from XML tree"); return readMap(node, filename); xmlFreeDoc(doc); } else { console.log(CON_LOG, CON_ALWAYS, "Error while parsing map file (%s), trying old format...!", filename); TiledMap *mmap = new SquareMap(TILES_W, TILES_H); mmap->loadMap(filename); return mmap; } return NULL; } TiledMap* 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", TILES_W); int tileh = getProperty(node, "tileheight", TILES_H); TiledMap* map = new SquareMap(tilew, tileh); map->width = w; map->height = h; map->deleteLayers(); 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")) { console.log(CON_LOG, CON_VDEBUG, "- Loading layer %d", map->mapLayers.size() + 1); map->mapLayers.push_back(readLayer(node, map)); } 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"); console.log(CON_LOG, CON_VDEBUG, "- Adding %s at (%d, %d)", (char*) prop, x, y); map->addObject((double) x / TILES_W, (double) y / TILES_H, (char*) prop); xmlFree(prop); } } return map; } TiledMapLayer* MapReader::readLayer(xmlNodePtr node, TiledMap *map) { TiledMapLayer *layer = new TiledMapLayer(); // Get layer attributes int w = getProperty(node, "width", 0); int h = getProperty(node, "height", 0); xmlChar *name = xmlGetProp(node, BAD_CAST "name"); bool obstacleLayer = false; if (name) { layer->setName((char*)name); if (xmlStrEqual(name, BAD_CAST "Obstacle")) { obstacleLayer = true; } xmlFree(name); } layer->resizeTo(w, h); 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"); //xmlChar *obs = xmlGetProp(node, BAD_CAST "obstacle"); int gid = getProperty(node, "gid", -1); if (gid > -1) { layer->setTile(Point(x, y), map->getTile(gid)); } else if (name) { // DEPRECATED: Old way of storing tiles char buf[64]; strncpy(buf, (char*) name, 64); char *nr = strstr(buf, "."); if (nr) { *nr = '\0'; int id = atoi(++nr); Tileset* ts = map->getTileset(buf); if (ts) { layer->setTile(Point(x, y), ts->getTile(id)); } } xmlFree(name); } else { layer->setTile(Point(x, y), NULL); } /* if (obs) { tile->obstacle = ((obs[0] == '1') ? OB_TOP : 0) | ((obs[1] == '1') ? OB_RIGHT : 0) | ((obs[2] == '1') ? OB_BOTTOM : 0) | ((obs[3] == '1') ? OB_LEFT : 0); xmlFree(obs); } else { tile->obstacle = 0; } */ x++; if (x == w) {x = 0; y++;} } if (xmlStrEqual(node->name, BAD_CAST "data")) { xmlChar *encoding = xmlGetProp(node, BAD_CAST "encoding"); xmlChar *compression = xmlGetProp(node, BAD_CAST "compression"); bool base64Encoded = false; bool gzipCompressed = false; if (encoding && xmlStrEqual(encoding, BAD_CAST "base64")) { base64Encoded = true; xmlFree(encoding); } if (compression && xmlStrEqual(compression, BAD_CAST "gzip")) { gzipCompressed = true; xmlFree(compression); } if (base64Encoded) { xmlNodePtr dataChild = node->xmlChildrenNode; if (!dataChild) { console.log(CON_QUIT, CON_ALWAYS, "Layer data missing!"); } int len = strlen((char const *)dataChild->content) + 1; unsigned char *charData = new unsigned char[len + 1]; char const *charStart = (char const *)dataChild->content; unsigned char *charIndex = charData; while (*charStart) { if (*charStart != ' ' && *charStart != '\t' && *charStart != '\n') { *charIndex = *charStart; charIndex++; } charStart++; } *charIndex = '\0'; int binLen; unsigned char *binData = php3_base64_decode(charData, strlen((const char*) charData), &binLen); delete[] charData; if (!binData) { console.log(CON_QUIT, CON_ALWAYS, "Layer data decode failed!"); } if (gzipCompressed) { unsigned char *inflatedData; unsigned int inflatedLen; inflateMemory(binData, binLen, inflatedData, inflatedLen); free(binData); binData = inflatedData; binLen = inflatedLen; if (inflatedData == NULL) { console.log(CON_QUIT, CON_ALWAYS, "Layer data decompression failed!"); } } for (int i = 0; i < binLen - 3; i += 4) { int gid = binData[i] | binData[i + 1] << 8 | binData[i + 2] << 16 | binData[i + 3] << 24; TileType *type = map->getTile(gid); if (obstacleLayer) { Tile *tile = map->getLayer((unsigned int)0)->getTile( Point(x, y)); if (type) { tile->obstacle = type->getId(); } } else { layer->setTile(Point(x, y), type); } x++; if (x == w) { x = 0; y++; } } free(binData); // Make sure the while loop stops node = NULL; } else { // This is to support tile elements in a data element node = node->xmlChildrenNode; } } else { node = node->next; } } return layer; } 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", TILES_W); int th = getProperty(node, "tileheight", TILES_H); 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) { std::string filename = path.substr(0, path.rfind("/") + 1) + std::string((const char*)source); const char *nameOnly = get_filename(filename.c_str()); BITMAP* tilebmp = module->findBitmap(nameOnly); 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) for map " "%s\n", nameOnly, (char*)name, path.c_str()); } } 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; } } Index: console.cpp =================================================================== RCS file: /cvsroot/moeng/BBRpg/src/shared/console.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- console.cpp 7 Feb 2007 17:50:31 -0000 1.5 +++ console.cpp 13 Feb 2007 01:49:22 -0000 1.6 @@ -41,7 +41,7 @@ Console::~Console() { // Deallocate console string messages - list<char*>::iterator i; + std::list<char*>::iterator i; while (!logMessages.empty()) { i = logMessages.begin(); @@ -77,7 +77,7 @@ font = engine_font; - list<char*>::iterator i = logMessages.begin(); + std::list<char*>::iterator i = logMessages.begin(); while (i != logMessages.end() && posY > - text_height(font)) { textprintf_ex(dest, font, 2, posY, makecol(200,200,200), -1, (*i)); Index: object.cpp =================================================================== RCS file: /cvsroot/moeng/BBRpg/src/shared/object.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- object.cpp 23 Oct 2004 11:54:19 -0000 1.8 +++ object.cpp 13 Feb 2007 01:49:22 -0000 1.9 @@ -111,7 +111,7 @@ if (col && obstacle) { // Check for map obstacle - Tile *nextTile = map->getLayer(0)->getTile( + Tile *nextTile = map->getLayer((unsigned int)0)->getTile( Point((int)next_x, (int)next_y)); if (!nextTile || next_x < 0 || next_y < 0 || @@ -126,7 +126,7 @@ } // Check for object in the way - list<Object*>::iterator i; + std::list<Object*>::iterator i; for (i = map->objects.begin(); i != map->objects.end(); i++) { Object *obj = (*i); if ((obj->obstacle) && @@ -183,7 +183,7 @@ if (!map) return; // Check if this object is now standing on something - list<Object*>::iterator i; + std::list<Object*>::iterator i; for (i = map->objects.begin(); i != map->objects.end(); i++) { Object *obj = (*i); if ((obj != this) && --- NEW FILE: inflate.cpp --- /* * The Mana World * Copyright 2006 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: inflate.cpp,v 1.1 2007/02/13 01:49:22 b_lindeijer Exp $ */ #include "inflate.h" #include "console.h" #include <zlib.h> static void logZlibError(int error) { char *errorString; switch (error) { case Z_MEM_ERROR: errorString = "Out of memory while decompressing data!"; break; case Z_VERSION_ERROR: errorString = "Incompatible zlib version!"; break; case Z_DATA_ERROR: errorString = "Incorrect zlib compressed data!"; break; default: errorString = "Unknown error while decompressing data!"; } // TODO: Well, make it actually log the error printf("%s\n", errorString); exit(1); } bool inflateMemory(unsigned char *in, unsigned int inLength, unsigned char *&out, unsigned int &outLength) { int bufferSize = 256 * 1024; int ret; z_stream strm; out = (unsigned char*) malloc(bufferSize); strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.next_in = (Bytef *)in; strm.avail_in = inLength; strm.next_out = (Bytef *)out; strm.avail_out = bufferSize; ret = inflateInit2(&strm, 15 + 32); if (ret != Z_OK) { logZlibError(ret); return false; } do { ret = inflate(&strm, Z_SYNC_FLUSH); switch (ret) { case Z_NEED_DICT: case Z_STREAM_ERROR: ret = Z_DATA_ERROR; case Z_DATA_ERROR: case Z_MEM_ERROR: inflateEnd(&strm); logZlibError(ret); return false; } if (ret != Z_STREAM_END) { out = (unsigned char*) realloc(out, bufferSize * 2); if (!out) { inflateEnd(&strm); logZlibError(Z_MEM_ERROR); return false; } strm.next_out = (Bytef*) (out + bufferSize); strm.avail_out = bufferSize; bufferSize *= 2; } } while (ret != Z_STREAM_END); if (strm.avail_in != 0) { logZlibError(Z_DATA_ERROR); return false; } outLength = bufferSize - strm.avail_out; inflateEnd(&strm); return true; } Index: console.h =================================================================== RCS file: /cvsroot/moeng/BBRpg/src/shared/console.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- console.h 7 Feb 2007 17:50:31 -0000 1.4 +++ console.h 13 Feb 2007 01:49:22 -0000 1.5 @@ -11,22 +11,25 @@ #ifndef _INCLUDED_CONSOLE_H_ #define _INCLUDED_CONSOLE_H_ + #include <stdio.h> #include <list> +#include <allegro.h> -using namespace std; - - -#define CON_CONSOLE 1 -#define CON_LOG 2 -#define CON_QUIT 4 -#define CON_POPUP 8 -#define CON_ALWAYS 1 -#define CON_DEBUG 2 -#define CON_VDEBUG 4 +#define CON_CONSOLE 1 +#define CON_LOG 2 +#define CON_QUIT 4 +#define CON_POPUP 8 +#define CON_ALWAYS 1 +#define CON_DEBUG 2 +#define CON_VDEBUG 4 +/** + * The console. This class handles logging as well as displaying a console with + * the log in the game when the tilde is pressed. + */ class Console { public: @@ -36,14 +39,14 @@ void update(); void draw(BITMAP *dest); bool handleInput(int key); - void log(int where, int when, const char* what, ...); + void log(int where, int when, const char *what, ...); bool enableLogfile; private: FILE* logFile; char* logFilename; - list<char*> logMessages; + std::list<char*> logMessages; bool active; int progress; }; --- NEW FILE: base64.cpp --- /* +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2000 PHP Development Team (See Credits file) | +----------------------------------------------------------------------+ | This program is free software; you can redistribute it and/or modify | | it under the terms of one of the following licenses: | | | | A) the GNU General Public License as published by the Free Software | | Foundation; either version 2 of the License, or (at your option) | | any later version. | | | | B) the PHP License as published by the PHP Development Team and | | included in the distribution in the file: LICENSE | | | | This program 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 both licenses referred to here. | | If you did not, or have any questions about PHP licensing, please | | contact co...@ph.... | +----------------------------------------------------------------------+ | Author: Jim Winstead (ji...@ph...) | +----------------------------------------------------------------------+ */ /* $Id: base64.cpp,v 1.1 2007/02/13 01:49:22 b_lindeijer Exp $ */ #include <string.h> #include <stdlib.h> #include "base64.h" static char base64_table[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' }; static char base64_pad = '='; unsigned char *php3_base64_encode(const unsigned char *string, int length, int *ret_length) { const unsigned char *current = string; int i = 0; unsigned char *result = (unsigned char *)malloc(((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char)); while (length > 2) { /* keep going until we have less than 24 bits */ result[i++] = base64_table[current[0] >> 2]; result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)]; result[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)]; result[i++] = base64_table[current[2] & 0x3f]; current += 3; length -= 3; /* we just handle 3 octets of data */ } /* now deal with the tail end of things */ if (length != 0) { result[i++] = base64_table[current[0] >> 2]; if (length > 1) { result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)]; result[i++] = base64_table[(current[1] & 0x0f) << 2]; result[i++] = base64_pad; } else { result[i++] = base64_table[(current[0] & 0x03) << 4]; result[i++] = base64_pad; result[i++] = base64_pad; } } if(ret_length) { *ret_length = i; } result[i] = '\0'; return result; } /* as above, but backwards. :) */ unsigned char *php3_base64_decode(const unsigned char *string, int length, int *ret_length) { const unsigned char *current = string; int ch, i = 0, j = 0, k; char *chp; unsigned char *result = (unsigned char *)malloc(length + 1); if (result == NULL) { return NULL; } /* run through the whole string, converting as we go */ while ((ch = *current++) != '\0') { if (ch == base64_pad) break; /* When Base64 gets POSTed, all pluses are interpreted as spaces. This line changes them back. It's not exactly the Base64 spec, but it is completely compatible with it (the spec says that spaces are invalid). This will also save many people considerable headache. - Turadg Aleahmad <tu...@wi...> */ if (ch == ' ') ch = '+'; chp = strchr(base64_table, ch); if (chp == NULL) continue; ch = chp - base64_table; switch(i % 4) { case 0: result[j] = ch << 2; break; case 1: result[j++] |= ch >> 4; result[j] = (ch & 0x0f) << 4; break; case 2: result[j++] |= ch >>2; result[j] = (ch & 0x03) << 6; break; case 3: result[j++] |= ch; break; } i++; } k = j; /* mop things up if we ended on a boundary */ if (ch == base64_pad) { switch(i % 4) { case 0: case 1: free(result); return NULL; case 2: k++; case 3: result[k++] = 0; } } if(ret_length) { *ret_length = j; } result[k] = '\0'; return result; } --- NEW FILE: map_reader.h --- /* * RAGE - Role & Adventure Games Engine * Website: http://alternativegamers.com/ * Copyright 2005 Ramine Darabiha * * This file is part of RAGE. * * RAGE 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. * * RAGE 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 RAGE; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: map_reader.h,v 1.1 2007/02/13 01:49:22 b_lindeijer Exp $ */ #ifndef _RAGE_MAPREADER_H #define _RAGE_MAPREADER_H #include <string> #include <libxml/xmlwriter.h> class TiledMap; class TiledMapLayer; class Tileset; /** * Map reader. */ class MapReader { public: static TiledMap* readMap(const char *filename); static TiledMap* readMap(xmlNodePtr node, const std::string &path); private: static TiledMapLayer* readLayer(xmlNodePtr node, TiledMap *map); static Tileset* readTileset(xmlNodePtr node, const std::string &path); static int getProperty(xmlNodePtr node, const char *name, int def); }; #endif Index: tiled_map.cpp =================================================================== RCS file: /cvsroot/moeng/BBRpg/src/shared/tiled_map.cpp,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- tiled_map.cpp 8 Feb 2007 17:51:50 -0000 1.11 +++ tiled_map.cpp 13 Feb 2007 01:49:22 -0000 1.12 @@ -16,6 +16,7 @@ #include <stdio.h> #include <allegro.h> #include <map> +#include <cassert> #include <algorithm> #include <libxml/xmlwriter.h> #include <libxml/xmlreader.h> @@ -39,11 +40,11 @@ this->z = z; } -Vector::Vector(const Vector &v) +Vector::Vector(const Vector &v): + x(v.x), + y(v.y), + z(v.z) { - this->x = v.x; - this->y = v.y; - this->z = v.z; } Vector Vector::operator*(double c) @@ -108,23 +109,27 @@ bool Rectangle::collides(const Rectangle &r) { - return !( - x + w < r.x || - y + h < r.y || - x > r.x + r.w || - y > r.y + r.h - ); + return !(x + w < r.x || + y + h < r.y || + x > r.x + r.w || + y > r.y + r.h); } // TileType ================================================================== // An object holding static information about a tile type. -TileType::TileType(BITMAP *tileBitmap, const char *tileName) +TileType::TileType(BITMAP *tileBitmap, const char *tileName, int id): + mId(id) { bitmap = tileBitmap; - name = (char*)malloc(ustrsizez(tileName)); - ustrcpy(name, tileName); + if (tileName) { + name = (char*)malloc(ustrsizez(tileName)); + ustrcpy(name, tileName); + } + else { + name = NULL; + } int x, y; unsigned long r = 0, g = 0, b = 0; unsigned long pixels = tileBitmap->w * tileBitmap->h; @@ -152,8 +157,8 @@ // Tile class ================================================================ Tile::Tile(): - tileType(NULL), - obstacle(0) + obstacle(0), + tileType(NULL) { } @@ -201,32 +206,6 @@ obstacle = pack_igetw(file); } -void Tile::loadFrom(xmlNodePtr cur, TileRepository *tileRepository) -{ - xmlChar *prop; - - prop = xmlGetProp(cur, BAD_CAST "name"); - if (prop) { - setType(tileRepository->getTileType((char*)prop)); - xmlFree(prop); - } - else { - setType(NULL); - } - prop = xmlGetProp(cur, BAD_CAST "obstacle"); - if (prop) { - obstacle = - ((prop[0] == '1') ? OB_TOP : 0) | - ((prop[1] == '1') ? OB_RIGHT : 0) | - ((prop[2] == '1') ? OB_BOTTOM : 0) | - ((prop[3] == '1') ? OB_LEFT : 0); - xmlFree(prop); - } - else { - obstacle = 0; - } -} - void Tile::setType(TileType *tileType) { this->tileType = tileType; @@ -280,7 +259,7 @@ tempTileType = new TileType(tempBitmap, get_datafile_property(file, DAT_ID('N','A','M','E'))); - tileTypes.insert(make_pair( + tileTypes.insert(std::make_pair( tempTileType->getName(), tempTileType)); break; } @@ -316,7 +295,7 @@ y * (tileBitmap->w / tile_w) + x); tempTileType = new TileType(tempBitmap, tempTilename); - tileTypes.insert(make_pair(tempTileType->getName(), tempTileType)); + tileTypes.insert(std::make_pair(tempTileType->getName(), tempTileType)); } } } @@ -347,9 +326,9 @@ const char *filename, int tile_w, int tile_h, int tile_spacing, int tiles_in_row) { - list<TileType*> tiles_to_save; - map<const char*, TileType*, ltstr>::iterator i; - list<TileType*>::iterator j; + std::list<TileType*> tiles_to_save; + std::map<const char*, TileType*, ltstr>::iterator i; + std::list<TileType*>::iterator j; char tempTilename[256]; char tempFilename[256]; replace_extension(tempFilename, get_filename(filename), "", 256); @@ -404,7 +383,7 @@ TileType* TileRepository::getTileType(const char *tileName) { - map<const char*, TileType*, ltstr>::iterator found = + std::map<const char*, TileType*, ltstr>::iterator found = tileTypes.find(tileName); if (found != tileTypes.end()) { @@ -414,10 +393,10 @@ } } -vector<TileType*> TileRepository::generateTileArray() +std::vector<TileType*> TileRepository::generateTileArray() { - map<const char*, TileType*, ltstr>::iterator i; - vector<TileType*> tileArray; + std::map<const char*, TileType*, ltstr>::iterator i; + std::vector<TileType*> tileArray; for (i = tileTypes.begin(); i != tileTypes.end(); i++) { @@ -427,6 +406,52 @@ return tileArray; } +// Tileset =================================================================== + +Tileset::Tileset() +{ + tileWidth = tileHeight = tileSpacing = 0; + firstgid = 0; +} + +void +Tileset::importTileBitmap(BITMAP *tileImage, + const std::string &source, + int tw, int th, int ts) +{ + assert(tw > 0 && th > 0 && ts >= 0 && tileImage); + + mImgSource = source; + int x, y, id = 0; + tileWidth = tw; + tileHeight = th; + tileSpacing = ts; + + for (y = 0; y < (tileImage->h / (th + ts)); y++) + { + for (x = 0; x < (tileImage->w / (tw + ts)); x++) + { + // Create a new tile type and add it to the vector + BITMAP *subImage = create_sub_bitmap(tileImage, + x * (tw + ts), + y * (th + ts), + tw, th); + + TileType *tileType = new TileType(subImage, NULL, id++); + tileType->setTileset(this); + tiles.push_back(tileType); + } + } +} + +TileType* Tileset::getTile(int id) +{ + if (id >= 0 && (unsigned int) id < tiles.size()) { + return tiles[id]; + } else { + return NULL; + } +} // TiledMapLayer ============================================================= // Defines a tiled layer, used by tiled maps @@ -568,39 +593,9 @@ getTile(Point(x,y))->loadFrom(file, tileRepository); } -void TiledMapLayer::loadFrom(xmlNodePtr cur, TileRepository *tileRep) -{ - xmlChar *prop; - - // Load the map header - prop = xmlGetProp(cur, BAD_CAST "width"); - int w = atoi((char*)prop); - xmlFree(prop); - prop = xmlGetProp(cur, BAD_CAST "height"); - int h = atoi((char*)prop); - xmlFree(prop); - - resizeTo(w, h); - - cur = cur->xmlChildrenNode; - int x = 0; - int y = 0; - - // Load the tile data - while (cur != NULL) { - if (xmlStrEqual(cur->name, BAD_CAST "tile") && y < height) { - getTile(Point(x,y))->loadFrom(cur, tileRepository); - x++; - if (x == width) {x = 0; y++;} - } - cur = cur->next; - } -} - Tile *TiledMapLayer::getTile(const Point &tile) { - if (tile.x < 0 || tile.x >= width || - tile.y < 0 || tile.y >= height) + if (tile.x < 0 || tile.x >= width || tile.y < 0 || tile.y >= height) { return NULL; } @@ -610,26 +605,38 @@ } } +void +TiledMapLayer::setTile(const Point &tile, TileType *type) +{ + if (!(tile.x < 0 || tile.x >= width || tile.y < 0 || tile.y >= height)) { + tileMap[tile.x + tile.y * width]->setType(type); + } +} + // TiledMap class ============================================================ // Defines a generic tiled map interface and data model. TiledMap::TiledMap(): -nrLayers(2), width(0), height(0) + width(0), height(0) { - mapLayers[0] = new TiledMapLayer(); - mapLayers[1] = new TiledMapLayer(); + mapLayers.push_back(new TiledMapLayer()); + mapLayers.push_back(new TiledMapLayer()); } TiledMap::~TiledMap() { - // Delete the layers - for (int i = 0; i < nrLayers; i++) { + deleteLayers(); +} + +void TiledMap::deleteLayers() +{ + for (unsigned int i = 0; i < mapLayers.size(); i++) { if (mapLayers[i]) { delete mapLayers[i]; - mapLayers[i] = NULL; } } + mapLayers.clear(); } void TiledMap::setCamera(Point cam, Rectangle rect, bool center, bool modify) @@ -650,8 +657,10 @@ void TiledMap::resizeTo(int w, int h, int dx, int dy) { - mapLayers[0]->resizeTo(w, h, dx, dy); - mapLayers[1]->resizeTo(w, h, dx, dy); + for (unsigned int i = 0; i < mapLayers.size(); i++) + { + mapLayers[i]->resizeTo(w, h, dx, dy); + } width = w; height = h; } @@ -666,15 +675,15 @@ // Version 3: Object list stored at end of tile data. pack_iputw(3, file); // The map header - pack_iputw(nrLayers, file); + pack_iputw(mapLayers.size(), file); // The tile data - for (int i = 0; i < nrLayers; i++) { + for (unsigned int i = 0; i < mapLayers.size(); i++) { mapLayers[i]->saveTo(file); } // Object data - list<Object*>::iterator i; + std::list<Object*>::iterator i; pack_iputw(objects.size(), file); for (i = objects.begin(); i != objects.end(); i++) { pack_iputw(int(TILES_W * (*i)->x), file); @@ -695,13 +704,14 @@ xmlTextWriterWriteAttribute(writer, BAD_CAST "version", BAD_CAST "4.0"); // Tile data - for (int i = 0; i < nrLayers; i++) { + for (unsigned int i = 0; i < mapLayers.size(); i++) { mapLayers[i]->saveTo(writer); } // Object data - list<Object*>::iterator i; - for (i = objects.begin(); i != objects.end(); i++) { + std::list<Object*>::iterator i; + for (i = objects.begin(); i != objects.end(); i++) + { xmlTextWriterStartElement(writer, BAD_CAST "object"); snprintf(strbuf, 16, "%d", int(TILES_W * (*i)->x)); @@ -724,57 +734,18 @@ { console.log(CON_LOG, CON_VDEBUG, "- Attempting to parse XML map data"); - FILE* f = fopen(filename, "rb"); - char *map_string; - - if (!f) { - console.log(CON_QUIT, CON_ALWAYS, "Error: %s 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) { - console.log(CON_LOG, CON_VDEBUG, "- Looking for root node"); - xmlNodePtr cur = xmlDocGetRootElement(doc); - - if (!cur || !xmlStrEqual(cur->name, BAD_CAST "map")) { - console.log(CON_LOG, CON_ALWAYS, - "Warning, no map file (%s)!", filename); - return 1; - } + console.log(CON_LOG, CON_VDEBUG, "- Attempting to load packfile map"); + PACKFILE *file = pack_fopen(filename, F_READ_PACKED); - console.log(CON_LOG, CON_VDEBUG, "- Loading map from XML tree"); - loadFrom(cur, tileRepository); - xmlFreeDoc(doc); + if (!file) { + console.log(CON_LOG, CON_ALWAYS, + "Warning, no such file (%s)!", filename); + return 1; } - else { - console.log(CON_LOG, CON_VDEBUG, "- Attempting to load packfile map"); - PACKFILE *file = pack_fopen(filename, F_READ_PACKED); - if (!file) { - console.log(CON_LOG, CON_ALWAYS, - "Warning, no such file (%s)!", filename); - return 1; - } - - console.log(CON_LOG, CON_VDEBUG, "- Loading map from packfile"); - this->loadFrom(file, tileRepository); - pack_fclose(file); - } + console.log(CON_LOG, CON_VDEBUG, "- Loading map from packfile"); + this->loadFrom(file, tileRepository); + pack_fclose(file); return 0; } @@ -820,57 +791,9 @@ height = mapLayers[0]->getHeight(); } -void TiledMap::loadFrom(xmlNodePtr cur, TileRepository *tileRep) -{ - int layerNr = 0; - xmlChar *prop; - - removeObjects(); - - prop = xmlGetProp(cur, BAD_CAST "version"); - xmlFree(prop); - - cur = cur->xmlChildrenNode; - - while (cur != NULL) { - if (xmlStrEqual(cur->name, BAD_CAST "layer")) { - if (layerNr < 2) { - console.log(CON_LOG, CON_VDEBUG, "- Loading layer %d", - layerNr + 1); - mapLayers[layerNr]->loadFrom(cur, tileRepository); - layerNr++; - } - } - else if (xmlStrEqual(cur->name, BAD_CAST "object")) { - prop = xmlGetProp(cur, BAD_CAST "x"); - int x = atoi((char*)prop); - xmlFree(prop); - prop = xmlGetProp(cur, BAD_CAST "y"); - int y = atoi((char*)prop); - xmlFree(prop); - - // Spawn the object - prop = xmlGetProp(cur, BAD_CAST "type"); - - console.log(CON_LOG, CON_VDEBUG, "- Adding %s at (%d, %d)", - (char*)prop, x, y); - addObject( - double(x) / TILES_W, - double(y) / TILES_H, - (char*)prop); - xmlFree(prop); - } - - cur = cur->next; - } - - width = mapLayers[0]->getWidth(); - height = mapLayers[0]->getHeight(); -} - -TiledMapLayer *TiledMap::getLayer(int i) +TiledMapLayer *TiledMap::getLayer(unsigned int i) { - if (i < 0 || i >= nrLayers) { + if (i < 0 || i >= mapLayers.size()) { return NULL; } else { @@ -878,6 +801,17 @@ } } +TiledMapLayer* +TiledMap::getLayer(const char *name) +{ + for (unsigned int i = 0; i < mapLayers.size(); i++) { + if (mapLayers[i] && strcmp(mapLayers[i]->getName(), name) == 0) { + return mapLayers[i]; + } + } + return NULL; +} + Object* TiledMap::addObject(double x, double y, const char* type) { int objectInstance = 0; @@ -937,7 +871,7 @@ void TiledMap::removeObjects() { // Delete the objects - list<Object*>::iterator i; + std::list<Object*>::iterator i; while (!objects.empty()) { i = objects.begin(); delete (*i); @@ -946,11 +880,35 @@ } +Tileset* TiledMap::getTileset(const char* name) const +{ + std::list<Tileset*>::const_iterator i; + for (i = tilesets.begin(); i != tilesets.end(); i++) { + if (!strcmp(name, (*i)->getName().c_str())) { + return (*i); + } + } + return NULL; +} + +TileType* TiledMap::getTile(int gid) const +{ + std::list<Tileset*>::const_reverse_iterator i; + for (i = tilesets.rbegin(); i != tilesets.rend(); i++) + { + if ((*i)->getFirstGid() <= gid) + { + return (*i)->getTile(gid - (*i)->getFirstGid()); + } + } + return NULL; +} + void TiledMap::drawEntities(BITMAP *dest) { - list<EntityP> visibleEnts; - list<Object*>::iterator i; - list<EntityP>::iterator j; + std::list<EntityP> visibleEnts; + std::list<Object*>::iterator i; + std::list<EntityP>::iterator j; for (i = objects.begin(); i != objects.end(); i++) { @@ -983,9 +941,9 @@ void TiledMap::drawAirborneEntities(BITMAP *dest) { - list<EntityP> visibleEnts; - list<Object*>::iterator i; - list<EntityP>::iterator j; + std::list<EntityP> visibleEnts; + std::list<Object*>::iterator i; + std::list<EntityP>::iterator j; for (i = objects.begin(); i != objects.end(); i++) { @@ -1013,7 +971,7 @@ void TiledMap::updateObjects() { - list<Object*>::iterator i; + std::list<Object*>::iterator i; // Destroy all objects at the beginning of the object map // that should be destroyed @@ -1029,7 +987,7 @@ for (i = objects.begin(); i != objects.end(); i++) { if ((*i)->_destroy) { - list<Object*>::iterator i2 = i; + std::list<Object*>::iterator i2 = i; // We can safely iterate one back because the first object never // needs to be destroyed. @@ -1087,9 +1045,13 @@ oldClip.clipToRect(dest); cameraScreenRect.rectToClip(dest); - if (mapLayers[0]) drawLayer(dest, drawObstacle, mapLayers[0]); + if (mapLayers.size() > 0 && mapLayers[0]) { + drawLayer(dest, drawObstacle, mapLayers[0]); + } drawEntities(dest); - if (mapLayers[1]) drawLayer(dest, drawObstacle, mapLayers[1]); + if (mapLayers.size() > 1 && mapLayers[1]) { + drawLayer(dest, drawObstacle, mapLayers[1]); + } drawAirborneEntities(dest); oldClip.rectToClip(dest); --- NEW FILE: base64.h --- /* +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | +----------------------------------------------------------------------+ | This program is free software; you can redistribute it and/or modify | | it under the terms of one of the following licenses: | | | | A) the GNU General Public License as published by the Free Software | | Foundation; either version 2 of the License, or (at your option) | | any later version. | | | | B) the PHP License as published by the PHP Development Team and | | included in the distribution in the file: LICENSE | | | | This program 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 both licenses referred to here. | | If you did not, or have any questions about PHP licensing, please | | contact co...@ph.... | +----------------------------------------------------------------------+ | Author: Jim Winstead (ji...@ph...) | +----------------------------------------------------------------------+ */ /* $Id: base64.h,v 1.1 2007/02/13 01:49:22 b_lindeijer Exp $ */ #ifndef _RAGE_BASE64_H_ #define _RAGE_BASE64_H_ /** * Encode binary data into base64. */ extern unsigned char* php3_base64_encode(const unsigned char *string, int length, int *ret_length); /** * Decode a base64 string into binary data. */ extern unsigned char* php3_base64_decode(const unsigned char *string, int length, int *ret_length); #endif |