War2.ru Slogan
News: Back by popular demand, the SMF Arcade!!!
PLAY NOW!!!!!!!!!!!!!!!!!!!!!!!!


Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
Welcome to the forums! We're glad to have you here! :) You can register your account here, then feel free to introduce yourself in the Server.War2.ru board & let us know who you are on the server.

War2 fonts (.fnt) 159  3

Administrator Ogre Posts: 1126 Karma: +110/-9 *****

iL

  • Administrator
  • Ogre
  • *****
  • *
  • Posts: 1126
    • View Profile
*

iL

War2 fonts (.fnt)
« on: January 23, 2019, 03:00:53 PM »
Anybody knows any software to work with war2 .fnt-files?

I know the .fnt-file format, but how to work with it if i'm a user, not a programmer? What if i want to add a new language into war2?
I can't trust there's no software for that purposes, but i googled any .fnt-related software for war2/starcraft and find nothing except the description of font/letter headers.

Looks like i have to write my own program, but i'm lazy for that.
Any ideas?
Sappers Posts: 795 Karma: +42/-0 ******

Szwagier

  • Sappers
  • ******
  • Posts: 795
    • View Profile
Re: War2 fonts (.fnt)
« Reply #1 on: January 24, 2019, 03:03:36 AM »
Hex editor work with it, you need Just translate everything
Administrator Ogre Posts: 1126 Karma: +110/-9 *****

iL

  • Administrator
  • Ogre
  • *****
  • *
  • Posts: 1126
    • View Profile
*

iL

