/* ---------------------------------------------------------------------------
関数 shift_jis_to_display

この関数は、ASCIIコード、シフトJIS漢字コードが混じった文字列情報を受け取り
ディスプレイ表示関数に渡します。

 この関数で使用するグローバル変数

 1)dot8x16font  半角フォント情報配列約2kbyte   この関数外で設定する。

 2)dot16x16font 全角フォント情報配列約400kbyte この関数外で設定する。

 3)dot16x16data
   unsigned char  dot16x16data[]; // BitMap情報32byte文字列ポインタ
                                  // 半角ならば前半16byteを使用
 4)last_byte     漢字コードの前半と判断した場合、前回の最終1byteを保管する。
                 イニシャライズ時には、ゼロクリアしておく。

 関数 display_function(int mode)を呼び出す
 半角、全角フォント情報は全て配列に入っている事が前提です。
 
 画面クリアは、ctrl-lで実施されます。
-----------------------------------------------------------------------------*/

void shift_jis_to_display( recvData, lengthRecvData )
unsigned char recvData[]; // 配列長 1510byte
int  lengthRecvData;      // 1500まで
{
  int i, parsePos, byte2_flag, mode;  unsigned long font_offset;

  if( lengthRecvData > 1500 ) lengthRecvData=0;//異常引数ならば処理しない。
  /* 漢字コード2byteがパケット分割された時の処理
     漢字コードの2byte目では無いという条件で、パケットの最終byteが0x80以上
     である場合、このプログラムでは漢字コードの前半と判断。
     本関数の前回実行時にこの1byteをlast_byteに記憶しておき、今回処理開始時に
     この1byteを先頭に付けて本関数の処理を開始する。*/

  if( last_byte>=0x80 )
  {
    for( parsePos=lengthRecvData; parsePos>0; --parsePos )
      recvData[parsePos]=recvData[parsePos-1];//1byte後ろにずらせながら同じ配列に代入
    ++lengthRecvData;       //全データ長を1byte長くする
    recvData[0]=last_byte;  //前回データの最終byteを今回受信したデータの先頭に付ける
    last_byte=0;            //次回情報代入無し時に誤処理しないようにここで変数クリア
  }

  // シフトJISの第1byte範囲      0x81〜0x9f, （0xe0〜0xfc は非対応）
  // それ以外のbyteは半角文字および保留域です。保留域は0x80、0xa0、0xfd、0xfe、0xffです。
  // シフトJISの第2byte範囲      0x40〜0x7e, 0x80〜0xfc 
  //
  // このプログラムでは、第1バイト0x81〜0x9fの文字および半角文字のアルファベット、数字を表示します。
  byte2_flag=0;//漢字コードの2byte目判定フラグをクリア

  for(parsePos=0; parsePos<lengthRecvData; ++parsePos)//受信byte数ループ
  {
    if(byte2_flag==0)// /漢字コードの2byte目で無ければ本処理を行う
    {               // byte2_flag=1ならば漢字コードの2byte目なので処理を丸ごとパスする
      mode=0; font_offset=0; //パラメータ初期化

      ///////////           文字コードを分類する処理               ///////////
      if(recvData[parsePos]<=0x1F) //この場合制御コードと判定
      {
//        if( recvData[parsePos]==0x0D )  //0x0D改行コードならば改行する。
//                                        //それ以外は無視
//        {
//          position_x=0;
//          position_y=position_y+1; if(position_y>3) position_y=0;
//          if( position_x==0 && position_y==0 ) //LCDを全クリア
//          {
//            delay_msec_function(STOP_TIME_OF_DISPLAY);//人間が読む時間分、表示を一時停止させる
//            display_function(400);//画面クリア
//          }
//        }//0x0Dでは、modeは0のままなので後の表示処理には入らない
        if( recvData[parsePos]==0x0C )  //0x0C CLコードならば画面クリアする。0x0C=ctrl-l
                                        //それ以外は無視
        {
            display_function(400);//画面クリア
            break;                //0x0Cに続く文字は無視する
        }//0x0Cでは、modeは0のままなので後の表示処理には入らない
      }

      if( recvData[parsePos]>=0x20 && recvData[parsePos]<=0x7F )
                                             //半角英数と判定 半角情報代入
      {
      //printf( "a" );//半角英数と判定した場合はaをシリアル出力
        for( i=0; i<16; ++i )
          dot16x16data[i]=dot8x16font[i+(recvData[parsePos]-0x20)*16];
                                                       //フォントデータ代入
        mode=101;//半角英数。後の表示処理には入る。
        display_function(mode);//文字を表示
      }
      if(recvData[parsePos]>=0x80)
      { // 0x80以上だけでは漢字もしくは半角カタカナの可能性有り。
        // 本プログラムでは表示可能コード以外は全て無視する。(スペースにしない)
        // しかし半角カタカナをカタカナと関係の無い漢字と誤判定するのは
        // そのままとなっている。
      //printf( "k" );//全角文字と判定した場合はkをシリアル出力
        if(parsePos==(lengthRecvData-1))//最終データという事は
                                        //漢字コードの2byte目は無いという判定。
          last_byte=recvData[parsePos]; //パケットの最終byteが0x80以上なので
                                        //保管処理を実施

        // 0x8140=space offset=0 から  0x9FFC=滌 offset=186464まで
        if(recvData[parsePos]>=0x81 && recvData[parsePos]<=0x9F)
                               ///漢字コード1bye目判定  1byte目=0x81〜0x9F
        {
          font_offset= (recvData[parsePos]-0x81)
                           *(256-68/*0x40-0x7e,0x80-0xfc分が無いため-68*/)*32;

          if(parsePos!=(lengthRecvData-1))//2byte目が有る事を確認して処理
          {
            if(recvData[parsePos+1]>=0x40 && recvData[parsePos+1]<=0x7E)
            {
              font_offset=font_offset+((recvData[parsePos+1]-0x40)*32);
              byte2_flag=1; mode=102;//全角文字を書くmode

            }
            if(recvData[parsePos+1]>=0x80 && recvData[parsePos+1]<=0xFC)
            {
              font_offset=font_offset+((recvData[parsePos+1]-0x40-1)*32);
                                                   //0x7Fの空白分1データを引く
              byte2_flag=1; mode=102;//全角文字を書くmode
            }
          }
        }///byte2_flag=1かつmode=102  ならば後の漢字表示処理に入る

        // 0xE040=漾 offset=186496 から  0xEAA5=熙 offset=249824まで
        if(recvData[parsePos]>=0xE0 && recvData[parsePos]<=0xEC)
                               ///漢字コード1bye目判定  1byte目=0xE0〜0xEC
        {
          font_offset=186496;  //漢字コード1bye目=E0 の場合の開始位置
          font_offset=font_offset+ (recvData[parsePos]-0xE0)
                           *(256-68/*0x40-0x7e,0x80-0xfc分が無いため-68*/)*32;
          if(parsePos!=(lengthRecvData-1))//2byte目が有る事を確認して処理
          {
            if(recvData[parsePos+1]>=0x40 && recvData[parsePos+1]<=0x7E)
            {
              font_offset=font_offset+((recvData[parsePos+1]-0x40)*32);
              byte2_flag=1; mode=102;//全角文字を書くmode
            }
            if(recvData[parsePos+1]>=0x80 && recvData[parsePos+1]<=0xFC)
            {
              font_offset=font_offset+((recvData[parsePos+1]-0x40-1)*32);
                                                   //0x7Fの空白分1データを引く
              byte2_flag=1; mode=102;//全角文字を書くmode
            }
          }
        }///byte2_flag=1かつmode=102  ならば後の漢字表示処理に入る


      }
      if( byte2_flag==1 && mode==102 )
      {
        for( i=0; i<32; ++i )
        {
//			dot16x16data[i]=dot16x16test[i];//テスト用表示
          dot16x16data[i]=dot16x16font[font_offset];
          ++font_offset;//変数タイプが違うのでfont_offset+iはNG
        }
        display_function(mode);//文字を表示 表示するフォントはグローバル配列内
      }
    }else
    {
      byte2_flag=0;// / byte2_flagが1（漢字2byte目）ならば0にする
    }
  }//受信byte数ループ
}
