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

Last change on this file since 481 was 481, checked in by Sam Hocevar, 10 years ago

Fuck the history, I'm renaming all .hpp files to .h for my own sanity.

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