Asynchronous Input in Dark GDK


For a while I was puzzled as to how to get input asynchronously in Dark GDK - that is, without interrupting the regular flow of things, mostly drawing functions. It turns out there is a function for that, dbGetInput(). By the way, DarkGDK’s documentation isn’t the greatest - dbGetInput is listed as dbInput$ in the docs.

Anyway, as soon as I used it, I ran into another problem; dbGetInput didn’t support backspace. After a bit of poking around on the forums, it turns out you need to do that manually. Someone on the forums made a little function to do just that, which I modified to support multisync and C++ strings. Here it is:

//Function to get input asychronously; returns true if input is still being fed, false if the input has been sent to the server
//Credit goes here: http://forum.thegamecreators.com/?m=forum_view&t=160546&b=22
bool GetInput(std::string& Buffer, int MaxChars)
{
	std::string NewEntry = dbGetEntry();

	// dbGetEntry returns zero before the first character is typed.
	if (NewEntry.length() > 0)
	{
		// Afterwards, the returned pointer is not zero but the string can be empty.
		if (NewEntry[0] != 0)
		{
			dbClearEntryBuffer();

			// There can be more than one characters in the returned string
			// if the user types fast. Add the characters one by one.
			int NewLength = NewEntry.length();
			for (int i = 0; i < NewLength; i++)
			{
				// Backspace: remove the last character from the string
				// if there is still any left.
				if (NewEntry[i] == 8 && !Buffer.empty())
					Buffer.pop_back();
				// Enter: Send the message to the server if there is a message.
				else if (dbReturnKey())
				{
					if(!Buffer.empty())
					{
						//Send the message to the server so it can distribute the message
						NetPutString("PlayerMessage");
						NetPutString((char*)Buffer.c_str());
						NetSend(0);
					}member
					return false;
				}
				// Otherwise: add the character if the buffer is not full yet.
				else if (Buffer.size() < MaxChars - 1)
					Buffer.push_back(NewEntry[i]);
			}
		}
	}
	return true;
}

Here’s the function in use:

// ============ TYPING HANDLING =============
//If the player presses T, start the typing prompt
if(dbKeyState(DIK_T) || typing)
{
	//The player is now typing, set the typing flag to true
	if(!typing)
	{
		dbClearEntryBuffer();
		chatBuffer.clear();
		typing = true;
	}
	//Get the input asynchrounously
	if(!GetInput(chatBuffer, CHATBUFFER_MAX_SIZE))
		typing = false;
	dbText(0, dbScreenHeight() - dbTextHeight("a"), "> ");
	dbText(dbTextWidth(" > "), dbScreenHeight() - dbTextHeight("a"), (char*)chatBuffer.c_str());
}

Edit: Made the code a little cleaner, using strings more.