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

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