Sign in to follow this  
coderWalker

File Reading and Writing not working on Windows

Recommended Posts

I just don't see a problem. I have went over this 100x. I open the streams I close the streams.
The problem is the game generates a "chunk" or peice of the world if not found in a file then saves it.
Later when coming back the game loads it so it doesn't have to regenerate it.

The problem is:
The game generates the "chunk"
[u]the game saves a blank txt file (Windows only)[/u]
the game reads the blank file making a huge hole in the world.
The player falls until a new chunk is hit.
Then after leaving it the process repeats.

I just can't hone in on whats throwing the streams off?

Someone please tell me what I am messing up.
Thanks in advance!

file.h:
[code]class file
{
public:
file();
void writeData();
void readData();
void writeChunk(signed int x,signed int y,signed int z,signed int xArray,signed int yArray,signed int zArray);
bool readChunk(signed int x,signed int y,signed int z,signed int xArray,signed int yArray,signed int zArray);
void readGame();
private:
////Variables
std::stringstream name;
std::string temp;
ofstream fileStream;
ifstream fileStreamRead;
};

[/code]
file.cpp :
[code]#include "Global.h"

file::file()
{
////Clear Variables
name.str(std::string());
}

void file::writeData()
{
name.str(std::string());
name << "save/" << Map->name << "xData.txt";
temp = name.str();
fileStream.open(temp.c_str(), ios::out|ios::binary);
if (fileStream.is_open())
{
char *pStoreMemory;
char *pLoc;
pStoreMemory = new char [8+TOTALBLOCKS];
pLoc = pStoreMemory;
////Write (x,y,z)
*pLoc = static_cast<int>(player1->x) & 0xFF;
pLoc++;
*pLoc = static_cast<int>(player1->y) & 0xFF;
pLoc++;
*pLoc = static_cast<int>(player1->z) & 0xFF;
pLoc++;
//Write Rot
*pLoc = static_cast<int>(player1->yRot) & 0xFF;
pLoc++;
*pLoc = static_cast<int>(player1->zRot) & 0xFF;
pLoc++;
cout << "# Player yRot=" << player1->yRot << "\n# Player zRot=" << player1->zRot << "\n";
////Write Offsets
*pLoc = Map->xOffset & 0xFF;
pLoc++;
*pLoc = Map->yOffset & 0xFF;
pLoc++;
*pLoc = Map->zOffset & 0xFF;
pLoc++;
////Set inventory to 0
for (int i=0;i<TOTALBLOCKS;i++)
{
*pLoc = player1->inventory[i] & 0xFF;
pLoc++;
}
//*pLoc = Map->zOffset & 0xFF;
// !! 4 bytes to an address ?
fileStream.write(pStoreMemory,8+TOTALBLOCKS);
delete[] pStoreMemory;
}
fileStream.close();
}

void file::readData()
{
name.str(std::string());
name << "save/" << Map->name << "xData.txt";
temp = name.str();
fileStreamRead.open(temp.c_str(), ios::in|ios::binary);
if (fileStreamRead.is_open())
{
char *pStoreMemory;
char *pLoc;
pStoreMemory = new char [8+TOTALBLOCKS];
pLoc = pStoreMemory;
fileStreamRead.read(pStoreMemory,8+TOTALBLOCKS);
player1->x = (*pLoc & 0xFF)+.5;
pLoc++;
player1->y = (*pLoc & 0xFF)+.5;
pLoc++;
player1->z = (*pLoc & 0xFF)+.5;
pLoc++;
////Read Rot
player1->yRot = (*pLoc & 0xFF);
pLoc++;
player1->zRot = (*pLoc & 0xFF);
pLoc++;
////Write (x,y)
Map->xOffset = *pLoc & 0xFF;
pLoc++;
Map->yOffset = *pLoc & 0xFF;
pLoc++;
Map->zOffset = *pLoc & 0xFF;
pLoc++;
cout << "# Player yRot=" << player1->yRot << "\n# Player zRot=" << player1->zRot << "\n";
// !! 4 bytes to an address ?
////Set inventory to 0
for (int i=0;i<TOTALBLOCKS;i++)
{
player1->inventory[i]= *pLoc & 0xFF;
pLoc++;
}
delete[] pStoreMemory;
cout << "# Map Offsets (" << Map->xOffset << "," << Map->yOffset << ")\n";
player1->zRot=0;
player1->yRot=0;
}
else
{
player1->x=7.5;
player1->y=7.5;
player1->z=7.5;
Map->xOffset=((CLIPDIST-1)/2)+1;
Map->yOffset=Map->xOffset;
Map->zOffset=10;
}
fileStreamRead.close();
Map->checkChunks();
}

