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

Last change on this file since 643 was 643, checked in by Sam Hocevar, 9 years ago

imlib: refactor Event and EventHandler?.

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