├── .gitignore
├── src
├── aim1_mod_maker
│ ├── aim_fixes.natvis
│ └── aim.exe.injections.h
├── common
│ ├── bmp.h
│ ├── mmap.h
│ ├── tga.h
│ ├── common.h
│ ├── color.h
│ ├── common.natvis
│ ├── common.cpp
│ ├── db.h
│ ├── objects.cpp
│ ├── types.cpp
│ ├── objects.h
│ ├── buffer.h
│ ├── buffer.cpp
│ ├── mat.h
│ ├── db.cpp
│ ├── dxt5.h
│ ├── mmo2.h
│ └── types.h
├── mpj_loader
│ ├── mpj_loader.cpp
│ ├── mpj.h
│ └── mpj.cpp
├── aim1_mod_activator
│ └── mod_activator.cpp
├── mmo_extractor2
│ └── mmo_extractor2.cpp
├── save_loader
│ └── save_loader.cpp
├── mod_reader
│ └── mod_reader.cpp
├── unpaker
│ ├── decode.h
│ └── unpaker.cpp
├── mmm_extractor
│ └── mmm_extractor.cpp
├── db_extractor2
│ └── db_extractor2.cpp
├── mmp_extractor
│ ├── mmp_extractor.cpp
│ ├── mmp.h
│ └── mmp_tex_aim1.txt
├── txt2script
│ └── txt2script.cpp
├── name_generator
│ └── name_generator.cpp
├── tm_converter
│ └── tm_converter.cpp
├── rgb_converter
│ └── rgb_converter.cpp
├── script2txt
│ └── script2txt.cpp
├── db_extractor
│ └── db_extractor.cpp
├── mod_converter2
│ └── mod_converter2.cpp
├── mod_converter
│ └── mod_converter.cpp
├── paker
│ └── paker.cpp
├── mmo_extractor
│ └── other.h
├── bms_converter
│ └── bms_converter.cpp
├── tm_converter2
│ └── tm_converter2.cpp
├── aim1_language_switcher
│ └── language_switcher.cpp
├── db_add_language
│ └── db_add_language.cpp
└── model
│ └── model.h
├── .github
└── workflows
│ └── sw.yml
├── formats
└── tab.ksy
├── README.md
└── sw.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | win*
2 | build
3 | bin
4 | .cppan
5 | doc
6 |
7 | *.dll
8 | *.lnk
9 | *.exe
10 | *.bat
11 |
12 | .sw
13 |
14 | *.diff
15 | *.patch
16 |
17 | *.dat
18 | *.ind
19 | *.tab
20 | *.json
21 |
22 | *.bmp
--------------------------------------------------------------------------------
/src/aim1_mod_maker/aim_fixes.natvis:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {&idx,s}
7 |
8 |
9 |
10 | {idx}
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.github/workflows/sw.yml:
--------------------------------------------------------------------------------
1 | name: sw
2 |
3 | on:
4 | push:
5 | pull_request:
6 | schedule:
7 | # every day
8 | - cron: 0 0 * * *
9 |
10 | jobs:
11 | build:
12 | runs-on: ${{ matrix.os }}
13 | strategy:
14 | fail-fast: false
15 | matrix:
16 | os: [windows-latest]
17 |
18 | steps:
19 | - uses: actions/checkout@v1
20 | - uses: egorpugin/sw-action@master
21 |
22 | - name: build
23 | run: ./sw -static build
24 |
25 | - uses: actions/upload-artifact@v3
26 | with:
27 | name: sw
28 | path: .sw/out/**/*.exe
29 |
--------------------------------------------------------------------------------
/src/common/bmp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #pragma pack(push, 1)
6 |
7 | struct bmp_header
8 | {
9 | int16_t bfType;
10 | int32_t bfSize;
11 | int16_t bfReserved1;
12 | int16_t bfReserved2;
13 | int32_t bfOffBits;
14 | };
15 |
16 | struct bmp_info_header
17 | {
18 | int32_t biSize;
19 | int32_t biWidth;
20 | int32_t biHeight;
21 | int16_t biPlanes;
22 | int16_t biBitCount;
23 | int32_t biCompression;
24 | int32_t biSizeImage;
25 | int32_t biXPelsPerMeter;
26 | int32_t biYPelsPerMeter;
27 | int32_t biClrUsed;
28 | int32_t biClrImportant;
29 | };
30 |
31 | struct rgb_quad
32 | {
33 | int8_t rgbBlue;
34 | int8_t rgbGreen;
35 | int8_t rgbRed;
36 | int8_t rgbReserved;
37 | };
38 |
39 | struct bmp_info
40 | {
41 |
42 | bmp_info_header bmiHeader;
43 | rgb_quad bmiColors[1];
44 | };
45 |
46 | #pragma pack(pop)
47 |
--------------------------------------------------------------------------------
/src/common/mmap.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | struct stream {
7 | primitives::templates2::mmap_file &m;
8 | uint8_t *p{m.p};
9 |
10 | template
11 | operator T &() {
12 | auto &r = *(T *)p;
13 | p += sizeof(T);
14 | return r;
15 | }
16 | template
17 | auto span(size_t len) {
18 | auto s = std::span((T *)p, len);
19 | p += sizeof(T) * len;
20 | return s;
21 | }
22 | template
23 | void operator=(const T &v) {
24 | memcpy(p, (uint8_t*)&v, sizeof(v));
25 | p += sizeof(v);
26 | }
27 | template
28 | void read(std::vector &v) {
29 | memcpy(v.data(), p, sizeof(T) * v.size());
30 | p += sizeof(T) * v.size();
31 | }
32 | void skip(size_t len) {
33 | p += len;
34 | }
35 | };
36 |
--------------------------------------------------------------------------------
/formats/tab.ksy:
--------------------------------------------------------------------------------
1 | meta:
2 | id: aim_db_tab
3 | endian: le
4 |
5 | seq:
6 | - id: header
7 | type: tab
8 | - id: tables
9 | type: table
10 | repeat: expr
11 | repeat-expr: header.n_tables
12 | - id: fields
13 | type: field
14 | repeat: expr
15 | repeat-expr: header.n_fields
16 |
17 | types:
18 | char20:
19 | seq:
20 | - id: str
21 | type: str
22 | encoding: ASCII
23 | size: 0x20
24 |
25 | tab:
26 | seq:
27 | - id: n_tables
28 | type: u4
29 | - id: n_fields
30 | type: u4
31 |
32 | table:
33 | seq:
34 | - id: id
35 | type: u4
36 | - id: name
37 | type: char20
38 | - id: unk
39 | type: u4
40 |
41 | field:
42 | seq:
43 | - id: table_id
44 | type: u4
45 | - id: id
46 | type: u4
47 | - id: name
48 | type: char20
49 | - id: field_type
50 | type: u4
51 |
--------------------------------------------------------------------------------
/src/aim1_mod_maker/aim.exe.injections.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #ifdef DONT_OPTIMIZE
6 | #pragma optimize("", off)
7 | #endif
8 |
9 | constexpr auto call_command_length = 5;
10 |
11 | // public enums
12 | enum aim1_fix : uint32_t {
13 | script_function__ISGLIDER = 0x0043A1F6,
14 | trade_actions_weapon_checks = 0x004072FA,
15 | setup_proper_weapon_slots_for_a_glider = 0x004D62E4,
16 | put_weapon_into_the_right_slot_after_purchase = 0x00417A6D,
17 | sell_correct_weapon = 0x004176BC,
18 | empty_light_weapon_message = 0x004067C4,
19 | empty_heavy_weapon_message = 0x0040688B,
20 | can_leave_trade_window = 0x0040C20E,
21 | };
22 | // set different size if your injection takes more than default 5 bytes
23 | uint32_t get_injection_size(uint32_t key) {
24 | switch (key) {
25 | case aim1_fix::script_function__ISGLIDER: return 10;
26 | case aim1_fix::can_leave_trade_window: return 6;
27 | default: return call_command_length;
28 | }
29 | }
30 |
31 | #ifdef DONT_OPTIMIZE
32 | #pragma optimize("", on)
33 | #endif
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # A.I.M. Tools
2 | This repository contains different tools for A.I.M. games.
3 |
4 | # List of tools
5 | 1. AIM unpaker. Unpacks any .pak archive from AIM1/AIM2/AIM:R games.
6 | 1. AIM paker. Makes archive for AIM1 game (without compression).
7 | 1. DB extractor. Converts (db|quest) databases from any AIM game into .sql file to be executed with sqlite3 DBMS.
8 | 1. MMO extractor (object extractor). Extracts all data about objects on the map from .mmo file.
9 | 1. MMP extractor. Extract texture-, alpha-, height- maps etc.
10 | 1. MMM extractor. Minimap -> BMP.
11 | 1. Models converter: AIM1/2 format -> .OBJ + .MTL. Textures are included.
12 | 1. Script to TXT convertor.
13 | 1. TXT to Script convertor.
14 | 1. Texture converter: TM -> TGA.
15 | 1. MPJ loader (dummy implementation).
16 | 1. Save loader (dummy implementation).
17 | 1. AIM1 mod maker. Makes routine actions for you.
18 |
19 | # Build instructions
20 | 1. Download and add to PATH latest SW https://software-network.org/
21 | 2. Clone this repository
22 | 3. Open the source directory
23 | 4. Execute in console `sw generate`
24 | 5. Open generated solution file (Visual Studio solution file)
25 | 6. Build the project
26 |
--------------------------------------------------------------------------------
/src/mpj_loader/mpj_loader.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * AIM mpj_loader
3 | * Copyright (C) 2015 lzwdgc
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "mpj.h"
20 |
21 | #include
22 | #include
23 | #include
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | using namespace std;
32 |
33 | int main(int argc, char *argv[])
34 | {
35 | cl::opt p(cl::Positional, cl::desc(""), cl::Required);
36 |
37 | cl::ParseCommandLineOptions(argc, argv);
38 |
39 | mpj m;
40 | m.load(p);
41 | return 0;
42 | }
43 |
--------------------------------------------------------------------------------
/src/common/tga.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "buffer.h"
4 |
5 | #include
6 | #include
7 |
8 | #pragma pack(push, 1)
9 |
10 | // http://paulbourke.net/dataformats/tga/
11 | struct tga
12 | {
13 | uint8_t idlength; // label length
14 | uint8_t colourmaptype = 0;
15 | uint8_t datatypecode = 2;
16 | uint16_t colourmaporigin = 0;
17 | uint16_t colourmaplength = 0;
18 | uint8_t colourmapdepth = 0;
19 | uint16_t x_origin = 0;
20 | uint16_t y_origin = 0;
21 | uint16_t width;
22 | uint16_t height;
23 | uint8_t bitsperpixel = 32;
24 | uint8_t imagedescriptor = 0x28;
25 |
26 | tga()
27 | {
28 | idlength = (uint8_t)strlen(label());
29 | }
30 | constexpr const char *label() const
31 | {
32 | return "AIMTMConverter";
33 | }
34 |
35 | void write(buffer &b)
36 | {
37 | b.write(idlength);
38 | b.write(colourmaptype);
39 | b.write(datatypecode);
40 | b.write(colourmaporigin);
41 | b.write(colourmaplength);
42 | b.write(colourmapdepth);
43 | b.write(x_origin);
44 | b.write(y_origin);
45 | b.write(width);
46 | b.write(height);
47 | b.write(bitsperpixel);
48 | b.write(imagedescriptor);
49 | b.write(label(), idlength);
50 | }
51 | };
52 |
53 | #pragma pack(pop)
54 |
--------------------------------------------------------------------------------
/src/aim1_mod_activator/mod_activator.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * AIM mod_activator
3 | * Copyright (C) 2024 lzwdgc
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | void activate(auto &&fn) {
24 | // files will get new timestamp automatically
25 | // our unpack_file() does not preserve timestamps
26 | unpack_file(fn, fs::current_path());
27 | }
28 |
29 | int main(int argc, char *argv[])
30 | {
31 | cl::opt p(cl::Positional, cl::desc(""), cl::value_desc("file"), cl::Required);
32 |
33 | cl::ParseCommandLineOptions(argc, argv);
34 |
35 | if (fs::is_regular_file(p)) {
36 | activate(p);
37 | } else {
38 | throw std::runtime_error("Bad fs object");
39 | }
40 |
41 | return 0;
42 | }
43 |
--------------------------------------------------------------------------------
/src/mmo_extractor2/mmo_extractor2.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * AIM mmo_extractor2 (only for aim1)
3 | * Copyright (C) 2024 lzwdgc
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "mmo2.h"
20 | #include "objects.h"
21 |
22 | #include
23 | #include
24 |
25 | void read_mmo(const path &fn)
26 | {
27 | mmo_storage2 s{fn};
28 | s.load();
29 | }
30 |
31 | int main(int argc, char *argv[])
32 | {
33 | cl::opt p(cl::Positional, cl::desc("<.mmo file or directory with .mmo files>"), cl::value_desc("file or directory"), cl::Required);
34 |
35 | cl::ParseCommandLineOptions(argc, argv);
36 |
37 | if (fs::is_regular_file(p))
38 | read_mmo(p);
39 | else if (fs::is_directory(p))
40 | {
41 | auto files = enumerate_files_like(p, ".*\\.[Mm][Mm][Oo]", false);
42 | for (auto &file : files)
43 | {
44 | std::cerr << "processing: " << file << "\n";
45 | read_mmo(file);
46 | }
47 | }
48 | else
49 | throw std::runtime_error("Bad fs object");
50 |
51 | return 0;
52 | }
53 |
--------------------------------------------------------------------------------
/src/common/common.h:
--------------------------------------------------------------------------------
1 | /*
2 | * AIM tools
3 | * Copyright (C) 2015 lzwdgc
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include
22 | #include