Results 1 to 3 of 3
  1. #1
    Neokill's Avatar
    Join Date
    Dec 2011
    Gender
    male
    Posts
    17
    Reputation
    30
    Thanks
    16

    Measure Engine Strings.

    Wrong Thread Area

    So some people were wondering how to measure engine strings, so today I have a treat for those people. When writing up my new sdk I decided I was going to write my own wrappers/helper functions to manually draw strings, functions that would act much in the manner of the Q3 wrapper functions, and that's what I get to share with you..

    So to begin, we're going to need some structures and info on the engine fonts.

    #define GLYPH_START 0
    #define GLYPH_END 255
    #define GLYPH_CHARSTART 32
    #define GLYPH_CHAREND 127
    #define GLYPHS_PER_FONT GLYPH_END - GLYPH_START + 1
    typedef struct {
    char number; // glyph number
    char top; // top of glyph in buffer
    char bottom; // bottom of glyph in buffer
    char pitch; // width for copying
    char xSkip; // x adjustment
    char imageWidth; // width of actual image
    char imageHeight; // height of actual image
    float s; // x offset in image where glyph starts
    float t; // y offset in image where glyph starts
    float s2;
    float t2;
    } glyphInfo_t;

    typedef void *fontInfo_t;
    Very similar to the Q3 structure, the glyphInfo_t is going to give us almost all of our measurement information.

    Next you'll need this function to get the glyphInfo_t[] from the fontInfo_t* you get from R_RegisterFont(...)


    // this is terrible, terrible stuff.. but brute-forcing is the 'easy' way i guess.
    // if you have a better solution, let me know.. because i want to punch myself in the face.
    static __inline glyphInfo_t *H_GetGlyphInfo( fontInfo_t *font ) {
    const int size = sizeof(glyphInfo_t);
    int i, f;

    f = *((int*)font);
    if (font == 0 || f == 0) {
    return 0;
    }

    for (i = 0; i < size * GLYPHS_PER_FONT; i++) {
    if (*(char*)(f+i) == GLYPH_CHARSTART && *(char*)(f+i+size) == GLYPH_CHARSTART+1) {
    return (glyphInfo_t*)(f+i);
    }
    }
    return 0;
    }
    This horrible thing is what I made the get the start of the glyphInfo_t[] ( As I didn't feel like spending a lot of time reversing the fontInfo_t,
    which is why it's a void* ), if you have more information on the fontInfo_t struct and/or a better way to get the glyphInfo, please let me know .

    Next up are the helper functions to measure and draw our strings..


    float H_GetTextWidth( const char *text, fontInfo_t *font, float scale )
    {
    glyphInfo_t *glyphs;
    int count, len;
    float w, t;

    w = t = count = 0;
    glyphs = H_GetGlyphInfo(font);
    if (text && glyphs) {
    const char *s = text;

    len = strlen(text);
    while (s && *s && count < len) {
    if (Q_IsColorString(s)) {
    s+=2, count+=2;
    continue;
    } else if (*s == '\n') {
    w = 0;
    } else if (*s >= GLYPH_CHARSTART && *s < GLYPH_CHAREND) {
    w += glyphs[*s - GLYPH_CHARSTART].xSkip;
    t = max(t, w);
    }

    s++;
    count++;
    }
    }

    return t * scale;
    }

    float H_GetTextHeight( const char *text, fontInfo_t *font, float scale )
    {
    glyphInfo_t *glyphs;
    int count, len;
    float h, t;

    h = t = count = 0;
    glyphs = H_GetGlyphInfo(font);
    if (text && glyphs) {
    const char *s = text;

    len = strlen(text);
    while (s && *s && count < len) {
    if (Q_IsColorString(s)) {
    s+=2, count+=2;
    continue;
    } else if (*s == '\n') {
    t += h; // add our height to our total height
    h = 0; // reset our height
    }
    else if (*s >= GLYPH_CHARSTART && *s < GLYPH_CHAREND) {
    h = max(h, glyphs[*s - GLYPH_CHARSTART].imageHeight);
    }

    s++;
    count++;
    }
    t += h; // add our last line height
    }

    return t * scale;
    }

    float H_GetLineWidth( const char *text, fontInfo_t *font, float scale )
    {
    glyphInfo_t *glyphs;
    int count, len;
    float w;

    w = count = 0;
    glyphs = H_GetGlyphInfo(font);
    if (text && glyphs) {
    const char *s = text;

    len = strlen(text);
    while (s && *s && count < len) {
    if (Q_IsColorString(s)) {
    s+=2, count+=2;
    continue;
    } else if (*s == '\n') {
    break;
    } else if (*s >= GLYPH_CHARSTART && *s < GLYPH_CHAREND) {
    w += glyphs[*s - GLYPH_CHARSTART].xSkip;
    }

    s++;
    count++;
    }
    }

    return w * scale;
    }

    float H_GetLineHeight( const char *text, fontInfo_t *font, float scale )
    {
    glyphInfo_t *glyphs;
    int count, len;
    float h;

    h = count = 0;
    glyphs = H_GetGlyphInfo(font);
    if (text && glyphs) {
    const char *s = text;

    len = strlen(text);
    while (s && *s && count < len) {
    if (Q_IsColorString(s)) {
    s+=2, count+=2;
    continue;
    } else if (*s == '\n') {
    break;
    } else if (*s >= GLYPH_CHARSTART && *s < GLYPH_CHAREND) {
    h = max(h, glyphs[*s - GLYPH_CHARSTART].imageHeight);
    }

    s++;
    count++;
    }
    }

    return h * scale;
    }

    void H_DrawString( const char *text, fontInfo_t *font, float x, float y, float scale, vec4_t color )
    {
    glyphInfo_t *glyphs, *glyph;
    float h, xadj, yadj;
    vec4_t newColor;
    int len, count;

    glyphs = H_GetGlyphInfo(font);
    if (text && glyphs) {
    char *s = (char*)text, c[2];

    len = strlen(text);
    c[1] = h = xadj = yadj = count = 0;
    memcpy(&newColor[0], &color[0], sizeof(vec4_t));
    while (s && *s && count < len) {
    glyph = &glyphs[*s - GLYPH_CHARSTART];

    if (h == 0) {
    h = H_GetLineHeight(s, font, scale);
    }

    if (Q_IsColorString(s)) {
    memcpy(&newColor[0], &g_color_table[ColorIndex(*(s+1))][0], sizeof(vec4_t));
    s+=2, count+=2;
    continue;
    } else if (*s == '\n') {
    y += h;
    h = xadj = 0;
    } else {
    c[0] = *s; // this makes me sad, need to find DrawChar stuff
    yadj = glyph->top + (h - (glyph->imageHeight * scale));
    CG_DrawString(c, 0x7FFFFFFF, font, x + xadj, y + yadj - (glyph->pitch * scale), scale, scale, newColor, 0);
    xadj += glyph->xSkip * scale;
    }
    s++;
    count++;
    }
    }
    }
    A couple notes on these functions..

    H_GetTextWidth: Gets the width of a string of text ( returns the widest line of a multi-line string ), string must be null terminated, multi-line supported.
    H_GetTextHeight: Gets the height of a string of text, string must be null terminated, multi-line supported, relies on how H_DrawString pads multi-line strings.
    H_GetLineWidth: Gets the width of the first line of a string of text, string must be multi-line or null terminated.
    H_GetLineHeight: Gets the height of the first line of a string of text, string must be multi-line or null terminated.
    H_DrawString: Manually draws a string of characters, string must be null terminated, multi-line and inline-coloring supported.

    Now when drawing a measured string it is vital you use the helper function H_DrawString, this is because it pads multi-line strings by the height of the previous string; The default CG_DrawString function handles multi-line padding differently, I did this because the default padding is not worth my time completely reversing and is annoying at best ( in my opinion ).

    I hope this is helpful to at least one person, and it should work on other Call of Duty games just fine also..
    As always, have fun!
    Last edited by Neokill; 12-24-2011 at 05:14 PM.

  2. #2
    lmaobox's Avatar
    Join Date
    Nov 2011
    Gender
    male
    Posts
    319
    Reputation
    38
    Thanks
    1,126
    Wrong section, not related to private servers at all.
    get good.

  3. #3
    ☬Ξη†τσρîζ Ζσ♍βîε δτσηε☬
    Former Staff
    Premium Member
    Lehsyrus's Avatar
    Join Date
    Aug 2009
    Gender
    male
    Location
    Jersey
    Posts
    10,899
    Reputation
    1281
    Thanks
    3,064
    Quote Originally Posted by lmaobox View Post
    Wrong section, not related to private servers at all.
    This guy gives out a shit ton of information and that's all you have to say? Asshole.

    Thanks for the information Neokill.

Similar Threads

  1. [Release] Engine DUMP [TEXT STRINGS]
    By harpreet10 in forum Combat Arms Hack Coding / Programming / Source Code
    Replies: 5
    Last Post: 05-14-2011, 08:49 AM
  2. [Tutorial] Cheat Engine - Weapons
    By darkshinez in forum WarRock - International Hacks
    Replies: 49
    Last Post: 07-29-2006, 02:55 PM
  3. Cheat Engine Values
    By Bull3t in forum WarRock - International Hacks
    Replies: 0
    Last Post: 05-31-2006, 05:10 AM
  4. Replies: 6
    Last Post: 05-21-2006, 10:09 PM
  5. Plz I Want Maple Global Hacks And Where Do I Get Game Engine 2 Make The Hacks Work???
    By mattinthehat in forum MapleStory Hacks, Cheats & Trainers
    Replies: 3
    Last Post: 01-15-2006, 07:12 PM