Game.cpp
Go to the documentation of this file.
1 #include <ivorium_config.hpp>
2 #if IV_FSPLATFORM_WIN
3  #define WINVER 0x0600
4  #define _WIN32_WINNT 0x0600
5  #include <windows.h>
6  #include <shlobj.h>
7  #include <locale>
8  #include <codecvt>
9 #endif
10 
11 #include "Game.hpp"
12 
14 #include "Misc/DefaultBinder.hpp"
18 
19 #if IV_FSPLATFORM_ANDROID
20  #include <glfm.h>
21 #endif
22 
23 namespace iv
24 {
25 
26 static std::string l_ConfigBase( std::string application_name )
27 {
28 #if IV_FSPLATFORM_XDG
29 
30  std::string conf_home;
31  const char * xdg_config_home = std::getenv( "XDG_CONFIG_HOME" );
32  if( xdg_config_home )
33  {
34  conf_home = xdg_config_home;
35  }
36  else
37  {
38  const char * home = std::getenv( "HOME" );
39  if( home )
40  {
41  conf_home = home;
42  conf_home += "/.config";
43  }
44  else
45  {
46  conf_home = "./.config";
47  }
48  }
49 
50  return conf_home + "/" + application_name;
51 
52 #elif IV_FSPLATFORM_ANDROID
53 
54  #if IV_GLPLATFORM_GLFM
55  return glfmAndroidGetActivity()->externalDataPath;
56  #else
57  #error "Can not retrieve configuration base directory."
58  #endif
59 
60 #elif IV_FSPLATFORM_EMSCRIPTEN
61 
62  return "";
63 
64 #elif IV_FSPLATFORM_WIN
65 
66  // read local appdata path
67  PWSTR localAppDataPath;
68  HRESULT call_result = SHGetKnownFolderPath( FOLDERID_LocalAppData, 0, nullptr, &localAppDataPath );
69  if( call_result != S_OK )
70  {
71  runtime_warning( SRC_INFO, "Failed to get FOLDERID_LocalAppData path." );
72  return "";
73  }
74  std::wstring wpath = localAppDataPath;
75  CoTaskMemFree( static_cast< void * >( localAppDataPath ) );
76 
77  // convert from wstring to string
78  using convert_typeX = std::codecvt_utf8< wchar_t >;
79  std::wstring_convert< convert_typeX, wchar_t > converterX;
80  std::string path = converterX.to_bytes( wpath );
81 
82  // extend with application name and return
83  return path + "/" + application_name;
84 
85 #else
86  #error "Unknown filesystem platform."
87 #endif
88 }
89 
90 Game::Game( Window * window, GameIdentity const & identity ) :
91  _window( window )
92 {
93  // basic systems
94  this->sc.template createOwnSystem< InstanceSystem >();
95  this->sc.template createOwnSystem< DVarSystem >();
96  this->sc.template createOwnSystem< DelayedLoadSystem >();
97  this->sc.template createOwnSystem< TimeSystem >();
98  this->sc.template createOwnSystem< ConfigFileSystem >( l_ConfigBase( identity.configuration_tag.c_str() ) );
99  this->sc.template createOwnSystem< RandomSystem >();
100  this->sc.template createOwnSystem< ResourceManagementSystem >();
101  this->sc.template createOwnSystem< GlSystem >( this->render_target(), this->_window->gpu_enabled() );
102  this->sc.template createOwnSystem< InputSystem >( window );
103  this->sc.template createOwnSystem< InputBindingSystem >();
104  this->sc.template createOwnSystem< ElementSystem >();
105  this->sc.template createOwnSystem< AnimSystem >();
106  this->sc.template createOwnSystem< LumaSystem >();
107 
108  // resource providers
109  this->heap.template create< I< VirtualResourceProvider > >( "virtual_resources", this->system_container(), 0 );
110  this->heap.template create< I< PlatformDefault_ResourceProvider > >( "stream_resources", this->system_container(), 1 );
111 
112  // input binding
113  this->heap.template create< I< DefaultBinder > >( "default_binder", this->system_container() );
114 
115  //
116  this->_window->set_listener( this );
117 }
118 
120 {
121  // delete all objects before systems are deinitialized
122  this->heap.clear();
123 
124  // remove systems in right order (automatic system removal uses random order, which is not ideal)
125  this->sc.template removeSystem< LumaSystem >();
126  this->sc.template removeSystem< AnimSystem >();
127  this->sc.template removeSystem< ElementSystem >();
128  this->sc.template removeSystem< InputBindingSystem >();
129  this->sc.template removeSystem< InputSystem >();
130  this->sc.template removeSystem< GlSystem >();
131  this->sc.template removeSystem< ResourceManagementSystem >();
132  this->sc.template removeSystem< RandomSystem >();
133  this->sc.template removeSystem< ConfigFileSystem >();
134  this->sc.template removeSystem< TimeSystem >();
135  this->sc.template removeSystem< DelayedLoadSystem >();
136  this->sc.template removeSystem< DVarSystem >();
137  this->sc.template removeSystem< InstanceSystem >();
138 }
139 
141 {
142  return &this->sc;
143 }
144 
146 {
147  return this->_window->geometry();
148 }
149 
151 {
152  return this->_window->render_target();
153 }
154 
155 bool Game::input( Input const * input )
156 {
157  return this->game_input( input );
158 }
159 
161 {
162  this->game_focusLost();
163 }
164 
165 void Game::update( uint64_t delta_ms )
166 {
167  this->system_container()->nextFrame();
168  this->system_container()->getSystem< TimeSystem >()->nextFrame();
169  this->system_container()->getSystem< TimeSystem >()->addTime( delta_ms );
170  this->system_container()->flushSystems();
171  this->system_container()->getSystem< AnimSystem >()->AnimUpdate( delta_ms );
172 }
173 
175 {
176  this->game_draw();
177 }
178 
179 void Game::gpu( bool enabled, bool dropped )
180 {
181  auto * gls = this->system_container()->getSystem< GlSystem >();
182 
183  if( dropped )
184  gls->gl_drop();
185 
186  if( enabled )
187  gls->gl_enable();
188  else
189  gls->gl_disable();
190 }
191 
193 {
194  this->system_container()->getSystem< InputSystem >()->window_size( geometry.size );
195  this->game_geometryChanged( geometry );
196 }
197 
199 {
200  if( auto dls = this->system_container()->getSystem< DelayedLoadSystem >() )
201  return dls->loadStep();
202 
203  return false;
204 }
205 
206 }