Re: War2 fonts (.fnt)
« Reply #2 on: January 24, 2019, 03:42:12 AM »
im still not sure if this is the fnt war2 is using
Yes, as i understand that uses a well-known old dos .fnt-format that is not compatible with war2 (just the same file extension as it's also a font).

At least, war2 fonts looks completely different than any other .fnt-files.

So, still looking for any war2-font-working software, let me know if you know something...
Administrator Ogre Posts: 1126 Karma: +110/-9 *****

iL

  • Administrator
  • Ogre
  • *****
  • *
  • Posts: 1126
    • View Profile
*

iL

Re: War2 fonts (.fnt)
« Reply #3 on: January 24, 2019, 06:44:00 PM »
Well, i'll just publish my source code here, i used it to fix russian fonts about 10 years ago.
That program can be started as:
prog.exe font.fnt
it shows all the letters raster in text mode (each point is a number).
Program is most likely useless, except the source code to read and parse the whole .fnt-file
You can make something useful based on it.
Here's it:
Code: [Select]
// fontwar2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<stdio.h>
#include<windows.h>

#define MAX_LEETER_NUM 256
void bmp2fnt();
void cp2win(char *,int,int);
int getletter(char *,unsigned,char *);

typedef struct _FontHeader {
DWORD Name; // Always is "FONT"
BYTE LowIndex; // Index of first letter in file
BYTE HighIndex; // Index of the last letter in file
BYTE MaxWidth; // Maximum width
BYTE MaxHeight; // Maximum height
DWORD Unk1; // Unknown / Unused
} FontHeader;

typedef struct  _FontLetterRaw {
BYTE Width; // Width of the letter
BYTE Height; // Height of the letter
BYTE XOffset; // X Offset for the topleft corner of the letter.
BYTE YOffset; // Y Offset for the topleft corner of the letter.
} FontLetterRaw;

//DWORD letterofs[MAX_LEETER_NUM];
//FontHeader fontheader;
//FontLetterRaw letterheader;


int main(int argc, char* argv[])
{
/* FILE *in;
int i,pixelcounter,toskip;
BYTE c;
if(argc<2){printf("Usage: fontwar2 <filename.fnt> [-w]\n");return 0;}
in=fopen(argv[1],"rb");
if(!in){printf("Data error reading file %s\n",argv[1]);return 1;}
if(!fread(&fontheader,sizeof(FontHeader),1,in)){printf("Error in %s\n",argv[1]);return 2;}
printf("ok: %d, %d, %d, %d",fontheader.LowIndex,fontheader.HighIndex,fontheader.MaxWidth,fontheader.MaxHeight);
for(i=fontheader.LowIndex;i<fontheader.HighIndex;i++)
{
if(i>=MAX_LEETER_NUM){printf("Error! too many letters\n");return 3;}
fread(&letterofs[i],4,1,in);
// printf("%d ",letterofs[i]);
}

printf("\n");

for(i=fontheader.LowIndex;i<fontheader.HighIndex;i++)
{
if(letterofs[i]==0){printf("skip\n");continue;}
fseek(in,letterofs[i],SEEK_SET);
fread(&letterheader,sizeof(FontLetterRaw),1,in);
printf("%d %d^\n",letterheader.Width,letterheader.Height);
toskip=0;
printf("Begin %d\n",i+1);
for(pixelcounter=0;pixelcounter<letterheader.Width*letterheader.Height;pixelcounter++)
{
if(toskip-->0)
{
printf("-");
}
else{
if(pixelcounter)printf("%d",c&7);
c=fgetc(in);
toskip=c>>3;
}
if(pixelcounter%letterheader.Width==0)printf("\n");
}
printf("%d\n",c&7);
printf("End\n");
}
printf("!%d!\n",ftell(in));
fclose(in);

// bmp2fnt();
if(argc>2&&strcmp(argv[2],"-w")==0)cp2win(argv[1],fontheader.LowIndex,fontheader.HighIndex);*/
char buf[1024]; // FIXME! insecure
// if(argc<4){printf("Usage: fontwar2 <source1.fnt> <source2.fnt> <target.fnt>\n");return 0;}

int outfnt[32768]; // FIXME! insecure
int outfnt_seek=0,letsize;
char header[]={'F','O','N','T',0x20,0xff,0x0e,0x0e};
FontHeader outfh;
outfh.LowIndex=header[4];
outfh.HighIndex=header[5];
outfh.MaxWidth=header[6];
outfh.MaxHeight=header[7];

memset(outfnt,0,sizeof(outfnt));
memcpy(outfnt,header,sizeof(header));
outfnt_seek=(outfh.HighIndex+1-outfh.LowIndex)*4+sizeof(header);

if(argc==2)
{
for(int i=outfh.LowIndex;i<=outfh.HighIndex;i++)
getletter(argv[1],i,(char *)outfnt+outfnt_seek);
return 0;
}

for(int i=outfh.LowIndex;i<=outfh.HighIndex;i++)
{
switch(i)
{
case 128:letsize=getletter(argv[2],'З',(char *)outfnt+outfnt_seek);break;
case 129:letsize=getletter(argv[2],'ь',(char *)outfnt+outfnt_seek);break;
case 130:letsize=getletter(argv[2],'й',(char *)outfnt+outfnt_seek);break;
case 131:letsize=getletter(argv[2],'в',(char *)outfnt+outfnt_seek);break;
case 132:letsize=getletter(argv[2],'д',(char *)outfnt+outfnt_seek);break;
case 133:letsize=getletter(argv[2],'а',(char *)outfnt+outfnt_seek);break;
case 134:letsize=getletter(argv[2],'е',(char *)outfnt+outfnt_seek);break;
case 135:letsize=getletter(argv[2],'з',(char *)outfnt+outfnt_seek);break;
case 136:letsize=getletter(argv[2],'к',(char *)outfnt+outfnt_seek);break;
case 137:letsize=getletter(argv[2],'л',(char *)outfnt+outfnt_seek);break;
case 138:letsize=getletter(argv[2],'и',(char *)outfnt+outfnt_seek);break;
case 139:letsize=getletter(argv[2],'п',(char *)outfnt+outfnt_seek);break;
case 140:letsize=getletter(argv[2],'о',(char *)outfnt+outfnt_seek);break;
case 141:letsize=getletter(argv[2],'м',(char *)outfnt+outfnt_seek);break;
case 142:letsize=getletter(argv[2],'Д',(char *)outfnt+outfnt_seek);break;
case 143:letsize=getletter(argv[2],'Е',(char *)outfnt+outfnt_seek);break;
case 144:letsize=getletter(argv[2],'Й',(char *)outfnt+outfnt_seek);break;
case 145:letsize=getletter(argv[2],'ж',(char *)outfnt+outfnt_seek);break;
case 146:letsize=getletter(argv[2],'Ж',(char *)outfnt+outfnt_seek);break;
case 147:letsize=getletter(argv[2],'ф',(char *)outfnt+outfnt_seek);break;
case 148:letsize=getletter(argv[2],'ц',(char *)outfnt+outfnt_seek);break;
case 149:letsize=getletter(argv[2],'т',(char *)outfnt+outfnt_seek);break;
case 150:letsize=getletter(argv[2],'ы',(char *)outfnt+outfnt_seek);break;
case 151:letsize=getletter(argv[2],'щ',(char *)outfnt+outfnt_seek);break;
case 152:letsize=getletter(argv[2],'я',(char *)outfnt+outfnt_seek);break;
case 153:letsize=getletter(argv[2],'Ц',(char *)outfnt+outfnt_seek);break;
case 154:letsize=getletter(argv[2],'Ь',(char *)outfnt+outfnt_seek);break;
case 155:letsize=getletter(argv[2],'ш',(char *)outfnt+outfnt_seek);break;
// case 156:letsize=getletter(argv[2],'Ь',(char *)outfnt+outfnt_seek);break;
case 157:letsize=getletter(argv[2],'Ш',(char *)outfnt+outfnt_seek);break;
case 158:letsize=getletter(argv[2],'Ч',(char *)outfnt+outfnt_seek);break;
// case 159:letsize=getletter(argv[2],'Я',(char *)outfnt+outfnt_seek);break;
case 160:letsize=getletter(argv[2],'б',(char *)outfnt+outfnt_seek);break;
case 161:letsize=getletter(argv[2],'н',(char *)outfnt+outfnt_seek);break;
case 162:letsize=getletter(argv[2],'у',(char *)outfnt+outfnt_seek);break;
case 163:letsize=getletter(argv[2],'ъ',(char *)outfnt+outfnt_seek);break;
case 164:letsize=getletter(argv[2],'с',(char *)outfnt+outfnt_seek);break;
case 165:letsize=getletter(argv[2],'С',(char *)outfnt+outfnt_seek);break;

case 181:letsize=getletter(argv[2],'Б',(char *)outfnt+outfnt_seek);break;
case 182:letsize=getletter(argv[2],'В',(char *)outfnt+outfnt_seek);break;
case 183:letsize=getletter(argv[2],'А',(char *)outfnt+outfnt_seek);break;
case 198:letsize=getletter(argv[2],'г',(char *)outfnt+outfnt_seek);break;
case 199:letsize=getletter(argv[2],'Г',(char *)outfnt+outfnt_seek);break;
case 208:letsize=getletter(argv[2],'р',(char *)outfnt+outfnt_seek);break;
case 209:letsize=getletter(argv[2],'Р',(char *)outfnt+outfnt_seek);break;
case 210:letsize=getletter(argv[2],'К',(char *)outfnt+outfnt_seek);break;
case 211:letsize=getletter(argv[2],'Л',(char *)outfnt+outfnt_seek);break;
case 212:letsize=getletter(argv[2],'И',(char *)outfnt+outfnt_seek);break;
case 214:letsize=getletter(argv[2],'Н',(char *)outfnt+outfnt_seek);break;
case 215:letsize=getletter(argv[2],'О',(char *)outfnt+outfnt_seek);break;
case 216:letsize=getletter(argv[2],'П',(char *)outfnt+outfnt_seek);break;
case 222:letsize=getletter(argv[2],'М',(char *)outfnt+outfnt_seek);break;
case 224:letsize=getletter(argv[2],'У',(char *)outfnt+outfnt_seek);break;
case 225:letsize=getletter(argv[2],'Я',(char *)outfnt+outfnt_seek);break;
case 226:letsize=getletter(argv[2],'Ф',(char *)outfnt+outfnt_seek);break;
case 227:letsize=getletter(argv[2],'Т',(char *)outfnt+outfnt_seek);break;
case 228:letsize=getletter(argv[2],'х',(char *)outfnt+outfnt_seek);break;
case 229:letsize=getletter(argv[2],'Х',(char *)outfnt+outfnt_seek);break;
case 231:letsize=getletter(argv[2],'ю',(char *)outfnt+outfnt_seek);break;
case 232:letsize=getletter(argv[2],'Ю',(char *)outfnt+outfnt_seek);break;
case 233:letsize=getletter(argv[2],'Ъ',(char *)outfnt+outfnt_seek);break;
case 234:letsize=getletter(argv[2],'Ы',(char *)outfnt+outfnt_seek);break;
case 235:letsize=getletter(argv[2],'Щ',(char *)outfnt+outfnt_seek);break;
case 236:letsize=getletter(argv[2],'э',(char *)outfnt+outfnt_seek);break;
case 237:letsize=getletter(argv[2],'Э',(char *)outfnt+outfnt_seek);break;
case 246:letsize=getletter(argv[2],'ч',(char *)outfnt+outfnt_seek);break;
default:
if(i<128)letsize=getletter(argv[2],i,(char *)outfnt+outfnt_seek);
else letsize=getletter(argv[1],i,(char *)outfnt+outfnt_seek);
}

printf("len: %d\twriting %x\t",letsize,letsize?outfnt_seek:0);
outfnt[i-outfh.LowIndex+sizeof(header)/4]=letsize?outfnt_seek:0;
outfnt_seek+=letsize;
}
// int i=getletter(argv[1],247,buf);
// printf("len: %d\n",i);
FILE *out=fopen(argv[3],"wb");
if(!out){printf("!out");return 1;}
if(!fwrite(outfnt,outfnt_seek,1,out))printf("Error writing %s\n",argv[3]);

printf("!%x!",getletter(argv[1],33,(char *)outfnt));
return 0;
}
int getletter(char *filename,unsigned letnum,char *buf)
{
FILE *in;
FontHeader fh;
FontLetterRaw flr;
int pixelcounter;
int ofs=0,toskip=0,in_ofs;
char c;
in=fopen(filename,"rb");
letnum=(letnum+256)%256;
printf ("let:%d:num\t",letnum);
if(!in){printf("Data error reading file %s\n",filename);return 1;}
if(!fread(&fh,sizeof(FontHeader),1,in)){printf("Error in %s\n",filename);return 2;}
if(letnum<=fh.LowIndex||letnum>fh.HighIndex)return 0;
fseek(in,8+(letnum-fh.LowIndex)*4,SEEK_SET);
if(!fread(&in_ofs,4,1,in)){printf("Error in %s\n",filename);return 2;}
//printf("letofs: %X\n",in_ofs);
if(in_ofs==0)return 0;
fseek(in,in_ofs,SEEK_SET);
if(!fread(&flr,sizeof(FontLetterRaw),1,in)){printf("Error in %s\n",filename);return 2;}
memcpy(buf+ofs,&flr,sizeof(flr));
ofs+=sizeof(flr);
for(pixelcounter=0;pixelcounter<flr.Width*flr.Height;pixelcounter++)
{
if(toskip-->0)
{
printf("-");
}
else{
if(pixelcounter)printf("%d",c&7);
c=fgetc(in);
toskip=c>>3;
buf[ofs++]=c;
}
if(pixelcounter%flr.Width==0)printf("\n");
}
printf("%d\n",c&7);
return ofs;
}
/*void cp2win(char *fntfilename,int low,int high)
{
DWORD cp[256];
DWORD win[256];
FILE *fnt;
fnt=fopen(fntfilename,"r+b");
if(!fnt){printf("!fnt\n");return;}
fseek(fnt,12,SEEK_SET);
memset(cp,0,sizeof(cp));
memset(win,0,sizeof(win));
if(fread(cp+low,4,high-low,fnt)!=(unsigned)(high-low)){printf("!fread\n");return;}
//for(int i=low;i<high;i++)printf("%4X ",cp[i]);
for(int i=low;i<high;i++)
{
//      if(i>=0x80-1&&i<0xb0-1)win[i]=cp[i+0x40];
// else if(i>=0xc0-1&&i<0xf0-1)win[i]=cp[i-0x40];
// else if(i>=0xb0-1&&i<0xc0-1)win[i]=cp[i+0x40];
// else if(i>=0xf0-1&&i<0x100-1)win[i]=cp[i-0x10];
// if(i==128)win[i]=cp[129];
// else
// win[i]=cp[i];
// switch(i)
// {
// case "└":win[]=cp[i];
// }
}
fseek(fnt,12,SEEK_SET);
if(fwrite(win+low,4,high-low,fnt)!=(unsigned)(high-low)){printf("!fwrite\n");return;}
printf("font file written successfully\n");
fclose(fnt);
}
/*void bmp2fnt()
{
BYTE fnt[65536];
BYTE buf[16][16];
int fnt_len=0;
int width=14,bmp_width=16,height=14,letternum=239-32;

int i,j,k,len,seek,c,toskip=0;
FILE *in=fopen("game.bmp","rb");
if(!in){printf("!in");return;}
FILE *out=fopen("out.fnt","wb");
if(!out){printf("!out");return;}
fseek(in,0,2);
len=ftell(in);

memcpy(fnt+fnt_len,&fontheader,sizeof(FontHeader));
fnt_len+=sizeof(FontHeader);
fnt_len+=letternum*4;
for(k=0;k<letternum;k++)
{
seek=len-k*bmp_width*height;
for(j=0;j<height;j++)
for(i=0;i<bmp_width;i++)
{
seek--;
if((len-seek)%16==1||(len-seek)%16==2)continue;
fseek(in,seek,0);
buf[bmp_width-1-i][j]=fgetc(in);
}
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
printf("%2x",buf[i][j]);
printf("\n");
}
}
}
*/