fb214142a3
lots of hexen2 fixes fixed clipped decals again, still not using any... fixed zips over 2g rewrote bloom to use glsl. should be slightly more usable now. lots more hexen2 fixes git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3957 fc73d0e0-1445-4013-8a0c-d673dee63da5
284 lines
7.2 KiB
C
284 lines
7.2 KiB
C
#include "quakedef.h"
|
|
#include "fs.h"
|
|
#include <windows.h>
|
|
|
|
#ifndef INVALID_SET_FILE_POINTER
|
|
#define INVALID_SET_FILE_POINTER ~0
|
|
#endif
|
|
|
|
//read-only memory mapped files.
|
|
//for write access, we use the stdio module as a fallback.
|
|
|
|
#define VFSW32_Open VFSOS_Open
|
|
#define w32filefuncs osfilefuncs
|
|
|
|
typedef struct {
|
|
vfsfile_t funcs;
|
|
HANDLE hand;
|
|
HANDLE mmh;
|
|
void *mmap;
|
|
unsigned int length;
|
|
unsigned int offset;
|
|
} vfsw32file_t;
|
|
static int VFSW32_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
|
|
{
|
|
DWORD read;
|
|
vfsw32file_t *intfile = (vfsw32file_t*)file;
|
|
if (intfile->mmap)
|
|
{
|
|
if (intfile->offset+bytestoread > intfile->length)
|
|
bytestoread = intfile->length-intfile->offset;
|
|
|
|
memcpy(buffer, (char*)intfile->mmap + intfile->offset, bytestoread);
|
|
intfile->offset += bytestoread;
|
|
return bytestoread;
|
|
}
|
|
if (!ReadFile(intfile->hand, buffer, bytestoread, &read, NULL))
|
|
return 0;
|
|
return read;
|
|
}
|
|
static int VFSW32_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestoread)
|
|
{
|
|
DWORD written;
|
|
vfsw32file_t *intfile = (vfsw32file_t*)file;
|
|
if (intfile->mmap)
|
|
{
|
|
if (intfile->offset+bytestoread > intfile->length)
|
|
bytestoread = intfile->length-intfile->offset;
|
|
|
|
memcpy((char*)intfile->mmap + intfile->offset, buffer, bytestoread);
|
|
intfile->offset += bytestoread;
|
|
return bytestoread;
|
|
}
|
|
|
|
if (!WriteFile(intfile->hand, buffer, bytestoread, &written, NULL))
|
|
return 0;
|
|
return written;
|
|
}
|
|
static qboolean VFSW32_Seek (struct vfsfile_s *file, unsigned long pos)
|
|
{
|
|
unsigned long upper, lower;
|
|
vfsw32file_t *intfile = (vfsw32file_t*)file;
|
|
if (intfile->mmap)
|
|
{
|
|
intfile->offset = pos;
|
|
return true;
|
|
}
|
|
|
|
lower = (pos & 0xffffffff);
|
|
upper = ((pos>>16)>>16);
|
|
|
|
return SetFilePointer(intfile->hand, lower, &upper, FILE_BEGIN) != INVALID_SET_FILE_POINTER;
|
|
}
|
|
static unsigned long VFSW32_Tell (struct vfsfile_s *file)
|
|
{
|
|
vfsw32file_t *intfile = (vfsw32file_t*)file;
|
|
if (intfile->mmap)
|
|
return intfile->offset;
|
|
return SetFilePointer(intfile->hand, 0, NULL, FILE_CURRENT);
|
|
}
|
|
static void VFSW32_Flush(struct vfsfile_s *file)
|
|
{
|
|
vfsw32file_t *intfile = (vfsw32file_t*)file;
|
|
if (intfile->mmap)
|
|
FlushViewOfFile(intfile->mmap, intfile->length);
|
|
FlushFileBuffers(intfile->hand);
|
|
}
|
|
static unsigned long VFSW32_GetSize (struct vfsfile_s *file)
|
|
{
|
|
vfsw32file_t *intfile = (vfsw32file_t*)file;
|
|
|
|
if (intfile->mmap)
|
|
return intfile->length;
|
|
return GetFileSize(intfile->hand, NULL);
|
|
}
|
|
static void VFSW32_Close(vfsfile_t *file)
|
|
{
|
|
vfsw32file_t *intfile = (vfsw32file_t*)file;
|
|
if (intfile->mmap)
|
|
{
|
|
UnmapViewOfFile(intfile->mmap);
|
|
CloseHandle(intfile->mmh);
|
|
}
|
|
CloseHandle(intfile->hand);
|
|
Z_Free(file);
|
|
}
|
|
|
|
vfsfile_t *VFSW32_Open(const char *osname, const char *mode)
|
|
{
|
|
HANDLE h, mh;
|
|
unsigned int fsize;
|
|
void *mmap;
|
|
|
|
vfsw32file_t *file;
|
|
qboolean read = !!strchr(mode, 'r');
|
|
qboolean write = !!strchr(mode, 'w');
|
|
qboolean append = !!strchr(mode, 'a');
|
|
qboolean text = !!strchr(mode, 't');
|
|
write |= append;
|
|
if (strchr(mode, '+'))
|
|
read = write = true;
|
|
|
|
if ((write && read) || append)
|
|
h = CreateFileA(osname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
else if (write)
|
|
h = CreateFileA(osname, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
else if (read)
|
|
h = CreateFileA(osname, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
else
|
|
h = INVALID_HANDLE_VALUE;
|
|
if (h == INVALID_HANDLE_VALUE)
|
|
return NULL;
|
|
|
|
if (write || append || text)
|
|
{
|
|
fsize = 0;
|
|
mh = INVALID_HANDLE_VALUE;
|
|
mmap = NULL;
|
|
|
|
/*if appending, set the access position to the end of the file*/
|
|
if (append)
|
|
SetFilePointer(h, 0, NULL, FILE_END);
|
|
}
|
|
else
|
|
{
|
|
fsize = GetFileSize(h, NULL);
|
|
mh = CreateFileMapping(h, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
if (mh == INVALID_HANDLE_VALUE)
|
|
mmap = NULL;
|
|
else
|
|
{
|
|
mmap = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, fsize);
|
|
if (mmap == NULL)
|
|
{
|
|
CloseHandle(mh);
|
|
mh = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
file = Z_Malloc(sizeof(vfsw32file_t));
|
|
file->funcs.ReadBytes = read?VFSW32_ReadBytes:NULL;
|
|
file->funcs.WriteBytes = (write||append)?VFSW32_WriteBytes:NULL;
|
|
file->funcs.Seek = VFSW32_Seek;
|
|
file->funcs.Tell = VFSW32_Tell;
|
|
file->funcs.GetLen = VFSW32_GetSize;
|
|
file->funcs.Close = VFSW32_Close;
|
|
file->funcs.Flush = VFSW32_Flush;
|
|
file->hand = h;
|
|
file->mmh = mh;
|
|
file->mmap = mmap;
|
|
file->offset = 0;
|
|
file->length = fsize;
|
|
|
|
return (vfsfile_t*)file;
|
|
}
|
|
|
|
static vfsfile_t *VFSW32_OpenVFS(void *handle, flocation_t *loc, const char *mode)
|
|
{
|
|
//path is already cleaned, as anything that gets a valid loc needs cleaning up first.
|
|
|
|
return VFSW32_Open(loc->rawname, mode);
|
|
}
|
|
|
|
static void VFSW32_PrintPath(void *handle)
|
|
{
|
|
Con_Printf("%s\n", (char *)handle);
|
|
}
|
|
static void VFSW32_ClosePath(void *handle)
|
|
{
|
|
Z_Free(handle);
|
|
}
|
|
static int VFSW32_RebuildFSHash(const char *filename, int filesize, void *data)
|
|
{
|
|
if (filename[strlen(filename)-1] == '/')
|
|
{ //this is actually a directory
|
|
|
|
char childpath[256];
|
|
Q_snprintfz(childpath, sizeof(childpath), "%s*", filename);
|
|
Sys_EnumerateFiles((char*)data, childpath, VFSW32_RebuildFSHash, data);
|
|
return true;
|
|
}
|
|
if (!Hash_GetInsensative(&filesystemhash, filename))
|
|
{
|
|
bucket_t *bucket = (bucket_t*)BZ_Malloc(sizeof(bucket_t) + strlen(filename)+1);
|
|
strcpy((char *)(bucket+1), filename);
|
|
#ifdef _WIN32
|
|
Q_strlwr((char *)(bucket+1));
|
|
#endif
|
|
Hash_AddInsensative(&filesystemhash, (char *)(bucket+1), data, bucket);
|
|
|
|
fs_hash_files++;
|
|
}
|
|
else
|
|
fs_hash_dups++;
|
|
return true;
|
|
}
|
|
static void VFSW32_BuildHash(void *handle)
|
|
{
|
|
Sys_EnumerateFiles(handle, "*", VFSW32_RebuildFSHash, handle);
|
|
}
|
|
static qboolean VFSW32_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)
|
|
{
|
|
FILE *f;
|
|
int len;
|
|
char netpath[MAX_OSPATH];
|
|
|
|
|
|
if (hashedresult && (void *)hashedresult != handle)
|
|
return false;
|
|
|
|
/*
|
|
if (!static_registered)
|
|
{ // if not a registered version, don't ever go beyond base
|
|
if ( strchr (filename, '/') || strchr (filename,'\\'))
|
|
continue;
|
|
}
|
|
*/
|
|
|
|
// check a file in the directory tree
|
|
snprintf (netpath, sizeof(netpath)-1, "%s/%s",(char*)handle, filename);
|
|
|
|
f = fopen(netpath, "rb");
|
|
if (!f)
|
|
return false;
|
|
|
|
fseek(f, 0, SEEK_END);
|
|
len = ftell(f);
|
|
fclose(f);
|
|
if (loc)
|
|
{
|
|
loc->len = len;
|
|
loc->offset = 0;
|
|
loc->index = 0;
|
|
snprintf(loc->rawname, sizeof(loc->rawname), "%s/%s", (char*)handle, filename);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
static void VFSW32_ReadFile(void *handle, flocation_t *loc, char *buffer)
|
|
{
|
|
FILE *f;
|
|
f = fopen(loc->rawname, "rb");
|
|
if (!f) //err...
|
|
return;
|
|
fseek(f, loc->offset, SEEK_SET);
|
|
fread(buffer, 1, loc->len, f);
|
|
fclose(f);
|
|
}
|
|
static int VFSW32_EnumerateFiles (void *handle, const char *match, int (*func)(const char *, int, void *), void *parm)
|
|
{
|
|
return Sys_EnumerateFiles(handle, match, func, parm);
|
|
}
|
|
|
|
searchpathfuncs_t w32filefuncs = {
|
|
VFSW32_PrintPath,
|
|
VFSW32_ClosePath,
|
|
VFSW32_BuildHash,
|
|
VFSW32_FLocate,
|
|
VFSW32_ReadFile,
|
|
VFSW32_EnumerateFiles,
|
|
NULL,
|
|
NULL,
|
|
VFSW32_OpenVFS
|
|
};
|