Пример #1
0
void carEngineSoundEffect(int chan, void *stream, int len, void *udata)
{
	CCar *car = (CCar *)udata;

	float f;
	unsigned int i, j, k;
	Sint16 *ip, *ip2;
	SOUNDT ces = car->getcarEngineSound();

#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("carEngineSoundEffect of %i\n",chan);
#endif


	if (car->get_state()!=2) {
		// state = 2 is when the car has crashed, thus we don't have to play the engine:

		// "f" is the factor at which we are modifying the pitch of the engine sample
		// if "f=2", the sound will be with twice the pitch of the original engine sample.
		// the formula weare using is: f = ((rpm-2000)/2000)+0.5
		f = (car->get_rpm() - 2000.0F) / 2000.0F;

		if (f < 0)
			f = 0;

		f = 0.5F + f;

		ip = (Sint16 *)stream;
		ip2 = (Sint16 *)ces->abuf;

		// Fill the S_carengine_working with a pitch modified version of the engine sample (S_carengine)
		// Since the sample is stereo and 16bits, each sample is "4 bytes"
		// "j" is the index that moves over the S_carengine_working sound, 
		// and k = j*f is the index that moves over the S_carengine sound.
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("carengine_position of channel %i is %i  (f: %g)\n",chan,car->carengine_position,f);
#endif
		for (i = 0, j = 0;i < len;i += 4, j++) {
			k = car->carengine_position + (unsigned int)(j * f);

			while (k*4 >= ces->alen)
				k -= ces->alen / 4;

			// Stereo mixing: 
			ip[j*2] = ip2[k * 2];  // L 

			ip[j*2 + 1] = ip2[k * 2 + 1]; // R 
		} 
		car->carengine_position = k;
	} else {
		// When the car has crashed, just set the buffer to all 0:

		ip = (Sint16 *)stream;
		for (i = 0, j = 0;i < len;i += 4, j++) {
			ip[j*2]=0;
			ip[j*2+1]=0;
		}
		car->carengine_position = 0;
	} // if
}
Пример #2
0
void finalization()
{
#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Finalizing SDL\n");
#endif

	if (network) {
		SDLNet_Quit();
	} 

	delete rg;

	rg = 0;

	free_auxiliar_menu_surfaces();

	if (sound)
		Sound_release();
		
	IMG_Quit();
	
#ifdef HAVE_GLES
	EGL_Close();
#endif
	SDL_Quit();

#ifdef F1SPIRIT_DEBUG_MESSAGES

	output_debug_message("SDL finalized\n");

#endif

} /* finalization */
Пример #3
0
Mix_Music *Sound_create_stream(char *file)
{
	int n_ext = 6;
	char *ext[6] = {".ogg", ".wav", ".mp3", ".OGG", ".WAV", ".MP3"};
	char name[256];
	int i;

	if (sound_enabled) {
		for (i = 0;i < n_ext;i++) {
			strcpy(name, file);
			strcat(name, ext[i]);

			if (file_check(name))
				return Mix_LoadMUS(name);
		} 

#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("ERROR in Sound_create_stream(): Could not load sound file: %s.(wav|ogg|mp3)\n", file);

#endif

		exit(1);
	} else {
		return 0;
	} 
} /* Sound_create_stream */
Пример #4
0
/* a check to see if file is readable and greater than zero */
int file_check(char *fname)
{
	FILE *fp;

	if ((fp=fopen(fname,"rb"))!=NULL) {
		if (fseek(fp,0L, SEEK_END)==0 && ftell(fp)>0) {
  			fclose(fp);
			return true;
		} // if 
		/* either the file could not be read (==-1) or size was zero (==0) */ 
#ifdef __DEBUG_MESSAGES
		output_debug_message("ERROR in file_check(): the file %s is corrupted.\n", fname);
#endif		
		fclose(fp);
		exit(1);
	} // if 
	return false;
} /* file_check */ 
Пример #5
0
int Resume_playback(int nc,int nrc)
{
//    char SoundcardName[256];
	int audio_rate = 44100;
	int audio_channels = 2;
	int audio_bufsize = AUDIO_BUFFER;
	Uint16 audio_format = AUDIO_S16;
	SDL_version compile_version;
	n_channels=8;

	sound_enabled=true;
#ifdef __DEBUG_MESSAGES
	output_debug_message("Initializing SDL_mixer.\n");
#endif
	if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_bufsize))  {
	  sound_enabled=false;
#ifdef __DEBUG_MESSAGES
  	  output_debug_message("Unable to open audio: %s\n", Mix_GetError());
  	  output_debug_message("Running the game without audio.\n");
#endif
	  return -1;	
	} // if 

