mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
Reimplement decode_f4(). It uses RLE.
This commit is contained in:
parent
aad50f9160
commit
13be828ef6
4 changed files with 111 additions and 18 deletions
|
|
@ -222,7 +222,7 @@ int decode_f3(char *input, int size, char *output)
|
|||
v10 = v21;
|
||||
memset32(v16, v18, v15 >> 1);
|
||||
v19 = (int)((char *)v16 + 4 * (v15 >> 1));
|
||||
for (i = (v13 + 3) & 1; i; --i)
|
||||
for (i = v15 & 1; i; --i)
|
||||
{
|
||||
*(_WORD *)v19 = v18;
|
||||
v19 += 2;
|
||||
|
|
@ -231,7 +231,10 @@ int decode_f3(char *input, int size, char *output)
|
|||
}
|
||||
goto LABEL_13;
|
||||
}
|
||||
*(_WORD *)v11 = *(_WORD *)&v4[2 * idx];
|
||||
else
|
||||
{
|
||||
*(_WORD *)v11 = *(_WORD *)&v4[2 * idx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -307,3 +310,69 @@ int decode_f4(char *input, int size, char *output, int segment_offset)
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void decode_rle(const short *input, const int size, short *output)
|
||||
{
|
||||
if (size < 2)
|
||||
return;
|
||||
|
||||
// input ptr, also rle_indicator
|
||||
const auto rle_indicator = input++;
|
||||
while (1)
|
||||
{
|
||||
auto c = *input++;
|
||||
if ((c & 0xFF00) != (*rle_indicator << 8))
|
||||
*output++ = c;
|
||||
else
|
||||
{
|
||||
uint32_t count = (uint8_t)c;
|
||||
if (count == (*rle_indicator << 8) + 255)
|
||||
*output++ = c; // insert indicator byte itself
|
||||
else
|
||||
{
|
||||
count += 3;
|
||||
for (int i = 0; i < count / 2; i++)
|
||||
{
|
||||
*output++ = *input;
|
||||
*output++ = *input;
|
||||
}
|
||||
for (int i = 0; i < ((count / 2) & 1); i++)
|
||||
{
|
||||
*output++ = *input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input >= rle_indicator + size)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void decode_rle(const char *input, const int size, char *output)
|
||||
{
|
||||
if (size < 2)
|
||||
return;
|
||||
|
||||
// input ptr, also rle_indicator
|
||||
const auto rle_indicator = input++;
|
||||
while (1)
|
||||
{
|
||||
auto c = *input++;
|
||||
if (c != *rle_indicator)
|
||||
*output++ = c;
|
||||
else
|
||||
{
|
||||
uint32_t count = (uint8_t)*input++;
|
||||
if (count == 255)
|
||||
*output++ = *rle_indicator; // insert indicator byte itself
|
||||
else
|
||||
{
|
||||
memset(output, *input++, count += 3);
|
||||
output += count;
|
||||
}
|
||||
}
|
||||
|
||||
if (input >= rle_indicator + size)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@
|
|||
|
||||
#define FREAD(var) fread(&var, 1, sizeof(var), f)
|
||||
|
||||
const int header_size = 0xC;
|
||||
|
||||
void header::load(FILE *f)
|
||||
{
|
||||
FREAD(unk1);
|
||||
|
|
@ -42,7 +40,9 @@ void header::load(FILE *f)
|
|||
|
||||
void record::load(FILE *f)
|
||||
{
|
||||
FREAD(name);
|
||||
char n[0x50];
|
||||
FREAD(n);
|
||||
name = n;
|
||||
FREAD(pos);
|
||||
FREAD(len);
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ int record::read(pak *pak, void *output, int size)
|
|||
void segment::load_header(FILE *f)
|
||||
{
|
||||
FREAD(unk1);
|
||||
FREAD(flags);
|
||||
FREAD(algorithm);
|
||||
FREAD(offset);
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ void segment::load_segment()
|
|||
auto f = file;
|
||||
|
||||
fseek(f, offset, SEEK_SET);
|
||||
if (flags == 0)
|
||||
if (algorithm == 0)
|
||||
{
|
||||
std::cerr << "Something is wrong. Maybe you trying to open aim2 files?\n";
|
||||
std::cerr << "They can be opened with SDK extractor.\n";
|
||||
|
|
@ -114,7 +114,7 @@ void segment::load_segment()
|
|||
|
||||
FREAD(size1);
|
||||
size2 = size1;
|
||||
if ((flags & 0x3) && (flags & 0xC))
|
||||
if ((algorithm & 0x3) && (algorithm & 0xC))
|
||||
{
|
||||
FREAD(size2);
|
||||
fread(&decoded[0], 1, size2, f);
|
||||
|
|
@ -129,19 +129,30 @@ void segment::decompress(int segment_id)
|
|||
{
|
||||
load_segment();
|
||||
|
||||
if (flags & 0xC)
|
||||
if ((algorithm & DA_1) || (algorithm & DA_2))
|
||||
{
|
||||
if (flags & 0x4)
|
||||
if (algorithm & DA_1)
|
||||
decode_f1((char*)decoded, size2, (char*)encoded);
|
||||
else
|
||||
decode_f2((char*)decoded, size2, (char*)encoded);
|
||||
}
|
||||
if (flags & 0x3)
|
||||
if ((algorithm & RLE_1_byte) || (algorithm & RLE_2_bytes))
|
||||
{
|
||||
if (flags & 0x1)
|
||||
decode_f3((char*)encoded, size1, (char*)decoded);
|
||||
if (algorithm & RLE_2_bytes)
|
||||
{
|
||||
//static std::vector<uint8_t> buf(4194432);
|
||||
decode_f3((char*)encoded, size1, (char*)decoded/*buf.data()*/);
|
||||
//decode_rle((short*)encoded, size1, (short*)decoded);
|
||||
//assert(memcmp(decoded, buf.data(), size1) == 0);
|
||||
}
|
||||
else
|
||||
decode_f4((char*)encoded, size1, (char*)decoded, segment_id * header_size);
|
||||
{
|
||||
//static std::vector<uint8_t> buf(4194432);
|
||||
//const int header_size = 0xC;
|
||||
//decode_f4((char*)encoded, size1, (char*)buf.data(), segment_id * header_size);
|
||||
decode_rle((char*)encoded, size1, (char*)decoded);
|
||||
//assert(memcmp(decoded, buf.data(), size1) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ struct header
|
|||
|
||||
struct record
|
||||
{
|
||||
char name[0x50];
|
||||
std::string name;
|
||||
uint32_t pos;
|
||||
uint32_t len;
|
||||
|
||||
|
|
@ -55,8 +55,16 @@ struct record
|
|||
|
||||
struct segment
|
||||
{
|
||||
enum decode_algorithm
|
||||
{
|
||||
RLE_2_bytes = 0x1,
|
||||
RLE_1_byte = 0x2,
|
||||
DA_1 = 0x4,
|
||||
DA_2 = 0x8,
|
||||
};
|
||||
|
||||
uint32_t unk1;
|
||||
uint32_t flags;
|
||||
decode_algorithm algorithm;
|
||||
uint32_t offset;
|
||||
|
||||
uint32_t size1;
|
||||
|
|
|
|||
|
|
@ -27,14 +27,19 @@ void unpak(string fn)
|
|||
return;
|
||||
pak p;
|
||||
p.load(f);
|
||||
for (auto &f : p.files)
|
||||
|
||||
auto unpack = [&](auto &file)
|
||||
{
|
||||
record &file = f.second;
|
||||
cout << "Unpacking " << file.name << "\n";
|
||||
vector<char> buf(file.len);
|
||||
file.read(&p, &buf[0], file.len);
|
||||
file.write(fn + ".dir", buf);
|
||||
};
|
||||
|
||||
unpack(p.files["arena.mmp"]);
|
||||
|
||||
//for (auto &[n,f] : p.files)
|
||||
//unpack(f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue