1 // WARNING: copy of this file is used in OpenGL platform, modify both files if possible 2 #include "Precompiled.h" 3 #include "BaseManager.h" 4 5 #include <SDL_image.h> 6 7 namespace base 8 { BaseManager()9 BaseManager::BaseManager() : 10 mGUI(nullptr), 11 mPlatform(nullptr), 12 mWindow(nullptr), 13 mContext(nullptr), 14 mExit(false), 15 mWindowOn(false), 16 mResourceFileName("MyGUI_Core.xml"), 17 mFpsCounter(0) 18 { 19 } 20 _windowResized(int w,int h)21 void BaseManager::_windowResized( int w, int h ) 22 { 23 if (mPlatform) 24 MyGUI::RenderManager::getInstance().setViewSize(w, h); 25 26 setInputViewSize(w, h); 27 } 28 create(int _width,int _height)29 bool BaseManager::create(int _width, int _height) 30 { 31 // initialize SDL 32 if (SDL_Init(SDL_INIT_VIDEO) != 0) 33 { 34 std::cerr << "Failed to initialize SDL2."; 35 exit(1); 36 } 37 // initialize SDL_image 38 #ifndef EMSCRIPTEN 39 if (IMG_Init(~0) == 0) 40 { 41 std::cerr << "Failed to initialize SDL_image."; 42 exit(1); 43 } 44 #endif 45 //chdir("/"); 46 SDL_Surface *image = nullptr; 47 std::string fileName = "/MyGUI_Media/DejaVuSansFontGenerated_15.png"; 48 image = IMG_Load(fileName.c_str()); 49 if (image == nullptr) 50 { 51 std::cerr << "Failed to load " << fileName << " image" << std::endl; 52 exit(-1); 53 } 54 // fileName = "test.png"; 55 // image = IMG_Load(fileName.c_str()); 56 // if (image == nullptr) 57 // { 58 // std::cerr << "Failed to load " << fileName << " image" << std::endl; 59 // exit(-1); 60 // } 61 62 const unsigned int width = _width; 63 const unsigned int height = _height; 64 bool windowed = true; 65 66 // create window and position it at the center of the screen 67 SDL_DisplayMode currDisp; 68 MYGUI_ASSERT(SDL_GetCurrentDisplayMode(0, &currDisp) == 0, "Failed to retrieve screen info."); 69 int left = (currDisp.w - width) / 2; 70 int top = (currDisp.h - height) / 2; 71 72 mWindow = SDL_CreateWindow("OpenGLES Render Window", left, top, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); 73 MYGUI_ASSERT(mWindow != nullptr, "Failed to create SDL window."); 74 mContext = SDL_GL_CreateContext(mWindow); 75 MYGUI_ASSERT(mContext != nullptr, "Failed to create SDL context."); 76 mWindowOn = true; 77 78 if (!createRender(width, height, windowed)) 79 { 80 return false; 81 } 82 83 createGui(); 84 85 createInput(); 86 87 createPointerManager(); 88 89 // this needs to be called before createScene() since some demos require 90 // screen size to properly position the widgets 91 _windowResized(width, height); 92 93 createScene(); 94 95 return true; 96 } 97 run()98 void BaseManager::run() 99 { 100 #ifndef EMSCRIPTEN 101 while (!mExit) 102 #endif 103 { 104 while (SDL_PollEvent(&mEvent) != 0) 105 { 106 switch (mEvent.type) 107 { 108 // keyboard events 109 case SDL_KEYDOWN: 110 mKeyCode = mEvent.key.keysym.sym; 111 keyPressed(mKeyCode, nullptr); 112 break; 113 case SDL_TEXTINPUT: 114 mKeyCode = SDLK_UNKNOWN; 115 keyPressed(mKeyCode, &mEvent.text); 116 break; 117 case SDL_KEYUP: 118 keyReleased(mEvent.key); 119 break; 120 // mouse events 121 case SDL_MOUSEMOTION: 122 mouseMoved(mEvent.motion); 123 break; 124 case SDL_MOUSEBUTTONDOWN: 125 mousePressed(mEvent.button); 126 break; 127 case SDL_MOUSEBUTTONUP: 128 mouseReleased(mEvent.button); 129 break; 130 case SDL_MOUSEWHEEL: 131 mouseWheelMoved(mEvent.wheel); 132 break; 133 // drop file events 134 case SDL_DROPFILE: 135 break; 136 // windows events 137 case SDL_WINDOWEVENT: 138 switch (mEvent.window.event) 139 { 140 case SDL_WINDOWEVENT_CLOSE: 141 mExit = true; 142 break; 143 case SDL_WINDOWEVENT_RESIZED: 144 _windowResized(mEvent.window.data1, mEvent.window.data2); 145 break; 146 case SDL_WINDOWEVENT_SHOWN: 147 case SDL_WINDOWEVENT_RESTORED: 148 case SDL_WINDOWEVENT_EXPOSED: 149 case SDL_WINDOWEVENT_MAXIMIZED: 150 mWindowOn = true; 151 break; 152 case SDL_WINDOWEVENT_MINIMIZED: 153 case SDL_WINDOWEVENT_HIDDEN: 154 mWindowOn = false; 155 default: 156 break; 157 } 158 break; 159 default: 160 break; 161 } 162 } 163 glClearColor(0, 0, 0, 1); 164 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 165 166 drawOneFrame(); 167 if (!mWindowOn) 168 SDL_Delay(50); 169 } 170 } 171 destroy()172 void BaseManager::destroy() 173 { 174 destroyScene(); 175 176 destroyPointerManager(); 177 178 destroyInput(); 179 180 destroyGui(); 181 182 destroyRender(); 183 184 SDL_GL_DeleteContext(mContext); 185 IMG_Quit(); 186 SDL_Quit(); 187 } 188 setupResources()189 void BaseManager::setupResources() 190 { 191 #ifdef EMSCRIPTEN 192 mRootMedia = "/"; 193 addResourceLocation(mRootMedia, false); 194 addResourceLocation(mRootMedia + "MyGUI_Media/", false); 195 return; 196 #endif 197 198 MyGUI::xml::Document doc; 199 200 if (!doc.open(std::string("resources.xml"))) 201 doc.getLastError(); 202 203 MyGUI::xml::ElementPtr root = doc.getRoot(); 204 if (root == nullptr || root->getName() != "Paths") 205 return; 206 207 MyGUI::xml::ElementEnumerator node = root->getElementEnumerator(); 208 while (node.next()) 209 { 210 if (node->getName() == "Path") 211 { 212 if (node->findAttribute("root") != "") 213 { 214 bool rootAttribute = MyGUI::utility::parseBool(node->findAttribute("root")); 215 if (rootAttribute) 216 mRootMedia = node->getContent(); 217 } 218 addResourceLocation(node->getContent(), false); 219 } 220 } 221 222 addResourceLocation(getRootMedia() + "/Common/Base"); 223 } 224 createGui()225 void BaseManager::createGui() 226 { 227 mPlatform = new MyGUI::OpenGLESPlatform(); 228 mPlatform->initialise(this); 229 230 setupResources(); 231 232 mGUI = new MyGUI::Gui(); 233 mGUI->initialise(mResourceFileName); 234 235 SDL_StartTextInput(); 236 } 237 destroyGui()238 void BaseManager::destroyGui() 239 { 240 SDL_StopTextInput(); 241 if (mGUI) 242 { 243 mGUI->shutdown(); 244 delete mGUI; 245 mGUI = nullptr; 246 } 247 248 if (mPlatform) 249 { 250 mPlatform->shutdown(); 251 delete mPlatform; 252 mPlatform = nullptr; 253 } 254 } 255 setWindowMaximized(bool _value)256 void BaseManager::setWindowMaximized(bool _value) 257 { 258 if (mWindow != nullptr && _value) 259 { 260 SDL_MaximizeWindow(mWindow); 261 } 262 } 263 getWindowMaximized()264 bool BaseManager::getWindowMaximized() 265 { 266 Uint32 windowState = SDL_GetWindowFlags(mWindow); 267 return windowState & SDL_WINDOW_MAXIMIZED || windowState & SDL_WINDOW_FULLSCREEN; 268 } 269 setWindowCoord(const MyGUI::IntCoord & _value)270 void BaseManager::setWindowCoord(const MyGUI::IntCoord& _value) 271 { 272 if (_value.empty()) 273 return; 274 275 MyGUI::IntCoord coord = _value; 276 277 SDL_SetWindowPosition(mWindow, coord.left, coord.top); 278 } 279 getWindowCoord()280 MyGUI::IntCoord BaseManager::getWindowCoord() 281 { 282 int left, top, width, height; 283 SDL_GetWindowPosition(mWindow, &left, &top); 284 SDL_GetWindowSize(mWindow, &width, &height); 285 return MyGUI::IntCoord(left, top, width, height); 286 } 287 setWindowCaption(const std::wstring & _text)288 void BaseManager::setWindowCaption(const std::wstring& _text) 289 { 290 MyGUI::UString title(_text); 291 SDL_SetWindowTitle(mWindow, title.asUTF8_c_str()); 292 } 293 prepare()294 void BaseManager::prepare() 295 { 296 } 297 addResourceLocation(const std::string & _name,bool _recursive)298 void BaseManager::addResourceLocation(const std::string& _name, bool _recursive) 299 { 300 mPlatform->getDataManagerPtr()->addResourceLocation(_name, _recursive); 301 } 302 getStatistic()303 MyGUI::MapString BaseManager::getStatistic() 304 { 305 MyGUI::MapString statistics; 306 statistics["FPS"] = MyGUI::utility::toString(mFpsCounter); 307 mFpsCounter = 0; 308 return statistics; 309 } 310 injectMouseMove(int _absx,int _absy,int _absz)311 void BaseManager::injectMouseMove(int _absx, int _absy, int _absz) 312 { 313 if (!mGUI) 314 return; 315 316 MyGUI::InputManager::getInstance().injectMouseMove(_absx, _absy, _absz); 317 } 318 injectMousePress(int _absx,int _absy,MyGUI::MouseButton _id)319 void BaseManager::injectMousePress(int _absx, int _absy, MyGUI::MouseButton _id) 320 { 321 if (!mGUI) 322 return; 323 324 MyGUI::InputManager::getInstance().injectMousePress(_absx, _absy, _id); 325 } 326 injectMouseRelease(int _absx,int _absy,MyGUI::MouseButton _id)327 void BaseManager::injectMouseRelease(int _absx, int _absy, MyGUI::MouseButton _id) 328 { 329 if (!mGUI) 330 return; 331 332 MyGUI::InputManager::getInstance().injectMouseRelease(_absx, _absy, _id); 333 } 334 injectKeyPress(MyGUI::KeyCode _key,MyGUI::Char _text)335 void BaseManager::injectKeyPress(MyGUI::KeyCode _key, MyGUI::Char _text) 336 { 337 if (!mGUI) 338 return; 339 340 if (_key == MyGUI::KeyCode::Escape) 341 { 342 mExit = true; 343 return; 344 } 345 346 MyGUI::InputManager::getInstance().injectKeyPress(_key, _text); 347 } 348 injectKeyRelease(MyGUI::KeyCode _key)349 void BaseManager::injectKeyRelease(MyGUI::KeyCode _key) 350 { 351 if (!mGUI) 352 return; 353 354 MyGUI::InputManager::getInstance().injectKeyRelease(_key); 355 } 356 createRender(int _width,int _height,bool _windowed)357 bool BaseManager::createRender(int _width, int _height, bool _windowed) 358 { 359 return true; 360 } 361 drawOneFrame()362 void BaseManager::drawOneFrame() 363 { 364 mFpsCounter++; 365 if (mPlatform) 366 mPlatform->getRenderManagerPtr()->drawOneFrame(); 367 368 SDL_GL_SwapWindow(mWindow); 369 } 370 destroyRender()371 void BaseManager::destroyRender() 372 { 373 } 374 convertPixelData(SDL_Surface * _image,MyGUI::PixelFormat & _myGuiPixelFormat)375 void* BaseManager::convertPixelData(SDL_Surface *_image, MyGUI::PixelFormat& _myGuiPixelFormat) 376 { 377 void* ret = nullptr; 378 SDL_PixelFormat *format = _image->format; 379 unsigned int bpp = format->BytesPerPixel; 380 switch (bpp) { 381 case 1: 382 _myGuiPixelFormat = MyGUI::PixelFormat::L8; 383 break; 384 case 2: 385 _myGuiPixelFormat = MyGUI::PixelFormat::L8A8; 386 break; 387 case 3: 388 _myGuiPixelFormat = MyGUI::PixelFormat::R8G8B8; 389 break; 390 case 4: 391 _myGuiPixelFormat = MyGUI::PixelFormat::R8G8B8A8; 392 break; 393 default: 394 break; 395 } 396 SDL_LockSurface(_image); 397 398 int pitchSrc = _image->pitch; //the length of a row of pixels in bytes 399 size_t size = _image->h * pitchSrc; 400 ret = new unsigned char[size]; 401 unsigned char* ptr_source = (unsigned char*)_image->pixels; 402 unsigned char* ptr_dst = (unsigned char*)ret; 403 int pitchDst = _image->w * bpp; 404 if (pitchSrc == pitchDst) 405 { 406 memcpy(ret, _image->pixels, size); 407 } 408 else 409 { 410 for (unsigned int y = 0; y < (unsigned int)_image->h; ++y) 411 { 412 memcpy(ptr_dst, ptr_source, pitchDst); 413 ptr_dst += pitchDst; 414 ptr_source += pitchSrc; 415 } 416 } 417 418 SDL_UnlockSurface(_image); 419 return ret; 420 } 421 loadImage(int & _width,int & _height,MyGUI::PixelFormat & _format,const std::string & _filename)422 void* BaseManager::loadImage(int& _width, int& _height, MyGUI::PixelFormat& _format, const std::string& _filename) 423 { 424 std::string fullname = MyGUI::OpenGLESDataManager::getInstance().getDataPath(_filename); 425 void* result = nullptr; 426 SDL_Surface *image = nullptr; 427 SDL_Surface *cvtImage = nullptr; // converted surface with RGBA/RGB pixel format 428 image = IMG_Load(fullname.c_str()); 429 MYGUI_ASSERT(image != nullptr, "Failed to load image: " + fullname); 430 431 _width = image->w; 432 _height = image->h; 433 434 int bpp = image->format->BytesPerPixel; 435 if (bpp < 3) 436 { 437 result = convertPixelData(image, _format); 438 } 439 else 440 { 441 Uint32 pixelFmt = bpp == 3 ? SDL_PIXELFORMAT_BGR24 : SDL_PIXELFORMAT_ARGB8888; 442 cvtImage = SDL_ConvertSurfaceFormat(image, pixelFmt, 0); 443 result = convertPixelData(cvtImage, _format); 444 SDL_FreeSurface(cvtImage); 445 } 446 SDL_FreeSurface(image); 447 448 return result; 449 } 450 saveImage(int _width,int _height,MyGUI::PixelFormat _format,void * _texture,const std::string & _filename)451 void BaseManager::saveImage(int _width, int _height, MyGUI::PixelFormat _format, void* _texture, const std::string& _filename) 452 { 453 454 } 455 quit()456 void BaseManager::quit() 457 { 458 mExit = true; 459 } 460 getRootMedia()461 const std::string& BaseManager::getRootMedia() 462 { 463 return mRootMedia; 464 } 465 setResourceFilename(const std::string & _flename)466 void BaseManager::setResourceFilename(const std::string& _flename) 467 { 468 mResourceFileName = _flename; 469 } 470 471 } // namespace base 472