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

Last change on this file since 111 was 111, checked in by Sam Hocevar, 11 years ago
  • Simplified the window creation arguments. Got rid of a lot of macros and hid stuff in private namespaces.

Inspired by Win32 Abuse changelog for January 28, 2001:

  • Well, in the process of adding changes necessary to

handle recovery from alt-tabbing away from Abuse
(which is why I was updating jwindow::redraw()),
the entire windowing system is getting an overhaul.
It's gonna be sweet when I'm done, though.

  • jwindow::redraw() has been changed to a virtual

function requiring no parameters. This'll make
it much easier to implement special specific-
purpose windows.

File size: 16.5 KB
RevLine 
[56]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
[88]12#include "game.hpp"
13
14
[2]15#include "netcfg.hpp"
16#include "input.hpp"
17#include "cache.hpp"
18#include "sock.hpp"
19#include "timing.hpp"
20#include "light.hpp"
21
[39]22#include "dev.hpp"
23
[2]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
[39]53void net_configuration::cfg_error(char const *msg)
[2]54{
[111]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"));
[2]57  event ev;
58  do
59  {
[106]60    wm->flush_screen();
61    do { wm->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && wm->event_waiting());
[2]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));
[106]63  wm->close_window(j);
64  wm->flush_screen();
[2]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;
[4]75    default:
76      break;
[2]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;
[4]88    default: break;
[2]89  }
90
91
92  return 1;
93}
94
95
96int net_configuration::confirm_inputs(input_manager *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=WINDOW_FRAME_LEFT,y=WINDOW_FRAME_TOP;
172 
[106]173  jwindow *sv=wm->new_window(50,80,-1,-1,new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,NET_SERVER,symbol_str("server"),
174                                     new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+wm->font()->height()*2,NET_CLIENT,symbol_str("client"),
175                                     new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+wm->font()->height()*4,NET_SINGLE,symbol_str("single_play"),
176                                     new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+wm->font()->height()*6,NET_CANCEL,symbol_str("cancel_net"),
[2]177                                                NULL)))),symbol_str("Networking"));
178
179  event ev;
180  int done=0;
181  do
182  {
[106]183    wm->flush_screen();
184    do { wm->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && wm->event_waiting());
[2]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
[106]195  wm->close_window(sv);
196  wm->flush_screen();
[2]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;
[106]230    i->area(x1,y1,x2,y2);
[2]231    y=y2+2;
232  }
233
234
[106]235  jwindow *nw=wm->new_window(0,0,-1,-1,ilist,symbol_str("Networking"));
[2]236
237  done=0;
238  do
239  {
[106]240    wm->flush_screen();
241    do { wm->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && wm->event_waiting());
[2]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);
[106]250  wm->close_window(nw);
251  wm->flush_screen();
[2]252
253  return ev.message.id==NET_OK;
254}
255
256*/
257
258
[39]259void net_configuration::error(char const *message)
[2]260{
261  image *screen_backup=screen->copy();
262
263  image *ns=cash.img(cash.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);
[106]267  JCFont *fnt=wm->font();
[2]268
[17]269  uint8_t *remap=white_light+30*256;
[2]270
[17]271  uint8_t *sl=screen->scan_line(0);
[2]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
[106]278  fnt->put_string(screen,fx+1,fy+1,message,wm->black());
279  fnt->put_string(screen,fx,fy,message,wm->bright_color());
[2]280
281 
282  {   
[39]283    char const *ok = symbol_str("ok_button");
[2]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
[106]290    input_manager inm(screen,sb);
[2]291    inm.allow_no_selections();
292    inm.clear_current();
293
294    int done=0;
295    event ev;
296    do
297    {
[106]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);
[2]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);
[106]307  wm->flush_screen();
[2]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;
[106]315  i->area(X1,Y1,X2,Y2);
[2]316  i->x=(x1+x2)/2-(X2-X1)/2;
317
318  if (place_below)
319  {
[106]320    place_below->area(X1,Y1,X2,Y2);
[2]321    i->y=Y2+2;
322  }
323  return i;
324}
325
326int net_configuration::get_options(int server)
327{
328  image *ns=cash.img(cash.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);
[106]332  JCFont *fnt=wm->font();
[2]333  image *ok_image=cash.img(cash.reg("art/frame.spe","dev_ok",SPEC_IMAGE,1))->copy(),
334    *cancel_image=cash.img(cash.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
[106]358    b->arrange_left_right();
[2]359    center_ifield(b,x,x+ns_w,list);
[106]360    b->arrange_left_right();
[2]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));
[106]374    b->arrange_left_right();
[2]375    center_ifield(b,x,x+ns_w,list);
[106]376    b->arrange_left_right();   
[2]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
[106]388    b->arrange_left_right();
[2]389    center_ifield(b,x,x+ns_w,list);
[106]390    b->arrange_left_right();   
[2]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  {
[106]410    input_manager inm(screen,list);
[2]411    inm.allow_no_selections();
412    inm.clear_current();
413   
414    int done=0;
415    event ev;
416    do
417    {
[106]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);
[2]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=cash.img(cash.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);
[39]451  char const *nw_s = symbol_str("Networking");
[106]452  JCFont *fnt=wm->font();
[2]453
454
[106]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());
[2]457  {
458
[39]459    char const *server_str = symbol_str("server");
[2]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
[106]465    input_manager inm(screen,sb);
[2]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    {
[106]481      if (wm->event_waiting())
[2]482      {
[106]483        do  { wm->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && wm->event_waiting());
484        inm.handle_event(ev,NULL);
[2]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
[106]511      wm->flush_screen();
[2]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.