Writing text to files - fixed

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

Moderators: cheriff, TyRaNiD

Post Reply
Marach
Posts: 31
Joined: Sun May 24, 2009 7:16 pm

Writing text to files - fixed

Post by Marach »

I'm writing my small homebrew game.
I decided to make it an "Asteroids" way: write some general functions and divide them to smaller ones until you're done. If I didn't implement one function I put a printf in them to know it has been called.

Here's the code:
main.cpp

Code: Select all

#include "app.h"

extern "C"
int main(int, char*[]){
	App app;
	app.init();
	app.run(app_splash);
	while(app.running){
		app.run(app_title);
		app.run(app_game);
	}
	app.run(app_exit);
	app.end();
	return 0;
}
app.cpp

Code: Select all

#include "app.h"

#include <cstdlib>
#include <SDL/SDL.h>
#include "appspec.h"

void App&#58;&#58;init&#40;&#41;&#123;
#ifdef DEBUG
	freopen&#40;"log.txt", "w", stdout&#41;;
	setbuf&#40;stdout, NULL&#41;;
	printf&#40;"App&#58;&#58;init\n"&#41;;
#endif
	SDL_Init&#40;SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK&#41;;
	atexit&#40;SDL_Quit&#41;;
	screen = SDL_SetVideoMode&#40;480, 272, 32, SDL_SWSURFACE&#41;;
	SDL_JoystickEventState&#40;SDL_ENABLE&#41;;
	SDL_JoystickOpen&#40;0&#41;;
	running = true;
&#125;

void App&#58;&#58;run&#40;app_state s&#41;&#123;
#ifdef DEBUG
	printf&#40;"App&#58;&#58;run&#40;"&#41;;
#endif
	switch&#40;s&#41;&#123;
		case app_splash&#58; stateSplash&#40;&#41;; break;
		case app_title&#58; stateTitle&#40;&#41;; break;
		case app_game&#58; stateGame&#40;&#41;; break;
		case app_exit&#58; stateExit&#40;&#41;; break;
		default&#58; error&#40;AT&#41;;
	&#125;
&#125;

void App&#58;&#58;stateSplash&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"splash&#41;\n"&#41;;
#endif
&#125;

void App&#58;&#58;stateTitle&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"title&#41;\n"&#41;;
#endif
&#125;

void App&#58;&#58;stateExit&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"exit&#41;\n"&#41;;
#endif
&#125;

void App&#58;&#58;end&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"App&#58;&#58;end\n"&#41;;
#endif
&#125;
game.h

Code: Select all

#ifndef GAME_H
#define GAME_H

#include "app.h"

struct Game &#123;
	bool running;
	//----------//
	void init&#40;&#41;;
	void initPlayer&#40;&#41;;
	void editor&#40;&#41;;
	void run&#40;&#41;;
&#125;;

#endif // GAME_H
game.cpp

Code: Select all

#include "game.h"

#include "app.h"

void App&#58;&#58;stateGame&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"game&#41;\n"&#41;;
#endif
	Game game;
	game.init&#40;&#41;; // TODO&#58; difficulty
	game.initPlayer&#40;&#41;;
	game.editor&#40;&#41;;
	while&#40;true&#41;&#123;
		game.run&#40;&#41;;
		if&#40;!game.running&#41; break;
		game.editor&#40;&#41;;
		if&#40;!game.running&#41; break;
	&#125;
	running = false;
&#125;

void Game&#58;&#58;init&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"Game&#58;&#58;init\n"&#41;;
#endif
	running = true;
&#125;

void Game&#58;&#58;initPlayer&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"Game&#58;&#58;initPlayer\n"&#41;;
#endif
&#125;

void Game&#58;&#58;editor&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"Game&#58;&#58;editor\n"&#41;;
#endif
&#125;

void Game&#58;&#58;run&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"Game&#58;&#58;run\n"&#41;;
#endif
	running = false;
&#125;
Output

Code: Select all

App&#58;&#58;init
App&#58;&#58;run&#40;splash&#41;
App&#58;&#58;run&#40;title&#41;
App&#58;&#58;run&#40;game&#41;
Game&#58;&#58;init
Game&#58;&#58;initPlayer
Game&#58;&#58;editor
If it matters, the output file has 98 bytes.

Makefile

Code: Select all

#SOME LINES
CFLAGS = -O2 -G0 -Wall -Wno-write-strings -DDEBUG
#SOME LINES
LIBS = -lSDLmain -lstdc++ -lc
#SOME LINES
Skipped files: appspec.h, appspec.cpp, app.h

What's wrong??? Why this program throws only half of an output??? I have no idea!
And, what makes the case even more complicated THE SAME CODE RUNS PERFECTLY on my Ubuntu g++!!! I begin to get tired with that PSPSDK pointless errors...

Output using G++ compiler on Ubuntu

Code: Select all

App&#58;&#58;init
App&#58;&#58;run&#40;splash&#41;
App&#58;&#58;run&#40;title&#41;
App&#58;&#58;run&#40;game&#41;
Game&#58;&#58;init
Game&#58;&#58;initPlayer
Game&#58;&#58;editor
Game&#58;&#58;run
App&#58;&#58;run&#40;exit&#41;
App&#58;&#58;end
And that's good.
Last edited by Marach on Fri Jun 05, 2009 9:51 pm, edited 1 time in total.
Why my REAL email adress has been BANNED???
marach5 (at) gmail (dot) com ???
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

