audio on android is now configurable, hopefully.

tweaks to the media decoder's input controls and media plugin decoder stability.
lame basic volumetric fog support. needs improvements.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4115 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-10-08 04:36:10 +00:00
parent e70af9bb9e
commit 63994793c9
34 changed files with 14413 additions and 14028 deletions

View file

@ -844,7 +844,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break; break;
case CG_S_STARTSOUND:// ( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx ) case CG_S_STARTSOUND:// ( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx )
S_StartSound(VM_LONG(arg[1]), VM_LONG(arg[2]), S_PrecacheSound(VM_FROMSTRCACHE(arg[3])), VM_POINTER(arg[0]), 1, 1, 0, 0); S_StartSound(VM_LONG(arg[1])+1, VM_LONG(arg[2]), S_PrecacheSound(VM_FROMSTRCACHE(arg[3])), VM_POINTER(arg[0]), 1, 1, 0, 0);
break; break;
case CG_S_ADDLOOPINGSOUND: case CG_S_ADDLOOPINGSOUND:

View file

@ -3658,7 +3658,8 @@ double Host_Frame (double time)
SV_Frame(); SV_Frame();
RSpeedEnd(RSPEED_SERVER); RSpeedEnd(RSPEED_SERVER);
host_frametime = ohft; host_frametime = ohft;
CL_ReadPackets (); if (cls.protocol != CP_QUAKE3)
CL_ReadPackets (); //q3's cgame cannot cope with input commands with the same time as the most recent snapshot value
} }
#endif #endif
CL_CalcClientTime(); CL_CalcClientTime();

View file