#ifndef __EMSCRIPTEN__
	Mix_QuerySpec (&audio_rate, &audio_format, &audio_channels);
#ifdef __DEBUG_MESSAGES
	output_debug_message("    opened %d Hz %d bit %s, %d bytes audio buffer\n",
						 audio_rate, audio_format & 0xFF,
						 audio_channels > 1 ? "stereo" : "mono", audio_bufsize);
#endif
#endif

	MIX_VERSION (&compile_version);
#ifdef __DEBUG_MESSAGES
	output_debug_message("    compiled with SDL_mixer version: %d.%d.%d\n",
						 compile_version.major,
						 compile_version.minor,
						 compile_version.patch);
	output_debug_message("    running with SDL_mixer version: %d.%d.%d\n",
						 Mix_Linked_Version()->major,
						 Mix_Linked_Version()->minor,
						 Mix_Linked_Version()->patch);
#endif

	if (nc>0) n_channels=Mix_AllocateChannels(nc);
	if (nrc>0) Mix_ReserveChannels(nrc);

	Sound_unpause_music();

	return n_channels;
} /* Resume_playback */ 
Пример #6
0
SDL_Surface *initialization(int flags)
{
	const SDL_VideoInfo* info = 0;
	int bpp = 0;
	SDL_Surface *screen;

	rg = new TRanrotBGenerator(0);

#ifdef F1SPIRIT_DEBUG_MESSAGES

	output_debug_message("Initializing SDL\n");
#endif

	if (SDL_Init(SDL_INIT_VIDEO | (sound ? SDL_INIT_AUDIO : 0) | SDL_INIT_JOYSTICK | SDL_INIT_EVENTTHREAD) < 0) {
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("Video initialization failed: %s\n", SDL_GetError());
#endif

		return 0;
	} 

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("SDL initialized\n");

#endif

	info = SDL_GetVideoInfo();

	if (!info) {
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("Video query failed: %s\n", SDL_GetError());
#endif

		return 0;
	} 

	if (fullscreen) {
		bpp = COLOUR_DEPTH;
	} else {
		bpp = info->vfmt->BitsPerPixel;
	}

	desktopW = info->current_w;
	desktopH = info->current_h;
#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Setting OpenGL attributes\n");

#endif
#ifndef HAVE_GLES
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
#endif
#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("OpenGL attributes set\n");

#endif

#ifdef F1SPIRIT_DEBUG_MESSAGES

	output_debug_message("Initializing video mode\n");

#endif
#ifdef HAVE_GLES
	fullscreen = true;
	flags = SDL_FULLSCREEN;
#else
	flags = SDL_OPENGL | flags;
#endif
	screen = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, bpp, flags);

	if (screen == 0) {
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("Video mode set failed: %s\n", SDL_GetError());
#endif

		return 0;
	} 
#ifdef HAVE_GLES
	EGL_Open((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
#endif

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Video mode initialized\n");

#endif

	calcMinMax((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);

	SDL_WM_SetCaption(application_name, 0);

	SDL_WM_SetIcon(SDL_LoadBMP("graphics/f1sicon.bmp"), NULL);

	SDL_ShowCursor(SDL_DISABLE);

	if (sound) {
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("Initializing Audio\n");
#endif

		N_SFX_CHANNELS = Sound_initialization(N_SFX_CHANNELS, 0);

#ifdef F1SPIRIT_DEBUG_MESSAGES

		output_debug_message("Audio initialized\n");
#endif

	} 

	// Network:
#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Initializing SDL_net...\n");

#endif

	if (SDLNet_Init() == -1) {
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("Error initializing SDL_net: %s.\n", SDLNet_GetError());
#endif

		network = false;
	} else {
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("SDL_net initialized.\n");
#endif

		network = true;
	} 

	SDL_EnableUNICODE(1);

	glGetIntegerv(GL_STENCIL_BITS, &g_stencil_bits);

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("OpenGL stencil buffer bits: %i\n", g_stencil_bits);

#endif


	return screen;
} /* initialization */
Пример #7
0
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow)
{
#else
int main(int argc, char** argv) {
#endif

	SDL_Surface *screen_sfc;
	F1SpiritApp *game;
	KEYBOARDSTATE *k;

	int time, act_time;
	SDL_Event event;
	bool quit = false;
	bool need_to_redraw = true;

#ifdef F1SPIRIT_DEBUG_MESSAGES

	output_debug_message("Application started\n");
#endif
#ifdef HAVE_GLES
	fullscreen = true;
#endif
	screen_sfc = initialization((fullscreen ? SDL_FULLSCREEN : 0));

	if (screen_sfc == 0)
		return 0;

	k = new KEYBOARDSTATE();

	game = new F1SpiritApp();

	#if 0//ndef HAVE_GLES
	// why recreating the context ???
	if (fullscreen) {
	#ifdef HAVE_GLES
		EGL_Close();
		screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, (fullscreen ? SDL_FULLSCREEN : 0));
		EGL_Open((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
	#else
		screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
	#endif
		SDL_WM_SetCaption(application_name, 0);
		SDL_ShowCursor(SDL_DISABLE);
		reload_textures++;

	#ifndef HAVE_GLES
		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	#endif
	} 
	#endif

	time = init_time = SDL_GetTicks();
	
	IMG_Init(IMG_INIT_JPG|IMG_INIT_PNG);

	while (!quit) {
		while ( SDL_PollEvent( &event ) ) {
			switch ( event.type ) {
					/* Keyboard event */

				case SDL_KEYDOWN:
#ifdef __APPLE__

					if (event.key.keysym.sym == SDLK_q) {
						SDLMod modifiers;
						modifiers = SDL_GetModState();

						if ((modifiers &KMOD_META) != 0) {
							quit = true;
						}
					}

#else
					if (event.key.keysym.sym == SDLK_F12) {
						quit = true;
					} 

#endif
					if (event.key.keysym.sym == SDLK_F10) {
						game->save_configuration("f1spirit.cfg");
						game->load_configuration("f1spirit.cfg");
					} 

#ifdef _WIN32
					if (event.key.keysym.sym == SDLK_F4) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_ALT) != 0)
							quit = true;
					} 

#endif
#ifdef __APPLE__
					if (event.key.keysym.sym == SDLK_f) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_META) != 0) {
							/* Toggle FULLSCREEN mode: */
							if (fullscreen)
								fullscreen = false;
							else
								fullscreen = true;

							screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));

							calcMinMax((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);

							SDL_WM_SetCaption(application_name, 0);

							SDL_ShowCursor(SDL_DISABLE);

							reload_textures++;

							SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);

							SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);

							SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);

							SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
						}
					}

#else
					if (event.key.keysym.sym == SDLK_RETURN) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_ALT) != 0) {
							/* Toggle FULLSCREEN mode: */
							if (fullscreen)
								fullscreen = false;
							else
								fullscreen = true;
							#ifndef HAVE_GLES

							#ifdef HAVE_GLES
							EGL_Close();
							screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
							EGL_Open((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
							#else
							screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
							#endif

							calcMinMax((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
							
							SDL_WM_SetCaption(application_name, 0);

							SDL_ShowCursor(SDL_DISABLE);

							reload_textures++;

							#ifndef HAVE_GLES
							SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
							SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
							#endif
							#endif
						}
					}

#endif

					if (event.key.keysym.sym == SDLK_f) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_ALT) != 0) {
							/* toggle FPS mode: */
							if (show_fps)
								show_fps = false;
							else
								show_fps = true;
						} 
					} 

					/* Keyboard event */
					SDL_keysym *ks;

					ks = new SDL_keysym();

					*ks = event.key.keysym;

					k->keyevents.Add(ks);

					break;

					/* SDL_QUIT event (window close) */

				case SDL_QUIT:
					quit = true;

					break;
			} 
		} 

		act_time = SDL_GetTicks();

		if (act_time - time >= REDRAWING_PERIOD) 
		{
			int max_frame_step = 10;
			/*
			   frames_per_sec_tmp+=1;
			   if ((act_time-init_time)>=1000) {
			    frames_per_sec=frames_per_sec_tmp;
			    frames_per_sec_tmp=0;
			    init_time=act_time;
			   } // if
			*/
			// On PANDORA, let's target 25 fps...
			int min_frame=1;
			#ifdef PANDORA
			min_frame=2;
			#endif

			do {
				time += REDRAWING_PERIOD;

				if ((act_time - time) > 10*REDRAWING_PERIOD)
					time = act_time;

				/* cycle */
				k->cycle();

				if (!game->cycle(k))
					quit = true;

				need_to_redraw = true;

				k->keyevents.Delete();

				act_time = SDL_GetTicks();

				max_frame_step--;
				min_frame--;
			} while (((act_time - time >= REDRAWING_PERIOD) && (max_frame_step > 0)) || (min_frame > 0));

		} 

		/* Redraw */
		if (need_to_redraw) {
			game->draw();
			need_to_redraw = false;
			frames_per_sec_tmp += 1;
		} 

		if ((act_time - init_time) >= 1000) {
			frames_per_sec = frames_per_sec_tmp;
			frames_per_sec_tmp = 0;
			init_time = act_time;
		} 

		#ifndef PANDORA
		SDL_Delay(1);
		#endif

	} 


	delete k;

	k = 0;

	delete game;

	game = 0;

	Stop_playback();

	finalization();