can you post a .tar.gz of your code somewhere?
What you posted here isn't complete so it's hard to debug (we're missing app.h, at least).
Marach
Posts: 31
Joined: Sun May 24, 2009 7:16 pm

Post by Marach »

Ok, I will upload it to my website, but I'm posting from PSP right now :/

Ready! if you want it, here you are:
http://elementgame.boo.pl/downloads/pub ... ted.tar.gz
Why my REAL email adress has been BANNED???
marach5 (at) gmail (dot) com ???
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Printing to a file doesn't immediately write to the file. It goes to a cache. You need to flush the file, then wait a few seconds or the print may be lost. Ran into that myself once - the log file didn't go anywhere nearly as far as I could SEE the program going because the PSP would hang before the log data could actually be written to the log file.
Marach
Posts: 31
Joined: Sun May 24, 2009 7:16 pm

Post by Marach »

BUT.

I after opening the text file, I wrote

Code: Select all

setbuf&#40;stdout, NULL&#41;;
to prevent saving to cache first.

I even tried writing

Code: Select all

fflush&#40;NULL&#41;;
to flush the cache what already doesn't exist!
I will try waiting some seconds to save that data...

So the verdict is:
"File handling in PSP is crappy."
My Meritous port has some problem with files too! But saving is much more important than some debug info...

BTW, I managed to use MinPSPW in Ubuntu with Code::Blocks =D
Why my REAL email adress has been BANNED???
marach5 (at) gmail (dot) com ???
Marach
Posts: 31
Joined: Sun May 24, 2009 7:16 pm

Post by Marach »

OMG it's crazy...

I changed the final cleanup function:

Code: Select all

void App&#58;&#58;end&#40;&#41;&#123;
#ifdef DEBUG
	printf&#40;"App&#58;&#58;end\n"&#41;;
	fflush&#40;stdout&#41;;
	SDL_Delay&#40;5000&#41;;
#endif
&#125;
5000 = 5 seconds.

And guess what? File stays at 98 kB! It changes nothing. Any MORE ideas? xD

SORRY, it's 98 bytes :/
Why my REAL email adress has been BANNED???
marach5 (at) gmail (dot) com ???
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Uh, you misunderstood me - you need to fflush and wait after EVERY SINGLE WRITE. If it hangs, you lose the data right then... you'll never get to the cleanup code.
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

You probably need to actually close the file when you're done writing to it. fflush flushes application buffers but never guarantees that data will hit the media. I don't know whether the PSP kernel has a fsync() equivalent, but we know from experience that flushing, closing the file, and then waiting a short while should work.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Yeah, probably should for each debug print: reopen std for append, write, close, then wait a few secs.
Marach
Posts: 31
Joined: Sun May 24, 2009 7:16 pm

Post by Marach »

The app doesn't hang, it just peacefully quits to XMB. I will try to fflush every write and close the file AND wait 5 seconds, let's see if it works...
Why my REAL email adress has been BANNED???
marach5 (at) gmail (dot) com ???
Marach
Posts: 31
Joined: Sun May 24, 2009 7:16 pm

Post by Marach »

YAAAY xD
Thanks guys, it's working :)

I removed setbuf(NULL); and added fflush(stdout); after every printf, then added fclose(stdout); on cleanup function.
BUT that does not change the verdict that file handling in PSP is crappy.
Why my REAL email adress has been BANNED???
marach5 (at) gmail (dot) com ???
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

I think your expectations are wrong. The lib code seems to me to comply with the C standard.

Jim
Marach
Posts: 31
Joined: Sun May 24, 2009 7:16 pm

Post by Marach »

The same code is working on my PC and not working on my PSP, that clearly states that something is wrong with AT LEAST exit callbacks - it's not that hard to wait for saving to complete! My PC somehow does it...

EDIT: Only C++, cstdlib and SDL, of course.
Why my REAL email adress has been BANNED???
marach5 (at) gmail (dot) com ???
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

Both can be compliant and behave differently.
The fact your PC is line buffered and stuff appears on the console right away is irrelevant.

Jim
Marach
Posts: 31
Joined: Sun May 24, 2009 7:16 pm

Post by Marach »

Idon't write to console, I reopen stdout to write always to text file. It's shorter then that Fprintf.
Why my REAL email adress has been BANNED???
marach5 (at) gmail (dot) com ???
jsharrad
Posts: 100
Joined: Thu Oct 20, 2005 3:06 am

Post by jsharrad »

Your pc doesn't reboot every time a program ends, it needs to do some cleanup... the PSP does. If you want a "clean" exit, you have to code it yourself.
NoEffex
Posts: 106
Joined: Thu Nov 27, 2008 6:48 am

Post by NoEffex »

jsharrad wrote:Your pc doesn't reboot every time a program ends, it needs to do some cleanup... the PSP does. If you want a "clean" exit, you have to code it yourself.
If it's a plugin, you'd do

int status;
sceKernelStopUnloadSelfModule(0, NULL, &status, NULL);

However, if it's an eboot, then you'd be correct :).
Programming with:
Geany + Latest PSPSDK from svn
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

A lot of conversions to consoles like the PSP don't even bother cleaning up. Where the PC version calls a bunch of cleanup code, the console version just exits. Depending on the console, it may not even do that. My conversion of Wolf3D for the 32X doesn't even exit much less clean up. If you want to quit, you turn off the SEGA.
Post Reply