TeapotWarsView.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. //========================================================================
  2. // TeapotWars.cpp : source file for the sample game
  3. //
  4. // Part of the GameCode4 Application
  5. //
  6. // GameCode4 is the sample application that encapsulates much of the source code
  7. // discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
  8. // "Rez" Graham, published by Charles River Media.
  9. // ISBN-10: 1133776574 | ISBN-13: 978-1133776574
  10. //
  11. // If this source code has found it's way to you, and you think it has helped you
  12. // in any way, do the authors a favor and buy a new copy of the book - there are
  13. // detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
  14. // by clicking here:
  15. // http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
  16. //
  17. // There's a companion web site at http://www.mcshaffry.com/GameCode/
  18. //
  19. // The source code is managed and maintained through Google Code:
  20. // http://code.google.com/p/gamecode4/
  21. //
  22. // (c) Copyright 2012 Michael L. McShaffry and David Graham
  23. //
  24. // This program is free software; you can redistribute it and/or
  25. // modify it under the terms of the GNU Lesser GPL v3
  26. // as published by the Free Software Foundation.
  27. //
  28. // This program is distributed in the hope that it will be useful,
  29. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  31. // http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
  32. //
  33. // You should have received a copy of the GNU Lesser GPL v3
  34. // along with this program; if not, write to the Free Software
  35. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  36. //
  37. //========================================================================
  38. #include "../GCC4/Unix/GameCodeStd.cpp"
  39. #include "Unix/TeapotWars.h"
  40. #include "../GCC4/EventManager/Events.h"
  41. #include "../GCC4/EventManager/EventManagerImpl.h"
  42. // #include "../GCC4/Physics/PhysicsEventListener.h"
  43. #include "../GCC4/LUAScripting/LuaStateManager.h" // [rez] For debugging only; the view shouldn't use Lua
  44. #include "TeapotWarsView.h"
  45. #include "TeapotEvents.h"
  46. #include <GL/glew.h>
  47. #include <memory>
  48. #include <misc/cpp/imgui_stdlib.h>
  49. extern TeapotWarsApp g_TeaportWarsApp;
  50. //========================================================================
  51. //
  52. // MainMenuUI & MainMenuView implementation
  53. //
  54. //
  55. //========================================================================
  56. #define CID_START_BUTTON (0)
  57. #define CID_QUIT_BUTTON (1)
  58. const int g_SampleUIWidth = 600;
  59. const int g_SampleUIHeight = 600;
  60. MainMenuUI::MainMenuUI()
  61. {
  62. m_bCreatingGame = true;
  63. m_Levels = g_pApp->GetGameLogic()->GetLevelManager()->GetLevels();
  64. m_LevelIndex = 0;
  65. // grab defaults from the game options.
  66. m_NumAIs = g_pApp->m_Options.m_numAIs;
  67. m_NumPlayers = g_pApp->m_Options.m_expectedPlayers;
  68. m_HostName = g_pApp->m_Options.m_gameHost;
  69. m_HostListenPort = g_pApp->m_Options.m_listenPort;
  70. m_ClientAttachPort = g_pApp->m_Options.m_listenPort;
  71. }
  72. int MainMenuUI::VOnRestore()
  73. {
  74. // m_SampleUI.SetLocation( (g_pApp->GetScreenSize().x - g_SampleUIWidth)/2, (g_pApp->GetScreenSize().y - g_SampleUIHeight) / 2 );
  75. // m_SampleUI.SetSize( g_SampleUIWidth, g_SampleUIHeight );
  76. // return S_OK;
  77. return 0;
  78. }
  79. int MainMenuUI::VOnRender(double fTime, float fElapsedTime)
  80. {
  81. ImGuiIO& io = ImGui::GetIO();
  82. // don't let title bar change colour when clicked
  83. ImVec4 titleBgColor = ImGui::GetStyleColorVec4(ImGuiCol_TitleBg);
  84. ImGui::PushStyleColor(ImGuiCol_TitleBgActive, titleBgColor);
  85. // maths to centre window on screen
  86. ImVec2 screenSize = io.DisplaySize;
  87. ImVec2 screenCenter = ImVec2(screenSize.x * 0.5f, screenSize.y * 0.5f);
  88. ImGui::SetNextWindowPos(screenCenter, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
  89. // Let's draw a menu!
  90. ImGui::Begin("Teapot Wars Main Menu", nullptr,
  91. ImGuiWindowFlags_NoMove |
  92. ImGuiWindowFlags_NoCollapse |
  93. ImGuiWindowFlags_NoResize |
  94. ImGuiWindowFlags_AlwaysAutoResize
  95. );
  96. ImGui::Text("Level");
  97. if (ImGui::BeginCombo("##Level", m_Levels[m_LevelIndex].c_str(), 0))
  98. {
  99. for (int i = 0; i < m_Levels.size(); i++)
  100. {
  101. const bool isSelected = (m_LevelIndex == i);
  102. if (ImGui::Selectable(m_Levels[i].c_str(), m_LevelIndex == i))
  103. m_LevelIndex = i;
  104. // Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
  105. if (isSelected)
  106. ImGui::SetItemDefaultFocus();
  107. }
  108. ImGui::EndCombo();
  109. }
  110. ImGui::Dummy(ImVec2(0.0f, 20.0f));
  111. if (ImGui::RadioButton("Create Game", m_bCreatingGame)) {
  112. m_bCreatingGame = true;
  113. }
  114. ImGui::Text("Number of Players");
  115. ImGui::SliderInt("##Number of Players", &m_NumPlayers, 1, g_pApp->m_Options.m_maxPlayers);
  116. ImGui::Dummy(ImVec2(0.0f, 5.0f));
  117. ImGui::Text("Number of AIs");
  118. ImGui::SliderInt("##Number of AIs", &m_NumAIs, 0, g_pApp->m_Options.m_maxAIs);
  119. ImGui::Dummy(ImVec2(0.0f, 20.0f));
  120. if (ImGui::RadioButton("Join Game", !m_bCreatingGame)) {
  121. m_bCreatingGame = false;
  122. }
  123. ImGui::Text("Host Attach Port");
  124. ImGui::InputText("##Host Attach Port", &m_HostListenPort);
  125. ImGui::Dummy(ImVec2(0.0f, 5.0f));
  126. ImGui::Text("Host Name");
  127. ImGui::InputText("##Host Name", &m_HostName);
  128. ImGui::Dummy(ImVec2(0.0f, 20.0f));
  129. if (ImGui::Button("Start Game"))
  130. _OnGUIEvent(CID_START_BUTTON);
  131. ImGui::SameLine();
  132. if (ImGui::Button("Quit"))
  133. _OnGUIEvent(CID_QUIT_BUTTON);
  134. ImGui::End();
  135. ImGui::PopStyleColor();
  136. return 0;
  137. }
  138. int MainMenuUI::VOnMsgProc( SDL_Event &e )
  139. {
  140. return 0;
  141. }
  142. //--------------------------------------------------------------------------------------
  143. // Handles the GUI events
  144. //--------------------------------------------------------------------------------------
  145. // Note: pUserContext added to comply with DirectX 9c - June 2005 Update
  146. //
  147. void MainMenuUI::_OnGUIEvent(unsigned int event)
  148. {
  149. switch (event)
  150. {
  151. case CID_START_BUTTON:
  152. {
  153. g_pApp->m_Options.m_numAIs = m_NumAIs;
  154. g_pApp->m_Options.m_expectedPlayers = m_NumPlayers;
  155. if (m_bCreatingGame)
  156. {
  157. if (m_LevelIndex == -1)
  158. {
  159. // FUTURE WORK - AN ERROR DIALOG WOULD BE GOOD HERE, OR JUST DEFALT THE SELECTION TO SOMETHING VALID
  160. return;
  161. }
  162. g_pApp->m_Options.m_Level = m_Levels[m_LevelIndex];
  163. g_pApp->m_Options.m_gameHost = "";
  164. g_pApp->m_Options.m_listenPort = atoi(m_HostListenPort.c_str());
  165. }
  166. else
  167. {
  168. g_pApp->m_Options.m_gameHost = m_HostName;
  169. g_pApp->m_Options.m_listenPort = atoi(m_ClientAttachPort.c_str());
  170. }
  171. VSetVisible(false);
  172. std::shared_ptr<EvtData_Request_Start_Game> pRequestStartGameEvent(GCC_NEW EvtData_Request_Start_Game());
  173. IEventManager::Get()->VQueueEvent(pRequestStartGameEvent);
  174. break;
  175. }
  176. case CID_QUIT_BUTTON:
  177. {
  178. break;
  179. }
  180. }
  181. }
  182. MainMenuView::MainMenuView() : HumanView(std::shared_ptr<IRenderer>())
  183. {
  184. // TODO(munnellg) - implement
  185. m_MainMenuUI.reset(GCC_NEW MainMenuUI);
  186. VPushElement(m_MainMenuUI);
  187. }
  188. MainMenuView::~MainMenuView()
  189. {
  190. }
  191. void MainMenuView::VRenderText()
  192. {
  193. HumanView::VRenderText();
  194. }
  195. void MainMenuView::VOnUpdate(unsigned long deltaMs)
  196. {
  197. HumanView::VOnUpdate(deltaMs);
  198. }
  199. int MainMenuView::VOnMsgProc( SDL_Event &e )
  200. {
  201. if (m_MainMenuUI->VIsVisible() )
  202. {
  203. if (HumanView::VOnMsgProc(e))
  204. return 1;
  205. }
  206. return 0;
  207. }
  208. //========================================================================
  209. //
  210. // TeapotWarsHumanView Implementation
  211. //
  212. //========================================================================
  213. //
  214. // TeapotWarsHumanView::TeapotWarsHumanView - Chapter 19, page 724
  215. //
  216. TeapotWarsHumanView::TeapotWarsHumanView(std::shared_ptr<IRenderer> renderer) : HumanView(renderer)
  217. {
  218. m_bShowUI = true;
  219. RegisterAllDelegates();
  220. }
  221. TeapotWarsHumanView::~TeapotWarsHumanView()
  222. {
  223. RemoveAllDelegates();
  224. }
  225. //
  226. // TeapotWarsHumanView::VOnMsgProc - Chapter 19, page 727
  227. //
  228. int TeapotWarsHumanView::VOnMsgProc( SDL_Event &e )
  229. {
  230. if (HumanView::VOnMsgProc(e))
  231. return 1;
  232. switch (e.type)
  233. {
  234. case SDL_EVENT_KEY_DOWN:
  235. switch (e.key.scancode)
  236. {
  237. case SDL_SCANCODE_F4:
  238. {
  239. Resource resource("scripts/test.lua");
  240. std::shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource); // this actually loads the lua file from the zip file
  241. return 1;
  242. }
  243. case SDL_SCANCODE_F5:
  244. {
  245. std::shared_ptr<EvtData_ScriptEventTest_ToLua> pEvent(GCC_NEW EvtData_ScriptEventTest_ToLua);
  246. IEventManager::Get()->VQueueEvent(pEvent);
  247. return 1;
  248. }
  249. // case SDL_SCANCODE_F6:
  250. // {
  251. // LuaStateManager::Get()->VExecuteString("TestProcess()");
  252. // return 1;
  253. // }
  254. case SDL_SCANCODE_F8:
  255. {
  256. // m_KeyboardHandler = m_pTeapotController;
  257. // m_PointerHandler = m_pTeapotController;
  258. m_pCamera->SetTarget(m_pTeapot);
  259. // m_pTeapot->SetAlpha(0.8f);
  260. SDL_SetWindowRelativeMouseMode(g_pApp->GetWindow(), false);
  261. return 1;
  262. }
  263. case SDL_SCANCODE_F11:
  264. {
  265. m_KeyboardHandler = m_pFreeCameraController;
  266. m_PointerHandler = m_pFreeCameraController;
  267. m_pCamera->ClearTarget();
  268. // m_pTeapot->SetAlpha(0.8f);
  269. SDL_SetWindowRelativeMouseMode(g_pApp->GetWindow(), true);
  270. return 1;
  271. }
  272. default:
  273. break;
  274. }
  275. default:
  276. break;
  277. }
  278. return 0;
  279. }
  280. void TeapotWarsHumanView::VRenderText()
  281. {
  282. // TODO(munnellg) - implement
  283. }
  284. void TeapotWarsHumanView::VOnUpdate(unsigned long deltaMs)
  285. {
  286. HumanView::VOnUpdate( deltaMs );
  287. if (m_pFreeCameraController)
  288. {
  289. m_pFreeCameraController->OnUpdate(deltaMs);
  290. }
  291. // if (m_pTeapotController)
  292. // {
  293. // m_pTeapotController->OnUpdate(deltaMs);
  294. // }
  295. //Send out a tick to listeners
  296. // std::shared_ptr<EvtData_Update_Tick> pTickEvent(GCC_NEW EvtData_Update_Tick(deltaMs));
  297. // IEventManager::Get()->VTriggerEvent(pTickEvent);
  298. }
  299. void TeapotWarsHumanView::VOnAttach(GameViewId vid, ActorId aid)
  300. {
  301. // TODO(munnellg) - implement
  302. }
  303. bool TeapotWarsHumanView::VLoadGameDelegate(TiXmlElement* pLevelData)
  304. {
  305. if (!HumanView::VLoadGameDelegate(pLevelData))
  306. return false;
  307. // m_StandardHUD.reset(GCC_NEW StandardHUD);
  308. // VPushElement(m_StandardHUD);
  309. // A movement controller is going to control the camera,
  310. // but it could be constructed with any of the objects you see in this
  311. // function. You can have your very own remote controlled sphere. What fun...
  312. m_pFreeCameraController.reset(GCC_NEW MovementController(m_pCamera, 0, 0, false));
  313. m_pScene->VOnRestore();
  314. return true;
  315. }
  316. void TeapotWarsHumanView::VSetControlledActor(ActorId actorId)
  317. {
  318. m_pTeapot = static_pointer_cast<SceneNode>(m_pScene->FindActor(actorId));
  319. if (!m_pTeapot)
  320. {
  321. GCC_ERROR("Invalid teapot");
  322. return;
  323. }
  324. HumanView::VSetControlledActor(actorId);
  325. // m_pTeapotController.reset(GCC_NEW TeapotController(m_pTeapot));
  326. // m_KeyboardHandler = m_pTeapotController;
  327. // m_PointerHandler = m_pTeapotController;
  328. m_pCamera->SetTarget(m_pTeapot);
  329. // m_pTeapot->SetAlpha(0.8f);
  330. }
  331. void TeapotWarsHumanView::SetControlledActorDelegate(IEventDataPtr pEventData)
  332. {
  333. std::shared_ptr<EvtData_Set_Controlled_Actor> pCastEventData = static_pointer_cast<EvtData_Set_Controlled_Actor>(pEventData);
  334. VSetControlledActor(pCastEventData->GetActorId());
  335. }
  336. void TeapotWarsHumanView::RegisterAllDelegates(void)
  337. {
  338. // TODO(munnellg) - implement
  339. // [mrmike] Move, New, and Destroy actor events are now handled by the HumanView, as are the PlaySound and GameState events
  340. IEventManager* pGlobalEventManager = IEventManager::Get();
  341. // pGlobalEventManager->VAddListener(MakeDelegate(this, &TeapotWarsHumanView::GameplayUiUpdateDelegate), EvtData_Gameplay_UI_Update::sk_EventType);
  342. pGlobalEventManager->VAddListener(MakeDelegate(this, &TeapotWarsHumanView::SetControlledActorDelegate), EvtData_Set_Controlled_Actor::sk_EventType);
  343. }
  344. void TeapotWarsHumanView::RemoveAllDelegates(void)
  345. {
  346. // TODO(munnellg) - implement
  347. IEventManager* pGlobalEventManager = IEventManager::Get();
  348. // pGlobalEventManager->VRemoveListener(MakeDelegate(this, &TeapotWarsHumanView::GameplayUiUpdateDelegate), EvtData_Gameplay_UI_Update::sk_EventType);
  349. pGlobalEventManager->VRemoveListener(MakeDelegate(this, &TeapotWarsHumanView::SetControlledActorDelegate), EvtData_Set_Controlled_Actor::sk_EventType);
  350. }