Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 21 Feb 2008
Offline Last Active May 23 2014 12:55 PM

#4935356 Manager/Simulation Games Requirements

Posted by MatsK on 27 April 2012 - 05:55 AM

You don't "need" a team of programmers to do anything. Heck, if a lone wolf coder wanted to, he could recode WoW from scratch alone. What it comes down to is time. And often what takes the most time isn't the programming anyways, it's creating all the art and sound assets. So it depends on how big and complex you want your game to be and whether you want it to be in 3D or 2D.

#4919871 Looking for the engine to the game ;P

Posted by MatsK on 06 March 2012 - 01:28 PM

There's the IdTech4 engine on GitHub.

#4885294 How to display a model on top of textures? [XNA]

Posted by MatsK on 18 November 2011 - 06:17 AM

I'm trying to achieve an effect like this:

Posted Image

The part marked in red is a 3D model, everything else is rendered using 'normal' XNA rendering with 2D textures.

If I understand you correctly, I have to render the model as well as the textures to a rendertarget, and then... draw the screen using the rendertarget as a texture?
How do I use the rendertarget as a texture? Can I go (Texture2D)MyRenderTarget ?

I chose SurfaceFormat.Single because it seemed the reasonable thing to do, since there's only 1 channel.

#4808852 Which engine should we use for our browser-based MMORPG?

Posted by MatsK on 10 May 2011 - 12:40 AM

Java-engine? There are Java MMO engines out there? Which ones?

#4808482 What happened to the pc game industry?

Posted by MatsK on 09 May 2011 - 05:09 AM

What happened to the pc game industry?

It's right here.
And here, here, here and here.
Also here. And here(here), and here.
Plus here and here.

I noticed you linked to OnLive. I hope I'm not the only one consistantly choosing not to support it. Quite frankly, I think the notion of cloud computing is ruining the PC industry altogether. The day that Microsoft releases a cloud-based OS is the day they won't get my money. I want the right and the priviledge it is to be able to store games and applications on my harddrive, so I can make modifications for them. OnLive, if truly successful, will ruin indie mod development.

#4806868 Male is now the weak sex?

Posted by MatsK on 05 May 2011 - 06:24 AM

If so many girls are applying to universities and actually having better chances of getting accepted than boys, something should be done to level the playing field (which it seems these universities are doing).

This makes no sense to me. Should they make sure there's equal representation from every year of birth-date, every hair colour, every choice of favorite colour, every skin pigment, every religious dedication, every choice of car-make? Those things are all just as arbitrary as trying to ensure equal representation from both genders.

I wouldn't say that trying to ensure equal representation from both genders is 'arbitrary'. How men and women are educated and ultimately earning has alot to say for family compositions and birth rates in a society. The article also mentions that the number of single mothers is steadily increasing, as there simply aren't enough partners with equal or better status to choose from, and the girls are steadfastly rejecting the guys with a poor or no education. Also, women with higher education tend to postpone familylife, and by the time they're starting to reach their biological peak of 35-40, they're either finding that there aren't enough potential partners to choose from at a higher or equal status, or that males with a lower status have altogether given up the prospect of marriage and/or dating.

The terms of marriage have changed radically since 1970. Typically, women’s income has been the main factor in determining whether a family moves up the class ladder or stays stagnant. And increasing numbers of women—unable to find men with a similar income and education—are forgoing marriage altogether. In 1970, 84 percent of women ages 30 to 44 were married; now 60 percent are. In 2007, among American women without a high-school diploma, 43 percent were married. And yet, for all the hand-wringing over the lonely spinster, the real loser in society—the only one to have made just slight financial gains since the 1970s—is the single man, whether poor or rich, college-educated or not. Hens rejoice; it’s the bachelor party that’s over.The sociologist Kathryn Edin spent five years talking with low-income mothers in the inner suburbs of Philadelphia. Many of these neighborhoods, she found, had turned into matriarchies, with women making all the decisions and dictating what the men should and should not do. “I think something feminists have missed,” Edin told me, “is how much power women have” when they’re not bound by marriage. The women, she explained, “make every important decision”—whether to have a baby, how to raise it, where to live. “It’s definitely ‘my way or the highway,’” she said. “Thirty years ago, cultural norms were such that the fathers might have said, ‘Great, catch me if you can.’ Now they are desperate to father, but they are pessimistic about whether they can meet her expectations.” The women don’t want them as husbands, and they have no steady income to provide. So what do they have?

