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.
Header¶
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;
}