// LZSSデータを使用したDXライブラリのサンプル // include --------- #include "DxLib.h" #include #include #include // define ---------- // 各型とバイト数の関係( 環境によって変わりますが・・・ ) // int : 4バイト(0〜4,294,967,295) // short : 2バイト(0〜65,535) // char : 1バイト(0〜255) // data type ------- // 圧縮データの情報構造体 struct LZSS_ENCODE_INFO { int OriginalSize ; // 圧縮前のデータのサイズ(バイト数) int PressSize ; // 圧縮後のデータのサイズ(この構造体のサイズも含む) int EncodeCode ; // 圧縮情報の開始を示す数値 } ; // proto type ------ // 圧縮されたグラフィックデータからグラフィックハンドルを作成する int LZSS_LoadGraph( char *FilePath ) ; // 圧縮されたグラフィックデータからサウンドハンドルを作成する int LZSS_LoadSoundMem( char *FilePath ) ; // 圧縮データを解凍する // // 戻り値:解凍後のサイズ -1 はエラー Dest に NULL を入れると解凍データ格納に必要なサイズが返る int LZSS_Decode( void *Press, void *Dest ) ; // code ------------ // WinMain 関数 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int Graph, Sound ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // グラフィックを読み込む Graph = LZSS_LoadGraph( "PressGraph.lzs" ) ; // サウンドを読み込む Sound = LZSS_LoadSoundMem( "PressSound.lzs" ) ; // グラフィックを描画する DrawGraph( 0, 0, Graph, FALSE ) ; // 音を鳴らす PlaySoundMem( Sound, DX_PLAYTYPE_BACK ) ; // キー入力待ち WaitKey() ; // DXライブラリの後始末 DxLib_End() ; // ソフト終了 return 0 ; } // 圧縮されたグラフィックデータからグラフィックハンドルを作成する int LZSS_LoadGraph( char *FilePath ) { void *GraphBuffer, *SrcBuffer ; int GraphSize, SrcSize, GraphHandle ; // 圧縮データファイルを丸ごと読み込む { FILE *fp ; // ファイルを開く fp = fopen( FilePath, "rb" ) ; if( fp == NULL ) { printf( " File open Error!!\n" ) ; return -1 ; } // ファイルサイズを調べる { // ファイルポインタをファイルの末尾に fseek( fp, 0L, SEEK_END ) ; // ファイルの末尾で現在のファイルポインタアドレスを取得すればそれはファイルのサイズ SrcSize = ftell( fp ) ; // ファイルポインタをファイルの先頭に戻す fseek( fp, 0L, SEEK_SET ) ; } // ファイルを丸ごと読み込む為のメモリを確保する SrcBuffer = malloc( SrcSize ) ; if( SrcBuffer == NULL ) { printf( " Memory alloc Error!!\n" ) ; return -1 ; } // ファイルを丸ごと読み込む fread( SrcBuffer, SrcSize, 1, fp ) ; // ファイルを閉じる fclose( fp ) ; } // 解凍した時のデータのサイズを取得する GraphSize = LZSS_Decode( SrcBuffer, NULL ) ; // 解凍したデータを格納するためのメモリを確保する GraphBuffer = malloc( GraphSize ) ; if( GraphBuffer == NULL ) { printf( " Memory alloc Error!!\n" ) ; return -1 ; } // 解凍したデータを確保したメモリ領域に保存する LZSS_Decode( SrcBuffer, GraphBuffer ) ; // 圧縮データを解放する free( SrcBuffer ) ; // グラフィックハンドルを作成する GraphHandle = CreateGraphFromMem( GraphBuffer, GraphSize ) ; // 解凍したデータを解放する free( GraphBuffer ) ; // グラフィックハンドルを返す return GraphHandle ; } // 圧縮されたグラフィックデータからサウンドハンドルを作成する int LZSS_LoadSoundMem( char *FilePath ) { void *SoundBuffer, *SrcBuffer ; int SoundSize, SrcSize, SoundHandle ; // 圧縮データファイルを丸ごと読み込む { FILE *fp ; // ファイルを開く fp = fopen( FilePath, "rb" ) ; if( fp == NULL ) { printf( " File open Error!!\n" ) ; return -1 ; } // ファイルサイズを調べる { // ファイルポインタをファイルの末尾に fseek( fp, 0L, SEEK_END ) ; // ファイルの末尾で現在のファイルポインタアドレスを取得すればそれはファイルのサイズ SrcSize = ftell( fp ) ; // ファイルポインタをファイルの先頭に戻す fseek( fp, 0L, SEEK_SET ) ; } // ファイルを丸ごと読み込む為のメモリを確保する SrcBuffer = malloc( SrcSize ) ; if( SrcBuffer == NULL ) { printf( " Memory alloc Error!!\n" ) ; return -1 ; } // ファイルを丸ごと読み込む fread( SrcBuffer, SrcSize, 1, fp ) ; // ファイルを閉じる fclose( fp ) ; } // 解凍した時のデータのサイズを取得する SoundSize = LZSS_Decode( SrcBuffer, NULL ) ; // 解凍したデータを格納するためのメモリを確保する SoundBuffer = malloc( SoundSize ) ; if( SoundBuffer == NULL ) { printf( " Memory alloc Error!!\n" ) ; return -1 ; } // 解凍したデータを確保したメモリ領域に保存する LZSS_Decode( SrcBuffer, SoundBuffer ) ; // 圧縮データを解放する free( SrcBuffer ) ; // サウンドハンドルを作成する SoundHandle = LoadSoundMemByMemImage( SoundBuffer, SoundSize ) ; // 解凍したデータを解放する free( SoundBuffer ) ; // サウンドハンドルを返す return SoundHandle ; } // 圧縮データを解凍する // // 戻り値:解凍後のサイズ -1 はエラー Dest に NULL を入れると解凍データ格納に必要なサイズが返る int LZSS_Decode( void *Press, void *Dest ) { int PressSize, PressSizeCounter, DestSizeCounter ; unsigned char *PressPoint, *DestPoint ; LZSS_ENCODE_INFO EncodeInfo ; // void 型のポインタではアドレスの操作が出来ないので unsigned char 型のポインタにする PressPoint = ( unsigned char * )Press ; DestPoint = ( unsigned char * )Dest ; // 圧縮データの情報を取得する memcpy( &EncodeInfo, Press, sizeof( LZSS_ENCODE_INFO ) ) ; // Dest が NULL の場合は 解凍後のデータのサイズを返す if( Dest == NULL ) return EncodeInfo.OriginalSize ; // 圧縮データ本体のサイズを取得する PressSize = EncodeInfo.PressSize - sizeof( LZSS_ENCODE_INFO ) ; // 解凍処理 { int Index, EqualNum ; unsigned char *PressData ; // 圧縮データ本体の先頭アドレスをセット // (圧縮データ本体は元のサイズ、圧縮後のサイズ、各数値の出現数等を // 格納するデータ領域の後にある) PressData = PressPoint + sizeof( LZSS_ENCODE_INFO ) ; // 解凍したデータを格納するアドレスの初期化 DestSizeCounter = 0 ; // 解凍する圧縮データの参照アドレスの初期化 PressSizeCounter = 0 ; // 全ての圧縮データを解凍するまでループ while( PressSizeCounter < PressSize ) { // 圧縮情報の開始を示す数値かどうかで処理を分岐 if( PressData[PressSizeCounter] == EncodeInfo.EncodeCode ) { PressSizeCounter ++ ; // 2バイト連続で圧縮情報の開始を示す数値だった場合、開始を示す // 数値そのものを示しているのでそのまま出力する if( PressData[PressSizeCounter] == EncodeInfo.EncodeCode ) { DestPoint[DestSizeCounter] = ( unsigned char )EncodeInfo.EncodeCode ; DestSizeCounter ++ ; PressSizeCounter ++ ; } else { // 普通に圧縮情報を示す数値だった場合 // 『何バイト前から?』の数値を得る { Index = PressData[PressSizeCounter] ; PressSizeCounter ++ ; // 『何バイト前から?』の数値が圧縮情報を示す数値より // 大きい値の場合は−1する(詳しくはエンコードプログラムを参照してください) if( Index > EncodeInfo.EncodeCode ) Index -- ; } // 『何バイト同じか?』の数値を得る EqualNum = PressData[PressSizeCounter] ; PressSizeCounter ++ ; // 指定のバイト数分だけ前のアドレスから、指定の // バイト数分だけコピー memcpy( &DestPoint[DestSizeCounter], &DestPoint[DestSizeCounter - Index], EqualNum ) ; DestSizeCounter += EqualNum ; } } else { // 普通に数値を出力 DestPoint[DestSizeCounter] = PressData[PressSizeCounter] ; DestSizeCounter ++ ; PressSizeCounter ++ ; } } } // 解凍後のサイズを返す return EncodeInfo.OriginalSize ; }