#4806820 Theory - Handling TCP data that is split on recv calls

Posted by MatsK on 05 May 2011 - 03:55 AM

The first will always happen, because recv() blocks until data has been received.
You haven't specified which language you're using, but assuming you're using C++, you should use an asynchronous solution like IOCP so that your main application thread doesn't have to block in order to wait for data.
This way, you can easily handle data asynchronously. Just attach a packet-ID to your packets, compare the packet-ID to the packetsize (which is predetermined), and if you've received PACKETSIZE number of bytes, the packet has been fully received. If the current buffer contains any data before the packet-ID, that data belonged to the previously received packet. If you've received more than PACKETSIZE number of bytes, you've received the start of a new packet also.

#4802971 Idea for game

Posted by MatsK on 26 April 2011 - 01:37 AM

I have tried to read programming books and such, the language just does not click.

That's how most people feel when they start programming. It is mainly a question of motivation. In my opinion, anyone can learn to become a decent programmer (notice I said decent, not great) if they have the motivation to stay in there until they start to get a grip on things.
In essence, programming is about finding solutions to problems. This goes for programming games as well. Modern games consists of thousands to millions of problems that must be solved, and the ones that you cannot solve off the top of your head have most likely already been solved by someone else. To find these pre-solved problems (otherwise known as solutions), use Google. That's what I use. It is a very helpful tool.
On the off-chance that it doesn't provide you with anything, that's why you have the forums on this site to post to so others can help you find a solution to your problem. Most of the time, they'll even do it for free!
For example;

Q: How do you figure out if a button has been clicked?!
A: There is a formula for that! It goes like this:

if(MouseX > ButtonX AND MouseX <= ButtonWidth)
if(MouseY > ButtonY AND MouseY <= ButtonHeight)
//If the left mouse button is down, the button has been clicked!
end if[/size]
end if [/size]

#4780018 Size of binary file? [C++]

Posted by MatsK on 28 February 2011 - 03:52 AM

Nevermind, I figured it out!
Thanks guys!

Part of the idea here on gamedev is sharing solutions to problems. So, what was the problem and what was the fix (in case someone else runs into a similar problem)?

The problem was that the filename was wrong. When I tried to print it out to the console, it only displayed part of the filename. That probably had something to do with the way I was doing it though.
The thing is, my program converts files from *.bmp to *.png, and I had already deleted all my extracted *.bmp files when this particular piece of code was being run, so the filename was not found.
I ended up converting the char* to a std::string and replacing 'bmp' with 'png'.

char* Filename = new char[m_Entries[i].FilenameLength];
			memcpy(Filename, &m_Entries[i].Filename, m_Entries[i].FilenameLength);
			string StrFilename(Filename, Filename + m_Entries[i].FilenameLength);
			StrFilename = Replace(StrFilename, "bmp", "png");

			ifstream CurrentFile(StrFilename.c_str(), ios::in | ios::binary | ios::ate);
			//CurrentFile.seekg(0, ios::end);
			ifstream::pos_type size = CurrentFile.tellg();

string Replace(string Str, string From, string To)
		int Position = Str.find(From);

		while(Position != string::npos)
			Str = Str.replace(Position, From.length(), To);
			Position = Str.find(From, Position + From.length());

		return Str;

I had already written the Replace() function before I ran into this problem.
Now that I think about it, I should probably replace 'bmp' with '.bmp' and 'png' with '.png' in order to minimize the chance that a random character sequence that is actually part of the filename itself is replaced.

Here is the full sourcecode for the class I'm working on:

