Beispiel #1
0
//load a level off disk. level numbers start at 1.  Secret levels are -1,-2,-3
void LoadLevel(int level_num,int page_in_textures)
{
	char *level_name;
	player save_player;

	save_player = Players[Player_num];

	Assert(level_num <= Last_level  && level_num >= Last_secret_level  && level_num != 0);

	level_name = get_level_file(level_num);

	if (!load_level(level_name))
		Current_level_num=level_num;

	gr_use_palette_table( "palette.256" );

	show_boxed_message(TXT_LOADING, 0);
#ifdef RELEASE
	timer_delay(F1_0);
#endif

#ifdef NETWORK
	my_segments_checksum = netmisc_calc_checksum();
#endif

	load_endlevel_data(level_num);
	
	load_custom_data(level_name);

#ifdef NETWORK
	reset_network_objects();
#endif

	Players[Player_num] = save_player;

	set_sound_sources();

	songs_play_level_song( Current_level_num, 0 );

	gr_palette_load(gr_palette);		//actually load the palette

	if ( page_in_textures )
		piggy_load_level_data();
}
Beispiel #2
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();
}
Beispiel #3
0
//load a level off disk. level numbers start at 1.  Secret levels are -1,-2,-3
void LoadLevel(int level_num) 
{
	char *level_name;
	player save_player;

	save_player = Players[Player_num];	

	Assert(level_num <= Last_level  && level_num >= Last_secret_level  && level_num != 0);

	level_name = get_level_file(level_num);

	if (!load_level(level_name))
		Current_level_num=level_num;

	gr_use_palette_table( "palette.256" );

	show_boxed_message(TXT_LOADING, 0);
	timer_delay2(1);

	#ifdef NETWORK
	my_segments_checksum = netmisc_calc_checksum(Segments, sizeof(segment)*(Highest_segment_index+1));
	#endif

	load_endlevel_data(level_num);

	#ifdef NETWORK
	reset_network_objects();
	#endif

	Players[Player_num] = save_player;

	set_sound_sources();

	songs_play_level_song( Current_level_num );

}
Beispiel #4
0
void change_res()
{
 //edited 05/27/99 Matt Mueller - ingame fullscreen changing
 newmenu_item m[11];
 u_int32_t modes[11];
 int i=0, mc=0, num_presets=0;
 char customres[16];
#ifdef GR_SUPPORTS_FULLSCREEN_TOGGLE
 int fullscreenc;
#endif
 //end edit -MM
 u_int32_t screen_mode = 0;
 int screen_width = 0;
 int screen_height = 0;
 int vr_mode = VR_NONE;
 int screen_compatible = 0;
 int use_double_buffer = 0;
 
//changed 6/15/1999 by Owen Evans to fix some platform-related problems
#ifdef __MSDOS__
 m[mc].type = NM_TYPE_RADIO; m[mc].text = "320x100"; m[mc].value=(Game_screen_mode==SM(320,100)); m[mc].group=0; modes[mc] = SM(320,100); mc++;
#endif
 m[mc].type = NM_TYPE_RADIO; m[mc].text = "320x200"; m[mc].value=(Game_screen_mode==SM(320,200)); m[mc].group=0; modes[mc] = SM(320,200); mc++;
 m[mc].type = NM_TYPE_RADIO; m[mc].text = "320x240"; m[mc].value=(Game_screen_mode==SM(320,240)); m[mc].group=0; modes[mc] = SM(320,240); mc++;
 m[mc].type = NM_TYPE_RADIO; m[mc].text = "320x400"; m[mc].value=(Game_screen_mode==SM(320,400)); m[mc].group=0; modes[mc] = SM(320,400); mc++;
//#ifndef __LINUX__ - heh?  640x400 is perfectly fine on linux
 m[mc].type = NM_TYPE_RADIO; m[mc].text = "640x400"; m[mc].value=(Game_screen_mode==SM(640,400)); m[mc].group=0; modes[mc] = SM(640,400); mc++;
//#endif
 m[mc].type = NM_TYPE_RADIO; m[mc].text = "640x480"; m[mc].value=(Game_screen_mode==SM(640,480)); m[mc].group=0; modes[mc] = SM(640,480); mc++;
 m[mc].type = NM_TYPE_RADIO; m[mc].text = "800x600"; m[mc].value=(Game_screen_mode==SM(800,600)); m[mc].group=0; modes[mc] = SM(800,600); mc++;
 m[mc].type = NM_TYPE_RADIO; m[mc].text = "1024x768"; m[mc].value=(Game_screen_mode==SM(1024,768)); m[mc].group=0; modes[mc] = SM(1024,768); mc++;
//end section - OE
 num_presets = mc;
 for (i=0; i<mc; i++)
	 if (m[mc].value)
		 break;
 m[mc].type = NM_TYPE_RADIO; m[mc].text = "custom:"; m[mc].value=(i==mc); m[mc].group=0; modes[mc] = 0; mc++;
 sprintf(customres, "%ix%i", SM_W(Game_screen_mode), SM_H(Game_screen_mode));
 m[mc].type = NM_TYPE_INPUT; m[mc].text = customres; m[mc].text_len=11; modes[mc] = 0; mc++;

// m[mc].type = NM_TYPE_CHECK; m[mc].text = "No Doublebuffer"; m[mc].value = use_double_buffer;

 //added 05/27/99 Matt Mueller - ingame fullscreen changing
#ifdef GR_SUPPORTS_FULLSCREEN_TOGGLE
 fullscreenc=mc;m[mc].type = NM_TYPE_CHECK; m[mc].text = "Fullscreen"; m[mc].value = gr_check_fullscreen();mc++;
#endif
 //end addition -MM


   i=newmenu_do1( NULL, "Screen Resolution", mc, m, &change_res_poll, 0);

  //added 05/27/99 Matt Mueller - ingame fullscreen changing
#ifdef GR_SUPPORTS_FULLSCREEN_TOGGLE
   if (m[fullscreenc].value != gr_check_fullscreen()){
	   gr_toggle_fullscreen();
        Game_screen_mode = -1;
   }
#endif
  //end addition -MM
   
  for(i=0;(m[i].value==0)&&(i<num_presets);i++);
  if (modes[i]==0){
	  char *h=strchr(customres, 'x');
	  if (!h) 
		  return;
	  screen_mode = SM(atoi(customres), atoi(h+1));
  }else{
	  screen_mode = modes[i];
  }

  screen_width = SM_W(screen_mode);
  screen_height = SM_H(screen_mode);
  if (screen_height<=0 || screen_width<=0)
	  return;

  switch(screen_mode)
   {
    case SM(320,100)://19:
           screen_compatible = 0;
           use_double_buffer = 0;
           break;
	case SM(320,200)://SM_320x200C:
           screen_compatible = 1;
           use_double_buffer = 0;
           break;
	default:
           screen_compatible = 0;
           use_double_buffer = 1;
           break;
   }
#ifdef __MSDOS__
  if ( FindArg( "-nodoublebuffer" ) )
#endif
   use_double_buffer = 0;

//added 6/15/1999 by Owen Evans to eliminate unneccesary mode modification
	if (Game_screen_mode == screen_mode)
		return;
//      gr_set_mode(Game_screen_mode);
//end section - OE

        VR_offscreen_buffer = 0;        //Disable VR (so that VR_Screen_mode doesnt mess us up
        Game_screen_mode = screen_mode;
        Game_window_w=screen_width;
        Game_window_h=screen_height;
        game_init_render_buffers(screen_mode, screen_width, screen_height, use_double_buffer, vr_mode, screen_compatible);
        

        mprintf( (0, "\nInitializing palette system..." ));
        gr_use_palette_table( "PALETTE.256" );
        mprintf( (0, "\nInitializing font system..." ));
        gamefont_init();        // must load after palette data loaded.


  reset_palette_add();
  init_cockpit();
  last_drawn_cockpit[0]=-1;
  last_drawn_cockpit[1]=-1;
//  init_gauges();

   vr_reset_display();
}
Beispiel #5
0
//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();
}
Beispiel #6
0
//load a palette by name. returns 1 if new palette loaded, else 0
//if used_for_level is set, load pig, etc.
//if no_change_screen is set, the current screen does not get remapped,
//and the hardware palette does not get changed
int load_palette(char *name,int used_for_level,int no_change_screen)
{
	char pigname[FILENAME_LEN];
	ubyte old_pal[256*3];

	//special hack to tell that palette system about a pig that's been loaded elsewhere
	if (used_for_level == -2) {
		strncpy(last_palette_loaded_pig,name,sizeof(last_palette_loaded_pig));
		return 1;
	}

	if (name==NULL)
		name = last_palette_loaded_pig;

	if (used_for_level && stricmp(last_palette_loaded_pig,name) != 0) {

		_splitpath(name,NULL,NULL,pigname,NULL);
		strcat(pigname,".pig");
		//if not editor, load pig first so small install message can come
		//up in old palette.  If editor version, we must load the pig after
		//the palette is loaded so we can remap new textures.
		#ifndef EDITOR
		piggy_new_pigfile(pigname);
		#endif
	}

	if (stricmp(last_palette_loaded,name) != 0) {

		memcpy(old_pal,gr_palette,sizeof(old_pal));

		strncpy(last_palette_loaded,name,sizeof(last_palette_loaded));

		gr_use_palette_table(name);

		if (Function_mode == FMODE_GAME && !no_change_screen)
			gr_remap_bitmap_good( &grd_curscreen->sc_canvas.cv_bitmap, old_pal, -1, -1 );

#if defined(POLY_ACC)
        if (bg.bmp && bg.bmp->bm_type == BM_LINEAR)
#else
        if (bg.bmp)
#endif
            gr_remap_bitmap_good( bg.bmp, old_pal, -1, -1 );

		if (!gr_palette_faded_out && !no_change_screen)
			gr_palette_load(gr_palette);

		remap_fonts_and_menus(0);

		Color_0_31_0 = -1;		//for gauges
		HUD_color = -1;

		load_background_bitmap();

		g3_remap_interp_colors();
	}


	if (used_for_level && stricmp(last_palette_loaded_pig,name) != 0) {

		strncpy(last_palette_loaded_pig,name,sizeof(last_palette_loaded_pig));

		#ifdef EDITOR
		piggy_new_pigfile(pigname);
		#endif

		texmerge_flush();
		rle_cache_flush();
	}

	return 1;
}
Beispiel #7
0
static int main(int argc, char *argv[])
{
	if (!PHYSFSX_init(argc, argv))
		return 1;
	con_init();  // Initialise the console

	setbuf(stdout, NULL); // unbuffered output via printf
#ifdef _WIN32
	freopen( "CON", "w", stdout );
	freopen( "CON", "w", stderr );
#endif

	if (CGameArg.SysShowCmdHelp) {
		print_commandline_help();

		return(0);
	}

	printf("\nType '%s -help' for a list of command-line options.\n\n", PROGNAME);

	PHYSFSX_listSearchPathContent();
	
	if (!PHYSFSX_checkSupportedArchiveTypes())
		return(0);

#if defined(DXX_BUILD_DESCENT_I)
	if (! PHYSFSX_contfile_init("descent.hog", 1))
#define DXX_NAME_NUMBER	"1"
#define DXX_HOGFILE_NAMES	"descent.hog"
#elif defined(DXX_BUILD_DESCENT_II)
	if (! PHYSFSX_contfile_init("descent2.hog", 1) && ! PHYSFSX_contfile_init("d2demo.hog", 1))
#define DXX_NAME_NUMBER	"2"
#define DXX_HOGFILE_NAMES	"descent2.hog or d2demo.hog"
#endif
	{
#if defined(__unix__) && !defined(__APPLE__)
#define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY	\
			      "\t$HOME/.d" DXX_NAME_NUMBER "x-rebirth\n"	\
			      "\t" SHAREPATH "\n"
#else
#define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY	\
				  "\tDirectory containing D" DXX_NAME_NUMBER "X\n"
#endif
#if (defined(__APPLE__) && defined(__MACH__)) || defined(macintosh)
#define DXX_HOGFILE_APPLICATION_BUNDLE	\
				  "\tIn 'Resources' inside the application bundle\n"
#else
#define DXX_HOGFILE_APPLICATION_BUNDLE	""
#endif
#define DXX_MISSING_HOGFILE_ERROR_TEXT	\
		"Could not find a valid hog file (" DXX_HOGFILE_NAMES ")\nPossible locations are:\n"	\
		DXX_HOGFILE_PROGRAM_DATA_DIRECTORY	\
		"\tIn a subdirectory called 'Data'\n"	\
		DXX_HOGFILE_APPLICATION_BUNDLE	\
		"Or use the -hogdir option to specify an alternate location."
		UserError(DXX_MISSING_HOGFILE_ERROR_TEXT);
	}

#if defined(DXX_BUILD_DESCENT_I)
	switch (PHYSFSX_fsize("descent.hog"))
	{
		case D1_MAC_SHARE_MISSION_HOGSIZE:
		case D1_MAC_MISSION_HOGSIZE:
			MacHog = 1;	// used for fonts and the Automap
			break;
	}
#endif

	load_text();

	//print out the banner title
#if defined(DXX_BUILD_DESCENT_I)
	con_printf(CON_NORMAL, "%s  %s", DESCENT_VERSION, g_descent_build_datetime); // D1X version
	con_printf(CON_NORMAL, "This is a MODIFIED version of Descent, based on %s.", BASED_VERSION);
	con_printf(CON_NORMAL, "%s\n%s",TXT_COPYRIGHT,TXT_TRADEMARK);
	con_printf(CON_NORMAL, "Copyright (C) 2005-2013 Christian Beckhaeuser");
#elif defined(DXX_BUILD_DESCENT_II)
	con_printf(CON_NORMAL, "%s%s  %s", DESCENT_VERSION, PHYSFSX_exists(MISSION_DIR "d2x.hog",1) ? "  Vertigo Enhanced" : "", g_descent_build_datetime); // D2X version
	con_printf(CON_NORMAL, "This is a MODIFIED version of Descent 2, based on %s.", BASED_VERSION);
	con_printf(CON_NORMAL, "%s\n%s",TXT_COPYRIGHT,TXT_TRADEMARK);
	con_printf(CON_NORMAL, "Copyright (C) 1999 Peter Hawkins, 2002 Bradley Bell, 2005-2013 Christian Beckhaeuser");
#endif

	if (CGameArg.DbgVerbose)
		con_puts(CON_VERBOSE, TXT_VERBOSE_1);
	
	ReadConfigFile();

	PHYSFSX_addArchiveContent();

	arch_init();

	select_tmap(CGameArg.DbgTexMap);

#if defined(DXX_BUILD_DESCENT_II)
	Lighting_on = 1;
#endif

	con_printf(CON_VERBOSE, "Going into graphics mode...");
	gr_set_mode(Game_screen_mode);

	// Load the palette stuff. Returns non-zero if error.
	con_printf(CON_DEBUG, "Initializing palette system..." );
#if defined(DXX_BUILD_DESCENT_I)
	gr_use_palette_table( "PALETTE.256" );
#elif defined(DXX_BUILD_DESCENT_II)
	gr_use_palette_table(D2_DEFAULT_PALETTE );
#endif

	con_printf(CON_DEBUG, "Initializing font system..." );
	gamefont_init();	// must load after palette data loaded.

#if defined(DXX_BUILD_DESCENT_II)
	con_printf( CON_DEBUG, "Initializing movie libraries..." );
	init_movies();		//init movie libraries
#endif

	show_titles();

	set_screen_mode(SCREEN_MENU);
#ifdef DEBUG_MEMORY_ALLOCATIONS
	/* Memdebug runs before global destructors, so it incorrectly
	 * reports as leaked any allocations that would be freed by a global
	 * destructor.  This local will force the newmenu globals to be
	 * reset before memdebug scans, which prevents memdebug falsely
	 * reporting them as leaked.
	 *
	 * External tools, such as Valgrind, know to run global destructors
	 * before checking for leaks, so this hack is only necessary when
	 * memdebug is used.
	 */
	struct hack_free_global_backgrounds
	{
		~hack_free_global_backgrounds()
		{
			newmenu_free_background();
		}
	};
	hack_free_global_backgrounds hack_free_global_background;
#endif

	con_printf( CON_DEBUG, "\nDoing gamedata_init..." );
	gamedata_init();

#if defined(DXX_BUILD_DESCENT_II)
#if DXX_USE_EDITOR
	if (GameArg.EdiSaveHoardData) {
		save_hoard_data();
		exit(1);
	}
	#endif
#endif

	if (CGameArg.DbgNoRun)
		return(0);

	con_printf( CON_DEBUG, "\nInitializing texture caching system..." );
	texmerge_init();		// 10 cache bitmaps

#if defined(DXX_BUILD_DESCENT_II)
	piggy_init_pigfile("groupa.pig");	//get correct pigfile
#endif

	con_printf( CON_DEBUG, "\nRunning game..." );
	init_game();

	get_local_player().callsign = {};

#if defined(DXX_BUILD_DESCENT_I)
	key_flush();
#elif defined(DXX_BUILD_DESCENT_II)
	//	If built with editor, option to auto-load a level and quit game
	//	to write certain data.
	#ifdef	EDITOR
	if (!GameArg.EdiAutoLoad.empty()) {
		Players[0].callsign = "dummy";
	} else
	#endif
#endif
	{
		if (!CGameArg.SysPilot.empty())
		{
			char filename[sizeof(PLAYER_DIRECTORY_TEXT) + CALLSIGN_LEN + 4];

			/* Step over the literal PLAYER_DIRECTORY_TEXT when it is
			 * present.  Point at &filename[0] when
			 * PLAYER_DIRECTORY_TEXT is absent.
			 */
			const auto b = &filename[-CGameArg.SysUsePlayersDir];
			snprintf(filename, sizeof(filename), PLAYER_DIRECTORY_STRING("%.12s"), CGameArg.SysPilot.c_str());
			/* The pilot name is never used after this.  Clear it to
			 * free the allocated memory, if any.
			 */
			CGameArg.SysPilot.clear();
			auto p = b;
			for (const auto &facet = std::use_facet<std::ctype<char>>(std::locale::classic()); char &c = *p; ++p)
			{
				c = facet.tolower(static_cast<uint8_t>(c));
			}
			auto j = p - filename;
			if (j < sizeof(filename) - 4 && (j <= 4 || strcmp(&filename[j - 4], ".plr"))) // if player hasn't specified .plr extension in argument, add it
			{
				strcpy(&filename[j], ".plr");
				j += 4;
			}
			if(PHYSFSX_exists(filename,0))
			{
				get_local_player().callsign.copy(b, std::distance(b, &filename[j - 4]));
				read_player_file();
				WriteConfigFile();
			}
		}
	}

#if defined(DXX_BUILD_DESCENT_II)
#if DXX_USE_EDITOR
	if (!GameArg.EdiAutoLoad.empty()) {
		/* Any number >= FILENAME_LEN works */
		Level_names[0].copy_if(GameArg.EdiAutoLoad.c_str(), GameArg.EdiAutoLoad.size());
		LoadLevel(1, 1);
	}
	else
#endif
#endif
	{
		Game_mode = GM_GAME_OVER;
		DoMenu();
	}

	while (window_get_front())
		// Send events to windows and the default handler
		event_process();
	
	// Tidy up - avoids a crash on exit
	{
		window *wind;

		show_menus();
		while ((wind = window_get_front()))
			window_close(wind);
	}

	WriteConfigFile();
	show_order_form();

	con_printf( CON_DEBUG, "\nCleanup..." );
	close_game();
	texmerge_close();
	gamedata_close();
	gamefont_close();
	Current_mission.reset();
	PHYSFSX_removeArchiveContent();

	return(0);		//presumably successful exit
}
Beispiel #8
0
// Process a character for the briefing,
// including special characters preceded by a '$'.
// Return 1 when page is finished, 0 otherwise
static int briefing_process_char(grs_canvas &canvas, briefing *const br)
{
	auto &game_font = *GAME_FONT;
	char ch = *br->message++;
	if (ch == '$') {
		ch = *br->message++;
#if defined(DXX_BUILD_DESCENT_II)
		if (ch=='D') {
			br->cur_screen = DefineBriefingBox(canvas.cv_bitmap, br->message);
			br->screen.reset(&Briefing_screens[br->cur_screen]);
			init_char_pos(br, br->screen->text_ulx, br->screen->text_uly);
			br->line_adjustment=0;
			br->prev_ch = 10;                                   // read to eoln
		} else if (ch=='U') {
			br->cur_screen = get_message_num(br->message);
			br->screen.reset(&Briefing_screens[br->cur_screen]);
			init_char_pos(br, br->screen->text_ulx, br->screen->text_uly);
			br->prev_ch = 10;                                   // read to eoln
		} else
#endif
		if (ch == 'C') {
			auto cc = get_message_num(br->message) - 1;
			if (cc < 0)
				cc = 0;
			else if (cc > Briefing_text_colors.size() - 1)
				cc = Briefing_text_colors.size() - 1;
			Current_color = &Briefing_text_colors[cc];
			br->prev_ch = 10;
		} else if (ch == 'F') {     // toggle flashing cursor
			br->flashing_cursor = !br->flashing_cursor;
			br->prev_ch = 10;
			while (*br->message++ != 10)
				;
		} else if (ch == 'T') {
			br->tab_stop = get_message_num(br->message);
			br->prev_ch = 10;							//	read to eoln
		} else if (ch == 'R') {
			br->robot_canv.reset();
#if defined(DXX_BUILD_DESCENT_II)
			if (br->robot_playing) {
				DeInitRobotMovie(br->pMovie);
				br->robot_playing=0;
			}
#endif

			if (EMULATING_D1) {
				init_spinning_robot(canvas, *br);
				br->robot_num = get_message_num(br->message);
#if defined(DXX_BUILD_DESCENT_II)
				while (*br->message++ != 10)
					;
#endif
			} else {
#if defined(DXX_BUILD_DESCENT_II)
				char spinRobotName[]="RBA.MVE", kludge;  // matt don't change this!

				kludge=*br->message++;
				spinRobotName[2]=kludge; // ugly but proud

				br->robot_playing=InitRobotMovie(spinRobotName, br->pMovie);

				// gr_remap_bitmap_good( &grd_curcanv->cv_bitmap, pal, -1, -1 );

				if (br->robot_playing) {
					RotateRobot(br->pMovie);
					set_briefing_fontcolor(*br);
				}
#endif
			}
			br->prev_ch = 10;                           // read to eoln
		}
		else if ((ch == 'N' && (br->animating_bitmap_type = 0, true)) ||
				(ch == 'O' && (br->animating_bitmap_type = 1, true)))
		{
			br->robot_canv.reset();
			br->prev_ch = 10;
			get_message_name(br->message, br->bitmap_name, "#0");
		} else if (ch=='A') {
#if defined(DXX_BUILD_DESCENT_II)
			br->line_adjustment=1-br->line_adjustment;
#endif
		} else if (ch=='Z') {
#if defined(DXX_BUILD_DESCENT_II)
			char fname[15];
			int i;

			br->got_z=1;
			br->dumb_adjust=1;
			i=0;
			while ((fname[i]=*br->message) != '\n') {
				i++;
				br->message++;
			}
			fname[i]=0;
			if (*br->message != 10)
				while (*br->message++ != 10)    //  Get and drop eoln
					;

			{
				char fname2[15];

				i=0;
				while (fname[i]!='.') {
					fname2[i] = fname[i];
					i++;
				}
				fname2[i++]='b';
				fname2[i++]='.';
				fname2[i++]='p';
				fname2[i++]='c';
				fname2[i++]='x';
				fname2[i++]=0;

				if ((HIRESMODE && PHYSFSX_exists(fname2,1)) || !PHYSFSX_exists(fname,1))
					strcpy(fname,fname2);
				load_briefing_screen(*grd_curcanv, br, fname);
			}

#endif
		} else if (ch == 'B') {
			array<char, 32> bitmap_name;
			palette_array_t		temp_palette;
			int		iff_error;
			br->robot_canv.reset();
			get_message_name(br->message, bitmap_name, ".bbm");
			br->guy_bitmap.reset();
			iff_error = iff_read_bitmap(&bitmap_name[0], br->guy_bitmap, &temp_palette);
#if defined(DXX_BUILD_DESCENT_II)
			gr_remap_bitmap_good( br->guy_bitmap, temp_palette, -1, -1 );
#endif
			Assert(iff_error == IFF_NO_ERROR);
			(void)iff_error;

			br->prev_ch = 10;
		} else if (ch == 'S') {
#if defined(DXX_BUILD_DESCENT_II)
			br->chattering = 0;
			br->printing_channel.reset();
#endif

			br->new_screen = 1;
			return 1;
		} else if (ch == 'P') {		//	New page.
#if defined(DXX_BUILD_DESCENT_II)
			if (!br->got_z) {
				Int3(); // Hey ryan!!!! You gotta load a screen before you start
				// printing to it! You know, $Z !!!
				load_briefing_screen(*grd_curcanv, br, HIRESMODE ? "end01b.pcx" : "end01.pcx");
			}

			br->chattering = 0;
			br->printing_channel.reset();
#endif

			br->new_page = 1;

			while (*br->message != 10) {
				br->message++;	//	drop carriage return after special escape sequence
			}
			br->message++;
			br->prev_ch = 10;

			return 1;
		}
#if defined(DXX_BUILD_DESCENT_II)
		else if (ch == ':') {
			br->prev_ch = 10;
			auto p = br->message;
			/* Legacy clients do not understand $: and will instead show
			 * the remainder of the line.  However, if the next two
			 * characters after $: are $F, legacy clients will treat
			 * the $F as above, toggle the flashing_cursor flag, then
			 * discard the rest of the line.  This special case allows
			 * briefing authors to hide the directive from legacy
			 * clients, but get the same state of flashing_cursor for
			 * both legacy and aware clients.  Briefing authors will
			 * likely need an additional $F nearby to balance this
			 * toggle, but no additional code here is needed to support
			 * that.
			 *
			 * The trailing colon is cosmetic, so that the compatibility
			 * $F is not directly adjacent to the directive.
			 */
			if (!strncmp(p, "$F:", 3))
			{
				br->flashing_cursor = !br->flashing_cursor;
				p += 3;
			}
			auto &rotate_robot_label = "Rebirth.rotate.robot ";
			constexpr auto rotate_robot_len = sizeof(rotate_robot_label) - 1;
			if (!strncmp(p, rotate_robot_label, rotate_robot_len))
			{
				char *p2;
				const auto id = strtoul(p + rotate_robot_len, &p2, 10);
				if (*p2 == '\n')
				{
					p = p2;
					br->robot_canv.reset();
					if (br->robot_playing)
					{
						br->robot_playing = 0;
						DeInitRobotMovie(br->pMovie);
					}
					init_spinning_robot(canvas, *br);
					/* This modifies the appearance of the frame, which
					 * is unfortunate.  However, without it, all robots
					 * come out blue shifted.
					 */
					gr_use_palette_table("groupa.256");
					br->robot_num = id;
				}
			}
			else
			{
				const char *p2 = p;
				/* Suppress non-printing characters.  No need to support
				 * encodings.
				 */
				for (char c; (c = *p2) >= ' ' && c <= '~'; ++p2)
				{
				}
				con_printf(CON_VERBOSE, "warning: unknown briefing directive \"%.*s\"", DXX_ptrdiff_cast_int(p2 - p), p);
			}
			for (char c; (c = *p) && (++p, c) != '\n';)
			{
				/* Discard through newline.  On break, *p is '\0' or
				 * p[-1] is '\n'.
				 */
			}
			br->message = p;
		}
#endif
		else if (ch == '$' || ch == ';') // Print a $/;
			put_char_delay(game_font, br, ch);
	} else if (ch == '\t') {		//	Tab
		const auto &&fspacx = FSPACX();
		if (br->text_x - br->screen->text_ulx < fspacx(br->tab_stop))
			br->text_x = br->screen->text_ulx + fspacx(br->tab_stop);
	} else if ((ch == ';') && (br->prev_ch == 10)) {
		while (*br->message++ != 10)
			;
		br->prev_ch = 10;
	} else if (ch == '\\') {
		br->prev_ch = ch;
	} else if (ch == 10) {
		if (br->prev_ch != '\\') {
			br->prev_ch = ch;
#if defined(DXX_BUILD_DESCENT_II)
			if (br->dumb_adjust)
				br->dumb_adjust--;
			else
#endif
				br->text_y += FSPACY(5)+FSPACY(5)*3/5;
			br->text_x = br->screen->text_ulx;
			if (br->text_y > br->screen->text_uly + br->screen->text_height) {
#if defined(DXX_BUILD_DESCENT_I)
				load_briefing_screen(*grd_curcanv, br, D1_Briefing_screens[br->cur_screen].bs_name);
#elif defined(DXX_BUILD_DESCENT_II)
				load_briefing_screen(*grd_curcanv, br, Briefing_screens[br->cur_screen].bs_name);
#endif
				br->text_x = br->screen->text_ulx;
				br->text_y = br->screen->text_uly;
			}
		} else {
			if (ch == 13)		//Can this happen? Above says ch==10
				Int3();
			br->prev_ch = ch;
		}
	} else {
#if defined(DXX_BUILD_DESCENT_II)
		if (!br->got_z) {
			LevelError("briefing wrote to screen without using $Z to load a screen; loading default.");
			//Int3(); // Hey ryan!!!! You gotta load a screen before you start
			// printing to it! You know, $Z !!!
			load_briefing_screen(*grd_curcanv, br, HIRESMODE ? "end01b.pcx" : "end01.pcx");
		}
#endif
		put_char_delay(game_font, br, ch);
	}

	return 0;
}
Beispiel #9
0
int main(int argc, char *argv[])
{
	mem_init();
#ifdef __LINUX__
	error_init(NULL);
#else
	error_init(msgbox_error);
	set_warn_func(msgbox_warning);
#endif
	PHYSFSX_init(argc, argv);
	con_init();  // Initialise the console

	setbuf(stdout, NULL); // unbuffered output via printf
#ifdef _WIN32
	freopen( "CON", "w", stdout );
	freopen( "CON", "w", stderr );
#endif

	if (GameArg.SysShowCmdHelp) {
		print_commandline_help();

		return(0);
	}

	printf("\nType %s -help' for a list of command-line options.\n\n", PROGNAME);

	PHYSFSX_listSearchPathContent();
	
	if (!PHYSFSX_checkSupportedArchiveTypes())
		return(0);

	if (! PHYSFSX_contfile_init("descent2.hog", 1)) {
		if (! PHYSFSX_contfile_init("d2demo.hog", 1))
#define DXX_NAME_NUMBER	"2"
#define DXX_HOGFILE_NAMES	"descent2.hog or d2demo.hog"
#if defined(__unix__) && !defined(__APPLE__)
#define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY	\
			      "\t$HOME/.d" DXX_NAME_NUMBER "x-rebirth\n"	\
			      "\t" SHAREPATH "\n"
#else
#define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY	\
				  "\tDirectory containing D" DXX_NAME_NUMBER "X\n"
#endif
#if (defined(__APPLE__) && defined(__MACH__)) || defined(macintosh)
#define DXX_HOGFILE_APPLICATION_BUNDLE	\
				  "\tIn 'Resources' inside the application bundle\n"
#else
#define DXX_HOGFILE_APPLICATION_BUNDLE	""
#endif
#define DXX_MISSING_HOGFILE_ERROR_TEXT	\
		"Could not find a valid hog file (" DXX_HOGFILE_NAMES ")\nPossible locations are:\n"	\
		DXX_HOGFILE_PROGRAM_DATA_DIRECTORY	\
		"\tIn a subdirectory called 'Data'\n"	\
		DXX_HOGFILE_APPLICATION_BUNDLE	\
		"Or use the -hogdir option to specify an alternate location."
		Error(DXX_MISSING_HOGFILE_ERROR_TEXT);
	}

	load_text();

	//print out the banner title
	con_printf(CON_NORMAL, "%s%s  %s\n", DESCENT_VERSION, PHYSFSX_exists(MISSION_DIR "d2x.hog",1) ? "  Vertigo Enhanced" : "", g_descent_build_datetime); // D2X version
	con_printf(CON_NORMAL, "This is a MODIFIED version of Descent 2, based on %s.\n", BASED_VERSION);
	con_printf(CON_NORMAL, "%s\n%s\n",TXT_COPYRIGHT,TXT_TRADEMARK);
	con_printf(CON_NORMAL, "Copyright (C) 1999 Peter Hawkins, 2002 Bradley Bell, 2005-2011 Christian Beckhaeuser\n\n");

	if (GameArg.DbgVerbose)
		con_printf(CON_VERBOSE,"%s%s", TXT_VERBOSE_1, "\n");
	
	ReadConfigFile();

	PHYSFSX_addArchiveContent();

	arch_init();

	select_tmap(GameArg.DbgTexMap);

	Lighting_on = 1;

	con_printf(CON_VERBOSE, "Going into graphics mode...\n");
	gr_set_mode(Game_screen_mode);

	// Load the palette stuff. Returns non-zero if error.
	con_printf(CON_DEBUG, "Initializing palette system...\n" );
	gr_use_palette_table(D2_DEFAULT_PALETTE );

	con_printf(CON_DEBUG, "Initializing font system...\n" );
	gamefont_init();	// must load after palette data loaded.

	set_default_handler(standard_handler);

	con_printf( CON_DEBUG, "Initializing movie libraries...\n" );
	init_movies();		//init movie libraries

	show_titles();

	set_screen_mode(SCREEN_MENU);

	con_printf( CON_DEBUG, "\nDoing gamedata_init..." );
	gamedata_init();

	#ifdef EDITOR
	if (GameArg.EdiSaveHoardData) {
		save_hoard_data();
		exit(1);
	}
	#endif

	if (GameArg.DbgNoRun)
		return(0);

	con_printf( CON_DEBUG, "\nInitializing texture caching system..." );
	texmerge_init( 10 );		// 10 cache bitmaps

	piggy_init_pigfile("groupa.pig");	//get correct pigfile

	con_printf( CON_DEBUG, "\nRunning game...\n" );
	init_game();

	Players[Player_num].callsign[0] = '\0';

	//	If built with editor, option to auto-load a level and quit game
	//	to write certain data.
	#ifdef	EDITOR
	if (GameArg.EdiAutoLoad) {
		strcpy(Auto_file, GameArg.EdiAutoLoad);
		strcpy(Players[0].callsign, "dummy");
	} else
	#endif
	{
		if(GameArg.SysPilot)
		{
			char filename[32] = "";
			int j;

			if (GameArg.SysUsePlayersDir)
				strcpy(filename, "Players/");
			strncat(filename, GameArg.SysPilot, 12);
			filename[8 + 12] = '\0';	// unfortunately strncat doesn't put the terminating 0 on the end if it reaches 'n'
			for (j = GameArg.SysUsePlayersDir? 8 : 0; filename[j] != '\0'; j++) {
				switch (filename[j]) {
					case ' ':
						filename[j] = '\0';
				}
			}
			if(!strstr(filename,".plr")) // if player hasn't specified .plr extension in argument, add it
				strcat(filename,".plr");
			if(PHYSFSX_exists(filename,0))
			{
				strcpy(strstr(filename,".plr"),"\0");
				strcpy(Players[Player_num].callsign, GameArg.SysUsePlayersDir? &filename[8] : filename);
				read_player_file();
				WriteConfigFile();
			}
		}
	}

#ifdef EDITOR
	if (GameArg.EdiAutoLoad) {
		strcpy((char *)&Level_names[0], Auto_file);
		LoadLevel(1, 1);
	}
	else
#endif
	{
		Game_mode = GM_GAME_OVER;
		DoMenu();
	}

	setjmp(LeaveEvents);
	while (window_get_front())
		// Send events to windows and the default handler
		event_process();
	
	// Tidy up - avoids a crash on exit
	{
		window *wind;

		show_menus();
		while ((wind = window_get_front()))
			window_close(wind);
	}

	WriteConfigFile();
	show_order_form();

	con_printf( CON_DEBUG, "\nCleanup...\n" );
	close_game();
	texmerge_close();
	gamedata_close();
	gamefont_close();
	free_text();
	args_exit();
	newmenu_free_background();
	free_mission();
	PHYSFSX_removeArchiveContent();

	return(0);		//presumably successful exit
}
Beispiel #10
0
void init_editor()
{
	void med_show_warning(char *s);

	// first, make sure we can find the files we need
	PHYSFSX_addRelToSearchPath("editor/data", 1);	// look in source directory first (for work in progress)
	PHYSFSX_addRelToSearchPath("editor", 1);		// then in editor directory
	PHYSFSX_addRelToSearchPath("editor.zip", 1);	// then in a zip file

	ui_init();

	init_med_functions();	// Must be called before medlisp_init

	ui_pad_read( 0, "segmove.pad" );
	ui_pad_read( 1, "segsize.pad" );
	ui_pad_read( 2, "curve.pad" );
	ui_pad_read( 3, "texture.pad" );
	ui_pad_read( 4, "object.pad" );
	ui_pad_read( 5, "objmov.pad" );
	ui_pad_read( 6, "group.pad" );
	ui_pad_read( 7, "lighting.pad" );
	ui_pad_read( 8, "test.pad" );

	medkey_init();

	game_flush_inputs();
	
	editor_font = gr_init_font( "pc8x16.fnt" );
	
	menubar_init( "MED.MNU" );

	Draw_all_segments = 1;						// Say draw all segments, not just connected ones
	
	if (!Cursegp)
		Cursegp = &Segments[0];

	init_autosave();
  
//	atexit(close_editor);

	Clear_window = 1;	//	do full window clear.
	
	InitCurve();
	
	restore_effect_bitmap_icons();
	
	if (!set_screen_mode(SCREEN_EDITOR))	{
		set_screen_mode(SCREEN_MENU);
		show_menus();			//force back into menu
		return;
	}
	
	gr_use_palette_table( "palette.256" );
	
	gr_palette_load( gr_palette );
	
	//Editor renders into full (320x200) game screen 
	
	game_init_render_buffers(320, 200, VR_NONE);
	gr_init_sub_canvas( &VR_editor_canvas, &grd_curscreen->sc_canvas, 0, 0, SWIDTH, SHEIGHT );
	Canv_editor = &VR_editor_canvas;
	gr_set_current_canvas( Canv_editor );
	init_editor_screen(); // load the main editor dialog
	gr_set_current_canvas( NULL );
	gr_set_curfont(editor_font);
	
	set_warn_func(med_show_warning);
	
	//	_MARK_("start of editor");//Nuked to compile -KRB
	
	//@@	//create a camera for viewing in the editor. copy position from ConsoleObject
	//@@	camera_objnum = obj_create(OBJ_CAMERA,0,ConsoleObject->segnum,&ConsoleObject->pos,&ConsoleObject->orient,0);
	//@@	Viewer = &Objects[camera_objnum];
	//@@	slew_init(Viewer);		//camera is slewing
	
	Viewer = ConsoleObject;
	slew_init(ConsoleObject);
	init_player_object();
	
	Update_flags = UF_ALL;
	
	//set the wire-frame window to be the current view
	current_view = &LargeView;
	
	if (faded_in==0)
	{
		faded_in = 1;
		//gr_pal_fade_in( grd_curscreen->pal );
	}
	
	gr_set_current_canvas( GameViewBox->canvas );
	gr_set_curfont(editor_font);
	//gr_setcolor( CBLACK );
	//gr_deaccent_canvas();
	//gr_grey_canvas();
	
	gr_set_curfont(editor_font);
	FNTScaleX = FNTScaleY = 1;		// No font scaling!
	ui_pad_goto(padnum);
	
	ModeFlag = 0;
	
	gamestate_restore_check();
}
Beispiel #11
0
int main(int argc, char *argv[])
{
	mem_init();
#ifdef __LINUX__
	error_init(NULL, NULL);
#else
	error_init(msgbox_error, NULL);
	set_warn_func(msgbox_warning);
#endif
	PHYSFSX_init(argc, argv);
	con_init();  // Initialise the console

	setbuf(stdout, NULL); // unbuffered output via printf
#ifdef _WIN32
	freopen( "CON", "w", stdout );
	freopen( "CON", "w", stderr );
#endif

	if (GameArg.SysShowCmdHelp) {
		print_commandline_help();
		set_exit_message("");

		return(0);
	}

	printf("\nType %s -help' for a list of command-line options.\n\n", PROGNAME);

	PHYSFSX_listSearchPathContent();
	
	if (!PHYSFSX_checkSupportedArchiveTypes())
		return(0);

	if (! PHYSFSX_contfile_init("descent.hog", 1))
		Error("Could not find a valid hog file (descent.hog)\nPossible locations are:\n"
#if defined(__unix__) && !defined(__APPLE__)
			  "\t$HOME/.d1x-rebirth\n"
			  "\t" SHAREPATH "\n"
#else
			  "\tDirectory containing D1X\n"
#endif
			  "\tIn a subdirectory called 'Data'\n"
#if (defined(__APPLE__) && defined(__MACH__)) || defined(macintosh)
			  "\tIn 'Resources' inside the application bundle\n"
#endif
			  "Or use the -hogdir option to specify an alternate location.");
	
	switch (PHYSFSX_fsize("descent.hog"))
	{
		case D1_MAC_SHARE_MISSION_HOGSIZE:
		case D1_MAC_MISSION_HOGSIZE:
			MacHog = 1;	// used for fonts and the Automap
			break;
	}

	load_text();

	//print out the banner title
	con_printf(CON_NORMAL, "%s", DESCENT_VERSION); // D1X version
	con_printf(CON_NORMAL, "  %s %s\n", __DATE__,__TIME__);
	con_printf(CON_NORMAL, "This is a MODIFIED version of Descent, based on %s.\n", BASED_VERSION);
	con_printf(CON_NORMAL, "%s\n%s\n",TXT_COPYRIGHT,TXT_TRADEMARK);
	con_printf(CON_NORMAL, "Copyright (C) 2005-2011 Christian Beckhaeuser\n\n");

	if (GameArg.DbgVerbose)
		con_printf(CON_VERBOSE,"%s%s", TXT_VERBOSE_1, "\n");
	
	ReadConfigFile();

	PHYSFSX_addArchiveContent();

	arch_init();

	select_tmap(GameArg.DbgTexMap);

	con_printf(CON_VERBOSE, "Going into graphics mode...\n");
	gr_set_mode(Game_screen_mode);

	// Load the palette stuff. Returns non-zero if error.
	con_printf(CON_DEBUG, "Initializing palette system...\n" );
	gr_use_palette_table( "PALETTE.256" );

	con_printf(CON_DEBUG, "Initializing font system...\n" );
	gamefont_init();	// must load after palette data loaded.

	set_default_handler(standard_handler);

	show_titles();

	set_screen_mode(SCREEN_MENU);

	con_printf( CON_DEBUG, "\nDoing gamedata_init..." );
	gamedata_init();

	if (GameArg.DbgNoRun)
		return(0);

	con_printf( CON_DEBUG, "\nInitializing texture caching system..." );
	texmerge_init( 10 );		// 10 cache bitmaps

	con_printf( CON_DEBUG, "\nRunning game...\n" );
	init_game();

	Players[Player_num].callsign[0] = '\0';

	key_flush();

	if(GameArg.SysPilot)
	{
		char filename[32] = "";
		int j;

		if (GameArg.SysUsePlayersDir)
			strcpy(filename, "Players/");
		strncat(filename, GameArg.SysPilot, 12);
		filename[8 + 12] = '\0';	// unfortunately strncat doesn't put the terminating 0 on the end if it reaches 'n'
		for (j = GameArg.SysUsePlayersDir? 8 : 0; filename[j] != '\0'; j++) {
			switch (filename[j]) {
				case ' ':
					filename[j] = '\0';
			}
		}
		if(!strstr(filename,".plr")) // if player hasn't specified .plr extension in argument, add it
			strcat(filename,".plr");
		if(PHYSFSX_exists(filename,0))
		{
			strcpy(strstr(filename,".plr"),"\0");
			strcpy(Players[Player_num].callsign, GameArg.SysUsePlayersDir? &filename[8] : filename);
			read_player_file();
			WriteConfigFile();
		}
	}


	Game_mode = GM_GAME_OVER;
	DoMenu();

	setjmp(LeaveEvents);
	while (window_get_front())
		// Send events to windows and the default handler
		event_process();
	
	// Tidy up - avoids a crash on exit
	{
		window *wind;

		show_menus();
		while ((wind = window_get_front()))
			window_close(wind);
	}

	WriteConfigFile();
	show_order_form();

	con_printf( CON_DEBUG, "\nCleanup...\n" );
	close_game();
	texmerge_close();
	gamedata_close();
	gamefont_close();
	free_text();
	args_exit();
	newmenu_free_background();
	free_mission();
	PHYSFSX_removeArchiveContent();

	return(0);		//presumably successful exit
}
Beispiel #12
0
//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();
}
Beispiel #13
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);
}