Hi,
Does anyone have ever do a grabber to load a Mugen's sff file format or fnt file format for Allegro or can help making one, for KOF91 project ( http://koflinux.sourceforge.net )?
Thanks a lot for the help.
why you want to write a new grabber.
You can make plugins for Allegro's current grabber.
It's also possible that you can load your file without a plugin.
I don't specially want to write a new grabber, nor plugins, nor specific function. I just want to know if somebody have ever do it and would like to share his code with me to save me lot of time writing one of this solution. Especially because I'm not really familiar with file structure loading.
If nobody never do such a thing I will publish it when I wrote it (time, time, time) as part of the KOF91 source code.
Thanks a lot for any help.
I'd like to help, but I can't find a file spec for either sff or fnt.
Care to share a link?
Thanks a lot spellcaster,
Here is the définition of the formats:
/*--| SFF file structure
|--------------------------------------------------*\
Version 1.01
HEADER (512 bytes)
------
Bytes
00-11 "ElecbyteSpr\0" signature [12]
12-15 1 verhi, 1 verlo, 1 verlo2, 1 verlo3 [04]
16-19 Number of groups [04]
20-24 Number of images [04]
24-27 File offset where first subfile is located [04]
28-31 Size of subheader in bytes [04]
32 Palette type (1=SPRPALTYPE_SHARED or 0=SPRPALTYPE_INDIV) [01]
33-35 Blank; set to zero [03]
36-511 Blank; can be used for comments [476]
SUBFILEHEADER (32 bytes)
-------
Bytes
00-03 File offset where next subfile in the "linked list" is [04]
located. Null if last subfile
04-07 Subfile length (not including header) [04]
Length is 0 if it is a linked sprite
08-09 Image axis X coordinate [02]
10-11 Image axis Y coordinate [02]
12-13 Group number [02]
14-15 Image number (in the group) [02]
16-17 Index of previous copy of sprite (linked sprites only) [02]
This is the actual
18 True if palette is same as previous image [01]
19-31 Blank; can be used for comments [14]
32- PCX graphic data. If palette data is available, it is the last
768 bytes.
*--------------------------------------------------------------------------*/
/*--| SND file structure
|--------------------------------------------------*\
Version 1.01
HEADER
------
Bytes
00-11 "ElecbyteSnd\0" signature [12]
12-15 4 verhi, 4 verlo [04]
16-19 Number of sounds [04]
20-23 File offset where first subfile is located. [04]
24-511 Blank; can be used for comments. [488]
SUBFILEHEADER
-------
Bytes
00-03 File offset where next subfile in the linked list is [04]
located. Null if last subfile.
04-07 Subfile length (not including header.) [04]
08-11 Group number [04]
12-15 Sample number [04]
08- Sound data (WAV)
*--------------------------------------------------------------------------*/
/*--| FNT file structure
|--------------------------------------------------*\
/*
Very simple file format, formed by concatenating a pcx file and a text
file together and prepending a header.
May be optimized for size by stripping the text file of comments before
adding it to the .fnt file. Be sure text data comes last in the file.
*/
Version 1.0
HEADER
------
Bytes
00-11 "ElecbyteFnt\0" signature
[12]
12-15 2 verhi, 2 verlo
[04]
16-20 File offset where PCX data is located.
[04]
20-23 Length of PCX data in bytes.
[04]
24-27 File offset where TEXT data is located.
[04]
28-31 Length of TEXT data in bytes.
[04]
32-63 Blank; can be used for comments.
[40]
*--------------------------------------------------------------------------*/
I can't myself explain everything and hope this will look simplest for you than for me.
Thanks a lot if you can help me
it seems to be pretty straight forward.
I'll see what I can do
It will realy help me, thanks a lot.
Just a couple of questions:
Do you have some files I could test my loader with?
What output do you expect? For the SFF file, you could get a list or an array of BITMAPs + some extra data (like the (x,y) offset; group, index, etc.) is that what you want?
You could download Mugen on my website:
http://zesensei.free.fr/mugen/tools/mug10414.exe It has fnt, sff, snd files.
For me a good result would be:
for sff and snd a linked list with a structure of this type:
and same for sound.
For fnt it will be great it Fonts became Allegro font.
Thanks for the help
Ok, here's the sff loader.
Right now it exports a linked list... but you can change that easily so it returns an array. Just check the source.
Here's the implementation of the loader:
And here a small demo:
Please note that the file specs above seem to be incorrect.
Some fields seem to have different sizes than listed. And in some cases the logic doesn't seem to be correct (like the way to determine the last subfile).
Thanks a lot for the code, it works well.
I think linked list will be fine, if there's any problem I could easely convert it into array.
Could I use your code in KOF 91 project (it's opend source, you'll be mentionned in the developement team if you want)?
Do you think you can do the same thing for other formats?
If not, the sff management is already a huge part, thanks again.
Sure, just use it - that's why I wrote it
Regarding the array: It's already there, I'm using it internally ofr index sprites - so if you want it, you could just change the return type to the array. That way you'd have both array (since it was returned) and the linked list (since the array members are still linked).
I'm working on the other formats. Just a question to the FNT format - the txt file is pretty simple, but for some chars the it looks weird... mainly for the [ and ] I guess. Not sure why. Is there any documentation for the TXT part of the FNT?
I think I could guess how it's composed... but that would be just a guess.
(oh... and please answer to this post, so I can add the new loaders in my next reply )
Might take some time though... the allegro font structure is quite complex IIRC - so I might have to play around with it a bit.
Thanks a lot,
here's a litle explanation of how the elecbyte's fntmaker works, it could help about the format:
====================
III. Fntmaker
====================
The fonts generated by fntmaker work for 2000.06.27 and newer versions
of M.U.G.E.N.
pcx file - Supply a pcx file which contains all the characters in your font
alphabet, arranged from left to right in a single row. The pcx
file must be an 8-bit color sprite.
txt file - Copy a txt file from work/font in custom.zip, and edit it to fit
your font's pcx file. The first part is are the font settings.
It is followed by character and offset pairs. The character is a
letter or symbol in your pcx file you wish to represent. The
offset is the starting x location within the pcx file of the
character. For example,
B 55
means that character 'B' begins at an offset of 55 pixels from the
left. Semicolon is treated as a comment character. To put in
entries for special characters such as a semi-colon, you need to
use a hex sequence representing the ASCII number of the
character. Hex sequences start with 0x. For example, a semicolon
(ASCII value 5B) starting at pixel 100 would have an entry:
0x5B 100
Fonts with more than one color use "color banks" in their palette to store
multiple color arrangements. Each color bank in the palette has a number of
palette entries equal to the value of the "Color" parameter in the font's
txt file. The first color bank starts at color 255, and its entries are
laid out in reverse palette order. The next color bank's first palette entry
starts immediately following the first, and so on. For example, a font with
16 colors has its first bank's entries from 255 to 240. The second bank has
entries 239 to 224 and so on. The number of banks you can have is limited by
the palette space.
I hope it could help you.
Thanks for that info... makes sense now
Regarding the multiple color banks... allegro can't handle that.
I can copy the data into an allegro FONT and return a struct containing both FONT and palette .. but the actual color bank switch has to be made programmtically - if you're using hicolor display you could change the palette, set the changed pal and blit it. If you're in a 8 bit mode, things get a bit more messy.
You could either "clone" the fonts to get different versions (in different color sets) or create totally new font rendering functions.
Cloning would be faster, more easy to implement but does of course waste some memory.
What do you prefer?
I know you weren't directing this at me, but here's an idea. What if you load all the font data as true-color bitmap (according to their color banks), then do an optimized palette generation on it and make it an 8-bit bitmap to cut up for the font? Granted it won't look the same, but if you're gonna put it in FONT, you won't have much choice.
The font is already an 8bit bmp. It has it's own palette (256 colors). The point is that you'd have to add an offset to each pixel to support the color bank feature.
Hmm.. I'm not sure I understand the color banks portion then. What does it do? Whats its purpose?
Assume you have a font with a gradient red->yellow using 8 colors.
The font is using the colors 247-255.
These 8 colors are color bank 0.
You could now use another 8 indices in the palette to define a blue->white gradient. Those colors would now be color bank 1.
I guess that mugens font drawing allows you to specify the color bank... so you could draw a text with font A, color bank 0 (red->yellow text) or using color bank 1 (blue->white text).
Allegro's glyph drawing functions don't work that way.
So, I could either generate several fonts (not much efford, not really memory wasting) or create functions mimicing the color bank switching.
I think, I'll go for the creation of multiple fonts
I think the creation of clone fonts is a good idea, as it will become possible to have palettes that are not specify with the original font picture's pal.
Spellcaster is right, mugen call a font and then its color bank to show it with right palette. I think a call to an array of fonts (or linked list) with an index that is correspinding to the bank used to make the clone will be a good idea.
A little explaination too, Mugen use fixed fonts and proportional fonts. I don't understand really the differences, but it's one of the attribute you specify when you create a font. I don't know if it's really important, but I think I've seen something like that (fixed and proportionnal) in Allegro doc.
Thanks a lot for the help.
Mugen use fixed fonts and proportional fonts. I don't understand really the differences
In a fixed width font all characters are the same width (for instance, W and I). In a proportional font, W is wider than I.
spellcaster: if you really wanted to, you could probably hack the FONT vtable so that it can draw the colourbanked fonts. That's probably going to be a lot of work for little obvious gain over what you're proposing.
Don't think that this is needed. Mugen fonts are pretty small - I doubt it'll be a big overhead if one would simply clone the fonts.
I'll add a
FONT* fntGetColorBankFont( FntFont* fnt, int bank);
to my code. Or something similar. If somebody can come up with a good name for that function, I'd be grateful
Expect the font functions today (sorry... I was pretty busy yesterday).
Regarding the proportional fonts: What evert said... in theory, at least. It seems like a lot of mugen fonts are labeled as "proportional" but are in fact fixed size... but that's not a big problem, IMO.
I might need to bug Bruce about the wave formats, though
Thanks again,
FONT* fntGetColorBankFont( FntFont* fnt, int bank); could become get_cfont( FntFont* fnt, int bank); for get colored font??
I'm not really good at function baptism...
Thanks for the help
Here's the loader.
I decided to create different palettes instead of different fonts - so this solution will only work in a high color mode.
If you want to support 8 bit, you need to clone the font and change the actual pixel data of the glyphs.
Thanks again, and again,
It works good for some fonts. Just a detail, the code didn't compile on my Win98 with Mingw32.
It was because of a detail: declaration of variables MUST be before calling any function with my GCC. So for the testloader.c I got to put allegro_init() after declarations. Same problem in loader.c where I got to declare int count, and char * txt at the beginning of the function in order to make it compile.
I learn a lot with your code fully documented, really clean and structured.
For the bugs, here are some fonts that didn't work with the testloader prog. And if I pass the same name as the exemple font you give in your zip file (name1.fnt) as an argument color banks seems to disappear. Pretty weird...
I'll look later the how of this... It works with some fnt, a great beginning.
Get a new gcc - it should work with the later 3.0 versions... but to be honest, it was an mistake...
I normally try to declare my vars at the beginning. Regarding the testloader - I used only the font testing part and had the other stuff REMed. At the end I removed the comments and made a test run.
Since it worked, I was assuming it would be ok.
Same problem in loader.c where I got to declare int count, and char * txt
Sorry. But, as I said, it'll work in any c99 compiler (say the later gccs). But I changed that - it wasn't intentional in the first place.
There's no need to put txt at the beginning, though. Just swap the char* txt; with the line above that.
And if I pass the same name as the exemple font you give in your zip file (name1.fnt) as an argument color banks seems to disappear. Pretty weird...
Check the testloader code. There's a bug in name1.fnt. If you split it (I think I have the split.c code in that zip as well) and look into the txt.txt file, you'll see that it has colors=1 in it. And that's wrong. The numbers of colors should be 16 for that font.
That's why I added a small hack inside the loader - if it is using the default font, then it'll override the number of colors.
EDIT:
Just in case I didn't put the split stuff in the zip, here it is:
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | |
4 | int readIntFrom(FILE *f, int ofs) { |
5 | int i; |
6 | fseek(f, ofs, SEEK_SET); |
7 | fread(&i, 4, 1, f); |
8 | return i; |
9 | } |
10 | |
11 | int main(int argc, char** argv) { |
12 | |
13 | FILE *f = fopen(argv[1], "rb"); |
14 | FILE *o = NULL; |
15 | int pcxOfs = readIntFrom(f, 16); |
16 | int pcxLen = readIntFrom(f, 20); |
17 | int txtOfs = readIntFrom(f, 24); |
18 | int txtLen = readIntFrom(f, 28); |
19 | |
20 | char *buffer = NULL; |
21 | |
22 | printf("pcx: %i, %i\ntxt: %i, %i\n", pcxOfs, pcxLen, txtOfs, txtLen); |
23 | |
24 | o = fopen("pcx.pcx", "wb"); |
25 | buffer = malloc(pcxLen); |
26 | fseek(f, pcxOfs, SEEK_SET); |
27 | fread(buffer, 1, pcxLen, f); |
28 | fwrite(buffer, 1, pcxLen, o); |
29 | fclose(o); |
30 | free(buffer); |
31 | |
32 | o = fopen("txt.txt", "wb"); |
33 | buffer = malloc(txtLen); |
34 | fseek(f, txtOfs, SEEK_SET); |
35 | fread(buffer, 1, txtLen, f); |
36 | fwrite(buffer, 1, txtLen, o); |
37 | fclose(o); |
38 | free(buffer); |
39 | |
40 | fclose(f); |
41 | } |
Thanks for the reply.
For the name1.fnt that's my fault, I haven't read that this fount was malformed.
For GCC I'll do so later, it could explain some warning I did'nt have on others computers (or on Linux). Note: <mem.h> should not be include on my Mandrake 9.2, it didn't found it.
But what about fnts I put in my last post? Did you try them, did it work or crash (segmentation fault), like on my computer?
Do you have an idea fo the reason fo that crash?
Fixed.
There was a bug in my pcx loading code.
Better and better...
All work good now. Thanks a lot.
Do you plan to do .snd as well?
I think I could release a new version of KOF 91 in some hours with your code and it will looks like far better than other versions...
I'll look into the snd format as well, but I'm not an expert with waveforms. On the other hand, I do have some spare time now...
Anyway, please reply to this post, so I can answer again as soon as I have something for you
Well got to reply...
I've made a new version of KOF 91 with fnt support (a really limited one, as I haven't fix every call to text for now).
It'll be ready for dowload (binaries and sources) on my website : http://zesensei.free.fr
It's already nicer than ever, thanks to you.