大家注意到沒有,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 〈string.h>
#include "SDL.h"
#include "SDL_image.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 HZK16[766080];
bool HZ_Init();
bool HZ_TextOut( SDL_Surface * image, int x, int y, int width, int space, const 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;
int main()
{
char TimeString[256];
time_t timer;
struct tm *tblock;
HZ_Init();
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_SWSURFACEScreenMode );
SDL_ShowCursor(0);
SDL_WM_SetCaption( "demo", "demo" );
bg = IMG_Load( "2k_bg.jpg" );
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;
return 1;
}
void DrawFrame( )
{
char tmp[256];
int step = 4;
//
sprintf( tmp, "TotalFrame=%u", frames );
TileBlt( bg, 0, 0 );
if ( rand( ) % 400 < 2 )
{
jx = rand( ) % ( Width - 10 );
jy = rand( ) % ( Height - 10 );
}
sprintf( tmp, "FPS=%d", fps );
HZ_TextOut( screen, 10, 300, 12, 0, "正面面板");
HZ_TextOut( screen, 10, 318, 12, 0, "電子對抗顯示" );
HZ_TextOut( screen, 10, 334, 12, 0, "陳青山" );
HZ_TextOut( screen , 10, 380, 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_IN99v_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
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
if ( shiftx >0 ) shiftx -= image->w;
if ( shifty >0 ) shifty -= image->h;
Row = screen->h / image->h + 2;
Col = screen->w