source: abuse/trunk/src/newlight.cpp

Last change on this file was 555, checked in by Sam Hocevar, 8 years ago

ps3: make everything compile on the PS3. Of course, nothing links yet
because so much support is missing.

File size: 20.1 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, by
8 *  Jonathan Clark, or by Sam Hocevar.
9 */
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <stdlib.h>
16
17#include "light.h"
18#include "image.h"
19#include "video.h"
20#include "palette.h"
21#include "timing.h"
22#include "specs.h"
23#include "dprint.h"
24#include "filter.h"
25#include "video.h"
26
27light_source *first_light_source=NULL;
28unsigned char *white_light,*green_light;
29unsigned short min_light_level=0;
30extern int vmode;
31
32int light_detail=MEDIUM_DETAIL;
33
34long light_to_number(light_source *l)
35{
36    if( !l ) return 0;
37    int x = 1;
38    light_source *s;
39    for (s = first_light_source; s; s = s->next, x++)
40        if (s == l) return x;
41    return 0;
42}
43
44
45light_source *number_to_light(long x)
46{
47    if (x == 0) return NULL;
48    x--;
49    light_source *s;
50    for (s = first_light_source; x && s; x--, s = s->next);
51    return s;
52}
53
54light_source *light_source::copy()
55{
56    next = new light_source(type,x,y,inner_radius,outer_radius,xshift,yshift,next);
57    return next;
58}
59
60void delete_all_lights()
61{
62    while (first_light_source)
63    {
64        light_source *p = first_light_source;
65        first_light_source = first_light_source->next;
66        delete p;
67    }
68}
69
70void delete_light(light_source *which)
71{
72  if (which==first_light_source)
73  {
74    first_light_source=first_light_source->next;
75    delete which;
76  }
77  else
78  {
79    for (light_source *f=first_light_source; f->next!=which && f; f=f->next);
80    if (f)
81    {
82      f->next=which->next;
83      delete which;
84    }
85  }
86}
87
88void light_source::calc_range()
89{
90  switch (type)
91  {
92    case 0 :
93    { x1=x-(outer_radius>>xshift); y1=y-(outer_radius>>yshift);
94      x2=x+(outer_radius>>xshift); y2=y+(outer_radius>>yshift);
95    } break;
96    case 1 :
97    { x1=x-(outer_radius>>xshift); y1=y-(outer_radius>>yshift);
98      x2=x+(outer_radius>>xshift); y2=y;
99    } break;
100    case 2 :
101    { x1=x-(outer_radius>>xshift); y1=y;
102      x2=x+(outer_radius>>xshift); y2=y+(outer_radius>>yshift);
103    } break;
104    case 3 :
105    { x1=x; y1=y-(outer_radius>>yshift);
106      x2=x+(outer_radius>>xshift); y2=y+(outer_radius>>yshift);
107    } break;
108    case 4 :
109    { x1=x-(outer_radius>>xshift); y1=y-(outer_radius>>yshift);
110      x2=x; y2=y+(outer_radius>>yshift);
111    } break;
112
113
114    case 5 :
115    { x1=x; y1=y-(outer_radius>>yshift);
116      x2=x+(outer_radius>>xshift); y2=y;
117    } break;
118    case 6 :
119    { x1=x-(outer_radius>>xshift); y1=y-(outer_radius>>yshift);
120      x2=x; y2=y;
121    } break;
122    case 7 :
123    { x1=x-(outer_radius>>xshift); y1=y;
124      x2=x; y2=y+(outer_radius>>yshift);
125    } break;
126    case 8 :
127    { x1=x; y1=y;
128      x2=x+(outer_radius>>xshift); y2=y+(outer_radius>>yshift);
129    } break;
130    case 9 :
131    {
132      x1=x;
133      y1=y;
134      x2=x+xshift;
135      y2=y+yshift;
136    } break;
137
138  }
139  mul_div=(1<<16)/(outer_radius-inner_radius)*64;
140}
141
142light_source::light_source(char Type, long X, long Y, long Inner_radius,
143               long Outer_radius, long Xshift,  long Yshift, light_source *Next)
144{
145  type=Type;
146  x=X; y=Y;
147  inner_radius=Inner_radius;
148  outer_radius=Outer_radius;
149  next=Next;
150  known=0;
151  xshift=Xshift;
152  yshift=Yshift;
153  calc_range();
154}
155
156light_source *add_light_source(char type, long x, long y,
157                   long inner, long outer, long xshift, long yshift)
158{
159    first_light_source = new light_source(type,x,y,inner,outer,xshift,yshift,first_light_source);
160    return first_light_source;
161}
162
163
164#define TTINTS 9
165uchar *tints[TTINTS];
166
167void calc_tint(uchar *tint, int rs, int gs, int bs, int ra, int ga, int ba, palette *pal)
168{
169  palette npal;
170  memset(npal.addr(),0,256);
171
172  for (int i=0; i<256; i++)
173  {
174    npal.set(i,(int)rs,(int)gs,(int)bs);
175    rs+=ra; if (rs>255) rs=255; if (rs<0) rs=0;
176    gs+=ga; if (gs>255) gs=255; if (gs<0) gs=0;
177    bs+=ba; if (bs>255) bs=255; if (bs<0) bs=0;
178  }
179  filter f(pal,&npal);
180  filter f2(&npal,pal);
181
182  for (i=0; i<256; i++,tint++)
183    *tint=f2.get_mapping(f.get_mapping(i));
184}
185
186
187void calc_light_table(palette *pal)
188{
189  white_light=(unsigned char *)malloc(256*64);
190  green_light=(unsigned char *)malloc(256*64);
191  for (int i=0; i<TTINTS; i++)
192      tints[i]=(uchar *)malloc(256);
193
194  jFILE fp("light.tbl","rb");
195  int recalc=0;
196  if (fp.open_failure()) recalc=1;
197  else
198  {
199    if (fp.read_uint16()!=calc_crc((unsigned char *)pal->addr(),768))
200      recalc=1;
201    else
202    {
203      fp.read(white_light,256*64);
204      fp.read(green_light,256*64);
205      for (i=0; i<TTINTS; i++)
206        fp.read(tints[i],256);
207    }
208  }
209
210  if (recalc)
211  {
212    fprintf(stderr,"Palette has changed, recalculating light table...\n");
213    fprintf(stderr,"white : ");
214    for (int color=0; color<256; color++)
215    {
216      unsigned char r,g,b;
217      pal->get(color,r,g,b);
218      if (color%16==0)
219        fprintf(stderr,"%d ",color);
220      for (int intensity=63; intensity>=0; intensity--)
221      {
222    if (r>0 || g>0 || b>0)
223          white_light[intensity*256+color]=pal->find_closest(r,g,b);
224    else
225          white_light[intensity*256+color]=0;
226    if (r) r--;  if (g) g--;  if (b) b--;
227      }
228    }
229
230    fprintf(stderr,"green : ");
231    for (color=0; color<256; color++)
232    {
233      unsigned char r,g,b;
234      pal->get(color,r,g,b);
235      r=r*3/5; b=b*3/5; g+=7; if (g>255) g=255;
236      if (color%16==0)
237        fprintf(stderr,"%d ",color);
238      for (int intensity=63; intensity>=0; intensity--)
239      {
240    if (r>0 || g>0 || b>0)
241          green_light[intensity*256+color]=pal->find_closest(r,g,b);
242    else
243          green_light[intensity*256+color]=0;
244    if (r) r--;
245    if ((intensity&1)==1)
246      if (g) g--;
247    if (b) b--;
248      }
249    }
250
251    dprintf("\ncalculating tints : \n");
252    uchar t[TTINTS*6]={ 0,0,0,0,0,0, // normal
253                   0,0,0,1,0,0,     // red
254           0,0,0,1,1,0,     // yellow
255           0,0,0,1,0,1,     // purple
256           0,0,0,1,1,1,     // gray
257           0,0,0,0,1,0,     // green
258           0,0,0,0,0,1,     // blue
259           0,0,0,0,1,1,     // cyan
260
261
262
263
264
265
266           0,0,0,0,0,0   // reverse green  (night vision effect)
267         } ;
268    uchar *ti=t+6;
269    uchar *c;
270    for (i=0,c=tints[0]; i<256; i++,c++) *c=i;  // make the normal tint (maps everthing to itself)
271    for (i=0,c=tints[TTINTS-1]; i<256; i++,c++)  // reverse green
272    {
273      int r=pal->red(i)/2,g=255-pal->green(i)-30,b=pal->blue(i)*3/5+50;
274      if (g<0) g=0;
275      if (b>255) b=0;
276      *c=pal->find_closest(r,g,b);
277    }
278
279    // make the colored tints
280    for (i=1; i<TTINTS-1; i++)
281    {
282      calc_tint(tints[i],ti[0],ti[1],ti[2],ti[3],ti[4],ti[5],pal);
283      ti+=6;
284    }
285
286
287
288    jFILE f("light.tbl","wb");
289    f.write_uint16(calc_crc((unsigned char *)pal->addr(),768));
290    f.write(white_light,256*64);
291    f.write(green_light,256*64);
292    for (int i=0; i<TTINTS; i++)
293      f.write(tints[i],256);
294  }
295}
296
297
298light_patch *light_patch::copy(light_patch *Next)
299{
300  light_patch *p=new light_patch(x1,y1,x2,y2,Next);
301  p->total=total;
302  if (total)
303  {
304    p->lights=(light_source **)malloc(total*sizeof(light_source *));
305    memcpy(p->lights,lights,total*(sizeof(light_source *)));
306  }
307  else
308    p->lights=NULL;
309  return p;
310}
311
312#define MAX_LP 10
313
314
315void add_light(light_patch *&first, long x1, long y1, long x2, long y2,
316                light_source *who)
317{
318  light_patch *last=NULL;
319  for (light_patch *p=first; p; p=p->next)
320  {
321    // first see if light patch we are adding is enclosed entirely by another patch
322    if (x1>=p->x1 && y1>=p->y1 && x2<=p->x2 && y2<=p->y2)
323    {
324      if (p->total==MAX_LP) return ;
325
326      if (x1>p->x1)
327      {
328    first=p->copy(first);
329    first->x2=x1-1;
330      }
331      if (x2<p->x2)
332      {
333    first=p->copy(first);
334    first->x1=x2+1;
335      }
336      if (y1>p->y1)
337      {
338    first=p->copy(first);
339    first->x1=x1;
340    first->x2=x2;
341    first->y2=y1-1;
342      }
343      if (y2<p->y2)
344      {
345    first=p->copy(first);
346    first->x1=x1;
347    first->x2=x2;
348    first->y1=y2+1;
349      }
350      p->x1=x1; p->y1=y1; p->x2=x2; p->y2=y2;
351      p->total++;
352      p->lights=(light_source **)realloc(p->lights,sizeof(light_source *)*p->total);
353      p->lights[p->total-1]=who;
354      return ;
355    }
356
357    // see if the patch completly covers another patch.
358    if (x1<=p->x1 && y1<=p->y1 && x2>=p->x2 && y2>=p->y2)
359    {
360      if (x1<p->x1)
361        add_light(first,x1,y1,p->x1-1,y2,who);
362      if (x2>p->x2)
363        add_light(first,p->x2+1,y1,x2,y2,who);
364      if (y1<p->y1)
365        add_light(first,p->x1,y1,p->x2,p->y1-1,who);
366      if (y2>p->y2)
367        add_light(first,p->x1,p->y2+1,p->x2,y2,who);
368      if (p->total==MAX_LP)  return ;
369      p->total++;
370      p->lights=(light_source **)realloc(p->lights,sizeof(light_source *)*p->total);
371      p->lights[p->total-1]=who;
372      return ;
373    }
374
375    // see if we intersect another rect
376    if (!(x2<p->x1 || y2<p->y1 || x1>p->x2 || y1>p->y2))
377    {
378      int ax1,ay1,ax2,ay2;
379      if (x1<p->x1)
380      {
381        add_light(first,x1,max(y1,p->y1),p->x1-1,min(y2,p->y2),who);
382    ax1=p->x1;
383      } else
384    ax1=x1;
385
386      if (x2>p->x2)
387      {
388        add_light(first,p->x2+1,max(y1,p->y1),x2,min(y2,p->y2),who);
389    ax2=p->x2;
390      }
391      else
392    ax2=x2;
393
394      if (y1<p->y1)
395      {
396        add_light(first,x1,y1,x2,p->y1-1,who);
397    ay1=p->y1;
398      } else
399    ay1=y1;
400
401      if (y2>p->y2)
402      {
403        add_light(first,x1,p->y2+1,x2,y2,who);
404    ay2=p->y2;
405      } else
406    ay2=y2;
407
408
409      add_light(first,ax1,ay1,ax2,ay2,who);
410
411      return ;
412    }
413  }
414}
415
416light_patch *find_patch(int screenx, int screeny, light_patch *list)
417{
418  for (; list; list=list->next)
419  {
420    if (screenx>=list->x1 && screenx<=list->x2 && screeny>=list->y1 && screeny<=list->y2)
421      return list;
422  }
423  return NULL;
424}
425
426int calc_light_value(long x, long y, light_patch *which)
427{
428  int lv=0;
429  int t=which->total;
430  for (register int i=t-1; i>=0; i--)
431  {
432    light_source *fn=which->lights[i];
433    if (fn->type==9)
434    {
435      lv=fn->inner_radius;
436      i=0;
437    }
438    else
439    {
440      long dx=abs(fn->x-x)<<fn->xshift;
441      long dy=abs(fn->y-y)<<fn->yshift;
442      long  r2;
443      if (dx<dy)
444        r2=dx+dy-(dx>>1);
445      else r2=dx+dy-(dy>>1);
446
447      if (r2>=fn->inner_radius)
448      {
449    if (r2<fn->outer_radius)
450    {
451      lv+=((fn->outer_radius-r2)*fn->mul_div)>>16;
452    }
453      } else lv=63;
454    }
455  }
456  if (lv>63) return 63;
457  else
458    return lv;
459}
460
461
462void reduce_patches(light_patch *f)   // find constant valued patches
463{
464
465}
466
467light_patch *make_patch_list(int cx1,int cy1,int cx2,int cy2, long screenx, long screeny)
468{
469  light_patch *first=new light_patch(cx1,cy1,cx2,cy2,NULL);
470
471  for (light_source *f=first_light_source; f; f=f->next)   // determine which lights will have effect
472  {
473    long x1=f->x1-screenx,y1=f->y1-screeny,x2=f->x2-screenx,y2=f->y2-screeny;
474    if (x1<cx1) x1=cx1;
475    if (y1<cy1) y1=cy1;
476    if (x2>cx2) x2=cx2;
477    if (y2>cy2) y2=cy2;
478
479    if (x1<=x2 && y1<=y2)
480      add_light(first,x1,y1,x2,y2,f);
481  }
482  reduce_patches(first);
483
484  return first;
485}
486
487void delete_patch_list(light_patch *first)
488{
489  while (first)
490  {
491    light_patch *p=first;
492    first=first->next;
493    delete p;
494  }
495}
496
497
498inline long MAP_PUT(long pad, long screen_addr, long remap, long w)
499{ while (w--)
500  {
501    *((uchar *)(screen_addr))=*((uchar *)remap+*((uchar *)screen_addr));
502    screen_addr++;
503  }
504  return screen_addr;
505}
506
507inline long MAP_PUT2(long dest_addr, long screen_addr, long remap, long w)
508{ while (w--)
509  {
510    *((uchar *)(dest_addr))=*((uchar *)remap+*((uchar *)screen_addr));
511    screen_addr++;
512    dest_addr++;
513  }
514  return dest_addr;
515}
516
517inline long calc_lv(light_patch *lp, long sx, long sy)
518{
519  light_source **lon_p=lp->lights;
520  long lv=min_light_level;
521  int light_on;
522  for (light_on=lp->total-1; light_on>=0; light_on--)
523  {
524    light_source *fn=*lon_p;
525    long *dt=&(*lon_p)->type;
526    if (*dt==9)
527    {
528      lv=fn->inner_radius;
529      light_on=0;
530    } else
531    {
532      dt++;
533      int dx=abs(*dt-sx); dt++;
534      dx<<=*dt;  dt++;
535
536      int dy=abs(*dt-sy); dt++;
537      dy<<=*dt;  dt++;
538
539      int r2;
540      if (dx<dy)
541      r2=dx+dy-(dx>>1);
542      else r2=dx+dy-(dy>>1);
543
544      if (r2<*dt)
545      {
546    int v=*dt-r2; dt++;
547    lv+=v*(*dt)>>16;
548      }
549    }
550    lon_p++;
551  }
552  if (lv>63) return 63;
553  else return lv;
554
555}
556
557
558void light_screen(image *sc, long screenx, long screeny, uchar *light_lookup)
559{
560  int lx_run,ly_run;
561  switch (light_detail)
562  {
563    case HIGH_DETAIL :
564    { lx_run=2; ly_run=1; } break;
565    case MEDIUM_DETAIL :
566    { lx_run=3; ly_run=2; } break;
567    case LOW_DETAIL :
568    { lx_run=4; ly_run=3; } break;
569    case POOR_DETAIL :                   // low detail lighting alread taken care of.
570    return ;
571  }
572
573  int cx1, cy1, cx2, cy2;
574  sc->GetClip(cx1, cy1, cx2, cy2);
575//  sc->AddDirty(cx1, cy1, cx2, cy2);
576  uint8_t *mint = light_lookup + min_light_level * 256;
577  screenx-=cx1;
578  screeny-=cy1;
579
580
581  light_patch *first = make_patch_list(cx1, cy1, cx2 - 1, cy2 - 1, screenx, screeny);
582
583
584  int ytry=(1<<ly_run),xtry=(1<<lx_run);
585  int calcx_mask=(0xefffffff-(xtry-1));
586  int calcy_mask=(0xefffffff-(ytry-1));
587  int scr_w=screen->width();
588
589  for (light_patch *lp=first; lp; lp=lp->next)
590  {
591    register int x2=lp->x2;
592    if (lp->total==0)  // do dark patches really fast.
593    {
594      unsigned char *sl=screen->scan_line(lp->y1)+lp->x1,*dest;
595      dest=sl;
596
597      int y2=lp->y2;
598      for (int y=lp->y1; y<=y2; y++,sl+=scr_w,dest+=scr_w)
599      {
600    int w=lp->x2-lp->x1+1;
601        MAP_PUT2((long)dest,(long)sl,(long)mint,w);
602      }
603    }
604    else
605    {
606      int todoy;
607      int y2=lp->y2;
608
609      int xmask=(xtry-1);
610      int ymask=(ytry-1);
611
612      uchar *yaddr=screen->scan_line(lp->y1)+lp->x1,*dyaddr;
613      dyaddr=yaddr;
614
615      for (int y=lp->y1; y<=y2; )
616      {
617    long sy=(screeny+y);
618    if (y+ytry>lp->y2)        // see how many y lines to do for this block
619      todoy=lp->y2-y+1;
620    else todoy=ytry;
621    int maxy=ytry-(sy&ymask);
622    if (todoy>maxy)
623      todoy=maxy;
624
625    uchar *xaddr=yaddr,*dxaddr=dyaddr;
626    for (register int x=lp->x1; x<=x2; )
627    {
628      long lv=min_light_level;
629      unsigned char *ct;
630      light_source *f;
631      int todox;
632      if (x+xtry>lp->x2)
633        todox=lp->x2-x+1;
634      else todox=xtry;
635      int sx=(screenx+x);
636      int max=xtry-(sx&xmask);
637      if (todox>max)
638        todox=max;
639
640
641      ct=light_lookup+calc_lv(lp,sx,sy)*256;
642      switch (todox)
643      {
644        case 8 :
645        {
646          x+=8;
647          switch (todoy)
648          {
649        case 4 :
650        {
651          uchar *addr=xaddr,*daddr=dxaddr;
652          dxaddr=(uchar *)MAP_PUT2((long)daddr,(long)addr,(long)ct,8);
653          xaddr+=8;
654
655          addr+=scr_w; daddr+=scr_w;
656          MAP_PUT2((long)daddr,(long)addr,(long)ct,8);   addr+=scr_w; daddr+=scr_w;
657          MAP_PUT2((long)daddr,(long)addr,(long)ct,8);   addr+=scr_w; daddr+=scr_w;
658          MAP_PUT2((long)daddr,(long)addr,(long)ct,8);
659        } break;
660        case 3 :
661        {
662          uchar *addr=xaddr,*daddr=dxaddr;
663          dxaddr=(uchar *)MAP_PUT2((long)daddr,(long)addr,(long)ct,8);
664          xaddr+=8;
665
666          addr+=scr_w; daddr+=scr_w;
667          MAP_PUT2((long)daddr,(long)addr,(long)ct,8);   addr+=scr_w; daddr+=scr_w;
668          MAP_PUT2((long)daddr,(long)addr,(long)ct,8);
669
670
671        } break;
672        case 2 :
673        {
674          uchar *addr=xaddr,*daddr=dxaddr;
675          dxaddr=(uchar *)MAP_PUT2((long)daddr,(long)addr,(long)ct,8);
676          xaddr+=8;
677
678          addr+=scr_w; daddr+=scr_w;
679          MAP_PUT2((long)daddr,(long)addr,(long)ct,8);
680
681        } break;
682        case 1 :
683        { dxaddr=(uchar *)MAP_PUT((long)dxaddr,(long)xaddr,(long)ct,8);
684          xaddr+=8;
685        } break;
686          }
687        } break;
688/*        case 4 :
689        {
690          x+=4;
691          switch (todoy)
692          {
693        case 4 :
694        {
695          uchar *addr=xaddr;
696          xaddr=(uchar *)MAP_PUT(0,(long)addr,(long)ct,4); addr+=scr_w; daddr+=scr_w;
697          MAP_PUT(0,(long)addr,(long)ct,4);                addr+=scr_w; daddr+=scr_w;
698          MAP_PUT(0,(long)addr,(long)ct,4);                addr+=scr_w; daddr+=scr_w;
699          MAP_PUT(0,(long)addr,(long)ct,4);
700        } break;
701        case 3 :
702        {
703          uchar *addr=xaddr;
704          xaddr=(uchar *)MAP_PUT(0,(long)addr,(long)ct,4); addr+=scr_w;  daddr+=scr_w;
705          MAP_PUT(0,(long)addr,(long)ct,4);                addr+=scr_w;  daddr+=scr_w;
706          MAP_PUT(0,(long)addr,(long)ct,4);
707        } break;
708        case 2 :
709        {
710          uchar *addr=xaddr;
711          xaddr=(uchar *)MAP_PUT(0,(long)addr,(long)ct,4); addr+=scr_w; daddr+=scr_w;
712          MAP_PUT(0,(long)addr,(long)ct,4);
713        } break;
714        case 1 : xaddr=(uchar *)MAP_PUT(0,(long)xaddr,(long)ct,4); break;
715          }
716        } break; */
717        default :
718        {
719          x+=todox;
720          if (todoy==1)
721          {
722            dxaddr=(uchar *)MAP_PUT2((long)dxaddr,(long)xaddr,(long)ct,todox);
723        xaddr+=todox;
724          }
725          else
726          {
727        uchar *addr=xaddr,*daddr=dxaddr;
728        dxaddr=(uchar *)MAP_PUT2((long)dxaddr,(long)xaddr,(long)ct,todox);
729        xaddr+=todox;
730
731        addr+=scr_w;
732        daddr+=scr_w;
733
734        int cc=todoy-1;
735        while (cc--)
736        {
737          MAP_PUT2((long)daddr,(long)addr,(long)ct,todox);
738          addr+=scr_w;
739          daddr+=scr_w;
740        }
741          }
742        }
743      }
744    }
745
746    int yadd=scr_w*todoy;
747    yaddr+=yadd;
748    dyaddr+=yadd;
749
750    y+=todoy;
751      }
752    }
753  }
754  while (first)
755  {
756    light_patch *p=first;
757    first=first->next;
758    delete p;
759  }
760}
761
762
763
764
765void add_light_spec(spec_directory *sd, char *level_name)
766{
767  long size=4+4;  // number of lights and minimum light levels
768  for (light_source *f=first_light_source; f; f=f->next)
769    size+=6*4+1;
770  sd->add(new spec_entry(SPEC_LIGHT_LIST,"lights",NULL,size,0));
771}
772
773void write_lights(jFILE *fp)
774{
775  int t=0;
776  for (light_source *f=first_light_source; f; f=f->next) t++;
777  fp->write_uint32(t);
778  fp->write_uint32(min_light_level);
779  for (f=first_light_source; f; f=f->next)
780  {
781    fp->write_uint32(f->x);
782    fp->write_uint32(f->y);
783    fp->write_uint32(f->xshift);
784    fp->write_uint32(f->yshift);
785    fp->write_uint32(f->inner_radius);
786    fp->write_uint32(f->outer_radius);
787    fp->write_uint8(f->type);
788  }
789}
790
791
792int send_lights(net_descriptor *os)
793{
794  packet pk;
795  int t=0;
796  for (light_source *f=first_light_source; f; f=f->next) t++;
797  pk.write_uint32(t);
798  pk.write_uint16(min_light_level);
799  if (!os->send(pk)) return 0;
800  for (f=first_light_source; f; f=f->next)
801  {
802    pk.reset();
803    pk.write_uint32(f->x);
804    pk.write_uint32(f->y);
805    pk.write_uint32(f->xshift);
806    pk.write_uint32(f->yshift);
807    pk.write_uint32(f->inner_radius);
808    pk.write_uint32(f->outer_radius);
809    pk.write_uint32(f->type);
810    if (!os->send(pk)) return 0;
811  }
812  return 1;
813}
814
815
816void read_lights(spec_directory *sd, jFILE *fp, char const *level_name)
817{
818  delete_all_lights();
819  spec_entry *se=sd->find("lights");
820  if (se)
821  {
822    fp->seek(se->offset,SEEK_SET);
823    long t=fp->read_uint32();
824    min_light_level=fp->read_uint32();
825    light_source *last;
826    while (t)
827    {
828      t--;
829      long x=fp->read_uint32();
830      long y=fp->read_uint32();
831      long xshift=fp->read_uint32();
832      long yshift=fp->read_uint32();
833      long ir=fp->read_uint32();
834      long ora=fp->read_uint32();
835      long ty=fp->read_uint8();
836
837      light_source *p=new light_source(ty,x,y,ir,ora,xshift,yshift,NULL);
838
839      if (first_light_source)
840        last->next=p;
841      else first_light_source=p;
842      last=p;
843    }
844  }
845}
846
847
848int receive_lights(net_descriptor *os)
849{
850  packet pk;
851  if (!os->get(pk)) { printf("net error : light total\n"); return 0; }
852  long t;
853  if (pk.read((uchar *)&t,4)!=4)
854  { printf("net error : (t) packet incomplete\n"); return 0; }
855  t=lltl(t);
856
857  if (pk.read((uchar *)&min_light_level,2)!=2)
858  { printf("net error : (minl) packet incomplete\n"); return 0; }
859  min_light_level=lstl(min_light_level);
860
861  light_source *last;
862  printf("Reading %d lights\n",t);
863  while (t)
864  {
865    if (!os->get(pk)) { printf("net error : read light\n"); return 0; }
866    t--;
867    long dt[7];
868    if (pk.read((uchar *)dt,7*4)!=7*4) return 0;
869
870
871    light_source *p=new light_source(lltl(dt[6]),
872                       lltl(dt[0]),lltl(dt[1]),
873                       lltl(dt[4]),lltl(dt[5]),
874                       lltl(dt[2]),lltl(dt[3]),NULL);
875
876    if (first_light_source)
877      last->next=p;
878    else first_light_source=p;
879      last=p;
880  }
881  return 1;
882}
883
884
885
Note: See TracBrowser for help on using the repository browser.