From fc86ff0c577a972deb47b8d563823151cd6d5815 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Wed, 7 Mar 2018 01:03:54 +0300 Subject: [PATCH] FS -> FileSystem interface --- src/lwjake2/client/Menu.java | 3 - src/lwjake2/client/SCR.java | 12 +- src/lwjake2/game/Cmd.java | 13 +- src/lwjake2/qcommon/BaseQ2FileSystem.java | 204 +++- src/lwjake2/qcommon/Cvar.java | 4 +- src/lwjake2/qcommon/FS.java | 971 -------------------- src/lwjake2/qcommon/FileSystem.java | 11 +- src/lwjake2/qcommon/Qcommon.java | 6 +- src/lwjake2/render/lwjgl/Image.java | 14 +- src/lwjake2/render/lwjgl/Misc.java | 8 +- src/lwjake2/render/lwjgl/Model.java | 6 +- src/lwjake2/server/SV_CCMDS.java | 54 +- src/lwjake2/server/SV_INIT.java | 6 +- src/lwjake2/server/SV_MAIN.java | 2 - src/lwjake2/server/SV_USER.java | 18 +- src/lwjake2/sound/WaveLoader.java | 6 +- src/lwjake2/sound/lwjgl/LWJGLSoundImpl.java | 9 +- src/lwjake2/util/Lib.java | 6 +- 18 files changed, 287 insertions(+), 1066 deletions(-) delete mode 100644 src/lwjake2/qcommon/FS.java diff --git a/src/lwjake2/client/Menu.java b/src/lwjake2/client/Menu.java index ab3e90a..42210cb 100644 --- a/src/lwjake2/client/Menu.java +++ b/src/lwjake2/client/Menu.java @@ -1890,9 +1890,6 @@ public final class Menu extends Key { public static String Credits_Key(int key) { switch (key) { case K_ESCAPE: - if (creditsBuffer != null) - //FS.FreeFile(creditsBuffer); - ; PopMenu(); break; } diff --git a/src/lwjake2/client/SCR.java b/src/lwjake2/client/SCR.java index 74796e7..0f9d1c1 100644 --- a/src/lwjake2/client/SCR.java +++ b/src/lwjake2/client/SCR.java @@ -23,12 +23,7 @@ import lwjake2.Defines; import lwjake2.Globals; import lwjake2.game.Cmd; import lwjake2.game.cvar_t; -import lwjake2.qcommon.Com; -import lwjake2.qcommon.Cvar; -import lwjake2.qcommon.FS; -import lwjake2.qcommon.MSG; -import lwjake2.qcommon.SZ; -import lwjake2.qcommon.qfiles; +import lwjake2.qcommon.*; import lwjake2.sound.S; import lwjake2.sys.Timer; import lwjake2.util.Lib; @@ -44,6 +39,7 @@ import java.util.Arrays; */ @Slf4j public final class SCR extends Globals { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); // cl_scrn.c -- master for refresh, status bar, console, chat, notify, etc static String[][] sb_nums = { @@ -1392,7 +1388,7 @@ public final class SCR extends Globals { qfiles.pcx_t pcx; // load the file - ByteBuffer raw = FS.LoadMappedFile(filename); + ByteBuffer raw = fileSystem.loadMappedFile(filename); if (raw == null) { VID.Printf(Defines.PRINT_DEVELOPER, "Bad pcx file " + filename @@ -1831,7 +1827,7 @@ public final class SCR extends Globals { } String name = "video/" + arg; - cl.cinematic_file = FS.LoadMappedFile(name); + cl.cinematic_file = fileSystem.loadMappedFile(name); if (cl.cinematic_file == null) { //Com.Error(ERR_DROP, "Cinematic " + name + " not found.\n"); FinishCinematic(); diff --git a/src/lwjake2/game/Cmd.java b/src/lwjake2/game/Cmd.java index d960fac..cac93d8 100644 --- a/src/lwjake2/game/Cmd.java +++ b/src/lwjake2/game/Cmd.java @@ -22,13 +22,7 @@ import lombok.extern.slf4j.Slf4j; import lwjake2.Defines; import lwjake2.Globals; import lwjake2.game.monsters.M_Player; -import lwjake2.qcommon.Cbuf; -import lwjake2.qcommon.Com; -import lwjake2.qcommon.Cvar; -import lwjake2.qcommon.FS; -import lwjake2.qcommon.MSG; -import lwjake2.qcommon.SZ; -import lwjake2.qcommon.cmd_function_t; +import lwjake2.qcommon.*; import lwjake2.server.SV_GAME; import lwjake2.util.Lib; @@ -41,6 +35,7 @@ import java.util.Vector; */ @Slf4j public final class Cmd { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); static Runnable List_f = new Runnable() { public void run() { cmd_function_t cmd = Cmd.cmd_functions; @@ -63,7 +58,7 @@ public final class Cmd { } byte[] f = null; - f = FS.LoadFile(Cmd.Argv(1)); + f = fileSystem.loadFile(Cmd.Argv(1)); if (f == null) { log.info("couldn't exec {}", Cmd.Argv(1)); return; @@ -71,8 +66,6 @@ public final class Cmd { log.info("execing {}", Cmd.Argv(1)); Cbuf.InsertText(new String(f)); - - FS.FreeFile(f); } }; diff --git a/src/lwjake2/qcommon/BaseQ2FileSystem.java b/src/lwjake2/qcommon/BaseQ2FileSystem.java index 9ce4ba8..eb0e784 100644 --- a/src/lwjake2/qcommon/BaseQ2FileSystem.java +++ b/src/lwjake2/qcommon/BaseQ2FileSystem.java @@ -13,6 +13,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; @@ -24,7 +25,6 @@ import java.util.LinkedList; import java.util.List; import static lwjake2.Defines.*; -import static lwjake2.qcommon.FS.MAX_READ; /* * ================================================== @@ -38,6 +38,8 @@ public class BaseQ2FileSystem implements FileSystem { private static final BaseQ2FileSystem instance = new BaseQ2FileSystem(); private static final int IDPAKHEADER = (('K' << 24) + ('C' << 16) + ('A' << 8) + 'P'); private static final int MAX_FILES_IN_PACK = 4096; + // read in blocks of 64k + private static final int MAX_READ = 0x10000; public static BaseQ2FileSystem getInstance() { return instance; @@ -401,13 +403,15 @@ public class BaseQ2FileSystem implements FileSystem { /** * set baseq2 directory */ - private void setCDDir() { + @Override + public void setCDDir() { fs_cddir = Cvar.Get("cddir", "", CVAR_ARCHIVE); if (fs_cddir.string.length() > 0) addGameDirectory(fs_cddir.string + '/' + Globals.BASEDIRNAME); } - private void markBaseSearchPaths() { + @Override + public void markBaseSearchPaths() { // any set gamedirs will be freed up to here fs_base_searchpaths = fs_searchpaths; } @@ -477,6 +481,112 @@ public class BaseQ2FileSystem implements FileSystem { return (fs_gamedir != null) ? fs_gamedir : Globals.BASEDIRNAME; } + /* + * LoadMappedFile + * + * Filename are reletive to the quake search path a null buffer will just + * return the file content as ByteBuffer (memory mapped) + */ + @Override + public ByteBuffer loadMappedFile(String filename) { + searchpath_t search; + String netpath; + pack_t pak; + File file; + + int fileLength; + FileChannel channel = null; + FileInputStream input = null; + ByteBuffer buffer; + + file_from_pak = 0; + + try { + // check for links first + for (filelink_t link : fs_links) { + 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 = 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 ignored) { + } + try { + if (input != null) + input.close(); + else if (channel != null && channel.isOpen()) + channel.close(); + } catch (IOException ignored) { + } + return null; + } + @Override public void execAutoexec() { String dir = fs_userdir; @@ -500,13 +610,99 @@ public class BaseQ2FileSystem implements FileSystem { /** * Check for "+set game" override - Used to properly set gamedir */ - private void checkOverride() { + @Override + public void checkOverride() { fs_gamedirvar = Cvar.Get("game", "", CVAR_LATCH | CVAR_SERVERINFO); if (fs_gamedirvar.string.length() > 0) setGamedir(fs_gamedirvar.string); } + /* + * 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. + */ + @Override + public RandomAccessFile FOpenFile(String filename) throws IOException { + searchpath_t search; + String netpath; + pack_t pak; + filelink_t link; + File file = null; + + file_from_pak = 0; + + // check for links first + for (Iterator it = fs_links.iterator(); it.hasNext();) { + link = 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 = 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; + } + + @Override + public int getFileFromPak() { + return file_from_pak; + } + @Override public void init() { Cmd.AddCommand("path", new Runnable() { diff --git a/src/lwjake2/qcommon/Cvar.java b/src/lwjake2/qcommon/Cvar.java index cf14892..3f13727 100644 --- a/src/lwjake2/qcommon/Cvar.java +++ b/src/lwjake2/qcommon/Cvar.java @@ -195,8 +195,8 @@ public class Cvar extends Globals { var.value = 0.0f; } if (var.name.equals("game")) { - FS.SetGamedir(var.string); - FS.ExecAutoexec(); + fileSystem.setGamedir(var.string); + fileSystem.execAutoexec(); } } return var; diff --git a/src/lwjake2/qcommon/FS.java b/src/lwjake2/qcommon/FS.java deleted file mode 100644 index 5d1f15f..0000000 --- a/src/lwjake2/qcommon/FS.java +++ /dev/null @@ -1,971 +0,0 @@ -/* - * 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 lwjake2.qcommon; - -import lombok.extern.slf4j.Slf4j; -import lwjake2.Defines; -import lwjake2.Globals; -import lwjake2.game.Cmd; -import lwjake2.game.cvar_t; -import lwjake2.sys.Sys; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -/** - * FS - * - * @author cwei - */ -@Slf4j -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()) { - log.warn("can't create path \"{}\"", path); - } - } - } - - /* - * 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; - filelink_t link; - - file_from_pak = 0; - - // check for links first - for (Iterator it = fs_links.iterator(); it.hasNext();) { - link = 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 = 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; - filelink_t link; - File file = null; - - file_from_pak = 0; - - // check for links first - for (Iterator it = fs_links.iterator(); it.hasNext();) { - link = 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 = 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; - - // 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; - 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 = 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 = 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(); - } catch (IOException ioe) { - } - return null; - } - - /* - * FreeFile - */ - public static void FreeFile(byte[] buffer) { - buffer = null; - } - - static final int IDPAKHEADER = (('K' << 24) + ('C' << 16) + ('A' << 8) + 'P'); - - static class dpackheader_t { - int ident; // IDPAKHEADER - - int dirofs; - - int dirlen; - } - - static final int MAX_FILES_IN_PACK = 4096; - - // buffer for C-Strings char[56] - static byte[] tmpText = new byte[packfile_t.NAME_SIZE]; - - /* - * LoadPackFile - * - * Takes an explicit (not game tree related) path to a pak file. - * - * Loads the header and directory, adding the files at the beginning of the - * list so they override previous pack files. - */ - static pack_t LoadPackFile(String packfile) { - - dpackheader_t header; - Hashtable newfiles; - RandomAccessFile file; - int numpackfiles = 0; - pack_t pack = null; - // unsigned checksum; - // - try { - file = new RandomAccessFile(packfile, "r"); - FileChannel fc = file.getChannel(); - ByteBuffer packhandle = fc.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); - packhandle.order(ByteOrder.LITTLE_ENDIAN); - - fc.close(); - - if (packhandle == null || packhandle.limit() < 1) - return null; - // - header = new dpackheader_t(); - header.ident = packhandle.getInt(); - header.dirofs = packhandle.getInt(); - header.dirlen = packhandle.getInt(); - - if (header.ident != IDPAKHEADER) - Com.Error(Defines.ERR_FATAL, packfile + " is not a packfile"); - - numpackfiles = header.dirlen / packfile_t.SIZE; - - if (numpackfiles > MAX_FILES_IN_PACK) - Com.Error(Defines.ERR_FATAL, packfile + " has " + numpackfiles - + " files"); - - newfiles = new Hashtable(numpackfiles); - - packhandle.position(header.dirofs); - - // parse the directory - packfile_t entry = null; - - for (int i = 0; i < numpackfiles; i++) { - packhandle.get(tmpText); - - entry = new packfile_t(); - entry.name = new String(tmpText).trim(); - entry.filepos = packhandle.getInt(); - entry.filelen = packhandle.getInt(); - - newfiles.put(entry.name.toLowerCase(), entry); - } - - } catch (IOException e) { - Com.DPrintf(e.getMessage() + '\n'); - return null; - } - - pack = new pack_t(); - pack.filename = new String(packfile); - pack.handle = file; - pack.numfiles = numpackfiles; - pack.files = newfiles; - - log.info("Added packfile {} ({} files)", packfile, numpackfiles); - - return pack; - } - - /* - * AddGameDirectory - * - * Sets fs_gamedir, adds the directory to the head of the path, then loads - * and adds pak1.pak pak2.pak ... - */ - static void AddGameDirectory(String dir) { - int i; - searchpath_t search; - pack_t pak; - String pakfile; - - fs_gamedir = new String(dir); - - // - // add the directory to the search path - // ensure fs_userdir is first in searchpath - search = new searchpath_t(); - search.filename = new String(dir); - if (fs_searchpaths != null) { - search.next = fs_searchpaths.next; - fs_searchpaths.next = search; - } else { - fs_searchpaths = search; - } - - // - // add any pak files in the format pak0.pak pak1.pak, ... - // - for (i = 0; i < 10; i++) { - pakfile = dir + "/pak" + i + ".pak"; - if (!(new File(pakfile).canRead())) - continue; - - pak = LoadPackFile(pakfile); - if (pak == null) - continue; - - search = new searchpath_t(); - search.pack = pak; - search.filename = ""; - search.next = fs_searchpaths; - fs_searchpaths = search; - } - } - - /* - * Gamedir - * - * Called to find where to write a file (demos, savegames, etc) - * this is modified to /.lwjake2 - */ - public static String Gamedir() { - return (fs_userdir != null) ? fs_userdir : Globals.BASEDIRNAME; - } - - /* - * BaseGamedir - * - * Called to find where to write a downloaded file - */ - public static String BaseGamedir() { - return (fs_gamedir != null) ? fs_gamedir : Globals.BASEDIRNAME; - } - - /* - * ExecAutoexec - */ - public static void ExecAutoexec() { - String dir = fs_userdir; - - String name; - if (dir != null && dir.length() > 0) { - name = dir + "/autoexec.cfg"; - } else { - name = fs_basedir.string + '/' + Globals.BASEDIRNAME - + "/autoexec.cfg"; - } - - int canthave = Defines.SFF_SUBDIR | Defines.SFF_HIDDEN - | Defines.SFF_SYSTEM; - - if (Sys.FindAll(name, 0, canthave) != null) { - Cbuf.AddText("exec autoexec.cfg\n"); - } - } - - /* - * SetGamedir - * - * Sets the gamedir and path to a different directory. - */ - public static void SetGamedir(String dir) { - searchpath_t next; - - if (dir.indexOf("..") != -1 || dir.indexOf("/") != -1 - || dir.indexOf("\\") != -1 || dir.indexOf(":") != -1) { - log.warn("Gamedir should be a single filename, not a path"); - return; - } - - // - // free up any current game dir info - // - while (fs_searchpaths != fs_base_searchpaths) { - if (fs_searchpaths.pack != null) { - try { - fs_searchpaths.pack.handle.close(); - } catch (IOException e) { - Com.DPrintf(e.getMessage() + '\n'); - } - // clear the hashtable - fs_searchpaths.pack.files.clear(); - fs_searchpaths.pack.files = null; - fs_searchpaths.pack = null; - } - next = fs_searchpaths.next; - fs_searchpaths = null; - fs_searchpaths = next; - } - - // - // flush all data, so it will be forced to reload - // - if ((Globals.dedicated != null) && (Globals.dedicated.value == 0.0f)) - Cbuf.AddText("vid_restart\nsnd_restart\n"); - - fs_gamedir = fs_basedir.string + '/' + dir; - - if (dir.equals(Globals.BASEDIRNAME) || (dir.length() == 0)) { - Cvar.FullSet("gamedir", "", CVAR_SERVERINFO | CVAR_NOSET); - Cvar.FullSet("game", "", CVAR_LATCH | CVAR_SERVERINFO); - } else { - Cvar.FullSet("gamedir", dir, CVAR_SERVERINFO | CVAR_NOSET); - if (fs_cddir.string != null && fs_cddir.string.length() > 0) - AddGameDirectory(fs_cddir.string + '/' + dir); - - AddGameDirectory(fs_basedir.string + '/' + dir); - } - } - - /* - * Link_f - * - * Creates a filelink_t - */ - public static void Link_f() { - filelink_t entry = null; - - if (Cmd.Argc() != 3) { - log.info("USAGE: link "); - return; - } - - // see if the link already exists - for (Iterator it = fs_links.iterator(); it.hasNext();) { - entry = it.next(); - - if (entry.from.equals(Cmd.Argv(1))) { - if (Cmd.Argv(2).length() < 1) { - // delete it - it.remove(); - return; - } - entry.to = new String(Cmd.Argv(2)); - return; - } - } - - // create a new link if the is not empty - if (Cmd.Argv(2).length() > 0) { - entry = new filelink_t(); - entry.from = new String(Cmd.Argv(1)); - entry.fromlength = entry.from.length(); - entry.to = new String(Cmd.Argv(2)); - fs_links.add(entry); - } - } - - /* - * ListFiles - */ - public static String[] ListFiles(String findname, int musthave, int canthave) { - String[] list = new String[0]; - - File[] files = Sys.FindAll(findname, musthave, canthave); - - if (files != null) { - list = new String[files.length]; - for (int i = 0; i < files.length; i++) { - list[i] = files[i].getPath(); - } - } - - return list; - } - - /* - * Dir_f - */ - public static void Dir_f() { - String path = null; - String findname = null; - String wildcard = "*.*"; - String[] dirnames; - - if (Cmd.Argc() != 1) { - wildcard = Cmd.Argv(1); - } - - while ((path = NextPath(path)) != null) { - String tmp = findname; - - findname = path + '/' + wildcard; - - if (tmp != null) - tmp.replaceAll("\\\\", "/"); - - log.info("Directory of {}", findname); - log.info("----"); - - dirnames = ListFiles(findname, 0, 0); - - if (dirnames.length != 0) { - int index = 0; - for (int i = 0; i < dirnames.length; i++) { - if ((index = dirnames[i].lastIndexOf('/')) > 0) { - log.info(dirnames[i].substring(index + 1, dirnames[i].length())); - } else { - log.info(dirnames[i]); - } - } - } - - } - } - - /* - * Path_f - */ - public static void Path_f() { - - searchpath_t s; - filelink_t link; - - log.info("Current search path:"); - for (s = fs_searchpaths; s != null; s = s.next) { - if (s == fs_base_searchpaths) - log.info("----------"); - if (s.pack != null) - log.info("{} ({} files)", s.pack.filename, s.pack.numfiles); - else - log.info(s.filename); - } - - log.info("Links:"); - for (Iterator it = fs_links.iterator(); it.hasNext();) { - link = it.next(); - log.info("{} : {}", link.from, link.to); - } - } - - /* - * NextPath - * - * Allows enumerating all of the directories in the search path - */ - public static String NextPath(String prevpath) { - searchpath_t s; - String prev; - - if (prevpath == null || prevpath.length() == 0) - return fs_gamedir; - - prev = fs_gamedir; - for (s = fs_searchpaths; s != null; s = s.next) { - if (s.pack != null) - continue; - - if (prevpath == prev) - return s.filename; - - prev = s.filename; - } - - return null; - } - - /* - * InitFilesystem - */ - public static void InitFilesystem() { - Cmd.AddCommand("path", new Runnable() { - public void run() { - Path_f(); - } - }); - Cmd.AddCommand("link", new Runnable() { - public void run() { - Link_f(); - } - }); - Cmd.AddCommand("dir", new Runnable() { - public void run() { - Dir_f(); - } - }); - - fs_userdir = System.getProperty("user.home") + "/.lwjake2"; - FS.CreatePath(fs_userdir + "/"); - FS.AddGameDirectory(fs_userdir); - - // - // basedir - // allows the game to run from outside the data tree - // - fs_basedir = Cvar.Get("basedir", ".", CVAR_NOSET); - - // - // cddir - // Logically concatenates the cddir after the basedir for - // allows the game to run from outside the data tree - // - - setCDDir(); - - // - // start up with baseq2 by default - // - AddGameDirectory(fs_basedir.string + '/' + Globals.BASEDIRNAME); - - // any set gamedirs will be freed up to here - markBaseSearchPaths(); - - // check for game override - checkOverride(); - } - - /** - * set baseq2 directory - */ - static void setCDDir() { - fs_cddir = Cvar.Get("cddir", "", CVAR_ARCHIVE); - if (fs_cddir.string.length() > 0) - AddGameDirectory(fs_cddir.string + '/' + Globals.BASEDIRNAME); - } - - /** Check for "+set game" override - Used to properly set gamedir */ - static void checkOverride() { - fs_gamedirvar = Cvar.Get("game", "", CVAR_LATCH | CVAR_SERVERINFO); - - if (fs_gamedirvar.string.length() > 0) - SetGamedir(fs_gamedirvar.string); - } - - static void markBaseSearchPaths() { - // any set gamedirs will be freed up to here - fs_base_searchpaths = fs_searchpaths; - } - - // RAFAEL - /* - * Developer_searchpath - */ - public static int Developer_searchpath(int who) { - - // PMM - warning removal - // char *start; - searchpath_t s; - - - for (s = fs_searchpaths; s != null; s = s.next) { - if (s.filename.indexOf("xatrix") != -1) - return 1; - - if (s.filename.indexOf("rogue") != -1) - return 2; - } - - return 0; - } -} \ No newline at end of file diff --git a/src/lwjake2/qcommon/FileSystem.java b/src/lwjake2/qcommon/FileSystem.java index 77b0904..e46f8de 100644 --- a/src/lwjake2/qcommon/FileSystem.java +++ b/src/lwjake2/qcommon/FileSystem.java @@ -6,10 +6,12 @@ package lwjake2.qcommon; import lwjake2.game.cvar_t; +import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.ByteBuffer; public interface FileSystem { - void init(); // FS.InitFilesystem(); + void init(); byte[] loadFile(String path); void read(byte[] buffer, int len, RandomAccessFile file); void execAutoexec(); @@ -25,4 +27,11 @@ public interface FileSystem { String getGamedir(); String getBaseGamedir(); + + ByteBuffer loadMappedFile(String filename); + void setCDDir(); + void markBaseSearchPaths(); + void checkOverride(); + RandomAccessFile FOpenFile(String filename) throws IOException; + int getFileFromPak(); } diff --git a/src/lwjake2/qcommon/Qcommon.java b/src/lwjake2/qcommon/Qcommon.java index 68af0e0..299d59d 100644 --- a/src/lwjake2/qcommon/Qcommon.java +++ b/src/lwjake2/qcommon/Qcommon.java @@ -74,9 +74,9 @@ public final class Qcommon extends Globals { reconfigure(false); - FS.setCDDir(); // use cddir from config.cfg - FS.markBaseSearchPaths(); // mark the default search paths - FS.checkOverride(); + fileSystem.setCDDir(); // use cddir from config.cfg + fileSystem.markBaseSearchPaths(); // mark the default search paths + fileSystem.checkOverride(); reconfigure(true); // reload default.cfg and config.cfg diff --git a/src/lwjake2/render/lwjgl/Image.java b/src/lwjake2/render/lwjgl/Image.java index 0374fd7..ef4c20e 100644 --- a/src/lwjake2/render/lwjgl/Image.java +++ b/src/lwjake2/render/lwjgl/Image.java @@ -22,10 +22,7 @@ import lwjake2.Defines; import lwjake2.client.VID; import lwjake2.client.particle_t; import lwjake2.game.cvar_t; -import lwjake2.qcommon.Com; -import lwjake2.qcommon.Cvar; -import lwjake2.qcommon.FS; -import lwjake2.qcommon.qfiles; +import lwjake2.qcommon.*; import lwjake2.render.image_t; import lwjake2.util.Lib; import lwjake2.util.Vargs; @@ -51,6 +48,7 @@ import org.lwjgl.opengl.GL11; * @author cwei */ public abstract class Image extends Main { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); image_t draw_chars; @@ -450,7 +448,7 @@ public abstract class Image extends Main { // // load the file // - byte[] raw = FS.LoadFile(filename); + byte[] raw = fileSystem.loadFile(filename); if (raw == null) { VID.Printf(Defines.PRINT_DEVELOPER, "Bad pcx file " + filename + '\n'); @@ -547,7 +545,7 @@ public abstract class Image extends Main { // // load the file // - raw = FS.LoadFile(name); + raw = fileSystem.loadFile(name); if (raw == null) { @@ -1446,7 +1444,7 @@ public abstract class Image extends Main { image_t image = null; - byte[] raw = FS.LoadFile(name); + byte[] raw = fileSystem.loadFile(name); if (raw == null) { VID.Printf(Defines.PRINT_ALL, "GL_FindImage: can't load " + name + '\n'); return r_notexture; @@ -1630,7 +1628,7 @@ public abstract class Image extends Main { Draw_GetPalette(); if (qglColorTableEXT) { - gl_state.d_16to8table = FS.LoadFile("pics/16to8.dat"); + gl_state.d_16to8table = fileSystem.loadFile("pics/16to8.dat"); if (gl_state.d_16to8table == null) Com.Error(Defines.ERR_FATAL, "Couldn't load pics/16to8.pcx"); } diff --git a/src/lwjake2/render/lwjgl/Misc.java b/src/lwjake2/render/lwjgl/Misc.java index cd32bd7..c78e385 100644 --- a/src/lwjake2/render/lwjgl/Misc.java +++ b/src/lwjake2/render/lwjgl/Misc.java @@ -20,7 +20,7 @@ package lwjake2.render.lwjgl; import lwjake2.Defines; import lwjake2.client.VID; -import lwjake2.qcommon.FS; +import lwjake2.qcommon.BaseQ2FileSystem; import java.io.File; import java.io.IOException; @@ -29,6 +29,7 @@ import java.nio.FloatBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; +import lwjake2.qcommon.FileSystem; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.ARBMultitexture; import org.lwjgl.opengl.EXTPointParameters; @@ -42,6 +43,7 @@ import org.lwjgl.opengl.GL12; * @author cwei */ public abstract class Misc extends Mesh { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); /* ================== @@ -121,8 +123,8 @@ public abstract class Misc extends Mesh { ================== */ void GL_ScreenShot_f() { - StringBuffer sb = new StringBuffer(FS.Gamedir() + "/scrshot/jake00.tga"); - FS.CreatePath(sb.toString()); + StringBuffer sb = new StringBuffer(fileSystem.getGamedir() + "/scrshot/jake00.tga"); + fileSystem.createPath(sb.toString()); File file = new File(sb.toString()); // find a valid file name int i = 0; int offset = sb.length() - 6; diff --git a/src/lwjake2/render/lwjgl/Model.java b/src/lwjake2/render/lwjgl/Model.java index c1f01eb..4a7e410 100644 --- a/src/lwjake2/render/lwjgl/Model.java +++ b/src/lwjake2/render/lwjgl/Model.java @@ -24,7 +24,8 @@ import lwjake2.game.cplane_t; import lwjake2.game.cvar_t; import lwjake2.qcommon.Com; import lwjake2.qcommon.Cvar; -import lwjake2.qcommon.FS; +import lwjake2.qcommon.FileSystem; +import lwjake2.qcommon.BaseQ2FileSystem; import lwjake2.qcommon.lump_t; import lwjake2.qcommon.qfiles; import lwjake2.qcommon.texinfo_t; @@ -54,6 +55,7 @@ import org.lwjgl.BufferUtils; * @author cwei */ public abstract class Model extends Surf { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); // models.c -- model loading and caching @@ -271,7 +273,7 @@ public abstract class Model extends Surf { // // load the file // - fileBuffer = FS.LoadFile(name); + fileBuffer = fileSystem.loadFile(name); if (fileBuffer == null) { diff --git a/src/lwjake2/server/SV_CCMDS.java b/src/lwjake2/server/SV_CCMDS.java index fbbb684..9c8019d 100644 --- a/src/lwjake2/server/SV_CCMDS.java +++ b/src/lwjake2/server/SV_CCMDS.java @@ -30,7 +30,8 @@ import lwjake2.game.cvar_t; import lwjake2.qcommon.CM; import lwjake2.qcommon.Com; import lwjake2.qcommon.Cvar; -import lwjake2.qcommon.FS; +import lwjake2.qcommon.FileSystem; +import lwjake2.qcommon.BaseQ2FileSystem; import lwjake2.qcommon.MSG; import lwjake2.qcommon.Netchan; import lwjake2.qcommon.SZ; @@ -50,6 +51,7 @@ import java.util.Calendar; @Slf4j public class SV_CCMDS { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); /* =============================================================================== @@ -176,13 +178,13 @@ public class SV_CCMDS { Com.DPrintf("SV_WipeSaveGame(" + savename + ")\n"); - name = FS.Gamedir() + "/save/" + savename + "/server.ssv"; + name = fileSystem.getGamedir() + "/save/" + savename + "/server.ssv"; remove(name); - name = FS.Gamedir() + "/save/" + savename + "/game.ssv"; + name = fileSystem.getGamedir() + "/save/" + savename + "/game.ssv"; remove(name); - name = FS.Gamedir() + "/save/" + savename + "/*.sav"; + name = fileSystem.getGamedir() + "/save/" + savename + "/*.sav"; File f = Sys.FindFirst(name, 0, 0); while (f != null) { @@ -191,7 +193,7 @@ public class SV_CCMDS { } Sys.FindClose(); - name = FS.Gamedir() + "/save/" + savename + "/*.sv2"; + name = fileSystem.getGamedir() + "/save/" + savename + "/*.sv2"; f = Sys.FindFirst(name, 0, 0); @@ -281,23 +283,23 @@ public class SV_CCMDS { SV_WipeSavegame(dst); // copy the savegame over - name = FS.Gamedir() + "/save/" + src + "/server.ssv"; - name2 = FS.Gamedir() + "/save/" + dst + "/server.ssv"; - FS.CreatePath(name2); + name = fileSystem.getGamedir() + "/save/" + src + "/server.ssv"; + name2 = fileSystem.getGamedir() + "/save/" + dst + "/server.ssv"; + fileSystem.createPath(name2); CopyFile(name, name2); - name = FS.Gamedir() + "/save/" + src + "/game.ssv"; - name2 = FS.Gamedir() + "/save/" + dst + "/game.ssv"; + name = fileSystem.getGamedir() + "/save/" + src + "/game.ssv"; + name2 = fileSystem.getGamedir() + "/save/" + dst + "/game.ssv"; CopyFile(name, name2); - String name1 = FS.Gamedir() + "/save/" + src + "/"; - name = FS.Gamedir() + "/save/" + src + "/*.sav"; + String name1 = fileSystem.getGamedir() + "/save/" + src + "/"; + name = fileSystem.getGamedir() + "/save/" + src + "/*.sav"; found = Sys.FindFirst(name, 0, 0); while (found != null) { name = name1 + found.getName(); - name2 = FS.Gamedir() + "/save/" + dst + "/" + found.getName(); + name2 = fileSystem.getGamedir() + "/save/" + dst + "/" + found.getName(); CopyFile(name, name2); @@ -324,7 +326,7 @@ public class SV_CCMDS { Com.DPrintf("SV_WriteLevelFile()\n"); - name = FS.Gamedir() + "/save/current/" + SV_INIT.sv.name + ".sv2"; + name = fileSystem.getGamedir() + "/save/current/" + SV_INIT.sv.name + ".sv2"; try { f = new QuakeFile(name, "rw"); @@ -340,7 +342,7 @@ public class SV_CCMDS { e.printStackTrace(); } - name = FS.Gamedir() + "/save/current/" + SV_INIT.sv.name + ".sav"; + name = fileSystem.getGamedir() + "/save/current/" + SV_INIT.sv.name + ".sav"; GameSave.WriteLevel(name); } /* @@ -356,7 +358,7 @@ public class SV_CCMDS { Com.DPrintf("SV_ReadLevelFile()\n"); - name = FS.Gamedir() + "/save/current/" + SV_INIT.sv.name + ".sv2"; + name = fileSystem.getGamedir() + "/save/current/" + SV_INIT.sv.name + ".sv2"; try { f = new QuakeFile(name, "r"); @@ -372,7 +374,7 @@ public class SV_CCMDS { e1.printStackTrace(); } - name = FS.Gamedir() + "/save/current/" + SV_INIT.sv.name + ".sav"; + name = fileSystem.getGamedir() + "/save/current/" + SV_INIT.sv.name + ".sav"; GameSave.ReadLevel(name); } /* @@ -389,7 +391,7 @@ public class SV_CCMDS { Com.DPrintf("SV_WriteServerFile(" + (autosave ? "true" : "false") + ")\n"); - filename = FS.Gamedir() + "/save/current/server.ssv"; + filename = fileSystem.getGamedir() + "/save/current/server.ssv"; try { f = new QuakeFile(filename, "rw"); @@ -442,7 +444,7 @@ public class SV_CCMDS { } // write game state - filename = FS.Gamedir() + "/save/current/game.ssv"; + filename = fileSystem.getGamedir() + "/save/current/game.ssv"; GameSave.WriteGame(filename, autosave); } /* @@ -460,7 +462,7 @@ public class SV_CCMDS { Com.DPrintf("SV_ReadServerFile()\n"); - filename = FS.Gamedir() + "/save/current/server.ssv"; + filename = fileSystem.getGamedir() + "/save/current/server.ssv"; f = new QuakeFile(filename, "r"); @@ -487,7 +489,7 @@ public class SV_CCMDS { SV_INIT.svs.mapcmd = mapcmd; // read game state - filename = FS.Gamedir() + "/save/current/game.ssv"; + filename = fileSystem.getGamedir() + "/save/current/game.ssv"; GameSave.ReadGame(filename); } catch (Exception e) { @@ -538,7 +540,7 @@ public class SV_CCMDS { Com.DPrintf("SV_GameMap(" + Cmd.Argv(1) + ")\n"); - FS.CreatePath(FS.Gamedir() + "/save/current/"); + fileSystem.createPath(fileSystem.getGamedir() + "/save/current/"); // check for clearing the current savegame map = Cmd.Argv(1); @@ -599,7 +601,7 @@ public class SV_CCMDS { map = Cmd.Argv(1); if (map.indexOf(".") < 0) { expanded = "maps/" + map + ".bsp"; - if (FS.LoadFile(expanded) == null) { + if (fileSystem.loadFile(expanded) == null) { Com.Printf("Can't find " + expanded + "\n"); return; @@ -644,7 +646,7 @@ public class SV_CCMDS { } // make sure the server.ssv file exists - name = FS.Gamedir() + "/save/" + Cmd.Argv(1) + "/server.ssv"; + name = fileSystem.getGamedir() + "/save/" + Cmd.Argv(1) + "/server.ssv"; try { f = new RandomAccessFile(name, "r"); } @@ -913,10 +915,10 @@ public class SV_CCMDS { // // open the demo file // - name = FS.Gamedir() + "/demos/" + Cmd.Argv(1) + ".dm2"; + name = fileSystem.getGamedir() + "/demos/" + Cmd.Argv(1) + ".dm2"; Com.Printf("recording to " + name + ".\n"); - FS.CreatePath(name); + fileSystem.createPath(name); try { SV_INIT.svs.demofile = new RandomAccessFile(name, "rw"); } diff --git a/src/lwjake2/server/SV_INIT.java b/src/lwjake2/server/SV_INIT.java index 613109b..fa1da8a 100644 --- a/src/lwjake2/server/SV_INIT.java +++ b/src/lwjake2/server/SV_INIT.java @@ -32,7 +32,8 @@ import lwjake2.qcommon.CM; import lwjake2.qcommon.Cbuf; import lwjake2.qcommon.Com; import lwjake2.qcommon.Cvar; -import lwjake2.qcommon.FS; +import lwjake2.qcommon.FileSystem; +import lwjake2.qcommon.BaseQ2FileSystem; import lwjake2.qcommon.MSG; import lwjake2.qcommon.PMove; import lwjake2.qcommon.SZ; @@ -45,6 +46,7 @@ import java.io.RandomAccessFile; @Slf4j public class SV_INIT { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); /** * SV_FindIndex. */ @@ -134,7 +136,7 @@ public class SV_INIT { if (Cvar.VariableValue("deathmatch") != 0) return; - name = FS.Gamedir() + "/save/current/" + sv.name + ".sav"; + name = fileSystem.getGamedir() + "/save/current/" + sv.name + ".sav"; try { f = new RandomAccessFile(name, "r"); } diff --git a/src/lwjake2/server/SV_MAIN.java b/src/lwjake2/server/SV_MAIN.java index 69d1928..3755a51 100644 --- a/src/lwjake2/server/SV_MAIN.java +++ b/src/lwjake2/server/SV_MAIN.java @@ -29,7 +29,6 @@ import lwjake2.game.cvar_t; import lwjake2.game.edict_t; import lwjake2.qcommon.Com; import lwjake2.qcommon.Cvar; -import lwjake2.qcommon.FS; import lwjake2.qcommon.MSG; import lwjake2.qcommon.Netchan; import lwjake2.qcommon.SZ; @@ -116,7 +115,6 @@ public class SV_MAIN { } if (drop.download != null) { - FS.FreeFile(drop.download); drop.download = null; } diff --git a/src/lwjake2/server/SV_USER.java b/src/lwjake2/server/SV_USER.java index 61cef8c..2c1287e 100644 --- a/src/lwjake2/server/SV_USER.java +++ b/src/lwjake2/server/SV_USER.java @@ -27,17 +27,13 @@ import lwjake2.game.PlayerClient; import lwjake2.game.edict_t; import lwjake2.game.entity_state_t; import lwjake2.game.usercmd_t; -import lwjake2.qcommon.Cbuf; -import lwjake2.qcommon.Com; -import lwjake2.qcommon.Cvar; -import lwjake2.qcommon.FS; -import lwjake2.qcommon.MSG; -import lwjake2.qcommon.SZ; +import lwjake2.qcommon.*; import lwjake2.util.Lib; import java.io.IOException; public class SV_USER { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); static edict_t sv_player; @@ -120,7 +116,7 @@ public class SV_USER { name = "demos/" + SV_INIT.sv.name; try { - SV_INIT.sv.demofile = FS.FOpenFile(name); + SV_INIT.sv.demofile = fileSystem.FOpenFile(name); } catch (IOException e) { Com.Error(Defines.ERR_DROP, "Couldn't open " + name + "\n"); } @@ -365,7 +361,6 @@ public class SV_USER { if (SV_MAIN.sv_client.downloadcount != SV_MAIN.sv_client.downloadsize) return; - FS.FreeFile(SV_MAIN.sv_client.download); SV_MAIN.sv_client.download = null; } @@ -409,9 +404,9 @@ public class SV_USER { } if (SV_MAIN.sv_client.download != null) - FS.FreeFile(SV_MAIN.sv_client.download); + SV_MAIN.sv_client.download = null; - SV_MAIN.sv_client.download = FS.LoadFile(name); + SV_MAIN.sv_client.download = fileSystem.loadFile(name); // rst: this handles loading errors, no message yet visible if (SV_MAIN.sv_client.download == null) @@ -429,11 +424,10 @@ public class SV_USER { // came from a pak file, don't // allow // download ZOID - || (name.startsWith("maps/") && FS.file_from_pak != 0)) { + || (name.startsWith("maps/") && fileSystem.getFileFromPak() != 0)) { Com.DPrintf("Couldn't download " + name + " to " + SV_MAIN.sv_client.name + "\n"); if (SV_MAIN.sv_client.download != null) { - FS.FreeFile(SV_MAIN.sv_client.download); SV_MAIN.sv_client.download = null; } diff --git a/src/lwjake2/sound/WaveLoader.java b/src/lwjake2/sound/WaveLoader.java index 50e56ab..cca5b1d 100644 --- a/src/lwjake2/sound/WaveLoader.java +++ b/src/lwjake2/sound/WaveLoader.java @@ -20,14 +20,16 @@ package lwjake2.sound; import lombok.extern.slf4j.Slf4j; import lwjake2.Defines; +import lwjake2.qcommon.BaseQ2FileSystem; import lwjake2.qcommon.Com; -import lwjake2.qcommon.FS; +import lwjake2.qcommon.FileSystem; /** * SND_MEM */ @Slf4j public class WaveLoader { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); /** * The ResampleSfx can squeeze and stretch samples to a default sample rate. * Since Joal and lwjgl sound drivers support this, we don't need it and the samples @@ -66,7 +68,7 @@ public class WaveLoader { else namebuffer = "sound/" + name; - byte[] data = FS.LoadFile(namebuffer); + byte[] data = fileSystem.loadFile(namebuffer); if (data == null) { Com.DPrintf("Couldn't load " + namebuffer + "\n"); diff --git a/src/lwjake2/sound/lwjgl/LWJGLSoundImpl.java b/src/lwjake2/sound/lwjgl/LWJGLSoundImpl.java index 473dec2..44eb8b7 100644 --- a/src/lwjake2/sound/lwjgl/LWJGLSoundImpl.java +++ b/src/lwjake2/sound/lwjgl/LWJGLSoundImpl.java @@ -25,9 +25,7 @@ import lwjake2.game.Cmd; import lwjake2.game.GameBase; import lwjake2.game.cvar_t; import lwjake2.game.entity_state_t; -import lwjake2.qcommon.Com; -import lwjake2.qcommon.Cvar; -import lwjake2.qcommon.FS; +import lwjake2.qcommon.*; import lwjake2.sound.S; import lwjake2.sound.Sound; import lwjake2.sound.WaveLoader; @@ -57,6 +55,7 @@ import org.lwjgl.openal.OpenALException; */ @Slf4j public final class LWJGLSoundImpl implements Sound { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); static { S.register(new LWJGLSoundImpl()); }; @@ -379,14 +378,14 @@ public final class LWJGLSoundImpl implements Sound { // fall back strategies // // not found , so see if it exists - if (FS.FileLength(sexedFilename.substring(1)) > 0) { + if (fileSystem.fileLength(sexedFilename.substring(1)) > 0) { // yes, register it return RegisterSound(sexedFilename); } // try it with the female sound in the pak0.pak if (model.equalsIgnoreCase("female")) { String femaleFilename = "player/female/" + base.substring(1); - if (FS.FileLength("sound/" + femaleFilename) > 0) + if (fileSystem.fileLength("sound/" + femaleFilename) > 0) return AliasName(sexedFilename, femaleFilename); } // no chance, revert to the male sound in the pak0.pak diff --git a/src/lwjake2/util/Lib.java b/src/lwjake2/util/Lib.java index 5bba8b3..9ec91be 100644 --- a/src/lwjake2/util/Lib.java +++ b/src/lwjake2/util/Lib.java @@ -20,8 +20,9 @@ package lwjake2.util; import lombok.extern.slf4j.Slf4j; import lwjake2.Globals; +import lwjake2.qcommon.BaseQ2FileSystem; import lwjake2.qcommon.Com; -import lwjake2.qcommon.FS; +import lwjake2.qcommon.FileSystem; import java.io.File; import java.io.IOException; @@ -34,6 +35,7 @@ import java.nio.IntBuffer; @Slf4j public class Lib { + private static final FileSystem fileSystem = BaseQ2FileSystem.getInstance(); /** Converts a vector to a string. */ public static String vtos(float[] v) { return (int) v[0] + " " + (int) v[1] + " " + (int) v[2]; @@ -240,7 +242,7 @@ public class Lib { /** Like in libc */ public static String freadString(RandomAccessFile f, int len) { byte buffer[] = new byte[len]; - FS.Read(buffer, len, f); + fileSystem.read(buffer, len, f); return Lib.CtoJava(buffer); }