News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: C++ Read bytes from a binary file and store them as a variable?  (Read 3783 times)

DarkSamus993

  • Sr. Member
  • ****
  • Posts: 291
    • View Profile
I'm working on writing a decompression utility for Mega Man X4-6 and I can't seem to find information on how to read bytes from a binary file and store them as a variable (little endian, because that's what the PSX uses). I'm coding in C++ (just a simple console app) and this is to emulate the MIPS instruction LHU (Load Half-Word Unsigned = 16 bits). I also need to do the converse and store a half-word.

The necessary R3000 registers for the decompression routine are stored as variables of the same name. The user supplies the name of the input/output files and the address (hex) to start reading data from the input file.

For example:
MIPS: lhu    t1, $0000(a0)    =    t1 = memory[a0 + $0000]     =    Compressed data is loaded into t1 from address a0.
C++ : go to input file offset from variable a0 and read 16 bits (little endian) and store  into variable t1.

MIPS: sh     v0, $0000(a1)    =    memory[a1 + $0000] = v0    =    Uncompressed data is stored at address a1 from v0.
C++ : go to output file offset from variable a1 and write 16 bits (little endian) from variable v0.

Can someone give me some code examples on how this would work?

Gemini

  • Hero Member
  • *****
  • Posts: 2026
  • 時を越えよう、そして彼女の元に戻ろう
    • View Profile
    • Apple of Eden
Re: C++ Read bytes from a binary file and store them as a variable?
« Reply #1 on: March 07, 2016, 05:43:44 pm »
Easier solution: store the whole input as a buffer, same for the output, and typecast both buffers as unsigned short values, then simply write and read like a byte array.
Hipster solution: use buffers again, but access them with something like *(unsigned short*)&buffer[pos].
I am the lord, you all know my name, now. I got it all: cash, money, and fame.

RyanfaeScotland

  • Sr. Member
  • ****
  • Posts: 366
    • View Profile
    • My Brill Game Site
Re: C++ Read bytes from a binary file and store them as a variable?
« Reply #2 on: March 07, 2016, 05:51:48 pm »
Where have you searched and what have you found so far? I assume you've googled it but I googled c++ read binary file and got a lot of good results so it would be handy to narrow it down a little!

tvtoon

  • Sr. Member
  • ****
  • Posts: 371
    • View Profile
Re: C++ Read bytes from a binary file and store them as a variable?
« Reply #3 on: March 07, 2016, 06:30:02 pm »
"How can I open a stream in binary mode?" Save yourself for later requests. ;)

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: C++ Read bytes from a binary file and store them as a variable?
« Reply #4 on: March 07, 2016, 06:45:07 pm »
Easier solution: store the whole input as a buffer, same for the output, and typecast both buffers as unsigned short values, then simply write and read like a byte array.
Hipster solution: use buffers again, but access them with something like *(unsigned short*)&buffer[pos].

Note that this solution will only work if the machine you're running on has the same endianness as the file expects.  Most machines now are little endian so this is "mostly safe" -- but mostly isn't enough for me and I don't recommend it be enough for you.

Golden rule is never data from a binary file in chunks that are any larger than a single byte.  Assemble larger types from individual bytes yourself.  Yeah it takes 10 extra lines of code, but big whoop.

BlackDog61

  • Hero Member
  • *****
  • Posts: 784
    • View Profile
    • Super Robot Wars A Portable translation thread
Re: C++ Read bytes from a binary file and store them as a variable?
« Reply #5 on: March 08, 2016, 02:15:04 pm »
i happened to have these at hand, so here's lazy time:

Code: [Select]
int openBinFile(fstream &myfile, const char *myfile_name) {
myfile.open (myfile_name, ios::in|ios::out|ios::binary );
if (false == myfile.is_open()) {
cout << "Error opening " << myfile_name << "\n";
return 2;
} else {
cout << "File " << myfile_name << " has been opened OK.\n";
return 0;
}
}

Code: [Select]
fstream in_file;
// open it up with previous function, then
char file_data;
in_file.read((char*)(&file_data), sizeof(char));
I let file_data in a single byte as per Ditch's comment, so you need to iterate on this.

Gemini

  • Hero Member
  • *****
  • Posts: 2026
  • 時を越えよう、そして彼女の元に戻ろう
    • View Profile
    • Apple of Eden
Re: C++ Read bytes from a binary file and store them as a variable?
« Reply #6 on: March 08, 2016, 03:08:10 pm »
Note that this solution will only work if the machine you're running on has the same endianness as the file expects.  Most machines now are little endian so this is "mostly safe" -- but mostly isn't enough for me and I don't recommend it be enough for you.
I doubt endianness is really a problem unless user is a dummy; x86-64 and r3000 are endian-compatible, so there's no harm unless you're using some crappy Motorola CPU from the early 90's.
I am the lord, you all know my name, now. I got it all: cash, money, and fame.

DarkSamus993

  • Sr. Member
  • ****
  • Posts: 291
    • View Profile
Re: C++ Read bytes from a binary file and store them as a variable?
« Reply #7 on: March 08, 2016, 09:16:18 pm »
Thanks guys! You've given me some good insight on how to handle this situation. I started learning MIPS assembly and C++ roughly three weeks ago, so everything for this project is new territory for me. As such, I've been doing a lot of reading and happen to stumble upon this article which describes exactly what Disch is talking about. Hopefully, I can implement something similar.

henke37

  • Hero Member
  • *****
  • Posts: 643
    • View Profile
Re: C++ Read bytes from a binary file and store them as a variable?
« Reply #8 on: March 15, 2016, 08:15:30 am »
Find a library that wraps the stream and provides handy member functions like setEndian and readU32.