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

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

game: slightly shift the game view so that the player gets more visibility
above them.

File size: 27.8 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, by
8 *  Jonathan Clark, or by Sam Hocevar.
9 */
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <unistd.h>
16
17#include "common.h"
18
19#include "game.h"
20
21#include "view.h"
22#include "lisp.h"
23#include "jwindow.h"
24#include "configuration.h"
25#include "scroller.h"
26#include "id.h"
27#include "dev.h"
28#include "jrand.h"
29#include "dprint.h"
30#include "transp.h"
31#include "clisp.h"
32#include "demo.h"
33#include "sbar.h"
34#include "nfserver.h"
35#include "chat.h"
36
37#define SHIFT_DOWN_DEFAULT 24
38#define SHIFT_RIGHT_DEFAULT 0
39
40extern int get_key_binding( char const *dir, int i );
41view *player_list=NULL;
42int morph_sel_frame_color;
43
44view::~view()
45{
46  if (local_player())
47    sbar.associate(NULL);
48
49  if (total_weapons)
50  {
51    free(weapons);
52    free(last_weapons);
53  }
54}
55
56
57extern uint8_t bright_tint[256];
58
59void view::add_ammo(int weapon_type, int total)
60{
61  if (weapon_type>=total_weapons || weapon_type<0)
62  {
63    printf("weapon out of range\n");
64    return ;
65  }
66  if (weapons[weapon_type]==-1) return ;   // don't have weapon yet, can't give ammo
67
68  weapons[weapon_type]+=total;
69  if (weapons[weapon_type]<0)
70    weapons[weapon_type]=0;
71
72  if (weapons[weapon_type]>999)
73    weapons[weapon_type]=999;
74
75  if (weapon_total(current_weapon)==0 && current_weapon)
76  {
77    suggest.send_weapon_change=1;
78    if (DEFINEDP(symbol_value(l_switch_to_powerful)) && symbol_value(l_switch_to_powerful))
79    {
80      int x=total_weapons-1;
81      while (x>0 && (x==3 || weapons[x]<=0)) x--;
82      suggest.new_weapon=x;
83    } else
84      suggest.new_weapon=0;
85  }
86
87}
88
89void view::give_weapon(int type)
90{
91  if (type>=total_weapons || type<0)
92  {
93    printf("weapon out of range\n");
94    return ;
95  }
96  if (weapons[type]==-1)
97  {
98    weapons[type]=0;
99    sbar.need_refresh();
100  }
101}
102
103int view::weapon_total(int type)
104{
105  if (type>=total_weapons || type<0)
106  {
107    printf("weapon out of range\n");
108    return 0;
109  }
110  if (god) return 100;
111  else if (weapons[type]==-1) return 0;
112  else return weapons[type];
113}
114
115
116int32_t view::xoff()
117{
118    if (!focus)
119        return pan_x;
120
121    return Max(0, last_x - (m_bb.x - m_aa.x + 1) / 2 + shift_right + pan_x);
122}
123
124int32_t view::interpolated_xoff()
125{
126    if (!focus)
127        return pan_x;
128
129    return Max(0, (last_last_x + last_x) / 2
130                    - (m_bb.x - m_aa.x + 1) / 2 + shift_right + pan_x);
131}
132
133
134int32_t view::yoff()
135{
136    if (!focus)
137        return pan_y;
138
139    return Max(0, last_y - (m_bb.y - m_aa.y + 1) / 2 - shift_down + pan_y);
140}
141
142
143int32_t view::interpolated_yoff()
144{
145    if (!focus)
146        return pan_y;
147
148    return Max(0, (last_last_y + last_y) / 2
149                    - (m_bb.y - m_aa.y + 1) / 2 - shift_down + pan_y);
150}
151
152
153void view::update_scroll()
154{
155  if (focus)
156  {
157    last_last_x=last_x;
158    last_last_y=last_y;
159    if (focus->x>last_x)
160    {
161      if (focus->x-last_x>=no_xright)
162        last_x=focus->x-no_xright;
163    } else if (focus->x<last_x)
164    {
165      if (last_x-focus->x>=no_xleft)
166        last_x=focus->x+no_xleft;
167    }
168    if (focus->y>last_y)
169    {
170      if (focus->y-last_y>=no_ybottom)
171        last_y=focus->y-no_ybottom;
172    } else if (focus->y<last_y)
173    {
174      if (last_y-focus->y>=no_ytop)
175        last_y=focus->y+no_ytop;
176    }
177  }
178}
179
180static char cur_user_name[20] = { 0 };
181
182char const *get_login()
183{
184    if (cur_user_name[0])
185        return cur_user_name;
186
187#if defined __CELLOS_LV2__
188    /* FIXME: retrieve login name */
189    return "Player";
190#else
191    char const *login = getlogin();
192    return login ? login : "unknown";
193#endif
194}
195
196void set_login(char const *name)
197{
198    strncpy(cur_user_name, name, 20);
199}
200
201view::view(game_object *Focus, view *Next, int number)
202{
203  chat_buf[0]=0;
204
205  draw_solid=-1;
206  no_xleft=0;
207  no_xright=0;
208  no_ytop=0;
209  no_ybottom=0;
210  if (Focus)
211  {
212    last_x=Focus->x;
213    last_y=Focus->y;
214  } else
215  {
216    last_x=last_y=0;
217  }
218
219  last_last_x=last_x;
220  last_last_y=last_y;
221  last_hp=last_ammo=-1;
222  last_type=-1;
223  tsecrets=secrets=0;
224  tkills=kills=0;
225
226  reset_keymap();
227
228  ambient=32;
229  current_weapon=0;
230
231  strcpy(name,get_login());
232  suggest.send_view=0;
233  suggest.send_weapon_change=0;
234
235
236  god=0;
237
238  player_number=number;
239    m_aa = vec2i(0);
240    m_bb = vec2i(100);
241  focus=Focus;
242  next=Next;
243  shift_down=SHIFT_DOWN_DEFAULT;
244  shift_right=SHIFT_RIGHT_DEFAULT;
245  x_suggestion=0;
246  y_suggestion=0;
247  b1_suggestion=0;
248  b2_suggestion=0;
249  b3_suggestion=0;
250  b4_suggestion=0;
251  pointer_x=0;
252  pointer_y=0;
253
254  pan_x=0;
255  pan_y=0;
256  last_type=0;
257  freeze_time=0;
258
259  if (total_weapons)
260  {
261    weapons=(int32_t *)malloc(total_weapons*sizeof(int32_t));
262    last_weapons=(int32_t *)malloc(total_weapons*sizeof(int32_t));
263    memset(weapons,0xff,total_weapons*sizeof(int32_t));   // set all to -1
264    memset(last_weapons,0xff,total_weapons*sizeof(int32_t));   // set all to -1
265  }
266
267  if (total_weapons)
268    weapons[0]=0;
269  if (local_player())
270    sbar.associate(this);
271  set_tint(number);
272  set_team(-1);
273  sbar.need_refresh();
274}
275
276int32_t view::x_center()
277{
278    return focus ? focus->x : (m_aa.x + m_bb.x) / 2;
279}
280
281int32_t view::y_center()
282{
283    return focus ? focus->y : (m_aa.y + m_bb.y) / 2;
284}
285
286void view::draw_character_damage()
287{
288  if (focus && drawable())
289  {
290    if (last_hp!=focus->hp()) draw_hp();
291    int i;
292    for (i=0; i<total_weapons; i++)
293      if (weapons[i]!=last_weapons[i])
294      {
295    last_weapons[i]=weapons[i];
296        sbar.draw_ammo(main_screen,i,weapons[i],current_weapon==i);
297      }
298  }
299}
300
301
302
303uint16_t make_sync()
304{
305  uint16_t x=0;
306  if (!current_level) return 0;
307  if (current_level)
308  {
309    view *f=player_list;
310    for (; f; f=f->next)
311    {
312      if (f->focus)
313      {
314    x^=(f->focus->x&0xffff);
315    x^=(f->focus->y&0xffff);
316      }
317    }
318  }
319  x^=rand_on;
320
321  return x;
322}
323
324
325
326void view::get_input()
327{
328    int sug_x,sug_y,sug_b1,sug_b2,sug_b3,sug_b4;
329    vec2i sug_p(0, 0);
330
331// NOTE:(AK) I have commented this out so we don't use the lisp
332//        file "input.lsp" to get our key mappings.
333/*    if( DEFINEDP( symbol_function( l_get_local_input ) ) )
334    {
335        void *ret = ((LSymbol *)l_get_local_input->EvalFunction(NULL);
336        sug_x = lnumber_value( CAR( ret ) );
337        ret = CDR( ret );
338        sug_y = lnumber_value( CAR( ret ) );
339        ret = CDR( ret );
340        if( CAR( ret ) )
341            sug_b1 = 1;
342        else
343            sug_b1 = 0;
344        ret = CDR( ret );
345        if( CAR( ret ) )
346            sug_b2 = 1;
347        else
348            sug_b2 = 0;
349        ret = CDR( ret );
350        int x = lnumber_value( CAR( ret ) );
351        ret = CDR( ret );
352        if( x < 0 )
353            sug_b3 = 1;
354        else
355            sug_b3 = 0;
356        if( x > 0 )
357            sug_b4 = 1;
358        else sug_b4 = 0;
359
360        int32_t bx = lnumber_value( CAR( ret ) );
361        ret = CDR( ret );
362        int32_t by = lnumber_value( CAR( ret ) );
363        ret = CDR( ret );
364        the_game->mouse_to_game( bx, by, sug_px, sug_py, this );
365
366    }
367    else*/
368    {
369        get_movement( 0, sug_x, sug_y, sug_b1, sug_b2, sug_b3, sug_b4 );
370        if( focus )
371        {
372            sug_p = the_game->MouseToGame(last_demo_mpos);
373            if(last_demo_mbut & 1)
374                sug_b2 = 1;
375            if(last_demo_mbut & 2)
376                sug_b1 = 1;
377        }
378    }
379
380    if( view_changed() )
381    {
382        base->packet.write_uint8( SCMD_VIEW_RESIZE );
383        base->packet.write_uint8( player_number );
384        base->packet.write_uint32( suggest.cx1 );
385        base->packet.write_uint32( suggest.cy1 );
386        base->packet.write_uint32( suggest.cx2 );
387        base->packet.write_uint32( suggest.cy2 );
388
389        base->packet.write_uint32( suggest.pan_x );
390        base->packet.write_uint32( suggest.pan_y );
391        base->packet.write_uint32( suggest.shift_down );
392        base->packet.write_uint32( suggest.shift_right );
393    }
394
395    if( weapon_changed() )
396    {
397        base->packet.write_uint8( SCMD_WEAPON_CHANGE );
398        base->packet.write_uint8( player_number );
399        base->packet.write_uint32( suggest.new_weapon );
400    }
401
402    base->packet.write_uint8( SCMD_SET_INPUT );
403    base->packet.write_uint8( player_number );
404
405    uint8_t mflags = 0;
406    if( sug_x > 0 )
407        mflags |= 1;
408    else if ( sug_x < 0 )
409        mflags |= 2;
410
411    if( sug_y > 0 )
412        mflags |= 4;
413    else if( sug_y < 0 )
414        mflags |= 8;
415
416    if( sug_b1 )
417        mflags |= 16;
418    if( sug_b2 )
419        mflags |= 32;
420    if( sug_b3 )
421        mflags |= 64;
422    if( sug_b4 )
423        mflags |= 128;
424
425    base->packet.write_uint8(mflags);
426    base->packet.write_uint16((uint16_t)sug_p.x);
427    base->packet.write_uint16((uint16_t)sug_p.y);
428}
429
430
431void view::add_chat_key(int key)  // return string if buf is complete
432{
433  int len=strlen(chat_buf);
434  if (key==JK_BACKSPACE)
435  {
436    if (len)
437    {
438      chat_buf[len-1]=0;
439      if (local_player() && chat)
440        chat->draw_user(chat_buf);
441    }
442  } else if (key!=JK_ENTER)
443  {
444    chat_buf[len]=key;
445    chat_buf[len+1]=0;
446    if (local_player() && chat)
447      chat->draw_user(chat_buf);
448  }
449
450  if (len>38 || key==JK_ENTER)
451  {
452    if (DEFINEDP(l_chat_input->GetFunction()))
453    {
454      game_object *o=current_object;
455      current_object=focus;
456
457      void *m = LSpace::Tmp.Mark();
458      void *list=NULL;
459      push_onto_list(LString::Create(chat_buf),list);
460      ((LSymbol *)l_chat_input)->EvalFunction(list);
461      LSpace::Tmp.Restore(m);
462
463      current_object=o;
464
465    } else
466    {
467      if (chat)
468        chat->put_all(chat_buf);
469    }
470    chat_buf[0]=0;
471    if (local_player() && chat)
472      chat->draw_user(chat_buf);
473  }
474}
475
476int view::process_input(char cmd, uint8_t *&pk)   // return 0 if something went wrong
477{
478  switch (cmd)
479  {
480    case SCMD_CHAT_KEYPRESS :
481    {
482      add_chat_key(*(pk++));
483    } break;
484    case SCMD_VIEW_RESIZE :
485    {
486      int32_t x[8];
487      memcpy(x,pk,8*4);  pk+=8*4;
488      m_aa = vec2i(lltl(x[0]), lltl(x[1]));
489      m_bb = vec2i(lltl(x[2]), lltl(x[3]));
490
491      pan_x=lltl(x[4]);
492      pan_y=lltl(x[5]);
493      shift_down=lltl(x[6]);
494      shift_right=lltl(x[7]);
495      if (small_render)
496          small_render->Scale(m_bb - m_aa + vec2i(1));
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      int32_t 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      uint8_t 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      uint16_t p[2];
533      memcpy(p,pk,2*2);  pk+=2*2;
534
535      pointer_x=(int16_t)(lstl(p[0]));
536      pointer_y=(int16_t)(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( main_screen, focus->hp() );
696    }
697    else
698    {
699        sbar.draw_health( main_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 (main_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->m_aa = vec2i(f->suggest.cx1, f->suggest.cy1);
745      f->m_bb = vec2i(f->suggest.cx2, f->suggest.cy2);
746      f->suggest.send_view = 0;
747    }
748    y+=h;
749      }
750    }
751  }
752
753}
754
755
756void set_local_players(int total)
757{
758  int rdw=0;
759  if (total<1) return ;
760
761  view *last=NULL;
762  for (view *f=player_list; f; f=f->next)
763  {
764    if (total && f->local_player())
765      total--;
766    else if (!total && f->local_player())  // too many local players, delete this one
767    {
768      view *n=last->next;
769      while (n && !n->local_player()) n=n->next;  // find next local player
770
771      if (last)
772        last->next=n;
773      else
774      {
775    if (n)    // make sure we have at least one local player
776          player_list=n;
777      }
778      last=f;
779      rdw=1;
780    }
781  }
782
783  while (total)   // see if we need to add new players
784  {
785    game_object *o=create(current_start_type,50,50);
786    view *v;
787    if (!player_list)
788    {
789      player_list=new view(o,NULL,0);
790      v=player_list;
791    }
792    else
793    {
794      view *f=player_list;
795      for (; f && f->next; f=f->next);
796      f->next=new view(o,NULL,f->player_number+1);
797      v=f->next;
798    }
799    v->m_aa = vec2i(320 / 2 - 155, 200 / 2 - 95);
800    v->m_bb = vec2i(320 / 2 + 155, 200 / 2 + total_weapons ? 60 : 95);
801    v->focus->set_controller(v);
802    total--;
803    rdw=1;
804  }
805  if (rdw)
806    recalc_local_view_space();
807}
808
809
810int total_local_players()
811{
812  int t=0;
813  for (view *f=player_list; f; f=f->next)
814    if (f->local_player()) t++;
815  return t;
816}
817
818void view::set_input(int cx, int cy, int b1, int b2, int b3, int b4, int px, int py)
819{
820    x_suggestion=cx;
821    y_suggestion=cy;
822    b1_suggestion=b1;
823    b2_suggestion=b2;
824    b3_suggestion=b3;
825    b4_suggestion=b4;
826    pointer_x=px;
827    pointer_y=py;
828}
829
830
831
832void view::reset_player()
833{
834  if (focus)
835  {
836
837    game_object *start=current_level ? current_level->get_random_start(320,focus->controller()) : 0;
838    focus->defaults();
839    if (start)
840    {
841      focus->x=start->x;
842      focus->y=start->y;
843      dprintf("reset player position to %d %d\n",start->x,start->y);
844    }
845    focus->set_state(stopped);
846    focus->set_tint(_tint);
847    focus->set_team(_team);
848    memset(weapons,0xff,total_weapons*sizeof(int32_t));
849    memset(last_weapons,0xff,total_weapons*sizeof(int32_t));
850
851    shift_down=SHIFT_DOWN_DEFAULT;
852    shift_right=SHIFT_RIGHT_DEFAULT;
853
854    if (total_weapons)
855      weapons[0]=0;  // give him the first weapon
856    current_weapon=0;
857
858    memset(focus->lvars,0,figures[focus->otype]->tv*4);
859    focus->set_aistate(0);
860    if (figures[focus->otype]->get_fun(OFUN_CONSTRUCTOR))
861    {
862      game_object *o=current_object;
863      current_object=focus;
864      ((LSymbol *)figures[focus->otype]->get_fun(OFUN_CONSTRUCTOR))->EvalUserFunction(NULL);
865      current_object=o;
866    }
867    sbar.redraw(main_screen);
868
869    int i;
870    for (i=0; i<focus->total_objects(); i++)   // reset the vars for the attached objects
871    {
872      game_object *o=focus->get_object(i);
873      memset(o->lvars,0,figures[o->otype]->tv*4);
874    }
875
876  }
877}
878
879
880
881
882
883object_node *make_player_onodes(int player_num)
884{
885  object_node *first=NULL,*last=NULL;
886  for (view *o=player_list; o; o=o->next)
887  {
888    if (o->focus && (player_num==-1 || o->player_number==player_num))
889    {
890      if (!object_to_number_in_list(o->focus,first))
891      {
892    object_node *q=new object_node(o->focus,NULL);
893    if (first)
894      last->next=q;
895    else first=q;
896    last=q;
897      }
898      for (int i=0; i<o->focus->total_objects(); i++)
899      {
900    game_object *p=o->focus->get_object(i);
901
902    if (!object_to_number_in_list(p,first))
903    {
904      object_node *q=new object_node(p,NULL);
905      if (first)
906        last->next=q;
907      else first=q;
908      last=q;
909    }
910      }
911    }
912  }
913  return first;
914}
915
916
917
918
919enum { V_CX1, V_CY1, V_CX2, V_CY2,
920       V_SHIFT_DOWN, V_SHIFT_RIGHT,
921       V_GOD,
922       V_PLAYER_NUMBER,
923       V_DRAW_SOLID,
924       V_LIVES,
925       V_CURRENT_WEAPON,
926       V_X_SUGGESTION, V_Y_SUGGESTION, V_B1_SUGGESTION, V_B2_SUGGESTION, V_B3_SUGGESTION, V_B4_SUGGESTION,
927       V_PAN_X, V_PAN_Y,
928       V_NO_XLEFT, V_NO_XRIGHT, V_NO_YTOP, V_NO_YBOTTOM,
929       V_LAST_X, V_LAST_Y, V_LAST_LEFT, V_LAST_RIGHT, V_LAST_UP, V_LAST_DOWN,
930       V_LAST_B1, V_LAST_B2, V_LAST_B3, V_LAST_B4,
931       V_LAST_HP,
932       V_SECRETS, V_KILLS, V_TSECRETS, V_TKILLS,
933       V_AMBIENT,
934       V_POINTER_X, V_POINTER_Y,
935       V_LAST_LAST_X, V_LAST_LAST_Y,
936       V_FREEZE_TIME };
937
938#define TVV (V_FREEZE_TIME+1)
939
940static char const *vv_names[TVV] =
941{
942    "view.cx1",  "view.cy1",  "view.cx2",  "view.cy2",
943    "view.shift_down",  "view.shift_right",
944    "view.god",
945    "view.player_number",
946    "view.draw_solid",
947    "view.lives",
948    "view.current_weapon",
949    "view.x_suggestion",  "view.y_suggestion",
950    "view.b1_suggestion",  "view.b2_suggestion",  "view.b3_suggestion",  "view.b4_suggestion",
951    "view.pan_x",  "view.pan_y",
952    "view.no_xleft",  "view.no_xright",  "view.no_ytop",  "view.no_ybottom",
953    "view.last_x",  "view.last_y",  "view.last_left",  "view.last_right",  "view.last_up",  "view.last_down",
954    "view.last_b1",  "view.last_b2",  "view.last_b3",  "view.last_b4",
955    "view.last_hp",
956    "view.secrets",  "view.kills",  "view.tsecrets",  "view.tkills",
957    "view.ambient",
958    "view.pointer_x",  "view.pointer_y",
959    "view.last_last_x",  "view.last_last_y",
960    "view.freeze_time"
961};
962
963
964int total_view_vars()
965{ return TVV;
966}
967
968char const *get_view_var_name(int num)
969{ return vv_names[num]; }
970
971int32_t view::get_view_var_value(int num)
972{
973  switch (num)
974  {
975    case V_CX1 : return m_aa.x; break;
976    case V_CY1 : return m_aa.y; break;
977    case V_CX2 : return m_bb.x; break;
978    case V_CY2 : return m_bb.y; break;
979    case V_SHIFT_DOWN : return shift_down; break;
980    case V_SHIFT_RIGHT : return shift_right; break;
981    case V_GOD : return god; break;
982    case V_PLAYER_NUMBER : return player_number; break;
983
984    case V_DRAW_SOLID : return draw_solid; break;
985    case V_CURRENT_WEAPON : return current_weapon; break;
986    case V_X_SUGGESTION : return x_suggestion; break;
987    case V_Y_SUGGESTION : return y_suggestion; break;
988    case V_B1_SUGGESTION : return b1_suggestion; break;
989    case V_B2_SUGGESTION : return b2_suggestion; break;
990    case V_B3_SUGGESTION : return b3_suggestion; break;
991    case V_B4_SUGGESTION : return b4_suggestion; break;
992
993    case V_PAN_X : return pan_x; break;
994    case V_PAN_Y : return pan_y; break;
995    case V_NO_XLEFT : return no_xleft; break;
996    case V_NO_XRIGHT : return no_xright; break;
997    case V_NO_YTOP : return no_ytop; break;
998    case V_NO_YBOTTOM : return no_ybottom; break;
999    case V_LAST_X : return last_x; break;
1000    case V_LAST_Y : return last_y; break;
1001    case V_LAST_LEFT : return last_left; break;
1002    case V_LAST_RIGHT : return last_right; break;
1003    case V_LAST_UP : return last_up; break;
1004    case V_LAST_DOWN : return last_down; break;
1005    case V_LAST_B1 : return last_b1; break;
1006    case V_LAST_B2 : return last_b2; break;
1007    case V_LAST_B3 : return last_b3; break;
1008    case V_LAST_B4 : return last_b4; break;
1009    case V_LAST_HP : return last_hp; break;
1010    case V_SECRETS : return secrets; break;
1011    case V_KILLS : return kills; break;
1012    case V_TSECRETS : return tsecrets; break;
1013    case V_TKILLS : return tkills; break;
1014    case V_AMBIENT : return ambient; break;
1015    case V_POINTER_X : return pointer_x; break;
1016    case V_POINTER_Y : return pointer_y; break;
1017    case V_LAST_LAST_X : return last_last_x; break;
1018    case V_LAST_LAST_Y : return last_last_y; break;
1019    case V_FREEZE_TIME : return freeze_time; break;
1020  }
1021  return 0;
1022}
1023
1024
1025
1026int32_t view::set_view_var_value(int num, int32_t x)
1027{
1028  switch (num)
1029  {
1030    case V_CX1 : m_aa.x = x; break;
1031    case V_CY1 : m_aa.y = x; break;
1032    case V_CX2 : m_bb.x = x; break;
1033    case V_CY2 : m_bb.y = x; break;
1034    case V_SHIFT_DOWN : shift_down=x; break;
1035    case V_SHIFT_RIGHT : shift_right=x; break;
1036    case V_GOD : god=x; break;
1037    case V_PLAYER_NUMBER : { player_number=x; if (local_player()) sbar.associate(this); }  break;
1038
1039    case V_DRAW_SOLID : draw_solid=x; break;
1040    case V_CURRENT_WEAPON : { current_weapon=x; sbar.need_refresh(); } break;
1041    case V_X_SUGGESTION : x_suggestion=x; break;
1042    case V_Y_SUGGESTION : y_suggestion=x; break;
1043    case V_B1_SUGGESTION : b1_suggestion=x; break;
1044    case V_B2_SUGGESTION : b2_suggestion=x; break;
1045    case V_B3_SUGGESTION : b3_suggestion=x; break;
1046    case V_B4_SUGGESTION : b4_suggestion=x; break;
1047
1048    case V_PAN_X : pan_x=x; break;
1049    case V_PAN_Y : pan_y=x; break;
1050    case V_NO_XLEFT : no_xleft=x; break;
1051    case V_NO_XRIGHT : no_xright=x; break;
1052    case V_NO_YTOP : no_ytop=x; break;
1053    case V_NO_YBOTTOM : no_ybottom=x; break;
1054    case V_LAST_X : last_x=x; break;
1055    case V_LAST_Y : last_y=x; break;
1056    case V_LAST_LEFT : last_left=x; break;
1057    case V_LAST_RIGHT : last_right=x; break;
1058    case V_LAST_UP : last_up=x; break;
1059    case V_LAST_DOWN : last_down=x; break;
1060    case V_LAST_B1 : last_b1=x; break;
1061    case V_LAST_B2 : last_b2=x; break;
1062    case V_LAST_B3 : last_b3=x; break;
1063    case V_LAST_B4 : last_b4=x; break;
1064
1065    case V_LAST_HP : last_hp=x; break;
1066    case V_SECRETS : secrets=x; break;
1067    case V_KILLS : kills=x; break;
1068    case V_TSECRETS : tsecrets=x; break;
1069    case V_TKILLS : tkills=x; break;
1070    case V_AMBIENT : ambient=x; break;
1071    case V_POINTER_X : pointer_x=x; break;
1072    case V_POINTER_Y : pointer_y=x; break;
1073    case V_LAST_LAST_X : last_last_x=x; break;
1074    case V_LAST_LAST_Y : last_last_y=x; break;
1075    case V_FREEZE_TIME : freeze_time=x; break;
1076  }
1077  return 1;
1078}
1079
1080
1081void view::configure_for_area(area_controller *a)
1082{
1083  if (a->ambient>=0 && a->ambient!=ambient)
1084  {
1085    if (ambient>a->ambient)
1086    {
1087      ambient-=a->ambient_speed;
1088      if (ambient<a->ambient)
1089        ambient=a->ambient;
1090    }
1091    else
1092    {
1093      ambient+=a->ambient_speed;
1094      if (ambient>a->ambient)
1095        ambient=a->ambient;
1096    }
1097  }
1098
1099  if (!view_shift_disabled)
1100  {
1101    if (a->view_xoff!=pan_x)
1102    {
1103      if (pan_x>a->view_xoff)
1104      {
1105    pan_x-=a->view_xoff_speed;
1106    if (pan_x<a->view_xoff)
1107        pan_x=a->view_xoff;
1108      }
1109      else
1110      {
1111    pan_x+=a->view_xoff_speed;
1112    if (pan_x>a->view_xoff)
1113        pan_x=a->view_xoff;
1114      }
1115    }
1116
1117    if (a->view_yoff!=pan_y)
1118    {
1119      if (pan_y>a->view_yoff)
1120      {
1121    pan_y-=a->view_yoff_speed;
1122    if (pan_y<a->view_yoff)
1123        pan_y=a->view_yoff;
1124      }
1125      else
1126      {
1127    pan_y+=a->view_yoff_speed;
1128    if (pan_y>a->view_yoff)
1129        pan_y=a->view_yoff;
1130      }
1131    }
1132  }
1133}
1134
1135
1136void process_packet_commands(uint8_t *pk, int size)
1137{
1138  int32_t sync_uint16=-1;
1139
1140  if (!size) return ;
1141  pk[size]=SCMD_END_OF_PACKET;
1142
1143  uint8_t cmd;
1144  int already_reloaded=0;
1145
1146
1147  do
1148  {
1149    cmd=*(pk++);
1150    switch (cmd)
1151    {
1152      case SCMD_WEAPON_CHANGE :
1153      case SCMD_SET_INPUT :
1154      case SCMD_VIEW_RESIZE :
1155      case SCMD_KEYPRESS :
1156      case SCMD_KEYRELEASE :
1157      case SCMD_EXT_KEYPRESS :
1158      case SCMD_EXT_KEYRELEASE :
1159      case SCMD_CHAT_KEYPRESS :
1160      {
1161    uint8_t player_num=*(pk++);
1162
1163    view *v=player_list;
1164    for (; v && v->player_number!=player_num; v=v->next);
1165    if (v)
1166    {
1167      if (v->player_number==player_num)
1168      v->process_input(cmd,pk);
1169    }
1170    else
1171    {
1172      dprintf("Evil error : bad player number in packet\n");
1173      return ;
1174    }
1175      } break;
1176      case SCMD_RELOAD :
1177      {
1178    if (!already_reloaded)
1179    {
1180      net_reload();
1181      already_reloaded=1;
1182    }
1183      } break;
1184
1185      case SCMD_SYNC :
1186      {
1187    uint16_t x;
1188    memcpy(&x,pk,2);  pk+=2;
1189    x=lstl(x);
1190    if (demo_man.current_state()==demo_manager::PLAYING)
1191    sync_uint16=make_sync();
1192
1193    if (sync_uint16==-1)
1194    sync_uint16=x;
1195    else if (x!=sync_uint16 && !already_reloaded)
1196    {
1197      dprintf("out of sync %d (packet=%d, calced=%d)\n",current_level->tick_counter(),x,sync_uint16);
1198      if (demo_man.current_state()==demo_manager::NORMAL)
1199        net_reload();
1200      already_reloaded=1;
1201    }
1202      } break;
1203      case SCMD_DELETE_CLIENT :
1204      {
1205    uint8_t player_num=*(pk++);
1206    view *v=player_list,*last=NULL;
1207    for (; v && v->player_number!=player_num; v=v->next)
1208    last=v;
1209    if (!v)
1210    dprintf("evil : delete client %d, but no such client\n");
1211    else
1212    {
1213
1214      // make a list of all objects associated with this player
1215      object_node *on=make_player_onodes(player_num);
1216      while (on)
1217      {
1218        current_level->delete_object(on->me);
1219        object_node *last=on;
1220        on=on->next;
1221        delete last;
1222      }
1223
1224      v->focus=NULL;
1225      if (last)
1226      last->next=v->next;
1227      else player_list=player_list->next;
1228
1229      delete v;
1230    }
1231      } break;
1232      default :
1233      dprintf("Unknown net command %d\n",cmd);
1234
1235    }
1236  } while (cmd!=SCMD_END_OF_PACKET);
1237}
1238
1239void view::set_tint(int tint)
1240{
1241    if(tint < 0)
1242        tint = 0;
1243    _tint = tint;
1244    focus->set_tint(tint);
1245}
1246
1247int view::get_tint()
1248{
1249    return _tint;
1250}
1251
1252void view::set_team(int team)
1253{
1254    if(team < 0)
1255        team = 0;
1256    _team = team;
1257    focus->set_team(team);
1258}
1259
1260int view::get_team()
1261{
1262    return _team;
1263}
1264
Note: See TracBrowser for help on using the repository browser.