source: abuse/trunk/src/netcfg.cpp @ 32

Last change on this file since 32 was 17, checked in by Sam Hocevar, 17 years ago
  • absolute shitloads of 64 bit fixes.
File size: 16.3 KB
Line 
1#include "netcfg.hpp"
2#include "input.hpp"
3#include "cache.hpp"
4#include "sock.hpp"
5#include "timing.hpp"
6#include "light.hpp"
7
8extern char *get_login();
9extern window_manager *eh;
10net_configuration *main_net_cfg=NULL;
11extern char lsf[256];
12char *symbol_str(char *name);
13
14extern net_protocol *prot;
15
16net_configuration::net_configuration()
17{
18  strcpy(name,get_login());
19
20  strcpy(server_name,"My Netgame");
21
22
23  min_players=2;
24  max_players=8;
25  kills=25;
26  port=20202;
27  server_port=20202;
28  state=SINGLE_PLAYER;
29}
30
31
32extern char game_name[50];
33
34enum { NET_OK=1, NET_CANCEL, NET_SERVER_NAME, NET_NAME, NET_PORT, NET_SERVER_PORT, NET_MAX, NET_MIN, NET_KILLS, CFG_ERR_OK, NET_SERVER,
35       NET_CLIENT, NET_SINGLE, NET_GAME=400,  MIN_1,MIN_2,MIN_3,MIN_4,MIN_5,MIN_6,MIN_7,MIN_8,   MAX_2,MAX_3,MAX_4,MAX_5,MAX_6,MAX_7,MAX_8,
36       LVL_2,LVL_4,LVL_8,LEVEL_BOX } ;
37
38
39void net_configuration::cfg_error(char *msg)
40{
41  jwindow *j=eh->new_window(-1,0,-1,-1,new info_field(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,0,msg,
42      new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+30,CFG_ERR_OK,symbol_str("ok_button"),NULL)),symbol_str("input_error"));
43  event ev;
44  do
45  {
46    eh->flush_screen();
47    do { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting());
48  } while (ev.type!=EV_MESSAGE || ev.message.id!=CFG_ERR_OK || ev.type==EV_CLOSE_WINDOW || (ev.type==EV_KEY && ev.key==JK_ESC));
49  eh->close_window(j);
50  eh->flush_screen();
51}
52
53int net_configuration::restart_state()
54{
55  switch (state)
56  {
57    case RESTART_SERVER :
58    case RESTART_CLIENT :
59    case RESTART_SINGLE :
60      return 1;
61    default:
62      break;
63  }
64  return 0;
65}
66
67int net_configuration::notify_reset()
68{
69  switch (state)
70  {
71    case RESTART_SERVER : { state=SERVER; } break;
72    case RESTART_CLIENT : { state=CLIENT; } break;
73    case RESTART_SINGLE : { state=SINGLE_PLAYER; } break;
74    default: break;
75  }
76
77
78  return 1;
79}
80
81
82int net_configuration::confirm_inputs(input_manager *i, int server)
83{
84  if (server)
85  {
86    int kl;
87
88    if (sscanf(i->get(NET_KILLS)->read(),"%d",&kl)!=1 || kl<1 || kl>99)  {  error(symbol_str("kill_error")); return 0; }
89
90    char *nm=i->get(NET_NAME)->read();
91    if (strstr(nm,"\"")) {  error(symbol_str("name_error")); return 0; }   
92    strcpy(name,nm);
93
94    min_players=((ifield *)(i->get(NET_MIN)->read()))->id-MIN_1+1;
95    max_players=((ifield *)(i->get(NET_MAX)->read()))->id-MAX_2+2;
96    if (max_players<min_players)  {  error(symbol_str("max_error")); return 0; }   
97
98    char *s_nm=i->get(NET_SERVER_NAME)->read();
99    if (strstr(s_nm,"\"")) {  error(symbol_str("game_error")); return 0; }   
100
101    strcpy(game_name,s_nm);
102
103    bFILE *fp=open_file("addon/deathmat/gamename.lsp","wb");
104    if (!fp->open_failure())
105    {
106      char str[100];
107      sprintf(str,"(setq gamename \"%s\")\n",game_name);
108      fp->write(str,strlen(str)+1);
109    }
110    delete fp;
111    strcpy(lsf,"addon/deathmat/deathmat.lsp");
112
113
114    fp=open_file("addon/deathmat/levelset.lsp","wb");
115    if (!fp->open_failure())
116    {
117      char str[100];
118      if (((ifield *)(i->get(LEVEL_BOX)->read()))->id==LVL_2)
119        sprintf(str,"(load \"addon/deathmat/small.lsp\")\n");
120      else if (((ifield *)(i->get(LEVEL_BOX)->read()))->id==LVL_4)
121        sprintf(str,"(load \"addon/deathmat/medium.lsp\")\n");
122      else
123        sprintf(str,"(load \"addon/deathmat/large.lsp\")\n");
124      fp->write(str,strlen(str)+1);
125    }
126    delete fp;
127
128
129    kills=kl;
130
131  } else  {
132    char *nm=i->get(NET_NAME)->read();
133    if (strstr(nm,"\"")) {  error(symbol_str("name_error")); return 0; }   
134    strcpy(name,nm);
135  }
136
137  bFILE *fp=open_file("addon/deathmat/username.lsp","wb");
138  if (!fp->open_failure())
139  {
140    char str[100];
141    sprintf(str,"(setq username \"%s\")\n",name);
142    fp->write(str,strlen(str)+1);
143  }
144  delete fp;
145
146
147
148  return 1;
149
150}
151
152extern int start_running,demo_start,start_edit;
153
154/*int net_configuration::input()   // pulls up dialog box and input fileds
155{
156  ifield *ilist=NULL;
157  int x=WINDOW_FRAME_LEFT,y=WINDOW_FRAME_TOP;
158 
159  jwindow *sv=eh->new_window(50,80,-1,-1,new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,NET_SERVER,symbol_str("server"),
160                                     new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+eh->font()->height()*2,NET_CLIENT,symbol_str("client"),
161                                     new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+eh->font()->height()*4,NET_SINGLE,symbol_str("single_play"),
162                                     new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+eh->font()->height()*6,NET_CANCEL,symbol_str("cancel_net"),
163                                                NULL)))),symbol_str("Networking"));
164
165  event ev;
166  int done=0;
167  do
168  {
169    eh->flush_screen();
170    do { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting());
171    if (ev.type==EV_MESSAGE)
172    {
173      if (ev.message.id==NET_SERVER) { done=1; state=RESTART_SERVER;  start_edit=0; demo_start=0; start_running=1; }
174      else if (ev.message.id==NET_CLIENT) { done=1; state=RESTART_CLIENT;  start_edit=0; demo_start=0; start_running=1; }
175      else if (ev.message.id==NET_SINGLE) { done=1; state=RESTART_SINGLE;  start_edit=0; demo_start=0; start_running=0; }
176      else if (ev.message.id==NET_CANCEL) { done=1; }
177    } else if (ev.type==EV_CLOSE_WINDOW || (ev.type==EV_KEY & ev.key==JK_ESC)) done=1;
178 
179  } while (!done);
180
181  eh->close_window(sv);
182  eh->flush_screen();
183           
184  if (state==RESTART_SINGLE)
185  {
186    strcpy(lsf,"abuse.lsp");
187    return 1;
188  }
189  if (ev.message.id==NET_CANCEL || state==RESTART_SINGLE) return 0;
190
191  if (state==RESTART_SERVER)
192  {
193    ilist=new button(x,y,NET_CANCEL,symbol_str("cancel_button"),ilist);
194    ilist=new button(x,y,NET_OK,       symbol_str("server"),ilist);
195    ilist=new text_field(x,y,NET_KILLS,symbol_str("kills_to_win"),"******",kills,ilist);
196    ilist=new text_field(x,y,NET_MAX,symbol_str("max_play"),"******",max_players,ilist);
197    ilist=new text_field(x,y,NET_MIN,symbol_str("min_play"),"******",min_players,ilist);
198    ilist=new text_field(x,y,NET_PORT,symbol_str("use_port"),"******",port,ilist);
199    ilist=new text_field(x,y,NET_NAME,symbol_str("your_name"),"****************",name,ilist);
200
201  } else
202  {
203    ilist=new button(x,y,NET_CANCEL,symbol_str("cancel_button"),ilist);
204    ilist=new button(x,y,NET_OK,symbol_str("client"),ilist);
205//    ilist=new text_field(x,y,NET_PORT,symbol_str("use_port"),"******",port,ilist);
206    ilist=new text_field(x,y,NET_SERVER_PORT,symbol_str("server_port"),"******",server_port,ilist);
207    ilist=new text_field(x,y,NET_SERVER_NAME,symbol_str("server_name"),"*********************************",game_name,ilist);
208    ilist=new text_field(x,y,NET_NAME,symbol_str("your_name"),"****************",name,ilist);
209  }
210
211  ifield *i=ilist;
212  for (;i;i=i->next)
213  {
214    i->y=y;
215    int x1,y1,x2,y2;
216    i->area(x1,y1,x2,y2,eh);
217    y=y2+2;
218  }
219
220
221  jwindow *nw=eh->new_window(0,0,-1,-1,ilist,symbol_str("Networking"));
222
223  done=0;
224  do
225  {
226    eh->flush_screen();
227    do { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting());
228    if (ev.type==EV_MESSAGE && ev.message.id==NET_OK && confirm_inputs(nw,state==RESTART_SERVER))
229      done=1;
230    if (ev.type==EV_MESSAGE && (ev.message.id==NET_CANCEL || ev.message.id==NET_SINGLE))
231       done=1;
232    if (ev.type==EV_CLOSE_WINDOW || (ev.type==EV_KEY && ev.key==JK_ESC))
233      done=1;
234
235  } while (!done);
236  eh->close_window(nw);
237  eh->flush_screen();
238
239  return ev.message.id==NET_OK;
240}
241
242*/
243
244
245void net_configuration::error(char *message)
246{
247  image *screen_backup=screen->copy();
248
249  image *ns=cash.img(cash.reg("art/frame.spe","net_screen",SPEC_IMAGE,1));
250  int ns_w=ns->width(),ns_h=ns->height();
251  int x=(xres+1)/2-ns_w/2,y=(yres+1)/2-ns_h/2;
252  ns->put_image(screen,x,y);
253  JCFont *fnt=eh->font();
254
255  uint8_t *remap=white_light+30*256;
256
257  uint8_t *sl=screen->scan_line(0);
258  int xx=screen->width()*screen->height();
259  for (;xx;xx--,sl++) *sl=remap[*sl];
260
261  int fx=x+ns_w/2-strlen(message)*fnt->width()/2,
262    fy=y+ns_h/2-fnt->height();
263
264  fnt->put_string(screen,fx+1,fy+1,message,eh->black());
265  fnt->put_string(screen,fx,fy,message,eh->bright_color());
266
267 
268  {   
269    char *ok=symbol_str("ok_button");
270
271    int bx=x+ns_w/2-strlen(ok)*fnt->width()/2-3,
272      by=y+ns_h/2+fnt->height()*3;
273   
274    button *sb=new button(bx,by,NET_SERVER,ok,NULL);
275
276    input_manager inm(screen,eh,sb);
277    inm.allow_no_selections();
278    inm.clear_current();
279
280    int done=0;
281    event ev;
282    do
283    {
284      eh->flush_screen();
285      do  { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting());
286      inm.handle_event(ev,NULL,eh);
287      if ((ev.type==EV_KEY && (ev.key==JK_ESC || ev.key==JK_ENTER)) ||
288          ev.type==EV_MESSAGE) done=1;
289    } while (!done);
290  }
291
292  screen_backup->put_image(screen,0,0);
293  eh->flush_screen();
294  delete screen_backup;
295}
296
297
298ifield *net_configuration::center_ifield(ifield *i,int x1, int x2, ifield *place_below)
299{
300  int X1,Y1,X2,Y2;
301  i->area(X1,Y1,X2,Y2,eh);
302  i->x=(x1+x2)/2-(X2-X1)/2;
303
304  if (place_below)
305  {
306    place_below->area(X1,Y1,X2,Y2,eh);
307    i->y=Y2+2;
308  }
309  return i;
310}
311
312int net_configuration::get_options(int server)
313{
314  image *ns=cash.img(cash.reg("art/frame.spe","net_screen",SPEC_IMAGE,1));
315  int ns_w=ns->width(),ns_h=ns->height();
316  int x=(xres+1)/2-ns_w/2,y=(yres+1)/2-ns_h/2;
317  ns->put_image(screen,x,y);
318  JCFont *fnt=eh->font();
319  image *ok_image=cash.img(cash.reg("art/frame.spe","dev_ok",SPEC_IMAGE,1))->copy(),
320    *cancel_image=cash.img(cash.reg("art/frame.spe","cancel",SPEC_IMAGE,1))->copy();
321
322  ifield *list=NULL;
323
324  if (server)
325  {       
326    list=center_ifield(new text_field(x,y+30,NET_NAME,symbol_str("your_name"),"************************",name,list),x,x+ns_w,NULL);
327    list=center_ifield(new text_field(0,0,NET_SERVER_NAME,symbol_str("server_name"),"************************",game_name,list),x,x+ns_w,list);
328    list=center_ifield(new info_field(0,0,0,symbol_str("min_play"),list),x,x+ns_w,list);
329
330
331    button_box *b=new button_box(0,0,NET_MIN,1,NULL,list);
332    b->add_button(new button(0,0,MIN_8,"8",NULL));
333    b->add_button(new button(0,0,MIN_7,"7",NULL));
334    b->add_button(new button(0,0,MIN_6,"6",NULL));
335    b->add_button(new button(0,0,MIN_5,"5",NULL));
336    b->add_button(new button(0,0,MIN_4,"4",NULL));
337    b->add_button(new button(0,0,MIN_3,"3",NULL));
338    button *r=new button(0,0,MIN_2,"2",NULL); r->push();
339    b->add_button(r);
340    b->add_button(new button(0,0,MIN_1,"1",NULL));
341
342
343
344    b->arrange_left_right(eh);
345    center_ifield(b,x,x+ns_w,list);
346    b->arrange_left_right(eh);
347    list=b;
348
349    list=center_ifield(new info_field(0,0,0,symbol_str("max_play"),list),x,x+ns_w,list);
350
351    b=new button_box(0,0,NET_MAX,1,NULL,list);
352    button *q=new button(0,0,MAX_8,"8",NULL); q->push();
353    b->add_button(q);
354    b->add_button(new button(0,0,MAX_7,"7",NULL));
355    b->add_button(new button(0,0,MAX_6,"6",NULL));
356    b->add_button(new button(0,0,MAX_5,"5",NULL));
357    b->add_button(new button(0,0,MAX_4,"4",NULL));
358    b->add_button(new button(0,0,MAX_3,"3",NULL));
359    b->add_button(new button(0,0,MAX_2,"2",NULL));
360    b->arrange_left_right(eh);
361    center_ifield(b,x,x+ns_w,list);
362    b->arrange_left_right(eh);   
363    list=b;
364
365
366    list=center_ifield(new info_field(0,0,0,symbol_str("level_size"),list),x,x+ns_w,list);
367
368    b=new button_box(0,0,LEVEL_BOX,1,NULL,list);
369    b->add_button(new button(0,0,LVL_8,symbol_str("lvl_8"),NULL));
370    b->add_button(new button(0,0,LVL_4,symbol_str("lvl_4"),NULL));
371    q=new button(0,0,LVL_2,symbol_str("lvl_2"),NULL); q->push();
372    b->add_button(q);
373
374    b->arrange_left_right(eh);
375    center_ifield(b,x,x+ns_w,list);
376    b->arrange_left_right(eh);   
377    list=b;
378
379    list=center_ifield(new text_field(0,0,NET_KILLS,symbol_str("kills_to_win"),"***","25",list),x,x+ns_w,list);
380
381
382
383                                   
384  } else
385  {
386    list=center_ifield(new text_field(x,y+80,NET_NAME,symbol_str("your_name"),"************************",name,list),x,x+ns_w,NULL);
387  }
388
389
390  list=new button(x+80-17,y+ns_h-20-fnt->height(),NET_OK,ok_image,list);
391  list=new button(x+80+17,y+ns_h-20-fnt->height(),NET_CANCEL,cancel_image,list);
392
393  int ret=0;
394
395  {
396    input_manager inm(screen,eh,list);
397    inm.allow_no_selections();
398    inm.clear_current();
399   
400    int done=0;
401    event ev;
402    do
403    {
404      eh->flush_screen();
405      do { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting());
406      inm.handle_event(ev,NULL,eh);
407      if (ev.type==EV_MESSAGE)
408      {
409        switch (ev.message.id)
410        {
411          case NET_OK : { if (confirm_inputs(&inm,server))
412          { ret=1; done=1; }                     
413          else { ((button *)inm.get(NET_OK))->push(); inm.redraw(); }
414          } break;
415          case NET_CANCEL : done=1;         
416        }
417      } if (ev.type==EV_KEY && ev.key==JK_ESC) done=1;
418
419    } while (!done);
420
421  }
422  delete ok_image;
423  delete cancel_image;
424
425  return ret;
426}
427
428int net_configuration::input()   // pulls up dialog box and input fileds
429{
430  int ret=0;
431  screen->clear();
432 
433  image *ns=cash.img(cash.reg("art/frame.spe","net_screen",SPEC_IMAGE,1));
434  int ns_w=ns->width(),ns_h=ns->height();
435  int x=(xres+1)/2-ns_w/2,y=(yres+1)/2-ns_h/2;
436  ns->put_image(screen,x,y);
437  char *nw_s=symbol_str("Networking");
438  JCFont *fnt=eh->font();
439
440
441  eh->font()->put_string(screen,x+ns_w/2-strlen(nw_s)*fnt->width()/2,y+21/2-fnt->height()/2,
442      nw_s,eh->medium_color());
443  {
444
445    char *server_str=symbol_str("server");
446    button *sb=new button(x+40,y+ns_h-23-fnt->height(),NET_SERVER,server_str,NULL);
447
448    if (main_net_cfg && (main_net_cfg->state==CLIENT || main_net_cfg->state==SERVER))
449      sb=new button(x+40,y+ns_h-9-fnt->height(),NET_SINGLE,symbol_str("single_play"),sb);
450
451    input_manager inm(screen,eh,sb);
452
453    inm.allow_no_selections();
454    inm.clear_current();
455
456
457    event ev;
458    int done=0;
459    int button_y=25,total_games=0;
460    enum { MAX_GAMES=9 };
461    net_address *game_addr[MAX_GAMES+1];
462    int join_game=-1;
463    time_marker start,now;
464
465    do
466    {
467      if (eh->event_waiting())
468      {
469        do  { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting());
470        inm.handle_event(ev,NULL,eh);
471        if (ev.type==EV_MESSAGE)
472        {
473          switch (ev.message.id)
474          {
475            case NET_CANCEL : done=1; break;
476            case NET_SERVER : done=1; break;
477            case NET_SINGLE : done=1; break;
478            default :
479              if (ev.message.id>=NET_GAME && ev.message.id<NET_GAME+MAX_GAMES)
480              {
481                join_game=ev.message.id-NET_GAME;
482                done=1;
483              }
484          }
485        }
486                else if (ev.type==EV_KEY && ev.key==JK_ESC )
487                {
488                        done=1;
489                }
490                else
491                {
492                        // No event waiting...  We can't wait for long, because we are pretending to broadcast.
493                        milli_wait(5); // ECS - Added so waiting in dialog doesn't use 100% of CPU
494                }
495        }
496
497      eh->flush_screen();
498      char name[256];
499
500      now.get_time();
501      if (total_games<MAX_GAMES && now.diff_time(&start)>0.5)
502      {
503        start.get_time();
504        net_address *find=prot->find_address(0x9090,name);    // was server_port
505        if (find)
506        {
507          int bw=strlen(name)*fnt->width();
508          inm.add(new button(x+ns_w/2-bw/2,y+button_y,NET_GAME+total_games,name,NULL));
509          find->set_port(server_port);
510          game_addr[total_games]=find;
511                       
512          total_games++;
513          button_y+=fnt->height()+10;
514          inm.redraw();
515        }
516      }
517
518    } while (!done);
519
520    prot->reset_find_list();
521
522    if (join_game>=0)
523    {
524      if (get_options(0))
525      {
526        int still_there=1;  // change this back to 0, to check if games are stil alive
527        time_marker start,now;
528        do
529        {
530          now.get_time();
531          char name[256];
532          net_address *find=prot->find_address(0x9090,name);  // was server_port
533          if (find)
534          {       
535            if (find->equal(game_addr[join_game]))
536              still_there=1;
537            delete find;
538          }
539                       
540        } while (now.diff_time(&start)<3 && !still_there);
541                       
542        if (still_there)
543        {
544          game_addr[join_game]->store_string(server_name,sizeof(server_name));
545          state=RESTART_CLIENT;
546          ret=1;
547                       
548        } else error(symbol_str("not_there"));
549                       
550                       
551        prot->reset_find_list();
552        int i;
553        for (i=0;i<total_games;i++)        // delete all the addresses we found and stored
554          delete game_addr[join_game]; 
555      }
556    } else if (ev.type==EV_MESSAGE && ev.message.id==NET_SERVER)
557    {
558      if (get_options(1))
559      {
560        state=RESTART_SERVER;
561        return 1;
562      }
563      else return 0;
564    } else if (ev.type==EV_MESSAGE && ev.message.id==NET_SINGLE)
565    {
566      state=RESTART_SINGLE;
567      start_running=0;
568
569      strcpy(lsf,"abuse.lsp");
570      return 1;     
571    }     
572  }
573
574  return ret;
575}
576
577
Note: See TracBrowser for help on using the repository browser.