Pie Noon
An open source project by FPL.
 All Classes Pages
pie_noon_game.h
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef PIE_NOON_GAME_H
16 #define PIE_NOON_GAME_H
17 
18 #ifdef __ANDROID__
19 #define PIE_NOON_USES_GOOGLE_PLAY_GAMES
20 #endif // __ANDROID__
21 
22 #include "ai_controller.h"
23 #include "cardboard_controller.h"
24 #include "fplbase/asset_manager.h"
25 #include "fplbase/input.h"
26 #include "fplbase/renderer.h"
27 #include "full_screen_fader.h"
28 #include "game_state.h"
29 #include "gui_menu.h"
30 #include "multiplayer_controller.h"
31 #include "multiplayer_director.h"
32 #include "pindrop/pindrop.h"
33 #include "player_controller.h"
34 #include "scene_description.h"
35 #include "touchscreen_button.h"
36 #include "touchscreen_controller.h"
37 
38 #ifdef ANDROID_GAMEPAD
39 #include "gamepad_controller.h"
40 #endif // ANDROID_GAMEPAD
41 #ifdef PIE_NOON_USES_GOOGLE_PLAY_GAMES
42 #include "gpg_manager.h"
43 #include "gpg_multiplayer.h"
44 #endif
45 
46 namespace fpl {
47 namespace pie_noon {
48 
49 struct Config;
50 class CharacterStateMachine;
51 struct RenderingAssets;
52 
53 enum PieNoonState {
54  kUninitialized = 0,
55  kLoadingInitialMaterials,
56  kLoading,
57  kTutorial,
58  kJoining,
59  kPlaying,
60  kPaused,
61  kFinished,
62  kMultiplayerWaiting,
63  kMultiscreenClient,
64 };
65 
66 class PieNoonGame {
67  public:
68  PieNoonGame();
69  ~PieNoonGame();
70  bool Initialize(const char* const binary_directory);
71  void Run();
72 
73  // Set the overlay directory name to optionally load assets from.
74  static void SetOverlayName(const char* overlay_name) {
75  overlay_name_ = overlay_name;
76  }
77 
78 #if defined(__ANDROID__)
79  // Parse launch mode and overlay directory name from Intent data.
80  static void ParseViewIntentData(const std::string& intent_data,
81  std::string* launch_mode,
82  std::string* overlay);
83 #endif // defined(__ANDROID__)
84 
85  private:
86  bool InitializeConfig();
87 #ifdef ANDROID_HMD
88  bool InitializeCardboardConfig();
89 #endif
90  bool InitializeGpgIds();
91  bool InitializeRenderer();
92  fplbase::Mesh* CreateVerticalQuadMesh(
93  const flatbuffers::String* material_name, const vec3& offset,
94  const vec2& pixel_bounds, float pixel_to_world_scale);
95  bool InitializeRenderingAssets();
96  bool InitializeGameState();
97  void RenderCardboard(const SceneDescription& scene,
98  const mat4& camera_transform);
99  void Render(const SceneDescription& scene);
100  void RenderForDefault(const SceneDescription& scene);
101  void RenderForCardboard(const SceneDescription& scene);
102  void RenderScene(const SceneDescription& scene,
103  const mat4& additional_camera_changes,
104  const vec2i& resolution);
105  void Render2DElements(const SceneDescription& scene,
106  const mat4& additional_camera_changes);
107  void CorrectCardboardCamera(mat4& cardboard_camera);
108  void DebugPrintCharacterStates();
109  void DebugPrintPieStates();
110  void DebugCamera();
111  const Config& GetConfig() const;
112  const Config& GetCardboardConfig() const;
113  const CharacterStateMachineDef* GetStateMachine() const;
114  fplbase::Mesh* GetCardboardFront(int renderable_id, int variant);
115  PieNoonState UpdatePieNoonState();
116  void TransitionToPieNoonState(PieNoonState next_state);
117  PieNoonState UpdatePieNoonStateAndTransition();
118  void FadeToPieNoonState(PieNoonState next_state, const WorldTime& fade_time,
119  const mathfu::vec4& color, const bool fade_in);
120  bool Fading() const { return fade_exit_state_ != kUninitialized; }
121  void UploadEvents();
122  void UploadAndShowLeaderboards();
123  void UpdateGamepadControllers();
124  int FindAiPlayer();
125  ControllerId AddController(Controller* new_controller);
126  Controller* GetController(ControllerId id);
127  ControllerId FindNextUniqueControllerId();
128  void HandlePlayersJoining(Controller* controller);
129  void HandlePlayersJoining();
130  void AttachMultiplayerControllers();
131  PieNoonState HandleMenuButtons(WorldTime time);
132  // void HandleMenuButton(Controller* controller, TouchscreenButton* button);
133  void UpdateControllers(WorldTime delta_time);
134  void UpdateTouchButtons(WorldTime delta_time);
135 
136  pindrop::Channel PlayStinger();
137  void InitCountdownImage(int seconds);
138  void UpdateCountdownImage(WorldTime time);
139 
140  ButtonId CurrentlyAnimatingJoinImage(WorldTime time) const;
141  const char* TutorialSlideName(int slide_index);
142  bool AnyControllerPresses();
143  void LoadTutorialSlide(int slide_index);
144  void LoadInitialTutorialSlides();
145  void RenderInMiddleOfScreen(const mathfu::mat4& ortho_mat, float x_scale,
146  fplbase::Material* material);
147 
148  void ProcessMultiplayerMessages();
149  void ProcessPlayerStatusMessage(const multiplayer::PlayerStatus&);
150 
151  // returns true if a new splat was displayed
152  bool ShowMultiscreenSplat(int splat_num);
153 
154  static void StringArrayResource(const char* resource_name,
155  std::vector<std::string>* strings);
156 
157  void CheckForNewAchievements();
158 
159 #ifdef PIE_NOON_USES_GOOGLE_PLAY_GAMES
160  void StartMultiscreenGameAsHost();
161  void StartMultiscreenGameAsClient(CharacterId id);
162  void SendMultiscreenPlayerCommand();
163 #endif
164  void ReloadMultiscreenMenu();
165  void UpdateMultiscreenMenuIcons();
166  void SetupWaitingForPlayersMenu();
167  bool ShouldTransitionFromSlide(WorldTime world_time);
168 
169  // Overrides fplbase::LoadFile() in order to optionally load files from
170  // overlay directories.
171  static bool LoadFile(const char* filename, std::string* dest);
172 
173  // The overall operating mode of our game. See CalculatePieNoonState for the
174  // state machine definition.
175  PieNoonState state_;
176 
177  // The elapsed time when we entered state_. In the same time system as
178  // prev_world_time_.
179  WorldTime state_entry_time_;
180 
181  // Hold configuration binary data.
182  std::string config_source_;
183 #ifdef ANDROID_HMD
184  std::string cardboard_config_source_;
185 #endif
186 
187  // Report touches, button presses, keyboard presses.
188  fplbase::InputSystem input_;
189 
190  // Hold rendering context.
191  fplbase::Renderer renderer_;
192 
193  // Load and own rendering resources.
194  fplbase::AssetManager matman_;
195 
196  // Manage ownership and playing of audio assets.
197  pindrop::AudioEngine audio_engine_;
198 
199  // Map RenderableId to rendering mesh.
200  std::vector<fplbase::Mesh*> cardboard_fronts_[RenderableId_Count];
201  fplbase::Mesh* cardboard_backs_[RenderableId_Count];
202 
203  // Rendering mesh for front and back of the stick that props cardboard.
204  fplbase::Mesh* stick_front_;
205  fplbase::Mesh* stick_back_;
206 
207  // Shaders we use.
208  fplbase::Shader* shader_cardboard;
209  fplbase::Shader* shader_lit_textured_normal_;
210  fplbase::Shader* shader_simple_shadow_;
211  fplbase::Shader* shader_textured_;
212  fplbase::Shader* shader_grayscale_;
213 
214  // Shadow material.
215  fplbase::Material* shadow_mat_;
216 
217  // Hold state machine binary data.
218  std::string state_machine_source_;
219 
220  // Hold characters, pies, camera state.
221  GameState game_state_;
222 
223  // Map containing every active controller, referenced by a unique,
224  // unchanging ID.
225  std::vector<std::unique_ptr<Controller>> active_controllers_;
226 
227  // On the host, directs the fake controllers in the multiscreen gameplay.
228  std::unique_ptr<MultiplayerDirector> multiplayer_director_;
229  // On the client, which player are we? 0-3
230  CharacterId multiscreen_my_player_id_;
231  // On the client, Which action we are performing: Attack, Defend, or Cancel
232  // (for waiting).
233  ButtonId multiscreen_action_to_perform_;
234  // On the client, which other player we are aimed at. In multiscreen, each
235  // player starts aimed at the next player (or p3 is aimed back at p0).
236  CharacterId multiscreen_action_aim_at_;
237  int multiscreen_turn_number_;
238  // Animation for the multiscreen splats that appear.
239  float multiscreen_splat_param;
240  float multiscreen_splat_param_speed;
241 
242  // Description of the scene to be rendered. Isolates gameplay and rendering
243  // code with a type-light structure. Recreated every frame.
244  SceneDescription scene_;
245 
246  // World time of previous update. We use this to calculate the delta_time
247  // of the current update. This value is tied to the real-world clock.
248  // Note that it is distict from game_state_.time_, which is *not* tied to the
249  // real-world clock. If the game is paused, game_state.time_ will pause, but
250  // prev_world_time_ will keep chugging.
251  WorldTime prev_world_time_;
252 
253  // Debug data. For displaying when a character's state has changed.
254  std::vector<int> debug_previous_states_;
255  std::vector<motive::Angle> debug_previous_angles_;
256 
257  TouchscreenController* touch_controller_;
258  GuiMenu gui_menu_;
259 
260  std::map<int, ControllerId> gamepad_to_controller_map_;
261 
262  CardboardController* cardboard_controller_;
263 
264  ButtonId join_id_;
265  motive::Motivator1f join_motivator_;
266 
267  // Used to render an overlay to fade the screen.
268  FullScreenFader full_screen_fader_;
269  // State to enter after the fade is complete.
270  PieNoonState fade_exit_state_;
271 
272  // Channel used to play the ambience sound effect.
273  pindrop::Channel ambience_channel_;
274 
275  // A stinger will play before transition to the finished state. Don't
276  // transition until the stinger is complete.
277  pindrop::Channel stinger_channel_;
278 
279  // Channel for the menu music or in-game music.
280  pindrop::Channel music_channel_;
281 
282  // Tutorial slides we are in the midst of displaying.
283  const flatbuffers::Vector<flatbuffers::Offset<fpl::pie_noon::Slide>>*
284  tutorial_slides_;
285 
286  // Tutorial aspect ratio
287  float tutorial_aspect_ratio_;
288 
289  // Our current slide of the tutorial. Valid when state_ is kTutorial.
290  int tutorial_slide_index_;
291 
292  // The Worldtime when the curent tutorial slide was displayed.
293  WorldTime tutorial_slide_time_;
294 
295  // The time we started animating the "join" countdown image
296  WorldTime join_animation_start_time_;
297 
298  ButtonId countdown_start_button_;
299 
300  // The time at which the current turn is over.
301  WorldTime multiscreen_turn_end_time_;
302 
303  int next_achievement_index_;
304 
305  // String version number of the game.
306  const char* version_;
307 
308  // The Worldtime when the game was paused, used just for analytics.
309  WorldTime pause_time_;
310 
311  // Name of the optional overlay to load assets from.
312  static std::string overlay_name_;
313 
314 #ifdef PIE_NOON_USES_GOOGLE_PLAY_GAMES
315  GPGManager gpg_manager;
316 
317  // Network multiplayer library for multi-screen version
318  GPGMultiplayer gpg_multiplayer_;
319 #endif
320 };
321 
322 } // pie_noon
323 } // fpl
324 
325 #endif // PIE_NOON_GAME_H
Definition: gui_menu.h:40
Definition: scene_description.h:60
Definition: touchscreen_controller.h:35
Definition: game_state.h:56
Definition: pie_noon_game.h:66
Definition: full_screen_fader.h:27
Definition: cardboard_controller.h:26
Definition: gpg_multiplayer.h:63
Definition: controller.h:26
Definition: gpg_manager.h:33