Code Search for Developers
 
 
  

Keyboard.cpp from Scorched 3D at Krugle


Show Keyboard.cpp syntax highlighted

////////////////////////////////////////////////////////////////////////////////
//    Scorched3D (c) 2000-2003
//
//    This file is part of Scorched3D.
//
//    Scorched3D is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//    Scorched3D is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with Scorched3D; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
////////////////////////////////////////////////////////////////////////////////

#include <common/Keyboard.h>
#include <common/Defines.h>
#include <XML/XMLFile.h>

bool Keyboard::dvorak_ = false;

Keyboard *Keyboard::instance_ = 0;

Keyboard *Keyboard::instance()
{
	if (!instance_)
	{
		instance_ = new Keyboard;
	}

	return instance_;
}

Keyboard::Keyboard() : keybHistCnt_(0)
{

}

Keyboard::~Keyboard()
{

}

bool Keyboard::init()
{
 	SDL_EnableUNICODE(1);
	SDL_EnableKeyRepeat(250, 100);
	return true;
}

unsigned int Keyboard::getKeyboardState()
{
	// Ingore capslock, numlock and scroll lock
	const unsigned int keymask = KMOD_LSHIFT | KMOD_RSHIFT | KMOD_LCTRL | KMOD_RCTRL |
		KMOD_LALT | KMOD_RALT | KMOD_LMETA | KMOD_RMETA;

	return SDL_GetModState() & keymask;
}

char *Keyboard::getkeyboardbuffer(unsigned int &bufCnt)
{
 	bufCnt = SDLK_LAST;
 	return (char *) SDL_GetKeyState(NULL);
}
 
KeyboardHistory::HistoryElement *Keyboard::getkeyboardhistory(unsigned int &histCnt)
{
 	histCnt = keybHistCnt_;
 	keybHistCnt_=0;

 	return keybHist_;
}
 
void Keyboard::processKeyboardEvent(SDL_Event &event)
{
	// Check we have enough space in the array
	if (keybHistCnt_ >= MAX_KEYBDHIST) return;

	// Check we are adding the correct key type
	if (event.type != SDL_KEYDOWN) return;

	// Check we don't have an international character
	if ( (event.key.keysym.unicode & 0xFF80) == 0 )
	{
		char ch = event.key.keysym.unicode & 0x7F;

		KeyboardHistory::HistoryElement newElement =
		{
			event.key.keysym.sym,
			ch
		};

		// Add characater and symbol to history
		keybHist_[keybHistCnt_++] = newElement;
	}
}

bool &Keyboard::getDvorak()
{
	return dvorak_;
}

void Keyboard::clear()
{
	std::map<std::string, KeyboardKey *>::iterator itor;
	for (itor = keyMap_.begin();
		itor != keyMap_.end();
		itor++)
	{
		delete (*itor).second;
	}
	keyMap_.clear();
	keyList_.clear();
	commandKeys_.clear();	
}

bool Keyboard::saveKeyFile()
{
	XMLNode keysNode("keys");
	std::list<std::string>::iterator itor;
	for (itor = keyList_.begin();
		itor != keyList_.end();
		itor++)
	{
		KeyboardKey *key = getKey((*itor).c_str());
		if (!key || !key->getChanged()) continue;

		XMLNode *keyNode = new XMLNode("keyentry");
		if (key->getNameIsCommand())
			keyNode->addChild(new XMLNode("command", key->getName()));
		else keyNode->addChild(new XMLNode("name", key->getName()));
		keyNode->addChild(new XMLNode("title", key->getTitle()));
		keyNode->addChild(new XMLNode("description", key->getDescription()));
		keyNode->addChild(new XMLNode("group", formatString("%i", key->getGroup())));

		std::vector<KeyboardKey::KeyEntry> &keys = key->getKeys();
		std::vector<KeyboardKey::KeyEntry>::iterator subitor;
		for (subitor = keys.begin();
			subitor != keys.end();
			subitor++)
		{
			KeyboardKey::KeyEntry &subentry = (*subitor);
			const char *name = "";
			const char *state = "";
			KeyboardKey::translateKeyNameValue(subentry.key, name);
			KeyboardKey::translateKeyStateValue(subentry.state, state);
			XMLNode *subnode = new XMLNode("key", name);
			if (strcmp(state, "NONE") != 0) subnode->addParameter(
				new XMLNode("state", state, XMLNode::XMLParameterType));
			keyNode->addChild(subnode);
		}

		keysNode.addChild(keyNode);
	}

	const char *fileName = getSettingsFile("keys.xml");
	if (!keysNode.writeToFile(fileName)) return false;

	return true;
}

