59 |
if (listener) listener->on_action(this); |
if (listener) listener->on_action(this); |
60 |
} |
} |
61 |
|
|
62 |
|
void change_levelpack (LevelPack *lp); |
63 |
|
|
64 |
void page_up() { |
void page_up() { |
65 |
set_selected (ifirst - width*height, iselected - width*height); |
set_selected (ifirst - width*height, iselected - width*height); |
66 |
} |
} |
69 |
} |
} |
70 |
void start() {set_selected (0,0);} |
void start() {set_selected (0,0);} |
71 |
void end() { |
void end() { |
72 |
set_selected (ifirst, level_pack.levels.size()-1); |
set_selected (ifirst, level_pack->size()-1); |
73 |
} |
} |
74 |
|
|
75 |
bool on_event(const SDL_Event &e); |
bool on_event(const SDL_Event &e); |
86 |
|
|
87 |
// Variables. |
// Variables. |
88 |
ImageCache cache; |
ImageCache cache; |
89 |
LevelPack &level_pack; // The level pack |
LevelPack *level_pack; // The level pack |
90 |
int ifirst; // Index of "upper left" level |
int ifirst; // Index of "upper left" level |
91 |
int iselected; // Index of selected level |
int iselected; // Index of selected level |
92 |
int width, height; |
int width, height; |
93 |
vector<px::Rect> areas; // Screen areas occupied by level previews |
vector<px::Rect> areas; // Screen areas occupied by level previews |
|
bool show_filenames_p; |
|
94 |
ActionListener *listener; |
ActionListener *listener; |
95 |
}; |
}; |
96 |
|
|
113 |
|
|
114 |
Widget *newgame; |
Widget *newgame; |
115 |
Widget *back; |
Widget *back; |
116 |
|
Widget *m_nextlp, *m_prevlp; // Next/previous level pack |
117 |
|
Widget *m_lpbutton; // Current level pack |
118 |
LevelWidget *levelwidget; |
LevelWidget *levelwidget; |
119 |
LevelPack *level_pack; |
LevelPack *level_pack; |
120 |
|
unsigned m_ilevelpack; |
121 |
}; |
}; |
122 |
|
|
123 |
class LevelPackMenu : public Menu { |
class LevelPackMenu : public Menu { |
143 |
|
|
144 |
// Private methods. |
// Private methods. |
145 |
void show_credits(); |
void show_credits(); |
146 |
void show_help(); |
void show_help(); |
147 |
void show_text( const char *text[]); |
void show_text( const char *text[]); |
148 |
|
|
149 |
// Variables. |
// Variables. |
150 |
Widget *newgame; |
Widget *m_startgame; |
|
Widget *playenigma; |
|
|
Widget *playoxyd; |
|
151 |
Widget *leveled; |
Widget *leveled; |
152 |
Widget *manual; |
Widget *manual; |
153 |
Widget *options; |
Widget *options; |
161 |
// LevelWidget implementation |
// LevelWidget implementation |
162 |
//---------------------------------------------------------------------- |
//---------------------------------------------------------------------- |
163 |
LevelWidget::LevelWidget(LevelPack *lp, int w, int h) |
LevelWidget::LevelWidget(LevelPack *lp, int w, int h) |
164 |
: level_pack(*lp), |
: level_pack(lp), |
165 |
ifirst(0), iselected(0), |
ifirst(0), iselected(0), |
166 |
width(w), height(h), |
width(w), height(h), |
167 |
areas(), |
areas(), |
168 |
listener(0) |
listener(0) |
169 |
{} |
{} |
170 |
|
|
171 |
void |
void |
172 |
LevelWidget::scroll_up(int nlines) |
LevelWidget::scroll_up(int nlines) |
173 |
{ |
{ |
174 |
for (; nlines; --nlines) { |
for (; nlines; --nlines) { |
175 |
if (ifirst+width*height >= (int)level_pack.levels.size()) |
if (ifirst+width*height >= (int)level_pack->size()) |
176 |
break; |
break; |
177 |
ifirst += width; |
ifirst += width; |
178 |
if (iselected < ifirst) |
if (iselected < ifirst) |
194 |
redraw(); |
redraw(); |
195 |
} |
} |
196 |
|
|
197 |
|
void |
198 |
|
LevelWidget::change_levelpack (LevelPack *lp) |
199 |
|
{ |
200 |
|
iselected = 0; |
201 |
|
ifirst = 0; |
202 |
|
level_pack = lp; |
203 |
|
cache.clear(); |
204 |
|
redraw(); |
205 |
|
} |
206 |
|
|
207 |
|
|
208 |
void |
void |
209 |
LevelWidget::draw (px::GC &gc, const px::Rect &r) |
LevelWidget::draw (px::GC &gc, const px::Rect &r) |
210 |
{ |
{ |
211 |
areas.clear(); |
areas.clear(); |
212 |
|
|
|
// blit(gc, 0,0, enigma::GetImage("menu_bg")); |
|
|
// set_color(gc, 0,0,0); |
|
|
// box(gc, r); |
|
|
|
|
213 |
const int imgw = 120; //238; |
const int imgw = 120; //238; |
214 |
const int imgh = 78; |
const int imgh = 78; |
215 |
const int hgap = 30, vgap=30; |
const int hgap = 30, vgap=40; |
216 |
|
|
217 |
const int x0 = get_x()+(get_w() - width*(imgw+hgap)+hgap)/2; |
const int x0 = get_x()+(get_w() - width*(imgw+hgap)+hgap)/2; |
218 |
const int y0 = get_y()+(get_h() - height*(imgh+vgap))/2; //get_y(); //30; |
const int y0 = get_y()+(get_h() - height*(imgh+vgap))/2; //get_y(); //30; |
219 |
|
|
|
unsigned i=ifirst; |
|
|
vector<LevelInfo> &levels = level_pack.levels; |
|
220 |
Font *smallfnt = enigma::GetFont("levelmenu"); |
Font *smallfnt = enigma::GetFont("levelmenu"); |
221 |
|
|
222 |
|
LevelInfo *info=0; |
223 |
|
|
224 |
|
unsigned i=ifirst; |
225 |
|
|
226 |
for (int y=0; y<height; y++) |
for (int y=0; y<height; y++) |
227 |
{ |
{ |
228 |
for (int x=0; x<width; x++, i++) |
for (int x=0; x<width; x++, i++) |
229 |
{ |
{ |
230 |
if (i >= levels.size()) |
if (i >= level_pack->size()) |
231 |
goto done_painting; |
goto done_painting; |
232 |
|
|
233 |
int xpos = x0 + x*(imgw + hgap); |
int xpos = x0 + x*(imgw + hgap); |
234 |
int ypos = y0 + y*(imgh + vgap); |
int ypos = y0 + y*(imgh + vgap); |
235 |
areas.push_back(Rect(xpos-10, ypos-10, imgw+20, imgh+35)); |
areas.push_back(Rect(xpos-10, ypos-10, imgw+20, imgh+35)); |
236 |
|
|
237 |
|
// if (i == (unsigned) iselected) { |
238 |
|
// set_color(gc, 255,0,0); |
239 |
|
// Rect a=areas.back(); |
240 |
|
// frame(gc, a); |
241 |
|
// frame(gc, smaller(a,1)); |
242 |
|
// frame(gc, smaller(a,2)); |
243 |
|
// } |
244 |
|
|
245 |
if (i == (unsigned) iselected) { |
if (i == (unsigned) iselected) { |
246 |
set_color(gc, 255,0,0); |
// Rect imgr (xpos,ypos,imgw, imgh); |
247 |
|
Rect imgr = areas.back(); |
248 |
|
|
249 |
|
px::TintRect (video::GetScreen(), intersect(imgr, r), |
250 |
|
120,120,120,120); |
251 |
|
set_color(gc, 200,200,200); |
252 |
Rect a=areas.back(); |
Rect a=areas.back(); |
253 |
frame(gc, a); |
frame(gc, a); |
|
frame(gc, smaller(a,1)); |
|
|
frame(gc, smaller(a,2)); |
|
254 |
} |
} |
255 |
|
|
256 |
string fname = string("levels/") + levels[i].filename + ".png"; |
info = level_pack->get_info(i); |
257 |
|
string fname = string("levels/") + info->filename + ".png"; |
258 |
if (Surface *img = cache.get(enigma::FindDataFile(fname))) |
if (Surface *img = cache.get(enigma::FindDataFile(fname))) |
259 |
blit (gc, xpos, ypos, img); |
blit (gc, xpos, ypos, img); |
260 |
|
|
261 |
|
|
262 |
|
|
263 |
options::LevelStatus *ls; |
options::LevelStatus *ls; |
264 |
|
|
265 |
if ((ls=options::GetLevelStatus(level_pack.name, |
if ((ls=options::GetLevelStatus(level_pack->name(), |
266 |
levels[i].filename))) |
info->filename))) |
267 |
{ |
{ |
268 |
if (ls->finished != 0) |
if (ls->finished != 0) |
269 |
blit (gc, xpos, ypos, enigma::GetImage("completed")); |
blit (gc, xpos, ypos, enigma::GetImage("completed")); |
270 |
} |
} |
271 |
|
|
272 |
string tstr = levels[i].name; |
string tstr = info->name; |
273 |
smallfnt->render (gc, |
smallfnt->render (gc, |
274 |
xpos+(imgw-smallfnt->get_width(tstr.c_str()))/2, |
xpos+(imgw-smallfnt->get_width(tstr.c_str()))/2, |
275 |
ypos+imgh+1, |
ypos+imgh+1, |
279 |
done_painting: |
done_painting: |
280 |
|
|
281 |
char bottom_line_text[255]; |
char bottom_line_text[255]; |
282 |
|
info = level_pack->get_info(iselected); |
283 |
snprintf (bottom_line_text, 254, " #%d %s (%s)", |
snprintf (bottom_line_text, 254, " #%d %s (%s)", |
284 |
iselected+1, |
iselected+1, |
285 |
levels[iselected].name.c_str(), |
info->name.c_str(), |
286 |
levels[iselected].filename.c_str()); |
info->filename.c_str()); |
287 |
smallfnt->render (gc, 5, 460, bottom_line_text); |
smallfnt->render (gc, 5, 460, bottom_line_text); |
288 |
} |
} |
289 |
|
|
290 |
void |
void |
291 |
LevelWidget::set_selected (int newfirst, int newsel) |
LevelWidget::set_selected (int newfirst, int newsel) |
292 |
{ |
{ |
293 |
vector<LevelInfo> &levels = level_pack.levels; |
int numlevels = static_cast<int>(level_pack->size()); |
294 |
if (newfirst!=ifirst && newfirst>=0 && newfirst<(int)levels.size()) |
|
295 |
|
if (newfirst!=ifirst && newfirst>=0 && newfirst < numlevels) |
296 |
{ |
{ |
297 |
sound::PlaySound("menumove"); |
sound::PlaySound("menumove"); |
298 |
ifirst = newfirst; |
ifirst = newfirst; |
299 |
iselected = Max(Min(newsel,(int)levels.size()-1), 0); |
iselected = Max(Min(newsel, numlevels-1), 0); |
300 |
redraw(); |
redraw(); |
301 |
} |
} |
302 |
else if (newsel!=iselected && newsel>=0 && newsel<(int)levels.size()) |
else if (newsel!=iselected && newsel>=0 && newsel<numlevels) |
303 |
{ |
{ |
304 |
sound::PlaySound("menumove"); |
sound::PlaySound("menumove"); |
305 |
while (newsel < ifirst) |
while (newsel < ifirst) |
371 |
{ |
{ |
372 |
switch (e->key.keysym.sym) { |
switch (e->key.keysym.sym) { |
373 |
case SDLK_l: // Reload level index |
case SDLK_l: // Reload level index |
374 |
level_pack.init(); |
// level_pack.init(); |
375 |
redraw(); |
redraw(); |
376 |
break; |
break; |
377 |
case SDLK_o: // Show/hide "todo" levels |
case SDLK_o: // Show/hide "todo" levels |
544 |
public: |
public: |
545 |
SkipSolvedButton() : TextButton("", this) { update(); } |
SkipSolvedButton() : TextButton("", this) { update(); } |
546 |
}; |
}; |
|
|
|
|
class AlphaShadowButton : public TextButton { |
|
|
void update() { |
|
|
// if (lua::get_num("AlphaShadows") > 0) |
|
|
// set_text("Blended Shadows"); |
|
|
// else |
|
|
// set_text("Stippled Shadows"); |
|
|
} |
|
|
// ActionListener interface. |
|
|
void on_action(Widget *) { |
|
|
// video::ToggleFullscreen(); |
|
|
update(); |
|
|
} |
|
|
public: |
|
|
AlphaShadowButton() : TextButton("") { update(); } |
|
|
}; |
|
547 |
} |
} |
548 |
|
|
549 |
|
|
598 |
vlist.add (new MusicVolumeButton); |
vlist.add (new MusicVolumeButton); |
599 |
vlist.add (new InGameMusicButton); |
vlist.add (new InGameMusicButton); |
600 |
vlist.add (new StereoButton); |
vlist.add (new StereoButton); |
|
// add(new AlphaShadowButton, Rect(0,50,150,40)); |
|
601 |
vlist.add (new SkipSolvedButton); |
vlist.add (new SkipSolvedButton); |
602 |
vlist.add(back); |
vlist.add(back); |
603 |
} |
} |
631 |
// Level menu |
// Level menu |
632 |
//---------------------------------------------------------------------- |
//---------------------------------------------------------------------- |
633 |
LevelMenu::LevelMenu(LevelPack *lp, unsigned ilevel_pack) |
LevelMenu::LevelMenu(LevelPack *lp, unsigned ilevel_pack) |
634 |
: newgame(new TextButton("Start Game", this)), |
: newgame (new TextButton("Start Game", this)), |
635 |
back(new TextButton("Back", this)), |
back (new TextButton("Back", this)), |
636 |
levelwidget(new LevelWidget(lp, 3, 4)), |
m_nextlp (new TextButton("Next", this)), |
637 |
level_pack(lp) |
m_prevlp (new TextButton("Prev", this)), |
638 |
|
m_lpbutton (new TextButton("Game: ", this)), |
639 |
|
levelwidget (new LevelWidget(lp, 4, 3)), |
640 |
|
level_pack (lp), |
641 |
|
m_ilevelpack (ilevel_pack) |
642 |
{ |
{ |
643 |
{ |
{ |
644 |
BuildVList hlist(this, Rect(510,20,100,28), 5); |
BuildHList hlist(this, Rect(30,420,100,28), 5); |
645 |
start = hlist.add(new ImageButton("ic-top", "ic-top1")); |
start = hlist.add(new ImageButton("ic-top", "ic-top1")); |
646 |
pgup = hlist.add(new ImageButton("ic-up", "ic-up1")); |
pgup = hlist.add(new ImageButton("ic-up", "ic-up1")); |
647 |
pgdown = hlist.add(new ImageButton("ic-down", "ic-down1")); |
pgdown = hlist.add(new ImageButton("ic-down", "ic-down1")); |
653 |
end->set_listener(this); |
end->set_listener(this); |
654 |
} |
} |
655 |
{ |
{ |
656 |
|
BuildHList hlist(this, Rect(30,30,100,28), 5); |
657 |
|
hlist.add (m_prevlp); |
658 |
|
hlist.add (m_lpbutton); |
659 |
|
hlist.add (m_nextlp); |
660 |
|
} |
661 |
|
|
662 |
|
{ |
663 |
BuildVList vlist(this, Rect(510,400,100,28), 5); |
BuildVList vlist(this, Rect(510,400,100,28), 5); |
664 |
// vlist.add(new TextButton("Timer on")); |
// vlist.add(new TextButton("Timer on")); |
665 |
vlist.add(newgame); |
vlist.add(newgame); |
667 |
} |
} |
668 |
|
|
669 |
// Add levelwidget at the center |
// Add levelwidget at the center |
670 |
add(levelwidget, Rect(10,10,500,480)); |
add(levelwidget, Rect(10,10,600,480)); |
671 |
levelwidget->set_listener(this); |
levelwidget->set_listener(this); |
672 |
} |
} |
673 |
|
|
692 |
{ |
{ |
693 |
if (w == newgame || w==levelwidget) { |
if (w == newgame || w==levelwidget) { |
694 |
int ilevel=levelwidget->selected_level(); |
int ilevel=levelwidget->selected_level(); |
695 |
StartGame(level_pack, ilevel); |
StartGame(enigma::LevelPacks[m_ilevelpack], ilevel); |
696 |
invalidate_all(); |
invalidate_all(); |
697 |
} else if (w == back) { |
} else if (w == back) { |
698 |
Menu::quit(); |
Menu::quit(); |
704 |
levelwidget->start(); |
levelwidget->start(); |
705 |
} else if (w == end) { |
} else if (w == end) { |
706 |
levelwidget->end(); |
levelwidget->end(); |
707 |
|
} |
708 |
|
else if (w == m_prevlp) { |
709 |
|
if (m_ilevelpack > 0) { |
710 |
|
m_ilevelpack -= 1; |
711 |
|
levelwidget->change_levelpack (enigma::LevelPacks[m_ilevelpack]); |
712 |
|
} |
713 |
|
} |
714 |
|
else if (w == m_nextlp) { |
715 |
|
if (m_ilevelpack < enigma::LevelPacks.size() - 1) { |
716 |
|
m_ilevelpack += 1; |
717 |
|
levelwidget->change_levelpack (enigma::LevelPacks[m_ilevelpack]); |
718 |
|
} |
719 |
} |
} |
720 |
} |
} |
721 |
|
|
742 |
|
|
743 |
for (unsigned i=0; i<enigma::LevelPacks.size(); ++i) { |
for (unsigned i=0; i<enigma::LevelPacks.size(); ++i) { |
744 |
LevelPack *lp = enigma::LevelPacks[i]; |
LevelPack *lp = enigma::LevelPacks[i]; |
745 |
if( lp->levels.size() > 0) |
if (lp->size() > 0) |
746 |
buttons.push_back(b.add(new TextButton(lp->name, this))); |
buttons.push_back(b.add(new TextButton(lp->name(), this))); |
747 |
} |
} |
748 |
|
|
749 |
BuildVList vlist(this, Rect(510,433,100,28), 5); |
BuildVList vlist(this, Rect(510,433,100,28), 5); |
783 |
MainMenu::MainMenu() |
MainMenu::MainMenu() |
784 |
{ |
{ |
785 |
BuildVList b(this, Rect((640-150)/2,150,150,40), 5); |
BuildVList b(this, Rect((640-150)/2,150,150,40), 5); |
786 |
if (enigma::LevelPacks.size() > 2) { |
m_startgame = b.add(new TextButton("Start Game", this)); |
787 |
newgame = b.add(new TextButton("New Game", this)); |
leveled = b.add(new TextButton("Editor", this)); |
788 |
playenigma = 0; |
manual = b.add(new TextButton("Manual", this)); |
789 |
playoxyd = 0; |
options = b.add(new TextButton("Options", this)); |
790 |
} else { |
credits = b.add(new TextButton("Credits", this)); |
791 |
newgame = 0; |
quit = b.add(new TextButton("Quit", this)); |
|
playenigma = b.add(new TextButton("Play Enigma", this)); |
|
|
playoxyd = b.add(new TextButton("Play Oxyd & Co", this)); |
|
|
} |
|
|
leveled = b.add(new TextButton("Editor", this)); |
|
|
manual = b.add(new TextButton("Manual", this)); |
|
|
options = b.add(new TextButton("Options", this)); |
|
|
credits = b.add(new TextButton("Credits", this)); |
|
|
quit = b.add(new TextButton("Quit", this)); |
|
792 |
} |
} |
793 |
|
|
794 |
void |
void |
810 |
void |
void |
811 |
MainMenu::on_action(Widget *w) |
MainMenu::on_action(Widget *w) |
812 |
{ |
{ |
813 |
if (w == newgame) { |
if (w == m_startgame) { |
|
LevelPackMenu m; |
|
|
//m.center(video::GetScreen()); |
|
|
m.manage(video::GetScreen()); |
|
|
} |
|
|
else if (w == playenigma) { |
|
814 |
LevelMenu m(enigma::LevelPacks[0], 0); |
LevelMenu m(enigma::LevelPacks[0], 0); |
815 |
m.manage(video::GetScreen()); |
m.manage(video::GetScreen()); |
816 |
invalidate_all(); |
invalidate_all(); |
817 |
} |
} |
|
else if (w == playoxyd) { |
|
|
LevelMenu m(enigma::LevelPacks[1], 0); |
|
|
m.manage(video::GetScreen()); |
|
|
invalidate_all(); |
|
|
} |
|
818 |
else if (w == manual) { |
else if (w == manual) { |
819 |
show_help (); |
show_help (); |
820 |
} else if (w == credits) { |
} else if (w == credits) { |