分享
 
 
 

在SDL中显示GBK点阵汉字

王朝other·作者佚名  2008-05-18
窄屏简体版  字體: |||超大  

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

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

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

#include <time.h>

#include <stdio.h>

#include <stdlib.h>

#include <windows.h>

#include "sdl.h"

#include "SDL_image.h"

#include "sfont.h"

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

#define STDOUT_FILE "stdout.txt"

#define STDERR_FILE "stderr.txt"

SDL_Surface *screen;

Uint32 fps;

Uint32 AppStartTime = 0;

Uint32 frame_count = 0;

static Uint32 frames;

SDL_Event event;

SDL_Surface * SetMode( int Width, int Height, int BPP, int Flags );

SDL_Surface * LoadBMP( char * filename );

void MainLoops( int ( * EventFunc)( ), void ( * DrawFunc )( ), int DelayTime );

void Blt( SDL_Surface * image, int x, int y );

void TileBlt( SDL_Surface * image, int x, int y );

void SetTransparentColor( SDL_Surface * sprite, int R, int G, int B );

void IoRedirect( );

void cleanup_output( );

void initfps();

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

Uint8 HZK12[574560];

Uint8 HZK14[670320];

Uint8 HZK16[766080];

BOOL HZ_Init();

BOOL HZ_TextOut( SDL_Surface * image, int x, int y, int width, int space, unsigned char * str );

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

int ProcessEvent( );

void DrawFrame( );

SDL_Surface * bg, * font;

int ix, iy, jx, jy;

int Width = 640;

int Height = 480;

int bpp = 16;

int ScreenMode = 0;

WINAPI WinMain(HINSTANCE hInstPre, HINSTANCE hInstance, LPSTR cmd, int 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 );

printf( "%s\\n", TimeString );

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

SDL_ShowCursor(0);

SDL_WM_SetCaption( "demo", "demo" );

bg = IMG_Load( ".\\\\2k_bg.gif" );

font = IMG_Load( ".\\\\small.gif" );

InitFont(font);

SDL_SetAlpha( font, SDL_SRCALPHA|SDL_RLEACCEL, 127 );

ix=iy=0;

jx=jy= Height>>1;

srand( (Uint32)timer );

MainLoops( ProcessEvent, DrawFrame, 0 );

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

return 0;

}

int ProcessEvent( )

{

Uint8 *keystate;

keystate = SDL_GetKeyState( NULL );

if ( ( keystate[SDLK_ESCAPE] ) || ( keystate[SDLK_q] ) )

return 0;

if ( keystate[SDLK_F4] )

{

if ( ScreenMode )

ScreenMode = 0;

else

ScreenMode = SDL_FULLSCREEN;

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

initfps( );

}

return 1;

}

void DrawFrame( )

