embeding images/fonts into the elf file

Discuss the development of software, tools, libraries and anything else that helps make ps2dev happen.

Moderators: cheriff, Herben

Post Reply
methos3
Posts: 89
Joined: Fri Feb 01, 2008 3:21 am

embeding images/fonts into the elf file

Post 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;

J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post 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;
methos3
Posts: 89
Joined: Fri Feb 01, 2008 3:21 am

Post 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
Post Reply