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

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