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つ来る。これが、③の終わりを意味する。
    • ⑤おのおののデータ。③で求めた各々の「開始アドレス」から、各々の「データ長」分だけ続く
    PICTURE