------------------------------------------------------------------------
r4214 | acceptthis | 2013-02-18 03:33:35 +0000 (Mon, 18 Feb 2013) | 1 line my attempt at manifest file support. ------------------------------------------------------------------------ git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4211 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
55cb101be1
commit
f7c0eff8c6
|
@ -862,21 +862,13 @@ static int CL_BootDownload_Extract(const char *fname, int fsize, void *ptr)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qboolean FS_LoadPackageFromFile(vfsfile_t *vfs, char *pname, char *localname, int *crc, qboolean copyprotect, qboolean istemporary, qboolean isexplicit);
|
||||||
|
|
||||||
|
void FS_GenCachedPakName(char *pname, char *crc, char *local, int llen);
|
||||||
static void CL_BootDownload_Complete(struct dl_download *dl)
|
static void CL_BootDownload_Complete(struct dl_download *dl)
|
||||||
{
|
{
|
||||||
void *zip;
|
void *zip;
|
||||||
/*
|
|
||||||
int sz;
|
|
||||||
char *buf;
|
|
||||||
FILE *f;
|
|
||||||
sz = VFS_GETLEN(dl->file);
|
|
||||||
buf = malloc(sz);
|
|
||||||
VFS_READ(dl->file, buf, sz);
|
|
||||||
f = fopen("C:/Games/Quake/test/emptybasedir/test.zip", "wb");
|
|
||||||
fwrite(buf, 1, sz, f);
|
|
||||||
fclose(f);
|
|
||||||
free(buf);
|
|
||||||
*/
|
|
||||||
if (dl->status == DL_FINISHED)
|
if (dl->status == DL_FINISHED)
|
||||||
zip = zipfilefuncs.OpenNew(dl->file, dl->url);
|
zip = zipfilefuncs.OpenNew(dl->file, dl->url);
|
||||||
else
|
else
|
||||||
|
@ -885,11 +877,71 @@ static void CL_BootDownload_Complete(struct dl_download *dl)
|
||||||
dl->file = NULL;
|
dl->file = NULL;
|
||||||
if (zip)
|
if (zip)
|
||||||
{
|
{
|
||||||
/*scan it to extract its contents*/
|
if (dl->user_ctx)
|
||||||
zipfilefuncs.EnumerateFiles(zip, "*/*.pk3", CL_BootDownload_Extract, zip);
|
{
|
||||||
zipfilefuncs.EnumerateFiles(zip, "*/*.pak", CL_BootDownload_Extract, zip);
|
vfsfile_t *in, *out;
|
||||||
zipfilefuncs.EnumerateFiles(zip, "*/*/*.pk3", CL_BootDownload_Extract, zip);
|
flocation_t loc;
|
||||||
zipfilefuncs.EnumerateFiles(zip, "*/*/*.pak", CL_BootDownload_Extract, zip);
|
qboolean found = false;
|
||||||
|
int crc;
|
||||||
|
|
||||||
|
found = zipfilefuncs.FindFile(zip, &loc, dl->user_ctx, NULL);
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
char *s = COM_SkipPath(dl->user_ctx);
|
||||||
|
if (s != dl->user_ctx)
|
||||||
|
found = zipfilefuncs.FindFile(zip, &loc, s, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
in = zipfilefuncs.OpenVFS(zip, &loc, "rb");
|
||||||
|
if (in)
|
||||||
|
{
|
||||||
|
char local[MAX_OSPATH];
|
||||||
|
FS_GenCachedPakName(dl->user_ctx, va("%i", dl->user_num), local, sizeof(local));
|
||||||
|
FS_CreatePath(local, FS_ROOT);
|
||||||
|
out = FS_OpenVFS(local, "wb", FS_ROOT);
|
||||||
|
if (out)
|
||||||
|
{
|
||||||
|
char buffer[8192];
|
||||||
|
int read;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
read = VFS_READ(in, buffer, sizeof(buffer));
|
||||||
|
if (read <= 0)
|
||||||
|
break;
|
||||||
|
if (VFS_WRITE(out, buffer, read) != read)
|
||||||
|
{
|
||||||
|
Con_Printf("write failed writing %s. disk full?\n", local);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VFS_CLOSE(out);
|
||||||
|
out = FS_OpenVFS(local, "rb", FS_ROOT);
|
||||||
|
crc = dl->user_num;
|
||||||
|
if (!FS_LoadPackageFromFile(out, dl->user_ctx, local, &crc, true, false, true))
|
||||||
|
{
|
||||||
|
if (crc == dl->user_num)
|
||||||
|
Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable.\n", dl->user_ctx);
|
||||||
|
else
|
||||||
|
Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable or has invalid crc. Stated crc %#x is not calculated crc %#x\n", dl->user_ctx, dl->user_num, crc);
|
||||||
|
FS_Remove(local, FS_ROOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VFS_CLOSE(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(dl->user_ctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*scan it to extract its contents*/
|
||||||
|
zipfilefuncs.EnumerateFiles(zip, "*/*.pk3", CL_BootDownload_Extract, zip);
|
||||||
|
zipfilefuncs.EnumerateFiles(zip, "*/*.pak", CL_BootDownload_Extract, zip);
|
||||||
|
zipfilefuncs.EnumerateFiles(zip, "*/*/*.pk3", CL_BootDownload_Extract, zip);
|
||||||
|
zipfilefuncs.EnumerateFiles(zip, "*/*/*.pak", CL_BootDownload_Extract, zip);
|
||||||
|
}
|
||||||
|
|
||||||
/*close it, delete the temp file from disk, etc*/
|
/*close it, delete the temp file from disk, etc*/
|
||||||
zipfilefuncs.ClosePath(zip);
|
zipfilefuncs.ClosePath(zip);
|
||||||
|
@ -907,6 +959,71 @@ static void CL_BootDownload_Complete(struct dl_download *dl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CL_Manifest_Complete(struct dl_download *dl)
|
||||||
|
{
|
||||||
|
if (dl->file)
|
||||||
|
{
|
||||||
|
vfsfile_t *f;
|
||||||
|
char buffer[1024];
|
||||||
|
char *fname;
|
||||||
|
int crc;
|
||||||
|
char local[MAX_OSPATH];
|
||||||
|
while(VFS_GETS(dl->file, buffer, sizeof(buffer)))
|
||||||
|
{
|
||||||
|
Cmd_TokenizeString(buffer, false, false);
|
||||||
|
if (!Cmd_Argc())
|
||||||
|
continue;
|
||||||
|
fname = Cmd_Argv(0);
|
||||||
|
crc = strtoul(Cmd_Argv(1), NULL, 0);
|
||||||
|
|
||||||
|
f = FS_OpenVFS(fname, "rb", FS_ROOT);
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
//should be loaded as needed
|
||||||
|
VFS_CLOSE(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FS_GenCachedPakName(fname, va("%i", crc), local, sizeof(local));
|
||||||
|
f = FS_OpenVFS(local, "rb", FS_ROOT);
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
int truecrc = crc;
|
||||||
|
if (!FS_LoadPackageFromFile(f, fname, local, &truecrc, true, false, true))
|
||||||
|
{
|
||||||
|
if (crc == truecrc)
|
||||||
|
Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable.\n", fname);
|
||||||
|
else
|
||||||
|
Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable or has invalid crc. Stated crc %#x is not calculated crc %#x\n", fname, crc, truecrc);
|
||||||
|
FS_Remove(local, FS_ROOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Con_Printf("Downloading %s from %s\n", fname, Cmd_Argv(2));
|
||||||
|
dl = HTTP_CL_Get(Cmd_Argv(2), "", CL_BootDownload_Complete);
|
||||||
|
if (dl)
|
||||||
|
{
|
||||||
|
dl->user_ctx = strdup(fname);
|
||||||
|
dl->user_num = crc;
|
||||||
|
#ifdef MULTITHREAD
|
||||||
|
DL_CreateThread(dl, FS_OpenTemp(), CL_BootDownload_Complete);
|
||||||
|
#endif
|
||||||
|
numbootdownloads++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!--numbootdownloads)
|
||||||
|
{
|
||||||
|
CL_ExecInitialConfigs();
|
||||||
|
Cmd_StuffCmds();
|
||||||
|
Cbuf_Execute ();
|
||||||
|
Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qboolean CL_CheckBootDownloads(void)
|
qboolean CL_CheckBootDownloads(void)
|
||||||
{
|
{
|
||||||
char *downloads = fs_gamedownload.string;
|
char *downloads = fs_gamedownload.string;
|
||||||
|
@ -916,6 +1033,23 @@ qboolean CL_CheckBootDownloads(void)
|
||||||
struct dl_download *dl;
|
struct dl_download *dl;
|
||||||
int mirrors;
|
int mirrors;
|
||||||
|
|
||||||
|
int man = COM_CheckParm("-manifest");
|
||||||
|
if (man)
|
||||||
|
{
|
||||||
|
const char *fname = com_argv[man+1];
|
||||||
|
|
||||||
|
Con_Printf("Checking manifest from \"%s\"\n", fname);
|
||||||
|
|
||||||
|
dl = HTTP_CL_Get(fname, token, CL_Manifest_Complete);
|
||||||
|
if (dl)
|
||||||
|
{
|
||||||
|
#ifdef MULTITHREAD
|
||||||
|
DL_CreateThread(dl, FS_OpenTemp(), CL_Manifest_Complete);
|
||||||
|
#endif
|
||||||
|
numbootdownloads++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while ((downloads = COM_ParseOut(downloads, token, sizeof(token))))
|
while ((downloads = COM_ParseOut(downloads, token, sizeof(token))))
|
||||||
{
|
{
|
||||||
//FIXME: do we want to add some sort of file size indicator?
|
//FIXME: do we want to add some sort of file size indicator?
|
||||||
|
|
|
@ -1866,6 +1866,47 @@ void FS_GenCachedPakName(char *pname, char *crc, char *local, int llen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qboolean FS_LoadPackageFromFile(vfsfile_t *vfs, char *pname, char *localname, int *crc, qboolean copyprotect, qboolean istemporary, qboolean isexplicit)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *ext = COM_FileExtension(pname);
|
||||||
|
void *handle;
|
||||||
|
|
||||||
|
searchpath_t *sp;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(searchpathformats)/sizeof(searchpathformats[0]); i++)
|
||||||
|
{
|
||||||
|
if (!searchpathformats[i].extension || !searchpathformats[i].funcs || !searchpathformats[i].funcs->OpenNew)
|
||||||
|
continue;
|
||||||
|
if (!strcmp(ext, searchpathformats[i].extension))
|
||||||
|
{
|
||||||
|
handle = searchpathformats[i].funcs->OpenNew (vfs, localname);
|
||||||
|
if (!handle)
|
||||||
|
break;
|
||||||
|
if (crc)
|
||||||
|
{
|
||||||
|
int truecrc = searchpathformats[i].funcs->GeneratePureCRC(handle, 0, false);
|
||||||
|
if (truecrc != *crc)
|
||||||
|
{
|
||||||
|
*crc = truecrc;
|
||||||
|
VFS_CLOSE(vfs);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sp = FS_AddPathHandle(pname, localname, searchpathformats[i].funcs, handle, copyprotect, istemporary, isexplicit, (unsigned int)-1);
|
||||||
|
|
||||||
|
if (sp)
|
||||||
|
{
|
||||||
|
FS_FlushFSHashReally();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VFS_CLOSE(vfs);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//if a server is using private pak files then load the same version of those, but deprioritise them
|
//if a server is using private pak files then load the same version of those, but deprioritise them
|
||||||
//crcs are not used, but matched only if the server has a different version from a previous file
|
//crcs are not used, but matched only if the server has a different version from a previous file
|
||||||
void FS_ImpurePacks(const char *names, const char *crcs)
|
void FS_ImpurePacks(const char *names, const char *crcs)
|
||||||
|
@ -1873,6 +1914,7 @@ void FS_ImpurePacks(const char *names, const char *crcs)
|
||||||
int crc;
|
int crc;
|
||||||
searchpath_t *sp;
|
searchpath_t *sp;
|
||||||
char *pname;
|
char *pname;
|
||||||
|
qboolean success;
|
||||||
|
|
||||||
while(names)
|
while(names)
|
||||||
{
|
{
|
||||||
|
@ -1899,31 +1941,14 @@ void FS_ImpurePacks(const char *names, const char *crcs)
|
||||||
char local[MAX_OSPATH];
|
char local[MAX_OSPATH];
|
||||||
vfsfile_t *vfs;
|
vfsfile_t *vfs;
|
||||||
char *ext = COM_FileExtension(pname);
|
char *ext = COM_FileExtension(pname);
|
||||||
void *handle;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
FS_GenCachedPakName(pname, va("%i", crc), local, sizeof(local));
|
FS_GenCachedPakName(pname, va("%i", crc), local, sizeof(local));
|
||||||
vfs = FS_OpenVFS(local, "rb", FS_ROOT);
|
vfs = FS_OpenVFS(local, "rb", FS_ROOT);
|
||||||
|
success = false;
|
||||||
if (vfs)
|
if (vfs)
|
||||||
{
|
success = FS_LoadPackageFromFile(vfs, pname, local, NULL, true, true, false);
|
||||||
for (i = 0; i < sizeof(searchpathformats)/sizeof(searchpathformats[0]); i++)
|
|
||||||
{
|
|
||||||
if (!searchpathformats[i].extension || !searchpathformats[i].funcs || !searchpathformats[i].funcs->OpenNew)
|
|
||||||
continue;
|
|
||||||
if (!strcmp(ext, searchpathformats[i].extension))
|
|
||||||
{
|
|
||||||
handle = searchpathformats[i].funcs->OpenNew (vfs, local);
|
|
||||||
if (!handle)
|
|
||||||
break;
|
|
||||||
sp = FS_AddPathHandle(pname, local, searchpathformats[i].funcs, handle, true, true, false, (unsigned int)-1);
|
|
||||||
|
|
||||||
FS_FlushFSHashReally();
|
if (!success)
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sp)
|
|
||||||
Con_DPrintf("Unable to load matching package file %s\n", pname);
|
Con_DPrintf("Unable to load matching package file %s\n", pname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,244 +1,244 @@
|
||||||
#include "bothdefs.h"
|
#include "bothdefs.h"
|
||||||
#if defined(GLQUAKE) && defined(USE_EGL)
|
#if defined(GLQUAKE) && defined(USE_EGL)
|
||||||
#include "gl_videgl.h"
|
#include "gl_videgl.h"
|
||||||
|
|
||||||
EGLContext eglctx = EGL_NO_CONTEXT;
|
EGLContext eglctx = EGL_NO_CONTEXT;
|
||||||
EGLDisplay egldpy = EGL_NO_DISPLAY;
|
EGLDisplay egldpy = EGL_NO_DISPLAY;
|
||||||
EGLSurface eglsurf = EGL_NO_SURFACE;
|
EGLSurface eglsurf = EGL_NO_SURFACE;
|
||||||
|
|
||||||
static dllhandle_t egllibrary;
|
static dllhandle_t egllibrary;
|
||||||
static dllhandle_t eslibrary;
|
static dllhandle_t eslibrary;
|
||||||
|
|
||||||
static EGLint (*qeglGetError)(void);
|
static EGLint (*qeglGetError)(void);
|
||||||
|
|
||||||
static EGLDisplay (*qeglGetDisplay)(EGLNativeDisplayType display_id);
|
static EGLDisplay (*qeglGetDisplay)(EGLNativeDisplayType display_id);
|
||||||
static EGLBoolean (*qeglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
static EGLBoolean (*qeglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||||
static EGLBoolean (*qeglTerminate)(EGLDisplay dpy);
|
static EGLBoolean (*qeglTerminate)(EGLDisplay dpy);
|
||||||
|
|
||||||
static EGLBoolean (*qeglGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
static EGLBoolean (*qeglGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||||
static EGLBoolean (*qeglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
static EGLBoolean (*qeglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||||
|
|
||||||
static EGLSurface (*qeglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
|
static EGLSurface (*qeglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
|
||||||
static EGLBoolean (*qeglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
|
static EGLBoolean (*qeglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
|
||||||
static EGLBoolean (*qeglQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
|
static EGLBoolean (*qeglQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
|
||||||
|
|
||||||
static EGLBoolean (*qeglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
|
static EGLBoolean (*qeglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
|
||||||
static EGLBoolean (*qeglMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
static EGLBoolean (*qeglMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
||||||
static EGLContext (*qeglCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
|
static EGLContext (*qeglCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
|
||||||
static EGLBoolean (*qeglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
|
static EGLBoolean (*qeglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
|
||||||
static void *(*qeglGetProcAddress) (char *name);
|
static void *(*qeglGetProcAddress) (char *name);
|
||||||
|
|
||||||
static dllfunction_t qeglfuncs[] =
|
static dllfunction_t qeglfuncs[] =
|
||||||
{
|
{
|
||||||
{(void*)&qeglGetError, "eglGetError"},
|
{(void*)&qeglGetError, "eglGetError"},
|
||||||
|
|
||||||
{(void*)&qeglGetDisplay, "eglGetDisplay"},
|
{(void*)&qeglGetDisplay, "eglGetDisplay"},
|
||||||
{(void*)&qeglInitialize, "eglInitialize"},
|
{(void*)&qeglInitialize, "eglInitialize"},
|
||||||
{(void*)&qeglTerminate, "eglTerminate"},
|
{(void*)&qeglTerminate, "eglTerminate"},
|
||||||
|
|
||||||
{(void*)&qeglGetConfigs, "eglGetConfigs"},
|
{(void*)&qeglGetConfigs, "eglGetConfigs"},
|
||||||
{(void*)&qeglChooseConfig, "eglChooseConfig"},
|
{(void*)&qeglChooseConfig, "eglChooseConfig"},
|
||||||
|
|
||||||
{(void*)&qeglCreateWindowSurface, "eglCreateWindowSurface"},
|
{(void*)&qeglCreateWindowSurface, "eglCreateWindowSurface"},
|
||||||
{(void*)&qeglDestroySurface, "eglDestroySurface"},
|
{(void*)&qeglDestroySurface, "eglDestroySurface"},
|
||||||
{(void*)&qeglQuerySurface, "eglQuerySurface"},
|
{(void*)&qeglQuerySurface, "eglQuerySurface"},
|
||||||
|
|
||||||
{(void*)&qeglSwapBuffers, "eglSwapBuffers"},
|
{(void*)&qeglSwapBuffers, "eglSwapBuffers"},
|
||||||
{(void*)&qeglMakeCurrent, "eglMakeCurrent"},
|
{(void*)&qeglMakeCurrent, "eglMakeCurrent"},
|
||||||
{(void*)&qeglCreateContext, "eglCreateContext"},
|
{(void*)&qeglCreateContext, "eglCreateContext"},
|
||||||
{(void*)&qeglDestroyContext, "eglDestroyContext"},
|
{(void*)&qeglDestroyContext, "eglDestroyContext"},
|
||||||
|
|
||||||
{(void*)&qeglGetProcAddress, "eglGetProcAddress"},
|
{(void*)&qeglGetProcAddress, "eglGetProcAddress"},
|
||||||
|
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void *EGL_Proc(char *f)
|
void *EGL_Proc(char *f)
|
||||||
{
|
{
|
||||||
void *proc = NULL;
|
void *proc = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
char fname[512];
|
char fname[512];
|
||||||
{
|
{
|
||||||
sprintf(fname, "wrap_%s", f);
|
sprintf(fname, "wrap_%s", f);
|
||||||
f = fname;
|
f = fname;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (qeglGetProcAddress)
|
if (qeglGetProcAddress)
|
||||||
proc = qeglGetProcAddress(f);
|
proc = qeglGetProcAddress(f);
|
||||||
if (!proc)
|
if (!proc)
|
||||||
proc = Sys_GetAddressForName(eslibrary, f);
|
proc = Sys_GetAddressForName(eslibrary, f);
|
||||||
if (!proc)
|
if (!proc)
|
||||||
proc = Sys_GetAddressForName(egllibrary, f);
|
proc = Sys_GetAddressForName(egllibrary, f);
|
||||||
|
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EGL_UnloadLibrary(void)
|
void EGL_UnloadLibrary(void)
|
||||||
{
|
{
|
||||||
if (egllibrary)
|
if (egllibrary)
|
||||||
Sys_CloseLibrary(egllibrary);
|
Sys_CloseLibrary(egllibrary);
|
||||||
if (egllibrary == eslibrary)
|
if (egllibrary == eslibrary)
|
||||||
eslibrary = NULL;
|
eslibrary = NULL;
|
||||||
if (eslibrary)
|
if (eslibrary)
|
||||||
Sys_CloseLibrary(eslibrary);
|
Sys_CloseLibrary(eslibrary);
|
||||||
eslibrary = egllibrary = NULL;
|
eslibrary = egllibrary = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean EGL_LoadLibrary(char *driver)
|
qboolean EGL_LoadLibrary(char *driver)
|
||||||
{
|
{
|
||||||
/* apps seem to load glesv2 first for dependency issues */
|
/* apps seem to load glesv2 first for dependency issues */
|
||||||
Sys_Printf("Attempting to dlopen libGLESv2... ");
|
Sys_Printf("Attempting to dlopen libGLESv2... ");
|
||||||
eslibrary = Sys_LoadLibrary("libGLESv2", NULL);
|
eslibrary = Sys_LoadLibrary("libGLESv2", NULL);
|
||||||
if (!eslibrary)
|
if (!eslibrary)
|
||||||
{
|
{
|
||||||
Sys_Printf("failed\n");
|
Sys_Printf("failed\n");
|
||||||
// return false;
|
// return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Sys_Printf("success\n");
|
Sys_Printf("success\n");
|
||||||
if (!eslibrary)
|
if (!eslibrary)
|
||||||
{
|
{
|
||||||
eslibrary = dlopen("libGL", RTLD_NOW|RTLD_GLOBAL);
|
eslibrary = dlopen("libGL", RTLD_NOW|RTLD_GLOBAL);
|
||||||
if (eslibrary) Sys_Printf("Loaded libGL\n");
|
if (eslibrary) Sys_Printf("Loaded libGL\n");
|
||||||
}
|
}
|
||||||
if (!eslibrary)
|
if (!eslibrary)
|
||||||
{
|
{
|
||||||
eslibrary = dlopen("libGL.so.1.2", RTLD_NOW|RTLD_GLOBAL);
|
eslibrary = dlopen("libGL.so.1.2", RTLD_NOW|RTLD_GLOBAL);
|
||||||
if (eslibrary) Sys_Printf("Loaded libGL.so.1.2\n");
|
if (eslibrary) Sys_Printf("Loaded libGL.so.1.2\n");
|
||||||
}
|
}
|
||||||
if (!eslibrary)
|
if (!eslibrary)
|
||||||
{
|
{
|
||||||
eslibrary = dlopen("libGL.so.1", RTLD_NOW|RTLD_GLOBAL);
|
eslibrary = dlopen("libGL.so.1", RTLD_NOW|RTLD_GLOBAL);
|
||||||
if (eslibrary) Sys_Printf("Loaded libGL.so.1\n");
|
if (eslibrary) Sys_Printf("Loaded libGL.so.1\n");
|
||||||
}
|
}
|
||||||
if (!eslibrary)
|
if (!eslibrary)
|
||||||
Sys_Printf("unable to load some libGL\n");
|
Sys_Printf("unable to load some libGL\n");
|
||||||
|
|
||||||
Sys_Printf("Attempting to dlopen libEGL... ");
|
Sys_Printf("Attempting to dlopen libEGL... ");
|
||||||
egllibrary = Sys_LoadLibrary("libEGL", qeglfuncs);
|
egllibrary = Sys_LoadLibrary("libEGL", qeglfuncs);
|
||||||
if (!egllibrary)
|
if (!egllibrary)
|
||||||
{
|
{
|
||||||
Sys_Printf("failed\n");
|
Sys_Printf("failed\n");
|
||||||
Con_Printf("libEGL library not loadable\n");
|
Con_Printf("libEGL library not loadable\n");
|
||||||
/* TODO: some implementations combine EGL/GLESv2 into single library... */
|
/* TODO: some implementations combine EGL/GLESv2 into single library... */
|
||||||
Sys_CloseLibrary(eslibrary);
|
Sys_CloseLibrary(eslibrary);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Sys_Printf("success\n");
|
Sys_Printf("success\n");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EGL_Shutdown(void)
|
void EGL_Shutdown(void)
|
||||||
{
|
{
|
||||||
if (eglctx == EGL_NO_CONTEXT)
|
if (eglctx == EGL_NO_CONTEXT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qeglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
qeglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
qeglDestroyContext(egldpy, eglctx);
|
qeglDestroyContext(egldpy, eglctx);
|
||||||
|
|
||||||
if (eglsurf != EGL_NO_SURFACE)
|
if (eglsurf != EGL_NO_SURFACE)
|
||||||
qeglDestroySurface(egldpy, eglsurf);
|
qeglDestroySurface(egldpy, eglsurf);
|
||||||
|
|
||||||
qeglTerminate(egldpy);
|
qeglTerminate(egldpy);
|
||||||
|
|
||||||
eglctx = EGL_NO_CONTEXT;
|
eglctx = EGL_NO_CONTEXT;
|
||||||
egldpy = EGL_NO_DISPLAY;
|
egldpy = EGL_NO_DISPLAY;
|
||||||
eglsurf = EGL_NO_SURFACE;
|
eglsurf = EGL_NO_SURFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EGL_BeginRendering (void)
|
void EGL_BeginRendering (void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EGL_EndRendering (void)
|
void EGL_EndRendering (void)
|
||||||
{
|
{
|
||||||
qeglSwapBuffers(egldpy, eglsurf);
|
qeglSwapBuffers(egldpy, eglsurf);
|
||||||
/* TODO: check result? */
|
/* TODO: check result? */
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean EGL_Init (rendererstate_t *info, unsigned char *palette, EGLNativeWindowType window, EGLNativeDisplayType dpy)
|
qboolean EGL_Init (rendererstate_t *info, unsigned char *palette, EGLNativeWindowType window, EGLNativeDisplayType dpy)
|
||||||
{
|
{
|
||||||
EGLint numconfig;
|
EGLint numconfig;
|
||||||
EGLConfig cfg;
|
EGLConfig cfg;
|
||||||
EGLint major, minor;
|
EGLint major, minor;
|
||||||
EGLint attrib[] =
|
EGLint attrib[] =
|
||||||
{
|
{
|
||||||
EGL_BUFFER_SIZE, info->bpp,
|
EGL_BUFFER_SIZE, info->bpp,
|
||||||
EGL_SAMPLES, info->multisample,
|
EGL_SAMPLES, info->multisample,
|
||||||
EGL_STENCIL_SIZE, 8,
|
EGL_STENCIL_SIZE, 8,
|
||||||
EGL_ALPHA_MASK_SIZE, 8,
|
EGL_ALPHA_MASK_SIZE, 8,
|
||||||
EGL_DEPTH_SIZE, 16,
|
EGL_DEPTH_SIZE, 16,
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
EGLint contextattr[] =
|
EGLint contextattr[] =
|
||||||
{
|
{
|
||||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||||
EGL_NONE, EGL_NONE
|
EGL_NONE, EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
/* if (!EGL_LoadLibrary(""))
|
/* if (!EGL_LoadLibrary(""))
|
||||||
{
|
{
|
||||||
Con_Printf(CON_ERROR "EGL: unable to load library!\n");
|
Con_Printf(CON_ERROR "EGL: unable to load library!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
egldpy = qeglGetDisplay(dpy);
|
egldpy = qeglGetDisplay(dpy);
|
||||||
if (egldpy == EGL_NO_DISPLAY)
|
if (egldpy == EGL_NO_DISPLAY)
|
||||||
egldpy = qeglGetDisplay(EGL_DEFAULT_DISPLAY);
|
egldpy = qeglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
if (egldpy == EGL_NO_DISPLAY)
|
if (egldpy == EGL_NO_DISPLAY)
|
||||||
{
|
{
|
||||||
Con_Printf(CON_ERROR "EGL: can't get display!\n");
|
Con_Printf(CON_ERROR "EGL: can't get display!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: mesa's egl really loves to crash on this call, and I define crash as 'anything that fails to return to caller', which fucks everything up.
|
//NOTE: mesa's egl really loves to crash on this call, and I define crash as 'anything that fails to return to caller', which fucks everything up.
|
||||||
if (!qeglInitialize(egldpy, &major, &minor))
|
if (!qeglInitialize(egldpy, &major, &minor))
|
||||||
{
|
{
|
||||||
Con_Printf(CON_ERROR "EGL: can't initialize display!");
|
Con_Printf(CON_ERROR "EGL: can't initialize display!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (!qeglGetConfigs(egldpy, NULL, 0, &numconfigs) || !numconfigs)
|
if (!qeglGetConfigs(egldpy, NULL, 0, &numconfigs) || !numconfigs)
|
||||||
{
|
{
|
||||||
Con_Printf(CON_ERROR "EGL: can't get configs!");
|
Con_Printf(CON_ERROR "EGL: can't get configs!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!qeglChooseConfig(egldpy, attrib, &cfg, 1, &numconfig))
|
if (!qeglChooseConfig(egldpy, attrib, &cfg, 1, &numconfig))
|
||||||
{
|
{
|
||||||
Con_Printf(CON_ERROR "EGL: can't choose config!");
|
Con_Printf(CON_ERROR "EGL: can't choose config!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
eglsurf = qeglCreateWindowSurface(egldpy, cfg, window, NULL);
|
eglsurf = qeglCreateWindowSurface(egldpy, cfg, window, NULL);
|
||||||
if (eglsurf == EGL_NO_SURFACE)
|
if (eglsurf == EGL_NO_SURFACE)
|
||||||
{
|
{
|
||||||
Con_Printf(CON_ERROR "EGL: no surface!");
|
Con_Printf(CON_ERROR "EGL: no surface!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
eglctx = qeglCreateContext(egldpy, cfg, EGL_NO_SURFACE, contextattr);
|
eglctx = qeglCreateContext(egldpy, cfg, EGL_NO_SURFACE, contextattr);
|
||||||
if (eglctx == EGL_NO_CONTEXT)
|
if (eglctx == EGL_NO_CONTEXT)
|
||||||
{
|
{
|
||||||
Con_Printf(CON_ERROR "EGL: no context!");
|
Con_Printf(CON_ERROR "EGL: no context!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!qeglMakeCurrent(egldpy, eglsurf, eglsurf, eglctx))
|
if (!qeglMakeCurrent(egldpy, eglsurf, eglsurf, eglctx))
|
||||||
{
|
{
|
||||||
Con_Printf(CON_ERROR "EGL: can't make current!");
|
Con_Printf(CON_ERROR "EGL: can't make current!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -14,5 +14,8 @@
|
||||||
</Description>
|
</Description>
|
||||||
</em:targetApplication>
|
</em:targetApplication>
|
||||||
<em:unpack>true</em:unpack>
|
<em:unpack>true</em:unpack>
|
||||||
|
<em:creator>The FTE Contributors</em:creator>
|
||||||
|
<em:description>Run quake in your browser and stuff!</em:creator>
|
||||||
|
<em:homepageURL>http://fteqw.com/</em:creator>
|
||||||
</Description>
|
</Description>
|
||||||
</RDF>
|
</RDF>
|
||||||
|
|
Loading…
Reference in New Issue