fix gameclock in mvds.

implement hardware cursors in d3d9+d3d11
fix crash from closing the audio menu in the webgl port.
make deluxemapping+softwarebanding require a vid_reload before anything happens. this solves missing textures until the user does it anyway.
fix scores+spectating issue. again. oops.
rename openal devices in the webgl port, so that it makes more sense.
remove glsl/hlsl parameter limit. this also fixes the final ie webgl issue (still gets half the framerate though).
fix some issues with bloom and waterwarp active at the same time.
attempted to give properish error messages from emscripten, despite emscripten hating me.
hack drag+drop into fteqccgui. I ought to make fteqw accept demos etc this way some time too.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4959 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-08-07 17:49:49 +00:00
parent 257610c89f
commit f520bdede7
43 changed files with 1388 additions and 1027 deletions

View File

@ -1261,8 +1261,12 @@ ifeq ($(FTE_TARGET),web)
COMMON_OBJS+=sys_web.o fs_web.o
WEB_PREJS ?= --pre-js web/prejs.js
# WEB_MEMORY?=402653184 #384mb
ASMJS_MEMORY?=536870912 #512mb (required for asm.js)
# ASMJS_MEMORY?=268435456 #256mb (required for asm.js)
# ASMJS_MEMORY?=16777216 #16mb
# ASMJS_MEMORY?=33554432 #32mb
ASMJS_MEMORY?=268435456 #256mb
# ASMJS_MEMORY?=536870912 #512mb
# ASMJS_MEMORY?=1073741824 #1025mb
# ASMJS_MEMORY?=2147483648 #2048mb
WEB_MEMORY?=$(ASMJS_MEMORY)
JSLIBS=--js-library web/ftejslib.js -s LEGACY_GL_EMULATION=0
EMCC_ARGS=$(JSLIBS) $(WEB_PREJS) --shell-file web/fteshell.html -s ERROR_ON_UNDEFINED_SYMBOLS=1
@ -1292,7 +1296,7 @@ ifeq ($(FTE_TARGET),web)
#GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) cd_null.o
#GL_LDFLAGS=$(GLLDFLAGS)
GLB_DIR=gl_web
GL_EXE_NAME=../ftewebgl.html
GL_EXE_NAME=../ftewebgl.js
GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS)
GL_CFLAGS=$(GLCFLAGS)
@ -1695,15 +1699,17 @@ EMSCRIPTENPATH=$(realpath $(EMSCRIPTENROOT)):$(realpath $(EMSCRIPTENROOT)/clang/
web-rel:
@$(MAKE) gl-rel FTE_TARGET=web PATH="$(EMSCRIPTENPATH)" CC="emcc.bat"
cp $(BASE_DIR)/fteshell.html $(RELEASE_DIR)/ftewebgl.html
@gzip -f $(RELEASE_DIR)/ftewebgl.html
@gzip -f $(RELEASE_DIR)/ftewebgl.js
@gzip -f $(RELEASE_DIR)/ftewebgl.html.mem
@gzip -f $(RELEASE_DIR)/ftewebgl.js.mem
web-dbg:
@$(MAKE) gl-dbg FTE_TARGET=web PATH="$(EMSCRIPTENPATH)" CC="emcc.bat"
cp $(BASE_DIR)/fteshell.html $(RELEASE_DIR)/ftewebgl.html
@gzip -f $(DEBUG_DIR)/ftewebgl.html
@gzip -f $(DEBUG_DIR)/ftewebgl.js
@gzip -f $(DEBUG_DIR)/ftewebgl.html.map
@gzip -f $(DEBUG_DIR)/ftewebgl.js.map
#################################################
#android

View File

@ -972,12 +972,12 @@ void CLQW_ParsePacketEntities (qboolean delta)
cl.inframes[newpacket].frameid = cls.netchan.incoming_sequence;
cl.inframes[newpacket].receivedtime = realtime;
if (cls.protocol == CP_QUAKEWORLD && cls.demoplayback == DPB_MVD)
if (cls.protocol == CP_QUAKEWORLD && (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV))
{
extern float olddemotime; //time from the most recent demo packet
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = olddemotime;
cl.gametime = olddemotime + cl.demogametimebias;
cl.gametimemark = realtime;
}
else if (!(cls.fteprotocolextensions & PEXT_ACCURATETIMINGS) && cls.protocol == CP_QUAKEWORLD)
@ -3399,6 +3399,7 @@ void CL_LinkPacketEntities (void)
static int flicker;
int trailef, trailidx;
int modelflags;
struct itemtimer_s *timer, **timerlink;
pack = cl.currentpackentities;
if (!pack)
@ -3417,22 +3418,43 @@ void CL_LinkPacketEntities (void)
CSQC_DeltaStart(cl.currentpacktime);
#endif
for (timerlink = &cl.itemtimers; (timer=*timerlink); )
{
if (cl.time > timer->end)
{
*timerlink = timer->next;
Z_Free(timer);
}
else
{
timerlink = &(*timerlink)->next;
if (timer->entnum >= cl.maxlerpents)
continue;
le = &cl.lerpents[timer->entnum];
if (le->sequence != cl.lerpentssequence)
continue;
R_AddItemTimer(timer->origin, cl.time*90 + timer->origin[0] + timer->origin[1] + timer->origin[2], timer->radius, (cl.time - timer->start) / timer->duration);
}
}
for (newpnum=0 ; newpnum<pack->num_entities ; newpnum++)
{
state = &pack->entities[newpnum];
if (cl_numvisedicts == cl_maxvisedicts)
{
break;
}
#ifdef CSQC_DAT
if (CSQC_DeltaUpdate(state))
continue;
#endif
if (cl_numvisedicts == cl_maxvisedicts)
break;
if (state->number >= cl.maxlerpents)
continue;
le = &cl.lerpents[state->number];
ent = &cl_visedicts[cl_numvisedicts];
ent->rtype = RT_MODEL;
ent->playerindex = -1;
@ -3445,11 +3467,6 @@ void CL_LinkPacketEntities (void)
ent->light_known = 0;
ent->forcedshader = NULL;
if (state->number >= cl.maxlerpents)
continue;
le = &cl.lerpents[state->number];
memset(&ent->framestate, 0, sizeof(ent->framestate));
VectorCopy(le->origin, ent->origin);

View File

@ -2919,6 +2919,7 @@ void CLQW_ParseServerData (void)
/*mvds have different parsing*/
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{
extern float olddemotime;
int i,j;
if (cls.fteprotocolextensions2 & PEXT2_MAXPLAYERS)
@ -2933,6 +2934,8 @@ void CLQW_ParseServerData (void)
cl.oldgametime = cl.gametime;
cl.oldgametimemark = realtime;
cl.demogametimebias = cl.gametime - olddemotime;
for (j = 0; j < MAX_SPLITS; j++)
{
cl.playerview[j].playernum = cl.allocated_client_slots + j;
@ -4261,9 +4264,15 @@ void CLQW_ParseStartSoundPacket(void)
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation, 0, 0, 0);
}
if (ent == cl.playerview[0].playernum+1)
TP_CheckPickupSound(cl.sound_name[sound_num], pos);
for (i = 0; i < cl.splitclients; i++)
{
if (ent == cl.playerview[i].playernum+1)
{
TP_CheckPickupSound(cl.sound_name[sound_num], pos, i);
return;
}
}
TP_CheckPickupSound(cl.sound_name[sound_num], pos, -1);
}
#ifdef Q2CLIENT
@ -4427,8 +4436,15 @@ void CLNQ_ParseStartSoundPacket(void)
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation, timeofs, pitchadj, flags);
}
if (ent == cl.playerview[0].playernum+1)
TP_CheckPickupSound(cl.sound_name[sound_num], pos);
for (i = 0; i < cl.splitclients; i++)
{
if (ent == cl.playerview[i].playernum+1)
{
TP_CheckPickupSound(cl.sound_name[sound_num], pos, i);
return;
}
}
TP_CheckPickupSound(cl.sound_name[sound_num], pos, -1);
}
#endif

View File

