mirror of
https://github.com/Mikompilation/Mikompilation.git
synced 2024-11-27 00:20:48 +00:00
Add New Logo By @MasterHimuro (#17)
* Add New Logo By @MasterHimuro * Fix compiler issues for VS 2019 * Extractor cli is completed, still has some issues for file name for us and jp * Add Linux 32bit Toolchain
This commit is contained in:
parent
569a77c4fb
commit
911b59c202
@ -1,5 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.20.2)
|
||||
|
||||
if (UNIX)
|
||||
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux-compiler-i386-multilib.cmake CACHE STRING "")
|
||||
endif ()
|
||||
|
||||
project(Mikompilation CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
@ -20,7 +24,11 @@ set(SOURCES
|
||||
src/main.cpp
|
||||
)
|
||||
|
||||
add_executable(Mikompilation ${SOURCES})
|
||||
if (WIN32)
|
||||
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/icon.rc")
|
||||
ENDIF ()
|
||||
|
||||
add_executable(Mikompilation ${SOURCES} ${APP_ICON_RESOURCE_WINDOWS})
|
||||
|
||||
target_link_libraries(Mikompilation PUBLIC
|
||||
${UI_LIB}
|
||||
@ -35,8 +43,8 @@ target_include_directories(Mikompilation PUBLIC
|
||||
)
|
||||
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/resources $<TARGET_FILE_DIR:${PROJECT_NAME}>/resources)
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/resources $<TARGET_FILE_DIR:${PROJECT_NAME}>/resources)
|
||||
|
||||
file(
|
||||
GENERATE
|
||||
|
24
README.md
24
README.md
@ -1,11 +1,17 @@
|
||||
# Mikompilation
|
||||
[![Build Mikompilation](https://github.com/wagrenier/Mikompilation/actions/workflows/Build.yml/badge.svg)](https://github.com/wagrenier/Mikompilation/actions/workflows/Build.yml) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/Ap4Sfcmwd9)
|
||||
|
||||
![Logo](logo/logo_blood.png)
|
||||
|
||||
Decompilation project for the Fatal Frame 2 : Crimson Butterfly;Project Zero 2;<ruby>零<rt>ぜろ</rt></ruby>~<ruby>紅い蝶<rt>あかいちょう</rt> game engine. Our goal is to have a fully playable port on PC and maybe on future platforms too.
|
||||
|
||||
Mainly a project to learn about reversing and coding in OpenGL.
|
||||
|
||||
## Special Thanks
|
||||
* [@MasterHimuro](https://twitter.com/masterhimuro) for doing the logo
|
||||
|
||||
## Build
|
||||
Right now, the application only builds for `x32` due to restrictions from the game's code and memory layout.
|
||||
### Linux
|
||||
|
||||
Run the following commands to install the required dependencies:
|
||||
@ -15,22 +21,26 @@ sudo apt install xorg-dev
|
||||
```
|
||||
|
||||
## Common
|
||||
Library containing all common functions needed by most libraries of the proejct. Contains things like vector math, configurations and printing.
|
||||
Library containing all common functions needed by most libraries of the project. Contains things like vector math, configurations and printing.
|
||||
|
||||
## Engine
|
||||
This folder contains all sources related to the game engine.
|
||||
|
||||
## Extractor
|
||||
Tools for extracting game files.
|
||||
## Tools
|
||||
### Argparse
|
||||
Library for making cli simple
|
||||
|
||||
## Render
|
||||
Library for interfacing with the graphics api, for the moment it is only OpenGL
|
||||
### ExportStruct
|
||||
Tool to export raw values from an elf to a well formatted struct.
|
||||
|
||||
### Extractor
|
||||
Tools for extracting game files. This tool should run before the main executable
|
||||
|
||||
## Third-Party
|
||||
Library containing all of the project's external libraries.
|
||||
Library containing all the project's external libraries.
|
||||
|
||||
## UI
|
||||
Library containing the source code for the UI, mostly ImGui realted stuff.
|
||||
Library containing the source code for the UI, mostly ImGui related stuff.
|
||||
|
||||
## Src
|
||||
Folder containing the main logic of the application.
|
||||
|
55
cmake/linux-compiler-i386-multilib.cmake
Normal file
55
cmake/linux-compiler-i386-multilib.cmake
Normal file
@ -0,0 +1,55 @@
|
||||
# Tell cmake we are cross compiling and targeting linux
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR i686)
|
||||
|
||||
# It could be i?86-*linux-gnu, x86_64-*linux-gnu, x86_64-*linux-gnux32, etc.
|
||||
# Leave it generic to only support amd64 or x32 to i386 with any compiler.
|
||||
if ("$ENV{CC}" STREQUAL "")
|
||||
set(CMAKE_C_COMPILER cc -m32)
|
||||
elseif(NOT "$ENV{CC}" MATCHES "-m32")
|
||||
set(CMAKE_C_COMPILER $ENV{CC} -m32)
|
||||
endif()
|
||||
if ("$ENV{CXX}" STREQUAL "")
|
||||
set(CMAKE_CXX_COMPILER c++ -m32)
|
||||
elseif(NOT "$ENV{CXX}" MATCHES "-m32")
|
||||
set(CMAKE_CXX_COMPILER $ENV{CXX} -m32)
|
||||
endif()
|
||||
|
||||
# cmake 2.8.5 correctly sets CMAKE_LIBRARY_ARCHITECTURE for Debian multiarch.
|
||||
# Be really strict about what gets used.
|
||||
if(EXISTS /usr/lib/i386-linux-gnu)
|
||||
set(CMAKE_SYSTEM_IGNORE_PATH
|
||||
/lib /lib64 /lib32
|
||||
/usr/lib /usr/lib64 /usr/lib32
|
||||
/usr/local/lib /usr/local/lib64 /usr/local/lib32)
|
||||
list(APPEND CMAKE_LIBRARY_PATH /usr/local/lib/i386-linux-gnu)
|
||||
list(APPEND CMAKE_LIBRARY_PATH /usr/lib/i386-linux-gnu)
|
||||
list(APPEND CMAKE_LIBRARY_PATH /lib/i386-linux-gnu)
|
||||
elseif(EXISTS /usr/lib32)
|
||||
set(CMAKE_SYSTEM_IGNORE_PATH
|
||||
/lib /lib64
|
||||
/usr/lib /usr/lib64
|
||||
/usr/local/lib /usr/local/lib64)
|
||||
set(CMAKE_LIBRARY_ARCHITECTURE "../lib32")
|
||||
list(APPEND CMAKE_LIBRARY_PATH /usr/local/lib32)
|
||||
list(APPEND CMAKE_LIBRARY_PATH /usr/lib32)
|
||||
list(APPEND CMAKE_LIBRARY_PATH /lib32)
|
||||
else()
|
||||
set(CMAKE_SYSTEM_IGNORE_PATH
|
||||
/lib64
|
||||
/usr/lib64
|
||||
/usr/local/lib64)
|
||||
set(CMAKE_LIBRARY_ARCHITECTURE ".")
|
||||
list(APPEND CMAKE_LIBRARY_PATH /usr/local/lib)
|
||||
list(APPEND CMAKE_LIBRARY_PATH /usr/lib)
|
||||
list(APPEND CMAKE_LIBRARY_PATH /lib)
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES CMAKE_LIBRARY_PATH)
|
||||
|
||||
# If given a CMAKE_FIND_ROOT_PATH then
|
||||
# FIND_PROGRAM ignores CMAKE_FIND_ROOT_PATH (probably can't run)
|
||||
# FIND_{LIBRARY,INCLUDE,PACKAGE} only uses the files in CMAKE_FIND_ROOT_PATH.
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
|
@ -1,23 +1,20 @@
|
||||
#include "glf3_render.h"
|
||||
#include "GFX_CONFIG.h"
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "logging/printing.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <cstdio>
|
||||
|
||||
void GLAPIENTRY
|
||||
MessageCallback(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
const void* userParam )
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb/stb_image.h"
|
||||
|
||||
void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id,
|
||||
GLenum severity, GLsizei length,
|
||||
const GLchar *message, const void *userParam)
|
||||
{
|
||||
const auto logger = spdlog::get(ENGINE_LOGGER);
|
||||
logger->error("GL CALLBACK: {} type = {:x}, severity = {:x}, message = {}",
|
||||
(type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
|
||||
type, severity, message);
|
||||
(type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type,
|
||||
severity, message);
|
||||
}
|
||||
|
||||
GLFWwindow *InitializeWindow()
|
||||
@ -36,22 +33,36 @@ GLFWwindow *InitializeWindow()
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
glEnable(GL_DEBUG_OUTPUT );
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
|
||||
engineLogger->info("Creating GLFW window");
|
||||
|
||||
GLFWwindow *window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Mikompilation", NULL, NULL);
|
||||
GLFWwindow *window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT,
|
||||
"Mikompilation", NULL, NULL);
|
||||
|
||||
int width, height, channel;
|
||||
stbi_uc *img = stbi_load("resources/icon.png", &width, &height, &channel, 0);
|
||||
GLFWimage glfwImage;
|
||||
|
||||
glfwImage.width = width;
|
||||
glfwImage.height = height;
|
||||
glfwImage.pixels = img;
|
||||
|
||||
glfwSetWindowIcon(window, 1, &glfwImage);
|
||||
|
||||
stbi_image_free(img);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
glewExperimental = GL_TRUE;
|
||||
GLenum err = glewInit();
|
||||
|
||||
glDebugMessageCallback( MessageCallback, 0 );
|
||||
glDebugMessageCallback(MessageCallback, 0);
|
||||
|
||||
if (GLEW_OK != err)
|
||||
{
|
||||
engineLogger->critical("GLFW failed to initialize: {}", glewGetErrorString(err));
|
||||
engineLogger->critical("GLFW failed to initialize: {}",
|
||||
glewGetErrorString(err));
|
||||
}
|
||||
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
@ -89,7 +100,7 @@ void teardown(GLFWwindow *window)
|
||||
|
||||
void startNewFrame()
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f );
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
|
BIN
logo/logo_blood.png
Normal file
BIN
logo/logo_blood.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 274 KiB |
BIN
logo/logo_blood_icon.ico
Normal file
BIN
logo/logo_blood_icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 148 KiB |
BIN
logo/logo_icon_png.png
Normal file
BIN
logo/logo_icon_png.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 242 KiB |
BIN
logo/logo_water.png
Normal file
BIN
logo/logo_water.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 276 KiB |
BIN
resources/icon.png
Normal file
BIN
resources/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 242 KiB |
@ -1,4 +1,3 @@
|
||||
#pragma once
|
||||
#include "gfx/glf3_render.h"
|
||||
#include "MainWindow.h"
|
||||
#include "game_main.h"
|
||||
|
1
third-party/CMakeLists.txt
vendored
1
third-party/CMakeLists.txt
vendored
@ -27,6 +27,7 @@ set(THIRDPARTY_SOURCES
|
||||
|
||||
set(THIRDPARTY_HEADERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imgui_memory_editor/imgui_memory_editor.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/stb/stb_image.h
|
||||
)
|
||||
|
||||
|
||||
|
7897
third-party/stb/stb_image.h
vendored
Normal file
7897
third-party/stb/stb_image.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,24 +1,47 @@
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const char* FILE_NAME = "";
|
||||
const char* FILE_NAME = "D:\\Games\\Emulator\\PS2\\Games\\Fatal Frame\\Europe\\Debug\\Project Zero 2 Prototype (Feb_6,_2004_prototype)\\SLES_523.elf";
|
||||
|
||||
const int NUM_ELEMENTS = 94;
|
||||
const int NUM_ELEMENTS = 0x118B;
|
||||
|
||||
const int OFFSET_ADDRESS = 0x218758;
|
||||
const int OFFSET_ADDRESS = 0x2DE3D0;
|
||||
|
||||
const int ELF_OFFSET_ADDRESS = 0x003dd3d0;
|
||||
|
||||
const int OFFSET_DIFF = ELF_OFFSET_ADDRESS - OFFSET_ADDRESS;
|
||||
|
||||
struct StructToConvert
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
int d;
|
||||
char a;
|
||||
char b;
|
||||
char c;
|
||||
char d;
|
||||
int e;
|
||||
};
|
||||
|
||||
StructToConvert* readFullFile()
|
||||
char* readFullFile()
|
||||
{
|
||||
std::ifstream infile(FILE_NAME, std::ios::binary);
|
||||
|
||||
auto fileSize = std::filesystem::file_size(FILE_NAME);
|
||||
|
||||
infile.seekg(0, std::ios::beg);
|
||||
|
||||
char *buffer = new char[fileSize];
|
||||
|
||||
infile.read(buffer, fileSize);
|
||||
|
||||
infile.close();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
StructToConvert* readFileFromOffset()
|
||||
{
|
||||
std::ifstream infile(FILE_NAME, std::ios::binary);
|
||||
|
||||
@ -37,24 +60,63 @@ StructToConvert* readFullFile()
|
||||
|
||||
void printStructCode(const StructToConvert* structToConvert)
|
||||
{
|
||||
printf("GPHASE_STRUCT gphase_tbl[%d] = \n{", NUM_ELEMENTS);
|
||||
//printf("inline Zero2FileInfo filename_dat_us[0x106B] = \n{");
|
||||
|
||||
auto fullFile = readFullFile();
|
||||
|
||||
int totalFiles = 0;
|
||||
for(int i = 0; i < NUM_ELEMENTS; i++)
|
||||
{
|
||||
printf("\n\t{");
|
||||
printf("\n\t\t(GPHASE_LAYER) %d,", structToConvert[i].a);
|
||||
printf("\n\t\t(GPHASE_ID) %d,", structToConvert[i].b);
|
||||
printf("\n\t\t(GPHASE_ID) %d,", structToConvert[i].c);
|
||||
printf("\n\t\t(GPHASE_ID) %d", structToConvert[i].d);
|
||||
printf("\n\t},");
|
||||
// Since it is a pointer in the elf
|
||||
char* a = (char*) &fullFile[structToConvert[i].e - OFFSET_DIFF];
|
||||
|
||||
std::string b = a;
|
||||
|
||||
auto justFilename = b.substr(0, b.find("."));
|
||||
|
||||
if (justFilename == "ubi_rogo")
|
||||
{
|
||||
printf("\n%s", a);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fileLanguage = justFilename.substr(justFilename.size() - 2, 2);
|
||||
|
||||
if (b == "snp_tb2_nar_s.pk2" || b == "lang_sl.pk2")
|
||||
{
|
||||
}
|
||||
else if (fileLanguage == "_f" || fileLanguage == "_g" || fileLanguage == "_s" || fileLanguage == "_i")
|
||||
{
|
||||
printf("\n%s", a);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fileRegion = justFilename.substr(justFilename.size() - 3, 3);
|
||||
|
||||
if (fileRegion == "PAL")
|
||||
{
|
||||
printf("\n%s", a);
|
||||
continue;
|
||||
}
|
||||
|
||||
totalFiles += 1;
|
||||
|
||||
//printf("\n\t{");
|
||||
//printf("\n\t\t%d,", structToConvert[i].a);
|
||||
//printf("\n\t\t%d,", structToConvert[i].b);
|
||||
//printf("\n\t\t%d,", structToConvert[i].c);
|
||||
//printf("\n\t\t%d,", structToConvert[i].d);
|
||||
//printf("\n\t\t(char*) \"%s\"", a);
|
||||
//printf("\n\t},");
|
||||
}
|
||||
|
||||
printf("\n};");
|
||||
//printf("\n};");
|
||||
printf("\n%d", totalFiles);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
StructToConvert* structToConvert = readFullFile();
|
||||
StructToConvert* structToConvert = readFileFromOffset();
|
||||
|
||||
printStructCode(structToConvert);
|
||||
|
||||
|
@ -4,4 +4,6 @@ project(Extractor CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(Extractor extractor.h extractor.cpp deless.h deless.cpp)
|
||||
include_directories(../argparse)
|
||||
|
||||
add_executable(Extractor extractor.h extractor.cpp deless.h deless.cpp ../argparse/argparse.hpp)
|
||||
|
@ -1,6 +1,11 @@
|
||||
#include "extractor.h"
|
||||
#include <fstream>
|
||||
#include "deless.h"
|
||||
#include <fstream>
|
||||
|
||||
int NUM_FILES;
|
||||
int FILE_TABLE_ADDRESS;
|
||||
std::string REGION;
|
||||
bool EXTRACT_FILE_NAME;
|
||||
|
||||
char *ReadFullFile(const char *filename)
|
||||
{
|
||||
@ -35,10 +40,10 @@ char *ReadRangeFile(const char *filename, int startAddress, int readLength)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void DecompressFile(int file, const std::filesystem::path outputFolder)
|
||||
void DecompressFile(std::string file)
|
||||
{
|
||||
std::string initialFile = outputFolder.string() + "/" + std::to_string(file) + ".bin";
|
||||
std::string targetFile = outputFolder.string() + "/" + std::to_string(file) + ".bin" + ".LED";
|
||||
std::string initialFile = file;
|
||||
std::string targetFile = file + ".LED";
|
||||
|
||||
Decompress(initialFile.c_str(), targetFile.c_str());
|
||||
|
||||
@ -47,7 +52,8 @@ void DecompressFile(int file, const std::filesystem::path outputFolder)
|
||||
std::filesystem::rename(targetFile, initialFile);
|
||||
}
|
||||
|
||||
void ExtractZero2GameFiles(const char *imgBdFile, const char *elf, const std::filesystem::path outputFolder)
|
||||
void ExtractZero2GameFiles(const char *imgBdFile, const char *elf,
|
||||
const std::filesystem::path outputFolder)
|
||||
{
|
||||
if (!std::filesystem::exists(outputFolder))
|
||||
{
|
||||
@ -55,21 +61,26 @@ void ExtractZero2GameFiles(const char *imgBdFile, const char *elf, const std::fi
|
||||
}
|
||||
|
||||
std::ifstream fileDataBank(imgBdFile, std::ios::binary);
|
||||
Zero2File *fileHd = (Zero2File *)ReadRangeFile(elf, FILE_TABLE_ADDRESS_US_ZERO2, NUM_FILES_US_JP_ZERO2 * sizeof(Zero2File));
|
||||
|
||||
Zero2File *fileHd = (Zero2File *) ReadRangeFile(
|
||||
elf, FILE_TABLE_ADDRESS, NUM_FILES * sizeof(Zero2File));
|
||||
|
||||
char fileBuffer[PS2_SECTOR_SIZE];
|
||||
|
||||
for (int i = 0; i < NUM_FILES_US_JP_ZERO2; i++)
|
||||
for (int i = 0; i < NUM_FILES; i++)
|
||||
{
|
||||
printf("Extracting file %d/%d done\n", i, NUM_FILES_US_JP_ZERO2);
|
||||
std::string outputFile = GetFilenameWithPath(i, outputFolder);
|
||||
|
||||
printf("Extracting %d/%d %s\n", i, NUM_FILES - 1, outputFile.c_str());
|
||||
|
||||
FileType fileStatus = (FileType) (fileHd[i].info & 0b00000011);
|
||||
|
||||
// Some files index are bugged and have a type File but with a size of 0 bytes
|
||||
if (fileStatus == NoFile ||
|
||||
(fileStatus == FileNotCompressed && fileHd[i].size == 0) ||
|
||||
(fileStatus == FileCompressed && fileHd[i].sizeCompressed == 0))
|
||||
if (fileStatus == NoFile
|
||||
|| (fileStatus == FileNotCompressed && fileHd[i].size == 0)
|
||||
|| (fileStatus == FileCompressed && fileHd[i].sizeCompressed == 0))
|
||||
{
|
||||
printf("Ignored\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -77,9 +88,9 @@ void ExtractZero2GameFiles(const char *imgBdFile, const char *elf, const std::fi
|
||||
|
||||
fileDataBank.seekg(startAddress, std::ios::beg);
|
||||
|
||||
int size = fileStatus == FileNotCompressed ? fileHd[i].size : fileHd[i].sizeCompressed;
|
||||
int size = fileStatus == FileNotCompressed ? fileHd[i].size
|
||||
: fileHd[i].sizeCompressed;
|
||||
|
||||
std::string outputFile = outputFolder.string() + "/" + std::to_string(i) + ".bin";
|
||||
FILE *pFile = fopen(outputFile.c_str(), "wb+");
|
||||
|
||||
for (int k = 0; k <= size / PS2_SECTOR_SIZE; k++)
|
||||
@ -92,7 +103,7 @@ void ExtractZero2GameFiles(const char *imgBdFile, const char *elf, const std::fi
|
||||
|
||||
if (fileStatus == FileCompressed)
|
||||
{
|
||||
DecompressFile(i, outputFolder);
|
||||
DecompressFile(outputFile);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +111,32 @@ void ExtractZero2GameFiles(const char *imgBdFile, const char *elf, const std::fi
|
||||
delete[] fileHd;
|
||||
}
|
||||
|
||||
void ExtractGameFilesFromBank(const char *imgHdFile, const char *imgBdFile, std::filesystem::path outputFolder)
|
||||
std::string GetFilenameWithPath(int fileId, std::filesystem::path outputFolder)
|
||||
{
|
||||
if (!EXTRACT_FILE_NAME)
|
||||
{
|
||||
return outputFolder.string() + std::to_string(fileId) + ".bin";
|
||||
}
|
||||
|
||||
auto fileInfo =
|
||||
REGION == REGION_EU ? filename_dat[fileId] : filename_dat_us[fileId];
|
||||
|
||||
auto filename = fileInfo.name;
|
||||
|
||||
auto directory = filename_path[fileInfo.directory];
|
||||
|
||||
auto fullDirectory = outputFolder.string() + "/" + directory;
|
||||
|
||||
if (!std::filesystem::exists(fullDirectory))
|
||||
{
|
||||
std::filesystem::create_directories(fullDirectory);
|
||||
}
|
||||
|
||||
return fullDirectory + filename;
|
||||
}
|
||||
|
||||
void ExtractGameFilesFromBank(const char *imgHdFile, const char *imgBdFile,
|
||||
std::filesystem::path outputFolder)
|
||||
{
|
||||
ZeroFile *fileHd = (ZeroFile *) ReadFullFile(imgHdFile);
|
||||
|
||||
@ -108,7 +144,7 @@ void ExtractGameFilesFromBank(const char *imgHdFile, const char *imgBdFile, std:
|
||||
|
||||
char fileBuffer[PS2_SECTOR_SIZE];
|
||||
|
||||
for (int i = 0; i < NUM_FILES_US_ZERO; i++)
|
||||
for (int i = 0; i < NUM_FILES; i++)
|
||||
{
|
||||
unsigned long startAddress = fileHd[i].address * PS2_SECTOR_SIZE;
|
||||
|
||||
@ -119,7 +155,8 @@ void ExtractGameFilesFromBank(const char *imgHdFile, const char *imgBdFile, std:
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string outputFile = outputFolder.string() + "/" + std::to_string(i) + ".bin";
|
||||
std::string outputFile = GetFilenameWithPath(i, outputFolder);
|
||||
|
||||
FILE *pFile = fopen(outputFile.c_str(), "wb+");
|
||||
|
||||
for (int k = 0; k <= fileHd[i].size / PS2_SECTOR_SIZE; k++)
|
||||
@ -135,15 +172,79 @@ void ExtractGameFilesFromBank(const char *imgHdFile, const char *imgBdFile, std:
|
||||
delete[] fileHd;
|
||||
}
|
||||
|
||||
void Extractor(argparse::ArgumentParser args)
|
||||
{
|
||||
REGION = args.get("region");
|
||||
EXTRACT_FILE_NAME = args["--name"] == true;
|
||||
|
||||
if (REGION == REGION_US)
|
||||
{
|
||||
NUM_FILES = NUM_FILES_US_JP_ZERO2;
|
||||
FILE_TABLE_ADDRESS = FILE_TABLE_ADDRESS_US_ZERO2;
|
||||
}
|
||||
else if (REGION == REGION_JP)
|
||||
{
|
||||
NUM_FILES = NUM_FILES_US_JP_ZERO2;
|
||||
FILE_TABLE_ADDRESS = FILE_TABLE_ADDRESS_JP_ZERO2;
|
||||
}
|
||||
else
|
||||
{
|
||||
NUM_FILES = NUM_FILES_EU_ZERO2;
|
||||
FILE_TABLE_ADDRESS = FILE_TABLE_ADDRESS_EU_ZERO2;
|
||||
}
|
||||
|
||||
ExtractZero2GameFiles(args.get("bin").c_str(), args.get("elf").c_str(),
|
||||
args.get("output").c_str());
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 4)
|
||||
argparse::ArgumentParser program("Mikompilation Extractor");
|
||||
|
||||
program.add_argument("bin")
|
||||
.help("Absolute path with file to the game's IMG_BD.BIN")
|
||||
.required();
|
||||
|
||||
program.add_argument("elf")
|
||||
.help("Absolute path with file to the game's elf (US: SLUS_207.66)")
|
||||
.required();
|
||||
|
||||
program.add_argument("-o", "--output")
|
||||
.help("Output folder where all files will be extracted")
|
||||
.default_value(std::filesystem::current_path().string());
|
||||
|
||||
program.add_argument("-n", "--name")
|
||||
.help("Will extract the files' name and directory")
|
||||
.default_value(false)
|
||||
.implicit_value(true);
|
||||
|
||||
program.add_argument("-r", "--region")
|
||||
.default_value("us")
|
||||
.action([](const std::string &value) {
|
||||
static const std::vector<std::string> choices = {
|
||||
REGION_US, REGION_EU, REGION_JP
|
||||
};
|
||||
|
||||
if (std::find(choices.begin(), choices.end(), value) != choices.end())
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return std::string {REGION_US};
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
printf("ERROR NOT ENOUGH ARGUMENTS\n To use: <full path to IMG_BD.BIN> <full path to SLUS_207.66> <Your output folder>");
|
||||
return -1;
|
||||
program.parse_args(argc, argv);
|
||||
}
|
||||
|
||||
ExtractZero2GameFiles(argv[1], argv[2], argv[3]);
|
||||
catch (const std::runtime_error &err)
|
||||
{
|
||||
std::cerr << err.what() << std::endl;
|
||||
std::cerr << program;
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
Extractor(program);
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
1174
tools/argparse/argparse.hpp
Normal file
1174
tools/argparse/argparse.hpp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user