From 2383c618ee4df5f63c41f65b3d55d7ee1b48a345 Mon Sep 17 00:00:00 2001 From: Spoike Date: Mon, 9 Jan 2023 05:12:12 +0000 Subject: [PATCH] Fix up some SDL issues. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6315 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- CMakeLists.txt | 4 +- engine/client/image.c | 39 ++++---- engine/client/render.h | 2 +- engine/client/sys_sdl.c | 204 +++++++++++++++++++++++++++++++-------- engine/common/fs_stdio.c | 17 +++- engine/common/pr_bgcmd.c | 4 +- 6 files changed, 205 insertions(+), 65 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc156c1cb..e2328dcac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,7 +201,9 @@ IF(CMAKE_C_COMPILER_ID MATCHES "GNU") ELSE() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") ENDIF() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--warn-common") + IF (NOT FTE_USE_SDL) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--warn-common") + ENDIF() #SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wc++-compat") #lul, thousands of errors! ENDIF() IF(CMAKE_BUILD_TYPE MATCHES "Debug") diff --git a/engine/client/image.c b/engine/client/image.c index 6d5373e2c..63c1d3062 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -1570,7 +1570,7 @@ static void VARGS png_onwarning(png_structp png_ptr, png_const_charp warning_msg #endif } -qbyte *ReadPNGFile(const char *fname, qbyte *buf, int length, int *width, int *height, uploadfmt_t *format) +qbyte *ReadPNGFile(const char *fname, qbyte *buf, int length, int *width, int *height, uploadfmt_t *format, qboolean force_rgb32) { qbyte header[8], **rowpointers = NULL, *data = NULL; png_structp png; @@ -1638,7 +1638,7 @@ error: int numpal = 0, numtrans = 0; png_colorp pal = NULL; png_bytep trans = NULL; - if (bitdepth==8 && format) + if (bitdepth==8 && !force_rgb32) { qpng_get_tRNS(png, pnginfo, &trans, &numtrans, NULL); qpng_get_PLTE(png, pnginfo, &pal, &numpal); @@ -1691,7 +1691,7 @@ error: qpng_set_filler(png, ~0u, PNG_FILLER_AFTER); //expand greyscale to rgb when we're forcing 32bit output (with padding, as appropriate). - if ((colortype == PNG_COLOR_TYPE_GRAY || colortype == PNG_COLOR_TYPE_GRAY_ALPHA)&&!format) + if ((colortype == PNG_COLOR_TYPE_GRAY || colortype == PNG_COLOR_TYPE_GRAY_ALPHA)&&force_rgb32) { qpng_set_gray_to_rgb( png ); if (colortype == PNG_COLOR_TYPE_GRAY) @@ -1700,7 +1700,7 @@ error: if (bitdepth < 8) qpng_set_expand (png); - else if (bitdepth == 16 && (!format || colortype!=PNG_COLOR_TYPE_RGB_ALPHA)) + else if (bitdepth == 16 && (force_rgb32 || colortype!=PNG_COLOR_TYPE_RGB_ALPHA)) qpng_set_strip_16(png); else if (bitdepth == 16) qpng_set_swap(png); @@ -1712,27 +1712,24 @@ error: if (colortype == PNG_COLOR_TYPE_PALETTE) *format = PTI_P8; - else if (bitdepth == 8 && channels == 1 && format) + else if (bitdepth == 8 && channels == 1 && !force_rgb32) *format = PTI_L8; - else if (bitdepth == 8 && channels == 2 && format) + else if (bitdepth == 8 && channels == 2 && !force_rgb32) *format = (colortype == PNG_COLOR_TYPE_GRAY_ALPHA)?PTI_L8A8:PTI_RG8; - else if (bitdepth == 8 && channels == 3 && format) + else if (bitdepth == 8 && channels == 3 && !force_rgb32) *format = PTI_RGB8; else if (bitdepth == 8 && channels == 4) { - if (format) - { - if (colortype == PNG_COLOR_TYPE_GRAY) - *format = PTI_LLLX8; - else if (colortype == PNG_COLOR_TYPE_GRAY_ALPHA) - *format = PTI_LLLA8; - else if (colortype == PNG_COLOR_TYPE_RGB) - *format = PTI_RGBX8; - else //if (colortype == PNG_COLOR_TYPE_RGB_ALPHA) - *format = PTI_RGBA8; - } + if (colortype == PNG_COLOR_TYPE_GRAY) + *format = PTI_LLLX8; + else if (colortype == PNG_COLOR_TYPE_GRAY_ALPHA) + *format = PTI_LLLA8; + else if (colortype == PNG_COLOR_TYPE_RGB) + *format = PTI_RGBX8; + else //if (colortype == PNG_COLOR_TYPE_RGB_ALPHA) + *format = PTI_RGBA8; } - else if (bitdepth == 16 && channels == 4 && format) + else if (bitdepth == 16 && channels == 4 && !force_rgb32) *format = PTI_RGBA16; else { @@ -3352,7 +3349,7 @@ static qbyte *ReadICOFile(const char *fname, qbyte *buf, int length, int *width, qbyte *indata = buf + (bestimg->dwOffset_low | (bestimg->dwOffset_high<<16)); size_t insize = (bestimg->dwSize_low | (bestimg->dwSize_high<<16)); #ifdef AVAIL_PNGLIB - if (insize > 4 && (indata[0] == 137 && indata[1] == 'P' && indata[2] == 'N' && indata[3] == 'G') && (ret = ReadPNGFile(fname, indata, insize, width, height, fmt))) + if (insize > 4 && (indata[0] == 137 && indata[1] == 'P' && indata[2] == 'N' && indata[3] == 'G') && (ret = ReadPNGFile(fname, indata, insize, width, height, fmt, true))) { TRACE(("dbg: Read32BitImageFile: icon png\n")); return ret; @@ -7298,7 +7295,7 @@ qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_ #endif #ifdef AVAIL_PNGLIB - if (len > 4 && (buf[0] == 137 && buf[1] == 'P' && buf[2] == 'N' && buf[3] == 'G') && (data = ReadPNGFile(fname, buf, len, width, height, force_rgba8?NULL:format))) + if (len > 4 && (buf[0] == 137 && buf[1] == 'P' && buf[2] == 'N' && buf[3] == 'G') && (data = ReadPNGFile(fname, buf, len, width, height, format, force_rgba8))) return data; #endif #ifdef AVAIL_JPEGLIB diff --git a/engine/client/render.h b/engine/client/render.h index 5e61d10e6..2b75767c6 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -636,7 +636,7 @@ void RQ_Shutdown(void); qboolean WritePCXfile (const char *filename, enum fs_relative fsroot, qbyte *data, int width, int height, int rowbytes, qbyte *palette, qboolean upload); //data is 8bit. qbyte *ReadPCXFile(qbyte *buf, int length, int *width, int *height); void *ReadTargaFile(qbyte *buf, int length, int *width, int *height, uploadfmt_t *format, qboolean greyonly, uploadfmt_t forceformat); -qbyte *ReadPNGFile(const char *fname, qbyte *buf, int length, int *width, int *height, uploadfmt_t *format); +qbyte *ReadPNGFile(const char *fname, qbyte *buf, int length, int *width, int *height, uploadfmt_t *format, qboolean force_rgb32); qbyte *ReadPCXPalette(qbyte *buf, int len, qbyte *out); qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_t *format, qboolean force_rgba8, const char *fname); diff --git a/engine/client/sys_sdl.c b/engine/client/sys_sdl.c index df408e170..477bf3120 100644 --- a/engine/client/sys_sdl.c +++ b/engine/client/sys_sdl.c @@ -199,53 +199,178 @@ void Sys_Printf (char *fmt, ...) fflush(stdout); } -unsigned int Sys_Milliseconds(void) + + + +//#define QCLOCK(e,n,q,f,i) //q must have t= + +#if SDL_VERSION_ATLEAST(2,0,18) //less wrappy... still terrible precision. + #define CLOCKDEF_SDL_TICKS QCLOCK(TICKS, "ticks", t=SDL_GetTicks64(), 1000,;) +#else + #define CLOCKDEF_SDL_TICKS QCLOCK(TICKS, "ticks", t=SDL_GetTicks(), 1000,;) +#endif + +static quint64_t sdlperf_freq; +#define CLOCKDEF_SDL_PERF QCLOCK(PERF, "perf", t=SDL_GetPerformanceCounter(), sdlperf_freq,sdlperf_freq=SDL_GetPerformanceFrequency()) + +#ifdef CLOCK_MONOTONIC + #define CLOCKDEF_LINUX_MONOTONIC QCLOCK(MONOTONIC, "monotonic", { \ + struct timespec ts; \ + clock_gettime(CLOCK_MONOTONIC, &ts); \ + t = (ts.tv_sec*(quint64_t)1000000000) + ts.tv_nsec; \ + }, 1000000000,;) +#else + #define CLOCKDEF_LINUX_MONOTONIC +#endif + +#ifdef CLOCK_REALTIME + #define CLOCKDEF_LINUX_REALTIME QCLOCK(REALTIME, "realtime", { \ + struct timespec ts; \ + clock_gettime(CLOCK_REALTIME, &ts); \ + t = (ts.tv_sec*(quint64_t)1000000000) + ts.tv_nsec; \ + }, 1000000000,;) +#else + #define CLOCKDEF_LINUX_REALTIME +#endif + +#if _POSIX_C_SOURCE >= 200112L + #include + #define CLOCKDEF_POSIX_GTOD QCLOCK(GTOD, "gettimeofday", { \ + struct timeval tp; \ + gettimeofday(&tp, NULL); \ + t = tp.tv_sec*(quint64_t)1000000 + tp.tv_usec; \ + }, 1000000,;) +#else + #define CLOCKDEF_POSIX_GTOD +#endif + +#define CLOCKDEF_ALL \ + CLOCKDEF_LINUX_MONOTONIC CLOCKDEF_LINUX_REALTIME /*linux-specific clocks*/\ + CLOCKDEF_SDL_PERF CLOCKDEF_SDL_TICKS /*sdl clocks*/\ + CLOCKDEF_POSIX_GTOD /*posix clocks*/ + +static quint64_t timer_basetime; //used by all clocks to bias them to starting at 0 +static quint64_t timer_nobacksies; //used by all clocks to bias them to starting at 0 +static void Sys_ClockType_Changed(cvar_t *var, char *oldval); +#define QCLOCK(e,n,q,f,i) n"\n" +static cvar_t sys_clocktype = CVARFCD("sys_clocktype", "", CVAR_NOTFROMSERVER, Sys_ClockType_Changed, "Controls which system clock to base timings from.\nAvailable Clocks:\n" + CLOCKDEF_ALL); +#undef QCLOCK + +static enum { - static int first = true; - static unsigned long starttime = 0; - unsigned long now; - - now = SDL_GetTicks(); - - if (first) - { - first = false; - starttime = now; - } - - return now - starttime; -} - -//return the current time, in the form of a double -double Sys_DoubleTime (void) +#define QCLOCK(e,n,q,f,i) CLOCKID_##e, + CLOCKDEF_ALL +#undef QCLOCK + CLOCKID_INVALID +} timer_clocktype=CLOCKID_INVALID; +static quint64_t Sys_GetClock(quint64_t *freq) { - return Sys_Milliseconds() / 1000.0; -/* - static int first = true; - static double oldtime = 0.0, curtime = 0.0; - double newtime; - - newtime = (double) SDL_GetTicks() / 1000.0; - - - if (first) + quint64_t t; + switch(timer_clocktype) { - first = false; - oldtime = newtime; + default: +#define QCLOCK(e,n,q,f,i) case CLOCKID_##e: *freq = f; q; break; + CLOCKDEF_ALL +#undef QCLOCK } - - if (newtime < oldtime) + t -= timer_basetime; + if (t < timer_nobacksies && t-*freq>timer_nobacksies) { - // warn if it's significant - if (newtime - oldtime < -0.01) - Con_Printf("Sys_DoubleTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime); + quint64_t back = timer_nobacksies-t; + t = timer_nobacksies; + if (back > 0)//*freq/1000) //warn if the clock went backwards by more than 1ms. + Con_Printf("Warning: clock went backwards by %g secs.\n", back/(double)*freq); + if (back > 0x8000000 && *freq==1000) + { //32bit value wrapped? + timer_basetime -= 0x8000000; + t += 0x8000000; + } } else - curtime += newtime - oldtime; - oldtime = newtime; + timer_nobacksies = t; + return t; +} +static void Sys_ClockType_Changed(cvar_t *var, char *oldval) +{ + int newtype; - return curtime; -*/ +#define QCLOCK(e,n,q,f,i) if (!strcasecmp(var->string, n)) newtype = CLOCKID_##e; else + CLOCKDEF_ALL +#undef QCLOCK + { + quint64_t freq; + if (!*var->string || !strcasecmp(var->string, "auto")) + ; + else + { + Con_Printf("%s: Unknown clock name %s available clocks", var->name, var->string); +#define QCLOCK(e,n,q,f,i) Con_Printf(", %s", n); + CLOCKDEF_ALL +#undef QCLOCK + Con_Printf("\n"); + } + + //look for any that work. + for(newtype = 0; ; newtype++) + { + switch(newtype) + { + default: + freq = 0; + Sys_Error("No usable clocks"); +#define QCLOCK(e,n,q,f,i) case CLOCKID_##e: freq = f; break; + CLOCKDEF_ALL +#undef QCLOCK + } + if (freq) + break; //this clock seems usable. + } + } + + if (newtype != timer_clocktype) + { + quint64_t oldtime, oldfreq; + quint64_t newtime, newfreq; + + oldtime = Sys_GetClock(&oldfreq); + timer_clocktype = newtype; + timer_nobacksies = timer_basetime = 0; //make sure we get the raw clock. + newtime = Sys_GetClock(&newfreq); + + timer_basetime = newtime - (newfreq * ((long double)oldtime) / oldfreq); + timer_nobacksies = newtime - timer_basetime; + + Sys_GetClock(&newfreq); + } +} +static void Sys_InitClock(void) +{ + quint64_t freq; + + Cvar_Register(&sys_clocktype, "System vars"); + +#define QCLOCK(e,n,q,f,i) i; + CLOCKDEF_ALL +#undef QCLOCK + + //calibrate it, and apply. + timer_clocktype = CLOCKID_INVALID; + Sys_ClockType_Changed(&sys_clocktype, NULL); + timer_basetime = timer_nobacksies = 0; + timer_basetime = Sys_GetClock(&freq); + timer_nobacksies = 0; +} +double Sys_DoubleTime (void) +{ + quint64_t denum, num = Sys_GetClock(&denum); + return num / (long double)denum; +} +unsigned int Sys_Milliseconds (void) +{ + quint64_t denum, num = Sys_GetClock(&denum); + num *= 1000; + return num / denum; } //create a directory @@ -733,6 +858,7 @@ char *Sys_URIScheme_NeedsRegistering(void) void Sys_Init(void) { SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE); + Sys_InitClock(); } void Sys_Shutdown(void) { diff --git a/engine/common/fs_stdio.c b/engine/common/fs_stdio.c index ad4120845..0f4450927 100644 --- a/engine/common/fs_stdio.c +++ b/engine/common/fs_stdio.c @@ -1,6 +1,9 @@ #include "quakedef.h" #include "fs.h" #include "errno.h" +#if _POSIX_C_SOURCE >= 200112L +#include +#endif #if !defined(NACL) && !defined(FTE_TARGET_WEB) && (!defined(_WIN32) || defined(FTE_SDL)) @@ -336,7 +339,19 @@ static unsigned int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t if (Q_snprintfz (netpath, sizeof(netpath), "%s/%s", sp->rootpath, filename)) return FF_NOTFOUND; -#if 0//def ANDROID +#if _POSIX_C_SOURCE >= 200112L + { + struct stat sb; + if (stat(netpath, &sb) == 0) + { + len = sb.st_size; + if ((sb.st_mode & S_IFMT) != S_IFREG) + return FF_NOTFOUND; //no directories nor sockets! boo! (any simlink will already have been resolved) + } + else + return FF_NOTFOUND; //some kind of screwup. + } +#elif 0//defined(ANDROID) { vfsfile_t *f = VFSSTDIO_Open(netpath, "rb", NULL); if (!f) diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index bab67aeb0..3c17dd9b6 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -3599,9 +3599,9 @@ static qboolean PF_search_getloc(flocation_t *loc, prvmsearch_t *s, int num) { const char *fname = s->entry[num].name; if (s->searchinfo.handle) //we were only searching a single package... - { + { //fail if its a directory, or a (pk3)symlink that we'd have to resolve. loc->search = &s->searchinfo; - return loc->search->handle->FindFile(loc->search->handle, loc, fname, NULL); + return loc->search->handle->FindFile(loc->search->handle, loc, fname, NULL) == FF_FOUND; } else if (!s->entry[num].package) {