作者按:罕徳岡曼先生重溫了《劍芒x曼史》這個遊戲,感慨萬千,老淚縱橫。想當年玩仙劍看到白布下的林月如也滅有哭過滴他,卻在本遊戲中香奈兒死的時候掉淚了……畢竟是前一天晚上才h過的亞……究竟本遊戲有滅有可以救香奈兒mm的方法呢?解出便知道了……
gpc的壓縮比並不高,因為它使用遊程碼的關係。每個包的第乙個位元組a控制大流程,它的每一位以8個位元組為單位指出非0的包。從高位開始,為0表示有8個全0位元組,為1表示要進一步觀察。為0時,簡單填充8個位元組即可;當為1時,下乙個位元組b指出本包中8個位元組是否為0。位元組b從高位開始,為0表示乙個0位元組,為1表示從流中讀乙個作為目標位元組。以此類推。
在解完一行後,要對解開的位元組進行異或的解密。具體解密過程請見**。
調色盤是2個位元組表示乙個顏色(相當粗略啊^^)
另外要注意的是gpc有隔行掃瞄方式,在第10h位元組指出共有幾次掃瞄。如只有1次,就直接從第0行到最後一行。如有2次,則是0,2,4,6...n,1,3,5,...n-1這樣的組織。以次類推。
下面給出gpc轉bmp的**,在vs2003上編譯通過。使用方法是gpc2bmp [檔名],檔名表示要轉化的gpc檔案,可包含萬用字元。預設為*.gpc。
// gpc2bmp.cpp : 定義控制台應用程式的入口點。
//#include "stdafx.h"
#include "windows.h"
#include "io.h"
#define gpc_eof -1
struct gpc_buf ;
int gpc_next_byte(struct gpc_buf* data);
int gpc_next_word(struct gpc_buf* data);
void gpc_seek(struct gpc_buf* data, int offset);
bool gpc_load(struct gpc_buf* data, const char * filename);
void gpc_free(struct gpc_buf* data);
int gpc_next_byte(struct gpc_buf* data)
return *data->buf++;
}int gpc_next_word(struct gpc_buf* data)
bool gpc_load(struct gpc_buf* data, const char * filename)
void gpc_free(struct gpc_buf* data)
void gpc_seek(struct gpc_buf* data, int offset)
void gpc2bmp(struct gpc_buf* data, const char* target_file)
unsigned char *bits_buffer = (unsigned char *)malloc(bpl * height);
gpc_seek(data, image_offset + 0x10);
unsigned char decode_buf[1024];
int line_words = (bpl + 1) / 2;
unsigned char *next_line_pos = decode_buf + line_words * 2 + 1;
unsigned char *p_target = decode_buf;
unsigned char *disp_buf = decode_buf + 0x180;
memset( disp_buf, 0, line_words * 2 );
memset( bits_buffer, 0, bpl * height );
for ( int s = 0; s < scans; ++ s ) else
}} else }}
}p_target = p;
// post_decode_1
int ch = decode_buf[0];
if ( ch != 0 )
start++;
p = start;}}
// post decode 2
unsigned char *src = decode_buf + 1;
unsigned char *dest = disp_buf;
for ( int j = 0; j < line_words * 2; ++j ) ;
// post decode 3
int size = (int)(p_target - next_line_pos);
memcpy( decode_buf, next_line_pos, p_target - next_line_pos );
p_target = decode_buf + (p_target - next_line_pos);
src = disp_buf;
// 4 planes -> b4b4
// a0 a1 a2 a3 a4 a5 a6 a7
// b0 b1 b2 b3 b4 b5 b6 b7
// c0 c1 c2 c3 c4 c5 c6 c7
// d0 d1 d2 d3 d4 d5 d6 d7
// ==>
// a0b0c0d0 a1b1c1d1 ; a2b2c2d2 a3b3c3d3 ; a4b4c4d4 a5b5c5d5 ; a6b6c6d6 a7b7c7d7
unsigned char bits;
for ( int j = 0; j < 4; ++j )
}i += scans;}}
bitmapfileheader bfh;
bitmapinfoheader bmi;
memset(&bfh, 0, sizeof(bitmapfileheader));
bfh.bftype = 'mb';
bfh.bfsize = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader);
bfh.bfoffbits = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader) + 64;
memset(&bmi, 0, sizeof(bitmapinfoheader));
bmi.bisize = sizeof(bitmapinfoheader);
bmi.bisizeimage = bpl * height;
bmi.biwidth = width;
bmi.biheight = height;
bmi.biplanes = 1;
bmi.bibitcount = 4;
bmi.biclrused = 16;
bmi.biclrimportant = 16;
file *fp = fopen(target_file, "wb");
fwrite(&bfh, 1, sizeof bfh, fp);
fwrite(&bmi, 1, sizeof bmi, fp);
fwrite(palette, 4, 16, fp);
fwrite(bits_buffer, 1, bpl * height, fp);
fclose(fp);
free(bits_buffer);
}int _tmain(int argc, _tchar* argv)
if ( argc > 2 )
struct _finddata_t t;
long handle;
if ((handle = (long)_findfirst(input_files, &t)) != -1)
while(_findnext(handle, &t) != -1);
}return 0;
}
檔案格式分析
檔案格式實質上是資訊的一種的編碼方式,在windows中,採用副檔名來區分不同的檔案格式。文字格式 txt doc docx 音訊格式 txt arsii碼的方式存在 doc 以二進位制格式儲存 docx 作為乙個zip壓縮格式存在,是doc結合xml的一種格式,由於是分塊儲存,相比與doc檔案完整...
lucene檔案格式分析
segment 每個segment代表lucene乙個完整的索引段。通常乙個索引中包含了多個segment。每個segment都有統一的字首,字首名由document的數量轉成36進製後,在前面加 而構成的。通常乙個完整索引中,有且只有乙個沒有字尾名的segment檔案,它記錄了當前索引中所有的se...
FLV檔案格式分析
flv header 一般比較簡單,包括檔案型別之類的全域性資訊,如圖 檔案型別 3bytes 總是flv 0x46 0x4c 0x56 否則.版本1byte 一般是0x01,表示flv version 1 流資訊1byte header長度 4bytes 整個檔案頭的長度,一般是9 3 1 1 4...