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

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