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

Last change on this file since 524 was 524, checked in by Sam Hocevar, 12 years ago

core: Get rid of mostly useless headers, move endianness handling to
common.h (and rewrite functions so that they do not need the SDL headers)
and move a few functions out of sdlport's video.cpp. These functions
were in the original video.cpp (which reappears) and shouldn't be part
of the SDL port.

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