@ -1300,6 +1300,21 @@ void SCR_Init (void)
void SCR_DeInit (void)
{
int i;
if (scr_curcursor)
{
rf->VID_SetCursor(scr_curcursor);
scr_curcursor = NULL;
}
for (i = 0; i < countof(key_customcursor); i++)
{
if (key_customcursor[i].handle)
{
rf->VID_DestroyCursor(key_customcursor[i].handle);
key_customcursor[i].handle = NULL;
}
key_customcursor[i].dirty = true;
}
if (scr_initialized)
{
scr_initialized = false;

View File

@ -753,6 +753,7 @@ typedef struct
float gametimemark;
float oldgametime; //used as the old time to lerp cl.time from.
float oldgametimemark; //if it's 0, cl.time will casually increase.
float demogametimebias; //mvd timings are weird.
float minpitch;
float maxpitch;
@ -829,6 +830,18 @@ typedef struct
float predicted_step_time;
float predicted_step;
struct itemtimer_s
{
float end;
int entnum;
float start;
float duration;
vec3_t origin;
float radius;
struct itemtimer_s *next;
} *itemtimers;
//interpolation+snapshots
float packfrac;
packet_entities_t *currentpackentities;
@ -1354,7 +1367,7 @@ void QDECL vectoangles(vec3_t fwd, vec3_t ang);
void CL_Say (qboolean team, char *extra);
int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr);
void TP_CheckPickupSound(char *s, vec3_t org);
void TP_CheckPickupSound(char *s, vec3_t org, int seat);
qboolean TP_CheckSoundTrigger (char *str);
int TP_CountPlayers (void);
char* TP_EnemyName (void);

View File

@ -4527,8 +4527,8 @@ void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, in
Image_GenerateMips(&mips, flags);
Image_ChangeFormat(&mips, fmt);
rf->IMG_LoadTextureMips(tex, &mips);
tex->width = mips.mip[0].width;
tex->height = mips.mip[0].height;
tex->width = width;
tex->height = height;
tex->status = TEX_LOADED;
for (i = 0; i < mips.mipcount; i++)

View File

@ -387,8 +387,10 @@ struct audiomenuinfo
{
char **outdevnames;
char **outdevdescs;
#ifdef VOICECHAT
char **capdevnames;
char **capdevdescs;
#endif
};
void M_Menu_Audio_Remove(menu_t *menu)
{
@ -400,12 +402,14 @@ void M_Menu_Audio_Remove(menu_t *menu)
for (i = 0; info->outdevdescs[i]; i++)
Z_Free(info->outdevdescs[i]);
Z_Free(info->outdevdescs);
#ifdef VOICECHAT
for (i = 0; info->capdevnames[i]; i++)
Z_Free(info->capdevnames[i]);
Z_Free(info->capdevnames);
for (i = 0; info->capdevdescs[i]; i++)
Z_Free(info->capdevdescs[i]);
Z_Free(info->capdevdescs);
#endif
}
struct audiomenuinfo *M_Menu_Audio_Setup(menu_t *menu)
{
@ -1110,7 +1114,8 @@ void M_Menu_Textures_f (void)
MB_COMBOCVAR("2D Filter Mode", gl_texturemode2d, texture2dfilternames, texture2dfiltervalues, "Chooses the texture filtering method used for HUD, menus, and other 2D assets."),
MB_COMBOCVAR("Anisotropy", gl_texture_anisotropic_filtering, anisotropylevels, anisotropyvalues, NULL),
MB_SPACING(4),
MB_CHECKBOXCVAR("Deluxemapping", r_deluxemapping, 0),
MB_CHECKBOXCVAR("Software-style Rendering", r_softwarebanding_cvar, 0),
MB_CHECKBOXCVAR("Deluxemapping", r_deluxemapping_cvar, 0),
MB_CHECKBOXCVAR("Specular Highlights", gl_specular, 0),
// MB_CHECKBOXCVAR("Detail Textures", gl_detail, 0),
MB_CHECKBOXCVAR("offsetmapping", r_glsl_offsetmapping, 0),

View File

@ -3000,7 +3000,7 @@ TRACE(("dbg: Surf_NewMap: tp\n"));
void Surf_PreNewMap(void)
{
r_loadbumpmapping = r_deluxemapping.ival || r_glsl_offsetmapping.ival;
r_loadbumpmapping = r_deluxemapping || r_glsl_offsetmapping.ival;
#ifdef RTLIGHTS
r_loadbumpmapping |= r_shadow_realtime_world.ival || r_shadow_realtime_dlight.ival;
#endif

View File

@ -568,7 +568,10 @@ extern cvar_t r_telestyle;
extern cvar_t r_dynamic;
extern cvar_t r_novis;
extern cvar_t r_netgraph;
extern cvar_t r_deluxemapping;
extern cvar_t r_deluxemapping_cvar;
extern qboolean r_deluxemapping;
extern cvar_t r_softwarebanding_cvar;
extern qboolean r_softwarebanding;
#ifdef R_XFLIP
extern cvar_t r_xflip;

View File

@ -39,8 +39,13 @@ void QDECL SCR_Viewsize_Callback (struct cvar_s *var, char *oldvalue);
void QDECL SCR_Fov_Callback (struct cvar_s *var, char *oldvalue);
void QDECL Image_TextureMode_Callback (struct cvar_s *var, char *oldvalue);
#ifdef FTE_TARGET_WEB //webgl sucks too much to get a stable framerate without vsync.
cvar_t vid_vsync = CVARAF ("vid_wait", "1",
"vid_vsync", CVAR_ARCHIVE);
#else
cvar_t vid_vsync = CVARAF ("vid_wait", "0",
"vid_vsync", CVAR_ARCHIVE);
#endif
cvar_t _windowed_mouse = CVARF ("_windowed_mouse","1",
CVAR_ARCHIVE);
@ -71,7 +76,7 @@ cvar_t r_bouncysparks = CVARFD ("r_bouncysparks", "1",
CVAR_ARCHIVE,
"Enables particle interaction with world surfaces, allowing for bouncy particles, stains, and decals.");
cvar_t r_drawentities = CVAR ("r_drawentities", "1");
cvar_t r_drawflat = CVARF ("r_drawflat", "0",
cvar_t r_drawflat = CVARAF ("r_drawflat", "0", "gl_textureless",
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
cvar_t r_wireframe = CVARFD ("r_wireframe", "0",
CVAR_CHEAT, "Developer feature where everything is drawn with wireframe over the top. Only active where cheats are permitted.");
@ -135,7 +140,8 @@ cvar_t r_part_rain = CVARFD ("r_part_rain", "0",
"Enable particle effects to emit off of surfaces. Mainly used for weather or lava/slime effects.");
cvar_t r_skyboxname = SCVARF ("r_skybox", "",
CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
cvar_t r_softwarebanding = CVARFD ("r_softwarebanding", "0", CVAR_SHADERSYSTEM, "Utilise the Quake colormap in order to emulate 8bit software rendering. This results in banding as well as other artifacts that some believe adds character. Also forces nearest sampling on affected surfaces (palette indicies do not interpolate well).");
cvar_t r_softwarebanding_cvar = CVARFD ("r_softwarebanding", "0", CVAR_SHADERSYSTEM, "Utilise the Quake colormap in order to emulate 8bit software rendering. This results in banding as well as other artifacts that some believe adds character. Also forces nearest sampling on affected surfaces (palette indicies do not interpolate well).");
qboolean r_softwarebanding;
cvar_t r_speeds = SCVAR ("r_speeds", "0");
cvar_t r_stainfadeammount = SCVAR ("r_stainfadeammount", "1");
cvar_t r_stainfadetime = SCVAR ("r_stainfadetime", "1");
@ -283,8 +289,9 @@ cvar_t gl_ati_truform_type = CVAR ("gl_ati_truform_type", "1");
cvar_t gl_ati_truform_tesselation = CVAR ("gl_ati_truform_tesselation", "3");
cvar_t gl_blend2d = CVAR ("gl_blend2d", "1");
cvar_t gl_blendsprites = CVARD ("gl_blendsprites", "0", "Blend sprites instead of alpha testing them");
cvar_t r_deluxemapping = CVARAFD ("r_deluxemapping", "0", "r_glsl_deluxemapping",
CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Enables bumpmapping based upon precomputed light directions");
cvar_t r_deluxemapping_cvar = CVARAFD ("r_deluxemapping", "0", "r_glsl_deluxemapping",
CVAR_ARCHIVE, "Enables bumpmapping based upon precomputed light directions");
qboolean r_deluxemapping;
cvar_t r_shaderblobs = CVARD ("r_shaderblobs", "0", "If enabled, can massively accelerate vid restarts / loading (especially with the d3d renderer). Can cause issues when upgrading engine versions, so this is disabled by default.");
cvar_t gl_compress = CVARFD ("gl_compress", "0", CVAR_ARCHIVE, "Enable automatic texture compression even for textures which are not pre-compressed.");
cvar_t gl_conback = CVARFDC ("gl_conback", "",
@ -451,7 +458,7 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_smoothcrosshair, GRAPHICALNICETIES);
Cvar_Register (&r_deluxemapping, GRAPHICALNICETIES);
Cvar_Register (&r_deluxemapping_cvar, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_reliefmapping, GRAPHICALNICETIES);
@ -668,7 +675,7 @@ void Renderer_Init(void)
Cvar_Register (&r_mirroralpha, GLRENDEREROPTIONS);
Cvar_Register (&r_skyboxname, GRAPHICALNICETIES);
Cbuf_AddText("alias sky r_skybox\n", RESTRICT_LOCAL); /*alternative name for users*/
Cvar_Register (&r_softwarebanding, GRAPHICALNICETIES);
Cvar_Register (&r_softwarebanding_cvar, GRAPHICALNICETIES);
Cvar_Register(&r_dodgytgafiles, "Bug fixes");
Cvar_Register(&r_dodgypcxfiles, "Bug fixes");
@ -1111,6 +1118,9 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
pmove.numphysent = 0;
pmove.physents[0].model = NULL;
r_softwarebanding = r_softwarebanding_cvar.ival;
r_deluxemapping = r_deluxemapping_cvar.ival;
if (qrenderer != QR_NONE) //graphics stuff only when not dedicated
{
size_t sz;

View File

@ -2155,7 +2155,7 @@ void Sbar_DrawScoreboard (void)
if (cl.spectator)
{
int t = cl.playerview[pnum].cam_spec_track;
if (t < 0)
if (t < 0 || !CAM_ISLOCKED(&cl.playerview[pnum]))
continue;
if (cl.players[t].statsf[STAT_HEALTH] <= 0)
deadcount++;

View File

@ -14,8 +14,11 @@ FIXME: a capture device would be useful (voice chat).
#ifdef AVAIL_OPENAL
#ifdef FTE_TARGET_WEB
//our javascript port doesn't support dynamic linking.
#define OPENAL_STATIC
//emscripten provides an openal -> webaudio wrapper. its not the best, but does get the job done.
#define OPENAL_STATIC //our javascript port doesn't support dynamic linking (bss+data segments get too messy).
#define SDRVNAME "WebAudio" //IE doesn't support webaudio, resulting in noticable error messages about no openal, which is technically incorrect. So lets be clear about this.
#else
#define SDRVNAME "OpenAL"
#endif
#ifdef OPENAL_STATIC
@ -278,7 +281,7 @@ static AL_API ALvoid (AL_APIENTRY *palEffectf)(ALuint effect, ALenum param, ALfl
static AL_API ALvoid (AL_APIENTRY *palEffectfv)(ALuint effect, ALenum param, const ALfloat *pflValues);
#endif
#define SOUNDVARS "OpenAL variables"
#define SOUNDVARS SDRVNAME" variables"
extern sfx_t *known_sfx;
@ -830,13 +833,13 @@ static qboolean OpenAL_Init(soundcardinfo_t *sc, const char *devname)
if (!OpenAL_InitLibrary())
{
Con_Printf("OpenAL is not installed\n");
Con_Printf(SDRVNAME" is not installed\n");
return false;
}
if (oali->OpenAL_Context)
{
Con_Printf("OpenAL: only able to load one device at a time\n");
Con_Printf(SDRVNAME": only able to load one device at a time\n");
return false;
}
@ -1085,17 +1088,17 @@ static qboolean QDECL OpenAL_InitCard(soundcardinfo_t *sc, const char *devname)
if (!devname || !*devname)
devname = palcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
Con_Printf("Initiating OpenAL: %s.\n", devname);
Con_Printf("Initiating "SDRVNAME": %s.\n", devname);
if (OpenAL_Init(sc, devname) == false)
{
Con_Printf(CON_ERROR "OpenAL init failed\n");
Con_Printf(CON_ERROR SDRVNAME " init failed\n");
return false;
}
oali = sc->handle;
Con_DPrintf("OpenAL AL Extension : %s\n",palGetString(AL_EXTENSIONS));
Con_DPrintf("OpenAL ALC Extension : %s\n",palcGetString(oali->OpenAL_Device,ALC_EXTENSIONS));
Con_DPrintf(SDRVNAME" AL Extension : %s\n",palGetString(AL_EXTENSIONS));
Con_DPrintf(SDRVNAME" ALC Extension : %s\n",palcGetString(oali->OpenAL_Device,ALC_EXTENSIONS));
sc->Lock = OpenAL_LockBuffer;
sc->Unlock = OpenAL_UnlockBuffer;
@ -1142,7 +1145,6 @@ static qboolean QDECL OpenAL_InitCard(soundcardinfo_t *sc, const char *devname)
return true;
}
#define SDRVNAME "OpenAL"
static qboolean QDECL OpenAL_Enumerate(void (QDECL *callback)(const char *driver, const char *devicecode, const char *readabledevice))
{
const char *devnames;
@ -1154,7 +1156,11 @@ static qboolean QDECL OpenAL_Enumerate(void (QDECL *callback)(const char *driver
devnames = palcGetString(NULL, ALC_DEVICE_SPECIFIER);
while(*devnames)
{
#ifdef FTE_TARGET_WEB
callback(SDRVNAME, devnames, va("WebAudio:%s", devnames));
#else
callback(SDRVNAME, devnames, va("OAL:%s", devnames));
#endif
devnames += strlen(devnames)+1;
}
return true;

View File

@ -4275,4 +4275,122 @@ void Sys_Sleep (double seconds)
{
Sleep(seconds * 1000);
}
HCURSOR hArrowCursor, hCustomCursor;
void *WIN_CreateCursor(char *filename, float hotx, float hoty, float scale)
{
int width, height;
BITMAPV5HEADER bi;
DWORD x,y;
HCURSOR hAlphaCursor = NULL;
ICONINFO ii;
HDC maindc;
qbyte *rgbadata, *rgbadata_start, *bgradata, *bgradata_start;
qboolean hasalpha;
void *filedata;
int filelen;
if (!filename || !*filename)
return NULL;
filelen = FS_LoadFile(filename, &filedata);
if (!filedata)
return NULL;
rgbadata_start = Read32BitImageFile(filedata, filelen, &width, &height, &hasalpha, "cursor");
FS_FreeFile(filedata);
if (!rgbadata_start)
return NULL;
if (scale != 1)
{
int nw,nh;
qbyte *nd;
nw = width * scale;
nh = height * scale;
if (nw <= 0 || nh <= 0 || nw > 128 || nh > 128) //don't go crazy.
return NULL;
nd = BZ_Malloc(nw*nh*4);
Image_ResampleTexture((unsigned int*)rgbadata_start, width, height, (unsigned int*)nd, nw, nh);
width = nw;
height = nh;
BZ_Free(rgbadata_start);
rgbadata_start = nd;
}
memset(&bi,0, sizeof(BITMAPV5HEADER));
bi.bV5Size = sizeof(BITMAPV5HEADER);
bi.bV5Width = width;
bi.bV5Height = height;
bi.bV5Planes = 1;
bi.bV5BitCount = 32;
bi.bV5Compression = BI_BITFIELDS;
// The following mask specification specifies a supported 32 BPP
// alpha format for Windows XP.
//FIXME: can we not just specify it as RGBA? meh.
bi.bV5RedMask = 0x00FF0000;
bi.bV5GreenMask = 0x0000FF00;
bi.bV5BlueMask = 0x000000FF;
bi.bV5AlphaMask = 0xFF000000;
// Create the DIB section with an alpha channel.
maindc = GetDC(mainwindow);
ii.hbmColor = CreateDIBSection(maindc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&bgradata_start, NULL, 0);
ReleaseDC(mainwindow, maindc);
if (!ii.hbmColor)
{
BZ_Free(rgbadata_start);
return NULL;
}
for (rgbadata=rgbadata_start,y=0;y<height;y++)
{
bgradata = bgradata_start + (height-1-y)*width*4;
for (x=0;x<width;x++)
{
bgradata[0] = rgbadata[2];
bgradata[1] = rgbadata[1];
bgradata[2] = rgbadata[0];
bgradata[3] = rgbadata[3];
bgradata+=4;
rgbadata+=4;
}
}
BZ_Free(rgbadata_start);
ii.fIcon = FALSE; // Change fIcon to TRUE to create an alpha icon
ii.xHotspot = hotx;
ii.yHotspot = hoty;
ii.hbmMask = CreateBitmap(width,height,1,1,NULL);
// Create the alpha cursor with the alpha DIB section.
hAlphaCursor = CreateIconIndirect(&ii);
DeleteObject(ii.hbmColor);
DeleteObject(ii.hbmMask);
return hAlphaCursor;
}
qboolean WIN_SetCursor(void *cursor)
{
static POINT current_pos; //static to avoid bugs in vista(32) with largeaddressaware (this is fixed in win7). fixed exe base address prevents this from going above 2gb.
hCustomCursor = cursor;
//move the cursor to ensure the WM_SETCURSOR thing is invoked properly.
//this ensures all the nastyness of random programs randomly setting the current global cursor is handled by microsoft's code instead of mine.
//if you're using rawinput there'll be no lost inpuit problems, yay...
GetCursorPos(&current_pos);
SetCursorPos(current_pos.x, current_pos.y);
return true;
}
void WIN_DestroyCursor(void *cursor)
{
DestroyIcon(cursor);
}
#endif

View File

@ -109,6 +109,11 @@ extern qboolean mouseinitialized;
//extern HANDLE hinput, houtput;
extern HCURSOR hArrowCursor, hCustomCursor;
void *WIN_CreateCursor(char *filename, float hotx, float hoty, float scale);
qboolean WIN_SetCursor(void *cursor);
void WIN_DestroyCursor(void *cursor);
void INS_UpdateClipCursor (void);
void CenterWindow(HWND hWndCenter, int width, int height, BOOL lefttopjustify);
void INS_TranslateKeyEvent(WPARAM wParam, LPARAM lParam, qboolean down, int pnum, qboolean genkeystate);

View File

@ -2467,123 +2467,133 @@ typedef struct {
char *modelname;
vec3_t offset; // offset of model graphics center
float radius; // model graphics radius
float respawntime;// automatic respawn timer for mvds.
int flags; // TODO: "NOPICKUP" (disp), "TEAMENEMY" (flag, disp)
} item_t;
static item_t tp_items[] = {
{ it_quad, &tp_name_quad, "progs/quaddama.mdl",
{0, 0, 24}, 25,
{0, 0, 24}, 25, 60
},
{ it_pent, &tp_name_pent, "progs/invulner.mdl",
{0, 0, 22}, 25,
{0, 0, 22}, 25, 5*60
},
{ it_ring, &tp_name_ring, "progs/invisibl.mdl",
{0, 0, 16}, 12,
{0, 0, 16}, 12, 5*60
},
{ it_suit, &tp_name_suit, "progs/suit.mdl",
{0, 0, 24}, 20,
{0, 0, 24}, 20, 60
},
{ it_lg, &tp_name_lg, "progs/g_light.mdl",
{0, 0, 30}, 20,
{0, 0, 30}, 20, 30
},
{ it_rl, &tp_name_rl, "progs/g_rock2.mdl",
{0, 0, 30}, 20,
{0, 0, 30}, 20, 30
},
{ it_gl, &tp_name_gl, "progs/g_rock.mdl",
{0, 0, 30}, 20,
{0, 0, 30}, 20, 30
},
{ it_sng, &tp_name_sng, "progs/g_nail2.mdl",
{0, 0, 30}, 20,
{0, 0, 30}, 20, 30
},
{ it_ng, &tp_name_ng, "progs/g_nail.mdl",
{0, 0, 30}, 20,
{0, 0, 30}, 20, 30
},
{ it_ssg, &tp_name_ssg, "progs/g_shot.mdl",
{0, 0, 30}, 20,
{0, 0, 30}, 20, 30
},
{ it_cells, &tp_name_cells, "maps/b_batt0.bsp",
{16, 16, 24}, 18,
{16, 16, 24}, 18, 30
},
{ it_cells, &tp_name_cells, "maps/b_batt1.bsp",
{16, 16, 24}, 18,
{16, 16, 24}, 18, 30
},
{ it_rockets, &tp_name_rockets,"maps/b_rock0.bsp",
{8, 8, 20}, 18,
{8, 8, 20}, 18, 30
},
{ it_rockets, &tp_name_rockets,"maps/b_rock1.bsp",
{16, 8, 20}, 18,
{16, 8, 20}, 18, 30
},
{ it_nails, &tp_name_nails, "maps/b_nail0.bsp",
{16, 16, 10}, 18,
{16, 16, 10}, 18, 30
},
{ it_nails, &tp_name_nails, "maps/b_nail1.bsp",
{16, 16, 10}, 18,
{16, 16, 10}, 18, 30
},
{ it_shells, &tp_name_shells,"maps/b_shell0.bsp",
{16, 16, 10}, 18,
{16, 16, 10}, 18, 30
},
{ it_shells, &tp_name_shells,"maps/b_shell1.bsp",
{16, 16, 10}, 18,
{16, 16, 10}, 18, 30
},
{ it_health, &tp_name_health,"maps/b_bh10.bsp",
{16, 16, 8}, 18,
{16, 16, 8}, 18, 20
},
{ it_health, &tp_name_health,"maps/b_bh25.bsp",
{16, 16, 8}, 18,
{16, 16, 8}, 18, 20
},
{ it_mh, &tp_name_mh, "maps/b_bh100.bsp",
{16, 16, 14}, 20,
{16, 16, 14}, 20, 0
},
{ it_pack, &tp_name_backpack, "progs/backpack.mdl",
{0, 0, 18}, 18,
{0, 0, 18}, 18, 0
},
{ it_flag, &tp_name_flag, "progs/tf_flag.mdl",
{0, 0, 14}, 25,
{0, 0, 14}, 25, 0
},
{ it_flag, &tp_name_flag, "progs/tf_stan.mdl",
{0, 0, 45}, 40,
{0, 0, 45}, 40, 0
},
{ it_ra|it_ya|it_ga, NULL, "progs/armor.mdl",
{0, 0, 24}, 22,
{0, 0, 24}, 22, 0
},
{ it_ga, &tp_name_ga, "progs/armor.mdl",
{0, 0, 24}, 22, 20
},
{ it_ya, &tp_name_ya, "progs/armor.mdl",
{0, 0, 24}, 22, 20
},
{ it_ra, &tp_name_ra, "progs/armor.mdl",
{0, 0, 24}, 22, 20
},
{ it_flag, &tp_name_flag, "progs/w_g_key.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_flag, &tp_name_flag, "progs/w_s_key.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_flag, &tp_name_flag, "progs/m_g_key.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_flag, &tp_name_flag, "progs/m_s_key.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_flag, &tp_name_flag, "progs/b_s_key.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_flag, &tp_name_flag, "progs/b_g_key.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_flag, &tp_name_flag, "progs/flag.mdl",
{0, 0, 14}, 25,
{0, 0, 14}, 25, 0
},
{ it_runes, &tp_name_rune_1, "progs/end1.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_runes, &tp_name_rune_2, "progs/end2.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_runes, &tp_name_rune_3, "progs/end3.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_runes, &tp_name_rune_4, "progs/end4.mdl",
{0, 0, 20}, 18,
{0, 0, 20}, 18, 0
},
{ it_sentry, &tp_name_sentry, "progs/turrgun.mdl",
{0, 0, 23}, 25,
{0, 0, 23}, 25, 0
},
{ it_disp, &tp_name_disp, "progs/disp.mdl",
{0, 0, 24}, 25,
{0, 0, 24}, 25, 0
}
};
@ -2612,18 +2622,16 @@ static void TP_FindModelNumbers (void)
// on success, result is non-zero
// on failure, result is zero
// for armors, returns skinnum+1 on success
static int FindNearestItem (int flags, item_t **pitem)
static int FindNearestItem (vec3_t org, int flags, item_t **pitem)
{
inframe_t *frame;
packet_entities_t *pak;
entity_state_t *ent;
int i = 0, bestidx = 0, bestskin = 0;
float bestdist = 0.0, dist = 0.0;
vec3_t org, v;
vec3_t v;
item_t *item;
VectorCopy (cl.inframes[cl.validsequence&UPDATE_MASK]
.playerstate[cl.playerview[SP].playernum].origin, org);
entity_state_t *baseline;
// look in previous frame
frame = &cl.inframes[cl.oldvalidsequence&UPDATE_MASK];
@ -2647,14 +2655,39 @@ static int FindNearestItem (int flags, item_t **pitem)
if (dist <= bestdist) {
bestdist = dist;
bestidx = ent->modelindex;
bestidx = ent->number;
bestskin = ent->skinnum;
*pitem = item;
}
}
if (!bestidx)
for (i=1; i<cl_baselines_count ; i++)
{
baseline = &cl_baselines[i];
item = model2item[baseline->modelindex];
if (!item)
continue;
if ( ! (item->itemflag & flags) )
continue;
VectorCopy(baseline->origin, v);
VectorSubtract (v, org, v);
VectorAdd (v, item->offset, v);
dist = VectorLength (v);
// Com_Printf ("%s %f\n", item->modelname, dist);
if (dist <= bestdist) {
bestdist = dist;
bestidx = i;
bestskin = baseline->skinnum;
*pitem = item;
}
}
if (bestidx && (*pitem)->itemflag == it_armor)
return bestskin + 1; // 1=green, 2=yellow, 3=red
if (bestskin >= 0 && bestskin <= 3)
*pitem += bestskin + 1;
return bestidx;
}
@ -2708,7 +2741,7 @@ static qboolean CheckTrigger (void)
return count;
}
static void ExecTookTrigger (char *s, int flag, vec3_t org)
static void ExecTookTrigger_ (char *s, int flag, vec3_t org)
{
int pkflags_dmm, tookflags_dmm;
@ -2732,6 +2765,34 @@ static void ExecTookTrigger (char *s, int flag, vec3_t org)
TP_ExecTrigger ("f_took", false);
}
/*
void TP_GetSimpleItemTexture ()
{
}
*/
static void TP_ItemTaken (char *s, int flag, vec3_t org, int entnum, item_t *item, int seat)
{
if (seat == 0)
ExecTookTrigger_(s, flag, org);
/* if (entnum < cl_baselines_count && cl_baselines[entnum].modelindex && item && item->respawntime && (cl.spectator || cls.demoplayback))
{
struct itemtimer_s *timer = Z_Malloc(sizeof(*timer));
timer->next = cl.itemtimers;
cl.itemtimers = timer;
timer->origin[0] = cl_baselines[entnum].origin[0] + item->offset[0];
timer->origin[1] = cl_baselines[entnum].origin[1] + item->offset[1];
timer->origin[2] = cl_baselines[entnum].origin[2];
timer->start = cl.time;
timer->duration = item->respawntime;
timer->end = cl.time + item->respawntime;
timer->radius = item->radius;
timer->entnum = entnum;
}
*/
}
void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_info_t *info)
{
// if (TP_NeedRefreshSkins())
@ -2763,7 +2824,7 @@ void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_
{
if ((state->effects & (QWEF_FLAG1|QWEF_FLAG2)) && !(oldstate->effects & (QWEF_FLAG1|QWEF_FLAG2)))
{
ExecTookTrigger (tp_name_flag.string, it_flag, cl.inframes[cl.validsequence & UPDATE_MASK].playerstate[cl.playerview[SP].playernum].origin);
ExecTookTrigger_ (tp_name_flag.string, it_flag, cl.inframes[cl.validsequence & UPDATE_MASK].playerstate[cl.playerview[SP].playernum].origin);
}
else if (!(state->effects & (QWEF_FLAG1|QWEF_FLAG2)) && (oldstate->effects & (QWEF_FLAG1|QWEF_FLAG2)))
{
@ -2773,24 +2834,47 @@ void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_
}
}
void TP_CheckPickupSound (char *s, vec3_t org)
void TP_CheckPickupSound (char *s, vec3_t org, int seat)
{
int entnum;
item_t *item;
//if we're spectating, we don't want to do any actual triggers, so pretend it was someone else.
if (cl.spectator)
return;
seat = -1;
//FIXME: on items/itembk2.wav kill relevant item timer.
if (!strcmp(s, "items/damage.wav"))
ExecTookTrigger (tp_name_quad.string, it_quad, org);
{
entnum = FindNearestItem (org, it_quad, &item);
TP_ItemTaken (tp_name_quad.string, it_quad, org, entnum, item, seat);
}
else if (!strcmp(s, "items/protect.wav"))
ExecTookTrigger (tp_name_pent.string, it_pent, org);
{
entnum = FindNearestItem (org, it_pent, &item);
TP_ItemTaken (tp_name_pent.string, it_pent, org, entnum, item, seat);
}
else if (!strcmp(s, "items/inv1.wav"))
ExecTookTrigger (tp_name_ring.string, it_ring, org);
{
entnum = FindNearestItem (org, it_ring, &item);
TP_ItemTaken (tp_name_ring.string, it_ring, org, entnum, item, seat);
}
else if (!strcmp(s, "items/suit.wav"))
ExecTookTrigger (tp_name_suit.string, it_suit, org);
{
entnum = FindNearestItem (org, it_suit, &item);
TP_ItemTaken (tp_name_suit.string, it_suit, org, entnum, item, seat);
}
else if (!strcmp(s, "items/health1.wav") ||
!strcmp(s, "items/r_item1.wav"))
ExecTookTrigger (tp_name_health.string, it_health, org);
{
entnum = FindNearestItem (org, it_health, &item);
TP_ItemTaken (tp_name_health.string, it_health, org, entnum, item, seat);
}
else if (!strcmp(s, "items/r_item2.wav"))
ExecTookTrigger (tp_name_mh.string, it_mh, org);
{
entnum = FindNearestItem (org, it_mh, &item);
TP_ItemTaken (tp_name_mh.string, it_mh, org, entnum, item, seat);
}
else
goto more;
return;
@ -2802,27 +2886,26 @@ more:
// weapons
if (!strcmp(s, "weapons/pkup.wav"))
{
item_t *item;
if (FindNearestItem (it_weapons, &item)) {
ExecTookTrigger (item->cvar->string, item->itemflag, org);
}
else
entnum = FindNearestItem (org, it_weapons, &item);
if (item)
TP_ItemTaken (item->cvar->string, item->itemflag, org, entnum, item, seat);
else if (seat >= 0)
{
// we don't know what entity caused the sound, try to guess...
if (vars.stat_framecounts[STAT_ITEMS] == cls.framecount)
{
if (vars.items & ~vars.olditems & IT_LIGHTNING)
ExecTookTrigger (tp_name_lg.string, it_lg, cl.playerview[SP].simorg);
TP_ItemTaken (tp_name_lg.string, it_lg, cl.playerview[SP].simorg, entnum, item, seat);
else if (vars.items & ~vars.olditems & IT_ROCKET_LAUNCHER)
ExecTookTrigger (tp_name_rl.string, it_rl, cl.playerview[SP].simorg);
TP_ItemTaken (tp_name_rl.string, it_rl, cl.playerview[SP].simorg, entnum, item, seat);
else if (vars.items & ~vars.olditems & IT_GRENADE_LAUNCHER)
ExecTookTrigger (tp_name_gl.string, it_gl, cl.playerview[SP].simorg);
TP_ItemTaken (tp_name_gl.string, it_gl, cl.playerview[SP].simorg, entnum, item, seat);
else if (vars.items & ~vars.olditems & IT_SUPER_NAILGUN)
ExecTookTrigger (tp_name_sng.string, it_sng, cl.playerview[SP].simorg);
TP_ItemTaken (tp_name_sng.string, it_sng, cl.playerview[SP].simorg, entnum, item, seat);
else if (vars.items & ~vars.olditems & IT_NAILGUN)
ExecTookTrigger (tp_name_ng.string, it_ng, cl.playerview[SP].simorg);
TP_ItemTaken (tp_name_ng.string, it_ng, cl.playerview[SP].simorg, entnum, item, seat);
else if (vars.items & ~vars.olditems & IT_SUPER_SHOTGUN)
ExecTookTrigger (tp_name_ssg.string, it_ssg, cl.playerview[SP].simorg);
TP_ItemTaken (tp_name_ssg.string, it_ssg, cl.playerview[SP].simorg, entnum, item, seat);
}
}
return;
@ -2833,16 +2916,20 @@ more:
{
item_t *item;
qbool armor_updated;
int armortype;
armor_updated = (vars.stat_framecounts[STAT_ARMOR] == cls.framecount);
armortype = FindNearestItem (it_armor, &item);
if (armortype == 1 || (!armortype && armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 100))
ExecTookTrigger (tp_name_ga.string, it_ga, org);
else if (armortype == 2 || (!armortype && armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 150))
ExecTookTrigger (tp_name_ya.string, it_ya, org);
else if (armortype == 3 || (!armortype && armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 200))
ExecTookTrigger (tp_name_ra.string, it_ra, org);
entnum = FindNearestItem (org, it_armor, &item);
if (item)
TP_ItemTaken (item->cvar->string, item->itemflag, org, entnum, item, seat);
else if (seat >= 0)
{
if (armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 100)
TP_ItemTaken (tp_name_ga.string, it_ga, org, entnum, NULL, seat);
else if (armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 150)
TP_ItemTaken (tp_name_ya.string, it_ya, org, entnum, NULL, seat);
else if (armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 200)
TP_ItemTaken (tp_name_ra.string, it_ra, org, entnum, NULL, seat);
}
return;
}
@ -2850,9 +2937,10 @@ more:
if (!strcmp (s, "weapons/lock4.wav"))
{
item_t *item;
if (!FindNearestItem (it_ammo|it_pack|it_runes, &item))
entnum = FindNearestItem (org, it_ammo|it_pack|it_runes, &item);
if (!item && seat < 0)
return;
ExecTookTrigger (item->cvar->string, item->itemflag, org);
TP_ItemTaken (item->cvar->string, item->itemflag, org, entnum, item, seat);
}
}
@ -3290,7 +3378,7 @@ void TP_StatChanged (int stat, int value)
if (i & (IT_KEY1|IT_KEY2)) {
if (cl.teamfortress && !cl.spectator)
{
ExecTookTrigger (tp_name_flag.string, it_flag,
ExecTookTrigger_ (tp_name_flag.string, it_flag,
cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[cl.playerview[SP].playernum].origin);
}
}

View File

@ -31,7 +31,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define FTEPLUGIN
#define pCvar_Register Cvar_Get
#define pCvar_GetFloat(x) Cvar_FindVar(x)->value
#define pSys_Error Sys_Error
#define Sys_Errorf Sys_Error
#define pSys_Error(p) Sys_Errorf("%s",p)
#define Plug_Init Plug_ODE_Init
#endif
@ -2228,7 +2229,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
dMassSetCylinderTotal(&mass, massval, axisindex+1, radius, length);
break;
default:
pSys_Error(va("World_ODE_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid));
Sys_Errorf("World_ODE_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
}
Matrix3x4_InvertTo4x4_Simple(ed->ode.ode_offsetmatrix, ed->ode.ode_offsetimatrix);
ed->ode.ode_massbuf = BZ_Malloc(sizeof(dMass));

View File

@ -1946,20 +1946,20 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
shaderstate.lcbuffer //light buffer that changes rarelyish
};
//FIXME: how many of these calls can we avoid?
ID3D11DeviceContext_IASetInputLayout(d3ddevctx, prog->permu[permu].handle.hlsl.layout);
ID3D11DeviceContext_VSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.vert, NULL, 0);
ID3D11DeviceContext_HSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.hull, NULL, 0);
ID3D11DeviceContext_DSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.domain, NULL, 0);
ID3D11DeviceContext_GSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.geom, NULL, 0);
ID3D11DeviceContext_PSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.frag, NULL, 0);
ID3D11DeviceContext_IASetPrimitiveTopology(d3ddevctx, prog->permu[permu].handle.hlsl.topology);
ID3D11DeviceContext_IASetInputLayout(d3ddevctx, prog->permu[permu].h.hlsl.layout);
ID3D11DeviceContext_VSSetShader(d3ddevctx, prog->permu[permu].h.hlsl.vert, NULL, 0);
ID3D11DeviceContext_HSSetShader(d3ddevctx, prog->permu[permu].h.hlsl.hull, NULL, 0);
ID3D11DeviceContext_DSSetShader(d3ddevctx, prog->permu[permu].h.hlsl.domain, NULL, 0);
ID3D11DeviceContext_GSSetShader(d3ddevctx, prog->permu[permu].h.hlsl.geom, NULL, 0);
ID3D11DeviceContext_PSSetShader(d3ddevctx, prog->permu[permu].h.hlsl.frag, NULL, 0);
ID3D11DeviceContext_IASetPrimitiveTopology(d3ddevctx, prog->permu[permu].h.hlsl.topology);
ID3D11DeviceContext_VSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
if (prog->permu[permu].handle.hlsl.hull)
if (prog->permu[permu].h.hlsl.hull)
ID3D11DeviceContext_HSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
if (prog->permu[permu].handle.hlsl.domain)
if (prog->permu[permu].h.hlsl.domain)
ID3D11DeviceContext_DSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
if (prog->permu[permu].handle.hlsl.geom)
if (prog->permu[permu].h.hlsl.geom)
ID3D11DeviceContext_GSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
ID3D11DeviceContext_PSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
}
@ -1971,13 +1971,13 @@ static void BE_RenderMeshProgram(const shader_t *s, unsigned int vertcount, unsi
program_t *p = s->prog;
if (TEXLOADED(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].handle.hlsl.vert)
if (TEXLOADED(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].h.loaded)
perm |= PERMUTATION_BUMPMAP;
if (TEXLOADED(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].handle.hlsl.vert)
if (TEXLOADED(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].h.loaded)
perm |= PERMUTATION_FULLBRIGHT;
if (p->permu[perm|PERMUTATION_UPPERLOWER].handle.hlsl.vert && (TEXLOADED(shaderstate.curtexnums->upperoverlay) || TEXLOADED(shaderstate.curtexnums->loweroverlay)))
if (p->permu[perm|PERMUTATION_UPPERLOWER].h.loaded && (TEXLOADED(shaderstate.curtexnums->upperoverlay) || TEXLOADED(shaderstate.curtexnums->loweroverlay)))
perm |= PERMUTATION_UPPERLOWER;
if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].handle.hlsl.vert)
if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].h.loaded)
perm |= PERMUTATION_FOG;
// if (r_glsl_offsetmapping.ival && TEXLOADED(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET.hlsl.vert)
// perm |= PERMUTATION_OFFSET;

View File

@ -220,9 +220,9 @@ void D3D11Shader_DeleteProg(program_t *prog, unsigned int permu)
ID3D11InputLayout *layout;
ID3D11PixelShader *frag;
ID3D11VertexShader *vert;
vert = prog->permu[permu].handle.hlsl.vert;
frag = prog->permu[permu].handle.hlsl.frag;
layout = prog->permu[permu].handle.hlsl.layout;
vert = prog->permu[permu].h.hlsl.vert;
frag = prog->permu[permu].h.hlsl.frag;
layout = prog->permu[permu].h.hlsl.layout;
if (vert)
ID3D11VertexShader_Release(vert);
if (frag)
@ -241,25 +241,25 @@ static qboolean D3D11Shader_CreateShaders(program_t *prog, const char *name, int
{
qboolean success = true;
if (FAILED(ID3D11Device_CreateVertexShader(pD3DDev11, vblob, vsize, NULL, (ID3D11VertexShader**)&prog->permu[permu].handle.hlsl.vert)))
if (FAILED(ID3D11Device_CreateVertexShader(pD3DDev11, vblob, vsize, NULL, (ID3D11VertexShader**)&prog->permu[permu].h.hlsl.vert)))
success = false;
if (hblob || dblob)
{
prog->permu[permu].handle.hlsl.topology = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST;
if (FAILED(ID3D11Device_CreateHullShader(pD3DDev11, hblob, hsize, NULL, (ID3D11HullShader**)&prog->permu[permu].handle.hlsl.hull)))
prog->permu[permu].h.hlsl.topology = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST;
if (FAILED(ID3D11Device_CreateHullShader(pD3DDev11, hblob, hsize, NULL, (ID3D11HullShader**)&prog->permu[permu].h.hlsl.hull)))
success = false;
if (FAILED(ID3D11Device_CreateDomainShader(pD3DDev11, dblob, dsize, NULL, (ID3D11DomainShader**)&prog->permu[permu].handle.hlsl.domain)))
if (FAILED(ID3D11Device_CreateDomainShader(pD3DDev11, dblob, dsize, NULL, (ID3D11DomainShader**)&prog->permu[permu].h.hlsl.domain)))
success = false;
}
else
prog->permu[permu].handle.hlsl.topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
prog->permu[permu].h.hlsl.topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
if (gblob && FAILED(ID3D11Device_CreateGeometryShader(pD3DDev11, gblob, gsize, NULL, (ID3D11GeometryShader**)&prog->permu[permu].handle.hlsl.geom)))
if (gblob && FAILED(ID3D11Device_CreateGeometryShader(pD3DDev11, gblob, gsize, NULL, (ID3D11GeometryShader**)&prog->permu[permu].h.hlsl.geom)))
success = false;
if (FAILED(ID3D11Device_CreatePixelShader(pD3DDev11, fblob, fsize, NULL, (ID3D11PixelShader**)&prog->permu[permu].handle.hlsl.frag)))
if (FAILED(ID3D11Device_CreatePixelShader(pD3DDev11, fblob, fsize, NULL, (ID3D11PixelShader**)&prog->permu[permu].h.hlsl.frag)))
success = false;
if (success)
@ -350,7 +350,7 @@ static qboolean D3D11Shader_CreateShaders(program_t *prog, const char *name, int
decl[elements].InstanceDataStepRate = 0;
elements++;
*/
if (FAILED(ID3D11Device_CreateInputLayout(pD3DDev11, decl, elements, vblob, vsize, (ID3D11InputLayout**)&prog->permu[permu].handle.hlsl.layout)))
if (FAILED(ID3D11Device_CreateInputLayout(pD3DDev11, decl, elements, vblob, vsize, (ID3D11InputLayout**)&prog->permu[permu].h.hlsl.layout)))
{
Con_Printf("HLSL Shader %s requires unsupported inputs\n", name);
success = false;
@ -479,12 +479,12 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
fsformat = "ps_4_0_level_9_1";
}
prog->permu[permu].handle.hlsl.vert = NULL;
prog->permu[permu].handle.hlsl.frag = NULL;
prog->permu[permu].handle.hlsl.hull = NULL;
prog->permu[permu].handle.hlsl.domain = NULL;
prog->permu[permu].handle.hlsl.geom = NULL;
prog->permu[permu].handle.hlsl.layout = NULL;
prog->permu[permu].h.hlsl.vert = NULL;
prog->permu[permu].h.hlsl.frag = NULL;
prog->permu[permu].h.hlsl.hull = NULL;
prog->permu[permu].h.hlsl.domain = NULL;
prog->permu[permu].h.hlsl.geom = NULL;
prog->permu[permu].h.hlsl.layout = NULL;
if (pD3DCompile)
{

View File

@ -1748,17 +1748,17 @@ static void R_FetchPlayerColour(unsigned int cv, vec3_t rgb)
static void BE_ApplyUniforms(program_t *prog, int permu)
{
struct programpermu_s *perm = &prog->permu[permu];
shaderprogparm_t *pp;
vec4_t param4;
int h;
int i;
IDirect3DDevice9_SetVertexShader(pD3DDev9, prog->permu[permu].handle.hlsl.vert);
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[permu].handle.hlsl.frag);
for (i = 0; i < prog->numparams; i++)
IDirect3DDevice9_SetVertexShader(pD3DDev9, perm->h.hlsl.vert);
IDirect3DDevice9_SetPixelShader(pD3DDev9, perm->h.hlsl.frag);
for (i = 0, pp = perm->parm; i < perm->numparms; i++, pp++)
{
h = prog->permu[permu].parm[i];
if (h == -1)
continue;
switch (prog->parm[i].type)
h = pp->handle;
switch (pp->type)
{
case SP_M_PROJECTION:
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, d3d_trueprojection, 4);
@ -1865,7 +1865,7 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
case SP_CVARF:
case SP_CVAR3F:
case SP_TEXTURE:
Con_Printf("shader property %i not implemented\n", prog->parm[i].type);
Con_Printf("shader property %i not implemented\n", pp->type);
break;
}
}
@ -1881,27 +1881,27 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned in
if (shaderstate.batchvbo && shaderstate.batchvbo->numbones)
{
if (p->permu[perm|PERMUTATION_SKELETAL].handle.hlsl.vert)
if (p->permu[perm|PERMUTATION_SKELETAL].h.loaded)
perm |= PERMUTATION_SKELETAL;
else
return;
}
if (TEXVALID(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].handle.hlsl.vert)
if (TEXVALID(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].h.loaded)
perm |= PERMUTATION_BUMPMAP;
if (TEXVALID(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].handle.hlsl.vert)
if (TEXVALID(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].h.loaded)
perm |= PERMUTATION_FULLBRIGHT;
if (p->permu[perm|PERMUTATION_UPPERLOWER].handle.hlsl.vert && (TEXLOADED(shaderstate.curtexnums->upperoverlay) || TEXLOADED(shaderstate.curtexnums->loweroverlay)))
if (p->permu[perm|PERMUTATION_UPPERLOWER].h.loaded && (TEXLOADED(shaderstate.curtexnums->upperoverlay) || TEXLOADED(shaderstate.curtexnums->loweroverlay)))
perm |= PERMUTATION_UPPERLOWER;
if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].handle.hlsl.vert)
if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].h.loaded)
perm |= PERMUTATION_FOG;
if (p->permu[perm|PERMUTATION_FRAMEBLEND].handle.hlsl.vert && shaderstate.batchvbo && shaderstate.batchvbo->coord2.d3d.buff)
if (p->permu[perm|PERMUTATION_FRAMEBLEND].h.loaded && shaderstate.batchvbo && shaderstate.batchvbo->coord2.d3d.buff)
{
perm |= PERMUTATION_FRAMEBLEND;
vdec |= D3D_VDEC_POS2;
}
// if (p->permu[perm|PERMUTATION_DELUXE].handle.hlsl.vert && TEXVALID(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe)
// if (p->permu[perm|PERMUTATION_DELUXE].h.loaded && TEXVALID(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe)
// perm |= PERMUTATION_DELUXE;
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].handle.hlsl.vert)
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].h.loaded)
perm |= PERMUTATION_LIGHTSTYLES;
BE_ApplyUniforms(p, perm);

