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

Last change on this file since 682 was 682, checked in by Sam Hocevar, 8 years ago

core: rename vec2i to ivec2 and update matrix.h from Lol Engine.

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