예제 #1
0
static void credits_show_common(RAIIPHYSFS_File file, const int have_bin_file)
{
	palette_array_t backdrop_palette;
	auto cr = make_unique<credits>();
	*cr = {};
	cr->file = std::move(file);
	cr->have_bin_file = have_bin_file;

	set_screen_mode(SCREEN_MENU);
#if defined(DXX_BUILD_DESCENT_II)
	gr_use_palette_table( "credits.256" );
#endif
	cr->backdrop.bm_data=NULL;

	const auto pcx_error = pcx_read_bitmap(STARS_BACKGROUND, cr->backdrop,backdrop_palette);
	if (pcx_error != PCX_ERROR_NONE)		{
		return;
	}

	songs_play_song( SONG_CREDITS, 1 );

	gr_remap_bitmap_good(cr->backdrop,backdrop_palette, -1, -1);

	gr_set_current_canvas(NULL);
	show_fullscr(cr->backdrop);
	gr_palette_load( gr_palette );

	key_flush();

	credits *pcr = cr.get();
	const auto wind = window_create(grd_curscreen->sc_canvas, 0, 0, SWIDTH, SHEIGHT, credits_handler, cr.release());
	if (!wind)
	{
		d_event event = { EVENT_WINDOW_CLOSE };
		credits_handler(NULL, event, pcr);
		return;
	}

	event_process_all();
}
예제 #2
0
파일: menu.c 프로젝트: Ringdingcoder/d1x
//returns flag, true means quit menu
void do_option ( int select) 
{
	switch (select) {
		case MENU_NEW_GAME:
			do_new_game_menu();
			break;
		case MENU_GAME:
			break;
		case MENU_DEMO_PLAY:
			{ 
				char demo_file[16];
				if (newmenu_get_filename( TXT_SELECT_DEMO, "*.dem", demo_file, 1 ))	{
					newdemo_start_playback(demo_file);
				}
			}
			break;
		case MENU_LOAD_GAME:
#ifdef SHAREWARE
			do_load_game_menu();
#else
			state_restore_all(0);	
#endif
			break;
		#ifdef EDITOR
		case MENU_EDITOR:
			Function_mode = FMODE_EDITOR;
			init_cockpit();
			break;
		#endif
		case MENU_VIEW_SCORES:
			gr_palette_fade_out( gr_palette,32,0 );
			scores_view(-1);
			break;
		#ifdef SHAREWARE
		case MENU_ORDER_INFO:
			show_order_form();
			break;
		#endif
		case MENU_QUIT:
			#ifdef EDITOR
			if (! SafetyCheck()) break;
			#endif
			gr_palette_fade_out( gr_palette,32,0);
			Function_mode = FMODE_EXIT;
			break;
		case MENU_NEW_PLAYER:
			RegisterPlayer();		//1 == allow escape out of menu
			break;

		case MENU_HELP:
			do_show_help();
			break;

                #ifndef RELEASE

		case MENU_PLAY_SONG:	{
				int i;
				char * m[MAX_SONGS];

				for (i=0;i<MAX_SONGS;i++) {
					m[i] = Songs[i].filename;
				}
				i = newmenu_listbox( "Select Song", MAX_SONGS, m, 1, NULL );

				if ( i > -1 )	{
					songs_play_song( i, 0 );
				}
			}
			break;
		case MENU_LOAD_LEVEL: {
			newmenu_item m;
			char text[10]="";
			int new_level_num;

			m.type=NM_TYPE_INPUT; m.text_len = 10; m.text = text;

			newmenu_do( NULL, "Enter level to load", 1, &m, NULL );

			new_level_num = atoi(m.text);

			if (new_level_num!=0 && new_level_num>=Last_secret_level && new_level_num<=Last_level)	{
				gr_palette_fade_out( gr_palette, 32, 0 );
				StartNewGame(new_level_num);
			}

			break;
		}
                #endif


		case MENU_START_NETGAME:
#ifdef NETWORK
//temp!
#ifndef SHAREWARE
			load_mission(0);
#endif
                        read_player_file();
			network_start_game();
#endif
			break;
		case MENU_JOIN_NETGAME:
//temp!
#ifdef NETWORK
#ifndef SHAREWARE
			load_mission(0);
#endif
                        read_player_file();
			network_join_game();
#endif
			break;
#ifdef NETWORK
		case MENU_IPX_MULTIPLAYER:
			do_ipx_multi_player_menu();
			break;
		case MENU_KALI_MULTIPLAYER:
			do_kali_multi_player_menu();
			break;
#ifdef SUPPORTS_NET_IP
		case MENU_IP_MULTIPLAYER:
			do_ip_multi_player_menu();
			break;
		case MENU_IP_SERV_CONNECT:
			do_ip_serv_connect_menu();
			break;
		case MENU_MANUAL_IP_JOIN:
			do_ip_manual_join_menu();
			break;
#endif
		case MENU_START_SERIAL:
			com_main_menu();
			break;
		case MENU_MULTIPLAYER:
			do_multi_player_menu();
			break;
#endif //NETWORK
		case MENU_CONFIG:
			do_options_menu();
			break;
		case MENU_SHOW_CREDITS:
			gr_palette_fade_out( gr_palette,32,0);
			credits_show();	
			break;
		default:
			Error("Unknown option %d in do_option",select);
			break;
        }

}
예제 #3
0
start_endlevel_sequence()
{
	int last_segnum,exit_side,tunnel_length;

	if (Newdemo_state == ND_STATE_RECORDING)		// stop demo recording
		Newdemo_state = ND_STATE_PAUSED;

	if (Newdemo_state == ND_STATE_PLAYBACK)		// don't do this if in playback mode
		return;

	if (Player_is_dead || ConsoleObject->flags&OF_SHOULD_BE_DEAD)
		return;				//don't start if dead!

	Players[Player_num].homing_object_dist = -F1_0; // Turn off homing sound.

	reset_rear_view();		//turn off rear view if set

	if (!endlevel_data_loaded) {

		#ifdef NETWORK
		if (Game_mode & GM_MULTI) {
			multi_send_endlevel_start(0);
			#ifdef NETWORK
			network_do_frame(1, 1);
			#endif
		}
		#endif

		gr_palette_fade_out(gr_palette, 32, 0);

		PlayerFinishedLevel(0);		//don't do special sequence
		return;
	}

	{
		int segnum,old_segnum,entry_side,i;

		//count segments in exit tunnel

		old_segnum = ConsoleObject->segnum;
		exit_side = find_exit_side(ConsoleObject);
		segnum = Segments[old_segnum].children[exit_side];
		tunnel_length = 0;
		do {
			entry_side = matt_find_connect_side(segnum,old_segnum);
			exit_side = Side_opposite[entry_side];
			old_segnum = segnum;
			segnum = Segments[segnum].children[exit_side];
			tunnel_length++;
		} while (segnum >= 0);

		if (segnum != -2) {
			PlayerFinishedLevel(0);		//don't do special sequence
			return;
		}

		last_segnum = old_segnum;

		//now pick transition segnum 1/3 of the way in

		old_segnum = ConsoleObject->segnum;
		exit_side = find_exit_side(ConsoleObject);
		segnum = Segments[old_segnum].children[exit_side];
		i=tunnel_length/3;
		while (i--) {
			entry_side = matt_find_connect_side(segnum,old_segnum);
			exit_side = Side_opposite[entry_side];
			old_segnum = segnum;
			segnum = Segments[segnum].children[exit_side];
		}
		transition_segnum = segnum;

	}

	Assert(last_segnum == exit_segnum);

	cockpit_mode_save = Cockpit_mode;

	#ifdef NETWORK
	if (Game_mode & GM_MULTI) {
		multi_send_endlevel_start(0);
		network_do_frame(1, 1);
	}
	#endif

	songs_play_song( SONG_ENDLEVEL, 0 );

	Endlevel_sequence = EL_FLYTHROUGH;

	ConsoleObject->movement_type = MT_NONE;			//movement handled by flythrough
	ConsoleObject->control_type = CT_NONE;

	Game_suspended |= SUSP_ROBOTS;          //robots don't move

	cur_fly_speed = desired_fly_speed = FLY_SPEED;

	start_endlevel_flythrough(0,ConsoleObject,cur_fly_speed);		//initialize

	HUD_init_message( TXT_EXIT_SEQUENCE );

	outside_mine = ext_expl_playing = 0;

	flash_scale = f1_0;

	//init_endlevel();

	mine_destroyed=0;

}
예제 #4
0
파일: gameseq.c 프로젝트: Mako88/DXX-Retro
//called when the player is starting a new level for normal game mode and restore state
void StartNewLevelSub(int level_num, int page_in_textures, int secret_flag)
{
	/*
	 * This flag is present for compatibility with D2X.  Set it to zero
	 * so the optimizer deletes all reference to it.
	 */
	secret_flag = 0;
	if (!(Game_mode & GM_MULTI)) {
		last_drawn_cockpit = -1;
	}

	if (Newdemo_state == ND_STATE_PAUSED)
		Newdemo_state = ND_STATE_RECORDING;

	if (Newdemo_state == ND_STATE_RECORDING) {
		newdemo_set_new_level(level_num);
		newdemo_record_start_frame(FrameTime );
	}

	LoadLevel(level_num, page_in_textures);

	Assert(Current_level_num == level_num);	//make sure level set right

	gameseq_init_network_players(); // Initialize the Players array for
											  // this level

#ifdef NETWORK
	if (Game_mode & GM_NETWORK)
	{
		if(multi_level_sync()) // After calling this, Player_num is set
		{
			songs_play_song( SONG_TITLE, 1 ); // level song already plays but we fail to start level...
			return;
		}
	}
#endif

	HUD_clear_messages();

	automap_clear_visited();

	init_player_stats_level(secret_flag);

	gr_use_palette_table( "palette.256" );
	gr_palette_load(gr_palette);

#ifndef SHAREWARE
#ifdef NETWORK
	if ((Game_mode & GM_MULTI_COOP) && Network_rejoined)
	{
		int i;
		for (i = 0; i < N_players; i++)
			Players[i].flags |= Netgame.player_flags[i];
	}
#endif
#endif

	Viewer = &Objects[Players[Player_num].objnum];

#ifdef NETWORK
	if (Game_mode & GM_MULTI)
	{
		multi_prep_level(); // Removes robots from level if necessary
	}
#endif

	gameseq_remove_unused_players();

	Game_suspended = 0;

	Control_center_destroyed = 0;

	init_cockpit();
	init_robots_for_level();
	init_ai_objects();
	init_morphs();
	init_all_matcens();
	reset_palette_add();

	if (!(Game_mode & GM_MULTI) && !cheats.enabled)
		set_highest_level(Current_level_num);

	reset_special_effects();

#ifdef OGL
	ogl_cache_level_textures();
#endif

#ifdef NETWORK
	if (Network_rejoined == 1)
	{
		Network_rejoined = 0;
		StartLevel(1);
	}
	else
#endif
		StartLevel(0);		// Note link to above if!

	copy_defaults_to_robot_all();
	init_controlcen_for_level();

	//	Say player can use FLASH cheat to mark path to exit.
	Last_level_path_created = -1;

	// Initialise for palette_restore()
	if (!((Game_mode & GM_MULTI) && (Newdemo_state != ND_STATE_PLAYBACK)))
		palette_save();

	if (!Game_wind)
		game();
}
예제 #5
0
//called to go to the next level (if there is one)
//if secret_flag is true, advance to secret level, else next normal one
//	Return true if game over.
int AdvanceLevel(int secret_flag)
{
	Fuelcen_control_center_destroyed = 0;

	#ifdef EDITOR
	if (PLAYING_BUILTIN_MISSION)
		return 0;		//not a real level
	#endif

	#ifdef NETWORK
	if (Game_mode & GM_MULTI)
	{
          int result;
		result = multi_endlevel(&secret_flag); // Wait for other players to reach this point
		if (result) // failed to sync
			return (Current_level_num == Last_level);
	}
	#endif

	if (Current_level_num == Last_level) {		//player has finished the game!
		
		Function_mode = FMODE_MENU;
		if ((Newdemo_state == ND_STATE_RECORDING) || (Newdemo_state == ND_STATE_PAUSED))
			newdemo_stop_recording();

		#ifndef SHAREWARE
		songs_play_song( SONG_ENDGAME, 0 );
		#endif

		do_end_game();
		return 1;

	} else {

		Next_level_num = Current_level_num+1;		//assume go to next normal level

		if (secret_flag) {			//go to secret level instead
			int i;

			for (i=0;i<-Last_secret_level;i++)
				if (Secret_level_table[i]==Current_level_num) {
					Next_level_num = -(i+1);
					break;
				}
			Assert(i<-Last_secret_level);		//couldn't find which secret level
		}

		if (Current_level_num < 0)	{			//on secret level, where to go?

			Assert(!secret_flag);				//shouldn't be going to secret level
			Assert(Current_level_num<=-1 && Current_level_num>=Last_secret_level);

			Next_level_num = Secret_level_table[(-Current_level_num)-1]+1;
		}

		StartNewLevel(Next_level_num);

	}

	return 0;
}
예제 #6
0
void show_titles(void)
{
#if defined(DXX_BUILD_DESCENT_I)
	songs_play_song(SONG_TITLE, 1);
#endif
	if (CGameArg.SysNoTitles)
		return;
#if defined(DXX_BUILD_DESCENT_I)

	show_first_found_title_screen(
		"macplay.pcx",	// Mac Shareware
		"mplaycd.pcx",	// Mac Registered
		"iplogo1.pcx"	// PC. Only down here because it's lowres ;-)
	);
	const bool resolution_at_least_640_480 = (SWIDTH >= 640 && SHEIGHT >= 480);
	auto &logo_hires_pcx = "logoh.pcx";
	auto &descent_hires_pcx = "descenth.pcx";
	show_title_screen((resolution_at_least_640_480 && PHYSFSX_exists(logo_hires_pcx, 1)) ? logo_hires_pcx : "logo.pcx", 1, 1);
	show_title_screen((resolution_at_least_640_480 && PHYSFSX_exists(descent_hires_pcx, 1)) ? descent_hires_pcx : "descent.pcx", 1, 1);
#elif defined(DXX_BUILD_DESCENT_II)
	int played=MOVIE_NOT_PLAYED;    //default is not played
	int song_playing = 0;

#define MOVIE_REQUIRED 1	//(!is_D2_OEM && !is_SHAREWARE && !is_MAC_SHARE)	// causes segfault

	const auto hiresmode = HIRESMODE;
	{       //show bundler screens
		played=MOVIE_NOT_PLAYED;        //default is not played

		played = PlayMovie(NULL, "pre_i.mve",0);

		if (!played) {
			char filename[12];
			strcpy(filename, hiresmode ? "pre_i1b.pcx" : "pre_i1.pcx");

			while (PHYSFSX_exists(filename,0))
			{
				show_title_screen( filename, 1, 0 );
				filename[5]++;
			}
		}
	}

	played = PlayMovie("intro.tex", "intro.mve",MOVIE_REQUIRED);

	if (played != MOVIE_NOT_PLAYED)
		intro_played = 1;
	else
	{                                               //didn't get intro movie, try titles

		played = PlayMovie(NULL, "titles.mve",MOVIE_REQUIRED);

		if (played == MOVIE_NOT_PLAYED)
		{
			con_puts(CON_DEBUG, "Playing title song...");
			songs_play_song( SONG_TITLE, 1);
			song_playing = 1;
			con_puts(CON_DEBUG, "Showing logo screens...");

			show_first_found_title_screen(
				hiresmode ? "iplogo1b.pcx" : "iplogo1.pcx", // OEM
				"iplogo1.pcx", // SHAREWARE
				"mplogo.pcx" // MAC SHAREWARE
				);
			show_first_found_title_screen(
				hiresmode ? "logob.pcx" : "logo.pcx", // OEM
				"logo.pcx", // SHAREWARE
				"plogo.pcx" // MAC SHAREWARE
				);
		}
	}

	{       //show bundler movie or screens
		played=MOVIE_NOT_PLAYED;        //default is not played

		//check if OEM movie exists, so we don't stop the music if it doesn't
		if (RAIIPHYSFS_File{PHYSFS_openRead("oem.mve")})
		{
			played = PlayMovie(NULL, "oem.mve",0);
			song_playing = 0;               //movie will kill sound
		}

		if (!played)
		{
			char filename[12];
			strcpy(filename, hiresmode ? "oem1b.pcx" : "oem1.pcx");
			while (PHYSFSX_exists(filename,0))
			{
				show_title_screen( filename, 1, 0 );
				filename[3]++;
			}
		}
	}

	if (!song_playing)
	{
		con_puts(CON_DEBUG, "Playing title song...");
		songs_play_song( SONG_TITLE, 1);
	}
	con_puts(CON_DEBUG, "Showing logo screen...");
	const auto filename = hiresmode ? "descentb.pcx" : "descent.pcx";
	if (PHYSFSX_exists(filename,1))
		show_title_screen(filename, 1, 1);
#endif
}
예제 #7
0
파일: songs.c 프로젝트: paud/d2x-xl
void songs_play_current_song( int repeat )
{
songs_play_song (gameStates.sound.nCurrentSong, repeat);
}
예제 #8
0
파일: credits.c 프로젝트: CDarrow/DXX-Retro
int credits_handler(window *wind, d_event *event, credits *cr)
{
	int j, l, y;
	char * tempp;
	
	switch (event->type)
	{
		case EVENT_KEY_COMMAND:
			if (!call_default_handler(event))	// if not print screen, debug etc
				window_close(wind);
			return 1;

		case EVENT_MOUSE_BUTTON_DOWN:
		case EVENT_MOUSE_BUTTON_UP:
			if (event_mouse_get_button(event) == MBTN_LEFT || event_mouse_get_button(event) == MBTN_RIGHT)
			{
				window_close(wind);
				return 1;
			}
			break;

		case EVENT_IDLE:
			if (cr->done>NUM_LINES)
			{
				window_close(wind);
				return 0;
			}
			break;
			
		case EVENT_WINDOW_DRAW:
			timer_delay(F1_0/28);
			
			if (cr->row == 0)
			{
				do {
					cr->buffer_line = (cr->buffer_line+1) % NUM_LINES;
				get_line:;
					if (PHYSFSX_fgets( cr->buffer[cr->buffer_line], 80, cr->file ))	{
						char *p;
						if (cr->have_bin_file) // is this a binary tbl file
							decode_text_line (cr->buffer[cr->buffer_line]);
						p = cr->buffer[cr->buffer_line];
						if (p[0] == ';')
							goto get_line;
						
						if (p[0] == '%')
						{
							if (p[1] == ALLOWED_CHAR)
							{
								int i = 0, len = strlen(p);
								for (i = 0; i < len; i++)
									p[i] = p[i+2];
							}
							else
								goto get_line;
						}
						
					} else	{
						//fseek( file, 0, SEEK_SET);
						cr->buffer[cr->buffer_line][0] = 0;
						cr->done++;
					}
				} while (cr->extra_inc--);
				cr->extra_inc = 0;
			}

			// cheap but effective: towards end of credits sequence, fade out the music volume
			if (cr->done >= NUM_LINES-16)
			{
				static int curvol = -10; 
				if (curvol == -10) 
					curvol = GameCfg.MusicVolume;
				if (curvol > (NUM_LINES-cr->done)/2)
				{
					curvol = (NUM_LINES-cr->done)/2;
					songs_set_volume(curvol);
				}
			}
			
			y = cr->first_line_offset - cr->row;
			show_fullscr(&cr->backdrop);
			for (j=0; j<NUM_LINES; j++ )	{
				char *s;
				
				l = (cr->buffer_line + j + 1 ) %  NUM_LINES;
				s = cr->buffer[l];
				
				if ( s[0] == '!' ) {
					s++;
				} else if ( s[0] == '$' )	{
					gr_set_curfont( HUGE_FONT );
					s++;
				} else if ( s[0] == '*' )	{
					gr_set_curfont( MEDIUM3_FONT );
					s++;
				} else
					gr_set_curfont( MEDIUM2_FONT );
				
				tempp = strchr( s, '\t' );
				if ( !tempp )	{
					// Wacky Fast Credits thing
					int w, h, aw;
					
					gr_get_string_size( s, &w, &h, &aw);
					gr_string( 0x8000, y, s );
				}
				y += ROW_SPACING;
			}
			
			cr->row += SHEIGHT/200;
			if (cr->row >= ROW_SPACING)
				cr->row = 0;
			break;

		case EVENT_WINDOW_CLOSE:
			gr_free_bitmap_data (&cr->backdrop);
			PHYSFS_close(cr->file);
			songs_set_volume(GameCfg.MusicVolume);
			songs_play_song( SONG_TITLE, 1 );
			d_free(cr);
			break;
			
		default:
			break;
	}
	
	return 0;
}
예제 #9
0
파일: credits.c 프로젝트: CDarrow/DXX-Retro
//if filename passed is NULL, show normal credits
void credits_show(char *credits_filename)
{
	credits *cr;
	window *wind;
	int i;
	int pcx_error;
	char * tempp;
	char filename[32];
	ubyte backdrop_palette[768];
	
	MALLOC(cr, credits, 1);
	if (!cr)
		return;
	
	cr->have_bin_file = 0;
	cr->buffer_line = 0;
	cr->first_line_offset = 0;
	cr->extra_inc = 0;
	cr->done = 0;
	cr->row = 0;

	// Clear out all tex buffer lines.
	for (i=0; i<NUM_LINES; i++ )
		cr->buffer[i][0] = 0;

	sprintf(filename, "%s", CREDITS_FILE);
	cr->have_bin_file = 0;
	if (credits_filename) {
		strcpy(filename,credits_filename);
		cr->have_bin_file = 1;
	}
	cr->file = PHYSFSX_openReadBuffered( filename );
	if (cr->file == NULL) {
		char nfile[32];
		
		if (credits_filename)
		{
			d_free(cr);
			return;		//ok to not find special filename
		}

		tempp = strchr(filename, '.');
		*tempp = '\0';
		sprintf(nfile, "%s.txb", filename);
		cr->file = PHYSFSX_openReadBuffered(nfile);
		if (cr->file == NULL)
			Error("Missing CREDITS.TEX and CREDITS.TXB file\n");
		cr->have_bin_file = 1;
	}

	set_screen_mode(SCREEN_MENU);
	gr_use_palette_table( "credits.256" );
	cr->backdrop.bm_data=NULL;

	pcx_error = pcx_read_bitmap(STARS_BACKGROUND,&cr->backdrop, BM_LINEAR,backdrop_palette);
	if (pcx_error != PCX_ERROR_NONE)		{
		PHYSFS_close(cr->file);
		d_free(cr);
		return;
	}

	songs_play_song( SONG_CREDITS, 1 );

	gr_remap_bitmap_good( &cr->backdrop,backdrop_palette, -1, -1 );

	gr_set_current_canvas(NULL);
	show_fullscr(&cr->backdrop);
	gr_palette_load( gr_palette );

	key_flush();

	wind = window_create(&grd_curscreen->sc_canvas, 0, 0, SWIDTH, SHEIGHT, (int (*)(window *, d_event *, void *))credits_handler, cr);
	if (!wind)
	{
		d_event event = { EVENT_WINDOW_CLOSE };
		credits_handler(NULL, &event, cr);
		return;
	}

	while (window_exists(wind))
		event_process();
}
예제 #10
0
void credits_show()
{
	int i, j, l, done;
	CFILE * file;
	char buffer[NUM_LINES][80];
	grs_bitmap backdrop;
	ubyte backdrop_palette[768];
	int pcx_error;
	int buffer_line = 0;
	fix last_time;
	fix time_delay = 4180 / f2fl(Scale_y);			// ~ F1_0 / 12.9
	int first_line_offset,extra_inc=0;
	int have_bin_file = 0;
	char * tempp;
	grs_point scale_pts[] = FULLSCREEN_SCALE_PTS;
	ubyte *fade_values = malloc(grd_curscreen->sc_h);

	for (i = 0; i < grd_curscreen->sc_h; ++i) {
		fade_values[i] = fade_values_200[(int)(((float)i / (float)grd_curscreen->sc_h) * 200)];
	}

	set_screen_mode(SCREEN_MENU);

	// Clear out all tex buffer lines.
	for (i=0; i<NUM_LINES; i++ ) buffer[i][0] = 0;

	have_bin_file = 0;
	file = cfopen( "credits.tex", "rb" );
	if (file == NULL) {
		file = cfopen("credits.txb", "rb");
		if (file == NULL)
			Error("Missing CREDITS.TEX and CREDITS.TXB file\n");
		have_bin_file = 1;
	}

	gr_use_palette_table( "credits.256" );
	header_font = gr_init_font( "font1-1.fnt" );
	title_font = gr_init_font( "font2-3.fnt" );
	names_font = gr_init_font( "font2-2.fnt" );
	backdrop.bm_data=NULL;
	pcx_error = pcx_read_bitmap("stars.pcx",&backdrop,BM_LINEAR,backdrop_palette);
	if (pcx_error != PCX_ERROR_NONE)		{
		cfclose(file);
		return;
	}

	songs_play_song( SONG_CREDITS, 0 );

	gr_remap_bitmap_good( &backdrop,backdrop_palette, -1, -1 );

	gr_set_current_canvas(NULL);
	scale_bitmap(&backdrop,scale_pts);
	gr_palette_fade_in( gr_palette, 32, 0 );
	vfx_set_palette_sub( gr_palette );

	//gr_clear_canvas(BM_XRGB(0,0,0));
	key_flush();
	last_time = timer_get_fixed_seconds();
	done = 0;
	first_line_offset = 0;
	while( 1 )	{
		int k;

		do {
			buffer_line = (buffer_line+1) % NUM_LINES;
			if (cfgets( buffer[buffer_line], 80, file ))	{
				char *p;
				if (have_bin_file) {				// is this a binary tbl file
					for (i = 0; i < strlen(buffer[buffer_line]) - 1; i++) {
						encode_rotate_left(&(buffer[buffer_line][i]));
						buffer[buffer_line][i] ^= BITMAP_TBL_XOR;
						encode_rotate_left(&(buffer[buffer_line][i]));
					}
				}
				p = strchr(&buffer[buffer_line][0],'\n');
				if (p) *p = '\0';
			} else	{
				//fseek( file, 0, SEEK_SET);
				buffer[buffer_line][0] = 0;
				done++;
			}
		} while (extra_inc--);
		extra_inc = 0;

		for (i=0; i<ROW_SPACING; i++ )	{
			int y;

			y = first_line_offset - i;

#ifndef OGLES
			gr_set_current_canvas(VR_offscreen_buffer);
#endif
			scale_bitmap(&backdrop, scale_pts);
			for (j=0; j<NUM_LINES; j++ )	{
				char *s;

				l = (buffer_line + j + 1 ) %  NUM_LINES;
				s = buffer[l];

				if ( s[0] == '!' ) {
					s++;
				} else if ( s[0] == '$' )	{
					grd_curcanv->cv_font = header_font;
					s++;
				} else if ( s[0] == '*' )	{
					grd_curcanv->cv_font = title_font;
					s++;
				} else
					grd_curcanv->cv_font = names_font;

				gr_bitblt_fade_table = fade_values;

				tempp = strchr( s, '\t' );
				if ( tempp )	{
					int w, h, aw;
					*tempp = 0;
					gr_get_string_size( s, &w, &h, &aw );
					w *= f2fl(Scale_x);
					h *= f2fl(Scale_y);
					gr_scale_printf( (160-w)/2, y, Scale_factor, Scale_factor, s );
					gr_get_string_size( &tempp[1], &w, &h, &aw );
					w *= f2fl(Scale_x);
					h *= f2fl(Scale_y);
					gr_scale_printf( 160+((160-w)/2), y, Scale_factor, Scale_factor, &tempp[1] );
					*tempp = '\t';
				} else {
					gr_scale_printf( 0x8000, y, Scale_factor, Scale_factor, s );
				}
				gr_bitblt_fade_table = NULL;
				if (buffer[l][0] == '!')
					y += ROW_SPACING/2;
				else
					y += ROW_SPACING;
			}
#ifdef OGLES
			showRenderBuffer();
#else
			gr_bm_ubitblt(grd_curscreen->sc_w, grd_curscreen->sc_h, 0, 0, 0, 0, &(VR_offscreen_buffer->cv_bitmap), &(grd_curscreen->sc_canvas.cv_bitmap) );
#endif

			while( timer_get_fixed_seconds() < last_time+time_delay );
			last_time = timer_get_fixed_seconds();
		

			k = key_inkey();

			#ifndef NDEBUG
			if (k == KEY_BACKSP) {
				Int3();
				k=0;
			}
			#endif

//			{
//				fix ot = time_delay;
//				time_delay += (keyd_pressed[KEY_X] - keyd_pressed[KEY_Z])*100;
//				if (ot!=time_delay)	{
//					mprintf( (0, "[%x] ", time_delay ));
//				}
//			}

			if (k == KEY_PRINT_SCREEN) {
				save_screen_shot(0);
				k = 0;
			}

			if ((k>0)||(done>NUM_LINES))	{
					gr_close_font(header_font);
					gr_close_font(title_font);
					gr_close_font(names_font);
					gr_palette_fade_out( gr_palette, 32, 0 );
					gr_use_palette_table( "palette.256" );
					free(backdrop.bm_data);
					cfclose(file);
					songs_play_song( SONG_TITLE, 1 );
					return;
			}
		}

		if (buffer[(buffer_line + 1 ) %  NUM_LINES][0] == '!') {
			first_line_offset -= ROW_SPACING-ROW_SPACING/2;
			if (first_line_offset <= -ROW_SPACING) {
				first_line_offset += ROW_SPACING;
				extra_inc++;
			}
		}
	}
	free(fade_values);
}
예제 #11
0
static window_event_result credits_handler(window *, const d_event &event, credits *cr)
{
	int l, y;
	window_event_result result;

	switch (event.type)
	{
		case EVENT_KEY_COMMAND:
			if ((result = call_default_handler(event)) == window_event_result::ignored)	// if not print screen, debug etc
			{
				return window_event_result::close;
			}
			return result;

		case EVENT_MOUSE_BUTTON_DOWN:
		case EVENT_MOUSE_BUTTON_UP:
			if (event_mouse_get_button(event) == MBTN_LEFT || event_mouse_get_button(event) == MBTN_RIGHT)
			{
				return window_event_result::close;
			}
			break;

		case EVENT_IDLE:
			if (cr->done>NUM_LINES)
			{
				return window_event_result::close;
			}
			break;
			
		case EVENT_WINDOW_DRAW:
#if defined(DXX_BUILD_DESCENT_I)
			timer_delay(F1_0/17);
#elif defined(DXX_BUILD_DESCENT_II)
			timer_delay(F1_0/28);
#endif
			
			if (cr->row == 0)
			{
				do {
					cr->buffer_line = (cr->buffer_line+1) % NUM_LINES;
#if defined(DXX_BUILD_DESCENT_II)
				get_line:;
#endif
					if (PHYSFSX_fgets( cr->buffer[cr->buffer_line], cr->file ))	{
						char *p;
						if (cr->have_bin_file) // is this a binary tbl file
							decode_text_line (cr->buffer[cr->buffer_line]);
#if defined(DXX_BUILD_DESCENT_I)
						p = strchr(&cr->buffer[cr->buffer_line][0],'\n');
						if (p) *p = '\0';
#elif defined(DXX_BUILD_DESCENT_II)
						p = cr->buffer[cr->buffer_line];
						if (p[0] == ';')
							goto get_line;
						
						if (p[0] == '%')
						{
							if (p[1] == ALLOWED_CHAR)
							{
								for (int i = 0; p[i]; i++)
									p[i] = p[i+2];
							}
							else
								goto get_line;
						}
#endif	
					} else	{
						//fseek( file, 0, SEEK_SET);
						cr->buffer[cr->buffer_line][0] = 0;
						cr->done++;
					}
				} while (cr->extra_inc--);
				cr->extra_inc = 0;
			}

			// cheap but effective: towards end of credits sequence, fade out the music volume
			if (cr->done >= NUM_LINES-16)
			{
				static int curvol = -10; 
				if (curvol == -10) 
					curvol = GameCfg.MusicVolume;
				if (curvol > (NUM_LINES-cr->done)/2)
				{
					curvol = (NUM_LINES-cr->done)/2;
					songs_set_volume(curvol);
				}
			}
			
			y = cr->first_line_offset - cr->row;
			show_fullscr(cr->backdrop);
			for (uint_fast32_t j=0; j != NUM_LINES; ++j, y += ROW_SPACING)
			{
				l = (cr->buffer_line + j + 1 ) %  NUM_LINES;
				const char *s = cr->buffer[l];
				if (!s)
					continue;
				
				if ( s[0] == '!' ) {
					s++;
				} else if ( s[0] == '$' )	{
					gr_set_curfont( HUGE_FONT );
					s++;
				} else if ( s[0] == '*' )	{
					gr_set_curfont( MEDIUM3_FONT );
					s++;
				} else
					gr_set_curfont( MEDIUM2_FONT );
				
				const auto tempp = strchr( s, '\t' );
				if ( !tempp )	{
					// Wacky Fast Credits thing
					gr_string( 0x8000, y, s );
				}
			}
			
			cr->row += SHEIGHT/200;
			if (cr->row >= ROW_SPACING)
				cr->row = 0;
			break;

		case EVENT_WINDOW_CLOSE:
			songs_set_volume(GameCfg.MusicVolume);
			songs_play_song( SONG_TITLE, 1 );
			std::default_delete<credits>()(cr);
			break;
		default:
			break;
	}
	return window_event_result::ignored;
}