engine/engine/gl/gl_font.c

3604 lines
94 KiB
C
Raw Normal View History

#include "quakedef.h"
#ifndef SERVERONLY
#include "shader.h"
#include "gl_draw.h"
#ifdef _WIN32
#ifdef _XBOX
#include <xtl.h>
#else
#include <windows.h>
#endif
#endif
#include <ctype.h>
void Font_Init(void);
void Font_Shutdown(void);
struct font_s *Font_LoadFont(const char *fontfilename, float height, float scale, int outline, unsigned int flags);
void Font_Free(struct font_s *f);
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py);
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/
void Font_Transform(float vx, float vy, int *px, int *py);
int Font_CharHeight(void);
float Font_CharScaleHeight(void);
//FIXME: if we want to do emoji properly, then we're going to need support for variants somehow
// easiest is probably to make the next codepoint available too (and consumable)
// handling variants in the font cache is another issue. gah. not worth it.
int Font_CharWidth(unsigned int charflags, unsigned int codepoint);
float Font_CharScaleWidth(unsigned int charflags, unsigned int codepoint);
int Font_CharEndCoord(struct font_s *font, int x, unsigned int charflags, unsigned int codepoint);
int Font_DrawChar(int px, int py, unsigned int charflags, unsigned int codepoint);
float Font_DrawScaleChar(float px, float py, unsigned int charflags, unsigned int codepoint); /*avoid using*/
void Font_EndString(struct font_s *font);
int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int maxlines, conchar_t **starts, conchar_t **ends);
struct font_s *font_menu;
struct font_s *font_default;
struct font_s *font_console;
struct font_s *font_tiny;
static int font_be_flags;
extern unsigned int r2d_be_flags;
#ifdef AVAIL_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
struct fontface_s;
int Font_ChangeFTSize(struct fontface_s *qface, int pixelheight);
#ifndef FT_LOAD_COLOR
#define FT_LOAD_COLOR (1L<<20)
#endif
static FT_Library fontlib;
#ifdef FREETYPE_STATIC
#define pFT_Init_FreeType FT_Init_FreeType
#define pFT_Load_Char FT_Load_Char
#define pFT_Get_Char_Index FT_Get_Char_Index
#define pFT_Set_Pixel_Sizes FT_Set_Pixel_Sizes
#define pFT_Select_Size FT_Select_Size
#define pFT_New_Face FT_New_Face
#define pFT_New_Memory_Face FT_New_Memory_Face
#define pFT_Done_Face FT_Done_Face
openxr plugin: tweaked - inputs should be working properly now, and are visible to csqc. subject to further breaking changes, however. _pext_vrinputs: added cvar to enable vr inputs protocol extension allowing vr inputs to be networked to ssqc too. defaults to 0 for now, will be renamed when deemed final. updates menu: the prompt to enable sources is now more explicit instead of expecting the user to have a clue. updates menu: added a v3 sources format, which should be more maintainable. not final. updates menu: try to give reasons why sources might be failing (to help blame ISPs if they try fucking over TTH dns again). presets menu: no longer closes the instant a preset is chosen. some presets have a couple of modifiers listed. force the demo loop in the background to serve as a preview. prompts menus: now does word wrapping. ftemaster: support importing server lists from other master servers (requested by Eukara). server: try to detect when non-reply inbound packets are blocked by firewalls/nats/etc (using ftemaster to do so). qcvm: added pointcontentsmask builtin, allowing it to probe more than just world, with fte's full contentbit range instead of just q1 legacy. qcvm: memfill8 builtin now works on createbuffer() pointers. qcvm: add missing unsigned ops. Fixed double comparison ops. fixed bug with op_store_i64. added missing OP_LOADP_I64 qcc: added '#pragma framerate RATE' for overriding implicit nextthink durations. qcc: fixed '#pragma DONT_COMPILE_THIS_FILE' to not screw up comments. qcc: added __GITURL__ __GITHASH__ __GITDATE__ __GITDATETIME__ __GITDESC__ for any mods that might want to make use of that. qcc: fix up -Fhashonly a little setrenderer: support for vulkan gpu enumeration. rulesets: reworked to support custom rulesets (using hashes to catch haxxors, though still nothing prevents just changing the client to ignore rulesets) bspx: use our BIH code for the bspx BRUSHLIST lump instead of the older less efficient code. (static)iqm+obj: these model formats can now be used for the worldmodel (with a suitable .ent file). Also using BIH for much better collision performance. pmove: tried to optimise PM_NudgePosition, should boost fps in stress tests. wayland: fix a crash on startup. mousegrabs now works better. imagetool: uses sdl for previews. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5813 fc73d0e0-1445-4013-8a0c-d673dee63da5
2021-04-13 22:21:04 -07:00
#define pFT_Error_String FT_Error_String
#else
qboolean triedtoloadfreetype;
dllhandle_t *fontmodule;
FT_Error (VARGS *pFT_Init_FreeType) (FT_Library *alibrary);
FT_Error (VARGS *pFT_Load_Char) (FT_Face face, FT_ULong char_code, FT_Int32 load_flags);
FT_UInt (VARGS *pFT_Get_Char_Index) (FT_Face face, FT_ULong charcode);
FT_Error (VARGS *pFT_Set_Pixel_Sizes) (FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height);
FT_Error (VARGS *pFT_Select_Size) (FT_Face face, FT_Int strike_index);
FT_Error (VARGS *pFT_New_Face) (FT_Library library, const char *pathname, FT_Long face_index, FT_Face *aface);
FT_Error (VARGS *pFT_New_Memory_Face) (FT_Library library, const FT_Byte* file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface);
FT_Error (VARGS *pFT_Done_Face) (FT_Face face);
openxr plugin: tweaked - inputs should be working properly now, and are visible to csqc. subject to further breaking changes, however. _pext_vrinputs: added cvar to enable vr inputs protocol extension allowing vr inputs to be networked to ssqc too. defaults to 0 for now, will be renamed when deemed final. updates menu: the prompt to enable sources is now more explicit instead of expecting the user to have a clue. updates menu: added a v3 sources format, which should be more maintainable. not final. updates menu: try to give reasons why sources might be failing (to help blame ISPs if they try fucking over TTH dns again). presets menu: no longer closes the instant a preset is chosen. some presets have a couple of modifiers listed. force the demo loop in the background to serve as a preview. prompts menus: now does word wrapping. ftemaster: support importing server lists from other master servers (requested by Eukara). server: try to detect when non-reply inbound packets are blocked by firewalls/nats/etc (using ftemaster to do so). qcvm: added pointcontentsmask builtin, allowing it to probe more than just world, with fte's full contentbit range instead of just q1 legacy. qcvm: memfill8 builtin now works on createbuffer() pointers. qcvm: add missing unsigned ops. Fixed double comparison ops. fixed bug with op_store_i64. added missing OP_LOADP_I64 qcc: added '#pragma framerate RATE' for overriding implicit nextthink durations. qcc: fixed '#pragma DONT_COMPILE_THIS_FILE' to not screw up comments. qcc: added __GITURL__ __GITHASH__ __GITDATE__ __GITDATETIME__ __GITDESC__ for any mods that might want to make use of that. qcc: fix up -Fhashonly a little setrenderer: support for vulkan gpu enumeration. rulesets: reworked to support custom rulesets (using hashes to catch haxxors, though still nothing prevents just changing the client to ignore rulesets) bspx: use our BIH code for the bspx BRUSHLIST lump instead of the older less efficient code. (static)iqm+obj: these model formats can now be used for the worldmodel (with a suitable .ent file). Also using BIH for much better collision performance. pmove: tried to optimise PM_NudgePosition, should boost fps in stress tests. wayland: fix a crash on startup. mousegrabs now works better. imagetool: uses sdl for previews. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5813 fc73d0e0-1445-4013-8a0c-d673dee63da5
2021-04-13 22:21:04 -07:00
const char *(VARGS *pFT_Error_String) (FT_Error error_code);
#endif
#else
typedef unsigned int FT_Pixel_Mode; //for consistency even without freetype support.
#endif
#ifndef FT_PIXEL_MODE_MONO
#define FT_PIXEL_MODE_MONO 1
#endif
#ifndef FT_PIXEL_MODE_GRAY
#define FT_PIXEL_MODE_GRAY 2
#endif
#ifndef FT_PIXEL_MODE_BGRA
#define FT_PIXEL_MODE_BGRA 7 //added in FT 2.5
#endif
#define FT_PIXEL_MODE_RGBA_SA (100) //RGBA, straight alpha. not in freetype.
#define FT_PIXEL_MODE_RGBA (101) //RGBA, premultiplied alpha. not in freetype.
#ifdef QUAKEHUD
static const char *imgs[] =
{
//0xe10X
"e100","e101",
"inv_shotgun",
"inv_sshotgun",
"inv_nailgun",
"inv_snailgun",
"inv_rlaunch",
"inv_srlaunch",
"inv_lightng", //8
"e109","e10a","e10b","e10c","e10d","e10e","e10f",
//0xe11X
"e110","e111",
"inv2_shotgun",
"inv2_sshotgun",
"inv2_nailgun",
"inv2_snailgun",
"inv2_rlaunch",
"inv2_srlaunch",
"inv2_lightng",
"e119","e11a","e11b","e11c","e11d","e11e","e11f",
//0xe12X
"sb_shells",
"sb_nails",
"sb_rocket",
"sb_cells",
"sb_armor1",
"sb_armor2",
"sb_armor3",
"e127","e128","e129","e12a","e12b","e12c","e12d","e12e","e12f",
//0xe13X
"sb_key1",
"sb_key2",
"sb_invis",
"sb_invuln",
"sb_suit",
"sb_quad",
"sb_sigil1",
"sb_sigil2",
"sb_sigil3",
"sb_sigil4",
"e13a","e13b","e13c","e13d","e13e","e13f",
//0xe14X
"face1",
"face_p1",
"face2",
"face_p2",
"face3",
"face_p3",
"face4",
"face_p4",
"face5",
"face_p5",
"face_invis",
"face_invul2",
"face_inv2",
"face_quad",
"e14e",
"e14f",
//0xe15X
"e150",
"e151",
"e152",
"e153",
"e154",
"e155",
"e156",
"e157",
"e158",
"e159",
"e15a",
"e15b",
"e15c",
"e15d",
"e15e",
"e15f",
//0xe16X
"e160",
"e161",
"e162",
"e163",
"e164",
"e165",
"e166",
"e167",
"e168",
"e169",
"e16a",
"e16b",
"e16c",
"e16d",
"e16e",
"e16f"
};
#endif
#define FONT_MAXCHARS 0x110000 //as defined by UTF-16, and thus applied to all unicode because UTF-16 is the crappy limited one.
#define FONTBLOCKS ((FONT_MAXCHARS+FONTBLOCKSIZE-1)/FONTBLOCKSIZE)
#define FONTBLOCKSIZE 0x100 //must be power-of-two
#define FONTBLOCKMASK (FONTBLOCKSIZE-1)
#define FONTIMAGES (1<<2) //this is total, not per font.
#define FIMAGEIDXTYPE unsigned char
#define CHARIDXTYPE unsigned int
#define INVALIDPLANE ((1<<(8*sizeof(FIMAGEIDXTYPE)))-1)
#define BITMAPPLANE ((1<<(8*sizeof(FIMAGEIDXTYPE)))-2)
#define DEFAULTPLANE ((1<<(8*sizeof(FIMAGEIDXTYPE)))-3)
#define SINGLEPLANE ((1<<(8*sizeof(FIMAGEIDXTYPE)))-4)
#define TRACKERIMAGE ((1<<(8*sizeof(FIMAGEIDXTYPE)))-5)
#define FIMAGEWIDTH (1<<10)
#define FIMAGEHEIGHT FIMAGEWIDTH
#define FONTPLANES FONTIMAGES
#define PLANEWIDTH FIMAGEWIDTH
#define PLANEHEIGHT FIMAGEHEIGHT
//windows' font linking allows linking multiple extra fonts to a main font.
//this means that a single selected font can use chars from lots of different files if the first one(s) didn't provide that font.
//they're provided as fallbacks.
#define MAX_FACES 32
enum fontfmt_e
{
FMT_AUTO, //freetype, or quake
FMT_QUAKE, //first is default
FMT_ISO88591, //latin-1 (first 256 chars of unicode too, c1 glyphs are usually invisible)
FMT_WINDOWS1252,//variation of latin-1 with extra glyphs
FMT_KOI8U, //image is 16*16 koi8-u codepage.
FMT_HORIZONTAL, //unicode, charcount=width/(height-2). single strip of chars, like halflife.
};
typedef struct fontface_s
{
struct fontface_s *fnext;
struct fontface_s **flink; //like prev, but not.
char name[MAX_OSPATH];
int refs;
struct
{
qbyte *data;
size_t rows; //urgh.
size_t stride;
size_t charheight;
enum fontfmt_e codepage;
qboolean paletted;
} horiz;
#ifdef HALFLIFEMODELS
struct
{
int fontheight1;
int imgheight;
int rows;
int fontheight2;
struct
{
qbyte x;
qbyte y;
qbyte width;
qbyte pad;
} chartab[256];
// int unk[4];
qbyte data[1];//[256*imgheight];
//int pad
//palette[256*3];
} *halflife;
#endif
#ifdef AVAIL_FREETYPE
struct
{
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
int activeheight; //needs reconfiguring when different sizes are used (so the same face can be used at multiple different sizes
int actualsize; //sometimes that activeheight isn't usable and we need to manually rescale. :(
FT_Face face;
void *membuf;
} ft;
#endif
} fontface_t;
static fontface_t *faces;
#define GEN_CONCHAR_GLYPHS 0 //set to 0 or 1 to define whether to generate glyphs from conchars too, or if it should just draw them as glquake always used to
extern cvar_t cl_noblink;
extern cvar_t con_ocranaleds;
typedef struct font_s
{
//FIXME: use a hash table? will need it if we go beyond ucs-2.
//currently they're in a single block so the font can be checked from scanning the active chars when shutting down. we could instead scan all 65k chars in every font instead...
struct charcache_s
{
struct charcache_s *nextchar;
FIMAGEIDXTYPE texplane;
unsigned char advance; //how wide this char is, when drawn
unsigned short block; //to quickly find the char again
//texture offsets.
unsigned short bmx;
unsigned short bmy;
//texture/screen pixel sizes.
unsigned char bmw;
unsigned char bmh;
unsigned short flags;
#define CHARF_FORCEWHITE (1u<<0) //coloured emoji should not be tinted.
//screen offsets.
short top;
short left;
} *chars[FONTBLOCKS];
char name[MAX_OSPATH];
texid_t singletexture;
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
unsigned short charheight; //requested height (space between lines)
unsigned short truecharheight; //what you actually got, for compat with dp's lets-use-the-wrong-size-for-double-padding-between-lines thing.
float scale; //some sort of poop
short outline;
unsigned int flags;
unsigned short faces;
fontface_t *face[MAX_FACES];
struct font_s *alt;
vec3_t tint;
vec3_t alttint;
} font_t;
union byte_vec4_u
{
byte_vec4_t rgba;
quint32_t c;
};
//shared between fonts.
typedef struct {
texid_t texnum[FONTIMAGES];
texid_t defaultfont;
texid_t trackerimage;
union byte_vec4_u plane[PLANEWIDTH*PLANEHEIGHT]; //tracks the current plane
FIMAGEIDXTYPE activeplane;
unsigned short planerowx;
unsigned short planerowy;
unsigned short planerowh;
qboolean planechanged;
struct charcache_s *oldestchar;
struct charcache_s *newestchar;
shader_t *shader;
shader_t *backshader;
} fontplanes_t;
static fontplanes_t fontplanes;
#define FONT_CHAR_BUFFER 512
static index_t font_indicies[FONT_CHAR_BUFFER*6];
static vecV_t font_coord[FONT_CHAR_BUFFER*4];
static vecV_t font_backcoord[FONT_CHAR_BUFFER*4];
static vec2_t font_texcoord[FONT_CHAR_BUFFER*4];
static union byte_vec4_u font_forecoloura[FONT_CHAR_BUFFER*4];
static union byte_vec4_u font_backcoloura[FONT_CHAR_BUFFER*4];
static mesh_t font_foremesh;
static mesh_t font_backmesh;
static texid_t font_texture;
static int font_colourmask;
static union byte_vec4_u font_forecolour;
static union byte_vec4_u font_backcolour;
static avec4_t font_foretint;
static struct font_s *curfont;
static float curfont_scale[2];
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
//static qboolean curfont_scaled;
extern cvar_t r_font_linear;
//^Ue2XX
static struct
{
image_t *image;
char name[64];
} trackerimages[256];
static int numtrackerimages;
#define TRACKERFIRST 0xe200
int Font_RegisterTrackerImage(const char *image)
{
int i;
for (i = 0; i < numtrackerimages; i++)
{
if (!strcmp(trackerimages[i].name, image))
return TRACKERFIRST + i;
}
if (numtrackerimages == 256)
return 0;
trackerimages[i].image = NULL; //actually load it elsewhere, because we're lazy.
Q_strncpyz(trackerimages[i].name, image, sizeof(trackerimages[i].name));
numtrackerimages++;
return TRACKERFIRST + i;
}
//called from the font display code for tracker images
static image_t *Font_GetTrackerImage(unsigned int imid)
{
if (!trackerimages[imid].image)
{
if (!*trackerimages[imid].name)
return NULL;
trackerimages[imid].image = Image_GetTexture(trackerimages[imid].name, NULL, IF_PREMULTIPLYALPHA|IF_UIPIC, NULL, NULL, 0, 0, TF_INVALID);
}
if (!trackerimages[imid].image)
return NULL;
if (trackerimages[imid].image->status != TEX_LOADED)
return NULL;
return trackerimages[imid].image;
}
qboolean Font_TrackerValid(unsigned int imid)
{
imid -= TRACKERFIRST;
if (imid >= countof(trackerimages))
return false;
if (!trackerimages[imid].image)
{
if (!*trackerimages[imid].name)
return false;
trackerimages[imid].image = Image_GetTexture(trackerimages[imid].name, NULL, IF_PREMULTIPLYALPHA|IF_UIPIC, NULL, NULL, 0, 0, TF_INVALID);
}
if (!trackerimages[imid].image)
return false;
if (trackerimages[imid].image->status == TEX_LOADING)
COM_WorkerPartialSync(trackerimages[imid].image, &trackerimages[imid].image->status, TEX_LOADING);
if (trackerimages[imid].image->status != TEX_LOADED)
return false;
return true;
}
//called at load time - initalises font buffers
void Font_Init(void)
{
int i;
TEXASSIGN(fontplanes.defaultfont, r_nulltex);
//clear tracker images, just in case they were still set for the previous renderer context
for (i = 0; i < sizeof(trackerimages)/sizeof(trackerimages[0]); i++)
trackerimages[i].image = NULL;
font_foremesh.indexes = font_indicies;
font_foremesh.xyz_array = font_coord;
font_foremesh.st_array = font_texcoord;
font_foremesh.colors4b_array = &font_forecoloura->rgba;
font_backmesh.indexes = font_indicies;
font_backmesh.xyz_array = font_backcoord;
font_backmesh.st_array = font_texcoord;
font_backmesh.colors4b_array = &font_backcoloura->rgba;
for (i = 0; i < FONT_CHAR_BUFFER; i++)
{
font_indicies[i*6+0] = i*4+0;
font_indicies[i*6+1] = i*4+1;
font_indicies[i*6+2] = i*4+2;
font_indicies[i*6+3] = i*4+0;
font_indicies[i*6+4] = i*4+2;
font_indicies[i*6+5] = i*4+3;
}
for (i = 0; i < FONTPLANES; i++)
{
TEXASSIGN(fontplanes.texnum[i], Image_CreateTexture("***fontplane***", NULL, IF_UIPIC|(r_font_linear.ival?IF_LINEAR:IF_NEAREST|IF_NOPURGE)|IF_NOPICMIP|IF_NOMIPMAP|IF_NOGAMMA|IF_NOPURGE));
}
fontplanes.shader = R_RegisterShader("ftefont", SUF_2D,
"{\n"
"fullrate\n" //don't hurt readability of text.
"if $nofixed\n"
"program default2d\n"
"endif\n"
"nomipmaps\n"
"{\n"
"if r_font_linear\n"
"map $linear:$diffuse\n"
"else\n"
"map $nearest:$diffuse\n"
"endif\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"blendfunc gl_one gl_one_minus_src_alpha\n"
"}\n"
"}\n"
);
fontplanes.backshader = R_RegisterShader("ftefontback", SUF_2D,
"{\n"
"nomipmaps\n"
"{\n"
"map $whiteimage\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"blendfunc gl_one gl_one_minus_src_alpha\n"
"}\n"
"}\n"
);
font_colourmask = ~0;
}
//flush the font buffer, by drawing it to the screen
static void Font_Flush(void)
{
R2D_Flush = NULL;
if (!font_foremesh.numindexes)
return;
if (fontplanes.planechanged)
{
Image_Upload(fontplanes.texnum[fontplanes.activeplane], TF_RGBA32, (void*)fontplanes.plane, NULL, PLANEWIDTH, PLANEHEIGHT, 1, IF_UIPIC|IF_NEAREST|IF_NOPICMIP|IF_NOMIPMAP|IF_NOGAMMA|IF_NOPURGE);
fontplanes.planechanged = false;
}
font_foremesh.istrifan = (font_foremesh.numvertexes == 4);
if ((font_colourmask & (CON_RICHFORECOLOUR|CON_NONCLEARBG)) == CON_NONCLEARBG && font_foremesh.numindexes)
{
font_backmesh.numindexes = font_foremesh.numindexes;
font_backmesh.numvertexes = font_foremesh.numvertexes;
font_backmesh.istrifan = font_foremesh.istrifan;
BE_DrawMesh_Single(fontplanes.backshader, &font_backmesh, NULL, font_be_flags);
}
TEXASSIGN(fontplanes.shader->defaulttextures->base, font_texture);
BE_DrawMesh_Single(fontplanes.shader, &font_foremesh, NULL, font_be_flags);
font_foremesh.numindexes = 0;
font_foremesh.numvertexes = 0;
}
static int Font_BeginChar(texid_t tex)
{
int fvert;
if (font_foremesh.numindexes >= FONT_CHAR_BUFFER*6 || font_texture != tex)
{
Font_Flush();
TEXASSIGNF(font_texture, tex);
}
fvert = font_foremesh.numvertexes;
font_foremesh.numindexes += 6;
font_foremesh.numvertexes += 4;
return fvert;
}
//clear the shared planes and free memory etc
void Font_Shutdown(void)
{
int i;
for (i = 0; i < FONTPLANES; i++)
TEXASSIGN(fontplanes.texnum[i], r_nulltex);
fontplanes.activeplane = 0;
fontplanes.oldestchar = NULL;
fontplanes.newestchar = NULL;
fontplanes.planechanged = 0;
fontplanes.planerowx = 0;
fontplanes.planerowy = 0;
fontplanes.planerowh = 0;
}
//we got too many chars and switched to a new plane - purge the chars in that plane
void Font_FlushPlane(void)
{
/*
assumption:
oldest chars must be of the oldest plane
*/
//we've not broken anything yet, flush while we can
Font_Flush();
if (fontplanes.planechanged)
{
Image_Upload(fontplanes.texnum[fontplanes.activeplane], TF_RGBA32, (void*)fontplanes.plane, NULL, PLANEWIDTH, PLANEHEIGHT, 1, IF_UIPIC|IF_NEAREST|IF_NOPICMIP|IF_NOMIPMAP|IF_NOGAMMA|IF_NOPURGE);
fontplanes.planechanged = false;
}
fontplanes.activeplane++;
fontplanes.activeplane = fontplanes.activeplane % FONTPLANES;
fontplanes.planerowh = 0;
fontplanes.planerowx = 0;
fontplanes.planerowy = 0;
while (fontplanes.oldestchar)
{
if (fontplanes.oldestchar->texplane != fontplanes.activeplane)
break;
//remove it from the list of active chars, and invalidate it
fontplanes.oldestchar->texplane = INVALIDPLANE;
fontplanes.oldestchar = fontplanes.oldestchar->nextchar;
}
if (!fontplanes.oldestchar)
fontplanes.newestchar = NULL;
}
static struct charcache_s *Font_GetCharIfLoaded(font_t *f, unsigned int charidx)
{
struct charcache_s *c = f->chars[charidx/FONTBLOCKSIZE];
if (c)
{
c += charidx&FONTBLOCKMASK;
if (c->texplane == INVALIDPLANE)
c = NULL;
}
return c;
}
static struct charcache_s *Font_GetCharStore(font_t *f, unsigned int charidx)
{ //should only be called if generating a char cache
struct charcache_s *c;
size_t i;
c = f->chars[charidx/FONTBLOCKSIZE];
if (!c)
{
c = Z_Malloc(sizeof(struct charcache_s) * FONTBLOCKSIZE);
f->chars[charidx/FONTBLOCKSIZE] = c;
for (i = 0; i < FONTBLOCKSIZE; i++)
{
c[i].texplane = INVALIDPLANE;
}
}
c += charidx&FONTBLOCKMASK;
c->block = charidx/FONTBLOCKSIZE;
return c;
}
static struct charcache_s *Font_CopyChar(font_t *f, unsigned int oldcharidx, unsigned int newcharidx)
{
struct charcache_s *new, *old = Font_GetCharIfLoaded(f, oldcharidx);
if (!old)
return NULL;
new = Font_GetCharStore(f, newcharidx);
*new = *old;
new->block = newcharidx/FONTBLOCKSIZE;
return new;
}
//loads a new image into a given character slot for the given font.
//note: make sure it doesn't already exist or things will get cyclic
//alphaonly says if its a greyscale image. false means rgba.
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
static struct charcache_s *Font_LoadGlyphData(font_t *f, CHARIDXTYPE charidx, FT_Pixel_Mode pixelmode, void *data, unsigned int bmw, unsigned int bmh, unsigned int pitch){
int x, y;
union byte_vec4_u *out;
struct charcache_s *c = Font_GetCharStore(f, charidx);
int pad = 0;
#define BORDERCOLOUR 0
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
#define MAXOUTLINE 4
int outline = min(f->outline, MAXOUTLINE);
if (!bmw || !bmh)
outline = 0;
pad+=outline;
if (fontplanes.texnum[0]->flags & IF_LINEAR)
pad += 1; //pad the image data to avoid sampling outside
if (fontplanes.planerowx + (int)bmw+pad*2 >= PLANEWIDTH)
{
fontplanes.planerowx = 0;
fontplanes.planerowy += fontplanes.planerowh;
fontplanes.planerowh = 0;
}
if (fontplanes.planerowy+(int)bmh+pad*2 >= PLANEHEIGHT)
Font_FlushPlane();
if (fontplanes.newestchar)
fontplanes.newestchar->nextchar = c;
else
fontplanes.oldestchar = c;
fontplanes.newestchar = c;
c->nextchar = NULL;
c->flags = 0;
c->texplane = fontplanes.activeplane;
c->bmx = fontplanes.planerowx+pad;
c->bmy = fontplanes.planerowy+pad;
c->bmw = bmw;
c->bmh = bmh;
if (fontplanes.planerowh < (int)bmh+pad*2)
fontplanes.planerowh = bmh+pad*2;
fontplanes.planerowx += bmw+pad*2;
out = &fontplanes.plane[c->bmx+((int)c->bmy-pad)*PLANEHEIGHT];
if (pixelmode == FT_PIXEL_MODE_GRAY)
{ //8bit font
for (y = -pad; y < 0; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
for (; y < bmh; y++)
{
for (x = -pad; x < 0; x++)
out[x].c = BORDERCOLOUR;
for (; x < bmw; x++)
out[x].c = 0x01010101 * ((unsigned char*)data)[x];
for (; x < bmw+pad; x++)
out[x].c = BORDERCOLOUR;
data = (char*)data + pitch;
out += PLANEWIDTH;
}
for (; y < bmh+pad; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
}
else if (pixelmode == FT_PIXEL_MODE_MONO)
{ //1bit font (
for (y = -pad; y < 0; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
for (; y < bmh; y++)
{
for (x = -pad; x < 0; x++)
out[x].c = BORDERCOLOUR;
for (; x < bmw; x++)
out[x].c = (((unsigned char*)data)[x>>3]&(1<<(7-(x&7))))?0xffffffff:0;
for (; x < bmw+pad; x++)
out[x].c = BORDERCOLOUR;
data = (char*)data + pitch;
out += PLANEWIDTH;
}
for (; y < bmh+pad; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
}
else if ((unsigned int)pixelmode == FT_PIXEL_MODE_RGBA_SA)
{ //rgba source using standard alpha.
//(we'll multiply out the alpha for the gpu)
for (y = -pad; y < 0; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
for (; y < bmh; y++)
{
for (x = -pad; x < 0; x++)
out[x].c = BORDERCOLOUR;
for (; x < bmw; x++)
{
if (((unsigned char*)data)[x*4+3] == 255)
out[x] = ((union byte_vec4_u*)data)[x];
else
{
out[x].rgba[0] = (((unsigned char*)data)[x*4+3]*((unsigned char*)data)[x*4+0])<<8;
out[x].rgba[1] = (((unsigned char*)data)[x*4+3]*((unsigned char*)data)[x*4+1])<<8;
out[x].rgba[2] = (((unsigned char*)data)[x*4+3]*((unsigned char*)data)[x*4+2])<<8;
out[x].rgba[3] = ((unsigned char*)data)[x*4+3];
}
}
for (; x < bmw+pad; x++)
out[x].c = BORDERCOLOUR;
data = (char*)data + pitch;
out += PLANEWIDTH;
}
for (; y < (int)bmh+pad; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
}
else if (pixelmode == FT_PIXEL_MODE_BGRA)
{ //bgra srgb font, already premultiplied
for (y = -pad; y < 0; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
for (; y < bmh; y++)
{
for (x = -pad; x < 0; x++)
out[x].c = BORDERCOLOUR;
for (; x < bmw; x++)
{
out[x].rgba[0] = ((unsigned char*)data)[x*4+2];
out[x].rgba[1] = ((unsigned char*)data)[x*4+1];
out[x].rgba[2] = ((unsigned char*)data)[x*4+0];
out[x].rgba[3] = ((unsigned char*)data)[x*4+3];
}
for (; x < bmw+pad; x++)
out[x].c = BORDERCOLOUR;
data = (char*)data + pitch;
out += PLANEWIDTH;
}
for (; y < bmh+pad; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
c->flags = CHARF_FORCEWHITE; //private glyph colours
}
else if ((unsigned int)pixelmode == FT_PIXEL_MODE_RGBA)
{ //bgra srgb font, already premultiplied
for (y = -pad; y < 0; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
for (; y < bmh; y++)
{
for (x = -pad; x < 0; x++)
out[x].c = BORDERCOLOUR;
for (; x < bmw; x++)
out[x].c = ((unsigned int*)data)[x];
for (; x < bmw+pad; x++)
out[x].c = BORDERCOLOUR;
data = (char*)data + pitch;
out += PLANEWIDTH;
}
for (; y < bmh+pad; y++)
{
for (x = -pad; x < (int)bmw+pad; x++)
out[x].c = BORDERCOLOUR;
out += PLANEWIDTH;
}
c->flags = CHARF_FORCEWHITE; //private glyph colours
}
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
if (outline)
{
static int filter_outline;
static unsigned char filter_highest[MAXOUTLINE*2+1][MAXOUTLINE*2+1];
if (outline != filter_outline)
{
filter_outline = outline;
for (y = -outline; y <= outline; y++)
for (x = -outline; x <= outline; x++)
filter_highest[outline+y][outline+x] = bound(0, (outline + 1 - sqrt(x*x + y*y))*255+.5, 255);
}
//expand it to out full(ish) size
if (pixelmode == FT_PIXEL_MODE_MONO)
{
qbyte *alpha = (char*)data - pitch*bmh;
qbyte a;
int bit;
alpha -= pitch*outline;
out = &fontplanes.plane[c->bmx+((int)c->bmy-outline)*PLANEHEIGHT];
for (y = -outline; y < (int)bmh+outline; y++, out += PLANEWIDTH)
for (x = -outline; x < (int)bmw+outline; x++)
{
int xn, x1 = max(outline-x, 0), x2 = min(2*outline, (int)bmw-1-x+outline);
int yn, y1 = max(outline-y, 0), y2 = min(2*outline, (int)bmh-1-y+outline);
int v, m = out[x].rgba[3]*255;
for (yn = y1; yn <= y2; yn++)
for (xn = x1; xn <= x2; xn++)
{
bit = (xn+x)-outline;
a = alpha[(bit>>3)+(yn+y)*pitch];
a = (a&(1<<(7-(bit&7))))?0xff:0;
v = filter_highest[yn][xn] * a;
m = max(m, v);
}
//out[x].c = 0;
out[x].rgba[3] = m/255;
}
}
else
{
int bytes = (pixelmode == FT_PIXEL_MODE_GRAY)?1:4;
qbyte *alpha = (char*)data + bytes-1 - pitch*bmh;
alpha -= pitch*outline + bytes*outline;
out = &fontplanes.plane[c->bmx+((int)c->bmy-outline)*PLANEHEIGHT];
for (y = -outline; y < (int)bmh+outline; y++, out += PLANEWIDTH)
for (x = -outline; x < (int)bmw+outline; x++)
{
int xn, x1 = max(outline-x, 0), x2 = min(2*outline, (int)bmw-1-x+outline);
int yn, y1 = max(outline-y, 0), y2 = min(2*outline, (int)bmh-1-y+outline);
int v, m = out[x].rgba[3]*255;
for (yn = y1; yn <= y2; yn++)
for (xn = x1; xn <= x2; xn++)
{
v = filter_highest[yn][xn] * alpha[(xn+x)*bytes+(yn+y)*pitch];
m = max(m, v);
}
//out[x].c = 0;
out[x].rgba[3] = m/255;
}
}
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
c->bmx -= outline;
c->bmy -= outline;
c->bmw += outline*2;
c->bmh += outline*2;
}
fontplanes.planechanged = true;
return c;
}
unsigned short hex[16] = {
/*0*/ (7<<0)|(5<<3)|(5<<6)|(5<<9)|(7<<12),
/*1*/ (2<<0)|(2<<3)|(2<<6)|(2<<9)|(2<<12),
/*2*/ (7<<0)|(1<<3)|(7<<6)|(4<<9)|(7<<12),
/*3*/ (7<<0)|(1<<3)|(3<<6)|(1<<9)|(7<<12),
/*4*/ (5<<0)|(5<<3)|(7<<6)|(1<<9)|(1<<12),
/*5*/ (7<<0)|(4<<3)|(7<<6)|(1<<9)|(7<<12),
/*6*/ (4<<0)|(4<<3)|(7<<6)|(5<<9)|(7<<12),
/*7*/ (7<<0)|(1<<3)|(1<<6)|(1<<9)|(1<<12),
/*8*/ (7<<0)|(5<<3)|(7<<6)|(5<<9)|(7<<12),
/*9*/ (7<<0)|(5<<3)|(7<<6)|(1<<9)|(1<<12),
/*A*/ (7<<0)|(5<<3)|(7<<6)|(5<<9)|(5<<12),
/*B*/ (6<<0)|(5<<3)|(7<<6)|(5<<9)|(6<<12),
/*C*/ (7<<0)|(5<<3)|(4<<6)|(5<<9)|(7<<12),
/*D*/ (6<<0)|(5<<3)|(5<<6)|(5<<9)|(6<<12),
/*E*/ (7<<0)|(4<<3)|(6<<6)|(4<<9)|(7<<12),
/*F*/ (7<<0)|(4<<3)|(6<<6)|(4<<9)|(4<<12)
};
static struct charcache_s *Font_LoadPlaceholderGlyph(font_t *f, CHARIDXTYPE charidx)
{
struct charcache_s *c;
unsigned int out[169*4], i, o, g, b, w, h, d, n;
if (charidx == 0xe080 || charidx == 0xe081 || charidx == 0xe082 || charidx == 0xe083)
{ //scrollbar glyps
w = min(16,f->charheight);
h = max(1,w/8);
d = 0;
if (charidx == 0xe083) //centre
{
h *= 3;
memset(out+w*h*0, 0xff, w*4*h);
}
else
{
memset(out+w*h*0, 0xff, w*4*h);
memset(out+w*h*1, 0x00, w*4*h);
memset(out+w*h*2, 0xff, w*4*h);
for (i = 0; i < h; i++)
{
if (charidx == 0xe080) //left
memset(out+w*(i+h*1), 0xff, h*4);
if (charidx == 0xe082) //right
memset(out+w*(i+h*1)+w-h, 0xff, h*4);
}
h *= 3;
}
}
else if (charidx == 0xe01d || charidx == 0xe01e || charidx == 0xe01f)
{ //horizontal separator
w = min(16,f->charheight);
h = max(1,w/8);
d = 0;
memset(out, 0xff, w*4*h);
}
else if (charidx == 0xe00b)
{ //console input cursor
h = min(16,f->charheight);
w = max(1,h/8);
d = 1;
memset(out, 0xff, w*4*h);
}
else if (charidx == 0xe00d)
{ //filled > arrow indicator (used by the menus)
h = min(16,f->charheight);
w = (h+1)/2;
d = 1;
memset(out, 0xff, w*4*h);
for (i = 0; i < w; i++)
{
memset(out + w*i + (i+1), 0x0, (w-i-1)*4);
memset(out + w*(h-i-1) + (i+1), 0x0, (w-i-1)*4);
}
}
else
{
d = (f->charheight >= 11);
if (d)
{ //two rows
h = 11;
if (charidx > 0xffff)
n = 3;
else if (charidx > 0xff)
n = 2;
else
n = 1;
w = n*4-1;
n*=2;
}
else
{ //single row. bye bye fixed-width.
if (charidx > 0xfffff)
n = 6;
else if (charidx > 0xffff)
n = 5;
else if (charidx > 0xfff)
n = 4;
else if (charidx > 0xff)
n = 3;
else
n = 2;
w = n*4-1;
h = 5;
}
//figure out if we can get away with giving it a little more border to boost readability
b = (h+2 < f->charheight);
w += b*2;
h += b*2;
memset(out, 0xff, sizeof(out));
for (i = 0; i < n; i++)
{
g = hex[0xf & (charidx>>(i<<2))];
o = b + w*b;
if (d)
{ //stradle them over the two rows.
if (i >= (n>>1))
o += 4*(n-i-1);
else
{
o += 4*((n>>1)-i-1);
o += w * 6;
}
}
else
o += 4*(n-i-1); //just arrange them in order
for (; g; g>>=3, o+=w)
{
if (g & 4) out[o+0] = 0xff0000ff;
if (g & 2) out[o+1] = 0xff0000ff;
if (g & 1) out[o+2] = 0xff0000ff;
}
}
d = 1;
}
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, out, w, h, w*4);
if (c)
{
c->advance = w+d;
c->left = 0;
c->top = (f->charheight-h-1)/2;
}
return c;
}
static struct charcache_s *Font_TryLoadGlyphRaster(font_t *f, fontface_t *qface, CHARIDXTYPE charidx)
{
size_t maxchar = 256;
const unsigned short *c1tab;
size_t c1tabsize;
size_t glyph = charidx;
safeswitch(qface->horiz.codepage)
{
safedefault:
case FMT_AUTO: //shouldn't happen.
case FMT_ISO88591: //all identity.
case FMT_HORIZONTAL: //erk...
c1tab = NULL;
c1tabsize = 0;
break;
case FMT_WINDOWS1252:
{
static const unsigned short win1252[] = {
0x20ac, 0x81,0x201a,0x0192, 0x201e,0x2026,0x2020,0x2021, 0x02c6,0x2030,0x0160,0x2039, 0x0152, 0x8d,0x017d, 0x8f,
0x90,0x2018,0x2019,0x101c, 0x201d,0x2022,0x2013,0x2014, 0x02dc,0x2122,0x0161,0x203a, 0x0153, 0x9d,0x017e,0x0178};
c1tab = win1252;
c1tabsize = sizeof(win1252);
}
break;
case FMT_KOI8U:
{
static const unsigned short koi8u[] = {
0x2500,0x2502,0x250C,0x2510, 0x2514,0x2518,0x251C,0x2524, 0x252C,0x2534,0x253C,0x2580, 0x2584,0x2588,0x258C,0x2590,
0x2591,0x2592,0x2593,0x2320, 0x25A0,0x2219,0x221A,0x2248, 0x2264,0x2265,0x00A0,0x2321, 0x00B0,0x00B2,0x00B7,0x00F7,
0x2550,0x2551,0x2552,0x0451, 0x0454,0x2554,0x0456,0x0457, 0x2557,0x2558,0x2559,0x255A, 0x255B,0x0491,0x255D,0x255E,
0x255F,0x2560,0x2561,0x0401, 0x0404,0x2563,0x0406,0x0407, 0x2566,0x2567,0x2568,0x2569, 0x256A,0x0490,0x256C,0x00A9,
0x044E,0x0430,0x0431,0x0446, 0x0434,0x0435,0x0444,0x0433, 0x0445,0x0438,0x0439,0x043A, 0x043B,0x043C,0x043D,0x043E,
0x043F,0x044F,0x0440,0x0441, 0x0442,0x0443,0x0436,0x0432, 0x044C,0x044B,0x0437,0x0448, 0x044D,0x0449,0x0447,0x044A,
0x042E,0x0410,0x0411,0x0426, 0x0414,0x0415,0x0424,0x0413, 0x0425,0x0418,0x0419,0x041A, 0x041B,0x041C,0x041D,0x041E,
0x041F,0x042F,0x0420,0x0421, 0x0422,0x0423,0x0416,0x0412, 0x042C,0x042B,0x0417,0x0428, 0x042D,0x0429,0x0427,0x042A};
c1tab = koi8u;
c1tabsize = sizeof(koi8u);
}
break;
case FMT_QUAKE:
{
c1tab = NULL;
c1tabsize = 0;
if (glyph >= 0xe000 && glyph < 0xe100)
glyph -= 0xe000;
else if (glyph < 32 || glyph >= 0x80)
return NULL;
}
break;
}
if (glyph >= maxchar)
return NULL;
if (glyph >= 0x80 && glyph < 0x80+c1tabsize)
{
int i;
for (i = 0; ; i++)
{
if (i == c1tabsize)
return NULL;
if (glyph == c1tab[i])
{
glyph = 0x80+i;
break;
}
}
}
{
int gw = (qface->horiz.stride)/(maxchar/qface->horiz.rows);
int gr = glyph / (maxchar/qface->horiz.rows);
int gc = glyph - (gr*(maxchar/qface->horiz.rows));
int gs = qface->horiz.stride;
int gh = qface->horiz.charheight;
struct charcache_s *c;
if (qface->horiz.paletted)
{
qbyte *in = (qbyte*)qface->horiz.data + gc*gw + gr*gs*gh;
/*while (gw >= 1)
{
int y;
gw--; //see if we can strip this column
for (y = 0; y < gh; y++)
if (in[gw+y*gs])
break;
if (y < gh)
{
gw++;
break;
}
}*/
{
int ngw = (gw * f->charheight) / gh;
int ngh = f->charheight;
int x, y;
unsigned int *out2 = alloca(ngw*ngh*4);
if (ngw&&ngh)
{
unsigned int *out1 = alloca(gw*gh*4);
for (y = 0; y < gh; y++)
for (x = 0; x < gw; x++)
out1[x+y*gw] = in[x+y*gs]?d_8to24rgbtable[in[x+y*gs]]:0;
Image_ResampleTexture(PTI_RGBA8, out1, gw, gh, out2, ngw, ngh);
}
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, out2, ngw, ngh, ngw*4);
gw = ngw;
}
}
else
{
unsigned int *in = (unsigned int*)qface->horiz.data + gc*gw + gr*gs*gh;
while (gw >= 1)
{
int y;
gw--; //see if we can strip this column
for (y = 0; y < gh; y++)
if (in[gw+y*gs] & 0x00ffffff)
break;
if (y < gh)
{
gw++;
break;
}
}
if (f->charheight != gh)
{
int ngw = (gw * f->charheight) / gh;
int ngh = f->charheight;
int x, y;
unsigned int *out2 = alloca(ngw*ngh*4);
if (ngw&&ngh)
{ //we need to repack the input, because Image_ResampleTexture can't handle strides
unsigned int *out1 = alloca(gw*gh*4);
for (y = 0; y < gh; y++)
for (x = 0; x < gw; x++)
out1[x+y*gw] = in[x+y*gs];
Image_ResampleTexture(PTI_RGBA8, out1, gw, gh, out2, ngw, ngh);
}
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, out2, ngw, ngh, ngw*4);
gw = ngw;
}
else
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, in, gw, gh, gs*4);
}
if (!gw) //for invisble glyphs (eg: space), we attempt to ensure that there's some substance there. missing spaces is weird.
gw = gh/3;
if (c)
{
c->advance = gw;
c->left = 0;
c->top = 0;
c->flags &= ~CHARF_FORCEWHITE;
return c;
}
}
return NULL;
}
//loads the given charidx for the given font, importing from elsewhere if needed.
static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx)
{
struct charcache_s *c;
#if GEN_CONCHAR_GLYPHS != 0
if (charidx >= 0xe000 && charidx <= 0xe0ff)
{
int cpos = charidx & 0xff;
unsigned int img[64*64], *d;
unsigned char *s;
int scale;
int x,y, ys;
qbyte *draw_chars = W_GetLumpName("conchars");
if (draw_chars)
{
d = img;
s = draw_chars + 8*(cpos&15)+128*8*(cpos/16);
scale = f->charheight/8;
if (scale < 1)
scale = 1;
if (scale > 64/8)
scale = 64/8;
for (y = 0; y < 8; y++)
{
for (ys = 0; ys < scale; ys++)
{
for (x = 0; x < 8*scale; x++)
d[x] = d_8to24rgbtable[s[x/scale]];
d+=8*scale;
}
s+=128;
}
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA_SA, img, 8*scale, 8*scale, 8*scale*4);
if (c)
{
c->advance = 8*scale;
c->left = 0;
c->top = 7*scale;
}
return c;
}
if ((charidx&0x7f) > 0x20)
charidx &= 0x7f;
}
#endif
#ifdef QUAKEHUD
if (charidx >= 0xe100 && charidx <= 0xe1ff)
{
qpic_t *wadimg;
qbyte lumptype = 0;
unsigned char *src;
unsigned int img[64*64];
int nw, nh;
int x, y;
unsigned int stepx, stepy;
unsigned int srcx, srcy;
size_t lumpsize = 0;
if (charidx-0xe100 >= sizeof(imgs)/sizeof(imgs[0]))
wadimg = NULL;
else
wadimg = W_GetLumpName(imgs[charidx-0xe100], &lumpsize, &lumptype);
if (wadimg && lumptype == TYP_QPIC && lumpsize == 8+wadimg->height*wadimg->width)
{
nh = wadimg->height;
nw = wadimg->width;
while (nh < f->charheight)
{
nh *= 2;
nw *= 2;
}
if (nh > f->charheight)
{
nw = (nw * f->charheight)/nh;
nh = f->charheight;
}
stepy = 0x10000*((float)wadimg->height/nh);
stepx = 0x10000*((float)wadimg->width/nw);
if (nh > 64)
nh = 64;
if (nw > 64)
nw = 64;
srcy = 0;
for (y = 0; y < nh; y++)
{
src = (unsigned char *)(wadimg->data);
src += wadimg->width * (srcy>>16);
srcy += stepy;
srcx = 0;
for (x = 0; x < nw; x++)
{
img[x+y*64] = d_8to24rgbtable[src[srcx>>16]];
srcx += stepx;
}
}
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA_SA, img, nw, nh, 64*4);
if (c)
{
c->flags = CHARF_FORCEWHITE; //private glyph colours
c->left = 0;
c->top = f->charheight - nh;
c->advance = nw;
return c;
}
}
}
#endif
/*make tab invisible*/
if (charidx == '\t' || charidx == '\n')
{
c = &f->chars[charidx/FONTBLOCKSIZE][charidx&FONTBLOCKMASK];
c->left = 0;
c->advance = f->charheight;
c->top = 0;
c->texplane = 0;
c->bmx = 0;
c->bmy = 0;
c->bmw = 0;
c->bmh = 0;
return c;
}
if (f->faces)
{
int file;
for (file = 0; file < f->faces; file++)
{
fontface_t *qface = f->face[file];
#ifdef AVAIL_FREETYPE
if (qface->ft.face)
{
FT_Face face = qface->ft.face;
if (qface->ft.activeheight != f->charheight)
{
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
if (!Font_ChangeFTSize(qface, f->charheight))
return NULL; //some sort of error.
}
if (charidx == 0xfffe || pFT_Get_Char_Index(face, charidx)) //ignore glyph 0 (undefined)
if (pFT_Load_Char(face, charidx, FT_LOAD_RENDER|(((f->flags&FONT_MONO)&&qface->ft.activeheight==qface->ft.actualsize/*FIXME*/)?FT_LOAD_TARGET_MONO:FT_LOAD_TARGET_NORMAL)|FT_LOAD_COLOR) == 0)
{
FT_GlyphSlot slot;
FT_Bitmap *bm;
slot = face->glyph;
bm = &slot->bitmap;
if (qface->ft.activeheight!=qface->ft.actualsize)
{
//I'm just going to assume full-height raster glyphs here. I'm sure I'll be proven wrong some time but w/e.
int nw, nh;
if (bm->rows)
{
nh = f->charheight;
nw = (bm->width*nh)/bm->rows;
}
else
nw = f->charheight, nh = 0;
if (!nw || !nh)
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_GRAY, NULL, nw, nh, 0);
else if (bm->pixel_mode == FT_PIXEL_MODE_BGRA)
{
unsigned int *out = alloca(nw*nh*sizeof(*out));
Image_ResampleTexture(PTI_BGRA8, (void*)bm->buffer, bm->width, bm->rows, out, nw, nh);
c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, out, nw, nh, nw*sizeof(*out));
}
else if (bm->pixel_mode == FT_PIXEL_MODE_GRAY)
{
unsigned char *out = alloca(nw*nh*sizeof(*out));
Image_ResampleTexture(PTI_L8, (void*)bm->buffer, bm->width, bm->rows, out, nw, nh);
c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, out, nw, nh, nw*sizeof(*out));
}
/*else if (bm->pixel_mode == FT_PIXEL_MODE_MONO)
{
unsigned char *out = alloca(nw*nh*sizeof(*out));
Image_ResampleTexture(PTI_L1, (void*)bm->buffer, bm->width, bm->rows, out, nw, nh);
c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, out, nw, nh, nw*sizeof(*out));
}*/
else
c = NULL;
if (c)
{
c->advance = nw;
c->left = 0;
c->top = 0;
return c;
}
}
else
{
c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, bm->buffer, bm->width, bm->rows, bm->pitch);
if (c)
{
c->advance = slot->advance.x >> 6;
c->left = slot->bitmap_left;
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
/*if(1)
c->top = f->truecharheight - slot->bitmap_top;
else*/
c->top = f->charheight*3/4 - slot->bitmap_top;
return c;
}
}
}
}
else
#endif
#ifdef HALFLIFEMODELS
if (qface->halflife)
{
size_t glyph = charidx;
if (glyph > 0xe000)
glyph -= 0xe000;
if (glyph < 0x100)
{
int gw = qface->halflife->chartab[glyph].width;
int gh = qface->halflife->fontheight1;
qbyte *in = qface->halflife->data + 256 * qface->halflife->chartab[glyph].y + qface->halflife->chartab[glyph].x;
qbyte *pal = qface->halflife->data + 256 * qface->halflife->imgheight+2;
qbyte *out = alloca(gw*gh*4);
int x, y;
for (y = 0; y < gh; y++, in += 256-gw)
for (x = 0; x < gw; x++, in++)
{
if (*in==0xff)
{
out[(x+y*gw)*4+0] = 0;
out[(x+y*gw)*4+1] = 0;
out[(x+y*gw)*4+2] = 0;
out[(x+y*gw)*4+3] = 0;
}
else
{
qbyte val;
val = max(pal[*in*3+0], pal[*in*3+1]);
val = max(val, pal[*in*3+2]);
out[(x+y*gw)*4+0] =
out[(x+y*gw)*4+1] =
out[(x+y*gw)*4+2] = val;
out[(x+y*gw)*4+3] = 0xff;
}
}
if (f->charheight != gh)
{
int ngw = (gw * f->charheight) / gh;
int ngh = f->charheight;
qbyte *out2 = alloca(ngw*ngh*4);
if (ngw&&ngh)
Image_ResampleTexture(PTI_RGBA8, out, gw, gh, out2, ngw, ngh);
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, out2, ngw, ngh, ngw*4);
gw = ngw;
}
else
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, out, gw, gh, gw*4);
if (c)
{
c->flags = 0; //private glyph colours
c->advance = gw;
c->left = 0;
c->top = 0;
return c;
}
}
}
else
#endif
if (qface->horiz.data)
{
c = Font_TryLoadGlyphRaster(f, qface, charidx);
if (c)
return c;
}
}
}
if (charidx == '\r')
return Font_CopyChar(f, charidx|0xe000, charidx);
return NULL;
}
//obtains a cached char, null if not cached
static struct charcache_s *Font_GetChar(font_t *f, unsigned int codepoint)
{
CHARIDXTYPE charidx;
struct charcache_s *c;
if (codepoint > FONT_MAXCHARS)
charidx = 0xfffd;
else
charidx = codepoint;
c = Font_GetCharIfLoaded(f, charidx);
if (!c)
{
if (charidx >= TRACKERFIRST && charidx < TRACKERFIRST+100)
{
static struct charcache_s tc;
tc.texplane = TRACKERIMAGE;
fontplanes.trackerimage = Font_GetTrackerImage(charidx-TRACKERFIRST);
if (!fontplanes.trackerimage)
return Font_GetChar(f, '?');
tc.advance = fontplanes.trackerimage->width * ((float)f->charheight / fontplanes.trackerimage->height);
return &tc;
}
if (charidx == 0x00a0) //nbsp
{
c = Font_GetCharIfLoaded(f, ' ');
if (c)
return c;
}
//not cached, can't get.
c = Font_TryLoadGlyph(f, charidx);
if (!c && charidx >= 0x400 && charidx <= 0x45f)
{ //apparently there's a lot of russian players out there.
//if we just replace all their chars with a '?', they're gonna get pissed.
//so lets at least attempt to provide some default mapping that makes sense even if they don't have a full font.
//koi8-u is a mapping useful with 7-bit email because the message is still vaugely readable in latin if the high bits get truncated.
//not being a language specialist, I'm just going to use that mapping, with the high bit truncated to ascii (which mostly exists in the quake charset).
//this exact table is from ezquake. because I'm too lazy to figure out the proper mapping. (beware of triglyphs)
static char *wc2koi_table =
"?3??4?67??" "??" "??" ">?" //400
"abwgdevzijklmnop" //410
"rstufhc~{}/yx|`q" //420
"ABWGDEVZIJKLMNOP" //430
"RSTUFHC^[]_YX\\@Q" //440
"?#??$?&'??" "??" "??.?"; //450
charidx = wc2koi_table[charidx - 0x400];
if (charidx != '?')
{
c = Font_GetCharIfLoaded(f, charidx);
if (!c)
c = Font_TryLoadGlyph(f, charidx);
}
}
if (!c && charidx >= 0xA0 && charidx <= 0x17F)
{ //try to make sense of iso8859-1
//(mostly for zerstorer's o-umlout...)
static char *latin_table =
" ?c###|S?c?<??R?" //A0
"??""??""'u?.,??"">??""??" //B0
"AAAAAAECEEEEIIII" //C0
"DNOOOOO*OUUUUYYs" //D0
"aaaaaaeceeeeiiii" //E0
"onooooo/ouuuuyyy" //F0
"AaAaAaCcCcCcCcDd" //100
"DdEeEeEeEeEeGgGg" //110
"GgGgHhHhIiIiIiIi" //120
"IiIiJjKkkLlLlLlL" //130
"lllNnNnNnnNnOoOo" //140
"OoEeRrRrRrSsSsSs" //150
"SsTtTtTtUuUuUuUu" //160
"UuUuWwYyYZzZzZzf"; //170
charidx = latin_table[charidx - 0xA0];
if (charidx != '?')
{
c = Font_GetCharIfLoaded(f, charidx);
if (!c)
c = Font_TryLoadGlyph(f, charidx);
}
}
if (!c)
c = Font_LoadPlaceholderGlyph(f, charidx);
if (!c)
{
charidx = 0xfffd; //unicode's replacement char
c = Font_GetCharIfLoaded(f, charidx);
if (!c)
c = Font_TryLoadGlyph(f, charidx);
}
if (!c)
{
charidx = '?'; //meh
c = Font_GetCharIfLoaded(f, charidx);
if (!c)
c = Font_TryLoadGlyph(f, charidx);
}
}
return c;
}
qboolean Font_LoadHorizontalFont(struct font_s *f, int fheight, const char *fontfilename)
{ //halflife-style.
fontface_t *qface;
void *rawdata;
qofs_t rawsize;
qbyte *rgbadata = NULL;
int width=0,height=0;
uploadfmt_t format;
if (fheight < 1)
fheight = 1;
//ran out of font slots.
if (f->faces == MAX_FACES)
return false;
for (qface = faces; qface; qface = qface->fnext)
{
if (!strcmp(qface->name, fontfilename) && qface->horiz.data)
{
qface->refs++;
f->face[f->faces++] = qface;
return true;
}
}
rawdata = FS_MallocFile(fontfilename, FS_GAME, &rawsize);
if (rawdata)
rgbadata = ReadRawImageFile(rawdata, rawsize, &width, &height, &format, true, fontfilename);
FS_FreeFile(rawdata);
if (rgbadata)
{
/*success!*/
qface = Z_Malloc(sizeof(*qface));
qface->flink = &faces;
qface->fnext = *qface->flink;
*qface->flink = qface;
if (qface->fnext)
qface->fnext->flink = &qface->fnext;
qface->horiz.data = rgbadata;
qface->horiz.stride = width;
qface->horiz.charheight = height;
qface->horiz.rows = 1;
qface->horiz.paletted = false;
qface->horiz.codepage = FMT_ISO88591;
qface->refs++;
Q_strncpyz(qface->name, fontfilename, sizeof(qface->name));
f->face[f->faces++] = qface;
return true;
}
return false;
}
qboolean Font_LoadKexFont(struct font_s *f, int fheight, const char *fontfilename)
{
vfsfile_t *kfont = FS_OpenVFS(va("fonts/%s.kfont", fontfilename), "rb", FS_GAME);
char line[256];
char val[256], *s;
struct charcache_s *c;
fontface_t *qface;
if (!kfont)
return false;
while(VFS_GETS(kfont, line, sizeof(line)))
{
s = COM_ParseOut(line, val, sizeof(val));
if (!s)
continue;
if (!strcmp(val, "texture") && (s=COM_ParseOut(s, val, sizeof(val))))
{
TEXDOWAIT(f->singletexture);
if (!TEXLOADED(f->singletexture))
{ //noworker is needed because we need to know the size to make sense of char positions
//exactextension is needed to work around quakeex fuckups
f->singletexture = Image_GetTexture(val, NULL, IF_NOWORKER|IF_EXACTEXTENSION|IF_UIPIC|(r_font_linear.ival?IF_LINEAR:IF_NEAREST)|IF_NOPICMIP|IF_NOMIPMAP|IF_NOGAMMA|IF_NOPURGE, NULL, NULL, 0, 0, PTI_INVALID);
}
}
else if (*val >= '0' && *val <='9')
{
unsigned int codepoint = atoi(val);
unsigned int x, y, w, h;//, u;
if (!TEXLOADED(f->singletexture))
break;
s=COM_ParseOut(s, val, sizeof(val));
x = atoi(val);
s=COM_ParseOut(s, val, sizeof(val));
y = atoi(val);
s=COM_ParseOut(s, val, sizeof(val));
w = atoi(val);
s=COM_ParseOut(s, val, sizeof(val));
h = atoi(val);
s=COM_ParseOut(s, val, sizeof(val));
//u = atoi(val);
if (!s)
continue; //something truncated.
if (codepoint >= FONT_MAXCHARS || h<=0)
continue; //out of range.
c = Font_GetCharStore(f, codepoint);
if (codepoint != ' ')
{
y+=2;
h-=4;
}
c->advance = max(1,(f->charheight * w)/h);
c->bmw = (w * PLANEWIDTH) / f->singletexture->width;
c->bmh = (h * PLANEHEIGHT) / f->singletexture->height;
c->bmx = (x * PLANEWIDTH) / f->singletexture->width;
c->bmy = (y * PLANEHEIGHT) / f->singletexture->height;
c->left = 0;
c->nextchar = 0; //these chars are not linked in
c->texplane = BITMAPPLANE;
}
}
VFS_CLOSE(kfont);
if (!TEXLOADED(f->singletexture))
return false;
/*success!*/
qface = Z_Malloc(sizeof(*qface));
qface->flink = &faces;
qface->fnext = *qface->flink;
*qface->flink = qface;
if (qface->fnext)
qface->fnext->flink = &qface->fnext;
qface->refs++;
Q_snprintfz(qface->name, sizeof(qface->name), "fonts/%s.kfont", fontfilename);
f->face[f->faces++] = qface;
return true;
}
#ifdef AVAIL_FREETYPE
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
extern cvar_t dpcompat_smallerfonts;
int Font_ChangeFTSize(fontface_t *qface, int pixelheight)
{
FT_Face face = qface->ft.face;
qface->ft.activeheight = pixelheight;
#ifdef HAVE_LEGACY
if (dpcompat_smallerfonts.ival)
{ //sizes specified include extra spacing in dp, giving extra padding somewhere.
int s = pixelheight;
for(s = pixelheight; s; s--)
{
if (0==pFT_Set_Pixel_Sizes(face, 0, s))
if (face->size->metrics.height>>6 <= pixelheight)
break;
}
if (!s)
{
qface->ft.activeheight = 0; //something invalid
qface->ft.actualsize = qface->ft.activeheight;
return 0;
}
qface->ft.actualsize = qface->ft.activeheight;
return s;
}
else
#endif
if (FT_HAS_FIXED_SIZES(face) && !FT_IS_SCALABLE(face))
{ //freetype doesn't like scaling these for us, so we have to pick a usable size ourselves.
FT_Int best = 0, s;
int bestheight = 0, h;
for (s = 0; s < qface->ft.face->num_fixed_sizes; s++)
{
h = qface->ft.face->available_sizes[s].height;
//always try to pick the smallest size that is also >= our target size
if ((h > bestheight && bestheight < pixelheight) || (h >= pixelheight && h < bestheight))
{
bestheight = h;
best = s;
}
}
qface->ft.actualsize = qface->ft.face->available_sizes[best].height;
pFT_Select_Size(face, best);
}
else
{
pFT_Set_Pixel_Sizes(face, 0, pixelheight);
qface->ft.actualsize = pixelheight;
}
return pixelheight;
}
qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, const char *fontfilename)
{
fontface_t *qface;
FT_Face face = NULL;
FT_Error error;
flocation_t loc;
void *fbase = NULL;
if (!*fontfilename)
return false;
if (height < 1)
height = 1;
//ran out of font slots.
if (f->faces == MAX_FACES)
return false;
for (qface = faces; qface; qface = qface->fnext)
{
if (!strcmp(qface->name, fontfilename) && qface->ft.face)
{
qface->refs++;
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
if (!f->faces)
f->truecharheight = Font_ChangeFTSize(qface, f->charheight);
f->face[f->faces++] = qface;
return true;
}
}
if (!fontlib)
{
#ifndef FREETYPE_STATIC
dllfunction_t ft2funcs[] =
{
{(void**)&pFT_Init_FreeType, "FT_Init_FreeType"},
{(void**)&pFT_Load_Char, "FT_Load_Char"},
{(void**)&pFT_Get_Char_Index, "FT_Get_Char_Index"},
{(void**)&pFT_Set_Pixel_Sizes, "FT_Set_Pixel_Sizes"},
{(void**)&pFT_Select_Size, "FT_Select_Size"},
{(void**)&pFT_New_Face, "FT_New_Face"},
{(void**)&pFT_New_Memory_Face, "FT_New_Memory_Face"},
{(void**)&pFT_Init_FreeType, "FT_Init_FreeType"},
{(void**)&pFT_Done_Face, "FT_Done_Face"},
openxr plugin: tweaked - inputs should be working properly now, and are visible to csqc. subject to further breaking changes, however. _pext_vrinputs: added cvar to enable vr inputs protocol extension allowing vr inputs to be networked to ssqc too. defaults to 0 for now, will be renamed when deemed final. updates menu: the prompt to enable sources is now more explicit instead of expecting the user to have a clue. updates menu: added a v3 sources format, which should be more maintainable. not final. updates menu: try to give reasons why sources might be failing (to help blame ISPs if they try fucking over TTH dns again). presets menu: no longer closes the instant a preset is chosen. some presets have a couple of modifiers listed. force the demo loop in the background to serve as a preview. prompts menus: now does word wrapping. ftemaster: support importing server lists from other master servers (requested by Eukara). server: try to detect when non-reply inbound packets are blocked by firewalls/nats/etc (using ftemaster to do so). qcvm: added pointcontentsmask builtin, allowing it to probe more than just world, with fte's full contentbit range instead of just q1 legacy. qcvm: memfill8 builtin now works on createbuffer() pointers. qcvm: add missing unsigned ops. Fixed double comparison ops. fixed bug with op_store_i64. added missing OP_LOADP_I64 qcc: added '#pragma framerate RATE' for overriding implicit nextthink durations. qcc: fixed '#pragma DONT_COMPILE_THIS_FILE' to not screw up comments. qcc: added __GITURL__ __GITHASH__ __GITDATE__ __GITDATETIME__ __GITDESC__ for any mods that might want to make use of that. qcc: fix up -Fhashonly a little setrenderer: support for vulkan gpu enumeration. rulesets: reworked to support custom rulesets (using hashes to catch haxxors, though still nothing prevents just changing the client to ignore rulesets) bspx: use our BIH code for the bspx BRUSHLIST lump instead of the older less efficient code. (static)iqm+obj: these model formats can now be used for the worldmodel (with a suitable .ent file). Also using BIH for much better collision performance. pmove: tried to optimise PM_NudgePosition, should boost fps in stress tests. wayland: fix a crash on startup. mousegrabs now works better. imagetool: uses sdl for previews. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5813 fc73d0e0-1445-4013-8a0c-d673dee63da5
2021-04-13 22:21:04 -07:00
{(void**)&pFT_Error_String, "FT_Error_String"},
{NULL, NULL}
};
if (triedtoloadfreetype)
return false;
triedtoloadfreetype = true;
#ifdef _WIN32
fontmodule = Sys_LoadLibrary("libfreetype-6", ft2funcs);
if (!fontmodule)
fontmodule = Sys_LoadLibrary("freetype6", ft2funcs);
#else
fontmodule = Sys_LoadLibrary("libfreetype.so.6", ft2funcs);
#endif
if (!fontmodule)
{
Con_DPrintf("Couldn't load freetype library.\n");
return false;
}
#endif
error = pFT_Init_FreeType(&fontlib);
if (error)
{
Con_Printf("FT_Init_FreeType failed.\n");
#ifndef FREETYPE_STATIC
Sys_CloseLibrary(fontmodule);
#endif
return false;
}
/*any other errors leave freetype open*/
}
error = FT_Err_Cannot_Open_Resource;
if (FS_FLocateFile(fontfilename, FSLF_IFFOUND|FSLF_QUIET, &loc) || FS_FLocateFile(va("%s.ttf", fontfilename), FSLF_IFFOUND|FSLF_QUIET, &loc) || FS_FLocateFile(va("%s.otf", fontfilename), FSLF_IFFOUND|FSLF_QUIET, &loc))
{
if (*loc.rawname && !loc.offset)
{
fbase = NULL;
/*File is directly fopenable with no bias (not in a pk3/pak). Use the system-path form, so we don't have to eat the memory cost*/
error = pFT_New_Face(fontlib, loc.rawname, 0, &face);
}
else
{
/*File is inside an archive, we need to read it and pass it as memory (and keep it available)*/
vfsfile_t *f;
f = FS_OpenReadLocation(loc.rawname, &loc);
if (f && loc.len > 0)
{
fbase = BZ_Malloc(loc.len);
VFS_READ(f, fbase, loc.len);
VFS_CLOSE(f);
error = pFT_New_Memory_Face(fontlib, fbase, loc.len, 0, &face);
}
}
}
#if defined(_WIN32)
if (error)
{
static qboolean firsttime = true;
static char fontdir[MAX_OSPATH];
if (firsttime)
{
HRESULT (WINAPI *dSHGetFolderPath) (HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath);
dllfunction_t shfolderfuncs[] =
{
{(void**)&dSHGetFolderPath, "SHGetFolderPathA"},
{NULL, NULL}
};
dllhandle_t *shfolder = Sys_LoadLibrary("shfolder.dll", shfolderfuncs);
firsttime = false;
if (shfolder)
{
// 0x14 == CSIDL_FONTS
if (dSHGetFolderPath(NULL, 0x14, NULL, 0, fontdir) != S_OK)
*fontdir = 0;
Sys_CloseLibrary(shfolder);
}
}
if (*fontdir)
{
error = pFT_New_Face(fontlib, va("%s/%s", fontdir, fontfilename), 0, &face);
if (error)
error = pFT_New_Face(fontlib, va("%s/%s.ttf", fontdir, fontfilename), 0, &face);
}
}
#else
if (error)
{ //eg: /usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf
error = pFT_New_Face(fontlib, va("/usr/share/fonts/%s", fontfilename), 0, &face);
if (error)
error = pFT_New_Face(fontlib, va("/usr/share/fonts/truetype/%s.ttf", fontfilename), 0, &face);
if (error) //just to give a chance of the same names working on more than one os, with the right package installed.
error = pFT_New_Face(fontlib, va("/usr/share/fonts/truetype/msttcorefonts/%s.ttf", fontfilename), 0, &face);
}
#endif
if (!error)
{
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
int trueheight;
/*success!*/
qface = Z_Malloc(sizeof(*qface));
qface->ft.face = face;
qface->ft.activeheight = qface->ft.actualsize = 0;//height;
qface->ft.membuf = fbase;
qface->refs++;
Q_strncpyz(qface->name, fontfilename, sizeof(qface->name));
trueheight = Font_ChangeFTSize(qface, f->charheight);
if (trueheight)
{ //okay, we can use it, link it in.
qface->flink = &faces;
qface->fnext = *qface->flink;
*qface->flink = qface;
if (qface->fnext)
qface->fnext->flink = &qface->fnext;
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
if (!f->faces)
f->truecharheight = trueheight;
f->face[f->faces++] = qface;
return true;
}
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
Z_Free(qface);
}
if (error && error != FT_Err_Cannot_Open_Resource)
openxr plugin: tweaked - inputs should be working properly now, and are visible to csqc. subject to further breaking changes, however. _pext_vrinputs: added cvar to enable vr inputs protocol extension allowing vr inputs to be networked to ssqc too. defaults to 0 for now, will be renamed when deemed final. updates menu: the prompt to enable sources is now more explicit instead of expecting the user to have a clue. updates menu: added a v3 sources format, which should be more maintainable. not final. updates menu: try to give reasons why sources might be failing (to help blame ISPs if they try fucking over TTH dns again). presets menu: no longer closes the instant a preset is chosen. some presets have a couple of modifiers listed. force the demo loop in the background to serve as a preview. prompts menus: now does word wrapping. ftemaster: support importing server lists from other master servers (requested by Eukara). server: try to detect when non-reply inbound packets are blocked by firewalls/nats/etc (using ftemaster to do so). qcvm: added pointcontentsmask builtin, allowing it to probe more than just world, with fte's full contentbit range instead of just q1 legacy. qcvm: memfill8 builtin now works on createbuffer() pointers. qcvm: add missing unsigned ops. Fixed double comparison ops. fixed bug with op_store_i64. added missing OP_LOADP_I64 qcc: added '#pragma framerate RATE' for overriding implicit nextthink durations. qcc: fixed '#pragma DONT_COMPILE_THIS_FILE' to not screw up comments. qcc: added __GITURL__ __GITHASH__ __GITDATE__ __GITDATETIME__ __GITDESC__ for any mods that might want to make use of that. qcc: fix up -Fhashonly a little setrenderer: support for vulkan gpu enumeration. rulesets: reworked to support custom rulesets (using hashes to catch haxxors, though still nothing prevents just changing the client to ignore rulesets) bspx: use our BIH code for the bspx BRUSHLIST lump instead of the older less efficient code. (static)iqm+obj: these model formats can now be used for the worldmodel (with a suitable .ent file). Also using BIH for much better collision performance. pmove: tried to optimise PM_NudgePosition, should boost fps in stress tests. wayland: fix a crash on startup. mousegrabs now works better. imagetool: uses sdl for previews. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5813 fc73d0e0-1445-4013-8a0c-d673dee63da5
2021-04-13 22:21:04 -07:00
Con_Printf("Freetype(%s): error %i - %s\n", fontfilename, error, pFT_Error_String(error));
if (fbase)
BZ_Free(fbase);
return false;
}
#endif
static texid_t Font_LoadReplacementConchars(void)
{
texid_t tex;
//q1 replacement
tex = R_LoadHiResTexture("gfx/conchars.lmp", NULL, (r_font_linear.ival?IF_LINEAR:IF_NEAREST)|IF_PREMULTIPLYALPHA|IF_LOADNOW|IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA|IF_NOPURGE);
TEXDOWAIT(tex);
if (TEXLOADED(tex))
return tex;
//q2
tex = R_LoadHiResTexture("pics/conchars.pcx", NULL, (r_font_linear.ival?IF_LINEAR:IF_NEAREST)|IF_PREMULTIPLYALPHA|IF_LOADNOW|IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA|IF_NOPURGE);
TEXDOWAIT(tex);
if (TEXLOADED(tex))
return tex;
//q3
tex = R_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, (r_font_linear.ival?IF_LINEAR:IF_NEAREST)|IF_PREMULTIPLYALPHA|IF_LOADNOW|IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA|IF_NOPURGE);
TEXDOWAIT(tex);
if (TEXLOADED(tex))
return tex;
return r_nulltex;
}
#ifdef HEXEN2
static texid_t Font_LoadHexen2Conchars(qboolean iso88591)
{
//gulp... so it's come to this has it? rework the hexen2 conchars into the q1 system.
texid_t tex;
unsigned int i, x;
unsigned char *tempchars;
unsigned char *in, *out, *outbuf;
FS_LoadFile("gfx/menu/conchars.lmp", (void**)&tempchars);
/*hexen2's conchars are arranged 32-wide, 16 high.
the upper 8 rows are 256 8859-1 chars
the lower 8 rows are a separate set of recoloured 8859-1 chars.
if we're loading for the fallback then we're loading this data for quake compatibility,
so we grab only the first 4 rows of each set of chars (128 low chars, 128 high chars).
if we're loading a proper charset, then we load only the first set of chars, we can recolour the rest anyway (com_parseutf8 will do so anyway).
as a final note, parsing iso8859-1 french/german/etc as utf8 will generally result in decoding errors which can gracefully revert to 8859-1 safely. If this premise fails too much, we can always change the parser for different charsets - the engine always uses unicode and thus 8859-1 internally.
*/
if (tempchars)
{
outbuf = BZ_Malloc(8*8*256*8);
out = outbuf;
i = 0;
/*read the low chars*/
for (; i < 8*8*1; i+=1)
{
if (i&(1<<3))
in = tempchars + (i>>3)*16*8*8+(i&7)*32*8 - 256*4+128;
else
in = tempchars + (i>>3)*16*8*8+(i&7)*32*8;
for (x = 0; x < 16*8; x++)
*out++ = *in++;
}
if (iso88591)
{
/*read the non 8859-1 quake-compat control chars*/
for (; i < 8*8*1 + 16; i+=1)
{
if (i&(1<<3))
in = tempchars+128*128 + ((i>>3)&7)*16*8*8+(i&7)*32*8 - 256*4+128;
else
in = tempchars+128*128 + ((i>>3)&7)*16*8*8+(i&7)*32*8;
for (x = 0; x < 16*8; x++)
*out++ = *in++;
}
/*read the final low chars (final if 8859-1 anyway)*/
for (; i < 8*8*2; i+=1)
{
if (i&(1<<3))
in = tempchars + (i>>3)*16*8*8+(i&7)*32*8 - 256*4+128;
else
in = tempchars + (i>>3)*16*8*8+(i&7)*32*8;
for (x = 0; x < 16*8; x++)
*out++ = *in++;
}
}
else
{
/*read the high chars*/
for (; i < 8*8*2; i+=1)
{
if (i&(1<<3))
in = tempchars+128*128 + ((i>>3)&15)*16*8*8+(i&7)*32*8 - 256*4+128;
else
in = tempchars+128*128 + ((i>>3)&15)*16*8*8+(i&7)*32*8;
for (x = 0; x < 16*8; x++)
*out++ = *in++;
}
}
FS_FreeFile(tempchars);
// add ocrana leds
if (!iso88591 && con_ocranaleds.value && con_ocranaleds.value != 2)
AddOcranaLEDsIndexed (outbuf, 128, 128);
for (i=0 ; i<128*128 ; i++)
if (outbuf[i] == 0)
outbuf[i] = 255; // proper transparent color
tex = R_LoadTexture8 (iso88591?"gfx/menu/8859-1.lmp":"charset", 128, 128, outbuf, IF_PREMULTIPLYALPHA|IF_LOADNOW|IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA, 1);
Z_Free(outbuf);
return tex;
}
return r_nulltex;
}
#endif
FTE_ALIGN(4) qbyte default_conchar[/*11356*/] =
{
#include "lhfont.h"
};
static void Font_CopyGlyph(int src, int dst, void *data)
{
int glyphsize = 16;
int y;
int x;
char *srcptr = (char*)data + (src&15)*glyphsize*4 + (src>>4)*glyphsize*256*4;
char *dstptr = (char*)data + (dst&15)*glyphsize*4 + (dst>>4)*glyphsize*256*4;
for (y = 0; y < glyphsize; y++)
{
for (x = 0; x < glyphsize; x++)
{
dstptr[x*4+0] = srcptr[x*4+0];
dstptr[x*4+1] = srcptr[x*4+1];
dstptr[x*4+2] = srcptr[x*4+2];
dstptr[x*4+3] = srcptr[x*4+3];
}
dstptr += 256*4;
srcptr += 256*4;
}
}
static texid_t Font_LoadFallbackConchars(void)
{
texid_t tex;
int width, height;
unsigned int i;
uploadfmt_t format;
qbyte *lump = ReadRawImageFile(default_conchar, sizeof(default_conchar), &width, &height, &format, false, "conchars");
if (!lump || (format != PTI_RGBX8 && format != PTI_RGBA8 && format != PTI_LLLX8))
return r_nulltex;
/*convert greyscale to alpha*/
for (i = 0; i < width*height; i++)
{
lump[i*4+3] = lump[i*4];
lump[i*4+0] = 255;
lump[i*4+1] = 255;
lump[i*4+2] = 255;
}
if (width == 256 && height == 256)
{ //make up some scroll-bar/download-progress-bar chars, so that webgl doesn't look so buggy with the initial pak file(s).
Font_CopyGlyph('[', 128, lump);
Font_CopyGlyph('-', 129, lump);
Font_CopyGlyph(']', 130, lump);
Font_CopyGlyph('|', 131, lump);
Font_CopyGlyph('>', 13, lump);
}
tex = Image_GetTexture("charset", NULL, IF_PREMULTIPLYALPHA|IF_LOADNOW|IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA|IF_NOPURGE, (void*)lump, NULL, width, height, PTI_RGBA8);
BZ_Free(lump);
return tex;
}
/*loads a fallback image. not allowed to fail (use syserror if needed)*/
static texid_t Font_LoadDefaultConchars(enum fontfmt_e *fmt)
{
texid_t tex;
tex = Font_LoadReplacementConchars();
if (TEXLOADED(tex))
return tex;
#ifdef HEXEN2
tex = Font_LoadHexen2Conchars(true);
if (tex && tex->status == TEX_LOADING)
COM_WorkerPartialSync(tex, &tex->status, TEX_LOADING);
if (TEXLOADED(tex))
{
*fmt = FMT_ISO88591;
return tex;
}
#endif
tex = Font_LoadFallbackConchars();
if (tex && tex->status == TEX_LOADING)
COM_WorkerPartialSync(tex, &tex->status, TEX_LOADING);
if (TEXLOADED(tex))
{
*fmt = FMT_QUAKE;
return tex;
}
Sys_Error("Unable to load any conchars\n");
}
typedef struct
{
short width;
short height;
short leftoffset; // pixels to the left of origin
short topoffset; // pixels below the origin
int columnofs[1];
} doompatch_t;
typedef struct
{
unsigned char topdelta; // -1 is the last post in a column
unsigned char length; // length data bytes follows
} doomcolumn_t;
void Doom_ExpandPatch(doompatch_t *p, unsigned char *b, int stride)
{
doomcolumn_t *col;
unsigned char *src, *dst;
int x, y;
for (x = 0; x < p->width; x++)
{
col = (doomcolumn_t *)((unsigned char *)p + p->columnofs[x]);
while(col->topdelta != 0xff)
{
//exploit protection
if (col->length + col->topdelta > p->height)
break;
src = (unsigned char *)col + 2; /*why 3? why not, I suppose*/
dst = b + stride*col->topdelta;
for (y = 0; y < col->length; y++)
{
*dst = *src++;
dst += stride;
}
src++;
col = (doomcolumn_t *)((unsigned char*)col + col->length + 4);
}
b++;
}
}
static qboolean Font_LoadFontLump(font_t *f, const char *facename)
{
size_t lumpsize = 0;
qbyte lumptype = 0;
void *lumpdata;
if (f->faces == MAX_FACES)
return false; //can't store it...
lumpdata = W_GetLumpName(facename, &lumpsize, &lumptype);
if (!lumpdata)
return false;
if ((lumptype == TYP_MIPTEX && lumpsize==(8*8)*(16*16)) || //proper format
(lumptype == TYP_QPIC && lumpsize==(8*8)*(16*16)+8)) //fucked up buggy format used by some people
{
fontface_t *fa = Z_Malloc(sizeof(*fa));
fa->horiz.data = lumpdata;
fa->horiz.stride = 8*16;
fa->horiz.charheight = 8;
fa->horiz.codepage = FMT_QUAKE;
fa->horiz.paletted = true;
fa->horiz.rows = 16;
if (con_ocranaleds.ival)
{
openxr plugin: tweaked - inputs should be working properly now, and are visible to csqc. subject to further breaking changes, however. _pext_vrinputs: added cvar to enable vr inputs protocol extension allowing vr inputs to be networked to ssqc too. defaults to 0 for now, will be renamed when deemed final. updates menu: the prompt to enable sources is now more explicit instead of expecting the user to have a clue. updates menu: added a v3 sources format, which should be more maintainable. not final. updates menu: try to give reasons why sources might be failing (to help blame ISPs if they try fucking over TTH dns again). presets menu: no longer closes the instant a preset is chosen. some presets have a couple of modifiers listed. force the demo loop in the background to serve as a preview. prompts menus: now does word wrapping. ftemaster: support importing server lists from other master servers (requested by Eukara). server: try to detect when non-reply inbound packets are blocked by firewalls/nats/etc (using ftemaster to do so). qcvm: added pointcontentsmask builtin, allowing it to probe more than just world, with fte's full contentbit range instead of just q1 legacy. qcvm: memfill8 builtin now works on createbuffer() pointers. qcvm: add missing unsigned ops. Fixed double comparison ops. fixed bug with op_store_i64. added missing OP_LOADP_I64 qcc: added '#pragma framerate RATE' for overriding implicit nextthink durations. qcc: fixed '#pragma DONT_COMPILE_THIS_FILE' to not screw up comments. qcc: added __GITURL__ __GITHASH__ __GITDATE__ __GITDATETIME__ __GITDESC__ for any mods that might want to make use of that. qcc: fix up -Fhashonly a little setrenderer: support for vulkan gpu enumeration. rulesets: reworked to support custom rulesets (using hashes to catch haxxors, though still nothing prevents just changing the client to ignore rulesets) bspx: use our BIH code for the bspx BRUSHLIST lump instead of the older less efficient code. (static)iqm+obj: these model formats can now be used for the worldmodel (with a suitable .ent file). Also using BIH for much better collision performance. pmove: tried to optimise PM_NudgePosition, should boost fps in stress tests. wayland: fix a crash on startup. mousegrabs now works better. imagetool: uses sdl for previews. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5813 fc73d0e0-1445-4013-8a0c-d673dee63da5
2021-04-13 22:21:04 -07:00
if (con_ocranaleds.ival != 2 || CalcHashInt(&hash_crc16, lumpdata, 128*128) == 798)
AddOcranaLEDsIndexed (lumpdata, 128, 128);
}
fa->flink = &fa->fnext;
fa->refs = 1;
f->face[f->faces++] = fa;
return true;
}
#ifdef HALFLIFEMODELS
else if (lumptype == TYP_HLFONT)
{
fontface_t *fa = Z_Malloc(sizeof(*fa));
fa->halflife = lumpdata;
fa->flink = &fa->fnext;
fa->refs = 1;
f->face[f->faces++] = fa;
// f->charheight = fa->halflife->fontheight1; //force the font to a specific size.
return true;
}
#endif
return false; //doesn't match a valid known format
}
//creates a new font object from the given file, with each text row with the given height.
//width is implicit and scales with height and choice of font.
struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scale, int outline, unsigned int flags)
{
struct font_s *f;
int i = 0;
int defaultplane;
char *aname;
char *parms;
int height = ((vheight * vid.rotpixelheight)/vid.height) + 0.5;
char facename[MAX_QPATH*12];
struct charcache_s *c;
float aspect = 1;
enum fontfmt_e fmt = FMT_AUTO;
qboolean explicit;
Q_strncpyz(facename, fontfilename, sizeof(facename));
aname = strstr(facename, ":");
if (aname)
*aname++ = 0;
parms = strstr(facename, "?");
if (parms)
*parms++ = 0;
f = Z_Malloc(sizeof(*f));
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
f->outline = outline;
f->scale = scale;
f->charheight = height;
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
f->truecharheight = height;
f->flags = flags;
Q_strncpyz(f->name, fontfilename, sizeof(f->name));
switch(M_GameType())
{
case MGT_QUAKE2:
VectorSet(f->alttint, 0.44, 1.0, 0.2);
break;
default:
VectorSet(f->alttint, 1.16, 0.54, 0.41);
break;
}
VectorSet(f->tint, 1, 1, 1);
fontfilename = facename;
if (parms)
{
while (*parms)
{
if (!strncmp(parms, "col=", 4))
{
char *t = parms+4;
f->tint[0] = strtod(t, &t);
if (*t == ',') t++;
if (*t == ' ') t++;
f->tint[1] = strtod(t, &t);
if (*t == ',') t++;
if (*t == ' ') t++;
f->tint[2] = strtod(t, &t);
parms = t;
}
if (!strncmp(parms, "fmt=", 4))
{
char *t = parms+4;
fmt = 0;
if (*t == 'q')
fmt = FMT_QUAKE;
else if (*t == 'l')
fmt = FMT_ISO88591;
else if (*t == 'w')
fmt = FMT_WINDOWS1252;
else if (*t == 'k')
fmt = FMT_KOI8U;
else if (*t == 'h')
fmt = FMT_HORIZONTAL;
}
if (!strncmp(parms, "aspect=", 7))
{
char *t = parms+7;
aspect = strtod(t, &t);
parms = t;
}
while(*parms && *parms != '&')
parms++;
if (*parms == '&')
{
parms++;
continue;
}
}
}
if (vid.flags&VID_SRGBAWARE)
{
f->tint[0] = M_SRGBToLinear(f->tint[0], 1);
f->tint[1] = M_SRGBToLinear(f->tint[1], 1);
f->tint[2] = M_SRGBToLinear(f->tint[2], 1);
f->alttint[0] = M_SRGBToLinear(f->alttint[0], 1);
f->alttint[1] = M_SRGBToLinear(f->alttint[1], 1);
f->alttint[2] = M_SRGBToLinear(f->alttint[2], 1);
}
#ifdef PACKAGE_DOOMWAD
if (!*fontfilename)
{
unsigned char buf[PLANEWIDTH*PLANEHEIGHT];
int i;
int x=0,y=0,h=0;
doompatch_t *dp;
memset(buf, 0, sizeof(buf));
for (i = '!'; i <= '_'; i++)
{
dp = NULL;
FS_LoadFile(va("wad/stcfn%.3d", i), (void**)&dp);
if (!dp)
break;
/*make sure it can fit*/
if (x + dp->width > PLANEWIDTH)
{
x = 0;
y += h;
h = 0;
}
f->chars[i].advance = dp->width; /*this is how much line space the char takes*/
f->chars[i].left = -dp->leftoffset;
f->chars[i].top = -dp->topoffset;
f->chars[i].nextchar = 0;
f->chars[i].pad = 0;
f->chars[i].texplane = SINGLEPLANE;
f->chars[i].bmx = x;
f->chars[i].bmy = y;
f->chars[i].bmh = dp->height;
f->chars[i].bmw = dp->width;
Doom_ExpandPatch(dp, &buf[y*PLANEWIDTH + x], PLANEWIDTH);
x += dp->width;
if (dp->height > h)
{
h = dp->height;
if (h > f->charheight)
f->charheight = h;
}
FS_FreeFile(dp);
}
/*if all loaded okay, replicate the chars to the quake-compat range (both white+red chars)*/
if (i == '_'+1)
{
//doom doesn't have many chars, so make sure the lower case chars exist.
for (i = 'a'; i <= 'z'; i++)
f->chars[i] = f->chars[i-'a'+'A'];
//no space char either
f->chars[' '].advance = 8;
f->singletexture = R_LoadTexture8("doomfont", PLANEWIDTH, PLANEHEIGHT, buf, 0, true);
for (i = 0xe000; i <= 0xe0ff; i++)
{
f->chars[i] = f->chars[toupper(i&0x7f)];
}
return f;
}
}
#endif
#ifdef HEXEN2
if (!strcmp(fontfilename, "gfx/tinyfont"))
{
unsigned int *img;
int x, y;
size_t lumpsize;
qbyte lumptype;
unsigned char *w = W_GetLumpName(fontfilename+4, &lumpsize, &lumptype);
if (!w || lumpsize != 32*128 || lumptype != 'D')
{
Z_Free(f);
return NULL;
}
img = Z_Malloc(PLANEWIDTH*PLANEWIDTH*4);
for (y = 0; y < 32; y++)
for (x = 0; x < 128; x++)
img[x + y*PLANEWIDTH] = w[x + y*128]?d_8to24rgbtable[w[x + y*128]]:0;
f->singletexture = R_LoadTexture("tinyfont",PLANEWIDTH,PLANEWIDTH,TF_RGBA32,img,IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_NOPURGE);
if (f->singletexture->status == TEX_LOADING)
COM_WorkerPartialSync(f->singletexture, &f->singletexture->status, TEX_LOADING);
Z_Free(img);
for (i = 0x00; i <= 0xff; i++)
{
c = Font_GetCharStore(f, i);
c->advance = (height*3)/4;
c->left = 0;
c->top = 0;
c->nextchar = 0; //these chars are not linked in
c->texplane = BITMAPPLANE; /*if its a 'raster' font, don't use the default chars, always use the raster images*/
if (i >= 'a' && i <= 'z')
{
c->bmx = ((i - 64)&15)*8;
c->bmy = ((i - 64)/16)*8;
c->bmh = 8;
c->bmw = 8;
}
else if (i >= 32 && i < 96)
{
c->bmx = ((i - 32)&15)*8;
c->bmy = ((i - 32)/16)*8;
c->bmh = 8;
c->bmw = 8;
}
else
{
c->bmh = 0;
c->bmw = 0;
c->bmx = 0;
c->bmy = 0;
}
Font_CopyChar(f, i, i|0xe0ff);
}
return f;
}
#endif
if (aname)
{
if (!strncmp(aname, "?col=", 5))
{
char *t = aname+5;
f->alttint[0] = strtod(t, &t);
if (*t == ',') t++;
if (*t == ' ') t++;
f->alttint[1] = strtod(t, &t);
if (*t == ',') t++;
if (*t == ' ') t++;
f->alttint[2] = strtod(t, &t);
}
else
{
f->alt = Font_LoadFont(aname, vheight, scale, outline, flags);
if (f->alt)
{
VectorCopy(f->alt->tint, f->alttint);
VectorCopy(f->alt->tint, f->alt->alttint);
}
}
}
explicit = false; //singletexture is some weird custom layout and not to be trusted.
{
const char *start;
qboolean success;
start = fontfilename;
for(;;)
{
char *end = strchr(start, ',');
if (end)
*end = 0;
if (fmt == FMT_AUTO && *start && Font_LoadKexFont(f, height, start))
success = explicit = true;
else if (fmt == FMT_HORIZONTAL)
success = Font_LoadHorizontalFont(f, height, start);
#ifdef AVAIL_FREETYPE
else if (fmt == FMT_AUTO && Font_LoadFreeTypeFont(f, height, start))
success = true;
#endif
else
success = false;
if (!success && !TEXLOADED(f->singletexture) && *start)
{
f->singletexture = R_LoadHiResTexture(start, "fonts:charsets", IF_PREMULTIPLYALPHA|(r_font_linear.ival?IF_LINEAR:IF_NEAREST)|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_NOPURGE|IF_LOADNOW);
if (f->singletexture->status == TEX_LOADING)
COM_WorkerPartialSync(f->singletexture, &f->singletexture->status, TEX_LOADING);
if (!TEXLOADED(f->singletexture) && f->faces < MAX_FACES)
Font_LoadFontLump(f, start);
}
if (end)
{
*end = ',';
start = end+1;
}
else
break;
}
}
if (!f->faces && !TEXLOADED(f->singletexture) && r_font_linear.ival)
Font_LoadFontLump(f, "conchars");
defaultplane = INVALIDPLANE;/*assume the bitmap plane - don't use the fallback as people don't think to use com_parseutf8*/
if (!explicit && TEXLOADED(f->singletexture))
defaultplane = BITMAPPLANE;
else if (TEXLOADED(fontplanes.defaultfont))
defaultplane = DEFAULTPLANE;
if (defaultplane == INVALIDPLANE)
{
if (!TEXLOADED(fontplanes.defaultfont))
{
fontplanes.defaultfont = Font_LoadDefaultConchars(&fmt);
}
#ifdef HEXEN2
if (!strcmp(fontfilename, "gfx/hexen2"))
{
f->singletexture = Font_LoadHexen2Conchars(false);
defaultplane = DEFAULTPLANE;
}
#endif
if (!TEXLOADED(f->singletexture))
f->singletexture = fontplanes.defaultfont;
if (TEXLOADED(f->singletexture))
defaultplane = BITMAPPLANE;
else if (TEXLOADED(fontplanes.defaultfont))
defaultplane = DEFAULTPLANE;
}
if (defaultplane != INVALIDPLANE)
{
if (fmt==FMT_AUTO)
fmt=FMT_QUAKE;
if (!f->faces)
{
static const unsigned short iso88591[] = {
0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87, 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f,
0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97, 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f};
static const unsigned short win1252[] = {
0x20ac, 0x81,0x201a,0x0192, 0x201e,0x2026,0x2020,0x2021, 0x02c6,0x2030,0x0160,0x2039, 0x0152, 0x8d,0x017d, 0x8f,
0x90,0x2018,0x2019,0x101c, 0x201d,0x2022,0x2013,0x2014, 0x02dc,0x2122,0x0161,0x203a, 0x0153, 0x9d,0x017e,0x0178};
static const unsigned short koi8u[] = {
0x2500,0x2502,0x250C,0x2510, 0x2514,0x2518,0x251C,0x2524, 0x252C,0x2534,0x253C,0x2580, 0x2584,0x2588,0x258C,0x2590,
0x2591,0x2592,0x2593,0x2320, 0x25A0,0x2219,0x221A,0x2248, 0x2264,0x2265,0x00A0,0x2321, 0x00B0,0x00B2,0x00B7,0x00F7,
0x2550,0x2551,0x2552,0x0451, 0x0454,0x2554,0x0456,0x0457, 0x2557,0x2558,0x2559,0x255A, 0x255B,0x0491,0x255D,0x255E,
0x255F,0x2560,0x2561,0x0401, 0x0404,0x2563,0x0406,0x0407, 0x2566,0x2567,0x2568,0x2569, 0x256A,0x0490,0x256C,0x00A9,
0x044E,0x0430,0x0431,0x0446, 0x0434,0x0435,0x0444,0x0433, 0x0445,0x0438,0x0439,0x043A, 0x043B,0x043C,0x043D,0x043E,
0x043F,0x044F,0x0440,0x0441, 0x0442,0x0443,0x0436,0x0432, 0x044C,0x044B,0x0437,0x0448, 0x044D,0x0449,0x0447,0x044A,
0x042E,0x0410,0x0411,0x0426, 0x0414,0x0415,0x0424,0x0413, 0x0425,0x0418,0x0419,0x041A, 0x041B,0x041C,0x041D,0x041E,
0x041F,0x042F,0x0420,0x0421, 0x0422,0x0423,0x0416,0x0412, 0x042C,0x042B,0x0417,0x0428, 0x042D,0x0429,0x0427,0x042A};
const unsigned short *c1;
unsigned int c1size;
if (fmt == FMT_WINDOWS1252)
{ //some tools use these extra ones (latin-1 has no visible c1 entries)
c1 = win1252;
c1size = countof(win1252);
}
else if (fmt == FMT_KOI8U)
{ //lots of russians in the quake scene
c1 = koi8u;
c1size = countof(koi8u);
}
else
{
c1 = iso88591;
c1size = countof(iso88591);
}
c1size += 128;
/*force it to load, even if there's nothing there*/
for (i = ((fmt==FMT_QUAKE)?32:0); i < ((fmt==FMT_QUAKE)?128:256); i++)
{
if (i >= 128 && i < c1size)
c = Font_GetCharStore(f, c1[i-128]);
else
c = Font_GetCharStore(f, i);
c->advance = f->charheight * aspect;
c->bmh = PLANEWIDTH/16;
c->bmw = PLANEWIDTH/16;
c->bmx = (i&15)*(PLANEWIDTH/16);
c->bmy = (i/16)*(PLANEWIDTH/16);
c->left = 0;
c->top = 0;
c->nextchar = 0; //these chars are not linked in
c->texplane = defaultplane;
}
}
if (fmt == FMT_QUAKE)
{
/*pack the default chars into it*/
for (i = 0xe000; i <= 0xe0ff; i++)
{
c = Font_GetCharStore(f, i);
c->advance = f->charheight * aspect;
c->bmh = PLANEWIDTH/16;
c->bmw = PLANEWIDTH/16;
c->bmx = ((i&15))*(PLANEWIDTH/16);
c->bmy = ((i&0xf0)/16)*(PLANEWIDTH/16);
c->left = 0;
c->top = 0;
c->nextchar = 0; //these chars are not linked in
c->texplane = defaultplane;
}
}
}
return f;
}
//removes a font from memory.
void Font_Free(struct font_s *f)
{
size_t i;
struct charcache_s **link, *c, *valid;
if (!f)
return;
//kill the alt font first.
if (f->alt)
{
Font_Free(f->alt);
f->alt = NULL;
}
valid = NULL;
//walk all chars, unlinking any that appear to be within this font's char cache
for (link = &fontplanes.oldestchar; *link; )
{
c = *link;
if (f->chars[c->block] && c >= f->chars[c->block] && c <= f->chars[c->block] + FONTBLOCKSIZE)
{
c = c->nextchar;
if (!c)
fontplanes.newestchar = valid;
*link = c;
}
else
{
valid = c;
link = &c->nextchar;
}
}
while(f->faces --> 0)
{
fontface_t *qface = f->face[f->faces];
qface->refs--;
if (!qface->refs)
{
#ifdef AVAIL_FREETYPE
if (qface->ft.face)
pFT_Done_Face(qface->ft.face);
if (qface->ft.membuf)
BZ_Free(qface->ft.membuf);
#endif
*qface->flink = qface->fnext;
if (qface->fnext)
qface->fnext->flink = qface->flink;
Z_Free(qface);
}
}
for (i = 0; i < FONTBLOCKS; i++)
if (f->chars[i])
Z_Free(f->chars[i]);
Z_Free(f);
}
//maps a given virtual screen coord to a pixel coord, which matches the font's height/width values
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py)
{
if (R2D_Flush && (R2D_Flush != Font_Flush || curfont != font || font_be_flags != r2d_be_flags))
R2D_Flush();
R2D_Flush = Font_Flush;
font_be_flags = r2d_be_flags;
curfont = font;
*px = (vx*(int)vid.rotpixelwidth) / (float)vid.width;
*py = (vy*(int)vid.rotpixelheight) / (float)vid.height;
curfont_scale[0] = curfont->charheight;
curfont_scale[1] = curfont->charheight;
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
// curfont_scaled = false;
}
void Font_Transform(float vx, float vy, int *px, int *py)
{
if (px)
*px = (vx*(int)vid.rotpixelwidth) / (float)vid.width;
if (py)
*py = (vy*(int)vid.rotpixelheight) / (float)vid.height;
}
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py)
{
if (R2D_Flush && (R2D_Flush != Font_Flush || curfont != font || font_be_flags != r2d_be_flags))
R2D_Flush();
R2D_Flush = Font_Flush;
font_be_flags = r2d_be_flags;
curfont = font;
*px = (vx*(float)vid.rotpixelwidth) / (float)vid.width;
*py = (vy*(float)vid.rotpixelheight) / (float)vid.height;
//now that its in pixels, clamp it so the text is at least consistant with its position.
//an individual char may end straddling a pixel boundary, but at least the pixels won't jiggle around as the text moves.
*px = (int)*px;
*py = (int)*py;
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
/* if ((int)(szx * vid.rotpixelheight/vid.height) == curfont->charheight && (int)(szy * vid.rotpixelheight/vid.height) == curfont->charheight)
curfont_scaled = false;
else
curfont_scaled = true;
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
*/
curfont_scale[0] = (szx * (float)vid.rotpixelheight) / (curfont->charheight * (float)vid.height);
curfont_scale[1] = (szy * (float)vid.rotpixelheight) / (curfont->charheight * (float)vid.height);
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
curfont_scale[0] *= curfont->scale;
curfont_scale[1] *= curfont->scale;
}
void Font_EndString(struct font_s *font)
{
// Font_Flush();
// curfont = NULL;
R2D_Flush = font_foremesh.numindexes?Font_Flush:NULL;
}
//obtains the font's row height (each row of chars should be drawn using this increment)
int Font_CharHeight(void)
{
return curfont->charheight;
}
int Font_CharPHeight(struct font_s *font)
{
return font->charheight;
}
Too many changes, sorry. Change revision displays, use the SVN commit date instead of using __DATE__ (when there's no local changes). This should allow reproducible builds. Added s_al_disable cvar, to block openal and all the various problems people have had with it, without having to name an explicit fallback (which would vary by system). Add mastervolume cvar (for ss). Add r_shadows 2 (aka fake shadows - for ss). Add scr_loadingscreen_aspect -1 setting, to disable levelshots entirely, also disables the progress bar (for ss). Better support for some effectinfo hacks (for ss). Added dpcompat_nocsqcwarnings (because of lazy+buggy mods like ss). Rework the dpcsqc versions of project+unproject builtins for better compat (for ss). Added dpcompat_csqcinputeventtypes to block unexpected csqc input events (for ss). Better compat with DP's loadfont console command (for ss). Added dpcompat_smallerfonts cvar to replicate a DP bug (for ss). Detect dp's m_draw extension, to work around it (for ss). Cvar dpcompat_ignoremodificationtimes added. A value of 0 favour the most recently modified file, 1 will use DP-like alphabetically sorted preferences (for ss). loadfont builtin can now accept outline=1 in the sizes arg for slightly more readable fonts. Fix bbox calcs for rotated entities, fix needed for r_ignorenetpvs 0. Hackily parse emoji.json to provide :poop: etc suggestions. Skip prediction entirely when there's no local entity info. This fixes stair-smoothing in xonotic. screenshot_cubemap will now capture half-float images when saving to ktx or dds files. Fix support for xcf files larger than 4gb, mostly to avoid compiler warnings. Fixed size of gfx/loading.lmp when replacement textures are used. Added mipmap support for rg8 and l8a8 textures. r_hdr_framebuffer cvar updated to support format names instead of random negative numbers. Description updated to name some interesting ones. Perform autoupdate _checks_ ONLY with explicit user confirmation (actual updating already needed user confirmation, but this extra step should reduce the chances of us getting wrongly accused of exfiltrating user data if we're run in a sandbox - we ONLY ever included the updating engine's version in the checks, though there's nothing we can do to avoid sending the user's router's IP). Removed the 'summon satan all over your harddrive' quit message, in case paranoid security researchers are idiots and don't bother doing actual research. Removed the triptohell.info and fte.triptohell.info certificates, they really need to stop being self-signed. The updates domain is still self-signed for autoupdates. Video drivers are now able to report supported video resolutions, visible to menuqc. Currently only works with SDL2 builds. Added setmousepos builtin. Should work with glx+win32 build. VF_SKYROOM_CAMERA can now accept an extra two args, setviewprop(VF_SKYROOM_CAMERA, org, axis, degrees). Removed v_skyroom_origin+v_skyroom_orientation cvars in favour just v_skyroom, which should make it behave more like the 'fog' command (used when csqc isn't overriding). Added R_EndPolygonRibbon builtin to make it faster+easier to generate textured ribbon/cable/etc wide lines (for TW). sdl: Fix up sys_sdl.c's file enumeration to support wildcards in directories. edit command now displays end1.bin/end2.bin correctly, because we can. Finally add support for f_modified - though ruleset_allow_larger_models and ruleset_allow_overlong_sounds generally make it redundant. Fix threading race condition in sha1 lookups. Updated f_ruleset to include the same extra flags reported by ezquake. A mod's default.fmf file can now contain an eg 'mainconfig config.cfg' line (to explicitly set the main config saved with cfg_save_auto 1 etc). fmf: basegame steam:GameName/GameDir can be used to try to load a mod directory from an installed steam game. The resulting gamedir will be read-only. HOMEDIR CHANGE: use homedirs only if the basedir cannot be written or a homedir already exists, which should further reduce the probability of microsoft randomly uploading our data to their cloud (but mostly because its annoying to never know where your data is written). Fixed buf_cvarlist, should work in xonotic now, and without segfaults. Added an extra arg to URI_Get_Callback calls - the response size, also changed the tempstring to contain all bytes of the response, you need to be careful about nulls though. Try to work around nvidia's forced-panning bug on x11 when changing video modes. This might screw with other programs. sdl: support custom icons. sdl: support choosing a specific display. Added some documentation to menuqc builtins. menusys: use outlines for slightly more readable fonts. menusys: switch vid_width and vid_height combos into a single video mode combo to set both according to reported video modes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5581 fc73d0e0-1445-4013-8a0c-d673dee63da5
2019-11-19 19:09:50 -08:00
int Font_GetTrueHeight(struct font_s *font) //Char[P]Height lies for compat with DP.
{
return font->truecharheight;
}
float Font_CharVHeight(struct font_s *font)
{
return ((float)font->charheight * vid.height)/vid.rotpixelheight;
}
//obtains the font's row height (each row of chars should be drawn using this increment)
float Font_CharScaleHeight(void)
{
return curfont->charheight * curfont_scale[1];
}
int Font_TabWidth(int x)
{
int tabwidth = Font_CharWidth(CON_WHITEMASK, ' ');
if (!tabwidth)
tabwidth = curfont->charheight;
tabwidth *= 8;
x++;
x = x + ((tabwidth - (x % tabwidth)) % tabwidth);
return x;
}
/*
This is where the character ends.
Note: this function supports tabs - x must always be based off 0, with Font_LineDraw actually used to draw the line.
*/
int Font_CharEndCoord(struct font_s *font, int x, unsigned int charflags, unsigned int codepoint)
{
struct charcache_s *c;
if (charflags&CON_HIDDEN)
return x;
if (codepoint == '\t')
return Font_TabWidth(x);
if ((charflags & CON_2NDCHARSETTEXT) && font->alt)
font = font->alt;
c = Font_GetChar(font, codepoint);
if (!c)
{
return x+0;
}
return x+c->advance;
}
//obtains the width of a character from a given font. This is how wide it is. The next char should be drawn at x + result.
//FIXME: this function cannot cope with tab and should not be used.
int Font_CharWidth(unsigned int charflags, unsigned int codepoint)
{
struct charcache_s *c;
struct font_s *font = curfont;
if (charflags&CON_HIDDEN)
return 0;
if ((charflags & CON_2NDCHARSETTEXT) && font->alt)
font = font->alt;
c = Font_GetChar(curfont, codepoint);
if (!c)
{
return 0;
}
return c->advance;
}
//obtains the width of a character from a given font. This is how wide it is. The next char should be drawn at x + result.
//FIXME: this function cannot cope with tab and should not be used.
float Font_CharScaleWidth(unsigned int charflags, unsigned int codepoint)
{
struct charcache_s *c;
struct font_s *font = curfont;
if (charflags&CON_HIDDEN)
return 0;
if ((charflags & CON_2NDCHARSETTEXT) && font->alt)
font = font->alt;
c = Font_GetChar(curfont, codepoint);
if (!c)
{
return 0;
}
return c->advance * curfont_scale[0];
}
conchar_t *Font_DecodeReverse(conchar_t *start, conchar_t *stop, unsigned int *codeflags, unsigned int *codepoint)
{
if (start <= stop)
{
*codeflags = 0;
*codepoint = 0;
return stop;
}
start--;
if (start > stop && start[-1] & CON_LONGCHAR)
if (!(start[-1] & CON_RICHFORECOLOUR))
{
start--;
*codeflags = start[1];
*codepoint = ((start[0] & CON_CHARMASK)<<16) | (start[1] & CON_CHARMASK);
return start;
}
*codeflags = start[0];
*codepoint = start[0] & CON_CHARMASK;
return start;
}
//for a given font, calculate the line breaks and word wrapping for a block of text
//start+end are the input string
//starts+ends are an array of line start and end points, which have maxlines elements.
//(end is the terminator, null or otherwise)
//maxpixelwidth is the width of the display area in pixels
int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int maxlines, conchar_t **starts, conchar_t **ends)
{
conchar_t *l, *bt, *n;
int px;
int foundlines = 0;
struct font_s *font = curfont;
unsigned int codeflags, codepoint;
while (start < end)
{
// scan the width of the line
for (px=0, l=start ; px <= maxpixelwidth; )
{
if (l >= end)
break;
n = Font_Decode(l, &codeflags, &codepoint);
if (!(codeflags & CON_HIDDEN) && (codepoint == '\n' || codepoint == '\v'))
break;
px = Font_CharEndCoord(font, px, codeflags, codepoint);
l = n;
}
//if we did get to the end
if (px > maxpixelwidth)
{
bt = l;
//backtrack until we find a space
for(;;)
{
n = Font_DecodeReverse(l, start, &codeflags, &codepoint);
if (codepoint > ' ')
l = n;
else
disabled some quake-only teamplay stuff in non-quake builds. GL: r_dynamic -1 is now r_temporalscenecache 1, which makes menu options etc a little friendlier. fixed a serious memory leak. GL: Lightmaps are now uploaded using pbos to reduce cpu stalls (especially with temporalscenecache) and the resulting periodic framerate drops. Requires gl4.4. PM: moved manifest-downloads to the package manager. still needs some proper testing. PM: Fixed bug with downloading updates from every known mirror for that update. PM: Fixed bug with duplicate mirrors... PM: menuqc is now able to query available updates. engine's Draw_TextBox centers the text box more appropriately and easily. SV: added sv_autooffload cvar, when set the map command will automatically create a server in a separate process to reduce the effects of stutter in inefficient ssqc mods. Menu: menu_mods now shares data with getgamedirinfo builtin. MenuQC: Added some extra properties to the getgamedirinfo builtin. MenuQC: Added Menu_RendererRestarted entrypoint. MenuQC: _vid_renderer_opts cvar now has a value that actually reflects the windowing systems in the build, rather than just renderers. CQSC: Added getlocationname builtin. ALSA: device names are now more consistent with other audio drivers. SV: added unsavegame console command, to delete unwanted saved games. SV: hashtable entries are now saved into saved games. SV: reworked player remapping strategy when loading games. Player slots are now directly swapped serverside, not reconnected. SV: resend all csqc entity state when a client signals that it started recording a demo. SV: Added SOLID_BSPTRIGGER as a shapely alternative to the aabb SOLID_TRIGGER. modelindex must still be set for this to work. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5668 fc73d0e0-1445-4013-8a0c-d673dee63da5
2020-04-18 18:23:32 -07:00
{
l = n;
break;
disabled some quake-only teamplay stuff in non-quake builds. GL: r_dynamic -1 is now r_temporalscenecache 1, which makes menu options etc a little friendlier. fixed a serious memory leak. GL: Lightmaps are now uploaded using pbos to reduce cpu stalls (especially with temporalscenecache) and the resulting periodic framerate drops. Requires gl4.4. PM: moved manifest-downloads to the package manager. still needs some proper testing. PM: Fixed bug with downloading updates from every known mirror for that update. PM: Fixed bug with duplicate mirrors... PM: menuqc is now able to query available updates. engine's Draw_TextBox centers the text box more appropriately and easily. SV: added sv_autooffload cvar, when set the map command will automatically create a server in a separate process to reduce the effects of stutter in inefficient ssqc mods. Menu: menu_mods now shares data with getgamedirinfo builtin. MenuQC: Added some extra properties to the getgamedirinfo builtin. MenuQC: Added Menu_RendererRestarted entrypoint. MenuQC: _vid_renderer_opts cvar now has a value that actually reflects the windowing systems in the build, rather than just renderers. CQSC: Added getlocationname builtin. ALSA: device names are now more consistent with other audio drivers. SV: added unsavegame console command, to delete unwanted saved games. SV: hashtable entries are now saved into saved games. SV: reworked player remapping strategy when loading games. Player slots are now directly swapped serverside, not reconnected. SV: resend all csqc entity state when a client signals that it started recording a demo. SV: Added SOLID_BSPTRIGGER as a shapely alternative to the aabb SOLID_TRIGGER. modelindex must still be set for this to work. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5668 fc73d0e0-1445-4013-8a0c-d673dee63da5
2020-04-18 18:23:32 -07:00
}
}
if (l == start && bt>start)
l = Font_DecodeReverse(bt, start, &codeflags, &codepoint);
}
starts[foundlines] = start;
ends[foundlines] = l;
foundlines++;
if (foundlines == maxlines)
break;
disabled some quake-only teamplay stuff in non-quake builds. GL: r_dynamic -1 is now r_temporalscenecache 1, which makes menu options etc a little friendlier. fixed a serious memory leak. GL: Lightmaps are now uploaded using pbos to reduce cpu stalls (especially with temporalscenecache) and the resulting periodic framerate drops. Requires gl4.4. PM: moved manifest-downloads to the package manager. still needs some proper testing. PM: Fixed bug with downloading updates from every known mirror for that update. PM: Fixed bug with duplicate mirrors... PM: menuqc is now able to query available updates. engine's Draw_TextBox centers the text box more appropriately and easily. SV: added sv_autooffload cvar, when set the map command will automatically create a server in a separate process to reduce the effects of stutter in inefficient ssqc mods. Menu: menu_mods now shares data with getgamedirinfo builtin. MenuQC: Added some extra properties to the getgamedirinfo builtin. MenuQC: Added Menu_RendererRestarted entrypoint. MenuQC: _vid_renderer_opts cvar now has a value that actually reflects the windowing systems in the build, rather than just renderers. CQSC: Added getlocationname builtin. ALSA: device names are now more consistent with other audio drivers. SV: added unsavegame console command, to delete unwanted saved games. SV: hashtable entries are now saved into saved games. SV: reworked player remapping strategy when loading games. Player slots are now directly swapped serverside, not reconnected. SV: resend all csqc entity state when a client signals that it started recording a demo. SV: Added SOLID_BSPTRIGGER as a shapely alternative to the aabb SOLID_TRIGGER. modelindex must still be set for this to work. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5668 fc73d0e0-1445-4013-8a0c-d673dee63da5
2020-04-18 18:23:32 -07:00
for (;;)
{
if (l >= end)
break;
disabled some quake-only teamplay stuff in non-quake builds. GL: r_dynamic -1 is now r_temporalscenecache 1, which makes menu options etc a little friendlier. fixed a serious memory leak. GL: Lightmaps are now uploaded using pbos to reduce cpu stalls (especially with temporalscenecache) and the resulting periodic framerate drops. Requires gl4.4. PM: moved manifest-downloads to the package manager. still needs some proper testing. PM: Fixed bug with downloading updates from every known mirror for that update. PM: Fixed bug with duplicate mirrors... PM: menuqc is now able to query available updates. engine's Draw_TextBox centers the text box more appropriately and easily. SV: added sv_autooffload cvar, when set the map command will automatically create a server in a separate process to reduce the effects of stutter in inefficient ssqc mods. Menu: menu_mods now shares data with getgamedirinfo builtin. MenuQC: Added some extra properties to the getgamedirinfo builtin. MenuQC: Added Menu_RendererRestarted entrypoint. MenuQC: _vid_renderer_opts cvar now has a value that actually reflects the windowing systems in the build, rather than just renderers. CQSC: Added getlocationname builtin. ALSA: device names are now more consistent with other audio drivers. SV: added unsavegame console command, to delete unwanted saved games. SV: hashtable entries are now saved into saved games. SV: reworked player remapping strategy when loading games. Player slots are now directly swapped serverside, not reconnected. SV: resend all csqc entity state when a client signals that it started recording a demo. SV: Added SOLID_BSPTRIGGER as a shapely alternative to the aabb SOLID_TRIGGER. modelindex must still be set for this to work. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5668 fc73d0e0-1445-4013-8a0c-d673dee63da5
2020-04-18 18:23:32 -07:00
n = Font_Decode(l, &codeflags, &codepoint);
if (!(codeflags & CON_HIDDEN) && (codepoint != ' '))
break;
l = n;
}
start=l;
if (start == end)
break;
if ((*start&(CON_CHARMASK|CON_HIDDEN)) == '\n' || (*start&(CON_CHARMASK|CON_HIDDEN)) == '\v')
start++; // skip the \n
}
return foundlines;
}
int Font_LineWidth(conchar_t *start, conchar_t *end)
{
//fixme: does this do the right thing with tabs?
int x = 0;
struct font_s *font = curfont;
unsigned int codeflags, codepoint;
for (; start < end; )
{
start = Font_Decode(start, &codeflags, &codepoint);
x = Font_CharEndCoord(font, x, codeflags, codepoint);
}
return x;
}
float Font_LineScaleWidth(conchar_t *start, conchar_t *end)
{
int x = 0;
struct font_s *font = curfont;
unsigned int codeflags, codepoint;
while(start < end)
{
start = Font_Decode(start, &codeflags, &codepoint);
x = Font_CharEndCoord(font, x, codeflags, codepoint);
}
return x * curfont_scale[0];
}
void Font_LineDraw(int x, int y, conchar_t *start, conchar_t *end)
{
int lx = 0;
struct font_s *font = curfont;
unsigned int codeflags, codepoint;
for (; start < end; )
{
start = Font_Decode(start, &codeflags, &codepoint);
Font_DrawChar(x+lx, y, codeflags, codepoint);
lx = Font_CharEndCoord(font, lx, codeflags, codepoint);
}
}
conchar_t *Font_CharAt(int x, conchar_t *start, conchar_t *end)
{
int lx = 0, nx;
struct font_s *font = curfont;
unsigned int codeflags, codepoint;
conchar_t *nc;
for (; start < end; lx = nx, start = nc)
{
nc = Font_Decode(start, &codeflags, &codepoint);
nx = Font_CharEndCoord(font, lx, codeflags, codepoint);
if (x >= lx && x < nx)
return start;
}
return NULL;
}
/*Note: *all* strings after the current one will inherit the same colour, until one changes it explicitly
correct usage of this function thus requires calling this with 1111 before Font_EndString*/
void Font_InvalidateColour(vec4_t newcolour)
{
if (font_foretint[0] == newcolour[0] && font_foretint[1] == newcolour[1] && font_foretint[2] == newcolour[2] && font_foretint[3] == newcolour[3])
return;
if ((font_colourmask & CON_NONCLEARBG) && font_foremesh.numindexes)
{
if (R2D_Flush)
R2D_Flush();
R2D_Flush = Font_Flush;
}
font_colourmask = CON_WHITEMASK;
VectorScale(newcolour, newcolour[3], font_foretint);
font_foretint[3] = newcolour[3];
Vector4Scale(font_foretint, 255, font_forecolour.rgba);
font_backcolour.rgba[3] = 0;
/*Any drawchars that are now drawn will get the forced colour*/
}
//draw a character from the current font at a pixel location.
int Font_DrawChar(int px, int py, unsigned int charflags, unsigned int codepoint)
{
struct charcache_s *c;
float s0, s1;
float t0, t1;
float nextx;
float sx, sy, sw, sh;
int col;
int v;
struct font_s *font = curfont;
#ifdef D3D11QUAKE
float dxbias = 0;//(qrenderer == QR_DIRECT3D11)?0.5:0;
#else
#define dxbias 0
#endif
if (charflags & CON_HIDDEN)
return px;
if (charflags & CON_2NDCHARSETTEXT)
{
if (font->alt)
{
font = font->alt;
// charflags &= ~CON_2NDCHARSETTEXT;
}
else if ((codepoint) >= 0xe000 && (codepoint) <= 0xe0ff)
charflags &= ~CON_2NDCHARSETTEXT; //don't double-dip
}
//crash if there is no current font.
c = Font_GetChar(font, codepoint);
if (!c)
return px;
nextx = px + c->advance;
if (codepoint == '\t')
return Font_TabWidth(px);
if (codepoint == ' ' && (charflags & (CON_RICHFORECOLOUR|CON_NONCLEARBG)) != CON_NONCLEARBG)
return nextx;
/* if (charcode & CON_BLINKTEXT)
{
if (!cl_noblink.ival)
if ((int)(realtime*3) & 1)
return nextx;
}
*/
if (charflags & CON_RICHFORECOLOUR)
{
col = charflags & (CON_2NDCHARSETTEXT|CON_BLINKTEXT|CON_RICHFORECOLOUR|(0xfff<<CON_RICHBSHIFT));
if (col != font_colourmask)
{
vec4_t rgba;
if (font_colourmask & CON_NONCLEARBG)
{
Font_Flush();
R2D_Flush = Font_Flush;
}
font_colourmask = col;
rgba[0] = ((col>>CON_RICHRSHIFT)&0xf)*0x11;
rgba[1] = ((col>>CON_RICHGSHIFT)&0xf)*0x11;
rgba[2] = ((col>>CON_RICHBSHIFT)&0xf)*0x11;
rgba[3] = 255;
font_backcolour.c = 0;
if (charflags & CON_2NDCHARSETTEXT)
{
rgba[0] *= font->alttint[0];
rgba[1] *= font->alttint[1];
rgba[2] *= font->alttint[2];
}
else
{
rgba[0] *= font->tint[0];
rgba[1] *= font->tint[1];
rgba[2] *= font->tint[2];
}
rgba[0] *= font_foretint[0];
rgba[1] *= font_foretint[1];
rgba[2] *= font_foretint[2];
rgba[3] *= font_foretint[3];
if (charflags & CON_BLINKTEXT)
{
float a = (sin(realtime*3)+1)*0.4 + 0.2;
Vector4Scale(rgba, a, rgba);
}
font_forecolour.rgba[0] = min(rgba[0], 255);
font_forecolour.rgba[1] = min(rgba[1], 255);
font_forecolour.rgba[2] = min(rgba[2], 255);
font_forecolour.rgba[3] = min(rgba[3], 255);
}
}
else
{
col = charflags & (CON_2NDCHARSETTEXT|CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA|CON_BLINKTEXT);
if (col != font_colourmask)
{
vec4_t rgba;
if ((col ^ font_colourmask) & CON_NONCLEARBG)
{
Font_Flush();
R2D_Flush = Font_Flush;
}
font_colourmask = col;
col = (charflags&CON_FGMASK)>>CON_FGSHIFT;
if(charflags & CON_HALFALPHA)
{
rgba[0] = consolecolours[col].fr*0x7f;
rgba[1] = consolecolours[col].fg*0x7f;
rgba[2] = consolecolours[col].fb*0x7f;
rgba[3] = 0x7f;
}
else
{
rgba[0] = consolecolours[col].fr*255;
rgba[1] = consolecolours[col].fg*255;
rgba[2] = consolecolours[col].fb*255;
rgba[3] = 255;
}
if (vid.flags&VID_SRGBAWARE)
{
rgba[0] = M_SRGBToLinear(rgba[0], 255);
rgba[1] = M_SRGBToLinear(rgba[1], 255);
rgba[2] = M_SRGBToLinear(rgba[2], 255);
}
col = (charflags&CON_BGMASK)>>CON_BGSHIFT;
if (charflags & CON_NONCLEARBG)
{
font_backcolour.rgba[0] = consolecolours[col].fr*255;
font_backcolour.rgba[1] = consolecolours[col].fg*255;
font_backcolour.rgba[2] = consolecolours[col].fb*255;
font_backcolour.rgba[3] = (charflags & CON_NONCLEARBG)?0xc0:0;
}
else
font_backcolour.c = 0;
if (charflags & CON_2NDCHARSETTEXT)
{
rgba[0] *= font->alttint[0];
rgba[1] *= font->alttint[1];
rgba[2] *= font->alttint[2];
}
else
{
rgba[0] *= font->tint[0];
rgba[1] *= font->tint[1];
rgba[2] *= font->tint[2];
}
rgba[0] *= font_foretint[0];
rgba[1] *= font_foretint[1];
rgba[2] *= font_foretint[2];
rgba[3] *= font_foretint[3];
if (charflags & CON_BLINKTEXT)
{
float a = (sin(realtime*3)+1)*0.4 + 0.2;
Vector4Scale(rgba, a, rgba);
}
font_forecolour.rgba[0] = min(rgba[0], 255);
font_forecolour.rgba[1] = min(rgba[1], 255);
font_forecolour.rgba[2] = min(rgba[2], 255);
font_forecolour.rgba[3] = min(rgba[3], 255);
}
}
s0 = (float)c->bmx/PLANEWIDTH;
t0 = (float)c->bmy/PLANEWIDTH;
s1 = (float)(c->bmx+c->bmw)/PLANEWIDTH;
t1 = (float)(c->bmy+c->bmh)/PLANEWIDTH;
switch(c->texplane)
{
case TRACKERIMAGE:
s0 = t0 = 0;
s1 = t1 = 1;
sx = ((px+c->left + dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top + dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
sw = (c->advance*vid.width) / (float)vid.rotpixelwidth;
sh = (font->charheight*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(fontplanes.trackerimage);
break;
case DEFAULTPLANE:
sx = ((px+c->left + dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top + dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((c->advance)*vid.width) / (float)vid.rotpixelwidth;
sh = ((font->charheight)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(fontplanes.defaultfont);
break;
case BITMAPPLANE:
sx = ((px+c->left + dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top + dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((c->advance)*vid.width) / (float)vid.rotpixelwidth;
sh = ((font->charheight)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(font->singletexture);
break;
case SINGLEPLANE:
sx = ((px+c->left + dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top + dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((c->bmw)*vid.width) / (float)vid.rotpixelwidth;
sh = ((c->bmh)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(font->singletexture);
break;
default:
sx = ((px+c->left + dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top + dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((c->bmw)*vid.width) / (float)vid.rotpixelwidth;
sh = ((c->bmh)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(fontplanes.texnum[c->texplane]);
break;
}
font_texcoord[v+0][0] = s0;
font_texcoord[v+0][1] = t0;
font_texcoord[v+1][0] = s1;
font_texcoord[v+1][1] = t0;
font_texcoord[v+2][0] = s1;
font_texcoord[v+2][1] = t1;
font_texcoord[v+3][0] = s0;
font_texcoord[v+3][1] = t1;
font_coord[v+0][0] = sx;
font_coord[v+0][1] = sy;
font_coord[v+1][0] = sx+sw;
font_coord[v+1][1] = sy;
font_coord[v+2][0] = sx+sw;
font_coord[v+2][1] = sy+sh;
font_coord[v+3][0] = sx;
font_coord[v+3][1] = sy+sh;
if (c->flags&CHARF_FORCEWHITE)
{
font_forecoloura[v+0].c =
font_forecoloura[v+1].c =
font_forecoloura[v+2].c =
font_forecoloura[v+3].c = 0xffffffff;
}
else
{
font_forecoloura[v+0] =
font_forecoloura[v+1] =
font_forecoloura[v+2] =
font_forecoloura[v+3] = font_forecolour;
}
if (font_colourmask & CON_NONCLEARBG)
{
sx = ((px+dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
sw = sx + ((c->advance)*vid.width) / (float)vid.rotpixelwidth;
sh = sy + ((font->charheight)*vid.height) / (float)vid.rotpixelheight;
//don't care about texcoords
font_backcoord[v+0][0] = sx;
font_backcoord[v+0][1] = sy;
font_backcoord[v+1][0] = sw;
font_backcoord[v+1][1] = sy;
font_backcoord[v+2][0] = sw;
font_backcoord[v+2][1] = sh;
font_backcoord[v+3][0] = sx;
font_backcoord[v+3][1] = sh;
font_backcoloura[v+0] = font_backcolour;
font_backcoloura[v+1] = font_backcolour;
font_backcoloura[v+2] = font_backcolour;
font_backcoloura[v+3] = font_backcolour;
}
return nextx;
}
/*there is no sane way to make this pixel-correct*/
float Font_DrawScaleChar(float px, float py, unsigned int charflags, unsigned int codepoint)
{
struct charcache_s *c;
float s0, s1;
float t0, t1;
float nextx;
float sx, sy, sw, sh;
int col;
int v;
struct font_s *font = curfont;
float cw, ch;
#ifdef D3D11QUAKE
float dxbias = 0;//(qrenderer == QR_DIRECT3D11)?0.5:0;
#else
#define dxbias 0
#endif
// if (!curfont_scaled)
// return Font_DrawChar(px, py, charcode);
if (charflags & CON_2NDCHARSETTEXT)
{
if (font->alt)
{
font = font->alt;
charflags &= ~CON_2NDCHARSETTEXT;
}
else if (codepoint >= 0xe000 && codepoint <= 0xe0ff)
charflags &= ~CON_2NDCHARSETTEXT; //don't double-dip
}
cw = curfont_scale[0];
ch = curfont_scale[1];
//crash if there is no current font.
c = Font_GetChar(font, codepoint);
if (!c)
return px;
nextx = px + c->advance*cw;
if (codepoint == ' ' && (charflags & (CON_RICHFORECOLOUR|CON_NONCLEARBG)) != CON_NONCLEARBG)
return nextx;
if (charflags & CON_BLINKTEXT)
{
if (!cl_noblink.ival)
if ((int)(realtime*3) & 1)
return nextx;
}
if (charflags & CON_RICHFORECOLOUR)
{
col = charflags & (CON_2NDCHARSETTEXT|CON_RICHFORECOLOUR|(0xfff<<CON_RICHBSHIFT));
if (col != font_colourmask)
{
vec4_t rgba;
if (font_backcolour.rgba[3])
{
Font_Flush();
R2D_Flush = Font_Flush;
}
font_colourmask = col;
rgba[0] = ((col>>CON_RICHRSHIFT)&0xf)*0x11;
rgba[1] = ((col>>CON_RICHGSHIFT)&0xf)*0x11;
rgba[2] = ((col>>CON_RICHBSHIFT)&0xf)*0x11;
rgba[3] = 255;
font_backcolour.c = 0;
if (charflags & CON_2NDCHARSETTEXT)
{
rgba[0] *= font->alttint[0];
rgba[1] *= font->alttint[1];
rgba[2] *= font->alttint[2];
}
else
{
rgba[0] *= font->tint[0];
rgba[1] *= font->tint[1];
rgba[2] *= font->tint[2];
}
rgba[0] *= font_foretint[0];
rgba[1] *= font_foretint[1];
rgba[2] *= font_foretint[2];
rgba[3] *= font_foretint[3];
font_forecolour.rgba[0] = min(rgba[0], 255);
font_forecolour.rgba[1] = min(rgba[1], 255);
font_forecolour.rgba[2] = min(rgba[2], 255);
font_forecolour.rgba[3] = min(rgba[3], 255);
}
}
else
{
col = charflags & (CON_2NDCHARSETTEXT|CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA);
if (col != font_colourmask)
{
vec4_t rgba;
if (font_backcolour.rgba[3] != ((charflags & CON_NONCLEARBG)?127:0))
{
Font_Flush();
R2D_Flush = Font_Flush;
}
font_colourmask = col;
col = (charflags&CON_FGMASK)>>CON_FGSHIFT;
if (charflags & CON_HALFALPHA)
{
rgba[0] = consolecolours[col].fr*0x7f;
rgba[1] = consolecolours[col].fg*0x7f;
rgba[2] = consolecolours[col].fb*0x7f;
rgba[3] = 0x7f;
}
else
{
rgba[0] = consolecolours[col].fr*255;
rgba[1] = consolecolours[col].fg*255;
rgba[2] = consolecolours[col].fb*255;
rgba[3] = 255;
}
col = (charflags&CON_BGMASK)>>CON_BGSHIFT;
if (charflags & CON_NONCLEARBG)
{
font_backcolour.rgba[0] = consolecolours[col].fr*0xc0;
font_backcolour.rgba[1] = consolecolours[col].fg*0xc0;
font_backcolour.rgba[2] = consolecolours[col].fb*0xc0;
font_backcolour.rgba[3] = 0xc0;
}
else
font_backcolour.c = 0;
if (charflags & CON_2NDCHARSETTEXT)
{
rgba[0] *= font->alttint[0];
rgba[1] *= font->alttint[1];
rgba[2] *= font->alttint[2];
}
else
{
rgba[0] *= font->tint[0];
rgba[1] *= font->tint[1];
rgba[2] *= font->tint[2];
}
rgba[0] *= font_foretint[0];
rgba[1] *= font_foretint[1];
rgba[2] *= font_foretint[2];
rgba[3] *= font_foretint[3];
font_forecolour.rgba[0] = min(rgba[0], 255);
font_forecolour.rgba[1] = min(rgba[1], 255);
font_forecolour.rgba[2] = min(rgba[2], 255);
font_forecolour.rgba[3] = min(rgba[3], 255);
}
}
s0 = (float)c->bmx/PLANEWIDTH;
t0 = (float)c->bmy/PLANEWIDTH;
s1 = (float)(c->bmx+c->bmw)/PLANEWIDTH;
t1 = (float)(c->bmy+c->bmh)/PLANEWIDTH;
if (c->texplane >= DEFAULTPLANE)
{
sx = ((px+c->left*cw));
sy = ((py+c->top*ch));
sw = ((font->charheight*cw));
sh = ((font->charheight*ch));
if (c->texplane == DEFAULTPLANE)
v = Font_BeginChar(fontplanes.defaultfont);
else
v = Font_BeginChar(font->singletexture);
}
else
{
sx = (px+c->left*cw);
sy = (py+c->top*ch);
sw = ((c->bmw*cw));
sh = ((c->bmh*ch));
v = Font_BeginChar(fontplanes.texnum[c->texplane]);
}
sx += dxbias;
sy += dxbias;
sx *= (int)vid.width / (float)vid.rotpixelwidth;
sy *= (int)vid.height / (float)vid.rotpixelheight;
sw *= (int)vid.width / (float)vid.rotpixelwidth;
sh *= (int)vid.height / (float)vid.rotpixelheight;
font_texcoord[v+0][0] = s0;
font_texcoord[v+0][1] = t0;
font_texcoord[v+1][0] = s1;
font_texcoord[v+1][1] = t0;
font_texcoord[v+2][0] = s1;
font_texcoord[v+2][1] = t1;
font_texcoord[v+3][0] = s0;
font_texcoord[v+3][1] = t1;
font_coord[v+0][0] = sx;
font_coord[v+0][1] = sy;
font_coord[v+1][0] = sx+sw;
font_coord[v+1][1] = sy;
font_coord[v+2][0] = sx+sw;
font_coord[v+2][1] = sy+sh;
font_coord[v+3][0] = sx;
font_coord[v+3][1] = sy+sh;
font_forecoloura[v+0] = font_forecolour;
font_forecoloura[v+1] = font_forecolour;
font_forecoloura[v+2] = font_forecolour;
font_forecoloura[v+3] = font_forecolour;
if (font_colourmask & CON_NONCLEARBG)
{
sx = px + dxbias;
sy = py + dxbias;
sw = sx + c->advance;
sh = sy + font->charheight;
sx *= (int)vid.width / (float)vid.rotpixelwidth;
sy *= (int)vid.height / (float)vid.rotpixelheight;
sw *= (int)vid.width / (float)vid.rotpixelwidth;
sh *= (int)vid.height / (float)vid.rotpixelheight;
//don't care about texcoords
font_backcoord[v+0][0] = sx;
font_backcoord[v+0][1] = sy;
font_backcoord[v+1][0] = sw;
font_backcoord[v+1][1] = sy;
font_backcoord[v+2][0] = sw;
font_backcoord[v+2][1] = sh;
font_backcoord[v+3][0] = sx;
font_backcoord[v+3][1] = sh;
font_backcoloura[v+0] = font_backcolour;
font_backcoloura[v+1] = font_backcolour;
font_backcoloura[v+2] = font_backcolour;
font_backcoloura[v+3] = font_backcolour;
}
return nextx;
}
#endif //!SERVERONLY