//===========================================================================// // File: Interface.cpp // // Project: MUNGA Brick: Interest Manager // // Contents: Interface specifications for interest manager // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- -----------------------------------------------------------// // 08/25/97 JMA Infrastructure changes. // // 08/25/97 ECH Infrastructure changes. // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "AdeptHeaders.hpp" #include "Interface.hpp" #include "Controls.hpp" #include "EntityManager.hpp" #include "CollisionGrid.hpp" #include "Player.hpp" extern "C" { typedef int BOOL; typedef unsigned char BYTE; BOOL _stdcall IsDBCSLeadByte(BYTE TestChar); char* _stdcall CharPrevA(const char* lpszStart, const char* lpszCurrent); char* _stdcall CharNextA(const char* lpsz); } #define CharPrev CharPrevA #define CharNext CharNextA extern DWORD g_bDisableImeCompletely; //############################################################################# //########################### Interface ################################# //############################################################################# Interface::ClassData* Interface::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Interface::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( InterfaceClassID, "Adept::Interface", BaseClass::DefaultData, 0, NULL, (Entity::Factory)Make, (Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage, ExecutionStateEngine::DefaultData, (Entity::GameModel::Factory)GameModel::ConstructGameModel, NULL, (Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify, (Entity::GameModel::ModelWrite)GameModel::WriteToText, (Entity::GameModel::ModelSave)GameModel::SaveGameModel ); Register_Object(DefaultData); g_ControlList = new CControlMappingList (); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Interface::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; delete g_ControlList; g_ControlList = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Interface* Interface::Make( const CreateMessage *message, ReplicatorID *base_id ) { Check_Object(message); gos_PushCurrentHeap(g_LibraryHeap); Interface *new_entity = new Interface(DefaultData, message, base_id, NULL); Check_Object(new_entity); gos_PopCurrentHeap(); return new_entity; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Interface::~Interface() { LeaveChatMode (); Check_Object(ControlsManager::Instance); ControlsManager::Instance->RemoveAllMappings(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Interface::Interface( ClassData *class_data, const CreateMessage *message, ReplicatorID *base_id, ElementRenderer::Element *element ): Entity(class_data, message, base_id, element), reticuleEntity(NULL), targetQuery(NULL, NULL, CanBeShotFlag, NULL) { Check_Pointer(this); // //------------------------------------------------------------ // Interfaces should only map controls on their master machine //------------------------------------------------------------ // m_ChatMode = false; m_InChatMessage = 0; m_InsertMode = true; m_CurrentChatMessage[m_InChatMessage] = 0; reticuleOffset = Point3D::Identity; Verify(GetReplicatorMode() == HermitMode); targetDistance = 2000.0f; // //--------------------------------------------------------------------- // Create the mapping stream and figure out how many mappings to create //--------------------------------------------------------------------- // // const GameModel *model = GetGameModel(); // Check_Object(model); Check_Object(ControlsManager::Instance); // //------------------------------------------ // Spin through the mappings and create them //------------------------------------------ // // LoadControlStream (model->mappingStreamResourceID); } void Interface::ClearMappings (void) { Check_Object (ControlsManager::Instance); ControlsManager::Instance->RemoveAllMappings (); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // static void MyInsertChar(char m_CurrentChatMessage[MaxChatSize], char c1, char c2, int& m_InChatMessage, int& m_ChatLen) { gosASSERT(m_ChatLen >= m_InChatMessage); int num = c2 ? 2 : 1; memmove(m_CurrentChatMessage + m_InChatMessage + num, m_CurrentChatMessage + m_InChatMessage, m_ChatLen - m_InChatMessage); m_CurrentChatMessage[m_InChatMessage++] = c1; if (c2) m_CurrentChatMessage[m_InChatMessage++] = c2; m_ChatLen += num; m_CurrentChatMessage[m_ChatLen] = 0; } static void MyDeleteChar(char m_CurrentChatMessage[MaxChatSize], int& m_InChatMessage, int& m_ChatLen) { gosASSERT(m_ChatLen >= m_InChatMessage); char* pszPrev = CharPrev(m_CurrentChatMessage, m_CurrentChatMessage + m_InChatMessage); int num = m_CurrentChatMessage + m_InChatMessage - pszPrev; memmove(pszPrev, m_CurrentChatMessage + m_InChatMessage, m_ChatLen - m_InChatMessage + 1); m_ChatLen -= num; m_InChatMessage -= num; } void Interface::pushChatKey (DWORD key) { char chr = char (key & 0xff); unsigned int ctrl = unsigned int ((key >> 8) & 0xff); if ((chr == 13) || (m_InChatMessage == (MaxChatSize-1))) { LeaveChatMode (); m_InChatMessage = 0; m_CurrentChatMessage[m_InChatMessage] = 0; return; } if (!g_bDisableImeCompletely) { switch (ctrl) { case KEY_LEFT: // Left arrow must be processed to make GOS IME support work correctly. m_InChatMessage = CharPrev(m_CurrentChatMessage, m_CurrentChatMessage + m_InChatMessage) - m_CurrentChatMessage; break; case KEY_RIGHT: // This is necessary as we support left arrow key. m_InChatMessage = CharNext(m_CurrentChatMessage + m_InChatMessage) - m_CurrentChatMessage; break; // Fix for patch 2 #403 (feature request) case KEY_DELETE: { char* p = m_CurrentChatMessage + m_InChatMessage; if (*p) { char* pNext = CharNext(p); memmove(p, pNext, strlen(pNext) + 1); } } break; } } if (!chr) return; static char bLeadByte; if (bLeadByte) { if (m_ChatLen + 2 < MaxChatSize) MyInsertChar(m_CurrentChatMessage, bLeadByte, chr, m_InChatMessage, m_ChatLen); bLeadByte = 0; } else if (IsDBCSLeadByte(chr)) bLeadByte = chr; else { switch (chr) { case '\\': // invalid keys case '/': break; case KEY_ESCAPE: m_CurrentChatMessage[0] = 0; LeaveChatMode (); break; case '\b': if (m_InChatMessage) MyDeleteChar(m_CurrentChatMessage, m_InChatMessage, m_ChatLen); break; default: MyInsertChar(m_CurrentChatMessage, chr, 0, m_InChatMessage, m_ChatLen); break; } } if (m_InChatMessage == (MaxChatSize-1)) { LeaveChatMode (); m_InChatMessage = 0; m_CurrentChatMessage[m_InChatMessage] = 0; return; } } static bool g_bImeOn = true; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Interface::EnterChatMode (bool team) { m_ChatMode = true; m_TeamChat = team; m_InChatMessage = 0; m_ChatLen = 0; memset (m_CurrentChatMessage,0,MaxChatSize); m_CurrentChatMessage[m_InChatMessage] = 0; Check_Object(ControlsManager::Instance); ControlsManager::Instance->EnterChatMode(this); gos_EnableIME(true); gos_ToggleIME(g_bImeOn); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Interface::LeaveChatMode (void) { m_ChatMode = false; if (ControlsManager::Instance) { Check_Object(ControlsManager::Instance); ControlsManager::Instance->LeaveChatMode(); } g_bImeOn = gos_GetMachineInformation(gos_Info_GetIMEStatus) ? true : false; gos_EnableIME(false); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Interface::LoadControlStream (const ResourceID& control_stream) { // ClearMappings (); // g_ControlList->LoadList (control_stream); g_ControlList->ApplyList (this); // list is already loaded by the player } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Entity* Interface::CastCollisionLine() { Check_Object(this); Stuff::Point3D local_point; Stuff::Point3D origin_point; LinearMatrix4D our_matrix; origin_point = GetLocalToWorld(); our_matrix = GetLocalToWorld(); UnitVector3D origin_direction; our_matrix.GetLocalForwardInWorld(&origin_direction); targetLine.SetOrigin(origin_point); targetLine.SetDirection(origin_direction); targetLine.m_length = targetDistance; targetQuery.m_line = &targetLine; targetQuery.m_normal = &reticuleNormal; targetQuery.m_collisionMask = CanBeShotFlag; Check_Object(Player::GetInstance()); Entity *vehicle = Player::GetInstance()->vehicle; Check_Object(vehicle); targetQuery.m_raySource = vehicle; Adept::Entity *entity_hit; Check_Object(CollisionGrid::Instance); entity_hit = CollisionGrid::Instance->ProjectLine(&targetQuery); targetQuery.m_raySource = entity_hit; reticuleEntity.Remove(); if (entity_hit != NULL) { Check_Object(entity_hit); reticuleEntity.Add(entity_hit); Point3D trans; targetLine.FindEnd(&trans); reticuleOffset.MultiplyByInverse( trans, entity_hit->GetLocalToWorld() ); } return entity_hit; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Interface::TestInstance() { Verify(IsDerivedFrom(DefaultData)); }