diff --git a/engine/client/keys.c b/engine/client/keys.c index 302a8b76..eb04ab14 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -2593,7 +2593,12 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down MP_Keydown (key, unicode, devid); #endif else if (Key_Dest_Has(kdm_message)) + { Key_Dest_Remove(kdm_message); + if (chat_buffer) + chat_buffer[0] = 0; + chat_bufferpos = 0; + } else { if (Media_PlayingFullScreen()) diff --git a/engine/client/merged.h b/engine/client/merged.h index 4c9a0857..afed70a2 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -451,7 +451,7 @@ typedef struct rendererinfo_s { char *alignment; //just to make sure that added functions cause compile warnings. //FIXME: keep this... - int (*VID_GetPriority) (void); //so that eg x11 or wayland can be prioritised depending on environment settings + int (*VID_GetPriority) (void); //so that eg x11 or wayland can be prioritised depending on environment settings. assumed to be 1. //FIXME: add getdestopres //FIXME: add clipboard handling diff --git a/engine/client/renderer.c b/engine/client/renderer.c index ea5e6307..89c51409 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -466,8 +466,9 @@ cvar_t vk_busywait = CVARD ("vk_busywait", "", "Force busy waiting unt cvar_t vk_waitfence = CVARD ("vk_waitfence", "", "Waits on fences, instead of semaphores. This is more likely to result in gpu stalls while the cpu waits."); cvar_t vk_nv_glsl_shader = CVARD ("vk_loadglsl", "", "Enable direct loading of glsl, where supported by drivers. Do not use in combination with vk_debug 2 (vk_debug should be 1 if you want to see any glsl compile errors). Don't forget to do a vid_restart after."); cvar_t vk_nv_dedicated_allocation = CVARD ("vk_nv_dedicated_allocation", "", "Flag vulkan memory allocations as dedicated, where applicable."); -cvar_t vk_khr_dedicated_allocation = CVARD ("vk_khr_dedicated_allocation", "", "Flag vulkan memory allocations as dedicated, where applicable."); +cvar_t vk_khr_dedicated_allocation = CVARD ("vk_khr_dedicated_allocation", "", "Flag vulkan memory allocations as dedicated, where applicable."); cvar_t vk_khr_push_descriptor = CVARD ("vk_khr_push_descriptor", "", "Enables better descriptor streaming."); +cvar_t vk_amd_rasterization_order = CVARD ("vk_amd_rasterization_order", "", "Enables the use of relaxed rasterization ordering, for a small speedup at the minor risk of a little zfighting."); #endif #ifdef D3D9QUAKE @@ -1007,6 +1008,7 @@ void Renderer_Init(void) Cvar_Register (&vk_nv_dedicated_allocation, VKRENDEREROPTIONS); Cvar_Register (&vk_khr_dedicated_allocation,VKRENDEREROPTIONS); Cvar_Register (&vk_khr_push_descriptor, VKRENDEREROPTIONS); + Cvar_Register (&vk_amd_rasterization_order, VKRENDEREROPTIONS); #endif // misc @@ -1300,10 +1302,12 @@ void R_ShutdownRenderer(qboolean devicetoo) { TRACE(("dbg: R_ApplyRenderer: R_DeInit\n")); R_DeInit(); + R_DeInit = NULL; } if (Draw_Shutdown) Draw_Shutdown(); + Draw_Shutdown = NULL; TRACE(("dbg: R_ApplyRenderer: SCR_DeInit\n")); SCR_DeInit(); @@ -1312,6 +1316,7 @@ void R_ShutdownRenderer(qboolean devicetoo) { TRACE(("dbg: R_ApplyRenderer: VID_DeInit\n")); VID_DeInit(); + VID_DeInit = NULL; } COM_FlushTempoaryPacks(); @@ -1423,7 +1428,14 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr) #endif if (newr) if (!r_forceheadless || newr->renderer->rtype != QR_HEADLESS) - Con_TPrintf("Setting mode %i*%i %ibpp %ihz %s%s\n", newr->width, newr->height, newr->bpp, newr->rate, newr->srgb?"SRGB ":"", newr->renderer->description); + { + if (newr->fullscreen == 2) + Con_TPrintf("Setting fullscreen windowed %s%s\n", newr->srgb?"SRGB ":"", newr->renderer->description); + else if (newr->fullscreen) + Con_TPrintf("Setting mode %i*%i %ibpp %ihz %s%s\n", newr->width, newr->height, newr->bpp, newr->rate, newr->srgb?"SRGB ":"", newr->renderer->description); + else + Con_TPrintf("Setting windowed mode %i*%i %s%s\n", newr->width, newr->height, newr->srgb?"SRGB ":"", newr->renderer->description); + } vid.fullbright=0; @@ -1796,6 +1808,25 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring) newr->stereo = (r_stereo_method.ival == 1); newr->srgb = vid_srgb.ival; +#ifdef _WIN32 + if (newr->bpp && newr->bpp < 24) + { + extern int qwinvermaj; + extern int qwinvermin; + if ((qwinvermaj == 6 && qwinvermin >= 2) || qwinvermaj>6) + { + /* + Note Apps that you design to target Windows 8 and later can no longer query or set display modes that are less than 32 bits per pixel (bpp); + these operations will fail. These apps have a compatibility manifest that targets Windows 8. + Windows 8 still supports 8-bit and 16-bit color modes for desktop apps that were built without a Windows 8 manifest; + Windows 8 emulates these modes but still runs in 32-bit color mode. + */ + Con_Printf("Starting with windows 8, windows no longer supports 16-bit video modes\n"); + newr->bpp = 24; //we don't count alpha as part of colour depth. windows does, so this'll end up as 32bit regardless. + } + } +#endif + if (com_installer) { newr->fullscreen = false; @@ -1813,9 +1844,9 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring) rendererstring = COM_Parse(rendererstring); if (r_forceheadless) { //special hack so that android doesn't weird out when not focused. - for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++) + for (i = 0; i < countof(rendererinfo); i++) { - if (rendererinfo[i] && rendererinfo[i]->name[0] && !stricmp(rendererinfo[i]->name[0], "headless")) + if (rendererinfo[i] && rendererinfo[i]->name[0] && rendererinfo[i]->rtype == QR_HEADLESS) { newr->renderer = rendererinfo[i]; break; @@ -1824,12 +1855,30 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring) } else if (!*com_token) { - for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++) + int bestpri = -2; + int pri; + newr->renderer = NULL; + //I'd like to just qsort the renderers, but that isn't stable and might reorder gl+d3d etc. + for (i = 0; i < countof(rendererinfo); i++) { - if (rendererinfo[i] && rendererinfo[i]->name[0] && stricmp(rendererinfo[i]->name[0], "none")) + if (rendererinfo[i] && rendererinfo[i]->name[0]) { + if (rendererinfo[i]->VID_GetPriority) + pri = rendererinfo[i]->VID_GetPriority(); + else if (rendererinfo[i]->rtype == QR_HEADLESS) + pri = -1; //headless renderers are a really poor choice, and will make the user think it buggy. + else if (rendererinfo[i]->rtype == QR_NONE) + pri = 0; //dedicated servers are possible, but we really don't want to use them unless we have no other choice. + else + pri = 1; //assume 1 for most renderers. + } + else + pri = -2; + + if (pri > bestpri) + { + bestpri = pri; newr->renderer = rendererinfo[i]; - break; } } } @@ -1965,20 +2014,33 @@ void R_RestartRenderer (rendererstate_t *newr) qboolean failed = true; rendererinfo_t *skip = newr->renderer; - if (newr->rate != 0) + if (failed && newr->fullscreen == 1) + { + Con_Printf(CON_NOTICE "Trying fullscreen windowed\n"); + newr->fullscreen = 2; + failed = !R_ApplyRenderer(newr); + } + if (failed && newr->rate != 0) { Con_Printf(CON_NOTICE "Trying default refresh rate\n"); newr->rate = 0; failed = !R_ApplyRenderer(newr); } - if (failed && newr->width != DEFAULT_WIDTH && newr->height != DEFAULT_HEIGHT) { Con_Printf(CON_NOTICE "Trying %i*%i\n", DEFAULT_WIDTH, DEFAULT_HEIGHT); + if (newr->fullscreen == 2) + newr->fullscreen = 1; newr->width = DEFAULT_WIDTH; newr->height = DEFAULT_HEIGHT; failed = !R_ApplyRenderer(newr); } + if (failed && newr->fullscreen) + { + Con_Printf(CON_NOTICE "Trying windowed\n"); + newr->fullscreen = 0; + failed = !R_ApplyRenderer(newr); + } //FIXME: query renderers for their priority and then use that. then we can favour X11 when DISPLAY is set and wayland when WAYLAND_DISPLAY is set, etc. for (i = 0; failed && i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++) diff --git a/engine/client/vid.h b/engine/client/vid.h index cd6a5557..f23dd270 100644 --- a/engine/client/vid.h +++ b/engine/client/vid.h @@ -36,7 +36,7 @@ typedef enum QR_VULKAN, // QR_DIRECT3D12, //no implementation QR_METAL, //no implementation - QR_DIRECT3D8 // + QR_DIRECT3D8 //liimted. available for win95 where d3d8.1+ does not. also only renderer supported on the original xbox, if that's ever relevant. } r_qrenderer_t; typedef struct { diff --git a/engine/client/vid_headless.c b/engine/client/vid_headless.c index f8d862d9..bd46b26a 100644 --- a/engine/client/vid_headless.c +++ b/engine/client/vid_headless.c @@ -158,6 +158,10 @@ static qboolean Headless_VID_ApplyGammaRamps (unsigned int gammarampsize, unsig static void Headless_VID_SetWindowCaption (const char *msg) { } +static int Headless_VID_GetPrioriy (void) +{ //headless renderers are the lowest priority possible, due to how broken they'd be perceived to be. + return -1; +} static char *Headless_VID_GetRGBInfo (int *bytestride, int *truevidwidth, int *truevidheight, enum uploadfmt *fmt) { *fmt = TF_INVALID; @@ -280,7 +284,8 @@ rendererinfo_t headlessrenderer = Headless_BE_VBO_Finish, Headless_BE_VBO_Destroy, Headless_BE_RenderToTextureUpdate2d, - "" + "", + Headless_VID_GetPrioriy }; @@ -375,9 +380,9 @@ rendererinfo_t headlessvkrendererinfo = GLVID_DeInit, GLVID_SwapBuffers, GLVID_ApplyGammaRamps, - WIN_CreateCursor, - WIN_SetCursor, - WIN_DestroyCursor, + NULL, + NULL, + NULL, GLVID_SetCaption, VKVID_GetRGBInfo, @@ -405,7 +410,9 @@ rendererinfo_t headlessvkrendererinfo = VKBE_RenderToTextureUpdate2d, - "no more" + "no more", + + Headless_VID_GetPrioriy }; #endif #endif diff --git a/engine/client/view.c b/engine/client/view.c index 57ea6338..257eda26 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1998,10 +1998,11 @@ void R_DrawNameTags(void) if (surf) { shader_t *shader = surf->texinfo->texture->shader; - char *body = shader?Shader_GetShaderBody(shader, NULL, 0):NULL; + char fname[MAX_QPATH]; + char *body = shader?Shader_GetShaderBody(shader, fname, countof(fname)):NULL; if (body) { - str = va("%s\n{%s\n", surf->texinfo->texture->name, body); + str = va("%s:\n%s\n{%s\n", fname, surf->texinfo->texture->name, body); Z_Free(body); } else diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index d9cd1949..74ec6c1b 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -1203,7 +1203,7 @@ static qboolean VID_SetFullDIBMode (rendererstate_t *info) if (ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { - Con_SafePrintf((gdevmode.dmFields&DM_DISPLAYFREQUENCY)?"Windows rejected mode %i*%i*%ibpp@%ihz\n":"Windows rejected mode %i*%i*%ibpp\n", (int)gdevmode.dmPelsWidth, (int)gdevmode.dmPelsHeight, (int)gdevmode.dmBitsPerPel, (int)gdevmode.dmDisplayFrequency); + Con_SafePrintf((gdevmode.dmFields&DM_DISPLAYFREQUENCY)?"Windows rejected mode %i*%i, %ibpp @%ihz\n":"Windows rejected mode %i*%i, %ibpp\n", (int)gdevmode.dmPelsWidth, (int)gdevmode.dmPelsHeight, (int)gdevmode.dmBitsPerPel, (int)gdevmode.dmDisplayFrequency); return false; } } @@ -3422,9 +3422,10 @@ static qboolean NVVKVID_Init (rendererstate_t *info, unsigned char *palette) } rendererinfo_t nvvkrendererinfo = { - "GL_NV_draw_vulkan_image", + "Vulkan via OpenGL (GL_NV_draw_vulkan_image)", { "nvvk", + "GL_NV_draw_vulkan_image", }, QR_VULKAN, diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 54217ba7..e36242e2 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -2499,7 +2499,7 @@ void PR_CleanUpStatements32(progfuncs_t *progfuncs, dstatement32_t *st, pbool he } char *decode(int complen, int len, int method, char *info, char *buffer); -unsigned char *PR_GetHeapBuffer (void *ctx, size_t bufsize) +unsigned char *PDECL PR_GetHeapBuffer (void *ctx, size_t bufsize) { return PRHunkAlloc(ctx, bufsize+1, "proginfo"); } diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index c2935602..f60cd272 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -202,7 +202,7 @@ struct pubprogfuncs_s typedef struct progexterns_s { int progsversion; //PROGSTRUCT_VERSION - void *(PDECL *ReadFile) (const char *fname, unsigned char *(*buf_get)(void *ctx, size_t len), void *buf_ctx, size_t *out_size); + void *(PDECL *ReadFile) (const char *fname, unsigned char *(PDECL *buf_get)(void *ctx, size_t len), void *buf_ctx, size_t *out_size); int (PDECL *FileSize) (const char *fname); //-1 if file does not exist pbool (PDECL *WriteFile) (const char *name, void *data, int len); int (VARGS *Printf) (const char *, ...) LIKEPRINTF(1); diff --git a/engine/qclib/qcc_cmdlib.c b/engine/qclib/qcc_cmdlib.c index 1d1cdb3c..b90748a7 100644 --- a/engine/qclib/qcc_cmdlib.c +++ b/engine/qclib/qcc_cmdlib.c @@ -1208,7 +1208,7 @@ char *QCC_SanitizeCharSet(char *mem, size_t *len, pbool *freeresult, int *origfm return mem; } -static unsigned char *QCC_LoadFileHunk(void *ctx, size_t size) +static unsigned char *PDECL QCC_LoadFileHunk(void *ctx, size_t size) { //2 ensures we can always put a \n in there. return (unsigned char*)qccHunkAlloc(sizeof(qcc_cachedsourcefile_t)+size+2) + sizeof(qcc_cachedsourcefile_t); } @@ -1288,7 +1288,7 @@ void QCC_AddFile (char *filename) qcc_sourcefile = sfile; } -static unsigned char *FS_ReadToMem_Alloc(void *ctx, size_t size) +static unsigned char *PDECL FS_ReadToMem_Alloc(void *ctx, size_t size) { unsigned char *mem; progfuncs_t *progfuncs = qccprogfuncs; diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index 092e5fca..5eac4653 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -2748,7 +2748,7 @@ static void QCC_MergeGlobalDefs16(ddef16_t *in, size_t num, void *values, size_t QCC_FreeDef(root); } -static unsigned char *QCC_LoadFileHunkAlloc(void *ctx, size_t size) +static unsigned char *PDECL QCC_LoadFileHunkAlloc(void *ctx, size_t size) { return (unsigned char*)qccHunkAlloc(size+1); }