Jump to content
  • Advertisement

Afr0m@n

Member
  • Content Count

    492
  • Joined

  • Last visited

Community Reputation

100 Neutral

About Afr0m@n

  • Rank
    Member
  1. Hm, what about sounds and such? Thanks for the advice though, I'll drop the zip loading for now and see how things turns out when more is known about the final complete datasize. [smile]
  2. Well, I'm not exactly sure yet, but if it's of any importance, I'd guesstimate roughly between 3.5 - 5 gigs of uncompressed data. At least a gig of those comes from the meshes alone, which are ASCII *.x files. I might decide to convert them to a binary format later on, but right now that really isn't my first priority, seeing as I'd like to concentrate on the game.
  3. Is there any way to do this? I've been searching around the net some, and the only documented way of loading (and, thus, rendering) meshes on MSDN seems to be to add references to all mesh files inside your project. This is something I'd really want to avoid doing, as the data I'm working with takes up so much space that keeping it uncompressed just seems like a really bad idea. Of course I could zip it and ask the users to zip it out to a specific folder before running my game, but that just seems like it would really push away alot of casual users. What I'm using currently is the Sharp Zip Lib, and it only returns loaded zip entries as a byte array (logically enough). This isn't a problem in itself, but I just cannot seem to integrate it with the way XNA handles meshes! :( Just as a reference, here's the code I'm currently using to load my data from zip archives: using System; using System.IO; using System.Collections.Generic; using TSOClient; using ICSharpCode.SharpZipLib.Zip; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; namespace TSOClient.Loading { public class InitialLoadingHandler { public static void Initialize() { Events.OnLoadInitialData += new LoadInitialDataEventHandler(OnLoadInitialData); } private static void OnLoadInitialData(List<string> Directories) { //Go through all the directories that were passed to this function. foreach (string Dir in Directories.ToArray()) { string[] Files = Directory.GetFiles(Dir, "*.zip"); //Go through all the zip archives in the directory. foreach (string Archive in Files) { using (ZipInputStream ZStream = new ZipInputStream(File.OpenRead(Archive))) { ZipEntry Entry; //Get all the entries in the zip archive. while ((Entry = ZStream.GetNextEntry()) != null) { if(Entry.Name.Contains("body")) { byte[] Data = new byte[Entry.Size]; ZStream.Read(Data, 0, (int)Entry.Size); DataManager.AddLoadedMesh(Data); } else if (Entry.Name.Contains("bottom")) { byte[] Data = new byte[Entry.Size]; ZStream.Read(Data, 0, (int)Entry.Size); DataManager.AddLoadedMesh(Data); } else if (Entry.Name.Contains("face")) { byte[] Data = new byte[Entry.Size]; ZStream.Read(Data, 0, (int)Entry.Size); DataManager.AddLoadedMesh(Data); } else if (Entry.Name.Contains("hair")) { byte[] Data = new byte[Entry.Size]; ZStream.Read(Data, 0, (int)Entry.Size); DataManager.AddLoadedMesh(Data); } } } } } } } } Also, here's the MSDN example showing how to load and render a model in XNA: MSDN: How to load a model Edit: I've also looked at XNA's Model class, and it doesn't seem to have any overloaded constructors for creating an instance based on a byte array, and no member functions for adding data to an instance from a byte array.
  4. Afr0m@n

    Note to aspiring MMO producers!

    Not for me it isn't! [cool]
  5. Afr0m@n

    Note to aspiring MMO producers!

    Oh, and just to make sure, for the last time, that noone has the wrong idea about my current attempt to remake TSO (it would appear that another post would be neccessary, as indicated by my declining rating (and on that note; Can someone please remove the nazi-inspired rating system and rather implement a more comfortable and normal post-count?!)), a game of this type is something I've wanted to do for a long time, but after my last failure, only recently have I felt that I have anywhere near the skills it would take to at least get something close to playable in a (relatively) limited amount of time. Of course, the sad part is that this time around, there's only one programmer working on it, but I am hoping to get more attracted to the project once a basic login and character selection system is in place. Edit: Am I seriously the only one here who feels that the rating system is restricting and differentiating, not to mention annoying and unneccessary, or should someone start a thread about removing it alltogether or at least alter it in a way so that, to vote on another member, a member would have to PM a moderator with a specific reason(ing), to avoid stupid PITA ratings from PITA members who needs to rate down other people to take out their personal frustrations? [Edited by - Afr0m@n on May 29, 2007 6:48:02 AM]
  6. Afr0m@n

    Note to aspiring MMO producers!

    Quote:Original post by Ravuya According to the linked thread, it says you were developing the game in .NET 2.0, not BlitzBasic. The first time: BlitzBasic, in 9th grade (might have been 8th, actually o_O). Second time (I.E, now): .NET 2.0, C#
  7. Afr0m@n

    Note to aspiring MMO producers!

    Quote:Original post by mikeman Quote:Original post by Afr0m@n Edit: To be absolutely frank, I did try to write a multiplayer clone of The Sims when I was in like... 9th grade or something... Oh,like, a month ago? This is so stupid. Ach! I knew someone would bring that up. I realize the irony in this, but the difference now is that this project is being written in C#, there are no girls involved (whatsoever!), I am much more resourceful this time around, and much more stubborn and pacient. The only thing that's changed for the worse is that now I'm essentially only one programmer, last time we were 2 (me and some guy from England).
  8. Afr0m@n

    Note to aspiring MMO producers!

    @aidan_walsh: Actually, no I haven't, but I've read that that's 'typical' behaviour from alot of MMO producing wannabes (AOL newbs?), and I just wanted to be sure. As a sidenote, though, I can add that today hasn't been my most fortunate day as far as girls are concerned, and so that is probably also part of the reason for this post. @Benjamin Heath: I think you may have misunderstood much of the point of this post. [smile] @ToohrVyk: Thanks for that insightful post! I'll be sure to note down some of those points in the back of my head for further use. Actually, this was the only post so far, maybe with the exception of Ravuya's, that qualified to the standard of what I had in mind when writing the OP. @ZQJ: Alot of Greenday's songs are actually very easy to play on guitar. [smile] Same thing goes for Foo Fighters. Not so much so with Metallica, but there are always exceptions. Songs that comes to mind (and that are good party songs) are 'Nothing Else Matters', 'Mama Said', 'Hero Of the Day', 'For whom the bell tolls' amongst others. Edit: To be absolutely frank, I did try to write a multiplayer clone of The Sims when I was in like... 9th grade or something, and I did that partially because I thought I'd be cool to impress a girl in my class that was completely into all things The Sims at the time. But as far as I'm concerned, that didn't really count, because I never foresaw a relationship with said girl, and I was using BlitzBasic and didn't even know what a pointer was. I think I actually managed to get to the point where we had some basic camera routines going and whatnot. But I'm really glad it happened though, because that's what sparked my interest for network programming initially. [Edited by - Afr0m@n on May 27, 2007 5:47:07 PM]
  9. To put in my share of 'work' to try to hold back the purported flood of MMO producers we'll receive here at Gamedev over the summer, I decided to write a little something to teach these wannabes a lesson. First of all; Creating an MMO, even if you are successful, will not get you a gir(s)! End of story. If anything, it'll make you (more) unpopular with them, as games, and especially MMOs, have a certain stigma around them. Need I say more about this? Secondly; If you absolutely want to try your luck with these beatiful, but yet so wild and sometimes very weird creatures, I suggest you go hang yourself right now, as all they'll do is bring you a massive headache. If you don't wanna listen though, you should at least follow my advice, which goes as follows; - Get out of your room! Now! Find a party to go to, or simply go to town. And find something to do! Nothing's worse than a girl coming up to you and asking 'What are you doing here?', with a reply that goes 'I just went outside to get some fresh air'. If you *really* don't feel like doing anything, lie and say that you went out to wet your throat (hint, hint). - Start playing a guitar! Who do girls like? They like Dave Grohl, James Hetfield, Billie Joe Armstrong etc. Nothing is better for lighting up a dull party than an accoustic guitar and some singing. If you're targeting a really tricky girl though, try to find out more about her interests and concider whether you should join a soccer team or go to the gym. - Get away from the PC! 'Nuff said. - In keeping with what was said above, start drinking. Girls like to go to parties, and all cool parties involves drinking. And even if they don't, you can still drink as a method of keeping up with any social problems you may have. - Start wearing cologne/perfume, or whatever it's called. Girls like men who smell manly, without smelling like Tarzan. If anyone's got more advice to come with, I suggest they post it here. If not, I suggest this post gets locked and stickified the moment a moderator sees this, so that all MMO producing wannabes can see it.
  10. Afr0m@n

    how nerdy are you? (test)

  11. Afr0m@n

    Uhm...

    Right. That's all I could think of putting in the Subject title. Honestly. I'm still scratching my head where I'm sitting. Today, I installed Vista. Of course I had to install it twice, nearly choking my C: drive in the process, because upgrading from Windows XP caused a BSOD on the Vista startup. But enough of that - what was one of the first things I tried out after having spent the usual 1 - 3 hours fighting a seemingly loosing war against drivers and such (which, for the record, pretty much happens everytime I install a new OS)? The new gadget sidebar, of course! So, I hastily make sure I'm still connected to the internet, and doubleclick on one of the headlines in the Newsfeed gadget, entitled 'Get your game on' (http://www.microsoft.com/athome/morefun/vistagames.mspx). 'Hm, this might be fun', I thought to myself. Oh how wrong I was! Instead of fun, it turned out to just be mindbogglingly... mysterious! The second - yes, second - argument that Microsoft uses in the referenced article to try to convince the everyday man/woman that Vista is the ultimate gaming platform, is this: 'Minimal system requirements—Even older PCs can play these titles. While peripherals like sound and graphics cards or wireless gamepads provide enhancements, add-ons are optional. If you compare the minimum system requirements to run Windows Vista with the system requirements to run Peggle—just one popular game—you'll see that you will be able to play these games for a long time.' What on EARTH?! I have a 2.40 GHZ CPU, a NVidia Geforce 7 Series GFX card and 1 gig RAM, and I still only get a 2.6 on the Vista Performance Score! Can someone please explain to me what Microsoft defines as an 'old' PC?
  12. Afr0m@n

    Recent Surge of Trolls?

    <HintToSuperpig> Isn't this supposed to be a site about, amongst other things, programming? </HintToSuperpig> Edit: Or did you mean it'd remove anyone's ability to search the lounge without being logged in?
  13. Afr0m@n

    Copy Protection

    Normally I would've told you to Google this, but since I'm trying to get my rating up - here goes nothing; Small codesnippets showing how to use the MD5CryptoServiceProvider class in .NET languages (this code is written in C#, but is easily translateable) MD5 for C++ SHA1 Hash Implementation for C++ C# SHA1 Hash Implementation C# HashTable tutorial C++ HashTable introduction
  14. Ok, so I've been trying to create a *.package archive successfully for a while now. At first, I tried writing directly to a file, but now I've decided writing directly to a memory stream that I can resize at will seems easier. Below is my entire class for reading and writing to and from package files. The reading part need'nt be looked at though, because as far as I can tell, it is fully compatible with all the *.package files I can throw at it. using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; using Utility; namespace DBPF.Package { /// <summary> /// Represents a *.package as used by The Sims 2. Kept modular to allow /// for changes as required by various expansions. Allows for reading, /// writing and decompressing *.package files (DBPF). /// </summary> public class PackageFile { private string ID; //(DBPF - the type of dat) private string MajorVersion; //Version Major (1 in TS2/SC4 Dats) private string MinorVersion; //Version Minor (0 in SC4 dats, 1 in most TS2 packages) private byte[] Reserved; //Reserved (Users can store DBPF info data here if they want) private string DateCreated; //Date Created in Hex (Unused in Version 1.1) private string DateModified; //Date Modified in Hex (Unused in Version 1.1) private UInt32 IndexMajVer; //Index Major Version (Always 7 in TS2/SC4 dats) private UInt32 NumEntries; //Number of entries in the index private UInt32 FirstEntry; //Location of first index entry private UInt32 IndexSize; //Size of index private UInt32 NumHoles; //Number of Hole entries in the Hole Record private UInt32 HoleLocation; //Location of the Hole Record private UInt32 HoleSize; //Size of the Hole Record private UInt32 IndexLoVer; //Index Minor Version (Version 1.1+ in TS2 only) private byte[] VerReserved; //Reserved for future use in other versions. private List<IndexEntry> m_IndexTable; //Compressed entries in the archive, stored in the archive's *.dir file. //Checked against m_IndexTable upon archive extraction, to determine //which files are compresed. private List<IndexEntry> m_CompressedEntries; private FileStream m_MemStream; private BinaryReader m_Reader; private BinaryWriter m_Writer; private ASCIIEncoding m_Encoding; //Partially complete index entries generated when creating an NMap for //files in a folder that are added to an archive. private List<IndexEntry> m_GeneratedIndexEntries; private string m_Path; /// <summary> /// Instantiates a new instance of this class for reading /// a *.package archive. /// </summary> /// <param name="ArchivePath">The full path and name of the archive.</param> public PackageFile(string ArchivePath) { m_IndexTable = new List<IndexEntry>(); m_CompressedEntries = new List<IndexEntry>(); m_MemStream = File.OpenRead(ArchivePath); m_Reader = new BinaryReader(m_MemStream); m_Encoding = new ASCIIEncoding(); } /// <summary> /// Instantiates a new instance of this class for /// creating a *.package archive from a directory. /// </summary> /// <param name="DirPath">The full path and name of the directory.</param> /// <param name="Compress">Set to true if you wish to compress archive.</param> public PackageFile(string DirPath, bool Compress) { m_MemStream = File.Create(DirPath + "\\" + Path.GetFileNameWithoutExtension(DirPath) + ".package"); m_Encoding = new ASCIIEncoding(); m_GeneratedIndexEntries = new List<IndexEntry>(); m_Path = DirPath; FindExtensionsInDir(); CreatePackage(); } /// <summary> /// Finds all the extensions in the directory given to the /// constructor of this class, and creates NMaps for them. /// </summary> private void FindExtensionsInDir() { string[] Files = Directory.GetFiles(m_Path); List<string> Extensions = new List<string>(); foreach (string TmpFile in Files) { string TmpExtension = Path.GetExtension(TmpFile); Extensions.Add(TmpExtension); } string[] ExtensionsArray = Extensions.ToArray(); for (int i = 0; i < Extensions.Count; i++) { if (!ExtensionsArray.Equals(".package")) { if (i != 0) { //Current extension in the array didn't equal the last one, //so we know we can create a NameMap for it. if (!ExtensionsArray.Equals(ExtensionsArray[i - 1])) { NameMap NMap = new NameMap(NameMap.DetermineTypeID(ExtensionsArray), m_Path); m_GeneratedIndexEntries.AddRange(NMap.CreateNMap()); } } else if (i == 0) { NameMap NMap = new NameMap(NameMap.DetermineTypeID(ExtensionsArray), m_Path); m_GeneratedIndexEntries.AddRange(NMap.CreateNMap()); } } } } private void CreatePackage() { MemoryStream PackageStream = new MemoryStream(); BinaryWriter PackageWriter = new BinaryWriter(PackageStream); PackageStream = WriteFilesToPackage(PackageWriter, PackageStream); PackageStream.Seek(0, SeekOrigin.Begin); PackageStream = WriteIndexTable(PackageWriter, PackageStream); PackageStream.Seek(0, SeekOrigin.Begin); PackageStream = WritePackageHeader(PackageWriter, PackageStream); PackageStream.Seek(0, SeekOrigin.Begin); m_Reader = new BinaryReader(PackageStream); m_Writer = new BinaryWriter(m_MemStream); m_Writer.Write(m_Reader.ReadBytes((int)PackageStream.Length)); m_Writer.Flush(); PackageWriter.Close(); m_Writer.Close(); m_Reader.Close(); } #region Archive writing functions private MemoryStream WritePackageHeader(BinaryWriter Writer, MemoryStream MemStream) { MemStream.SetLength(MemStream.Length + 96); //Identifier (DBPF - the type of dat). Writer.Write(m_Encoding.GetBytes("DBPF")); //Version Major (1 in TS2/SC4 Dats). Writer.Write((uint)1); //Version Minor (0 in SC4 dats, 1 in most TS2 packages). Writer.Write((uint)1); //Reserved (Users can store DBPF info data here if they want). Writer.Write(new byte[12]); //Date Created in Hex (Unused in Version 1.1). Writer.Write((uint)0); //Date Modified in Hex (Unused in Version 1.1). Writer.Write((uint)0); //Index Major Version (Always 7 in TS2/SC4 dats). Writer.Write((uint)7); //Number of entries in the index. Writer.Write((uint)m_GeneratedIndexEntries.Count); //Location of first index entry. Writer.Write((uint)96); //Size of index. Writer.Write(IndexSize); //Number of Hole entries in the Hole Record. Writer.Write((uint)0); //Location of the Hole Record. Writer.Write((uint)0); //Size of the Hole Record. Writer.Write((uint)0); //Index Minor Version (Version 1.1+ in TS2 only). //01 = 0 //02 = 1 Writer.Write((uint)01); //Reserved for future use in other versions. Writer.Write(new byte[32]); return MemStream; } private MemoryStream WriteIndexTable(BinaryWriter Writer, MemoryStream MemStream) { uint TmpIndexSize = 0; foreach (IndexEntry TmpEntry in m_GeneratedIndexEntries) { TmpIndexSize += 5 * 4; //20 bytes MemStream.SetLength(MemStream.Length + TmpIndexSize); Writer.Write(TmpEntry.TypeID); Writer.Write(TmpEntry.GroupID); Writer.Write(TmpEntry.InstanceID); Writer.Write(TmpEntry.Location); Writer.Write(TmpEntry.Size); Writer.Flush(); } IndexSize = TmpIndexSize; return MemStream; } private MemoryStream WriteFilesToPackage(BinaryWriter Writer, MemoryStream MemStream) { FileStream FStream; BinaryReader FileReader; foreach (IndexEntry TmpEntry in m_GeneratedIndexEntries) { FStream = File.OpenRead(TmpEntry.Name); FileReader = new BinaryReader(FStream); TmpEntry.Location = (uint)MemStream.Position; TmpEntry.Size = (uint)FStream.Length; Writer.Write(FileReader.ReadBytes((int)FStream.Length)); Writer.Flush(); FileReader.Close(); } return MemStream; } #endregion #region Archive reading functions /// <summary> /// Reads the header of a *.package (DBPF) archive. /// </summary> /// <returns>True if header was read, false if archive /// wasn't a DBPF archive.</returns> private bool ReadHeader() { ID = m_Encoding.GetString(m_Reader.ReadBytes(4)); if (!ID.Equals("DBPF")) { MessageBox.Show("Couldn't read package ID!"); return false; } MajorVersion = HexEncoding.ToString(m_Reader.ReadBytes(4)); MinorVersion = HexEncoding.ToString(m_Reader.ReadBytes(4)); Reserved = m_Reader.ReadBytes(12); DateCreated = HexEncoding.ToString(m_Reader.ReadBytes(4)); DateModified = HexEncoding.ToString(m_Reader.ReadBytes(4)); IndexMajVer = m_Reader.ReadUInt32(); NumEntries = m_Reader.ReadUInt32(); FirstEntry = m_Reader.ReadUInt32(); IndexSize = m_Reader.ReadUInt32(); NumHoles = m_Reader.ReadUInt32(); HoleLocation = m_Reader.ReadUInt32(); HoleSize = m_Reader.ReadUInt32(); IndexLoVer = m_Reader.ReadUInt32() - 1; VerReserved = m_Reader.ReadBytes(32); return true; } /// <summary> /// Reads the index table of a *.package (DBPF) archive. /// </summary> private void ReadIndex() { m_MemStream.Seek(FirstEntry, SeekOrigin.Begin); for (int i = 0; i < NumEntries; i++) { try { IndexEntry TmpEntry = new IndexEntry(); TmpEntry.TypeID = m_Reader.ReadUInt32(); TmpEntry.GroupID = m_Reader.ReadUInt32(); TmpEntry.InstanceID = m_Reader.ReadUInt32(); //Check the archive's version to determine whether or not to read //a second instance ID. if ((IndexMajVer == 7) && (IndexLoVer == 1)) TmpEntry.InstanceID2 = m_Reader.ReadUInt32(); TmpEntry.Location = m_Reader.ReadUInt32(); TmpEntry.Size = m_Reader.ReadUInt32(); //Check for *.dir file, which is a directory of all //compressed files in an archive. if ((InternalPackageFormats)TmpEntry.TypeID == InternalPackageFormats.Directory) { long CurrentStreamPos = m_MemStream.Position; m_MemStream.Seek(TmpEntry.Location, SeekOrigin.Begin); //Dump filedata into the entry's databuffer. TmpEntry.Data = new MemoryStream(m_Reader.ReadBytes((int)TmpEntry.Size)); TmpEntry.DataReader = new BinaryReader(TmpEntry.Data); //Loop through the filedata, reading all the dir entries //of compressed files, and add them to m_CompressedEntries. for (int j = 0; j <= TmpEntry.Size; j++) { IndexEntry CompressedEntry = new IndexEntry(); CompressedEntry.TypeID = TmpEntry.DataReader.ReadUInt32(); CompressedEntry.GroupID = TmpEntry.DataReader.ReadUInt32(); CompressedEntry.InstanceID = TmpEntry.DataReader.ReadUInt32(); CompressedEntry.UnpackedHexSize = HexEncoding.ToString(TmpEntry.DataReader.ReadBytes(4)); //A dir entry in the *.dir file/record takes 16 bytes. j += 12 + CompressedEntry.UnpackedHexSize.Length; m_CompressedEntries.Add(CompressedEntry); } //Seek back to the position in the index table where we left off. m_MemStream.Seek(CurrentStreamPos, SeekOrigin.Begin); TmpEntry.Data.Close(); TmpEntry.DataReader.Close(); } m_IndexTable.Add(TmpEntry); } catch (Exception) { return; } } } public void ExtractArchive(string Path) { foreach (IndexEntry CompressedEntry in m_CompressedEntries) { foreach (IndexEntry TmpEntry in m_IndexTable) { if (CompressedEntry.InstanceID == TmpEntry.InstanceID) TmpEntry.Compressed = true; } } int CurrentFilename = 0; string CurrentExtension = string.Empty; BinaryWriter Writer; FileStream Stream; if (!Directory.Exists(Path)) Directory.CreateDirectory(Path); foreach (IndexEntry TmpEntry in m_IndexTable) { m_MemStream.Seek(TmpEntry.Location, SeekOrigin.Begin); //Dump filedata into the entry's databuffer. TmpEntry.Data = new MemoryStream(m_Reader.ReadBytes((int)TmpEntry.Size)); TmpEntry.DataReader = new BinaryReader(TmpEntry.Data); if (TmpEntry.Compressed) { TmpEntry.ReadCompressedHeader(); byte[] buf = Uncompress(TmpEntry.Data.ToArray(), TmpEntry.UnpackedSize, 9); TmpEntry.Data = new MemoryStream(buf); buf = null; } CurrentFilename++; CurrentExtension = DetermineFileExtension((InternalPackageFormats)TmpEntry.TypeID); Stream = File.Open(Path + "\\" + CurrentFilename + CurrentExtension, FileMode.OpenOrCreate); Writer = new BinaryWriter(Stream); Writer.Write(TmpEntry.Data.ToArray()); TmpEntry.Data.Close(); TmpEntry.DataReader.Close(); Stream.Close(); Writer.Close(); } } #endregion public bool LoadArchive() { if (!ReadHeader()) return false; ReadIndex(); return true; } #region Helper Functions /// <summary> /// Uncompresses the File Data passed /// </summary> /// <param name="data">Relevant File Data</param> /// <param name="targetSize">Size of the uncompressed Data</param> /// <param name="offset">File offset, where we should start to decompress from</param> /// <returns>The uncompressed FileData</returns> public static Byte[] Uncompress(Byte[] data, uint targetSize, int offset) { Byte[] uncdata = null; int index = offset; try { uncdata = new Byte[targetSize]; } catch (Exception) { uncdata = new Byte[0]; } int uncindex = 0; int plaincount = 0; int copycount = 0; int copyoffset = 0; Byte cc = 0; Byte cc1 = 0; Byte cc2 = 0; Byte cc3 = 0; int source; try { while ((index < data.Length) && (data[index] < 0xfc)) { cc = data[index++]; if ((cc & 0x80) == 0) { cc1 = data[index++]; plaincount = (cc & 0x03); copycount = ((cc & 0x1C) >> 2) + 3; copyoffset = ((cc & 0x60) << 3) + cc1 + 1; } else if ((cc & 0x40) == 0) { cc1 = data[index++]; cc2 = data[index++]; plaincount = (cc1 & 0xC0) >> 6; copycount = (cc & 0x3F) + 4; copyoffset = ((cc1 & 0x3F) << 8) + cc2 + 1; } else if ((cc & 0x20) == 0) { cc1 = data[index++]; cc2 = data[index++]; cc3 = data[index++]; plaincount = (cc & 0x03); copycount = ((cc & 0x0C) << 6) + cc3 + 5; copyoffset = ((cc & 0x10) << 12) + (cc1 << 8) + cc2 + 1; } else { plaincount = (cc - 0xDF) << 2; copycount = 0; copyoffset = 0; } for (int i = 0; i < plaincount; i++) uncdata[uncindex++] = data[index++]; source = uncindex - copyoffset; for (int i = 0; i < copycount; i++) uncdata[uncindex++] = uncdata[source++]; }//while } //try catch (Exception ex) { //Helper.ExceptionMessage("", ex); throw ex; } if (index < data.Length) { plaincount = (data[index++] & 0x03); for (int i = 0; i < plaincount; i++) { if (uncindex >= uncdata.Length) break; uncdata[uncindex++] = data[index++]; } } return uncdata; } private string DetermineFileExtension(InternalPackageFormats TypeID) { switch (TypeID) { case InternalPackageFormats.UIData: return ".ui"; case InternalPackageFormats.WallGraph: return ".wgra"; case InternalPackageFormats.LotDescription: return ".desc"; case InternalPackageFormats.BinaryIndex: return ".binx"; case InternalPackageFormats.JPG: return ".jpg"; case InternalPackageFormats.NameReference: return ".nref"; case InternalPackageFormats.BusinessInfo: return ".bnfo"; case InternalPackageFormats.TextureImage: return ".txtr"; case InternalPackageFormats.XA: return ".xa"; case InternalPackageFormats.ThreeDArray: return ".3dary"; case InternalPackageFormats.TwoDArray: return ".2dary"; case InternalPackageFormats.TextureOverlay: return ".xtol"; case InternalPackageFormats.Popups: return ".pops"; case InternalPackageFormats.SimScores: return ".scor"; case InternalPackageFormats.ThreeDID: return ".3didr"; case InternalPackageFormats.BehaviourConstant: return "bcon"; case InternalPackageFormats.BehaviourFunction: return "bhav"; case InternalPackageFormats.CatalogString: return ".cats"; case InternalPackageFormats.CatalogDescription: return ".ctss"; case InternalPackageFormats.TextLists: return ".str#"; case InternalPackageFormats.PieMenuStrings: return ".tta"; case InternalPackageFormats.FaceProperties: return ".face"; case InternalPackageFormats.FamilyInformation: return ".fami"; case InternalPackageFormats.FamilyUnknown: return "famh"; case InternalPackageFormats.Function: return ".fcns"; case InternalPackageFormats.AudioReference: return "fwav"; case InternalPackageFormats.GlobalData: return ".glob"; case InternalPackageFormats.HouseDescriptor: return ".hous"; case InternalPackageFormats.TexturedMaterial: return ".txmt"; case InternalPackageFormats.WorldDatabase: return ".wrld"; case InternalPackageFormats.SkinToneXML: return ".xstn"; case InternalPackageFormats.CinematicScene: return ".cine"; case InternalPackageFormats.Memory: return ".ngbh"; case InternalPackageFormats.NameMap: return ".nmap"; case InternalPackageFormats.ObjectData: return ".objd"; case InternalPackageFormats.ObjectFunctions: return ".objf"; case InternalPackageFormats.ObjectMaterial: return ".objm"; case InternalPackageFormats.ImageColorPalette: return ".palt"; case InternalPackageFormats.PERS: return ".pers"; case InternalPackageFormats.Slot: return ".slot"; case InternalPackageFormats.TTAT: return ".ttat"; case InternalPackageFormats.TRPR: return ".trpr"; case InternalPackageFormats.TRCN: return ".trcn"; case InternalPackageFormats.Object: return ".mobjt"; case InternalPackageFormats.HitList: return ".hls"; case InternalPackageFormats.GeometricNode: return ".gmnd"; case InternalPackageFormats.LightMap: return ".lightmap"; case InternalPackageFormats.WallLayer: return ".wll"; case InternalPackageFormats.FamilyTies: return ".famt"; case InternalPackageFormats.PMAP: return ".pmap"; case InternalPackageFormats.SimDescription: return ".pdat"; case InternalPackageFormats.FencePostLayer: return ".fpl"; case InternalPackageFormats.HoodTerrain: return ".nhtr"; case InternalPackageFormats.NID: return ".nid"; case InternalPackageFormats.AgedCPF: return ".cpf"; case InternalPackageFormats.Anim: return ".anim"; case InternalPackageFormats.SMAP: return ".smap"; case InternalPackageFormats.BMP: return ".bmp"; case InternalPackageFormats.Vertext: return ".vertext"; case InternalPackageFormats.FacialStructure: return ".lxnr"; case InternalPackageFormats.MaterialShader: return ".matshad"; case InternalPackageFormats.WantsFears: return ".wfr"; case InternalPackageFormats.ContentRegistry: return ".creg"; case InternalPackageFormats.CIGE: return ".cige"; case InternalPackageFormats.ResourceNode: return ".cres"; case InternalPackageFormats.PropertySet: return ".cpf"; case InternalPackageFormats.VersionInfo: return ".ver"; case InternalPackageFormats.HoodView: return ".nhvw"; case InternalPackageFormats.LargeImage: return ".lifo"; case InternalPackageFormats.OBJT: return ".objt"; case InternalPackageFormats.Shape: return ".shpe"; case InternalPackageFormats.EffectsScript: return ".fx"; case InternalPackageFormats.GeometricData: return ".gmdc"; case InternalPackageFormats.LargeJPG: return ".jfif"; case InternalPackageFormats.BHAVTree: return ".tree"; default: return ".xyz"; } } #endregion /// <summary> /// Returns an array representing the IndexTable of the loaded archive. /// The index table contains entries which in turn contains information /// about each file in the archive that they represent, such as location /// and size of actual filedata, as well as a type ID representing the /// file's extension. /// </summary> public IndexEntry[] IndexTable { get { return m_IndexTable.ToArray(); } } } } The problem, if it isn't obvious yet, is that I am as of yet incapable of creating *.package files that can be extracted with my *.package reading code (and, thus, by other *.package reading tools as well). A thing I've noticed is that when I try to extract a *.package archive created with my *.package writing methods, the files seems to grow in size incrementally as they are extracted/created, which seems to suggest that there is something wrong with the way I am writing my Index Table. If needed, here's the specification I'm using for this code: *.package specification Any suggestions? Thanks in advance! Edit - Whoops, here's the class for creating NMaps; using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; namespace DBPF.Package { /// <summary> /// Encapsulates methods for creating, and returning a handle to, a /// new NameMap file that can be put in a new *.package file along /// with the files referenced in the new NameMap file. /// </summary> class NameMap { private string m_Filename; //Filename of this file (unimportant, as these files don't map their own names). private string m_Path; //Path of the created file. private InternalPackageFormats m_TypeID; //TypeID of the filetype that this file maps. private uint m_NumItems; //Number of files with the filetype that corresponds to this file. List<IndexEntry> m_Files; //List of files that are contained in this NMap. public NameMap(InternalPackageFormats TypeID, string Path) { m_TypeID = TypeID; m_Path = Path; m_Filename = DetermineFileExtension(m_TypeID).Replace(".", ""); m_Files = new List<IndexEntry>(); } public List<IndexEntry> CreateNMap() { string[] Files = Directory.GetFiles(m_Path); FileStream NMap = File.Create(m_Path + "\\" + m_Filename + ".nmap"); BinaryWriter Writer = new BinaryWriter(NMap); Random Rnd = new Random(); m_NumItems = (uint)Files.Length; Writer.Write(m_NumItems); uint InstanceID = 0; foreach (string TmpName in Files) { if (DetermineFileExtension(m_TypeID).Equals(Path.GetExtension(TmpName))) { IndexEntry TmpEntry = new IndexEntry(); TmpEntry.Name = TmpName; TmpEntry.InstanceID = InstanceID++; TmpEntry.TypeID = (uint)m_TypeID; //Is it neccessary to 'fill out' GroupID? Writer.Write((uint)0x0); Writer.Write(TmpEntry.InstanceID); Writer.Write((uint)TmpEntry.Name.Length); Writer.Write(Encoding.ASCII.GetBytes(Path.GetFileNameWithoutExtension(TmpEntry.Name))); m_Files.Add(TmpEntry); } } IndexEntry NMapEntry = new IndexEntry(); NMapEntry.Name = m_Path + "\\" + m_Filename + ".nmap"; NMapEntry.InstanceID = InstanceID++; NMapEntry.TypeID = (uint)InternalPackageFormats.NameMap; m_Files.Add(NMapEntry); NMap.Close(); Writer.Close(); return m_Files; } #region Helper Functions /// <summary> /// Determines a filetype based upon a TypeID. /// </summary> /// <param name="TypeID">A TypeID in the InternalPackageFormats enum.</param> /// <returns>A string containing the filetype.</returns> private string DetermineFileExtension(InternalPackageFormats TypeID) { switch (TypeID) { case InternalPackageFormats.UIData: return ".ui"; case InternalPackageFormats.WallGraph: return ".wgra"; case InternalPackageFormats.LotDescription: return ".desc"; case InternalPackageFormats.BinaryIndex: return ".binx"; case InternalPackageFormats.JPG: return ".jpg"; case InternalPackageFormats.NameReference: return ".nref"; case InternalPackageFormats.BusinessInfo: return ".bnfo"; case InternalPackageFormats.TextureImage: return ".txtr"; case InternalPackageFormats.XA: return ".xa"; case InternalPackageFormats.ThreeDArray: return ".3dary"; case InternalPackageFormats.TwoDArray: return ".2dary"; case InternalPackageFormats.TextureOverlay: return ".xtol"; case InternalPackageFormats.Popups: return ".pops"; case InternalPackageFormats.SimScores: return ".scor"; case InternalPackageFormats.ThreeDID: return ".3didr"; case InternalPackageFormats.BehaviourConstant: return ".bcon"; case InternalPackageFormats.BehaviourFunction: return ".bhav"; case InternalPackageFormats.CatalogString: return ".cats"; case InternalPackageFormats.CatalogDescription: return ".ctss"; case InternalPackageFormats.TextLists: return ".str#"; case InternalPackageFormats.PieMenuStrings: return ".tta"; case InternalPackageFormats.FaceProperties: return ".face"; case InternalPackageFormats.FamilyInformation: return ".fami"; case InternalPackageFormats.FamilyUnknown: return ".famh"; case InternalPackageFormats.Function: return ".fcns"; case InternalPackageFormats.AudioReference: return ".fwav"; case InternalPackageFormats.GlobalData: return ".glob"; case InternalPackageFormats.HouseDescriptor: return ".hous"; case InternalPackageFormats.TexturedMaterial: return ".txmt"; case InternalPackageFormats.WorldDatabase: return ".wrld"; case InternalPackageFormats.SkinToneXML: return ".xstn"; case InternalPackageFormats.CinematicScene: return ".cine"; case InternalPackageFormats.Memory: return ".ngbh"; case InternalPackageFormats.NameMap: return ".nmap"; case InternalPackageFormats.ObjectData: return ".objd"; case InternalPackageFormats.ObjectFunctions: return ".objf"; case InternalPackageFormats.ObjectMaterial: return ".objm"; case InternalPackageFormats.ImageColorPalette: return ".palt"; case InternalPackageFormats.PERS: return ".pers"; case InternalPackageFormats.Slot: return ".slot"; case InternalPackageFormats.TTAT: return ".ttat"; case InternalPackageFormats.TRPR: return ".trpr"; case InternalPackageFormats.TRCN: return ".trcn"; case InternalPackageFormats.Object: return ".mobjt"; case InternalPackageFormats.HitList: return ".hls"; case InternalPackageFormats.GeometricNode: return ".gmnd"; case InternalPackageFormats.LightMap: return ".lightmap"; case InternalPackageFormats.WallLayer: return ".wll"; case InternalPackageFormats.FamilyTies: return ".famt"; case InternalPackageFormats.PMAP: return ".pmap"; case InternalPackageFormats.SimDescription: return ".pdat"; case InternalPackageFormats.FencePostLayer: return ".fpl"; case InternalPackageFormats.HoodTerrain: return ".nhtr"; case InternalPackageFormats.NID: return ".nid"; case InternalPackageFormats.AgedCPF: return ".cpf"; case InternalPackageFormats.Anim: return ".anim"; case InternalPackageFormats.SMAP: return ".smap"; case InternalPackageFormats.BMP: return ".bmp"; case InternalPackageFormats.Vertext: return ".vertext"; case InternalPackageFormats.FacialStructure: return ".lxnr"; case InternalPackageFormats.MaterialShader: return ".matshad"; case InternalPackageFormats.WantsFears: return ".wfr"; case InternalPackageFormats.ContentRegistry: return ".creg"; case InternalPackageFormats.CIGE: return ".cige"; case InternalPackageFormats.ResourceNode: return ".cres"; case InternalPackageFormats.PropertySet: return ".cpf"; case InternalPackageFormats.VersionInfo: return ".ver"; case InternalPackageFormats.HoodView: return ".nhvw"; case InternalPackageFormats.LargeImage: return ".lifo"; case InternalPackageFormats.OBJT: return ".objt"; case InternalPackageFormats.Shape: return ".shpe"; case InternalPackageFormats.EffectsScript: return ".fx"; case InternalPackageFormats.GeometricData: return ".gmdc"; case InternalPackageFormats.LargeJPG: return ".jfif"; case InternalPackageFormats.BHAVTree: return ".tree"; case InternalPackageFormats.DirectXMesh: return ".x"; default: return "xyz"; } } /// <summary> /// Determines a TypeID based upon a file extension. /// </summary> /// <param name="Extension">The extension of a file.</param> /// <returns>A TypeID in the InternalPackageFormats enum.</returns> public static InternalPackageFormats DetermineTypeID(string Extension) { switch (Extension) { case ".cpf": return InternalPackageFormats.AgedCPF; case ".x": return InternalPackageFormats.DirectXMesh; default: return InternalPackageFormats.UnkownFiletype; } } #endregion } } Just in case, here's the specs: NMap Specification
  15. Afr0m@n

    snow crystals

    I have no idea how to 'model' a snowcrystal, especially not in OpenGL, since OpenGL incidentally isn't a modelling program. However, if you are referring to common techniques used for rendering snow, then I know that it is a common technique to render it as an animated texture infront of the camera. If you are doing a third person game, you can probably experiment with rendering the snow behind and/or in front of the player's character. More than that I am afraid I cannot tell you. A google search would probably be good. Either that, or simply wait until someone more knowledgeable replies.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!