source: abuse/trunk/src/loader2.cpp @ 503

Last change on this file since 503 was 503, checked in by Sam Hocevar, 11 years ago

cache: fix a crash caused by empty SFX objects being reused for other
purposes but still being deleted later on.

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