In a function

I have a program with all the SDL-stuff in one function (not
main()).
When I call it the first time, everything works file; the
surface is allocated, opened, images are loaded and
displayed. And everything appears to be closed and released
as supposed to.

But here things start to go wrong. If I break the loop in
main() with ctrl+c, the terminal locks. And if the
sdl_function() is called again, only a black screen is
opened, and then it freezes. Kill -9 is necessary…

A newer version of SDL gives a parachute instead og crash…

Am I forgetting something? Is there a specielt way,
functions should be exit?

Here’s the entire code. It is mainly copied from the HTML
manual:

#ifndef main_cpp
#define main_cpp

#include <iostream.h> // streams
#include <sys/stat.h> // file stats
#include <stdlib.h> // exit(), getenv()
#include <unistd.h> // sleep(), stat()
#include <math.h> // sin() …
#include <SDL.h> // Simple DirectMedia Layer library
#include <SDL_audio.h>
#include <SDL_error.h>
#include <SDL_timer.h>

#include “./flika.h” //
#include “./click.h” // Mouse clicks within area.

//
// Global variables.
//
SDL_Surface *screen,
*image_surface[IMAGES];

//
// Function prototypes.
//
int flika();
int filter_events(const SDL_Event *event);
void update_screen();
void display_image(int i);

int
main(int argc, char **argv)
{
bool newmail=0;

cout << "Flika started." << endl;


for(;;) {
	flika();
	sleep(5);
}


return 0;

}

int
flika()
{
SDL_Event event;
bool update = 0;

atexit(SDL_Quit);

if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
	cerr << "Error initiating video." << endl;
	exit(1);
}


SDL_WM_SetCaption("flika!", "flika");

SDL_SetEventFilter( filter_events );

for(int i=0; i<IMAGES; ++i) {
	cout << "Loading image [" << image_file[i] << "]: ";

	image_surface[i] = SDL_LoadBMP( image_file[i] );
	if( !image_surface[i] ) {
		cerr << "Error loading image!" << endl;
		exit(1);
	}

	cout << "Supergeil!" << endl;
}

screen = SDL_SetVideoMode(image_surface[0]->w, image_surface[0]->h, 16,
					SDL_SWSURFACE);
if( !screen ) {
	cerr << "Error initiating video mode." << endl;
	exit(1);
}
cout << "Set " << (int) screen->w << "x" << (int) screen->h
     << " at " << (int) screen->format->BitsPerPixel << " bpp." << endl;


update_screen();

    while ( SDL_WaitEvent(&event) >= 0 ) {
            switch (event.type) {

                    case SDL_ACTIVEEVENT: {
                            if ( event.active.state & SDL_APPACTIVE ) {
                                    if ( event.active.gain ) {
                                            cout << "activated" << endl;
                                    } else {
                                            cout << "iconified" << endl;
                                    }
                            }
                    }
		break;
                                    
                    case SDL_MOUSEBUTTONDOWN: {
			if( event.button.button == 3 ) {
				cout << "trickster!" << endl;
			}

			if( within_rectangle( (int) event.button.x,
			(int) event.button.y, 125, 90, 72, 24) ) {
				image_flags.mouth = !image_flags.mouth;
				update = 1;
			}

			if( within_rectangle( (int) event.button.x,
			(int) event.button.y, 143, 80, 40, 8) ) {
				for(int i=0; i<4; ++i) {
					image_flags.eyes
						= !image_flags.eyes;
					update_screen();
					SDL_Delay(200);
				}
			}

			if( within_circle( (int) event.button.x,
			(int) event.button.y, 212, 71, 20) ) {
				image_flags.fuck = !image_flags.fuck;
				update = 1;
			}

			if(update) update_screen();
			update = 0;
		}
		break;

// case SDL_MOUSEBUTTONUP: {
// }
// break;

                    case SDL_QUIT: {
                            cout << "Leaving.." << endl;
			for(int i=0; i<IMAGES; ++i) {
				cout << "Freeing surface ["
				     << image_file[i] << "].." << endl;
				SDL_FreeSurface(image_surface[i]);
			}
			cout << "Calling SDL_Quit()..";
			SDL_Quit();
			cout << "done." << endl;
                            return 0;
                    }
		break;
            }
    }
    /* This should never happen */
