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

Last change on this file since 513 was 513, checked in by Sam Hocevar, 11 years ago

imlib: some more vec2i transition for simplicity.

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