Exemplo n.º 1
0
void show_order_form()
{
	if (CGameArg.SysNoTitles)
		return;

#if defined(DXX_BUILD_DESCENT_I)
	show_first_found_title_screen(
		"warning.pcx",	// D1 Registered
		"apple.pcx",	// D1 Mac OEM Demo
		"order01.pcx"	// D1 Demo
	);
#elif defined(DXX_BUILD_DESCENT_II)
#if !DXX_USE_EDITOR
	key_flush();
	const auto hiresmode = HIRESMODE;
	/*
	 * If D2 registered, all checks fail and nothing is shown.
	 */
	const char *exit_screen = hiresmode ? "ordrd2ob.pcx" : "ordrd2o.pcx"; // OEM
	if ((PHYSFSX_exists(exit_screen, 1)) ||
		// SHAREWARE, prefer mac if hires
		(exit_screen = hiresmode ? "orderd2b.pcx" : "orderd2.pcx", PHYSFSX_exists(exit_screen, 1)) ||
		// SHAREWARE, have to rescale
		(exit_screen = hiresmode ? "orderd2.pcx" : "orderd2b.pcx", PHYSFSX_exists(exit_screen, 1)) ||
		// D1
		(exit_screen = hiresmode ? "warningb.pcx" : "warning.pcx", PHYSFSX_exists(exit_screen, 1))
		)
		show_title_screen(exit_screen,1,0);
#endif
#endif
}
Exemplo n.º 2
0
void save_screen_shot(int automap_flag)
{
	static int savenum=0;
	char savename[13+sizeof(SCRNS_DIR)];
	unsigned char *buf;

	if (!GameArg.DbgGlReadPixelsOk){
		if (!automap_flag)
			HUD_init_message_literal(HM_DEFAULT, "glReadPixels not supported on your configuration");
		return;
	}

	stop_time();

	if (!PHYSFSX_exists(SCRNS_DIR,0))
		PHYSFS_mkdir(SCRNS_DIR); //try making directory

	do
	{
		sprintf(savename, "%sscrn%04d.tga",SCRNS_DIR, savenum++);
	} while (PHYSFSX_exists(savename,0));

	if (!automap_flag)
		HUD_init_message(HM_DEFAULT, "%s 'scrn%04d.tga'", TXT_DUMPING_SCREEN, savenum-1 );

#ifndef OGLES
	glReadBuffer(GL_FRONT);
#endif

	buf = d_malloc(grd_curscreen->sc_w*grd_curscreen->sc_h*3);
	write_bmp(savename,grd_curscreen->sc_w,grd_curscreen->sc_h,buf);
	d_free(buf);

	start_time();
}
Exemplo n.º 3
0
static void show_first_found_title_screen(const char *oem, const char *share, const char *macshare)
{
	const char *filename = oem;
	if ((PHYSFSX_exists(filename, 1)) ||
		(filename = share, PHYSFSX_exists(filename, 1)) ||
		(filename = macshare, PHYSFSX_exists(filename, 1))
		)
		show_title_screen(filename, 1, 1);
}
Exemplo n.º 4
0
/* Open an m3u using fopen, not PHYSFS.  If the path seems to be under
 * PHYSFS, that will be preferred over a raw filesystem path.
 */
