Pure Pure Translation: (Photo Thread) (Last Update: Jan 29)

Post about your projects or talk about mirror moon projects that haven't been announced yet... or something.

Moderator: Staffers

User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Unread post by furyoftheskies » November 13th, 2008, 8:47 pm

phib wrote: Thanks for the offer, but I prefer 'teaching to fish' which is more entertaining than 'fishing for others'. Also I already have my hands full with other projects.
But I don't mind helping from time to time if you encounter any technical difficulties.
Okay then phib ^_^ If I run into something that baffles me and I can't figure it out, I'll ask you for your assistance then.

Thanks for teaching me how to fish lol, now I'm trying to learn how to automate the fishing. (Creating a tool doesn't seem too hard, I just need to know which programming language to use so hopefully if I learn that, things can speed up a bit)

If worse comes to worse, I can try writing a tool in C++ or C#, I just have to figure out how to write in binary though lol. I need a guide that teaches how to read bytes in a file or something.

Edit 1: Would you happen to know of a program that can create an .exe installer? So that I don't have to release a manual one?

User avatar
Balcerzak
Crack Addic!
Posts: 174
Joined: October 29th, 2007, 8:21 pm
Location: Michigan, USA

Unread post by Balcerzak » November 14th, 2008, 11:04 am

furyoftheskies wrote:If worse comes to worse, I can try writing a tool in C++ or C#, I just have to figure out how to write in binary though lol. I need a guide that teaches how to read bytes in a file or something.
I've never played around with actual binary in C++, but maybe the following is helpful?
Dealing with bits: http://www.cplusplus.com/reference/stl/bitset/
Dealing with files: http://www.cplusplus.com/reference/iostream/fstream/

User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Unread post by furyoftheskies » November 14th, 2008, 4:13 pm

Balcerzak wrote:I've never played around with actual binary in C++, but maybe the following is helpful?
Dealing with bits: http://www.cplusplus.com/reference/stl/bitset/
Dealing with files: http://www.cplusplus.com/reference/iostream/fstream/
Thanks, but I already have a bit of knowledge on that.

I know that if I open the file in binary, hexadecimal numbers are in binary sets of 4. (Ex. 1011 is the hex 0xA, 1111 would be 0xF, etc etc)

I need to read specifically the first 2 bytes, so its 16 binary bits, They have to be read in sets of 4 and translated to hex, and they also have to be read as little endian (backwards)

Ex. Let's say 1011 1101 0011 1000 are the first 2 bytes. This comes out as 0xAD38. Now, I need to read this backwards (Little endian) in bytes to get the actual value I'm looking for, so it becomes 0x38AD. So I guess the logic of the program would go something like this:

Open file in binary mode.
Get the first 2 bytes (16 bits)
Group bits into 4, then get the equivalent hex number.
Switch the first 2 hex numbers with the last 2 hex numbers.
Output the number obtained to the screen.
Determine the header by converting the number to decimal, then subtract it from the actual size of the file, then reconvert back to hex.
Output the size of the header to the screen.

That's pretty much all the logic I want to implement. I don't know if there is a function that can determine the size of a file or not, I have to explore that a bit more.

On a side note: I've translated and implemented 2/7 Scripts for the Intro. Lol, slow, I know, but I'm trying my best.

User avatar
Balcerzak
Crack Addic!
Posts: 174
Joined: October 29th, 2007, 8:21 pm
Location: Michigan, USA

Unread post by Balcerzak » November 14th, 2008, 7:29 pm

Code: Select all

#include <fstream>

