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 <math.h>
16 
17 #include "common.h"
18 
19 #include "timing.h"
20 #include "loader2.h"
21 #include "chars.h"
22 #include "specs.h"
23 #include "lisp.h"
24 #include "jrand.h"
25 #include "menu.h"
26 #include "dev.h"
27 #include "director.h"
28 
29 #include "dev.h"
30 #include "light.h"
31 #include "dprint.h"
32 #include "particle.h"
33 #include "clisp.h"
34 #include "compiled.h"
35 #include "sbar.h"
36 #include "help.h"
37 #include "loadgame.h"
38 #include "nfserver.h"
39 #include "specache.h"
40 
41 extern int past_startup;
42 
43 property_manager *prop;
44 int *backtiles;
45 int *foretiles;
46 JCFont *big_font,*console_font;
47 int nforetiles,nbacktiles,f_wid,f_hi,b_wid,b_hi,total_songs=0,sfx_volume,music_volume,sound_avail=0;
48 song *current_song=NULL;
49 
50 uint16_t current_start_type,start_position_type,last_start_number;
51 int light_buttons[13];
52 int joy_picts[2*9];
53 palette *pal;
54 
55 int big_font_pict=-1,small_font_pict=-1,console_font_pict=-1,cdc_logo;
56 
57 int title_screen;
58 
59 ColorFilter *color_table;
60 
61 
62 int border_tile,window_texture,
63     raise_volume,lower_volume,record_button,play_button,music_button,sfx_button,
64     window_colors,pause_image,damage_pict,block_pict,vmm_image,earth,earth_mask,clouds,
65     numbers[10],ok_button,cancel_button;
66 
67 int start_running=0;
68 
69 int c_mouse1,c_mouse2,c_normal,c_target;
70 
71 long bg_xmul,bg_xdiv,bg_ymul,bg_ydiv;    // brackground scroll rates
72 char mouse_scrolling=0,palettes_locked=1,view_shift_disabled=0;
73 
74 int light_connection_color;
75 
76 
load_image(spec_entry * e,bFILE * fp)77 image *load_image(spec_entry *e, bFILE *fp)
78 {
79     image *im = new image(fp, e);
80     if (scale_mult != 1 || scale_div != 1)
81         im->Scale(im->Size() * scale_mult / scale_div);
82     return im;
83 }
84 
load_image(bFILE * fp)85 image *load_image(bFILE *fp)
86 {
87     image *im = new image(fp);
88     if (scale_mult != 1 || scale_div != 1)
89         im->Scale(im->Size() * scale_mult / scale_div);
90     return im;
91 }
92 
use_file(char * filename,bFILE * & fp,spec_directory * & sd)93 void use_file(char *filename, bFILE *&fp, spec_directory *&sd)
94 {
95   char fn[100];
96   fp=open_file(filename,"rb");
97   if (fp->open_failure())
98   {
99     delete fp;
100     snprintf(fn, sizeof(fn), "art/%s", filename);
101     fp=open_file(fn,"rb");
102     if (fp->open_failure())
103     {
104       printf("Unable to open file %s\n",filename);
105       delete fp;
106       exit(1);
107     }
108   }
109   sd=new spec_directory(fp);
110 }
111 
done_file(bFILE * & fp,spec_directory * & sd)112 void done_file(bFILE *&fp, spec_directory *&sd)
113 {
114   delete fp;
115   delete sd;
116 }
117 
insert_tiles(char * filename)118 void insert_tiles(char *filename)
119 {
120   bFILE *fp=open_file(filename,"rb");
121   if (!fp->open_failure())
122   {
123     int ft=0,bt=0;
124     spec_directory sd(fp);
125     delete fp;
126     int i=0;
127     for (; i<sd.total; i++)
128     {
129       spec_entry *se=sd.entries[i];
130       if (se->type==SPEC_FORETILE)
131         ft++;
132       else if (se->type==SPEC_BACKTILE)
133         bt++;
134     }
135     if (bt)
136       printf("%s : adding %d background tiles (range %d-%d)\n",
137          filename,bt,nbacktiles,nbacktiles+bt-1);
138     if (ft)
139       printf("%s : adding %d foreground tiles (range %d-%d)\n",
140          filename,ft,nforetiles,nforetiles+bt-1);
141     if (!ft && !bt)
142       printf("Warning : file %s has no background or foreground tiles\n",filename);
143     else
144     {
145       int fon=nforetiles,bon=nbacktiles;
146       if (ft)
147         foretiles=(int *)realloc(foretiles,sizeof(int)*(nforetiles+ft));
148       if (bt)
149         backtiles=(int *)realloc(backtiles,sizeof(int)*(nbacktiles+bt));
150 
151       for (i=0; i<sd.total; i++)
152       {
153     if (sd.entries[i]->type==SPEC_FORETILE)
154     {
155       foretiles[fon]=cache.reg(filename,sd.entries[i]->name);
156       fon++;
157       nforetiles++;
158     }
159     if (sd.entries[i]->type==SPEC_BACKTILE)
160     {
161       backtiles[bon]=cache.reg(filename,sd.entries[i]->name);
162       bon++;
163       nbacktiles++;
164     }
165       }
166     }
167   } else
168     printf("Warning : insert_tiles -> file %s could not be read from\n",filename);
169 }
170 
load_tiles(Cell * file_list)171 void load_tiles(Cell *file_list)
172 {
173   bFILE *fp;
174   spec_directory *sd;
175   spec_entry *spe;
176 
177 
178   int num;
179 
180 
181 
182   Cell *fl;
183   int old_fsize=nforetiles,
184       old_bsize=nbacktiles;
185 
186   for (fl=file_list; !NILP(fl); fl=lcdr(fl))
187   {
188     fp=open_file(lstring_value(lcar(fl)),"rb");
189     if (fp->open_failure())
190     {
191       printf("Warning : open %s for reading\n",lstring_value(lcar(fl)));
192       delete fp;
193     }
194     else
195     {
196       sd=new spec_directory(fp);
197       delete fp;
198       int i;
199       for (i=0; i<sd->total; i++)
200       {
201     spe=sd->entries[i];
202         switch (spe->type)
203         {
204           case SPEC_BACKTILE :
205             if (!sscanf(spe->name,"%d",&num))
206               printf("Warning : background tile %s has no number\n",spe->name);
207             else if (nbacktiles<=num) nbacktiles=num+1;
208           break;
209 
210           case SPEC_FORETILE :
211             if (!sscanf(spe->name,"%d",&num))
212               printf("Warning : foreground tile %s has no number\n",spe->name);
213             else if (nforetiles<=num) nforetiles=num+1;
214           break;
215         }
216       }
217       delete sd;
218     }
219   }
220 
221   // enlarge the arrays if needed.
222   if (nbacktiles>old_bsize)
223   {
224     backtiles=(int *)realloc(backtiles,sizeof(int)*nbacktiles);
225     memset(backtiles+old_bsize,-1,(nbacktiles-old_bsize)*sizeof(int));
226   }
227 
228   if (nforetiles>old_fsize)
229   {
230     foretiles=(int *)realloc(foretiles,sizeof(int)*nforetiles);
231     memset(foretiles+old_fsize,-1,(nforetiles-old_fsize)*sizeof(int));
232   }
233 
234 
235 // now load them up
236   for (fl=file_list; !NILP(fl); fl=lcdr(fl))
237   {
238     char const *fn=lstring_value(lcar(fl));
239     fp=open_file(fn,"rb");
240     if (!fp->open_failure())
241     {
242       sd=new spec_directory(fp);
243       delete fp;
244 
245       int i;
246       for (i=0; i<sd->total; i++)
247       {
248     spe=sd->entries[i];
249         switch (spe->type)
250         {
251           case SPEC_BACKTILE :
252 
253             if (sscanf(spe->name,"%d",&num))
254         {
255           if (backtiles[num]>=0)
256           {
257         dprintf("Warning : background tile %d redefined\n",num);
258         cache.unreg(backtiles[num]);
259           }
260           backtiles[num]=cache.reg(fn,spe->name,SPEC_BACKTILE);
261         }
262             break;
263           case SPEC_FORETILE :
264             if (sscanf(spe->name,"%d",&num))
265         {
266           if (foretiles[num]>=0)
267           {
268         dprintf("Warning : foreground tile %d redefined\n",num);
269         cache.unreg(foretiles[num]);
270           }
271           foretiles[num]=cache.reg(fn,spe->name,SPEC_FORETILE);
272         }
273             break;
274         }
275       }
276       delete sd;
277     } else delete fp;
278   }
279 
280 }
281 
282 
283 extern unsigned char fnt6x13[192*104];
284 char lsf[256]="abuse.lsp";
285 
load_data(int argc,char ** argv)286 void load_data(int argc, char **argv)
287 {
288     total_objects=0;
289     total_weapons=0;
290     weapon_types=NULL;
291     figures=NULL;
292     nforetiles=nbacktiles=0;
293     foretiles=NULL;
294     backtiles=NULL;
295     pal=NULL;
296     color_table=NULL;
297 
298 # if 0
299     int should_save_sd_cache = 0;
300 
301     char *cachepath;
302     cachepath = (char *)malloc( strlen( get_save_filename_prefix() ) + 12 + 1 );
303     sprintf( cachepath, "%ssd_cache.tmp", get_save_filename_prefix() );
304 
305     bFILE *load = open_file( cachepath, "rb" );
306     if( !load->open_failure() )
307     {
308         sd_cache.load( load );
309     }
310     else
311     {
312         should_save_sd_cache = 1;
313     }
314     delete load;
315 #endif
316 
317 #if defined __CELLOS_LV2__
318   if (1)
319 #else
320   // don't let them specify a startup file we are connect elsewhere
321   if (!net_start())
322 #endif
323   {
324     for (int i=1; i<argc; i++)
325     {
326       if (!strcmp(argv[i],"-lsf"))
327       {
328     i++;
329     strcpy(lsf,argv[i]);
330       }
331       if (!strcmp(argv[i],"-a"))
332       {
333     i++;
334     snprintf(lsf, sizeof(lsf), "addon/%s/%s.lsp", argv[i], argv[i]);
335       }
336     }
337   }
338 #if !defined __CELLOS_LV2__
339   else if (!get_remote_lsf(net_server,lsf))
340   {
341     dprintf("Unable to get remote lsf from %s\n",net_server);
342     exit(0);
343   }
344 #endif
345   char prog[100];
346   char const *cs;
347 
348   c_mouse1=cache.reg("art/dev.spe","c_mouse1",SPEC_IMAGE,0);
349   c_mouse2=cache.reg("art/dev.spe","c_mouse2",SPEC_IMAGE,0);
350   c_normal=cache.reg("art/dev.spe","c_normal",SPEC_IMAGE,0);
351   c_target=cache.reg("art/dev.spe","c_target",SPEC_IMAGE,0);
352 
353 
354   snprintf(prog, sizeof(prog), "(load \"%s\")\n", lsf);
355 
356   cs=prog;
357   if (!LObject::Compile(cs)->Eval())
358   {
359     printf("unable to open file '%s'\n",lsf);
360     exit(0);
361   }
362   compiled_init();
363   clear_tmp();
364 
365   dprintf("Engine : Registering base graphics\n");
366   for (int z=0; z<=11; z++)
367   {
368     char nm[10];
369     snprintf(nm, sizeof(nm), "l%d", z);
370     light_buttons[z]=cache.reg("art/dev.spe",nm,SPEC_IMAGE,0);
371   }
372 
373 
374   image *tmp_image = new image(vec2i(192, 104), fnt6x13);
375   big_font=new JCFont(tmp_image);
376   delete tmp_image;
377 
378 
379   char const *ff;
380   // FIXME: unnecessary duplicate call
381   if (DEFINEDP(LSymbol::FindOrCreate("frame_file")->GetValue()))
382     ff = lstring_value(LSymbol::FindOrCreate("frame_file")->GetValue());
383   else
384     ff = "art/frame.spe";
385 
386   ok_button   =      cache.reg(ff,"dev_ok",SPEC_IMAGE);
387   cancel_button  =   cache.reg(ff,"cancel",SPEC_IMAGE);
388 
389 //  clouds      =      cache.reg(ff,"clouds",SPEC_IMAGE);
390 
391   lower_volume=      cache.reg(ff,"lower_volume",SPEC_IMAGE);
392   raise_volume=      cache.reg(ff,"raise_volume",SPEC_IMAGE);
393   music_button=      cache.reg(ff,"music",SPEC_IMAGE);
394   sfx_button=        cache.reg(ff,"sound_fx",SPEC_IMAGE);
395   record_button=     cache.reg(ff,"record",SPEC_IMAGE);
396   play_button=       cache.reg(ff,"play",SPEC_IMAGE);
397   window_colors=     cache.reg(ff,"window_colors",SPEC_IMAGE);
398   pause_image=       cache.reg(ff,"pause_image",SPEC_IMAGE);
399   vmm_image=         cache.reg(ff,"vmm",SPEC_IMAGE);
400   border_tile=       cache.reg(ff,"border_tile",SPEC_IMAGE);
401   window_texture=    cache.reg(ff,"window_texture",SPEC_IMAGE);
402 
403 
404   help_screens=NULL;
405   total_help_screens=0;
406 
407   if (DEFINEDP(symbol_value(l_help_screens)))
408   {
409     void *v=symbol_value(l_help_screens);
410     char *ff=lstring_value(CAR(v));  v=CDR(v);
411     total_help_screens=0;
412     while (v) { total_help_screens++; v=CDR(v); }
413     if (total_help_screens)
414     {
415       help_screens=(int *)malloc(sizeof(int)*total_help_screens);
416       v=CDR(symbol_value(l_help_screens));
417       int i=0;
418       for (; v; v=CDR(v),i++)
419         help_screens[i]=cache.reg(ff,lstring_value(CAR(v)),SPEC_IMAGE);
420     }
421     else
422       dprintf("Warning no help images following filename\n");
423   }
424 
425   int i;
426   for (i=1; i<argc; i++)
427   {
428     if (!strcmp(argv[i],"-ec"))
429       l_empty_cache->SetValue(true_symbol);
430     if (!strcmp(argv[i],"-t"))
431     {
432       i++;
433       insert_tiles(argv[i]);
434     }
435   }
436 
437   if (DEFINEDP(symbol_value(l_title_screen)))
438     title_screen=cache.reg_object(NULL,(LObject *)symbol_value(l_title_screen),SPEC_IMAGE,1);
439   else title_screen=-1;
440 
441   if (DEFINEDP(symbol_value(l_cdc_logo)))
442     cdc_logo=cache.reg_object(NULL,(LObject *)symbol_value(l_cdc_logo),SPEC_IMAGE,1);
443   else cdc_logo=-1;
444 
445   start_position_type=0xffff;
446   for(i=0; i<total_objects; i++)
447     if (!strcmp(object_names[i],"START"))
448       start_position_type=i;
449   if (start_position_type==0xffff)
450   {
451     printf("No object named START, cannot start game.\n");
452     exit(0);
453   }
454 
455   sbar.load();
456 
457   load_number_icons();
458 
459 
460   ERROR(nbacktiles,"No background tiles defined!");
461   ERROR(nforetiles,"No foreground tiles defined!");
462   ERROR(foretiles[0]>=0,"No black (0) foreground tile defined!");
463   ERROR(backtiles[0]>=0,"No black (0) background tile defined!");
464   ERROR(big_font_pict!=-1 || small_font_pict!=-1,
465     "No font loaded (use load_big_font or load_small_font)!");
466   f_wid=cache.foret(foretiles[0])->im->Size().x;
467   f_hi=cache.foret(foretiles[0])->im->Size().y;
468   b_wid=cache.backt(backtiles[0])->im->Size().x;
469   b_hi=cache.backt(backtiles[0])->im->Size().y;
470 
471 #if 0
472     if( should_save_sd_cache )
473     {
474         bFILE *save = open_file( cachepath, "wb" );
475         if( !save->open_failure() )
476         {
477             sd_cache.save( save );
478         }
479         delete save;
480     }
481 #endif
482 
483     sd_cache.clear();
484     past_startup = 1;
485 #if 0
486     free( cachepath );
487 #endif
488 }
489 
490 
491 
492 
493 
load_script(char * name)494 char *load_script(char *name)
495 {
496   char fn[100];
497   char *s;
498 
499   snprintf(fn, sizeof(fn), "%s", name);
500   bFILE *fp=open_file(fn,"rb");
501   if (fp->open_failure())
502   {
503     delete fp;
504     return NULL;
505   }
506 
507   long l=fp->file_size();
508   s=(char *)malloc(l+1);
509   ERROR(s,"Malloc error in load_script");
510 
511   fp->read(s,l);
512   s[l]=0;
513   delete fp;
514   return s;
515 }
516 
517 
518 
519 
520 
521 
522 
523 
524 
525 
526 
527 
528 
529 
530 
531 
532