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

Author Topic: Cartographer and bit shifting  (Read 4799 times)

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Cartographer and bit shifting
« on: April 21, 2016, 03:28:24 pm »
So I've looked around but can't find a solution to my problems using Cartographer with The Legend of Dragoon ROM.

There are a couple of problems dumping the script from this particular ROM that I've run into:

1. It uses relative pointer tables, but the hex values in the ROM are left shifted by two bits at runtime. Considering pointers seem to be 32-bit and the text occurs in relatively small chunks should not even require more than 16-bit pointers, I don't know why they do this, but that's how it is. Is there any way to have the pointers calculated on the fly when script dumping with Cartographer, while still keeping the original pointer values for later insertion? I guess I'd need Atlas to do something similar when updating pointer values.

2. After every segment of text (so after the end character $FFA0), there are either 8 bytes defining the dimensions of the text box that the text is displayed in. These bytes have their own separate relative pointer table that occurs immediately after the pointer table for the text. I'd need to dump and reinsert these bytes with updated pointers as well, since they're interleaved with the text. I don't think Cartographer supports having multiple pointer tables though, so the characters get dumped alongside the rest of the text, without their own pointer references.  Is there some way to use multiple pointer tables with their own separate base addresses, and have them dump the bytes sequentially? So [text][box dimensions][text][box dimensions].

3. The text box dimensions always start at the start of a full 32-bit word, so if the preceding text end character ends at the 16-bit point, it pads out the the remaining two bytes with $00 to keep everything word-aligned. Would the best way to deal with this to define both $FFA0 and $FFA00000 as end characters?

I haven't looked as much into Atlas yet, but I imagine some of these questions will apply to that too.
ROM wasn't hacked in a day.

Klarth

  • Sr. Member
  • ****
  • Posts: 484
    • View Profile
Re: Cartographer and bit shifting
« Reply #1 on: April 21, 2016, 08:02:33 pm »
1. It uses relative pointer tables, but the hex values in the ROM are left shifted by two bits at runtime. Considering pointers seem to be 32-bit and the text occurs in relatively small chunks should not even require more than 16-bit pointers, I don't know why they do this, but that's how it is. Is there any way to have the pointers calculated on the fly when script dumping with Cartographer, while still keeping the original pointer values for later insertion? I guess I'd need Atlas to do something similar when updating pointer values.
This will be problematic. Atlas has no support for pointer formulas like that. Your options would be to A) Download Visual Studio and make a new pointer type for Atlas (not very hard). B) Download Visual Studio and make a DLL for a new pointer type. C) Make a program that shifts all pointer bits left by two, dump with Cartographer, insert with Atlas, make a program that shifts all pointer bits right by two. I'd opt for A. Or making your own program.

Quote
2. After every segment of text (so after the end character $FFA0), there are either 8 bytes defining the dimensions of the text box that the text is displayed in. These bytes have their own separate relative pointer table that occurs immediately after the pointer table for the text. I'd need to dump and reinsert these bytes with updated pointers as well, since they're interleaved with the text. I don't think Cartographer supports having multiple pointer tables though, so the characters get dumped alongside the rest of the text, without their own pointer references.  Is there some way to use multiple pointer tables with their own separate base addresses, and have them dump the bytes sequentially? So [text][box dimensions][text][box dimensions].
The usual strategy for dealing with this will be to just dump this data with relevant table tags and dump the pointer data as hex. You'll have to do fairly substantial script editing to replace the pointer data with Atlas's embedded pointers.

Quote
3. The text box dimensions always start at the start of a full 32-bit word, so if the preceding text end character ends at the 16-bit point, it pads out the the remaining two bytes with $00 to keep everything word-aligned. Would the best way to deal with this to define both $FFA0 and $FFA00000 as end characters?
Use stringalign within Atlas. You will have to modify your script file manually.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Cartographer and bit shifting
« Reply #2 on: April 22, 2016, 09:17:05 pm »
This will be problematic. Atlas has no support for pointer formulas like that. Your options would be to A) Download Visual Studio and make a new pointer type for Atlas (not very hard). B) Download Visual Studio and make a DLL for a new pointer type. C) Make a program that shifts all pointer bits left by two, dump with Cartographer, insert with Atlas, make a program that shifts all pointer bits right by two. I'd opt for A. Or making your own program.
Since I my limited programming experience in Java, Python and R is nowhere near enough to create a program like that, I think I'll take your advice and go with option A. That'll still be a little tricky, since I have zero experience in Visual Studio and creating Atlas extensions, but I'll take a shot at it. Would I do this just by modifying the code in pointer.h and pointer.cpp to include code for a new type of pointer?

