Skip to content

NVEC

Applies to: GT5, GT6 · Extension: .vec · Endian: Big

NVEC is a font format converted from .ttf, friendly for the PS3 and rendered through SPUs. It uses UTF-16.

Note

NVEC files are also present in PS4 GTs, but they are not read nor can be used.


Size: 0x20

Field Offset Type Description
NVEC 0x00 Int Magic, (Not enforced, can be different)
Unknown 0x04 byte Unknown byte. It is not read.
Unknown 0x05 byte Unknown byte. It is not read.
Unknown 0x06 byte Unknown byte. It is not read.
Unknown 0x07 byte Unknown byte. It is not read.
Character Count 0x08 short Number of UTF-16 characters this font defines.
Unknown 0x0A short Unknown byte. It is not read.
Unknown 0x0C short Unknown byte. It is not read.
Empty 0x0E short N/A.
UTF-16 Char Table Pointer 0x10 wchar_t* Offset to the table of UTF-16 characters.
Glyph Info Table Pointer 0x14 GlyphInfo* Offset to the table of glyph infos.
Glyph Data Pointer 0x18 byte* Offset to the start of the encoded glyph data.
Unknown CVS Pointer 0x1C byte* Unknown. This is its own file with the .cvs extension in older GT5 builds. Always 0x2284 in size.

Glyph Info

Size: 0x14

Field Offset Type Description
Char 0x00 wchar_t UTF-16 character for this glyph.
Flags 0x02 ushort Appears unused.
Position Bits 0x04 uint Offset bits. 0-10: Unknown, 11-21: XOffset, 22-31: YOffset.
Data Length 0x08 int Length of the glyph data.
Width/Height Bits 0x0C int 0-11: Width, 12-23: Height Offset, 24-31: Stride count (0x10 each)
Height Offset 0x0E short Height offset of the glyph.
Data Offset 0x10 int Data offset. It is relative to the data pointer in the header.

Glyph Data

It is bit-packed, here is a sample on how to read it (snippet from PDTools.Files)

 public static GlyphShapes Read(BinaryStream bs, int size)
{
    var data = new GlyphShapes();
    byte[] bytes = bs.ReadBytes(size);
    BitStream bitStream = new BitStream(BitStreamMode.Read, bytes);

    ulong xMinBits = bitStream.ReadBits(12);
    data.XMin = BitValueToFloat((long)xMinBits, 12);

    ulong yMinBits = bitStream.ReadBits(12);
    data.YMin = BitValueToFloat((long)yMinBits, 12);

    while (true)
    {
        int flags = (int)bitStream.ReadBits(6);
        if (flags == 0)
            break;

        if ((flags & 0x20) != 0)
        {
            int elemSize = (flags & 0x0F) + 2;
            if ((flags & 0x10) != 0)
            {
                bool isPoint = bitStream.ReadBoolBit();
                if (isPoint)
                {
                    GlyphPoint point = new GlyphPoint();

                    int x = (int)bitStream.ReadBits(elemSize);
                    point.X = BitValueToFloat(x, elemSize);

                    int y = (int)bitStream.ReadBits(elemSize);
                    point.Y = BitValueToFloat(y, elemSize);

                    data.Data.Add(point);
                }
                else
                {
                    GlyphLine line = new GlyphLine();

                    line.Axis = bitStream.ReadBoolBit() ? GlyphAxis.Y : GlyphAxis.X;
                    int dist = (int)bitStream.ReadBits(elemSize);
                    line.Distance = BitValueToFloat(dist, elemSize);

                    data.Data.Add(line);

                }
            }
            else
            {
                GlyphQuadraticBezierCurve curve = new GlyphQuadraticBezierCurve();
                int x1 = (int)bitStream.ReadBits(elemSize);
                curve.P1_DistX = BitValueToFloat(x1, elemSize);

                int y1 = (int)bitStream.ReadBits(elemSize);
                curve.P1_DistY = BitValueToFloat(y1, elemSize);

                int x2 = (int)bitStream.ReadBits(elemSize);
                curve.P2_DistX = BitValueToFloat(x2, elemSize);

                int y2 = (int)bitStream.ReadBits(elemSize);
                curve.P2_DistY = BitValueToFloat(y2, elemSize);

                data.Data.Add(curve);
            }
        }
        else if ((flags & 0x01) != 0)
        {
            GlyphStartPoint startPoint = new GlyphStartPoint();

            int elemSize = (int)bitStream.ReadBits(5);
            int x = (int)bitStream.ReadBits(elemSize);
            startPoint.X = BitValueToFloat(x, elemSize);

            int y = (int)bitStream.ReadBits(elemSize);
            startPoint.Y = BitValueToFloat(y, elemSize);

            if ((flags & 0x02) != 0)
                startPoint.Unk = bitStream.ReadBoolBit();

            if ((flags & 0x04) != 0)
                startPoint.Unk2 = bitStream.ReadBoolBit();

            data.Data.Add(startPoint);
        }
    }

    return data;

}