FS -> FileSystem interface
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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<filelink_t> 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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<String, packfile_t> 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<filelink_t> fs_links = new LinkedList<filelink_t>();
|
||||
|
||||
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<filelink_t> 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<filelink_t> 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<filelink_t> 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<String, packfile_t> 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<String, packfile_t>(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 <user.home>/.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 <from> <to>");
|
||||
return;
|
||||
}
|
||||
|
||||
// see if the link already exists
|
||||
for (Iterator<filelink_t> 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 <to> 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<filelink_t> 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 <path>
|
||||
// allows the game to run from outside the data tree
|
||||
//
|
||||
fs_basedir = Cvar.Get("basedir", ".", CVAR_NOSET);
|
||||
|
||||
//
|
||||
// cddir <path>
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user