fopen problem (works in psplink)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

fopen problem (works in psplink)

Post by Ghoti »

Hi folks,

I have this wierd error which only occurs when I run the game from my psp and not through PSPLink.

The problem is that fopen in this piece of code:

Code: Select all

char ReadBuffer[256];
	char sBuffer[256];
	getcwd(ReadBuffer,100); 
	sprintf(sBuffer, "%s/Races/%s",ReadBuffer, race);
	if((f = fopen(sBuffer,"rb")) != NULL) {
... }
else { displayerrr("fopen fails..."); }
in psplink it does not return NULL but when I run it just in the psp XMB menu in eboot form then it displays fopen fails...

now I have encountered such a problem in the past with the analog stick and in that case I forgot to include the initialisation of the analog stick and psplink did that automaticly.

This time I have allready used fopen to load up player data and that works because it just shows the info but later on when I load some other file it returns NULL as stated above.

any ideas ?

PS I have check the full path stored in sBuffer to see if that one was correct and it is correct. the file also exists otherwise it would not load up through psplink i guess.


EDIT:: I have already opened the file before that so the file is not faulty also :s it is really strange :s
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

Without psplink .. you're putting your file where is the eboot ?

maybe a silly question .. but psplink read from your computer directory ... and the standalone EBOOT from your MS ... :) (if you work with a relative path)
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hi,

well as you can see in the code I construct the sBuffer from the currentworkingdir then /Races/ and then the race name.
printing out this sbuffer right before the fopen creates:

ms0:/PSP/GAME150/RAZE/Races/Apple circuit.rac

and that is exactly where the file is.
here is a copy of browsing it with windows (copied from the file explorer)

M:\PSP\GAME150\RAZE\Races

and the file

Apple circuit.rac

so that should not be the problem.
the file properties is only "a" (archive)

so unless I miss something that should be correct since I don't use relative paths
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

have you tried to remove the blank space in the race name .... (and change it everywhere according to it) ?
...
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hi well I open the file using the same functions in the mainmenu. It reads out the file to display a small map of the racetrack. after that I choose a car and then it loads the file again to load up all the objects and stuff.

So opening the file with space works fine. I have deleted the space just to be sure and it did not matter.

here is the code of the opening before the crash:

Code: Select all

