Guest ljd3000 Posted March 29, 2011 Share Posted March 29, 2011 Hi, all: I write a patch for gemrb to display simplified chinese . changes: Font.h Font.cpp -- double byte font support (now only simplified chinese) BAMImporter.cpp -- can get font with char count > 255 TextArea.cpp -- CaclRowCount changed Interface.h Interface.cpp -- add font replace, now in GemRB.cfg, we can change STONEBIG STONESML TOOLFONT FLOATTEXT 4 Font. I test in ubuntu 10.10 amd64, with BGT ( BWP8.3 ). to play chinese version , we need add this code in GemRB.cfg STONEBIG = REALMS STONESML = NORMAL TOOLFONT = NORMAL FLOATTEXT = NORMAL the patch: diff -Nur gemrb-0.6.4/gemrb/core/Font.cpp gemrb-0.6.4.new/gemrb/core/Font.cpp --- gemrb-0.6.4/gemrb/core/Font.cpp 2011-03-27 16:08:09.000000000 +0000 +++ gemrb-0.6.4.new/gemrb/core/Font.cpp 2011-03-29 06:38:48.000000000 +0000 @@ -32,7 +32,6 @@ #include <cassert> -unsigned int lastX = 0; #define PARAGRAPH_START_X 5; @@ -56,9 +55,8 @@ return count; } -Font::Font(int w, int h, Palette* pal) +Font::Font(int w, int h, Palette* pal, int maxCount) { - lastX = 0; count = 0; FirstChar = 0; sprBuffer = 0; @@ -67,8 +65,12 @@ height = h; tmpPixels = (unsigned char*)malloc(width*height); - memset( xPos, 0, sizeof( xPos) ); - memset( yPos, 0, sizeof( yPos) ); + xPos = new short[maxCount]; + yPos = new short[maxCount]; + size = new Region[maxCount]; + memset( xPos, 0, sizeof(short)*maxCount ); + memset( yPos, 0, sizeof(short)*maxCount ); + memset( size, 0, sizeof(Region)*maxCount ); pal->IncRef(); palette = pal; @@ -77,6 +79,9 @@ Font::~Font(void) { + delete[] size; + delete[] xPos; + delete[] yPos; Video *video = core->GetVideoDriver(); gamedata->FreePalette( palette ); video->FreeSprite( sprBuffer ); @@ -88,33 +93,26 @@ tmpPixels = 0; } -void Font::AddChar(unsigned char* spr, int w, int h, short xPos, short yPos) +void Font::AddChar(int line, int row, int charH, int charW, unsigned char* spr, int w, int h, short xPos, short yPos) { - if (!spr) { - size[count].x = 0; - size[count].y = 0; - size[count].w = 0; - size[count].h = 0; - this->xPos[count] = 0; - this->yPos[count] = 0; - count++; - return; - } - unsigned char * currPtr = tmpPixels + lastX; - unsigned char * srcPtr = ( unsigned char * ) spr; - for (int y = 0; y < h; y++) { - memcpy( currPtr, srcPtr, w ); - srcPtr += w; - currPtr += width; + if( spr ) + { + unsigned char * currPtr = tmpPixels + charW * row + line * charH * width; + unsigned char * srcPtr = ( unsigned char * ) spr; + + for (int y = 0; y < h; y++) { + memcpy( currPtr, srcPtr, w ); + srcPtr += w; + currPtr += width; + } } - size[count].x = lastX; - size[count].y = 0; + size[count].x = charW * row; + size[count].y = charH * line; size[count].w = w; size[count].h = h; this->xPos[count] = xPos; this->yPos[count] = yPos; count++; - lastX += w; } void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, @@ -144,13 +142,14 @@ sprBuffer->SetPalette( pal ); size_t len = strlen( ( char* ) string ); - char* tmp = ( char* ) malloc( len + 1 ); - memcpy( tmp, ( char * ) string, len + 1 ); - SetupString( tmp, rgn.w, NoColor ); + unsigned short* tmp = new unsigned short[len+1]; + len = GetDoubleByteString((char*)string, tmp, len); + SetupString( tmp, len, rgn.w, NoColor ); + int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { for (size_t i = 0; i < len; i++) { - int height = yPos[( unsigned char ) tmp[i] - 1]; + int height = yPos[tmp[i] - 1]; if (ystep < height) ystep = height; } @@ -159,7 +158,7 @@ } if (!ystep) ystep = maxHeight; int x = psx, y = ystep; - int w = CalcStringWidth( tmp, NoColor ); + int w = CalcStringWidth( len, tmp, NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { @@ -188,7 +187,7 @@ Video* video = core->GetVideoDriver(); int row = 0; for (size_t i = 0; i < len; i++) { - if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { + if ( tmp[i] == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; @@ -244,7 +243,7 @@ if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) { y += ystep; x = psx; - int w = CalcStringWidth( &tmp[i + 1], NoColor ); + int w = CalcStringWidth( len-i-1, &tmp[i + 1], NoColor ); if (initials_rows > 0) { initials_rows--; x += initials_x; @@ -257,7 +256,8 @@ } continue; } - unsigned char currChar = ( unsigned char ) tmp[i] - 1; + unsigned short currChar = tmp[i] - 1; + if (initials && capital && enablecap) { x = initials->PrintInitial( x, y, rgn, currChar ); initials_x = x; @@ -279,7 +279,7 @@ video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } - free( tmp ); + delete[] tmp; } void Font::Print(Region rgn, const unsigned char* string, Palette* hicolor, @@ -312,36 +312,39 @@ sprBuffer->SetPalette( pal ); size_t len = strlen( ( char* ) string ); - char* tmp = ( char* ) malloc( len + 1 ); - memcpy( tmp, ( char * ) string, len + 1 ); + + unsigned short* tmp = new unsigned short[len+1]; + len = GetDoubleByteString((char*)string, tmp, len); + SetupString( tmp, len, rgn.w, NoColor ); + while (len > 0 && (tmp[len - 1] == '\n' || tmp[len - 1] == '\r')) { // ignore trailing newlines tmp[len - 1] = 0; len--; } - SetupString( tmp, rgn.w, NoColor ); int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { for (size_t i = 0; i < len; i++) { if (tmp[i] == 0) continue; - int height = yPos[( unsigned char ) tmp[i] - 1]; + int height = yPos[tmp[i] - 1]; if (ystep < height) ystep = height; } } else { ystep = size[1].h; } + if (!ystep) ystep = maxHeight; int x = psx, y = ystep; Video* video = core->GetVideoDriver(); if (Alignment & IE_FONT_ALIGN_CENTER) { - int w = CalcStringWidth( tmp, NoColor ); + int w = CalcStringWidth( len, tmp, NoColor ); x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { - int w = CalcStringWidth( tmp, NoColor ); + int w = CalcStringWidth( len, tmp, NoColor ); x = ( rgn.w - w ); } @@ -364,8 +367,9 @@ } else if (Alignment & IE_FONT_ALIGN_TOP) { y += 5; } + for (size_t i = 0; i < len; i++) { - if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { + if (tmp[i] == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; @@ -413,7 +417,7 @@ if (tmp[i] == 0) { y += ystep; x = psx; - int w = CalcStringWidth( &tmp[i + 1], NoColor ); + int w = CalcStringWidth(len-i-1, &tmp[i + 1],NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { @@ -421,7 +425,8 @@ } continue; } - unsigned char currChar = ( unsigned char ) tmp[i] - 1; + unsigned short currChar = tmp[i] - 1; + if (initials && capital) { x = initials->PrintInitial( x, y, rgn, currChar ); enablecap=false; @@ -437,10 +442,11 @@ if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); } - free( tmp ); + delete[] tmp; + } -int Font::PrintInitial(int x, int y, const Region &rgn, unsigned char currChar) const +int Font::PrintInitial(int x, int y, const Region &rgn, unsigned short currChar) const { Video *video = core->GetVideoDriver(); video->BlitSpriteRegion( sprBuffer, size[currChar], @@ -449,38 +455,65 @@ return x; } +size_t Font::GetDoubleByteString(const char* string, unsigned short* dbString, size_t len) const +{ + size_t dbLen = 0; + for(size_t i=0; i<len; ++i) + { + if( (i+1 < len) && (unsigned char)string[i] > 0x80 ) + { + dbString[dbLen] = ((unsigned char)string[i]-0x81)*255 + (unsigned char)string[i+1] + 128; + ++i; + } + else + dbString[dbLen] = (unsigned char)string[i]; + ++dbLen; + } + + return dbLen; +} + int Font::CalcStringWidth(const char* string, bool NoColor) const { - size_t ret = 0, len = strlen( string ); - for (size_t i = 0; i < len; i++) { - if (( ( unsigned char ) string[i] ) == '[' && !NoColor) { + size_t len = strlen( string ); + unsigned short* dbString = new unsigned short[len+1]; + len = GetDoubleByteString(string, dbString, len); + int ret = CalcStringWidth(len, dbString, NoColor); + delete[] dbString; + return ret; +} + +int Font::CalcStringWidth(size_t len, unsigned short* string, bool NoColor) const +{ + size_t ret = 0; + for (size_t i = 0; i < len; i++) + { + if ( string[i] == '[' && !NoColor) + { i++; if (i>=len) break; - char tag[256]; - int k = 0; - for (k = 0; k < 256; k++) { - if (string[i] == ']') { - tag[k] = 0; + for (int k = 0; k < 256; k++) + { + if (string[i++] == ']') break; - } - tag[k] = string[i++]; } continue; } - ret += size[( unsigned char ) string[i] - 1].w; + ret += size[string[i] - 1].w; } return ( int ) ret; } -void Font::SetupString(char* string, unsigned int width, bool NoColor) const +void Font::SetupString(unsigned short* string, size_t len, unsigned int width, bool NoColor) const { - size_t len = strlen( string ); unsigned int psx = PARAGRAPH_START_X; int lastpos = 0; unsigned int x = psx, wx = 0; bool endword = false; - for (size_t pos = 0; pos < len; pos++) { + + for (size_t pos = 0; pos < len; pos++) + { if (x + wx > width) { if (!endword && ( x == psx )) lastpos = ( int ) pos; @@ -502,7 +535,7 @@ endword = true; continue; } - if (( ( unsigned char ) string[pos] ) == '[' && !NoColor) { + if ( string[pos] == '[' && !NoColor) { pos++; if (pos>=len) break; @@ -527,11 +560,11 @@ } if (string[pos] && string[pos] != ' ') { - string[pos] = ( unsigned char ) (string[pos] - FirstChar); + string[pos] = string[pos] - FirstChar; } - wx += size[( unsigned char ) string[pos] - 1].w; - if (( string[pos] == ' ' ) || ( string[pos] == '-' )) { + wx += size[ string[pos] - 1].w; + if (( string[pos] == ' ' ) || ( string[pos] == '-') || (string[pos] >= 128) ) { x += wx; wx = 0; lastpos = ( int ) pos; diff -Nur gemrb-0.6.4/gemrb/core/Font.h gemrb-0.6.4.new/gemrb/core/Font.h --- gemrb-0.6.4/gemrb/core/Font.h 2011-03-27 16:08:09.000000000 +0000 +++ gemrb-0.6.4.new/gemrb/core/Font.h 2011-03-29 03:42:52.000000000 +0000 @@ -64,8 +64,8 @@ Sprite2D* sprBuffer; unsigned char FirstChar; - short xPos[256]; - short yPos[256]; + short *xPos; + short *yPos; // For the temporary bitmap unsigned char* tmpPixels; @@ -74,11 +74,11 @@ /** ResRef of the Font image */ ieResRef ResRef; int maxHeight; - Region size[256]; + Region *size; public: - Font(int w, int h, Palette* palette); + Font(int w, int h, Palette* palette, int maxCount); ~Font(void); - void AddChar(unsigned char* spr, int w, int h, short xPos, short yPos); + void AddChar(int line, int row, int charW, int charH, unsigned char* spr, int w, int h, short xPos, short yPos); /** Call this after adding all characters */ void FinalizeSprite(bool cK, int index); @@ -99,13 +99,16 @@ void SetPalette(Palette* pal); /** Returns width of the string rendered in this font in pixels */ int CalcStringWidth(const char* string, bool NoColor = false) const; - void SetupString(char* string, unsigned int width, bool NoColor = false) const; + int CalcStringWidth(size_t len, unsigned short* string, bool NoColor = false) const; + + void SetupString(unsigned short* string, size_t len, unsigned int width, bool NoColor = false) const; + size_t GetDoubleByteString(const char* string, unsigned short* dbString, size_t len) const; /** Sets ASCII code of the first character in the font. * (it allows remapping numeric fonts from \000 to '0') */ void SetFirstChar(unsigned char first); private: - int PrintInitial(int x, int y, const Region &rgn, unsigned char currChar) const; + int PrintInitial(int x, int y, const Region &rgn, unsigned short currChar) const; }; #endif diff -Nur gemrb-0.6.4/gemrb/core/GUI/TextArea.cpp gemrb-0.6.4.new/gemrb/core/GUI/TextArea.cpp --- gemrb-0.6.4/gemrb/core/GUI/TextArea.cpp 2011-03-27 16:08:09.000000000 +0000 +++ gemrb-0.6.4.new/gemrb/core/GUI/TextArea.cpp 2011-03-29 03:43:13.000000000 +0000 @@ -712,11 +712,12 @@ // rows++; tr = 0; int len = ( int ) strlen( lines[i] ); - char* tmp = (char *) malloc( len + 1 ); - memcpy( tmp, lines[i], len + 1 ); - ftext->SetupString( tmp, w ); + + unsigned short* tmp = new unsigned short[len+1]; + len = ftext->GetDoubleByteString(lines[i], tmp, len); + ftext->SetupString( tmp, len, w ); for (int p = 0; p <= len; p++) { - if (( ( unsigned char ) tmp[p] ) == '[') { + if ( tmp[p] == '[') { p++; //char tag[256]; int k = 0; @@ -739,7 +740,7 @@ } lrows[i] = tr; rows += tr; - free( tmp ); + delete[] tmp; } } diff -Nur gemrb-0.6.4/gemrb/core/Interface.cpp gemrb-0.6.4.new/gemrb/core/Interface.cpp --- gemrb-0.6.4/gemrb/core/Interface.cpp 2011-03-27 16:08:09.000000000 +0000 +++ gemrb-0.6.4.new/gemrb/core/Interface.cpp 2011-03-29 07:44:25.000000000 +0000 @@ -468,6 +468,14 @@ // Removing all stuff from Cache, except bifs if (!KeepCache) DelTree((const char *) CachePath, true); + + if( fontReplaces.size() > 0 ) + { + for(unsigned int l=0; l<fontReplaces.size(); ++l) + { + delete fontReplaces[l]; + } + } } void Interface::SetWindowFrame(int i, Sprite2D *Picture) @@ -2283,6 +2291,19 @@ CONFIG_PATH("PluginsPath", PluginsPath); CONFIG_PATH("SavePath", SavePath); #undef CONFIG_PATH +#define CONFIG_FONT_REPLACE(str) \ + } else if (stricmp(name, str) == 0 ) { \ + FontReplace *fr = new FontReplace; \ + strncpy(fr->oragin, name, 15 ); \ + fr->oragin[15] = 0; \ + strncpy(fr->dest, value, 15 ); \ + fr->dest[15] = 0; \ + fontReplaces.push_back(fr); + CONFIG_FONT_REPLACE("STONEBIG"); + CONFIG_FONT_REPLACE("STONESML"); + CONFIG_FONT_REPLACE("TOOLFONT"); + CONFIG_FONT_REPLACE("FLOATTEXT"); +#undef CONFIG_FONT_REPLACE } else if (stricmp( name, "ModPath" ) == 0) { for (char *path = strtok(value,SPathListSeparator); path; @@ -2675,6 +2696,17 @@ /** Returns a preloaded Font */ Font* Interface::GetFont(const char *ResRef) const { + printf("ResRef = %s\n", ResRef); + for(unsigned int l=0; l<fontReplaces.size(); ++l) + { + if(strnicmp(ResRef, fontReplaces[l]->oragin,15) == 0 ) + { + ResRef = fontReplaces[l]->dest; + printf("replace = %s\n", ResRef); + break; + } + } + for (unsigned int i = 0; i < fonts.size(); i++) { if (strnicmp( fonts[i]->ResRef, ResRef, 8 ) == 0) { return fonts[i]; @@ -2688,6 +2720,22 @@ if (index >= fonts.size()) { return NULL; } + + printf("index = %d ResRef = %s \n", index, fonts[index]->ResRef); + for(unsigned int l=0; l<fontReplaces.size(); ++l) + { + if(strnicmp(fonts[index]->ResRef, fontReplaces[l]->oragin,15) == 0 ) + { + for (unsigned int i = 0; i < fonts.size(); i++) { + if (strnicmp( fonts[i]->ResRef, fontReplaces[l]->dest, 8 ) == 0) { + printf("replace to index = %d ResRef = %s \n", i, fonts[i]->ResRef); + return fonts[i]; + } + } + return NULL; + } + } + return fonts[index]; } diff -Nur gemrb-0.6.4/gemrb/core/Interface.h gemrb-0.6.4.new/gemrb/core/Interface.h --- gemrb-0.6.4/gemrb/core/Interface.h 2011-03-27 16:08:09.000000000 +0000 +++ gemrb-0.6.4.new/gemrb/core/Interface.h 2011-03-29 07:25:26.000000000 +0000 @@ -271,6 +271,11 @@ * @class Interface * Central interconnect for all GemRB parts, driving functions and utility functions possibly belonging to a better place */ +struct FontReplace +{ + char oragin[16]; + char dest[16]; +}; class GEM_EXPORT Interface { @@ -284,6 +289,7 @@ Image * pal32; Image * pal16; std::vector<Font*> fonts; + std::vector<FontReplace*> fontReplaces; EventMgr * evntmgr; Holder<WindowMgr> windowmgr; Window* ModalWindow; diff -Nur gemrb-0.6.4/gemrb/plugins/BAMImporter/BAMImporter.cpp gemrb-0.6.4.new/gemrb/plugins/BAMImporter/BAMImporter.cpp --- gemrb-0.6.4/gemrb/plugins/BAMImporter/BAMImporter.cpp 2011-03-27 16:08:09.000000000 +0000 +++ gemrb-0.6.4.new/gemrb/plugins/BAMImporter/BAMImporter.cpp 2011-03-29 03:42:39.000000000 +0000 @@ -317,58 +317,56 @@ /** This function will load the Animation as a Font */ Font* BAMImporter::GetFont() { - unsigned int i; + unsigned int i,j; int w = 0, h = 0; unsigned int Count; ieWord *FLT = CacheFLT(Count); - // Numeric fonts have all frames in single cycle - if (CyclesCount > 1) { - Count = CyclesCount; - } else { - Count = FramesCount; - } - - for (i = 0; i < Count; i++) { - unsigned int index; - if (CyclesCount > 1) { - index = FLT[cycles[i].FirstFrame]; - if (index >= FramesCount) - continue; - } else { - index = i; + unsigned int index; + unsigned int curFrame; + int charH = 0; + int charW = 0; + int maxFramesCount = 0; + Count = 0; + for(i=0; i<CyclesCount; ++i) + { + if( cycles[i].FramesCount > maxFramesCount ) + maxFramesCount = cycles[i].FramesCount; + curFrame = cycles[i].FirstFrame; + for(j=0; j<cycles[i].FramesCount; ++j,++curFrame) + { + ++Count; + index = FLT[curFrame]; + if( frames[index].Width > charW ) + charW = frames[index].Width; + if (frames[index].Height > charH) + charH = frames[index].Height; } - - w = w + frames[index].Width; - if (frames[index].Height > h) - h = frames[index].Height; } + + w = charW * maxFramesCount; + h = charH * CyclesCount; + Font* fnt = new Font( w, h, palette, Count); + + for(i=0; i<CyclesCount; ++i) + { + curFrame = cycles[i].FirstFrame; + for(j=0; j<cycles[i].FramesCount; ++j,++curFrame) + { + index = FLT[curFrame]; + unsigned char* pixels = (unsigned char*)GetFramePixels( index ); - Font* fnt = new Font( w, h, palette ); - for (i = 0; i < Count; i++) { - unsigned int index; - if (CyclesCount > 1) { - index = FLT[cycles[i].FirstFrame]; - if (index >= FramesCount) { - fnt->AddChar( NULL, 0, 0, 0, 0 ); - continue; - } - } else { - index = i; - } - - unsigned char* pixels = (unsigned char*)GetFramePixels( index ); - if( !pixels) { - fnt->AddChar( NULL, 0, 0, 0, 0 ); - continue; - } - fnt->AddChar( pixels, frames[index].Width, + fnt->AddChar(i, j, charH, charW, pixels, frames[index].Width, frames[index].Height, frames[index].XPos, frames[index].YPos ); - free( pixels ); + + if( pixels ) + free( pixels ); + + } } free( FLT ); Link to comment
lynx Posted March 29, 2011 Share Posted March 29, 2011 Nice! I think you could simplify it a bit by modifying gemrb/override/bg1/gemrb.ini and gemrb/override/bg1/fonts.2da, though then they'd have to be distributed differently. The hint could maybe come from our gametype autodetection phase and then nothing would need to be added to gemrb.cfg. Link to comment
Guest Edheldil Posted March 29, 2011 Share Posted March 29, 2011 Hi, what is that simplified chinese version of BG? Is it something officially released (with perhaps its own version of the engine), or a fan-made patch that works with the US version of BG and does not work with GemRB? Info, info And would you perhaps contribute some screenshots, manifests or a CD-cover for my collection at http://www.eowyn.cz/gemrb/ ? Thanks :-) Link to comment
Guest ljd3000 Posted March 29, 2011 Share Posted March 29, 2011 it's officially release, use chinese dialog.tlk and chinese fonts (REALMS.bam NORMAL.bam). but the translation from english to chinses is not very good, a lot error. so , some fan makes cirrect patch dialog.tlk. GemRB can't display chinese font , because chinise font is double byte, so i make the patch. some picture: cd cover: Link to comment
Avenger Posted March 29, 2011 Share Posted March 29, 2011 Yes, we should support the double byte stuff. I guess, we just need the bam file(s). And some samples how they should look like (using characters over 256). Link to comment
Guest ljd3000 Posted March 29, 2011 Share Posted March 29, 2011 Nice! I think you could simplify it a bit by modifying gemrb/override/bg1/gemrb.ini and gemrb/override/bg1/fonts.2da, though then they'd have to be distributed differently. The hint could maybe come from our gametype autodetection phase and then nothing would need to be added to gemrb.cfg. I'll have a try. Link to comment
Guest ljd3000 Posted April 2, 2011 Share Posted April 2, 2011 find a bug on patch. shuld add this line in GetDoubleByteString before return dbString[dbLen] = 0; Link to comment
Guest ljd3000 Posted April 2, 2011 Share Posted April 2, 2011 another bug in font.cpp patch in Font::Font change maxHeight = h; to maxHeight = 0; in Font::AddChar add this lines before return if( maxHeight < h ) maxHeight = h; Link to comment
lynx Posted April 2, 2011 Share Posted April 2, 2011 It's better to reupload the diff. If you're not experienced with git, then just use a pastebin (eg. pastebin.com) to dump the diff and save the forum layout. It can syntax highlight too. Do portrait icons work (the stuff you get when wearing magic items or when you're poisoned or in some other special state)? They are also done via a special font which has glyphs over the 128 margin. Link to comment
Guest Micru Posted August 29, 2011 Share Posted August 29, 2011 There is a patch to convert Planescape: Torment into traditional Chinese: http://goo.gl/99IJs It was created just by taking the files from the original localized version. In this patch a "setfont.exe" program is supplied, but I don't understand what it does. It would be great if someone could try it and see if it works (for me in win7, it doesn't) and maybe translate this screenshot: And how does it work exactly? Is there any pre-generated BAM/bitfont or the fonts are taken straight from the operative system? Link to comment
MephistoSatanDevil Posted October 26, 2011 Share Posted October 26, 2011 There is a patch to convert Planescape: Torment into traditional Chinese: http://goo.gl/99IJsIt was created just by taking the files from the original localized version. In this patch a "setfont.exe" program is supplied, but I don't understand what it does. It would be great if someone could try it and see if it works (for me in win7, it doesn't) and maybe translate this screenshot: And how does it work exactly? Is there any pre-generated BAM/bitfont or the fonts are taken straight from the operative system? There are three different fonts can be used in the game, use this program to change the font to display. like this Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.