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

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

lisp: implement LispString::Create.

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