⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resmgr.c

📁 空战游戏flacon源码
💻 C
📖 第 1 页 / 共 5 页
字号:

    /* haven't failed so far... */

    return( TRUE );
}




/* =======================================================

   FUNCTION:   ResDismountCD

   PURPOSE:    Dismount the currently mounted CD.

   PARAMETERS: None.

   RETURNS:    TRUE (pass) / FALSE (fail)

   ======================================================= */

RES_EXPORT int ResDismountCD( void )
{
    ARCHIVE    * archive;
    LIST       * list;
    int          hit;
    int         dir;   /* GFG change from char to int */

    if( GLOBAL_CD_DEVICE == -1 )
        return( FALSE );

    if( ARCHIVE_LIST ) {

        do {
    
            hit = 0;

            for( list = ARCHIVE_LIST; list; list = list -> next ) {
                archive = (ARCHIVE *)list -> node;

                if( archive -> volume == (char)GLOBAL_CD_DEVICE ) {
                    REQUEST_LOCK( archive -> lock );
                    dir = archive -> directory;
                    ResDetach( archive -> os_handle );
                    ResPurge( NULL, NULL, &dir, NULL );
                    hit = 1;
                    RELEASE_LOCK( archive -> lock );
                    break;
                }
            }

        } while( hit );
    }


    ResPurge( NULL, (char *)&GLOBAL_CD_DEVICE, NULL, NULL );

    return( TRUE );
}



/* =======================================================

   FUNCTION:   ResCheckMedia

   PURPOSE:    Determine if the end-user has swapped 
               the media for the specified device.

   PARAMETERS: 0=A, 1=B, 2=C (drive ordinal).

   RETURNS:    0  - yes they changed the media
               1  - no they didn't change media
               -1 - error reading device (probably in
                    process of changing media.

   ======================================================= */

RES_EXPORT int ResCheckMedia( int device )
{
    int  drive;
    int  retval = 1;
    char root[] = "C:\\";
    char name[26],
         dummy[6];          /* possible bug in GetVolumeInformation */

    unsigned long serial,
                  long1,    /* possible bug in GetVolumeInformation */
                  long2;    /* possible bug in GetVolumeInformation */

    DEVICE_ENTRY * dev;

#if( RES_DEBUG_PARAMS )
    if( device < 0 || device > MAX_DEVICES ) {
        SAY_ERROR( RES_ERR_INCORRECT_PARAMETER, "ResCheckMedia (use ordinals)" );
        return( -1 );
    }
#endif /* RES_DEBUG_PARAMS */

    drive = _getdrive();

    if( _chdrive( device + 1 ))
        return( -1 );

    _chdrive(drive);

    dev = &RES_DEVICES[ device ];
    root[0] = (char)(device + 'A');

    if( GetVolumeInformation( root, name, 22, &serial, &long1, &long2, dummy, 5 )) {
        if( strcmp( name, dev -> name ) || ( serial != dev -> serial )) {
            strcpy( dev -> name, name );
            dev -> serial = serial;
            IF_DEBUG( LOG( "Media has changed on volume %s\n", root ));

            SHOULD_I_CALL_WITH( CALLBACK_SWAP_CD, GLOBAL_CURRENT_CD, retval );

            return(0);
        }

        return(1);
    }

    IF_DEBUG( LOG( "Could not read media on volume %s\n", root ));
    return( -1 );
}



/* =======================================================

   FUNCTION:   ResAttach

   PURPOSE:    Open an archive file (zip).

   PARAMETERS: Directory to graft archive into, name of
               an archive file, replace flag.  If 
               attact_point is NULL, the archive is 
               grafted on to the current working 
               directory.  If replace_flag is TRUE, any
               files contained within the archive that
               collide with files on the attach_point
               are replaced (the matching files in the
               archive file replace those at the 
               destination attach point) otherwise
               the reverse is true (the files within 
               the archive take precedence).

   RETURNS:    Handle if sucessful, otherwise -1.

   ======================================================= */