bool MainMenu::LoadLevelLayout() {
	int x, y, i;

	FILE *f;

	char sBuffer[256];
	char ReadBuffer[256];

	sprintf(sBuffer, "Races/%s", Races[RaceItem]);

	for&#40;x=0;x<16;x++&#41;
		for&#40;y=0;y<10;y++&#41;
			trackLayout&#91;x&#93;&#91;y&#93; = 0;


	if&#40;&#40;f = fopen&#40;sBuffer,"rb"&#41;&#41; != NULL&#41; &#123;
		// parse the info.
		// read version
		for&#40;i = 0; i<7; i++&#41;
			fgets&#40;ReadBuffer, 256, f&#41;;
	
		// read the dimensions
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+2&#41;,"%d",&x &#41;;
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+2&#41;,"%d",&y &#41;;

		if&#40;x>16&#41; &#123; fclose&#40;f&#41;; return false; &#125;
		if&#40;y>10&#41; &#123; fclose&#40;f&#41;; return false; &#125;
		
		for&#40;i=0;i<y;i++&#41;&#123;
			fgets&#40;ReadBuffer, 256, f&#41;;
			// readbuffer has now one row of the field.
			for&#40;unsigned int j=0;j<strlen&#40;ReadBuffer&#41;-1;j++&#41;&#123;
				//trackLayout&#91;j&#93;&#91;i&#93; = 1;
				switch&#40;ReadBuffer&#91;j&#93;&#41;&#123;
				case '1'&#58;
					trackLayout&#91;j&#93;&#91;i&#93; = 1;
					break;
				case '2'&#58;
					trackLayout&#91;j&#93;&#91;i&#93; = 2;
					break;
				case '3'&#58;
					trackLayout&#91;j&#93;&#91;i&#93; = 3;
					break;
				case '4'&#58;
					trackLayout&#91;j&#93;&#91;i&#93; = 4;
					break;
				case '5'&#58;
					trackLayout&#91;j&#93;&#91;i&#93; = 5;
					break;
				case '6'&#58;
					trackLayout&#91;j&#93;&#91;i&#93; = 6;
					break;
				default&#58;
					trackLayout&#91;j&#93;&#91;i&#93; = 0;
					break;
				&#125;
			&#125;
			//
		&#125;

		// done so close
		fclose&#40;f&#41;;
	&#125;
	return true;

&#125;;
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

hummm can we have an example of your race file ?...

it seems that your format version take 7 lines !!??!! (fgets stops when a '\n' is found)

... why don't you do a

while(fgets(....))
{
//parsing with sscanf ...
...
}

?
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hiya,

well the last code that I sended works fine, it opens the file reads out the data and then shows the layout, the first seven line have info only needed for the actual build of the track so not needed in that function and thus skipped.

I showed that function because maybe I did not close the correctly or something it is just very strange why the file is opened at that moment and then 2 menuscreen further it crashes :s
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

Why do you add "2" on the readbuffer ? ...

Code: Select all

sscanf&#40;&#40;ReadBuffer+2&#41;,"%d",&x &#41;; 

Your code looks strange for me :P
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

because those lines start with:
x=
y=

but that code is not the problem i guess, this is the code which states the errormessage:

Code: Select all

int SingleRace&#58;&#58;ParseSingleRace&#40;const char* race&#41; &#123;

	FILE *f;

	char ReadBuffer&#91;256&#93;;
	char sBuffer&#91;256&#93;;
	getcwd&#40;ReadBuffer,100&#41;; 
	sprintf&#40;sBuffer, "%s/Races/%s",ReadBuffer, race&#41;;
	//DebugTools&#58;&#58;PrintTextLoop&#40;sBuffer&#41;;
	//DebugTools&#58;&#58;PrintTextLoop&#40;"Het komt nog tot hiero \n"&#41;;

	if&#40;&#40;f = fopen&#40;sBuffer,"rb"&#41;&#41; != NULL&#41; &#123;
		// parse the info.
		// read version
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+8&#41;,"%d",&version&#41;;

		// read difficulty
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+11&#41;,"%d",&difficulty&#41;;

		// read difficulty
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+11&#41;,"%d",&maxplayers&#41;;

		// start reading x and y start&#40;finish&#41;.
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+8&#41;,"%d",&startPos.y &#41;;
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+8&#41;,"%d",&startPos.x &#41;;

		// start reading x and y halfway.
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+9&#41;,"%d",&halfwayPos.y &#41;;
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+9&#41;,"%d",&halfwayPos.x &#41;;

		// read the dimensions
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+2&#41;,"%d",&dimension.x &#41;;
		fgets&#40;ReadBuffer, 256, f&#41;;
		sscanf&#40;&#40;ReadBuffer+2&#41;,"%d",&dimension.y &#41;;
		
		// create the 2D array
		Track = new std&#58;&#58;vector<std&#58;&#58;vector<TrackPart*>*>;

		//DebugTools&#58;&#58;PrintTextLoop&#40;"Het komt nog tot hiero \n"&#41;;


		for&#40;int i=0;i<dimension.y;i++&#41;&#123;
			fgets&#40;ReadBuffer, 256, f&#41;;
			// readbuffer has now one row of the field.
			//create the vector for 2d array
			TrackLine = new std&#58;&#58;vector<TrackPart*>;

			for&#40;unsigned int j=0;j<strlen&#40;ReadBuffer&#41;;j++&#41;&#123;
				DebugTools&#58;&#58;PrintText&#40;&ReadBuffer&#91;j&#93;&#41;;
				switch&#40;ReadBuffer&#91;j&#93;&#41;&#123;
				case '1'&#58;
					//straight1.addLocation&#40;i*BLOCKSIZE, 0.0f, j*BLOCKSIZE, i, j&#41;;
					tmpPart = new TrackPart&#40;1&#41;;
					tmpPart->setPosition&#40;j*BLOCKSIZE, 0.0f, i*BLOCKSIZE&#41;;
					tmpPart->setObject&#40;&trackpartStraight2&#41;;
					tmpPart->setWaypoints&#40;1&#41;;
					TrackLine->push_back&#40;tmpPart&#41;;
					break;
				case '2'&#58;
					//straight2.addLocation&#40;i*BLOCKSIZE, 0.0f, j*BLOCKSIZE, i, j&#41;;
					tmpPart = new TrackPart&#40;2&#41;;
					tmpPart->setPosition&#40;j*BLOCKSIZE, 0.0f, i*BLOCKSIZE&#41;;
					tmpPart->setObject&#40;&trackpartStraight1&#41;;
					tmpPart->setWaypoints&#40;2&#41;;
					TrackLine->push_back&#40;tmpPart&#41;;
					break;
				case '3'&#58;
					//corner1.addLocation&#40;i*BLOCKSIZE, 0.0f, j*BLOCKSIZE, i, j&#41;;
					tmpPart = new TrackPart&#40;3&#41;;
					tmpPart->setPosition&#40;j*BLOCKSIZE, 0.0f, i*BLOCKSIZE&#41;;
					tmpPart->setObject&#40;&trackpartCorner4&#41;;
					tmpPart->setWaypoints&#40;3&#41;;
					TrackLine->push_back&#40;tmpPart&#41;;
					break;
				case '4'&#58;
					//corner2.addLocation&#40;i*BLOCKSIZE, 0.0f, j*BLOCKSIZE, i, j&#41;;
					tmpPart = new TrackPart&#40;4&#41;;
					tmpPart->setPosition&#40;j*BLOCKSIZE, 0.0f, i*BLOCKSIZE&#41;;
					tmpPart->setObject&#40;&trackpartCorner1&#41;;
					tmpPart->setWaypoints&#40;4&#41;;
					TrackLine->push_back&#40;tmpPart&#41;;
					break;
				case '5'&#58;
					//corner3.addLocation&#40;i*BLOCKSIZE, 0.0f, j*BLOCKSIZE, i, j&#41;;
					tmpPart = new TrackPart&#40;5&#41;;
					tmpPart->setPosition&#40;j*BLOCKSIZE, 0.0f, i*BLOCKSIZE&#41;;
					tmpPart->setObject&#40;&trackpartCorner2&#41;;
					tmpPart->setWaypoints&#40;5&#41;;
					TrackLine->push_back&#40;tmpPart&#41;;
					break;
				case '6'&#58;
					//corner4.addLocation&#40;i*BLOCKSIZE, 0.0f, j*BLOCKSIZE, i, j&#41;;
					tmpPart = new TrackPart&#40;6&#41;;
					tmpPart->setPosition&#40;j*BLOCKSIZE, 0.0f, i*BLOCKSIZE&#41;;
					tmpPart->setObject&#40;&trackpartCorner3&#41;;
					tmpPart->setWaypoints&#40;6&#41;;
					TrackLine->push_back&#40;tmpPart&#41;;
					break;
				case ' '&#58;
					TrackLine->push_back&#40;NULL&#41;;
					break;
				&#125;
			&#125;
			//save the array in the 2d array
			Track->push_back&#40;TrackLine&#41;;
		&#125;

		// done so close
		fclose&#40;f&#41;;
	&#125;
	else &#123;
		DebugTools&#58;&#58;PrintTextLoop&#40;"Error reading the race \n"&#41;;
	&#125;
	return 0;
&#125;
maybe there is something not correct ?
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

try to break your code into small parts and checks each part l.. part by part.. displaying some variable status etc... ... and put some pspdebugprintf to display the debug on the PSP

and for reading files ...

Code: Select all

sscanf&#40;ReadBuffer,"y=%d",&y&#41;;

should be better (for example). because in your case, if "y=" is set before the "x=" in the file ... your parsing will be wrong ...
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

well the problem is that it output this line:
DebugTools::PrintTextLoop("Error reading the race \n");
which means the fopen returns NULL
I just don't know why that happens normally but in PSPlink not.
the sBuffer is filled in correctly.
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

very strange ... can you get the strlen of sBuffer and be sure that there is no '\n' or something else ? maybe there is a blank space before or after you "real" sBuffer ... the fopen method seems to be called perfectly ... so if you're sure that the file is at the correct place and sBuffer doesn't hidden any specific unwanted char .... i can only recommend you , if you are in C++, to use <string> lib (with std::ifstream for files) ...
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

well there is no \n because my debugger adds one and when it loop prints it there is now empty line which was the case with two \n

the length is 44 which is the exact total of character in sBuffer.

the only thing that comes to my mind is that the file is open or something :s
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Hmmm I have now set the path and filename hardcoded and both the old way i did and now with strings:

Code: Select all

std&#58;&#58;ifstream input;
	std&#58;&#58;string line, file;
	std&#58;&#58;string&#58;&#58;size_type	loc;
	file = "ms0&#58;/PSP/GAME150/RAZE/Races/C Circuit.rac";

	input.open&#40;file.c_str&#40;&#41;&#41;;

	getline&#40;input,line&#41;;
	DebugTools&#58;&#58;PrintTextLoop&#40;line.c_str&#40;&#41;&#41;;
	sscanf&#40;line.c_str&#40;&#41;,"version=%d",&version&#41;;
	
	input.close&#40;&#41;;
It does not show any line....

so this means that 1.) the path and filename is incorrect or 2.) the file is already opened.

