-
Notifications
You must be signed in to change notification settings - Fork 3
/
adt.js
151 lines (128 loc) · 3.27 KB
/
adt.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import H from '../boot/hex.js'
import File from './file.js'
//
// 解压缩 ADT 数据
//
export default {
unpack,
load,
room,
};
function load(file) {
//TODO: 解析错误
return unpack(File.open(file).buf);
}
//
// 解析房间图片, 带有遮掩图片
//
function room(sbuf) {
const img = unpack_base(Uint16Array, sbuf, 320, 240);
const mask = parseMaskBuf(img.nonbuf);
if (mask) {
img.bindMaskTexTo = bindMaskTexTo;
img.maskw = mask.w;
img.maskh = mask.h;
img.maskbuf = mask.buf;
}
return img;
function bindMaskTexTo(tex) {
tex.bindTexImage(mask.buf, mask.w, mask.h, gl.GL_RED, gl.GL_UNSIGNED_BYTE);
tex.setParameter(gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST);
}
}
//
// 只解析图片, 并重建碎片
//
function unpack(srcbuf) {
return unpack_base(Uint16Array, srcbuf, 320, 240);
}
//
// 如果缓冲区数据异常, 会导致 bio2_adt_unpack_img 崩溃.
// srcbuf - ArrayBuffer
// ImgType - 图像缓冲区类型, Uint16Array 表示两个字节一个像素
//
function unpack_base(ImgType, srcbuf, width, height) {
const nonbuf = parseImgBuffer(ImgType, srcbuf);
const imgbuf = rebuildMapPic(ImgType, nonbuf, width, height);
return {
// 解析完成并重建碎片的图片缓冲区
buf : imgbuf,
// 解析完成但没有重建碎片的图片缓冲区
nonbuf,
// 高度
height,
// 宽度
width,
// 绑定到纹理对象
bindTexTo,
};
function bindTexTo(tex) {
tex.bindTexImage(imgbuf, width, height,
gl.GL_RGBA, gl.GL_UNSIGNED_SHORT_1_5_5_5_REV);
tex.setParameter(gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST);
}
}
//
// ArrType - 输出缓冲区类型
// srcbuf - 带解析的缓冲区
//
function parseImgBuffer(ArrType, srcbuf) {
let skip_buf;
if (isNaN(srcbuf.byteOffset)) {
// srcbuf is ArrayBuffer
skip_buf = new Uint8Array(srcbuf, 4);
} else {
// srcbuf is TypedBuffer,
// 从字节视图取出 ArrayBuffer 重建偏移视图.
skip_buf = new Uint8Array(srcbuf.buffer,
srcbuf.byteOffset + 4, srcbuf.byteLength - 4);
}
let abuf = special.bio2_adt_unpack_img(skip_buf);
return new ArrType(abuf);
}
//
// sbuf 图像 256 * (256+64)
// 第一部分为 256*240
// 第二部分被分割为 4 个小图片
// 两个小图片为一组逐行交叉. 上半部分图片比下半部分多出 8 像素.
// ImgType - 返回图像的缓冲区类型 (Uint16Array)
//
function rebuildMapPic(ImgType, sbuf, width, height) {
let img = new ImgType(width * height);
let offx = 0;
let offy = 256;
let h = 0;
for (let v = 0; v < height; ++v) {
let i = 0;
for (i=0; i<256; ++i) {
img[i + v*width] = sbuf[i + v*256];
}
if (v < 128) {
offx = ((0x01 & v) << 7);
h = 64;
} else {
offx = ((0x01 & v) << 7) + 64;
h = 60;
}
for (; i<width; ++i, ++offx) {
img[i + v*width] = sbuf[offx + 256 * offy];
}
if (1 & v) {
++offy;
if (offy >= 256 + h) offy = 256;
}
// console.log(offx, offy);
}
return img;
}
function parseMaskBuf(sbuf) {
const w = 256;
const h = 256;
const offy = 256 + 64 + 1;
const beginOff = offy * w * 2 + 32;
if (beginOff >= sbuf.byteLength) {
return null;
}
let buf = new Uint8Array(sbuf.buffer, sbuf.byteOffset + beginOff);
return { buf, w, h };
}