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"
28 #include "fileSwapper.h"
30 #include "PathResolver.h"
35 #include <boost/filesystem/path.hpp>
36 #include <boost/filesystem/operations.hpp>
37 #include <boost/filesystem/convenience.hpp>
39 using namespace boost::filesystem
;
41 enum filetype
{ blk
, s16
, c16
, spr
, bmp
};
43 bool tryOpen(mmapifstream
*in
, shared_ptr
<creaturesImage
> &img
, std::string fname
, filetype ft
, bool is_background
= false) {
44 path cachefile
, realfile
;
45 std::string cachename
;
46 if (fname
.size() < 5) return false; // not enough chars for an extension and filename..
47 std::string basename
= fname
; basename
.erase(basename
.end() - 4, basename
.end());
50 realfile
= path(world
.findFile(std::string("/Backgrounds/") + fname
), native
);
52 realfile
= path(world
.findFile(std::string("/Images/") + fname
), native
);
55 // if it doesn't exist, too bad, give up.
56 if (!exists(realfile
)) return false;
58 // work out where the cached file should be
59 cachename
= engine
.storageDirectory().native_directory_string() + "/" + fname
;
60 if (ft
== c16
) { // TODO: we should really stop the caller from appending .s16/.c16
61 cachename
.erase(cachename
.end() - 4, cachename
.end());
62 cachename
.append(".s16");
67 cachename
= cachename
+ ".big";
69 cachefile
= path(cachename
, native
);
71 if (resolveFile(cachefile
)) {
72 // TODO: check for up-to-date-ness
74 in
->mmapopen(cachefile
.native_file_string());
75 if (ft
== c16
) ft
= s16
;
78 //std::cout << "couldn't find cached version: " << cachefile.native_file_string() << std::endl;
81 in
->mmapopen(realfile
.native_file_string());
83 if (in
->is_open() && (ft
!= spr
)) {
87 f
.convertblk(realfile
.native_file_string(), cachefile
.native_file_string());
90 f
.converts16(realfile
.native_file_string(), cachefile
.native_file_string());
93 //cachefile = change_extension(cachefile, "");
94 //cachefile = change_extension(cachefile, ".s16.big");
95 f
.convertc16(realfile
.native_file_string(), cachefile
.native_file_string());
99 return true; // TODO: exception?
101 in
->close(); // TODO: close the mmap too! how?
102 if (!exists(cachefile
)) return false; // TODO: exception?
103 in
->mmapopen(cachefile
.native_file_string());
109 case blk
: img
= shared_ptr
<creaturesImage
>(new blkImage(in
, basename
)); break;
110 case c16
: img
= shared_ptr
<creaturesImage
>(new c16Image(in
, basename
)); break; // this should never happen, actually, once we're done
111 case s16
: img
= shared_ptr
<creaturesImage
>(new s16Image(in
, basename
)); break;
112 case spr
: img
= shared_ptr
<creaturesImage
>(new sprImage(in
, basename
)); break;
113 case bmp
: img
= shared_ptr
<creaturesImage
>(new bmpImage(in
, basename
)); break; // TODO: don't commit this ;p
116 return in
->is_open();
120 * Retrieve an image for rendering use. To retrieve a sprite, pass the name without
121 * extension. To retrieve a background, pass the full filename (ie, with .blk).
123 shared_ptr
<creaturesImage
> imageManager::getImage(std::string name
, bool is_background
) {
124 if (name
.empty()) return shared_ptr
<creaturesImage
>(); // empty sprites definitely don't exist
126 // step one: see if the image is already in the gallery
127 std::map
<std::string
, boost::weak_ptr
<creaturesImage
> >::iterator i
= images
.find(name
);
128 if (i
!= images
.end() && i
->second
.lock()) {
129 if (!is_background
) return i
->second
.lock(); // TODO: handle backgrounds
132 // step two: try opening it in .c16 form first, then try .s16 form
133 mmapifstream
*in
= new mmapifstream();
134 shared_ptr
<creaturesImage
> img
;
136 bool successful
= true;
137 if (engine
.bmprenderer
) {
138 successful
= tryOpen(in
, img
, name
+ ".bmp", bmp
, is_background
);
141 successful
= tryOpen(in
, img
, name
+ ".blk", blk
, true);
143 if (!tryOpen(in
, img
, name
+ ".s16", s16
)) {
144 if (!tryOpen(in
, img
, name
+ ".c16", c16
)) {
145 if (!tryOpen(in
, img
, name
+ ".spr", spr
)) {
154 if (!is_background
) // TODO: handle backgrounds
157 std::cerr
<< "imageGallery couldn't find the sprite '" << name
<< "'" << std::endl
;
158 return shared_ptr
<creaturesImage
>();
161 in
->close(); // doesn't close the mmap, which we still need :)