well 1 I have hardcoded it and then it also does not work so it should be 2.
However I really do not know where I open the file and do not close it :s

it there a 3 ???????
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

does the same with a file at the root of the MS ? ...

seems very very strange ... hard reset your psp :D
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

well I open a lot of files previous to this, thats the strange thing even the same file.

If a file is already open what does the fopen?

is there a way to see if the file is open if you don'T have the filepointer structure ??
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

the only way of keep THIS file opened is to forget to close it ... is this file is opened before in your code ?

The psp doesn't open files itself "for fun" :Ptry maybe to recreate your race file .... copy/paste his content to a new file.
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

the only time it is opened is in that code i pasted in my post:

Code: Select all

bool MainMenu&#58;&#58;LoadLevelLayout&#40;&#41; &#123; 
   int x, y, i; 

   FILE *f; 

   char sBuffer&#91;256&#93;; 
   char ReadBuffer&#91;256&#93;; 

   sprintf&#40;sBuffer, "Races/%s", Races&#91;RaceItem&#93;&#41;; 

   for&#40;x=0;x<16;x++&#41; 
      for&#40;y=0;y<10;y++&#41; 
         trackLayout&#91;x&#93;&#91;y&#93; = 0; 


   if&#40;&#40;f = fopen&#40;sBuffer,"rb"&#41;&#41; != NULL&#41; &#123; 
      // parse the info. 
      // read version 
      for&#40;i = 0; i<7; i++&#41; 
         fgets&#40;ReadBuffer, 256, f&#41;; 
    
      // read the dimensions 
      fgets&#40;ReadBuffer, 256, f&#41;; 
      sscanf&#40;&#40;ReadBuffer+2&#41;,"%d",&x &#41;; 
      fgets&#40;ReadBuffer, 256, f&#41;; 
      sscanf&#40;&#40;ReadBuffer+2&#41;,"%d",&y &#41;; 

      if&#40;x>16&#41; &#123; fclose&#40;f&#41;; return false; &#125; 
      if&#40;y>10&#41; &#123; fclose&#40;f&#41;; return false; &#125; 
       
      for&#40;i=0;i<y;i++&#41;&#123; 
         fgets&#40;ReadBuffer, 256, f&#41;; 
         // readbuffer has now one row of the field. 
         for&#40;unsigned int j=0;j<strlen&#40;ReadBuffer&#41;-1;j++&#41;&#123; 
            //trackLayout&#91;j&#93;&#91;i&#93; = 1; 
            switch&#40;ReadBuffer&#91;j&#93;&#41;&#123; 
            case '1'&#58; 
               trackLayout&#91;j&#93;&#91;i&#93; = 1; 
               break; 
            case '2'&#58; 
               trackLayout&#91;j&#93;&#91;i&#93; = 2; 
               break; 
            case '3'&#58; 
               trackLayout&#91;j&#93;&#91;i&#93; = 3; 
               break; 
            case '4'&#58; 
               trackLayout&#91;j&#93;&#91;i&#93; = 4; 
               break; 
            case '5'&#58; 
               trackLayout&#91;j&#93;&#91;i&#93; = 5; 
               break; 
            case '6'&#58; 
               trackLayout&#91;j&#93;&#91;i&#93; = 6; 
               break; 
            default&#58; 
               trackLayout&#91;j&#93;&#91;i&#93; = 0; 
               break; 
            &#125; 
         &#125; 
         // 
      &#125; 

      // done so close 
      fclose&#40;f&#41;; 
   &#125; 
   return true; 

