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

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