/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program 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, or (at your option) any later version. ### File Specific: main-programmer: Christian Meyer co-programmer: Patrick Boenzli */ #include "command_node.h" #include "keynames.h" #include "ini_parser.h" #include "world_entity.h" #include "game_loader.h" #include #include #include using namespace std; /** \brief constructs a CommandNode to handle remote input \param ID: unique denumerator to identify the node in the network */ CommandNode::CommandNode (int ID) { bound = new List(); aliases = NULL; netID = ID; bLocalInput = false; } /** \brief constructs a CommandNode to handle local input \param filename: The path and name of the file to load the key bindings from */ CommandNode::CommandNode (char* filename = DEFAULT_KEYBIND_FILE) { aliases = NULL; bLocalInput = true; netID = 0; bound = new List(); load_bindings (filename); } /** \brief removes the CommandNode from memory */ CommandNode::~CommandNode () { if( aliases != NULL) free (aliases); if( bound != NULL) delete bound; } void CommandNode::reset() { this->bound->clear(); } /** \brief loads new key bindings from a file \param filename: The path and name of the file to load the bindings from */ void CommandNode::load_bindings (char* filename) { FILE* stream; printf("Loading key bindings from %s\n", filename); if( filename == NULL) filename = DEFAULT_KEYBIND_FILE; // remove old bindings if present if( aliases != NULL) { free (aliases); aliases = NULL; } // create parser IniParser parser (filename); if( parser.get_section ("Bindings") == -1) { printf("Could not find key bindings in %s\n", filename); return; } // allocate empty lookup table aliases = (KeyBindings*) calloc (1, sizeof (KeyBindings)); char namebuf[256]; char valuebuf[256]; memset (namebuf, 0, 256); memset (valuebuf, 0, 256); int* index; while( parser.next_var (namebuf, valuebuf) != -1) { index = name_to_index (namebuf); switch( index[0]) { case 0: printf("Key binding %d(%s) set to %s\n", index[1], SDLK_to_keyname( index[1]), valuebuf); strcpy (aliases->keys[index[1]], valuebuf); break; case 1: printf("Button binding %d(%s) set to %s\n", index[1], SDLB_to_buttonname( index[1]), valuebuf); strcpy (aliases->buttons[index[1]], valuebuf); break; default: break; } memset (namebuf, 0, 256); memset (valuebuf, 0, 256); } } /** \brief binds a WorldEntity to the CommandNode \param entity: Pointer to the entity to bind */ void CommandNode::bind (WorldEntity* entity) { bound->add (entity); } /** \brief removes an entity from the list of the CommandNode \param entity: Pointer to the entity to relese */ void CommandNode::unbind (WorldEntity* entity) { bound->remove (entity); } int* CommandNode::name_to_index (char* name) { coord[0] = -1; coord[1] = -1; int c; if( (c = keyname_to_SDLK (name)) != -1) { coord[1] = c; coord[0] = 0; } if( (c = buttonname_to_SDLB (name)) != -1) { coord[1] = c; coord[0] = 1; } return coord; } /** \brief tells the CommandNode to run through all pending events and relay them accordingly */ void CommandNode::process () { if( bLocalInput) process_local (); else process_network (); } void CommandNode::process_local () { SDL_Event event; Command cmd; while( SDL_PollEvent (&event)) { memset (cmd.cmd, 0, CMD_LENGHT); switch( event.type) { case SDL_KEYDOWN: strcpy (cmd.cmd, aliases->keys[event.key.keysym.sym]); cmd.bUp = false; if( strlen (cmd.cmd) > 0) relay (&cmd); break; case SDL_KEYUP: strcpy( cmd.cmd, aliases->keys[event.key.keysym.sym]); cmd.bUp = true; cmd.tottime=0.0f; if( strlen (cmd.cmd) > 0) relay (&cmd); break; case SDL_MOUSEMOTION: strcpy( cmd.cmd, "cursor"); cmd.x = event.motion.x; cmd.y = event.motion.y; cmd.xrel = event.motion.xrel; cmd.yrel = event.motion.yrel; break; case SDL_MOUSEBUTTONUP: strcpy( cmd.cmd, aliases->buttons[event.button.button]); cmd.bUp = true; if( strlen (cmd.cmd) > 0) relay (&cmd); break; case SDL_MOUSEBUTTONDOWN: strcpy( cmd.cmd, aliases->buttons[event.button.button]); cmd.bUp = false; if( strlen (cmd.cmd) > 0) relay (&cmd); break; case SDL_JOYAXISMOTION: case SDL_JOYBALLMOTION: case SDL_JOYHATMOTION: case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: break; default: Orxonox *orx = Orxonox::getInstance(); orx->event_handler (&event); break; } } } void CommandNode::process_network () { } void CommandNode::relay (Command* cmd) { Orxonox *orx = Orxonox::getInstance(); if( orx->system_command (cmd)) return; GameLoader* gl = GameLoader::getInstance(); if(gl->worldCommand(cmd)) return; if( bLocalInput) send_over_network (cmd); WorldEntity* entity = bound->enumerate(); while( entity != NULL) { entity->command (cmd); entity = bound->nextElement(); } } /** \brief sets the network identifier of the CommandNode \param ID: the new ID to use */ void CommandNode::set_netID (int ID) { netID = ID; } void CommandNode::send_over_network (Command* cmd) { }