Converting SDL code from C++ to C

Started by
3 comments, last by kaktusas2598 11 years, 5 months ago
Hello all I am refreshing my kwoledge on SDL, using Lazy foo tutorials, and I need to code all my projects for SDL in C. So I convert all his C++ code to C. Bet I have serious issue in 12th tutorial about timing. Here is my code:
[source lang="cpp"]#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

SDL_Surface* message = NULL;
SDL_Surface* seconds = NULL;
SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;
SDL_Event event;

TTF_Font* font = NULL;
SDL_Color textColor = {255,0,0};//white, same 0xff,0xff,0xff

SDL_Surface *load_image( char *filename )
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;
loadedImage = IMG_Load( filename );
if( loadedImage != NULL )
{
optimizedImage = SDL_DisplayFormat( loadedImage );
SDL_FreeSurface( loadedImage );
if (optimizedImage != NULL)
{
//map the color key
Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 0,0xFF,0xFF);
//sets all pixels of color R0, G 0xFF, B 0xFF to be tranparent
SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey);
}
}
return optimizedImage;
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface( source, NULL, destination, &offset );
}

int init(char * caption)
{
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return 0;
}
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
if( screen == NULL )
{
return 0;
}
//initiliaze SDL_ttf
if (TTF_Init() == -1)
{
return 0;
}
SDL_WM_SetCaption( caption, NULL );
return 1;
}
int load_files()
{
background = load_image("background.png");
//open the font
font = TTF_OpenFont("lazy.ttf",30);
if( background == NULL )
{
return 0;
}
if( font == NULL )
{
return 0;
}
return 1;
}
void clean_up()
{
SDL_FreeSurface( background );
SDL_FreeSurface( message );
TTF_CloseFont(font);

TTF_Quit();
SDL_Quit();
}

int main( int argc, char* args[] )
{
int quit = 0;//make sure program waits for quit

//the timer starting time
Uint32 start = 0;

//the timer start/stop flag
int running = 0;

if( init("Simple timer") == 0 )return 1;

if(load_files() == 0) return 1;

message = TTF_RenderText_Solid(font,"Press s to start/stop the timer", textColor);
if (message == 0) return 1;

//start the timer
start = SDL_GetTicks();

//main loop
while (!quit)//while user hasnt quit
{
//while there's event to handle!
while(SDL_PollEvent(&event))
{
//if user has Xed out
if(event.type == SDL_QUIT)
{
//quit the program
quit = 1;
}
else if(event.type == SDL_KEYDOWN)
{
if(event.key.keysym.sym == SDLK_s)
{
//if timer is running
if(running)
{
//stop the timer
running = 0;
start = 0;
}
else
{
//start the timer
running = 1;
start = SDL_GetTicks();
}
}
else if(event.key.keysym.sym == SDLK_ESCAPE)
{
quit = 1;
}
}
//rendering
apply_surface(0,0,background,screen);
apply_surface((SCREEN_WIDTH - message->w)/2,SCREEN_HEIGHT/2,message,screen);

//if the timer is running
if(running)
{
//timer: as a string
char* time = "Timer: ";
//current time as a string
char* current = 0;
//convert timers time to a string
itoa((SDL_GetTicks() - start), current, 10);
//adds time (Timer: ) + time in ms
strcat(time, current);
//renders the time surface
seconds = TTF_RenderText_Solid(font, time, textColor);
//apply the times surface
apply_surface((SCREEN_WIDTH - seconds->w)/2,50,seconds,screen);
SDL_FreeSurface(seconds);
}

//updating
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
}
}
clean_up();
return 0;
}
[/source]
It doesn't have any compile or link errors, I can launch it, surfaces loads, but when I press 's'(to start/stop timer) it suddenly quits. I don't have idea what the problem might be, but I think issue in my "C version" of converting SDL time to string (Lazy Foo used string streams to handle this). This is the code where I used some standart C functions for doing so:
[source lang="cpp"]//rendering
apply_surface(0,0,background,screen);
apply_surface((SCREEN_WIDTH - message->w)/2,SCREEN_HEIGHT/2,message,screen);

//if the timer is running
if(running)
{
//timer: as a string
char* time = "Timer: ";
//current time as a string
char* current = 0;
//convert timers time to a string
itoa((SDL_GetTicks() - start), current, 10);
//adds time (Timer: ) + time in ms
strcat(time, current);
//renders the time surface
seconds = TTF_RenderText_Solid(font, time, textColor);
//apply the times surface
apply_surface((SCREEN_WIDTH - seconds->w)/2,50,seconds,screen);
SDL_FreeSurface(seconds);
}[/source]

Deltron Zero and Automator.

Advertisement


//timer: as a string
char* time = "Timer: ";
/*...*/
strcat(time, current);



The length of "time" is fixed at 7. You can't concatenate anything to it.
Besides what ultramailman said...

char* current = 0;
//convert timers time to a string
itoa((SDL_GetTicks() - start), current, 10);


I am not sure what the semantics of you itoa function are (itoa is not a standard function), but you typically have to pass a pointer to a buffer big enough to hold the answer. If you pass 0, you are asking for trouble.

You don't seem to have a grasp of how to handle strings in C. Try to read up on it, because it's not easy to teach you about it in a forum post.

Why don't you want to use C++ anyway? C++ provides much cleaner ways to handle this type of thing.
Besides your C string issues, do you also realize your rendering code will only run while this is true: ?

while(SDL_PollEvent(&event))

since all the rendering is done within that loop (meaning, it only renders when it gets an event, typically an input event).

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

You are right guys, it was silly mistake, now it works, thanks for your assistance :)

Deltron Zero and Automator.

This topic is closed to new replies.

Advertisement