diff options
Diffstat (limited to 'src/resources')
-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 |
6 files changed, 664 insertions, 0 deletions
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 |