Changeset 503


Ignore:
Timestamp:
Apr 18, 2011, 3:03:48 PM (6 years ago)
Author:
sam
Message:

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

Location:
abuse/trunk/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • abuse/trunk/src/cache.cpp

    r500 r503  
    162162}
    163163
    164 char *CrcManager::get_filename(int32_t filenumber)
     164char *CrcManager::get_filename(int filenumber)
    165165{
    166166  CHECK(filenumber>=0 && filenumber<total_files);
     
    168168}
    169169
    170 uint32_t CrcManager::get_crc(int32_t filenumber, int &failed)
     170uint32_t CrcManager::get_crc(int filenumber, int &failed)
    171171{
    172172  CHECK(filenumber>=0 && filenumber<total_files);
     
    180180}
    181181
    182 void CrcManager::set_crc(int32_t filenumber, uint32_t crc)
     182void CrcManager::set_crc(int filenumber, uint32_t crc)
    183183{
    184184  CHECK(filenumber>=0 && filenumber<total_files);
     
    813813}
    814814
    815 int32_t CacheList::alloc_id()
    816 {
    817   int id;
    818   if (prof_data)
    819   {
    820     the_game->show_help("new id allocated, cache profiling turned off\n");
    821     prof_uninit();
    822   }
    823 
    824   // see if we previously allocated an id, if so check the next spot in the array
    825   // otherwise we will have to scan the whole list for a free id and possible
    826   // grow the list.
    827   if (last_registered+1<total && list[last_registered+1].file_number<0)
    828     id=last_registered+1;
    829   else
    830   {
    831     int i;
    832     CacheItem *ci=list;
    833     for (i=0,id=-1; i<total && id<0; i++,ci++)        // scan list for a free id
    834     {
    835       if (ci->file_number<0)
    836         id=i;
    837     }
    838 
    839     if (id<0)                                 // if no free id's then make list bigger
    840     {
    841       int add_size=20;
    842       list=(CacheItem *)realloc(list,(sizeof(CacheItem)*(total+add_size)));
    843       for (i=0; i<add_size; i++)
    844       {
    845         list[total+i].file_number=-1;         // mark new entries as new
    846     list[total+i].last_access=-1;
    847     list[total+i].data=NULL;
    848       }
    849       id=total;
    850       if (prof_data)                          // new id's have been added old prof_data size won't work
    851       { free(prof_data); prof_data=NULL; }
    852       total+=add_size;
    853     }
    854   }
    855   last_registered=id;
    856   return id;
    857 }
    858 
    859 int32_t CacheList::reg_lisp_block(Cell *block)
    860 {
    861     if (lcache_number == -1)
    862         lcache_number = crc_manager.get_filenumber(lfname);
    863 
    864     int id = alloc_id(), fn = crc_manager.get_filenumber(lfname);
    865     CacheItem *ci = list + id;
    866     CHECK(id < total && list[id].file_number < 0);
    867 
    868     ci->file_number = fn;
    869     ci->last_access = -1;
    870     ci->type = SPEC_EXTERNAL_LCACHE;
    871     ci->data = (void *)block; // we can't cache it out so it must be in memory
    872     return id;
    873 }
    874 
    875 int32_t CacheList::reg_object(char const *filename, void *object, int type, int rm_dups)
    876 {
    877   char *name;
    878   if (item_type(object)==L_CONS_CELL)      // see if we got a object with a filename included
    879   {
    880     filename=lstring_value(lcar(object));
    881     name=lstring_value(lcdr(object));
    882   }
    883   else name=lstring_value(object);        // otherwise should be a string
    884   return reg(filename,name,type,rm_dups);
     815int CacheList::AllocId()
     816{
     817    if (prof_data)
     818    {
     819        the_game->show_help("new id allocated, cache profiling turned off\n");
     820        prof_uninit();
     821    }
     822
     823    // See if we previously allocated an id, if so check the next spot in
     824    // the array otherwise we will have to scan the whole list for a free
     825    // id and possibly grow the list.
     826    int ret = last_registered + 1;
     827    if (ret >= total || list[ret].file_number < 0)
     828    {
     829        // Scan list for a free id
     830        CacheItem *ci = list;
     831        ret = -1;
     832        for (int i = 0; i < total && ret < 0; i++, ci++)
     833            if (ci->file_number < 0)
     834                ret = i;
     835
     836        if (ret < 0) // if no free id then make list bigger
     837        {
     838            int add_size = 20;
     839            list = (CacheItem *)realloc(list,
     840                                  (sizeof(CacheItem) * (total + add_size)));
     841            for (int i = 0; i < add_size; i++)
     842            {
     843                list[total + i].file_number = -1; // mark new entries as new
     844                list[total + i].last_access = -1;
     845                list[total + i].data = NULL;
     846            }
     847            ret = total;
     848            // If new id's have been added, old prof_data size won't work
     849            if (prof_data)
     850            {
     851                free(prof_data);
     852                prof_data = NULL;
     853            }
     854            total += add_size;
     855        }
     856    }
     857    last_registered = ret;
     858    return ret;
     859}
     860
     861int CacheList::reg_object(char const *filename, LObject *object,
     862                          int type, int rm_dups)
     863{
     864    // See if we got a object with a filename included. Otherwise,
     865    // it's a string.
     866    if (item_type(object) == L_CONS_CELL)
     867    {
     868        filename = lstring_value(lcar(object));
     869        object = lcdr(object);
     870    }
     871
     872    return reg(filename, lstring_value(object), type, rm_dups);
    885873}
    886874
    887875extern int total_files_open;
    888876
    889 int32_t CacheList::reg(char const *filename, char const *name, int type, int rm_dups)
    890 {
    891     int id=alloc_id(),i,fn=crc_manager.get_filenumber(filename);
    892     CacheItem *ci=list+id;
    893     CHECK(id<total && list[id].file_number<0);
    894 
    895     if( type == SPEC_EXTERN_SFX ) // If a extern sound effect then just make sure it's there
    896     {
    897         bFILE *check=open_file(filename,"rb");
    898         if (check->open_failure())
     877int CacheList::reg(char const *filename, char const *name, int type, int rm_dups)
     878{
     879    int fn = crc_manager.get_filenumber(filename);
     880    int offset = 0;
     881
     882    if (type == SPEC_EXTERN_SFX)
     883    {
     884        // If an extern sound effect then just make sure it's there. If sound
     885        // is disabled, ignore the load error, just pretend it's all OK.
     886        bFILE *check = open_file(filename, "rb");
     887        if (!check->open_failure())
    899888        {
    900             delete check;
    901             if( sound_avail )
     889            char buf[4];
     890            check->read(buf, 4);
     891            if (memcmp(buf, "RIFF", 4))
    902892            {
    903                 printf("Unable to open file '%s' for reading\n",filename);
     893                printf("File %s is not a WAV file\n", filename);
    904894                exit(0);
    905895            }
    906             else
    907             {
    908                 // Sound is disabled, we don't really care if the sound file
    909                 // is there or not, just pretend it's all ok.
    910                 return id;
    911             }
    912896        }
    913         char buf[4];
    914         check->read(buf,4);
    915         delete check;
    916         if (memcmp(buf,"RIFF",4))
     897        else if (sound_avail)
    917898        {
    918             printf("File %s is not a WAV file\n",filename);
     899            printf("Unable to open file '%s' for reading\n", filename);
    919900            exit(0);
    920901        }
    921         ci->file_number=fn;
    922         ci->last_access=-1;
    923         ci->data=NULL;
    924         ci->offset=0;
    925         ci->type=type;
    926         return id;
    927     }
    928 
    929     spec_directory *sd=sd_cache.get_spec_directory(filename);
    930 
    931     if (!sd)
    932     {
    933         printf("Unable to open filename %s for requested item %s\n",filename,name);
    934         exit(0);
    935     }
    936 
    937     spec_entry *se;
    938     if (type!=-1)
    939     {
    940         se=sd->find(name,type);
    941         if (!se) se=sd->find(name);
    942     }
    943     else se=sd->find(name);
    944 
    945 
    946     if (!se)
    947     {
    948         printf("No such item %s in file %s\n",name,filename);
    949         exit(0);
    950     }
    951     else if (type>=0 && (type!=se->type && ((type!=SPEC_CHARACTER2 && type!=SPEC_CHARACTER)  ||
    952                         (se->type!=SPEC_CHARACTER && se->type!=SPEC_CHARACTER2))))
    953     {
    954         printf("Item %s of file %s should be type %s\n",name,filename,spec_types[type]);
    955         exit(0);
    956     }
    957 
     902        delete check;
     903    }
     904    else
     905    {
     906        // If a classic spec item, look for it in the archive.
     907        spec_directory *sd = sd_cache.get_spec_directory(filename);
     908
     909        if (!sd)
     910        {
     911            printf("Unable to open file %s for item %s\n", filename, name);
     912            exit(0);
     913        }
     914
     915        spec_entry *se = NULL;
     916        if (type != -1)
     917            se = sd->find(name, type);
     918        if (!se)
     919            se = sd->find(name);
     920        if (!se)
     921        {
     922            printf("No such item %s in file %s\n", name, filename);
     923            exit(0);
     924        }
     925
     926        if (type >= 0 && type != se->type &&
     927             ((type != SPEC_CHARACTER2 && type != SPEC_CHARACTER)
     928               || (se->type != SPEC_CHARACTER && se->type != SPEC_CHARACTER2)))
     929        {
     930            printf("Item %s of file %s should be type %s\n",
     931                   name, filename, spec_types[type]);
     932            exit(0);
     933        }
     934
     935        type = se->type;
     936        offset = se->offset;
     937    }
     938
     939    // Check whether there is another entry pointing to the same
     940    // file and offset, and return it as a shortcut.
    958941    if (rm_dups)
    959942    {
    960         for (i=0; i<total; i++)
    961             if (list[i].file_number == fn && (unsigned)list[i].offset == se->offset)
     943        for (int i = 0; i < total; i++)
     944            if (list[i].file_number == fn && list[i].offset == offset)
    962945                return i;
    963946    }
    964947
    965     ci->file_number=fn;
    966     ci->last_access=-1;
    967     ci->data=NULL;
    968     ci->offset=se->offset;
    969     ci->type=se->type;
     948    int id = AllocId();
     949
     950    CHECK(id < total && list[id].file_number < 0);
     951
     952    list[id].file_number = fn;
     953    list[id].last_access = -1;
     954    list[id].data = NULL;
     955    list[id].offset = offset;
     956    list[id].type = type;
     957
    970958    return id;
    971959}
     
    10421030    locate(me);
    10431031    me->data=(void *)new figure(fp,me->type);
    1044     last_offset=fp->tell();
     1032     last_offset=fp->tell();
    10451033    return (figure *)me->data;
    10461034  }
     
    11071095
    11081096
    1109 Cell *CacheList::lblock(int id)
     1097LObject *CacheList::lblock(int id)
    11101098{
    11111099  CacheItem *me=list+id;
    11121100  CONDITION(id<total && id>=0 && me->file_number>=0,"Bad id");
    1113   return (Cell *)me->data;
     1101  return (LObject *)me->data;
    11141102}
    11151103
  • abuse/trunk/src/cache.h

    r494 r503  
    4747
    4848    int get_filenumber(char const *filename);
    49     uint32_t get_crc(int32_t filenumber, int &failed);
    50     void set_crc(int32_t filenumber, uint32_t crc);
    51     char *get_filename(int32_t filenumber);
     49    uint32_t get_crc(int filenumber, int &failed);
     50    void set_crc(int filenumber, uint32_t crc);
     51    char *get_filename(int filenumber);
    5252    void clean_up();
    5353    int total_filenames() { return total_files; }
     
    9090
    9191    int16_t lcache_number;
    92     int32_t alloc_id();
     92
     93    int AllocId();
    9394    void locate(CacheItem *i, int local_only = 0); // set up file and offset for this item
    9495    void normalize();
     
    108109    int in_use() { if (used) { used = 0; return 1; } else return 0; }
    109110    int full() { if (ful) { ful = 0; return 1; } else return 0; }
    110     int32_t reg_object(char const *filename, void *object, int type,
    111                        int rm_dups); // lisp object
    112     int32_t reg(char const *filename, char const *name, int type = -1,
     111    int reg_object(char const *filename, LObject *object, int type,
     112                   int rm_dups); // lisp object
     113    int reg(char const *filename, char const *name, int type = -1,
    113114                int rm_dups = 0); // returns id to item
    114     int32_t reg_lisp_block(Cell *block);
    115115    int loaded(int id);
    116116    void unreg(int id);
     
    123123    part_frame *part(int id);
    124124    sound_effect *sfx(int id);
    125     Cell *lblock(int id);
     125    LObject *lblock(int id);
    126126    char_tint *ctint(int id);
    127127
  • abuse/trunk/src/loader2.cpp

    r496 r503  
    426426
    427427  if (DEFINEDP(symbol_value(l_title_screen)))
    428     title_screen=cache.reg_object(NULL,symbol_value(l_title_screen),SPEC_IMAGE,1);
     428    title_screen=cache.reg_object(NULL,(LObject *)symbol_value(l_title_screen),SPEC_IMAGE,1);
    429429  else title_screen=-1;
    430430
    431431  if (DEFINEDP(symbol_value(l_cdc_logo)))
    432     cdc_logo=cache.reg_object(NULL,symbol_value(l_cdc_logo),SPEC_IMAGE,1);
     432    cdc_logo=cache.reg_object(NULL,(LObject *)symbol_value(l_cdc_logo),SPEC_IMAGE,1);
    433433  else cdc_logo=-1;
    434434
  • abuse/trunk/src/seq.cpp

    r494 r503  
    4545  seq=(int *) malloc(sizeof(int)*total);
    4646  if (item_type(pict_list)==L_STRING)
    47     seq[0]=cache.reg_object(filename,pict_list,SPEC_CHARACTER2,1);
     47    seq[0]=cache.reg_object(filename,(LObject *)pict_list,SPEC_CHARACTER2,1);
    4848  else
    4949  {
Note: See TracChangeset for help on using the changeset viewer.