#ifdef F1SPIRIT_DEBUG_MESSAGES

	output_debug_message("Application finished\n");

	close_debug_messages();

#endif

	return 0;
} /* main */
Пример #8
0
int F1SpiritApp::gameoptions_cycle(KEYBOARDSTATE *k)
{
	if (state_cycle == 0) {

		menu_fading = -1;
		menu_fading_ctnt = MENU_CONSTANT;
		menu_current_menu = 5;

		/* ... */

	} 

	if (menu_fading == 0) {} else {
		if (menu_fading > 0)
			menu_fading_ctnt++;
		else
			menu_fading_ctnt--;

		if (menu_fading_ctnt <= 0 && menu_fading == -1) {
			menu_fading = 0;
		} 

		if (menu_fading_ctnt >= MENU_CONSTANT && menu_fading == 1) {
			menu_fading = 0;
			race_game->race_state = 3;
			race_game->race_state_timmer = 0;
			race_desired_action = 0;
			Sound_unpause_music();
			race_game->resumeSFX();
			race_game->rain_channel = 0;
			return APP_STATE_RACE;
		} 

		if (menu_fading_ctnt >= MENU_CONSTANT && menu_fading == 2) {
			menu_fading = 0;
			Sound_unpause_music();
			race_game->resumeSFX();
			race_game->rain_channel = 0;
			return APP_STATE_RACE;
		} 

		if (menu_fading_ctnt >= MENU_CONSTANT && menu_fading == 3) {
			menu_fading = 0;
			race_game->race_state = 3;
			race_game->race_state_timmer = 0;
			race_desired_action = 1;
			Sound_unpause_music();
			race_game->resumeSFX();
			race_game->rain_channel = 0;
			return APP_STATE_RACE;
		} 
	} 

	if (state_cycle == 0 || menu_state == MENU_CONSTANT*2 || menu_redefining_key || menu_force_rebuild_menu) {
		int browsing = 0;

		if (menu_options[1] != 0)
			browsing = 1;

		if (state_cycle != 0) {

#ifdef F1SPIRIT_DEBUG_MESSAGES
			output_debug_message("Executing gameoptions action: %i(%i)\n", menu_option_type[browsing][menu_selected[browsing]], menu_option_parameter[browsing][menu_selected[browsing]]);
#endif

			switch (menu_option_type[browsing][menu_selected[browsing]]) {

				case 0:  /* QUIT RACE: */
					menu_fading = 1;
					menu_fading_ctnt = 0;
					break;

				case 1:  /* MENU CHANGE: */
					menu_current_menu = menu_option_parameter[browsing][menu_selected[browsing]];

					if (menu_current_menu == 23) {
						menu_readme_start_y = 0;
						menu_readme_move_y = 0;
					} 

					break;

				case 7:  /* SET A KEY: */
					break;

				case 8:  /* SET A JOYSTICK: */
					menu_current_menu = menu_option_parameter[browsing][menu_selected[browsing]];

					{
						int i;
						FILE *fp;
						PlayerCCar *v;
						current_player->set_joystick(menu_selected[0] - 7, menu_selected[1] - 1);
						i = menu_selected[0] - 7;
						v = race_game->player_cars[i];

						if (menu_selected[1] - 1 == -1) {
							v->up = current_player->get_key(i, 0);
							v->down = current_player->get_key(i, 1);
							v->left = current_player->get_key(i, 2);
							v->right = current_player->get_key(i, 3);
							v->accelerate = current_player->get_key(i, 4);
							v->brake = current_player->get_key(i, 5);
						} else {
							int j = menu_selected[1] - 1;
							v->up = k->joystick_0_pos + j * k->joystick_size + 2;
							v->down = k->joystick_0_pos + j * k->joystick_size + 3;
							v->left = k->joystick_0_pos + j * k->joystick_size;
							v->right = k->joystick_0_pos + j * k->joystick_size + 1;
							v->accelerate = k->joystick_0_pos + j * k->joystick_size + 4;
							v->brake = k->joystick_0_pos + j * k->joystick_size + 5;
						} 

						if (v->up < 0)
							v->up = 0;

						if (v->up >= k->k_size)
							v->up = 0;

						if (v->down < 0)
							v->down = 0;

						if (v->down >= k->k_size)
							v->down = 0;

						if (v->left < 0)
							v->left = 0;

						if (v->left >= k->k_size)
							v->left = 0;

						if (v->up < 0)
							v->up = 0;

						if (v->right >= k->k_size)
							v->right = 0;

						if (v->up < 0)
							v->up = 0;

						if (v->accelerate >= k->k_size)
							v->accelerate = 0;

						if (v->up < 0)
							v->up = 0;

						if (v->brake >= k->k_size)
							v->brake = 0;

						v = 0;

						fp = f1open(player_filename, "wb", USERDATA);

						if (fp != 0) {
							current_player->save(fp);
							fclose(fp);
						} 
					}

					break;

				case 11:  /* MENU CHANGE TO SUBMENU: */
					menu_current_menu = menu_option_parameter[browsing][menu_selected[browsing]];
					break;

				case 13: { /* CONTINUE RACE: */
						menu_selecting_player++;
						menu_fading = 2;
						menu_fading_ctnt = 0;
					}

					break;

				case 15: { /* CHANGE MUSIC VOLUME: */
					}

					break;

				case 16: { /* CHANGE SFX VOLUME: */
					}

					break;

				case 24: { /* RESTART RACE: */
						menu_selecting_player++;
						menu_fading = 3;
						menu_fading_ctnt = 0;

						// also stop music/sfx on restart
						Mix_HaltChannel(SFX_RAIN);
						Sound_pause_music();
					}

					break;

			} 
		} 

		delete []menu_title[0];

		menu_title[0] = 0;

		delete []menu_options[0];

		menu_options[0] = 0;

		delete []menu_title[1];

		menu_title[1] = 0;

		delete []menu_options[1];

		menu_options[1] = 0;

#ifdef F1SPIRIT_DEBUG_MESSAGES

		output_debug_message("Generating a new gameoptions menu: %i\n", menu_current_menu);

#endif

		switch (menu_current_menu) {

			case 5:

			case 6:

			case 7:

			case 8:

			case 19:

			case 20:

			case 22:

			case 24: {
					int i, l, pos;
					char *volumes[5] = {"NONE", "LOW ", "MED.", "HIGH", "MAX."};

					l = strlen("PLAYER 000\n") * current_player->get_nplayers() + strlen("CONTINUE\nQUIT\nRESTART\n\nMUSIC VOL: MAX.\nSFX VOL: MAX.\nPLAYER 1\nPLAYER 2\nPLAYER 3\nPLAYER 4\n") + 1;
					if (arcade)
						l = strlen("CONTINUE\nQUIT\n\nMUSIC VOL: MAX.\nSFX VOL: MAX.\nPLAYER 1\n")+1;
					menu_options[0] = new char[l];
					pos = 0;
					{
						int v1 = 0, v2 = 0;
						v1 = current_player->get_music_volume() / 32;
						v2 = current_player->get_sfx_volume() / 32;

						if (arcade)
							sprintf(menu_options[0], "CONTINUE\nQUIT\n\nMUSIC VOL: %s\nSFX VOL: %s\n", volumes[v1], volumes[v2]);
						else
							sprintf(menu_options[0], "CONTINUE\nQUIT\nRESTART\n\nMUSIC VOL: %s\nSFX VOL: %s\n", volumes[v1], volumes[v2]);
					}

					pos = strlen(menu_options[0]);

					if(arcade) {
						for (i = 0;i < 1;i++) {
							sprintf(menu_options[0] + pos, "PLAYER %i\n", i + 1);
							pos = strlen(menu_options[0]);
						} 
					} else 
					{
						for (i = 0;i < current_player->get_nplayers();i++) {
							sprintf(menu_options[0] + pos, "PLAYER %i\n", i + 1);
							pos = strlen(menu_options[0]);
						} 
					}

					menu_title[0] = new char[strlen("PAUSE") + 1];

					strcpy(menu_title[0], "PAUSE");

					if (arcade)
						menu_noptions[0] = 5+1;
					else
						menu_noptions[0] = current_player->get_nplayers() + 7;

					menu_option_type[0][0] = 13;
					menu_option_type[0][1] = 0;

					if (arcade) {
						menu_option_type[0][2] = -1;
						menu_option_type[0][3] = 15;
						menu_option_type[0][4] = 16;
						menu_option_type[0][5] = 11;
						menu_option_parameter[0][5] = 22;
					} else 
					{
						menu_option_type[0][2] = 24;
						menu_option_type[0][3] = -1;
						menu_option_type[0][4] = 15;
						menu_option_type[0][5] = 16;
						menu_option_type[0][6] = 11;
						menu_option_parameter[0][6] = 22;

						for (i = 0;i < current_player->get_nplayers();i++) {
							menu_option_type[0][i + 7] = 11;
							menu_option_parameter[0][i + 7] = 22;
						} 
					}

					menu_first_option[0] = 0;
				}

				if (menu_current_menu == 22) {
					menu_title[1] = 0;
					menu_options[1] = new char[strlen("KEYBOARD CFG.\nJOYSTICK/KEYS\nBACK\n") + 1];
					strcpy(menu_options[1], "KEYBOARD CFG.\nJOYSTICK/KEYS\nBACK\n");
					menu_noptions[1] = 3;
					menu_option_type[1][0] = 1;
					menu_option_type[1][1] = 1;
					menu_option_type[1][2] = 1;
					menu_option_parameter[1][0] = 7;
					menu_option_parameter[1][1] = 8;
					menu_option_parameter[1][2] = 5;
					menu_first_option[1] = 0;
				} 

				if (menu_current_menu == 7) {
					char tmp[256];
					menu_title[1] = 0;
					sprintf(tmp, "GEAR UP: %s\nGEAR DOWN: %s\nLEFT: %s\nRIGHT: %s\nACCEL.: %s\nBRAKE: %s\nBACK\n",
					        SDL_GetKeyName(SDLKey(current_player->get_key(menu_selected[0] - 6, 0))),
					        SDL_GetKeyName(SDLKey(current_player->get_key(menu_selected[0] - 6, 1))),
					        SDL_GetKeyName(SDLKey(current_player->get_key(menu_selected[0] - 6, 2))),
					        SDL_GetKeyName(SDLKey(current_player->get_key(menu_selected[0] - 6, 3))),
					        SDL_GetKeyName(SDLKey(current_player->get_key(menu_selected[0] - 6, 4))),
					        SDL_GetKeyName(SDLKey(current_player->get_key(menu_selected[0] - 6, 5))));
					//    strupr(tmp);
					menu_options[1] = new char[strlen(tmp) + 1];
					strcpy(menu_options[1], tmp);
					menu_noptions[1] = 7;
					menu_option_type[1][0] = 7;
					menu_option_type[1][1] = 7;
					menu_option_type[1][2] = 7;
					menu_option_type[1][3] = 7;
					menu_option_type[1][4] = 7;
					menu_option_type[1][5] = 7;
					menu_option_type[1][6] = 1;
					menu_option_parameter[1][0] = 7;
					menu_option_parameter[1][1] = 7;
					menu_option_parameter[1][2] = 7;
					menu_option_parameter[1][3] = 7;
					menu_option_parameter[1][4] = 7;
					menu_option_parameter[1][5] = 7;
					menu_option_parameter[1][6] = 6;
					menu_first_option[1] = 0;

					if (current_player->get_joystick(menu_selected[0]) != -1) {
						current_player->set_joystick(menu_selected[0], -1);
						{
							FILE *fp;

							fp = f1open(player_filename, "wb", USERDATA);

							if (fp != 0) {
								current_player->save(fp);
								fclose(fp);
							} 
						}
					} 
				} 

				if (menu_current_menu == 8) {
					int nj = SDL_NumJoysticks();
					int i, pos;

					menu_options[1] = new char[nj * strlen("JOYSTICK 000\n") + strlen("KEYBOARD\nBACK\n") + 1];
					pos = 0;
					sprintf(menu_options[1] + pos, "KEYBOARD\n");
					pos = strlen(menu_options[1]);

					for (i = 0;i < nj;i++) {
						sprintf(menu_options[1] + pos, "JOYSTICK %i\n", i);
						pos = strlen(menu_options[1]);
					} 

					sprintf(menu_options[1] + pos, "BACK\n");

					menu_noptions[1] = nj + 2;

					for (i = 0;i < nj + 1;i++) {
						menu_option_type[1][i] = 8;
						menu_option_parameter[1][i] = 6;
					} 

					menu_option_type[1][nj + 1] = 1;

					menu_option_parameter[1][nj + 1] = 6;

					menu_first_option[1] = 0;
				} 
		} 


		if ((menu_options[1] == 0 && menu_prev_nmenus != 2 && !menu_force_rebuild_menu)) {
			menu_selected[0] = 0;
			menu_selected_timmer[0] = 0;
		} 

		if (!menu_redefining_key && !menu_force_rebuild_menu)
			menu_selected[1] = 0;

		if (!menu_redefining_key && !menu_force_rebuild_menu)
			menu_selected_timmer[1] = 0;

		if (!menu_redefining_key && !menu_force_rebuild_menu)
			menu_state = 0;

		menu_force_rebuild_menu = false;
	} else {
		if (menu_fading == 0) {
			if (menu_state < MENU_CONSTANT)
				menu_state++;

			if (menu_state == MENU_CONSTANT) {
				menu_prev_nmenus = 0;

				if (menu_options[0] != 0)
					menu_prev_nmenus++;

				if (menu_options[1] != 0)
					menu_prev_nmenus++;
			} 

			if (menu_state > MENU_CONSTANT)
				menu_state++;
		} 
	} 


	if (menu_readme_move_y != 0) {
		menu_readme_start_y += menu_readme_move_y;

		if (menu_readme_move_y > 0)
			menu_readme_move_y--;

		if (menu_readme_move_y < 0)
			menu_readme_move_y++;

		if (menu_readme_start_y < 0)
			menu_readme_start_y = 0;
	} 

	if (menu_state == MENU_CONSTANT) {
		int browsing = 0;

		if (menu_options[1] != 0)
			browsing = 1;

		if (!menu_redefining_key) {
			if ((k->keyboard[SDLK_DOWN] && !k->old_keyboard[SDLK_DOWN]) ||
			        (k->keyboard[SDLK_RIGHT] && !k->old_keyboard[SDLK_RIGHT])) {
				if ((k->keyboard[SDLK_RIGHT] && !k->old_keyboard[SDLK_RIGHT]) &&
				        (menu_option_type[browsing][menu_selected[browsing]] == 15 ||
				         menu_option_type[browsing][menu_selected[browsing]] == 16)) {
					if (menu_option_type[browsing][menu_selected[browsing]] == 15) {
						int v = current_player->get_music_volume();

						if (v == 128)
							current_player->set_music_volume(0);

						if (v == 96)
							current_player->set_music_volume(128);

						if (v == 64)
							current_player->set_music_volume(96);

						if (v == 32)
							current_player->set_music_volume(64);

						if (v == 0)
							current_player->set_music_volume(32);
					} else {
						int v = current_player->get_sfx_volume();

						if (v == 128)
							current_player->set_sfx_volume(0);

						if (v == 96)
							current_player->set_sfx_volume(128);

						if (v == 64)
							current_player->set_sfx_volume(96);

						if (v == 32)
							current_player->set_sfx_volume(64);

						if (v == 0)
							current_player->set_sfx_volume(32);
					} 

					menu_force_rebuild_menu = true;

					Sound_play(S_menu_move, 128);

					{
						FILE *fp;

						fp = f1open(player_filename, "wb", USERDATA);

						if (fp != 0) {
							current_player->save(fp);
							fclose(fp);
						} 
					}
				} else {
					menu_selected[browsing]++;

					if (menu_option_type[browsing][menu_selected[browsing]] == -1)
						menu_selected[browsing]++;

					Sound_play(S_menu_move, 128);

					if (menu_selected[browsing] >= menu_noptions[browsing])
						menu_selected[browsing] -= menu_noptions[browsing];

					menu_selected_timmer[browsing] = 0;
				} 
			} 

			if ((k->keyboard[SDLK_UP] && !k->old_keyboard[SDLK_UP]) ||
			        (k->keyboard[SDLK_LEFT] && !k->old_keyboard[SDLK_LEFT])) {

				if ((k->keyboard[SDLK_LEFT] && !k->old_keyboard[SDLK_LEFT]) &&
				        (menu_option_type[browsing][menu_selected[browsing]] == 15 ||
				         menu_option_type[browsing][menu_selected[browsing]] == 16)) {
					if (menu_option_type[browsing][menu_selected[browsing]] == 15) {
						int v = current_player->get_music_volume();

						if (v == 128)
							current_player->set_music_volume(96);

						if (v == 96)
							current_player->set_music_volume(64);

						if (v == 64)
							current_player->set_music_volume(32);

						if (v == 32)
							current_player->set_music_volume(0);

						if (v == 0)
							current_player->set_music_volume(128);
					} else {
						int v = current_player->get_sfx_volume();

						if (v == 128)
							current_player->set_sfx_volume(96);

						if (v == 96)
							current_player->set_sfx_volume(64);

						if (v == 64)
							current_player->set_sfx_volume(32);

						if (v == 32)
							current_player->set_sfx_volume(0);

						if (v == 0)
							current_player->set_sfx_volume(128);
					} 

					menu_force_rebuild_menu = true;

					Sound_play(S_menu_move, 128);

					{
						FILE *fp;

						fp = f1open(player_filename, "wb", USERDATA);

						if (fp != 0) {
							current_player->save(fp);
							fclose(fp);
						} 
					}
				} else {
					menu_selected[browsing]--;

					if (menu_option_type[browsing][menu_selected[browsing]] == -1)
						menu_selected[browsing]--;

					Sound_play(S_menu_move, 128);

					if (menu_selected[browsing] < 0)
						menu_selected[browsing] += menu_noptions[browsing];

					menu_selected_timmer[browsing] = 0;
				} 
			} 

			if (k->keyboard[SDLK_ESCAPE] && !k->old_keyboard[SDLK_ESCAPE]) {
				if (menu_current_menu == 5)
					menu_selected[browsing] = 0;
				else
					menu_selected[browsing] = menu_noptions[browsing] - 1;

				Sound_play(S_menu_select, 128);

				menu_state++;
			} 

			if (menu_option_type[browsing][menu_selected[browsing]] != 2 &&
			        ((k->keyboard[SDLK_SPACE] && !k->old_keyboard[SDLK_SPACE])
#ifdef PANDORA
					||  (k->keyboard[SDLK_PAGEDOWN] && !k->old_keyboard[SDLK_PAGEDOWN])
#endif
				))
				{
				if (menu_option_type[browsing][menu_selected[browsing]] != 19 &&
				        menu_option_type[browsing][menu_selected[browsing]] != 20)
					Sound_play(S_menu_select, 128);

				if (menu_option_type[browsing][menu_selected[browsing]] == 7) {
					/* redefining a key: */
					menu_redefining_key = true;
				} else {
					if (menu_option_type[browsing][menu_selected[browsing]] == 15 ||
					        menu_option_type[browsing][menu_selected[browsing]] == 16 ||
					        menu_option_type[browsing][menu_selected[browsing]] == 19 ||
					        menu_option_type[browsing][menu_selected[browsing]] == 20) {
						if (menu_option_type[browsing][menu_selected[browsing]] == 15) {
							int v = current_player->get_music_volume();

							if (v == 128)
								current_player->set_music_volume(0);

							if (v == 96)
								current_player->set_music_volume(128);

							if (v == 64)
								current_player->set_music_volume(96);

							if (v == 32)
								current_player->set_music_volume(64);

							if (v == 0)
								current_player->set_music_volume(32);
						} 

						if (menu_option_type[browsing][menu_selected[browsing]] == 16) {
							int v = current_player->get_sfx_volume();

							if (v == 128)
								current_player->set_sfx_volume(0);

							if (v == 96)
								current_player->set_sfx_volume(128);

							if (v == 64)
								current_player->set_sfx_volume(96);

							if (v == 32)
								current_player->set_sfx_volume(64);

							if (v == 0)
								current_player->set_sfx_volume(32);
						} 

						menu_force_rebuild_menu = true;
					} else {
						menu_state++;
					} 
				} 
			} 


		} else {
			int i, np;
			np = menu_selected[0] - 6;
			PlayerCCar *v = race_game->player_cars[np];

			for (i = 0;i < SDLK_LAST;i++) {
				if (k->keyboard[i] && !k->old_keyboard[i]) {
					current_player->set_key(np, menu_selected[1], i);

					if (current_player->get_joystick(np) == -1) {
						v->up = current_player->get_key(np, 0);
						v->down = current_player->get_key(np, 1);
						v->left = current_player->get_key(np, 2);
						v->right = current_player->get_key(np, 3);
						v->accelerate = current_player->get_key(np, 4);
						v->brake = current_player->get_key(np, 5);
					} 

					if (v->up < 0)
						v->up = 0;

					if (v->up >= k->k_size)
						v->up = 0;

					if (v->down < 0)
						v->down = 0;

					if (v->down >= k->k_size)
						v->down = 0;

					if (v->left < 0)
						v->left = 0;

					if (v->left >= k->k_size)
						v->left = 0;

					if (v->up < 0)
						v->up = 0;

					if (v->right >= k->k_size)
						v->right = 0;

					if (v->up < 0)
						v->up = 0;

					if (v->accelerate >= k->k_size)
						v->accelerate = 0;

					if (v->up < 0)
						v->up = 0;

					if (v->brake >= k->k_size)
						v->brake = 0;

					v = 0;

					menu_redefining_key = false;

					menu_force_rebuild_menu = true;

					Sound_play(S_menu_select, 128);

					{
						FILE *fp;

						fp = f1open(player_filename, "wb", USERDATA);

						if (fp != 0) {
							current_player->save(fp);
							fclose(fp);
						} 
					}
				} 
			} 
		} 
	} 

	menu_selected_timmer[0]++;

	menu_selected_timmer[1]++;

	return APP_STATE_GAMEOPTIONS;
}