&#125;;
but to my knowledge i close it here fine.
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

instead of :

Code: Select all

FILE *f; 
try

Code: Select all

auto FILE *f;

declare your FILE ressource like this everywhere :)
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

that also does not work :(

I will check the paths and stuff again :s
MikeMax
Posts: 5
Joined: Thu Apr 05, 2007 8:32 pm

Post by MikeMax »

it seems that your problem is very strange as KoalaDB said ... good luck ...
MikeMax,
Lead developper
Vertex Origin Studios
www.VertexOrigin.net
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

Ghoti wrote:that also does not work :(

I will check the paths and stuff again :s

Yes check check check ... i don't see any other solution ... :(
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

well I now use:

Code: Select all

sprintf&#40;sBuffer, "ms0&#58;/a.rac"&#41;;
if&#40;&#40;f = fopen&#40;sBuffer,"rb"&#41;&#41; != NULL&#41; &#123;
...
&#125;
else&#123;
 debug out error message
&#125;
that is a file in the root; I never opened it before that moment and I still get the error message :s


EDIT:::::

I have changed the a.rac into the name of a file already in the root, ss.png and I can't open that one either...

it seems that at that moment I can't read anything from the memorystick or something is there some switch or something which I can have used by acident ??
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

well I have tried the third option, using the pspsceiopen function:

Code: Select all

int fdout = sceIoOpen&#40;"ms0&#58;/a.rac", PSP_O_WRONLY | PSP_O_CREAT | PSP_O_APPEND, 0777&#41;;
	if&#40;fdout < 0&#41;
	&#123;
		char s&#91;200&#93;;
		sprintf&#40;s, "Openen is niet gelukt. Err&#58; %d", fdout&#41;;
		DebugTools&#58;&#58;PrintTextLoop&#40;s&#41;;
	&#125;


this also does not work but now it returns some error value, maybe someone knows what the error value means?

Err = -2147418088
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Post by crazyc »

Ghoti wrote:Err = -2147418088
-2147418088 == 0x80010018
0x80010018 is the same as the 0x18 posix errno or

Code: Select all

EMFILE 24	/* Too many open files */
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Yes that old chestnut ;) Basically for what ever reason the memory stick driver is quite limited in the number of files it can open, however the psplink host driver can open far more. Cant remember off hand but it is something like 16 files vs 64 or so. I guess if I was that bothered I could add an emulation mode to the host driver like I do to enable case insensitivity but I doubt it is worthwhile :)
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

hmmm that not so good :s do you means 16 files open at one moment or you can't open more then 16 files even when you have closed them ? because at that moment there are not many files open... only that file actually.

so when I do not open all the other files it should be opened ?
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

By the way, after your "fopen" fails, you should always check "errno" to see the cause; it should have contained EMFILE in this case. If it doesn't, it's a bug and I can look into it. perror and strerror are also useful functions.
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

Well Tyranid you are my hero, it was exactly that, one of my classes opened a file but did not close it. Now it is closed and it does not crash anymore !!! :D

@jimparis: thank you for that info, did not know of the "errno" that was the reason why I used the native psp open function because that returned an error number. I will also look into perror and strerror, it sound helpfull! thanks
KoalaDB
Posts: 20
Joined: Mon Aug 06, 2007 8:32 pm

Post by KoalaDB »

Ghoti wrote:one of my classes opened a file but did not close it. Now it is closed and it does not crash anymore !!! :D

... The next time when it is asked to check ... please check :p
Post Reply