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

Last change on this file since 497 was 497, checked in by Sam Hocevar, 10 years ago

lisp: implement LSymbol::EvalFunction? and ensure all local pointers are
protected against collection.

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