libnds コンソールで ANK コード(日本語)表示(4)。


RGKT-NDS-STDY-020(004)


文字列内でオプション指定することで カタカナ <-> ひらがな の切替を出来るようにしました。
記号は相変わらず文字コード指定です。残念ながら。(ぉ
自分が使う分にはこれで事足りそうなのでここらで CAVE GAME の方に戻ろうかと思います。


変換オプションチェックと、カタカナとひらがな変換の箇所が後付サクサクなので若干見辛いかも知れないです。
while で NULL 文字があったら終了するようにしてるので、
添え字に+2したりしてる辺りが個人的には見苦しさをかもし出してる気がしないでもないですが。
次回、+αで弄るようなことがあれば見直したいところです。


フォントリソースは CAVE だもんね(15)。 のものを使ってます。


CAVE だもんね(15)。
http://d.hatena.ne.jp/dumbo001/20090322/1237762244

//---------------------------------------------------------------------------------
#include <nds.h>
#include <stdio.h>
#include "font.h"

// 配列要素数カウント用マクロ。
#define countof(array) (sizeof(array)/sizeof((array)[0]))

//strConvKana 関数、変換モード切替用定数
typedef enum{
	CONV_KATAKANA,
	CONV_HIRAGANA
}CONV_MODE;

//---------------------------------------------------------------------------------
// 
// ■書式
// void strConvKana(char *dst, const char *src);
// 
// ■引数
// char *dst       : 変換処理を行った文字列の保存先
// const char *src : 変換処理を行う文字列の参照先
// 
// ■説明
// 参照先 src が指す文字列に含まれる
// 半角カタカナ(ANK コード)で入力された文字列の、
// 任意箇所を 半角ひらがな(MSX 独自コード)へ変換して
// 保存先 dst が指す配列にコピーする。
// 
// ●変換オプション
// "-k" : 変換モードを 半角カタカナ にする。
// "-h" : 変換モードを 半角ひらがな にする。
// 
// ※変換オプションは文字列内に含めて(記述して)指定する。
// 記述例)
// char str[] ="イロハニホヘト-hチリヌルヲ。";
// この場合、
// "イロハニホヘト" が「半角カタカナ」に、
// "ちりぬるを。" が「半角ひらがな」に変換される。
// 
// ※デフォルトでは 半角カタカナ 変換モードが有効になっている。
// 
// ■注意
// 保存先が参照先より配列数が少ない場合を考慮してない為、
// 利用時には、参照先と同じ配列数かそれ以上の保存先を用意して使用すること。
// 参照先の文字列が終端文字を持たない場合の動作は未定義の為、
// 参照先は必ず終端文字で終わる文字列としてください。
// 参照先と保存先が重なる場合の動作は未定義の為、そのような利用は避けること。
// 
//---------------------------------------------------------------------------------
void strConvKana(char *dst, const char *src)
{
	int r = 0, w = 0;
	CONV_MODE conv_mode = CONV_KATAKANA;
	
	// NULL 文字(終端文字)を検出するまで繰り返す。
	while(src[r]){
		
		// 変換オプションの確認と切替。
		if((src[r] == '-') && ((src[r + 1] == 'k') || (src[r + 1] == 'h')) ){
			
			switch(src[r + 1]){
			case 'k':
				conv_mode = CONV_KATAKANA;
				break;
				
			case 'h':
				conv_mode = CONV_HIRAGANA;
				break;
				
			default:
				break;
			}
			
			r += 2;
				
		// カタカナ変換処理の実行。
		}else{
		
			switch(conv_mode){
				
			// 変換モード「半角ひらがな」
			// 半角カタカナ -> 半角ひらがな の変換。
			case CONV_HIRAGANA:
				
				// "ヲ〜ッ" または "ア〜ソ" の範囲だった場合、ひらがなへ変換する。
				if(((src[r] >= 0xA6) && (src[r] <= 0xAF)) || ((src[r] >= 0xB1) && (src[r] <= 0xBF)))
					dst[w] = src[r] - 0x20;
					
				// "タ〜ン" の範囲だった場合、ひらがなへ変換する。
				else if((src[r] >= 0xC0) && (src[r] <= 0xDD))
					dst[w] = src[r] + 0x20;
					
				// それ以外の文字だった場合、無変換とする。
				else
					dst[w] = src[r];
				
				break;
				
			// 変換モード「半角カタカナ」
			// 半角カタカナ のまま(無変換)。
			case CONV_KATAKANA:
				dst[w] = src[r];
				break;
			}
			
			r++;
			w++;
		}
	}
	
	// 最後に終端文字を入れる。
	dst[w] = src[r];
}
//---------------------------------------------------------------------------------
// 
// ■書式
// void clearStrBuff(char *str_buff, const int str_num);
// 
// ■引数
// char *str_buff    : クリアしたい文字列を指定する。
// const int str_num : クリアしたい文字列の配列数を指定する。
// 
// ■返値
// なし
// 
// ■説明
// 指定した文字列をクリア(初期化)する。
// 
// ■注意
// クリアしたい文字列と要素数が一致しない場合の動作は保障されない。
// 指定した文字列と配列数に違いがないよう注意すること。
// 
//---------------------------------------------------------------------------------
void clearStrBuff(char *str_buff, const int str_num)
{
	int i;
	
	for(i = 0;i < str_num;i++)
		str_buff[i] = '\0';
}
//---------------------------------------------------------------------------------
int main(void)
{
	// カタカナ -> ひらがな 変換した文字列の一時保存先。
	char buff[100] = {0};
	
	// ANK コードを表示するには予め先に、変数に文字列をセットしておく必要があるため、
	// ここで文字列を持たせる(処理系の問題。)。
	const char str1[] = "MSX ANK コード -hノ -kカタカナ -hモジレツ ノ\nニンイカショ ヲ ヒラガナ ニ -kコンバート -hシマース";
	const char str2[] = "-hヘンカン -kモード オプション\n\"--kk\" : カタカナ, \"--hh\" : ヒラガナ\n";
	
	//フォント変更を適用するコンソールステータスを PrintConsole 構造体で持つ。
	PrintConsole console = *consoleDemoInit();
	
	//フォント再定義の為のフォントステータスを ConsoleFont 構造体で持つ。
	ConsoleFont font;
	
	// フォント画像データのある先頭アドレスを指定する。
	font.gfx = (u16*)fontTiles;
	
	// パレット定義データのある先頭アドレスを指定する。
	// 但しシングルカラーモードの場合、この指定は意味を成さない。
	//font.pal = (u16*)fontPal;
	
	// パレット定義されてる色数を指定する。
	// 但しシングルカラーモードの場合、この指定は意味を成さない。
	// 16 : 4ビットカラー, 256 : 8ビットカラー
	//font.numColors =  fontPalLen / 2;
	
	// フォント描画のカラーモードを指定する。
	// 4 : 16色モード, 8 : 256色モード
	font.bpp = 4;
	
	// アスキーコード開始オフセットを指定する。
	// フルセットある場合は 0 、空白スペースから始まるようなら 32 という風に、
	// アスキーコードに準じた指定をする必要がある。
	font.asciiOffset = 0;
	
	// 利用可能とするキャラクタ数を指定する。
	// アスキーコード開始オフセットで定義した位置から数えて何文字までを利用可能とするか指定する。
	font.numChars = 256;
	
	// シングルカラーモードを利用するかどうか指定する。
	// 
	// true  : シングルカラー有効。透明色以外は全て同一色に変換されてマッピングされる。
	//         この場合パレットデータは読み込まれず、
	//         0 番カラーを透明色に、デフォルトカラー(255 番カラー)をフォント色として設定される。
	// 
	// false : シングルカラー無効。元のフォントデータの色通りに展開、マッピングされる。
	// 
	font.convertSingleColor = true;
	
	// 設定変更を行ったフォントステータスを現在のコンソールステータスに適用する。
	consoleSetFont(&console, &font);
	
	iprintf("MSX2J font demo\n");
	iprintf("   by AYUMI.KAWAI\n");
	iprintf("(C)2009 REGEKATSU\n");
	
	iprintf("\n\nvoid strConvKana\n(char *dst, const char *src)\n\n");
	
	// "MSX ANK コード の カタカナ もじれつ の
	// にんいかしょ を ひらがな に コンバート しまーす (はぁと)"
	clearStrBuff(buff, countof(buff));
	strConvKana(buff, str1);
	iprintf("%s %c\n", buff, 0x81);
	
	// "● へんかん モード オプション
	// "-k" : カタカナ, "-h" : ひらがな"
	clearStrBuff(buff, countof(buff));
	strConvKana(buff, str2);
	iprintf("\n%c %s\n", 0x85, buff);
	
	while(1) {
		swiWaitForVBlank();
	}

	return 0;
}