{

char tmp[256];

int step = 4;

//

sprintf( 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 );

if ( rand( ) % 400 < 2 )

{

jx = rand( ) % ( Width - 10 );

jy = rand( ) % ( Height - 10 );

}

sprintf( 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( int Width, int Height, int BPP, int Flags )

{

/* Initialize the SDL library */

if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )

{

fprintf(stderr, "Couldn't initialize SDL: %s\\n", SDL_GetError( ) );

return NULL;

}

/* Clean up on exit */

atexit(SDL_Quit);

/* Initialize the display in a 640x480 8-bit palettized mode */

screen = SDL_SetVideoMode( Width, Height, BPP, Flags );

if ( screen == NULL )

{

fprintf( stderr, "Couldn't set %dx%dx%d video mode: %s\\n", Width, Height, BPP, SDL_GetError( ) );

}

return screen;

}

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

void initfps( )

{

AppStartTime = SDL_GetTicks();

frame_count = 0;

}

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

void MainLoops( int ( * EventFunc)( ), void ( * DrawFunc)( ), int DelayTime )

{

if ( EventFunc&&DrawFunc )

{

memset( &event, 0, sizeof( SDL_Event ) );

initfps( );

while( EventFunc( ) )

{

SDL_PollEvent(&event);

if ( event.type == SDL_ACTIVEEVENT )

{

if ( ( ( 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 );

if ( DelayTime ) SDL_Delay( DelayTime );

}

}

}

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

SDL_Surface * LoadBMP( char * filename )

{

SDL_Surface * imagebmp, * image;

imagebmp = SDL_LoadBMP( filename );

if ( imagebmp == NULL )

return NULL;

if ( 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 );

return image;

}

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

void Blt( SDL_Surface * image, int x, int y )

{

int Row, Col, r, c, shiftx, shifty;

SDL_Rect dest, src;

/* out of screen */

if ( ( x > screen->w ) || ( y > screen->h ) ||

( x + image->w < 1 ) || ( y + image->h < 1 ) )

return;

src.x = 0;

src.y = 0;

src.w = image->w;

src.h = image->h;

dest.x = x;

dest.y = y;

dest.w = src.w;

if ( 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, int x, int y )

{

int Row, Col, r, c, shiftx, shifty;

SDL_Rect dest, src;

shiftx = x % image->w;

shifty = y % image->h;

if ( shiftx >0 ) shiftx -= image->w;

if ( shifty >0 ) shifty -= 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 ++ )

{

if ( r )

{

src.y = 0;

src.h = image->h;

dest.h = image->h;

dest.y = image->h * r + shifty;

}

else

{ /* first line ? */

src.y = 0 - shifty;

src.h = image->h;

dest.h = image->h + shifty;

dest.y = 0;

}

for ( c = 0; c < Col; c ++ )

{

dest.x = image->w * c + shiftx;

SDL_BlitSurface( image, &src, screen, &dest );

}

}

}

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

void SetTransparentColor( SDL_Surface * sprite, int R, int G, int B )

{

SDL_SetColorKey( sprite, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB( sprite->format, R, G, B ) );

}

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

/* Remove the output files if there was no output written */

static void cleanup_output( )

{

FILE *file;

int empty;

/* Flush the output in case anything is queued */

fclose(stdout);

fclose(stderr);

/* See if the files have any output in them */

file = fopen(STDOUT_FILE, "rb");

if ( file )

{

empty = (fgetc(file) == EOF) ? 1 : 0;

fclose(file);

if ( empty )

remove(STDOUT_FILE);

}

file = fopen(STDERR_FILE, "rb");

if ( file )

{

empty = (fgetc(file) == EOF) ? 1 : 0;

fclose(file);

if ( empty )

remove(STDERR_FILE);

}

}

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

void IoRedirect( )

{

FILE *newfp;

/* Redirect standard standard output */

newfp = freopen(STDOUT_FILE, "w", stdout);

if ( newfp == NULL )

{ /* This happens on NT */

#if !defined(stdout)

stdout = fopen(STDOUT_FILE, "w");

#else

newfp = fopen(STDOUT_FILE, "w");

if ( newfp ) *stdout = *newfp;

#endif

}

/* Redirect standard standard error */

newfp = freopen(STDERR_FILE, "w", stderr);

if ( newfp == NULL )

{ /* This happens on NT */

#if !defined(stderr)

stderr = fopen(STDERR_FILE, "w");

#else

newfp = fopen(STDERR_FILE, "w");

if ( newfp ) *stderr = *newfp;

#endif

}

setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */

setbuf(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 );

return TRUE;

}

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

BOOL HZ_TextOut( SDL_Surface * image, int x, int y, int width, int space, unsigned char * str )

{

Uint8 * bufptr;

Uint8 * HZK;

Uint16 Bits[16];

int i,j,k, m, offset = 0;

unsigned char q;

unsigned char w;

switch ( width )

{

case 12:

HZK = HZK12;

break;

case 14:

HZK = HZK14;

break;

case 16:

HZK = HZK16;

break;

default:

return FALSE;

}

bufptr = (unsigned char*)image->pixels;

m = strlen( str );

for ( k = 0; k < m; k +=2 )

{

Uint32 X, Y, Z, M;

q = str[k];

w = str[k+1];

if ( w > 0xa0 )

{

M = 0x5e;

Y = w - 0xa1;

if ( q > 0xa0 )

{

X = q - 0xa1;

Z = 0;

}

else

{

X = q - 0x81;

Z = 0x2284;

}

}

else

{

M = 0x60;

if ( w > 0x7f ) Y = w - 0x41;

else Y = w - 0x40;

if ( q > 0xa0 )

{

X = q - 0xa1;

Z = 0x3a44;

}

else

{

X = q - 0x81;

Z = 0x2e44;

}

}

memcpy( Bits, HZK + ( X * M + Y + Z ) * width * 2, width * 2 );

for ( i = 0; i < width; i ++ ) // row

{

Uint16 line;

line = Bits[ i ];

line = ( line >> 8 ) + ( line << 8 );

for ( j = 0; j < 16 ; j ++ ) //col

{

int index;

int mask = 1;

index = offset + x + 16 - j - 1 + ( y + i ) * image->pitch / image->format->BytesPerPixel;

mask <<= j;

if ( mask & line )

{

bufptr[ index * 2 ] = 0xff;

bufptr[ index * 2 + 1 ] = 0xff;

}

}

}

offset += width + space;

}

return TRUE;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有