source: abuse/trunk/src/imlib/specs.cpp @ 86

Last change on this file since 86 was 86, checked in by Sam Hocevar, 14 years ago
  • Get rid of nonexistent macify_name() function. According to the original source tree, this function simply replaced slashes with underscores in filenames.
File size: 20.5 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *
5 *  This software was released into the Public Domain. As with most public
6 *  domain software, no warranty is made or implied by Crack dot Com or
7 *  Jonathan Clark.
8 */
9
10#include "config.h"
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <stdint.h>
15#include <ctype.h>
16#include <fcntl.h>
17#include <math.h>
18#if (defined(__MACH__) || !defined(__APPLE__))
19#   include <sys/types.h>
20#   include <sys/stat.h>
21#endif
22
23#include "image.hpp"
24#include "palette.hpp"
25#include "specs.hpp"
26#include "system.h"
27#include "jmalloc.hpp"
28#include "dprint.hpp"
29
30char const *spec_types[] =
31{
32    "Invalid type", // 0
33    "Color table",  // 1
34    "Palette",      // 2
35    "Invalid Type", // 3
36    "Image",        // 4
37    "Fore Tile",
38    "Back Tile",
39    "Character",
40    "8 Morph",
41    "16 Morph",
42    "Grue objs",
43    "Extern WAV",
44    "DMX MUS",
45    "Patched morph",
46    "Normal file",
47    "Compress1 file",
48    "Vector Image",
49    "Light list",
50    "Grue fgmap",
51    "Grue bgmap",
52    "Data array",
53    "Character2",
54    "Particle",
55    "Extern lcache"
56};
57
58
59int total_files_open=0;
60char spec_main_file[100];
61
62static char *spec_prefix=NULL;
63static char *save_spec_prefix=NULL;
64
65static jFILE spec_main_jfile((FILE*)0);
66static int spec_main_fd = -1;
67static long spec_main_offset = -1;
68static spec_directory spec_main_sd;
69
70static int fast_load_fd = -1;
71static int fast_load_mode = 0;
72
73void set_filename_prefix(char const *prefix)
74{
75        if( spec_prefix )
76        {
77                jfree( spec_prefix );
78        }
79       
80        if( prefix )
81        {
82                spec_prefix = strcpy( (char *)jmalloc( strlen( prefix ) + 2, "prefix_name" ), prefix );
83                int len = strlen( prefix );
84                if( prefix[len - 1] != '\\' && prefix[len - 1] != '/')
85                {
86                        spec_prefix[len] = '/';
87                        spec_prefix[len + 1] = 0;
88                }
89        }
90        else
91        {
92                spec_prefix = NULL;
93        }
94}
95
96char *get_filename_prefix()
97{
98        return spec_prefix;
99}
100
101
102void set_save_filename_prefix(char const *save_prefix)
103{
104        if( save_spec_prefix )
105        {
106                jfree( save_spec_prefix );
107        }
108
109        if( save_prefix )
110        {
111                int len = strlen( save_prefix );
112                save_spec_prefix = (char *)jmalloc( len + 1, "prefix_name" );
113                strcpy( save_spec_prefix, save_prefix );
114/* AK - Commented this out as it may cause problems
115                if( save_prefix[len - 1] != '\\' && save_prefix[len - 1] != '/' )
116                {
117                        save_spec_prefix[len] = '/';
118                        save_spec_prefix[len + 1] = '\0';
119                } */
120        }
121        else
122        {
123                save_spec_prefix = NULL;
124        }
125}
126
127char *get_save_filename_prefix()
128{
129  return save_spec_prefix;
130}
131
132int search_order=SPEC_SEARCH_OUTSIDE_INSIDE;
133
134static void (*no_space_handle_fun)()=NULL;
135
136void set_no_space_handler(void (*handle_fun)())
137{
138  no_space_handle_fun=handle_fun;
139}
140
141
142bFILE::bFILE()
143{
144  rbuf_size=8192;
145  rbuf=(unsigned char *)jmalloc(rbuf_size,"File read buffer");
146  rbuf_start=rbuf_end=0; 
147
148  wbuf_size=8192;
149  wbuf=(unsigned char *)jmalloc(wbuf_size,"File write buffer");
150  wbuf_end=0; 
151}
152
153bFILE::~bFILE()
154{
155  if (rbuf) jfree(rbuf);
156  flush_writes();
157  if (wbuf) jfree(wbuf);
158}
159
160int bFILE::flush_writes()
161{
162  if (wbuf_end!=0)
163  {
164    unsigned long ret=unbuffered_write(wbuf,wbuf_end);
165    if (ret!=wbuf_end && no_space_handle_fun)
166      no_space_handle_fun();
167     
168    wbuf_end=0;
169    return ret;
170  }
171  return 0;
172}
173
174int bFILE::read(void *buf, size_t count)       // returns number of bytes read, calls unbuffer_read
175{
176  if (!allow_read_buffering())
177    return unbuffered_read(buf,count);
178
179  int total_read=0,error=0;
180  if (!count) return 0;
181  while (count && !error)
182  {
183    if (rbuf_start<rbuf_end)
184    {
185      unsigned int avail_size=rbuf_end-rbuf_start;
186      int copy_size=avail_size>count ? count : avail_size;
187      memcpy(buf,rbuf+rbuf_start,copy_size);
188      buf=(void *)(((unsigned char *)buf)+copy_size);
189      rbuf_start+=copy_size;
190      if (rbuf_start>=rbuf_end)   
191      {
192                                if (rbuf_end!=rbuf_size)  // buffer wasn't full before so there is no way we can complete read
193                                  error=1;
194                                rbuf_start=rbuf_end=0;
195      }
196      total_read+=copy_size;
197      count-=copy_size;
198    } else
199    {
200      rbuf_end=unbuffered_read(rbuf,rbuf_size);
201      if (rbuf_end==0) error=1;
202      rbuf_start=0;
203    }
204  }
205  return total_read;
206}
207
208
209int bFILE::write(void const *buf, size_t count)      // returns number of bytes written
210{
211  if (allow_write_buffering())
212  {
213    int total_written=0;
214    while (count)
215    {
216      int copy_size=wbuf_end+count<=wbuf_size ? count :  wbuf_size-wbuf_end;           
217      memcpy(wbuf+wbuf_end,buf,copy_size);
218      wbuf_end+=copy_size;
219      count-=copy_size;
220      buf=(void *)(((char *)buf)+copy_size);
221      if (wbuf_end==wbuf_size)
222        if ((unsigned int)flush_writes()!=wbuf_size)
223          return total_written;
224     
225      total_written+=copy_size;     
226    }
227    return total_written;
228  } else
229  {
230    unsigned long ret=unbuffered_write(buf,count);
231    if (ret!=count && no_space_handle_fun)
232      no_space_handle_fun();
233  }
234  return 0;
235}
236
237int bFILE::seek(long offset, int whence) // whence=SEEK_SET, SEEK_CUR, SEEK_END, ret=0=success
238
239//    rbuf_start=rbuf_end=0;
240//    unbuffered_seek(offset,SEEK_SET);
241
242  long realpos=unbuffered_tell();
243  long curpos=realpos-rbuf_end+rbuf_start;
244  if (whence==SEEK_CUR) offset+=curpos;
245  else if (whence==SEEK_END) offset=file_size()-offset;
246
247  if (offset<realpos-(long)rbuf_end || offset>=realpos)
248  {
249    rbuf_start=rbuf_end=0;
250    unbuffered_seek(offset,SEEK_SET);
251  } else 
252    rbuf_start=rbuf_end-(realpos-offset);
253  return 1;
254}
255
256int bFILE::tell()
257{
258  return unbuffered_tell()-rbuf_end+rbuf_start+
259         wbuf_end;    // if this a write file, add on how much we've written
260}
261
262int bFILE::allow_read_buffering() { return 1; }
263int bFILE::allow_write_buffering() { return 1; }
264
265void bFILE::set_read_buffer_size(long size)
266{
267  unbuffered_seek(tell(),SEEK_SET);
268  rbuf_start=rbuf_end=0;
269  if (rbuf)
270    jfree(rbuf);
271  rbuf_size=size;
272  rbuf=(unsigned char *)jmalloc(rbuf_size,"File buffer");
273}
274
275void set_spec_main_file(char const *filename, int Search_order)
276{
277  dprintf("Specs : main file set to %s\n",filename);
278  strcpy(spec_main_file,filename);
279  search_order=Search_order;
280 
281#if (defined(__APPLE__) && !defined(__MACH__))
282  spec_main_jfile.open_external(filename,"rb",O_BINARY|O_RDONLY);
283#else
284  spec_main_jfile.open_external(filename,"rb",O_RDONLY);
285#endif
286  spec_main_fd = spec_main_jfile.get_fd();
287  if (spec_main_fd==-1)
288    return;
289  spec_main_sd.startup(&spec_main_jfile);
290}
291
292void fast_load_start_recording(char *filename)
293{
294    fast_load_fd = ::open(filename,O_CREAT|O_RDWR,S_IRWXU | S_IRWXG | S_IRWXO);
295    fast_load_mode = 1;
296}
297
298void fast_load_stop_recording()
299{
300    fast_load_mode = 0;
301}
302
303void fast_load_start_reloading(char *filename)
304{
305    fast_load_fd = ::open(filename,O_RDONLY);
306    fast_load_mode = 2;
307}
308
309void fast_load_stop_reloading()
310{
311    fast_load_mode = 0;
312}
313
314jFILE::jFILE(FILE *file_pointer)                       // assumes fp is at begining of file
315{
316  access=0;
317  fd=-1;
318  file_length=0;
319  start_offset=0;
320  flags=JFILE_CLONED;
321}
322
323void jFILE::open_external(char const *filename, char const *mode, int flags)
324{
325  int skip_size=0;
326  char tmp_name[200];
327  if (spec_prefix && filename[0] != '/')
328    sprintf(tmp_name,"%s%s",spec_prefix,filename);
329  else strcpy(tmp_name,filename);
330
331//  int old_mask=umask(S_IRWXU | S_IRWXG | S_IRWXO);
332#ifdef __WATCOMC__
333  flags|=O_BINARY;
334#endif
335  if (flags&O_WRONLY)
336  {
337    if ((flags&O_APPEND)==0)
338    {
339      skip_size=1;
340      //int errval = unlink(tmp_name);
341    }
342
343    flags-=O_WRONLY;
344    flags|=O_CREAT|O_RDWR;
345
346    fd=open(tmp_name,flags,S_IRWXU | S_IRWXG | S_IRWXO);
347  } else
348    fd=open(tmp_name,flags);
349
350//  umask(old_mask);
351  if (fd>=0 && !skip_size)
352  {
353    file_length=lseek(fd,0,SEEK_END);
354    if ((flags&O_APPEND)==0)
355      lseek(fd,0,SEEK_SET);
356    else
357        current_offset = file_length;
358    start_offset=0;
359  } else
360  {
361    file_length=0;
362    start_offset=0;
363  }
364}
365
366
367class null_file : public bFILE     // this file type will use virtual opens inside of a spe
368{
369  public :
370  virtual int open_failure() { return 1; }
371  virtual int unbuffered_read(void *buf, size_t count)   { return 0; }
372  virtual int unbuffered_write(void const *buf, size_t count)  { return 0; }
373  virtual int unbuffered_seek(long offset, int whence)   { return 0; }
374
375  virtual int unbuffered_tell() { return 0; }
376  virtual int file_size() { return 0; }
377  virtual ~null_file() { ; }
378} ;
379
380
381static bFILE *(*open_file_fun)(char const *,char const *)=NULL;
382int (*verify_file_fun)(char const *,char const *)=NULL;
383
384void set_file_opener(bFILE *(*open_fun)(char const *, char const *))
385{
386  open_file_fun=open_fun;
387}
388
389bFILE *open_file(char const *filename, char const *mode)
390{
391  if (!verify_file_fun || verify_file_fun(filename,mode))
392  {
393    if (open_file_fun)
394      return open_file_fun(filename,mode);
395    else return new jFILE(filename,mode);
396  } else return new null_file;
397}
398
399void jFILE::open_internal(char const *filename, char const *mode, int flags)
400{
401  int wr=0;
402  for (char const *s=mode;*s;s++)
403    if (toupper(*s)=='A' || toupper(*s)=='W')
404      wr=1;
405
406  if (wr)
407    fd=-1;                 // only allow extern file openings for writing
408  else
409  {
410        fd = spec_main_fd;
411    if (fd>=0)                    // if we were able to open the main file, see if it's in there
412    {
413      start_offset=0;
414      spec_entry *se=spec_main_sd.find(filename);
415      if (se)   
416      {
417        start_offset=se->offset;
418        current_offset = 0;
419        file_length=se->size;
420        rbuf_start=rbuf_end=0;
421      } else
422      {
423        close(fd);
424        fd=-1;
425      }
426    } 
427  }
428}
429
430jFILE::jFILE(char const *filename, char const *access_string)      // same as fopen parameters
431{
432 flags=access=0; 
433 char const *s=access_string;
434  for (;*s;s++)
435    if (toupper(*s)=='R') access=O_RDONLY;
436
437  for (s=access_string;*s;s++)
438    if (toupper(*s)=='W')     
439      if (access)
440        access=O_RDWR;
441      else access=O_WRONLY;
442
443  for (s=access_string;*s;s++)
444    if (toupper(*s)=='A')     
445      access|=O_APPEND|O_WRONLY;
446
447  file_length=start_offset=-1;
448  current_offset = 0;
449
450  fd=-1;
451  if (search_order==SPEC_SEARCH_OUTSIDE_INSIDE)
452    open_external(filename,access_string,access);
453
454  if (fd<0)
455    open_internal(filename,access_string,access);
456
457  if (fd<0 && search_order==SPEC_SEARCH_INSIDE_OUTSIDE)
458    open_external(filename,access_string,access);
459
460  total_files_open++;
461}
462
463jFILE::~jFILE()
464{
465  flush_writes();
466  if (fd>=0 && !(flags&JFILE_CLONED))
467  {
468    total_files_open--;
469    if (fd != spec_main_fd)
470            close(fd);
471  }
472}
473
474int jFILE::unbuffered_tell()
475{
476//      int ret = ::lseek(fd,0,SEEK_CUR) - start_offset;
477//      if (ret != current_offset)
478//              fprintf(stderr,"Bad tell %d\n",current_offset);
479        return current_offset;
480}
481
482int jFILE::unbuffered_read(void *buf, size_t count)
483{
484        unsigned long len;
485
486        if (fd == spec_main_fd)
487        {
488                switch (fast_load_mode)
489                {
490                case 0:
491                        if (current_offset+start_offset != spec_main_offset)
492                                spec_main_offset = lseek(fd, start_offset+current_offset, SEEK_SET);
493                       
494                        len = ::read(fd,(char*)buf,count);
495                        break;
496                case 1:
497                        if (current_offset+start_offset != spec_main_offset)
498                                spec_main_offset = lseek(fd, start_offset+current_offset, SEEK_SET);
499                       
500                        len = ::read(fd,(char*)buf,count);
501                        ::write(fast_load_fd,(char*)&len,sizeof(len));
502                        ::write(fast_load_fd,(char*)buf,len);
503                        break;
504                case 2:
505                        ::read(fast_load_fd,(char*)&len,sizeof(len));
506                        len = ::read(fast_load_fd,(char*)buf,len);
507                        break;
508                }
509               
510                spec_main_offset += len;
511        }
512        else
513        {
514                switch (fast_load_mode)
515                {
516                case 0:
517                len = ::read(fd,(char*)buf,count);
518                break;
519                case 1:
520                len = ::read(fd,(char*)buf,count);
521                        ::write(fast_load_fd,(char*)&len,sizeof(len));
522                        ::write(fast_load_fd,(char*)buf,len);
523                break;
524                case 2:
525                        ::read(fast_load_fd,(char*)&len,sizeof(len));
526                        len = ::read(fast_load_fd,(char*)buf,len);
527                        if (count != len)
528                                printf("short read! %ld:%ld\n",current_offset,len);
529                break;
530          }
531        }
532        current_offset += len;
533        return len;
534}
535
536int jFILE::unbuffered_write(void const *buf, size_t count)
537{
538  long ret = ::write(fd,(char*)buf,count);
539        current_offset += ret;
540        return ret;
541}
542
543int jFILE::unbuffered_seek(long offset, int whence) // whence=SEEK_SET, SEEK_CUR, SEEK_END, ret=0=success
544{
545  long ret;
546
547  if (fast_load_mode == 2)
548  {
549    switch (whence)
550    {
551    case SEEK_SET :
552      current_offset = start_offset+offset;
553      break;
554    case SEEK_END :
555      current_offset = start_offset+file_length-offset;
556      break;
557    case SEEK_CUR :
558      current_offset += offset;
559      break;
560    default:
561      ret = -1;
562      break;
563    }
564    return current_offset;
565  }
566
567  switch (whence)
568  {
569    case SEEK_SET :
570    { ret = lseek(fd,start_offset+offset,SEEK_SET); } break;
571    case SEEK_END :
572    { ret = lseek(fd,start_offset+file_length-offset,SEEK_SET); } break;
573    case SEEK_CUR :
574    { ret = lseek(fd,offset,SEEK_CUR); } break;
575    default:
576        ret = -1;
577        break;
578  }
579  if (ret>=0)
580  {
581    current_offset = ret - start_offset;
582    if (spec_main_fd == fd)
583      spec_main_offset = ret;
584    return ret;
585  }
586  else
587    return -1;  // if a bad whence, then failure
588}
589
590
591uint8_t bFILE::read_uint8()
592{ uint8_t x;
593  read(&x,1);
594  return x;
595}
596
597uint16_t bFILE::read_uint16()
598{
599  uint16_t x;
600  read(&x,2);
601  return uint16_to_local(x);
602}
603
604
605uint32_t bFILE::read_uint32()
606{
607  uint32_t x;
608  read(&x,4);
609  return uint32_to_local(x);
610}
611
612void bFILE::write_uint8(uint8_t x)
613{
614  write(&x,1);
615}
616
617void bFILE::write_uint16(uint16_t x)
618{
619  x=uint16_to_local(x);
620  write(&x,2);
621}
622
623
624void bFILE::write_uint32(uint32_t x)
625{
626  x=uint32_to_local(x);
627  write(&x,4);
628}
629
630void bFILE::write_double(double x)
631{
632  double a;
633  write_uint32((long)(modf(x,&a)*(double)(1<<32-1)));
634  write_uint32((long)a);
635}
636
637double bFILE::read_double()
638{
639  long a,b;
640  a=read_uint32();
641  b=read_uint32();
642  return (double)b+a/(double)(1<<32-1);
643}
644
645spec_directory::~spec_directory()
646{
647
648  if (total)
649  {
650    jfree(data);
651    jfree(entries);
652  }
653}
654
655void spec_entry::print()
656{
657  printf("%15s%25s%8ld%8ld\n",spec_types[type],name,size,offset);
658}
659
660void spec_directory::calc_offsets()
661{
662  spec_entry **e;
663  int i;
664  long o=SPEC_SIG_SIZE+2;
665  if (total)
666  {
667    for (i=0,e=entries;i<total;i++,e++)          // calculate the size of directory info
668    {
669      o+=1+1+strlen((*e)->name)+1 +1 +8;
670    }
671
672    for (i=0,e=entries;i<total;i++,e++)          // calculate offset for each entry
673    {
674      (*e)->offset=o;
675      o+=(*e)->size;
676    }
677  }
678}
679
680spec_entry *spec_directory::find(char const *name, int type)
681{
682  int i;
683  spec_entry **e;
684  for (i=0,e=entries;i<total;i++,e++)
685    if (!strcmp((*e)->name,name) && (*e)->type==type)
686      return (*e);
687  return NULL;
688}
689
690spec_entry *spec_directory::find(char const *name)
691{
692  int i;
693  spec_entry **e;
694  for (i=0,e=entries;i<total;i++,e++)
695    if (!strcmp((*e)->name,name))
696      return (*e);
697  return NULL;
698}
699
700long spec_directory::find_number(char const *name)
701{
702  int i;
703  spec_entry **e;
704  for (i=0,e=entries;i<total;i++,e++)
705    if (!strcmp((*e)->name,name))
706      return i;
707  return -1;
708}
709
710spec_entry *spec_directory::find(int type)
711{
712  int i;
713  spec_entry **e;
714  for (i=0,e=entries;i<total;i++,e++)
715    if ((*e)->type==type)
716      return (*e);
717  return NULL;
718}
719
720long spec_directory::type_total(int type)
721{
722  int i,x=0;
723  spec_entry **e;
724  for (i=0,e=entries;i<total;i++,e++)
725    if ((*e)->type==type) x++;
726  return x;
727}
728
729long spec_directory::find_number(int type)
730{
731  int i;
732  spec_entry **e;
733  for (i=0,e=entries;i<total;i++,e++)
734    if ((*e)->type==type)
735      return i;
736  return -1;
737}
738
739void spec_directory::print()
740{
741  spec_entry **se;
742  int i;
743  printf("[   Entry type   ][   Entry name   ][  Size  ][ Offset ]\n");
744  for (i=0,se=entries;i<total;i++,se++)
745    (*se)->print();
746}
747
748
749void spec_directory::startup(bFILE *fp)
750{
751  char buf[256];
752  memset(buf,0,256);
753  fp->read(buf,8);
754  buf[9]=0;
755  size=0;
756  if (!strcmp(buf,SPEC_SIGNATURE))
757  {   
758    total=fp->read_uint16();   
759    entries=(spec_entry **)jmalloc(sizeof(spec_entry *)*total,"spec_directory::entries");
760    long start=fp->tell();
761
762    int i;
763    for (i=0;i<total;i++)
764    {           
765      fp->read(buf,2);
766      long entry_size=sizeof(spec_entry)+(unsigned char)buf[1];
767      entry_size=(entry_size+3)&(~3);
768      fp->read(buf,(unsigned char)buf[1]);
769      fp->read(buf,9);
770
771      size+=entry_size;
772    }
773    data=jmalloc(size,"spec_directory::data");
774    char *dp=(char *)data;
775    fp->seek(start,SEEK_SET);
776    for (i=0;i<total;i++)
777    {           
778      spec_entry *se=(spec_entry *)dp;
779      entries[i]=se;
780
781      unsigned char len,flags,type;
782      fp->read(&type,1);     
783      fp->read(&len,1);
784      se->type=type;
785      se->name=dp+sizeof(spec_entry);
786      fp->read(se->name,len);
787      fp->read(&flags,1);
788
789      se->size=fp->read_uint32();
790      se->offset=fp->read_uint32();
791      dp+=((sizeof(spec_entry)+len)+3)&(~3);
792    }
793  }
794  else
795  {
796    total=0;
797    data=NULL;
798    entries=NULL;
799  } 
800}
801
802
803spec_directory::spec_directory(bFILE *fp)
804{ startup(fp); }
805
806spec_directory::spec_directory(FILE *fp)
807{
808  jFILE jfp(fp);
809  startup(&jfp);
810}
811
812spec_directory::spec_directory()
813{
814  size=0;
815  total=0;
816  data=NULL;
817  entries=NULL;
818}
819
820/*
821spec_directory::spec_directory(char *filename)
822{
823  jFILE *fp;
824  if (filename)
825  {
826    fp=new jFILE(filename,"rb");
827    if (!fp->open_failure())
828      startup(fp);
829    else
830    {
831      total=0;
832      entries=NULL;
833    }
834    delete fp;
835  } else printf("NULL filename to spec_directory::spec_directory\n");
836}*/
837
838int write_string(bFILE *fp, char const *st)
839{
840  unsigned char length=strlen(st)+1;
841  if (fp->write(&length,1)!=1) return 0;
842  if (fp->write(st,length)!=length) return 0;
843  return 1;
844}
845
846long spec_directory::data_start_offset()
847{
848  long i;
849  for (i=0;i<total;i++)
850    return entries[i]->offset;
851
852  return SPEC_SIG_SIZE+2;     // if no entries, then no data, but return where it would
853                              // start anyway
854}
855
856long spec_directory::data_end_offset()
857{
858  spec_entry **e;
859  long i;
860  for (i=total-1,e=entries;i>=0;i--,e++)
861    return (*e)->offset+(*e)->size;
862
863  return SPEC_SIG_SIZE+2;
864}
865
866int spec_directory::write(bFILE *fp)
867{
868
869  char sig[SPEC_SIG_SIZE];
870  unsigned char flags=0;
871  unsigned long offset,data_size;
872  spec_entry **e;
873  strcpy(sig,SPEC_SIGNATURE);
874
875  if (fp->write(sig,sizeof(sig))!=sizeof(sig))    return 0;
876  fp->write_uint16(total);
877
878
879  int i;
880  for (i=0,e=entries;i<total;i++,e++)
881  {
882    if (fp->write(&(*e)->type,1)!=1)                 return 0;
883    if (!write_string(fp,(*e)->name))                return 0;
884    flags=0;
885    if (fp->write(&flags,1)!=1)                     return 0;
886
887    data_size=uint32_to_intel((*e)->size);
888    if (fp->write((char *)&data_size,4)!=4)              return 0;
889    offset=uint32_to_intel((*e)->offset);
890    if (fp->write((char *)&offset,4)!=4)                  return 0;
891
892  }
893  return 1;
894}
895
896jFILE *spec_directory::write(char const *filename)
897{
898  jFILE *fp;
899  fp=new jFILE(filename,"wb");
900  if (fp->open_failure()) { delete fp; return NULL; }
901  if (!write(fp))
902  {
903    delete fp;
904    return NULL;
905  } else return fp;
906
907}
908
909uint16_t read_uint16(FILE *fp)
910{
911  uint16_t x;
912  fread(&x,1,2,fp);
913  return uint16_to_local(x);
914}
915
916uint32_t read_uint32(FILE *fp)
917{
918  uint32_t x;
919  fread(&x,1,4,fp);
920  return uint32_to_local(x);
921}
922void write_uint16(FILE *fp, uint16_t x)
923{
924  x=uint16_to_local(x);
925  fwrite(&x,1,2,fp);
926}
927
928void write_uint32(FILE *fp, uint32_t x)
929{
930  x=uint32_to_local(x);
931  fwrite(&x,1,4,fp);
932}
933
934uint8_t read_uint8(FILE *fp) { return fgetc(fp)&0xff; }
935void write_uint8(FILE *fp, uint8_t x) { fputc((unsigned char)x,fp); }
936
937uint32_t read_other_int32(FILE *fp)
938{
939  uint32_t x;
940  fread(&x,1,4,fp);
941  return big_uint32_to_local(x);
942}
943
944uint16_t read_other_uint16(FILE *fp)
945{
946  uint16_t x;
947  fread(&x,1,2,fp);
948  return big_uint16_to_local(x);
949}
950
951
952void write_other_uint16(FILE *fp, uint16_t x)
953{
954  x=big_uint16_to_local(x);
955  fwrite(&x,1,2,fp);
956}
957
958void write_other_int32(FILE *fp, uint32_t x)
959{
960  x=big_uint32_to_local(x);
961  fwrite(&x,1,4,fp);
962}
963
964void spec_directory::remove(spec_entry *e)
965{
966  int i;
967  for (i=0;i<total && entries[i]!=e;i++);            // find the entry in the array first
968 
969  if (entries[i]==e)                                 // make sre it was found
970  {
971    delete e;
972    total--;
973    for (;i<total;i++)                               // compact the pointer array
974      entries[i]=entries[i+1];
975    entries=(spec_entry **)jrealloc(entries,sizeof(spec_entry *)*total,"spec_directory::entries");
976  }
977  else
978    printf("Spec_directory::remove bad entry pointer\n");
979}
980
981
982
983void spec_directory::add_by_hand(spec_entry *e)
984{
985  total++;
986  entries=(spec_entry **)jrealloc(entries,sizeof(spec_entry *)*total,"spec_directory::entries");
987  entries[total-1]=e;
988}
989
990void spec_directory::delete_entries()   // if the directory was created by hand instead of by file
991{
992  int i;
993  for (i=0;i<total;i++)
994    delete entries[i];
995
996  if (total)
997    jfree(entries);
998}
999
1000
1001void note_open_fd(int fd, char const *str)
1002{
1003  total_files_open++;
1004}
1005
1006void note_close_fd(int fd)
1007{
1008  total_files_open--;
1009}
1010
1011
1012void list_open_fds()
1013{
1014  printf("Total open dos fds=%d\n",total_files_open);
1015}
1016
Note: See TracBrowser for help on using the repository browser.