void main(){
  fstream file("charaprof.scn",ios::binary | ios::in | ios::out);
  char bytes[2];
  file.get(bytes[0]);
  file.get(bytes[1]);
  short* foo = &bytes;
  char revbytes[2];
  revbytes[0] = bytes[1];
  revbytes[1] = bytes[0];
  short* bar = &revbytes;

  std::cout << "Hex values of the first two bytes: " << hex << (short) bytes[0] << " " << hex << (short) bytes[1] <<std::endl;
  std::cout << "Hex values of the first two bytes (reversed): " << hex << (short) revbytes[0] << " " << hex << (short) revbytes[1] <<std::endl;
  std::cout << *foo << std::endl;
  std::cout << "Hex values of the first two bytes: " << hex << *bar << std::endl;
  std::cout << "Hex values of the first two bytes (reversed): " << hex << *foo << std::endl;
  std::cout << *foo << std::endl;
  std::cout << "Dec value of the first two bytes: " << dec << *bar <<std::endl;
  std::cout << "Dec value of the first two bytes (reversed): " << dec << *foo <<std::endl;
  std::cout << *foo << std::endl;


  file.seekg(0,ios::beg);
  int filebegin = file.tellg();
  file.seekg(0,ios::end);
  int fileend = file.tellg();
  int filesize = fileend - filebegin;
  short* headersize = new short;
  *headersize = filesize - *foo;
  std::cout << "File size is " << filesize << " bytes" << std::endl;
  std::cout << "Header size is " << *headersize << " bytes" << std::endl;
  std::cout << "Header size is (hex) " << hex << *headersize << " bytes" << std::endl;

  unsigned char* finalbytes = headersize;
  std::cout << "Hex values of the manipulated two bytes: " << hex << (short) finalbytes[0] << " " << hex << (short) finalbytes[1] <<std::endl;
}
gave the following output:
stdout wrote:Hex values of the first two bytes: fff0 b
Hex values of the first two bytes (reversed): b fff0
bf0
Hex values of the first two bytes: f00b
Hex values of the first two bytes (reversed): bf0
bf0
Dec value of the first two bytes: -4085
Dec value of the first two bytes reversed: 3056
3056
File size is 3284 bytes
Header size is 228 bytes
Header size is (hex) e4 bytes
Hex values of the manipulated two bytes: e4 0
Is this doing anything like what you were hoping it to? [Note charaprof.scn was obtained from http://www.megaupload.com/?d=B6BTMJ42 that you posted in this thread, as I needed something actually worth testing this on.]

The bar variable is included in case the endianness of the system your running on is not little endian, as otherwise it will misinterpret things when it creates a short value out of the character array.

This is just the result of a couple hours idle fiddling and looking at the references I linked you earlier [turned out that you didn't need individual bits at all, dealing in whole bytes (or equivalently chars) seems to be good enough].

You could probably even go ahead and actually replace the bytes here too, adding

Code: Select all

file.seekg(0,ios::beg);
file.put(finalbytes[0]);
file.put(finalbytes[1]);
to the very end of the code, if that's what you ultimately hope to do.

Sorry, I haven't been paying full attention to the conversation thus far, only got my curiousity aroused when you mentioned C++.

Edit: There may or may not be problems with signed vs unsigned characters. From what little I can guess from the results here, I don't think it will be a problem, but I'm making no guarantees about this piece of code. It's strictly use at your own risk.

Also, I forgot to delete headersize, which means as it stands there's a (currently inconsequential) memory leak in the function.

User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Unread post by furyoftheskies » November 15th, 2008, 3:07 am

Holy cow Balcerzak, you've done pretty much the basic thing that I want to do lol. I meet another genius now lol.

What C++ program are you using? Dev-C? Visual C++?

Your program does what I want to do with the file. It specifically does almost all of what I want to do.

From your code, I want to change this:

Code: Select all

void main()
{
   fstream file("charaprof.scn",ios::binary | ios::in | ios::out); 
   char bytes[2];
   file.get(bytes[0]);
   file.get(bytes[1]);
   short* foo = &bytes;
   char revbytes[2];
   revbytes[0] = bytes[1];
   revbytes[1] = bytes[0];
   short* bar = &revbytes; 
}
and add this on to it:

Code: Select all

void main()
{
   fstream oldFile("X:\script\filename.scn", ios::binary | ios::in | ios::out);
   char oldBytes[2];
   oldFile.get(oldBytes[0]);
   oldFile.get(oldBytes[1]);
   short* foo = &oldBytes;
   char oldRevbytes[2];
   oldRevbytes[0] = oldBytes[1];
   oldRevbytes[1] = oldBytes[0];
   short* bar = &oldRevbytes;

   fstream newFile("X:\newScript\filename.scn", ios::binary | ios::in | ios::out);
   char newBytes[2];
   newFile.get(newBytes[0]);
   newFile.get(newBytes[1]);
   short* foo = &newBytes;
   char newRevbytes[2];
   newRevbytes[0] = newBytes[1];
   newRevbytes[1] = newBytes[0];
   short* bar = &newRevbytes;  
}
As you can see, filename.scn is the same file in terms of name, but the location (and most likely size) will be different. The original one is located in x:\script\, while the modified one will be located in x:\newScript\

After that, I determine the size and header of the original. From there, I compare those values obtained to the new script. If the new script's header size:

1) Does not correct match the file of the original (As in, if the file size minus the little endian bytes DOES NOT equal the header) then the program will fix it and output it for verification by using the data of the original. (In other words, it will show me what it will do, with a Y/N question confirming if I want to do it.)

I'll go and write the code and see if I can get it done. Believe it or not, I'm actually going to try and convert this to C# (C Sharp) since I've been using it a bit often. But I can always write it in C++ thanks to you Balcerzak.

Quick question: Is this how to skip to a certain byte? For example, I know that the offset of a file is located 76 bytes after the beginning, and every successive 76 bytes there is an offset read little endian. Would the code go something like this?

Code: Select all

   file.get(bytes[0+76x]); 
   file.get(bytes[1+76x]);
x is a variable integer. The program should run until it hits an offset that is too large. Ex if the filesize is 4500 bytes, if the program hits an offset that is lets say 6000, it will stop and then output x, which would tell me the number of offsets in the file.

User avatar
Balcerzak
Crack Addic!
Posts: 174
Joined: October 29th, 2007, 8:21 pm
Location: Michigan, USA

Unread post by Balcerzak » November 15th, 2008, 3:27 pm

furyoftheskies wrote:Holy cow Balcerzak, you've done pretty much the basic thing that I want to do lol. I meet another genius now lol.

What C++ program are you using? Dev-C? Visual C++?
Far from a genius, to be perfectly honest I'm really an amateur with little to no formal computer programming education (I took a one-month course on Intro to C++). I do use a lot of programming at work, so I do have a fair bit of practical experience, but I'm really more of a physicist that codes, rather than an actual computer programmer, and thus I may not always fully understand what's going on behind the scenes (though I do try to learn).

That said, as far as what I work with, I use the version of CINT that comes bundled with ROOT, as that's what I do most of my programming in for work, though it does have a standalone version. See wikipedia's entry on it or the project's homepage for more information. So that means most of what I do is interpreted C++, and I'm a little shakier when it comes to designing makefiles and compiling executables, so probably can't be of a whole lot of help there. There's also some nuance differences when feeding macros to ROOT to be interpreted, that I cleaned out already for you, to leave it in more generic C++. (For instance, ROOT tends to want the name of the main function to be executed to match the filename of the macro file you feed it for execution, and it uses that to build some sort of internal "main", as far as I'm aware.)

I'm going to rearrange your post and reply to it in a different order, so I hope that doesn't cause any confusion. Just FYI.
fury wrote:I'll go and write the code and see if I can get it done. Believe it or not, I'm actually going to try and convert this to C# (C Sharp) since I've been using it a bit often. But I can always write it in C++ thanks to you Balcerzak.
I encourage you to do this, actually. While I don't honestly know any C# myself, nor even much about it, so wouldn't be able to offer any language specific advice, it's really best to work in the framework you're most familiar with. This also means you don't have to worry about downloading new unfamiliar software or packages in order to make or run the tools you need or want.

On the other hand, some problems lend themselves to easier solutions in different environments, so sometimes it's not always feasible to do this, but when it is, and you're able to work with something you're familiar with, you tend to understand it better, and can then in the future apply it to solving similar puzzles. I honestly don't think there will be any issues here, though, as from what little I do know about C# leads me to believe that's is very closely related to C and C++, which means a simple transition should be possible, and easily workable.

Also, like phib (or at least how I understood what he said) I don't have any immediate or long term interest in the project, at this point, but I don't like seeing people struggle if I think I can help out. Ultimately though, I hope I can help you learn to help yourself. I am fully aware from my own personal experiences, however, of how much more convenient it is to be shown a complete working example of code. Also, I got a little intrigued by your particular problem and have a hard time resisting a well-defined challenge, just as a test of my own skills and understanding. :wink:

Now, onto the actual code part of the discussion. I suppose it would be helpful if I explained exactly what did what, so that you can do conversions more easily. First though, I'm going to answer your quick question from the end.
fury wrote:Quick question: Is this how to skip to a certain byte? For example, I know that the offset of a file is located 76 bytes after the beginning, and every successive 76 bytes there is an offset read little endian. Would the code go something like this?

Code: Select all

   file.get(bytes[0+76x]); 
   file.get(bytes[1+76x]);
x is a variable integer. The program should run until it hits an offset that is too large. Ex if the filesize is 4500 bytes, if the program hits an offset that is lets say 6000, it will stop and then output x, which would tell me the number of offsets in the file.
This will not work, for a couple of different reasons. First of all, you haven't properly defined x, and you're going to need some sort of external control structure to do what you're ultimately intending here (if it was me, I'd probably choose a for loop, I like for loops). Secondly, when we declared the bytes variable, we declared it as a static array with only enough room for two entries, meaning we can only properly use bytes[0] and bytes[1], anything else is asking for trouble (most likely unexpected runtime behaviour, segmentation faults, etc.).

Detailed TL;DR explanation: What you're actually asking the code to do here is to retrieve the amount of data from file that fills the same amount of space as a member of the bytes array, and to store that information at the memory address found by following the pointer to the beginning of the bytes array, and then continuing along until you're reached the specified offset (in the case of x == 1, that is putting things into bytes[76]). This is highly dangerous, as the bytes[76] may point to memory the program doesn't have access to, it may be a different variable that's important to the program running that now gets over-written, but doesn't end up crashing it, leading to unexpected behaviour, or any of a number of other things could go wrong.

I'd deal more with a couple of ways to try to do what you want to do here later, but I think I should now go ahead and actually explain step-by-step, how the various pieces go together. If I over-explain things you already know or understand, forgive me for being thorough, I don't mean it as disrespect. (Spoilered to save on visible space.)
► Show Spoiler

So that's the detailed summary of everything I had written for you earlier, so hopefully knowing the concepts behind the code will make your C# transition easier. For further reference, a look at http://www.cplusplus.com/doc/tutorial/files.html couldn't hurt, as it seems to lay out the basics very well, though if you need more information on any of the specific methods for fstream the link I provided earlier is probably a better bet.
furyoftheskies wrote:Your program does what I want to do with the file. It specifically does almost all of what I want to do.

From your code, I want to change to this:

Code: Select all

void main()
{
   fstream oldFile("X:\script\filename.scn", ios::binary | ios::in | ios::out);
   char oldBytes[2];
   oldFile.get(oldBytes[0]);
   oldFile.get(oldBytes[1]);
   short* foo = &oldBytes;
   char oldRevbytes[2];
   oldRevbytes[0] = oldBytes[1];
   oldRevbytes[1] = oldBytes[0];
   short* bar = &oldRevbytes;

   fstream newFile("X:\newScript\filename.scn", ios::binary | ios::in | ios::out);
   char newBytes[2];
   newFile.get(newBytes[0]);
   newFile.get(newBytes[1]);
   short* foo = &newBytes;
   char newRevbytes[2];
   newRevbytes[0] = newBytes[1];
   newRevbytes[1] = newBytes[0];
   short* bar = &newRevbytes;  
}
You're going to need to make sure to use different variables for the shorts for oldFile and newFile. oldfoo/newfoo might work, or you could actually give them a real descriptive name. I was just being lazy originally.
fury wrote:As you can see, filename.scn is the same file in terms of name, but the location (and most likely size) will be different. The original one is located in x:\script\, while the modified one will be located in x:\newScript\

After that, I determine the size and header of the original. From there, I compare those values obtained to the new script. If the new script's header size:

1) Does not correct match the file of the original (As in, if the file size minus the little endian bytes DOES NOT equal the header) then the program will fix it and output it for verification by using the data of the original. (In other words, it will show me what it will do, with a Y/N question confirming if I want to do it.)
Mmm, intriguing. I think I could figure out most of that, with the possible exception of the user prompt. I've not done a lot of work with user input. I may have to do a little more tinkering around just for fun here.