void file::writeChunk(signed int x,signed int y,signed int z,signed int xArray,signed int yArray,signed int zArray)
{
cout << "+ Saveing Chunk(" << x << "," << y << "," << z << ")...";
//cout << "Clipped " << Map->Chunk[xArray][yArray][zArray]->omitedFaces << "faces!\n";
////Open File to save in
name.str(std::string());
name << "save/" << Map->name << "x" << x << "x" << y << "x" << z << ".txt";
temp = name.str();
fileStream.open(temp.c_str(), ios::out|ios::binary);
if (fileStream.is_open())
{
////Make the 2 pointers
char *pStoreMemory;
char *pLoc;
////Allocate memory
pStoreMemory = new char [4*16*16*16];
pLoc = pStoreMemory;
////Write needed data to memory
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
for (int k = 0; k < 16; k++)
{
/* store the exists bit at the left */
*pLoc = (Map->Chunk[xArray][yArray][zArray]->space[i][j][k].exists ? (1 << 7) : 0);
/* store high 7 bits of 11 from tx in rest of byte */
//0x7F0 = 01111111
*pLoc |= (unsigned char)((Map->Chunk[xArray][yArray][zArray]->space[i][j][k].tx & 0x7F0) >> 4);
pLoc++;
/* store low 4 bits of 11 from tx in top of next byte */
//0xF = 11110000
*pLoc = (unsigned char)((Map->Chunk[xArray][yArray][zArray]->space[i][j][k].tx & 0xF) << 4);
/* store high 4 bits of 11 from ty in rest of byte */
//0x780 = 01111000
*pLoc |= (unsigned char)((Map->Chunk[xArray][yArray][zArray]->space[i][j][k].ty & 0x780) >> 7);
pLoc++;
/* store low 7 bits of 11 from tx in last byte */
//01111111
*pLoc = (unsigned char)(Map->Chunk[xArray][yArray][zArray]->space[i][j][k].ty & 0x7F);
pLoc++;
if (Map->Chunk[xArray][yArray][zArray]->space[i][j][k].amount!=-1)
{
//int a =0;
}
*pLoc = (unsigned char)(static_cast<int>((Map->Chunk[xArray][yArray][zArray]->space[i][j][k].amount+1)*5) & 0xFF);
pLoc++;
}
}
}
////Copy memory to file
fileStream.write(pStoreMemory,4*16*16*16);
fileStream.close();
delete[] pStoreMemory;
cout << "Done!\n";
}
else
{
cout << "/!\\ Cannot open " << temp.c_str() << "\n";
}
return;
}