bool Keyboard::loadKeyFile(bool loadDefaults)
{
	// Empty the current keys
	clear();

	// Load the master list of keys
	if (!loadKeyFile(getDataFile("data/keys.xml"), true)) return false;

	// Replace with any custom keys
	const char *fileName = getSettingsFile("keys.xml");
	if (s3d_fileExists(fileName) && !loadDefaults)
	{
		if (!loadKeyFile(fileName, false)) return false;
	}

	// Build the command list
	std::map<std::string, KeyboardKey *>::iterator keyItor;
	for (keyItor = keyMap_.begin();
		keyItor != keyMap_.end();
		keyItor++)
	{
		KeyboardKey *key = keyItor->second;		

		// Add a command
		if (key->getNameIsCommand()) commandKeys_.push_back(key);

		// Find if this key is already in use
		std::map<std::string, KeyboardKey *>::iterator dupeItor;
		for (dupeItor = keyMap_.begin();
			dupeItor != keyMap_.end();
			dupeItor++)
		{
			KeyboardKey *dupe = dupeItor->second;
			if (dupe == key) continue;

			std::vector<KeyboardKey::KeyEntry> &dupeKeys = dupe->getKeys();
			std::vector<KeyboardKey::KeyEntry>::iterator itor;
			for (itor = dupeKeys.begin();
				itor != dupeKeys.end();
				itor++)
			{
				KeyboardKey::KeyEntry &entry = *itor;
				if (key->hasKey(entry.key, entry.state))
				{
					const char *keyName = "", *stateName = "";
					KeyboardKey::translateKeyNameValue(entry.key, keyName);
					KeyboardKey::translateKeyStateValue(entry.state, stateName);

					dialogMessage("Keyboard", formatString(
								  "Key \"%s\" and state \"%s\" defined for \"%s\" was also defined for \"%s\"",
								  keyName, stateName, key->getName(), dupe->getName()));
					return false;					
				}
			}
		}
	}

	return true;
}

bool Keyboard::loadKeyFile(const char *fileName, bool masterFile)
{
	// Load key definition file
	XMLFile file;
    if (!file.readFile(fileName))
	{
		dialogMessage("Keyboard", formatString(
					  "Failed to parse \"%s\"\n%s", 
					  fileName,
					  file.getParserError()));
		return false;
	}

	// Check file exists
	if (!file.getRootNode())
	{
		dialogMessage("Keyboard", formatString(
					  "Failed to find key definition file \"%s\"",
					  fileName));
		return false;		
	}

	// Itterate all of the keys in the file
    std::list<XMLNode *>::iterator childrenItor;
	std::list<XMLNode *> &children = file.getRootNode()->getChildren();
    for (childrenItor = children.begin();
		 childrenItor != children.end();
		 childrenItor++)
    {
		// Parse the tank entry
        XMLNode *currentNode = (*childrenItor);
		if (strcmp(currentNode->getName(), "keyentry"))
		{
			dialogMessage("Keyboard",
						  "Failed to find keyentry node");
			return false;
		}

		// Get the name of the key
		const char *keyName = 0;
		bool command = false;
		XMLNode *nameNode;
		XMLNode *commandNode;
		if (currentNode->getNamedChild("name", nameNode, false))
		{
			keyName = nameNode->getContent();
			command = false;
		}
		else if (currentNode->getNamedChild("command", commandNode, false))
		{
			keyName = commandNode->getContent();
			command = true;
		}
		else
		{
			dialogMessage("Keyboard",
						  "Failed to find name node");
			return false;
		}

		if (masterFile)
		{
			// We have already seen this key entry, 
			// and we are loading the master key file.
			std::map<std::string, KeyboardKey *>::iterator findItor =
				keyMap_.find(keyName);
			if (findItor != keyMap_.end())
			{
				// Delete it to make space for the new entry.
				delete findItor->second;
				keyMap_.erase(findItor);
			}
		}
		else
		{
			// We have already seen this key entry, 
			// and we are loading custom keys.
			// Only load custom key entries for keys that we have already
			// seen in the master file
			std::map<std::string, KeyboardKey *>::iterator findItor =
				keyMap_.find(keyName);
			if (findItor != keyMap_.end())
			{
				// Delete it to make space for the new entry.
				delete findItor->second;
				keyMap_.erase(findItor);		
			}
			else
			{
				// This is not in the master file
				// Ignore it
				continue;
			}
		}
		
		// Get the description for the key
		XMLNode *descNode;
		if (!currentNode->getNamedChild("description", descNode)) return false;
		const char *keyDesc = descNode->getContent();

		// Get the group
		int group = 0;
		if (!currentNode->getNamedChild("group", group)) return false;

		// Get the title
		XMLNode *titleNode;
		if (!currentNode->getNamedChild("title", titleNode)) return false;
		const char *keyTitle = titleNode->getContent();

		// Add all the key names
		XMLNode *currentKey = 0;
		std::list<std::string> keyNames, keyStateNames;
		while (currentNode->getNamedChild("key", currentKey, false))
		{
			const char *state = "NONE";
			XMLNode *stateNode;
			if (currentKey->getNamedParameter("state", stateNode, false)) 
			state = stateNode->getContent();

			// Add a key and state
			keyNames.push_back(currentKey->getContent());
			keyStateNames.push_back(state);
		}

		// Create the key
		KeyboardKey *newKey = new KeyboardKey(keyName, keyTitle, keyDesc, group, command);
		if (!newKey->addKeys(keyNames, keyStateNames)) return false;
		if (masterFile) newKey->setChanged(false);

		// Add to the list of pre-defined keys
		keyMap_[keyName] = newKey;
		if (masterFile) keyList_.push_back(keyName);
		if (!currentNode->failChildren()) return false;
	}

	return true;
}

KeyboardKey *Keyboard::getKey(const char *name)
{
	static KeyboardKey defaultKey("None", "None", "None", 0, false);

	std::map<std::string, KeyboardKey *>::iterator itor =
		keyMap_.find(name);
	if (itor != keyMap_.end()) return (*itor).second;

	dialogMessage("Keyboard", formatString(
				  "Failed to find key for key name \"%s\"",
				  name));	
	return &defaultKey;
}





See more files for this project here

Scorched 3D

Scorched3D is a 3D remake of the popular 2D artillery game Scorched Earth.\r\nScorched3D can be played against the computer, other players and remotely across the internet or LAN.

Project homepage: http://sourceforge.net/projects/scorched3d
Programming language(s): C,C++,XML
License: gpl2

  ARGParser.cpp
  ARGParser.h
  ChannelManager.cpp
  ChannelManager.h
  ChannelText.cpp
  ChannelText.h
  ChannelTextParser.cpp
  ChannelTextParser.h
  Clock.cpp
  Clock.h
  Counter.cpp
  Counter.h
  Defines.cpp
  Defines.h
  DefinesAssert.cpp
  DefinesAssert.h
  DefinesFile.cpp
  DefinesFile.h
  DefinesMath.cpp
  DefinesMath.h
  DefinesScorched.cpp
  DefinesScorched.h
  DefinesString.cpp
  DefinesString.h
  FileLines.cpp
  FileLines.h
  FileList.cpp
  FileList.h
  FileLogger.cpp
  FileLogger.h
  ImageID.cpp
  ImageID.h
  KeyStateTranslate.h
  KeyTranslate.h
  KeyTranslateWx.h
  Keyboard.cpp
  Keyboard.h
  KeyboardHistory.h
  KeyboardKey.cpp
  KeyboardKey.h
  Line.cpp
  Line.h
  Logger.cpp
  Logger.h
  LoggerI.cpp
  LoggerI.h
  ModelID.cpp
  ModelID.h
  NumberParser.cpp
  NumberParser.h
  OptionEntry.cpp
  OptionEntry.h
  OptionsGame.cpp
  OptionsGame.h
  OptionsMasterListServer.cpp
  OptionsMasterListServer.h
  OptionsParameters.cpp
  OptionsParameters.h
  OptionsScorched.cpp
  OptionsScorched.h
  OptionsTransient.cpp
  OptionsTransient.h
  ProgressCounter.cpp
  ProgressCounter.h
  RandomGenerator.cpp
  RandomGenerator.h
  SplineCurve.cpp
  SplineCurve.h
  SplinePath.cpp
  SplinePath.h
  StatsLogger.cpp
  StatsLogger.h
  StatsLoggerDatabase.cpp
  StatsLoggerDatabase.h
  StatsLoggerFile.cpp
  StatsLoggerFile.h
  StatsLoggerMySQL.cpp
  StatsLoggerMySQL.h
  StatsLoggerPGSQL.cpp
  StatsLoggerPGSQL.h
  StdVectorPtr.h
  ToolTip.cpp
  ToolTip.h
  Triangle.cpp
  Triangle.h
  Vector.cpp
  Vector.h
  Vector4.cpp
  Vector4.h
  VectorLib.cpp
  VectorLib.h
  main.h
  sha2.cpp
  sha2.h
  snprintf.c