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,10 +384,16 @@ 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)
{ {
px = Font_DrawScaleChar(px, py, size[0], size[1], *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++);
} }
Font_InvalidateColour(); Font_InvalidateColour();
Font_EndString(font_conchar); Font_EndString(font_conchar);

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)
{ {
Con_Printf("S( ) : %s\n", sfx->name); sc = sfx->decoder.decodedata(sfx, &scachebuf, 0, 0x0fffffff);
if (!sc)
{
Con_Printf("S( ) : %s\n", sfx->name);
continue;
}
}
else
sc = sfx->decoder.buf;
if (!sc)
{
Con_Printf("?( ) : %s\n", sfx->name);
continue; continue;
} }
sc = Cache_Check (&sfx->cache); size = (sc->soundoffset+sc->length)*sc->width*(sc->numchannels);
if (!sc) duration = (sc->soundoffset+sc->length) / sc->speed;
continue;
size = sc->length*sc->width*(sc->numchannels);
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;
@ -114,6 +136,8 @@ static int Droid_InitCard (soundcardinfo_t *sc, int cardnum)
sc->sn.buffer = malloc(sc->sn.samples*sc->sn.samplebits/8); sc->sn.buffer = malloc(sc->sn.samples*sc->sn.samplebits/8);
sys_sc = sc; sys_sc = sc;
sys_soundflags = 3;
// pthread_mutex_unlock(&mutex); // pthread_mutex_unlock(&mutex);

View file

@ -125,33 +125,41 @@ 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*/
dec->decodedbytecount = 0;
dec->decodedbytestart = start;
//check pos
p_ov_pcm_seek(&dec->vf, dec->decodedbytestart);
}
if (dec->decodedbytecount > snd_speed*8)
{
/*everything is okay, but our buffer is getting needlessly large.
keep anything after the 'new' position, but discard all before that
trim shouldn't be able to go negative
*/
int trim = start - dec->decodedbytestart;
if (trim < 0)
{ {
/*something rewound, purge clear the buffer*/
dec->decodedbytecount = 0; dec->decodedbytecount = 0;
dec->decodedbytestart = start; dec->decodedbytestart = start;
//check pos
p_ov_pcm_seek(&dec->vf, dec->decodedbytestart);
} }
else
if (start+length <= dec->decodedbytestart + dec->decodedbytecount)
break;
if (dec->decodedbytecount > snd_speed*8)
{ {
/*everything is okay, but our buffer is getting needlessly large.
keep anything after the 'new' position, but discard all before that
trim shouldn't be able to go negative
*/
unsigned int trim = start - dec->decodedbytestart;
//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])
{ {
BE_LegacyLighting(); if (!shaderstate.inited_shader_light[shaderstate.lightmode])
break; {
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();
break;
}
} }
if (TEXVALID(shaderstate.lightcubemap) && shaderstate.shader_cubeproj->prog)
BE_RenderMeshProgram(shaderstate.shader_cubeproj, shaderstate.shader_cubeproj->passes); BE_RenderMeshProgram(shaderstate.shader_light[shaderstate.lightmode], shaderstate.shader_light[shaderstate.lightmode]->passes);
else if (shaderstate.shader_rtlight->prog)
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->lightmap[1] == surf->lightmaptexturenums[1] && lbatch->texture == surf->texinfo->texture &&
lbatch->lightmap[2] == surf->lightmaptexturenums[2] && lbatch->lightmap[0] == surf->lightmaptexturenums[0] &&
lbatch->lightmap[3] == surf->lightmaptexturenums[3]) Vector4Compare(plane, lbatch->plane) &&
lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) &&
lbatch->lightmap[1] == surf->lightmaptexturenums[1] &&
lbatch->lightmap[2] == surf->lightmaptexturenums[2] &&
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->lightmap[1] == surf->lightmaptexturenums[1] && batch->texture == surf->texinfo->texture &&
batch->lightmap[2] == surf->lightmaptexturenums[2] && batch->lightmap[0] == surf->lightmaptexturenums[0] &&
batch->lightmap[3] == surf->lightmaptexturenums[3]) Vector4Compare(plane, batch->plane) &&
batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES &&
batch->lightmap[1] == surf->lightmaptexturenums[1] &&
batch->lightmap[2] == surf->lightmaptexturenums[2] &&
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,9 +3171,23 @@ 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);
QCC_PR_Expect(")"); if (t)
return QCC_MakeIntConst(t->size * 4); {
QCC_PR_Expect(")");
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, "_"))
{ {

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"