cout << "SDL_WaitEvent error: " << (int) SDL_GetError() << "." << endl;



cout << "HMM..." << endl;

return 0;

}

//
// Event filter
//
int
filter_events(const SDL_Event event)
{
if( event->type == SDL_MOUSEMOTION ) {
/

cout << “moved to (”
<< (int) event->motion.x << “;”
<< (int) event->motion.y << “).\n”;
*/
return 0;
}

    return 1;

}

//
// Update screen and all the images.
//
void
update_screen()
{
if( image_flags.background != image_flags_backup.background )
display_image(0);

if( image_flags.mouth != image_flags_backup.mouth ) {
	if(image_flags.mouth)
		display_image(1);
	else
		display_image(2);
}

if( image_flags.eyes != image_flags_backup.eyes ) {
	if(image_flags.eyes)
		display_image(3);
	else
		display_image(4);
}

if( image_flags.fuck != image_flags_backup.fuck ) {
	if(image_flags.fuck)
		display_image(5);
	else
		display_image(6);
}


image_flags_backup = image_flags;

}

//
// Display individual images.
//
void
display_image(int i)
{
SDL_Rect area;

    area.x = image_offset[i].x;
    area.y = image_offset[i].y;
    area.w = image_surface[i]->w;
    area.h = image_surface[i]->h;
    SDL_BlitSurface(image_surface[i], NULL, screen, &area);
    SDL_UpdateRects(screen, 1, &area);

}

#endif

-Stephan /
/ tisprut productions [tm]

        http://wiktor.dk/~stephan

I haven’t read the whole code, but you’ve called
atexit(SDL_Quit)
Then inside the function you’re calling SDL_Quit. So when you ^C out you’re
possibly calling SDL_Quit twice?
-Dave

“Dave Ashley (SDL list)” wrote:

I haven’t read the whole code, but you’ve called
atexit(SDL_Quit)
Then inside the function you’re calling SDL_Quit. So when you ^C out you’re
possibly calling SDL_Quit twice?
-Dave

It’s a bug in SDL… should be fixed in the next release.–
-Sam Lantinga, Lead Programmer, Loki Entertainment Software
-------------- next part --------------
Index: SDL_video.c

RCS file: /cvs/SDL/src/video/SDL_video.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
— SDL_video.c 1999/10/21 15:56:34 1.1
+++ SDL_video.c 1999/10/26 20:06:58 1.2
@@ -668,9 +668,11 @@
/* Clean up miscellaneous memory */
if ( wm_title != NULL ) {
free(wm_title);

  •   wm_title=NULL;
    

    }
    if ( wm_icon != NULL ) {
    free(wm_icon);

  •   wm_icon=NULL;
    

    }

    /* Finish cleaning up video subsystem */

“Dave Ashley (SDL list)” wrote:

I haven’t read the whole code, but you’ve called
atexit(SDL_Quit)
Then inside the function you’re calling SDL_Quit. So when you ^C out you’re
possibly calling SDL_Quit twice?
-Dave

It’s a bug in SDL… should be fixed in the next release.

Yay! =)On Tue, 26 Oct 1999, Sam Lantinga wrote:

-Stephan /
/ tisprut productions [tm]

        http://wiktor.dk/~stephan

Stephan Dragehjerte once said:

It’s a bug in SDL… should be fixed in the next release.

Yay! =)

When is the next release coming? Mise desperate! =)–

-Stephan /
/ tisprut productions [tm]

        http://wiktor.dk/~stephan