Also, can something like this work with Cartographer as well, since it doesn't include the source code? Otherwise, I have no good way to dump the script in the first place.

Quote
The usual strategy for dealing with this will be to just dump this data with relevant table tags and dump the pointer data as hex. You'll have to do fairly substantial script editing to replace the pointer data with Atlas's embedded pointers.
Not sure I understand this. What do you mean by relevant table tags? And will Atlas's embedded pointers handle this? The pointer tables are all before the text. It's the text box dimensions that are between lines of script, not the pointers.
ROM wasn't hacked in a day.

Klarth

  • Sr. Member
  • ****
  • Posts: 484
    • View Profile
Re: Cartographer and bit shifting
« Reply #3 on: April 22, 2016, 11:47:49 pm »
Would I do this just by modifying the code in pointer.h and pointer.cpp to include code for a new type of pointer?
So to get you started, download Visual Studio. Open the Atlas.sln file to open the project. The easiest way is to add a new AddressType to Pointer.h. (Add a new constant, increase AddressTypeCount by 1, add "LINEARSHIFT2" or whatever to the AddressType strings). Then within Pointer.cpp Pointer::GetMachineAddress add a new case for LINEARSHIFT2.

Code: [Select]
case LINEARSHIFT2:
return Address >> 2;


Quote
Also, can something like this work with Cartographer as well, since it doesn't include the source code? Otherwise, I have no good way to dump the script in the first place.
Not sure I understand this. What do you mean by relevant table tags? And will Atlas's embedded pointers handle this? The pointer tables are all before the text. It's the text box dimensions that are between lines of script, not the pointers.
I think I misunderstood this the first time. The pointers to the window data are outside of the window data, right? If so, then you probably won't need embedded pointers. You would manually edit the script and setup pointer writes within the Atlas script. There may be a way to setup autowrite in this case, but I'd need more specifics.

Since you won't be able to recompile Cartographer, I would suggest not dumping by the pointer method if possible. You'll have to do some manual editing of the script to setup autowrite in Atlas and whatnot, but it's worth it IMO.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Cartographer and bit shifting
« Reply #4 on: April 23, 2016, 02:45:51 am »

I think I misunderstood this the first time. The pointers to the window data are outside of the window data, right? If so, then you probably won't need embedded pointers. You would manually edit the script and setup pointer writes within the Atlas script. There may be a way to setup autowrite in this case, but I'd need more specifics.

Since you won't be able to recompile Cartographer, I would suggest not dumping by the pointer method if possible. You'll have to do some manual editing of the script to setup autowrite in Atlas and whatnot, but it's worth it IMO.
Thanks for the programming tips. That should help me get started on that part.

As for your question, yes, the pointers are outside of the window data. The structure looks like this: http://imgur.com/NTYbz6D.

The pointer table for the text starts on the red byte. There are three sections of text, so that word and the two words after it point to the start text codes $00A5 and $01B0. $FFA1 is the newline code, while $FFA0 is the end text code. After each $FFA0 are either 8 or 10 bytes, depending on whether the preceding end code is word-aligned or not. So for instance, after the line "Chance of war more likely" is $1C000000 03000000. These two words define text window width and height, and afterward it goes straight into the next part of the script, no pointer. The pointer table for the text window in this example is the three words in between the last word of the text pointer table ($2C000000) and the start of the text highlighted in yellow. So there are two sequential pointer tables preceding the text, and each of them is relative to its own respective starting offset. Both also use the SLL operation.

I looked at the autowrite function, but I couldn't see a way to use it here. I'd need it to alternate writing pointers to two different pointer tables, and the text window just exists on its own; it doesn't have an end token to indicate when a pointer should be written.
ROM wasn't hacked in a day.

Klarth

  • Sr. Member
  • ****
  • Posts: 484
    • View Profile
Re: Cartographer and bit shifting
« Reply #5 on: April 23, 2016, 05:42:17 am »
The structure looks a bit complex for Atlas if you need to resize the text areas. Normally for PSX games, you need to write a program to extract/rebuild files.

