| 271 | } |
| 272 | |
| 273 | static void Decode(u8* src, u8* dst) |
| 274 | { |
| 275 | int j; |
| 276 | int linkOfs; |
| 277 | int chunkPos; |
| 278 | int i; |
| 279 | int maskTblPos; |
| 280 | int linkTblOfs; |
| 281 | int chunksOfs; |
| 282 | int count; |
| 283 | int expandSize; |
| 284 | u32 maskBits; |
| 285 | u32 mask; |
| 286 | |
| 287 | expandSize = *(int*)(src + 0x4); |
| 288 | linkTblOfs = *(int*)(src + 0x8); |
| 289 | chunksOfs = *(int*)(src + 0xC); |
| 290 | |
| 291 | i = 0; |
| 292 | maskBits = 0; |
| 293 | maskTblPos = 16; |
| 294 | |
| 295 | do |
| 296 | { |
| 297 | // Get next mask |
| 298 | if (maskBits == 0) |
| 299 | { |
| 300 | mask = *(u32*)(src + maskTblPos); |
| 301 | maskTblPos += sizeof(u32); |
| 302 | maskBits = sizeof(u32) * 8; |
| 303 | } |
| 304 | |
| 305 | // Non-linked chunk |
| 306 | if (mask & 0x80000000) |
| 307 | { |
| 308 | dst[i++] = src[chunksOfs++]; |
| 309 | } |
| 310 | // Linked chunk |
| 311 | else |
| 312 | { |
| 313 | // Read offset from link table |
| 314 | linkOfs = src[linkTblOfs] << 8 | src[linkTblOfs + 1]; |
| 315 | linkTblOfs += sizeof(u16); |
| 316 | |
| 317 | // Apply offset |
| 318 | chunkPos = i - (linkOfs & 0x0FFF); |
| 319 | count = linkOfs >> 12; |
| 320 | if (count == 0) |
| 321 | { |
| 322 | count = src[chunksOfs++] + 0x12; |
| 323 | } |
| 324 | else |
| 325 | { |
| 326 | count += 2; |
| 327 | } |
| 328 | |
| 329 | // Copy chunk |
| 330 | for (j = 0; j < count; j++, i++, chunkPos++) |