source: abuse/branches/lol/src/view.cpp @ 732

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

build: SDL2 compilation fixes.

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