User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Unread post by furyoftheskies » November 16th, 2008, 1:46 am

Ugh

First of all, I'm having a problem dealing with your short byte declaration:

Code: Select all

short* foo = &bytes;
My compiler says it can't convert short* int to a char*[2] lol.

Edit 1: I've managed to write the code on C#. I'll paste it later.

Edit 2: Heres the code on C#. This one actually replaces the file size given that the user inputs a decimal! This will be the first part of the program. The second part will compare the two and make the neccesary changes ^_^.
► Show Spoiler
Spoiled to save space. Comments are in there lol.

User avatar
Balcerzak
Crack Addic!
Posts: 174
Joined: October 29th, 2007, 8:21 pm
Location: Michigan, USA

Unread post by Balcerzak » November 16th, 2008, 5:55 pm

furyoftheskies wrote:Ugh

First of all, I'm having a problem dealing with your short byte declaration:

Code: Select all

short* foo = &bytes;
My compiler says it can't convert short* int to a char*[2] lol.
Ooh, yeah, good call on that. As I say, I mostly run interpretted C++ and CINT is fairly forgiving on dealing with strict syntax. When I tried to compile the macro, it gave me the same errors. I've since developed a much cleaner implementation which fixes this. I've also added a lot of functionality and some other neat things in the latest iteration of the code. Also, I've been having the damnedest time trying to get it to work on windows, while it runs fine on linux, which boggles my mind...

