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

📄 fs.java

📁 Jake2是一个Java 3D游戏引擎.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * FS.java * Copyright (C) 2003 *  * $Id: FS.java,v 1.15 2005/11/13 13:36:00 cawe Exp $ *//* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */package jake2.qcommon;import jake2.Defines;import jake2.Globals;import jake2.game.Cmd;import jake2.game.cvar_t;import jake2.sys.Sys;import java.io.*;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.channels.FileChannel;import java.util.*;/** * FS *  * @author cwei */public final class FS extends Globals {    /*     * ==================================================     *      * QUAKE FILESYSTEM     *      * ==================================================     */    public static class packfile_t {        static final int SIZE = 64;        static final int NAME_SIZE = 56;        String name; // char name[56]        int filepos, filelen;        public String toString() {            return name + " [ length: " + filelen + " pos: " + filepos + " ]";        }    }    public static class pack_t {        String filename;        RandomAccessFile handle;                ByteBuffer backbuffer;        int numfiles;        Hashtable files; // with packfile_t entries    }    public static String fs_gamedir;    private static String fs_userdir;    public static cvar_t fs_basedir;    public static cvar_t fs_cddir;    public static cvar_t fs_gamedirvar;    public static class filelink_t {        String from;        int fromlength;        String to;    }    // with filelink_t entries    public static List fs_links = new LinkedList();    public static class searchpath_t {        String filename;        pack_t pack; // only one of filename or pack will be used        searchpath_t next;    }    public static searchpath_t fs_searchpaths;    // without gamedirs    public static searchpath_t fs_base_searchpaths;    /*     * All of Quake's data access is through a hierchal file system, but the     * contents of the file system can be transparently merged from several     * sources.     *      * The "base directory" is the path to the directory holding the quake.exe     * and all game directories. The sys_* files pass this to host_init in     * quakeparms_t->basedir. This can be overridden with the "-basedir" command     * line parm to allow code debugging in a different directory. The base     * directory is only used during filesystem initialization.     *      * The "game directory" is the first tree on the search path and directory     * that all generated files (savegames, screenshots, demos, config files)     * will be saved to. This can be overridden with the "-game" command line     * parameter. The game directory can never be changed while quake is     * executing. This is a precacution against having a malicious server     * instruct clients to write files over areas they shouldn't.     *       */    /*     * CreatePath     *      * Creates any directories needed to store the given filename.     */    public static void CreatePath(String path) {        int index = path.lastIndexOf('/');        // -1 if not found and 0 means write to root        if (index > 0) {            File f = new File(path.substring(0, index));            if (!f.mkdirs() && !f.isDirectory()) {                Com.Printf("can't create path \"" + path + '"' + "\n");            }        }    }    /*     * FCloseFile     *      * For some reason, other dll's can't just call fclose() on files returned     * by FS_FOpenFile...     */    public static void FCloseFile(RandomAccessFile file) throws IOException {        file.close();    }    public static void FCloseFile(InputStream stream) throws IOException {        stream.close();    }    public static int FileLength(String filename) {        searchpath_t search;        String netpath;        pack_t pak;        int i;        filelink_t link;        file_from_pak = 0;        // check for links first        for (Iterator it = fs_links.iterator(); it.hasNext();) {            link = (filelink_t) it.next();            if (filename.regionMatches(0, link.from, 0, link.fromlength)) {                netpath = link.to + filename.substring(link.fromlength);                File file = new File(netpath);                if (file.canRead()) {                    Com.DPrintf("link file: " + netpath + '\n');                    return (int) file.length();                }                return -1;            }        }        // search through the path, one element at a time        for (search = fs_searchpaths; search != null; search = search.next) {            // is the element a pak file?            if (search.pack != null) {                // look through all the pak file elements                pak = search.pack;                filename = filename.toLowerCase();                packfile_t entry = (packfile_t) pak.files.get(filename);                if (entry != null) {                    // found it!                    file_from_pak = 1;                    Com.DPrintf("PackFile: " + pak.filename + " : " + filename                            + '\n');                    // open a new file on the pakfile                    File file = new File(pak.filename);                    if (!file.canRead()) {                        Com.Error(Defines.ERR_FATAL, "Couldn't reopen "                                + pak.filename);                    }                    return entry.filelen;                }            } else {                // check a file in the directory tree                netpath = search.filename + '/' + filename;                File file = new File(netpath);                if (!file.canRead())                    continue;                Com.DPrintf("FindFile: " + netpath + '\n');                return (int) file.length();            }        }        Com.DPrintf("FindFile: can't find " + filename + '\n');        return -1;    }    public static int file_from_pak = 0;    /*     * FOpenFile     *      * Finds the file in the search path. returns a RadomAccesFile. Used for     * streaming data out of either a pak file or a seperate file.     */    public static RandomAccessFile FOpenFile(String filename)            throws IOException {        searchpath_t search;        String netpath;        pack_t pak;        int i;        filelink_t link;        File file = null;        file_from_pak = 0;        // check for links first        for (Iterator it = fs_links.iterator(); it.hasNext();) {            link = (filelink_t) it.next();            //			if (!strncmp (filename, link->from, link->fromlength))            if (filename.regionMatches(0, link.from, 0, link.fromlength)) {                netpath = link.to + filename.substring(link.fromlength);                file = new File(netpath);                if (file.canRead()) {                    //Com.DPrintf ("link file: " + netpath +'\n');                    return new RandomAccessFile(file, "r");                }                return null;            }        }        //        // search through the path, one element at a time        //        for (search = fs_searchpaths; search != null; search = search.next) {            // is the element a pak file?            if (search.pack != null) {                // look through all the pak file elements                pak = search.pack;                filename = filename.toLowerCase();                packfile_t entry = (packfile_t) pak.files.get(filename);                if (entry != null) {                    // found it!                    file_from_pak = 1;                    //Com.DPrintf ("PackFile: " + pak.filename + " : " +                    // filename + '\n');                    file = new File(pak.filename);                    if (!file.canRead())                        Com.Error(Defines.ERR_FATAL, "Couldn't reopen "                                + pak.filename);                    if (pak.handle == null || !pak.handle.getFD().valid()) {                        // hold the pakfile handle open                        pak.handle = new RandomAccessFile(pak.filename, "r");                    }                    // open a new file on the pakfile                    RandomAccessFile raf = new RandomAccessFile(file, "r");                    raf.seek(entry.filepos);                    return raf;                }            } else {                // check a file in the directory tree                netpath = search.filename + '/' + filename;                file = new File(netpath);                if (!file.canRead())                    continue;                //Com.DPrintf("FindFile: " + netpath +'\n');                return new RandomAccessFile(file, "r");            }        }        //Com.DPrintf ("FindFile: can't find " + filename + '\n');        return null;    }    // read in blocks of 64k    public static final int MAX_READ = 0x10000;    /**     * Read     *      * Properly handles partial reads     */    public static void Read(byte[] buffer, int len, RandomAccessFile f) {        int block, remaining;        int offset = 0;        int read = 0;        boolean tries = true;        // read in chunks for progress bar        remaining = len;        while (remaining != 0) {            block = Math.min(remaining, MAX_READ);            try {                read = f.read(buffer, offset, block);            } catch (IOException e) {                Com.Error(Defines.ERR_FATAL, e.toString());            }            if (read == 0) {                Com.Error(Defines.ERR_FATAL, "FS_Read: 0 bytes read");            } else if (read == -1) {                Com.Error(Defines.ERR_FATAL, "FS_Read: -1 bytes read");            }            //            // do some progress bar thing here...            //            remaining -= read;            offset += read;        }    }    /*     * LoadFile     *      * Filename are reletive to the quake search path a null buffer will just     * return the file content as byte[]     */    public static byte[] LoadFile(String path) {        RandomAccessFile file;        byte[] buf = null;        int len = 0;        // TODO hack for bad strings (fuck \0)        int index = path.indexOf('\0');        if (index != -1)            path = path.substring(0, index);        // look for it in the filesystem or pack files        len = FileLength(path);        if (len < 1)            return null;        try {            file = FOpenFile(path);            //Read(buf = new byte[len], len, h);            buf = new byte[len];            file.readFully(buf);            file.close();        } catch (IOException e) {            Com.Error(Defines.ERR_FATAL, e.toString());        }        return buf;    }    /*     * LoadMappedFile     *      * Filename are reletive to the quake search path a null buffer will just     * return the file content as ByteBuffer (memory mapped)     */    public static ByteBuffer LoadMappedFile(String filename) {        searchpath_t search;        String netpath;        pack_t pak;        int i;        filelink_t link;        File file = null;        int fileLength = 0;        FileChannel channel = null;        FileInputStream input = null;        ByteBuffer buffer = null;        file_from_pak = 0;        try {            // check for links first            for (Iterator it = fs_links.iterator(); it.hasNext();) {                link = (filelink_t) it.next();                if (filename.regionMatches(0, link.from, 0, link.fromlength)) {                    netpath = link.to + filename.substring(link.fromlength);                    file = new File(netpath);                    if (file.canRead()) {                        input = new FileInputStream(file);                        channel = input.getChannel();                        fileLength = (int) channel.size();                        buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0,                                fileLength);                        input.close();                        return buffer;                    }                    return null;                }            }            //            // search through the path, one element at a time            //            for (search = fs_searchpaths; search != null; search = search.next) {                // is the element a pak file?                if (search.pack != null) {                    // look through all the pak file elements                    pak = search.pack;                    filename = filename.toLowerCase();                    packfile_t entry = (packfile_t) pak.files.get(filename);                    if (entry != null) {                        // found it!                        file_from_pak = 1;                        //Com.DPrintf ("PackFile: " + pak.filename + " : " +                        // filename + '\n');                        file = new File(pak.filename);                        if (!file.canRead())                            Com.Error(Defines.ERR_FATAL, "Couldn't reopen "                                    + pak.filename);                        if (pak.handle == null || !pak.handle.getFD().valid()) {                            // hold the pakfile handle open                            pak.handle = new RandomAccessFile(pak.filename, "r");                        }                        // open a new file on the pakfile                        if (pak.backbuffer == null) {                            channel = pak.handle.getChannel();                            pak.backbuffer = channel.map(                                    FileChannel.MapMode.READ_ONLY, 0,                                    pak.handle.length());                            channel.close();                        }                        pak.backbuffer.position(entry.filepos);                        buffer = pak.backbuffer.slice();                        buffer.limit(entry.filelen);                        return buffer;                    }                } else {                    // check a file in the directory tree                    netpath = search.filename + '/' + filename;                    file = new File(netpath);                    if (!file.canRead())                        continue;                    //Com.DPrintf("FindFile: " + netpath +'\n');                    input = new FileInputStream(file);                    channel = input.getChannel();                    fileLength = (int) channel.size();                    buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0,                            fileLength);                    input.close();                    return buffer;                }            }        } catch (Exception e) {        }        try {            if (input != null)                input.close();            else if (channel != null && channel.isOpen())                channel.close();

⌨️ 快捷键说明

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