I looked at the autowrite function, but I couldn't see a way to use it here. I'd need it to alternate writing pointers to two different pointer tables, and the text window just exists on its own; it doesn't have an end token to indicate when a pointer should be written.
You can define multiple autowrites in Atlas. You would have two end tags in your table, one for the dialogue (ie. /FFA0=<END>) and a value-less tag for the table (ie. /<END2>) and associate each end tag with a different pointer table using autowrite.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Cartographer and bit shifting
« Reply #6 on: April 23, 2016, 12:01:39 pm »
The structure looks a bit complex for Atlas if you need to resize the text areas. Normally for PSX games, you need to write a program to extract/rebuild files.
You can define multiple autowrites in Atlas. You would have two end tags in your table, one for the dialogue (ie. /FFA0=<END>) and a value-less tag for the table (ie. /<END2>) and associate each end tag with a different pointer table using autowrite.
Haha, oh good. I was afraid things would be manageable for a moment.  :P Because I would like to be able expand the dialogue. I know I can at least do it manually as long as I don't exceed the length of the final sector of a particular file object, but that only works if I also delete code padding at the end of it, which was never something Atlas would do for me.

So now I guess I have to decide what will take longer: Manually hex editing dialogue for a 4 disc game (yes, I'm probably insane), or learning enough programming to write my own extractor/inserter, using it, then editing the script. I'm honestly not sure which would take me longer.

Any suggestions for a program language that is a good combination of best/easiest to learn for doing this kind of thing? Or a programmer looking to take on a new project?  ;D
ROM wasn't hacked in a day.

Klarth

  • Sr. Member
  • ****
  • Posts: 484
    • View Profile
Re: Cartographer and bit shifting
« Reply #7 on: April 23, 2016, 01:09:21 pm »
So now I guess I have to decide what will take longer: Manually hex editing dialogue for a 4 disc game (yes, I'm probably insane), or learning enough programming to write my own extractor/inserter, using it, then editing the script. I'm honestly not sure which would take me longer.
The process is typically to extract the virtual file system into individual files, extract the script from the individual files, translate/edit, insert the script with a tool that can rebuild/resize individual files, then rebuild the virtual file system. So you would be looking at ~4 small programs if all of those are necessary. Most of which is simple loops and file i/o. I would recommend this approach in any project because otherwise the project will be very unorganized and you'll inevitably end up redoing substantial amounts of work.

Quote
Any suggestions for a program language that is a good combination of best/easiest to learn for doing this kind of thing? Or a programmer looking to take on a new project?  ;D
You could do it in Python if you're familiar with it. I released TableLib quite a long time ago that has C++ source code for an inserter/dumper along with simple samples. Unfortunately, it cannot be used outside of C++ as-is.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Cartographer and bit shifting
« Reply #8 on: April 23, 2016, 03:13:30 pm »
I haven't looked at Python since I made a simple blackjack game 2 years ago, so I wouldn't say I'm familiar at this point unfortunately. I might as well learn C++ so I can more easily incorporate the things you've already done if I'm going to do this.

I'd like to clarify the process a little though. So I've extracted the individual files from the iso with CDMage to get rid of all that error detection/correction code. The file I'm working on is a .bin file, but it's composed of a bunch of other files all merged together (headed with MRG codes). The first of these merged files is an index for the others (is that what a TOC is?) containing word pairs; the first word gives the sector number, the second word gives the byte length of the file.

Each of these files in turn contain more basic files, like image files, and their own index for those files.

When you talk about extracting individual files, down to what level are you talking? Is extracting/inserting the script from the .bin file sufficient, or should I split it into subfiles, and work with those (looks like 712 of them)? Or do I need to split it even further, all the way to the lowest level (images, script files, etc.), and fully rebuild it from the bottom up?
ROM wasn't hacked in a day.

Klarth

  • Sr. Member
  • ****
  • Posts: 484
    • View Profile
Re: Cartographer and bit shifting
« Reply #9 on: April 23, 2016, 03:48:03 pm »
When you talk about extracting individual files, down to what level are you talking? Is extracting/inserting the script from the .bin file sufficient, or should I split it into subfiles, and work with those (looks like 712 of them)? Or do I need to split it even further, all the way to the lowest level (images, script files, etc.), and fully rebuild it from the bottom up?
So when working on ToP PSX (and some other games), I would extract the files from the .bin file, which represented a lot of different types of data but ~1/2 of the files were "room files" and contained everything for a room. Then I extracted all subfiles from the room files only. Then dumped the script from the script subfiles (which had event code and whatnot).  Most subfiles weren't touched, but it was easier to just completely rebuild all of the room files because the archive formats were relatively clean. This allowed for modifications of mostly any magnitude without finicky manual work.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Cartographer and bit shifting
« Reply #10 on: April 23, 2016, 04:13:23 pm »
So when working on ToP PSX (and some other games), I would extract the files from the .bin file, which represented a lot of different types of data but ~1/2 of the files were "room files" and contained everything for a room. Then I extracted all subfiles from the room files only. Then dumped the script from the script subfiles (which had event code and whatnot).  Most subfiles weren't touched, but it was easier to just completely rebuild all of the room files because the archive formats were relatively clean. This allowed for modifications of mostly any magnitude without finicky manual work.
This approach should work for me, I think. I had already determined that LoD takes a similar approach to that, although I believe it uses multiple "room files" for each room, with each one containing different types of assets. One type contains the script sandwiched between other code that I can't identify. So I guess I'll try to split these files up and rebuild them after insertion, then rebuild the bin file.

I guess other than the initial learning process, the hardest parts will be dealing with things that don't fit the rules for the rest of it. Like the parts of the index that refer to the same file multiple times, but all but the last instance have 0 size; or the occasional bits of script that don't have start tokens like the rest; or that one that does that, is repeated three separate times, and each repetition has a different pointer table that doesn't point to all of the lines... ::)
ROM wasn't hacked in a day.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Cartographer and bit shifting
« Reply #11 on: May 07, 2016, 02:50:49 am »
So I opted to learn some C++ and try to write/modify programs to do what I need. Right now I have most of the bin splitter managed, but I'm having trouble with one part. I read the binary file into a char* array first. To get the location and size of all the files, I'm looping through the file system at the start of the array. The problem is that to get the offset and file size, I need to convert 4 bytes at a time into 32-bit integers, and this seems to be trickier than it seems like it should. I've tried several things and I keep getting either errors or weird output. I figure this has to be something people on here have done, so what's a good way to handle this?

EDIT: I fixed it, and my bin splitter appears to officially work now, but I feel like my solution to the char* to integer problem is still inelegant, even if it does work. I'd still be interested in opinions.
« Last Edit: May 07, 2016, 03:51:25 am by theflyingzamboni »
ROM wasn't hacked in a day.

AWJ

  • Full Member
  • ***
  • Posts: 105
    • View Profile
Re: Cartographer and bit shifting
« Reply #12 on: May 07, 2016, 04:35:35 am »
So I opted to learn some C++ and try to write/modify programs to do what I need. Right now I have most of the bin splitter managed, but I'm having trouble with one part. I read the binary file into a char* array first. To get the location and size of all the files, I'm looping through the file system at the start of the array. The problem is that to get the offset and file size, I need to convert 4 bytes at a time into 32-bit integers, and this seems to be trickier than it seems like it should. I've tried several things and I keep getting either errors or weird output. I figure this has to be something people on here have done, so what's a good way to handle this?

EDIT: I fixed it, and my bin splitter appears to officially work now, but I feel like my solution to the char* to integer problem is still inelegant, even if it does work. I'd still be interested in opinions.

The correct C++ type to use when working with raw binary bytes is unsigned char. Just char on its own is a signed type, meaning bytes bigger than 0x7f will be treated as negative numbers, which is almost never what you want.

As for reading 32-bit integers out of a blob of bytes:

Code: [Select]
inline unsigned readuint32le(unsigned char const *src) { return src[0] | src[1] << 8 | src[2] << 16 | src[3] << 24; }
inline unsigned readuint32be(unsigned char const *src) { return src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3]; }

Use whichever one matches the endianness of the source data (the little-endian version for PSX data, the big-endian for N64)

A common cause of bugs is getting operator precedence wrong, especially when you're doing bit manipulation, which is common in ROM hacking and emulation. The precedence rules for the common arithmetic operators in C++ are what you'd expect from high school algebra, but the rules for the bitwise operators are a bit screwy. A particular gotcha is that the bitwise operators &, | and ^ have lower precedence than the == operator. This means that a statement like
Code: [Select]
if(x & some_mask == some_value) { do_something(); }won't do what you expect; you have to put parentheses around the x & some_mask part. When in doubt, add parentheses.
« Last Edit: May 07, 2016, 04:56:26 am by AWJ »

Klarth

  • Sr. Member
  • ****
  • Posts: 484
    • View Profile
Re: Cartographer and bit shifting
« Reply #13 on: May 07, 2016, 05:14:31 pm »
EDIT: I fixed it, and my bin splitter appears to officially work now, but I feel like my solution to the char* to integer problem is still inelegant, even if it does work. I'd still be interested in opinions.
I typically don't read the entirety of the virtual file system into memory at once. I loop over each file info struct in the header and read/dump the file as the data is first read in.

For your char* to integer problem, if the system you compile on has the same endian-ness as the system you're working on (Intel and PSX are both little endian), then you can do this:

unsigned char* p = location;
unsigned int val = *(unsigned int*)p;

This casts the char pointer to a unsigned int pointer, then dereferences (grabs) the 32bit value.

In strict C++, you should use a reinterpret_cast<unsigned int*>, but I've always found the syntax to be awkward.
« Last Edit: May 08, 2016, 02:47:50 pm by Klarth »

STARWIN

  • Sr. Member
  • ****
  • Posts: 449
    • View Profile
Re: Cartographer and bit shifting
« Reply #14 on: May 08, 2016, 09:02:46 am »
(Intel and PSX are both big endian)

..little endian.

C would be simpler than C++ as far as programming concepts go, but whatever works.

char* array sounds wrong, as that implies an array of pointers. I don't know if C++ is different but you should read to an unsigned char array, without the asterisk, so an array of bytes.

edit: also, i hope you aren't just doing unsigned char array[filesize]; or such for a very large file, as that supposedly allocates from stack which is rather small.. in C you'd use malloc and in C++ new or vector for allocating memory.
« Last Edit: May 08, 2016, 10:16:48 am by STARWIN »

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Cartographer and bit shifting
« Reply #15 on: May 08, 2016, 02:14:10 pm »

C would be simpler than C++ as far as programming concepts go, but whatever works.

char* array sounds wrong, as that implies an array of pointers. I don't know if C++ is different but you should read to an unsigned char array, without the asterisk, so an array of bytes.

edit: also, i hope you aren't just doing unsigned char array[filesize]; or such for a very large file, as that supposedly allocates from stack which is rather small.. in C you'd use malloc and in C++ new or vector for allocating memory.
I wouldn't know, but Klarth's Atlas and TableLib are in C++ Since I plan on using/modifying them when I make a text dumper/inserter that will work with TLoD's peculiarities, I decided to learn some C++.

I actually misspoke about the char* array. What I meant is that it's a char* pointing to the array of bytes. fstream requires it as the file parameter. I just read the entire file into a dynamic array with char* array = new char[filesize] (which is allocated to the heap), and the value is simply a single char* value pointing to the array location. I then created a couple pointers for the file system and and the files respectively, and looped through the file system portion of the array, writing out files using pointer arithmetic to get the correct bytes. I realize that this is surely by no means the most efficient way, but this was easiest for me to conceptualize initially. I may go back and try to improve the code later, but as it is it can split a 100+ MB file into about 750 pieces in around 20 seconds. I'm sure it could be faster, but that's fast enough for me right now. I'd rather move on to writing the merger, so I can reverse the split and make sure the new file is the same as the old. Otherwise I have bigger problems than unoptimized code.
« Last Edit: May 08, 2016, 04:10:15 pm by theflyingzamboni »
ROM wasn't hacked in a day.

Klarth

  • Sr. Member
  • ****
  • Posts: 484
    • View Profile
Re: Cartographer and bit shifting
« Reply #16 on: May 08, 2016, 02:47:01 pm »
..little endian.
Oops, you're right.

When it comes to C++, I often opt to instead use C-style I/O for binary files. Here is an example to extract a straightforward VFS from Tales of Eternity.
« Last Edit: May 08, 2016, 03:00:13 pm by Klarth »

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Cartographer and bit shifting
« Reply #17 on: May 08, 2016, 05:36:34 pm »
So now I'm trying to write a file merger. I want to iterate through the directory and write the contents of each to the new merged file. I used an iterator using std::experimental::filesystem (like boost::filesystem), and tested that printing out filenames, using:

   for (auto& p : directory_iterator(out_dir_path))
         cout << p << endl;

All my files are numbered sequentially (DRGN21_1.bin, DRGN21_2.bin, etc.). Unfortunately, when I use this, it goes through everything starting with _1, then _2, etc., so it's all out of order.

How do I get it to count up normally? I could just do a regular for loop and create each name sequentially, then open the file with that name, but I was hoping for something less clumsy.
« Last Edit: May 08, 2016, 05:53:06 pm by theflyingzamboni »
ROM wasn't hacked in a day.

Klarth

  • Sr. Member
  • ****
  • Posts: 484
    • View Profile
Re: Cartographer and bit shifting
« Reply #18 on: May 08, 2016, 05:47:23 pm »
If order matters, I would write the filenames to a separate text file as you're dumping the individual files. That way you're sure to know the order for rebuilding. In games that don't have filenames, I just name them sequentially like File0000, File0001, etc.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Cartographer and bit shifting
« Reply #19 on: May 10, 2016, 10:33:06 pm »
If order matters, I would write the filenames to a separate text file as you're dumping the individual files. That way you're sure to know the order for rebuilding. In games that don't have filenames, I just name them sequentially like File0000, File0001, etc.
Good call, that worked out well. I just read the filenames out of the text file and used them to open the files in sequence. The file merger can now put everything back together and yield the original file, so that's good. I'm having trouble when I try to update the VFS table though. I set up the output file to be read/write, so once it's written the table (it's the first file), the loop will start running the conditional code to check for differences in the table, and update them with new values if necessary. For some reason though, when I add this code in, it crashes after the fifth merged file, and always the fifth. I stepped through the debugger, and it gets to the closing brace on the loop, then throws an "Access violation reading location."