Anyway, the new code (with added in-line commentary)
► Show Spoiler
I ran the code on two versions of charaprof.scn, the unmodified one, and the one that was two bytes different (obtained from megaupload). I did two passes, the first where I was prompted to make the replacements, replacing them in all cases (mostly using default enter, but once each for 'y' and 'Y') but the last, where I demonstrate the use of 'n', and bad input protection. The output is included here:
► Show Spoiler
The second time, I ran it over, just to demonstrate that yes, the file was actually changed. This can be see here:
► Show Spoiler
fury wrote:Edit 1: I've managed to write the code on C#. I'll paste it later.

Edit 2: Heres the code on C#. This one actually replaces the file size given that the user inputs a decimal! This will be the first part of the program. The second part will compare the two and make the neccesary changes ^_^.
► Show Spoiler
Spoiled to save space. Comments are in there lol.
Looking nice! I don't follow a lot of the technical details, but the basic structure is definitely there, and it looks like C# has some convenient utilities built-in for you as well, so you don't have to do a lot of defining your own functions. Let me know if there's anything else I can help with, but for the most part, I think you've got the general scheme of things going quite well, now. (I borrowed some ideas from this code to use in mine, namely using strings to represent the bytes in the print-out statements. It was too good an idea to pass up. :3)

User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Unread post by furyoftheskies » November 16th, 2008, 9:23 pm

