source: abuse/trunk/src/view.cpp @ 2

Last change on this file since 2 was 2, checked in by Sam Hocevar, 14 years ago
  • imported original 0.7.0 tarball
File size: 25.9 KB
Line 
1#include "system.h"
2#include "view.hpp"
3#include "lisp.hpp"
4#include "jwindow.hpp"
5#include "config.hpp"
6#include "scroller.hpp"
7#include "id.hpp"
8#include "dev.hpp"
9#include "jrand.hpp"
10#include "dprint.hpp"
11#include "transp.hpp"
12#include "clisp.hpp"
13#include "demo.hpp"
14#include "sbar.hpp"
15#include "nfserver.hpp"
16#include "chat.hpp"
17
18#define SHIFT_DOWN_DEFAULT 15
19#define SHIFT_RIGHT_DEFAULT 0
20
21extern int get_key_binding( char *dir, int i );
22extern window_manager *eh;
23view *player_list=NULL;
24int morph_sel_frame_color;
25
26view::~view()
27{
28  if (local_player())
29    sbar.associate(NULL);
30
31  if (total_weapons)
32  {
33    jfree(weapons);
34    jfree(last_weapons);
35  }
36}
37
38
39extern uchar bright_tint[256];
40
41void view::add_ammo(int weapon_type, int total)
42
43  if (weapon_type>=total_weapons || weapon_type<0)
44  {
45    printf("weapon out of range\n");
46    return ;
47  }
48  if (weapons[weapon_type]==-1) return ;   // don't have weapon yet, can't give ammo
49
50  weapons[weapon_type]+=total;
51  if (weapons[weapon_type]<0) 
52    weapons[weapon_type]=0; 
53
54  if (weapons[weapon_type]>999)
55    weapons[weapon_type]=999;
56
57  if (weapon_total(current_weapon)==0 && current_weapon)
58  {
59    suggest.send_weapon_change=1;
60    if (DEFINEDP(symbol_value(l_switch_to_powerful)) && symbol_value(l_switch_to_powerful))
61    {
62      int x=total_weapons-1;
63      while (x>0 && (x==3 || weapons[x]<=0)) x--;         
64      suggest.new_weapon=x;
65    } else
66      suggest.new_weapon=0;
67  }
68
69}
70
71void view::give_weapon(int type)
72{
73  if (type>=total_weapons || type<0)
74  {
75    printf("weapon out of range\n");
76    return ;
77  }
78  if (weapons[type]==-1)
79  {
80    weapons[type]=0;
81    sbar.need_refresh();
82  }
83}
84
85int view::weapon_total(int type)
86{
87  if (type>=total_weapons || type<0)
88  {
89    printf("weapon out of range\n");
90    return 0;
91  }
92  if (god) return 100;
93  else if (weapons[type]==-1) return 0;
94  else return weapons[type];
95}
96
97
98long view::xoff()
99{
100  if (focus)
101  {
102    int x=last_x-(cx2-cx1+1)/2+shift_right+pan_x;
103    if (x<0) return 0;
104    else return x;
105  } else return pan_x;
106}
107
108long view::interpolated_xoff()
109{
110  if (focus)
111  {
112    int x=(last_last_x+last_x)/2-(cx2-cx1+1)/2+shift_right+pan_x;
113    if (x<0) return 0;
114    else return x;
115  } else return pan_x;
116}
117
118
119long view::yoff()
120{
121  if (focus)
122  {
123    int y=last_y-(cy2-cy1+1)/2-shift_down+pan_y;
124    if (y<0) return 0;
125    else return y;
126  } else return pan_y;
127}
128
129
130long view::interpolated_yoff()
131{
132  if (focus)
133  {
134    int y=(last_y+last_last_y)/2-(cy2-cy1+1)/2-shift_down+pan_y;
135    if (y<0) return 0;
136    else return y;
137  } else return pan_y;
138}
139
140
141void view::update_scroll()
142{
143  if (focus)
144  {
145    last_last_x=last_x;
146    last_last_y=last_y;
147    if (focus->x>last_x)
148    {
149      if (focus->x-last_x>=no_xright)
150        last_x=focus->x-no_xright;
151    } else if (focus->x<last_x)
152    {
153      if (last_x-focus->x>=no_xleft)
154        last_x=focus->x+no_xleft;
155    }
156    if (focus->y>last_y)
157    {
158      if (focus->y-last_y>=no_ybottom)
159        last_y=focus->y-no_ybottom;
160    } else if (focus->y<last_y)
161    {
162      if (last_y-focus->y>=no_ytop)
163        last_y=focus->y+no_ytop;
164    }
165  }
166}
167
168char cur_user_name[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
169
170#ifdef __WATCOMC__
171char *get_login()
172{  if (cur_user_name[0]) return cur_user_name; else return "DOS user"; }
173
174#include <dos.h>
175#elif defined( __APPLE__ )
176
177char *get_login()
178{  if (cur_user_name[0]) return cur_user_name; else return "Mac user"; }
179
180#else
181char *get_login()
182{  if (cur_user_name[0]) return cur_user_name; else return (getlogin() ? getlogin() : (char *)"unknown"); }
183
184#endif
185
186void set_login(char *name)
187{ strncpy(cur_user_name,name,20); }
188
189view::view(game_object *Focus, view *Next, int number)
190{
191  chat_buf[0]=0;
192
193  draw_solid=-1;
194  no_xleft=0;
195  no_xright=0;
196  no_ytop=0;
197  no_ybottom=0;
198  if (Focus)
199  {
200    last_x=Focus->x;
201    last_y=Focus->y;
202  } else
203  {
204    last_x=last_y=0;
205  }
206
207  last_last_x=last_x;
208  last_last_y=last_y;
209  last_hp=last_ammo=-1;
210  last_type=-1;
211  tsecrets=secrets=0;
212  tkills=kills=0;
213
214  reset_keymap();
215
216  ambient=32;
217  current_weapon=0;
218
219  strcpy(name,get_login());
220  suggest.send_view=0;
221  suggest.send_weapon_change=0;
222
223
224  god=0;
225
226  player_number=number;
227  cx1=0;
228  cy1=0;
229  cx2=100;
230  cy2=100;
231  focus=Focus;
232  next=Next;
233  shift_down=SHIFT_DOWN_DEFAULT;
234  shift_right=SHIFT_RIGHT_DEFAULT;
235  x_suggestion=0;
236  y_suggestion=0;
237  b1_suggestion=0;
238  b2_suggestion=0;
239  b3_suggestion=0;
240  b4_suggestion=0;
241  pointer_x=0;
242  pointer_y=0;
243
244  pan_x=0;
245  pan_y=0;
246  last_type=0;
247  freeze_time=0;
248
249  if (total_weapons)
250  {
251    weapons=(long *)jmalloc(total_weapons*sizeof(long),"weapon array");
252    last_weapons=(long *)jmalloc(total_weapons*sizeof(long),"last weapon array");
253    memset(weapons,0xff,total_weapons*sizeof(long));   // set all to -1
254    memset(last_weapons,0xff,total_weapons*sizeof(long));   // set all to -1 
255  }
256
257  if (total_weapons)
258    weapons[0]=0;
259  if (local_player())
260    sbar.associate(this);
261  sbar.need_refresh();
262}
263
264long view::x_center()
265{
266  if (!focus)
267    return (cx1+cx2)/2;
268  else
269    return focus->x;
270}   
271
272long view::y_center()
273{
274  if (!focus)
275    return (cy1+cy2)/2;
276  else
277    return focus->y;
278}
279
280void view::draw_character_damage()
281{   
282  if (focus && drawable())
283  {
284    if (last_hp!=focus->hp()) draw_hp();
285    int i;
286    for (i=0;i<total_weapons;i++)
287      if (weapons[i]!=last_weapons[i])
288      {
289        last_weapons[i]=weapons[i];
290        sbar.draw_ammo(screen,i,weapons[i],current_weapon==i);
291      }
292  }
293}
294
295
296
297ushort make_sync()
298{
299  ushort x=0;
300  if (!current_level) return 0;
301  if (current_level)
302  {
303    view *f=player_list;
304    for (;f;f=f->next)
305    {
306      if (f->focus)
307      {
308        x^=(f->focus->x&0xffff);
309        x^=(f->focus->y&0xffff);
310      }
311    }
312  }
313  x^=rand_on;
314
315  return x;
316}
317
318
319
320void view::get_input()
321{
322        int sug_x,sug_y,sug_b1,sug_b2,sug_b3,sug_b4;
323        long sug_px,sug_py;
324
325// NOTE:(AK) I have commented this out so we don't use the lisp
326//              file "input.lsp" to get our key mappings.
327/*      if( DEFINEDP( symbol_function( l_get_local_input ) ) )
328        {
329                void *ret = eval_function((lisp_symbol *)l_get_local_input, NULL );
330                sug_x = lnumber_value( CAR( ret ) );
331                ret = CDR( ret );
332                sug_y = lnumber_value( CAR( ret ) );
333                ret = CDR( ret );
334                if( CAR( ret ) )
335                        sug_b1 = 1;
336                else
337                        sug_b1 = 0;
338                ret = CDR( ret );
339                if( CAR( ret ) )
340                        sug_b2 = 1;
341                else
342                        sug_b2 = 0;
343                ret = CDR( ret );
344                int x = lnumber_value( CAR( ret ) );
345                ret = CDR( ret );
346                if( x < 0 )
347                        sug_b3 = 1;
348                else
349                        sug_b3 = 0;
350                if( x > 0 )
351                        sug_b4 = 1;
352                else sug_b4 = 0;
353
354                long bx = lnumber_value( CAR( ret ) );
355                ret = CDR( ret );
356                long by = lnumber_value( CAR( ret ) );
357                ret = CDR( ret );
358                the_game->mouse_to_game( bx, by, sug_px, sug_py, this );
359
360        }
361        else*/
362        {
363                get_movement( 0, sug_x, sug_y, sug_b1, sug_b2, sug_b3, sug_b4 );
364                if( focus )
365                {
366                        the_game->mouse_to_game( last_demo_mx, last_demo_my, sug_px, sug_py, this );
367                        if( last_demo_mbut & 1 )
368                                sug_b2 = 1;
369                        if( last_demo_mbut & 2 )
370                                sug_b1 = 1;
371                }
372                else
373                        sug_px = sug_py = 0;
374        }
375
376        if( view_changed() )
377        {
378                base->packet.write_byte( SCMD_VIEW_RESIZE );
379                base->packet.write_byte( player_number );
380                base->packet.write_long( suggest.cx1 );
381                base->packet.write_long( suggest.cy1 );
382                base->packet.write_long( suggest.cx2 );
383                base->packet.write_long( suggest.cy2 );
384
385                base->packet.write_long( suggest.pan_x );
386                base->packet.write_long( suggest.pan_y );
387                base->packet.write_long( suggest.shift_down );
388                base->packet.write_long( suggest.shift_right );
389        }
390
391        if( weapon_changed() )
392        {
393                base->packet.write_byte( SCMD_WEAPON_CHANGE );
394                base->packet.write_byte( player_number );
395                base->packet.write_long( suggest.new_weapon );
396        }
397
398        base->packet.write_byte( SCMD_SET_INPUT );
399        base->packet.write_byte( player_number );
400
401        uchar mflags = 0;
402        if( sug_x > 0 )
403                mflags |= 1;
404        else if ( sug_x < 0 )
405                mflags |= 2;
406
407        if( sug_y > 0 )
408                mflags |= 4;
409        else if( sug_y < 0 )
410                mflags |= 8;
411
412        if( sug_b1 )
413                mflags |= 16;
414        if( sug_b2 )
415                mflags |= 32;
416        if( sug_b3 )
417                mflags |= 64;
418        if( sug_b4 )
419                mflags |= 128;
420
421        base->packet.write_byte( mflags );
422        base->packet.write_short((ushort)((short)sug_px));
423        base->packet.write_short((ushort)((short)sug_py));
424}
425
426
427void view::add_chat_key(int key)  // return string if buf is complete
428{
429  int len=strlen(chat_buf);
430  if (key==JK_BACKSPACE)
431  {
432    if (len)
433    {
434      chat_buf[len-1]=0;
435      if (local_player() && chat)
436        chat->draw_user(chat_buf);
437    }
438  } else if (key!=JK_ENTER)
439  {
440    chat_buf[len]=key;
441    chat_buf[len+1]=0;
442    if (local_player() && chat)
443      chat->draw_user(chat_buf);
444  }
445
446  if (len>38 || key==JK_ENTER)
447  {
448    if (DEFINEDP(symbol_function(l_chat_input)))
449    {
450      game_object *o=current_object;
451      current_object=focus;
452
453      void *m=mark_heap(TMP_SPACE);
454      void *list=NULL;
455      push_onto_list(new_lisp_string(chat_buf),list);       
456      eval_function((lisp_symbol *)l_chat_input,list);
457      restore_heap(m,TMP_SPACE);
458
459      current_object=o;
460
461    } else
462    {           
463      if (chat)
464        chat->put_all(chat_buf);
465    }
466    chat_buf[0]=0;
467    if (local_player() && chat)
468      chat->draw_user(chat_buf);
469  }
470}
471
472int view::process_input(char cmd, uchar *&pk)   // return 0 if something went wrong
473{
474  switch (cmd)
475  {
476    case SCMD_CHAT_KEYPRESS :
477    {
478      add_chat_key(*(pk++));
479    } break;
480    case SCMD_VIEW_RESIZE :
481    {
482      long x[8];
483      memcpy(x,pk,8*4);  pk+=8*4;
484      cx1=lltl(x[0]);
485      cy1=lltl(x[1]);
486      cx2=lltl(x[2]);
487      cy2=lltl(x[3]);
488       
489      pan_x=lltl(x[4]);
490      pan_y=lltl(x[5]);
491      shift_down=lltl(x[6]);
492      shift_right=lltl(x[7]);
493      if (small_render)
494      {
495        small_render->resize(cx2-cx1+1,cy2-cy1+1);
496      }
497
498      suggest.send_view=0;
499      if (local_player())
500        the_game->draw();
501      return 1;
502    }
503    case SCMD_WEAPON_CHANGE :
504    {
505      long x;
506      memcpy(&x,pk,4);  pk+=4;
507      current_weapon=lltl(x);
508
509      if (local_player())
510        sbar.need_refresh();
511      suggest.send_weapon_change=0;
512      return 1;
513    } break;
514
515    case SCMD_SET_INPUT :
516    {
517      uchar x=*(pk++);
518
519      if (x&1) x_suggestion=1;
520      else if (x&2) x_suggestion=-1;
521      else x_suggestion=0;
522
523      if (x&4) y_suggestion=1;
524      else if (x&8) y_suggestion=-1;
525      else y_suggestion=0;
526
527      if (x&16) b1_suggestion=1; else b1_suggestion=0;
528      if (x&32) b2_suggestion=1; else b2_suggestion=0;
529      if (x&64) b3_suggestion=1; else b3_suggestion=0;
530      if (x&128) b4_suggestion=1; else b4_suggestion=0;
531
532      ushort p[2];
533      memcpy(p,pk,2*2);  pk+=2*2;
534     
535      pointer_x=(short)(lstl(p[0]));
536      pointer_y=(short)(lstl(p[1]));
537       
538      return 1;
539    } break;
540    case SCMD_KEYPRESS : set_key_down(*(pk++),1); break;
541    case SCMD_EXT_KEYPRESS : set_key_down(*(pk++)+256,1); break;
542    case SCMD_KEYRELEASE : set_key_down(*(pk++),0); break;
543    case SCMD_EXT_KEYRELEASE : set_key_down(*(pk++)+256,0); break;
544  }
545  return 1;
546}
547
548int view::local_player()
549{
550  return player_number==client_number();
551}
552
553void view::next_weapon()
554{
555  int c=current_weapon;
556
557  while (c<total_weapons-1)
558  {
559    c++;
560    if (weapon_total(c)>0)
561    {
562      suggest.send_weapon_change=1;
563      suggest.new_weapon=c;
564      return ;
565    }
566  }
567 
568  c=0;
569  while (c!=current_weapon)
570  {
571    if (weapon_total(c)>0)
572    {
573      suggest.send_weapon_change=1;
574      suggest.new_weapon=c;
575      return ;
576    }
577    c++;
578  }
579}
580
581void view::last_weapon()
582{
583 
584  int c=current_weapon;
585
586  while (c>=1)
587  {
588    c--;
589    if (weapon_total(c)>0 || c==0)
590    {
591      suggest.send_weapon_change=1;
592      suggest.new_weapon=c;
593      return ;
594    }
595  }
596
597  c=total_weapons-1;
598  while (c!=current_weapon)
599  {
600    if (weapon_total(c)>0 || c==0)
601    {
602      suggest.send_weapon_change=1;
603      suggest.new_weapon=c;
604      return ;
605    }
606    c--;
607  }
608
609}
610
611int view::handle_event(event &ev)
612{
613        if( ev.type == EV_KEY )
614        {
615                if( ev.key == (int)',' )
616                {
617                        if( total_weapons )
618                        {
619                                last_weapon();
620                        }
621                        return 1;
622                }
623                else if( ev.key == (int)'.' )
624                {
625                        if( total_weapons )
626                        {
627                                next_weapon();
628                        }
629                        return 1;
630                }
631                else if( ev.key == get_key_binding( "b3", 0 ) )
632                {
633                        if( total_weapons )
634                        {
635                                last_weapon();
636                        }
637                        return 1;
638                }
639                else if( ev.key == get_key_binding( "b4", 0 ) )
640                {
641                        if( total_weapons )
642                        {
643                                next_weapon();
644                        }
645                        return 1;
646                }
647
648                switch( ev.key )
649                {
650                        case '1':
651                        case '2':
652                        case '3':
653                        case '4':
654                        case '5':
655                        case '6':
656                        case '7':
657                        {
658                                if((( dev & EDIT_MODE ) == 0 ) && ( weapon_total( ev.key - '1' ) > 0 ))
659                                {
660                                        suggest.send_weapon_change = 1;
661                                        suggest.new_weapon=ev.key - '1';
662                                }
663                        } break;
664
665                        case JK_HOME:
666                        case JK_CTRL_L:
667                        case JK_CTRL_R:
668                        {
669                                if( total_weapons )
670                                {
671                                        last_weapon();
672                                }
673                                return 1;
674                        } break;
675                        case JK_PAGEUP:
676                        case JK_INSERT:
677                        {
678                                if( total_weapons )
679                                {
680                                        next_weapon();
681                                }
682                                return 1;
683                        } break;
684                }
685        }
686        return 0;
687}
688
689void view::draw_hp()
690{
691        if (focus)
692        {
693                int h = focus->hp();
694                last_hp=h;
695                sbar.draw_health( screen, focus->hp() );
696        }
697        else
698        {
699                sbar.draw_health( screen, 0 );
700        }
701}
702
703int view::drawable()
704{
705        return local_player();
706}
707
708
709void recalc_local_view_space()   // calculates view areas for local players, should be called
710                                 // when adding or deleting local players
711{
712  if (screen)
713  {
714    int t=total_local_players();
715    if (!t) return ;
716
717    int Xres=small_render ? xres/2 : xres;
718    int Yres=small_render ? yres/2 : yres;
719
720    int h=Yres/t;
721    int w=h*320/200,y=5;
722    if (w<300) w=300;
723
724    for (view *f=player_list;f;f=f->next)
725    {
726      if (f->local_player())
727      {
728        f->suggest.cx1=Xres/2-w/2;
729        f->suggest.cx2=Xres/2+w/2;
730        if (f->suggest.cx1<2) f->suggest.cx1=2;
731        if (f->suggest.cx2>Xres-2) f->suggest.cx2=Xres-2;   
732
733        f->suggest.cy1=y;
734        f->suggest.cy2=h-(total_weapons ? 33 : 0);
735
736        f->suggest.shift_down=f->shift_down;
737        f->suggest.shift_right=f->shift_right;
738        f->suggest.pan_x=f->pan_x;
739        f->suggest.pan_y=f->pan_y;
740        f->suggest.send_view=1;
741
742        if (!player_list->next)
743        {
744          f->cx1=f->suggest.cx1;
745          f->cy1=f->suggest.cy1;
746          f->cx2=f->suggest.cx2;
747          f->cy2=f->suggest.cy2;
748          f->suggest.send_view=0;
749        }
750        y+=h;
751      }
752    }
753  }
754
755}
756
757
758void set_local_players(int total)
759{
760  int rdw=0;
761  if (total<1) return ;
762
763  view *last=NULL;
764  for (view *f=player_list;f;f=f->next)
765  {
766    if (total && f->local_player())
767      total--;
768    else if (!total && f->local_player())  // too many local players, delete this one
769    {
770      view *n=last->next;
771      while (n && !n->local_player()) n=n->next;  // find next local player
772
773      if (last)
774        last->next=n;
775      else       
776      {
777        if (n)    // make sure we have at least one local player
778          player_list=n;
779      }           
780      last=f;
781      rdw=1;
782    }
783  }
784 
785  while (total)   // see if we need to add new players
786  {
787    game_object *o=create(current_start_type,50,50);   
788    view *v;
789    if (!player_list)
790    {
791      player_list=new view(o,NULL,0);
792      v=player_list;
793    }
794    else
795    {
796      view *f=player_list;
797      for (;f && f->next;f=f->next);     
798      f->next=new view(o,NULL,f->player_number+1);
799      v=f->next;
800    }
801    v->cx1=320/2-155; v->cy1=200/2-95; v->cx2=320/2+155; v->cy2=200/2+(total_weapons ? 60 : 95);
802    v->focus->set_controller(v);
803    total--;
804    rdw=1;
805  } 
806  if (rdw)
807    recalc_local_view_space();
808}
809
810
811int total_local_players()
812{
813  int t=0;
814  for (view *f=player_list;f;f=f->next)
815    if (f->local_player()) t++;
816  return t;
817}
818
819
820void view::resize_view(long Cx1, long Cy1, long Cx2, long Cy2)
821{
822  if (cx1!=Cx1 || cx2!=Cx2 || cy1!=Cy1 || cy2!=Cy2)
823  {
824    cx1=Cx1; cy1=Cy1;
825    cx2=Cx2; cy2=Cy2;
826    if (playing_state(the_game->state) && local_player())
827      the_game->draw(0);
828  }
829}
830
831
832void view::set_input(int cx, int cy, int b1, int b2, int b3, int b4, int px, int py)
833{
834        x_suggestion=cx;
835        y_suggestion=cy;
836        b1_suggestion=b1;
837        b2_suggestion=b2;
838        b3_suggestion=b3;
839        b4_suggestion=b4;
840        pointer_x=px;
841        pointer_y=py;
842}
843
844
845
846void view::reset_player()
847{
848  if (focus)
849  {
850   
851    game_object *start=current_level ? current_level->get_random_start(320,focus->controller()) : 0;
852    focus->defaults();
853    if (start)
854    {
855      focus->x=start->x;
856      focus->y=start->y;
857      dprintf("reset position to %d %d\n",start->x,start->y);
858    }
859    focus->set_state(stopped);
860    memset(weapons,0xff,total_weapons*sizeof(long));   
861    memset(last_weapons,0xff,total_weapons*sizeof(long));   
862
863    shift_down=SHIFT_DOWN_DEFAULT;
864    shift_right=SHIFT_RIGHT_DEFAULT;
865
866    if (total_weapons)
867      weapons[0]=0;  // give him the first weapon
868    current_weapon=0;
869
870    memset(focus->lvars,0,figures[focus->otype]->tv*4);
871    focus->set_aistate(0);
872    if (figures[focus->otype]->get_fun(OFUN_CONSTRUCTOR))
873    {
874      game_object *o=current_object;
875      current_object=focus;
876      eval_user_fun((lisp_symbol *)figures[focus->otype]->get_fun(OFUN_CONSTRUCTOR),NULL);
877      current_object=o;
878    }
879    sbar.redraw(screen);
880
881    int i;
882    for (i=0;i<focus->total_objects();i++)   // reset the vars for the attached objects
883    {     
884      game_object *o=focus->get_object(i);
885      memset(o->lvars,0,figures[o->otype]->tv*4);
886    }
887
888  }
889}
890
891
892
893
894
895object_node *make_player_onodes(int player_num)
896{
897  object_node *first=NULL,*last=NULL;
898  for (view *o=player_list;o;o=o->next)
899  {
900    if (o->focus && (player_num==-1 || o->player_number==player_num))
901    {
902      if (!object_to_number_in_list(o->focus,first))
903      {
904        object_node *q=new object_node(o->focus,NULL);
905        if (first)
906          last->next=q;
907        else first=q;
908        last=q;
909      }
910      for (int i=0;i<o->focus->total_objects();i++)
911      {
912        game_object *p=o->focus->get_object(i);
913
914        if (!object_to_number_in_list(p,first))
915        {
916          object_node *q=new object_node(p,NULL);
917          if (first)
918            last->next=q;
919          else first=q;
920          last=q;
921        }
922      }     
923    }
924  }
925  return first;
926}
927
928
929
930
931enum { V_CX1, V_CY1, V_CX2, V_CY2,
932       V_SHIFT_DOWN, V_SHIFT_RIGHT,
933       V_GOD,
934       V_PLAYER_NUMBER,
935       V_DRAW_SOLID,
936       V_LIVES,
937       V_CURRENT_WEAPON,
938       V_X_SUGGESTION, V_Y_SUGGESTION, V_B1_SUGGESTION, V_B2_SUGGESTION, V_B3_SUGGESTION, V_B4_SUGGESTION,
939       V_PAN_X, V_PAN_Y,
940       V_NO_XLEFT, V_NO_XRIGHT, V_NO_YTOP, V_NO_YBOTTOM,
941       V_LAST_X, V_LAST_Y, V_LAST_LEFT, V_LAST_RIGHT, V_LAST_UP, V_LAST_DOWN,
942       V_LAST_B1, V_LAST_B2, V_LAST_B3, V_LAST_B4,
943       V_LAST_HP,
944       V_SECRETS, V_KILLS, V_TSECRETS, V_TKILLS,
945       V_AMBIENT,
946       V_POINTER_X, V_POINTER_Y,
947       V_LAST_LAST_X, V_LAST_LAST_Y,
948       V_FREEZE_TIME };
949
950#define TVV (V_FREEZE_TIME+1)
951
952static char *vv_names[TVV]={
953  "view.cx1",  "view.cy1",  "view.cx2",  "view.cy2",
954  "view.shift_down",  "view.shift_right",
955  "view.god",
956  "view.player_number",
957  "view.draw_solid",
958  "view.lives",
959  "view.current_weapon",
960  "view.x_suggestion",  "view.y_suggestion", 
961   "view.b1_suggestion",  "view.b2_suggestion",  "view.b3_suggestion",  "view.b4_suggestion",
962  "view.pan_x",  "view.pan_y",
963  "view.no_xleft",  "view.no_xright",  "view.no_ytop",  "view.no_ybottom",
964  "view.last_x",  "view.last_y",  "view.last_left",  "view.last_right",  "view.last_up",  "view.last_down",
965  "view.last_b1",  "view.last_b2",  "view.last_b3",  "view.last_b4",
966  "view.last_hp",
967  "view.secrets",  "view.kills",  "view.tsecrets",  "view.tkills",
968  "view.ambient",
969  "view.pointer_x",  "view.pointer_y",
970  "view.last_last_x",  "view.last_last_y",
971  "view.freeze_time"
972};
973
974
975int total_view_vars()
976{ return TVV;
977}
978
979char *get_view_var_name(int num)
980{ return vv_names[num]; }
981
982long view::get_view_var_value(int num)
983{
984  switch (num)
985  {
986    case V_CX1 : return cx1; break;
987    case V_CY1 : return cy1; break;
988    case V_CX2 : return cx2; break;
989    case V_CY2 : return cy2; break;
990    case V_SHIFT_DOWN : return shift_down; break;
991    case V_SHIFT_RIGHT : return shift_right; break;
992    case V_GOD : return god; break;
993    case V_PLAYER_NUMBER : return player_number; break;
994
995    case V_DRAW_SOLID : return draw_solid; break;
996    case V_CURRENT_WEAPON : return current_weapon; break;
997    case V_X_SUGGESTION : return x_suggestion; break;
998    case V_Y_SUGGESTION : return y_suggestion; break;
999    case V_B1_SUGGESTION : return b1_suggestion; break;
1000    case V_B2_SUGGESTION : return b2_suggestion; break;
1001    case V_B3_SUGGESTION : return b3_suggestion; break;
1002    case V_B4_SUGGESTION : return b4_suggestion; break;
1003
1004    case V_PAN_X : return pan_x; break;
1005    case V_PAN_Y : return pan_y; break;
1006    case V_NO_XLEFT : return no_xleft; break;
1007    case V_NO_XRIGHT : return no_xright; break;
1008    case V_NO_YTOP : return no_ytop; break;
1009    case V_NO_YBOTTOM : return no_ybottom; break;
1010    case V_LAST_X : return last_x; break;
1011    case V_LAST_Y : return last_y; break;
1012    case V_LAST_LEFT : return last_left; break;
1013    case V_LAST_RIGHT : return last_right; break;
1014    case V_LAST_UP : return last_up; break;
1015    case V_LAST_DOWN : return last_down; break;
1016    case V_LAST_B1 : return last_b1; break;
1017    case V_LAST_B2 : return last_b2; break;
1018    case V_LAST_B3 : return last_b3; break;
1019    case V_LAST_B4 : return last_b4; break;
1020    case V_LAST_HP : return last_hp; break;
1021    case V_SECRETS : return secrets; break;
1022    case V_KILLS : return kills; break;
1023    case V_TSECRETS : return tsecrets; break;
1024    case V_TKILLS : return tkills; break;
1025    case V_AMBIENT : return ambient; break;
1026    case V_POINTER_X : return pointer_x; break;
1027    case V_POINTER_Y : return pointer_y; break;
1028    case V_LAST_LAST_X : return last_last_x; break;
1029    case V_LAST_LAST_Y : return last_last_y; break;
1030    case V_FREEZE_TIME : return freeze_time; break;
1031  }
1032  return 0;
1033}
1034
1035
1036
1037long view::set_view_var_value(int num, long x)
1038{
1039  switch (num)
1040  {
1041    case V_CX1 : cx1=x; break;
1042    case V_CY1 : cy1=x; break;
1043    case V_CX2 : cx2=x; break;
1044    case V_CY2 : cy2=x; break;
1045    case V_SHIFT_DOWN : shift_down=x; break;
1046    case V_SHIFT_RIGHT : shift_right=x; break;
1047    case V_GOD : god=x; break;
1048    case V_PLAYER_NUMBER : { player_number=x; if (local_player()) sbar.associate(this); }  break;
1049
1050    case V_DRAW_SOLID : draw_solid=x; break;
1051    case V_CURRENT_WEAPON : { current_weapon=x; sbar.need_refresh(); } break;
1052    case V_X_SUGGESTION : x_suggestion=x; break;
1053    case V_Y_SUGGESTION : y_suggestion=x; break;
1054    case V_B1_SUGGESTION : b1_suggestion=x; break;
1055    case V_B2_SUGGESTION : b2_suggestion=x; break;
1056    case V_B3_SUGGESTION : b3_suggestion=x; break;
1057    case V_B4_SUGGESTION : b4_suggestion=x; break;
1058
1059    case V_PAN_X : pan_x=x; break;
1060    case V_PAN_Y : pan_y=x; break;
1061    case V_NO_XLEFT : no_xleft=x; break;
1062    case V_NO_XRIGHT : no_xright=x; break;
1063    case V_NO_YTOP : no_ytop=x; break;
1064    case V_NO_YBOTTOM : no_ybottom=x; break;
1065    case V_LAST_X : last_x=x; break;
1066    case V_LAST_Y : last_y=x; break;
1067    case V_LAST_LEFT : last_left=x; break;
1068    case V_LAST_RIGHT : last_right=x; break;
1069    case V_LAST_UP : last_up=x; break;
1070    case V_LAST_DOWN : last_down=x; break;
1071    case V_LAST_B1 : last_b1=x; break;
1072    case V_LAST_B2 : last_b2=x; break;
1073    case V_LAST_B3 : last_b3=x; break;
1074    case V_LAST_B4 : last_b4=x; break;
1075
1076    case V_LAST_HP : last_hp=x; break;
1077    case V_SECRETS : secrets=x; break;
1078    case V_KILLS : kills=x; break;
1079    case V_TSECRETS : tsecrets=x; break;
1080    case V_TKILLS : tkills=x; break;
1081    case V_AMBIENT : ambient=x; break;
1082    case V_POINTER_X : pointer_x=x; break;
1083    case V_POINTER_Y : pointer_y=x; break;
1084    case V_LAST_LAST_X : last_last_x=x; break;
1085    case V_LAST_LAST_Y : last_last_y=x; break;
1086    case V_FREEZE_TIME : freeze_time=x; break;
1087  }
1088  return 1;
1089}
1090
1091
1092void view::configure_for_area(area_controller *a)
1093{
1094  if (a->ambient>=0 && a->ambient!=ambient)
1095  {
1096    if (ambient>a->ambient)
1097    {
1098      ambient-=a->ambient_speed;
1099      if (ambient<a->ambient)
1100        ambient=a->ambient;
1101    }
1102    else
1103    {
1104      ambient+=a->ambient_speed;
1105      if (ambient>a->ambient)
1106        ambient=a->ambient;
1107    }   
1108  }
1109
1110  if (!view_shift_disabled)
1111  {
1112    if (a->view_xoff!=pan_x)
1113    {
1114      if (pan_x>a->view_xoff)
1115      {
1116        pan_x-=a->view_xoff_speed;
1117        if (pan_x<a->view_xoff)
1118        pan_x=a->view_xoff;
1119      }
1120      else
1121      {
1122        pan_x+=a->view_xoff_speed;
1123        if (pan_x>a->view_xoff)
1124        pan_x=a->view_xoff;
1125      }
1126    }
1127
1128    if (a->view_yoff!=pan_y)
1129    {
1130      if (pan_y>a->view_yoff)
1131      {
1132        pan_y-=a->view_yoff_speed;
1133        if (pan_y<a->view_yoff)
1134        pan_y=a->view_yoff;
1135      }
1136      else
1137      {
1138        pan_y+=a->view_yoff_speed;
1139        if (pan_y>a->view_yoff)
1140        pan_y=a->view_yoff;
1141      }
1142    } 
1143  }
1144}
1145
1146
1147void process_packet_commands(uchar *pk, int size)
1148{
1149  long sync_short=-1;
1150
1151  if (!size) return ;
1152  pk[size]=SCMD_END_OF_PACKET;
1153
1154  uchar cmd;
1155  int already_reloaded=0;
1156
1157
1158  do
1159  {
1160    cmd=*(pk++);
1161    switch (cmd)
1162    {
1163      case SCMD_WEAPON_CHANGE :
1164      case SCMD_SET_INPUT :
1165      case SCMD_VIEW_RESIZE :
1166      case SCMD_KEYPRESS :
1167      case SCMD_KEYRELEASE :
1168      case SCMD_EXT_KEYPRESS :
1169      case SCMD_EXT_KEYRELEASE :
1170      case SCMD_CHAT_KEYPRESS :
1171      {
1172        uchar player_num=*(pk++);
1173
1174        view *v=player_list;
1175        for (;v && v->player_number!=player_num;v=v->next);
1176        if (v)
1177        {
1178          if (v->player_number==player_num)
1179          v->process_input(cmd,pk);
1180        }     
1181        else
1182        {
1183          dprintf("Evil error : bad player number in packet\n");
1184          return ;
1185        }
1186      } break;
1187      case SCMD_RELOAD :
1188      {
1189        if (!already_reloaded)
1190        {
1191          net_reload();
1192          already_reloaded=1;
1193        }
1194      } break;
1195
1196      case SCMD_SYNC :
1197      {
1198        ushort x;
1199        memcpy(&x,pk,2);  pk+=2;
1200        x=lstl(x);
1201        if (demo_man.current_state()==demo_manager::PLAYING)
1202        sync_short=make_sync();
1203
1204        if (sync_short==-1)
1205        sync_short=x;
1206        else if (x!=sync_short && !already_reloaded)
1207        {
1208          dprintf("out of sync %d (packet=%d, calced=%d)\n",current_level->tick_counter(),x,sync_short);
1209          if (demo_man.current_state()==demo_manager::NORMAL)
1210            net_reload();
1211          already_reloaded=1;
1212        }
1213      } break;
1214      case SCMD_DELETE_CLIENT :
1215      {
1216        uchar player_num=*(pk++);
1217        view *v=player_list,*last=NULL;
1218        for (;v && v->player_number!=player_num;v=v->next)
1219        last=v;
1220        if (!v)
1221        dprintf("evil : delete client %d, but no such client\n");
1222        else
1223        {
1224
1225          // make a list of all objects associated with this player
1226          object_node *on=make_player_onodes(player_num);   
1227          while (on)
1228          {
1229            current_level->delete_object(on->me);
1230            object_node *last=on;
1231            on=on->next;
1232            delete last;
1233          }
1234
1235          v->focus=NULL;
1236          if (last)
1237          last->next=v->next;
1238          else player_list=player_list->next;
1239
1240          delete v;
1241        }
1242      } break;
1243      default :
1244      dprintf("Unknown net command %d\n",cmd);
1245
1246    }
1247  } while (cmd!=SCMD_END_OF_PACKET);
1248}
Note: See TracBrowser for help on using the repository browser.