-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathjames_camerons_avatar_the_game_pak.bms
155 lines (151 loc) · 4.15 KB
/
james_camerons_avatar_the_game_pak.bms
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
152
153
154
155
# Ubisoft - *.pak(PAK!)
# ---
# James Cameron's Avatar: The Game (Windows Vista, PlayStation 3?, Xbox 360)
math max_chunk_size = 0x10000
goto 0
idstring "PAK!"
get pak_01 long
if pak_01 != 4
print " unknown PAK version number "
cleanexit
endif
get pak_info_offset1 long
goto pak_info_offset1
get compressed_info_size long
xmath pak_info_offset2 "pak_info_offset1 + compressed_info_size"
goto pak_info_offset2
get pak_info_chunks long
for i = 0 < pak_info_chunks
get chunk1 long
putarray 0 i chunk1
get chunk2 long
xmath chunk2_1 "chunk2 & 0x7fffffff"
putarray 1 i chunk2_1
xmath chunk2_2 "(chunk2 & 0x80000000) >> 31"
putarray 2 i chunk2_2
xmath chunk2_3 "chunk2_1 + pak_info_offset1"
putarray 3 i chunk2_3
next i
xmath pak_info_c2 "pak_info_chunks - 1"
for i1 = 0 < pak_info_chunks
getarray chunk1 0 i1
getarray chunk2_1 1 i1
if i1 != pak_info_c2
xmath i2 "i1 + 1"
getarray chunk1_1 0 i2
getarray chunk2_1_1 1 i2
xmath chunk3 "chunk1_1 - chunk1"
xmath chunk4 "chunk2_1_1 - chunk2_1"
putarray 4 i1 chunk3
putarray 5 i1 chunk4
else
putarray 4 i1 0
putarray 5 i1 0
endif
next i1
xmath pak_info_alloc "pak_info_chunks * max_chunk_size"
putvarchr MEMORY_FILE pak_info_alloc 0
log MEMORY_FILE 0 0
append
for i3 = 0 < pak_info_chunks
getarray chunk1 0 i3
getarray chunk2_1 1 i3
getarray chunk2_2 2 i3
getarray chunk2_3 3 i3
getarray chunk3 4 i3
getarray chunk4 5 i3
if chunk2_2 != 1
log MEMORY_FILE chunk2_3 chunk3
else
clog MEMORY_FILE chunk2_3 chunk4 chunk3
endif
next i3
append
goto 0 MEMORY_FILE
comtype lzo1x
get info1 byte MEMORY_FILE
if info1 != 1
print " unknown PAK info number. "
cleanexit
endif
get pak_files long MEMORY_FILE
math pak_file_info_offset1 = 5
for steps = 0 < 2
for i4 = 0 < pak_files
get file_offset long MEMORY_FILE
get file_size long MEMORY_FILE # full filesize
get file_name_hash long MEMORY_FILE
xmath file_chunks1 "file_size / max_chunk_size"
xmath file_chunks2 "file_size % max_chunk_size"
if file_chunks2 != 0
math file_chunks1 + 1
endif
if steps == 0
for j1 = 0 < file_chunks1
get file_chunk1 short MEMORY_FILE
get file_chunk2 short MEMORY_FILE
next j1
elif steps == 1
savepos temp1 MEMORY_FILE
goto pak_file_info_offset2 MEMORY_FILE
get file_creation_date time64 MEMORY_FILE
get file_name_string_size byte MEMORY_FILE
getdstring file_name file_name_string_size MEMORY_FILE
savepos pak_file_info_offset2 MEMORY_FILE
goto temp1 MEMORY_FILE
callfunction extract_file 1
endif
next i4
if steps == 0
savepos pak_file_info_offset2 MEMORY_FILE
endif
goto pak_file_info_offset1 MEMORY_FILE
next steps
startfunction extract_file
putvarchr MEMORY_FILE2 file_size 0
log MEMORY_FILE2 0 0
math chunk_offset = file_offset
math remaining_size = file_size
xmath file_chunks3 "file_chunks1 - 1"
append
for j2 = 0 < file_chunks1
math chunk_is_compressed = 1
get file_chunk11 short MEMORY_FILE
get file_chunk21 short MEMORY_FILE
math compressed_size = 0
math decompressed_size = 0
if file_chunk21 == 0
math compressed_size = file_chunk11
if file_chunks2 == 1
math decompressed_size = file_size
else
if j2 == file_chunks3
math decompressed_size = remaining_size
else
math decompressed_size = max_chunk_size
endif
endif
math remaining_size - decompressed_size
elif file_chunk21 == 0xffff
math chunk_is_compressed = 0
if file_chunk11 == 0
math remaining_size - max_chunk_size
math compressed_size = max_chunk_size
math decompressed_size = compressed_size
else
xmath compressed_size "(file_chunk11 ^ file_chunk21) + 1"
math decompressed_size = compressed_size
math remaining_size - decompressed_size
endif
endif
if chunk_is_compressed != 0
clog MEMORY_FILE2 chunk_offset compressed_size decompressed_size 0
else
log MEMORY_FILE2 chunk_offset compressed_size 0
endif
math chunk_offset + compressed_size
next j2
append
log file_name 0 file_size MEMORY_FILE2
log MEMORY_FILE2 0 0
endfunction