29 |
#include "display.hh" |
#include "display.hh" |
30 |
#include "oxyd.hh" |
#include "oxyd.hh" |
31 |
|
|
32 |
|
#include <map> |
33 |
#include <cassert> |
#include <cassert> |
34 |
|
|
35 |
using namespace enigma; |
using namespace enigma; |
51 |
|
|
52 |
typedef Cache<px::Surface*, ImageAlloc> ImageCache; |
typedef Cache<px::Surface*, ImageAlloc> ImageCache; |
53 |
|
|
54 |
|
|
55 |
|
class LevelPreviewCacheElem { |
56 |
|
Surface *surface; |
57 |
|
unsigned idx; |
58 |
|
|
59 |
|
LevelPreviewCacheElem(const LevelPreviewCacheElem&); |
60 |
|
LevelPreviewCacheElem& operator = (const LevelPreviewCacheElem& other); |
61 |
|
public: |
62 |
|
LevelPreviewCacheElem(LevelPack *lp, unsigned idx_, int xsize, int ysize) |
63 |
|
: surface(0) , idx(idx_) |
64 |
|
{ |
65 |
|
surface = LevelPreview(lp, idx); // do not free, points to BackBuffer |
66 |
|
if (surface) { |
67 |
|
const Rect& game_area = display::GetGameArea(); |
68 |
|
Surface *game_surface = Grab(surface, game_area); |
69 |
|
|
70 |
|
if (game_surface) { |
71 |
|
surface = game_surface->zoom(xsize, ysize); |
72 |
|
delete game_surface; |
73 |
|
} |
74 |
|
else { |
75 |
|
surface = 0; // avoid delete |
76 |
|
} |
77 |
|
} |
78 |
|
|
79 |
|
// fprintf(stderr, "Created preview for #%i. surface=%p\n", idx, surface); |
80 |
|
} |
81 |
|
~LevelPreviewCacheElem() { delete surface; } |
82 |
|
bool operator<(const LevelPreviewCacheElem& other) { return idx<other.idx; } |
83 |
|
Surface *get_surface() { return surface; } |
84 |
|
}; |
85 |
|
|
86 |
|
class LevelPreviewCache { |
87 |
|
typedef std::map<unsigned,LevelPreviewCacheElem*> PreviewMap; |
88 |
|
|
89 |
|
PreviewMap cache; |
90 |
|
int xsize, ysize; |
91 |
|
|
92 |
|
void release() { |
93 |
|
PreviewMap::iterator i = cache.begin(); |
94 |
|
PreviewMap::iterator e = cache.end(); |
95 |
|
for (; i != e; ++i) |
96 |
|
delete i->second; |
97 |
|
} |
98 |
|
|
99 |
|
public: |
100 |
|
LevelPreviewCache() : xsize(0), ysize(0) {} |
101 |
|
~LevelPreviewCache() { release(); } |
102 |
|
|
103 |
|
void clear() { release(); cache.clear(); } |
104 |
|
void set_size(int xs, int ys) { xsize = xs; ysize = ys; } |
105 |
|
|
106 |
|
Surface *getPreview(LevelPack *lp, unsigned idx) { |
107 |
|
PreviewMap::iterator i = cache.find(idx); |
108 |
|
if (i != cache.end()) |
109 |
|
return i->second->get_surface(); |
110 |
|
|
111 |
|
assert(xsize != 0 && ysize != 0); // forgot to call set_size() ? |
112 |
|
LevelPreviewCacheElem *ce = new LevelPreviewCacheElem(lp, idx, xsize, ysize); |
113 |
|
cache[idx] = ce; |
114 |
|
|
115 |
|
return ce->get_surface(); |
116 |
|
} |
117 |
|
}; |
118 |
|
|
119 |
|
|
120 |
class LevelMenu; |
class LevelMenu; |
121 |
|
|
122 |
class LevelWidget : public Widget { |
class LevelWidget : public Widget { |
174 |
/* |
/* |
175 |
** Variables. |
** Variables. |
176 |
*/ |
*/ |
177 |
ImageCache cache; |
ImageCache cache; |
178 |
LevelPack *level_pack; // The current level pack |
LevelPack *level_pack; // The current level pack |
179 |
|
LevelPreviewCache preview_cache; |
180 |
|
|
181 |
int ifirst; // Index of "upper left" level |
int ifirst; // Index of "upper left" level |
182 |
int iselected; // Index of selected level |
int iselected; // Index of selected level |
331 |
level_pack = lp; |
level_pack = lp; |
332 |
oxyd::ChangeSoundset(options::SoundSet, level_pack->get_default_SoundSet()); |
oxyd::ChangeSoundset(options::SoundSet, level_pack->get_default_SoundSet()); |
333 |
cache.clear(); |
cache.clear(); |
334 |
|
preview_cache.clear(); |
335 |
redraw(); |
redraw(); |
336 |
|
sound::PlaySound("menumove"); |
337 |
} |
} |
338 |
|
|
339 |
void |
void |
351 |
LevelWidget::draw (px::GC &gc, const px::Rect &r) |
LevelWidget::draw (px::GC &gc, const px::Rect &r) |
352 |
{ |
{ |
353 |
// Size of the level previews |
// Size of the level previews |
354 |
const int imgw = 120; //238; |
const int imgw = 120; //238; |
355 |
const int imgh = 78; |
const int imgh = 78; |
356 |
|
|
357 |
|
preview_cache.set_size(imgw, imgh); |
358 |
|
|
359 |
const int buttonw = imgw+20; |
const int buttonw = imgw+20; |
360 |
const int buttonh = imgh+35; |
const int buttonh = imgh+35; |
361 |
|
|
405 |
frame(gc, buttonarea); |
frame(gc, buttonarea); |
406 |
} |
} |
407 |
|
|
408 |
info = level_pack->get_info(i); |
info = level_pack->get_info(i); |
409 |
string fname = string("levels/") + info->filename + ".png"; |
Surface *img = 0; |
410 |
Surface *img = cache.get(enigma::FindDataFile(fname)); |
|
411 |
bool img_delete = false; |
if (level_pack->may_have_previews()) { |
412 |
if( !img && !Nozoom) { |
string fname = string("levels/") + info->filename + ".png"; |
413 |
img = LevelPreview (level_pack, i); |
img = cache.get(enigma::FindDataFile(fname)); |
414 |
if( img) { |
} |
415 |
fprintf(stderr,"ZOOM!\n"); |
|
416 |
img = img->zoom (imgw,imgh); |
if (!img && !Nozoom) { |
417 |
img_delete = true; |
img = preview_cache.getPreview(level_pack, i); |
418 |
} else img = 0; |
if (!img) |
419 |
|
img = cache.get(enigma::FindDataFile("levels/error.png")); |
420 |
} |
} |
421 |
|
|
422 |
int imgx = xpos + 10; |
int imgx = xpos + 10; |
424 |
if (img) |
if (img) |
425 |
blit (gc, imgx, imgy, img); |
blit (gc, imgx, imgy, img); |
426 |
|
|
|
if (img_delete) |
|
|
delete img; |
|
|
|
|
427 |
if (LevelStatus *ls=GetLevelStatus(level_pack->get_name(), |
if (LevelStatus *ls=GetLevelStatus(level_pack->get_name(), |
428 |
info->filename)) |
info->filename)) |
429 |
{ |
{ |