5 |
* modify it under the terms of the GNU General Public License |
* modify it under the terms of the GNU General Public License |
6 |
* as published by the Free Software Foundation; either version 2 |
* as published by the Free Software Foundation; either version 2 |
7 |
* of the License, or (at your option) any later version. |
* of the License, or (at your option) any later version. |
8 |
* |
* |
9 |
* This program is distributed in the hope that it will be useful, |
* This program is distributed in the hope that it will be useful, |
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
30 |
|
|
31 |
namespace |
namespace |
32 |
{ |
{ |
33 |
|
|
34 |
class ImageAlloc { |
class ImageAlloc { |
35 |
public: |
public: |
36 |
px::Surface *acquire(const std::string &name) { |
px::Surface *acquire(const std::string &name) { |
52 |
void draw(px::GC &gc, const px::Rect &r); |
void draw(px::GC &gc, const px::Rect &r); |
53 |
|
|
54 |
void set_listener(ActionListener *al) { |
void set_listener(ActionListener *al) { |
55 |
listener = al; |
listener = al; |
56 |
} |
} |
57 |
void trigger_action() { |
void trigger_action() { |
58 |
cache.clear(); |
cache.clear(); |
62 |
void change_levelpack (LevelPack *lp); |
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 |
} |
} |
67 |
void page_down() { |
void page_down() { |
68 |
set_selected (ifirst + width*height, iselected + width*height); |
set_selected (ifirst + width*height, iselected + width*height); |
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->size()-1); |
set_selected (ifirst, level_pack->size()-1); |
73 |
} |
} |
74 |
|
|
75 |
|
void next_unsolved(); |
76 |
|
|
77 |
bool on_event(const SDL_Event &e); |
bool on_event(const SDL_Event &e); |
78 |
private: |
private: |
79 |
// Private functions. |
// Private functions. |
102 |
private: |
private: |
103 |
// Menu interface. |
// Menu interface. |
104 |
void draw_background(px::GC &gc); |
void draw_background(px::GC &gc); |
105 |
|
|
106 |
// Widget interface. |
// Widget interface. |
107 |
bool on_event (const SDL_Event &e); |
bool on_event (const SDL_Event &e); |
108 |
|
|
109 |
// ActionListener interface. |
// ActionListener interface. |
110 |
void on_action(Widget *w); |
void on_action(Widget *w); |
111 |
|
|
112 |
// Variables. |
// Variables. |
113 |
|
|
114 |
Widget *pgup, *pgdown, *start, *end; |
Widget *pgup, *pgdown, *start, *end, *unsolved; |
115 |
|
|
116 |
Widget *newgame; |
Widget *newgame; |
117 |
Widget *back; |
Widget *back; |
118 |
Widget *m_nextlp, *m_prevlp; // Next/previous level pack |
Widget *m_nextlp, *m_prevlp; // Next/previous level pack |
132 |
vector<Widget *> buttons; |
vector<Widget *> buttons; |
133 |
Widget *back; |
Widget *back; |
134 |
}; |
}; |
135 |
|
|
136 |
class MainMenu : public Menu { |
class MainMenu : public Menu { |
137 |
public: |
public: |
138 |
MainMenu(); |
MainMenu(); |
183 |
redraw(); |
redraw(); |
184 |
} |
} |
185 |
|
|
186 |
void |
void |
187 |
LevelWidget::scroll_down(int nlines) |
LevelWidget::scroll_down(int nlines) |
188 |
{ |
{ |
189 |
for (; nlines; --nlines) { |
for (; nlines; --nlines) { |
196 |
redraw(); |
redraw(); |
197 |
} |
} |
198 |
|
|
199 |
void |
void |
200 |
LevelWidget::change_levelpack (LevelPack *lp) |
LevelWidget::change_levelpack (LevelPack *lp) |
201 |
{ |
{ |
202 |
iselected = 0; |
iselected = 0; |
206 |
redraw(); |
redraw(); |
207 |
} |
} |
208 |
|
|
209 |
|
void |
210 |
|
LevelWidget::next_unsolved() |
211 |
|
{ |
212 |
|
int curr = iselected; |
213 |
|
int next = curr+1; |
214 |
|
bool found = false; |
215 |
|
|
216 |
|
while (next != curr) { |
217 |
|
if (next >= level_pack->size()) next = 0; |
218 |
|
|
219 |
|
LevelInfo *info = level_pack->get_info(next); |
220 |
|
options::LevelStatus *ls = options::GetLevelStatus(level_pack->name(), info->filename); |
221 |
|
|
222 |
|
if (!ls || !ls->finished) { |
223 |
|
found = true; |
224 |
|
break; |
225 |
|
} |
226 |
|
|
227 |
|
++next; |
228 |
|
} |
229 |
|
|
230 |
|
if (found) { |
231 |
|
set_selected(ifirst, next); |
232 |
|
} |
233 |
|
else { |
234 |
|
printf("No unsolved level found.\n"); |
235 |
|
} |
236 |
|
} |
237 |
|
|
238 |
void |
void |
239 |
LevelWidget::draw (px::GC &gc, const px::Rect &r) |
LevelWidget::draw (px::GC &gc, const px::Rect &r) |
252 |
LevelInfo *info=0; |
LevelInfo *info=0; |
253 |
|
|
254 |
unsigned i=ifirst; |
unsigned i=ifirst; |
255 |
|
|
256 |
for (int y=0; y<height; y++) |
for (int y=0; y<height; y++) |
257 |
{ |
{ |
258 |
for (int x=0; x<width; x++, i++) |
for (int x=0; x<width; x++, i++) |
259 |
{ |
{ |
260 |
if (i >= level_pack->size()) |
if (i >= level_pack->size()) |
261 |
goto done_painting; |
goto done_painting; |
275 |
if (i == (unsigned) iselected) { |
if (i == (unsigned) iselected) { |
276 |
// Rect imgr (xpos,ypos,imgw, imgh); |
// Rect imgr (xpos,ypos,imgw, imgh); |
277 |
Rect imgr = areas.back(); |
Rect imgr = areas.back(); |
278 |
|
|
279 |
px::TintRect (video::GetScreen(), intersect(imgr, r), |
px::TintRect (video::GetScreen(), intersect(imgr, r), |
280 |
120,120,120,120); |
120,120,120,120); |
281 |
set_color(gc, 200,200,200); |
set_color(gc, 200,200,200); |
291 |
|
|
292 |
|
|
293 |
options::LevelStatus *ls; |
options::LevelStatus *ls; |
294 |
|
|
295 |
if ((ls=options::GetLevelStatus(level_pack->name(), |
if ((ls=options::GetLevelStatus(level_pack->name(), |
296 |
info->filename))) |
info->filename))) |
297 |
{ |
{ |
298 |
if (ls->finished != 0) |
if (ls->finished != 0) |
299 |
blit (gc, xpos, ypos, enigma::GetImage("completed")); |
blit (gc, xpos, ypos, enigma::GetImage("completed")); |
300 |
} |
} |
301 |
|
|
302 |
string tstr = info->name; |
string tstr = info->name; |
303 |
smallfnt->render (gc, |
smallfnt->render (gc, |
304 |
xpos+(imgw-smallfnt->get_width(tstr.c_str()))/2, |
xpos+(imgw-smallfnt->get_width(tstr.c_str()))/2, |
305 |
ypos+imgh+1, |
ypos+imgh+1, |
306 |
tstr.c_str()); |
tstr.c_str()); |
307 |
} |
} |
310 |
|
|
311 |
char bottom_line_text[255]; |
char bottom_line_text[255]; |
312 |
info = level_pack->get_info(iselected); |
info = level_pack->get_info(iselected); |
313 |
snprintf (bottom_line_text, 254, " #%d %s (%s)", |
snprintf (bottom_line_text, 254, " #%d %s (%s)", |
314 |
iselected+1, |
iselected+1, |
315 |
info->name.c_str(), |
info->name.c_str(), |
316 |
info->filename.c_str()); |
info->filename.c_str()); |
317 |
smallfnt->render (gc, 5, 460, bottom_line_text); |
smallfnt->render (gc, 5, 460, bottom_line_text); |
318 |
} |
} |
364 |
} |
} |
365 |
} |
} |
366 |
break; |
break; |
367 |
case SDL_MOUSEBUTTONDOWN: |
case SDL_MOUSEBUTTONDOWN: |
368 |
h=handle_mousedown (&e); |
h=handle_mousedown (&e); |
369 |
break; |
break; |
370 |
case SDL_KEYDOWN: |
case SDL_KEYDOWN: |
371 |
h= handle_keydown (&e); |
h= handle_keydown (&e); |
372 |
break; |
break; |
373 |
} |
} |
469 |
class SoundVolumeButton : public TextButton { |
class SoundVolumeButton : public TextButton { |
470 |
int get_vol() const { return int(0.5+options::SoundVolume*10.0); } |
int get_vol() const { return int(0.5+options::SoundVolume*10.0); } |
471 |
void set_vol(int v) { options::SoundVolume = v/10.0; } |
void set_vol(int v) { options::SoundVolume = v/10.0; } |
472 |
|
|
473 |
void update() { |
void update() { |
474 |
if (options::SoundVolume == 0) |
if (options::SoundVolume == 0) |
475 |
set_text("Sound off"); |
set_text("Sound off"); |
495 |
class MusicVolumeButton : public TextButton { |
class MusicVolumeButton : public TextButton { |
496 |
int get_vol() const { return int(0.5+options::MusicVolume*10.0); } |
int get_vol() const { return int(0.5+options::MusicVolume*10.0); } |
497 |
void set_vol(int v) { options::MusicVolume = v/10.0; } |
void set_vol(int v) { options::MusicVolume = v/10.0; } |
498 |
|
|
499 |
void update() { |
void update() { |
500 |
if (options::MusicVolume == 0) |
if (options::MusicVolume == 0) |
501 |
set_text("Music off"); |
set_text("Music off"); |
517 |
public: |
public: |
518 |
MusicVolumeButton() : TextButton("", this) { update(); } |
MusicVolumeButton() : TextButton("", this) { update(); } |
519 |
}; |
}; |
520 |
|
|
521 |
class StereoButton : public TextButton { |
class StereoButton : public TextButton { |
522 |
void update() { |
void update() { |
523 |
if (options::StereoSeparation == 0) |
if (options::StereoSeparation == 0) |
540 |
public: |
public: |
541 |
StereoButton() : TextButton("", this) { update(); } |
StereoButton() : TextButton("", this) { update(); } |
542 |
}; |
}; |
543 |
|
|
544 |
class InGameMusicButton : public TextButton { |
class InGameMusicButton : public TextButton { |
545 |
void update() { |
void update() { |
546 |
if (options::InGameMusic) |
if (options::InGameMusic) |
650 |
Menu::quit(); |
Menu::quit(); |
651 |
} |
} |
652 |
|
|
653 |
void OptionsMenu::draw_background(px::GC &gc) |
void OptionsMenu::draw_background(px::GC &gc) |
654 |
{ |
{ |
655 |
video::SetCaption("Enigma - Options Menu"); |
video::SetCaption("Enigma - Options Menu"); |
656 |
blit(gc, 0,0, enigma::GetImage("menu_bg")); |
blit(gc, 0,0, enigma::GetImage("menu_bg")); |
661 |
// Level menu |
// Level menu |
662 |
//---------------------------------------------------------------------- |
//---------------------------------------------------------------------- |
663 |
LevelMenu::LevelMenu(LevelPack *lp, unsigned ilevel_pack) |
LevelMenu::LevelMenu(LevelPack *lp, unsigned ilevel_pack) |
664 |
: newgame (new TextButton("Start Game", this)), |
: newgame (new TextButton("Start Game", this)), |
665 |
back (new TextButton("Back", this)), |
back (new TextButton("Back", this)), |
666 |
m_nextlp (new TextButton("Next", this)), |
m_nextlp (new TextButton("Next", this)), |
667 |
m_prevlp (new TextButton("Prev", this)), |
m_prevlp (new TextButton("Prev", this)), |
670 |
level_pack (lp), |
level_pack (lp), |
671 |
m_ilevelpack (ilevel_pack) |
m_ilevelpack (ilevel_pack) |
672 |
{ |
{ |
|
{ |
|
|
BuildHList hlist(this, Rect(30,420,100,28), 5); |
|
|
start = hlist.add(new ImageButton("ic-top", "ic-top1")); |
|
|
pgup = hlist.add(new ImageButton("ic-up", "ic-up1")); |
|
|
pgdown = hlist.add(new ImageButton("ic-down", "ic-down1")); |
|
|
end = hlist.add(new ImageButton("ic-bottom", "ic-bottom1")); |
|
673 |
|
|
674 |
pgup->set_listener(this); |
#define BX 100 // button xsize |
675 |
pgdown->set_listener(this); |
#define BY 28 // button ysize |
676 |
start->set_listener(this); |
#define SX 5 // x spacing |
677 |
end->set_listener(this); |
#define SY 2 // y spacing |
678 |
} |
#define OX (BX+SX) |
679 |
|
#define OY (BY+SY) |
680 |
|
#define RJ (605+SX) // right justification |
681 |
|
#define Y1 15 // y position for top button row |
682 |
|
#define Y2 410 // y position for bottom button row |
683 |
|
|
684 |
{ |
{ |
685 |
BuildHList hlist(this, Rect(30,30,100,28), 5); |
BuildHList hlist(this, Rect(RJ-3*OX, Y1, BX, BY), 5); |
686 |
|
|
687 |
hlist.add (m_prevlp); |
hlist.add (m_prevlp); |
688 |
hlist.add (m_lpbutton); |
hlist.add (m_lpbutton); |
689 |
hlist.add (m_nextlp); |
hlist.add (m_nextlp); |
690 |
} |
} |
691 |
|
|
692 |
{ |
{ |
693 |
BuildVList vlist(this, Rect(510,400,100,28), 5); |
pgup = new ImageButton("ic-up", "ic-up1"); |
694 |
// vlist.add(new TextButton("Timer on")); |
pgdown = new ImageButton("ic-down", "ic-down1"); |
695 |
vlist.add(newgame); |
start = new ImageButton("ic-top", "ic-top1"); |
696 |
vlist.add(back); |
end = new ImageButton("ic-bottom", "ic-bottom1"); |
697 |
|
unsolved = new ImageButton("ic-unsolved", "ic-unsolved1"); |
698 |
|
// new TextButton("Timer on") |
699 |
|
|
700 |
|
BuildHList hlist1(this, Rect(RJ-4*OX, Y2, BX, BY), 5); |
701 |
|
BuildHList hlist2(this, Rect(RJ-3*OX, Y2+OY, BX, BY), 5); |
702 |
|
|
703 |
|
hlist1.add (unsolved); |
704 |
|
hlist1.add (newgame); |
705 |
|
hlist1.add (pgup); |
706 |
|
hlist1.add (start); |
707 |
|
|
708 |
|
hlist2.add (back); |
709 |
|
hlist2.add (pgdown); |
710 |
|
hlist2.add (end); |
711 |
|
|
712 |
|
pgup->set_listener(this); |
713 |
|
pgdown->set_listener(this); |
714 |
|
start->set_listener(this); |
715 |
|
end->set_listener(this); |
716 |
|
unsolved->set_listener(this); |
717 |
} |
} |
718 |
|
|
719 |
// Add levelwidget at the center |
// Add levelwidget at the center |
720 |
add(levelwidget, Rect(10,10,600,480)); |
add(levelwidget, Rect(10,3,600,480)); |
721 |
|
// add(levelwidget, Rect(10,10,600,480)); |
722 |
levelwidget->set_listener(this); |
levelwidget->set_listener(this); |
723 |
|
|
724 |
|
#undef BX |
725 |
|
#undef BY |
726 |
|
#undef SX |
727 |
|
#undef SY |
728 |
|
#undef OX |
729 |
|
#undef OY |
730 |
|
#undef RJ |
731 |
|
#undef Y1 |
732 |
|
#undef Y2 |
733 |
} |
} |
734 |
|
|
735 |
bool |
bool |
737 |
{ |
{ |
738 |
bool handled=levelwidget->on_event(e); |
bool handled=levelwidget->on_event(e); |
739 |
// Pass all events to the level widget first |
// Pass all events to the level widget first |
740 |
if (!handled) { |
if (!handled) { |
741 |
if (e.type == SDL_MOUSEBUTTONDOWN |
if (e.type == SDL_MOUSEBUTTONDOWN |
742 |
&& e.button.button == SDL_BUTTON_RIGHT) |
&& e.button.button == SDL_BUTTON_RIGHT) |
743 |
{ |
{ |
765 |
levelwidget->start(); |
levelwidget->start(); |
766 |
} else if (w == end) { |
} else if (w == end) { |
767 |
levelwidget->end(); |
levelwidget->end(); |
768 |
} |
} else if (w == unsolved) { |
769 |
|
levelwidget->next_unsolved(); |
770 |
|
} |
771 |
else if (w == m_prevlp) { |
else if (w == m_prevlp) { |
772 |
if (m_ilevelpack > 0) { |
if (m_ilevelpack > 0) { |
773 |
m_ilevelpack -= 1; |
m_ilevelpack -= 1; |
774 |
levelwidget->change_levelpack (enigma::LevelPacks[m_ilevelpack]); |
levelwidget->change_levelpack (enigma::LevelPacks[m_ilevelpack]); |
775 |
} |
} |
776 |
} |
} |
777 |
else if (w == m_nextlp) { |
else if (w == m_nextlp) { |
778 |
if (m_ilevelpack < enigma::LevelPacks.size() - 1) { |
if (m_ilevelpack < enigma::LevelPacks.size() - 1) { |
779 |
m_ilevelpack += 1; |
m_ilevelpack += 1; |
783 |
} |
} |
784 |
|
|
785 |
void |
void |
786 |
LevelMenu::draw_background(px::GC &gc) |
LevelMenu::draw_background(px::GC &gc) |
787 |
{ |
{ |
788 |
video::SetCaption("Enigma - Level Menu"); |
video::SetCaption("Enigma - Level Menu"); |
789 |
sound::PlayMusic( options::MenuMusicFile.c_str()); |
sound::PlayMusic( options::MenuMusicFile.c_str()); |
793 |
|
|
794 |
|
|
795 |
//---------------------------------------------------------------------- |
//---------------------------------------------------------------------- |
796 |
// Level pack menu |
// Level pack menu |
797 |
//---------------------------------------------------------------------- |
//---------------------------------------------------------------------- |
798 |
|
|
799 |
LevelPackMenu::LevelPackMenu() |
LevelPackMenu::LevelPackMenu() |
808 |
if (lp->size() > 0) |
if (lp->size() > 0) |
809 |
buttons.push_back(b.add(new TextButton(lp->name(), this))); |
buttons.push_back(b.add(new TextButton(lp->name(), this))); |
810 |
} |
} |
811 |
|
|
812 |
BuildVList vlist(this, Rect(510,433,100,28), 5); |
BuildVList vlist(this, Rect(510,433,100,28), 5); |
813 |
back = new TextButton("Back", this); |
back = new TextButton("Back", this); |
814 |
vlist.add( back); |
vlist.add( back); |
829 |
} |
} |
830 |
|
|
831 |
void |
void |
832 |
LevelPackMenu::draw_background(px::GC &gc) |
LevelPackMenu::draw_background(px::GC &gc) |
833 |
{ |
{ |
834 |
video::SetCaption("Enigma - Level Pack Menu"); |
video::SetCaption("Enigma - Level Pack Menu"); |
835 |
sound::PlayMusic( options::MenuMusicFile.c_str()); |
sound::PlayMusic( options::MenuMusicFile.c_str()); |
855 |
} |
} |
856 |
|
|
857 |
void |
void |
858 |
MainMenu::draw_background(px::GC &gc) |
MainMenu::draw_background(px::GC &gc) |
859 |
{ |
{ |
860 |
video::SetCaption("Enigma - Main Menu"); |
video::SetCaption("Enigma - Main Menu"); |
861 |
sound::PlayMusic( options::MenuMusicFile.c_str()); |
sound::PlayMusic( options::MenuMusicFile.c_str()); |