Samson wrote:Based on
yagcd the font is a compressed I4 texture. And looking at libogc/system.c I'd say SYS_InitFont decompresses the font and fills in the font header with the information how to render text.
SYS_GetFontTexture seems to just return the texture address and glyph position, if you want to render it using the existing texture, SYS_GetFontTexel copies the glyph into your own texture.
Trying to use this is on my TODO list, but so far I didn't have the time.
Let me know if you get anything working.
By the way, would it be worth overriding the font encoding instead of selecting it automatically? Both the PAL and NTSC firmware seem to have the font at the same position, so an application could use whatever encoding it wants.
seems like I don't get it working but at least this lead me trying to figure how the stuff was working
now there are some things confusing me, here is what I figured so far (would have been easier if the code had been commented btw
) :
1/ beside the wellknown YaY0 font compression, the original texture data is also in compressed format: 1 byte represents 4 pixels, so each pixel is coded as a 2-bytes value (0-3) and represent an index into a 4-entry color lookup table stored at the end of the font header (c0,c1,c2,c3 in libogc definition). Each LUT entry is one byte, with a 4bits color intensity value most probably duplicated in LSB and MSB...
2/ the compressed texture data is "expanded" to a I4 texture (1 byte = 2 pixels, each 4-bits nibble representing pixel color intensity) by SYS_InitFont and the original compresssed data is
overwritten by I4 texture data:
Code: Select all
sys_fontimage = (u8*)((((u32)unpacked_data+sys_fontdata->sheet_image)+31)&~31);
__expand_font(unpacked_data+sys_fontdata->sheet_image,sys_fontimage);
The expand function starts from the end of the texture data so there is no mistake or unexpected overwrites
3/ SYS_GetFontTexture returns a pointer to the decompressed texture data (I4 format) and horizontal/vertical offsets (in pixels) to the cell containing the character. It's up to you to read the texture data correctly (all texture are generally stored in 32 bytes block, which means 8x8 texels blocks are stored consecutively in memory)
Code: Select all
*image = [b]sys_fontimage[/b]+(sys_fontdata->sheet_size*sheets);
4/ SYS_GetFontTexel, on the contrary, is trying to
expand compressed texture data "on the fly", and fill the texture data pointer you passed in parameter as a I4 texture. Maybe I'm missing something but this seems problematic: since the compressed texture data has already been expanded AND overwriten in SYS_InitFont, you are "expanding" something that is already in I4 format, which is wrong.
Code: Select all
img_start = (u8*)[b]sys_fontdata+sys_fontdata->sheet_image[/b]+(sys_fontdata->sheet_size*sheets);
Then, it seems there are two errors in this function, regarding the byte offset calculation in the destination texture:
Code: Select all
ptr2 = image+((ypos/8)*(((stride<<2)/8)<<5));
ptr2 = ptr2+(((xpos+pos)/8)<<5);
ptr2 = ptr2+(((xpos+pos)%8)/2);
We always have to keep in mind that texture data are stored as consecutive 8x8 texels blocks in memory.
- "stride" generally means the width in
bytes of the texture image, so to get the base offset for a given line, it should be:
vertical offset in number of 8x8 texels blocks = line / 8
horizontal offset in number of 8x8 texels blocks = (stride * 2) / 8
offset in bytes = (line /8) * (stride * 2 /
* 32
so
Code: Select all
ptr2 = image+((ypos/8)*(((stride<<1)/8)<<5));
instead of
Code: Select all
ptr2 = image+((ypos/8)*(((stride<<2)/8)<<5));
- a final vertical offset is missing, the offset within the 8x8 block. The following line should be added :
Hope that helps..