#include "stdafx.h"
#include "FileArchive.h"
#include <assert.h>
#include <iostream>
#include "Compress.h"
#include "FreeImage.h"

namespace Archives
	string Replace(string Str, string From, string To);

	FileArchive::FileArchive(string Path)
		char Signature[8];
		char Version[4];
		char ManifestOffset[4];
		char NumFiles[4];

		m_ArchivePath = Path;

		ifstream Archive(Path.c_str(), ios::in | ios::binary);
		Archive.read(Signature, sizeof(FARSignature));

		string StrSignature(Signature, Signature + 8);

		assert(StrSignature == "FAR!byAZ");
		cout << "Signature: " << StrSignature << "\r\n";
		Archive.read(Version, 4);
		m_Version = *((int*)Version);

		assert(m_Version == 1 || 3);

		Archive.read(ManifestOffset, 4);
		m_ManifestOffset = *((unsigned int*)ManifestOffset);
		Archive.seekg(m_ManifestOffset, ios::beg);

		Archive.read(NumFiles, 4);
		m_NumFiles = *((unsigned int*)NumFiles);


	void FileArchive::Process()
		ifstream Archive(m_ArchivePath.c_str(), ios::in | ios::binary);

		char DecompressedDataSize[4];
		char CompressedDataSize[3];
		char DataType[1];
		char DataOffset[4];
		char Compressed[1];
		char AccessNumber[1];
		char FilenameLength[2];
		char TypeID[4];
		char FileID[4];
		char* Filename;
		//Seek past the number of files...
		Archive.seekg(m_ManifestOffset + 4, ios::beg);

		for(unsigned int i = 0; i < m_NumFiles; i++)
			FAR3Entry Entry;
			Archive.read(DecompressedDataSize, sizeof(unsigned int));
			Entry.DecompressedDataSize = *((unsigned int*)DecompressedDataSize);

			Archive.read(CompressedDataSize, 3);
			Entry.CompressedDataSize = *((unsigned int*)CompressedDataSize);

			Archive.read(DataType, sizeof(unsigned char));
			Entry.DataType = *((unsigned char*)DataType);

			Archive.read(DataOffset, sizeof(unsigned int));
			Entry.DataOffset = *((unsigned int*)DataOffset);

			Archive.read(Compressed, sizeof(unsigned char));
			Entry.Compressed = *((unsigned char*)Compressed);

			Archive.read(AccessNumber, sizeof(unsigned char));
			Entry.AccessNumber = *((unsigned char*)AccessNumber);

			Archive.read(FilenameLength, sizeof(unsigned short));
			Entry.FilenameLength = *((unsigned short*)FilenameLength);

			Archive.read(TypeID, sizeof(unsigned int));
			Entry.TypeID = *((unsigned int*)TypeID);

			Archive.read(FileID, sizeof(unsigned int));
			Entry.FileID = *((unsigned int*)FileID);

			Filename = new char[Entry.FilenameLength];
			Archive.read(Filename, Entry.FilenameLength);
			memcpy(&Entry.Filename, Filename, Entry.FilenameLength);

			string StrFilename(Filename, Filename + Entry.FilenameLength);
			cout << "Filename: " << StrFilename << "\r\n";


			char* Buffer = new char[Entry.DecompressedDataSize];
			//Don't convert tgas...
			if(StrFilename.find(".tga") == string::npos)
				FARExtractItemFromFileByName(m_ArchivePath.c_str(), StrFilename.c_str(), 
					(unsigned char**)&Buffer, 1);

				FREE_IMAGE_FORMAT Fif = FreeImage_GetFIFFromFilename(StrFilename.c_str());
				if(Fif != FIF_UNKNOWN)
					FIBITMAP *Img = FreeImage_Load(Fif, StrFilename.c_str());
					FreeImage_Save(FREE_IMAGE_FORMAT::FIF_PNG, Img, Replace(StrFilename, ".bmp", ".png").c_str());

					//delete Img; //This causes an assertion... o_O

			delete Buffer;


	void FileArchive::RecreateArchive()
		int ManifestOffset = 11;

		ofstream Archive(Replace(m_ArchivePath, ".dat", ".tmp").c_str());
		Archive << "FAR!byAZ";	//Signature
		Archive << 3;			//Version
		Archive << 0x00;		//ManifestOffset

		for(unsigned int i = 0; i < m_NumFiles; i++)
			char* Filename = new char[m_Entries[i].FilenameLength];
			memcpy(Filename, &m_Entries[i].Filename, m_Entries[i].FilenameLength);
			string StrFilename(Filename, Filename + m_Entries[i].FilenameLength);
			StrFilename = Replace(StrFilename, ".bmp", ".png");

			ifstream CurrentFile(StrFilename.c_str(), ios::in | ios::binary | ios::ate);
			//CurrentFile.seekg(0, ios::end);
			ifstream::pos_type size = CurrentFile.tellg();

			unsigned char *MemBlock = new unsigned char[size];
			CurrentFile.seekg(0, ios::beg);
			CurrentFile.read((char*)MemBlock, size);

			unsigned char* Dst = mynew<unsigned char>((int)size - 1);
			unsigned char* DstEnd = compress((unsigned char*)MemBlock, (unsigned char*)MemBlock + size, 
				Dst, Dst + size - 1, false);
			cout << "Bob the builder, can he compress it? \r\n"; 

			//Write the compressed...
				unsigned int DstLength = DstEnd - Dst;

				//TODO: Write FAR3 Compression header.
				cout << "Yes he can!\r\n\r\n";
				//Update the offset for the location of the data!
				m_Entries[i].DataOffset = Archive.tellp();

				for(unsigned int i = 0; i < DstLength; i++)
					Archive << Dst[i];
			else //... or uncompressed file.
				cout << "No he can't!\r\n\r\n";
				m_Entries[i].Compressed = 0x00;

				for(int i = 0; i < size; i++)
					Archive << Dst[i];
			delete Dst;
			delete MemBlock;
			delete Filename;

		ifstream::pos_type ManifestOffsetStart = Archive.tellp();

		for(unsigned int i = 0; i < m_NumFiles; i++)
			Archive << m_Entries[i].DecompressedDataSize;
			//TODO: Write this as only 3 bytes!
			Archive << m_Entries[i].CompressedDataSize;
			Archive << m_Entries[i].DataType;
			Archive << m_Entries[i].DataOffset;
			Archive << m_Entries[i].Compressed;
			Archive << m_Entries[i].AccessNumber;
			Archive << m_Entries[i].FilenameLength;
			Archive << m_Entries[i].TypeID;
			Archive << m_Entries[i].FileID;
			//Note: Not entirely sure if this is the correct way to get the filename down...
			for(unsigned int j = 0; j < m_Entries[i].FilenameLength; j++)

	string Replace(string Str, string From, string To)
		int Position = Str.find(From);

		while(Position != string::npos)
			Str = Str.replace(Position, From.length(), To);
			Position = Str.find(From, Position + From.length());

		return Str;

I'm using FreeImage to convert the images, and some black voodoo magic to recompress an archive.
Oh, and, in case you can't figure it out by looking at this code, here's what a FAR3 entry looks like:

struct FAR3Entry {
	unsigned int DecompressedDataSize;
	unsigned int CompressedDataSize; /* Only 3 bytes large; refers to the total data's size including the RefPack header */
	unsigned char DataType; /* Normally equals 0x80 to denote that the data is in a RefPack container */
	unsigned int DataOffset; /* Relative to the beginning of the FAR file */
	unsigned char Compressed; /* Normally equals 0x01 */
	unsigned char AccessNumber; /* Refers to the number of times that the data at the specified offset has been used for other entries: Normally equals 0x00 (and works its way up) */
	unsigned short FilenameLength; /* Note that the file name does not terminate with a null character */
	unsigned int TypeID;
	unsigned int FileID;
	char Filename[256];

Lesson learned?
If you're trying to find the size of a 1,5kb file and end up allocating 3,9gigs for it, the file probably wasn't opened, or you did something wrong.