bool file::readChunk(signed int x,signed int y,signed int z,signed int xArray,signed int yArray,signed int zArray)
{
cout << "- Loading Chunk(" << x << "," << y << "," << z << ")...";
////Open File to load from
name.str(std::string());
name << "save/" << Map->name << "x" << x << "x" << y << "x" << z << ".txt";
//cout << name.str() << "...";
temp = name.str();
fileStreamRead.open(temp.c_str(), ios::in|ios::binary);
if (fileStreamRead.is_open())
{

////Make the 2 pointers
char *pStoreMemory;
char *pLoc;
////Allocate memory
pStoreMemory = new char [4*16*16*16];
pLoc = pStoreMemory;
////Copy memory to file
fileStreamRead.read(pStoreMemory,4*16*16*16);
////Write needed data to memory
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
for (int k = 0; k < 16; k++)
{
//cout << i << " " << j << " " << k << "\n";
/* store the exists bit at the left */
//*pLoc = (Map->Chunk[x][y]->space[i][j][k].exists ? (1 << 7) : 0);
//Map->Chunk[x][y];
//cout << Map->chunkExists[x][y];
Map->Chunk[xArray][yArray][zArray]->space[i][j][k].exists= (*pLoc >> 7);
/* store high 7 bits of 11 from tx in rest of byte */
//0x7F0 = 01111111
//*pLoc |= (unsigned char)((Map->Chunk[x][y]->space[i][j][k].tx & 0x7F0) >> 4);
//cout << "This will not be visible\n";
Map->Chunk[xArray][yArray][zArray]->space[i][j][k].tx = (*pLoc << 4) & 0x7F0;
pLoc++;
/* store low 4 bits of 11 from tx in top of next byte */
//0xF = 11110000
//*pLoc = (unsigned char)((Map->Chunk[x][y]->space[i][j][k].tx & 0xF) << 4);
Map->Chunk[xArray][yArray][zArray]->space[i][j][k].tx = (*pLoc >> 4) & 0xF;
/* store high 4 bits of 11 from ty in rest of byte */
//0x780 = 01111000
//*pLoc |= (unsigned char)((Map->Chunk[x][y]->space[i][j][k].ty & 0x780) >> 7);
Map->Chunk[xArray][yArray][zArray]->space[i][j][k].ty = (*pLoc << 7) & 0x780;
//STRIP LIQUIDS!!!
//Map->Chunk[x][y][z]->space[i][j][k].ty = 0 ;
pLoc++;
/* store low 7 bits of 11 from tx in last byte */
//01111111
//*pLoc = (unsigned char)(Map->Chunk[x][y]->space[i][j][k].tx & 0x7F);
Map->Chunk[xArray][yArray][zArray]->space[i][j][k].ty = (*pLoc) & 0x7F;
pLoc++;

Map->Chunk[xArray][yArray][zArray]->space[i][j][k].amount = (((*pLoc) & 0xFF)/5.0f)-1.0f;
if (Map->Chunk[xArray][yArray][zArray]->space[i][j][k].amount!=-1)
{
//int a=0;
Map->Chunk[xArray][yArray][zArray]->liquidBufferAdd(i,j,k);
}
pLoc++;
}
}
}
fileStreamRead.close();
delete[] pStoreMemory;
//Map->Chunk[xArray][yArray][zArray]->bufferInit();
cout << "Done!\n";
Map->Chunk[xArray][yArray][zArray]->bufferInit();
return true;
}
else
{
cout << "/!\\ Cannot open " << temp.c_str() << "\n";
Map->Chunk[xArray][yArray][zArray]->init();
return false;
}
}
[/code]

Share this post


Link to post
Share on other sites
Hidden
Just a guess without looking at your code yet -- but you're not writing to a protected location on Windows are you? If your program is in, for example, Program Files then you won't be able to write to the program's directory[sup]1.[/sup]
[size="2"]
[/size]
[sup][/sup][size="2"]If this is the case, the solution would be to write your files to application data or a user data directory instead.
[/size]
[sup]
[/sup]
[size="2"][sub]1. Unless you have admin [font=arial, sans-serif][size=2][i]p[/i][i]rivilege[/i][/size][/font]s, which your game should not.[/sub][/size]

Share this post


Link to post
You probably shouldn't store your streams as member variables. Instead, create local variables when opening the file. You can let it naturally fall out of scope and it will close itself. You also don't have to worry about resetting the state of the stream, which is tricky. You'll find that you don't actually have any state, and you can convert your class to a namespace of free functions.

If TOTALBLOCKS is a compile time constant you could use a local array rather than dynamically allocating memory. If it isn't a compile time constant, then use std::vector<> rather than managing your own memory. However, you shouldn't even need to do either of these; you should be able to read/write each value directly to the stream. Helper functions can simplify this.

You should check the return value of the read() and write() functions, and handle the case where the file fails to open reasonably. Also, if you want more robust code consider writing the file data to a temporary location, and then atomically replacing any existing file. This means that if you get an error half way through writing the file you don't corrupt the existing file.

Other than that, you might find the last post [url="http://stackoverflow.com/questions/839644/get-stdfstream-failure-error-messages-and-or-exceptions"]here[/url] useful if the problem persists after making these operations stateless (which I suspect will fix your problem).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this