Page 1 of 1

embeding images/fonts into the elf file

Posted: Sat Aug 15, 2009 11:06 pm
by methos3
Hello, me again :)
I was needing to put some fonts and textures into my elf file, and I did it in that way:
I took the original code of the font/texture loading functions and exchanged the fread()/fseek() calls to memcpy()/increment/decrement counter calls, using a counter to simulate the file position counter.
I used bin2c to convert the .fnt and .bmp files into a char array.
It worked great for bmp textures, but I wasn't so lucky with the fonts...
I didn't want to use romfs, and instead I preferred to use this method, that should work. (PCSX2 freezes when I try to use them :(, but work great with the modified texture ones... )

Look at the modified font loading functions, with the original parts commented:

Code: Select all

GSFONT *gsKit_init_font_buffer(u8 type, unsigned char *path, int size)
{

	GSFONT *gsFont = calloc(1,sizeof(GSFONT));
	gsFont->Texture = calloc(1,sizeof(GSTEXTURE));
	if(path)
	{
		gsFont->Path = path;//calloc(1,strlen(path));
		/*strcpy(gsFont->Path, path);*/
	}
	gsFont->Type = type;

	return gsFont;
}

int gsKit_font_buffer_upload(GSGLOBAL *gsGlobal, GSFONT *gsFont, int size)
{
    int i;
    if( gsFont->Type == GSKIT_FTYPE_FNT )
	{
		if( gsKit_texture_fnt_buffer(gsGlobal, gsFont, size) == -1 )
		{
			printf("Error uploading font!\n");
			return -1;
		}
		gsFont->Additional=malloc( 0x100 );
		for &#40;i=0; i<0x100; i++&#41; &#123;
			gsFont->Additional&#91;i&#93; = gsFont->CharWidth;
		&#125;

		return 0;
	&#125;
	else return -1;
&#125;

int gsKit_texture_fnt_buffer&#40;GSGLOBAL *gsGlobal, GSFONT *gsFont, int buffersize&#41;
&#123;
	u32 *mem;
	int size = 0;
	int vramsize = 0;
	int i, m=0;
	char* buffer = gsFont->Path;

	//FILE* File = fopen&#40;gsFont->Path, "r"&#41;;
	/*if &#40;File == NULL&#41;
	&#123;
		printf&#40;"Failed to load font&#58; %s\n", gsFont->Path&#41;;
		return -1;
	&#125;
	fseek&#40;File, 4, SEEK_SET&#41;;*/
	m=4;
	/*if&#40;fread&#40;&gsFont->Texture->Width, 4, 1, File&#41; <= 0&#41;
	&#123;
		printf&#40;"Could not load font&#58; %s\n", gsFont->Path&#41;;
		return -1;
	&#125;*/
	memcpy&#40;&gsFont->Texture->Width, &buffer&#91;m&#93;, 4&#41;;
	m+=4;
	/*if&#40;fread&#40;&gsFont->Texture->Height, 4, 1, File&#41; <= 0&#41;
	&#123;
		printf&#40;"Could not load font&#58; %s\n", gsFont->Path&#41;;
		return -1;
	&#125;*/
	memcpy&#40;&gsFont->Texture->Height, &buffer&#91;m&#93;, 4&#41;;
	m+=4;
	/*if&#40;fread&#40;&gsFont->Texture->PSM, 4, 1, File&#41; <= 0&#41;
	&#123;
		printf&#40;"Could not load font&#58; %s\n", gsFont->Path&#41;;
		return -1;
	&#125;*/
	memcpy&#40;&gsFont->Texture->PSM, &buffer&#91;m&#93;, 4&#41;;
	m+=4;
	/*if&#40;fread&#40;&gsFont->HChars, 4, 1, File&#41; <= 0&#41;
	&#123;
		printf&#40;"Could not load font&#58; %s\n", gsFont->Path&#41;;
		return -1;
	&#125;*/
	memcpy&#40;&gsFont->HChars, &buffer&#91;m&#93;, 4&#41;;
	m+=4;
	/*if&#40;fread&#40;&gsFont->VChars, 4, 1, File&#41; <= 0&#41;
	&#123;
		printf&#40;"Could not load font&#58; %s\n", gsFont->Path&#41;;
		return -1;
	&#125;*/
	memcpy&#40;&gsFont->VChars, &buffer&#91;m&#93;, 4&#41;;
	m+=4;
	/*if&#40;fread&#40;&gsFont->CharWidth, 4, 1, File&#41; <= 0&#41;
	&#123;
		printf&#40;"Could not load font&#58; %s\n", gsFont->Path&#41;;
		return -1;
	&#125;*/
	memcpy&#40;&gsFont->CharWidth, &buffer&#91;m&#93;, 4&#41;;
	m+=4;
	/*if&#40;fread&#40;&gsFont->CharHeight, 4, 1, File&#41; <= 0&#41;
	&#123;
		printf&#40;"Could not load font&#58; %s\n", gsFont->Path&#41;;
		return -1;
	&#125;*/
	memcpy&#40;&gsFont->CharHeight, &buffer&#91;m&#93;, 4&#41;;
	m+=4;
	//fseek&#40;File, 288, SEEK_SET&#41;;
	m=288;

	gsFont->Texture->Filter = GS_FILTER_NEAREST;

	size = gsKit_texture_size_ee&#40;gsFont->Texture->Width, gsFont->Texture->Height, gsFont->Texture->PSM&#41;;
	vramsize = gsKit_texture_size&#40;gsFont->Texture->Width, gsFont->Texture->Height, gsFont->Texture->PSM&#41;;
	gsFont->Texture->Mem = memalign&#40;128, size&#41;;
	gsFont->Texture->Vram = gsKit_vram_alloc&#40;gsGlobal, vramsize, GSKIT_ALLOC_USERBUFFER&#41;;
	if&#40;gsFont->Texture->Vram == GSKIT_ALLOC_ERROR&#41;
	&#123;
		printf&#40;"VRAM Allocation Failed. Will not upload texture.\n"&#41;;
		return -1;
	&#125;

	/*if&#40;fread&#40;gsFont->Texture->Mem, size, 1, File&#41; <= 0&#41;
	&#123;
	        printf&#40;"Font might be bad&#58; %s\n", gsFont->Path&#41;;
	&#125;
	fclose&#40;File&#41;;*/
	memcpy&#40;&gsFont->Texture->Mem, &buffer&#91;m&#93;, size&#41;;
	m+=4;

	if &#40;gsFont->Texture->PSM != 0&#41; &#123;
		printf&#40;"Unsupported fnt PSM %d\n", gsFont->Texture->PSM&#41;;
	&#125;
	mem = &#40;u32*&#41;gsFont->Texture->Mem;
	for &#40;i=0; i<size/4; i++&#41; &#123;
		if &#40;mem&#91;i&#93; == 0xFF00FFFF&#41; &#123;
			mem&#91;i&#93; = 0;
		&#125; else &#123;
			u32 c = &#40;mem&#91;i&#93; & 0x00FF0000&#41; >> 16;
			mem&#91;i&#93; = 0x80000000 | &#40;c&#41; | &#40;c<<8&#41; | &#40;c<<16&#41;;
		&#125;
	&#125;

	gsKit_texture_upload&#40;gsGlobal, gsFont->Texture&#41;;
	free&#40;gsFont->Texture->Mem&#41;;
	return 0;
&#125;


Posted: Sun Aug 16, 2009 12:58 am
by J.F.
The problem is

Code: Select all

memcpy&#40;&gsFont->Texture->Mem, &buffer&#91;m&#93;, size&#41;; 
It should be

Code: Select all

memcpy&#40;gsFont->Texture->Mem, &buffer&#91;m&#93;, size&#41;; 
->Mem is a variable pointing to the memory, not an array that is the memory.

Also, the m += 4; after that memcpy should be m+= size;

Posted: Sun Aug 16, 2009 9:39 am
by methos3
Ow, it was it...
I can explain: I didn't pay any attention while doing my custom font loading functions, I was only using ctrl+c and ctrl+v, this explains the lasting '&' and the m+=4 (instead of m+= size). But the m+=4 doesn't matter, since is's after the fclose() call, so I just left +=4.

Now it works, but... a weird thing is happening:
*the left part of each char is being cut (just some pixels) when using arial
*when using lucida, instead of each char, a strange "thing" appears
*I succesfully loaded lucida font from the memory, and from mass:lucida.fnt(using the normal load function), and both worked the same way (the strange "things", none of them being a char)
*I succesfully loaded Arial from the memory, and from the mass:arial.fnt, but the PS2 hangs when I try to write something on the screen using the one loaded from the pendrive.

Maybe it's a problem with the GSKit, I will end up having to download the latest version : (

Well, my doubt was solved, thanks J.F.!
Later!

[edit]
ok... if I don't load mass:lucida.fnt, mass:arial.fnt will work, the same way the embeded arial works. now I've gotta discover what's going on with lucida
and... the black square around the characters won't disappear, even using any king of alpha blending, but it's ok