70 |
|
|
71 |
void change_levelpack (LevelPack *lp); |
void change_levelpack (LevelPack *lp); |
72 |
|
|
73 |
void set_current(int newsel) { set_selected(ifirst, newsel); } |
void page_up(); |
74 |
|
void page_down(); |
75 |
void page_up() { |
void start() { set_selected (0,0); } |
|
set_selected (ifirst - width*height, iselected - width*height); |
|
|
} |
|
|
void page_down() { |
|
|
set_selected (ifirst + width*height, iselected + width*height); |
|
|
} |
|
|
void start() {set_selected (0,0);} |
|
76 |
void end() { set_current(level_pack->size()-1); } |
void end() { set_current(level_pack->size()-1); } |
77 |
|
|
78 |
|
void set_current(int newsel) { set_selected(ifirst, newsel); } |
79 |
void next_unsolved(); |
void next_unsolved(); |
80 |
|
|
81 |
bool on_event(const SDL_Event &e); |
bool on_event(const SDL_Event &e); |
115 |
} |
} |
116 |
|
|
117 |
private: |
private: |
118 |
|
void update_info(); |
119 |
|
|
120 |
|
|
121 |
void set_levelpack (unsigned index); |
void set_levelpack (unsigned index); |
122 |
|
|
123 |
// Menu interface. |
// Menu interface. |
137 |
Widget *back; |
Widget *back; |
138 |
Widget *m_nextlp, *m_prevlp; // Next/previous level pack |
Widget *m_nextlp, *m_prevlp; // Next/previous level pack |
139 |
TextButton *m_lpbutton; // Current level pack |
TextButton *m_lpbutton; // Current level pack |
140 |
|
TextButton *m_infobutton; |
141 |
|
TextButton *m_levelinfo; |
142 |
LevelWidget *levelwidget; |
LevelWidget *levelwidget; |
143 |
LevelPack *level_pack; |
LevelPack *level_pack; |
144 |
unsigned m_ilevelpack; |
unsigned m_ilevelpack; |
184 |
|
|
185 |
LevelMenu * |
LevelMenu * |
186 |
LevelWidget::get_menu() { |
LevelWidget::get_menu() { |
187 |
Menu *m = Widget::get_menu(); |
if (Menu *m = Widget::get_menu()) |
188 |
if (m) return dynamic_cast<LevelMenu*>(m); |
return dynamic_cast<LevelMenu*>(m); |
189 |
assert(0); |
else { |
190 |
return 0; |
assert(0); |
191 |
|
return 0; |
192 |
|
} |
193 |
} |
} |
194 |
|
|
195 |
void |
void |
218 |
redraw(); |
redraw(); |
219 |
} |
} |
220 |
|
|
221 |
|
void LevelWidget::page_up() { |
222 |
|
set_selected (ifirst - width*height, iselected - width*height); |
223 |
|
} |
224 |
|
void LevelWidget::page_down() { |
225 |
|
set_selected (ifirst + width*height, iselected + width*height); |
226 |
|
} |
227 |
|
|
228 |
|
|
229 |
void |
void |
230 |
LevelWidget::change_levelpack (LevelPack *lp) |
LevelWidget::change_levelpack (LevelPack *lp) |
231 |
{ |
{ |
251 |
void |
void |
252 |
LevelWidget::draw (px::GC &gc, const px::Rect &r) |
LevelWidget::draw (px::GC &gc, const px::Rect &r) |
253 |
{ |
{ |
254 |
|
// Size of the level previews |
255 |
const int imgw = 120; //238; |
const int imgw = 120; //238; |
256 |
const int imgh = 78; |
const int imgh = 78; |
|
const int hgap = 30, vgap=40; |
|
257 |
|
|
258 |
const int x0 = get_x()+(get_w() - width*(imgw+hgap)+hgap)/2; |
const int buttonw = imgw+20; |
259 |
const int y0 = get_y()+(get_h() - height*(imgh+vgap))/2; //get_y(); //30; |
const int buttonh = imgh+35; |
260 |
|
|
261 |
|
const int hgap = Max(0, (get_w() - width*buttonw) / (width-1)); |
262 |
|
const int vgap = Max(0, (get_h() - height*buttonh)/ (height-1)); |
263 |
|
|
264 |
|
const int x0 = get_x(); |
265 |
|
const int y0 = get_y(); |
266 |
|
|
267 |
Font *smallfnt = enigma::GetFont("levelmenu"); |
Font *smallfnt = enigma::GetFont("levelmenu"); |
268 |
|
|
269 |
const LevelInfo *info=0; |
const LevelInfo *info=0; |
270 |
|
|
271 |
|
px::Surface *img_easy = enigma::GetImage("completed-easy"); |
272 |
|
px::Surface *img_hard = enigma::GetImage("completed"); |
273 |
|
px::Surface *img_changed = enigma::GetImage("changed"); |
274 |
|
|
275 |
unsigned i=ifirst; |
unsigned i=ifirst; |
276 |
|
|
277 |
|
|
278 |
for (int y=0; y<height; y++) |
for (int y=0; y<height; y++) |
279 |
{ |
{ |
280 |
for (int x=0; x<width; x++, i++) |
for (int x=0; x<width; x++, i++) |
284 |
goto done_painting; |
goto done_painting; |
285 |
} |
} |
286 |
|
|
287 |
int xpos = x0 + x*(imgw + hgap); |
int xpos = x0 + x*(buttonw + hgap); |
288 |
int ypos = y0 + y*(imgh + vgap); |
int ypos = y0 + y*(buttonh + vgap); |
289 |
if( r.overlaps(Rect(xpos-10, ypos-10, imgw+20, imgh+35)) // This area is requested |
|
290 |
|
Rect buttonarea(xpos, ypos, buttonw, buttonh); |
291 |
|
if (r.overlaps(buttonarea) // This area is requested |
292 |
|| r.w == 0) // repaint whole screen |
|| r.w == 0) // repaint whole screen |
293 |
{ |
{ |
294 |
if( (i-ifirst) >= areas.size()) |
if( (i-ifirst) >= areas.size()) |
295 |
areas.push_back(Rect(xpos-10, ypos-10, imgw+20, imgh+35)); |
areas.push_back(buttonarea); |
296 |
else |
else |
297 |
areas[(i-ifirst)] = Rect(xpos-10, ypos-10, imgw+20, imgh+35); |
areas[(i-ifirst)] = buttonarea; |
|
|
|
|
// if (i == (unsigned) iselected) { |
|
|
// set_color(gc, 255,0,0); |
|
|
// Rect a=areas.back(); |
|
|
// frame(gc, a); |
|
|
// frame(gc, smaller(a,1)); |
|
|
// frame(gc, smaller(a,2)); |
|
|
// } |
|
298 |
|
|
299 |
if (i == (unsigned) iselected) { |
if (i == (unsigned) iselected) { |
300 |
// Rect imgr (xpos,ypos,imgw, imgh); |
px::TintRect (video::GetScreen(), |
301 |
Rect imgr = areas[(i-ifirst)]; |
intersect(buttonarea, r), |
|
|
|
|
px::TintRect (video::GetScreen(), intersect(imgr, r), |
|
302 |
120,120,120,120); |
120,120,120,120); |
303 |
set_color(gc, 200,200,200); |
set_color(gc, 200,200,200); |
304 |
Rect a = areas[(i-ifirst)]; |
frame(gc, buttonarea); |
|
frame(gc, a); |
|
305 |
} |
} |
306 |
|
|
307 |
info = level_pack->get_info(i); |
info = level_pack->get_info(i); |
308 |
string fname = string("levels/") + info->filename + ".png"; |
string fname = string("levels/") + info->filename + ".png"; |
309 |
Surface *img = cache.get(enigma::FindDataFile(fname)); |
Surface *img = cache.get(enigma::FindDataFile(fname)); |
310 |
if( !img && !Nozoom) { |
if( !img && !Nozoom) { |
311 |
img = LevelPreview( level_pack, i); |
img = LevelPreview (level_pack, i); |
312 |
if( img) { |
if( img) { |
313 |
fprintf(stderr,"ZOOM!\n"); |
fprintf(stderr,"ZOOM!\n"); |
314 |
img = img->zoom( imgw,imgh); |
img = img->zoom (imgw,imgh); |
315 |
} else img = 0; |
} else img = 0; |
316 |
} |
} |
|
if (img ) |
|
|
blit (gc, xpos, ypos, img); |
|
317 |
|
|
318 |
LevelStatus *ls; |
int imgx = xpos + 10; |
319 |
|
int imgy = ypos + 10; |
320 |
|
if (img) |
321 |
|
blit (gc, imgx, imgy, img); |
322 |
|
|
323 |
if ((ls=GetLevelStatus(level_pack->get_name(), |
if (LevelStatus *ls=GetLevelStatus(level_pack->get_name(), |
324 |
info->filename))) |
info->filename)) |
325 |
{ |
{ |
326 |
if (ls->finished != 0) { |
if (ls->finished != 0) { |
327 |
string image = (ls->finished & DIFFICULTY_HARD) ? |
bool hardp = ls->finished & DIFFICULTY_HARD; |
328 |
"completed" : "completed-easy"; |
blit (gc, imgx, imgy, hardp ? img_hard : img_easy); |
|
blit (gc, xpos, ypos, enigma::GetImage(image.c_str())); |
|
329 |
|
|
330 |
// Add warning sign if level has been changed since player solved it |
// Add warning sign if level has been changed since player solved it |
331 |
if (level_pack->get_modtime(i) > ls->solved_at) { |
if (level_pack->get_modtime(i) > ls->solved_at) |
332 |
blit (gc, xpos, ypos, enigma::GetImage("changed")); |
blit (gc, imgx-3, imgy-3, img_changed); |
|
} |
|
333 |
} |
} |
334 |
} |
} |
335 |
|
|
336 |
string tstr = info->name; |
string tstr = info->name; |
337 |
smallfnt->render (gc, |
smallfnt->render (gc, |
338 |
xpos+(imgw-smallfnt->get_width(tstr.c_str()))/2, |
xpos+(buttonw-smallfnt->get_width(tstr.c_str()))/2, |
339 |
ypos+imgh+1, |
ypos+10+imgh+1, |
340 |
tstr.c_str()); |
tstr.c_str()); |
341 |
} |
} |
342 |
} |
} |
387 |
LevelWidget::on_event(const SDL_Event &e) |
LevelWidget::on_event(const SDL_Event &e) |
388 |
{ |
{ |
389 |
bool h=false; |
bool h=false; |
390 |
|
|
391 |
|
bool inside_widget = get_area().contains(e.motion.x, e.motion.y); |
392 |
switch (e.type) { |
switch (e.type) { |
393 |
case SDL_MOUSEMOTION: |
case SDL_MOUSEMOTION: |
394 |
{ |
if (inside_widget) { |
395 |
int newsel=iselected; |
int newsel=iselected; |
396 |
for (unsigned i=0; i<areas.size(); ++i) |
for (unsigned i=0; i<areas.size(); ++i) |
397 |
if (areas[i].contains(e.motion.x, e.motion.y)) |
if (areas[i].contains(e.motion.x, e.motion.y)) |
399 |
newsel = ifirst+i; |
newsel = ifirst+i; |
400 |
break; |
break; |
401 |
} |
} |
402 |
set_current(newsel); |
set_current(newsel); |
403 |
h=true; |
h=true; |
404 |
} |
} |
405 |
break; |
break; |
406 |
case SDL_MOUSEBUTTONDOWN: |
case SDL_MOUSEBUTTONDOWN: |
407 |
h=handle_mousedown (&e); |
if (inside_widget) |
408 |
|
h=handle_mousedown (&e); |
409 |
break; |
break; |
410 |
case SDL_KEYDOWN: |
case SDL_KEYDOWN: |
411 |
h= handle_keydown (&e); |
h= handle_keydown (&e); |
447 |
0 |
0 |
448 |
}; |
}; |
449 |
|
|
|
|
|
|
|
|
450 |
bool |
bool |
451 |
LevelWidget::handle_keydown (const SDL_Event *e) |
LevelWidget::handle_keydown (const SDL_Event *e) |
452 |
{ |
{ |
797 |
return static_cast<video::VideoModes>(mode); |
return static_cast<video::VideoModes>(mode); |
798 |
} |
} |
799 |
void update() { |
void update() { |
800 |
string text ("Video mode: "); |
string text ("Video: "); |
801 |
text += video::GetInfo(get_mode())->name; |
text += video::GetInfo(get_mode())->name; |
802 |
set_text(text); |
set_text(text); |
803 |
} |
} |
944 |
back (new TextButton("Back", this)), |
back (new TextButton("Back", this)), |
945 |
m_nextlp (new TextButton(">", this)), |
m_nextlp (new TextButton(">", this)), |
946 |
m_prevlp (new TextButton("<", this)), |
m_prevlp (new TextButton("<", this)), |
947 |
m_lpbutton (new TextButton("Game: ", this)), |
m_lpbutton (new TextButton("Level Pack", this)), |
948 |
|
m_infobutton(new TextButton("", this)), |
949 |
|
m_levelinfo (new TextButton("", this)), |
950 |
levelwidget (new LevelWidget(lp, 4, 3)), |
levelwidget (new LevelWidget(lp, 4, 3)), |
951 |
level_pack (lp), |
level_pack (lp), |
952 |
m_ilevelpack () |
m_ilevelpack () |
953 |
{ |
{ |
954 |
const int |
const int |
955 |
BX=100, // button xsize |
BX=120, // button xsize |
956 |
BY=28, // button ysize |
BY=35, // button ysize |
957 |
SX=5, // x spacing |
SX=5, // x spacing |
958 |
SY=2, // y spacing |
SY=2, // y spacing |
959 |
OX=(BX+SX), |
OX=(BX+SX), |
960 |
OY=(BY+SY), |
OY=(BY+SY), |
961 |
RJ=(605+SX), // right justification |
RJ=(605+SX), // right justification |
962 |
Y1=15, // y position for top button row |
// Y1=15, // y position for top button row |
963 |
Y2=410; // y position for bottom button row |
Y2=430; // y position for bottom button row |
|
{ |
|
|
BuildHList hlist(this, Rect(RJ-370, Y1, BX, BY), 5); |
|
|
hlist.add (m_prevlp, 30); |
|
|
hlist.add (m_lpbutton, 300); |
|
|
hlist.add (m_nextlp, 30); |
|
|
} |
|
|
|
|
964 |
{ |
{ |
965 |
pgup = new ImageButton("ic-up", "ic-up1"); |
pgup = new ImageButton("ic-up", "ic-up1"); |
966 |
pgdown = new ImageButton("ic-down", "ic-down1"); |
pgdown = new ImageButton("ic-down", "ic-down1"); |
972 |
BuildHList hlist1(this, Rect(RJ-4*OX, Y2, BX, BY), 5); |
BuildHList hlist1(this, Rect(RJ-4*OX, Y2, BX, BY), 5); |
973 |
BuildHList hlist2(this, Rect(RJ-3*OX, Y2+OY, BX, BY), 5); |
BuildHList hlist2(this, Rect(RJ-3*OX, Y2+OY, BX, BY), 5); |
974 |
|
|
975 |
|
hlist1.add (m_lpbutton); |
976 |
hlist1.add (unsolved); |
hlist1.add (unsolved); |
977 |
hlist1.add (newgame); |
hlist1.add (newgame); |
978 |
hlist1.add (pgup); |
hlist1.add (back); |
|
hlist1.add (start); |
|
|
|
|
|
hlist2.add (back); |
|
|
hlist2.add (pgdown); |
|
|
hlist2.add (end); |
|
979 |
|
|
980 |
pgup->set_listener(this); |
pgup->set_listener(this); |
981 |
pgdown->set_listener(this); |
pgdown->set_listener(this); |
984 |
unsolved->set_listener(this); |
unsolved->set_listener(this); |
985 |
} |
} |
986 |
|
|
987 |
// Add levelwidget at the center |
{ |
988 |
add(levelwidget, Rect(10,3,600,480)); |
Rect r(10+590+10, 50,20,50); |
989 |
// add(levelwidget, Rect(10,10,600,480)); |
r.y = 50; |
990 |
|
add (pgup, r); |
991 |
|
r.y += 60; |
992 |
|
add (pgdown, r); |
993 |
|
r.y = 290; |
994 |
|
add (start, r); |
995 |
|
r.y += 60; |
996 |
|
add (end, r); |
997 |
|
} |
998 |
|
|
999 |
|
add (m_infobutton, Rect (10,10,305, 28)); |
1000 |
|
add (m_levelinfo, Rect (325,10,305,28)); |
1001 |
|
// add (levelwidget, Rect (10,50,620,350)); |
1002 |
|
add (levelwidget, Rect (10,50,590,350)); |
1003 |
levelwidget->set_listener(this); |
levelwidget->set_listener(this); |
1004 |
|
|
1005 |
set_levelpack (ilevel_pack); |
set_levelpack (ilevel_pack); |
1008 |
bool |
bool |
1009 |
LevelMenu::on_event (const SDL_Event &e) |
LevelMenu::on_event (const SDL_Event &e) |
1010 |
{ |
{ |
|
bool handled=levelwidget->on_event(e); |
|
1011 |
// Pass all events to the level widget first |
// Pass all events to the level widget first |
1012 |
|
bool handled=levelwidget->on_event(e); |
1013 |
|
|
1014 |
if (!handled) { |
if (!handled) { |
1015 |
if (e.type == SDL_MOUSEBUTTONDOWN |
if (e.type == SDL_MOUSEBUTTONDOWN |
1016 |
&& e.button.button == SDL_BUTTON_RIGHT) |
&& e.button.button == SDL_BUTTON_RIGHT) |
1018 |
Menu::quit(); |
Menu::quit(); |
1019 |
handled=true; |
handled=true; |
1020 |
} |
} |
1021 |
|
else |
1022 |
|
handled = Menu::on_event (e); |
1023 |
} |
} |
1024 |
|
else |
1025 |
|
update_info(); |
1026 |
return handled; |
return handled; |
1027 |
} |
} |
1028 |
|
|
1053 |
else if (w == m_nextlp) { |
else if (w == m_nextlp) { |
1054 |
set_levelpack (m_ilevelpack+1); |
set_levelpack (m_ilevelpack+1); |
1055 |
} |
} |
1056 |
|
update_info(); |
1057 |
|
} |
1058 |
|
|
1059 |
|
void |
1060 |
|
LevelMenu::update_info() |
1061 |
|
{ |
1062 |
|
char txt[100]; |
1063 |
|
enigma::LevelPack *lp = enigma::LevelPacks[m_ilevelpack]; |
1064 |
|
int iselected = levelwidget->selected_level(); |
1065 |
|
if (const enigma::LevelInfo *li = lp->get_info (iselected)) { |
1066 |
|
snprintf (txt, sizeof(txt), "#%d: %s", |
1067 |
|
iselected, li->name.c_str()); //, li->filename.c_str()); |
1068 |
|
m_levelinfo->set_text(txt); |
1069 |
|
} |
1070 |
} |
} |
1071 |
|
|
1072 |
void |
void |
1074 |
{ |
{ |
1075 |
if (index < enigma::LevelPacks.size()) { |
if (index < enigma::LevelPacks.size()) { |
1076 |
m_ilevelpack = index; |
m_ilevelpack = index; |
1077 |
levelwidget->change_levelpack (enigma::LevelPacks[m_ilevelpack]); |
|
1078 |
|
enigma::LevelPack *lp = enigma::LevelPacks[m_ilevelpack]; |
1079 |
|
levelwidget->change_levelpack (lp); |
1080 |
|
|
1081 |
char txt[100]; |
char txt[100]; |
1082 |
snprintf (txt, sizeof(txt), "Level pack: %s", |
snprintf (txt, sizeof(txt), "%s: %d levels", |
1083 |
enigma::LevelPacks[index]->get_name().c_str()); |
lp->get_name().c_str(), lp->size()); |
1084 |
m_lpbutton->set_text (txt); |
m_infobutton->set_text(txt); |
1085 |
|
|
1086 |
|
update_info(); |
1087 |
} |
} |
1088 |
} |
} |
1089 |
|
|