diff --git a/panda/src/express/multifile.I b/panda/src/express/multifile.I index 51ea640f66..a5a47cfb01 100644 --- a/panda/src/express/multifile.I +++ b/panda/src/express/multifile.I @@ -377,6 +377,36 @@ get_magic_number() { return string(_header, _header_size); } +//////////////////////////////////////////////////////////////////// +// Function: Multifile::set_header_prefix +// Access: Published +// Description: Sets the string which is written to the Multifile +// before the Multifile header. This string must begin +// with a hash mark and end with a newline character, +// and include at least 6 characters; and if it includes +// embedded newline characters, each one must be +// followed by a hash mark. +// +// This is primarily useful as a simple hack to allow +// p3d applications to be run directly from the command +// line on Unix-like systems. +//////////////////////////////////////////////////////////////////// +INLINE void Multifile:: +set_header_prefix(const string &header_prefix) { + _header_prefix = header_prefix; +} + +//////////////////////////////////////////////////////////////////// +// Function: Multifile::get_header_prefix +// Access: Published +// Description: Returns the string that preceded the Multifile header +// on the file, if any. See set_header_prefix(). +//////////////////////////////////////////////////////////////////// +INLINE const string &Multifile:: +get_header_prefix() const { + return _header_prefix; +} + //////////////////////////////////////////////////////////////////// // Function: Multifile::word_to_streampos // Access: Private diff --git a/panda/src/express/multifile.cxx b/panda/src/express/multifile.cxx index 863fb8bca5..76678ee1e9 100644 --- a/panda/src/express/multifile.cxx +++ b/panda/src/express/multifile.cxx @@ -1535,6 +1535,38 @@ read_index() { close(); return false; } + + // Here's a special case: if the multifile begins with a hash + // character, then we skip at least 6 characters (the length of the + // original header string we already read), and continue reading and + // discarding lines of ASCII text, until we come across a nonempty + // line that does not begin with a hash character. This allows a + // P3D application (which is a multifile) to be run directly on the + // command line on Unix-based systems. + _header_prefix = string(); + + if (this_header[0] == '#') { + _header_prefix = string(this_header, _header_size); + int ch = '#'; + + while (ch != EOF && ch == '#') { + // Skip to the end of the line. + while (ch != EOF && ch != '\n') { + _header_prefix += ch; + ch = read->get(); + } + // Skip to the first non-whitespace character of the line. + while (ch != EOF && (isspace(ch) || ch == '\r')) { + _header_prefix += ch; + ch = read->get(); + } + } + + // Now fill up the header. + this_header[0] = ch; + read->read(this_header + 1, _header_size - 1); + } + if (memcmp(this_header, _header, _header_size) != 0) { express_cat.info() << _multifile_name << " is not a Multifile.\n"; @@ -1657,6 +1689,7 @@ write_header() { nassertr(_write != (ostream *)NULL, false); nassertr(_write->tellp() == (streampos)0, false); + _write->write(_header_prefix.data(), _header_prefix.size()); _write->write(_header, _header_size); StreamWriter writer(_write, false); writer.add_int16(_current_major_ver); diff --git a/panda/src/express/multifile.h b/panda/src/express/multifile.h index d1ebfbd77c..21c8cf449e 100644 --- a/panda/src/express/multifile.h +++ b/panda/src/express/multifile.h @@ -114,6 +114,9 @@ PUBLISHED: static INLINE string get_magic_number(); + INLINE void set_header_prefix(const string &header_prefix); + INLINE const string &get_header_prefix() const; + public: bool read_subfile(int index, string &result); bool read_subfile(int index, pvector &result); @@ -199,6 +202,7 @@ private: pfstream _read_write_file; StreamWrapper _read_write_filew; Filename _multifile_name; + string _header_prefix; int _file_major_ver; int _file_minor_ver;