Yowza, interesting C++ code, haven't seen a union being used before. I'm mostly used to structures and classes lol.

After looking through your code, I got some ideas to use. I'm going to make this into a GUI tool lol, so I'll show you the progress I get along with the basic code implementation.

I like your fail counter lol, normally I don't use that and just use a try catch statement within a do while loop. When I make the GUI, I'll just make it so it has 2 buttons lol, the only other way for them to fail is if they decide to press ALT + F4 :shock: .

Oh yeah, theres also one more thing I'll need to add to the code by the way.

The first header is an offset that leads to the checkers of the file (the ones that offset to the other files).

In charaprof, its 0x880 + 0xE4 = 2404 or offset 0x964. From pretty much the offset to the end, I'll need to use another 2 byte array. I'll use the seeker to check for all F2 bytes. The same if else statement would look like this (In words, I'll write the language code for it later and paste it).

Code: Select all

file.position = firstHexHeader + headerSize
while (file.position < fileSize)
{
   look at the next byte;
   if (byte value == F2)
   {
      Look at the next two values afterwords, read little endian.
      if (next two bytes greater than firstHexHeader)
      {
         change it.
      }
   }
    file.position++
}
We'll see what happens lol.

Edit 1: REJOICE! MY GUI PROGRAM WORKS! Heres a picture of it, and heres the log it created for me! (I used a purposed messed up header on a file to verify it!

ImageImage

EDIT 2: This is the new log type, Its quite detailed actually, I hope it makes sense.
► Show Spoiler
Man Balcerzak, I gotta thank you very much for helping me out with the initial code. For now, I've got down the basic change the first 2 bytes. My next step would be to check the offsets and make sure they point to the correct byte (which isn't going to be too bad, since I know what value they have to point to) so I'll keep updating this till I have a tool I can rely on. That way, all I have to do is translation and nothing more!

User avatar
Balcerzak
Crack Addic!
Posts: 174
Joined: October 29th, 2007, 8:21 pm
Location: Michigan, USA

Unread post by Balcerzak » November 17th, 2008, 1:17 pm

furyoftheskies wrote:Yowza, interesting C++ code, haven't seen a union being used before. I'm mostly used to structures and classes lol.

After looking through your code, I got some ideas to use. I'm going to make this into a GUI tool lol, so I'll show you the progress I get along with the basic code implementation.

I like your fail counter lol, normally I don't use that and just use a try catch statement within a do while loop. When I make the GUI, I'll just make it so it has 2 buttons lol, the only other way for them to fail is if they decide to press ALT + F4 :shock: .
Yeah, to be perfectly honest, I'd never seen a union used ever before either. Nor really for that matter structures, it's mostly just been classes or nothing. But hey, this gave me a chance to learn something new, which was cool, whether or not it will ever prove useful again for me.

Like I said, I usually don't work with user input, and had completely forgotten about try/catch to be honest. I was pretty much making things up there as I went along.
fury wrote:Oh yeah, theres also one more thing I'll need to add to the code by the way.

The first header is an offset that leads to the checkers of the file (the ones that offset to the other files).

In charaprof, its 0x880 + 0xE4 = 2404 or offset 0x964. From pretty much the offset to the end, I'll need to use another 2 byte array. I'll use the seeker to check for all F2 bytes. The same if else statement would look like this (In words, I'll write the language code for it later and paste it).

Code: Select all

file.position = firstHexHeader + headerSize
while (file.position < fileSize)
{
   look at the next byte;
   if (byte value == F2)
   {
      Look at the next two values afterwords, read little endian.
      if (next two bytes greater than firstHexHeader)
      {
         change it.
      }
   }
    file.position++
}
We'll see what happens lol.
Yeah, I sort of noticed that when I went back and actually re-read the first page in more detail. The last time I'd actually tried much in the way of hex manipulation was back in the summer of '06 in an ill-fated attempt to do a rom-hack translation, in which I quickly found myself completely in over my head (mostly due to very similar pointer problems), so I wanted to make sure I could follow and understand what phib and you had been discussing, and make sure the way I was interpreting what was said correctly, and thus how I was designing the program actually made any sense.

(This was spearheaded in earnest when I had just blindly copied the offsets to look at from phibs image, and while the first several worked, a lot of the later ones did not; these being the ones after e4 + 880, where the two bytes to be looked at didn't live in the same place.)

I then gave up and left out implementing that part of the code, mostly because I was too lazy to try to figure out the best way to seek through and look for the F2 bits, and also because it wasn't really necessary for the demonstration of successful execution in simple cases. Also, there's the fact that I don't actually own a copy of the game, so all I've had to go on were the few test scripts you'd uploaded, and I couldn't just test to see whether or not what I was doing fixed any crashing problems. This lead me to desire a simple finished product, that while it may not completely do what was needed, at least did what it was supposed to do, and did that well.
fury wrote:Edit 1: REJOICE! MY GUI PROGRAM WORKS! Heres a picture of it, and heres the log it created for me! (I used a purposed messed up header on a file to verify it!



Heres the log that I implemented that comes out (I made it so you can save it to a text file! Woot!)
► Show Spoiler
Man Balcerzak, I gotta thank you very much for helping me out with the initial code. For now, I've got down the basic change the first 2 bytes. My next step would be to check the offsets and make sure they point to the correct byte (which isn't going to be too bad, since I know what value they have to point to) so I'll keep updating this till I have a tool I can rely on. That way, all I have to do is translation and nothing more!
That's awesome news. Glad to hear my tinkering has been of some help. I must admit I had been a little skeptical the first time I read this topic when you basically said that you were going to hex-edit the whole game by hand, but I must say now that there's been some real progress on tool development I think the outlook is a lot more positive. At least, I see it that way.

I'll keep checking up on how things are going here. Maybe if you get stuck again, I can try to help out, though I can't make any guarantees. (I must warn you, I've no experience in making GUIs whatsoever, nor [as previously mentioned] C sharp. But if there's a well-defined challenge that's stumping you, I could probably try to work through a C++ approach, which would at least give you something to look at.)

User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Unread post by furyoftheskies » November 18th, 2008, 12:05 pm

Balcerzak wrote: I'll keep checking up on how things are going here. Maybe if you get stuck again, I can try to help out, though I can't make any guarantees. (I must warn you, I've no experience in making GUIs whatsoever, nor [as previously mentioned] C sharp. But if there's a well-defined challenge that's stumping you, I could probably try to work through a C++ approach, which would at least give you something to look at.)
Yes, I'd appreciate your help in the future should I need it ^_^

As of right now, the offset checker is working very smoothly! Heres a sample log of what is going on when the program runs. I added comments denoted by // so you can tell what the log produced and what I entered so you can understand.
► Show Spoiler
Edit1: Well, the tool is nearly complete. Now what I need to figure out is how to hack the images of the pak file.

The problem with the pak file is that the files are compressed (There are 3 little endian hexes, one that states its size uncompressed, its size compressed, and then its offset location). I'm not sure how to decompress a file like that, so if someone could lead me to figuring out what type of compression its using, I would appreciate it.

I know that it must be possible, since the CG's are floating around the internet, so I want to know how so that I can try my hand at replacing bytes and image hacking.

Edit 2: Tool is 90% complete! I'm just fixing the ending header checker so that it fixes properly! After that, I'll have a working tool that will check ALL offsets and values for me! I'm going back to translating once I get this one done (unless someone teaches me to image hack first lol)

Edit 3: Tool 100% Complete! I'm going back to translation now! Hopefully I'll release an intro patch before mid december!

Heres the pic of the final tool. Its a whopping 64 KB file size exe.

ImageImage

User avatar
phib
Addict
Posts: 104
Joined: May 9th, 2007, 12:25 am

Unread post by phib » November 23rd, 2008, 7:15 pm

furyoftheskies wrote:Edit1: Well, the tool is nearly complete. Now what I need to figure out is how to hack the images of the pak file.

The problem with the pak file is that the files are compressed (There are 3 little endian hexes, one that states its size uncompressed, its size compressed, and then its offset location). I'm not sure how to decompress a file like that, so if someone could lead me to figuring out what type of compression its using, I would appreciate it.

I know that it must be possible, since the CG's are floating around the internet, so I want to know how so that I can try my hand at replacing bytes and image hacking.
You're lucky, I checked the decompression algorithm and it turns out it's exactly the same used in another game I coded an unpacker for.
http://www.megaupload.com/?d=W8GCE8LN
(Usage: purepak cg.pak outfolder)

If you create a folder named 'cg' and drop in the edited bmps, the game will read them first from there instead of the cg.pak.

User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Unread post by furyoftheskies » November 24th, 2008, 10:39 am

phib wrote: You're lucky, I checked the decompression algorithm and it turns out it's exactly the same used in another game I coded an unpacker for.
http://www.megaupload.com/?d=W8GCE8LN
(Usage: purepak cg.pak outfolder)

If you create a folder named 'cg' and drop in the edited bmps, the game will read them first from there instead of the cg.pak.
Oh. My. Gosh. phib, you are definitely an expert in this field. Argh, as much as I love the fact that you gave me the program to decompress the files, and the knowledge that the game will read a CG folder before cg.pak, I'd love to figure out how you got the decompression code (I'd like to make a miniature GUI). Would you be willing to teach that, or is that secret stuff I shouldn't touch yet?

Also, how did you know about the cg folder drop? Was that by chance or something?

One more question: These .bmp's have some transparency black channel don't they? I'm guessing I need to save alpha channels, but I don't know what the heck those are =(. Could someone direct me somewhere? I have photoshop, so I can do something.
Currently Translating: Pure Pure The Story of Ears and Tails AKA Pyua Pyua Mimi to Shippo no Monogatari

User avatar
phib
Addict
Posts: 104
Joined: May 9th, 2007, 12:25 am

Unread post by phib » November 24th, 2008, 1:07 pm

furyoftheskies wrote:I'd love to figure out how you got the decompression code (I'd like to make a miniature GUI).
Debugging. The algorithm is the typical lz variation with a sliding window.
http://purepure.pastebin.com/f2ff73105
Also, how did you know about the cg folder drop? Was that by chance or something?
Debugging.
One more question: These .bmp's have some transparency black channel don't they? I'm guessing I need to save alpha channels, but I don't know what the heck those are =(. Could someone direct me somewhere? I have photoshop, so I can do something.
They're 32bit bmp's, you'll need something better than paint to edit them, like gimp or probably photoshop.

User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Unread post by furyoftheskies » November 24th, 2008, 9:35 pm

phib wrote:Debugging. The algorithm is the typical lz variation with a sliding window.
http://purepure.pastebin.com/f2ff73105
Oh dang. I'm trying to understand what you gave me, but I have no clue what the heck a lz variation with a sliding window is :(

I can slightly understand the code, but it is a bit confusing.

I see the declaration of the dictionary obtained by the decoder for back referencing (I think?) but then I get lost after a few lines.

Would anyone out there care to explain?
Currently Translating: Pure Pure The Story of Ears and Tails AKA Pyua Pyua Mimi to Shippo no Monogatari


User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Unread post by furyoftheskies » November 25th, 2008, 2:45 am

I wonder how many thanks I'm going to owe you after this.

P.S. I've solved the japanese problems now. I just changed their names to hold the brackets, thanks for the idea.

Usually, the name is typed like this:

【Midou】

To get rid of the stupid brackets showing up on the tildes, I simply replaced the name to hold the brackets only:

「Midou」

This way, the program doesn't produce the annoying brackets if I decide to use full width tilde(~) or the music sign (♪).
Currently Translating: Pure Pure The Story of Ears and Tails AKA Pyua Pyua Mimi to Shippo no Monogatari

Randy1919
Totally hardly posted
Posts: 1
Joined: December 24th, 2008, 3:17 pm

Unread post by Randy1919 » January 13th, 2009, 5:15 pm

Hi.Great project keep up the good work.

Shadetale
Totally hardly posted
Posts: 2
Joined: January 21st, 2009, 8:27 pm

Pure Pure PS2

Unread post by Shadetale » January 21st, 2009, 8:36 pm

I'm curious if you're thinking about adding the PS2 bonuses(I.E. Midou as well as the random characters(like the teachers) being voiced, the ending song as well as the bonus CGs). I personally think Midou being voiced adds a LOT to the game. Plus the song they chose for Sachi's (Spoiler: Death scene /Spoiler)is rather poor compared to SA-CHI, the song they added for the PS2 release.

User avatar
furyoftheskies
Might just like this board
Posts: 37
Joined: November 2nd, 2008, 1:21 pm

Re: Pure Pure PS2

Unread post by furyoftheskies » January 27th, 2009, 8:05 am

Shadetale wrote:I'm curious if you're thinking about adding the PS2 bonuses(I.E. Midou as well as the random characters(like the teachers) being voiced, the ending song as well as the bonus CGs). I personally think Midou being voiced adds a LOT to the game. Plus the song they chose for Sachi's
► Show Spoiler
is rather poor compared to SA-CHI, the song they added for the PS2 release.
Well, if I could only find that song. I reviewed the scene, and while it is true the song might sound a bit too happy, it IS Sachi's character song.

I can change the BGMs of the song. Actually, if I really wanted, I make the game use a custom song that you can't access in the gallery.

I don't have access to a copy of the PS2 version of pure pure, either.
Currently Translating: Pure Pure The Story of Ears and Tails AKA Pyua Pyua Mimi to Shippo no Monogatari

Post Reply