Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DECODE2.DMG ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ;$Id: decode2.dmg,v 1.6 1994/12/13 01:14:03 yoshiki Exp $
- ;*************************************************************
- ; DMG用 汎用VRAMデータデコードルーチン
- ; *高速版!!*
- ; Created by S.Iwata on June, 1989
- ; (C) 1989 HAL Laboratory,inc.
- ;*************************************************************
- include common.def
- include macro.h
- bank0 group 0
- ;
- ; ビット反転テーブルの展開
- ;
- ifn 0
- public initlrchgdat
- initlrchgdat
- ld hl,lrchgdat
- _lp ld b,8
- _lp1 rrc l
- rla
- dec b
- jr nz,_lp1
- ld (hli),a
- inc a
- jr nz,_lp
- ret
- endif
- public BankChangeDecode
- BankChangeDecode:
- ld (decodeBank),a
- ld a,(rombankno)
- push af
- ld a,(decodeBank)
- BANK_SET
- ; ld (rombankno),a
- ; ld (ROMBANK),a
- call decode
- pop af
- BANK_SET
- ; ld (rombankno),a
- ; ld (ROMBANK),a
- ret
- ifn 0
- ;
- ; DMG版 データ圧縮のデータフォーマット
- ;
- ; <ヘッダ> <データフィールド>
- ; <ヘッダ> <位置指定フィールド>
- ;
- ; ◎ヘッダの構造
- ; ヘッダは1バイト形式と2バイト形式がある
- ; 11111111 ($ff) データの終端
- ; kkk lllll 1バイト形式ヘッダ
- ; kkkは 000~110のデータ種別フィールド(3ビット)
- ; lllllは 1~32を表わす長さフィールド(5ビット)
- ; 111 kkkll llllllll 2バイト形式ヘッダ
- ; kkkは 000~110のデータ種別フィールド(3ビット)
- ; ll lllllll は 1~1024を表わす長さフィールド(10ビット)
- ; ●データ種別フィールド(3ビット)
- ; 000 以下に非圧縮データが続く <データフィールド>が続く
- ; 001 1データ連続 <データフィールド>が続く
- ; 010 2データ連続 <データフィールド>が続く
- ; 011 +1データ連続 <データフィールド>が続く
- ; 100 参照(上下左右方向標準) <位置指定フィールド>が続く
- ; 101 参照(左右反転) <位置指定フィールド>が続く
- ; 110 参照(上下反転) <位置指定フィールド>が続く
- ; 111 特殊
- ;
- ; ◎データフィールド(nバイト)
- ; 種別 = 000 長さ指定分のデータが続く
- ; 種別 = 001 1バイトのデータが続く
- ; 種別 = 010 2バイトのデータが続く
- ; 種別 = 011 1バイトのデータが続く
- ;
- ; ◎位置指定フィールド(16ビット)
- ; xxxxxxxx xxxxxxxx 64kバイトの範囲内で、参照の位置指定を表わす
- ;
- ;
- ; segment program
- ;
- ; VRAM圧縮形式データの展開
- ; void decode(char *data, void *vadrs)
- ;
- ;Entry:
- ; [DE]:展開先のアドレス
- ; [HL]:圧縮データの先頭アドレス
- ;
- ;Return:
- ; [DE]:展開データの終端アドレス+1
- ;
- public decode
- decode
- ld a,e ;VRAM書き込みアドレスを退避
- ld (decodeAdrs),a
- ld a,d
- ld (decodeAdrs+1),a
- ;
- decode1
- ld a,(hl) ;ヘッダを取り出す
- cp %11111111 ;終了判定
- ret z ; Yes, データ終了
- ;
- and %11100000 ;2バイト形式か?
- cp %11100000
- jr nz,decode2 ; No, 1バイト形式である
- ; 2バイト形式ヘッダの長さの取得
- ld a,(hl) ;2バイト形式のデータ種別フィールドを取り出す
- add a,a
- add a,a
- add a,a ;上位3ビットにシフトする
- and %11100000
- push af ;データ種別フィールドの保存
- ld a,(hli) ;長さの上位バイト(2ビット)を取り出す
- and %00000011
- ld b,a
- ld a,(hli) ;長さの下位バイト(8ビット)を取り出す
- ld c,a
- inc bc ;0で1を表わしているので補正
- jr decode3
- ; 1バイト形式ヘッダの長さの取得
- decode2
- push af ;データ種別フィールドの保存
- ld a,(hli)
- and %00011111 ;短形式の長さを設定(5ビット)
- ld c,a
- ld b,0
- inc c ;0で1を表わしているので補正
- ;
- decode3 inc b ;指定回数のループの高速化のため、
- inc c ; あらかじめ[B],[C]をインクリメントしておく
- pop af ;データ種別フィールドの回復
- bit 7,a ;参照データか繰り返しデータかを区別する
- jr nz,decodeRef ; 参照データである
- ;
- cp %00100000
- jr z,decodeRepeat ;1データ連続の展開
- cp %01000000
- jr z,decodeRep2 ;2データ交互連続の展開
- cp %01100000
- jr z,decodeRepInc ;+1データ連続の展開
- ; 非圧縮データの展開
- decodeNormal
- dec c
- jr nz,decodeNorm1
- dec b
- jp z,decode1 ; データ展開終了
- decodeNorm1
- ld a,(hli) ;データを読み出す
- ld (de),a ;データを書き込む
- inc de
- jr decodeNormal
- ; 1データ連続の展開
- decodeRepeat
- ld a,(hli) ;展開するデータを[A]に読み出す
- decodeRep1
- dec c
- jr nz,decodeRep10
- dec b
- jp z,decode1 ; データ展開終了
- decodeRep10
- ld (de),a ;連続データを書き込む
- inc de
- jr decodeRep1
- ; 2データ交互連続の展開
- decodeRep2
- dec c
- jr nz,decodeRep20
- dec b
- jp z,decRep2End ; データ展開終了
- decodeRep20
- ld a,(hli) ;連続データを書き込む
- ld (de),a
- inc de
- ld a,(hld)
- ld (de),a
- inc de
- jr decodeRep2
- ;
- decRep2End
- inc hl
- inc hl
- jr decode1
- ; +1データ連続の展開
- decodeRepInc
- ld a,(hli) ;展開するデータを[A]に読み出す
- decodeInc1
- dec c
- jr nz,decodeInc10
- dec b
- jp z,decode1 ; データ展開終了
- decodeInc10
- ld (de),a
- inc de
- inc a
- jr decodeInc1
- ; 参照データの展開
- decodeRef
- push hl ;データアドレスの退避
- push af ;データ種別フィールドを再度退避
- ld a,(hli) ;参照アドレスを読み出す
- ld l,(hl)
- ld h,a
- ld a,(decodeAdrs) ;(decodeAdrs)を加えてデータ参照アドレスを算出
- add a,l
- ld l,a
- ld a,(decodeAdrs+1)
- adc a,h
- ld h,a
- ;
- pop af ;データ種別フィールドを回復
- ;
- cp %10000000
- jr z,refNormal ;通常参照展開
- cp %10100000
- jr z,refLR ;左右反転参照展開
- cp %11000000
- jr z,refUD ;上下反転参照展開
- ; データ参照
- refNormal
- dec c
- jr nz,refNorm1
- dec b
- jr z,refEnd ; データ展開終了
- refNorm1
- ld a,(hli) ;参照データを読み出す
- ld (de),a ;データを書き込む
- inc de
- jr refNormal
- ; 左右反転データ参照
- refLR
- dec c
- jr nz,refLR1
- dec b
- jp z,refEnd ; データ展開終了
- refLR1
- ld a,(hli) ;参照データを読み出す
- ife 1
- push hl ;テーブルを利用した高速左右反転
- ld h,>lrchgdat
- ld l,a
- ld a,(hl)
- pop hl
- endif
- ife 0
- push bc ;[BC](カウンタ)の退避
- ld bc,8 ;データの左右反転
- refLR2 rra
- rl b
- dec c
- jr nz,refLR2
- ld a,b
- pop bc ;[BC](カウンタ)の回復
- endif
- ld (de),a ;左右反転した参照データを書き込む
- inc de
- jr refLR
- ; 上下反転データ参照
- refUD
- dec c
- jr nz,refUD1
- dec b
- jp z,refEnd ; データ展開終了
- refUD1
- ld a,(hld) ;参照データを読み出す
- ld (de),a ;データを書き込む
- inc de ;上下反転なので、データを逆順に展開
- jr refUD
- ; 参照展開終了
- refEnd
- pop hl ;データアドレスの回復
- inc hl ;参照アドレスフィールドの2バイトをスキップ
- inc hl
- jp decode1 ;次のデータを展開
- else
- ;*************************************************************
- ; DMG用 汎用VRAMデータデコードルーチン
- ; *高速版!!*
- ; Created by S.Iwata on June, 1989
- ; for ポケモン金銀バージョン on September, 1998
- ; (C) 1989 HAL Laboratory,inc.
- ;*************************************************************
- ;
- ; DMG版 データ圧縮のデータフォーマット
- ;
- ; <ヘッダ> <データフィールド>
- ; <ヘッダ> <位置指定フィールド>
- ;
- ; ◎ヘッダの構造
- ; ヘッダは1バイト形式と2バイト形式がある
- ; 11111111 ($ff) データの終端
- ; kkk lllll 1バイト形式ヘッダ
- ; kkkは 000~110のデータ種別フィールド(3ビット)
- ; lllllは 1~32を表わす長さフィールド(5ビット)
- ; 111 kkkll llllllll 2バイト形式ヘッダ
- ; kkkは 000~110のデータ種別フィールド(3ビット)
- ; ll lllllll は 1~1024を表わす長さフィールド(10ビット)
- ; ●データ種別フィールド(3ビット)
- ; 000 以下に非圧縮データが続く <データフィールド>が続く
- ; 001 1データ連続 <データフィールド>が続く
- ; 010 2データ連続 <データフィールド>が続く
- ; 011 +1データ連続 <データフィールド>が続く
- ; 100 参照(上下左右方向標準) <位置指定フィールド>が続く
- ; 101 参照(左右反転) <位置指定フィールド>が続く
- ; 110 参照(上下反転) <位置指定フィールド>が続く
- ; 111 特殊
- ;
- ; ◎データフィールド(nバイト)
- ; 種別 = 000 長さ指定分のデータが続く
- ; 種別 = 001 1バイトのデータが続く
- ; 種別 = 010 2バイトのデータが続く
- ; 種別 = 011 1バイトのデータが続く
- ;
- ; ◎位置指定フィールド(16ビット)
- ; xxxxxxxx xxxxxxxx 64kバイトの範囲内で、参照の位置指定を表わす
- ;
- ;
- ; segment program
- ;
- ; VRAM圧縮形式データの展開
- ; void decode(char *data, void *vadrs)
- ;
- ;Entry:
- ; [DE]:展開先のアドレス
- ; [HL]:圧縮データの先頭アドレス
- ;
- ;Return:
- ; [DE]:展開データの終端アドレス+1
- ;
- public decode
- decode
- ld a,e ;VRAM書き込みアドレスを退避
- ld (decodeAdrs),a
- ld a,d
- ld (decodeAdrs+1),a
- decode1
- ld a,(hl) ;ヘッダを取り出す
- cp %11111111 ;終了判定
- ret z ; Yes, データ終了
- and %11100000 ;2バイト形式か?
- cp %11100000
- jr nz,decode2 ; No, 1バイト形式である
- ; 2バイト形式ヘッダの長さの取得
- ld a,(hl) ;2バイト形式のデータ種別フィールドを取り出す
- add a,a
- add a,a
- add a,a ;上位3ビットにシフトする
- and %11100000
- push af ;データ種別フィールドの保存
- ld a,(hli) ;長さの上位バイト(2ビット)を取り出す
- and %00000011
- ld b,a
- ld a,(hli) ;長さの下位バイト(8ビット)を取り出す
- ld c,a
- inc bc ;0で1を表わしているので補正
- jr decode3
- ; 1バイト形式ヘッダの長さの取得
- decode2
- push af ;データ種別フィールドの保存
- ld a,(hli)
- and %00011111 ;短形式の長さを設定(5ビット)
- ld c,a
- ld b,0
- inc c ;0で1を表わしているので補正
- decode3 inc b ;指定回数のループの高速化のため、
- inc c ; あらかじめ[B],[C]をインクリメントしておく
- pop af ;データ種別フィールドの回復
- bit 7,a ;参照データか繰り返しデータかを区別する
- jr nz,decodeRef ; 参照データである
- cp %00100000
- jr z,decodeRepeat ;1データ連続の展開
- cp %01000000
- jr z,decodeRep2 ;2データ交互連続の展開
- cp %01100000
- jr z,decodeRepInc ;+1データ連続の展開
- ; 非圧縮データの展開
- decodeNormal
- dec c
- jr nz,decodeNorm1
- dec b
- jp z,decode1 ; データ展開終了
- decodeNorm1
- ld a,(hli) ;データを読み出す
- ld (de),a ;データを書き込む
- inc de
- jr decodeNormal
- ; 1データ連続の展開
- decodeRepeat
- ld a,(hli) ;展開するデータを[A]に読み出す
- decodeRep1
- dec c
- jr nz,decodeRep10
- dec b
- jp z,decode1 ; データ展開終了
- decodeRep10
- ld (de),a ;連続データを書き込む
- inc de
- jr decodeRep1
- ; 2データ交互連続の展開
- decodeRep2
- dec c
- jr nz,decodeRep20
- dec b
- jp z,decRep2End ; データ展開終了
- decodeRep20
- ld a,(hli) ;連続データを書き込む
- ld (de),a
- inc de
- dec c ;ポケモン金銀モードでは奇数個のデータも許す
- jr nz,decodeRep21
- dec b
- jp z,decRep2End1 ; データ展開終了
- decodeRep21
- ld a,(hld)
- ld (de),a
- inc de
- jr decodeRep2
- ;
- decRep2End
- inc hl
- decRep2End1
- inc hl
- jr decode1
- ; +1データ連続の展開
- public decodeRepInc
- decodeRepInc
- xor a ;ポケモン金銀モードでは0の連続
- ;; ld a,(hli) ;展開するデータを[A]に読み出す
- decodeInc1
- dec c
- jr nz,decodeInc10
- dec b
- jp z,decode1 ; データ展開終了
- decodeInc10
- ld (de),a
- inc de
- ; inc a
- jr decodeInc1
- ; 参照データの展開
- decodeRef
- push hl ;データアドレスの退避
- push af ;データ種別フィールドを再度退避
- ld a,(hli) ;参照アドレスを読み出す
- bit 7,a ;ポケモン金銀モードでは最上位ビットの立っている場合
- jr z,decodeRef1
- and $7f ; -128 までの現在位置からのオフセットを意味する
- cpl
- add a,e
- ld l,a
- ld a,$ff
- adc a,d
- ld h,a
- jr decodeRef2
- decodeRef1
- ld l,(hl)
- ld h,a
- ld a,(decodeAdrs) ;(decodeAdrs)を加えてデータ参照アドレスを算出
- add a,l
- ld l,a
- ld a,(decodeAdrs+1)
- adc a,h
- ld h,a
- decodeRef2
- pop af ;データ種別フィールドを回復
- cp %10000000
- jr z,refNormal ;通常参照展開
- cp %10100000
- jr z,refLR ;左右反転参照展開
- cp %11000000
- jr z,refUD ;上下反転参照展開
- ; データ参照
- refNormal
- dec c
- jr nz,refNorm1
- dec b
- jr z,refEnd ; データ展開終了
- refNorm1
- ld a,(hli) ;参照データを読み出す
- ld (de),a ;データを書き込む
- inc de
- jr refNormal
- ; 左右反転データ参照
- refLR
- dec c
- jr nz,refLR1
- dec b
- jp z,refEnd ; データ展開終了
- refLR1
- ld a,(hli) ;参照データを読み出す
- ifn 0
- push hl ;テーブルを利用した高速左右反転
- ld h,>lrchgdat
- ld l,a
- ld a,(hl)
- pop hl
- else
- push bc ;[BC](カウンタ)の退避
- ld bc,8 ;データの左右反転
- refLR2 rra
- rl b
- dec c
- jr nz,refLR2
- ld a,b
- pop bc ;[BC](カウンタ)の回復
- endif
- ld (de),a ;左右反転した参照データを書き込む
- inc de
- jr refLR
- ; 上下反転データ参照
- refUD
- dec c
- jr nz,refUD1
- dec b
- jp z,refEnd ; データ展開終了
- refUD1
- ld a,(hld) ;参照データを読み出す
- ld (de),a ;データを書き込む
- inc de ;上下反転なので、データを逆順に展開
- jr refUD
- ; 参照展開終了
- refEnd
- pop hl ;データアドレスの回復
- bit 7,(hl) ;ポケモン金銀モードでは1バイトオフセットもある
- jr nz, refEnd1 ; 1バイトオフセット
- inc hl ;参照アドレスフィールドの2バイトをスキップ
- refEnd1
- inc hl
- jp decode1 ;次のデータを展開
- endif
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VPACKSUB.C ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- vpacksub.c TEXTdosa @ 5 イ,kxイ$M> /*
- * データ圧縮ユーティリティー
- * Written by S.Iwata
- * on April,1989
- * revised by M.Kanai
- * on Aug., 1989
- * revised by T.Gunji
- * on May., 1994
- * revised by S.Iwata
- * on September, 1996
- * revised by S.Iwata
- * on September, 1998
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- typedef unsigned char BYTE;
- typedef unsigned int WORD;
- typedef unsigned long DWORD;
- #define TRUE 1
- #define FALSE 0
- #define FILENAMELENGTH 64 /* ファイル名用バッファの大きさ */
- #define DATASIZELIMIT 65536 /* 扱えるデータの最大値 64KB */
- #define EMPTY (WORD)DATASIZELIMIT /* ハッシュテーブル内で空きを示す */
- #define HASHTABLESIZE 131111 /* 素数 524287 512KB */
- /* (old-version 131111) */
- BYTE data[DATASIZELIMIT + 1]; /* 圧縮データバッファ */
- BYTE algorythm[DATASIZELIMIT]; /* 圧縮アルゴリズム */
- WORD compLength[DATASIZELIMIT]; /* 圧縮対象データ長 */
- WORD reference[DATASIZELIMIT]; /* 参照インデックス */
- WORD originalSize = 0; /* 圧縮前のデータ長 */
- WORD packedSize = 0; /* 圧縮後のデータ長 */
- WORD nrefHash[HASHTABLESIZE];
- WORD vrefHash[HASHTABLESIZE];
- BYTE invertTable[256]; /* 左右反転用テーブル */
- #define Invert(n) (invertTable[n]) /* 左右反転データを得る */
- #define NORMAL (BYTE)0 /* 非圧縮通常データ */
- #define RUNLENGTH (BYTE)1 /* 1データ連続 */
- #define RUNLENGTH2 (BYTE)2 /* 2データ交互連続 */
- #define INCRUNLEN (BYTE)3 /* インクリメンタルデータ連続 */
- #define REFERENCE (BYTE)4 /* 通常データ参照 */
- #define REFERLR (BYTE)5 /* 左右反転データ参照 */
- #define REFERUD (BYTE)6 /* 上下反転データ参照 */
- #define SPECIAL (BYTE)7 /* 特殊データ */
- #define ENDMARK (BYTE)0xff /* データ終端 */
- WORD algoPacked[] = {1, 2, 3, 2, 3, 3, 3};
- /* 各アルゴリズムで圧縮した場合のバイト数 */
- WORD algoPackedZ[] = {1, 2, 3, 1, 2, 2, 2};
- WORD longEnough = 64;
- int op_quiet = TRUE;
- int op_percent = FALSE;
- int pockemonFlag = TRUE; /* ポケモン金銀モード */
- /* 最大データサイズを32KBに制限して1ByteOffset使用 */
- /* インクリメンタルデータ連続を0の連続の表記に使用 */
- /*
- * 1バイトのデータを出力する
- */
- void putByte(BYTE data, FILE *fpo)
- {
- fputc(data, fpo);
- packedSize++;
- }
- /*
- * ビットパターンを左右反転するためのテーブルを用意する
- */
- void makeInvertTable(void)
- {
- int i;
- BYTE d;
- for (i = 0; i < 256; ++i) {
- d = 0;
- if ( i & 0x01 ) d |= 0x80;
- if ( i & 0x02 ) d |= 0x40;
- if ( i & 0x04 ) d |= 0x20;
- if ( i & 0x08 ) d |= 0x10;
- if ( i & 0x10 ) d |= 0x08;
- if ( i & 0x20 ) d |= 0x04;
- if ( i & 0x40 ) d |= 0x02;
- if ( i & 0x80 ) d |= 0x01;
- invertTable[i] = d;
- }
- }
- /*
- * ハッシュテーブルを初期化する
- */
- void initHashTable(void )
- {
- WORD i;
- for (i = 0; i < HASHTABLESIZE; ++i) {
- nrefHash[i] = EMPTY;
- vrefHash[i] = EMPTY;
- }
- }
- /*
- * ハッシュ関数
- */
- WORD hashf(BYTE d0, BYTE d1, BYTE d2, BYTE d3)
- {
- DWORD x;
- x = (DWORD)d0 + ((DWORD)d1 << 8) + ((DWORD)d2 << 16) + ((DWORD)d3 << 24);
- return (WORD)(x % (DWORD)HASHTABLESIZE);
- }
- /*
- * オープンアドレッシングのハッシュテーブルから次々に値を返す
- */
- WORD scanNHash(WORD h)
- {
- static WORD lastH = HASHTABLESIZE;
- static WORD y, d;
- WORD r;
- if (h != lastH) {
- y = h;
- d = 1;
- }
- r = nrefHash[y];
- lastH = (r == EMPTY) ? HASHTABLESIZE : h;
- d += 2;
- if ((y += d) >= HASHTABLESIZE)
- y -= HASHTABLESIZE;
- return r;
- }
- WORD scanVHash(WORD h)
- {
- static WORD lastH = HASHTABLESIZE;
- static WORD y, d;
- WORD r;
- if (h != lastH) {
- y = h;
- d = 1;
- }
- r = vrefHash[y];
- lastH = (r == EMPTY) ? HASHTABLESIZE : h;
- d += 2;
- if ((y += d) >= HASHTABLESIZE)
- y -= HASHTABLESIZE;
- return r;
- }
- /*
- * ハッシュテーブルに登録する
- */
- void registNHash(WORD x, WORD y)
- {
- WORD d = 1;
- while (nrefHash[y] != EMPTY) {
- d += 2;
- if ((y += d) >= HASHTABLESIZE)
- y -= HASHTABLESIZE;
- }
- nrefHash[y] = x;
- }
- void registVHash(WORD x)
- {
- WORD y, d = 1;
- y = hashf(data[x], data[x-1], data[x-2], data[x-3]);
- while (vrefHash[y] != EMPTY) {
- d += 2;
- if ((y += d) >= HASHTABLESIZE)
- y -= HASHTABLESIZE;
- }
- vrefHash[y] = x;
- }
- /*
- * 連続性・参照などのチェック
- */
- void checkData(void)
- {
- unsigned int i, j, k, l;
- WORD r;
- BYTE *p1, *p2, *p3, *p1a;
- WORD hn, hh /*, hv*/;
- int cnt = 0;
- int skipFlag = 0;
- for ( i = 0 ; i < originalSize ; i++ ) {
- /* 同一データの連続性調査 */
- for ( j = 1 ; i+j < originalSize ; j++ ) {
- if ( data[i] != data[i+j] )
- break;
- }
- algorythm[i] = RUNLENGTH; /* 圧縮アルゴリズム */
- compLength[i] = j; /* 圧縮対象データ長 */
- if (pockemonFlag) { /* ポケモン金銀モードでは奇数の2データ連続を許す */
- /* 2データの交互連続性調査 */
- if (i+3 < originalSize && data[i] == data[i+2] && data[i+1] == data[i+3]) {
- for (j = 2 ; i+j < originalSize-1 ; j += 2) {
- if ( data[i] != data[i+j] || data[i+1] != data[i+j+1] )
- break;
- }
- if (data[i] == data[i+j]) j++;
- }
- if ( compLength[i] < j ) {
- algorythm[i] = RUNLENGTH2; /* 圧縮アルゴリズム */
- compLength[i] = j; /* 圧縮対象データ長 */
- }
- } else {
- /* 2データの交互連続性調査 */
- for ( j = 2 ; i+j < originalSize-1 ; j += 2 ) {
- if ( data[i] != data[i+j] || data[i+1] != data[i+j+1] )
- break;
- }
- if ( compLength[i] < j ) {
- algorythm[i] = RUNLENGTH2; /* 圧縮アルゴリズム */
- compLength[i] = j; /* 圧縮対象データ長 */
- }
- }
- if (pockemonFlag) { /* ポケモン金銀モードではインクリメンタルデータ連続を0の連続に使用 */
- /* 0の連続性調査 */
- if (data[i] == 0) {
- for ( j = 1 ; i+j < originalSize ; j++ ) {
- if (data[i+j] != 0) break;
- }
- algorythm[i] = INCRUNLEN; /* 圧縮アルゴリズム */
- compLength[i] = j; /* 圧縮対象データ長 */
- }
- } else {
- /* インクリメンタルデータの連続性調査 */
- for ( j = 1 ; i+j < originalSize ; j++ ) {
- if ( data[i+j-1] != data[i+j]-1 )
- break;
- }
- if ( compLength[i] < j ) {
- algorythm[i] = INCRUNLEN; /* 圧縮アルゴリズム */
- compLength[i] = j; /* 圧縮対象データ長 */
- }
- }
- /* */
- if (compLength[i] >= longEnough) {
- i += (compLength[i] - 1);
- if (!op_quiet && !op_percent)
- fputc('L' ,stderr);
- cnt++;
- continue;
- }
- /* 以前に出現したデータの参照の調査 */
- l = 0;
- hn = hashf(data[i], data[i+1], data[i+2], data[i+3]);
- while ((j = scanNHash(hn)) != EMPTY) {
- p1 = p1a = data + i;
- p2 = data + j;
- p3 = data + originalSize;
- while ((*p1 == *p2) /*&& (p2 < p1a)*/ && (p1 < p3))
- ++p1, ++p2;
- if ((k = p1 - p1a) > l) {
- l = k, r = j; /* 今回スキャンしたデータの方が長い一致 */
- } else if (k == l && j > r) {
- l = k, r = j; /* 同じ長さの一致なら近い方を優先 */
- }
- }
- if (l >= 3 && compLength[i] < l) {
- algorythm[i] = REFERENCE; /* 圧縮アルゴリズム */
- compLength[i] = l; /* 圧縮対象データ長 */
- reference[i] = r; /* 参照位置 */
- }
- /* 以前に出現したデータの左右反転の参照の調査 */
- l = 0;
- hh = hashf(Invert(data[i]), Invert(data[i+1]), Invert(data[i+2]), Invert(data[i+3]));
- while ((j = scanNHash(hh)) != EMPTY) {
- p1 = p1a = data + i;
- p2 = data + j;
- p3 = data + originalSize;
- while ((*p1 == Invert(*p2)) /*&& (p2 < p1a)*/ && (p1 < p3))
- ++p1, ++p2;
- if ((k = p1 - p1a) > l) {
- l = k, r = j; /* 今回スキャンしたデータの方が長い一致 */
- } else if (k == l && j > r) {
- l = k, r = j; /* 同じ長さの一致なら近い方を優先 */
- }
- }
- if (l >= 3 && compLength[i] < l) {
- algorythm[i] = REFERLR; /* 圧縮アルゴリズム */
- compLength[i] = l; /* 圧縮対象データ長 */
- reference[i] = r; /* 参照位置 */
- }
- /* 以前に出現したデータの上下反転の参照の調査 */
- l = 0;
- /*hv = hashf(data[i], data[i+1], data[i+2], data[i+3]); */
- while ((j = scanVHash(hn)) != EMPTY) {
- p1 = p1a = data + i;
- p2 = data + j;
- p3 = data + originalSize;
- while ((*p1 == *p2) && (p2 >= data) && (p1 < p3))
- ++p1, --p2;
- if ((k = p1 - p1a) > l) {
- l = k, r = j; /* 今回スキャンしたデータの方が長い一致 */
- } else if (k == l && j > r) {
- l = k, r = j; /* 同じ長さの一致なら近い方を優先 */
- }
- }
- if (l >= 3 && compLength[i] < l) {
- algorythm[i] = REFERUD; /* 圧縮アルゴリズム */
- compLength[i] = l; /* 圧縮対象データ長 */
- reference[i] = r; /* 参照位置 */
- }
- registNHash(i, hn);
- registVHash(i);
- if (compLength[i] >= longEnough) {
- i += (compLength[i] - 1);
- if (!op_quiet && !op_percent)
- fputc('L' ,stderr);
- cnt++;
- continue;
- }
- if ((i & 0x03F) == 0x03F) {
- if (!op_quiet && !op_percent)
- fputc('*' ,stderr);
- cnt++;
- }
- }
- /*
- if (!op_quiet)
- for (i = 0; i < cnt; i++)
- fputs("\b \b", stderr);
- */
- /*
- for (i = 0; i < originalSize ; i++)
- printf("%04X: %d %d\n", i, algorythm[i], compLength[i]);
- */
- }
- /*
- * 圧縮可能情報を順に調べて、圧縮した方が得かどうか調べる
- */
- void judge(void)
- {
- unsigned int i,j;
- /* そのデータを圧縮データにしてもトータルで損になる場合は除外 */
- for ( i = 0 ; i < originalSize ; i++ ) {
- if ( algorythm[i] ) {
- for ( j = 1 ; j < compLength[i] ; j++ ) {
- if ( compLength[i+j] > compLength[i] ) {
- compLength[i] = j;
- if (algorythm[i] == RUNLENGTH2 && (j & 1))
- compLength[i]--;
- }
- }
- }
- }
- /* 単純に圧縮してもデータが短くならない場合は圧縮対象から除外 */
- if (pockemonFlag) {
- for ( i = 0 ; i < originalSize ; i++ ) {
- if (compLength[i] <= algoPackedZ[algorythm[i]]) {
- algorythm[i] = NORMAL;
- compLength[i] = 0;
- }
- if (algorythm[i] >= REFERENCE && i-reference[i] > 128) {
- if ( compLength[i] <= algoPacked[algorythm[i]] ) {
- algorythm[i] = NORMAL;
- compLength[i] = 0;
- }
- }
- }
- } else {
- for ( i = 0 ; i < originalSize ; i++ ) {
- if ( compLength[i] <= algoPacked[algorythm[i]] ) {
- algorythm[i] = NORMAL;
- compLength[i] = 0;
- }
- }
- }
- /* 非圧縮データの連続性をチェックする */
- for ( i = 0; i < originalSize ; ) {
- if ( algorythm[i] == NORMAL ) {
- for ( j = 1 ; i+j < originalSize ; j++ ) {
- if ( algorythm[i+j] != NORMAL ) break;
- }
- compLength[i] = j;
- i += j;
- } else {
- i += compLength[i];
- }
- }
- }
- /*
- * 圧縮形式のデータを実際に出力する
- */
- void outData(FILE *fpo)
- {
- unsigned int i,j,k,len,loc;
- i = 0;
- while ( i < originalSize ) {
- len = compLength[i];
- if (!pockemonFlag) {
- if ( algorythm[i] == RUNLENGTH2 )
- len /= 2;
- }
- loc = i;
- do {
- j = (len > 1024) ? 1024 : len;
- if ( j > 32 ) {
- /* 圧縮長33以上 */
- putByte((BYTE)(0xe0+(algorythm[i]<<2)+((j-1)>>8)), fpo);
- putByte((BYTE)((j-1)&255), fpo);
- } else {
- /* 圧縮長1~32 */
- putByte((BYTE)((algorythm[i]<<5) + j-1), fpo);
- }
- switch ( algorythm[i] ) {
- case NORMAL:
- for ( k = 0; k < j; k++ )
- putByte(data[loc+k], fpo);
- loc += j;
- break;
- case RUNLENGTH:
- putByte(data[i], fpo);
- break;
- case INCRUNLEN:
- if (!pockemonFlag) {
- putByte(data[i], fpo);
- }
- break;
- case RUNLENGTH2:
- putByte(data[i], fpo);
- putByte(data[i+1], fpo);
- break;
- case REFERENCE:
- case REFERLR:
- if (pockemonFlag) {
- if (i - reference[i] <= 128) {
- putByte((BYTE)((i-reference[i]-1)|0x80), fpo);
- } else {
- putByte((BYTE)(reference[i]>>8), fpo);
- putByte((BYTE)(reference[i]&0xff), fpo);
- }
- } else {
- putByte((BYTE)(reference[i]>>8), fpo);
- putByte((BYTE)(reference[i]&0xff), fpo);
- }
- /*reference[i] += j;???*/
- break;
- case REFERUD:
- if (pockemonFlag) {
- if (i - reference[i] <= 128) {
- putByte((BYTE)((i-reference[i]-1)|0x80), fpo);
- } else {
- putByte((BYTE)(reference[i]>>8), fpo);
- putByte((BYTE)(reference[i]&0xff), fpo);
- }
- } else {
- putByte((BYTE)(reference[i]>>8), fpo);
- putByte((BYTE)(reference[i]&0xff), fpo);
- }
- /*reference[i] -= j;???*/
- break;
- }
- len -= j;
- } while ( len );
- i += compLength[i];
- }
- putByte(ENDMARK, fpo); /* エンドマークを書き出す */
- }
- int vpack(FILE *fpi, FILE *fpo)
- {
- packedSize = 0;
- /* 圧縮処理に必要な初期設定 */
- makeInvertTable();
- initHashTable();
- /* バッファにデータを読み出す */
- originalSize = fread(data, 1, DATASIZELIMIT + 1, fpi);
- if (originalSize > DATASIZELIMIT) {
- exit(1);
- }
- /* データの連続性・参照などのチェック */
- if (!op_quiet && !op_percent)
- fprintf(stderr, "データ解析.......");
- checkData();
- if (!op_quiet && !op_percent)
- fprintf(stderr, "...終了\n");
- /* 実際に圧縮するかどうか調べる */
- if (!op_quiet && !op_percent)
- fprintf(stderr, "圧縮効果解析.....");
- judge();
- if (!op_quiet && !op_percent)
- fprintf(stderr, "終了\n");
- /* 圧縮形式でデータを出力する */
- if (!op_quiet && !op_percent)
- fprintf(stderr, "圧縮データ出力...");
- outData(fpo);
- if (!op_quiet && !op_percent)
- fprintf(stderr, "終了 \n");
- if (!op_quiet)
- fprintf(stderr,
- " %u Byteから %u Byte( %d%% )に圧縮されました。差分は %u Byteです。\n", originalSize, packedSize, (int)((DWORD)packedSize*100/(DWORD)originalSize), originalSize-packedSize);
- return packedSize;
- }
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MONSPACK.C ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- monspack.c TEXTdosa + イ+ナzイ+ナp /*
- * ポケモングラフィックデータの圧縮・バンク詰めコンバータ
- * Created by S.Iwata / HAL Laboragtory, Inc.
- */
- #include <stdio.h>
- #include <stdlib.h>
- typedef unsigned char BYTE;
- typedef unsigned int WORD;
- typedef unsigned long DWORD;
- /* ファイルに1バイト出力 */
- void putByte(BYTE, FILE*);
- /* ファイルfpiの内容を圧縮してfpoに出力し圧縮後のサイズを返す */
- int vpack(FILE *fpi, FILE *fpo);
- /* 圧縮用データバッファ(データ出力に使用) */
- extern BYTE data[];
- /* データ種別定義 */
- typedef enum {
- MonsFront = 0, /* モンスター正面 */
- MonsBack, /* モンスター背面 */
- UnknownFront, /* アンノーン正面 */
- UnknownBack, /* アンノーン背面 */
- Trainer /* トレーナー */
- } DKind;
- /* データ断片 */
- typedef struct {
- DKind kind; /* データ種別 */
- int idno; /* データID(モンスター番号) */
- int bank; /* バンク番号 */
- long bpoint; /* バンク内のポインタ */
- int size; /* この情報のサイズ */
- } BLOCKREC;
- int comparec(const void*s1, const void *s2)
- {
- return( ((BLOCKREC*)s2)->size - ((BLOCKREC*)s1)->size );
- }
- BLOCKREC blockrec[1000]; /* ナップザックに格納するデータ断片 */
- long knaps[256]; /* ナップザックに格納されているデータサイズ */
- /*
- * ナップザック問題を解く
- */
- void PutIntoKnap(int blocknum, int minbank, int maxbank, int banksize)
- {
- BLOCKREC *thing;
- int i;
- long k;
- for (k = 0; k < blocknum; k++) {
- thing = &blockrec[k];
- for(i = minbank; i <= maxbank; i++) {
- if (banksize >= knaps[i] + thing->size) {
- thing->bank = i;
- thing->bpoint = knaps[i];
- knaps[i] += thing->size;
- goto next; /* put */
- }
- }
- fprintf(stderr , "knapsack: is full\n");
- exit(1);
- next:;
- }
- }
- #define NumMons (251) /* ポケモンの数 */
- #define MonsUnkown (201) /* アンノーンのモンスター番号(欠番) */
- #define NumUnknown (26) /* アンノーンの数 */
- #define NumTrainer (66) /* トレーナーの数 */
- #define MinBank (0x12) /* 先頭バンク番号 */
- #define MaxBank (0x20) /* 最終バンク番号 */
- #define BankSize (0x4000)/* バンクサイズ */
- #define BankOffset (0x4000)/* バンクの先頭アドレス */
- BYTE MonsFrontBank[NumMons]; /* モンスター正面のバンク */
- WORD MonsFrontAdrs[NumMons]; /* モンスター正面のアドレス */
- BYTE MonsBackBank[NumMons]; /* モンスター背面のバンク */
- WORD MonsBackAdrs[NumMons]; /* モンスター背面のアドレス */
- BYTE UnknownFrontBank[NumUnknown]; /* アンノーン正面のバンク */
- WORD UnknownFrontAdrs[NumUnknown]; /* アンノーン正面のアドレス */
- BYTE UnknownBackBank[NumUnknown]; /* アンノーン背面のバンク */
- WORD UnknownBackAdrs[NumUnknown]; /* アンノーン背面のアドレス */
- BYTE TrainerBank[NumTrainer]; /* トレイナーのバンク */
- WORD TrainerAdrs[NumTrainer]; /* トレイナーのアドレス */
- void main(int argc, char **argv)
- {
- int i, j;
- char infile[256];
- char outfile[256];
- FILE *fpi;
- FILE *fpo;
- int blockNum = 0;
- int offset;
- if (argc != 4) {
- fprintf(stderr, "monspack k|s datadir packdir");
- exit(1);
- }
- /* ポケモンキャラクタファイル群を圧縮 */
- for (i = 1; i <= NumMons; i++) {
- if (i == MonsUnkown) continue; /* アンノーンはスキップ */
- /* 正面グラフィック */
- sprintf(infile, "%s\\pm%sf_%03d.tmp", argv[2], argv[1], i);
- sprintf(outfile, "%s\\pm%sf_%03d.bin", argv[3], argv[1], i);
- fprintf(stderr, "File: %s\n", infile);
- fpi = fopen(infile, "rb");
- if (fpi != NULL) {
- fpo = fopen(outfile, "wb");
- blockrec[blockNum].kind = MonsFront;
- blockrec[blockNum].idno = i;
- blockrec[blockNum++].size = vpack(fpi, fpo);
- fclose(fpi);
- fclose(fpo);
- } else {
- fprintf(stderr, "%s not found\n", infile);
- }
- /* 背面グラフィック */
- sprintf(infile, "%s\\pm%sb_%03d.tmp", argv[2], argv[1], i);
- sprintf(outfile, "%s\\pm%sb_%03d.bin", argv[3], argv[1], i);
- fprintf(stderr, "File: %s\n", infile);
- fpi = fopen(infile, "rb");
- if (fpi != NULL) {
- fpo = fopen(outfile, "wb");
- blockrec[blockNum].kind = MonsBack;
- blockrec[blockNum].idno = i;
- blockrec[blockNum++].size = vpack(fpi, fpo);
- fclose(fpi);
- fclose(fpo);
- } else {
- fprintf(stderr, "%s not found\n", infile);
- }
- }
- /* アンノーンポケモンデータの圧縮 */
- for (i = 0; i < NumUnknown; i++) {
- /* 正面グラフィック */
- sprintf(infile, "%s\\pm%sf_un%c.tmp", argv[2], argv[1], i+'a');
- sprintf(outfile, "%s\\pm%sf_un%c.bin", argv[3], argv[1], i+'a');
- fprintf(stderr, "File: %s\n", infile);
- fpi = fopen(infile, "rb");
- if (fpi != NULL) {
- fpo = fopen(outfile, "wb");
- blockrec[blockNum].kind = UnknownFront;
- blockrec[blockNum].idno = i;
- blockrec[blockNum++].size = vpack(fpi, fpo);
- fclose(fpi);
- fclose(fpo);
- } else {
- fprintf(stderr, "%s not found\n", infile);
- }
- /* 背面グラフィック */
- sprintf(infile, "%s\\pm%sb_un%c.tmp", argv[2], argv[1], i+'a');
- sprintf(outfile, "%s\\pm%sb_un%c.bin", argv[3], argv[1], i+'a');
- fprintf(stderr, "File: %s\n", infile);
- fpi = fopen(infile, "rb");
- if (fpi != NULL) {
- fpo = fopen(outfile, "wb");
- blockrec[blockNum].kind = UnknownBack;
- blockrec[blockNum].idno = i;
- blockrec[blockNum++].size = vpack(fpi, fpo);
- fclose(fpi);
- fclose(fpo);
- } else {
- fprintf(stderr, "%s not found\n", infile);
- }
- }
- /* トレーナーファイル群を圧縮 */
- for (i = 1; i <= NumTrainer; i++) {
- sprintf(infile, "%s\\p%sdl_%03d.tmp", argv[2], argv[1], i);
- sprintf(outfile, "%s\\p%sdl_%03d.bin", argv[3], argv[1], i);
- fprintf(stderr, "File: %s\n", infile);
- fpi = fopen(infile, "rb");
- if (fpi != NULL) {
- fpo = fopen(outfile, "wb");
- blockrec[blockNum].kind = Trainer;
- blockrec[blockNum].idno = i;
- blockrec[blockNum++].size = vpack(fpi, fpo);
- fclose(fpi);
- fclose(fpo);
- } else {
- fprintf(stderr, "%s not found\n", infile);
- }
- }
- fprintf(stderr, "Total %d files\n", blockNum);
- /* ナップザック問題を解く準備 */
- qsort((void*)blockrec, (size_t)blockNum, sizeof(BLOCKREC), comparec);
- for(i = MinBank; i <= MaxBank; i++) knaps[i] = 0;
- knaps[MinBank] = (NumMons)*6; /* バンク12にはモンスター251体分のポインタ */
- knaps[MinBank+1] = (NumUnknown)*6; /* バンク13にはアンノーン26体分のポインタ */
- knaps[MinBank+2] = (NumTrainer)*3; /* バンク14にはトレーナー66体分のポインタ */
- /* ナップザック問題を解く */
- PutIntoKnap(blockNum, MinBank, MaxBank, BankSize);
- /* バンクの使用量表示 */
- for (i = MinBank; i <= MaxBank; i++) {
- fprintf(stderr, "Bank:%02X Size:%04X\n", i, knaps[i]);
- }
- /* バンクファイルの出力準備 */
- for (i = 0; i < NumMons; i++) {
- MonsFrontBank[i] = 0xff;
- MonsFrontAdrs[i] = 0xffff;
- MonsBackBank[i] = 0xff;
- MonsBackAdrs[i] = 0xffff;
- }
- for (i = 0; i < NumUnknown; i++) {
- UnknownFrontBank[i] = 0xff;
- UnknownFrontAdrs[i] = 0xffff;
- UnknownBackBank[i] = 0xff;
- UnknownBackAdrs[i] = 0xffff;
- }
- for (i = 0; i < NumTrainer; i++) {
- TrainerBank[i] = 0xff;
- TrainerAdrs[i] = 0xffff;
- }
- /* 詰め込まれたデータを確認してポインタテーブルをつくる */
- for (i = 0; i < blockNum; i++) {
- switch(blockrec[i].kind) {
- case MonsFront:
- if (blockrec[i].idno < 1 || blockrec[i].idno > NumMons) {
- fprintf(stderr, "Illegal monster no\n");
- exit(1);
- }
- MonsFrontBank[blockrec[i].idno-1] = blockrec[i].bank;
- MonsFrontAdrs[blockrec[i].idno-1] = blockrec[i].bpoint+BankOffset;
- break;
- case MonsBack:
- if (blockrec[i].idno < 1 || blockrec[i].idno > NumMons) {
- fprintf(stderr, "Illegal monster no\n");
- exit(1);
- }
- MonsBackBank[blockrec[i].idno-1] = blockrec[i].bank;
- MonsBackAdrs[blockrec[i].idno-1] = blockrec[i].bpoint+BankOffset;
- break;
- case UnknownFront:
- if (blockrec[i].idno < 0 || blockrec[i].idno >= NumUnknown) {
- fprintf(stderr, "Illegal monster no\n");
- exit(1);
- }
- UnknownFrontBank[blockrec[i].idno] = blockrec[i].bank;
- UnknownFrontAdrs[blockrec[i].idno] = blockrec[i].bpoint+BankOffset;
- break;
- case UnknownBack:
- if (blockrec[i].idno < 0 || blockrec[i].idno >= NumUnknown) {
- fprintf(stderr, "Illegal monster no\n");
- exit(1);
- }
- UnknownBackBank[blockrec[i].idno] = blockrec[i].bank;
- UnknownBackAdrs[blockrec[i].idno] = blockrec[i].bpoint+BankOffset;
- break;
- case Trainer:
- if (blockrec[i].idno < 1 || blockrec[i].idno > NumTrainer) {
- fprintf(stderr, "Illegal monster no\n");
- exit(1);
- }
- TrainerBank[blockrec[i].idno-1] = blockrec[i].bank;
- TrainerAdrs[blockrec[i].idno-1] = blockrec[i].bpoint+BankOffset;
- break;
- default:
- fprintf(stderr, "Illegal Data\n");
- exit(1);
- break;
- }
- }
- for (i = MinBank; i <= MaxBank; i++) {
- offset = 0;
- sprintf(outfile, "bank%02x.bin", i);
- fpo = fopen(outfile, "wb");
- /* バンク先頭にアドレステーブルを出力する必要あり? */
- switch(i) {
- case MinBank: /* バンク12の先頭にモンスターデータテーブル */
- for (j = 0; j < NumMons; j++) {
- putByte(MonsFrontBank[j], fpo);
- putByte((BYTE)(MonsFrontAdrs[j]&0xff), fpo);
- putByte((BYTE)(MonsFrontAdrs[j]>>8), fpo);
- putByte(MonsBackBank[j], fpo);
- putByte((BYTE)(MonsBackAdrs[j]&0xff), fpo);
- putByte((BYTE)(MonsBackAdrs[j]>>8), fpo);
- }
- offset += NumMons*6;
- break;
- case MinBank+1: /* バンク13の先頭にアンノーンデータテーブル */
- for (j = 0; j < NumUnknown; j++) {
- putByte(UnknownFrontBank[j], fpo);
- putByte((BYTE)(UnknownFrontAdrs[j]&0xff), fpo);
- putByte((BYTE)(UnknownFrontAdrs[j]>>8), fpo);
- putByte(UnknownBackBank[j], fpo);
- putByte((BYTE)(UnknownBackAdrs[j]&0xff), fpo);
- putByte((BYTE)(UnknownBackAdrs[j]>>8), fpo);
- }
- offset += NumUnknown*6;
- break;
- case MinBank+2: /* バンク14の先頭にトレイナーデータテーブル */
- for (j = 0; j < NumTrainer; j++) {
- putByte(TrainerBank[j], fpo);
- putByte((BYTE)(TrainerAdrs[j]&0xff), fpo);
- putByte((BYTE)(TrainerAdrs[j]>>8), fpo);
- }
- offset += NumTrainer*3;
- break;
- }
- /* このバンクに詰め込まれたデータを次々出力 */
- for (j = 0; j < blockNum; j++) {
- if (blockrec[j].bank != i) continue;
- if (blockrec[j].bpoint != offset) {
- fprintf(stderr, "Illegal Offset\n");
- exit(1);
- }
- offset += blockrec[j].size;
- switch(blockrec[j].kind) {
- case MonsFront:
- sprintf(infile, "%s\\pm%sf_%03d.bin", argv[3], argv[1], blockrec[j].idno);
- break;
- case MonsBack:
- sprintf(infile, "%s\\pm%sb_%03d.bin", argv[3], argv[1], blockrec[j].idno);
- break;
- case UnknownFront:
- sprintf(infile, "%s\\pm%sf_un%c.bin", argv[3], argv[1], blockrec[j].idno+'a');
- break;
- case UnknownBack:
- sprintf(infile, "%s\\pm%sb_un%c.bin", argv[3], argv[1], blockrec[j].idno+'a');
- break;
- case Trainer:
- sprintf(infile, "%s\\p%sdl_%03d.bin", argv[3], argv[1], blockrec[j].idno);
- break;
- }
- fpi = fopen(infile, "rb");
- fread(data, 1, blockrec[j].size, fpi);
- fwrite(data, 1, blockrec[j].size, fpo);
- fclose(fpi);
- }
- fclose(fpo);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement