gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > stdio question

#7991 - Ninja - Mon Jun 30, 2003 4:06 am

Hi. I have just finished my sprite text support for my game, which uses the last part of the OAM memory, and counts backwards to set up the sprite characters. Basically, the format is similar to TextOut() on the Windows GDI, and the prototype is like this:

u16 SpriteText256(s16 x, s16 y, char* text, u8 length);

x and y are the coordinates to print the text,
text is the text,
length is the length of the character array inputted.
it returns the current sprite number when it finishes to ease the erasure process.

I was going to use a string instead of the last two input parameters, but the compiler didn't seem to think that was such a great idea. It wouldn't accept a string as a data type.

Anyways, the function works just fine. I can print all the text I want until I run out of sprites. :) The problem is that I had intended to print numbers like this:

Code:

#include <stdio.h>

int framesPerSec = getFPS();  //pseudo-code
int length;
char buffer[32];

length = sprintf(buffer, "Current FPS: %d", framePerSec);
SpriteText256(10, 10, buffer, length);


That's essentially how I would handle this problem in windows. The problem is that I get a million linking errors when trying to compile this code in GCC. It could be that my make file is in error perhaps, but I would have absolutely no clue how to fix that... I am not so good with make files.

I am using the GBA Appwizard in Visual Studio 6.

Any ideas on how I could get this working would be greatly appreciated.

#7995 - tepples - Mon Jun 30, 2003 4:54 am

For one thing, you should not use sprintf() on the GBA because not only will it bring in the entire printf library, but it'll also bring in the floating-point library (for handling %e %f %g). Instead, use siprintf(), which is identical except for not handling floating-point types.

Better yet, just use some sort of itoa() function (you may have to write your own).
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#8001 - wizardgsz - Mon Jun 30, 2003 10:39 am

Use your own libc/stdlib or use some Linux one.

libgba, GameBoy Advance Development Library (Chuck Mason), has libc from a Linux box.
_________________
http://www.geocities.com/gabriele_scibilia/

#8014 - Cyberman - Mon Jun 30, 2003 7:25 pm

Ninja wrote:
Code:

#include <stdio.h>

int framesPerSec = getFPS();  //pseudo-code
int length;
char buffer[32];

length = sprintf(buffer, "Current FPS: %d", framePerSec);
SpriteText256(10, 10, buffer, length);


That's essentially how I would handle this problem in windows. The problem is that I get a million linking errors when trying to compile this code in GCC. It could be that my make file is in error perhaps, but I would have absolutely no clue how to fix that... I am not so good with make files.

I am using the GBA Appwizard in Visual Studio 6.

Any ideas on how I could get this working would be greatly appreciated.


Hmmm I've tackled similar problems before ..
I would recomend a slightly different approach
Code:

void s_printf(s16 X, s16 Y, s16 W, const char *Fmt, ...)
{
    char    Buff[128];
    va_list ap;
    char   *Str;

    // first print the formated text
    va_start ( ap, Fmt);
    vsprintf(Buff, Fmt, ap);
    va_end(ap);
    // now convert the formated text to the proper tiles.
    Str = Buff;
    while(*Str)
    {
        s_putc(X, Y, *Str++);
        X += W;
    }
}


You need to be sure to include the headers for var arg lists in your program.

This allows you to use it just like sprintf the big difference being that it gives a bit more flexibility.

Code:

void s_putc(s16 X, s16 Y, char Char)
{
    // find next available sprite
    // associate character tile in VRAM to sprite
    // set up other sprite characteristics
    // display sprite
}


This has all sorts of interesting uses obviously I suppose if you are worried about loading the floating point library in you can look for visprintf? :)

Use:
Code:

s_printf(10, 10, PITCH, "'%8s' Loses %03d gumballs!", Person->Name, Loss);


You will need a way to recycle the sprites you allocated doing this I might point out too.

Cyb

#8024 - Ninja - Mon Jun 30, 2003 9:00 pm

Thanks guys. This is sort of depressing actually... I was hoping for a quick fix. :) I guess now I will have to go out and find some way of converting an int to a char on my own. I imagine that would be faster and more efficient. Bummer.

Anyone have any idea how to divide by 10 without using division? hehe...

Maybe I will look up that siprintf() function, and try to figure out how to compile it without the linker errors... I still have no clue why I am getting all the errors when I try to compile.

#8073 - Cyberman - Tue Jul 01, 2003 4:32 pm

Hmmm dividing by ten huh?
Division is tricky period.
Since you are dividing by a FIXED number you can reduce it to shifts and subtracts I suppose.
It's also important to remember signed versus unsigned division.

Try this to get a start on what to do.

Cyb

#8096 - Ninja - Wed Jul 02, 2003 12:32 am

Thanks for the tip Cyberman. :) When it comes time to optimize my code, I might just program something like that. I did get siprintf() to work though, and it's just a beautiful function. :)