@ -635,6 +635,7 @@ short LerpAngles16(short to, short from, float frac)
void CL_CalcClientTime(void) void CL_CalcClientTime(void)
{ {
if (cls.protocol != CP_QUAKE3)
{ {
float oldst = realtime; float oldst = realtime;

View file

@ -1750,7 +1750,7 @@ void SCR_SetUpToDrawConsole (void)
key_dest = key_console; key_dest = key_console;
scr_conlines = scr_con_current = vid.height * fullscreenpercent; scr_conlines = scr_con_current = vid.height * fullscreenpercent;
} }
else if ((key_dest == key_console || key_dest == key_game) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active) else if ((key_dest == key_console || key_dest == key_game) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen())
{ {
if (cls.state < ca_demostart) if (cls.state < ca_demostart)
key_dest = key_console; key_dest = key_console;

View file

@ -1330,6 +1330,9 @@ qboolean Key_MouseShouldBeFree(void)
return false; return false;
#endif #endif
if (Media_PlayingFullScreen())
return true;
if (cl_prydoncursor.ival) if (cl_prydoncursor.ival)
return true; return true;

View file

@ -264,23 +264,30 @@ static void dlnotification(struct dl_download *dl)
static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m) static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
{ {
package_t *p; package_t *p;
int fl;
p = c->data; p = c->data;
if (p) if (p)
{ {
Draw_FunString (x+4, y, "^Ue080^Ue082"); Draw_FunString (x+4, y, "^Ue080^Ue082");
Draw_FunString (x+24, y, "^Ue080^Ue082");
if (p->flags&DPF_WANTTOINSTALL) fl = p->flags & (DPF_HAVEAVERSION | DPF_WANTTOINSTALL);
Draw_FunString (x+8, y, "^Ue083"); if ((p->flags & (DPF_DOWNLOADING|DPF_ENQUED)) && ((int)(realtime*4)&1))
else fl |= DPF_HAVEAVERSION; //flicker have if we're downloading it.
switch(fl)
{
case 0:
Draw_FunString (x+8, y, "^Ue081"); Draw_FunString (x+8, y, "^Ue081");
break;
//if you have it already case DPF_HAVEAVERSION:
if (p->flags&(DPF_HAVEAVERSION | ((((int)(realtime*4))&1)?(DPF_DOWNLOADING|DPF_ENQUED):0) )) Draw_FunString (x, y, "REM");
Draw_FunString (x+28, y, "^Ue083"); break;
else case DPF_WANTTOINSTALL:
Draw_FunString (x+28, y, "^Ue081"); Draw_FunString (x, y, "GET");
break;
case DPF_HAVEAVERSION | DPF_WANTTOINSTALL:
Draw_FunString (x+8, y, "^Ue083");
break;
}
if (&m->selecteditem->common == &c->common) if (&m->selecteditem->common == &c->common)
Draw_AltFunString (x+48, y, p->name); Draw_AltFunString (x+48, y, p->name);
@ -396,7 +403,7 @@ void M_AddItemsToDownloadMenu(menu_t *m)
int prefixlen; int prefixlen;
p = availablepackages; p = availablepackages;
MC_AddRedText(m, 0, 40, "WntHav", false); // MC_AddRedText(m, 0, 40, "WntHav", false);
prefixlen = strlen(info->pathprefix); prefixlen = strlen(info->pathprefix);
y = 48+4; y = 48+4;

View file

@ -960,7 +960,6 @@ static qboolean qAVIStartup(void)
struct cin_s struct cin_s
{ {
qboolean (*decodeframe)(cin_t *cin, qboolean nosound); qboolean (*decodeframe)(cin_t *cin, qboolean nosound);
void (*doneframe)(cin_t *cin); void (*doneframe)(cin_t *cin);
void (*shutdown)(cin_t *cin); //warning: doesn't free cin_t void (*shutdown)(cin_t *cin); //warning: doesn't free cin_t
@ -1022,6 +1021,8 @@ struct cin_s
void *ctx; void *ctx;
struct plugin_s *plug; struct plugin_s *plug;
media_decoder_funcs_t *funcs; /*fixme*/ media_decoder_funcs_t *funcs; /*fixme*/
struct cin_s *next;
struct cin_s *prev;
} plugin; } plugin;
#endif #endif
@ -1177,6 +1178,9 @@ cin_t *Media_WinAvi_TryLoad(char *name)
PAVIFILE pavi; PAVIFILE pavi;
flocation_t loc; flocation_t loc;
if (strchr(name, ':'))
return NULL;
if (!qAVIStartup()) if (!qAVIStartup())
return NULL; return NULL;
@ -1304,8 +1308,9 @@ cin_t *Media_WinAvi_TryLoad(char *name)
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
//Plugin Support //Plugin Support
#ifdef PLUGINS #ifdef PLUGINS
media_decoder_funcs_t *plugindecodersfunc[8]; static media_decoder_funcs_t *plugindecodersfunc[8];
struct plugin_s *plugindecodersplugin[8]; static struct plugin_s *plugindecodersplugin[8];
static cin_t *active_cin_plugins;
qboolean Media_RegisterDecoder(struct plugin_s *plug, media_decoder_funcs_t *funcs) qboolean Media_RegisterDecoder(struct plugin_s *plug, media_decoder_funcs_t *funcs)
{ {
@ -1321,19 +1326,69 @@ qboolean Media_RegisterDecoder(struct plugin_s *plug, media_decoder_funcs_t *fun
} }
return false; return false;
} }
/*funcs==null closes ALL decoders from this plugin*/
qboolean Media_UnregisterDecoder(struct plugin_s *plug, media_decoder_funcs_t *funcs) qboolean Media_UnregisterDecoder(struct plugin_s *plug, media_decoder_funcs_t *funcs)
{ {
qboolean success = true;
int i; int i;
static media_decoder_funcs_t deadfuncs;
struct plugin_s *oldplug = currentplug;
cin_t *cin, *next;
for (i = 0; i < sizeof(plugindecodersfunc)/sizeof(plugindecodersfunc[0]); i++) for (i = 0; i < sizeof(plugindecodersfunc)/sizeof(plugindecodersfunc[0]); i++)
{ {
if (plugindecodersfunc[i] == funcs || (!funcs && plugindecodersplugin[i] == plug)) if (plugindecodersfunc[i] == funcs || (!funcs && plugindecodersplugin[i] == plug))
{ {
//kill any cinematics currently using that decoder
for (cin = active_cin_plugins; cin; cin = next)
{
next = cin->plugin.next;
if (cin->plugin.plug == plug && cin->plugin.funcs == plugindecodersfunc[i])
{
//we don't kill the engine's side of it, not just yet anyway.
currentplug = cin->plugin.plug;
if (cin->plugin.funcs->shutdown)
cin->plugin.funcs->shutdown(cin->plugin.ctx);
cin->plugin.funcs = &deadfuncs;
cin->plugin.plug = NULL;
cin->plugin.ctx = NULL;
}
}
currentplug = oldplug;
plugindecodersfunc[i] = NULL; plugindecodersfunc[i] = NULL;
plugindecodersplugin[i] = NULL; plugindecodersplugin[i] = NULL;
return true; if (funcs)
return success;
} }
} }
return false;
if (!funcs)
{
static media_decoder_funcs_t deadfuncs;
struct plugin_s *oldplug = currentplug;
cin_t *cin, *next;
for (cin = active_cin_plugins; cin; cin = next)
{
next = cin->plugin.next;
if (cin->plugin.plug == plug)
{
//we don't kill the engine's side of it, not just yet anyway.
currentplug = cin->plugin.plug;
if (cin->plugin.funcs->shutdown)
cin->plugin.funcs->shutdown(cin->plugin.ctx);
cin->plugin.funcs = &deadfuncs;
cin->plugin.plug = NULL;
cin->plugin.ctx = NULL;
}
}
currentplug = oldplug;
}
return success;
} }
static qboolean Media_Plugin_DecodeFrame(cin_t *cin, qboolean nosound) static qboolean Media_Plugin_DecodeFrame(cin_t *cin, qboolean nosound)
@ -1343,6 +1398,8 @@ static qboolean Media_Plugin_DecodeFrame(cin_t *cin, qboolean nosound)
cin->outdata = cin->plugin.funcs->decodeframe(cin->plugin.ctx, nosound, &cin->outtype, &cin->outwidth, &cin->outheight); cin->outdata = cin->plugin.funcs->decodeframe(cin->plugin.ctx, nosound, &cin->outtype, &cin->outwidth, &cin->outheight);
currentplug = oldplug; currentplug = oldplug;
cin->outunchanged = (cin->outdata==NULL);
if (cin->outtype != TF_INVALID) if (cin->outtype != TF_INVALID)
return true; return true;
return false; return false;
@ -1362,6 +1419,13 @@ static void Media_Plugin_Shutdown(cin_t *cin)
if (cin->plugin.funcs->shutdown) if (cin->plugin.funcs->shutdown)
cin->plugin.funcs->shutdown(cin->plugin.ctx); cin->plugin.funcs->shutdown(cin->plugin.ctx);
currentplug = oldplug; currentplug = oldplug;
if (cin->plugin.prev)
cin->plugin.prev->plugin.next = cin->plugin.next;
else
active_cin_plugins = cin->plugin.next;
if (cin->plugin.next)
cin->plugin.next->plugin.prev = cin->plugin.prev;
} }
static void Media_Plugin_Rewind(cin_t *cin) static void Media_Plugin_Rewind(cin_t *cin)
{ {
@ -1443,6 +1507,11 @@ cin_t *Media_Plugin_TryLoad(char *name)
cin->plugin.funcs = funcs; cin->plugin.funcs = funcs;
cin->plugin.plug = plug; cin->plugin.plug = plug;
cin->plugin.ctx = ctx; cin->plugin.ctx = ctx;
cin->plugin.next = active_cin_plugins;
cin->plugin.prev = NULL;
if (cin->plugin.next)
cin->plugin.next->plugin.prev = cin;
active_cin_plugins = cin;
cin->decodeframe = Media_Plugin_DecodeFrame; cin->decodeframe = Media_Plugin_DecodeFrame;
cin->doneframe = Media_Plugin_DoneFrame; cin->doneframe = Media_Plugin_DoneFrame;
cin->shutdown = Media_Plugin_Shutdown; cin->shutdown = Media_Plugin_Shutdown;
@ -1587,6 +1656,9 @@ cin_t *Media_RoQ_TryLoad(char *name)
{ {
cin_t *cin; cin_t *cin;
roq_info *roqfilm; roq_info *roqfilm;
if (strchr(name, ':'))
return NULL;
if ((roqfilm = roq_open(name))) if ((roqfilm = roq_open(name)))
{ {
cin = Z_Malloc(sizeof(cin_t)); cin = Z_Malloc(sizeof(cin_t));
@ -2166,6 +2238,8 @@ qboolean Media_ShowFilm(void)
extern int mousecursor_x, mousecursor_y; extern int mousecursor_x, mousecursor_y;
cin->cursormove(cin, mousecursor_x/(float)vid.width, mousecursor_y/(float)vid.height); cin->cursormove(cin, mousecursor_x/(float)vid.width, mousecursor_y/(float)vid.height);
} }
if (cin->setsize)
cin->setsize(cin, vid.pixelwidth, vid.pixelheight);
// GL_Set2D (false); // GL_Set2D (false);
R2D_ImageColours(1, 1, 1, 1); R2D_ImageColours(1, 1, 1, 1);

View file

@ -355,7 +355,7 @@ void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_
float r, g, b; float r, g, b;
conchar_t buffer[2048], *str; conchar_t buffer[2048], *str;
float px, py; float px, py, ipx;
if (*prinst->callargc >= 6) if (*prinst->callargc >= 6)
{ {
@ -384,9 +384,15 @@ void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_
str = buffer; str = buffer;
Font_BeginScaledString(font_conchar, pos[0], pos[1], &px, &py); Font_BeginScaledString(font_conchar, pos[0], pos[1], &px, &py);
ipx = px;
Font_ForceColour(r, g, b, alpha); Font_ForceColour(r, g, b, alpha);
while(*str) while(*str)
{ {
if ((*str & CON_CHARMASK) == '\n')
py += Font_CharHeight();
else if ((*str & CON_CHARMASK) == '\r')
px = ipx;
else
px = Font_DrawScaleChar(px, py, size[0], size[1], *str++); px = Font_DrawScaleChar(px, py, size[0], size[1], *str++);
} }
Font_InvalidateColour(); Font_InvalidateColour();

View file

@ -2184,33 +2184,47 @@ void S_PlayVol(void)
void S_SoundList_f(void) void S_SoundList_f(void)
{ {
/*
int i; int i;
sfx_t *sfx; sfx_t *sfx;
sfxcache_t *sc; sfxcache_t *sc;
sfxcache_t scachebuf;
int size, total; int size, total;
int duration;
S_LockMixer();
total = 0; total = 0;
for (sfx=known_sfx, i=0 ; i<num_sfx ; i++, sfx++) for (sfx=known_sfx, i=0 ; i<num_sfx ; i++, sfx++)
{ {
if (!sfx->decoder) if (sfx->decoder.decodedata)
{
sc = sfx->decoder.decodedata(sfx, &scachebuf, 0, 0x0fffffff);
if (!sc)
{ {
Con_Printf("S( ) : %s\n", sfx->name); Con_Printf("S( ) : %s\n", sfx->name);
continue; continue;
} }
sc = Cache_Check (&sfx->cache); }
else
sc = sfx->decoder.buf;
if (!sc) if (!sc)
{
Con_Printf("?( ) : %s\n", sfx->name);
continue; continue;
size = sc->length*sc->width*(sc->numchannels); }
size = (sc->soundoffset+sc->length)*sc->width*(sc->numchannels);
duration = (sc->soundoffset+sc->length) / sc->speed;
total += size; total += size;
if (sc->loopstart >= 0) if (sc->loopstart >= 0)
Con_Printf ("L"); Con_Printf ("L");
else else
Con_Printf (" "); Con_Printf (" ");
Con_Printf("(%2db%2ic) %6i : %s\n",sc->width*8, sc->numchannels, size, sfx->name); Con_Printf("(%2db%2ic) %6i %2is : %s\n",sc->width*8, sc->numchannels, size, duration, sfx->name);
} }
Con_Printf ("Total resident: %i\n", total); Con_Printf ("Total resident: %i\n", total);
*/
S_UnlockMixer();
} }

View file

@ -8,8 +8,24 @@ java code has a function or two which just periodically calls us to ask us to du
//static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static soundcardinfo_t *sys_sc = NULL; static soundcardinfo_t *sys_sc = NULL;
extern int sys_soundflags;
JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_audioinfo(JNIEnv *env, jclass this, jint arg)
{
soundcardinfo_t *sc = sys_sc;
if (!sc)
return 0;
switch(arg)
{
case 1:
return sc->sn.numchannels;
case 2:
return sc->sn.samplebits;
default:
return sc->sn.speed;
}
}
//transfer the 'dma' buffer into the buffer it requests, called from a dedicated sound thread created by the java code. //transfer the 'dma' buffer into the buffer it requests, called from a dedicated sound thread created by the java code.
JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_paintaudio(JNIEnv *env, jclass this, jbyteArray stream, jint len) JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_paintaudio(JNIEnv *env, jclass this, jbyteArray stream, jint len)
@ -61,6 +77,7 @@ static void Droid_Shutdown(soundcardinfo_t *sc)
sys_sc = NULL; sys_sc = NULL;
free(sc->sn.buffer); free(sc->sn.buffer);
sys_soundflags = 0;
// pthread_mutex_unlock(&mutex); // pthread_mutex_unlock(&mutex);
} }
@ -90,6 +107,10 @@ static void Droid_Submit(soundcardinfo_t *sc, int start, int end)
{ {
} }
//on android, 16bit audio is 'guarenteed'.
//8bit is not guarenteed.
//there's no reference to sample rates. I assume 44.1khz will always work, though we want to avoid that cpu+mem load if we can
//nor any guarentee about channels supported. I assume mono will always work.
static int Droid_InitCard (soundcardinfo_t *sc, int cardnum) static int Droid_InitCard (soundcardinfo_t *sc, int cardnum)
{ {
if (sys_sc) if (sys_sc)
@ -98,9 +119,10 @@ static int Droid_InitCard (soundcardinfo_t *sc, int cardnum)
// if (!pthread_mutex_lock(&mutex)) // if (!pthread_mutex_lock(&mutex))
{ {
sc->selfpainting = true; sc->selfpainting = true;
sc->sn.speed = 11025; // sc->sn.speed = 11025;
sc->sn.samplebits = 16; // sc->sn.samplebits = 16;
sc->sn.numchannels = 1; // sc->sn.numchannels = 1;
/*internal buffer should have 1 sec audio*/ /*internal buffer should have 1 sec audio*/
sc->sn.samples = sc->sn.speed*sc->sn.numchannels; sc->sn.samples = sc->sn.speed*sc->sn.numchannels;
@ -115,6 +137,8 @@ static int Droid_InitCard (soundcardinfo_t *sc, int cardnum)
sys_sc = sc; sys_sc = sc;
sys_soundflags = 3;
// pthread_mutex_unlock(&mutex); // pthread_mutex_unlock(&mutex);
return 1; return 1;

View file

@ -125,8 +125,6 @@ sfxcache_t *OV_DecodeSome(struct sfx_s *sfx, struct sfxcache_s *buf, int start,
start *= 2*dec->srcchannels; start *= 2*dec->srcchannels;
length *= 2*dec->srcchannels; length *= 2*dec->srcchannels;
for (;;)
{
if (start < dec->decodedbytestart) if (start < dec->decodedbytestart)
{ {
/*something rewound, purge clear the buffer*/ /*something rewound, purge clear the buffer*/
@ -137,21 +135,31 @@ sfxcache_t *OV_DecodeSome(struct sfx_s *sfx, struct sfxcache_s *buf, int start,
p_ov_pcm_seek(&dec->vf, dec->decodedbytestart); p_ov_pcm_seek(&dec->vf, dec->decodedbytestart);
} }
if (start+length <= dec->decodedbytestart + dec->decodedbytecount)
break;
if (dec->decodedbytecount > snd_speed*8) if (dec->decodedbytecount > snd_speed*8)
{ {
/*everything is okay, but our buffer is getting needlessly large. /*everything is okay, but our buffer is getting needlessly large.
keep anything after the 'new' position, but discard all before that keep anything after the 'new' position, but discard all before that
trim shouldn't be able to go negative trim shouldn't be able to go negative
*/ */
unsigned int trim = start - dec->decodedbytestart; int trim = start - dec->decodedbytestart;
if (trim < 0)
{
dec->decodedbytecount = 0;
dec->decodedbytestart = start;
}
else
{
//FIXME: retain an extra half-second for dual+ sound devices running slightly out of sync //FIXME: retain an extra half-second for dual+ sound devices running slightly out of sync
memmove(dec->decodedbuffer, dec->decodedbuffer + trim, dec->decodedbytecount - trim); memmove(dec->decodedbuffer, dec->decodedbuffer + trim, dec->decodedbytecount - trim);
dec->decodedbytecount -= trim; dec->decodedbytecount -= trim;
dec->decodedbytestart += trim; dec->decodedbytestart += trim;
} }
}
for (;;)
{
if (start+length <= dec->decodedbytestart + dec->decodedbytecount)
break;
if (dec->decodedbufferbytes < start+length - dec->decodedbytestart + 128) //expand if needed. if (dec->decodedbufferbytes < start+length - dec->decodedbytestart + 128) //expand if needed.
{ {

View file

@ -20,6 +20,7 @@ qboolean isDedicated = false;
void *sys_window; /*public so the renderer can attach to the correct place*/ void *sys_window; /*public so the renderer can attach to the correct place*/
static int sys_running = false; static int sys_running = false;
int sys_glesversion; int sys_glesversion;
int sys_soundflags; /*1 means active. 2 means reset (so claim that its not active for one frame to force a reset)*/
static void *sys_memheap; static void *sys_memheap;
static unsigned int sys_lastframe; static unsigned int sys_lastframe;
static unsigned int vibrateduration; static unsigned int vibrateduration;
@ -98,6 +99,13 @@ JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject
ret |= 8; ret |= 8;
if (sys_orientation.modified) if (sys_orientation.modified)
ret |= 16; ret |= 16;
if (sys_soundflags)
{
if (sys_soundflags & 2)
sys_soundflags &= ~2;
else
ret |= 32;
}
return ret; return ret;
} }

View file

@ -119,6 +119,7 @@ dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
} }
if (funcs[i].name) if (funcs[i].name)
{ {
Con_DPrintf("Missing export \"%s\" in \"%s\"\n", funcs[i].name, name);
Sys_CloseLibrary((dllhandle_t*)lib); Sys_CloseLibrary((dllhandle_t*)lib);
lib = NULL; lib = NULL;
} }

View file

@ -2328,7 +2328,7 @@ mfog_t *CM_FogForOrigin(vec3_t org)
int i, j; int i, j;
mfog_t *ret = map_fogs; mfog_t *ret = map_fogs;
float dot; float dot;
if (!cl.worldmodel || cl.worldmodel->fromgame != fg_quake3) if (!map_numfogs || !cl.worldmodel || cl.worldmodel->fromgame != fg_quake3)
return NULL; return NULL;
for ( i=0 ; i<map_numfogs ; i++, ret++) for ( i=0 ; i<map_numfogs ; i++, ret++)

View file

@ -136,6 +136,7 @@ typedef struct plugin_s {
int svmsgfunction; int svmsgfunction;
int chatmsgfunction; int chatmsgfunction;
int centerprintfunction; int centerprintfunction;
int shutdown;
struct plugin_s *next; struct plugin_s *next;
} plugin_t; } plugin_t;
@ -379,6 +380,8 @@ qintptr_t VARGS Plug_ExportToEngine(void *offset, quintptr_t mask, const qintptr
currentplug->tick = functionid; currentplug->tick = functionid;
else if (!strcmp(name, "ExecuteCommand")) else if (!strcmp(name, "ExecuteCommand"))
currentplug->executestring = functionid; currentplug->executestring = functionid;
else if (!strcmp(name, "Shutdown"))
currentplug->shutdown = functionid;
#ifndef SERVERONLY #ifndef SERVERONLY
else if (!strcmp(name, "ConExecuteCommand")) else if (!strcmp(name, "ConExecuteCommand"))
currentplug->conexecutecommand = functionid; currentplug->conexecutecommand = functionid;
@ -1807,6 +1810,11 @@ void Plug_Close(plugin_t *plug)
} }
Con_Printf("Closing plugin %s\n", plug->name); Con_Printf("Closing plugin %s\n", plug->name);
#if defined(PLUGINS) && !defined(NOMEDIA) && !defined(SERVERONLY)
Media_UnregisterDecoder(plug, NULL);
#endif
if (plug->shutdown)
VM_Call(plug->vm, plug->shutdown);
VM_Destroy(plug->vm); VM_Destroy(plug->vm);
Plug_FreeConCommands(plug); Plug_FreeConCommands(plug);

View file

@ -425,6 +425,67 @@ void QCBUILTIN PF_getsurfacetriangle(progfuncs_t *prinst, struct globalvars_s *p
G_FLOAT(OFS_RETURN+2) = 0; G_FLOAT(OFS_RETURN+2) = 0;
} }
//vector(entity e, float s, float n, float a) getsurfacepointattribute
void QCBUILTIN PF_getsurfacepointattribute(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
wedict_t *ent = G_WEDICT(prinst, OFS_PARM0);
unsigned int surfnum = G_FLOAT(OFS_PARM1);
unsigned int pointnum = G_FLOAT(OFS_PARM2);
unsigned int attribute = G_FLOAT(OFS_PARM3);
world_t *w = prinst->parms->user;
model_t *model = w->Get_CModel(w, ent->v->modelindex);
G_FLOAT(OFS_RETURN+0) = 0;
G_FLOAT(OFS_RETURN+1) = 0;
G_FLOAT(OFS_RETURN+2) = 0;
if (model && model->type == mod_brush && surfnum < model->nummodelsurfaces)
{
surfnum += model->firstmodelsurface;
if (pointnum < model->surfaces[surfnum].mesh->numvertexes)
{
switch(attribute)
{
case 0:
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->xyz_array[pointnum][0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->xyz_array[pointnum][1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->xyz_array[pointnum][2];
break;
case 1:
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->snormals_array[pointnum][0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->snormals_array[pointnum][1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->snormals_array[pointnum][2];
break;
case 2:
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->tnormals_array[pointnum][0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->tnormals_array[pointnum][1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->tnormals_array[pointnum][2];
break;
case 3:
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->normals_array[pointnum][0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->normals_array[pointnum][1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->normals_array[pointnum][2];
break;
case 4:
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->st_array[pointnum][0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->st_array[pointnum][1];
G_FLOAT(OFS_RETURN+2) = 0;
break;
case 5:
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->lmst_array[0][pointnum][0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->lmst_array[0][pointnum][1];
G_FLOAT(OFS_RETURN+2) = 0;
break;
case 6:
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->colors4f_array[pointnum][0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->colors4f_array[pointnum][1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->colors4f_array[pointnum][2];
//no way to return alpha here.
break;
}
}
}
}
#ifndef TERRAIN #ifndef TERRAIN
void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {

View file

@ -52,7 +52,6 @@ struct wedict_s
#define PF_gecko_get_texture_extent PF_Fixme #define PF_gecko_get_texture_extent PF_Fixme
#define PF_pointsound PF_Fixme #define PF_pointsound PF_Fixme
#define PF_getsurfacepointattribute PF_Fixme
#define PF_gecko_mousemove PF_Fixme #define PF_gecko_mousemove PF_Fixme
#define PF_numentityfields PF_Fixme #define PF_numentityfields PF_Fixme
#define PF_entityfieldname PF_Fixme #define PF_entityfieldname PF_Fixme
@ -190,6 +189,7 @@ void QCBUILTIN PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s *
void QCBUILTIN PF_getsurfaceclippedpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_getsurfaceclippedpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfacenumtriangles(progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_getsurfacenumtriangles(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfacetriangle(progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_getsurfacetriangle(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfacepointattribute(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_skel_mmap(progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_skel_mmap(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_skel_ragedit(progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_skel_ragedit(progfuncs_t *prinst, struct globalvars_s *pr_globals);

View file

@ -26,6 +26,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nacl", "..\nacl\nacl.vcproj
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xsv", "..\..\plugins\xsv\xsv.vcproj", "{873CCE24-3549-49D4-A4B4-653F91B1532A}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xsv", "..\..\plugins\xsv\xsv.vcproj", "{873CCE24-3549-49D4-A4B4-653F91B1532A}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "berkelium", "..\..\plugins\berkelium\berkelium.vcproj", "{4877586B-E85B-4DF8-BCCE-59D31514D240}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
D3DDebug|Win32 = D3DDebug|Win32 D3DDebug|Win32 = D3DDebug|Win32
@ -130,45 +132,39 @@ Global
{F384725A-62D4-4063-9941-6D8D2D6C2A47}.Release|Win32.ActiveCfg = Release Dedicated Server_SDL|x64 {F384725A-62D4-4063-9941-6D8D2D6C2A47}.Release|Win32.ActiveCfg = Release Dedicated Server_SDL|x64
{F384725A-62D4-4063-9941-6D8D2D6C2A47}.Release|x64.ActiveCfg = Release Dedicated Server_SDL|x64 {F384725A-62D4-4063-9941-6D8D2D6C2A47}.Release|x64.ActiveCfg = Release Dedicated Server_SDL|x64
{F384725A-62D4-4063-9941-6D8D2D6C2A47}.Release|x64.Build.0 = Release Dedicated Server_SDL|x64 {F384725A-62D4-4063-9941-6D8D2D6C2A47}.Release|x64.Build.0 = Release Dedicated Server_SDL|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|Win32.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|Win32.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|Win32.Build.0 = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|x64.Build.0 = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DRelease|Win32.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DRelease|Win32.ActiveCfg = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DRelease|x64.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DRelease|x64.ActiveCfg = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|Win32.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|Win32.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|Win32.Build.0 = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|x64.Build.0 = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.Build.0 = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|x64.ActiveCfg = GLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|x64.Build.0 = GLDebug|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|Win32.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|x64.ActiveCfg = GLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|x64.Build.0 = GLDebug|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|Win32.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|Win32.ActiveCfg = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|x64.ActiveCfg = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|x64.Build.0 = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MDebug|Win32.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MDebug|Win32.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MDebug|Win32.Build.0 = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MDebug|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MDebug|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MDebug|x64.Build.0 = GLRelease|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|Win32.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|Win32.Build.0 = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|x64.ActiveCfg = GLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|x64.Build.0 = GLDebug|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|Win32.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|Win32.ActiveCfg = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|Win32.Build.0 = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|Win32.Build.0 = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|x64.ActiveCfg = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|x64.Build.0 = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MRelease|Win32.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MRelease|Win32.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MRelease|Win32.Build.0 = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MRelease|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MRelease|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MRelease|x64.Build.0 = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release Dedicated Server|Win32.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release Dedicated Server|Win32.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release Dedicated Server|Win32.Build.0 = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release Dedicated Server|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release Dedicated Server|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release Dedicated Server|x64.Build.0 = GLRelease|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|Win32.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|Win32.ActiveCfg = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|Win32.Build.0 = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|Win32.Build.0 = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|x64.Build.0 = GLRelease|x64
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|Win32.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|Win32.ActiveCfg = Debug
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|x64.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|x64.ActiveCfg = Debug
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DRelease|Win32.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DRelease|Win32.ActiveCfg = Release
@ -380,6 +376,42 @@ Global
{873CCE24-3549-49D4-A4B4-653F91B1532A}.Release|Win32.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Release|Win32.ActiveCfg = Release|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.Release|Win32.Build.0 = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Release|Win32.Build.0 = Release|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.Release|x64.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Release|x64.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DDebug|Win32.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DDebug|Win32.Build.0 = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DDebug|x64.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DRelease|Win32.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DRelease|Win32.Build.0 = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DRelease|x64.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|Win32.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|Win32.Build.0 = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|x64.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|Win32.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|Win32.Build.0 = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|x64.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLRelease|Win32.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLRelease|Win32.Build.0 = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLRelease|x64.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MDebug|Win32.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MDebug|Win32.Build.0 = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MDebug|x64.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLDebug|Win32.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLDebug|Win32.Build.0 = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLDebug|x64.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLRelease|Win32.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLRelease|Win32.Build.0 = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLRelease|x64.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MRelease|Win32.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MRelease|Win32.Build.0 = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.MRelease|x64.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Release Dedicated Server|Win32.Build.0 = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Release Dedicated Server|x64.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|Win32.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|Win32.Build.0 = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

File diff suppressed because it is too large Load diff

View file

@ -204,6 +204,13 @@ public class FTEDroidActivity extends Activity
}; };
act.runOnUiThread(r); act.runOnUiThread(r);
} }
if (((flags ^ notifiedflags) & 32) != 0)
{
if ((flags & 32) != 0)
view.audioInit(FTEDroidEngine.audioinfo(0), FTEDroidEngine.audioinfo(1), FTEDroidEngine.audioinfo(2));
else
view.audioStop();
}
//clear anything which is an impulse //clear anything which is an impulse
notifiedflags = flags; notifiedflags = flags;
@ -319,25 +326,38 @@ public class FTEDroidActivity extends Activity
private class audiothreadclass extends Thread private class audiothreadclass extends Thread
{ {
boolean timetodie; boolean timetodie;
int schannels;
int sspeed;
int sbits;
@Override @Override
public void run() public void run()
{ {
byte[] audbuf = new byte[2048]; byte[] audbuf = new byte[2048];
int avail; int avail;
int sspeed = 11025; int chans;
int speakers = 1; if (schannels >= 8) //the OUT enumeration allows specific speaker control. but also api level 5+
int sz = 2*AudioTrack.getMinBufferSize(sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT); chans = AudioFormat.CHANNEL_OUT_7POINT1;
else if (schannels >= 6)
chans = AudioFormat.CHANNEL_OUT_5POINT1;
else if (schannels >= 4)
chans = AudioFormat.CHANNEL_OUT_QUAD;
else if (schannels >= 2)
chans = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
else
chans = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int enc = (sbits == 8)?AudioFormat.ENCODING_PCM_8BIT:AudioFormat.ENCODING_PCM_16BIT;
int sz = 2*AudioTrack.getMinBufferSize(sspeed, chans, enc);
// if (sz < sspeed * 0.05) // if (sz < sspeed * 0.05)
// sz = sspeed * 0.05; // sz = sspeed * 0.05;
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT, sz, AudioTrack.MODE_STREAM); AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, chans, enc, sz, AudioTrack.MODE_STREAM);
at.setStereoVolume(1, 1); at.setStereoVolume(1, 1);
at.play(); at.play();
while(!timetodie) while(!timetodie)
{ {
avail = FTEDroidEngine.paintaudio(audbuf, audbuf.length); avail = FTEDroidEngine.paintaudio(audbuf, audbuf.length);
@ -356,14 +376,18 @@ public class FTEDroidActivity extends Activity
catch(InterruptedException e) catch(InterruptedException e)
{ {
} }
timetodie = false;
} }
}; };
private void audioInit() private void audioInit(int sspeed, int schannels, int sbits)
{ {
if (audiothread == null) if (audiothread == null)
{ {
audiothread = new audiothreadclass(); audiothread = new audiothreadclass();
audiothread.schannels = schannels;
audiothread.sspeed = sspeed;
audiothread.sbits = sbits;
audiothread.start(); audiothread.start();
} }
} }
@ -377,8 +401,11 @@ public class FTEDroidActivity extends Activity
} }
public void audioResume() public void audioResume()
{ {
audioStop(); if (audiothread != null)
audioInit(); {
audiothread.killoff();
audiothread.start();
}
} }
private FTELegacyInputEvent inputevent; private FTELegacyInputEvent inputevent;
@ -499,10 +526,6 @@ public class FTEDroidActivity extends Activity
setRenderer(rndr); setRenderer(rndr);
setFocusable(true); setFocusable(true);
setFocusableInTouchMode(true); setFocusableInTouchMode(true);
android.util.Log.i("FTEDroid", "starting audio");
audioInit();
android.util.Log.i("FTEDroid", "audio running");
} }
private void sendKey(final boolean presseddown, final int qcode, final int unicode) private void sendKey(final boolean presseddown, final int qcode, final int unicode)

View file

@ -8,6 +8,7 @@ public class FTEDroidEngine
public static native void keypress(int down, int qkey, int unicode); public static native void keypress(int down, int qkey, int unicode);
public static native void motion(int act, int pointerid, float x, float y, float size); public static native void motion(int act, int pointerid, float x, float y, float size);
public static native int paintaudio(byte[] stream, int len); public static native int paintaudio(byte[] stream, int len);
public static native int audioinfo(int arg);
public static native String geterrormessage(); public static native String geterrormessage();
public static native String getpreferedorientation(); public static native String getpreferedorientation();
public static native void newglcontext(); public static native void newglcontext();

View file

@ -1014,6 +1014,7 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
b->buildmeshes = R_GAlias_DrawBatch; b->buildmeshes = R_GAlias_DrawBatch;
b->ent = e; b->ent = e;
b->fog = CM_FogForOrigin(e->origin);
b->mesh = NULL; b->mesh = NULL;
b->firstmesh = 0; b->firstmesh = 0;
b->meshes = 1; b->meshes = 1;
@ -1770,6 +1771,13 @@ static void R_DB_Sprite(batch_t *batch)
Vector4Copy(e->shaderRGBAf, colours[2]); Vector4Copy(e->shaderRGBAf, colours[2]);
Vector4Copy(e->shaderRGBAf, colours[3]); Vector4Copy(e->shaderRGBAf, colours[3]);
VectorSubtract(sprorigin, e->origin, sprorigin);
if (!e->scale)
e->scale = 1;
VectorSet(e->axis[0], 1/e->scale, 0, 0);
VectorSet(e->axis[1], 0, 1/e->scale, 0);
VectorSet(e->axis[2], 0, 0, 1/e->scale);
VectorMA (sprorigin, frame->down, spraxis[2], point); VectorMA (sprorigin, frame->down, spraxis[2], point);
VectorMA (point, frame->left, spraxis[1], vertcoords[0]); VectorMA (point, frame->left, spraxis[1], vertcoords[0]);
@ -1782,7 +1790,6 @@ static void R_DB_Sprite(batch_t *batch)
VectorMA (sprorigin, frame->down, spraxis[2], point); VectorMA (sprorigin, frame->down, spraxis[2], point);
VectorMA (point, frame->right, spraxis[1], vertcoords[3]); VectorMA (point, frame->right, spraxis[1], vertcoords[3]);
batch->ent = &r_worldentity;
batch->mesh = &meshptr; batch->mesh = &meshptr;
memset(&mesh, 0, sizeof(mesh)); memset(&mesh, 0, sizeof(mesh));
@ -1856,6 +1863,7 @@ static void R_Sprite_GenerateBatch(entity_t *e, batch_t **batches, void (*drawfu
b->buildmeshes = drawfunc; b->buildmeshes = drawfunc;
b->ent = e; b->ent = e;
b->fog = CM_FogForOrigin(e->origin);
b->mesh = NULL; b->mesh = NULL;
b->firstmesh = 0; b->firstmesh = 0;
b->meshes = 1; b->meshes = 1;

View file

@ -90,6 +90,14 @@ static const char PCFPASS_SHADER[] = "\
}"; }";
enum
{
LSHADER_STANDARD,
LSHADER_CUBE,
LSHADER_SMAP,
LSHADER_SPOT,
LSHADER_MODES
};
extern cvar_t r_glsl_offsetmapping, r_noportals; extern cvar_t r_glsl_offsetmapping, r_noportals;
@ -105,7 +113,9 @@ struct {
// int vbo_texcoords[SHADER_PASS_MAX]; // int vbo_texcoords[SHADER_PASS_MAX];
// int vbo_deforms; //holds verticies... in case you didn't realise. // int vbo_deforms; //holds verticies... in case you didn't realise.
qboolean inited_shader_rtlight; const shader_t *shader_light[LSHADER_MODES];
qboolean inited_shader_light[LSHADER_MODES];
/* qboolean inited_shader_rtlight;
const shader_t *shader_rtlight; const shader_t *shader_rtlight;
qboolean inited_shader_cubeproj; qboolean inited_shader_cubeproj;
const shader_t *shader_cubeproj; const shader_t *shader_cubeproj;
@ -113,7 +123,7 @@ struct {
const shader_t *shader_smap; const shader_t *shader_smap;
qboolean inited_shader_spot; qboolean inited_shader_spot;
const shader_t *shader_spot; const shader_t *shader_spot;
*/
const shader_t *crepskyshader; const shader_t *crepskyshader;
const shader_t *crepopaqueshader; const shader_t *crepopaqueshader;
@ -193,10 +203,12 @@ struct {
const entity_t *curentity; const entity_t *curentity;
const batch_t *curbatch; const batch_t *curbatch;
const texnums_t *curtexnums; const texnums_t *curtexnums;
const mfog_t *fog;
float curtime; float curtime;
float updatetime; float updatetime;
int lightmode;
vec3_t lightorg; vec3_t lightorg;
vec3_t lightcolours; vec3_t lightcolours;
vec3_t lightcolourscale; vec3_t lightcolourscale;
@ -1165,6 +1177,12 @@ void GenerateFogTexture(texid_t *tex, float density, float zscale)
byte_vec4_t fogdata[FOGS*FOGT]; byte_vec4_t fogdata[FOGS*FOGT];
int s, t; int s, t;
float f, z; float f, z;
static float fogdensity, fogzscale;
if (TEXVALID(*tex) && density == fogdensity && zscale == fogzscale)
return;
fogdensity = density;
fogzscale = zscale;
for(s = 0; s < FOGS; s++) for(s = 0; s < FOGS; s++)
for(t = 0; t < FOGT; t++) for(t = 0; t < FOGT; t++)
{ {
@ -1172,7 +1190,7 @@ void GenerateFogTexture(texid_t *tex, float density, float zscale)
z *= zscale; z *= zscale;
if (0)//q3 if (0)//q3
f = pow(f, 0.5); f = pow(z, 0.5);
else if (1)//GL_EXP else if (1)//GL_EXP
f = 1-exp(-density * z); f = 1-exp(-density * z);
else //GL_EXP2 else //GL_EXP2
@ -1239,6 +1257,7 @@ void GLBE_Init(void)
for (i = 0; i < MAXLIGHTMAPS; i++) for (i = 0; i < MAXLIGHTMAPS; i++)
shaderstate.dummybatch.lightmap[i] = -1; shaderstate.dummybatch.lightmap[i] = -1;
#if FIXME
/*normally we load these lazily, but if they're probably going to be used anyway, load them now to avoid stalls.*/ /*normally we load these lazily, but if they're probably going to be used anyway, load them now to avoid stalls.*/
if (r_shadow_realtime_dlight.ival && !shaderstate.inited_shader_rtlight && gl_config.arb_shader_objects) if (r_shadow_realtime_dlight.ival && !shaderstate.inited_shader_rtlight && gl_config.arb_shader_objects)
{ {
@ -1250,6 +1269,7 @@ void GLBE_Init(void)
shaderstate.inited_shader_cubeproj = true; shaderstate.inited_shader_cubeproj = true;
shaderstate.shader_cubeproj = R_RegisterCustom("rtlight_cubeproj", Shader_LightPass_CubeProj, NULL); shaderstate.shader_cubeproj = R_RegisterCustom("rtlight_cubeproj", Shader_LightPass_CubeProj, NULL);
} }
#endif
gl_overbright.modified = true; /*in case the d3d renderer does the same*/ gl_overbright.modified = true; /*in case the d3d renderer does the same*/
/*lock the cvar down if the backend can't actually do it*/ /*lock the cvar down if the backend can't actually do it*/
@ -1311,7 +1331,7 @@ static void tcgen_environment(float *st, unsigned int numverts, float *xyz, floa
} }
} }
static void tcgen_fog(float *st, unsigned int numverts, float *xyz) static void tcgen_fog(float *st, unsigned int numverts, float *xyz, mfog_t *fog)
{ {
int i; int i;
@ -1359,9 +1379,6 @@ static float *tcgen(unsigned int tcgen, int cnt, float *dst, const mesh_t *mesh)
return (float*)mesh->st_array; return (float*)mesh->st_array;
tcgen_environment(dst, cnt, (float*)mesh->xyz_array, (float*)mesh->normals_array); tcgen_environment(dst, cnt, (float*)mesh->xyz_array, (float*)mesh->normals_array);
return dst; return dst;
case TC_GEN_FOG:
tcgen_fog(dst, cnt, (float*)mesh->xyz_array);
return dst;
// case TC_GEN_DOTPRODUCT: // case TC_GEN_DOTPRODUCT:
// return mesh->st_array[0]; // return mesh->st_array[0];
@ -1464,23 +1481,17 @@ static void tcmod(const tcmod_t *tcmod, int cnt, const float *src, float *dst, c
} }
} }
static void GenerateTCFog(int passnum) static void GenerateTCFog(int passnum, mfog_t *fog)
{ {
int m; int m;
float *src;
mesh_t *mesh; mesh_t *mesh;
for (m = 0; m < shaderstate.meshcount; m++) for (m = 0; m < shaderstate.meshcount; m++)
{ {
mesh = shaderstate.meshes[m]; mesh = shaderstate.meshes[m];
tcgen_fog(texcoordarray[passnum]+mesh->vbofirstvert*2, mesh->numvertexes, (float*)mesh->xyz_array, fog);
src = tcgen(TC_GEN_FOG, mesh->numvertexes, texcoordarray[passnum]+mesh->vbofirstvert*2, mesh);
if (src != texcoordarray[passnum]+mesh->vbofirstvert*2)
{
//this shouldn't actually ever be true
memcpy(texcoordarray[passnum]+mesh->vbofirstvert*2, src, 8*mesh->numvertexes);
}
} }
GL_SelectVBO(0); GL_SelectVBO(0);
qglClientActiveTextureARB(mtexid0 + passnum);
qglTexCoordPointer(2, GL_FLOAT, 0, texcoordarray[passnum]); qglTexCoordPointer(2, GL_FLOAT, 0, texcoordarray[passnum]);
} }
static void GenerateTCMods(const shaderpass_t *pass, int passnum) static void GenerateTCMods(const shaderpass_t *pass, int passnum)
@ -3088,36 +3099,6 @@ void GLBE_SelectMode(backendmode_t mode)
//don't actually change stencil stuff - caller needs to be //don't actually change stencil stuff - caller needs to be
//aware of how many times stuff is drawn, so they can do that themselves. //aware of how many times stuff is drawn, so they can do that themselves.
break; break;
case BEM_SMAPLIGHT:
if (!shaderstate.inited_shader_smap)
{
shaderstate.inited_shader_smap = true;
shaderstate.shader_smap = R_RegisterCustom("rtlight_shadowmap", Shader_LightPass_PCF, NULL);
}
break;
case BEM_SMAPLIGHTSPOT:
if (!shaderstate.inited_shader_spot)
{
shaderstate.inited_shader_spot = true;
shaderstate.shader_spot = R_RegisterCustom("rtlight_spot", Shader_LightPass_Spot, NULL);
}
break;
case BEM_LIGHT:
if (!shaderstate.inited_shader_rtlight && gl_config.arb_shader_objects)
{
shaderstate.inited_shader_rtlight = true;
shaderstate.shader_rtlight = R_RegisterCustom("rtlight", Shader_LightPass_Std, NULL);
}
if (!shaderstate.inited_shader_cubeproj && gl_config.arb_shader_objects)
{
shaderstate.inited_shader_cubeproj = true;
shaderstate.shader_cubeproj = R_RegisterCustom("rtlight_sube", Shader_LightPass_CubeProj, NULL);
}
break;
case BEM_CREPUSCULAR: case BEM_CREPUSCULAR:
if (!shaderstate.crepopaqueshader) if (!shaderstate.crepopaqueshader)
{ {
@ -3204,6 +3185,7 @@ static void BE_SelectFog(vec3_t colour, float alpha, float density)
void GLBE_SelectDLight(dlight_t *dl, vec3_t colour) void GLBE_SelectDLight(dlight_t *dl, vec3_t colour)
{ {
float view[16], proj[16]; float view[16], proj[16];
int lmode;
/*generate light projection information*/ /*generate light projection information*/
float nearplane = 4; float nearplane = 4;
@ -3229,6 +3211,15 @@ void GLBE_SelectDLight(dlight_t *dl, vec3_t colour)
#endif #endif
shaderstate.lastuniform = 0; shaderstate.lastuniform = 0;
lmode = 0;
if (dl->fov && shaderstate.shader_light[lmode|LSHADER_SPOT]->prog)
lmode |= LSHADER_SPOT;
if ((dl->flags & LFLAG_SHADOWMAP) && shaderstate.shader_light[lmode|LSHADER_SMAP]->prog)
lmode |= LSHADER_SMAP;
if (TEXVALID(shaderstate.lightcubemap) && shaderstate.shader_light[lmode|LSHADER_CUBE]->prog)
lmode |= LSHADER_CUBE;
shaderstate.lightmode = lmode;
} }
void GLBE_PushOffsetShadow(qboolean pushdepth) void GLBE_PushOffsetShadow(qboolean pushdepth)
@ -3435,23 +3426,46 @@ static void DrawMeshes(void)
break; break;
#ifdef RTLIGHTS #ifdef RTLIGHTS
case BEM_SMAPLIGHTSPOT: case BEM_SMAPLIGHTSPOT:
if (shaderstate.shader_smap->prog) // if (shaderstate.shader_spot->prog)
BE_RenderMeshProgram(shaderstate.shader_spot, shaderstate.shader_spot->passes); // BE_RenderMeshProgram(shaderstate.shader_spot, shaderstate.shader_spot->passes);
break; // break;
case BEM_SMAPLIGHT: case BEM_SMAPLIGHT:
if (shaderstate.shader_smap->prog) // if (shaderstate.shader_smap->prog)
BE_RenderMeshProgram(shaderstate.shader_smap, shaderstate.shader_smap->passes); // BE_RenderMeshProgram(shaderstate.shader_smap, shaderstate.shader_smap->passes);
break; // break;
case BEM_LIGHT: case BEM_LIGHT:
if (!shaderstate.inited_shader_rtlight) if (!shaderstate.shader_light[shaderstate.lightmode])
{
if (!shaderstate.inited_shader_light[shaderstate.lightmode])
{
shaderstate.inited_shader_light[shaderstate.lightmode] = true;
switch(shaderstate.lightmode)
{
case LSHADER_SMAP:
shaderstate.shader_light[shaderstate.lightmode] = R_RegisterCustom("rtlight_shadowmap", Shader_LightPass_PCF, NULL);
break;
case LSHADER_SPOT:
shaderstate.shader_light[shaderstate.lightmode] = R_RegisterCustom("rtlight_spot", Shader_LightPass_Spot, NULL);
break;
case LSHADER_STANDARD:
shaderstate.shader_light[shaderstate.lightmode] = R_RegisterCustom("rtlight", Shader_LightPass_Std, NULL);
break;
case LSHADER_CUBE:
shaderstate.shader_light[shaderstate.lightmode] = R_RegisterCustom("rtlight_cube", Shader_LightPass_CubeProj, NULL);
break;
}
if (!shaderstate.shader_light[shaderstate.lightmode])
break;
}
else
{ {
BE_LegacyLighting(); BE_LegacyLighting();
break; break;
} }
if (TEXVALID(shaderstate.lightcubemap) && shaderstate.shader_cubeproj->prog) }
BE_RenderMeshProgram(shaderstate.shader_cubeproj, shaderstate.shader_cubeproj->passes);
else if (shaderstate.shader_rtlight->prog) BE_RenderMeshProgram(shaderstate.shader_light[shaderstate.lightmode], shaderstate.shader_light[shaderstate.lightmode]->passes);
BE_RenderMeshProgram(shaderstate.shader_rtlight, shaderstate.shader_rtlight->passes);
break; break;
case BEM_DEPTHNORM: case BEM_DEPTHNORM:
BE_RenderMeshProgram(shaderstate.depthnormshader, shaderstate.depthnormshader->passes); BE_RenderMeshProgram(shaderstate.depthnormshader, shaderstate.depthnormshader->passes);
@ -3477,7 +3491,7 @@ static void DrawMeshes(void)
GL_DeselectVAO(); GL_DeselectVAO();
GL_DeSelectProgram(); GL_DeSelectProgram();
GenerateTCFog(0); GenerateTCFog(0, NULL);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX)); BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX));
BE_SubmitMeshChain(); BE_SubmitMeshChain();
break; break;
@ -3542,6 +3556,31 @@ static void DrawMeshes(void)
DrawPass(p); DrawPass(p);
} }
} }
if (shaderstate.curbatch->fog)
{
GL_DeselectVAO();
GL_DeSelectProgram();
GenerateFogTexture(&shaderstate.fogtexture, shaderstate.curbatch->fog->shader->fog_dist, 2048);
shaderstate.fogfar = 1.0f/2048; /*scaler for z coords*/
while(shaderstate.lastpasstmus>0)
{
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
}
GL_LazyBind(0, GL_TEXTURE_2D, shaderstate.fogtexture);
shaderstate.lastpasstmus = 1;
Vector4Scale(shaderstate.curbatch->fog->shader->fog_color, (1/255.0), shaderstate.pendingcolourflat);
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
BE_SetPassBlendMode(0, PBM_MODULATE);
BE_SendPassBlendDepthMask(SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | SBITS_MISC_DEPTHEQUALONLY);
GenerateTCFog(0, shaderstate.curbatch->fog);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR) | (1u<<VATTR_LEG_TMU0));
BE_SubmitMeshChain();
}
break; break;
} }
} }
@ -3944,12 +3983,15 @@ static void BE_UpdateLightmaps(void)
batch_t *GLBE_GetTempBatch(void) batch_t *GLBE_GetTempBatch(void)
{ {
batch_t *b;
if (shaderstate.wbatch >= shaderstate.maxwbatches) if (shaderstate.wbatch >= shaderstate.maxwbatches)
{ {
shaderstate.wbatch++; shaderstate.wbatch++;
return NULL; return NULL;
} }
return &shaderstate.wbatches[shaderstate.wbatch++]; b = &shaderstate.wbatches[shaderstate.wbatch++];
b->fog = NULL;
return b;
} }
/*called from shadowmapping code*/ /*called from shadowmapping code*/

View file

@ -2502,19 +2502,29 @@ static void RMod_Batches_Generate(model_t *mod)
plane[3] = 0; plane[3] = 0;
} }
if (lbatch && (lbatch->texture == surf->texinfo->texture && lbatch->lightmap[0] == surf->lightmaptexturenums[0] && Vector4Compare(plane, lbatch->plane) && lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) && if (lbatch && (
lbatch->texture == surf->texinfo->texture &&
lbatch->lightmap[0] == surf->lightmaptexturenums[0] &&
Vector4Compare(plane, lbatch->plane) &&
lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) &&
lbatch->lightmap[1] == surf->lightmaptexturenums[1] && lbatch->lightmap[1] == surf->lightmaptexturenums[1] &&
lbatch->lightmap[2] == surf->lightmaptexturenums[2] && lbatch->lightmap[2] == surf->lightmaptexturenums[2] &&
lbatch->lightmap[3] == surf->lightmaptexturenums[3]) lbatch->lightmap[3] == surf->lightmaptexturenums[3] &&
lbatch->fog == surf->fog)
batch = lbatch; batch = lbatch;
else else
{ {
for (batch = mod->batches[sortid]; batch; batch = batch->next) for (batch = mod->batches[sortid]; batch; batch = batch->next)
{ {
if (batch->texture == surf->texinfo->texture && batch->lightmap[0] == surf->lightmaptexturenums[0] && Vector4Compare(plane, batch->plane) && batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES && if (
batch->texture == surf->texinfo->texture &&
batch->lightmap[0] == surf->lightmaptexturenums[0] &&
Vector4Compare(plane, batch->plane) &&
batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES &&
batch->lightmap[1] == surf->lightmaptexturenums[1] && batch->lightmap[1] == surf->lightmaptexturenums[1] &&
batch->lightmap[2] == surf->lightmaptexturenums[2] && batch->lightmap[2] == surf->lightmaptexturenums[2] &&
batch->lightmap[3] == surf->lightmaptexturenums[3]) batch->lightmap[3] == surf->lightmaptexturenums[3] &&
batch->fog == surf->fog)
break; break;
} }
} }
@ -2528,6 +2538,7 @@ static void RMod_Batches_Generate(model_t *mod)
batch->texture = surf->texinfo->texture; batch->texture = surf->texinfo->texture;
batch->next = mod->batches[sortid]; batch->next = mod->batches[sortid];
batch->ent = &r_worldentity; batch->ent = &r_worldentity;
batch->fog = surf->fog;
Vector4Copy(plane, batch->plane); Vector4Copy(plane, batch->plane);
mod->batches[sortid] = batch; mod->batches[sortid] = batch;

View file

@ -108,6 +108,7 @@ typedef struct batch_s
int lightmap[MAXLIGHTMAPS]; /*used for shader lightmap textures*/ int lightmap[MAXLIGHTMAPS]; /*used for shader lightmap textures*/
unsigned char lightstyle[MAXLIGHTMAPS]; unsigned char lightstyle[MAXLIGHTMAPS];
struct mfog_s *fog;
struct texture_s *texture; /*is this used by the backend?*/ struct texture_s *texture; /*is this used by the backend?*/
struct texnums_s *skin; struct texnums_s *skin;

View file

@ -134,6 +134,7 @@ void GLSCR_UpdateScreen (void)
R2D_BrightenScreen(); R2D_BrightenScreen();
GL_EndRendering (); GL_EndRendering ();
GL_DoSwap(); GL_DoSwap();
GL_Set2D (false);
RSpeedEnd(RSPEED_TOTALREFRESH); RSpeedEnd(RSPEED_TOTALREFRESH);
return; return;
} }

View file

@ -2387,7 +2387,7 @@ static void Shaderpass_VideoMap (shader_t *shader, shaderpass_t *pass, char **pt
{ {
char *token; char *token;
token = Shader_ParseString (ptr); token = Shader_ParseSensString (ptr);
#ifdef NOMEDIA #ifdef NOMEDIA
#else #else

View file

@ -3026,7 +3026,7 @@ void Sh_DrawLights(qbyte *vis)
{ {
Sh_DrawShadowlessLight(dl, colour, vis); Sh_DrawShadowlessLight(dl, colour, vis);
} }
else if ((dl->flags & LFLAG_SHADOWMAP) || dl->fov || r_shadow_shadowmapping.ival) else if ((dl->flags & LFLAG_SHADOWMAP) || r_shadow_shadowmapping.ival)
{ {
#ifdef GLQUAKE #ifdef GLQUAKE
Sh_DrawShadowMapLight(dl, colour, vis); Sh_DrawShadowMapLight(dl, colour, vis);

View file

@ -498,10 +498,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#endif #endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwall", {QR_OPENGL, 110, "defaultwall",
"!!permu OFFSETMAPPING\n" "!!permu DELUXE\n"
"!!permu FULLBRIGHT\n" "!!permu FULLBRIGHT\n"
"!!permu FOG\n" "!!permu FOG\n"
"!!permu LIGHTSTYLED\n" "!!permu LIGHTSTYLED\n"
"!!permu BUMP\n"
"!!cvarf r_glsl_offsetmapping_scale\n" "!!cvarf r_glsl_offsetmapping_scale\n"
//this is what normally draws all of your walls, even with rtlights disabled //this is what normally draws all of your walls, even with rtlights disabled
@ -557,18 +558,22 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n" "#ifdef FRAGMENT_SHADER\n"
//samplers //samplers
"uniform sampler2D s_t0;\n" "uniform sampler2D s_t0; //diffuse\n"
"uniform sampler2D s_t1;\n" "uniform sampler2D s_t1; //lightmap0\n"
"#ifdef OFFSETMAPPING\n" "#if defined(OFFSETMAPPING) || defined(DELUXE)\n"
"uniform sampler2D s_t2;\n" "uniform sampler2D s_t2; //normal\n"
"#endif\n" "#endif\n"
"uniform sampler2D s_t3; //deluxe0\n"
"#ifdef FULLBRIGHT\n" "#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t4;\n" "uniform sampler2D s_t4; //fullbright\n"
"#endif\n" "#endif\n"
"#ifdef LIGHTSTYLED\n" "#ifdef LIGHTSTYLED\n"
"uniform sampler2D s_t5;\n" "uniform sampler2D s_t5; //lightmap1\n"
"uniform sampler2D s_t6;\n" "uniform sampler2D s_t6; //lightmap2\n"
"uniform sampler2D s_t7;\n" "uniform sampler2D s_t7; //lightmap3\n"
"uniform sampler2D s_t8; //deluxe1\n"
"uniform sampler2D s_t9; //deluxe2\n"
"uniform sampler2D s_t10; //deluxe3\n"
"#endif\n" "#endif\n"
"#ifdef LIGHTSTYLED\n" "#ifdef LIGHTSTYLED\n"
@ -582,26 +587,50 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
"void main ()\n" "void main ()\n"
"{\n" "{\n"
//adjust texture coords for offsetmapping
"#ifdef OFFSETMAPPING\n" "#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);\n" "vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);\n"
"#define tc tcoffsetmap\n" "#define tc tcoffsetmap\n"
"#endif\n" "#endif\n"
//yay, regular texture!
"gl_FragColor = texture2D(s_t0, tc);\n" "gl_FragColor = texture2D(s_t0, tc);\n"
//modulate that by the lightmap(s) including deluxemap(s)
"#ifdef LIGHTSTYLED\n" "#ifdef LIGHTSTYLED\n"
"vec4 lightmaps;\n" "vec4 lightmaps;\n"
"#ifdef DELUXE\n"
"vec3 norm = texture2D(s_t2, tc).rgb;\n"
"lightmaps = texture2D(s_t1, lm ) * e_lmscale[0] * dot(norm, texture2D(s_t3, lm ));\n"
"lightmaps += texture2D(s_t5, lm2) * e_lmscale[1] * dot(norm, texture2D(s_t8, lm2));\n"
"lightmaps += texture2D(s_t6, lm3) * e_lmscale[2] * dot(norm, texture2D(s_t9, lm3));\n"
"lightmaps += texture2D(s_t7, lm4) * e_lmscale[3] * dot(norm, texture2D(s_t10,lm4));\n"
"#else\n"
"lightmaps = texture2D(s_t1, lm ) * e_lmscale[0];\n" "lightmaps = texture2D(s_t1, lm ) * e_lmscale[0];\n"
"lightmaps += texture2D(s_t5, lm2) * e_lmscale[1];\n" "lightmaps += texture2D(s_t5, lm2) * e_lmscale[1];\n"
"lightmaps += texture2D(s_t6, lm3) * e_lmscale[2];\n" "lightmaps += texture2D(s_t6, lm3) * e_lmscale[2];\n"
"lightmaps += texture2D(s_t7, lm4) * e_lmscale[3];\n" "lightmaps += texture2D(s_t7, lm4) * e_lmscale[3];\n"
"#endif\n"
"gl_FragColor.rgb *= lightmaps.rgb;\n" "gl_FragColor.rgb *= lightmaps.rgb;\n"
"#else\n" "#else\n"
"#ifdef DELUXE\n"
//gl_FragColor.rgb = dot(normalize(texture2D(s_t2, tc).rgb - 0.5), normalize(texture2D(s_t3, lm).rgb - 0.5));
//gl_FragColor.rgb = texture2D(s_t3, lm).rgb;
"gl_FragColor.rgb *= (texture2D(s_t1, lm) * e_lmscale).rgb * dot(normalize(texture2D(s_t2, tc).rgb-0.5), 2.0*(texture2D(s_t3, lm).rgb-0.5));\n"
"#else\n"
"gl_FragColor.rgb *= (texture2D(s_t1, lm) * e_lmscale).rgb;\n" "gl_FragColor.rgb *= (texture2D(s_t1, lm) * e_lmscale).rgb;\n"
"#endif\n" "#endif\n"
"#endif\n"
//add on the fullbright
"#ifdef FULLBRIGHT\n" "#ifdef FULLBRIGHT\n"
"gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n" "gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n"
"#endif\n" "#endif\n"
//entity modifiers
"gl_FragColor = gl_FragColor * e_colourident;\n" "gl_FragColor = gl_FragColor * e_colourident;\n"
//and finally hide it all if we're fogged.
"#ifdef FOG\n" "#ifdef FOG\n"
"gl_FragColor = fog4(gl_FragColor);\n" "gl_FragColor = fog4(gl_FragColor);\n"
"#endif\n" "#endif\n"
@ -890,7 +919,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
{QR_OPENGL, 110, "rtlight", {QR_OPENGL, 110, "rtlight",
"!!permu BUMP\n" "!!permu BUMP\n"
"!!permu SPECULAR\n" "!!permu SPECULAR\n"
"!!permu OFFSETMAPPING\n"
"!!permu SKELETAL\n" "!!permu SKELETAL\n"
"!!permu FOG\n" "!!permu FOG\n"
"!!cvarf r_glsl_offsetmapping_scale\n" "!!cvarf r_glsl_offsetmapping_scale\n"

View file

@ -189,7 +189,6 @@ typedef struct shaderpass_s {
TC_GEN_ENVIRONMENT, TC_GEN_ENVIRONMENT,
TC_GEN_DOTPRODUCT, TC_GEN_DOTPRODUCT,
TC_GEN_VECTOR, TC_GEN_VECTOR,
TC_GEN_FOG,
//these are really for use only in glsl stuff or perhaps cubemaps, as they generate 3d coords. //these are really for use only in glsl stuff or perhaps cubemaps, as they generate 3d coords.
TC_GEN_NORMAL, TC_GEN_NORMAL,

View file

@ -3171,10 +3171,24 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
if (!func->initialized) if (!func->initialized)
func->initialized = 3; func->initialized = 3;
func->references++; func->references++;
t = QCC_PR_ParseType(false, false); t = QCC_PR_ParseType(false, true);
if (t)
{
QCC_PR_Expect(")"); QCC_PR_Expect(")");
return QCC_MakeIntConst(t->size * 4); return QCC_MakeIntConst(t->size * 4);
} }
else
{
int oldstcount = numstatements;
e = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
//the term should not have side effects, or generate any actual statements.
numstatements = oldstcount;
QCC_PR_Expect(")");
if (!e)
QCC_PR_ParseErrorPrintDef (ERR_NOTAFUNCTION, func, "sizeof term not supported");
return QCC_MakeIntConst(e->type->size * 4 * e->arraysize);
}
}
if (!strcmp(func->name, "_")) if (!strcmp(func->name, "_"))
{ {
if (!func->initialized) if (!func->initialized)

View file

@ -1674,6 +1674,7 @@ static void SV_InitBotLib(void)
qboolean SVQ3_InitGame(void) qboolean SVQ3_InitGame(void)
{ {
int i;
char buffer[8192]; char buffer[8192];
char *str; char *str;
char sysinfo[8192]; char sysinfo[8192];
@ -1748,10 +1749,13 @@ qboolean SVQ3_InitGame(void)
q3_next_snapshot_entities = 0; q3_next_snapshot_entities = 0;
q3_snapshot_entities = BZ_Malloc(sizeof( q3entityState_t ) * q3_num_snapshot_entities); q3_snapshot_entities = BZ_Malloc(sizeof( q3entityState_t ) * q3_num_snapshot_entities);
#ifdef USEBOTLIB
if (botlib) // run a few frames to allow everything to settle
VM_Call(q3gamevm, BOTAI_START_FRAME, (int)(sv.time*1000)); for (i = 0; i < 3; i++)
#endif {
SVQ3_RunFrame();
sv.time += 0.1;
}
return true; return true;
} }

View file

@ -178,6 +178,7 @@
/> />
<Tool <Tool
Name="VCManifestTool" Name="VCManifestTool"
EmbedManifest="false"
/> />
<Tool <Tool
Name="VCXDCMakeTool" Name="VCXDCMakeTool"

View file

@ -87,8 +87,9 @@
</Configuration> </Configuration>
<Configuration <Configuration
Name="Release|Win32" Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1" ConfigurationType="2"
> >
<Tool <Tool
Name="VCPreBuildEventTool" Name="VCPreBuildEventTool"
@ -119,12 +120,14 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="berkelium/berkelium.lib"
/> />
<Tool <Tool
Name="VCALinkTool" Name="VCALinkTool"
/> />
<Tool <Tool
Name="VCManifestTool" Name="VCManifestTool"
EmbedManifest="false"
/> />
<Tool <Tool
Name="VCXDCMakeTool" Name="VCXDCMakeTool"