source: abuse/tags/pd/macabuse/src/endgame.c @ 49

Last change on this file since 49 was 49, checked in by Sam Hocevar, 11 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 12.6 KB
Line 
1#include "menu.hpp"
2#include "lisp.hpp"
3#include "game.hpp"
4#include "timing.hpp"
5#include "game.hpp"
6#include "id.hpp"
7#include "pmenu.hpp"
8#include "gui.hpp"
9#include "property.hpp"
10#include "dev.hpp"
11#include "clisp.hpp"
12#include "dprint.hpp"
13#include "jrand.hpp"
14#include "director.hpp"
15#include <math.h>
16#include "lisp_gc.hpp"
17
18extern palette *old_pal;
19
20struct mask_line
21{
22  int x,size;
23  ushort *remap;
24  uchar *light;
25} ;
26
27
28int text_draw(int y, int x1, int y1, int x2, int y2, char *buf, JCFont *font, uchar *cmap, char color);
29
30mask_line *make_mask_lines(image *mask, int map_width)
31{
32  mask_line *p=(mask_line *)jmalloc(mask->height()*sizeof(mask_line),"mask_line");
33  for (int y=0;y<mask->height();y++)
34  {
35    // find the start of the run..
36    uchar *sl=mask->scan_line(y);   
37    int x=0;
38    while (*sl==0) { sl++; x++; }
39    p[y].x=x;
40
41   
42    // find the length of the run
43    int size=0;
44    uchar *sl_start=sl;
45    while (*sl!=0 && x<mask->width()) { sl++; x++; size++; }
46    p[y].size=size;
47
48    // now calculate remap for line
49    p[y].remap=(ushort *)jmalloc(size*2,"mask remap");
50    p[y].light=(uchar *)jmalloc(size,"mask light");
51    ushort *rem=p[y].remap;
52    uchar *lrem=p[y].light;
53    for (x=0;x<size;x++,rem++)
54    {
55      *(lrem++)=*(sl_start++);
56/*      if (x==size/2 || x==size/2-1 || x==size/2+1)
57        *rem=(int)(sqrt(0.5)*map_width/2.0);
58      else*/
59      if (x<=size/2)
60        *rem=(int)(sqrt(x/(double)(size*2.0))*map_width/2.0);
61      else
62        *rem=map_width/2-(int)(sqrt((size-x)/(double)(size*2.0))*map_width/2.0);
63
64//      (int)(mask->width()-(sqrt((size-x)/(double)size)*map_width/2.0)+mask->width()/2);
65    }
66  }
67  return p;
68}
69
70
71void scan_map(image *screen, int sx, int sy, image *im1, image *im2, int fade256, long *paddr, mask_line *p, int mask_height,
72              int xoff, int coff)
73
74  int x1=10000,x2=0;
75  int iw=im1->width(); 
76  ushort r,co,off,cc;
77  int y=0;
78  uchar *l;
79
80  for (;y<mask_height;y++)
81  {
82    mask_line *n=p+y;
83    uchar *sl=screen->scan_line(y+sy)+sx+n->x;
84    uchar *sl2=im1->scan_line(y);
85    uchar *sl3=im2->scan_line(y);
86    l=n->light;
87    ushort *rem=n->remap;
88    if (sx+n->x<x1) x1=sx+n->x;   
89    int x=0;
90    for (;x<n->size;x++,sl++,rem++,l++)   
91    {
92      r=*rem;
93
94      off=(r+xoff);
95      if (off>=iw) off-=iw;
96
97      long p1=*(paddr+sl2[off]);
98      long p2=*(paddr+sl3[off]);
99
100      int r1=p1>>16,g1=(p1>>8)&0xff,b1=p1&0xff;
101      int r2=p2>>16,g2=(p2>>8)&0xff,b2=p2&0xff;
102      int r3=r1+(r2-r1)*fade256/256,
103          g3=g1+(g2-g1)*fade256/256,
104          b3=b1+(b2-b1)*fade256/256;
105
106      uchar c=color_table->lookup_color(r3>>3,g3>>3,b3>>3);
107                               
108      *sl=*(white_light+((*l)/2+28+jrand()%4)*256+c);
109     
110    }
111    if (sx+n->x+x>x2) x2=sx+n->x+x;
112   
113  }
114  screen->add_dirty(x1,sy,x2,sy+mask_height-1);
115
116}
117
118
119
120void fade_in(image *im, int steps);
121void fade_out(int steps);
122
123class ex_char {
124  public :
125  uchar frame,char_num;
126  int x,y;
127  ex_char *next;
128  ex_char (int X, int Y, int Frame, int Char_num, ex_char *Next) { x=X; y=Y; frame=Frame; char_num=Char_num; next=Next; }
129} ;
130
131void scale_put      (image *im, image *screen, int x, int y, short new_width, short new_height);
132void scale_put_trans(image *im, image *screen, int x, int y, short new_width, short new_height);
133
134void show_end2()
135{
136  int i;
137  int planet=cash.reg("art/endgame.spe","planet",SPEC_IMAGE,1);
138  int planet2=cash.reg("art/endgame.spe","dead_planet",SPEC_IMAGE,1);
139  int mask=cash.reg("art/endgame.spe","mask",SPEC_IMAGE,1);
140  int ship=cash.reg("art/endgame.spe","ship",SPEC_IMAGE,1);
141
142
143  int explo_snd=lnumber_value(symbol_value(make_find_symbol("P_EXPLODE_SND")));
144  int space_snd=lnumber_value(symbol_value(make_find_symbol("SPACE_SND")));
145  int zip_snd=lnumber_value(symbol_value(make_find_symbol("SHIP_ZIP_SND")));
146 
147
148  mask_line *p=make_mask_lines(cash.img(mask),cash.img(planet)->width()); 
149
150  int explo_frames1[8],explo_frames2[7];
151
152  for (i=0;i<8;i++)
153  { char nm[100]; sprintf(nm,"small_wite%04d.pcx",i+1);
154    explo_frames1[i]=cash.reg("art/exp1.spe",nm,SPEC_CHARACTER,1);
155  }
156
157  for (i=0;i<7;i++)
158  { char nm[100]; sprintf(nm,"small_fire%04d.pcx",i+1);
159    explo_frames2[i]=cash.reg("art/exp1.spe",nm,SPEC_CHARACTER,1);
160  }
161
162  int eoff=0,coff=0;
163
164  int ex=xres/2-cash.img(mask)->width()/2;
165  int ey=yres/2-cash.img(mask)->height()/2;
166  fade_out(16);
167
168  image blank(2,2); blank.clear();
169  eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
170
171
172  screen->clear();
173  int c[4]={pal->find_closest(222,222,22),
174            pal->find_closest(200,200,200),
175            pal->find_closest(100,100,100),
176            pal->find_closest(64,64,64)};
177  ushort sinfo[800*3],*si;
178
179  for (si=sinfo,i=0;i<800;i++)
180  {
181    *(si++)=jrand()%320;
182    *(si++)=jrand()%200;     
183    *(si++)=c[jrand()%4];     
184    screen->putpixel(si[-3],si[-2],si[-1]);
185  }
186  long paddr[256];
187  if (old_pal)
188  {
189    for (i=0;i<256;i++)
190      paddr[i]=(old_pal->red(i)<<16)|(old_pal->green(i)<<8)|(old_pal->blue(i));
191  }
192  else
193  {
194    for (i=0;i<256;i++)
195      paddr[i]=(pal->red(i)<<16)|(pal->green(i)<<8)|(pal->blue(i));
196  }
197
198  int dx=(xres+1)/2-320/2,dy=(yres+1)/2-200/2;
199
200
201  scan_map(screen,ex,ey,cash.img(planet),cash.img(planet2),0,paddr,p,cash.img(mask)->height(),eoff,coff);     
202  image *tcopy=cash.img(planet)->copy();
203  fade_in(NULL,32);
204
205  time_marker old_time;
206
207
208 
209  for (i=0;i<80;)
210  {
211    time_marker new_time;   
212    if (new_time.diff_time(&old_time)>0.1)
213    {
214      if ((i%10)==0 && (sound_avail&SFX_INITIALIZED))
215        cash.sfx(space_snd)->play(64);
216
217      old_time.get_time();
218      screen->clear();
219      int j;
220      for (si=sinfo,j=0;j<800;j++,si+=3)
221        screen->putpixel(dx+si[0],dy+si[1],si[2]);
222
223      if (i>=30 && i<=37)
224      {
225        cash.img(planet)->put_image(tcopy,0,0);
226        cash.fig(explo_frames1[i-30])->forward->put_image(tcopy,100,50);
227        scan_map(screen,ex,ey,tcopy,
228               cash.img(planet2),
229               0,paddr,
230               p,cash.img(mask)->height(),eoff,coff);     
231      }
232      else
233        scan_map(screen,ex,ey,cash.img(planet),
234               cash.img(planet2),
235               0,paddr,
236               p,cash.img(mask)->height(),eoff,coff);     
237      if (i>38)
238      {
239        int t=i-38;
240        image *s=cash.img(ship);
241        int nw=s->width()*(t+2)/16,
242            nh=s->height()*(t+2)/16;
243
244
245        scale_put_trans(s,screen,ex-(i-38)*5,ey+cash.img(mask)->height()/2+t*4,nw,nh);
246        if (i==77)
247          if (sound_avail&SFX_INITIALIZED)
248            cash.sfx(zip_snd)->play(127);
249      }
250       
251      eoff+=2; if (eoff>=320) eoff-=320;
252      coff+=1; if (coff>=320) coff-=320;     
253      eh->flush_screen();
254      i++;
255    }
256  }
257  delete tcopy;
258
259
260  ex_char *clist=NULL;
261  for (i=0;i<200;)
262  {
263    time_marker new_time;
264    if (new_time.diff_time(&old_time)>0.1)
265    {
266      if ((i%10)==0 && (sound_avail&SFX_INITIALIZED))
267        cash.sfx(space_snd)->play(64);
268
269      old_time.get_time();
270      screen->clear();
271      int j;
272      for (si=sinfo,j=0;j<800;j++,si+=3)
273        screen->putpixel(dx+si[0],dy+si[1],si[2]);
274
275     
276      scan_map(screen,ex,ey,cash.img(planet),
277               cash.img(planet2),i*256/200,paddr,p,cash.img(mask)->height(),eoff,coff);     
278
279      eoff+=2; if (eoff>=320) eoff-=320;
280      coff+=1; if (coff>=320) coff-=320;     
281
282      i++;
283      if (i<150 || (i<170 && ((i-149)%2)==0) || (i<180 && ((i-149)%4)==0) || (i<190 && ((i-149)%8)==0))
284      {
285        clist=new ex_char(ex+jrand()%(cash.img(mask)->width()-cash.img(mask)->width()/3),
286                        ey+jrand()%(cash.img(mask)->height()-cash.img(mask)->height()/3),0,1,clist);
287        if (sound_avail&SFX_INITIALIZED)
288          cash.sfx(explo_snd)->play(127);
289      }
290
291//      clist=new ex_char(ex+jrand()%(cash.img(mask)->width(),
292//                      ey+jrand()%(cash.img(mask)->height(),0,1,clist);
293
294      ex_char *c=clist,*last=NULL;
295      for (;c;)
296      {
297        c->frame++;
298        if (c->frame>6)
299        {
300          ex_char *d=c;
301          if (last) last->next=c->next;
302          else clist=c->next;
303          c=c->next;
304          delete d;
305        } else
306        {
307          last=c;
308          if (c->char_num)     
309            cash.fig(explo_frames2[c->frame])->forward->put_image(screen,c->x,c->y);     
310
311          c->x-=3;
312          c=c->next;
313        }         
314      }
315
316      eh->flush_screen();
317
318    }
319
320
321  }
322  while (clist) { ex_char *p=clist; clist=clist->next; delete p; }
323
324  screen->clear();
325  int j;
326  for (si=sinfo,j=0;j<800;j++,si+=3)
327    screen->putpixel(si[0],si[1],si[2]);
328
329  event ev;
330  i=0;
331  do
332  {
333    time_marker new_time;
334    if (new_time.diff_time(&old_time)>0.1)
335    {
336      if ((i%10)==0 && (sound_avail&SFX_INITIALIZED))
337        cash.sfx(space_snd)->play(64);
338
339      old_time.get_time();
340      scan_map(screen,ex,ey,cash.img(planet),
341               cash.img(planet2),
342               256,paddr,
343               p,cash.img(mask)->height(),eoff,coff);     
344      eoff+=2; if (eoff>=320) eoff-=320;
345      coff+=1; if (coff>=320) coff-=320;     
346      eh->flush_screen();
347      i++;
348    }
349   
350    if (eh->event_waiting())
351      eh->get_event(ev);
352
353  } while (ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON);
354
355
356  uchar cmap[32];
357  for (i=0;i<32;i++)
358    cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
359
360  void *end_plot=symbol_value(make_find_symbol("plot_end"));
361
362
363  time_marker start;
364
365  ev.type=EV_SPURIOUS;
366  for (i=0;i<320 && ev.type!=EV_KEY;i++)
367  {
368    screen->clear();
369    int j;
370    for (si=sinfo,j=0;j<800;j++,si+=3)
371      screen->putpixel(dx+si[0],dy+si[1],si[2]);
372
373    scan_map(screen,ex,ey,cash.img(planet),
374             cash.img(planet2),
375             256,paddr,
376             p,cash.img(mask)->height(),eoff,coff);     
377    text_draw(205-i,dx+10,dy,dx+319-10,dy+199,lstring_value(end_plot),eh->font(),cmap,eh->bright_color());
378    eh->flush_screen();
379    time_marker now; while (now.diff_time(&start)<0.18) now.get_time(); start.get_time();
380
381    while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
382  }
383
384
385
386  for (i=0;i<cash.img(mask)->height();i++)
387  {
388    jfree(p[i].remap);
389    jfree(p[i].light);
390  }
391
392  jfree(p);
393
394
395  delete current_level;
396  current_level=NULL;
397
398  fade_out(16);
399  screen->clear();
400
401
402  eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
403  the_game->set_state(MENU_STATE);
404}
405
406void show_sell(int abortable);
407
408void share_end()
409{
410  fade_out(16);
411  switch_mode(VMODE_640x480);
412  image blank(2,2); blank.clear();
413  eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
414  screen->clear();
415
416  image *im=cash.img(cash.reg("art/endgame.spe","tbc",SPEC_IMAGE,1));
417
418  void *to_be=symbol_value(make_find_symbol("to_be_continued"));
419  p_ref r1(to_be);
420
421  void *mid_plot=symbol_value(make_find_symbol("plot_middle"));
422  p_ref r2(mid_plot);
423
424
425  int dx=(xres+1)/2-im->width()/2,dy=(yres+1)/2-im->height()/2;
426  im->put_image(screen,dx,dy);
427  console_font->put_string(screen,xres/2+35,yres/2+100-console_font->height()-2,
428                           lstring_value(to_be));
429  fade_in(NULL,32);
430
431  uchar cmap[32];
432  int i;
433  for (i=0;i<32;i++)
434    cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
435
436  event ev; ev.type=EV_SPURIOUS;
437  time_marker start;
438  for (i=0;i<320 && ev.type!=EV_KEY;i++)
439  {
440    im->put_image(screen,dx,dy);
441    console_font->put_string(screen,xres/2+35,yres/2+100-console_font->height()-2,
442                           lstring_value(to_be));
443
444    text_draw(205-i,dx+10,dy,dx+319-10,dy+199,lstring_value(mid_plot),eh->font(),cmap,eh->bright_color());
445    eh->flush_screen();
446    time_marker now; while (now.diff_time(&start)<0.18) now.get_time(); start.get_time();
447    while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
448  }
449
450  if (ev.type!=EV_KEY)
451  {
452    do
453    {
454      eh->flush_screen();
455      eh->get_event(ev);   
456    } while (ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON);
457  }
458
459  fade_out(16);
460  eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse 
461  show_sell(1);
462  eh->push_event(new event(ID_SHOW_SELL,NULL));
463}
464
465
466void show_end()
467{
468  fade_out(16);
469  switch_mode(VMODE_640x480);
470
471  image blank(2,2); blank.clear();
472  eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
473  screen->clear();
474
475  image *im=cash.img(cash.reg("art/endgame.spe","end.pcx",SPEC_IMAGE,1));
476
477  int dx=(xres+1)/2-640/2,dy=(yres+1)/2-400/2;
478
479  void *end_plot=symbol_value(make_find_symbol("plot_end"));
480  p_ref r2(end_plot);
481
482
483  fade_in(im,32);
484
485  uchar cmap[32];
486  int i;
487  for (i=0;i<32;i++)
488    cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
489
490  event ev; ev.type=EV_SPURIOUS;
491  time_marker start;
492  for (i=0;i<320 && ev.type!=EV_KEY;i++)
493  {
494    im->put_part(screen,dx,dy,0,0,319,199);
495
496    text_draw(205-i,dx+10,dy,dx+319-10,dy+199,lstring_value(end_plot),eh->font(),cmap,eh->bright_color());
497    eh->flush_screen();
498    time_marker now; while (now.diff_time(&start)<0.18) now.get_time(); start.get_time();
499    while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
500  }
501
502  if (ev.type!=EV_KEY)
503  {
504    do
505    {
506      eh->flush_screen();
507      eh->get_event(ev);   
508    } while (ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON);
509  }
510
511  delete current_level;
512  current_level=NULL;
513
514  fade_out(16);
515  screen->clear();
516
517  show_sell(1);
518
519  eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
520  the_game->set_state(MENU_STATE);
521}
522
Note: See TracBrowser for help on using the repository browser.