Lazy GLSL loading, for faster load times.

Fixed some xim issues, for proper keyboard input under x11.
Cmake project can now work for cross compiling win32 targets.
Some other fun-but-pointless stuff.



git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5344 fc73d0e0-1445-4013-8a0c-d673dee63da5
master
Spoike 5 years ago
parent 79689474b6
commit 5b4756f3d9

@ -64,6 +64,16 @@ IF(NOT ZLIB_FOUND)
SET(ZLIB_LIBRARIES )
ENDIF()
FIND_PACKAGE(BZip2)
IF(BZIP2_FOUND)
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};AVAIL_BZLIB)
SET(FTE_LIBS ${FTE_LIBS} bz2)
SET(FTESV_LIBS ${FTESV_LIBS} bz2)
MESSAGE(STATUS "bzip2 library found. bz2-compressed pk3s will work for the price of extra bloat! yay!")
ELSE()
MESSAGE(WARNING "bzip2 library NOT available. bz2-compressed pk3s will not be available, as if anyone cares.")
ENDIF()
SET(OpenGL_GL_PREFERENCE LEGACY)
FIND_PACKAGE(OpenGL)
IF(OpenGL_FOUND)
@ -93,14 +103,13 @@ ELSE()
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_FREETYPE)
ENDIF()
#FIND_PACKAGE(Vulkan)
#IF(Vulkan_FOUND)
# INCLUDE_DIRECTORIES( ${Vulkan_INCLUDE_DIRS} )
SET(FTE_DEFINES ${FTE_DEFINES};VKQUAKE)
#ELSE()
# SET(FTE_DEFINES ${FTE_DEFINES};VKQUAKE)
# MESSAGE(WARNING "System vulkan headers NOT available.")
#ENDIF()
FIND_PATH(VULKAN_INCLUDE_DIR vulkan/vulkan.h)
IF(VULKAN_INCLUDE_DIR)
INCLUDE_DIRECTORIES( ${VULKAN_INCLUDE_DIR} )
SET(FTE_DEFINES ${FTE_DEFINES};VKQUAKE) #no libs required, thankfully
ELSE()
MESSAGE(WARNING "Vulkan headers NOT available.")
ENDIF()
FIND_LIBRARY(VORBISFILE_LIBRARY NAMES vorbisfile)
IF(NOT VORBISFILE_LIBRARY)
@ -132,7 +141,7 @@ IF(${ANDROID})
# INCLUDE_DIRECTORIES( ${FREETYPE_INCLUDE_DIRS} )
SET(FTE_DEFINES ${FTE_DEFINES};ANDROID;VKQUAKE;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG;MULTITHREAD;stricmp=strcasecmp;strnicmp=strncasecmp)
SET(FTE_LIBS android log EGL ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS})
SET(FTE_LIBS ${FTE_LIBS} android log EGL ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS})
SET(FTE_ARCH_FILES
engine/client/sys_droid.c
engine/common/sys_linux_threads.c
@ -146,7 +155,7 @@ ELSEIF(${WIN32})
# engine/server/sv_sys_win.c
SET(FTE_LIBS ${ZLIB_LIBRARIES} ole32 gdi32 wsock32 winmm dxguid)
SET(FTE_LIBS ${FTE_LIBS} ${ZLIB_LIBRARIES} ole32 gdi32 wsock32 winmm dxguid)
SET(FTE_DEFINES ${FTE_DEFINES};D3D9QUAKE;D3D11QUAKE;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG)
SET(FTE_ARCH_FILES
engine/client/winquake.rc
@ -177,7 +186,7 @@ ELSEIF(${WIN32})
engine/d3d/vid_d3d8.c
)
SET(FTESV_LIBS ${ZLIB_LIBRARIES} wsock32 winmm)
SET(FTESV_LIBS ${FTESV_LIBS} ${ZLIB_LIBRARIES} wsock32 winmm)
SET(FTESV_ARCH_FILES
engine/client/winquake.rc
engine/common/sys_win_threads.c
@ -213,7 +222,7 @@ ELSEIF(${UNIX}) #linux(ish)
ENDIF()
SET(FTE_DEFINES ${FTE_DEFINES};DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG;DYNAMIC_SDL;MULTITHREAD;stricmp=strcasecmp;strnicmp=strncasecmp)
SET(FTE_LIBS ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} pthread ${SDL2_LIBRARIES})
SET(FTE_LIBS ${FTE_LIBS} ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} pthread ${SDL2_LIBRARIES})
SET(FTE_ARCH_FILES
engine/client/sys_linux.c
engine/common/sys_linux_threads.c
@ -267,7 +276,7 @@ ELSEIF(${UNIX}) #linux(ish)
engine/common/net_ssl_gnutls.c
# engine/common/net_ssl_openssl.c
)
SET(FTESV_LIBS ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} pthread)
SET(FTESV_LIBS ${FTESV_LIBS} ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} pthread)
# SET(FTE_DEFINES ${FTE_DEFINES};HAVE_OPENSSL)
# SET(FTESV_DEFINES ${FTESV_DEFINES};HAVE_OPENSSL)
@ -286,7 +295,7 @@ ELSEIF(1) #SDL
#SDL2.0.7 supports vulkan, so lets use it.
SET(FTE_DEFINES ${FTE_DEFINES};FTE_SDL;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG;stricmp=strcasecmp;strnicmp=strncasecmp)
SET(FTE_LIBS ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} ${SDL2_LIBRARIES})
SET(FTE_LIBS ${FTE_LIBS} ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} ${SDL2_LIBRARIES})
SET(FTE_ARCH_FILES
engine/client/sys_sdl.c
engine/client/snd_al.c
@ -297,7 +306,7 @@ ELSEIF(1) #SDL
)
SET(FTESV_DEFINES FTE_SDL;stricmp=strcasecmp;strnicmp=strncasecmp)
SET(FTESV_LIBS ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} ${SDL2_LIBRARIES})
SET(FTESV_LIBS ${FTESV_LIBS} ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} ${SDL2_LIBRARIES})
IF(WIN32)
SET(FTE_LIBS ${FTE_LIBS} wsock32 gdi32 ole32)
@ -375,6 +384,7 @@ SET(FTE_COMMON_FILES
engine/common/fs_stdio.c
engine/common/fs_xz.c
engine/common/fs_zip.c
engine/common/fs_vpk.c
engine/common/gl_q2bsp.c
engine/common/huff.c
engine/common/log.c
@ -394,6 +404,11 @@ SET(FTE_COMMON_FILES
engine/common/sha1.c
engine/common/translate.c
engine/common/zone.c
engine/common/config_fteqw.h
engine/common/config_minimal.h
engine/common/config_nocompat.h
engine/common/config_wastes.h
#sigh
engine/client/pr_skelobj.c
@ -542,6 +557,31 @@ SET(FTE_CLIENT_FILES
engine/vk/vk_init.c
)
FILE(STRINGS "${FTE_BUILD_CONFIG}" BULLET_INTERNAL REGEX "^#define[\t ]+USE_INTERNAL_BULLET")
IF(BULLET_INTERNAL)
#Built-in bullet physics plugin...
FIND_PACKAGE(Bullet REQUIRED)
SET(FTE_COMMON_FILES ${FTE_COMMON_FILES} plugins/bullet/bulletplug.cpp)
INCLUDE_DIRECTORIES( ${BULLET_INCLUDE_DIRS} )
SET(FTE_LIBS ${FTE_LIBS} ${BULLET_LIBRARIES})
SET(FTESV_LIBS ${FTESV_LIBS} ${BULLET_LIBRARIES})
ELSE()
#Bullet Physics library plugin
FIND_PACKAGE(Bullet)
IF (BULLET_FOUND)
ADD_LIBRARY(bullet MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/bullet/bulletplug.cpp
)
TARGET_INCLUDE_DIRECTORIES(bullet PUBLIC ${BULLET_INCLUDE_DIRS})
SET_TARGET_PROPERTIES(bullet PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN")
SET_TARGET_PROPERTIES(bullet PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(bullet PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(bullet m ${BULLET_LIBRARIES})
ENDIF()
ENDIF()
IF(ANDROID)
#android sucks. everything is a library. so we build the engine as a shared library and completely ignore dedicated servers+tools
ADD_LIBRARY(ftedroid MODULE
@ -581,6 +621,9 @@ ELSE()
engine/http/ftpserver.c
)
SET_TARGET_PROPERTIES(httpserver PROPERTIES COMPILE_DEFINITIONS "WEBSERVER;WEBSVONLY;${FTE_REVISON};stricmp=strcasecmp;strnicmp=strncasecmp")
IF(WIN32)
TARGET_LINK_LIBRARIES(httpserver ${ZLIB_LIBRARIES} ws2_32)
ENDIF()
ADD_EXECUTABLE(fteqcc
engine/qclib/qcctui.c
@ -626,31 +669,24 @@ ADD_LIBRARY(qi MODULE
)
SET_TARGET_PROPERTIES(qi PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(qi PROPERTIES PREFIX "fteplug_")
#Bullet Physics library plugin
#FIND_PACKAGE(Bullet)
IF (BULLET_FOUND)
ADD_LIBRARY(bullet MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/bullet/bulletplug.cpp
)
TARGET_INCLUDE_DIRECTORIES(bullet PUBLIC ${BULLET_INCLUDE_DIRS})
SET_TARGET_PROPERTIES(bullet PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN")
SET_TARGET_PROPERTIES(bullet PROPERTIES PREFIX "fteplug_")
ENDIF()
SET_TARGET_PROPERTIES(qi PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(qi m)
#ODE Physics library plugin
#FIND_PACKAGE(ode)
IF (ODE_FOUND)
FIND_PATH(LIBODE_INCLUDE_DIR ode/ode.h)
FIND_LIBRARY(LIBODE_LIBRARY ode)
IF (LIBODE_INCLUDE_DIR)
ADD_LIBRARY(ode MODULE
plugins/qvm_api.c
plugins/plugin.c
engine/common/com_phys_ode.c
engine/common/mathlib.c
)
TARGET_INCLUDE_DIRECTORIES(ode PUBLIC ${ODE_INCLUDE_DIRS})
SET_TARGET_PROPERTIES(ode PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;ODE_STATIC")
SET_TARGET_PROPERTIES(ode PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(ode PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(ode m ${LIBODE_LIBRARY})
ENDIF()
#EzQuake Hud port plugin
@ -664,6 +700,8 @@ ADD_LIBRARY(ezhud MODULE
)
SET_TARGET_PROPERTIES(ezhud PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(ezhud PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(ezhud PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(ezhud m)
#IRC client plugin
ADD_LIBRARY(irc MODULE
@ -673,6 +711,8 @@ ADD_LIBRARY(irc MODULE
)
SET_TARGET_PROPERTIES(irc PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(irc PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(irc PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(irc m)
#ffmpeg client plugin. no proper way to detect dependancies right now, so I've gotta try the manual way.
FIND_PATH(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)
@ -715,6 +755,11 @@ IF(NOT ANDROID)
)
SET_TARGET_PROPERTIES(xmpp PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(xmpp PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(xmpp PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
IF(${WIN32})
ELSE()
TARGET_LINK_LIBRARIES(xmpp m resolv)
ENDIF()
ENDIF()
#cef plugin

@ -0,0 +1,59 @@
#!/bin/sh
#this script is DANGEROUS
#be sure to have committed *BEFORE* running this script.
#Note: This script does not understand dead files (including botlib).
#expect '-Wmisleading-indentation' warnings (that were previously muted by nearby ifdefs).
#DO NOT COMMIT THE RESULTS TO FTE'S TRUNK
CONFIG=wastes
#must have trailing slashes
SRCDIR=./
NEWDIR=/tmp/fte-$CONFIG/
echo "WARNING: This script will lock-in a build config upon your C files."
echo "The resulting files will support only your choice of feature set, instead of having lots of unused code mixed in."
echo "THIS IS DESTRUCTIVE SO MUST ONLY BE USED FOR FORKS."
read -p "Press name the build config (or ctrl+c to abort)" CONFIG
if [ "$foo" == "" ]; then
echo "no config specified."
exit 1
fi
mkdir -p $NEWDIR
cat $SRCDIR/engine/common/config_$CONFIG.h | grep "#define" | sed "s/\/\/#define/#undef/g" > $NEWDIR/unifdefrules
cat $SRCDIR/engine/common/config_$CONFIG.h | grep "#undef" >> $NEWDIR/unifdefrules
if [ "$SRCDIR" != "$NEWDIR" ]; then
echo "Copying files to strip to $NEWDIR."
cp -r $SRCDIR* $NEWDIR
else
echo "WARNING: WRITING FILES IN PLACE MUST ONLY BE USED FOR FORKS."
read -p "Press y<enter> to confirm (or ctrl+c to abort)" foo
if [ "$foo" != "y" ]; then
exit 1
fi
fi
cd $NEWDIR
for FILENAME in engine/*/*.c; do
unifdef -f unifdefrules -m $FILENAME
done
#headers keep any defines that will be expanded in code.
cat $NEWDIR/unifdefrules | grep -v FULLENGINENAME | grep -v DISTRIBUTION | grep -v ENGINEWEBSITE | grep -v MAX_SPLITS | grep GAME_SHORTNAME > $NEWDIR/unifdefhrules
for FILENAME in engine/*/*.h; do
unifdef -f unifdefhrules -m $FILENAME
done
rm $NEWDIR/unifdefrules
echo "Files in $NEWDIR have now been stripped down."
echo "Some things may require hand-editing to remove warnings (or just compile with CFLAGS=-Wno-misleading-indentation)."
echo "You still need to set FTE_CONFIG too."
read -p "Press enter to test-compile" foo
cd $NEWDIR/engine && make sv-rel m-rel -j8 FTE_CONFIG=$CONFIG -k

@ -382,11 +382,13 @@ void CL_MakeActive(char *gamename)
//kill models left over from the last map.
Mod_Purge(MP_MAPCHANGED);
Image_Purge();
//and reload shaders now if needed (this was blocked earlier)
Shader_DoReload();
//and now free any textures that were not still needed.
Image_Purge();
SCR_EndLoadingPlaque();
CL_UpdateWindowTitle();
@ -5911,6 +5913,7 @@ double Host_Frame (double time)
{
RSpeedMark();
vid.ime_allow = false;
if (SCR_UpdateScreen())
fps_count++;
if (R2D_Flush)

@ -1638,9 +1638,9 @@ void SCR_SizeDown_f (void)
//============================================================================
void SCR_StringXY(char *str, float x, float y)
void SCR_StringXY(const char *str, float x, float y)
{
char *s2;
const char *s2;
int px, py;
unsigned int codepoint;
int error;
@ -3448,6 +3448,7 @@ void SCR_DeInit (void)
Cmd_RemoveCommand ("screenshot_mega");
Cmd_RemoveCommand ("screenshot_stereo");
Cmd_RemoveCommand ("screenshot_vr");
Cmd_RemoveCommand ("screenshot_360");
Cmd_RemoveCommand ("screenshot_cubemap");
Cmd_RemoveCommand ("envmap");
Cmd_RemoveCommand ("sizeup");

@ -1339,6 +1339,20 @@ DRAWING
==============================================================================
*/
qboolean COM_InsertIME(conchar_t *buffer, size_t buffersize, conchar_t **cursor, conchar_t **textend)
{
conchar_t *in = vid.ime_preview;
if (in && *in && *textend+vid.ime_previewlen < buffer+buffersize)
{
memmove(buffer + (*cursor-buffer) + vid.ime_previewlen, *cursor, ((*textend-*cursor)+1)*sizeof(conchar_t));
memcpy(buffer + (*cursor-buffer), in, vid.ime_previewlen*sizeof(conchar_t));
*cursor += vid.ime_caret;
*textend += vid.ime_previewlen;
return true;
}
return false;
}
/*
================
@ -1364,9 +1378,18 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
size_t textsize;
qboolean cursorframe;
unsigned int codeflags, codepoint;
int cursorpos;
qboolean hidecomplete;
int x;
if (focused)
{
vid.ime_allow = true;
vid.ime_position[0] = ((float)left/vid.pixelwidth)*vid.width;
vid.ime_position[1] = ((float)y/vid.pixelheight)*vid.height;
}
if (!con->linebuffered || con->linebuffered == Con_Navigate)
{
if (con->footerline)
@ -1383,6 +1406,8 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
text = key_lines[edit_line];
cursorpos = key_linepos;
//copy it to an alternate buffer and fill in text colouration escape codes.
//if it's recognised as a command, colour it yellow.
//if it's not a command, and the cursor is at the end of the line, leave it as is,
@ -1390,13 +1415,24 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
textstart = COM_ParseFunString(CON_WHITEMASK, con->prompt, maskedtext, sizeof(maskedtext) - sizeof(maskedtext[0]), PFS_FORCEUTF8);
textsize = (countof(maskedtext) - (textstart-maskedtext) - 1) * sizeof(maskedtext[0]);
i = text[key_linepos];
text[key_linepos] = 0;
i = text[cursorpos];
text[cursorpos] = 0;
cursor = COM_ParseFunString(CON_WHITEMASK, text, textstart, textsize, PFS_KEEPMARKUP | PFS_FORCEUTF8);
text[key_linepos] = i;
//okay, so that's where the cursor is. heal the input string and reparse (so we don't mess up escapes)
text[cursorpos] = i;
endmtext = COM_ParseFunString(CON_WHITEMASK, text, textstart, textsize, PFS_KEEPMARKUP | PFS_FORCEUTF8);
// endmtext = COM_ParseFunString(CON_WHITEMASK, text+key_linepos, cursor, ((char*)maskedtext)+sizeof(maskedtext) - (char*)(cursor+1), PFS_KEEPMARKUP | PFS_FORCEUTF8);
hidecomplete = COM_InsertIME(maskedtext, countof(maskedtext), &cursor, &endmtext);
/* if (cursorpos == strlen(text) && vid.ime_preview)
{
endmtext = COM_ParseFunString(COLOR_MAGENTA<<CON_FGSHIFT, vid.ime_preview, endmtext, (countof(maskedtext) - (endmtext-maskedtext) - 1) * sizeof(maskedtext[0]), PFS_KEEPMARKUP | PFS_FORCEUTF8);
cursor += strlen(vid.ime_preview);
cursorpos += strlen(vid.ime_preview);
text = va("%s%s", text, vid.ime_preview);
}
*/
if ((char*)endmtext == (char*)(maskedtext-2) + sizeof(maskedtext))
endmtext[-1] = CON_WHITEMASK | '+' | CON_NONCLEARBG;
endmtext[1] = 0;
@ -1432,7 +1468,7 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
i = 0;
x = left;
if (con->commandcompletion && con_showcompletion.ival && text[0] && !(text[0] == '/' && !text[1]))
if (!hidecomplete && con->commandcompletion && con_showcompletion.ival && text[0] && !(text[0] == '/' && !text[1]))
{
if (cl_chatmode.ival && (text[0] == '/' || (cl_chatmode.ival == 2 && Cmd_IsCommand(text))))
{ //color the first token yellow, it's a valid command
@ -1447,10 +1483,10 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
fname = Cmd_CompleteCommand(text+cmdstart, true, true, max(1, con_commandmatch), NULL);
if (fname && strlen(fname) < 256) //we can compleate it to:
{
for (p = min(strlen(fname), key_linepos-cmdstart); fname[p]>0; p++)
for (p = min(strlen(fname), cursorpos-cmdstart); fname[p]>0; p++)
textstart[p+cmdstart] = (unsigned int)fname[p] | (COLOR_GREEN<<CON_FGSHIFT);
if (p < key_linepos-cmdstart)
p = key_linepos-cmdstart;
if (p < cursorpos-cmdstart)
p = cursorpos-cmdstart;
p = min(p+cmdstart, sizeof(maskedtext)/sizeof(maskedtext[0]) - 3);
textstart[p] = 0;
textstart[p+1] = 0;
@ -1742,7 +1778,8 @@ void Con_DrawNotify (void)
conchar_t *ends[8];
conchar_t markup[MAXCMDLINE+64];
conchar_t *c, *end;
char *foo = va(chat_team?"say_team: %s":"say: %s", chat_buffer?(char*)chat_buffer:"");
char demoji[8192];
char *foo = va(chat_team?"say_team: %s":"say: %s", Key_Demoji(demoji, sizeof(demoji), chat_buffer?(char*)chat_buffer:""));
int lines, i, pos;
Font_BeginString(font_console, 0, 0, &x, &y);
y = con_numnotifylines.ival * Font_CharHeight();
@ -1767,7 +1804,7 @@ void Con_DrawNotify (void)
if (c == end)
end++;
lines = Font_LineBreaks(markup, end, Font_ScreenWidth(), 8, starts, ends);
lines = Font_LineBreaks(markup, end, Font_ScreenWidth(), countof(starts), starts, ends);
for (i = 0; i < lines; i++)
{
x = 0;
@ -1775,6 +1812,10 @@ void Con_DrawNotify (void)
y += Font_CharHeight();
}
Font_EndString(font_console);
vid.ime_allow = true;
vid.ime_position[0] = 0;
vid.ime_position[1] = y;
}
}
@ -2105,7 +2146,7 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
}
}
*/
if (seley < selsy)
if (seley <= selsy)
{ //selection goes upwards
x = selsy;
selsy = seley;
@ -2745,7 +2786,7 @@ void Con_DrawConsole (int lines, qboolean noback)
char *mouseover;
if (!mouseconsole->mouseover || !mouseconsole->mouseover(mouseconsole, &tiptext, &shader))
{
mouseover = Con_CopyConsole(mouseconsole, false, true);
mouseover = Con_CopyConsole(mouseconsole, false, true, true);
if (mouseover)
{
char *end = strstr(mouseover, "^]");
@ -3131,7 +3172,7 @@ void Con_ExpandConsoleSelection(console_t *con)
con->selstartoffset = cur-(conchar_t*)(l+1);
}
char *Con_CopyConsole(console_t *con, qboolean nomarkup, qboolean onlyiflink)
char *Con_CopyConsole(console_t *con, qboolean nomarkup, qboolean onlyiflink, qboolean forceutf8)
{
conchar_t *cur;
conline_t *l;
@ -3229,7 +3270,7 @@ char *Con_CopyConsole(console_t *con, qboolean nomarkup, qboolean onlyiflink)
else
lend = (conchar_t*)(l+1) + l->length;
outlen = COM_DeFunString(cur, lend, result + outlen, maxlen - outlen, nomarkup, !!(con->parseflags & PFS_FORCEUTF8)) - result;
outlen = COM_DeFunString(cur, lend, result + outlen, maxlen - outlen, nomarkup, forceutf8||!!(con->parseflags & PFS_FORCEUTF8)) - result;
if (l == con->selendline)
break;

@ -146,7 +146,7 @@ static void Stats_OwnFrag(char *name)
void VARGS Stats_Message(char *msg, ...);
qboolean Stats_TrackerImageLoaded(char *in)
qboolean Stats_TrackerImageLoaded(const char *in)
{
int error;
if (in)

@ -4030,6 +4030,190 @@ static struct pendingtextureinfo *Image_ReadBLPFile(unsigned int flags, const ch
}
#endif
#ifdef IMAGEFMT_VTF
//many of these look like dupes, not really sure how they're meant to work. probably legacy.
typedef enum {
VMF_INVALID=-1,
// VMF_RGBA8=0,
// VMF_ABGR8=1,
VMF_RGB8=2,
VMF_BGR8=3,
// VMF_RGB565=4,
// VMF_I8=5,
// VMF_IA8=6,
// VMF_P8=7,
// VMF_A8=8,
// VMF_RGB8_BS=9,
// VMF_BGR8_BS=10,
// VMF_ARGB_BS=11,
VMF_BGRA8=12,
VMF_BC1=13,
VMF_BC2=14,
VMF_BC3=15,
VMF_BGRX8=16,
// VMF_BGR565=17,
// VMF_BGRX5551=18,
// VMF_BGRA4444=19,
VMF_BC1A=20,
// VMF_BGRA5551=21,
VMF_UV88=22,
// VMF_UVWQ8=23,
VMF_RGBA16F=24,
// VMF_RGBA16N=25,
// VMF_UVLX8=26,
VMF_MAX
} fmtfmt_t;
static uploadfmt_t ImageVTF_VtfToFTE(fmtfmt_t f)
{
switch(f)
{
case VMF_BC1:
return PTI_BC1_RGB;
case VMF_BC1A:
return PTI_BC1_RGBA;
case VMF_BC2:
return PTI_BC2_RGBA;
case VMF_BC3:
return PTI_BC3_RGBA;
case VMF_RGB8:
return PTI_RGB8;
case VMF_BGR8:
return PTI_BGR8;
case VMF_BGRA8:
return PTI_BGRA8;
case VMF_BGRX8:
return PTI_BGRX8;
case VMF_RGBA16F:
return PTI_RGBA16F;
case VMF_UV88:
return PTI_RG8;
case VMF_INVALID:
return PTI_INVALID;
default:
return PTI_INVALID;
}
}
static struct pendingtextureinfo *Image_ReadVTFFile(unsigned int flags, const char *fname, qbyte *filedata, size_t filesize)
{
//FIXME: cba with endian.
struct vtf_s
{
char magic[4];
unsigned int major,minor;
unsigned int headersize;
unsigned short width, height;
unsigned int flags;
unsigned short numframes, firstframe;
unsigned int pad1;
vec3_t reflectivity;
float pad2;
float bumpmapscale;
unsigned int imgformat;
unsigned char mipmapcount;
unsigned char lowresfmt_misaligned[4];
unsigned char lowreswidth;
unsigned char lowresheight;
//7.2
unsigned char depth_misaligned[2];
//7.3
unsigned char pad3[3];
unsigned int numresources;
} *vtf;
fmtfmt_t vmffmt, lrfmt;
unsigned int bw, bh, bb;
qbyte *end = filedata + filesize;
unsigned int face, faces, frame, frames, miplevel, miplevels, img;
unsigned int w, h;
size_t datasize;
unsigned int version;
struct pendingtextureinfo *mips;
vtf = (void*)filedata;
if (memcmp(vtf->magic, "VTF\0", 4))
return NULL;
version = (vtf->major<<16)|vtf->minor;
if (version >= 0x00070003)
return NULL; //we don't support the whole resources thing.
lrfmt = (vtf->lowresfmt_misaligned[0]<<0)|(vtf->lowresfmt_misaligned[1]<<16)|(vtf->lowresfmt_misaligned[2]<<16)|(vtf->lowresfmt_misaligned[3]<<24);
vmffmt = vtf->imgformat;
if (vtf->lowreswidth && vtf->lowresheight)
Image_BlockSizeForEncoding(ImageVTF_VtfToFTE(lrfmt), &bb, &bw, &bh);
else
bb=bw=bh=1;
datasize = ((vtf->lowreswidth+bw-1)/bw) * ((vtf->lowresheight+bh-1)/bh) * bb;
mips = Z_Malloc(sizeof(*mips));
mips->type = (vtf->flags & 0x4000)?PTI_CUBEMAP:PTI_2D;
mips->extrafree = filedata;
filedata += vtf->headersize; //skip the header
filedata += datasize; //and skip the low-res image too.
mips->encoding = ImageVTF_VtfToFTE(vmffmt);
Image_BlockSizeForEncoding(mips->encoding, &bb, &bw, &bh);
miplevels = vtf->mipmapcount;
frames = 1;//vtf->numframes;
faces = ((mips->type==PTI_CUBEMAP)?6:1); //no cubemaps yet.
mips->mipcount = miplevels * frames * faces;
while (mips->mipcount > countof(mips->mip))
{
if (miplevels > 1)
miplevels--;
else
frames--;
mips->mipcount = miplevels * frames * faces;
}
if (!mips->mipcount)
{
Z_Free(mips);
return NULL;
}
for (miplevel = vtf->mipmapcount; miplevel-- > 0;)
{ //smallest to largest, which is awkward.
w = vtf->width>>miplevel;
h = vtf->height>>miplevel;
if (!w)
w = 1;
if (!h)
h = 1;
datasize = ((w+bw-1)/bw) * ((h+bh-1)/bh) * bb;
for (frame = 0; frame < vtf->numframes; frame++)
{
for (face = 0; face < faces; face++)
{
if (miplevel < miplevels && face < faces)
{
img = face+miplevel*faces + frame*miplevels*faces;
if (img >= countof(mips->mip))
break; //erk?
if (filedata + datasize > end)
break; //no more data here...
mips->mip[img].width = w;
mips->mip[img].height = h;
mips->mip[img].depth = 1;
mips->mip[img].data = filedata;
mips->mip[img].datasize = datasize;
}
filedata += datasize;
}
}
}
return mips;
}
#endif
//if force_rgba8 then it guarentees rgba8 or rgbx8, otherwise can return l8, etc
qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_t *format, qboolean force_rgba8, const char *fname)
{
@ -6957,6 +7141,10 @@ static struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char
if (!mips && filedata[0] == 'B' && filedata[1] == 'L' && filedata[2] == 'P' && filedata[3] == '2')
mips = Image_ReadBLPFile(flags, fname, filedata, filesize);
#endif
#ifdef IMAGEFMT_VTF
if (!mips && filedata[0] == 'V' && filedata[1] == 'T' && filedata[2] == 'F' && filedata[3] == '\0')
mips = Image_ReadVTFFile(flags, fname, filedata, filesize);
#endif
//the above formats are assumed to have consumed filedata somehow (probably storing into mips->extradata)
if (mips)

@ -541,7 +541,7 @@ void CompleteCommand (qboolean force, int direction)
Key_UpdateCompletionDesc();
}
int Con_Navigate(console_t *con, char *line)
int Con_Navigate(console_t *con, const char *line)
{
if (con->backshader)
{
@ -558,7 +558,7 @@ int Con_Navigate(console_t *con, char *line)
}
//lines typed at the main console enter here
int Con_ExecuteLine(console_t *con, char *line)
int Con_ExecuteLine(console_t *con, const char *line)
{
qboolean waschat = false;
char *deutf8 = NULL;
@ -598,7 +598,7 @@ int Con_ExecuteLine(console_t *con, char *line)
Cbuf_AddText (line, RESTRICT_LOCAL);
else
{
char *exec = NULL;
const char *exec = NULL;
if (line[0] == '\\' || line[0] == '/')
exec = line+1; // skip the slash
else if (cl_chatmode.value == 2 && Cmd_IsCommand(line))
@ -1128,6 +1128,19 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
{
if (con->selstartline)
{
if (con->userline)
{
if (con->flags & CONF_BACKSELECTION)
{
con->userline = con->selendline;
con->useroffset = con->selendoffset;
}
else
{
con->userline = con->selstartline;
con->useroffset = con->selstartoffset;
}
}
if (con->selstartline == con->selendline && con->selendoffset <= con->selstartoffset+1)
{
con->flags &= ~CONF_KEEPSELECTION;
@ -1135,7 +1148,7 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
;
else
{
buffer = Con_CopyConsole(con, false, true);
buffer = Con_CopyConsole(con, false, true, false);
if (buffer)
{
Key_HandleConsoleLink(con, buffer);
@ -1146,21 +1159,8 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
else
{
con->flags |= CONF_KEEPSELECTION;
if (con->userdata)
{
if (con->flags & CONF_BACKSELECTION)
{
con->userline = con->selendline;
con->useroffset = con->selendoffset;
}
else
{
con->userline = con->selstartline;
con->useroffset = con->selstartoffset;
}
}
buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard
buffer = Con_CopyConsole(con, true, false, true); //don't keep markup if we're copying to the clipboard
if (buffer)
{
Sys_SaveClipboard(CBT_SELECTION, buffer);
@ -1175,7 +1175,7 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
con->buttonsdown = CB_NONE;
if (abs(con->mousedown[0] - con->mousecursor[0]) < 5 && abs(con->mousedown[1] - con->mousecursor[1]) < 5)
{
buffer = Con_CopyConsole(con, false, false);
buffer = Con_CopyConsole(con, false, false, false);
Con_Footerf(con, false, "");
if (!buffer)
return;
@ -1208,7 +1208,7 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
if (key == K_MOUSE2 && con->buttonsdown == CB_COPY)
{
con->buttonsdown = CB_NONE;
buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard
buffer = Con_CopyConsole(con, true, false, true); //don't keep markup if we're copying to the clipboard
if (!buffer)
return;
Sys_SaveClipboard(CBT_CLIPBOARD, buffer);
@ -1236,6 +1236,111 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
}
#endif
}
const char *Key_Demoji(char *buffer, size_t buffersize, const char *in)
{
static const struct
{
const char *pattern;
const char *repl;
} emoji[] =
{
//https://www.webpagefx.com/tools/emoji-cheat-sheet/
// {":)", "\xE2\x98\xBA"},
#ifdef QUAKEHUD
{":sg:", "\xEE\x84\x82"},
{":ssg:", "\xEE\x84\x83"},
{":ng:", "\xEE\x84\x84"},
{":sng:", "\xEE\x84\x85"},
{":gl:", "\xEE\x84\x86"},
{":rl:", "\xEE\x84\x87"},
{":lg:", "\xEE\x84\x88"},
{":sg2:", "\xEE\x84\x92"},
{":ssg2:", "\xEE\x84\x93"},
{":ng2:", "\xEE\x84\x94"},
{":sng2:", "\xEE\x84\x95"},
{":gl2:", "\xEE\x84\x96"},
{":rl2:", "\xEE\x84\x97"},
{":lg2:", "\xEE\x84\x98"},
{":shells:", "\xEE\x84\xA0"},
{":nails:", "\xEE\x84\xA1"},
{":rocket:", "\xEE\x84\xA2"},
{":cells:", "\xEE\x84\xA3"},
{":ga:", "\xEE\x84\xA4"},
{":ya:", "\xEE\x84\xA5"},
{":ra:", "\xEE\x84\xA6"},
{":key1:", "\xEE\x84\xB0"},
{":key2:", "\xEE\x84\xB1"},
{":ring:", "\xEE\x84\xB2"},
{":pent:", "\xEE\x84\xB3"},
{":suit:", "\xEE\x84\xB4"},
{":quad:", "\xEE\x84\xB5"},
{":sigil1:", "\xEE\x84\xB6"},
{":sigil2:", "\xEE\x84\xB7"},
{":sigil3:", "\xEE\x84\xB8"},
{":sigil4:", "\xEE\x84\xB9"},
{":face1:", "\xEE\x85\x80"},
{":face_p1:", "\xEE\x85\x81"},
{":face2:", "\xEE\x85\x82"},
{":face_p2:", "\xEE\x85\x83"},
{":face3:", "\xEE\x85\x84"},
{":face_p3:", "\xEE\x85\x85"},
{":face4:", "\xEE\x85\x86"},
{":face_p4:", "\xEE\x85\x87"},
{":face5:", "\xEE\x85\x88"},
{":face_p5:", "\xEE\x85\x89"},
{":face_invis:", "\xEE\x85\x8A"},
{":face_invul2:", "\xEE\x85\x8B"},
{":face_inv2:", "\xEE\x85\x8C"},
{":face_quad:", "\xEE\x85\x8D"},
#endif
};
char *estart = strchr(in, ':');
size_t i;
char *out = buffer, *outend = buffer+buffersize-1;
if (!estart)
return in;
for(; estart; )
{
if (out + (estart-in) >= outend)
break; //not enough space
memcpy(out, in, estart-in);
out += estart-in;
in = estart;
for (i = 0; i < countof(emoji); i++)
{
if (!strncmp(in, emoji[i].pattern, strlen(emoji[i].pattern)))
break; //its this one!
}
if (i < countof(emoji))
{
if (out + strlen(emoji[i].repl) >= outend)
{
in = ""; //no half-emoji
break;
}
in += strlen(emoji[i].pattern);
memcpy(out, emoji[i].repl, strlen(emoji[i].repl));
out += strlen(emoji[i].repl);
estart = strchr(in, ':');
}
else
{
estart = strchr(in+1, ':');
}
}
while (*in && out < outend)
*out++ = *in++;
*out = 0;
return buffer;
}
//if the referenced (trailing) chevron is doubled up, then it doesn't act as part of any markup and should be ignored for such things.
static qboolean utf_specialchevron(unsigned char *start, unsigned char *chev)
{
@ -1456,7 +1561,7 @@ qboolean Key_EntryLine(console_t *con, unsigned char **line, int lineoffset, int
{
if (con && (con->flags & CONF_KEEPSELECTION))
{ //copy selected text to the system clipboard
char *buffer = Con_CopyConsole(con, true, false);
char *buffer = Con_CopyConsole(con, true, false, true);
if (buffer)
{
Sys_SaveClipboard(CBT_CLIPBOARD, buffer);
@ -1666,7 +1771,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
Con_ExpandConsoleSelection(con);
con->flags |= CONF_KEEPSELECTION;
buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard
buffer = Con_CopyConsole(con, true, false, true); //don't keep markup if we're copying to the clipboard
if (buffer)
{
Sys_SaveClipboard(CBT_SELECTION, buffer);
@ -1789,16 +1894,16 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START)
{ // backslash text are commands, else chat
int oldl = edit_line;
char demoji[8192];
const char *txt = Key_Demoji(demoji, sizeof(demoji), key_lines[edit_line]);
#ifndef FTE_TARGET_WEB
if (keydown[K_LALT] || keydown[K_RALT])
Cbuf_AddText("\nvid_toggle\n", RESTRICT_LOCAL);
#endif
if ((con_commandmatch && !strchr(key_lines[edit_line], ' ')) || shift)
if ((con_commandmatch && !strchr(txt, ' ')) || shift)
{ //if that isn't actually a command, and we can actually complete it to something, then lets try to complete it.
char *txt = key_lines[edit_line];
if (*txt == '/')
txt++;
@ -1814,7 +1919,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
if (con->linebuffered)
{
if (con->linebuffered(con, key_lines[oldl]) != 2)
if (con->linebuffered(con, txt) != 2)
{
edit_line = (edit_line + 1) & (CON_EDIT_LINES_MASK);
history_line = edit_line;
@ -1946,8 +2051,11 @@ void Key_Message (int key, int unicode)
{
if (chat_buffer && chat_buffer[0])
{ //send it straight into the command.
char *line = chat_buffer;
const char *line = chat_buffer;
char deutf8[8192];
char demoji[8192];
line = Key_Demoji(demoji, sizeof(demoji), line);
if (com_parseutf8.ival <= 0)
{
unsigned int unicode;

@ -316,6 +316,8 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode);
struct console_s;
qboolean Key_GetConsoleSelectionBox(struct console_s *con, int *sx, int *sy, int *ex, int *ey);
qboolean Key_MouseShouldBeFree(void);
const char *Key_Demoji(char *buffer, size_t buffersize, const char *in); //strips out :smile: stuff.
#endif
#endif

@ -385,7 +385,7 @@ void PM_ValidatePackage(package_t *p)
else
#endif
{
#ifdef AVAIL_ZLIB //assume zip/pk3/pk4/apk/etc
#ifdef PACKAGE_PK3 //assume zip/pk3/pk4/apk/etc
archive = FSZIP_LoadArchive(pf, NULL, n, n, NULL);
#else
archive = NULL;
@ -2011,6 +2011,7 @@ static void PM_Download_Got(struct dl_download *dl)
if (p->extract == EXTRACT_ZIP)
{
#ifdef PACKAGE_PK3
vfsfile_t *f = FS_OpenVFS(tempname, "rb", p->fsroot);
if (f)
{
@ -2038,7 +2039,9 @@ static void PM_Download_Got(struct dl_download *dl)
VFS_CLOSE(f);
}
PM_ValidatePackage(p);
#else
Con_Printf("zip format not supported in this build - %s (from %s)\n", p->name, dl->url);
#endif
FS_Remove (tempname, p->fsroot);
Z_Free(tempname);
PM_StartADownload();

@ -559,6 +559,10 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu
if (menu->selecteditem == option && (int)(realtime*4) & 1)
{
vid.ime_allow = true;
vid.ime_position[0] = x;
vid.ime_position[1] = y+8;
x += strlen(option->edit.text)*8;
Draw_FunString(x, y, "^Ue00b");
}

@ -101,6 +101,7 @@ static qboolean qacmStartup(void)
#endif
static char media_currenttrack[MAX_QPATH];
static cvar_t music_fade = CVAR("music_fade", "1");
//higher bits have priority (if they have something to play).
#define MEDIA_GAMEMUSIC (1u<<0) //cd music. also music command etc.
@ -295,7 +296,7 @@ static qboolean Media_Changed (unsigned int mediatype)
CDAudio_Stop();
}
#endif
media_fadeout = true;
media_fadeout = music_fade.ival;
media_fadeouttime = realtime;
return true;
}
@ -2450,9 +2451,10 @@ cin_t *Media_StartCin(char *name)
if (!name || !*name) //clear only.
return NULL;
#ifndef MINIMAL
if (!cin)
cin = Media_Static_TryLoad(name);
#endif
#ifdef Q2CLIENT
if (!cin)
cin = Media_Cin_TryLoad(name);
@ -5130,6 +5132,7 @@ void Media_Init(void)
Cmd_AddCommand ("menu_media", M_Menu_Media_f);
#endif
#endif
Cvar_Register(&music_fade, "Media player things");
#ifdef HAVE_SPEECHTOTEXT
Cmd_AddCommand("tts", TTS_Say_f);

@ -1394,6 +1394,7 @@ qboolean M_VideoApplyShadowLighting (union menuoption_s *op,struct menu_s *menu,
break;
}
#ifdef MINIMAL
(void)cvarv;
Cbuf_AddText(va("r_shadow_realtime_world %s;r_shadow_realtime_world_shadows %s\n", cvarsrw, cvarsrws), RESTRICT_LOCAL);
#else
Cbuf_AddText(va("r_vertexlight %s;r_shadow_realtime_world %s;r_shadow_realtime_world_shadows %s\n", cvarv, cvarsrw, cvarsrws), RESTRICT_LOCAL);

@ -485,11 +485,13 @@ int MP_GetServerCategory(int index);
#endif
#ifdef MENU_NATIVECODE
#ifdef HAVE_CLIENT
#include "api_menu.h"
extern menu_export_t *mn_entry;
void MN_Shutdown(void);
qboolean MN_Init(void);
#endif
#endif
#define MGT_BAD ~0
#define MGT_QUAKE1 0

@ -870,7 +870,7 @@ void QCBUILTIN PF_CL_drawrawstring (pubprogfuncs_t *prinst, struct globalvars_s
while(*text)
{
if (1)//VMUTF8)
c = unicode_decode(&error, text, (char**)&text, false);
c = unicode_decode(&error, text, &text, false);
else
{
//FIXME: which charset is this meant to be using?

@ -3689,7 +3689,8 @@ uploadfmt_t Surf_LightmapMode(model_t *model)
}
Con_DPrintf("%s: Using lightmap format %s\n", model->name, Image_FormatName(fmt));
if (!model->submodelof)
Con_DPrintf("%s: Using lightmap format %s\n", model->name, Image_FormatName(fmt));
return fmt;
}

@ -1232,7 +1232,7 @@ void Draw_TinyString (float x, float y, const qbyte *str)
while (*str)
{
codepoint = unicode_decode(&error, str, (char**)&str, true);
codepoint = unicode_decode(&error, str, (char const**)&str, true);
if (codepoint == '\n')
{
@ -2728,7 +2728,7 @@ static void Sbar_Voice(int y)
#endif
}
void SCR_StringXY(char *str, float x, float y);
void SCR_StringXY(const char *str, float x, float y);
void SCR_DrawClock(void);
void SCR_DrawGameClock(void);
static void Sbar_DrawUPS(playerview_t *pv)

@ -916,7 +916,7 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un
if (decodesamps > 0)
{ //calculate levels of other people. eukara demanded this.
float level;
float level = 0;
float f;
for (len = 0; len < decodesamps; len++)
{

@ -1,6 +1,6 @@
#include "quakedef.h"
#ifdef HAVE_MIXER
#if defined(HAVE_MIXER) || defined(VOICECHAT)
#include "winquake.h"
#ifdef DYNAMIC_SDL
@ -87,8 +87,8 @@ static dllhandle_t *libsdl;
#else
#include <SDL.h>
#endif
#define SELFPAINT
#define SDRVNAME "SDL"
#endif
//SDL calls a callback each time it needs to repaint the 'hardware' buffers
//This results in extra latency due it needing to buffer that much data.
@ -133,7 +133,8 @@ static qboolean SSDL_InitAudio(void)
return true;
}
#ifdef HAVE_MIXER
#define SELFPAINT
static void SSDL_Shutdown(soundcardinfo_t *sc)
{
Con_DPrintf("Shutdown SDL sound\n");
@ -328,7 +329,6 @@ static qboolean QDECL SDL_InitCard(soundcardinfo_t *sc, const char *devicename)
return true;
}
#define SDRVNAME "SDL"