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

Last change on this file since 512 was 512, checked in by Sam Hocevar, 11 years ago

imlib: use vec2i for image::size and unroll all necessary changes
everywhere else in the code.

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