static std::unique_ptr<FILE, FILE_deleter> open_m3u_from_disk(const char *const cfgpath)
{
	array<char, PATH_MAX> absbuf;
	return std::unique_ptr<FILE, FILE_deleter>(fopen(
	// it's a child of Sharepath, build full path
		(PHYSFSX_exists(cfgpath, 0)
			? (PHYSFSX_getRealPath(cfgpath, absbuf), absbuf.data())
			: cfgpath), "rb")
	);
}
Exemplo n.º 5
0
static void gamefont_loadfont(int gf,int fi)
{
	if (PHYSFSX_exists(font_conf[gf].font[fi].f.name,1)){
		gamefont_unloadfont(gf);
		Gamefonts[gf]=gr_init_font(font_conf[gf].font[fi].f.name);
	}else {
		if (Gamefonts[gf]==NULL){
			Gamefonts[gf]=gr_init_font(Gamefont_filenames_l[gf]);
			font_conf[gf].cur=-1;
		}
		return;
	}
	font_conf[gf].cur=fi;
}
Exemplo n.º 6
0
static void addfontconf(int gf, int x, int y, const char *const fn)
{
	if (!PHYSFSX_exists(fn,1))
		return;

	for (int i=0;i<font_conf[gf].num;i++){
		if (font_conf[gf].font[i].x==x && font_conf[gf].font[i].y==y){
			if (i==font_conf[gf].cur)
				gamefont_unloadfont(gf);
			strcpy(font_conf[gf].font[i].f.name,fn);
			if (i==font_conf[gf].cur)
				gamefont_loadfont(gf,i);
			return;
		}
	}
	font_conf[gf].font[font_conf[gf].num].x=x;
	font_conf[gf].font[font_conf[gf].num].y=y;
	strcpy(font_conf[gf].font[font_conf[gf].num].f.name,fn);
	font_conf[gf].num++;
}
Exemplo n.º 7
0
int load_exit_models()
{
	int start_num;

	bm_free_extra_models();
	bm_free_extra_objbitmaps();

	start_num = N_ObjBitmaps;
	if (!bm_load_extra_objbitmap("steel1.bbm") ||
		!bm_load_extra_objbitmap("rbot061.bbm") ||
		!bm_load_extra_objbitmap("rbot062.bbm") ||
		!bm_load_extra_objbitmap("steel1.bbm") ||
		!bm_load_extra_objbitmap("rbot061.bbm") ||
		!bm_load_extra_objbitmap("rbot063.bbm"))
	{
		con_puts(CON_NORMAL, "Can't load exit models!");
		return 0;
	}
	if (auto exit_hamfile = PHYSFSX_openReadBuffered("exit.ham"))
	{
		exit_modelnum = N_polygon_models++;
		destroyed_exit_modelnum = N_polygon_models++;
		polymodel_read(&Polygon_models[exit_modelnum], exit_hamfile);
		polymodel_read(&Polygon_models[destroyed_exit_modelnum], exit_hamfile);
		Polygon_models[exit_modelnum].first_texture = start_num;
		Polygon_models[destroyed_exit_modelnum].first_texture = start_num+3;

		polygon_model_data_read(&Polygon_models[exit_modelnum], exit_hamfile);

		polygon_model_data_read(&Polygon_models[destroyed_exit_modelnum], exit_hamfile);
	} else if (PHYSFSX_exists("exit01.pof",1) && PHYSFSX_exists("exit01d.pof",1)) {

		exit_modelnum = load_polygon_model("exit01.pof", 3, start_num, NULL);
		destroyed_exit_modelnum = load_polygon_model("exit01d.pof", 3, start_num + 3, NULL);

#if DXX_USE_OGL
		ogl_cache_polymodel_textures(exit_modelnum);
		ogl_cache_polymodel_textures(destroyed_exit_modelnum);
#endif
	}
	else if ((exit_hamfile = PHYSFSX_openReadBuffered(D1_PIGFILE)))
	{
		int offset, offset2;
		int hamsize;
		hamsize = PHYSFS_fileLength(exit_hamfile);
		switch (hamsize) { //total hack for loading models
		case D1_PIGSIZE:
			offset = 91848;     /* and 92582  */
			offset2 = 383390;   /* and 394022 */
			break;
		default:
		case D1_SHARE_BIG_PIGSIZE:
		case D1_SHARE_10_PIGSIZE:
		case D1_SHARE_PIGSIZE:
		case D1_10_BIG_PIGSIZE:
		case D1_10_PIGSIZE:
			Int3();             /* exit models should be in .pofs */
			/*-fallthrough*/
		case D1_OEM_PIGSIZE:
		case D1_MAC_PIGSIZE:
		case D1_MAC_SHARE_PIGSIZE:
			con_puts(CON_NORMAL, "Can't load exit models!");
			return 0;
		}
		PHYSFSX_fseek(exit_hamfile, offset, SEEK_SET);
		exit_modelnum = N_polygon_models++;
		destroyed_exit_modelnum = N_polygon_models++;
		polymodel_read(&Polygon_models[exit_modelnum], exit_hamfile);
		polymodel_read(&Polygon_models[destroyed_exit_modelnum], exit_hamfile);
		Polygon_models[exit_modelnum].first_texture = start_num;
		Polygon_models[destroyed_exit_modelnum].first_texture = start_num+3;

		PHYSFSX_fseek(exit_hamfile, offset2, SEEK_SET);
		polygon_model_data_read(&Polygon_models[exit_modelnum], exit_hamfile);
		polygon_model_data_read(&Polygon_models[destroyed_exit_modelnum], exit_hamfile);
	} else {
		con_puts(CON_NORMAL, "Can't load exit models!");
		return 0;
	}

	return 1;
}
Exemplo n.º 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;
}
Exemplo n.º 9
0
//read in the player's saved games.  returns errno (0 == no error)
int read_player_file()
{
	char filename[PATH_MAX];
	PHYSFS_file *file;
	int player_file_size, shareware_file = -1, id = 0;
	short saved_game_version, player_struct_version;

	Assert(Player_num>=0 && Player_num<MAX_PLAYERS);

	memset(filename, '\0', PATH_MAX);
	snprintf(filename, PATH_MAX, GameArg.SysUsePlayersDir? "Players/%.8s.plr" : "%.8s.plr", Players[Player_num].callsign);
	if (!PHYSFSX_exists(filename,0))
		return ENOENT;

	file = PHYSFSX_openReadBuffered(filename);

	if (!file)
		goto read_player_file_failed;

	new_player_config(); // Set defaults!

	// Unfortunatly d1x has been writing both shareware and registered
	// player files with a saved_game_version of 7 and 8, whereas the
	// original decent used 4 for shareware games and 7 for registered
	// games. Because of this the player files didn't get properly read
	// when reading d1x shareware player files in d1x registered or
	// vica versa. The problem is that the sizeof of the taunt macros
	// differ between the share and registered versions, causing the
	// reading of the player file to go wrong. Thus we now determine the
	// sizeof the player file to determine what kinda player file we are
	// dealing with so that we can do the right thing
	PHYSFS_seek(file, 0);
	player_file_size = PHYSFS_fileLength(file);

	PHYSFS_readSLE32(file, &id);
	saved_game_version = PHYSFSX_readShort(file);
	player_struct_version = PHYSFSX_readShort(file);
	PlayerCfg.NHighestLevels = PHYSFSX_readInt(file);
	PlayerCfg.DefaultDifficulty = PHYSFSX_readInt(file);
	PlayerCfg.AutoLeveling = PHYSFSX_readInt(file);

	if (id!=SAVE_FILE_ID) {
		nm_messagebox(TXT_ERROR, 1, TXT_OK, "Invalid player file");
		PHYSFS_close(file);
		return -1;
	}

	if (saved_game_version<COMPATIBLE_SAVED_GAME_VERSION || player_struct_version<COMPATIBLE_PLAYER_STRUCT_VERSION) {
		nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_ERROR_PLR_VERSION);
		PHYSFS_close(file);
		return -1;
	}

	/* determine if we're dealing with a shareware or registered playerfile */
	switch (saved_game_version)
	{
		case 4:
			shareware_file = 1;
			break;
		case 5:
		case 6:
			shareware_file = 0;
			break;
		case 7:
			/* version 7 doesn't have the saved games array */
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2212 - sizeof(saved_games)))
				shareware_file = 1;
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2252 - sizeof(saved_games)))
				shareware_file = 0;
			break;
		case 8:
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == 2212)
				shareware_file = 1;
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == 2252)
				shareware_file = 0;
			/* d1x-rebirth v0.31 to v0.42 broke things by adding stuff to the
			   player struct without thinking (sigh) */
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2212 + 2*sizeof(int)))
			{

				shareware_file = 1;
				/* skip the cruft added to the player_info struct */
				PHYSFS_seek(file, PHYSFS_tell(file)+2*sizeof(int));
			}
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2252 + 2*sizeof(int)))
			{
				shareware_file = 0;
				/* skip the cruft added to the player_info struct */
				PHYSFS_seek(file, PHYSFS_tell(file)+2*sizeof(int));
			}
	}

	if (shareware_file == -1) {
		nm_messagebox(TXT_ERROR, 1, TXT_OK, "Error invalid or unknown\nplayerfile-size");
		PHYSFS_close(file);
		return -1;
	}

	if (saved_game_version <= 5) {

		//deal with old-style highest level info

		PlayerCfg.HighestLevels[0].Shortname[0] = 0;							//no name for mission 0
		PlayerCfg.HighestLevels[0].LevelNum = PlayerCfg.NHighestLevels;	//was highest level in old struct

		//This hack allows the player to start on level 8 if he's made it to
		//level 7 on the shareware.  We do this because the shareware didn't
		//save the information that the player finished level 7, so the most
		//we know is that he made it to level 7.
		if (PlayerCfg.NHighestLevels==7)
			PlayerCfg.HighestLevels[0].LevelNum = 8;
		
	}
	else {	//read new highest level info
		if (PHYSFS_read(file,PlayerCfg.HighestLevels,sizeof(hli),PlayerCfg.NHighestLevels) != PlayerCfg.NHighestLevels)
			goto read_player_file_failed;
	}

	if ( saved_game_version != 7 ) {	// Read old & SW saved games.
		if (PHYSFS_read(file,saved_games,sizeof(saved_games),1) != 1)
			goto read_player_file_failed;
	}

	//read taunt macros
	{
		int i;
		int len = shareware_file? 25:35;

		#ifdef NETWORK
		for (i = 0; i < 4; i++)
			if (PHYSFS_read(file, PlayerCfg.NetworkMessageMacro[i], len, 1) != 1)
				goto read_player_file_failed;
		#else
		i = 0;
		PHYSFS_seek( file, PHYSFS_tell(file)+4*len );
		#endif
	}

	//read kconfig data
	{
		ubyte dummy_joy_sens;

		if (PHYSFS_read(file, &PlayerCfg.KeySettings[0], sizeof(PlayerCfg.KeySettings[0]),1)!=1)
			goto read_player_file_failed;
		if (PHYSFS_read(file, &PlayerCfg.KeySettings[1], sizeof(PlayerCfg.KeySettings[1]),1)!=1)
			goto read_player_file_failed;
		PHYSFS_seek( file, PHYSFS_tell(file)+(sizeof(ubyte)*MAX_CONTROLS*3) ); // Skip obsolete Flightstick/Thrustmaster/Gravis map fields
		if (PHYSFS_read(file, &PlayerCfg.KeySettings[2], sizeof(PlayerCfg.KeySettings[2]),1)!=1)
			goto read_player_file_failed;
		PHYSFS_seek( file, PHYSFS_tell(file)+(sizeof(ubyte)*MAX_CONTROLS) ); // Skip obsolete Cyberman map field
		if (PHYSFS_read(file, &PlayerCfg.ControlType, sizeof(ubyte), 1 )!=1)
			goto read_player_file_failed;
		else if (PHYSFS_read(file, &dummy_joy_sens, sizeof(ubyte), 1 )!=1)
			goto read_player_file_failed;
	}

	if ( saved_game_version != 7 ) 	{
		int i, found=0;
		
		Assert( N_SAVE_SLOTS == 10 );

		for (i=0; i<N_SAVE_SLOTS; i++ )	{
			if ( saved_games[i].name[0] )	{
				state_save_old_game(i, saved_games[i].name, &saved_games[i].sg_player, saved_games[i].difficulty_level, saved_games[i].primary_weapon, saved_games[i].secondary_weapon, saved_games[i].next_level_num );
				// make sure we do not do this again, which would possibly overwrite
				// a new newstyle savegame
				saved_games[i].name[0] = 0;
				found++;
			}
		}
		if (found)
			write_player_file();
	}

	if (!PHYSFS_close(file))
		goto read_player_file_failed;

	filename[strlen(filename) - 4] = 0;
	strcat(filename, ".plx");
	read_player_d1x(filename);
	kc_set_controls();

	return EZERO;

 read_player_file_failed:
	nm_messagebox(TXT_ERROR, 1, TXT_OK, "%s\n\n%s", "Error reading PLR file", PHYSFS_getLastError());
	if (file)
		PHYSFS_close(file);

	return -1;
}
Exemplo n.º 10
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
}
Exemplo n.º 11
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
}
Exemplo n.º 12
0
// read stored values from ngp file to netgame_info
void read_netgame_profile(netgame_info *ng)
{
	char filename[PATH_MAX], line[50], *token, *value, *ptr;
	PHYSFS_file *file;

	memset(filename, '\0', PATH_MAX);
	snprintf(filename, PATH_MAX, GameArg.SysUsePlayersDir? "Players/%.8s.ngp" : "%.8s.ngp", Players[Player_num].callsign);
	if (!PHYSFSX_exists(filename,0))
		return;

	file = PHYSFSX_openReadBuffered(filename);

	if (!file)
		return;

	// NOTE that we do not set any defaults here or even initialize netgame_info. For flexibility, leave that to the function calling this.
	while (!PHYSFS_eof(file))
	{
		memset(line, 0, 50);
		PHYSFSX_gets(file, line);
		ptr = &(line[0]);
		while (isspace(*ptr))
			ptr++;
		if (*ptr != '\0') {
			token = strtok(ptr, "=");
			value = strtok(NULL, "=");
			if (!value)
				value = "";
			if (!strcmp(token, "game_name"))
			{
				char * p;
				strncpy( ng->game_name, value, NETGAME_NAME_LEN+1 );
				p = strchr( ng->game_name, '\n');
				if ( p ) *p = 0;
			}
			else if (!strcmp(token, "gamemode"))
				ng->gamemode = strtol(value, NULL, 10);
			else if (!strcmp(token, "RefusePlayers"))
				ng->RefusePlayers = strtol(value, NULL, 10);
			else if (!strcmp(token, "difficulty"))
				ng->difficulty = strtol(value, NULL, 10);
			else if (!strcmp(token, "game_flags"))
				ng->game_flags = strtol(value, NULL, 10);
			else if (!strcmp(token, "AllowedItems"))
				ng->AllowedItems = strtol(value, NULL, 10);
			else if (!strcmp(token, "ShowEnemyNames"))
				ng->ShowEnemyNames = strtol(value, NULL, 10);
			else if (!strcmp(token, "BrightPlayers"))
				ng->BrightPlayers = strtol(value, NULL, 10);
			else if (!strcmp(token, "InvulAppear"))
				ng->InvulAppear = strtol(value, NULL, 10);
			else if (!strcmp(token, "KillGoal"))
				ng->KillGoal = strtol(value, NULL, 10);
			else if (!strcmp(token, "PlayTimeAllowed"))
				ng->PlayTimeAllowed = strtol(value, NULL, 10);
			else if (!strcmp(token, "control_invul_time"))
				ng->control_invul_time = strtol(value, NULL, 10);
			else if (!strcmp(token, "PacketsPerSec"))
				ng->PacketsPerSec = strtol(value, NULL, 10);
			else if (!strcmp(token, "NoFriendlyFire"))
				ng->NoFriendlyFire = strtol(value, NULL, 10);
#ifdef USE_TRACKER
			else if (!strcmp(token, "Tracker"))
				ng->Tracker = strtol(value, NULL, 10);
#endif
		}
	}

	PHYSFS_close(file);
}
Exemplo n.º 13
0
//loads the specfied mission from the mission list.
//build_mission_list() must have been called.
//Returns true if mission loaded ok, else false.
int load_mission(mle *mission)
{
	PHYSFS_file *mfile;
	char buf[PATH_MAX], *v;

	if (Current_mission)
		free_mission();
	Current_mission = d_malloc(sizeof(Mission));
	if (!Current_mission) return 0;
	*(mle *) Current_mission = *mission;
	Current_mission->path = d_strdup(mission->path);
	Current_mission->filename = Current_mission->path + (mission->filename - mission->path);
	Current_mission->n_secret_levels = 0;

	//init vars
	Last_level = 0;
	Last_secret_level = 0;
	memset(&Briefing_text_filename, '\0', sizeof(Briefing_text_filename));
	memset(&Ending_text_filename, '\0', sizeof(Ending_text_filename));
	Secret_level_table = NULL;
	Level_names = NULL;
	Secret_level_names = NULL;

	// for Descent 1 missions, load descent.hog
	if (!PHYSFSX_contfile_init("descent.hog", 1))
		Error("descent.hog not available!\n");
	if (!d_stricmp(Current_mission_filename, D1_MISSION_FILENAME))
		return load_mission_d1();

	//read mission from file

	switch (mission->location) {
	case ML_MISSIONDIR:
		strcpy(buf,MISSION_DIR);
		break;
	default:
		Int3();							//fall through
	case ML_CURDIR:
		strcpy(buf,"");
		break;
	}
	strcat(buf, mission->path);
	strcat(buf,".msn");

	PHYSFSEXT_locateCorrectCase(buf);

	mfile = PHYSFSX_openReadBuffered(buf);
	if (mfile == NULL) {
		free_mission();
		return 0;		//error!
	}

	//for non-builtin missions, load HOG
	strcpy(buf+strlen(buf)-4,".hog");		//change extension
	PHYSFSEXT_locateCorrectCase(buf);
	if (PHYSFSX_exists(buf,1))
		PHYSFSX_contfile_init(buf, 0);

	snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.tex",Current_mission_filename);
	if (!PHYSFSX_exists(Briefing_text_filename,1))
		snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.txb",Current_mission_filename);
	snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.tex",Current_mission_filename);
	if (!PHYSFSX_exists(Ending_text_filename,1))
		snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.txb",Current_mission_filename);

	while (PHYSFSX_fgets(buf,sizeof(buf),mfile)) {
		if (istok(buf,"type"))
			continue;						//already have name, go to next line
		else if (istok(buf,"briefing")) {
			if ((v = get_value(buf)) != NULL) {
				add_term(v);
				if (strlen(v) < FILENAME_LEN && strlen(v) > 0)
				{
					char *tmp, *ptr;
					MALLOC(tmp, char, FILENAME_LEN);
					snprintf(tmp, FILENAME_LEN, "%s", v);
					if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one.
						*ptr = '\0';
					strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion
					if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
						snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					else // ... otherwise ...
					{
						if ((ptr = strrchr(tmp, '.')))
							*ptr = '\0';
						strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension
						if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
							snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					}
					d_free(tmp);
				}
			}
		}
		else if (istok(buf,"ending")) {
			if ((v = get_value(buf)) != NULL) {
				add_term(v);
				if (strlen(v) < FILENAME_LEN && strlen(v) > 0)
				{
					char *tmp, *ptr;
					MALLOC(tmp, char, FILENAME_LEN);
					snprintf(tmp, FILENAME_LEN, "%s", v);
					if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one.
						*ptr = '\0';
					strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion
					if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
						snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					else // ... otherwise ...
					{
						if ((ptr = strrchr(tmp, '.')))
							*ptr = '\0';
						strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension
						if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
							snprintf(Ending_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					}
					d_free(tmp);
				}
			}
		}
		else if (istok(buf,"num_levels")) {

			if ((v=get_value(buf))!=NULL) {
				int n_levels,i;

				n_levels = atoi(v);
				
				Assert(n_levels <= MAX_LEVELS_PER_MISSION);
				n_levels = min(n_levels, MAX_LEVELS_PER_MISSION);
				
				MALLOC(Level_names, d_fname, n_levels);
				if (!Level_names)
				{
					free_mission();
					return 0;
				}

				for (i=0;i<n_levels;i++) {
					PHYSFSX_fgets(buf,sizeof(buf),mfile);
					add_term(buf);
					if (strlen(buf) <= 12) {
						strcpy(Level_names[i],buf);
						Last_level++;
					}
					else
						break;
				}

			}
		}
		else if (istok(buf,"num_secrets")) {
			if ((v=get_value(buf))!=NULL) {
				int i;

				N_secret_levels = atoi(v);

				Assert(N_secret_levels <= MAX_SECRET_LEVELS_PER_MISSION);
				N_secret_levels = min(N_secret_levels, MAX_SECRET_LEVELS_PER_MISSION);

				MALLOC(Secret_level_names, d_fname, N_secret_levels);
				if (!Secret_level_names)
				{
					free_mission();
					return 0;
				}
				
				MALLOC(Secret_level_table, ubyte, N_secret_levels);
				if (!Secret_level_table)
				{
					free_mission();
					return 0;
				}
				
				for (i=0;i<N_secret_levels;i++) {
					char *t;

					PHYSFSX_fgets(buf,sizeof(buf),mfile);
					if ((t=strchr(buf,','))!=NULL) *t++=0;
					else
						break;

					add_term(buf);
					if (strlen(buf) <= 12) {
						strcpy(Secret_level_names[i],buf);
						Secret_level_table[i] = atoi(t);
						if (Secret_level_table[i]<1 || Secret_level_table[i]>Last_level)
							break;
						Last_secret_level--;
					}
					else
						break;
				}

			}
		}

	}

	PHYSFS_close(mfile);

	if (Last_level <= 0) {
		free_mission();		//no valid mission loaded
		return 0;
	}

	return 1;
}
Exemplo n.º 14
0
// Set up everything for our music
// NOTE: you might think this is done once per runtime but it's not! It's done for EACH song so that each mission can have it's own descent.sng structure. We COULD optimize that by only doing this once per mission.
void songs_init()
{
    int i = 0;
    char inputline[80+1];
    PHYSFS_file * fp = NULL;
    char sng_file[PATH_MAX];

    Songs_initialized = 0;

    if (BIMSongs != NULL)
        d_free(BIMSongs);

    memset(sng_file, '\0', sizeof(sng_file));
    if (Current_mission != NULL) // try MISSION_NAME.sngdxx - might be rarely used but handy if you want a songfile for a specific mission outside of the mission hog file. use special extension to not crash with other ports of the game
    {
        snprintf(sng_file, strlen(Current_mission_filename)+8, "%s.sngdxx", Current_mission_filename);
        fp = PHYSFSX_openReadBuffered(sng_file);
    }

    if (fp == NULL) // try descent.sngdxx - a songfile specifically for dxx which level authors CAN use (dxx does not care if descent.sng contains MP3/OGG/etc. as well) besides the normal descent.sng containing files other versions of the game cannot play. this way a mission can contain a DOS-Descent compatible OST (hmp files) as well as a OST using MP3, OGG, etc.
        fp = PHYSFSX_openReadBuffered( "descent.sngdxx" );

    if (fp == NULL) // try to open regular descent.sng
        fp = PHYSFSX_openReadBuffered( "descent.sng" );

    if ( fp == NULL ) // No descent.sng available. Define a default song-set
    {
        int predef=30; // define 30 songs - period

        MALLOC(BIMSongs, bim_song_info, predef);
        if (!BIMSongs)
            return;

        strncpy(BIMSongs[SONG_TITLE].filename, "descent.hmp",sizeof(BIMSongs[SONG_TITLE].filename));
        strncpy(BIMSongs[SONG_BRIEFING].filename, "briefing.hmp",sizeof(BIMSongs[SONG_BRIEFING].filename));
        strncpy(BIMSongs[SONG_CREDITS].filename, "credits.hmp",sizeof(BIMSongs[SONG_CREDITS].filename));
        strncpy(BIMSongs[SONG_ENDLEVEL].filename, "endlevel.hmp",sizeof(BIMSongs[SONG_ENDLEVEL].filename));	// can't find it? give a warning
        strncpy(BIMSongs[SONG_ENDGAME].filename, "endgame.hmp",sizeof(BIMSongs[SONG_ENDGAME].filename));	// ditto

        for (i = SONG_FIRST_LEVEL_SONG; i < predef; i++) {
            snprintf(BIMSongs[i].filename, sizeof(BIMSongs[i].filename), "game%02d.hmp", i - SONG_FIRST_LEVEL_SONG + 1);
            if (!PHYSFSX_exists(BIMSongs[i].filename,1))
                snprintf(BIMSongs[i].filename, sizeof(BIMSongs[i].filename), "game%d.hmp", i - SONG_FIRST_LEVEL_SONG);
            if (!PHYSFSX_exists(BIMSongs[i].filename,1))
            {
                memset(BIMSongs[i].filename, '\0', sizeof(BIMSongs[i].filename)); // music not available
                break;
            }
        }
    }
    else
    {
        while (!PHYSFS_eof(fp))
        {
            PHYSFSX_fgets(inputline, 80, fp );
            if ( strlen( inputline ) )
            {
                BIMSongs = d_realloc(BIMSongs, sizeof(bim_song_info)*(i+1));
                memset(BIMSongs[i].filename, '\0', sizeof(BIMSongs[i].filename));
                sscanf( inputline, "%15s", BIMSongs[i].filename );

                if (strrchr(BIMSongs[i].filename, '.'))
                    if (!stricmp(strrchr(BIMSongs[i].filename, '.'), ".hmp") ||
                            !stricmp(strrchr(BIMSongs[i].filename, '.'), ".mp3") ||
                            !stricmp(strrchr(BIMSongs[i].filename, '.'), ".ogg") ||
                            !stricmp(strrchr(BIMSongs[i].filename, '.'), ".aif") ||
                            !stricmp(strrchr(BIMSongs[i].filename, '.'), ".mid") ||
                            !stricmp(strrchr(BIMSongs[i].filename, '.'), ".flac")
                       )
                        i++;
            }
        }

        // HACK: If Descent.hog is patched from 1.0 to 1.5, descent.sng is turncated. So let's patch it up here
        if (i==12 && PHYSFSX_fsize("descent.sng")==422)
        {
            BIMSongs = d_realloc(BIMSongs, sizeof(bim_song_info)*(i+15));
            for (i = 12; i <= 26; i++)
                snprintf(BIMSongs[i].filename, sizeof(BIMSongs[i].filename), "game%02d.hmp", i-4);
        }
    }

    Num_bim_songs = i;
    Songs_initialized = 1;
    if (fp != NULL)
        PHYSFS_close(fp);

    if (GameArg.SndNoMusic)
        GameCfg.MusicType = MUSIC_TYPE_NONE;

    // If SDL_Mixer is not supported (or deactivated), switch to no-music type if SDL_mixer-related music type was selected
#ifdef USE_SDLMIXER
    if (GameArg.SndDisableSdlMixer)
#else
    if (1)
#endif
    {
#ifndef _WIN32
        if (GameCfg.MusicType == MUSIC_TYPE_BUILTIN)
            GameCfg.MusicType = MUSIC_TYPE_NONE;
#endif
        if (GameCfg.MusicType == MUSIC_TYPE_CUSTOM)
            GameCfg.MusicType = MUSIC_TYPE_NONE;
    }

    if (GameCfg.MusicType == MUSIC_TYPE_REDBOOK)
        RBAInit();
#ifdef USE_SDLMIXER
    else if (GameCfg.MusicType == MUSIC_TYPE_CUSTOM)
        jukebox_load();
#endif

    songs_set_volume(GameCfg.MusicVolume);
}
Exemplo n.º 15
0
//loads the specfied mission from the mission list.
//build_mission_list() must have been called.
//Returns true if mission loaded ok, else false.
static int load_mission(mle *mission)
{
	PHYSFS_file *mfile;
	char buf[PATH_MAX], *v;

	if (Current_mission)
		free_mission();
	MALLOC(Current_mission, Mission, 1);
	if (!Current_mission) return 0;
	*(mle *) Current_mission = *mission;
	Current_mission->path = d_strdup(mission->path);
	Current_mission->filename = Current_mission->path + (mission->filename - mission->path);
	Current_mission->n_secret_levels = 0;
	Current_mission->enhanced = 0;

	//init vars
	Last_level = 0;
	Last_secret_level = 0;
	memset(&Briefing_text_filename, '\0', sizeof(Briefing_text_filename));
	memset(&Ending_text_filename, '\0', sizeof(Ending_text_filename));

	// for Descent 1 missions, load descent.hog
	if (EMULATING_D1) {
		if (!PHYSFSX_contfile_init("descent.hog", 1))
			Warning("descent.hog not available, this mission may be missing some files required for briefings and exit sequence\n");
		if (!stricmp(Current_mission_filename, D1_MISSION_FILENAME))
			return load_mission_d1();
	}

	if (PLAYING_BUILTIN_MISSION) {
		switch (Current_mission->builtin_hogsize) {
		case SHAREWARE_MISSION_HOGSIZE:
		case MAC_SHARE_MISSION_HOGSIZE:
			strcpy(Briefing_text_filename,BIMD2_BRIEFING_FILE_SHARE);
			strcpy(Ending_text_filename,BIMD2_ENDING_FILE_SHARE);
			return load_mission_shareware();
			break;
		case OEM_MISSION_HOGSIZE:
			strcpy(Briefing_text_filename,BIMD2_BRIEFING_FILE_OEM);
			strcpy(Ending_text_filename,BIMD2_ENDING_FILE_OEM);
			return load_mission_oem();
			break;
		default:
			Int3(); // fall through
		case FULL_MISSION_HOGSIZE:
		case FULL_10_MISSION_HOGSIZE:
		case MAC_FULL_MISSION_HOGSIZE:
			strcpy(Briefing_text_filename,BIMD2_BRIEFING_FILE);
			// continue on... (use d2.mn2 from hogfile)
			break;
		}
	}

	//read mission from file

	switch (mission->location) {
	case ML_MISSIONDIR:
		strcpy(buf,MISSION_DIR);
		break;
	default:
		Int3();							//fall through
	case ML_CURDIR:
		strcpy(buf,"");
		break;
	}
	strcat(buf, mission->path);
	if (mission->descent_version == 2)
		strcat(buf,".mn2");
	else
		strcat(buf,".msn");

	PHYSFSEXT_locateCorrectCase(buf);

	mfile = PHYSFSX_openReadBuffered(buf);
	if (mfile == NULL) {
		free_mission();
		return 0;		//error!
	}

	//for non-builtin missions, load HOG
	if (!PLAYING_BUILTIN_MISSION)
	{
		strcpy(buf+strlen(buf)-4,".hog");		//change extension
		PHYSFSEXT_locateCorrectCase(buf);
		if (PHYSFSX_exists(buf,1))
			PHYSFSX_contfile_init(buf, 0);

		snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.tex",Current_mission_filename);
		if (!PHYSFSX_exists(Briefing_text_filename,1))
			snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.txb",Current_mission_filename);
		snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.tex",Current_mission_filename);
		if (!PHYSFSX_exists(Ending_text_filename,1))
			snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.txb",Current_mission_filename);
	}

	while (PHYSFSX_fgets(buf,sizeof(buf),mfile)) {
		if (istok(buf,"name") && !Current_mission->enhanced) {
			Current_mission->enhanced = 0;
			continue;						//already have name, go to next line
		}
		if (istok(buf,"xname") && !Current_mission->enhanced) {
			Current_mission->enhanced = 1;
			continue;						//already have name, go to next line
		}
		if (istok(buf,"zname") && !Current_mission->enhanced) {
			Current_mission->enhanced = 2;
			continue;						//already have name, go to next line
		}
		else if (istok(buf,"type"))
			continue;						//already have name, go to next line
		else if (istok(buf,"briefing")) {
			if ((v = get_value(buf)) != NULL) {
				add_term(v);
				if (strlen(v) < FILENAME_LEN && strlen(v) > 0)
				{
					char *tmp, *ptr;
					MALLOC(tmp, char, FILENAME_LEN);
					snprintf(tmp, FILENAME_LEN, "%s", v);
					if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one.
						*ptr = '\0';
					strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion
					if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
						snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					else // ... otherwise ...
					{
						if ((ptr = strrchr(tmp, '.')))
							*ptr = '\0';
						strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension
						if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
							snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					}
					d_free(tmp);
				}
			}
		}
		else if (istok(buf,"ending")) {
			if ((v = get_value(buf)) != NULL) {
				add_term(v);
				if (strlen(v) < FILENAME_LEN && strlen(v) > 0)
				{
					char *tmp, *ptr;
					MALLOC(tmp, char, FILENAME_LEN);
					snprintf(tmp, FILENAME_LEN, "%s", v);
					if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one.
						*ptr = '\0';
					strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion
					if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
						snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					else // ... otherwise ...
					{
						if ((ptr = strrchr(tmp, '.')))
							*ptr = '\0';
						strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension
						if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
							snprintf(Ending_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					}
					d_free(tmp);
				}
			}
		}
		else if (istok(buf,"num_levels")) {

			if ((v=get_value(buf))!=NULL) {
				int n_levels,i;

				n_levels = atoi(v);

				for (i=0;i<n_levels;i++) {
					PHYSFSX_fgets(buf,sizeof(buf),mfile);
					add_term(buf);
					if (strlen(buf) <= 12) {
						strcpy(Level_names[i],buf);
						Last_level++;
					}
					else
						break;
				}

			}
		}
		else if (istok(buf,"num_secrets")) {
			if ((v=get_value(buf))!=NULL) {
				int i;

				N_secret_levels = atoi(v);

				Assert(N_secret_levels <= MAX_SECRET_LEVELS_PER_MISSION);

				for (i=0;i<N_secret_levels;i++) {
					char *t;

					PHYSFSX_fgets(buf,sizeof(buf),mfile);
					if ((t=strchr(buf,','))!=NULL) *t++=0;
					else
						break;

					add_term(buf);
					if (strlen(buf) <= 12) {
						strcpy(Secret_level_names[i],buf);
						Secret_level_table[i] = atoi(t);
						if (Secret_level_table[i]<1 || Secret_level_table[i]>Last_level)
							break;
						Last_secret_level--;
					}
					else
						break;
				}

			}
		}

	}

	PHYSFS_close(mfile);

	if (Last_level <= 0) {
		free_mission();		//no valid mission loaded
		return 0;
	}

	// re-read default HAM file, in case this mission brings it's own version of it
	free_polygon_models();
	read_hamfile();

	if (Current_mission->enhanced) {
		char t[50];
		sprintf(t,"%s.ham",Current_mission_filename);
		bm_read_extra_robots(t, Current_mission->enhanced);
		init_extra_robot_movie(Current_mission_filename);
	}

	return 1;
}
Exemplo n.º 16
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
}
Exemplo n.º 17
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
}
Exemplo n.º 18
0
int songs_play_song( int songnum, int repeat )
{
    songs_init();
    if (!Songs_initialized)
        return 0;

    switch (GameCfg.MusicType)
    {
    case MUSIC_TYPE_BUILTIN:
    {
        // EXCEPTION: If SONG_ENDLEVEL is not available, continue playing level song.
        if (Song_playing >= SONG_FIRST_LEVEL_SONG && songnum == SONG_ENDLEVEL && !PHYSFSX_exists(BIMSongs[songnum].filename, 1))
            return Song_playing;

        Song_playing = -1;
#ifdef _WIN32
        if (GameArg.SndDisableSdlMixer)
        {
            if (digi_win32_play_midi_song( BIMSongs[songnum].filename, repeat )) // NOTE: If SDL_mixer active, this will still be called in mix_play_file in case file is hmp
            {
                Song_playing = songnum;
            }
        }
        else
#endif
#ifdef USE_SDLMIXER
        {
            if (mix_play_file(BIMSongs[songnum].filename, repeat, NULL))
            {
                Song_playing = songnum;
            }
        }
#endif
        break;
    }
    case MUSIC_TYPE_REDBOOK:
    {
        int num_tracks = RBAGetNumberOfTracks();

        Song_playing = -1;
        if ((songnum < SONG_ENDGAME) && (songnum + 2 <= num_tracks))
        {
            if (RBAPlayTracks(songnum + 2, songnum + 2, repeat ? redbook_repeat_func : NULL))
            {
                Redbook_playing = songnum + 2;
                Song_playing = songnum;
            }
        }
        else if ((songnum == SONG_ENDGAME) && (REDBOOK_ENDGAME_TRACK <= num_tracks)) // The endgame track is the last track
        {
            if (RBAPlayTracks(REDBOOK_ENDGAME_TRACK, REDBOOK_ENDGAME_TRACK, repeat ? redbook_repeat_func : NULL))
            {
                Redbook_playing = REDBOOK_ENDGAME_TRACK;
                Song_playing = songnum;
            }
        }
        else if ((songnum > SONG_ENDGAME) && (songnum + 1 <= num_tracks))
        {
            if (RBAPlayTracks(songnum + 1, songnum + 1, repeat ? redbook_repeat_func : NULL))
            {
                Redbook_playing = songnum + 1;
                Song_playing = songnum;
            }
        }
        break;
    }
#ifdef USE_SDLMIXER
    case MUSIC_TYPE_CUSTOM:
    {
        // EXCEPTION: If SONG_ENDLEVEL is undefined, continue playing level song.
        if (Song_playing >= SONG_FIRST_LEVEL_SONG && songnum == SONG_ENDLEVEL && !strlen(GameCfg.CMMiscMusic[songnum]))
            return Song_playing;

        Song_playing = -1;
        if (mix_play_file(GameCfg.CMMiscMusic[songnum], repeat, NULL))
            Song_playing = songnum;
        break;
    }
#endif
    default:
        Song_playing = -1;
        break;
    }

    // If we couldn't play the song, most likely because it wasn't specified, play no music.
    if (Song_playing == -1)
        songs_stop_all();

    return Song_playing;
}
Exemplo n.º 19
0
int load_mine_data_compiled(PHYSFS_file *LoadFile)
{
	int     i, segnum, sidenum;
	ubyte   compiled_version;
	short   temp_short;
	ushort  temp_ushort = 0;
	ubyte   bit_mask;

	d1_pig_present = PHYSFSX_exists(D1_PIGFILE,1);
#if 0 // the following will be deleted once reading old pigfiles works reliably
	if (d1_pig_present) {
		PHYSFS_file * d1_Piggy_fp = PHYSFSX_openReadBuffered( D1_PIGFILE );
		switch (PHYSFS_fileLength(d1_Piggy_fp)) {
		case D1_SHARE_BIG_PIGSIZE:
		case D1_SHARE_10_PIGSIZE:
		case D1_SHARE_PIGSIZE:
		case D1_10_BIG_PIGSIZE:
		case D1_10_PIGSIZE:
			//d1_pig_present = 0;
		}
		PHYSFS_close (d1_Piggy_fp);
	}
#endif

	if (!strcmp(strchr(Gamesave_current_filename, '.'), ".sdl"))
		New_file_format_load = 0; // descent 1 shareware
	else
		New_file_format_load = 1;

	//	For compiled levels, textures map to themselves, prevent tmap_override always being gray,
	//	bug which Matt and John refused to acknowledge, so here is Mike, fixing it.
#ifdef EDITOR
	for (i=0; i<MAX_TEXTURES; i++)
		tmap_xlate_table[i] = i;
#endif

//	memset( Segments, 0, sizeof(segment)*MAX_SEGMENTS );
	fuelcen_reset();

	//=============================== Reading part ==============================
	compiled_version = PHYSFSX_readByte(LoadFile);
	(void)compiled_version;

	if (New_file_format_load)
		Num_vertices = PHYSFSX_readShort(LoadFile);
	else
		Num_vertices = PHYSFSX_readInt(LoadFile);
	Assert( Num_vertices <= MAX_VERTICES );

	if (New_file_format_load)
		Num_segments = PHYSFSX_readShort(LoadFile);
	else
		Num_segments = PHYSFSX_readInt(LoadFile);
	Assert( Num_segments <= MAX_SEGMENTS );

	for (i = 0; i < Num_vertices; i++)
		PHYSFSX_readVector( &(Vertices[i]), LoadFile);

	for (segnum=0; segnum<Num_segments; segnum++ )	{

		#ifdef EDITOR
		Segments[segnum].segnum = segnum;
		Segments[segnum].group = 0;
		#endif

		if (New_file_format_load)
			bit_mask = PHYSFSX_readByte(LoadFile);
		else
			bit_mask = 0x7f; // read all six children and special stuff...

		if (Gamesave_current_version == 5) { // d2 SHAREWARE level
			read_special(segnum,bit_mask,LoadFile);
			read_verts(segnum,LoadFile);
			read_children(segnum,bit_mask,LoadFile);
		} else {
			read_children(segnum,bit_mask,LoadFile);
			read_verts(segnum,LoadFile);
			if (Gamesave_current_version <= 1) { // descent 1 level
				read_special(segnum,bit_mask,LoadFile);
			}
		}

		Segments[segnum].objects = -1;

		if (Gamesave_current_version <= 5) { // descent 1 thru d2 SHAREWARE level
			// Read fix	Segments[segnum].static_light (shift down 5 bits, write as short)
			temp_ushort = PHYSFSX_readShort(LoadFile);
			Segment2s[segnum].static_light	= ((fix)temp_ushort) << 4;
			//PHYSFS_read( LoadFile, &Segments[segnum].static_light, sizeof(fix), 1 );
		}

		// Read the walls as a 6 byte array
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )	{
			Segments[segnum].sides[sidenum].pad = 0;
		}

		if (New_file_format_load)
			bit_mask = PHYSFSX_readByte(LoadFile);
		else
			bit_mask = 0x3f; // read all six sides
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
			ubyte byte_wallnum;

			if (bit_mask & (1 << sidenum)) {
				byte_wallnum = PHYSFSX_readByte(LoadFile);
				if ( byte_wallnum == 255 )
					Segments[segnum].sides[sidenum].wall_num = -1;
				else
					Segments[segnum].sides[sidenum].wall_num = byte_wallnum;
			} else
					Segments[segnum].sides[sidenum].wall_num = -1;
		}

		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )	{

			if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) )	{
				// Read short Segments[segnum].sides[sidenum].tmap_num;
				if (New_file_format_load) {
					temp_ushort = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].tmap_num = temp_ushort & 0x7fff;
				} else
					Segments[segnum].sides[sidenum].tmap_num = PHYSFSX_readShort(LoadFile);

				if (Gamesave_current_version <= 1)
					Segments[segnum].sides[sidenum].tmap_num = convert_d1_tmap_num(Segments[segnum].sides[sidenum].tmap_num);

				if (New_file_format_load && !(temp_ushort & 0x8000))
					Segments[segnum].sides[sidenum].tmap_num2 = 0;
				else {
					// Read short Segments[segnum].sides[sidenum].tmap_num2;
					Segments[segnum].sides[sidenum].tmap_num2 = PHYSFSX_readShort(LoadFile);
					if (Gamesave_current_version <= 1 && Segments[segnum].sides[sidenum].tmap_num2 != 0)
						Segments[segnum].sides[sidenum].tmap_num2 = convert_d1_tmap_num(Segments[segnum].sides[sidenum].tmap_num2);
				}

				// Read uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short)
				for (i=0; i<4; i++ )	{
					temp_short = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5;
					temp_short = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5;
					temp_ushort = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1;
					//PHYSFS_read( LoadFile, &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1 );
				}
			} else {
				Segments[segnum].sides[sidenum].tmap_num = 0;
				Segments[segnum].sides[sidenum].tmap_num2 = 0;
				for (i=0; i<4; i++ )	{
					Segments[segnum].sides[sidenum].uvls[i].u = 0;
					Segments[segnum].sides[sidenum].uvls[i].v = 0;
					Segments[segnum].sides[sidenum].uvls[i].l = 0;
				}
			}
		}
	}