RES_EXPORT int ResAttach( const char * attach_point_arg, const char * filename, int replace_flag )
{
    ARCHIVE    * archive;
    HASH_TABLE * table = NULL;
    char         path[_MAX_PATH];
    char         attach_point_backup[_MAX_PATH];
    char       * attach_point;
    int          len, i;
    struct _finddata_t  info;

  

#if( !RES_USE_FLAT_MODEL )
    HASH_ENTRY * entry;
#endif

//      _getcwd(old_cwd,MAX_PATH);

    if(attach_point_arg)
      {
        strcpy( attach_point_backup, attach_point_arg );
        attach_point = attach_point_backup;
      }
    else
      {
        attach_point = NULL;
      }


    IF_LOG( LOG( "attach: %s %s\n", attach_point, filename ));

#if( RES_DEBUG_PARAMS )
    if( !filename || (strlen(filename) > _MAX_FNAME)) {
        SAY_ERROR( RES_ERR_INCORRECT_PARAMETER, "ResAttach" );
        return( -1 );
    }
#endif

    if( !GLOBAL_HASH_TABLE ) {
        SAY_ERROR( RES_ERR_INCORRECT_PARAMETER, "ResAttach" );
        return( -1 );
    }

    if( !attach_point )
        attach_point = GLOBAL_CURRENT_PATH;

#if( RES_COERCE_FILENAMES )
    len = strlen( attach_point );

    if( attach_point[len-1] != ASCII_BACKSLASH ) {
        attach_point[len++] = ASCII_BACKSLASH;
        attach_point[len] = 0x00;
    }

    res_fullpath( path, attach_point, _MAX_PATH );

    attach_point = path;

#endif /* RES_COERCE_FILENAMES */

      info.size = 0;

#if( !RES_USE_FLAT_MODEL )
    entry = hash_find( attach_point, GLOBAL_HASH_TABLE );


    /* I used to force you to use a directory already in
       the resource manager for the attach point.  Roger
       Fujii asked for anything to be used (allowing you
       to create artificial directories).  If you want
       the original functionality, define RES_ALLOW_ALIAS
       to false. */


#if( !RES_ALLOW_ALIAS )
       if( !entry ) {
           SAY_ERROR( RES_ERR_PATH_NOT_FOUND, attach_point );
           return( -1 );
       }
#else

    /* The attach point does not have to be either a directory -or- 
       an 'added' directory (a directory that has been incorporated
       into the Resource Manager via ResAddPath or ResCreatePath */

    if( !entry ) {

#if( RES_DEBUG_VERSION )
        if( GLOBAL_SEARCH_INDEX >= (MAX_DIRECTORIES-1)) {
          assert(!"Exceeded MAX_DIRECTORIES as defined in omni.h");
//            SAY_ERROR( RES_ERR_TOO_MANY_DIRECTORIES, "ResAddPath" );
            return( FALSE );
        }
#endif
        table = hash_create( ARCHIVE_TABLE_SIZE, attach_point );

        strcpy( info.name, attach_point );                /* insert a dummy entry into the global hash table  */
        info.attrib = _A_SUBDIR | (unsigned int)FORCE_BIT;
        info.time_create = 0;
        info.time_access = 0;
        info.size = 0;

        entry = hash_add( &info, GLOBAL_HASH_TABLE );

        if( !entry ) {
            SAY_ERROR( RES_ERR_UNKNOWN, "ResAttach" );
            return( -1 );
        }

        entry -> archive       = -1; /* the actual directory existence should not be considered
                                        as part of the archive.  All of the contents found within
                                        the directory are.   This allows a hard disk based file to
                                        override a zip archive */

        entry -> volume = (char)(toupper(attach_point[0]) - 'A');
        entry -> directory = GLOBAL_SEARCH_INDEX;

        GLOBAL_SEARCH_PATH[ GLOBAL_SEARCH_INDEX++ ] = MemStrDup( attach_point );
        GLOBAL_PATH_LIST = LIST_APPEND( GLOBAL_PATH_LIST, table );
        strcpy( GLOBAL_CURRENT_PATH, attach_point );

        entry -> dir = table;
    }
#endif /* RES_ALLOW_ALIAS */
    archive = archive_create( attach_point, filename, (HASH_TABLE *)entry -> dir, replace_flag );
#else  /* RES_FLAT_MODEL  */
    archive = archive_create( attach_point, filename, GLOBAL_HASH_TABLE, replace_flag );
#endif /* RES_FLAT_MODEL  */

    if( !archive ) {
        SAY_ERROR( RES_ERR_CANT_OPEN_ARCHIVE, filename );
        return( -1 );
    }

    for( i=0; i<(GLOBAL_SEARCH_INDEX-1); i++ ) {
        if( !stricmp( GLOBAL_SEARCH_PATH[i], attach_point )) {
//            archive -> directory = (char)i;   /* GFG */
            archive -> directory = (char)(i);     /* GFG */
            break;
        }
    }

    if( i == GLOBAL_SEARCH_INDEX )
        DebugBreak();

    ARCHIVE_LIST = LIST_APPEND( ARCHIVE_LIST, archive );

    return( archive -> os_handle );
}



