/*
Giga Entergram .arc extractor
Copyright (C) 2024 rahcchi (https://github.com/rahcchi)
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 <vector>
#include <fstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
bool file_exists(char* filename) {
struct stat buffer;
return (stat(filename, &buffer) == 0);
}
#ifdef _WIN32
#include <direct.h>
#define mkdir(F,A) _mkdir(F)
#endif
typedef struct header {
uint32_t unk;
uint32_t file_number;
} header;
typedef struct entry_header {
char file_name[64];
uint32_t size;
uint32_t offset;
} entry_header;
template<typename T>
T get(const uint8_t* data, int offset) {
return *(T*)&data[offset];
}
int main(int argc, char* argv[]) {
setlocale(LC_ALL, "");
if (!file_exists(argv[1])) {
return -1;
}
std::vector<entry_header> entries;
std::vector<uint8_t> filedata;
std::ifstream is(argv[1], std::ios::binary);
is.seekg(0, std::ios_base::end);
std::size_t filesize = is.tellg();
is.seekg(0, std::ios_base::beg);
filedata.resize(filesize);
is.read((char*)&filedata[0], (std::streamsize)filesize);
is.close();
int global_offset = 0;
header file;
file.unk = get<uint32_t>(filedata.data(), global_offset);
global_offset += sizeof(uint32_t);
file.file_number = get<uint32_t>(filedata.data(), global_offset);
global_offset += sizeof(uint32_t);
std::vector<entry_header> files;
for (uint32_t i = 0; i < file.file_number; i++) {
entry_header f;
memcpy(&f.file_name, filedata.data() + global_offset, 64);
global_offset += 64;
f.size = get<uint32_t>(filedata.data(), global_offset);
global_offset += sizeof(uint32_t);
f.offset = get<uint32_t>(filedata.data(), global_offset);
global_offset += sizeof(uint32_t);
files.push_back(f);
}
printf("FOUND %d FILES\n", file.file_number);
mkdir("out", 0777);
for (int i = 0; i < files.size(); i++) {
char buffer[256];
memset(buffer, 0, 256);
sprintf(buffer, ".\\out\\%s", files[i].file_name);
FILE* f = fopen(buffer, "wb");
if (f != NULL) {
fwrite((char*)filedata.data() + files[i].offset, files[i].size, 1, f);
fclose(f);
printf("EXTRACTED %s\n", files[i].file_name);
}
}
return 0;
}