Skip to content
Permalink
Browse files

add animated inlined images for console text

Images are stored in packages/misc/igraph/*.png and loaded during game
start. Filenames consist of the image shorthand (mnemonic) and optional
frame times, separated by "_". Keep in mind, media file names may only
contain letters, digits and "_-.()".

All texts displayed in the game console are scanned for mnemonics prefixed
with ":". All found matches are replaced by the image.

The images are displayed as squares with width and height the same as the
regular font height. To create animations, put several square images side
by side into the file. For example, a 128x32 image is interpreted as four
frames. Frame duration is encoded in the filename, so, for example the file
"nop_1000_200_100.png" shows the first frame for 1000 milliseconds, the
second frame for 200 msec and the third (as the rest) for 100 msec.

Igraphs "1" to "9" are hardcoded and can be manually encoded in menu texts.
Use the new escape code "\i" plus the number of the image: "\i\1".."\i\9".
Other images can be used in menus as well, but the codes have to be fetched
by getigraph.

new commands:

  updateigraphs

    Checks for new files in packages/misc/igraph. Only necessary, if new
    files are added during the game - for example, by mod package download.

  getigraph <mnemonic>

    Returns an encoded string to display an image outside the console, or
    an empty string, if the mnemonic was not found.

new parameters:

  igraphsize 80..300 (default 120)

    scales the images (in percent)

  igraphsizehardcoded 80..160 (default 106)

    scales the hardcoded images "1".."9" (in percent)

  igraphanimate 0..1 (default 1)

    if 0, only the first frame of every image is displayed

  igraphdefaultframetime 5..2000 (default 200)

    used for images with multiple frames but no frame duration specified
    in the filename

  hideigraphs 0..1 (default 0)

    if 1, no new images will be shown in the console

DOCREF updateigraphs getigraph igraphsizehardcoded
DOCREF igraphsize igraphanimate igraphdefaultframetime hideigraphs
  • Loading branch information...
ac-stef committed May 28, 2017
1 parent 4e77b91 commit 5e20a2343b315855d94b006391fab5c17016d1aa
@@ -789,7 +789,7 @@ menuinit [
]
if (|| (strlen $activezips) (strlen $inactivezips)) [ ] [ menuitem "--- no mod packages available ---" -1 ]
if (strlen $activezips) [ menuitem "\f3Deactivate all mod packages" zipmodclear ]
menuitem "\f3Refresh textures (has no effect on already loaded models)" resetgl
menuitem "\f3Refresh textures (has no effect on already loaded models)" [ resetgl ; updateigraphs ]
pop activezips inactivezips ecurmenu
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,6 @@
igraphs "1" to "9" are hardcoded to be used in menus:

1: menu icon (indicating a sub-menu)
2: not assigned yet
3: ellipsis (three dots, indicating a sub-menu)
4..9: not assigned yet
@@ -763,7 +763,6 @@ void resetcomplete()
bool nickcomplete(char *s, bool reversedirection)
{
static int nickcompleteidx;
if(!players.length()) return false;

char *cp = strrchr(s, ' '); // find last space
cp = cp ? cp + 1 : s;
@@ -775,13 +774,18 @@ bool nickcomplete(char *s, bool reversedirection)
}

vector<int> matchingnames;
vector<const char *> matchingigs;
loopv(players) if(players[i] && !strncasecmp(players[i]->name, cp, nickcompletesize)) matchingnames.add(i); // find all matching player names first
if(matchingnames.length())
if(nickcompletesize > 0 && *cp == ':') enumigraphs(matchingigs, cp + 1, nickcompletesize - 1); // find all matching igraphs
int totalmatches = matchingnames.length() + matchingigs.length();
if(totalmatches)
{
nickcompleteidx += reversedirection ? matchingnames.length() - 1 : 1;
nickcompleteidx %= matchingnames.length();
const char *fillin = players[matchingnames[nickcompleteidx]]->name;
nickcompleteidx += reversedirection ? totalmatches - 1 : 1;
nickcompleteidx %= totalmatches;
bool isig = nickcompleteidx >= matchingnames.length();
const char *fillin = isig ? matchingigs[nickcompleteidx - matchingnames.length()] : players[matchingnames[nickcompleteidx]]->name;
if(*fillin == '/' && cp == s) *cp++ = ' ';
if(isig) cp++;
*cp = '\0';
concatstring(s, fillin);
return true;
@@ -12,7 +12,8 @@ template<class LINE> struct consolebuffer
LINE cl;
cl.line = conlines.length()>maxlines ? conlines.pop().line : newstringbuf(""); // constrain the buffer size
cl.millis = millis; // for how long to keep line on screen
copystring(cl.line, sf);
extern void encodeigraphs(char *d, const char *s, int len);
encodeigraphs(cl.line, sf, MAXSTRLEN);
return conlines.insert(0, cl);
}

@@ -152,9 +152,10 @@ void writeinitcfg()
f->printf("stencilbits %d\n", stencilbits);
f->printf("fsaa %d\n", fsaa);
f->printf("vsync %d\n", vsync);
extern int audio, soundchannels;
extern int audio, soundchannels, igraphdefaultframetime;
f->printf("audio %d\n", audio > 0 ? 1 : 0);
f->printf("soundchannels %d\n", soundchannels);
f->printf("igraphdefaultframetime %d\n", igraphdefaultframetime);
if(lang && *lang) f->printf("lang %s\n", lang);
extern void writezipmodconfig(stream *f);
writezipmodconfig(f);
@@ -1171,6 +1172,7 @@ int main(int argc, char **argv)
if(!notexture) fatal("could not find core textures (hint: run AssaultCube from the parent of the bin directory)");

initlog("console");
updateigraphs();
autostartscripts("_veryfirst_");
// Main font file, all other font files execute from here.
if(!execfile("config/font.cfg")) fatal("cannot find default font definitions");
@@ -287,6 +287,11 @@ char *filtertext(char *dst, const char *src, int flags, int len)
}
pass = true;
}
if(c == '\1')
{ // always filter encoded igraphs
if(src[1]) ++src;
continue;
}
if(mapname && !isalnum(c) && !strchr("_-./\\", c)) continue;
if(isspace(c))
{
@@ -326,6 +331,7 @@ void filterrichtext(char *dst, const char *src, int len)
{
case '\0': --src; continue;
case 'f': c = '\f'; break;
case 'i': c = '\1'; break;
case 'a': c = '\a'; break;
case 't': c = '\t'; break;
case 'n': c = '\n'; break;
@@ -448,6 +448,19 @@ extern void scaletmu(int n, int rgbscale, int alphascale = 0);
extern void colortmu(int n, float r = 0, float g = 0, float b = 0, float a = 0);
extern void setuptmu(int n, const char *rgbfunc = NULL, const char *alphafunc = NULL);

struct igraph
{
const char *fname;
struct Texture *tex;
vector<int> frames;
int used;
};
extern void updateigraphs();
extern igraph *getusedigraph(int i);
extern int getigraph(const char *mnem);
extern void encodeigraphs(char *d, const char *s, int len);
extern void enumigraphs(vector<const char *> &igs, const char *s, int len);

// renderhud
enum
{

0 comments on commit 5e20a23

Please sign in to comment.
You can’t perform that action at this time.