#if 0
	{
		FILE *fp;

		fp = fopen("segments.out", "wt");
		for (i = 0; i <= Highest_segment_index; i++) {
			side	sides[MAX_SIDES_PER_SEGMENT];	// 6 sides
			short	children[MAX_SIDES_PER_SEGMENT];	// indices of 6 children segments, front, left, top, right, bottom, back
			short	verts[MAX_VERTICES_PER_SEGMENT];	// vertex ids of 4 front and 4 back vertices
			int		objects;								// pointer to objects in this segment

			for (j = 0; j < MAX_SIDES_PER_SEGMENT; j++) {
				sbyte   type;                           // replaces num_faces and tri_edge, 1 = quad, 2 = 0:2 triangulation, 3 = 1:3 triangulation
				ubyte	pad;									//keep us longword alligned
				short	wall_num;
				short	tmap_num;
				short	tmap_num2;
				uvl		uvls[4];
				vms_vector	normals[2];						// 2 normals, if quadrilateral, both the same.
				fprintf(fp, "%d\n", Segments[i].sides[j].type);
				fprintf(fp, "%d\n", Segments[i].sides[j].pad);
				fprintf(fp, "%d\n", Segments[i].sides[j].wall_num);
				fprintf(fp, "%d\n", Segments[i].tmap_num);

			}
			fclose(fp);
		}
	}
