Add obj_extractor.

This commit is contained in:
lzwdgc 2015-03-28 00:48:16 +03:00
parent 2b5b48f4fe
commit 79e5ed74eb
5 changed files with 579 additions and 1 deletions

View file

@ -2,4 +2,7 @@ file(GLOB unpaker_src "unpaker/*")
add_executable(unpaker ${unpaker_src})
file(GLOB db_extractor_src "db_extractor/*")
add_executable(db_extractor ${db_extractor_src})
add_executable(db_extractor ${db_extractor_src})
file(GLOB obj_extractor_src "obj_extractor/*")
add_executable(obj_extractor ${obj_extractor_src})

View file

@ -0,0 +1,59 @@
/*
* AIM obj_extractor
* Copyright (C) 2015 lzwdgc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <stdio.h>
#include <string>
#include "objects.h"
#include "other.h"
void read_mmo(string fn)
{
FILE *f = fopen(fn.c_str(), "rb");
if (!f)
return;
Objects objects;
objects.load(f);
MechGroups mgs;
mgs.load(f);
if (feof(f))
{
// custom maps?
fclose(f);
return;
}
MapGoods mg;
mg.load(f);
MapMusic mm;
mm.load(f);
MapSounds ms;
ms.load(f);
fclose(f);
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
cout << "Usage:\n" << argv[0] << " file.mmo" << "\n";
return 1;
}
read_mmo(argv[1]);
return 0;
}

View file

@ -0,0 +1,99 @@
/*
* AIM obj_extractor
* Copyright (C) 2015 lzwdgc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "objects.h"
Segment *Segment::create_segment(FILE *f)
{
SegmentType segment_type;
FREAD(segment_type);
Segment *segment = 0;
switch (segment_type)
{
case SegmentType::ROAD:
segment = new SegmentObjects<Road>;
break;
case SegmentType::BUILDING:
segment = new SegmentObjects<Building>;
break;
case SegmentType::SURFACE:
segment = new SegmentObjects<Surface>;
break;
case SegmentType::STONE:
segment = new SegmentObjects<Stone>;
break;
case SegmentType::HELPER:
segment = new SegmentObjects<Helper>;
break;
case SegmentType::SHELL:
segment = new SegmentObjects<Shell>;
break;
case SegmentType::IMAGE:
segment = new SegmentObjects<Image>;
break;
case SegmentType::EXPLOSION:
segment = new SegmentObjects<Explosion>;
break;
case SegmentType::SOUND:
segment = new SegmentObjects<Sound>;
break;
case SegmentType::MUSIC:
segment = new SegmentObjects<Music>;
break;
case SegmentType::ANOMALY:
segment = new SegmentObjects<Anomaly>;
break;
case SegmentType::TOWER:
segment = new SegmentObjects<Tower>;
break;
case SegmentType::BOUNDARY:
segment = new SegmentObjects<Boundary>;
break;
case SegmentType::GOODS:
segment = new SegmentObjects<Goods>;
break;
case SegmentType::unk1:
segment = new SegmentObjects<unk1>;
break;
default:
assert(false);
break;
}
if (segment)
{
segment->segment_type = segment_type;
FREAD(segment->segment_len);
FREAD(segment->n_objects);
}
return segment;
}
void Objects::load(FILE *f)
{
FREAD(n_segments);
for (int s = 0; s < n_segments; s++)
{
auto seg = Segment::create_segment(f);
if (!seg)
break;
seg->load(f);
segments.push_back(seg);
}
}

185
src/obj_extractor/objects.h Normal file
View file

@ -0,0 +1,185 @@
/*
* AIM obj_extractor
* Copyright (C) 2015 lzwdgc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <string>
#include <vector>
#define FREAD(var) fread(&var, 1, sizeof(var), f)
#define FREAD_N(var, n) fread(&var, 1, n, f)
using namespace std;
enum class SegmentType : uint32_t
{
TEXTURE = 0x1,
MODEL,
SURFACE,
STONE,
TREE,
GLIDER,
HELPER,
ROAD,
WEAPON,
CONFIG,
SHELL, // (AMMO,BULLET)
IMAGE,
EXPLOSION,
EQUIPMENT,
ORGANIZATION,
BUILDING,
LAMP,
COVERING,
SOUND,
MUSIC,
GOODS,
ANOMALY,
TOWER,
BOUNDARY,
SOUND_ZONE,
unk1 = 0x1b,
};
struct Segment
{
SegmentType segment_type;
uint32_t segment_len;
uint32_t n_objects;
virtual ~Segment(){}
static Segment *create_segment(FILE *f);
virtual void load(FILE *f) = 0;
};
template <class T>
struct SegmentObjects : public Segment
{
vector<T> objects;
virtual void load(FILE *f)
{
for (int i = 0; i < n_objects; i++)
{
T r;
r.load(f);
objects.push_back(r);
}
}
};
struct Common
{
float unk2[2];
uint32_t unk3[2];
float unk4[2];
uint32_t unk5[2];
float unk6[8];
void load(FILE *f)
{
FREAD(unk2);
FREAD(unk3);
FREAD(unk4);
FREAD(unk5);
FREAD(unk6);
}
};
struct MapObject : public Common
{
char name1[0x20];
char name2[0x20];
void load(FILE *f)
{
Common::load(f);
FREAD(name1);
FREAD(name2);
}
};
struct MapObjectWithArray : public MapObject
{
uint32_t len;
vector<uint32_t> unk7;
void load(FILE *f)
{
MapObject::load(f);
FREAD(len);
unk7.resize(len);
for (int i = 0; i < len; i++)
FREAD(unk7[i]);
}
};
struct Sound : public Common
{
uint32_t unk1[11];
char name1[0x14];
void load(FILE *f)
{
Common::load(f);
FREAD(unk1);
FREAD(name1);
}
};
struct Road : public MapObjectWithArray {};
struct Tower : public MapObjectWithArray {};
#define KNOWN_OBJECT(name) \
struct name : public MapObject {}
KNOWN_OBJECT(Surface);
KNOWN_OBJECT(Helper);
KNOWN_OBJECT(Shell);
KNOWN_OBJECT(Stone);
KNOWN_OBJECT(Explosion);
KNOWN_OBJECT(Image);
KNOWN_OBJECT(Music);
KNOWN_OBJECT(Anomaly);
KNOWN_OBJECT(Boundary);
#define UNKNOWN_OBJECT(name) \
struct name : public MapObject { void load(FILE *f){ int pos = ftell(f); assert(false); } }
UNKNOWN_OBJECT(Building);
UNKNOWN_OBJECT(Goods);
UNKNOWN_OBJECT(unk1);
struct Objects
{
uint32_t n_segments;
vector<Segment *> segments;
void load(FILE *f);
};

232
src/obj_extractor/other.h Normal file
View file

@ -0,0 +1,232 @@
/*
* AIM obj_extractor
* Copyright (C) 2015 lzwdgc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <string>
#include <vector>
using namespace std;
struct MechGroup
{
char unk1[0x20];
char unk2[0x20];
uint32_t type1;
uint32_t len1;
char name1[0x70];
//{3,4
uint32_t unk30;
//}
//{2
uint32_t len;
vector<uint32_t> unk11;
//}
//{1,0
uint32_t unk20;
uint32_t unk21;
//}
vector<string> configs;
char unk100;
void load(FILE *f)
{
FREAD(unk1);
FREAD(unk2);
FREAD(type1);
FREAD(len1);
FREAD(name1);
if (type1 == 3 || type1 == 4)
{
FREAD(unk30);
}
else if (type1 == 2)
{
FREAD(len);
unk11.resize(len);
for (int i = 0; i < len; i++)
FREAD(unk11[i]);
}
else if (type1 == 1 || type1 == 0)
{
FREAD(unk20);
FREAD(unk21);
}
else
assert(false);
configs.resize(len1, string(0x20, 0));
for (int i = 0; i < len1; i++)
FREAD_N(configs[i][0], 0x20);
FREAD(unk100);
}
};
struct MechGroups
{
uint32_t n;
char prefix[0x30];
vector<MechGroup> mgs;
void load(FILE *f)
{
FREAD(n);
FREAD(prefix);
for (int s = 0; s < n; s++)
{
MechGroup mg;
mg.load(f);
mgs.push_back(mg);
}
}
};
struct Good
{
char name[0x20];
char unk1[0x40];
float price;
float unk2[10];
void load(FILE *f)
{
FREAD(name);
FREAD(unk1);
FREAD(price);
FREAD(unk2);
}
};
struct BuildingGoods
{
char name[0x20];
uint32_t n;
vector<Good> goods;
void load(FILE *f)
{
FREAD(name);
FREAD(n);
for (int i = 0; i < n; i++)
{
Good g;
g.load(f);
goods.push_back(g);
}
}
};
struct MapGoods
{
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t n;
vector<BuildingGoods> bgs;
void load(FILE *f)
{
FREAD(unk1);
FREAD(unk2);
FREAD(unk3);
FREAD(n);
for (int i = 0; i < n; i++)
{
BuildingGoods bg;
bg.load(f);
bgs.push_back(bg);
}
}
};
struct MapMusic
{
uint32_t unk1;
char name1[0x20];
char name2[0x20];
uint32_t n1;
vector<string> names1;
uint32_t n2;
vector<string> names2;
void load(FILE *f)
{
FREAD(unk1);
FREAD(name1);
FREAD(name2);
FREAD(n1);
for (int i = 0; i < n1; i++)
{
char name[0x20];
FREAD(name);
names1.push_back(name);
}
FREAD(n2);
for (int i = 0; i < n2; i++)
{
char name[0x20];
FREAD(name);
names2.push_back(name);
}
}
};
struct MapSound
{
char name[0x20];
float unk1[4];
uint32_t unk2;
float unk3[4];
void load(FILE *f)
{
FREAD(name);
FREAD(unk1);
FREAD(unk2);
FREAD(unk3);
}
};
struct MapSounds
{
uint32_t n;
vector<MapSound> sounds;
void load(FILE *f)
{
FREAD(n);
for (int i = 0; i < n; i++)
{
MapSound s;
s.load(f);
sounds.push_back(s);
}
}
};