LS11からのデコード、LS11へのエンコード

  • 概要

    ここでは、Ls11Mod APIの最も基本的なAPIとなる「デコード」と「エンコード」を解説しています。

  • デコードとエンコード

    • ls11_mod.hには4つ宣言されていますが、以下の2つを、先に先説します。
          // 圧縮されたLS11フォーマットをデコードする関数
          int ls11_DecodePack(char *szInputFileName, char *szOutputPattern, vector<vector<byte>> *pvecDstDataArray=NULL);
      
          // 展開された1つ以上(複数可)の一連の連番ファイルを、1つのLS11フォーマットにする。
          int ls11_EncodePack(char *szOutputFileName, char *szInputPattern, vector<vector<byte>> *pvecSrcDataArray=NULL, vector *pDstLS11PackedData=NULL);
          
  • デコードの具体例1

    • 実行ファイルと同じディレクトリに存在する、LS11フォーマットファイルである、hexgrp.nb6 を、ファイルに展開する。
      展開先としては、実行ファイルのサブディレクトリ、subhexに、subhex.000, subhex.001というように展開する。
          #include "ls11_mod.h"
      
          ls11_DecodePack("hexgrp.nb6", "subhex");
          

    • 実行ファイルと同じディレクトリに存在する、LS11フォーマットファイルである、hexgrp.nb6 を、展開する。
      しかし、ファイルに展開するのではなく。byte型の2次元可変長配列へと格納する。
          #include "ls11_mod.h"
      
          vector<vector<byte>> vBufExpandData;
          ls11_DecodePack("hexgrp.nb6", NULL, &vBufExpandData );
          
    • 以下は、上記の続きと仮定したデバッグ用
      
          // hexgrp.000相当のバイナリデータ
          vBufExpandData[0];
      
          // hexgrp.002相当のバイナリデータ
          vBufExpandData[2];
      
          // hexgrp.001相当のデータをバイナリエディタで開いたと仮定した時の、3番目のバイトデータ
          vBufExpandData[1][2];
      
          // hexgrp.001相当のバイナリデータの先頭のバイトのアドレス。
          // 各々のvectorは、必ず先頭から連続した配置位置であることが保障されているので、先頭のアドレスを取って処理することは有効に機能する。
          byte *pData1Begin = &vBufExpandData[1][0];
      
          
  • デコードの具体例2

    • シナリオデータ、sndata.n6pから、各々のシナリオデータを取得し、 そのうちの開始年代に相当する部分を表示する。
          #include <algorithm>
          #include <iostream>
          #include "ls11_mod.h"
      
          int main(void) {
      
              // sndata.n6pをvSnDataN6Pに格納
              vector<vector<byte>> vSnDataN6P;
              int iError = ls11_DecodePack("sndata.n6p", NULL, &vSnDataN6P);
      
              if (iError) { return -1; }
      
              // sndata.n6pと、実際の見た目上の並びがことなるため。要するにシナリオのIDは見た目どおりの昇順ではないということ。
              swap(vSnDataN6P[3],vSnDataN6P[4]);
              swap(vSnDataN6P[2],vSnDataN6P[3]);
              swap(vSnDataN6P[1],vSnDataN6P[2]);
      
              //デバッグ用
              for ( int i=0; i<(int)vSnDataN6P.size(); i++) {
                  cout << (int)(1454+vSnDataN6P[i][0xb7]) << endl; // 開始年代は、0xB7の位置に存在する。1454を足すと西暦となる。
              }
          }
          
  • エンコードの具体例

    • 実行ファイルのサブディレクトリ subhex 以下に、subhex.000 subhex.001 subhex.002 と並んでいるファイルを hexnew.nb6ファイルにパックする。
          #include "ls11_mod.h"
      
          ls11_EncodePack("hexnew.nb6", "subhex");
          
    • vector<vector<byte>>変数にあるバイナリデータを、hexgrp2.nb6ファイルにパックする。
          #include "ls11_mod.h"
      
          vector<vector<byte>> vBufExpandData;
          ls11_DecodePack("hexgrp.nb6", NULL, &vBufExpandData );
      
          ls11_EncodePack("hexnew2.nb6", NULL, &vBufExpandData );
          
    • vector<vector<byte>>変数にあるバイナリデータを、パックする。
      しかし、ファイル化するのではなく。vector<byte>型の並列に、パックされたバイナリを格納する。
          #include "ls11_mod.h"
      
          vector<vector<byte>> vBufExpandData;
          ls11_DecodePack("hexgrp.nb6", NULL, &vBufExpandData );
      
          vector<byte> vBufPacked;
          ls11_EncodePack(NULL, NULL, &vBufExpandData, &vBufPacked );
          
  • LS11のフォーマットデータの詳細

    • まず、基本的なLS11フォーマットについては、三国志Ⅸ覚書のLS11解説にある通りとなる。
      だが、問題は、この通りでは、天翔記のパックデータは解凍出来ないということだ。
      天翔記を含め、この時代のKOEIのLS11フォーマットには、1つのLS11ファイルに1つではなく、複数のファイルがまとめてパックされているためだ。

      • ①0位置~最初の10バイト。固定
      • ②~0x10Fまで。 辞書
      • ③ここから、3つが1セット、「(展開前の現在の)データ長」「展開後のデータサイズ」「開始アドレス」。 この3つ1セットが複数並ぶ
      • ④0が4バイトで1つ来る。これが、③の終わりを意味する。
      • ⑤おのおののデータ。③で求めた各々の「開始アドレス」から、各々の「データ長」分だけ続く