#endif

	Highest_vertex_index = Num_vertices-1;
	Highest_segment_index = Num_segments-1;

	validate_segment_all();			// Fill in side type and normals.

	for (i=0; i<Num_segments; i++) {
		if (Gamesave_current_version > 5)
			segment2_read(&Segment2s[i], LoadFile);
		fuelcen_activate( &Segments[i], Segment2s[i].special );
	}

	reset_objects(1);		//one object, the player

	return 0;
}
Exemplo n.º 20
0
int properties_init()
{
	int sbytes = 0;
	char temp_name_read[16];
	char temp_name[16];
	grs_bitmap temp_bitmap;
	digi_sound temp_sound;
	DiskBitmapHeader bmh;
	DiskSoundHeader sndh;
	int header_size, N_bitmaps, N_sounds;
	int i,size;
	int Pigdata_start;
	int pigsize;
	int retval;

	hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
	hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );

	
	for (i=0; i<MAX_SOUND_FILES; i++ )	{
#ifdef ALLEGRO
		GameSounds[i].len = 0;
#else
		GameSounds[i].length = 0;
#endif
		GameSounds[i].data = NULL;
		SoundOffset[i] = 0;

//added on 11/13/99 by Victor Rachels to ready for changing freq
                GameSounds[i].bits = 0;
                GameSounds[i].freq = 0;
//end this section addition - VR
	}

	for (i=0; i<MAX_BITMAP_FILES; i++ )		{
		GameBitmapXlat[i] = i;
		GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
	}

	if ( !bogus_bitmap_initialized )	{
		int i;
		ubyte c;
		bogus_bitmap_initialized = 1;
		c = gr_find_closest_color( 0, 0, 63 );
		for (i=0; i<4096; i++ ) bogus_data[i] = c;
		c = gr_find_closest_color( 63, 0, 0 );
		// Make a big red X !
		for (i=0; i<64; i++ )	{
			bogus_data[i*64+i] = c;
			bogus_data[i*64+(63-i)] = c;
		}
		gr_init_bitmap (&bogus_bitmap, 0, 0, 0, 64, 64, 64, bogus_data);
		piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
#ifdef ALLEGRO
		bogus_sound.len = 64*64;
#else
        bogus_sound.length = 64*64;
#endif
		bogus_sound.data = bogus_data;
//added on 11/13/99 by Victor Rachels to ready for changing freq
                bogus_sound.freq = 11025;
                bogus_sound.bits = 8;
//end this section addition - VR
		GameBitmapOffset[0] = 0;
	}
	
	Piggy_fp = PHYSFSX_openReadBuffered(DEFAULT_PIGFILE_REGISTERED);
	if (Piggy_fp==NULL)
	{
		if (!PHYSFSX_exists("BITMAPS.TBL",1) && !PHYSFSX_exists("BITMAPS.BIN",1))
			Error("Cannot find " DEFAULT_PIGFILE_REGISTERED " or BITMAPS.TBL");
		return 1;	// need to run gamedata_read_tbl
	}

	pigsize = PHYSFS_fileLength(Piggy_fp);
	switch (pigsize) {
		case D1_SHARE_BIG_PIGSIZE:
		case D1_SHARE_10_PIGSIZE:
		case D1_SHARE_PIGSIZE:
			PCSharePig = 1;
			Pigdata_start = 0;
			break;
		case D1_10_BIG_PIGSIZE:
		case D1_10_PIGSIZE:
			Pigdata_start = 0;
			break;
		default:
			Warning("Unknown size for " DEFAULT_PIGFILE_REGISTERED);
			Int3();
			// fall through
		case D1_MAC_PIGSIZE:
		case D1_MAC_SHARE_PIGSIZE:
			MacPig = 1;
		case D1_PIGSIZE:
		case D1_OEM_PIGSIZE:
			Pigdata_start = PHYSFSX_readInt(Piggy_fp );
			break;
	}
	
	HiresGFXAvailable = MacPig;	// for now at least

	if (PCSharePig)
		retval = PIGGY_PC_SHAREWARE;	// run gamedata_read_tbl in shareware mode
	else if (GameArg.EdiNoBm || (!PHYSFSX_exists("BITMAPS.TBL",1) && !PHYSFSX_exists("BITMAPS.BIN",1)))
	{
		properties_read_cmp( Piggy_fp );	// Note connection to above if!!!
		for (i = 0; i < MAX_BITMAP_FILES; i++)
		{
			GameBitmapXlat[i] = PHYSFSX_readShort(Piggy_fp);
			if (PHYSFS_eof(Piggy_fp))
				break;
		}
		retval = 0;	// don't run gamedata_read_tbl
	}
	else
		retval = 1;	// run gamedata_read_tbl

	PHYSFSX_fseek( Piggy_fp, Pigdata_start, SEEK_SET );
	size = PHYSFS_fileLength(Piggy_fp) - Pigdata_start;

	N_bitmaps = PHYSFSX_readInt(Piggy_fp);
	size -= sizeof(int);
	N_sounds = PHYSFSX_readInt(Piggy_fp);
	size -= sizeof(int);

	header_size = (N_bitmaps*sizeof(DiskBitmapHeader)) + (N_sounds*sizeof(DiskSoundHeader));

	for (i=0; i<N_bitmaps; i++ )	{
		DiskBitmapHeader_read(&bmh, Piggy_fp);
		
		GameBitmapFlags[i+1] = 0;
		if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_TRANSPARENT;
		if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_SUPER_TRANSPARENT;
		if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i+1] |= BM_FLAG_NO_LIGHTING;
		if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i+1] |= BM_FLAG_RLE;

		GameBitmapOffset[i+1] = bmh.offset + header_size + (sizeof(int)*2) + Pigdata_start;
		Assert( (i+1) == Num_bitmap_files );

		//size -= sizeof(DiskBitmapHeader);
		memcpy( temp_name_read, bmh.name, 8 );
		temp_name_read[8] = 0;
		if ( bmh.dflags & DBM_FLAG_ABM )	
			sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
		else
			strcpy( temp_name, temp_name_read );

		memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
		gr_init_bitmap( &temp_bitmap, 0, 0, 0, 
			(bmh.dflags & DBM_FLAG_LARGE) ? bmh.width + 256 : bmh.width, bmh.height,
			(bmh.dflags & DBM_FLAG_LARGE) ? bmh.width + 256 : bmh.width, Piggy_bitmap_cache_data);
		temp_bitmap.bm_flags |= BM_FLAG_PAGED_OUT;
		temp_bitmap.avg_color = bmh.avg_color;

		if (MacPig)
		{
			// HACK HACK HACK!!!!!
			if (!strnicmp(bmh.name, "cockpit", 7) || !strnicmp(bmh.name, "status", 6) || !strnicmp(bmh.name, "rearview", 8)) {
				temp_bitmap.bm_w = temp_bitmap.bm_rowsize = 640;
				if (GameBitmapFlags[i+1] & BM_FLAG_RLE)
					GameBitmapFlags[i+1] |= BM_FLAG_RLE_BIG;
			}
			if (!strnicmp(bmh.name, "cockpit", 7) || !strnicmp(bmh.name, "rearview", 8))
				temp_bitmap.bm_h = 480;
		}
		
		piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
	}

	for (i=0; !MacPig && i<N_sounds; i++ )     {
		DiskSoundHeader_read(&sndh, Piggy_fp);
		
		//size -= sizeof(DiskSoundHeader);
#ifdef ALLEGRO
		temp_sound.len = sndh.length;
#else
		temp_sound.length = sndh.length;
#endif

//added on 11/13/99 by Victor Rachels to ready for changing freq
                temp_sound.bits = 8;
                temp_sound.freq = 11025;
//end this section addition - VR
		temp_sound.data = (ubyte *)(sndh.offset + header_size + (sizeof(int)*2)+Pigdata_start);
		SoundOffset[Num_sound_files] = sndh.offset + header_size + (sizeof(int)*2)+Pigdata_start;
		if (PCSharePig)
			SoundCompressed[Num_sound_files] = sndh.data_length;
		memcpy( temp_name_read, sndh.name, 8 );
		temp_name_read[8] = 0;
		piggy_register_sound( &temp_sound, temp_name_read, 1 );
                sbytes += sndh.length;
	}

	if (!MacPig)
	{
		SoundBits = d_malloc( sbytes + 16 );
		if ( SoundBits == NULL )
			Error( "Not enough memory to load DESCENT.PIG sounds\n");
	}

