Common::Error GobEngine::initGraphics() { if (is800x600()) { warning("GobEngine::initGraphics(): 800x600 games currently unsupported"); return Common::kUnsupportedGameidError; } else if (is640x480()) { _width = 640; _height = 480; _mode = 0x18; } else { _width = 320; _height = 200; _mode = 0x14; } _video->setSize(is640x480()); _pixelFormat = g_system->getScreenFormat(); _video->_surfWidth = _width; _video->_surfHeight = _height; _video->_splitHeight1 = _height; _global->_mouseMaxX = _width; _global->_mouseMaxY = _height; _global->_primarySurfDesc = SurfacePtr(new Surface(_width, _height, _pixelFormat.bytesPerPixel)); return Common::kNoError; }
SurfacePtr TtFontAsset::RenderText( const char *text, const pei::Color& color /*= pei::Color(255,255,255)*/ ) { #ifdef _HAS_SDL_TTF_ if ( m_TtFont ) { // this is a hack! We swap r & g and correct the color format manually // SDL_ttf renders ARGB, but we need ABGR (or LE RGBA) SDL_Color c = { color.b, color.g, color.r, color.a }; SDL_Surface * s = TTF_RenderText_Blended( (TTF_Font*)m_TtFont->GetFontHandle(), text, c ); // swap r&g in the format description s->format->Rmask = 0x000000ff; s->format->Rshift = 0; s->format->Bmask = 0x00ff0000; s->format->Bshift = 16; return SurfacePtr( new pei::SDL::SurfaceWrapper(s) ); } #endif return SurfacePtr(); }
SurfacePtr SurfaceSDL::createFromFormat(int width, int height, PixelFormat::PF fmt) { auto s = std::make_shared<SurfaceSDL>(width, height, fmt); return SurfacePtr(s); }
SurfacePtr EglDisplay::getSurface(EGLSurface surface) const { emugl::Mutex::AutoLock mutex(m_lock); /* surface is "key" in map<unsigned int, SurfacePtr>. */ unsigned int hndl = SafeUIntFromPointer(surface); SurfacesHndlMap::const_iterator it = m_surfaces.find(hndl); return it != m_surfaces.end() ? (*it).second : SurfacePtr(NULL); }
SurfacePtr SurfaceSDL::createFromMask(int width, int height, int bpp, uint32_t rmask, uint32_t gmask, uint32_t bmask, uint32_t amask) { auto s = std::make_shared<SurfaceSDL>(width, height, bpp, rmask, gmask, bmask, amask); return SurfacePtr(s); }
SurfacePtr EglDisplay::getSurface(EGLSurface surface) { android::Mutex::Autolock mutex(m_lock); /* surface is "key" in map<unsigned int, SurfacePtr>. In 64-bit the upper 32-bit should be all zero. Assert for that. */ uintptr_t hndlptr = (uintptr_t)surface; unsigned int hndl = (unsigned int)hndlptr; assert(sizeof(hndl) == sizeof(hndlptr) || hndl == hndlptr); SurfacesHndlMap::iterator it = m_surfaces.find(hndl); return it != m_surfaces.end() ? (*it).second : SurfacePtr(NULL); }
SurfacePtr Video::initSurfDesc(int16 width, int16 height, int16 flags) { SurfacePtr descPtr; if (flags & PRIMARY_SURFACE) assert((width == _surfWidth) && (height == _surfHeight)); if (flags & PRIMARY_SURFACE) { _vm->_global->_primaryWidth = width; _vm->_global->_primaryHeight = height; descPtr = _vm->_global->_primarySurfDesc; descPtr->resize(width, height); } else { assert(!(flags & DISABLE_SPR_ALLOC)); if (!(flags & SCUMMVM_CURSOR)) width = (width + 7) & 0xFFF8; descPtr = SurfacePtr(new Surface(width, height, _vm->getPixelFormat().bytesPerPixel)); } return descPtr; }
EGLint EglDisplayImpl::MakeCurrent(EGLContext egl_ctx, EGLSurface egl_draw, EGLSurface egl_read) { if (egl_read != egl_draw) { LOG_ALWAYS_FATAL("Read and draw surfaces must be the same."); return EGL_BAD_MATCH; } ContextPtr ctx = contexts_.Get(egl_ctx); SurfacePtr sfc = surfaces_.Get(egl_draw); bool release = ctx == NULL && sfc == NULL; // If a context is being set, then a surface must be set. Similarly, if a // context is being cleared, the surface must be cleared. Any other // combination is an error. const bool invalid_surface = ctx != NULL ? sfc == NULL : sfc != NULL; if (!release && invalid_surface) { return EGL_BAD_MATCH; } EglThreadInfo& info = EglThreadInfo::GetInstance(); ContextPtr prev_ctx = info.GetCurrentContext(); SurfacePtr prev_sfc = prev_ctx != NULL ? prev_ctx->GetSurface() : SurfacePtr(); if (release) { if (prev_ctx != NULL) { prev_ctx->Flush(); info.SetCurrentContext(ContextPtr()); } } else { if (ctx == NULL) { return EGL_BAD_CONTEXT; } if (ctx->config != sfc->config) { return EGL_BAD_MATCH; } if (ctx != NULL && prev_ctx != NULL) { if (ctx == prev_ctx) { if (sfc == prev_sfc) { // Reassigning the same context and surface. return EGL_SUCCESS; } } else { // Make sure to clear the previous context. release = true; } } if (prev_ctx != NULL) { prev_ctx->Flush(); } if (!ctx->SetCurrent()) { return EGL_BAD_ACCESS; } info.SetCurrentContext(ctx); ctx->SetSurface(sfc); } if (prev_ctx != NULL && release) { prev_ctx->ClearCurrent(); prev_ctx->ClearSurface(); } return EGL_SUCCESS; }
SurfacePtr Surface::create(const std::string& file, const Rect& rect) { return SurfacePtr(new Surface(file, rect)); }
SurfacePtr Surface::create(const std::string& file) { return SurfacePtr(new Surface(file)); }
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context) { VALIDATE_DISPLAY(display); bool releaseContext = EglValidate::releaseContext(context, read, draw); if(!releaseContext && EglValidate::badContextMatch(context, read, draw)) { RETURN_ERROR(EGL_FALSE, EGL_BAD_MATCH); } ThreadInfo* thread = getThreadInfo(); ContextPtr prevCtx = thread->eglContext; if(releaseContext) { //releasing current context if(prevCtx.Ptr()) { g_eglInfo->getIface(prevCtx->version())->flush(); if(!dpy->nativeType()->makeCurrent(NULL,NULL,NULL)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS); } thread->updateInfo(ContextPtr(NULL),dpy,NULL,ShareGroupPtr(NULL),dpy->getManager(prevCtx->version())); } } else { //assining new context VALIDATE_CONTEXT(context); VALIDATE_SURFACE(draw,newDrawSrfc); VALIDATE_SURFACE(read,newReadSrfc); EglSurface* newDrawPtr = newDrawSrfc.Ptr(); EglSurface* newReadPtr = newReadSrfc.Ptr(); ContextPtr newCtx = ctx; if (newCtx.Ptr() && prevCtx.Ptr()) { if (newCtx.Ptr() == prevCtx.Ptr()) { if (newDrawPtr == prevCtx->draw().Ptr() && newReadPtr == prevCtx->read().Ptr()) { // nothing to do return EGL_TRUE; } } else { // Make sure previous context is detached from surfaces releaseContext = true; } } //surfaces compatibility check if(!((*ctx->getConfig()).compatibleWith((*newDrawPtr->getConfig()))) || !((*ctx->getConfig()).compatibleWith((*newReadPtr->getConfig())))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_MATCH); } EglOS::Display* nativeDisplay = dpy->nativeType(); EglOS::Surface* nativeRead = newReadPtr->native(); EglOS::Surface* nativeDraw = newDrawPtr->native(); //checking native window validity if(newReadPtr->type() == EglSurface::WINDOW && !nativeDisplay->isValidNativeWin(nativeRead)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); } if(newDrawPtr->type() == EglSurface::WINDOW && !nativeDisplay->isValidNativeWin(nativeDraw)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); } if(prevCtx.Ptr()) { g_eglInfo->getIface(prevCtx->version())->flush(); } if (!dpy->nativeType()->makeCurrent( newReadPtr->native(), newDrawPtr->native(), newCtx->nativeType())) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS); } //TODO: handle the following errors // EGL_BAD_CURRENT_SURFACE , EGL_CONTEXT_LOST , EGL_BAD_ACCESS thread->updateInfo(newCtx,dpy,newCtx->getGlesContext(),newCtx->getShareGroup(),dpy->getManager(newCtx->version())); newCtx->setSurfaces(newReadSrfc,newDrawSrfc); g_eglInfo->getIface(newCtx->version())->initContext(newCtx->getGlesContext(),newCtx->getShareGroup()); // Initialize the GLES extension function table used in // eglGetProcAddress for the context's GLES version if not // yet initialized. We initialize it here to make sure we call the // GLES getProcAddress after when a context is bound. g_eglInfo->initClientExtFuncTable(newCtx->version()); } // release previous context surface binding if(prevCtx.Ptr() && releaseContext) { prevCtx->setSurfaces(SurfacePtr(NULL),SurfacePtr(NULL)); } return EGL_TRUE; }