NDSFactory/ndsfactory/ndsfactory.cpp
2024-08-04 20:09:19 +02:00

173 lines
5.0 KiB
C++

#include <string>
#include <iostream>
#include <fstream>
#include <cmath>
#include "ndsfactory.h"
#include "fatstruct.h"
#include "crctable.h"
NDSFactory::NDSFactory()
{
}
bool NDSFactory::loadRomHeader(const std::string& romPath, std::vector<char>& romHeader)
{
std::streampos headerSize = sizeof(NDSHeader);
std::ifstream romFile (romPath, std::ios::in|std::ios::binary|std::ios::ate);
if (romFile.is_open())
{
romHeader.resize(static_cast<unsigned long>(headerSize));
romFile.seekg (0, std::ios::beg);
romFile.read (romHeader.data(), headerSize);
romFile.close();
return true;
}
return false;
}
bool NDSFactory::dumpDataFromFile(const std::string& romPath, const std::string& savePath, uint32_t startAddr, uint32_t size)
{
std::ifstream romFile (romPath, std::ios::in|std::ios::binary|std::ios::ate);
std::ofstream savedFile (savePath, std::ios::out|std::ios::binary|std::ios::ate);
if (romFile.is_open() && savedFile.is_open())
{
std::vector<char> dumpBuffer(size);
romFile.seekg (startAddr, std::ios::beg);
romFile.read (dumpBuffer.data(), size);
romFile.close();
savedFile.write(dumpBuffer.data(), size);
savedFile.close();
return true;
}
return false;
}
bool NDSFactory::readBytesFromFile(std::vector<char>& byteBuffer, const std::string& romPath, uint32_t startAddr, uint32_t size)
{
std::ifstream romFile (romPath, std::ios::in|std::ios::binary|std::ios::ate);
if (romFile.is_open())
{
romFile.seekg (startAddr, std::ios::beg);
romFile.read (byteBuffer.data(), size);
romFile.close();
return true;
}
return false;
}
bool NDSFactory::writeSectionToFile(const std::string& sectionPath, const std::string& savePath, uint32_t startAddr, uint32_t size)
{
std::ifstream sectionFile (sectionPath, std::ios::in|std::ios::binary|std::ios::ate);
std::ofstream savedFile (savePath, std::ios::out|std::ios::binary|std::ios::app);
if (sectionFile.is_open() && savedFile.is_open())
{
std::vector<char> dumpBuffer(size);
sectionFile.seekg (0, std::ios::beg);
sectionFile.read (dumpBuffer.data(), size);
sectionFile.close();
savedFile.seekp(startAddr, std::ios::beg);
savedFile.write(dumpBuffer.data(), size);
savedFile.close();
return true;
}
return false;
}
bool NDSFactory::writeFatSectionToFile(const std::string& romPath, FatRange* pfatrange, const std::string& savePath){
uint32_t size=pfatrange->endAddr-pfatrange->startAddr;
if(!dumpDataFromFile(romPath, savePath, pfatrange->startAddr, size)) return false;
return true;
}
bool NDSFactory::writeBytesToFile(std::vector<char>& byteBuffer, const std::string& savePath, uint32_t startAddr, uint32_t size)
{
std::ofstream savedFile (savePath, std::ios::out|std::ios::binary|std::ios::app);
if (savedFile.is_open())
{
savedFile.seekp(startAddr, std::ios::beg);
savedFile.write(byteBuffer.data(), size);
savedFile.close();
return true;
}
return false;
}
bool NDSFactory::writePaddingToFile(char paddingChar, const std::string& filePath, uint32_t startAddr, const uint32_t size)
{
std::vector<char> paddingBytes(size, paddingChar);
return writeBytesToFile(paddingBytes, filePath, startAddr, size);
}
int NDSFactory::getCardSizeInBytes(int cardType)
{
return static_cast<int>(pow(2, 17 + cardType));
}
bool NDSFactory::checkArm9FooterPresence(const std::string& sectionPath, uint32_t size)
{
std::ifstream sectionFile (sectionPath, std::ios::in|std::ios::binary|std::ios::ate);
if (sectionFile.is_open())
{
std::streamoff sectionRealSize = sectionFile.tellg();
sectionFile.close();
if (sectionRealSize >= size + Arm9FooterSize)
{
return true;
}
}
return false;
}
bool NDSFactory::patchFat(const std::string& fatSectionPath, uint32_t shiftSize, const std::string& savePath)
{
std::vector<char> fatBytes;
std::ifstream sectionFile (fatSectionPath, std::ios::in|std::ios::binary|std::ios::ate);
if (!sectionFile.is_open())
return false;
std::streamoff sectionSize = sectionFile.tellg();
fatBytes.resize(sectionSize);
sectionFile.seekg (0, std::ios::beg);
sectionFile.read (fatBytes.data(), sectionSize);
sectionFile.close();
FatRange* pfatrange = reinterpret_cast<FatRange*>(fatBytes.data());
for(size_t i = 0; i < fatBytes.size(); i += sizeof(FatRange), pfatrange++) {
pfatrange->startAddr += shiftSize;
pfatrange->endAddr += shiftSize;
}
return writeBytesToFile(fatBytes, savePath, 0, static_cast<uint32_t>(sectionSize));
}
uint16_t NDSFactory::calcHeaderCrc16(const std::vector<char>& romHeader)
{
uint8_t loc;
uint16_t crc = 0xFFFF;
size_t size = 0x15E;
size_t index = 0;
while (size--)
{
loc = static_cast<unsigned char>(romHeader[index] ^ crc);
index++;
crc >>= 8;
crc ^= lCRCTable[loc];
}
return crc;
}