/* =======================================================

   FUNCTION:   ResDevice

   PURPOSE:    Returns information about a given drive.

   PARAMETERS: Id of device to query.

   RETURNS:    TRUE (pass) / FALSE (fail).

   ======================================================= */

RES_EXPORT int ResDevice( int device_id, DEVICE_ENTRY * dev )
{
#if( RES_DEBUG_PARAMS )
    if( device_id < 0 || device_id > MAX_DEVICES || !dev ) {
        SAY_ERROR( RES_ERR_INCORRECT_PARAMETER, "ResDevice" );
        return( FALSE );
    }
#endif /* RES_DEBUG_PARAMS */

    memcpy( dev, (void *)&RES_DEVICES[device_id], sizeof( DEVICE_ENTRY ));

    return( TRUE );
}



/* =======================================================

   FUNCTION:   ResDetach

   PURPOSE:    Closes an open archive file (zip).

   PARAMETERS: Handle of an opened archive file.

   RETURNS:    None.

   ======================================================= */

RES_EXPORT void ResDetach( int handle )
{
    ARCHIVE    * archive=NULL;
    LIST       * list=NULL;

#if( RES_DEBUG_PARAMS )
    if( !ARCHIVE_LIST ) {
        SAY_ERROR( RES_ERR_UNKNOWN_ARCHIVE, "ResDetach" );
        return;
    }
#endif /* RES_DEBUG_PARAMS */

    /* using the handle, search the list for the structure */

    for( list = ARCHIVE_LIST; list; list = list -> next ) {
        archive = (ARCHIVE *)list -> node;

        if( archive -> os_handle == handle )
            break;
    }

    if( !list ) { /* couldn't find it, may already have been closed - or handle is incorrect */
        SAY_ERROR( RES_ERR_UNKNOWN_ARCHIVE, "ResDetach" );
        return;
    }

    IF_LOG( LOG( "detach: %s\n", archive -> name ));
    
    REQUEST_LOCK( archive -> lock );

    ResPurge((char *)&archive -> os_handle, NULL, NULL, NULL );

    /* remove the archive from out list */
    ARCHIVE_LIST = LIST_REMOVE( ARCHIVE_LIST, archive );


    /* The inflation code builds a table of constant values for decompressing 
       files compressed with pkzip's FIXED compression mode.  The tables are
       dynamically created (if they don't already exist) when you decompress
       data via that method.  Therefore, we don't want to free it up until
       all the zips are detached - then we might as well to reclaim memory */

    if( !ARCHIVE_LIST ) 
        inflate_free(); 

    /* close the actual archive file */
    _close( archive -> os_handle );

    RELEASE_LOCK( archive -> lock );
    DESTROY_LOCK( archive -> lock );

	#ifdef USE_SH_POOLS
    MemFreePtr( archive );
	#else
    MemFree( archive );
	#endif
}



/* =======================================================

   FUNCTION:   ResOpenFile

   PURPOSE:    Open a file via the Resource Manager.

   PARAMETERS: Filename, mode to open with.
               Wildcards are not supported.

   RETURNS:    File int if sucessful, otherwise -1.

   ======================================================= */

RES_EXPORT int ResOpenFile( const char * name, int mode )
{
    HASH_TABLE * table=NULL;
    HASH_ENTRY * entry=NULL;
    FILE_ENTRY * file=NULL;

    LIST * list=NULL;

    ARCHIVE * archive=NULL;

    char dirpath[_MAX_PATH];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -