点阵显示汉字:在游戏中显示GBK点阵汉字



  大家注意到没有RA2中文版本使用是GBK点阵字库这样做有个好处:不管玩家是用简体还是繁体都能识别显示文字

   GBK意思大概是“国家标准汉字扩展集”吧记不清了但它确是个好东东比GB2312、BIG5什么强多了它包括GB2312、GBK所有而且还补充了很多字另外还包括日文、朝鲜文以及大量符号

   我在UCDOS for win版本里面找到了GBK点阵字库(HZK12.GBK、HZK14.GBK、HZK16.GBK)分析了知道了结构这里是我写个演示编译需要有sdl库遵循“惯例”按F4切换全屏/窗口状态Esc退出把标准输出和标准重定向到\"stdout.txt\"和\"stderr.txt\"中


# <time.h>
# <stdio.h>
# <stdlib.h>
# <windows.h>

# \"sdl.h\"
# \"SDL_image.h\"
# \"sfont.h\"

//---------------------------------------------------------------------------
# STDOUT_FILE \"stdout.txt\"
# STDERR_FILE \"stderr.txt\"

SDL_Surface *screen;
U32 fps;
U32 AppStartTime = 0;
U32 frame_count = 0;
U32 frames;

SDL_Event event;
SDL_Surface * SetMode( Width, Height, BPP, Flags );
SDL_Surface * LoadBMP( char * filename );
void MainLoops( ( * EventFunc)( ), void ( * DrawFunc )( ), DelayTime );
void Blt( SDL_Surface * image, x, y );
void TileBlt( SDL_Surface * image, x, y );
void SetTransparentColor( SDL_Surface * sprite, R, G, B );
void IoRedirect( );
void cleanup_output( );
void initfps;

//---------------------------------------------------------------------------
U8 HZK12[574560];
U8 HZK14[670320];
U8 HZK16[766080];
BOOL HZ_Init;
BOOL HZ_TextOut( SDL_Surface * image, x, y, width, space, unsigned char * str );
//---------------------------------------------------------------------------

ProcessEvent( );
void DrawFrame( );

SDL_Surface * bg, * font;
ix, iy, jx, jy;
Width = 640;
Height = 480;
bpp = 16;
ScreenMode = 0;

WINAPI WinMain(HINSTANCE hInstPre, HINSTANCE hInstance, LPSTR cmd, xxx )
{
char TimeString[256];
time_t timer;
struct tm *tblock;

HZ_Init;
IoRedirect( );
frames = 0;
timer = time(NULL);
tblock = localtime(&timer);
strftime( TimeString, 256, \"Time=%Z: %Y-%m-%d %a %H:%M:%S\", tblock );
prf( \"%s\\n\", TimeString );

SetMode( Width, Height, bpp, SDL_SWSURFACE|ScreenMode );
SDL_ShowCursor(0);
SDL_WM_SetCaption( \"demo\", \"demo\" );

bg = IMG_Load( \".\\\\2k_bg.g\" );
font = IMG_Load( \".\\\\small.g\" );

InitFont(font);
SDL_SetAlpha( font, SDL_SRCALPHA|SDL_RLEACCEL, 127 );

ix=iy=0;
jx=jy= Height>>1;
srand( (U32)timer );

MainLoops( ProcessEvent, DrawFrame, 0 );

prf( \"ScreenMode=%d*%d*%d\\nFPS=%u\", Width, Height, bpp, fps );

0;
}

ProcessEvent( )
{
U8 *keystate;

keystate = SDL_GetKeyState( NULL );
( ( keystate[SDLK_ESCAPE] ) || ( keystate[SDLK_q] ) )
0;
( keystate[SDLK_F4] )
{
( ScreenMode )
ScreenMode = 0;

ScreenMode = SDL_FULLSCREEN;

SetMode( Width, Height, bpp, SDL_SWSURFACE|ScreenMode );
initfps( );
}

1;
}

void DrawFrame( )
{
char tmp[256];
step = 4;

//
sprf( tmp, \"TotalFrame=%u\", frames );

TileBlt( bg, 0, 0 );

SDL_SetAlpha( font, SDL_SRCALPHA|SDL_RLEACCEL, 4 );
PutString( screen, ix % Width - 6, iy % Height - 6, tmp );
SDL_SetAlpha( font, SDL_SRCALPHA|SDL_RLEACCEL, 8 );
PutString( screen, ix % Width - 5, iy % Height - 5, tmp );
SDL_SetAlpha( font, SDL_SRCALPHA|SDL_RLEACCEL, 16 );
PutString( screen, ix % Width - 4, iy % Height - 4, tmp );
SDL_SetAlpha( font, SDL_SRCALPHA|SDL_RLEACCEL, 32 );
PutString( screen, ix % Width - 3, iy % Height - 3, tmp );
SDL_SetAlpha( font, SDL_SRCALPHA|SDL_RLEACCEL, 64 );
PutString( screen, ix % Width - 2, iy % Height - 2, tmp );
SDL_SetAlpha( font, SDL_SRCALPHA|SDL_RLEACCEL, 128 );
PutString( screen, ix % Width - 1, iy % Height - 1, tmp );
SDL_SetAlpha( font, SDL_SRCALPHA|SDL_RLEACCEL, 192 );
PutString( screen, ix % Width, iy % Height, tmp );

PutString( screen, ix % Width, iy % Height + 40, tmp );

( rand( ) % 400 < 2 )
{
jx = rand( ) % ( Width - 10 );
jy = rand( ) % ( Height - 10 );
}

sprf( tmp, \"FPS=%d\", fps );
PutString( screen, 7, 7, tmp );
//聞波2000 
HZ_TextOut( screen, 10, 300, 16, 0, \"十步殺千里不留行\");
HZ_TextOut( screen, 10, 318, 14, 0, \"十步殺千里不留行\" );
HZ_TextOut( screen, 10, 334, 12, 0, \"十步殺千里不留行\" );
ix step;
iy step;
}


//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
SDL_Surface * SetMode( Width, Height, BPP, Flags )
{
/* Initialize the SDL library */
( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
fprf(stderr, \"Couldn\'t initialize SDL: %s\\n\", SDL_GetError( ) );
NULL;
}

/* Clean up _disibledevent=> ( screen NULL )
{
fprf( stderr, \"Couldn\'t %dx%dx%d video mode: %s\\n\", Width, Height, BPP, SDL_GetError( ) );
}

screen;
}
//---------------------------------------------------------------------------

void initfps( )
{
AppStartTime = SDL_GetTicks;
frame_count = 0;
}
//---------------------------------------------------------------------------

void MainLoops( ( * EventFunc)( ), void ( * DrawFunc)( ), DelayTime )
{
( EventFunc&&DrawFunc )
{
mem( &event, 0, ( SDL_Event ) );
initfps( );

while( EventFunc( ) )
{
SDL_PollEvent(&event);
( event.type SDL_ACTIVEEVENT )
{
( ( ( event.active.state & SDL_APPACTIVE ) FALSE ) ||
( event.active.gain FALSE ) )
initfps( );
}
SDL_PumpEvents;
DrawFunc( );
SDL_UpdateRect(screen,0, 0, 0, 0);
frame_count ;
frames ;
fps = frame_count * 1000 / ( SDL_GetTicks( ) - AppStartTime );
( DelayTime ) SDL_Delay( DelayTime );
}
}
}
//---------------------------------------------------------------------------

SDL_Surface * LoadBMP( char * filename )
{
SDL_Surface * imagebmp, * image;

imagebmp = SDL_LoadBMP( filename );
( imagebmp NULL )
NULL;

( imagebmp->format->palette != NULL )
{
SDL_SetColors( screen, imagebmp->format->palette->colors, 0, imagebmp->format->palette->ncolors );
}

/* Convert the image to the video format (maps colors) */
image = SDL_DisplayFormat( imagebmp );
SDL_FreeSurface( imagebmp );

image;
}
//---------------------------------------------------------------------------

void Blt( SDL_Surface * image, x, y )
{
Row, Col, r, c, shtx, shty;
SDL_Rect dest, src;

/* out of screen */
( ( x > screen->w ) || ( y > screen->h ) ||
( x + image->w < 1 ) || ( y + image->h < 1 ) )
;

src.x = 0;
src.y = 0;
src.w = image->w;
src.h = image->h;
dest.x = x;
dest.y = y;
dest.w = src.w;
( y < 0 )
{
src.y = 0 - y;
src.h = image->h + src.y;
dest.y = 0;
}
dest.h = src.h;

SDL_BlitSurface( image, &src, screen, &dest );
}
//---------------------------------------------------------------------------

void TileBlt( SDL_Surface * image, x, y )
{
Row, Col, r, c, shtx, shty;
SDL_Rect dest, src;

shtx = x % image->w;
shty = y % image->h;

( shtx >0 ) shtx -= image->w;
( shty >0 ) shty -= image->h;

Row = screen->h / image->h + 2;
Col = screen->w / image->w + 2;

dest.x = 0;
dest.y = 0;
dest.w = image->w;
dest.h = image->h;
src.x = 0;
src.y = 0;
src.w = image->w;
src.h = image->h;

for ( r = 0; r < Row; r )
{
( r )
{
src.y = 0;
src.h = image->h;
dest.h = image->h;
dest.y = image->h * r + shty;
}

{ /* first line ? */
src.y = 0 - shty;
src.h = image->h;
dest.h = image->h + shty;
dest.y = 0;
}

for ( c = 0; c < Col; c )
{
dest.x = image->w * c + shtx;
SDL_BlitSurface( image, &src, screen, &dest );
}
}
}
//---------------------------------------------------------------------------

void SetTransparentColor( SDL_Surface * sprite, R, G, B )
{
SDL_SetColorKey( sprite, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB( sprite->format, R, G, B ) );
}
//---------------------------------------------------------------------------

/* Remove the output files there was no output written */
void cleanup_output( )
{
FILE *file;
empty;

/* Flush the output in anything is queued */
fclose(stdout);
fclose(stderr);

/* See the files have any output in them */
file = fopen(STDOUT_FILE, \"rb\");
( file )
{
empty = (fgetc(file) EOF) ? 1 : 0;
fclose(file);
( empty )
remove(STDOUT_FILE);
}
file = fopen(STDERR_FILE, \"rb\");
( file )
{
empty = (fgetc(file) EOF) ? 1 : 0;
fclose(file);
( empty )
remove(STDERR_FILE);
}


}
//---------------------------------------------------------------------------

void IoRedirect( )
{
FILE *fp;

/* Redirect standard standard output */
fp = freopen(STDOUT_FILE, \"w\", stdout);
( fp NULL )
{ /* This happens _disibledevent=>#
fp = fopen(STDOUT_FILE, \"w\");
( fp ) *stdout = *fp;
#end
}

/* Redirect standard standard error */
fp = freopen(STDERR_FILE, \"w\", stderr);
( fp NULL )
{ /* This happens _disibledevent=>#
fp = fopen(STDERR_FILE, \"w\");
( fp ) *stderr = *fp;
#end
}

vbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */
buf(stderr, NULL); /* No buffering */
atexit(cleanup_output);
}
//---------------------------------------------------------------------------

BOOL HZ_Init
{
FILE * file;

file = fopen( \".\\\\HZK16.GBK\", \"rb\" );
fread( HZK16, 32, 0x5d84, file );
fclose( file );
file = fopen( \".\\\\HZK14.GBK\", \"rb\" );
fread( HZK14, 28, 0x5d84, file );
fclose( file );
file = fopen( \".\\\\HZK12.GBK\", \"rb\" );
fread( HZK12, 24, 0x5d84, file );
fclose( file );

TRUE;
}
//---------------------------------------------------------------------------

BOOL HZ_TextOut( SDL_Surface * image, x, y, width, space, unsigned char * str )
{
U8 * bufptr;
U8 * HZK;
U16 Bits[16];
i,j,k, m, off = 0;
unsigned char q;
unsigned char w;

switch ( width )
{
12:
HZK = HZK12;
;
14:
HZK = HZK14;
;
16:
HZK = HZK16;
;
default:
FALSE;
}
bufptr = (unsigned char*)image->pixels;

m = strlen( str );
for ( k = 0; k < m; k 2 )
{
U32 X, Y, Z, M;
q = str[k];
w = str[k+1];

( w > 0xa0 )
{
M = 0x5e;
Y = w - 0xa1;
( q > 0xa0 )
{
X = q - 0xa1;
Z = 0;
}

{
X = q - 0x81;
Z = 0x2284;
}
}

{
M = 0x60;
( w > 0x7f ) Y = w - 0x41;
Y = w - 0x40;

( q > 0xa0 )
{
X = q - 0xa1;
Z = 0x3a44;
}

{
X = q - 0x81;
Z = 0x2e44;
}
}
memcpy( Bits, HZK + ( X * M + Y + Z ) * width * 2, width * 2 );

for ( i = 0; i < width; i ) // row
{
U16 line;

line = Bits[ i ];
line = ( line >> 8 ) + ( line << 8 );

for ( j = 0; j < 16 ; j ) //col
{
index;
mask = 1;

index = off + x + 16 - j - 1 + ( y + i ) * image->pitch / image->format->BytesPerPixel;
mask <<= j;
( mask & line )
{
bufptr[ index * 2 ] = 0xff;
bufptr[ index * 2 + 1 ] = 0xff;
}
}
}
off width + space;
}
TRUE;
}
//---------------------------------------------------------------------------

Tags:  汉字点阵 8x8点阵显示汉字 1616点阵显示汉字 点阵显示汉字

延伸阅读

最新评论

发表评论