5 * Created by Alyssa Milburn on Sun Jun 06 2004.
6 * Copyright (c) 2004-2008 Alyssa Milburn. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
20 #include "imageManager.h"
27 #include "fileSwapper.h"
29 #include "PathResolver.h"
34 #include <boost/filesystem/path.hpp>
35 #include <boost/filesystem/operations.hpp>
36 #include <boost/filesystem/convenience.hpp>
38 using namespace boost::filesystem
;
40 enum filetype
{ blk
, s16
, c16
, spr
};
42 bool tryOpen(mmapifstream
*in
, shared_ptr
<creaturesImage
> &img
, std::string fname
, filetype ft
) {
43 path cachefile
, realfile
;
44 std::string cachename
;
45 if (fname
.size() < 5) return false; // not enough chars for an extension and filename..
46 std::string basename
= fname
; basename
.erase(basename
.end() - 4, basename
.end());
48 // work out where the real file should be
51 realfile
= path(world
.findFile(std::string("/Backgrounds/") + fname
), native
); break;
56 realfile
= path(world
.findFile(std::string("/Images/") + fname
), native
); break;
59 // if it doesn't exist, too bad, give up.
60 if (!exists(realfile
)) return false;
62 // work out where the cached file should be
63 cachename
= engine
.storageDirectory().native_directory_string() + "/" + fname
;
64 if (ft
== c16
) { // TODO: we should really stop the caller from appending .s16/.c16
65 cachename
.erase(cachename
.end() - 4, cachename
.end());
66 cachename
.append(".s16");
69 #ifdef __C2E_BIGENDIAN
71 cachename
= cachename
+ ".big";
73 cachefile
= path(cachename
, native
);
75 if (resolveFile(cachefile
)) {
76 // TODO: check for up-to-date-ness
78 in
->mmapopen(cachefile
.native_file_string());
79 if (ft
== c16
) ft
= s16
;
82 //std::cout << "couldn't find cached version: " << cachefile.native_file_string() << std::endl;
85 in
->mmapopen(realfile
.native_file_string());
86 #ifdef __C2E_BIGENDIAN
87 if (in
->is_open() && (ft
!= spr
)) {
91 f
.convertblk(realfile
.native_file_string(), cachefile
.native_file_string());
94 f
.converts16(realfile
.native_file_string(), cachefile
.native_file_string());
97 //cachefile = change_extension(cachefile, "");
98 //cachefile = change_extension(cachefile, ".s16.big");
99 f
.convertc16(realfile
.native_file_string(), cachefile
.native_file_string());
103 return true; // TODO: exception?
105 in
->close(); // TODO: close the mmap too! how?
106 if (!exists(cachefile
)) return false; // TODO: exception?
107 in
->mmapopen(cachefile
.native_file_string());
113 case blk
: img
= shared_ptr
<creaturesImage
>(new blkImage(in
)); break;
114 case c16
: img
= shared_ptr
<creaturesImage
>(new c16Image(in
)); break; // this should never happen, actually, once we're done
115 case s16
: img
= shared_ptr
<creaturesImage
>(new s16Image(in
)); break;
116 case spr
: img
= shared_ptr
<creaturesImage
>(new sprImage(in
)); break;
118 img
->name
= basename
;
120 return in
->is_open();
124 * Retrieve an image for rendering use. To retrieve a sprite, pass the name without
125 * extension. To retrieve a background, pass the full filename (ie, with .blk).
127 shared_ptr
<creaturesImage
> imageManager::getImage(std::string name
) {
128 if (name
.empty()) return shared_ptr
<creaturesImage
>(); // empty sprites definitely don't exist
130 // step one: see if the image is already in the gallery
131 std::map
<std::string
, boost::weak_ptr
<creaturesImage
> >::iterator i
= images
.find(name
);
132 if (i
!= images
.end() && i
->second
.lock()) {
133 return i
->second
.lock();
136 // step two: try opening it in .c16 form first, then try .s16 form
137 mmapifstream
*in
= new mmapifstream();
138 shared_ptr
<creaturesImage
> img
;
140 if (!tryOpen(in
, img
, name
+ ".s16", s16
)) {
141 if (!tryOpen(in
, img
, name
+ ".c16", c16
)) {
142 if (!tryOpen(in
, img
, name
+ ".spr", spr
)) {
143 bool lasttry
= tryOpen(in
, img
, name
, blk
);
145 std::cerr
<< "imageGallery couldn't find the sprite '" << name
<< "'" << std::endl
;
146 return shared_ptr
<creaturesImage
>();
159 in
->close(); // doesn't close the mmap, which we still need :)