This is an overhaul to the NetHack drawing mechanism. - eliminates the need to have separate lists in drawing.c for the things and their associated explanations by grouping those thing together on the same inializer in a struct. - replaces all of these options: IBMgraphics, DECgraphics, MACgraphics, graphics, monsters, objects, boulder, traps, effects - drawing.c contains only the set of NetHack standard symbols for the main game and a set of NetHack standard symbols for the roguelevel. - introduces a symbols file that contains named sets of symbols that can be loaded at run time making it extensible for situations like multinational code pages like those reported by <Someone>, without hardcoding additional sets into the game code. - symbols file uses names for the symbols, so offsets will not break when new things are introduced into the game, the way the older config file uchar load routines did. - symbols file only contains exceptions to the standard NetHack set, not entire sets so they are much less verbose than all of the g_FILLER() entries that were previously in drawing.c - 'symset' and 'roguesymset' config file options for preselecting a symbol set from the file called 'symbols' at startup time. The name of the symbols file is not under the users control, only the symbol set name desired from within the symbols file is. - 'symset' config file option loads a desired symbol set for everything but the rogue level. - 'roguesymset' config file option loads a desired symbol set for the rogue level. - 'SYMBOLS' config file option allows the user to specify replacement symbols on a per symbol basis. You can specify as many or as few symbols as you wish. The symbols are identified by a name:value pair, and line continuation is supported. Multiple symbol assignments can be made on the same line if each name:value pair is separated by a comma. For example: SYMBOLS = S_bars:\xf0, S_tree: \xf1, S_room:\xfa \ S_fountain:\xf4 \ S_boulder:0 - 'symbols' file has the following structure: start: DECgraphics Handling: DEC S_vwall: \xf8 # meta-x, vertical rule S_hwall: \xf1 # meta-q, horizontal rule finish start: IBMgraphics Handling: IBM S_vwall: \xb3 # meta-3, vertical rule S_hwall: \xc4 # meta-D, horizontal rule finish - 'symbols' file added to the source tree in the dat directory - Port Makefiles/scripts will need to be adjusted to move them into HACKDIR destination
179 lines
6.6 KiB
C
179 lines
6.6 KiB
C
/* SCCS Id: @(#)mhfont.c 3.5 2005/01/23 */
|
|
/* Copyright (C) 2001 by Alex Kompel */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
/* font management and such */
|
|
|
|
#include "mhfont.h"
|
|
|
|
#define MAXFONTS 64
|
|
|
|
/* font table - 64 fonts ought to be enough */
|
|
static struct font_table_entry {
|
|
int code;
|
|
HFONT hFont;
|
|
} font_table[MAXFONTS] ;
|
|
static int font_table_size = 0;
|
|
HFONT version_splash_font;
|
|
HFONT extrainfo_splash_font;
|
|
|
|
#define NHFONT_CODE(win, attr) (((attr&0xFF)<<8)|(win_type&0xFF))
|
|
|
|
static void __cdecl font_table_cleanup(void);
|
|
|
|
/* create font based on window type, charater attributes and
|
|
window device context */
|
|
HGDIOBJ mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace)
|
|
{
|
|
HFONT fnt = NULL;
|
|
LOGFONT lgfnt;
|
|
int font_size;
|
|
int font_index;
|
|
static BOOL once = FALSE;
|
|
|
|
if( !once ) {
|
|
once = TRUE;
|
|
atexit(font_table_cleanup);
|
|
}
|
|
|
|
ZeroMemory( &lgfnt, sizeof(lgfnt) );
|
|
|
|
/* try find font in the table */
|
|
for(font_index=0; font_index<font_table_size; font_index++)
|
|
if(NHFONT_CODE(win_type, attr)==font_table[font_index].code)
|
|
break;
|
|
|
|
if( !replace && font_index<font_table_size )
|
|
return font_table[font_index].hFont;
|
|
|
|
switch(win_type) {
|
|
case NHW_STATUS:
|
|
lgfnt.lfHeight = -iflags.wc_fontsiz_status*GetDeviceCaps(hdc, LOGPIXELSY)/72; // height of font
|
|
lgfnt.lfWidth = 0; // average character width
|
|
lgfnt.lfEscapement = 0; // angle of escapement
|
|
lgfnt.lfOrientation = 0; // base-line orientation angle
|
|
lgfnt.lfWeight = FW_NORMAL; // font weight
|
|
lgfnt.lfItalic = FALSE; // italic attribute option
|
|
lgfnt.lfUnderline = FALSE; // underline attribute option
|
|
lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
|
|
lgfnt.lfCharSet = mswin_charset(); // character set identifier
|
|
lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
|
|
lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
|
|
lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
|
|
if( iflags.wc_font_status &&
|
|
*iflags.wc_font_status ) {
|
|
lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
|
|
NH_A2W( iflags.wc_font_status, lgfnt.lfFaceName, LF_FACESIZE);
|
|
} else {
|
|
lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family
|
|
}
|
|
break;
|
|
|
|
case NHW_MENU:
|
|
lgfnt.lfHeight = -iflags.wc_fontsiz_menu*GetDeviceCaps(hdc, LOGPIXELSY)/72; // height of font
|
|
lgfnt.lfWidth = 0; // average character width
|
|
lgfnt.lfEscapement = 0; // angle of escapement
|
|
lgfnt.lfOrientation = 0; // base-line orientation angle
|
|
lgfnt.lfWeight = (attr==ATR_BOLD || attr==ATR_INVERSE)? FW_BOLD : FW_NORMAL; // font weight
|
|
lgfnt.lfItalic = (attr==ATR_BLINK)? TRUE: FALSE; // italic attribute option
|
|
lgfnt.lfUnderline = (attr==ATR_ULINE)? TRUE : FALSE; // underline attribute option
|
|
lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
|
|
lgfnt.lfCharSet = mswin_charset(); // character set identifier
|
|
lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
|
|
lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
|
|
lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
|
|
if( iflags.wc_font_menu &&
|
|
*iflags.wc_font_menu ) {
|
|
lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
|
|
NH_A2W( iflags.wc_font_menu, lgfnt.lfFaceName, LF_FACESIZE);
|
|
} else {
|
|
lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family
|
|
}
|
|
break;
|
|
|
|
case NHW_MESSAGE:
|
|
font_size = (attr==ATR_INVERSE)? iflags.wc_fontsiz_message+1 : iflags.wc_fontsiz_message;
|
|
lgfnt.lfHeight = -font_size*GetDeviceCaps(hdc, LOGPIXELSY)/72; // height of font
|
|
lgfnt.lfWidth = 0; // average character width
|
|
lgfnt.lfEscapement = 0; // angle of escapement
|
|
lgfnt.lfOrientation = 0; // base-line orientation angle
|
|
lgfnt.lfWeight = (attr==ATR_BOLD || attr==ATR_INVERSE)? FW_BOLD : FW_NORMAL; // font weight
|
|
lgfnt.lfItalic = (attr==ATR_BLINK)? TRUE: FALSE; // italic attribute option
|
|
lgfnt.lfUnderline = (attr==ATR_ULINE)? TRUE : FALSE; // underline attribute option
|
|
lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
|
|
lgfnt.lfCharSet = mswin_charset(); // character set identifier
|
|
lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
|
|
lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
|
|
lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
|
|
if( iflags.wc_font_message &&
|
|
*iflags.wc_font_message ) {
|
|
lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
|
|
NH_A2W( iflags.wc_font_message, lgfnt.lfFaceName, LF_FACESIZE);
|
|
} else {
|
|
lgfnt.lfPitchAndFamily = VARIABLE_PITCH; // pitch and family
|
|
}
|
|
break;
|
|
|
|
case NHW_TEXT:
|
|
lgfnt.lfHeight = -iflags.wc_fontsiz_text*GetDeviceCaps(hdc, LOGPIXELSY)/72; // height of font
|
|
lgfnt.lfWidth = 0; // average character width
|
|
lgfnt.lfEscapement = 0; // angle of escapement
|
|
lgfnt.lfOrientation = 0; // base-line orientation angle
|
|
lgfnt.lfWeight = (attr==ATR_BOLD || attr==ATR_INVERSE)? FW_BOLD : FW_NORMAL; // font weight
|
|
lgfnt.lfItalic = (attr==ATR_BLINK)? TRUE: FALSE; // italic attribute option
|
|
lgfnt.lfUnderline = (attr==ATR_ULINE)? TRUE : FALSE; // underline attribute option
|
|
lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
|
|
lgfnt.lfCharSet = mswin_charset(); // character set identifier
|
|
lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
|
|
lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
|
|
lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
|
|
if( iflags.wc_font_text &&
|
|
*iflags.wc_font_text ) {
|
|
lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
|
|
NH_A2W( iflags.wc_font_text, lgfnt.lfFaceName, LF_FACESIZE);
|
|
} else {
|
|
lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family
|
|
}
|
|
break;
|
|
}
|
|
|
|
fnt = CreateFontIndirect(&lgfnt);
|
|
|
|
/* add font to the table */
|
|
if( font_index==font_table_size ) {
|
|
if( font_table_size>=MAXFONTS ) panic( "font table overflow!" );
|
|
font_table_size++;
|
|
} else {
|
|
DeleteObject(font_table[font_index].hFont);
|
|
}
|
|
|
|
font_table[font_index].code = NHFONT_CODE(win_type, attr);
|
|
font_table[font_index].hFont = fnt;
|
|
return fnt;
|
|
}
|
|
|
|
UINT mswin_charset()
|
|
{
|
|
CHARSETINFO cis;
|
|
if( SYMHANDLING("IBM") )
|
|
if( TranslateCharsetInfo((DWORD*)GetOEMCP(), &cis, TCI_SRCCODEPAGE) )
|
|
return cis.ciCharset;
|
|
else
|
|
return OEM_CHARSET;
|
|
else
|
|
if( TranslateCharsetInfo((DWORD*)GetACP(), &cis, TCI_SRCCODEPAGE) )
|
|
return cis.ciCharset;
|
|
else
|
|
return ANSI_CHARSET;
|
|
}
|
|
|
|
void __cdecl font_table_cleanup(void)
|
|
{
|
|
int i;
|
|
for(i=0; i<font_table_size; i++) {
|
|
DeleteObject(font_table[i].hFont);
|
|
}
|
|
font_table_size = 0;
|
|
}
|
|
|