Specifically, it's here:

std::basic_ios<char,std::char_traits<char> >   <Unable to read memory>   

on this code:

   virtual __CLR_OR_THIS_CALL ~basic_ifstream() _NOEXCEPT
      {   // destroy the object
      }

I'm not even sure what it's trying to destroy. I didn't create any new fstream objects in the VFS updating portion of the code, and as I said, I don't have this problem when that code is commented out.

The problem portion of the code looks like

Code: [Select]
unsigned int filesize;
uint32_t tocPosition{ 0x08 };
        string tempWord;
uint32_t tocWord;

if (tocWritten)
{
//toc stuff here
//set a value to walk through the table
//jump to that value in the file
char tocWordBuffer[4];
outputFile.seekg(tocPosition, ios::beg);
//read the location
outputFile.read(tocWordBuffer, tocPosition + 0x04);
tocWord = *reinterpret_cast<uint32_t*>(tocWordBuffer);
cout << tocWord << endl;
//if current offset / 0x800 does not equal this value
                        //write new file offset to table
if (isMainFile)
{
if ((prevOffset / 0x800) != tocWord) //for sector alignment in main file
{
tempWord = to_string(prevOffset / 0x800);
outputFile.seekg(tocPosition, ios::beg);
outputFile.write(tempWord.c_str(), tocPosition + 0x04);
}
}
else
{
if (prevOffset != tocWord) //no sector alignment in subfiles
{
tempWord = to_string(prevOffset);
outputFile.seekg(tocPosition, ios::beg);
outputFile.write(tempWord.c_str(), tocPosition + 0x04);
}
}
tocPosition += 0x04; //move to filesize position in table

//move to filesize and read it
outputFile.seekg(tocPosition, ios::beg);
outputFile.read(tocWordBuffer, tocPosition + 0x04);
tocWord = *reinterpret_cast<uint32_t*>(tocWordBuffer);
cout << tocWord << endl;
//if table value does not equal current filesize
//write new filesize
if (filesize != tocWord)
{
tempWord = to_string(filesize);
outputFile.seekg(tocPosition, ios::beg);
outputFile.write(tempWord.c_str(), tocPosition);
}

tocPosition += 0x04; //move position to next file location
}

I know this code looks a mess, but it looks like it should work to me. I can't see what would be causing a problem with the stream.
ROM wasn't hacked in a day.