Path: chuka.playstation.co.uk!news From: "Mario Wynands" Newsgroups: scee.yaroze.programming.2d_graphics Subject: Re: User defined fonts Date: Sun, 20 Jun 1999 13:50:56 +1200 Organization: PlayStation Net Yaroze (SCEE) Lines: 169 Message-ID: <7khhk2$33u2@chuka.playstation.co.uk> References: <7kgohf$4fj24@chuka.playstation.co.uk> NNTP-Posting-Host: p59-max5.wlg.ihug.co.nz X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.00.2314.1300 X-MIMEOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 Ed Fear wrote in message news:7kgohf$4fj24@chuka.playstation.co.uk... > I know this has popped up before, but it seems to have been deleted by > Outlook... anyway... how the jeeves do I make my own font to use in my > game? I had an idea of creating a sprite for every character printed and > just changing the u and v values of one big sprite but this is unwieldy and > silly. How do you do it? I think I remember Rad posting some code from one > of his projects, but it didn't help. Can any of you? Please? Hi Ed, There are a number of different ways you could implement user-defined fonts. Probably the easiest is to use a set of predefined sprites and draw them as necessary (that way you don't have to mess around with uv values as you draw them). It takes a little bit more memory than by having one sprite, but is probably worth it for the simplicity. I'll try to describe it below but it could get a bit messy :) First off define your sprites using something like GsSPRITE letter_sprites[52]; // need 52 to hold upper and lower case if required GsSPRITE number_sprites[10]; GsSPRITE symbol_sprites[24]; // use as many symbols as you need or to make it a bit cleaner and flexible to allow multiple font sets you can wrap them up as a struct like typedef struct { int width; int height; int spacing; int multicase; GsSPRITE letter_sprites[52]; GsSPRITE number_sprites[10]; GsSPRITE symbol_sprites[24]; } CharSet; Then in the initialisation section of your game set up the sprites so they index into the font TIM // Set up letters (single case only) // the exact implementation will depend on the layout of your TIM for (i = 0; i < 26; i++) { LinkSpriteToImage( &char_set->letter_sprites[i], GetTIMIMAGE(tim_index)); char_set->letter_sprites[i].w = width; char_set->letter_sprites[i].h = height; if (i < 15) { char_set->letter_sprites[i].u = width + (i * width); char_set->letter_sprites[i].v = 2 * height; } else { char_set->letter_sprites[i].u = ((i-15) * width); char_set->letter_sprites[i].v = 3 * height; } } // and then do all the digits and symbols.... Then when you are drawing text to the screen you do something like length = strlen(string); for (i = 0; i < length; i++) { sprite = GetSpriteForCharacter(char_set, *string); if (sprite) { sprite->x = x; sprite->y = y; sprite->r = sprite->g = sprite->b = 128 + brightness; GsSortSprite(sprite, ot, 0); } x += char_set->width + char_set->spacing; string++; } where GetSpriteForCharacter works out which sprite to draw along the lines of // Make all one case if (character >= 65 && character <= 90) { if (char_set->multicase) character += 58; else character += 32; } // Check if letter if (character >= 97 && character <= 148) { index = ((int) character) - 97; result = &char_set->letter_sprites[index]; } else { // Check if digit if (character >= 48 && character <= 57) { index = ((int) character) - 48; result = &char_set->number_sprites[index]; } // Must be symbol else { switch (character) { case ' ': result = &char_set->symbol_sprites[0]; break; case '!': result = &char_set->symbol_sprites[1]; break; // I'm sure you get the idea... default: result = NULL; break; } } } Simple as that (if you understood any of that mess :) ). There are a couple Yaroze demos kicking around with similar sorts of implementations (the above code is a derivative of one of those if I remember correctly) if you want a full solution. Let me know if you need more help in a specific area. Hope this helps Mario Mario Wynands Company Director/Producer SIDHE INTERACTIVE mario@sidhe.co.nz http://www.sidhe.co.nz