diff options
-rw-r--r-- | file.list | 3 | ||||
-rw-r--r-- | makefile.linuxppc | 1 | ||||
-rw-r--r-- | makefile.macosx | 1 | ||||
-rw-r--r-- | makefile.mgw | 1 | ||||
-rw-r--r-- | makefile.static | 1 | ||||
-rw-r--r-- | obj/resources/placeholder.txt | 1 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/configuration.cpp | 4 | ||||
-rw-r--r-- | src/configuration.h | 2 | ||||
-rw-r--r-- | src/graphic/image.cpp | 46 | ||||
-rw-r--r-- | src/graphic/image.h | 73 | ||||
-rw-r--r-- | src/gui/char_select.cpp | 2 | ||||
-rw-r--r-- | src/gui/char_server.cpp | 2 | ||||
-rw-r--r-- | src/gui/login.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 12 | ||||
-rw-r--r-- | src/main.h | 3 | ||||
-rw-r--r-- | src/resources/image.cpp | 124 | ||||
-rw-r--r-- | src/resources/image.h | 125 | ||||
-rw-r--r-- | src/resources/resource.cpp | 57 | ||||
-rw-r--r-- | src/resources/resource.h | 73 | ||||
-rw-r--r-- | src/resources/resourcemanager.cpp | 179 | ||||
-rw-r--r-- | src/resources/resourcemanager.h | 106 |
22 files changed, 699 insertions, 122 deletions
@@ -35,6 +35,9 @@ MODULES = src/sound/sound.cpp \ src/gui/windowcontainer.cpp \ src/net/network.cpp \ src/net/protocol.cpp \ + src/resources/image.cpp \ + src/resources/resource.cpp \ + src/resources/resourcemanager.cpp \ src/configuration.cpp \ src/astar.cpp \ src/being.cpp \ diff --git a/makefile.linuxppc b/makefile.linuxppc index 9b1580fd..cadc0fbd 100644 --- a/makefile.linuxppc +++ b/makefile.linuxppc @@ -24,6 +24,7 @@ clean: - rm -fv obj/gui/*.o - rm -fv obj/sound/*.o - rm -fv obj/graphic/*.o + - rm -fv obj/resources/*.o - rm -fv tmw obj/%.o: src/%.cpp diff --git a/makefile.macosx b/makefile.macosx index 128caa25..ab1e9864 100644 --- a/makefile.macosx +++ b/makefile.macosx @@ -24,6 +24,7 @@ clean: - rm -fv obj/gui/*.o - rm -fv obj/sound/*.o - rm -fv obj/graphic/*.o + - rm -fv obj/resources/*.o - rm -fv tmw obj/%.o: src/%.cpp diff --git a/makefile.mgw b/makefile.mgw index 5ce34199..cbc6da7b 100644 --- a/makefile.mgw +++ b/makefile.mgw @@ -23,6 +23,7 @@ clean: - rm -fv obj/gui/*.o - rm -fv obj/sound/*.o - rm -fv obj/graphic/*.o + - rm -fv obj/resources/*.o - rm -fv tmw obj/%.o: src/%.cpp diff --git a/makefile.static b/makefile.static index c9eb9368..30ae3649 100644 --- a/makefile.static +++ b/makefile.static @@ -24,6 +24,7 @@ clean: - rm -fv obj/gui/*.o - rm -fv obj/sound/*.o - rm -fv obj/graphic/*.o + - rm -fv obj/resources/*.o - rm -fv tmw obj/%.o: src/%.cpp diff --git a/obj/resources/placeholder.txt b/obj/resources/placeholder.txt new file mode 100644 index 00000000..b951fc55 --- /dev/null +++ b/obj/resources/placeholder.txt @@ -0,0 +1 @@ +This file is here to make sure the otherwise empty directory is created. diff --git a/src/Makefile.am b/src/Makefile.am index 5589a5ff..962af4e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,6 +36,9 @@ tmw_SOURCES = sound/sound.cpp \ gui/windowcontainer.cpp \ net/network.cpp \ net/protocol.cpp \ + resources/image.cpp \ + resources/resource.cpp \ + resources/resourcemanager.cpp \ astar.cpp \ being.cpp \ configuration.cpp \ diff --git a/src/configuration.cpp b/src/configuration.cpp index 759a1fa9..074de7c6 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -24,6 +24,8 @@ #include "configuration.h" #include <math.h> +#include <iostream> +#include <fstream> Configuration::OptionValue::OptionValue(): numericValue(0.0f) @@ -46,7 +48,7 @@ void Configuration::init(std::string filename) { iniOptions.clear(); while (inFile.good()) { - getline(inFile, inBuffer, '\n'); + std::getline(inFile, inBuffer, '\n'); if (inBuffer.substr(0, 1) != INI_COMMENTER) { // Replace spaces with void diff --git a/src/configuration.h b/src/configuration.h index ef9c9fe2..28383765 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -29,8 +29,6 @@ #include <map> #include <string> -#include <iostream> -#include <fstream> /** * INI configuration handler for reading (and writing). diff --git a/src/graphic/image.cpp b/src/graphic/image.cpp index 9d0d3cac..008c4017 100644 --- a/src/graphic/image.cpp +++ b/src/graphic/image.cpp @@ -24,37 +24,13 @@ #include "image.h" -// Image - -Image::Image(int offset_x, int offset_y) { - this->offset_x = offset_x; - this->offset_y = offset_y; -} - - -// RleImage - -RleImage::RleImage(RLE_SPRITE *src, int offset_x, int offset_y): - Image(offset_x, offset_y) -{ - this->src = src; -} - -RleImage::~RleImage() { - destroy_rle_sprite(src); -} - -void RleImage::draw(BITMAP *dest, int x, int y) { - draw_rle_sprite(dest, src, x + offset_x, y + offset_y); -} - - // VideoImage VideoImage::VideoImage(BITMAP *src, int offset_x, int offset_y): - Image(offset_x, offset_y) + src(src), + offset_x(offset_x), + offset_y(offset_y) { - this->src = src; } VideoImage::~VideoImage() { @@ -73,22 +49,6 @@ void VideoImage::draw(BITMAP *dst, int x, int y) { // Spriteset -Spriteset::Spriteset(std::string filename) -{ - DATAFILE *datafile = load_datafile(filename.c_str()); - if (!datafile)error("Unable to load graphic file: " + filename); - int i = 0; - while (datafile[i].type != DAT_END) { - Image *temp_image; - temp_image = new RleImage( - (RLE_SPRITE*)datafile[i].dat, - getProperty(&datafile[i], DAT_ID('X','C','R','P')), - getProperty(&datafile[i], DAT_ID('Y','C','R','P'))); - spriteset.push_back(temp_image); - i++; - } -} - Spriteset::Spriteset(BITMAP *bmp, int width, int height, int offx, int offy) { /* diff --git a/src/graphic/image.h b/src/graphic/image.h index 60e04eac..1bc43ef4 100644 --- a/src/graphic/image.h +++ b/src/graphic/image.h @@ -31,72 +31,17 @@ #include "../log.h" /** - * A class storing a single sprite in video memory if available, - * else as a refernece to a RLE_SPRITE in a datafile. - * The class stores the offsets needed to compensate the cropping - * operated by the grabber utility. + * A video image stored in memory. */ -class Image { - public: - /** - * Creates an Image - * @param offset_x is the x offset from where to start drawing - * @param offset_y is the y offset from where to start drawing - */ - Image(int offset_x, int offset_y); - - /** - * Virtual function to draw a sprite - * @param dest is the destination bitmap on which to draw the sprite - * @param x is the horizontal position - * @param y is the vertical position - */ - virtual void draw(BITMAP *dest, int x, int y) = 0; - - protected: - // From where to start drawing - int offset_x, offset_y; -}; - -/** - * A RLE sprite - */ -class RleImage : public Image { - public: - /** - * Creates a RleSprite - * @param src is a reference to a RLE_SPRITE in a datafile - * @param offset_x is the x offset from where to start drawing - * @param offset_y is the y offset from where to start drawing - */ - RleImage(RLE_SPRITE *src, int offset_x, int offset_y); - - /** - * Destructor - */ - virtual ~RleImage(); - - /** - * Draws a sprite - */ - void draw(BITMAP *dest, int x, int y); - +class VideoImage { private: - // Reference to RLE_SPRITE - RLE_SPRITE *src; -}; - -/** - * An image stored in video memory - */ -class VideoImage : public Image { - private: - // Reference to bitmap stored in video memory BITMAP *src; + int offset_x, offset_y; + public: /** * Creates a VideoImage - * @param src is a reference to a BITMAP in video memory + * @param src is a reference to a BITMAP * @param offset_x is the x offset from where to start drawing * @param offset_y is the y offset from where to start drawing */ @@ -119,13 +64,7 @@ class VideoImage : public Image { class Spriteset { public: // Vector storing the whole spriteset. - std::vector<Image*> spriteset; - - /** - * Load a datafile containing the spriteset - * @param filename is the path of the datafile - */ - Spriteset(std::string filename); + std::vector<VideoImage*> spriteset; /* * Cuts the passed bitmap in a grid of sub bitmaps. diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp index 259a01b9..87a30000 100644 --- a/src/gui/char_select.cpp +++ b/src/gui/char_select.cpp @@ -437,7 +437,7 @@ void charSelect() } // Draw background - blit(login_wallpaper, buffer, 0, 0, 0, 0, 800, 600); + login_wallpaper->draw(buffer, 0, 0); gui->update(); diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp index 82c5f05e..3b9d03c8 100644 --- a/src/gui/char_server.cpp +++ b/src/gui/char_server.cpp @@ -117,7 +117,7 @@ void char_server() { showServerList = 1; while (showServerList) { - blit(login_wallpaper, buffer, 0, 0, 0, 0, 800, 600); + login_wallpaper->draw(buffer, 0, 0); gui->update(); blit(buffer, screen, 0, 0, 0, 0, 800, 600); } diff --git a/src/gui/login.cpp b/src/gui/login.cpp index b1e8b43e..6db212b2 100644 --- a/src/gui/login.cpp +++ b/src/gui/login.cpp @@ -131,7 +131,7 @@ void login() { LoginDialog *dialog = new LoginDialog(); while (state == LOGIN) { - blit(login_wallpaper, buffer, 0, 0, 0, 0, 800, 600); + login_wallpaper->draw(buffer, 0, 0); gui->update(); blit(buffer, screen, 0, 0, 0, 0, 800, 600); if (key[KEY_ESC]) { diff --git a/src/main.cpp b/src/main.cpp index 61de436f..663c2589 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,7 +28,7 @@ #include "gui/ok_dialog.h" #include "./sound/sound.h" #include "./graphic/graphic.h" - +#include "resources/resourcemanager.h" #include <iostream> #ifdef __USE_UNIX98 @@ -77,7 +77,7 @@ SERVER_INFO *server_info; PLAYER_INFO *char_info = new PLAYER_INFO; Spriteset *hairset, *playerset; -BITMAP *login_wallpaper; +Image *login_wallpaper; char username[LEN_USERNAME]; char password[LEN_PASSWORD]; @@ -222,7 +222,6 @@ void init_engine() { config.setValue("keyboard", "en"); config.setValue("language", ""); config.setValue("core_version", CORE_VERSION); - config.setValue("host", "animesites.de"); config.setValue("port", 6901); config.setValue("screen", 1); @@ -294,7 +293,9 @@ void init_engine() { error("Not enough memory to create buffer"); } - login_wallpaper = load_bitmap("data/graphic/login.bmp", NULL); + ResourceManager *resman = ResourceManager::getInstance(); + + login_wallpaper = resman->createImage("graphic/login.bmp"); if (!login_wallpaper) error("Couldn't load login.bmp"); BITMAP *playerbitmap = load_bitmap("data/graphic/playerset.bmp", NULL); @@ -352,6 +353,7 @@ void exit_engine() { config.write(dir); delete dir; gui_exit(); + ResourceManager::deleteInstance(); destroy_bitmap(buffer); allegro_exit(); } @@ -390,7 +392,7 @@ int main() { break; case ERROR: // Redraw GUI - blit(login_wallpaper, buffer, 0, 0, 0, 0, 800, 600); + login_wallpaper->draw(buffer, 0, 0); guiGraphics->setTarget(buffer); gui->update(); blit(buffer, screen, 0, 0, 0, 0, 800, 600); @@ -35,6 +35,7 @@ #include "gui/login.h" #include "gui/gui.h" #include "graphic/image.h" +#include "resources/image.h" #include "log.h" #include "game.h" #include "net/protocol.h" @@ -82,7 +83,7 @@ typedef struct { short weapon; } PLAYER_INFO; -extern BITMAP *login_wallpaper; +extern Image *login_wallpaper; extern Spriteset *hairset, *playerset; extern char username[25]; extern char password[25]; diff --git a/src/resources/image.cpp b/src/resources/image.cpp new file mode 100644 index 00000000..8a37a4e1 --- /dev/null +++ b/src/resources/image.cpp @@ -0,0 +1,124 @@ +/* + * 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 "../log.h" +#include "image.h" +#include <iostream> + +Image::Image(BITMAP *image): + image(image) +{ +} + +Image::~Image() +{ + unload(); +} + +Image* Image::load(const std::string &filePath) +{ + // Attempt to use SDL_Image to load the file. + //image = IMG_Load(filePath.c_str()); + std::cout << "Attempting to load image from " << filePath << std::endl; + BITMAP *image = load_bitmap(filePath.c_str(), NULL); + + // Check if the file was opened and return the appropriate value. + if (!image) { + //log("Error", "Image load failed : %s", IMG_GetError()); + log("Error", "Image load failed : %s", filePath.c_str()); + return NULL; + } + + return new Image(image); +} + +void Image::unload() +{ + // Free the image surface. + if (image != NULL) { + //SDL_FreeSurface(image); + destroy_bitmap(image); + image = NULL; + loaded = false; + } +} + +Image* Image::createSubImage(int x, int y, int width, int height) +{ + // Create a new clipped sub-image + return new SubImage(this, image, x, y, width, height); +} + +bool Image::draw(BITMAP *screen, int x, int y) +{ + // Check that preconditions for blitting are met. + if (screen == NULL || image == NULL) return false; + + // Draw the image onto the screen. + draw_sprite(screen, image, x, y); + //if (SDL_BlitSurface(image, NULL, screen, &screenRect) < 0) { + // return false; + //} + + return true; +} + +SubImage::SubImage(Image *parent, BITMAP *image, + int x, int y, int width, int height): + Image(create_sub_bitmap(image, x, y, width, height)), + parent(parent) +{ + //this->image = create_sub_bitmap(image, x, y, width, height); + parent->incRef(); + // Set up the clipping rectangle. + //clipRect.x = x; + //clipRect.y = y; + //clipRect.w = width; + //clipRect.h = height; +} + +SubImage::~SubImage() +{ + if (image) { + destroy_bitmap(image); + } + parent->decRef(); +} + +void SubImage::unload() +{ +} + +bool SubImage::draw(BITMAP *screen, int x, int y) +{ + // Check that drawing preconditions are satisfied. + if (screen == NULL || image == NULL) return false; + + // Draw the image onto the screen. + draw_sprite(screen, image, x, y); + //if (SDL_BlitSurface(image, &clipRect, screen, &screenRect) < 0) { + // return false; + //} + + return true; +} diff --git a/src/resources/image.h b/src/resources/image.h new file mode 100644 index 00000000..363dabde --- /dev/null +++ b/src/resources/image.h @@ -0,0 +1,125 @@ +/* + * 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 _TMW_IMAGE_H +#define _TMW_IMAGE_H + +#include "resource.h" +//#include <SDL/SDL.h> +#include <allegro.h> + +/** + * A clipped version of a larger image. + */ +class SubImage; + +/** + * Defines a class for loading and storing images. + */ +class Image : public Resource +{ + public: + /** + * Constructor. + */ + Image(BITMAP *image); + + /** + * Destructor. + */ + virtual ~Image(); + + /** + * Loads an image. + * @param filePath The path to the image file to load. + * @return <code>true</code> if the image was loaded + * <code>false</code> otherwise. + */ + static Image *load(const std::string &filePath); + + /** + * Frees the resources created by SDL. + */ + void unload(); + + /** + * Creates a new image with the desired clipping rectangle. + * @return <code>NULL</code> if creation failed and a valid + * object otherwise. + */ + Image* createSubImage(int x, int y, int width, int height); + + /** + * Attempts to blit the internal image onto the screen. + * @return <code>true</code> if the image was blitted properly + * <code>false</code> otherwise. + */ + bool draw(BITMAP *screen, int x, int y); + + protected: + //SDL_Rect screenRect; + //SDL_Surface *image; + BITMAP *image; +}; + +/** + * A clipped version of a larger image. + */ +class SubImage : public Image +{ + public: + /** + * Constructor. + */ + //SubImage(SDL_Surface *timage, int x, int y, int width, int height); + SubImage(Image *parent, BITMAP *image, + int x, int y, int width, int height); + + /** + * Destructor. + */ + ~SubImage(); + + /** + * Redefines unload to not do anything. + */ + void unload(); + + /** + * Draws the clipped image onto the screen. + * @return <code>true</code> if drawing was succesful + * <code>false</code> otherwise. + */ + bool draw(BITMAP *screen, int x, int y); + + private: + Image *parent; + //BITMAP *image; + //SDL_Rect clipRect; + //SDL_Rect screenRect; + //SDL_Surface *image; + //SDL_Surface *screen; + //unsigned int referenceCount; +}; + +#endif diff --git a/src/resources/resource.cpp b/src/resources/resource.cpp new file mode 100644 index 00000000..6b4a554f --- /dev/null +++ b/src/resources/resource.cpp @@ -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$ + */ + +#include "resource.h" + +Resource::Resource(): + referenceCount(0) +{ +} + +bool Resource::isLoaded() const +{ + return loaded; +} + +void Resource::incRef() +{ + ++referenceCount; +} + +bool Resource::decRef() +{ + /* Warning: There is still a serious problem with the object deleting + * itself and that is that the resource manager doesn't know about it + * currently, causing it to crash while trying to clean up. Don't use + * this function until that is solved. Probably we'll have to make it + * so that decrementing count goes through resource manager too. + */ + --referenceCount; + + if (!referenceCount) { + delete this; + return true; + } + + return false; +} diff --git a/src/resources/resource.h b/src/resources/resource.h new file mode 100644 index 00000000..f1252c12 --- /dev/null +++ b/src/resources/resource.h @@ -0,0 +1,73 @@ +/* + * 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 _TMW_RESOURCE_H +#define _TMW_RESOURCE_H + +#include <string> +//#include <SDL/SDL.h> + +/** + * A generic reference counted resource object. + */ +class Resource +{ + public: + /** + * Constructor + */ + Resource(); + + /** + * Frees this objects internal resources. + */ + virtual void unload() = 0; + + /** + * Indicates whether or not a resource is loaded. + * @return <code>true</code> if resource is loaded + * <code>false</code> otherwise. + */ + virtual bool isLoaded() const; + + /** + * Increments the internal reference count. + */ + void incRef(); + + /** + * Decrements the reference count and deletes the object + * if no references are left. + * @return <code>true</code> if the object was deleted + * <code>false</code> otherwise. + */ + bool decRef(); + + protected: + bool loaded; + + private: + unsigned int referenceCount; +}; + +#endif diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp new file mode 100644 index 00000000..1d65538f --- /dev/null +++ b/src/resources/resourcemanager.cpp @@ -0,0 +1,179 @@ +/* + * 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 "../log.h" +#include "image.h" +#include "resourcemanager.h" +#include <iostream> + +#ifdef WIN32 +#include <direct.h> +#else +#include <unistd.h> +#endif + +ResourceEntry::ResourceEntry(): + resource(NULL) +{ +} + +ResourceManager *ResourceManager::instance = NULL; + +ResourceManager::ResourceManager() +{ +} + +ResourceManager::~ResourceManager() +{ + // Create our resource iterator. + std::map<std::string, ResourceEntry>::iterator iter = resources.begin(); + int danglingResources = 0; + int danglingReferences = 0; + + // Iterate through and release references until objects are deleted. + while (iter != resources.end()) { + Resource *res = iter->second.resource; + danglingResources++; + danglingReferences++; + while (!res->decRef()) { + danglingReferences++; + } + iter++; + } + resources.clear(); + +#ifdef __DEBUG + std::cout << "ResourceManager::~ResourceManager() cleaned up " << + danglingReferences << " references to " << danglingResources << + " resources\n"; +#endif +} + +Resource* ResourceManager::create(const E_RESOURCE_TYPE &type, + const std::string &idPath) +{ + // Check if the id exists, and return the value if it does. + std::map<std::string, ResourceEntry>::iterator resIter = + resources.find(idPath); + + if (resIter != resources.end() && resIter->second.resource) { + resIter->second.resource->incRef(); + return resIter->second.resource; + } + + // Attempt to load the object if it doesn't exist. + + // The filePath string. + std::string filePath = ""; + + // Retrieve the current path for this program. + char programPath[260]; + getcwd(programPath, 260); + + // Set the filePath variable to the appropriate value + // this is only if we're not using a packed file. +#ifdef WIN32 + // Flip all of the idPath '/' to '\' + unsigned int begPos = 0; + unsigned int endPos = idPath.find("/"); + std::strstream result; + + // Loop through and replace all the characters. + while (endPos != std::string::npos) { + result << idPath.substr(begPos, endPos - begPos); + result << "\\"; + + begPos = endPos + 1; + endPos = (unsigned int)idPath.find("/"); + } + + filePath = std::string(programPath) + std::string("\\data\\") + + std::string(result.str()); +#else + filePath = std::string(programPath) + std::string("/data/") + idPath; +#endif + + Resource *resource = NULL; + + // Create an object of the specified type. + switch (type) + { + case MAP: + warning("Map resource not supported."); + break; + case MUSIC: + warning("Music resource not supported."); + break; + case IMAGE: + // Attempt to create and load our image object. + resource = reinterpret_cast<Resource*>(Image::load(filePath)); + break; + case SCRIPT: + warning("Script resource not supported."); + break; + case TILESET: + warning("Tileset resource not supported."); + break; + case SOUND_EFFECT: + warning("Sound FX resource not supported."); + break; + default: + warning("Unknown resource type"); + break; + } + + if (resource) { + resource->incRef(); + + // Create the resource entry for this object. + ResourceEntry entry; + entry.filePath = filePath; + entry.resource = resource; + + resources[idPath] = entry; + } + + // Return NULL if the object could not be created. + return resource; +} + +Image *ResourceManager::createImage(const std::string &idPath) +{ + return (Image*)create(IMAGE, idPath); +} + +ResourceManager* ResourceManager::getInstance() +{ + // Create a new instance if necessary. + if (instance == NULL) instance = new ResourceManager(); + + return instance; +} + +void ResourceManager::deleteInstance() +{ + if (instance != NULL) { + delete instance; + instance = NULL; + } +} diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h new file mode 100644 index 00000000..f7b7ab2a --- /dev/null +++ b/src/resources/resourcemanager.h @@ -0,0 +1,106 @@ +/* + * 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 _TMW_RESOURCE_MANAGER_H +#define _TMW_RESOURCE_MANAGER_H + +#include <map> +#include <string> +#include "resource.h" + +/** + * A resource entry descriptor. + */ +struct ResourceEntry +{ + ResourceEntry(); + + Resource* resource; + std::string filePath; +}; + +/** + * A class for loading and managing resources. + */ +class ResourceManager +{ + public: + /** + * An enumeration of resource types. + */ + enum E_RESOURCE_TYPE + { + MAP, + MUSIC, + IMAGE, + SCRIPT, + TILESET, + SOUND_EFFECT + }; + + /** + * Constructor. + */ + ResourceManager(); + + /** + * Destructor. + */ + ~ResourceManager(); + + /** + * Creates a resource and adds it to the resource map. The idPath is + * converted into the appropriate path for the current operating system + * and the resource is loaded. + * + * @param type The type of resource to load. + * @param idPath The resource identifier path. + * @return A valid resource or <code>NULL</code> if the resource could + * not be loaded. + */ + Resource *create( + const E_RESOURCE_TYPE &type, + const std::string &idPath); + + /** + * Convenience wrapper around ResourceManager::create. + */ + Image *createImage(const std::string &idPath); + + /** + * Returns an instance of the class, creating one if it does not + * already exist. + */ + static ResourceManager *getInstance(); + + /** + * Deletes the class instance if it exists. + */ + static void deleteInstance(); + + private: + static ResourceManager *instance; + std::map<std::string, ResourceEntry> resources; +}; + +#endif |