Hey everyone. I'm a beginner programmer learning C++ mainly for video game reverse engineering, as well as for writing tools to assist with game modding.
I'm trying to mod UV maps in 3D models from an old PSX game called WWF SmackDown in order to convert the models to a slightly different format that allows importing them into the game's sequel, WWF SmackDown 2, without glitches.
I need to change the X and Y position values of UV coordinates based on these criteria:
1. If X > 0xBF and Y > 0xBF, then decrease X by 0xC0
2. If X > 0x7F and X ≤ 0xBF and Y > 0xBF, then decrease X and Y by 0x40
I can do this manually with a hex editor but it's a long and error-prone process so I'd like to automate it.
Since X and Y position values are coded by one byte each and always go together, I believe that comes to reading input from a file, storing its contents in an array, then searching the array for 2-byte combinations matching my criteria and manipulating each byte individually. How can I do that?
Specifically the last two steps: finding byte combinations in an array and manipulating each byte of the found combinations individually.
I got a very basic code running that just opens a small 16-byte test file (not a real model file yet), stores its contents in an array and then outputs them as hex numbers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
#include <fstream>
#include <iostream>
#include <iomanip>
int main()
{
std::ifstream inf{ "Sample.dat", std::ios::binary };
if (!inf)
{
std::cerr << "Error: file could not be opened for reading!\n";
return 1;
}
unsigned char array[16]{ 0 };
int arrayIndex{ 0 };
while (inf >> array[arrayIndex])
{
std::cout.fill('0');
std::cout << std::hex << std::setw(2) << static_cast<int>(array[arrayIndex]);
++arrayIndex;
}
return 0;
}
|
The "Sample.dat" file contains the following bytes:
|
AB 12 FD BC 44 15 AA 6B DF 4D 3A EE E1 D7 06 78
|
And I actually have one more problem as well. As an experiment I tried adding one more simple loop that would go through the array and change every byte that has a value of 0xAB (that would only be the very first byte in my file) like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
#include <fstream>
#include <iostream>
#include <iomanip>
int main()
{
std::ifstream inf{ "Sample.dat", std::ios::binary };
if (!inf)
{
std::cerr << "Error: file could not be opened for reading!\n";
return 1;
}
unsigned char array[16]{ 0 };
int arrayIndex{ 0 };
while(inf >> array[arrayIndex])
{
if (array[arrayIndex] == 0xAB)
{
array[arrayIndex] -= 0xC0;
}
++arrayIndex;
}
while (inf >> array[arrayIndex])
{
std::cout.fill('0');
std::cout << std::hex << std::setw(2) << static_cast<int>(array[arrayIndex]);
++arrayIndex;
}
return 0;
}
|
But I immediately encountered a problem - the program wouldn't output anything to the console. I used a debugger and found out that what seems to be happening is that the first loop works correctly but the second loop doesn't start because the condition
inf >> array[arrayIndex]
evaluates to
false
. I guess because I reach the end of the file in the first loop? So another question is how do I loop through the same file again without closing and reopening it?
I tried adding
inf.seekg(0, std::ios::beg);
after the first loop but that doesn't help.
So this is where I'm stuck. I tried googling a bunch of stuff but nothing seems to be the solution to what I need. Any help would be greatly appreciated, even hints and pointers to subjects to research.