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