#if 1	//def EDITOR
	Piggy_bitmap_cache_size	= size - header_size - sbytes + 16;
	Assert( Piggy_bitmap_cache_size > 0 );
#else
	Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
	if (GameArg.SysLowMem)
		Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
#endif
	BitmapBits = d_malloc( Piggy_bitmap_cache_size );
	if ( BitmapBits == NULL )
		Error( "Not enough memory to load DESCENT.PIG bitmaps\n" );
	Piggy_bitmap_cache_data = BitmapBits;	
	Piggy_bitmap_cache_next = 0;

	return retval;
}
Exemplo n.º 21
0
//loads a level (.LVL) file from disk
//returns 0 if success, else error code
int load_level(const char * filename_passed)
{
#ifdef EDITOR
	int use_compiled_level=1;
#endif
	PHYSFS_file * LoadFile;
	char filename[PATH_MAX];
	int sig, minedata_offset, gamedata_offset, hostagetext_offset;
	int mine_err, game_err;
#ifdef NETWORK
	int i;
#endif

#ifdef NETWORK
   if (Game_mode & GM_NETWORK)
	 {
	  for (i=0;i<MAX_POWERUP_TYPES;i++)
		{
			MaxPowerupsAllowed[i]=0;
			PowerupsInMine[i]=0;
		}
	 }
#endif

	#ifdef COMPACT_SEGS
	ncache_flush();
	#endif

	#ifndef RELEASE
	Level_being_loaded = filename_passed;
	#endif

	strcpy(filename,filename_passed);

#ifdef EDITOR
	//if we have the editor, try the LVL first, no matter what was passed.
	//if we don't have an LVL, try what was passed or SDL/RDL  
	//if we don't have the editor, we just use what was passed

	change_filename_extension(filename,filename_passed,".lvl");
	use_compiled_level = 0;

	if (!PHYSFSX_exists(filename,1))
	{
		char *p = strrchr(filename_passed, '.');

		if (d_stricmp(p, ".lvl"))
			strcpy(filename, filename_passed);	// set to what was passed
		else
			change_filename_extension(filename, filename, ".rdl");
		use_compiled_level = 1;
	}		
#endif

	if (!PHYSFSX_exists(filename,1))
		sprintf(filename,"%s%s",MISSION_DIR,filename_passed);

	LoadFile = PHYSFSX_openReadBuffered( filename );

	if (!LoadFile)	{
		#ifdef EDITOR
			return 1;
		#else
			Error("Can't open file <%s>\n",filename);
		#endif
	}

	strcpy( Gamesave_current_filename, filename );

	sig                      = PHYSFSX_readInt(LoadFile);
	Gamesave_current_version = PHYSFSX_readInt(LoadFile);
	minedata_offset          = PHYSFSX_readInt(LoadFile);
	gamedata_offset          = PHYSFSX_readInt(LoadFile);

	Assert(sig == MAKE_SIG('P','L','V','L'));
	(void)sig;

	if (Gamesave_current_version < 5)
		hostagetext_offset = PHYSFSX_readInt(LoadFile);

	PHYSFSX_fseek(LoadFile,minedata_offset,SEEK_SET);
	#ifdef EDITOR
	if (!use_compiled_level)
		mine_err = load_mine_data(LoadFile);
	else
	#endif
		//NOTE LINK TO ABOVE!!
		mine_err = load_mine_data_compiled(LoadFile);

	/* !!!HACK!!!
	 * Descent 1 - Level 19: OBERON MINE has some ugly overlapping rooms (segment 484).
	 * HACK to make this issue less visible by moving one vertex a little.
	 */
	if (Current_mission && !d_stricmp("Descent: First Strike",Current_mission_longname) && !d_stricmp("level19.rdl",filename) && PHYSFS_fileLength(LoadFile) == 136706)
		Vertices[1905].z =-385*F1_0;

	if (mine_err == -1) {   //error!!
		PHYSFS_close(LoadFile);
		return 2;
	}

	PHYSFSX_fseek(LoadFile,gamedata_offset,SEEK_SET);
	game_err = load_game_data(LoadFile);

	if (game_err == -1) {   //error!!
		PHYSFS_close(LoadFile);
		return 3;
	}

	(void)hostagetext_offset;

	//======================== CLOSE FILE =============================

	PHYSFS_close( LoadFile );

	#if 0	//def EDITOR
	#ifndef RELEASE
	write_game_text_file(filename);
	if (Errors_in_mine) {
		if (is_real_level(filename)) {
			char  ErrorMessage[200];

			sprintf( ErrorMessage, "Warning: %i errors in %s!\n", Errors_in_mine, Level_being_loaded );
			stop_time();
			gr_palette_load(gr_palette);
			nm_messagebox( NULL, 1, "Continue", ErrorMessage );
			start_time();
		}
	}
	#endif
	#endif

	#ifdef EDITOR
	//If an old version, ask the use if he wants to save as new version
	if (((LEVEL_FILE_VERSION>1) && Gamesave_current_version<LEVEL_FILE_VERSION) || mine_err==1 || game_err==1) {
		char  ErrorMessage[200];

		sprintf( ErrorMessage, "You just loaded a old version level.  Would\n"
						"you like to save it as a current version level?");

		gr_palette_load(gr_palette);
		if (nm_messagebox( NULL, 2, "Don't Save", "Save", ErrorMessage )==1)
			save_level(filename);
	}
	#endif

	#ifdef EDITOR
	if (EditorWindow)
		editor_status_fmt("Loaded NEW mine %s, \"%s\"",filename,Current_level_name);
	#endif

	#if !defined(NDEBUG) && !defined(COMPACT_SEGS)
	if (check_segment_connections())
		nm_messagebox( "ERROR", 1, "Ok", 
				"Connectivity errors detected in\n"
				"mine.  See monochrome screen for\n"
				"details, and contact Matt or Mike." );
	#endif

	return 0;
}