View File

@ -155,8 +155,8 @@ static qboolean D3D9Shader_CreateProgram (program_t *prog, const char *sname, un
return false;
}
prog->permu[permu].handle.hlsl.vert = NULL;
prog->permu[permu].handle.hlsl.frag = NULL;
prog->permu[permu].h.hlsl.vert = NULL;
prog->permu[permu].h.hlsl.frag = NULL;
if (pD3DXCompileShader)
{
@ -190,11 +190,11 @@ static qboolean D3D9Shader_CreateProgram (program_t *prog, const char *sname, un
success = true;
defines[0].Name = "VERTEX_SHADER";
if (FAILED(pD3DXCompileShader(vert, strlen(vert), defines, NULL, "main", "vs_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].handle.hlsl.ctabv)))
if (FAILED(pD3DXCompileShader(vert, strlen(vert), defines, NULL, "main", "vs_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].h.hlsl.ctabv)))
success = false;
else
{
IDirect3DDevice9_CreateVertexShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DVertexShader9**)&prog->permu[permu].handle.hlsl.vert);
IDirect3DDevice9_CreateVertexShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DVertexShader9**)&prog->permu[permu].h.hlsl.vert);
code->lpVtbl->Release(code);
}
if (errors)
@ -205,11 +205,11 @@ static qboolean D3D9Shader_CreateProgram (program_t *prog, const char *sname, un
}
defines[0].Name = "FRAGMENT_SHADER";
if (FAILED(pD3DXCompileShader(frag, strlen(frag), defines, NULL, "main", "ps_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].handle.hlsl.ctabf)))
if (FAILED(pD3DXCompileShader(frag, strlen(frag), defines, NULL, "main", "ps_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].h.hlsl.ctabf)))
success = false;
else
{
IDirect3DDevice9_CreatePixelShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DPixelShader9**)&prog->permu[permu].handle.hlsl.frag);
IDirect3DDevice9_CreatePixelShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DPixelShader9**)&prog->permu[permu].h.hlsl.frag);
code->lpVtbl->Release(code);
}
if (errors)
@ -254,13 +254,13 @@ static int D3D9Shader_FindUniform(union programhandle_u *h, int type, const char
return -1;
}
static void D3D9Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvartypes)
static void D3D9Shader_ProgAutoFields(program_t *prog, const char *progname, char **cvarnames, int *cvartypes)
{
struct programpermu_s *pp;
unsigned int i, p;
qboolean found;
int uniformloc;
char tmpname[128];
cvar_t *cvar;
cvar_t *cvar[128];
static const char *defaultsamplers[] =
{
@ -289,66 +289,76 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cv
#define ALTLIGHTMAPSAMP 13
#define ALTDELUXMAPSAMP 16
prog->numparams = 0;
prog->nofixedcompat = true;
prog->defaulttextures = 0;
prog->numsamplers = 0;
/*set cvar uniforms*/
for (i = 0; cvarnames[i]; i++)
memset(cvar, 0, sizeof(cvar));
for (p = 0; p < PERMUTATIONS; p++)
{
for (p = 0; cvarnames[i][p] && (unsigned char)cvarnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
tmpname[p] = cvarnames[i][p];
tmpname[p] = 0;
cvar = Cvar_FindVar(tmpname);
if (!cvar)
int maxparms = 0;
pp = &prog->permu[p];
pp->parm = NULL;
pp->numparms = 0;
if (!pp->h.loaded)
continue;
cvar->flags |= CVAR_SHADERSYSTEM;
for (p = 0; p < PERMUTATIONS; p++)
IDirect3DDevice9_SetVertexShader(pD3DDev9, pp->h.hlsl.vert);
IDirect3DDevice9_SetPixelShader(pD3DDev9, pp->h.hlsl.frag);
for (i = 0; shader_unif_names[i].name; i++)
{
if (!prog->permu[p].handle.hlsl.vert || !prog->permu[p].handle.hlsl.frag)
continue;
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 1, va("cvar_%s", tmpname));
uniformloc = D3D9Shader_FindUniform(&pp->h, 0, shader_unif_names[i].name);
if (uniformloc != -1)
{
vec4_t v = {cvar->value, 0, 0, 0};
IDirect3DDevice9_SetVertexShader(pD3DDev9, prog->permu[p].handle.hlsl.vert);
if (pp->numparms == maxparms)
{
maxparms = maxparms?maxparms*2:8;
pp->parm = BZ_Realloc(pp->parm, sizeof(*pp->parm) * maxparms);
}
pp->parm[pp->numparms].handle = uniformloc;
pp->parm[pp->numparms].type = shader_unif_names[i].ptype;
pp->numparms++;
}
}
for (i = 0; cvarnames[i] && i < countof(cvar); i++)
{
if (!cvar[i])
{
for (p = 0; cvarnames[i][p] && (unsigned char)cvarnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
tmpname[p] = cvarnames[i][p];
tmpname[p] = 0;
cvar[i] = Cvar_FindVar(tmpname);
if (!cvar[i])
continue;
cvar[i]->flags |= CVAR_SHADERSYSTEM;
}
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].h, 1, va("cvar_%s", tmpname));
if (uniformloc != -1)
{
vec4_t v = {cvar[i]->value, 0, 0, 0};
IDirect3DDevice9_SetVertexShader(pD3DDev9, prog->permu[p].h.hlsl.vert);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, 0, v, 1);
}
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 2, va("cvar_%s", tmpname));
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].h, 2, va("cvar_%s", tmpname));
if (uniformloc != -1)
{
vec4_t v = {cvar->value, 0, 0, 0};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].handle.hlsl.frag);
vec4_t v = {cvar[i]->value, 0, 0, 0};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].h.hlsl.frag);
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, 0, v, 1);
}
}
}
for (i = 0; shader_unif_names[i].name; i++)
{
found = false;
for (p = 0; p < PERMUTATIONS; p++)
{
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 0, shader_unif_names[i].name);
if (uniformloc != -1)
found = true;
prog->permu[p].parm[prog->numparams] = uniformloc;
}
if (found)
{
prog->parm[prog->numparams].type = shader_unif_names[i].ptype;
prog->numparams++;
}
}
/*set texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++)
{
/*set texture uniforms*/
for (i = 0; i < 8; i++)
{
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 2, va("s_t%i", i));
uniformloc = D3D9Shader_FindUniform(&pp->h, 2, va("s_t%i", i));
if (uniformloc != -1)
{
int v[4] = {i};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].handle.hlsl.frag);
IDirect3DDevice9_SetPixelShader(pD3DDev9, pp->h.hlsl.frag);
IDirect3DDevice9_SetPixelShaderConstantI(pD3DDev9, 0, v, 1);
if (prog->numsamplers < i+1)
@ -361,7 +371,7 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cv
//figure out which ones are needed.
if (prog->defaulttextures & (1u<<i))
continue; //don't spam
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 2, defaultsamplers[i]);
uniformloc = D3D9Shader_FindUniform(&pp->h, 2, defaultsamplers[i]);
if (uniformloc != -1)
prog->defaulttextures |= (1u<<i);
}
@ -379,18 +389,18 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cv
/*set default texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl.handle)
if (!prog->permu[p].h.loaded)
continue;
sampnum = prog->numsamplers;
for (i = 0; i < sizeof(defaultsamplers)/sizeof(defaultsamplers[0]); i++)
{
if (prog->defaulttextures & (1u<<i))
{
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 2, defaultsamplers[i]);
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].h, 2, defaultsamplers[i]);
if (uniformloc != -1)
{
int v[4] = {sampnum};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].handle.hlsl.frag);
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].h.hlsl.frag);
IDirect3DDevice9_SetPixelShaderConstantI(pD3DDev9, 0, v, 1);
}
sampnum++;
@ -404,28 +414,28 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cv
void D3D9Shader_DeleteProg(program_t *prog, unsigned int permu)
{
if (prog->permu[permu].handle.hlsl.vert)
if (prog->permu[permu].h.hlsl.vert)
{
IDirect3DVertexShader9 *vs = prog->permu[permu].handle.hlsl.vert;
prog->permu[permu].handle.hlsl.vert = NULL;
IDirect3DVertexShader9 *vs = prog->permu[permu].h.hlsl.vert;
prog->permu[permu].h.hlsl.vert = NULL;
IDirect3DVertexShader9_Release(vs);
}
if (prog->permu[permu].handle.hlsl.frag)
if (prog->permu[permu].h.hlsl.frag)
{
IDirect3DPixelShader9 *fs = prog->permu[permu].handle.hlsl.frag;
prog->permu[permu].handle.hlsl.frag = NULL;
IDirect3DPixelShader9 *fs = prog->permu[permu].h.hlsl.frag;
prog->permu[permu].h.hlsl.frag = NULL;
IDirect3DPixelShader9_Release(fs);
}
if (prog->permu[permu].handle.hlsl.ctabv)
if (prog->permu[permu].h.hlsl.ctabv)
{
LPD3DXCONSTANTTABLE vct = prog->permu[permu].handle.hlsl.ctabv;
prog->permu[permu].handle.hlsl.ctabv = NULL;
LPD3DXCONSTANTTABLE vct = prog->permu[permu].h.hlsl.ctabv;
prog->permu[permu].h.hlsl.ctabv = NULL;
IUnknown_Release(vct);
}
if (prog->permu[permu].handle.hlsl.ctabf)
if (prog->permu[permu].h.hlsl.ctabf)
{
LPD3DXCONSTANTTABLE fct = prog->permu[permu].handle.hlsl.ctabf;
prog->permu[permu].handle.hlsl.ctabf = NULL;
LPD3DXCONSTANTTABLE fct = prog->permu[permu].h.hlsl.ctabf;
prog->permu[permu].h.hlsl.ctabf = NULL;
IUnknown_Release(fct);
}
}

View File

@ -346,6 +346,25 @@ static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
INS_RawInput_Read((HANDLE)lParam);
break;
case WM_SETCURSOR:
//only use a custom cursor if the cursor is inside the client area
switch(lParam&0xffff)
{
case 0:
break;
case HTCLIENT:
if (hCustomCursor) //custom cursor enabled
SetCursor(hCustomCursor);
else //fallback on an arrow cursor, just so we have something visible at startup or so
SetCursor(hArrowCursor);
lRet = TRUE;
break;
default:
lRet = DefWindowProcW (hWnd, uMsg, wParam, lParam);
break;
}
break;
case WM_GETMINMAXINFO:
{
RECT windowrect;
@ -665,7 +684,7 @@ static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette)
CLASSNAME
};
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hCursor = hArrowCursor = LoadCursor (NULL,IDC_ARROW);
vid_initializing = true;
@ -734,6 +753,12 @@ static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette)
// D3D9BE_Reset(false);
//FIXME: old hardware is not guarenteed to support hardware cursors.
//this should not be a problem on dx9+ hardware, but might on earlier stuff.
rf->VID_CreateCursor = WIN_CreateCursor;
rf->VID_DestroyCursor = WIN_DestroyCursor;
rf->VID_SetCursor = WIN_SetCursor;
return true;
}

View File

@ -484,6 +484,25 @@ static LRESULT WINAPI D3D11_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
INS_RawInput_Read((HANDLE)lParam);
break;
case WM_SETCURSOR:
//only use a custom cursor if the cursor is inside the client area
switch(lParam&0xffff)
{
case 0:
break;
case HTCLIENT:
if (hCustomCursor) //custom cursor enabled
SetCursor(hCustomCursor);
else //fallback on an arrow cursor, just so we have something visible at startup or so
SetCursor(hArrowCursor);
lRet = TRUE;
break;
default:
lRet = DefWindowProcW (hWnd, uMsg, wParam, lParam);
break;
}
break;
case WM_GETMINMAXINFO:
{
RECT windowrect;
@ -921,7 +940,7 @@ static qboolean D3D11_VID_Init(rendererstate_t *info, unsigned char *palette)
};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hCursor = hArrowCursor = LoadCursor (NULL,IDC_ARROW);
wc.hInstance = global_hInstance;
vid_initializing = true;
@ -983,6 +1002,10 @@ static qboolean D3D11_VID_Init(rendererstate_t *info, unsigned char *palette)
mouseactive = false;
}
rf->VID_CreateCursor = WIN_CreateCursor;
rf->VID_DestroyCursor = WIN_DestroyCursor;
rf->VID_SetCursor = WIN_SetCursor;
return true;
}
#endif

View File

@ -710,7 +710,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
(tex->upperoverlay && (tex->upperoverlay->status == TEX_LOADING || tex->upperoverlay->status == TEX_LOADED)))
return shader;
}
if (shader->prog && shader->prog->permu[PERMUTATION_UPPERLOWER].handle.glsl.handle && !h2playertranslations)
if (shader->prog && shader->prog->permu[PERMUTATION_UPPERLOWER].h.loaded && !h2playertranslations)
{ //this shader can do permutations. this means we can generate only a black image, with separate top+bottom textures.
tc = 0xfe000000;
bc = 0xfe000000;
@ -1442,7 +1442,7 @@ void R_GAlias_DrawBatch(batch_t *batch)
{
if (batch->surf_first == surfnum)
{
/*needrecolour =*/ Alias_GAliasBuildMesh(&mesh, &batch->vbo, inf, surfnum, e, batch->shader->prog && batch->shader->prog->permu[PERMUTATION_SKELETAL].handle.glsl.handle);
/*needrecolour =*/ Alias_GAliasBuildMesh(&mesh, &batch->vbo, inf, surfnum, e, batch->shader->prog && batch->shader->prog->permu[PERMUTATION_SKELETAL].h.loaded);
batch->mesh = &meshl;
if (!mesh.numindexes)
{

View File

@ -2962,13 +2962,10 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
if (entunchanged)
return;
for (i = 0; i < prog->numparams; i++)
p = prog->permu[perm].parm;
for (i = prog->permu[perm].numparms; i > 0; i--, p++)
{
p = &prog->parm[i];
ph = prog->permu[perm].parm[i];
if (ph == -1)
continue; /*not in this permutation*/
ph = p->handle;
switch(p->type)
{
/*
@ -3390,39 +3387,39 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
perm = 0;
if (shaderstate.sourcevbo->numbones)
{
if (p->permu[perm|PERMUTATION_SKELETAL].handle.glsl.handle)
if (p->permu[perm|PERMUTATION_SKELETAL].h.loaded)
perm |= PERMUTATION_SKELETAL;
else
return;
}
if (p->permu[perm|PERMUTATION_FRAMEBLEND].handle.glsl.handle && shaderstate.sourcevbo->coord2.gl.addr)
if (p->permu[perm|PERMUTATION_FRAMEBLEND].h.loaded && shaderstate.sourcevbo->coord2.gl.addr)
perm |= PERMUTATION_FRAMEBLEND;
if (TEXLOADED(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].handle.glsl.handle)
if (TEXLOADED(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].h.loaded)
perm |= PERMUTATION_BUMPMAP;
if (TEXLOADED(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].handle.glsl.handle)
if (TEXLOADED(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].h.loaded)
perm |= PERMUTATION_FULLBRIGHT;
if ((TEXLOADED(shaderstate.curtexnums->loweroverlay) || TEXLOADED(shaderstate.curtexnums->upperoverlay)) && p->permu[perm|PERMUTATION_UPPERLOWER].handle.glsl.handle)
if ((TEXLOADED(shaderstate.curtexnums->loweroverlay) || TEXLOADED(shaderstate.curtexnums->upperoverlay)) && p->permu[perm|PERMUTATION_UPPERLOWER].h.loaded)
perm |= PERMUTATION_UPPERLOWER;
if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].handle.glsl.handle)
if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].h.loaded)
perm |= PERMUTATION_FOG;
// if (p->permu[perm|PERMUTATION_DELUXE].handle.glsl.handle && TEXLOADED(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe)
// perm |= PERMUTATION_DELUXE;
if (TEXLOADED(shaderstate.curtexnums->reflectcube) && p->permu[perm|PERMUTATION_REFLECTCUBEMASK].handle.glsl.handle)
if (TEXLOADED(shaderstate.curtexnums->reflectcube) && p->permu[perm|PERMUTATION_REFLECTCUBEMASK].h.loaded)
perm |= PERMUTATION_REFLECTCUBEMASK;
#if MAXRLIGHTMAPS > 1
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].handle.glsl.handle)
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].h.loaded)
perm |= PERMUTATION_LIGHTSTYLES;
#endif
GL_SelectProgram(p->permu[perm].handle.glsl.handle);
GL_SelectProgram(p->permu[perm].h.glsl.handle);
#ifndef FORCESTATE
if (shaderstate.lastuniform == p->permu[perm].handle.glsl.handle)
if (shaderstate.lastuniform == shaderstate.currentprogram)
i = true;
else
#endif
{
i = false;
shaderstate.lastuniform = p->permu[perm].handle.glsl.handle;
shaderstate.lastuniform = shaderstate.currentprogram;
}
BE_Program_Set_Attributes(p, perm, i);
@ -3477,7 +3474,7 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
shaderstate.lastpasstmus = i; //in case it was already lower
}
BE_EnableShaderAttributes(p->permu[perm].attrmask, shaderstate.sourcevbo->vao);
BE_SubmitMeshChain(p->permu[perm].handle.glsl.usetesselation);
BE_SubmitMeshChain(p->permu[perm].h.glsl.usetesselation);
}
qboolean GLBE_LightCullModel(vec3_t org, model_t *model)
@ -4856,7 +4853,7 @@ void GLBE_RenderToTextureUpdate2d(qboolean destchanged)
else
GLBE_FBO_Push(NULL);
GL_Set2D(false);
GL_Set2D(false);
}
else
{

View File

@ -44,6 +44,8 @@ http://prideout.net/archive/bloom/ contains some sample code
#ifdef GLQUAKE
#include "shader.h"
#include "glquake.h"
#include "gl_draw.h"
cvar_t r_bloom = CVARAFD("r_bloom", "0", "gl_bloom", CVAR_ARCHIVE, "Enables bloom (light bleeding from bright objects). Fractional values reduce the amount shown.");
cvar_t r_bloom_filter = CVARD("r_bloom_filter", "0.7 0.7 0.7", "Controls how bright the image must get before it will bloom (3 separate values, in RGB order).");
cvar_t r_bloom_size = CVARD("r_bloom_size", "4", "Target bloom kernel size (assuming a video width of 320).");
@ -204,11 +206,18 @@ void R_BloomBlend (texid_t source, int x, int y, int w, int h)
TEXASSIGN(pingtex[0][0], Image_CreateTexture(name, NULL, IF_CLAMP|IF_NOMIPMAP|IF_NOPICMIP|IF_LINEAR));
Image_Upload(pingtex[0][0], TF_RGBA32, NULL, NULL, texwidth[0], texheight[0], IF_CLAMP|IF_NOMIPMAP|IF_NOPICMIP|IF_LINEAR);
}
if (R2D_Flush)
R2D_Flush();
oldfbo = GLBE_FBO_Update(&fbo_bloom, 0, &pingtex[0][0], 1, r_nulltex, 0, 0, 0);
GLBE_FBO_Sources(source, r_nulltex);
qglViewport (0, 0, texwidth[0], texheight[0]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomfilter);
if (R2D_Flush)
R2D_Flush();
intex = pingtex[0][0];
for (pixels = 1, i = 0; pixels < targetpixels && i < MAXLEVELS; i++, pixels <<= 1)
@ -227,6 +236,8 @@ void R_BloomBlend (texid_t source, int x, int y, int w, int h)
Image_Upload(pingtex[1][i], TF_RGBA32, NULL, NULL, texwidth[i], texheight[i], IF_CLAMP|IF_NOMIPMAP|IF_NOPICMIP|IF_LINEAR);
}
if (R2D_Flush)
R2D_Flush();
//downsize the blur, for added accuracy
if (i > 0 && r_bloom_downsize.ival)
{
@ -235,6 +246,8 @@ void R_BloomBlend (texid_t source, int x, int y, int w, int h)
GLBE_FBO_Sources(pingtex[0][i-1], r_nulltex);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomrescale);
if (R2D_Flush)
R2D_Flush();
intex = pingtex[0][i];
r_worldentity.glowmod[0] = 1.0 / intex->width;
}
@ -247,6 +260,8 @@ void R_BloomBlend (texid_t source, int x, int y, int w, int h)
qglViewport (0, 0, pingtex[1][i]->width, pingtex[1][i]->height);
BE_SelectEntity(&r_worldentity);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur);
if (R2D_Flush)
R2D_Flush();
r_worldentity.glowmod[0] = 0;
r_worldentity.glowmod[1] = 1.0 / pingtex[1][i]->height;
@ -261,6 +276,9 @@ void R_BloomBlend (texid_t source, int x, int y, int w, int h)
r_worldentity.glowmod[0] = 0;
r_worldentity.glowmod[1] = 0;
if (R2D_Flush)
R2D_Flush();
GL_Set2D(false);
bloomfinal->defaulttextures->base = intex;

View File

@ -5334,7 +5334,7 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
BE_VBO_Data(&ctx, arrays->tvector, sizeof(arrays->tvector [0])*numverts, &bb->vbo.tvector);
BE_VBO_Finish(&ctx, arrays->index, sizeof(arrays->index [0])*numindicies, &bb->vbo.indicies);
bb->mesh.xyz_array = (avec4_t*)(bb+1);
bb->mesh.xyz_array = (vecV_t*)(bb+1);
memcpy(bb->mesh.xyz_array, arrays->coord, sizeof(*bb->mesh.xyz_array) * numverts);
bb->mesh.st_array = (vec2_t*)(bb->mesh.xyz_array+numverts);
memcpy(bb->mesh.st_array, arrays->texcoord, sizeof(*bb->mesh.st_array) * numverts);

View File

@ -32,7 +32,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern cvar_t r_shadow_bumpscale_basetexture;
extern cvar_t r_replacemodels;
extern cvar_t gl_lightmap_average;
extern cvar_t r_softwarebanding;
cvar_t mod_loadentfiles = CVAR("sv_loadentfiles", "1");
cvar_t mod_loadentfiles_dir = CVAR("sv_loadentfiles_dir", "");
cvar_t mod_external_vis = CVARD("mod_external_vis", "1", "Attempt to load .vis patches for quake maps, allowing transparent water to work properly.");
@ -1743,7 +1742,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
samples = ql2->lmsize;
litdata = shifts+ql2->numsurfs;
if (r_deluxemapping.ival)
if (r_deluxemapping)
luxdata = litdata+samples*3;
}
}
@ -1805,7 +1804,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
}
if (!luxdata && r_loadlits.ival && r_deluxemapping.ival)
if (!luxdata && r_loadlits.ival && r_deluxemapping)
{ //the map util has a '-scalecos X' parameter. use 0 if you're going to use only just lux. without lux scalecos 0 is hideous.
char luxname[MAX_QPATH];
size_t luxsz = 0;
@ -1870,7 +1869,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
#endif
#ifdef RUNTIMELIGHTING
if (r_loadlits.value == 2 && !lightmodel && (!litdata || (!luxdata && r_deluxemapping.ival)))
if (r_loadlits.value == 2 && !lightmodel && (!litdata || (!luxdata && r_deluxemapping)))
{
if (!litdata)
writelitfile = true;
@ -1897,7 +1896,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
}
}
/*if we're relighting, make sure there's the proper lux data to be updated*/
if (lightmodel == loadmodel && r_deluxemapping.ival && !luxdata)
if (lightmodel == loadmodel && r_deluxemapping && !luxdata)
{
int i;
luxdata = ZG_Malloc(&loadmodel->memgroup, samples*3);

View File

@ -1652,22 +1652,31 @@ texid_t R_RenderPostProcess (texid_t sourcetex, int type, shader_t *shader, char
if (r_refdef.flags & type)
{
r_refdef.flags &= ~type;
GLBE_FBO_Sources(sourcetex, r_nulltex);
if (r_refdef.flags & RDF_ALLPOSTPROC)
{ //there's other post-processing passes that still need to be applied.
//thus we need to write this output to a texture.
int w = (r_refdef.vrect.width * vid.pixelwidth) / vid.width;
int h = (r_refdef.vrect.height * vid.pixelheight) / vid.height;
if (R2D_Flush)
R2D_Flush();
GLBE_FBO_Sources(sourcetex, r_nulltex);
sourcetex = R2D_RT_Configure(restexname, w, h, TF_RGBA32);
GLBE_FBO_Update(&fbo_postproc, 0, &sourcetex, 1, r_nulltex, w, h, 0);
R2D_ScalePic(0, vid.pixelheight-r_refdef.vrect.height, r_refdef.vrect.width, r_refdef.vrect.height, shader);
R2D_ScalePic(0, 0, r_refdef.vrect.width, r_refdef.vrect.height, shader);
if (R2D_Flush)
R2D_Flush();
GLBE_RenderToTextureUpdate2d(true);
}
else
{ //yay, dump it to the screen
//update stuff now that we're not rendering the 3d scene
if (R2D_Flush)
R2D_Flush();
GLBE_FBO_Sources(sourcetex, r_nulltex);
R2D_ScalePic(r_refdef.vrect.x, r_refdef.vrect.y, r_refdef.vrect.width, r_refdef.vrect.height, shader);
if (R2D_Flush)
R2D_Flush();
}
}
@ -1916,6 +1925,9 @@ void GLR_RenderView (void)
R_BloomBlend(sourcetex, r_refdef.vrect.x, r_refdef.vrect.y, r_refdef.vrect.width, r_refdef.vrect.height);
}
if (R2D_Flush)
R2D_Flush();
GLBE_FBO_Sources(r_nulltex, r_nulltex);
if (gl_motionblur.value>0 && gl_motionblur.value < 1 && qglCopyTexImage2D)

View File

@ -43,8 +43,7 @@ sh_config_t sh_config;
cvar_t r_vertexlight = CVARFD("r_vertexlight", "0", CVAR_SHADERSYSTEM, "Hack loaded shaders to remove detail pass and lightmap sampling for faster rendering.");
cvar_t r_forceprogramify = CVARAFD("r_forceprogramify", "0", "dpcompat_makeshitup", CVAR_SHADERSYSTEM, "Reduce the shader to a single texture, and then make stuff up about its mother. The resulting fist fight results in more colour when you shine a light upon its face.\nSet to 2 to ignore 'depthfunc equal' and 'tcmod scale' in order to tolerate bizzare shaders made for a bizzare engine.");
extern cvar_t r_glsl_offsetmapping_reliefmapping;
extern cvar_t r_deluxemapping;
extern cvar_t r_fastturb, r_fastsky, r_skyboxname, r_softwarebanding;
extern cvar_t r_fastturb, r_fastsky, r_skyboxname;
extern cvar_t r_drawflat;
extern cvar_t r_shaderblobs;
@ -269,7 +268,9 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
else if (!Q_stricmp(token, "lightmap"))
conditiontrue = conditiontrue == !r_fullbright.value;
else if (!Q_stricmp(token, "deluxmap"))
conditiontrue = conditiontrue == r_deluxemapping.ival;
conditiontrue = conditiontrue == r_deluxemapping;
else if (!Q_stricmp(token, "softwarebanding"))
conditiontrue = conditiontrue == r_softwarebanding;
//normalmaps are generated if they're not already known.
else if (!Q_stricmp(token, "normalmap"))
@ -1368,7 +1369,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
for (p = 0; p < PERMUTATIONS; p++)
{
memset(&prog->permu[p].handle, 0, sizeof(prog->permu[p].handle));
memset(&prog->permu[p].h, 0, sizeof(prog->permu[p].h));
if (nopermutation & p)
{
continue;
@ -1390,7 +1391,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
permutationdefines[pn++] = "#define RELIEFMAPPING\n";
}
if (r_deluxemapping.ival) //fixme: should be per-model really
if (r_deluxemapping) //fixme: should be per-model really
permutationdefines[pn++] = "#define DELUXE\n";
}
permutationdefines[pn++] = NULL;
@ -1455,7 +1456,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
}
if (sh_config.pProgAutoFields)
sh_config.pProgAutoFields(prog, cvarnames, cvartypes);
sh_config.pProgAutoFields(prog, name, cvarnames, cvartypes);
if (blobfile && blobadded)
{
@ -1937,7 +1938,7 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
else
token = Shader_ParseSensString(ptr);
#ifdef GLQUAKE
#if 0//def GLQUAKE
if (qrenderer == QR_OPENGL)
{
int p;
@ -5010,7 +5011,7 @@ void Shader_DefaultBSPQ2(const char *shortname, shader_t *s, const void *args)
"}\n"
);
}
else if (r_softwarebanding.ival)
else if (r_softwarebanding)
{
/*alpha bended*/
Shader_DefaultScript(shortname, s,
@ -5168,7 +5169,7 @@ void Shader_DefaultBSPQ1(const char *shortname, shader_t *s, const void *args)
);
}
if (!builtin && r_softwarebanding.ival)
if (!builtin && r_softwarebanding)
{
/*alpha bended*/
builtin = (

View File

@ -2178,7 +2178,7 @@ union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const cha
qboolean GLSlang_ValidateProgramPermu(program_t *prog, const char *name, unsigned int permu, qboolean noerrors, vfsfile_t *blobfile)
{
return GLSlang_ValidateProgram(&prog->permu[permu].handle, name, noerrors, blobfile);
return GLSlang_ValidateProgram(&prog->permu[permu].h, name, noerrors, blobfile);
}
qboolean GLSlang_CreateProgramPermu(program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *geom, const char *frag, qboolean noerrors, vfsfile_t *blobfile)
{
@ -2205,8 +2205,8 @@ qboolean GLSlang_CreateProgramPermu(program_t *prog, const char *name, unsigned
return false; //can happen in gles2
#endif
prog->permu[permu].handle = GLSlang_CreateProgram(name, ver, precompilerconstants, vert, tcs, tes, geom, frag, noerrors, blobfile);
if (prog->permu[permu].handle.glsl.handle)
prog->permu[permu].h = GLSlang_CreateProgram(name, ver, precompilerconstants, vert, tcs, tes, geom, frag, noerrors, blobfile);
if (prog->permu[permu].h.glsl.handle)
return true;
return false;
}
@ -2233,31 +2233,31 @@ static qboolean GLSlang_LoadBlob(program_t *prog, const char *name, unsigned int
VFS_READ(blobfile, &length, sizeof(length));
binary = BZ_Malloc(length);
VFS_READ(blobfile, binary, length);
VFS_READ(blobfile, &prog->permu[permu].handle.glsl.usetesselation, sizeof(prog->permu[permu].handle.glsl.usetesselation));
VFS_READ(blobfile, &prog->permu[permu].h.glsl.usetesselation, sizeof(prog->permu[permu].h.glsl.usetesselation));
prog->permu[permu].handle.glsl.handle = qglCreateProgramObjectARB();
qglProgramBinary(prog->permu[permu].handle.glsl.handle, fmt, binary, length);
prog->permu[permu].h.glsl.handle = qglCreateProgramObjectARB();
qglProgramBinary(prog->permu[permu].h.glsl.handle, fmt, binary, length);
BZ_Free(binary);
qglGetProgramParameteriv_(prog->permu[permu].handle.glsl.handle, GL_OBJECT_LINK_STATUS_ARB, &success);
qglGetProgramParameteriv_(prog->permu[permu].h.glsl.handle, GL_OBJECT_LINK_STATUS_ARB, &success);
if (!success)
{
qglDeleteProgramObject_(prog->permu[permu].handle.glsl.handle);
memset(&prog->permu[permu].handle, 0, sizeof(prog->permu[permu].handle));
qglDeleteProgramObject_(prog->permu[permu].h.glsl.handle);
memset(&prog->permu[permu].h, 0, sizeof(prog->permu[permu].h));
}
return !!success;
}
static void GLSlang_DeleteProg(program_t *prog, unsigned int permu)
{
if (prog->permu[permu].handle.glsl.handle)
if (prog->permu[permu].h.glsl.handle)
{
qglDeleteProgramObject_(prog->permu[permu].handle.glsl.handle);
prog->permu[permu].handle.glsl.handle = 0;
qglDeleteProgramObject_(prog->permu[permu].h.glsl.handle);
prog->permu[permu].h.glsl.handle = 0;
}
}
static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvartypes)
static void GLSlang_ProgAutoFields(program_t *prog, const char *progname, char **cvarnames, int *cvartypes)
{
static const char *defaultsamplers[] =
{
@ -2286,23 +2286,21 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
#define ALTLIGHTMAPSAMP 13
#define ALTDELUXMAPSAMP 16
unsigned int i, p;
qboolean found;
unsigned int i, j, p;
int uniformloc;
char tmpname[128];
cvar_t *cvar;
prog->numparams = 0;
cvar_t *cvar[128];
struct programpermu_s *pp;
//figure out visible attributes
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl.handle)
if (!prog->permu[p].h.loaded)
continue;
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
GLSlang_UseProgram(prog->permu[p].h.glsl.handle);
for (i = 0; shader_attr_names[i].name; i++)
{
uniformloc = qglGetAttribLocationARB(prog->permu[p].handle.glsl.handle, shader_attr_names[i].name);
uniformloc = qglGetAttribLocationARB(prog->permu[p].h.glsl.handle, shader_attr_names[i].name);
if (uniformloc != -1)
{
if (shader_attr_names[i].ptype != uniformloc)
@ -2313,98 +2311,81 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
}
}
//figure out the uniforms
for (i = 0; shader_unif_names[i].name; i++)
{
found = false;
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl.handle)
continue;
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, shader_unif_names[i].name);
if (uniformloc != -1)
found = true;
if (prog->numparams == SHADER_PROGPARMS_MAX)
{
if (found)
break;
}
else
prog->permu[p].parm[prog->numparams] = uniformloc;
}
if (found)
{
if (prog->numparams == SHADER_PROGPARMS_MAX)
Con_Printf("Too many paramters for program (ignoring %s)\n", shader_unif_names[i].name);
else
{
prog->parm[prog->numparams].type = shader_unif_names[i].ptype;
prog->numparams++;
}
}
}
/*set cvar unirforms*/
for (i = 0; cvarnames[i]; i++)
{
char *tmpval;
if (prog->numparams == SHADER_PROGPARMS_MAX)
{
Con_Printf("Too many cvar paramters for program\n");
break;
}
for (p = 0; cvarnames[i][p] && (unsigned char)cvarnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
tmpname[p] = cvarnames[i][p];
tmpname[p] = 0;
tmpval = strchr(tmpname, '=');
if (tmpval)
*tmpval++ = 0;
else
tmpval = "0";
while(p > 0 && (tmpname[p-1] == ' ' || tmpname[p-1] == '\t'))
tmpname[--p] = 0;
cvar = Cvar_Get(tmpname, tmpval, CVAR_SHADERSYSTEM, "glsl cvars");
if (!cvar)
continue;
// cvar->flags |= CVAR_SHADERSYSTEM;
prog->parm[prog->numparams].type = cvartypes[i];
prog->parm[prog->numparams].pval = cvar;
found = false;
for (p = 0; p < PERMUTATIONS; p++)
{
char uniformname[64];
if (!prog->permu[p].handle.glsl.handle)
continue;
GL_SelectProgram(prog->permu[p].handle.glsl.handle);
Q_snprintfz(uniformname, sizeof(uniformname), "cvar_%s", tmpname);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, uniformname);
if (uniformloc != -1)
{
//qglUniform1fARB(uniformloc, cvar->value);
found = true;
}
prog->permu[p].parm[prog->numparams] = uniformloc;
}
if (found)
prog->numparams++;
}
memset(cvar, 0, sizeof(cvar));
prog->numsamplers = 0;
prog->defaulttextures = 0;
/*set texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl.handle)
int maxparms = 0;
pp = &prog->permu[p];
if (!pp->h.loaded)
continue;
if (!(prog->permu[p].attrmask & (1u<<VATTR_VERTEX1))) //a shader kinda has to use one of these...
prog->permu[p].attrmask |= (1u<<VATTR_LEG_VERTEX);
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
pp->numparms = 0;
pp->parm = NULL;
GLSlang_UseProgram(prog->permu[p].h.glsl.handle); //we'll probably be setting samplers anyway.
for (i = 0; shader_unif_names[i].name; i++)
{
uniformloc = qglGetUniformLocationARB(pp->h.glsl.handle, shader_unif_names[i].name);
if (uniformloc >= 0)
{
if (pp->numparms >= maxparms)
{
maxparms = pp->numparms?pp->numparms * 2:8;
pp->parm = BZ_Realloc(pp->parm, sizeof(*pp->parm) * maxparms);
}
pp->parm[pp->numparms].type = shader_unif_names[i].ptype;
pp->parm[pp->numparms].handle = uniformloc;
pp->numparms++;
}
}
/*set cvar uniforms*/
/*FIXME: enumerate cvars automatically instead*/
for (i = 0; cvarnames[i] && i < countof(cvar); i++)
{
char *tmpval;
if (!cvar[i])
{
for (j = 0; cvarnames[i][j] && (unsigned char)cvarnames[i][j] > 32 && j < sizeof(tmpname)-1; j++)
tmpname[j] = cvarnames[i][j];
tmpname[j] = 0;
tmpval = strchr(tmpname, '=');
if (tmpval)
*tmpval++ = 0;
else
tmpval = "0";
while(j > 0 && (tmpname[j-1] == ' ' || tmpname[j-1] == '\t'))
tmpname[--j] = 0;
cvar[i] = Cvar_Get(tmpname, tmpval, CVAR_SHADERSYSTEM, "glsl cvars");
if (!cvar[i])
continue;
//cvar[i]->flags |= CVAR_SHADERSYSTEM;
}
uniformloc = qglGetUniformLocationARB(pp->h.glsl.handle, va("cvar_%s", cvar[i]->name));
if (uniformloc >= 0)
{
if (pp->numparms >= maxparms)
{
maxparms = pp->numparms?pp->numparms * 2:8;
pp->parm = BZ_Realloc(pp->parm, sizeof(*pp->parm) * maxparms);
}
pp->parm[pp->numparms].type = cvartypes[i];
pp->parm[pp->numparms].pval = cvar[i];
pp->parm[pp->numparms].handle = uniformloc;
pp->numparms++;
}
}
//now scan/set texture uniforms
if (!(pp->attrmask & (1u<<VATTR_VERTEX1))) //a shader kinda has to use one of these...
pp->attrmask |= (1u<<VATTR_LEG_VERTEX);
for (i = 0; i < 8; i++)
{
Q_snprintfz(tmpname, sizeof(tmpname), "s_t%i", i);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, tmpname);
uniformloc = qglGetUniformLocationARB(pp->h.glsl.handle, tmpname);
if (uniformloc != -1)
{
qglUniform1iARB(uniformloc, i);
@ -2417,7 +2398,7 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
//figure out which ones are needed.
if (prog->defaulttextures & (1u<<i))
continue; //don't spam
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, defaultsamplers[i]);
uniformloc = qglGetUniformLocationARB(pp->h.glsl.handle, defaultsamplers[i]);
if (uniformloc != -1)
prog->defaulttextures |= (1u<<i);
}
@ -2432,18 +2413,18 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
if (prog->defaulttextures)
{
unsigned int sampnum;
/*set default texture uniforms*/
/*set default texture uniforms now that we know the right sampler ids*/
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl.handle)
if (!prog->permu[p].h.glsl.handle)
continue;
sampnum = prog->numsamplers;
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
GLSlang_UseProgram(prog->permu[p].h.glsl.handle);
for (i = 0; i < sizeof(defaultsamplers)/sizeof(defaultsamplers[0]); i++)
{
if (prog->defaulttextures & (1u<<i))
{
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, defaultsamplers[i]);
uniformloc = qglGetUniformLocationARB(prog->permu[p].h.glsl.handle, defaultsamplers[i]);
if (uniformloc != -1)
qglUniform1iARB(uniformloc, sampnum);
sampnum++;

View File

@ -120,7 +120,6 @@ static qboolean vid_canalttab = false;
static qboolean vid_wassuspended = false;
extern qboolean mouseactive; // from in_win.c
static HICON hIcon;
static HCURSOR hArrowCursor, hCustomCursor;
extern qboolean vid_isfullscreen;
unsigned short originalgammaramps[3][256];
@ -586,117 +585,6 @@ RECT centerrect(unsigned int parentleft, unsigned int parenttop, unsigned int pa
return r;
}
void *WIN_CreateCursor(char *filename, float hotx, float hoty, float scale)
{
int width, height;
BITMAPV5HEADER bi;
DWORD x,y;
HCURSOR hAlphaCursor = NULL;
ICONINFO ii;
qbyte *rgbadata, *rgbadata_start, *bgradata, *bgradata_start;
qboolean hasalpha;
void *filedata;
int filelen;
if (!filename || !*filename)
return NULL;
filelen = FS_LoadFile(filename, &filedata);
if (!filedata)
return NULL;
rgbadata_start = Read32BitImageFile(filedata, filelen, &width, &height, &hasalpha, "cursor");
FS_FreeFile(filedata);
if (!rgbadata_start)
return NULL;
if (scale != 1)
{
int nw,nh;
qbyte *nd;
nw = width * scale;
nh = height * scale;
if (nw <= 0 || nh <= 0 || nw > 128 || nh > 128) //don't go crazy.
return NULL;
nd = BZ_Malloc(nw*nh*4);
Image_ResampleTexture((unsigned int*)rgbadata_start, width, height, (unsigned int*)nd, nw, nh);
width = nw;
height = nh;
BZ_Free(rgbadata_start);
rgbadata_start = nd;
}
memset(&bi,0, sizeof(BITMAPV5HEADER));
bi.bV5Size = sizeof(BITMAPV5HEADER);
bi.bV5Width = width;
bi.bV5Height = height;
bi.bV5Planes = 1;
bi.bV5BitCount = 32;
bi.bV5Compression = BI_BITFIELDS;
// The following mask specification specifies a supported 32 BPP
// alpha format for Windows XP.
//FIXME: can we not just specify it as RGBA? meh.
bi.bV5RedMask = 0x00FF0000;
bi.bV5GreenMask = 0x0000FF00;
bi.bV5BlueMask = 0x000000FF;
bi.bV5AlphaMask = 0xFF000000;
// Create the DIB section with an alpha channel.
ii.hbmColor = CreateDIBSection(maindc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&bgradata_start, NULL, 0);
if (!ii.hbmColor)
{
BZ_Free(rgbadata_start);
return NULL;
}
for (rgbadata=rgbadata_start,y=0;y<height;y++)
{
bgradata = bgradata_start + (height-1-y)*width*4;
for (x=0;x<width;x++)
{
bgradata[0] = rgbadata[2];
bgradata[1] = rgbadata[1];
bgradata[2] = rgbadata[0];
bgradata[3] = rgbadata[3];
bgradata+=4;
rgbadata+=4;
}
}
BZ_Free(rgbadata_start);
ii.fIcon = FALSE; // Change fIcon to TRUE to create an alpha icon
ii.xHotspot = hotx;
ii.yHotspot = hoty;
ii.hbmMask = CreateBitmap(width,height,1,1,NULL);
// Create the alpha cursor with the alpha DIB section.
hAlphaCursor = CreateIconIndirect(&ii);
DeleteObject(ii.hbmColor);
DeleteObject(ii.hbmMask);
return hAlphaCursor;
}
qboolean WIN_SetCursor(void *cursor)
{
static POINT current_pos; //static to avoid bugs in vista(32) with largeaddressaware (this is fixed in win7). fixed exe base address prevents this from going above 2gb.
hCustomCursor = cursor;
//move the cursor to ensure the WM_SETCURSOR thing is invoked properly.
//this ensures all the nastyness of random programs randomly setting the current global cursor is handled by microsoft's code instead of mine.
//if you're using rawinput there'll be no lost inpuit problems, yay...
GetCursorPos(&current_pos);
SetCursorPos(current_pos.x, current_pos.y);
return true;
}
void WIN_DestroyCursor(void *cursor)
{
DestroyIcon(cursor);
}
qboolean VID_SetWindowedMode (rendererstate_t *info)
//qboolean VID_SetWindowedMode (int modenum)
{

View File

@ -36,6 +36,14 @@ int Doom_SectorNearPoint(vec3_t p);
//4. That ALL sectors are fully enclosed, and not made of two areas.
//5. That no sectors are inside out.
/*FIXME:
we need to do a bsp2prt type thing (walk nodes and determine actual leaf/ssector shapes based upon those).
build sector geometry based upon this.
this is because flats in doom were implemented using a flood-fill algorithm and thus omits various unecessary inner edges, while 3d rendering apis all need tri-soup instead.
attempting to generate sane volumes from most doom maps is doomed to failure because quite often the sector values on linedefs is just buggy, resulting in some really whacky polygons that cannot be souped in any meaningful way.
this may still result in a mess of floor polygons outside the world, so be sure to draw those last, for early-z.
*/
enum {
THING_PLAYER = 1,
THING_PLAYER2 = 2,

View File

@ -37,8 +37,6 @@ typedef void (shader_gen_t)(const char *name, shader_t*, const void *args);
#define SHADER_DEFORM_MAX 8
#define SHADER_MAX_ANIMFRAMES 16
#define SHADER_PROGPARMS_MAX 16
typedef enum {
SHADER_BSP,
SHADER_BSP_VERTEX,
@ -427,48 +425,50 @@ typedef struct {
float fval;
void *pval;
};
unsigned int handle;
} shaderprogparm_t;
union programhandle_u
{
struct
{
int handle;
qboolean usetesselation;
} glsl;
#ifdef D3DQUAKE
struct
{
void *vert;
void *frag;
#ifdef D3D9QUAKE
void *ctabf;
void *ctabv;
#endif
#ifdef D3D11QUAKE
int topology; //D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST
void *hull;
void *domain;
void *geom;
void *layout;
#endif
} hlsl;
#endif
};
typedef struct programshared_s
{
int refs;
qboolean nofixedcompat;
unsigned short numparams;
unsigned short numsamplers; //shader system can strip any passes above this
unsigned int defaulttextures; //diffuse etc
shaderprogparm_t parm[SHADER_PROGPARMS_MAX];
struct {
union programhandle_u handle;
struct programpermu_s
{
union programhandle_u
{
qintptr_t loaded; //generic code must be able to test this to see if its valid. if not 0, then its considered loaded
#ifdef GLQUAKE
struct
{
int handle;
qboolean usetesselation;
} glsl;
#endif
#ifdef D3DQUAKE
struct
{
void *vert;
void *frag;
#ifdef D3D9QUAKE
void *ctabf;
void *ctabv;
#endif
#ifdef D3D11QUAKE
int topology; //D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST
void *hull;
void *domain;
void *geom;
void *layout;
#endif
} hlsl;
#endif
} h;
unsigned int attrmask;
unsigned int texmask; //'standard' textures that are in use
unsigned int parm[SHADER_PROGPARMS_MAX];
unsigned int numparms;
shaderprogparm_t *parm;
} permu[PERMUTATIONS];
} program_t;
@ -684,7 +684,7 @@ typedef struct
qboolean (*pLoadBlob) (program_t *prog, const char *name, unsigned int permu, vfsfile_t *blobfile);
qboolean (*pCreateProgram) (program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *geom, const char *frag, qboolean noerrors, vfsfile_t *blobfile);
qboolean (*pValidateProgram)(program_t *prog, const char *name, unsigned int permu, qboolean noerrors, vfsfile_t *blobfile);
void (*pProgAutoFields) (program_t *prog, char **cvarnames, int *cvartypes);
void (*pProgAutoFields) (program_t *prog, const char *name, char **cvarnames, int *cvartypes);
} sh_config_t;
extern sh_config_t sh_config;
#endif

View File

@ -607,7 +607,7 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val, pbool v
}
break;
case ev_accessor:
QC_snprintfz (line, sizeof(line), "(accessor)", type);
QC_snprintfz (line, sizeof(line), "(accessor)");
break;
default:
QC_snprintfz (line, sizeof(line), "(bad type %i)", type);

View File

@ -1484,7 +1484,7 @@ static int PR_ExecuteCode16 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
int ofs;
strcpy(stack, "This platform does not support QC debugging\nStack Trace:");
ofs = strlen(stack);
PR_SaveCallStack (&progfuncs->funcs, stack, &ofs, 4*1024);
PR_SaveCallStack (progfuncs, stack, &ofs, 4*1024);
PR_RunError (&progfuncs->funcs, stack);
free(stack);
return -1;

View File

@ -1391,6 +1391,32 @@ const QCC_eval_t *QCC_SRef_EvalConst(QCC_sref_t ref)
return NULL;
}
const char *QCC_GetRefName(QCC_ref_t *ref, char *buffer, size_t buffersize)
{
switch(ref->type)
{
case REF_FIELD:
case REF_NONVIRTUAL:
QC_snprintfz(buffer, buffersize, "%s.%s", QCC_GetSRefName(ref->base), QCC_GetSRefName(ref->index));
return buffer;
case REF_ARRAY:
case REF_STRING:
QC_snprintfz(buffer, buffersize, "%s[%s]", QCC_GetSRefName(ref->base), QCC_GetSRefName(ref->index));
return buffer;
case REF_POINTER:
QC_snprintfz(buffer, buffersize, "%s->%s", QCC_GetSRefName(ref->base), QCC_GetSRefName(ref->index));
return buffer;
case REF_ACCESSOR:
//FIXME
break;
case REF_ARRAYHEAD:
case REF_GLOBAL:
default:
break;
}
return QCC_GetSRefName(ref->base);
}
/*
============
PR_Statement
@ -1428,7 +1454,7 @@ static int QCC_ShouldConvert(QCC_type_t *from, etype_t wanted)
/*impossible*/
return -1;
}
QCC_sref_t QCC_SupplyConversionForAssignment(QCC_sref_t to, QCC_sref_t from, QCC_type_t *wanted, pbool fatal)
QCC_sref_t QCC_SupplyConversionForAssignment(QCC_ref_t *to, QCC_sref_t from, QCC_type_t *wanted, pbool fatal)
{
int o;
@ -1443,25 +1469,25 @@ QCC_sref_t QCC_SupplyConversionForAssignment(QCC_sref_t to, QCC_sref_t from, QCC
return from;
if (flag_typeexplicit)
{
char totypename[256], fromtypename[256];
char totypename[256], fromtypename[256], destname[256];
TypeName(wanted, totypename, sizeof(totypename));
TypeName(from.cast, fromtypename, sizeof(fromtypename));
QCC_PR_ParseErrorPrintSRef(ERR_TYPEMISMATCH, from, "Implicit type mismatch on assignment to %s. Needed %s, got %s.", QCC_GetSRefName(to), totypename, fromtypename);
QCC_PR_ParseErrorPrintSRef(ERR_TYPEMISMATCH, from, "Implicit type mismatch on assignment to %s. Needed %s, got %s.", QCC_GetRefName(to, destname, sizeof(destname)), totypename, fromtypename);
}
if (o < 0)
{
if (fatal && wanted->type != ev_variant && from.cast->type != ev_variant)
{
char totypename[256], fromtypename[256];
char totypename[256], fromtypename[256], destname[256];
TypeName(wanted, totypename, sizeof(totypename));
TypeName(from.cast, fromtypename, sizeof(fromtypename));
if (flag_laxcasts)
{
QCC_PR_ParseWarning(WARN_LAXCAST, "Implicit type mismatch on assignment to %s. Needed %s, got %s.", QCC_GetSRefName(to), totypename, fromtypename);
QCC_PR_ParseWarning(WARN_LAXCAST, "Implicit type mismatch on assignment to %s. Needed %s, got %s.", QCC_GetRefName(to, destname, sizeof(destname)), totypename, fromtypename);
QCC_PR_ParsePrintSRef(WARN_LAXCAST, from);
}
else
QCC_PR_ParseErrorPrintSRef(ERR_TYPEMISMATCH, from, "Implicit type mismatch on assignment to %s. Needed %s, got %s.", QCC_GetSRefName(to), totypename, fromtypename);
QCC_PR_ParseErrorPrintSRef(ERR_TYPEMISMATCH, from, "Implicit type mismatch on assignment to %s. Needed %s, got %s.", QCC_GetRefName(to, destname, sizeof(destname)), totypename, fromtypename);
}
return from;
}
@ -8282,7 +8308,7 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
//convert so we don't have issues with: i = (int)(float)(i+f)
//this will also catch things like vec *= vec; which would be trying to store a float into a vector.
rhsd = QCC_SupplyConversionForAssignment(lhsr->base, rhsd, lhsr->cast, true);
rhsd = QCC_SupplyConversionForAssignment(lhsr, rhsd, lhsr->cast, true);
}
else
{
@ -8304,7 +8330,7 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
rhsd.cast = lhsr->cast;
}
else
rhsd = QCC_SupplyConversionForAssignment(lhsr->base, rhsd, lhsr->cast, true);
rhsd = QCC_SupplyConversionForAssignment(lhsr, rhsd, lhsr->cast, true);
}
rhsd = QCC_StoreToRef(lhsr, rhsd, true, false); //FIXME: this should not always be true, but we don't know if the caller actually needs it
qcc_usefulstatement = true;

View File

@ -67,6 +67,7 @@ void GUI_RevealOptions(void);
#define SCI_STYLESETITALIC 2054
#define SCI_STYLESETSIZE 2055
#define SCI_STYLESETFONT 2056
#define SCI_STYLERESETDEFAULT 2058
#define SCI_STYLESETUNDERLINE 2059
#define SCI_STYLESETCASE 2060
#define SCI_AUTOCSHOW 2100
@ -160,6 +161,7 @@ void GUI_RevealOptions(void);
#define SCE_C_TASKMARKER 26
#define SCE_C_ESCAPESEQUENCE 27
#define STYLE_DEFAULT 32
#define STYLE_BRACELIGHT 34
#define STYLE_BRACEBAD 35
#define STYLE_LASTPREDEFINED 39
@ -872,6 +874,11 @@ HWND CreateAnEditControl(HWND parent, pbool *scintillaokay)
if (scintillaokay)
{
FILE *f;
SendMessage(newc, SCI_STYLERESETDEFAULT, 0, 0);
SendMessage(newc, SCI_STYLESETFONT, STYLE_DEFAULT, (LPARAM)"Consolas");
SendMessage(newc, SCI_STYLECLEARALL, 0, 0);
SendMessage(newc, SCI_SETCODEPAGE, SC_CP_UTF8, 0);
SendMessage(newc, SCI_SETLEXER, SCLEX_CPP, 0);
SendMessage(newc, SCI_STYLESETFORE, SCE_C_DEFAULT, RGB(0x00, 0x00, 0x00));
@ -990,6 +997,8 @@ HWND CreateAnEditControl(HWND parent, pbool *scintillaokay)
continue;
if (c[0] == '/' && c[1] == '/')
continue;
if (c[0] == '\r' || c[0] == '\n' || !c[0])
continue;
msg = strtoul(c, &c, 0);
while(*c == ' ' || *c == '\t')
c++;
@ -1627,7 +1636,7 @@ char *GetTooltipText(editor_t *editor, int pos, pbool dwell)
static void scin_get_line_indent(HWND editpane, int lineidx, char *indentbuf, size_t sizeofbuf)
{
int i;
int len;
size_t len;
while (lineidx --> 0)
{
len = SendMessage(editpane, SCI_LINELENGTH, lineidx, 0);
@ -3157,7 +3166,28 @@ void RunEngine(void)
PostMessage(mainwindow, WM_SIZE, 0, 0);
}
static void SetProgsSrcFileAndPath(char *filename)
{
char *s, *s2;
strcpy(progssrcdir, filename);
for(s = progssrcdir; s; s = s2)
{
s2 = strchr(s+1, '\\');
if (!s2)
break;
s = s2;
}
if (s)
{
*s = '\0';
strcpy(progssrcname, s+1);
}
else
strcpy(progssrcname, filename);
SetCurrentDirectory(progssrcdir);
*progssrcdir = '\0';
}
HWND targitem_hexen2;
HWND targitem_fte;
@ -3219,7 +3249,6 @@ static LRESULT CALLBACK OptionsWndProc(HWND hWnd,UINT message,
break;
case IDI_O_CHANGE_PROGS_SRC:
{
char *s, *s2;
char filename[MAX_PATH];
char oldpath[MAX_PATH+10];
OPENFILENAME ofn;
@ -3235,24 +3264,7 @@ static LRESULT CALLBACK OptionsWndProc(HWND hWnd,UINT message,
ofn.lpstrInitialDir = oldpath;
if (GetOpenFileName(&ofn))
{
strcpy(progssrcdir, filename);
for(s = progssrcdir; s; s = s2)
{
s2 = strchr(s+1, '\\');
if (!s2)
break;
s = s2;
}
if (s)
{
*s = '\0';
strcpy(progssrcname, s+1);
}
else
strcpy(progssrcname, filename);
SetCurrentDirectory(progssrcdir);
*progssrcdir = '\0';
SetProgsSrcFileAndPath(filename);
}
resetprogssrc = true;
}
@ -3764,6 +3776,9 @@ static LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,
CLIENTCREATESTRUCT ccs;
HMENU rootmenu, windowmenu, m;
DragAcceptFiles(hWnd, TRUE);
rootmenu = CreateMenu();
AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = CreateMenu()), "&File");
@ -3873,9 +3888,24 @@ static LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,
case WM_CTLCOLORBTN:
return (LRESULT)GetSysColorBrush(COLOR_HIGHLIGHT);//COLOR_BACKGROUND;
case WM_DESTROY:
DragAcceptFiles(hWnd, FALSE);
mainwindow = NULL;
break;
case WM_DROPFILES:
{
HDROP p = (HDROP)wParam;
char fname[MAX_PATH];
if (DragQueryFile(p, ~0, (LPSTR) NULL, 0) == 1)
{
DragQueryFile(p, 0, fname, sizeof(fname));
SetProgsSrcFileAndPath(fname);
resetprogssrc = true;
}
DragFinish(p);
}
break;
case WM_SIZE:
GetClientRect(mainwindow, &rect);
if (projecttree)
@ -4858,8 +4888,9 @@ void AddSourceFile(const char *parentpath, const char *filename)
}
}
//called when progssrcname has changed.
//progssrcname should already have been set.
void SetProgsSrc(void)
void UpdateFileList(void)
{
FILE *f;
@ -5128,7 +5159,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
if (resetprogssrc)
{ //this here, with the compiler below, means that we don't run recursivly.
resetprogssrc = false;
SetProgsSrc();
UpdateFileList();
}
EditorsRun();

View File

@ -9276,7 +9276,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"localcmd", PF_localcmd, 46, 46, 46, 0, D("void(string, ...)", "Adds the string to the console command queue. Commands will not be executed immediately, but rather at the start of the following frame.")},
{"nextent", PF_nextent, 47, 47, 47, 0, D("entity(entity)", "Returns the following entity. Skips over removed entities. Returns world when passed the last valid entity.")},
{"particle", PF_particle, 48, 0, 48, 48, D("void(vector pos, vector dir, float colour, float count)", "Spawn 'count' particles around 'pos' moving in the direction 'dir', with a palette colour index between 'colour' and 'colour+8'.")}, //48 nq readded. This isn't present in QW protocol (fte added it back).
{"changeyaw", PF_changeyaw, 49, 49, 49, 0, D("#define ChangeYaw changeyaw\nvoid()", "Changes the self.angles_y field towards self.ideal_yaw by up to self.yawspeed.")},
{"changeyaw", PF_changeyaw, 49, 49, 49, 0, D("#define ChangeYaw changeyaw\nvoid()", "Changes the self.angles_y field towards self.ideal_yaw by up to self.yaw_speed.")},
// {"qtest_precacheitem", NULL, 50}, // defined QTest builtin that is never called
{"vectoangles", PF_vectoangles, 51, 51, 51, 0, D("vector(vector fwd, optional vector up)", "Returns the angles (+x=UP) required to orient an entity to look in the given direction. The 'up' argument is required if you wish to set a roll angle, otherwise it will be limited to just monster-style turning.")},

View File

@ -24,6 +24,7 @@ int emscriptenfte_ws_recv(int sockid, void *data, int len); //receive data from
//misc stuff for printf replacements
void emscriptenfte_alert(const char *msg);
void emscriptenfte_print(const char *msg);
void emscriptenfte_setupmainloop(int(*mainloop)(void));
void emscriptenfte_abortmainloop(const char *caller);
//we're trying to avoid including libpng+libjpeg+libogg in javascript due to it being redundant bloat.

View File

@ -325,8 +325,6 @@ mergeInto(LibraryManager.library,
});
});
}
if (Module.print === undefined)
Module.print = function(msg){console.log(msg);};
var ctx = Browser.createContext(Module['canvas'], true, true);
if (ctx == null)
{
@ -375,10 +373,38 @@ mergeInto(LibraryManager.library,
{
document.title = Pointer_stringify(txt);
},
emscriptenfte_abortmainloop : function(msg)
emscriptenfte_abortmainloop : function(fname)
{
msg = Pointer_stringify(msg);
throw 'oh noes! something bad happened in ' + msg + '!';
fname = Pointer_stringify(fname);
throw 'oh noes! something bad happened in ' + fname + '!\n' + Module['stackTrace']();
},
emscriptenfte_setupmainloop : function(fnc)
{
Module['noExitRuntime'] = true;
//Module.abort = abort = function(msg) {};
Module["sched"] = function()
{
var dovsync = false;
if (ABORT)
return;
try
{
dovsync = Runtime.dynCall('i', fnc, []);
}
catch(err)
{
console.log(err);
}
if (dovsync)
Browser.requestAnimationFrame(Module["sched"]);
else
setTimeout(Module["sched"], 0);
};
//don't start it instantly, so we can distinguish between types of errors (emscripten sucks!).
setTimeout(Module["sched"], 1);
},
emscriptenfte_ticks_ms : function()

View File

@ -6,12 +6,12 @@
<meta name=viewport content="width=device-width, initial-scale=1">
<title>FTE QuakeWorld</title>
<style>
body { background-color:#000000; color:#808080; height:100%;width:100%;margin:0;padding:0;}
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
div.emscripten { text-align: center; padding:0; margin: 0;}
div.emscripten_border { padding:0; margin: 0; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
canvas.emscripten { border: 0px none; width:100%; height:100%; padding:0; margin: 0;}
body { background-color:#000000; color:#808080; height:100%;width:100%;margin:0;padding:0;}
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
div.emscripten { text-align: center; padding:0; margin: 0;}
div.emscripten_border { padding:0; margin: 0; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
canvas.emscripten { border: 0px none; width:100%; height:100%; padding:0; margin: 0;}
</style>
</head>
<body>
@ -22,57 +22,67 @@
<div class="emscripten_border">
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
</div>
<!-- <div class="emscripten">
<input type="checkbox" id="resize">Resize canvas
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
&nbsp;&nbsp;&nbsp;
<input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked,
document.getElementById('resize').checked)">
</div>
-->
<script type='text/javascript'>
// connect to canvas
var Module = {
preRun: [],
postRun: [],
print: (function() {
})(),
printErr: function(text) {
text = Array.prototype.slice.call(arguments).join(' ');
if (0) { // XXX disabled for safety typeof dump == 'function') {
dump(text + '\n'); // fast, straight to the real console
} else {
console.log(text);
}
},
// connect to canvas
var Module = {
// preRun: [],
postRun: [function()
{
if (Module["sched"] === undefined) //if this happens then our main function failed to set up the main loop. ie: main didn't get called.
alert("Unable to initialise. You may need to restart your browser. If you get this often and inconsistently, consider using a 64bit browser instead.");
}],
print: function(msg)
{
console.log(msg);
},
printErr: function(text)
{
//this is infuriating as hell.
//emscripten is a piece of shit for actual released work.
if (text.substr(0, 28) == "Cannot enlarge memory arrays")
alert("Memory full/fragmented. Please reload the page.");
else
console.log(text);
},
canvas: document.getElementById('canvas'),
setStatus: function(text) {
if (Module.setStatus.interval) clearInterval(Module.setStatus.interval);
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
if (m) {
text = m[1];
progressElement.value = parseInt(m[2])*100;
progressElement.max = parseInt(m[4])*100;
progressElement.hidden = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
}
statusElement.innerHTML = text;
setStatus: function(text)
{
if (Module.setStatus.interval)
clearInterval(Module.setStatus.interval);
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
if (m) {
text = m[1];
progressElement.value = parseInt(m[2])*100;
progressElement.max = parseInt(m[4])*100;
progressElement.hidden = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
}
statusElement.innerHTML = text;
},
totalDependencies: 0,
monitorRunDependencies: function(left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
}
};
Module.setStatus('Downloading...');
monitorRunDependencies: function(left)
{
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
}
};
Module.setStatus('Downloading...');
// make a script
var s = document.createElement('script');
// set it up
s.setAttribute('src',"ftewebgl.js");
s.setAttribute('type',"text/javascript");
s.setAttribute('charset',"utf-8");
s.addEventListener('error', function() {alert("Oh noes! we got an error!");}, false);
// add to DOM
document.head.appendChild(s);
</script>
{{{ SCRIPT }}}
</body>
</html>
</html>

View File

@ -1,7 +1,3 @@
Module['preRun'] = function()
{
};
{
Module['arguments'] = ['-nohome'];

View File

@ -1,395 +1,401 @@
#include "quakedef.h"
#include <SDL.h>
#ifdef MULTITHREAD
#include <SDL_thread.h>
#endif
#include <SDL_loadso.h>
#include <emscripten/emscripten.h>
#include "ftejslib.h"
#ifndef isDedicated
qboolean isDedicated;
#endif
void Sys_Error (const char *error, ...)
{
va_list argptr;
char string[1024];
va_start (argptr,error);
vsnprintf (string, sizeof (string), error, argptr);
va_end (argptr);
Sys_Printf("Error: %s\n", string);
Con_Print ("Quake Error: ");
Con_Print (string);
Con_Print ("\n");
Host_Shutdown ();
emscriptenfte_alert(string);
exit (1);
}
void Sys_RecentServer(char *command, char *target, char *title, char *desc)
{
}
qboolean Sys_RandomBytes(qbyte *string, int len)
{
return false;
}
//print into stdout
void Sys_Printf (char *fmt, ...)
{
va_list argptr;
char buf[1024];
va_start (argptr,fmt);
vsnprintf (buf, sizeof(buf), fmt, argptr);
emscriptenfte_print(buf);
va_end (argptr);
}
unsigned int Sys_Milliseconds(void)
{
static int first = true;
static unsigned long oldtime = 0, curtime = 0;
unsigned long newtime;
newtime = emscriptenfte_ticks_ms(); //return Date.now()
if (first)
{
first = false;
oldtime = newtime;
}
if (newtime < oldtime)
Con_Printf("Sys_Milliseconds stepped backwards!\n");
else
curtime += newtime - oldtime;
oldtime = newtime;
return curtime;
}
//return the current time, in the form of a double
double Sys_DoubleTime (void)
{
return Sys_Milliseconds() / 1000.0;
}
//create a directory
void Sys_mkdir (char *path)
{
}
//unlink a file
qboolean Sys_remove (char *path)
{
emscriptenfte_buf_delete(path);
return true;
}
qboolean Sys_Rename (char *oldfname, char *newfname)
{
return emscriptenfte_buf_rename(oldfname, newfname);
return false;
}
//someone used the 'quit' command
#include "glquake.h"
void Sys_Quit (void)
{
if (host_initialized)
{
qglClearColor(0,0,0,1);
qglClear(GL_COLOR_BUFFER_BIT);
Draw_FunString (0, 0, "Reload the page to restart");
Host_Shutdown();
}
exit (0);
}
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{
Con_DPrintf("Warning: Sys_EnumerateFiles not implemented\n");
return true;
}
//blink window if possible (it's not)
void Sys_ServerActivity(void)
{
}
void Sys_CloseLibrary(dllhandle_t *lib)
{
}
dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
{
return NULL;
}
void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname)
{
return NULL;
}
void Sys_Init(void)
{
extern cvar_t vid_width, vid_height, vid_fullscreen;
//vid_fullscreen takes effect only on mouse clicks, any suggestion to do a vid_restart is pointless.
vid_fullscreen.flags &= ~CVAR_RENDERERLATCH;
//these are not really supported. so silence any spam that suggests we do something about something not even supported.
vid_width.flags &= ~CVAR_RENDERERLATCH;
vid_height.flags &= ~CVAR_RENDERERLATCH;
}
void Sys_Shutdown(void)
{
}
int VARGS Sys_DebugLog(char *file, char *fmt, ...)
{
return 0;
};
qboolean Sys_InitTerminal(void)
{
return true;
}
char *Sys_ConsoleInput(void)
{
return NULL;
}
void Sys_CloseTerminal (void)
{
}
void Sys_MainLoop(void)
{
static float oldtime;
float newtime, time;
newtime = Sys_DoubleTime ();
if (!oldtime)
oldtime = newtime;
time = newtime - oldtime;
Host_Frame (time);
oldtime = newtime;
}
int QDECL main(int argc, char **argv)
{
quakeparms_t parms;
memset(&parms, 0, sizeof(parms));
parms.basedir = "";
parms.argc = argc;
parms.argv = (const char**)argv;
COM_InitArgv (parms.argc, parms.argv);
TL_InitLanguages("");
Sys_Printf ("Host_Init\n");
Host_Init (&parms);
//-1 fps should give vsync
emscripten_set_main_loop(Sys_MainLoop, -1, false);
return 0;
}
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
{
return false;
}
static char *clipboard_buffer;
char *Sys_GetClipboard(void)
{
return clipboard_buffer;
}
void Sys_CloseClipboard(char *bf)
{
}
void Sys_SaveClipboard(char *text)
{
free(clipboard_buffer);
clipboard_buffer = strdup(text);
}
#ifdef MULTITHREAD
/* Thread creation calls */
void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize)
{
// SDL threads do not support setting thread stack size
return (void *)SDL_CreateThread(func, args);
}
void Sys_WaitOnThread(void *thread)
{
SDL_WaitThread((SDL_Thread *)thread, NULL);
}
/* Mutex calls */
// SDL mutexes don't have try-locks for mutexes in the spec so we stick with 1-value semaphores
void *Sys_CreateMutex(void)
{
return (void *)SDL_CreateSemaphore(1);
}
qboolean Sys_TryLockMutex(void *mutex)
{
return !SDL_SemTryWait(mutex);
}
qboolean Sys_LockMutex(void *mutex)
{
return !SDL_SemWait(mutex);
}
qboolean Sys_UnlockMutex(void *mutex)
{
return !SDL_SemPost(mutex);
}
void Sys_DestroyMutex(void *mutex)
{
SDL_DestroySemaphore(mutex);
}
/* Conditional wait calls */
typedef struct condvar_s
{
SDL_mutex *mutex;
SDL_cond *cond;
} condvar_t;
void *Sys_CreateConditional(void)
{
condvar_t *condv;
SDL_mutex *mutex;
SDL_cond *cond;
condv = (condvar_t *)malloc(sizeof(condvar_t));
if (!condv)
return NULL;
mutex = SDL_CreateMutex();
cond = SDL_CreateCond();
if (mutex)
{
if (cond)
{
condv->cond = cond;
condv->mutex = mutex;
return (void *)condv;
}
else
SDL_DestroyMutex(mutex);
}
free(condv);
return NULL;
}
qboolean Sys_LockConditional(void *condv)
{
return !SDL_mutexP(((condvar_t *)condv)->mutex);
}
qboolean Sys_UnlockConditional(void *condv)
{
return !SDL_mutexV(((condvar_t *)condv)->mutex);
}
qboolean Sys_ConditionWait(void *condv)
{
return !SDL_CondWait(((condvar_t *)condv)->cond, ((condvar_t *)condv)->mutex);
}
qboolean Sys_ConditionSignal(void *condv)
{
return !SDL_CondSignal(((condvar_t *)condv)->cond);
}
qboolean Sys_ConditionBroadcast(void *condv)
{
return !SDL_CondBroadcast(((condvar_t *)condv)->cond);
}
void Sys_DestroyConditional(void *condv)
{
condvar_t *cv = (condvar_t *)condv;
SDL_DestroyCond(cv->cond);
SDL_DestroyMutex(cv->mutex);
free(cv);
}
#endif
void Sys_Sleep (double seconds)
{
SDL_Delay(seconds * 1000);
}
//emscripten does not support the full set of sdl functions, so we stub the extras.
int SDL_GetGammaRamp(Uint16 *redtable, Uint16 *greentable, Uint16 *bluetable)
{
return -1;
}
int SDL_SetGammaRamp(const Uint16 *redtable, const Uint16 *greentable, const Uint16 *bluetable)
{
return -1;
}
//SDL_GL_GetAttribute
void SDL_UnloadObject(void *object)
{
}
void *SDL_LoadObject(const char *sofile)
{
return NULL;
}
void *SDL_LoadFunction(void *handle, const char *name)
{
return NULL;
}
Uint8 SDL_GetAppState(void)
{
return SDL_APPACTIVE;
}
#define socklen_t int
/*
int getsockname(int socket, struct sockaddr *address, socklen_t *address_len)
{
return -1;
}
int getpeername(int socket, struct sockaddr *address, socklen_t *address_len)
{
return -1;
}
ssize_t sendto(int socket, const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
{
return -1;
}
*/
#include "quakedef.h"
#include <SDL.h>
#ifdef MULTITHREAD
#include <SDL_thread.h>
#endif
#include <SDL_loadso.h>
#include <emscripten/emscripten.h>
#include "ftejslib.h"
#ifndef isDedicated
qboolean isDedicated;
#endif
quakeparms_t parms;
void Sys_Error (const char *error, ...)
{
va_list argptr;
char string[1024];
va_start (argptr,error);
vsnprintf (string, sizeof (string), error, argptr);
va_end (argptr);
Sys_Printf("Error: %s\n", string);
Con_Print ("Quake Error: ");
Con_Print (string);
Con_Print ("\n");
Host_Shutdown ();
emscriptenfte_alert(string);
exit (1);
}
void Sys_RecentServer(char *command, char *target, char *title, char *desc)
{
}
qboolean Sys_RandomBytes(qbyte *string, int len)
{
return false;
}
//print into stdout
void Sys_Printf (char *fmt, ...)
{
va_list argptr;
char buf[1024];
va_start (argptr,fmt);
vsnprintf (buf, sizeof(buf), fmt, argptr);
emscriptenfte_print(buf);
va_end (argptr);
}
unsigned int Sys_Milliseconds(void)
{
static int first = true;
static unsigned long oldtime = 0, curtime = 0;
unsigned long newtime;
newtime = emscriptenfte_ticks_ms(); //return Date.now()
if (first)
{
first = false;
oldtime = newtime;
}
if (newtime < oldtime)
Con_Printf("Sys_Milliseconds stepped backwards!\n");
else
curtime += newtime - oldtime;
oldtime = newtime;
return curtime;
}
//return the current time, in the form of a double
double Sys_DoubleTime (void)
{
return Sys_Milliseconds() / 1000.0;
}
//create a directory
void Sys_mkdir (char *path)
{
}
//unlink a file
qboolean Sys_remove (char *path)
{
emscriptenfte_buf_delete(path);
return true;
}
qboolean Sys_Rename (char *oldfname, char *newfname)
{
return emscriptenfte_buf_rename(oldfname, newfname);
return false;
}
//someone used the 'quit' command
#include "glquake.h"
void Sys_Quit (void)
{
if (host_initialized)
{
qglClearColor(0,0,0,1);
qglClear(GL_COLOR_BUFFER_BIT);
Draw_FunString (0, 0, "Reload the page to restart");
Host_Shutdown();
}
exit (0);
}
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{
Con_DPrintf("Warning: Sys_EnumerateFiles not implemented\n");
return true;
}
//blink window if possible (it's not)
void Sys_ServerActivity(void)
{
}
void Sys_CloseLibrary(dllhandle_t *lib)
{
}
dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
{
return NULL;
}
void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname)
{
return NULL;
}
void Sys_Init(void)
{
extern cvar_t vid_width, vid_height, vid_fullscreen;
//vid_fullscreen takes effect only on mouse clicks, any suggestion to do a vid_restart is pointless.
vid_fullscreen.flags &= ~CVAR_RENDERERLATCH;
//these are not really supported. so silence any spam that suggests we do something about something not even supported.
vid_width.flags &= ~CVAR_RENDERERLATCH;
vid_height.flags &= ~CVAR_RENDERERLATCH;
}
void Sys_Shutdown(void)
{
}
int VARGS Sys_DebugLog(char *file, char *fmt, ...)
{
return 0;
};
qboolean Sys_InitTerminal(void)
{
return true;
}
char *Sys_ConsoleInput(void)
{
return NULL;
}
void Sys_CloseTerminal (void)
{
}
int Sys_MainLoop(void)
{
extern cvar_t vid_vsync;
static float oldtime;
float newtime, time;
newtime = Sys_DoubleTime ();
if (!oldtime)
oldtime = newtime;
time = newtime - oldtime;
if (!host_initialized)
{
Sys_Printf ("Host_Init\n");
Host_Init (&parms);
return 1;
}
oldtime = newtime;
Host_Frame (time);
return vid_vsync.ival;
}
int QDECL main(int argc, char **argv)
{
memset(&parms, 0, sizeof(parms));
parms.basedir = "";
parms.argc = argc;
parms.argv = (const char**)argv;
COM_InitArgv (parms.argc, parms.argv);
TL_InitLanguages("");
emscriptenfte_setupmainloop(Sys_MainLoop);
return 0;
}
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
{
return false;
}
static char *clipboard_buffer;
char *Sys_GetClipboard(void)
{
return clipboard_buffer;
}
void Sys_CloseClipboard(char *bf)
{
}
void Sys_SaveClipboard(char *text)
{
free(clipboard_buffer);
clipboard_buffer = strdup(text);
}
#ifdef MULTITHREAD
/* Thread creation calls */
void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize)
{
// SDL threads do not support setting thread stack size
return (void *)SDL_CreateThread(func, args);
}
void Sys_WaitOnThread(void *thread)
{
SDL_WaitThread((SDL_Thread *)thread, NULL);
}
/* Mutex calls */
// SDL mutexes don't have try-locks for mutexes in the spec so we stick with 1-value semaphores
void *Sys_CreateMutex(void)
{
return (void *)SDL_CreateSemaphore(1);
}
qboolean Sys_TryLockMutex(void *mutex)
{
return !SDL_SemTryWait(mutex);
}
qboolean Sys_LockMutex(void *mutex)
{
return !SDL_SemWait(mutex);
}
qboolean Sys_UnlockMutex(void *mutex)
{
return !SDL_SemPost(mutex);
}
void Sys_DestroyMutex(void *mutex)
{
SDL_DestroySemaphore(mutex);
}
/* Conditional wait calls */
typedef struct condvar_s
{
SDL_mutex *mutex;
SDL_cond *cond;
} condvar_t;
void *Sys_CreateConditional(void)
{
condvar_t *condv;
SDL_mutex *mutex;
SDL_cond *cond;
condv = (condvar_t *)malloc(sizeof(condvar_t));
if (!condv)
return NULL;
mutex = SDL_CreateMutex();
cond = SDL_CreateCond();
if (mutex)
{
if (cond)
{
condv->cond = cond;
condv->mutex = mutex;
return (void *)condv;
}
else
SDL_DestroyMutex(mutex);
}
free(condv);
return NULL;
}
qboolean Sys_LockConditional(void *condv)
{
return !SDL_mutexP(((condvar_t *)condv)->mutex);
}
qboolean Sys_UnlockConditional(void *condv)
{
return !SDL_mutexV(((condvar_t *)condv)->mutex);
}
qboolean Sys_ConditionWait(void *condv)
{
return !SDL_CondWait(((condvar_t *)condv)->cond, ((condvar_t *)condv)->mutex);
}
qboolean Sys_ConditionSignal(void *condv)
{
return !SDL_CondSignal(((condvar_t *)condv)->cond);
}
qboolean Sys_ConditionBroadcast(void *condv)
{
return !SDL_CondBroadcast(((condvar_t *)condv)->cond);
}
void Sys_DestroyConditional(void *condv)
{
condvar_t *cv = (condvar_t *)condv;
SDL_DestroyCond(cv->cond);
SDL_DestroyMutex(cv->mutex);
free(cv);
}
#endif
void Sys_Sleep (double seconds)
{
SDL_Delay(seconds * 1000);
}
//emscripten does not support the full set of sdl functions, so we stub the extras.
int SDL_GetGammaRamp(Uint16 *redtable, Uint16 *greentable, Uint16 *bluetable)
{
return -1;
}
int SDL_SetGammaRamp(const Uint16 *redtable, const Uint16 *greentable, const Uint16 *bluetable)
{
return -1;
}
//SDL_GL_GetAttribute
void SDL_UnloadObject(void *object)
{
}
void *SDL_LoadObject(const char *sofile)
{
return NULL;
}
void *SDL_LoadFunction(void *handle, const char *name)
{
return NULL;
}
Uint8 SDL_GetAppState(void)
{
return SDL_APPACTIVE;
}
#define socklen_t int
/*
int getsockname(int socket, struct sockaddr *address, socklen_t *address_len)
{
return -1;
}
int getpeername(int socket, struct sockaddr *address, socklen_t *address_len)
{
return -1;
}
ssize_t sendto(int socket, const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
{
return -1;
}
*/