[39] | 1 | #include <math.h> |
---|
| 2 | |
---|
[2] | 3 | #include "menu.hpp" |
---|
| 4 | #include "lisp.hpp" |
---|
| 5 | #include "game.hpp" |
---|
| 6 | #include "timing.hpp" |
---|
| 7 | #include "game.hpp" |
---|
| 8 | #include "id.hpp" |
---|
| 9 | #include "pmenu.hpp" |
---|
| 10 | #include "gui.hpp" |
---|
| 11 | #include "property.hpp" |
---|
| 12 | #include "dev.hpp" |
---|
| 13 | #include "clisp.hpp" |
---|
| 14 | #include "gamma.hpp" |
---|
| 15 | #include "dprint.hpp" |
---|
| 16 | #include "demo.hpp" |
---|
| 17 | #include "loadgame.hpp" |
---|
| 18 | #include "scroller.hpp" |
---|
| 19 | #include "netcfg.hpp" |
---|
| 20 | #include "sock.hpp" |
---|
| 21 | |
---|
| 22 | extern net_protocol *prot; |
---|
| 23 | jwindow *volume_window=NULL; |
---|
| 24 | extern int confirm_quit(); |
---|
| 25 | extern int registered; |
---|
| 26 | |
---|
| 27 | //percent is 0..256 |
---|
| 28 | void tint_area(int x1, int y1, int x2, int y2, int r_to, int g_to, int b_to, int percent) |
---|
| 29 | { |
---|
| 30 | int x,y; |
---|
| 31 | short cx1,cy1,cx2,cy2; |
---|
| 32 | screen->get_clip(cx1,cy1,cx2,cy2); |
---|
| 33 | if (x1<cx1) x1=cx1; |
---|
| 34 | if (y1<cy1) y1=cy1; |
---|
| 35 | if (x2>cx2) x2=cx2; |
---|
| 36 | if (y2>cy2) y2=cy2; |
---|
| 37 | if (x2<x1 || y2<y1) return ; |
---|
| 38 | |
---|
| 39 | percent=256-percent; |
---|
| 40 | |
---|
| 41 | for (y=y1;y<=y2;y++) |
---|
| 42 | { |
---|
| 43 | unsigned char *sl=screen->scan_line(y)+x1; |
---|
| 44 | for (x=x1;x<=x2;x++,sl++) |
---|
| 45 | { |
---|
| 46 | unsigned char *paddr=(unsigned char *)pal->addr()+(*sl)*3; |
---|
| 47 | unsigned char r=((*(paddr++))-r_to)*percent/256+r_to; |
---|
| 48 | unsigned char g=((*(paddr++))-g_to)*percent/256+g_to; |
---|
| 49 | unsigned char b=((*(paddr++))-b_to)*percent/256+b_to; |
---|
| 50 | *sl=color_table->lookup_color((r)>>3,(g)>>3,(b)>>3); |
---|
| 51 | } |
---|
| 52 | } |
---|
| 53 | screen->add_dirty(x1,y1,x2,y2); |
---|
| 54 | } |
---|
| 55 | |
---|
| 56 | void darken_area(int x1, int y1, int x2, int y2, int amount) |
---|
| 57 | { |
---|
| 58 | int x,y; |
---|
| 59 | short cx1,cy1,cx2,cy2; |
---|
| 60 | screen->get_clip(cx1,cy1,cx2,cy2); |
---|
| 61 | if (x1<cx1) x1=cx1; |
---|
| 62 | if (y1<cy1) y1=cy1; |
---|
| 63 | if (x2>cx2) x2=cx2; |
---|
| 64 | if (y2>cy2) y2=cy2; |
---|
| 65 | if (x2<x1 || y2<y1) return ; |
---|
| 66 | |
---|
| 67 | for (y=y1;y<=y2;y++) |
---|
| 68 | { |
---|
| 69 | unsigned char *sl=screen->scan_line(y)+x1; |
---|
| 70 | for (x=x1;x<=x2;x++,sl++) |
---|
| 71 | { |
---|
| 72 | unsigned char *paddr=(unsigned char *)pal->addr()+(*sl)*3; |
---|
| 73 | unsigned char r=(*(paddr++))*amount/256; |
---|
| 74 | unsigned char g=(*(paddr++))*amount/256; |
---|
| 75 | unsigned char b=(*(paddr++))*amount/256; |
---|
| 76 | *sl=color_table->lookup_color((r)>>3,(g)>>3,(b)>>3); |
---|
| 77 | } |
---|
| 78 | } |
---|
| 79 | screen->add_dirty(x1,y1,x2,y2); |
---|
| 80 | } |
---|
| 81 | |
---|
| 82 | void dark_wiget(int x1, int y1, int x2, int y2, int br, int dr, int amount) |
---|
| 83 | { |
---|
| 84 | screen->add_dirty(x1,y1,x2,y2); |
---|
| 85 | screen->line(x1,y1,x1,y2,br); |
---|
| 86 | screen->line(x1+1,y1,x2,y1,br); |
---|
| 87 | screen->line(x2,y1+1,x2,y2,dr); |
---|
| 88 | screen->line(x1+1,y2,x2,y2,dr); |
---|
| 89 | darken_area(x1+1,y1+1,x2-1,y2-1,amount); |
---|
| 90 | } |
---|
| 91 | |
---|
| 92 | char *men_str(void *arg) |
---|
| 93 | { |
---|
| 94 | switch (item_type(arg)) |
---|
| 95 | { |
---|
| 96 | case L_STRING : |
---|
| 97 | { return lstring_value(arg); } break; |
---|
| 98 | case L_CONS_CELL : |
---|
| 99 | { return lstring_value(CAR(arg)); } break; |
---|
| 100 | default : |
---|
| 101 | { |
---|
| 102 | lprint(arg); |
---|
| 103 | printf(" is not a valid menu option\n"); |
---|
| 104 | exit(0); |
---|
| 105 | } |
---|
| 106 | } |
---|
| 107 | return NULL; |
---|
| 108 | } |
---|
| 109 | |
---|
| 110 | void main_menu(); |
---|
| 111 | |
---|
| 112 | int menu(void *args, JCFont *font) // reurns -1 on esc |
---|
| 113 | { |
---|
| 114 | main_menu(); |
---|
| 115 | char *title=NULL; |
---|
| 116 | if (!NILP(CAR(args))) |
---|
| 117 | title=lstring_value(CAR(args)); |
---|
| 118 | Cell *def=lcar(lcdr(lcdr(args))); |
---|
| 119 | args=CAR(CDR(args)); |
---|
| 120 | |
---|
| 121 | int options=list_length(args); |
---|
| 122 | int mh=(font->height()+1)*options+10,maxw=0; |
---|
| 123 | |
---|
| 124 | Cell *c=(Cell *)args; |
---|
| 125 | for (;!NILP(c);c=CDR(c)) |
---|
| 126 | { |
---|
| 127 | if( strlen(men_str(CAR(c))) > (unsigned)maxw) |
---|
| 128 | maxw = strlen(men_str(CAR(c))); |
---|
| 129 | } |
---|
| 130 | |
---|
| 131 | int mw=(font->width())*maxw+20; |
---|
| 132 | int mx=screen->width()/2-mw/2, |
---|
| 133 | my=screen->height()/2-mh/2; |
---|
| 134 | |
---|
| 135 | |
---|
| 136 | screen->add_dirty(mx,my,mx+mw-1,my+mh-1); |
---|
| 137 | |
---|
| 138 | if (title) |
---|
| 139 | { |
---|
| 140 | int tl=strlen(title)*font->width(); |
---|
| 141 | int tx=screen->width()/2-tl/2; |
---|
| 142 | dark_wiget(tx-2,my-font->height()-4,tx+tl+2,my-2,eh->medium_color(),eh->dark_color(),180); |
---|
| 143 | font->put_string(screen,tx+1,my-font->height()-2,title,eh->bright_color()); |
---|
| 144 | } |
---|
| 145 | |
---|
| 146 | dark_wiget(mx,my,mx+mw-1,my+mh-1,eh->medium_color(),eh->dark_color(),200); |
---|
| 147 | |
---|
| 148 | |
---|
| 149 | int y=my+5; |
---|
| 150 | for (c=(Cell *)args;!NILP(c);c=CDR(c)) |
---|
| 151 | { |
---|
| 152 | char *ms=men_str(CAR(c)); |
---|
| 153 | font->put_string(screen,mx+10+1,y+1,ms,eh->black()); |
---|
| 154 | font->put_string(screen,mx+10,y,ms,eh->bright_color()); |
---|
| 155 | y+=font->height()+1; |
---|
| 156 | } |
---|
| 157 | |
---|
| 158 | eh->flush_screen(); |
---|
| 159 | event ev; |
---|
| 160 | int choice=0,done=0; |
---|
| 161 | int bh=font->height()+3; |
---|
| 162 | image *save=new image(mw-2,bh); |
---|
| 163 | int color=128,cdir=50; |
---|
| 164 | |
---|
| 165 | time_marker *last_color_time=NULL; |
---|
| 166 | if (!NILP(def)) |
---|
| 167 | choice=lnumber_value(def); |
---|
| 168 | do |
---|
| 169 | { |
---|
| 170 | eh->flush_screen(); |
---|
| 171 | if (eh->event_waiting()) |
---|
| 172 | { |
---|
| 173 | eh->get_event(ev); |
---|
| 174 | if (ev.type==EV_KEY) |
---|
| 175 | { |
---|
| 176 | switch (ev.key) |
---|
| 177 | { |
---|
| 178 | case JK_ESC : |
---|
| 179 | { choice=-1; done=1; } break; |
---|
| 180 | case JK_ENTER : |
---|
| 181 | { done=1; } break; |
---|
| 182 | case JK_DOWN : |
---|
| 183 | { if (choice<options-1) |
---|
| 184 | choice++; |
---|
| 185 | else choice=0; |
---|
| 186 | } break; |
---|
| 187 | case JK_UP : |
---|
| 188 | { |
---|
| 189 | if (choice>0) |
---|
| 190 | choice--; |
---|
| 191 | else choice=options-1; |
---|
| 192 | } break; |
---|
| 193 | } |
---|
| 194 | } else if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button) |
---|
| 195 | { |
---|
| 196 | if (ev.mouse_move.x>mx && ev.mouse_move.x<mx+mw && ev.mouse_move.y>my && |
---|
| 197 | ev.mouse_move.y<my+mh) |
---|
| 198 | { |
---|
| 199 | int msel=(ev.mouse_move.y-my)/(font->height()+1); |
---|
| 200 | if (msel>=options) msel=options-1; |
---|
| 201 | if (msel==choice) // clicked on already selected item, return it |
---|
| 202 | done=1; |
---|
| 203 | else choice=msel; // selects an item |
---|
| 204 | } |
---|
| 205 | } |
---|
| 206 | } |
---|
| 207 | |
---|
| 208 | time_marker cur_time; |
---|
| 209 | if (!last_color_time || (int)(cur_time.diff_time(last_color_time)*1000)>120) |
---|
| 210 | { |
---|
| 211 | if (last_color_time) |
---|
| 212 | delete last_color_time; |
---|
| 213 | last_color_time=new time_marker; |
---|
| 214 | |
---|
| 215 | int by1=(font->height()+1)*choice+my+5-2; |
---|
| 216 | int by2=by1+bh-1; |
---|
| 217 | |
---|
| 218 | screen->put_part(save,0,0,mx+1,by1,mx+mw-2,by2); |
---|
| 219 | tint_area(mx+1,by1,mx+mw-2,by2,63,63,63,color); |
---|
| 220 | |
---|
| 221 | char *cur=men_str(nth(choice,args)); |
---|
| 222 | font->put_string(screen,mx+10+1,by1+3,cur,eh->black()); |
---|
| 223 | font->put_string(screen,mx+10,by1+2,cur,eh->bright_color()); |
---|
| 224 | screen->rectangle(mx+1,by1,mx+mw-2,by2,eh->bright_color()); |
---|
| 225 | |
---|
| 226 | color+=cdir; |
---|
| 227 | |
---|
| 228 | if (color<12 || color>256) |
---|
| 229 | { |
---|
| 230 | cdir=-cdir; |
---|
| 231 | color+=cdir; |
---|
| 232 | } |
---|
| 233 | eh->flush_screen(); |
---|
| 234 | save->put_image(screen,mx+1,by1); |
---|
| 235 | } else milli_wait(10); |
---|
| 236 | |
---|
| 237 | } while (!done); |
---|
| 238 | if (last_color_time) |
---|
| 239 | delete last_color_time; |
---|
| 240 | delete save; |
---|
| 241 | the_game->draw(the_game->state==SCENE_STATE); |
---|
| 242 | |
---|
| 243 | if (choice!=-1) |
---|
| 244 | { |
---|
| 245 | void *val=nth(choice,args); |
---|
| 246 | if (item_type(val)==L_CONS_CELL) // is there another value that the user want us to return? |
---|
| 247 | return lnumber_value(lcdr(val)); |
---|
| 248 | } |
---|
| 249 | return choice; |
---|
| 250 | } |
---|
| 251 | |
---|
| 252 | |
---|
| 253 | static void draw_vol(image *screen, int x1, int y1, int x2, int y2, int t, int max, int c1, int c2, int slider) |
---|
| 254 | { |
---|
| 255 | int dx=x1+t*(x2-x1)/max; |
---|
| 256 | if (t!=0) |
---|
| 257 | { |
---|
| 258 | cash.img(slider)->put_image(screen,x1,y1); |
---|
| 259 | // screen->bar(x1,y1,dx,y2,c1); |
---|
| 260 | } |
---|
| 261 | else dx--; |
---|
| 262 | |
---|
| 263 | if (dx<x2) |
---|
| 264 | screen->bar(dx+1,y1,x2,y2,c2); |
---|
| 265 | } |
---|
| 266 | |
---|
| 267 | static void draw_sfx_vol(int slider) |
---|
| 268 | { |
---|
| 269 | draw_vol(volume_window->screen,6,16,34,22,sfx_volume,127,pal->find_closest(200,75,19), |
---|
| 270 | pal->find_closest(40,0,0),slider); |
---|
| 271 | } |
---|
| 272 | |
---|
| 273 | static void draw_music_vol(int slider) |
---|
| 274 | { |
---|
| 275 | draw_vol(volume_window->screen,6,61,34,67,music_volume,127,pal->find_closest(255,0,0), |
---|
| 276 | pal->find_closest(40,0,0),slider); |
---|
| 277 | } |
---|
| 278 | |
---|
| 279 | static void create_volume_window() |
---|
| 280 | { |
---|
| 281 | /* int vx=WINDOW_FRAME_LEFT,vy=WINDOW_FRAME_TOP+eh->font()->height()*2,scroller_height=130,bh=eh->font()->height()+5; |
---|
| 282 | |
---|
| 283 | volume_window=eh->new_window(prop->getd("volume_x",xres/2-20), |
---|
| 284 | prop->getd("volume_y",yres/2-50), |
---|
| 285 | -1, |
---|
| 286 | -1, |
---|
| 287 | new scroller(vx,vy,LOWER_SFX,0,scroller_height,0,127, |
---|
| 288 | new scroller(vx+30,vy,LOWER_MUSIC,0,scroller_height,0,127,NULL)),symbol_str("VOLUME")); |
---|
| 289 | event ev; |
---|
| 290 | int done=0; |
---|
| 291 | do |
---|
| 292 | { |
---|
| 293 | eh->flush_screen(); |
---|
| 294 | eh->get_event(ev); |
---|
| 295 | if (ev.type==EV_CLOSE_WINDOW && ev.window==volume_window) done=1; |
---|
| 296 | } while (!done); |
---|
| 297 | eh->close_window(volume_window); |
---|
| 298 | volume_window=NULL; */ |
---|
| 299 | |
---|
| 300 | |
---|
[39] | 301 | char const *ff = "art/frame.spe"; |
---|
[2] | 302 | int t=SPEC_IMAGE; |
---|
| 303 | int u_u=cash.reg(ff,"u_u",t,1), |
---|
| 304 | u_d=cash.reg(ff,"u_u",t,1), |
---|
| 305 | u_ua=cash.reg(ff,"u_ua",t,1), |
---|
| 306 | u_da=cash.reg(ff,"u_da",t,1), |
---|
| 307 | |
---|
| 308 | d_u=cash.reg(ff,"d_u",t,1), |
---|
| 309 | d_d=cash.reg(ff,"d_u",t,1), |
---|
| 310 | d_ua=cash.reg(ff,"d_ua",t,1), |
---|
| 311 | d_da=cash.reg(ff,"d_da",t,1), |
---|
| 312 | slider=cash.reg(ff,"volume_slide",t,1); |
---|
| 313 | |
---|
| 314 | volume_window=eh->new_window(prop->getd("volume_x",xres/2-20), |
---|
| 315 | prop->getd("volume_y",yres/2-50), |
---|
| 316 | 41-WINDOW_FRAME_LEFT-WINDOW_FRAME_RIGHT-2, |
---|
| 317 | 101-WINDOW_FRAME_TOP-WINDOW_FRAME_BOTTOM, |
---|
| 318 | new ico_button(10,27,ID_SFX_DOWN,d_u,d_d,d_ua,d_da, |
---|
| 319 | new ico_button(21,27,ID_SFX_UP,u_u,u_d,u_ua,u_da, |
---|
| 320 | new info_field(15,42,0,symbol_str("SFXv"), |
---|
| 321 | |
---|
| 322 | new ico_button(10,72,ID_MUSIC_DOWN,d_u,d_d,d_ua,d_da, |
---|
| 323 | new ico_button(21,72,ID_MUSIC_UP,u_u,u_d,u_ua,u_da, |
---|
| 324 | new info_field(10,86,0,symbol_str("MUSICv"), |
---|
| 325 | NULL))))))); |
---|
| 326 | |
---|
| 327 | cash.img(cash.reg(ff,"vcontrol",t,1))->put_image(volume_window->screen,0,0); |
---|
| 328 | draw_music_vol(slider); |
---|
| 329 | draw_sfx_vol(slider); |
---|
| 330 | volume_window->inm->redraw(); |
---|
| 331 | eh->grab_focus(volume_window); |
---|
| 332 | eh->flush_screen(); |
---|
| 333 | |
---|
| 334 | volume_window->inm->allow_no_selections(); |
---|
| 335 | volume_window->inm->clear_current(); |
---|
| 336 | |
---|
| 337 | event ev; |
---|
| 338 | do |
---|
| 339 | { |
---|
| 340 | do { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting()); |
---|
| 341 | eh->flush_screen(); |
---|
| 342 | if (ev.type==EV_MESSAGE) |
---|
| 343 | { |
---|
| 344 | switch (ev.message.id) |
---|
| 345 | { |
---|
| 346 | case ID_SFX_UP : |
---|
| 347 | { if (volume_window) |
---|
| 348 | { |
---|
| 349 | sfx_volume+=16; |
---|
| 350 | if (sfx_volume>127) sfx_volume=127; |
---|
| 351 | draw_sfx_vol(slider); |
---|
[39] | 352 | char const *s = "sfx/ambtech1.wav"; |
---|
[2] | 353 | if (sound_avail&SFX_INITIALIZED) |
---|
| 354 | cash.sfx(cash.reg(s,s,SPEC_EXTERN_SFX,1))->play(sfx_volume); |
---|
| 355 | } |
---|
| 356 | } break; |
---|
| 357 | case ID_SFX_DOWN : |
---|
| 358 | { if (volume_window) |
---|
| 359 | { |
---|
| 360 | sfx_volume-=16; |
---|
| 361 | if (sfx_volume<0) sfx_volume=0; |
---|
| 362 | draw_sfx_vol(slider); |
---|
[39] | 363 | char const *s = "sfx/ambtech1.wav"; |
---|
[2] | 364 | if (sound_avail&SFX_INITIALIZED) |
---|
| 365 | cash.sfx(cash.reg(s,s,SPEC_EXTERN_SFX,1))->play(sfx_volume); |
---|
| 366 | } |
---|
| 367 | } break; |
---|
| 368 | |
---|
| 369 | case ID_MUSIC_UP : |
---|
| 370 | { if (volume_window) |
---|
| 371 | { |
---|
| 372 | music_volume+=16; |
---|
| 373 | if (music_volume>127) music_volume=127; |
---|
| 374 | draw_music_vol(slider); |
---|
| 375 | if (current_song) current_song->set_volume(music_volume); |
---|
| 376 | } |
---|
| 377 | } break; |
---|
| 378 | case ID_MUSIC_DOWN : |
---|
| 379 | { if (volume_window) |
---|
| 380 | { |
---|
| 381 | music_volume-=16; |
---|
| 382 | if (music_volume<0) music_volume=0; |
---|
| 383 | draw_music_vol(slider); |
---|
| 384 | if (current_song) current_song->set_volume(music_volume); |
---|
| 385 | } |
---|
| 386 | } break; |
---|
| 387 | } |
---|
| 388 | } else if (ev.type==EV_CLOSE_WINDOW || (ev.type==EV_KEY && ev.key==JK_ESC)) |
---|
| 389 | { |
---|
| 390 | eh->close_window(volume_window); |
---|
| 391 | volume_window=NULL; |
---|
| 392 | } |
---|
| 393 | } while (volume_window); |
---|
| 394 | } |
---|
| 395 | |
---|
| 396 | |
---|
| 397 | void save_difficulty() |
---|
| 398 | { |
---|
| 399 | FILE *fp=open_FILE("hardness.lsp","wb"); |
---|
| 400 | if (!fp) |
---|
| 401 | dprintf("Unable to write to file hardness.lsp\n"); |
---|
| 402 | else |
---|
| 403 | { |
---|
| 404 | fprintf(fp,"(setf difficulty '"); |
---|
| 405 | if (DEFINEDP(symbol_value(l_difficulty))) |
---|
| 406 | { |
---|
| 407 | if (symbol_value(l_difficulty)==l_extreme) |
---|
| 408 | fprintf(fp,"extreme)\n"); |
---|
| 409 | else if (symbol_value(l_difficulty)==l_hard) |
---|
| 410 | fprintf(fp,"hard)\n"); |
---|
| 411 | else if (symbol_value(l_difficulty)==l_easy) |
---|
| 412 | fprintf(fp,"easy)\n"); |
---|
| 413 | else |
---|
| 414 | fprintf(fp,"medium)\n"); |
---|
| 415 | } else |
---|
| 416 | fprintf(fp,"medium)\n"); |
---|
| 417 | fclose(fp); |
---|
| 418 | } |
---|
| 419 | } |
---|
| 420 | |
---|
| 421 | void fade_out(int steps); |
---|
| 422 | void fade_in(image *im, int steps); |
---|
| 423 | |
---|
| 424 | |
---|
| 425 | void show_sell(int abortable) |
---|
| 426 | { |
---|
| 427 | void *ss=make_find_symbol("sell_screens"); |
---|
| 428 | if (!DEFINEDP(symbol_value(ss))) |
---|
| 429 | { |
---|
| 430 | int sp=current_space; |
---|
| 431 | current_space=PERM_SPACE; |
---|
| 432 | // char *prog="((\"art/help.spe\" . \"sell2\")(\"art/help.spe\" . \"sell4\")(\"art/help.spe\" . \"sell3\")(\"art/endgame.spe\" . \"credit\"))"; |
---|
| 433 | // char *prog="((\"art/endgame.spe\" . \"credit\") (\"art/help.spe\" . \"sell6\"))"; |
---|
[39] | 434 | char const *prog="((\"art/endgame.spe\" . \"credit\"))"; |
---|
[2] | 435 | set_symbol_value(ss,compile(prog)); |
---|
| 436 | current_space=sp; |
---|
| 437 | } |
---|
| 438 | |
---|
| 439 | if (DEFINEDP(symbol_value(ss))) |
---|
| 440 | { |
---|
| 441 | image blank(2,2); blank.clear(); |
---|
| 442 | eh->set_mouse_shape(blank.copy(),0,0); // don't show mouse |
---|
| 443 | |
---|
| 444 | ss=symbol_value(ss); |
---|
| 445 | int quit=0; |
---|
| 446 | while (ss && !quit) |
---|
| 447 | { |
---|
| 448 | int im=cash.reg_object("art/help.spe",CAR(ss),SPEC_IMAGE,1); |
---|
| 449 | fade_in(cash.img(im),16); |
---|
| 450 | |
---|
| 451 | event ev; |
---|
| 452 | do |
---|
| 453 | { eh->flush_screen(); |
---|
| 454 | eh->get_event(ev); |
---|
| 455 | } while (ev.type!=EV_KEY); |
---|
| 456 | if (ev.key==JK_ESC && abortable) |
---|
| 457 | quit=1; |
---|
| 458 | fade_out(16); |
---|
| 459 | ss=CDR(ss); |
---|
| 460 | } |
---|
| 461 | eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1); |
---|
| 462 | } |
---|
| 463 | } |
---|
| 464 | |
---|
| 465 | |
---|
| 466 | void menu_handler(event &ev, input_manager *inm) |
---|
| 467 | { |
---|
| 468 | switch (ev.type) |
---|
| 469 | { |
---|
| 470 | case EV_MESSAGE : |
---|
| 471 | { |
---|
| 472 | switch (ev.message.id) |
---|
| 473 | { |
---|
| 474 | case ID_LIGHT_OFF : |
---|
| 475 | if (!volume_window) |
---|
| 476 | { |
---|
| 477 | gamma_correct(pal,1); |
---|
| 478 | } break; |
---|
| 479 | case ID_RETURN : |
---|
| 480 | if (!volume_window) |
---|
| 481 | { |
---|
| 482 | the_game->set_state(RUN_STATE); |
---|
| 483 | } break; |
---|
| 484 | case ID_START_GAME : |
---|
| 485 | if (!volume_window) |
---|
| 486 | { |
---|
| 487 | the_game->load_level(level_file); |
---|
| 488 | the_game->set_state(RUN_STATE); |
---|
| 489 | view *v; |
---|
| 490 | for (v=player_list;v;v=v->next) |
---|
| 491 | if (v->focus) |
---|
| 492 | v->reset_player(); |
---|
| 493 | |
---|
| 494 | } break; |
---|
| 495 | |
---|
| 496 | |
---|
| 497 | case ID_LOAD_PLAYER_GAME : |
---|
| 498 | if (!volume_window) |
---|
| 499 | { |
---|
| 500 | int got_level=load_game(0,symbol_str("LOAD")); |
---|
| 501 | the_game->reset_keymap(); |
---|
| 502 | if (got_level) |
---|
| 503 | { |
---|
| 504 | char name[255]; |
---|
| 505 | sprintf(name,"%ssave%04d.spe", get_save_filename_prefix(), got_level); |
---|
| 506 | |
---|
| 507 | the_game->load_level(name); |
---|
| 508 | the_game->set_state(RUN_STATE); |
---|
| 509 | } |
---|
| 510 | } break; |
---|
| 511 | |
---|
| 512 | |
---|
| 513 | case ID_VOLUME : |
---|
| 514 | if (!volume_window) |
---|
| 515 | { create_volume_window(); } break; |
---|
| 516 | |
---|
| 517 | case ID_MEDIUM : |
---|
| 518 | { |
---|
| 519 | set_symbol_value(l_difficulty,l_medium); |
---|
| 520 | save_difficulty(); |
---|
| 521 | } break; |
---|
| 522 | case ID_HARD : |
---|
| 523 | { |
---|
| 524 | set_symbol_value(l_difficulty,l_hard); |
---|
| 525 | save_difficulty(); |
---|
| 526 | } break; |
---|
| 527 | case ID_EXTREME : |
---|
| 528 | { |
---|
| 529 | set_symbol_value(l_difficulty,l_extreme); |
---|
| 530 | save_difficulty(); |
---|
| 531 | } break; |
---|
| 532 | case ID_EASY : |
---|
| 533 | { |
---|
| 534 | set_symbol_value(l_difficulty,l_easy); |
---|
| 535 | save_difficulty(); |
---|
| 536 | } break; |
---|
| 537 | |
---|
| 538 | case ID_NETWORKING : |
---|
| 539 | { |
---|
| 540 | if (!volume_window) |
---|
| 541 | { |
---|
| 542 | net_configuration *cfg=new net_configuration; |
---|
| 543 | if (cfg->input()) |
---|
| 544 | { |
---|
| 545 | if (main_net_cfg) delete main_net_cfg; |
---|
| 546 | main_net_cfg=cfg; |
---|
| 547 | } else delete cfg; |
---|
| 548 | the_game->draw(0); |
---|
| 549 | inm->redraw(); |
---|
| 550 | } |
---|
| 551 | } break; |
---|
| 552 | |
---|
| 553 | case ID_SHOW_SELL : |
---|
| 554 | if (!volume_window) |
---|
| 555 | { |
---|
| 556 | show_sell(1); |
---|
| 557 | screen->clear(); |
---|
| 558 | if (title_screen>=0) |
---|
| 559 | { |
---|
| 560 | image *tit=cash.img(title_screen); |
---|
| 561 | tit->put_image(screen,screen->width()/2-tit->width()/2, |
---|
| 562 | screen->height()/2-tit->height()/2); |
---|
| 563 | } |
---|
| 564 | inm->redraw(); |
---|
| 565 | fade_in(NULL,8); |
---|
| 566 | eh->flush_screen(); |
---|
| 567 | |
---|
| 568 | } break; |
---|
| 569 | } break; |
---|
| 570 | } break; |
---|
| 571 | case EV_CLOSE_WINDOW : |
---|
| 572 | { |
---|
| 573 | if (ev.window==volume_window) |
---|
| 574 | { eh->close_window(volume_window); volume_window=NULL; } |
---|
| 575 | } break; |
---|
| 576 | } |
---|
| 577 | } |
---|
| 578 | |
---|
| 579 | void *current_demo=NULL; |
---|
| 580 | |
---|
[39] | 581 | static ico_button *load_icon(int num, int id, int x, int y, int &h, ifield *next, char const *key) |
---|
[2] | 582 | { |
---|
| 583 | char name[20]; |
---|
[39] | 584 | char const *base = "newi"; |
---|
[2] | 585 | int a,b,c; |
---|
| 586 | sprintf(name,"%s%04d.pcx",base,num*3+1); |
---|
| 587 | a=cash.reg("art/icons.spe",name,SPEC_IMAGE,1); |
---|
| 588 | |
---|
| 589 | sprintf(name,"%s%04d.pcx",base,num*3+2); |
---|
| 590 | b=cash.reg("art/icons.spe",name,SPEC_IMAGE,1); |
---|
| 591 | |
---|
| 592 | sprintf(name,"%s%04d.pcx",base,num*3+3); |
---|
| 593 | c=cash.reg("art/icons.spe",name,SPEC_IMAGE,1); |
---|
| 594 | |
---|
| 595 | h=cash.img(a)->height(); |
---|
| 596 | |
---|
| 597 | return new ico_button(x,y,id,b,b,a,c,next,-1,key); |
---|
| 598 | } |
---|
| 599 | |
---|
| 600 | ico_button *make_default_buttons(int x,int &y, ico_button *append_list) |
---|
| 601 | { |
---|
| 602 | int h; |
---|
| 603 | int diff_on; |
---|
| 604 | |
---|
| 605 | if (DEFINEDP(symbol_value(l_difficulty))) |
---|
| 606 | { |
---|
| 607 | if (symbol_value(l_difficulty)==l_extreme) |
---|
| 608 | diff_on=3; |
---|
| 609 | else if (symbol_value(l_difficulty)==l_hard) |
---|
| 610 | diff_on=2; |
---|
| 611 | else if (symbol_value(l_difficulty)==l_easy) |
---|
| 612 | diff_on=0; |
---|
| 613 | else |
---|
| 614 | diff_on=1; |
---|
| 615 | } else diff_on=3; |
---|
| 616 | |
---|
| 617 | |
---|
| 618 | ico_button *start=load_icon(0,ID_START_GAME,x,y,h,NULL,"ic_start"); y+=h; |
---|
| 619 | |
---|
| 620 | ico_switch_button *set=NULL; |
---|
| 621 | if (!main_net_cfg || (main_net_cfg->state!=net_configuration::SERVER && main_net_cfg->state!=net_configuration::CLIENT)) |
---|
| 622 | { |
---|
| 623 | set=new ico_switch_button(x,y,ID_NULL,diff_on, |
---|
| 624 | load_icon(3,ID_EASY,x,y,h, |
---|
| 625 | load_icon(8,ID_MEDIUM,x,y,h, |
---|
| 626 | load_icon(9,ID_HARD,x,y,h, |
---|
| 627 | load_icon(10,ID_EXTREME,x,y,h,NULL,"ic_extreme"), |
---|
| 628 | "ic_hard"),"ic_medium"),"ic_easy"),NULL); y+=h; |
---|
| 629 | |
---|
| 630 | } |
---|
| 631 | |
---|
| 632 | ico_button *color=load_icon(4,ID_LIGHT_OFF,x,y,h,NULL,"ic_gamma"); y+=h; |
---|
| 633 | ico_button *volume=load_icon(5,ID_VOLUME,x,y,h,NULL,"ic_volume"); y+=h; |
---|
| 634 | ico_button *sell=NULL; |
---|
| 635 | |
---|
| 636 | if (registered && prot) |
---|
| 637 | { |
---|
| 638 | sell=load_icon(11,ID_NETWORKING,x,y,h,NULL,"ic_networking"); |
---|
| 639 | y+=h; |
---|
| 640 | } else |
---|
| 641 | { |
---|
| 642 | sell=load_icon(2,ID_SHOW_SELL,x,y,h,NULL,"ic_sell"); |
---|
| 643 | y+=h; |
---|
| 644 | } |
---|
| 645 | ico_button *quit=load_icon(6,ID_QUIT,x,y,h,NULL,"ic_quit"); y+=h; |
---|
| 646 | |
---|
| 647 | if (set) |
---|
| 648 | { |
---|
| 649 | start->next=set; |
---|
| 650 | set->next=color; |
---|
| 651 | } |
---|
| 652 | else start->next=color; |
---|
| 653 | |
---|
| 654 | |
---|
| 655 | color->next=volume; |
---|
| 656 | if (sell) |
---|
| 657 | { |
---|
| 658 | volume->next=sell; |
---|
| 659 | sell->next=quit; |
---|
| 660 | } else volume->next=quit; |
---|
| 661 | |
---|
| 662 | ico_button *list=append_list; |
---|
| 663 | |
---|
| 664 | if (append_list) |
---|
| 665 | { |
---|
| 666 | while (append_list->next) |
---|
| 667 | append_list=(ico_button *)append_list->next; |
---|
| 668 | append_list->next=start; |
---|
| 669 | } else list=start; |
---|
| 670 | |
---|
| 671 | return list; |
---|
| 672 | } |
---|
| 673 | |
---|
| 674 | |
---|
| 675 | ico_button *make_conditional_buttons(int x,int &y) |
---|
| 676 | { |
---|
| 677 | ico_button *start_list=NULL; |
---|
| 678 | int h; |
---|
| 679 | if (current_level) // should we include a return icon? |
---|
| 680 | { |
---|
| 681 | start_list=load_icon(7,ID_RETURN,x,y,h,NULL,"ic_return"); y+=h; |
---|
| 682 | } |
---|
| 683 | |
---|
| 684 | |
---|
| 685 | ico_button *load; |
---|
| 686 | if (show_load_icon()) |
---|
| 687 | { load= load_icon(1,ID_LOAD_PLAYER_GAME,x,y,h,NULL,"ic_load"); y+=h;} |
---|
| 688 | else load=NULL; |
---|
| 689 | |
---|
| 690 | if (start_list) start_list->next=load; |
---|
| 691 | else start_list=load; |
---|
| 692 | |
---|
| 693 | return start_list; |
---|
| 694 | } |
---|
| 695 | |
---|
| 696 | void main_menu() |
---|
| 697 | { |
---|
| 698 | int y=yres/2-100; |
---|
| 699 | ico_button *list=make_conditional_buttons(xres-33,y); |
---|
| 700 | list=make_default_buttons(xres-33,y,list); |
---|
| 701 | |
---|
| 702 | input_manager *inm=new input_manager(screen,eh,list); |
---|
| 703 | inm->allow_no_selections(); |
---|
| 704 | inm->clear_current(); |
---|
| 705 | |
---|
| 706 | screen->add_dirty(0,0,319,199); |
---|
| 707 | |
---|
| 708 | event ev; |
---|
| 709 | |
---|
| 710 | int stop_menu=0; |
---|
| 711 | time_marker start; |
---|
| 712 | eh->flush_screen(); |
---|
| 713 | do |
---|
| 714 | { |
---|
| 715 | time_marker new_time; |
---|
| 716 | |
---|
| 717 | if (eh->event_waiting()) |
---|
| 718 | { |
---|
| 719 | do |
---|
| 720 | { |
---|
| 721 | eh->get_event(ev); |
---|
| 722 | } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting()); |
---|
| 723 | inm->handle_event(ev,NULL,eh); |
---|
| 724 | if (ev.type==EV_KEY && ev.key==JK_ESC) |
---|
| 725 | eh->push_event(new event(ID_QUIT,NULL)); |
---|
| 726 | |
---|
| 727 | menu_handler(ev,inm); |
---|
| 728 | start.get_time(); |
---|
| 729 | |
---|
| 730 | eh->flush_screen(); |
---|
| 731 | } |
---|
| 732 | else |
---|
| 733 | { |
---|
| 734 | // ECS - Added so that main menu doesn't grab 100% of CPU |
---|
| 735 | milli_wait(30); |
---|
| 736 | } |
---|
| 737 | |
---|
| 738 | if (new_time.diff_time(&start)>10) |
---|
| 739 | { |
---|
| 740 | if (volume_window) |
---|
| 741 | start.get_time(); |
---|
| 742 | else |
---|
| 743 | { |
---|
| 744 | if (!current_demo) |
---|
| 745 | { |
---|
| 746 | void *d=make_find_symbol("demos"); |
---|
| 747 | if (DEFINEDP(symbol_value(d))) |
---|
| 748 | current_demo=symbol_value(d); |
---|
| 749 | } |
---|
| 750 | if (current_demo) |
---|
| 751 | { |
---|
| 752 | demo_man.set_state(demo_manager::PLAYING,lstring_value(CAR(current_demo))); |
---|
| 753 | stop_menu=1; |
---|
| 754 | current_demo=CDR(current_demo); |
---|
| 755 | } |
---|
| 756 | } |
---|
| 757 | } |
---|
| 758 | |
---|
| 759 | if (volume_window) stop_menu=0; // can't exit with volume window open |
---|
| 760 | else if (main_net_cfg && main_net_cfg->restart_state()) stop_menu=1; |
---|
| 761 | else if (the_game->state==RUN_STATE) stop_menu=1; |
---|
| 762 | else if (ev.type==EV_MESSAGE) |
---|
| 763 | { |
---|
| 764 | if (ev.message.id==ID_START_GAME || ev.message.id==ID_RETURN) |
---|
| 765 | stop_menu=1; |
---|
| 766 | else if (ev.message.id==ID_QUIT) |
---|
| 767 | { |
---|
| 768 | if (confirm_quit()) |
---|
| 769 | stop_menu=1; |
---|
| 770 | else |
---|
| 771 | { |
---|
| 772 | ev.type=EV_SPURIOUS; |
---|
| 773 | start.get_time(); |
---|
| 774 | } |
---|
| 775 | } |
---|
| 776 | } |
---|
| 777 | } while (!stop_menu); |
---|
| 778 | |
---|
| 779 | delete inm; |
---|
| 780 | |
---|
| 781 | if (ev.type==EV_MESSAGE && ev.message.id==ID_QUIT) // propogate the quit message |
---|
| 782 | the_game->end_session(); |
---|
| 783 | } |
---|
| 784 | |
---|
| 785 | |
---|