mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-15 01:43: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;
|
v10 = v21;
|
||||||
memset32(v16, v18, v15 >> 1);
|
memset32(v16, v18, v15 >> 1);
|
||||||
v19 = (int)((char *)v16 + 4 * (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;
|
*(_WORD *)v19 = v18;
|
||||||
v19 += 2;
|
v19 += 2;
|
||||||
|
|
@ -231,8 +231,11 @@ int decode_f3(char *input, int size, char *output)
|
||||||
}
|
}
|
||||||
goto LABEL_13;
|
goto LABEL_13;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*(_WORD *)v11 = *(_WORD *)&v4[2 * idx];
|
*(_WORD *)v11 = *(_WORD *)&v4[2 * idx];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*(_WORD *)v11 = v12;
|
*(_WORD *)v11 = v12;
|
||||||
|
|
@ -307,3 +310,69 @@ int decode_f4(char *input, int size, char *output, int segment_offset)
|
||||||
}
|
}
|
||||||
return result;
|
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)
|
#define FREAD(var) fread(&var, 1, sizeof(var), f)
|
||||||
|
|
||||||
const int header_size = 0xC;
|
|
||||||
|
|
||||||
void header::load(FILE *f)
|
void header::load(FILE *f)
|
||||||
{
|
{
|
||||||
FREAD(unk1);
|
FREAD(unk1);
|
||||||
|
|
@ -42,7 +40,9 @@ void header::load(FILE *f)
|
||||||
|
|
||||||
void record::load(FILE *f)
|
void record::load(FILE *f)
|
||||||
{
|
{
|
||||||
FREAD(name);
|
char n[0x50];
|
||||||
|
FREAD(n);
|
||||||
|
name = n;
|
||||||
FREAD(pos);
|
FREAD(pos);
|
||||||
FREAD(len);
|
FREAD(len);
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +96,7 @@ int record::read(pak *pak, void *output, int size)
|
||||||
void segment::load_header(FILE *f)
|
void segment::load_header(FILE *f)
|
||||||
{
|
{
|
||||||
FREAD(unk1);
|
FREAD(unk1);
|
||||||
FREAD(flags);
|
FREAD(algorithm);
|
||||||
FREAD(offset);
|
FREAD(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ void segment::load_segment()
|
||||||
auto f = file;
|
auto f = file;
|
||||||
|
|
||||||
fseek(f, offset, SEEK_SET);
|
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 << "Something is wrong. Maybe you trying to open aim2 files?\n";
|
||||||
std::cerr << "They can be opened with SDK extractor.\n";
|
std::cerr << "They can be opened with SDK extractor.\n";
|
||||||
|
|
@ -114,7 +114,7 @@ void segment::load_segment()
|
||||||
|
|
||||||
FREAD(size1);
|
FREAD(size1);
|
||||||
size2 = size1;
|
size2 = size1;
|
||||||
if ((flags & 0x3) && (flags & 0xC))
|
if ((algorithm & 0x3) && (algorithm & 0xC))
|
||||||
{
|
{
|
||||||
FREAD(size2);
|
FREAD(size2);
|
||||||
fread(&decoded[0], 1, size2, f);
|
fread(&decoded[0], 1, size2, f);
|
||||||
|
|
@ -129,19 +129,30 @@ void segment::decompress(int segment_id)
|
||||||
{
|
{
|
||||||
load_segment();
|
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);
|
decode_f1((char*)decoded, size2, (char*)encoded);
|
||||||
else
|
else
|
||||||
decode_f2((char*)decoded, size2, (char*)encoded);
|
decode_f2((char*)decoded, size2, (char*)encoded);
|
||||||
}
|
}
|
||||||
if (flags & 0x3)
|
if ((algorithm & RLE_1_byte) || (algorithm & RLE_2_bytes))
|
||||||
{
|
{
|
||||||
if (flags & 0x1)
|
if (algorithm & RLE_2_bytes)
|
||||||
decode_f3((char*)encoded, size1, (char*)decoded);
|
{
|
||||||
|
//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
|
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
|
struct record
|
||||||
{
|
{
|
||||||
char name[0x50];
|
std::string name;
|
||||||
uint32_t pos;
|
uint32_t pos;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
|
|
||||||
|
|
@ -55,8 +55,16 @@ struct record
|
||||||
|
|
||||||
struct segment
|
struct segment
|
||||||
{
|
{
|
||||||
|
enum decode_algorithm
|
||||||
|
{
|
||||||
|
RLE_2_bytes = 0x1,
|
||||||
|
RLE_1_byte = 0x2,
|
||||||
|
DA_1 = 0x4,
|
||||||
|
DA_2 = 0x8,
|
||||||
|
};
|
||||||
|
|
||||||
uint32_t unk1;
|
uint32_t unk1;
|
||||||
uint32_t flags;
|
decode_algorithm algorithm;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
|
|
||||||
uint32_t size1;
|
uint32_t size1;
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,19 @@ void unpak(string fn)
|
||||||
return;
|
return;
|
||||||
pak p;
|
pak p;
|
||||||
p.load(f);
|
p.load(f);
|
||||||
for (auto &f : p.files)
|
|
||||||
|
auto unpack = [&](auto &file)
|
||||||
{
|
{
|
||||||
record &file = f.second;
|
|
||||||
cout << "Unpacking " << file.name << "\n";
|
cout << "Unpacking " << file.name << "\n";
|
||||||
vector<char> buf(file.len);
|
vector<char> buf(file.len);
|
||||||
file.read(&p, &buf[0], file.len);
|
file.read(&p, &buf[0], file.len);
|
||||||
file.write(fn + ".dir", buf);
|
file.write(fn + ".dir", buf);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unpack(p.files["arena.mmp"]);
|
||||||
|
|
||||||
|
//for (auto &[n,f] : p.files)
|
||||||
|
//unpack(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue