MFInitStatus MFFileSystemNative_InitModulePlatformSpecific() { if(gFilesystemExternal == 0) { FujiModule *pModule = (FujiModule*)pp::Module::Get(); pFSInterface = (PPB_FileSystem*)pModule->GetBrowserInterface(PPB_FILESYSTEM_INTERFACE); Fuji *pInstance = pModule->GetInstance(); if(!pInstance) return MFAIC_Failed; gFilesystemExternal = pFSInterface->Create(pInstance->pp_instance(), PP_FILESYSTEMTYPE_EXTERNAL); gFilesystemLocalPersistent = pFSInterface->Create(pInstance->pp_instance(), PP_FILESYSTEMTYPE_LOCALPERSISTENT); gFilesystemLocalTemporary = pFSInterface->Create(pInstance->pp_instance(), PP_FILESYSTEMTYPE_LOCALTEMPORARY); int32_t err = pFSInterface->Open(gFilesystemExternal, 0, PP_MakeOptionalCompletionCallback(CompletionCallback, (void*)0)); if(err == PP_OK) { gOpenComplete |= 1; } else if(err != PP_OK_COMPLETIONPENDING) { MFDebug_Error("MFFileSystemNative_InitModulePlatformSpecific: Error opening FS interface!"); return MFAIC_Failed; } err = pFSInterface->Open(gFilesystemLocalPersistent, 0, PP_MakeOptionalCompletionCallback(CompletionCallback, (void*)1)); if(err == PP_OK) { gOpenComplete |= 2; } else if(err != PP_OK_COMPLETIONPENDING) { MFDebug_Error("MFFileSystemNative_InitModulePlatformSpecific: Error opening FS interface!"); return MFAIC_Failed; } err = pFSInterface->Open(gFilesystemLocalTemporary, 0, PP_MakeOptionalCompletionCallback(CompletionCallback, (void*)2)); if(err == PP_OK) { gOpenComplete |= 4; } else if(err != PP_OK_COMPLETIONPENDING) { MFDebug_Error("MFFileSystemNative_InitModulePlatformSpecific: Error opening FS interface!"); return MFAIC_Failed; } } if(gOpenComplete == -1) return MFAIC_Failed; return gOpenComplete == 7 ? MFIS_Succeeded : MFAIC_Pending; }
static void CompletionCallback(void *user_data, int32_t result) { if(result != PP_OK) MFDebug_Error("MFFileSystemNative_InitModulePlatformSpecific: Error mounting filesystem!"); gOpenComplete |= 1 << (size_t)user_data; }
XVisualInfo *MFRenderer_GetVisualInfo() { XVisualInfo *visualInfo = NULL; if(!glXQueryExtension(xdisplay, NULL, NULL)) { MFDebug_Error("GLX extension not available"); return NULL; } int glXMajor, glXMinor; if(!glXQueryVersion(xdisplay, &glXMajor, &glXMinor) || (glXMajor == 1 && glXMinor < 3)) { MFDebug_Error(MFStr("Unable to open display, need GLX V1, and at least version 1.3 (Have version %d.%d)", glXMajor, glXMinor)); return NULL; } // Try and obtain a suitable FBconfig, try for double buffering first int numConfigs; fbConfigs = glXChooseFBConfig(xdisplay, screen, glAttrsDouble, &numConfigs); if(numConfigs == 0) { fbConfigs = glXChooseFBConfig(xdisplay, screen, glAttrsSingle, &numConfigs); if(numConfigs == 0) { MFDebug_Error("Unable to obtain a suitable glX FBConfig"); return NULL; } } if((visualInfo = glXGetVisualFromFBConfig(xdisplay, fbConfigs[0])) == NULL) { MFDebug_Error("Unable to obtain a visualInfo structure for the associated FBConfig"); return NULL; } if(visualInfo->depth < 16) { MFDebug_Error("Need at least a 16 bit screen!"); return NULL; } return visualInfo; }
void MFDisplay_InitModulePlatformSpecific() { MFZeroMemory(gXKeys, sizeof(gXKeys)); MFZeroMemory(&gXMouse, sizeof(gXMouse)); gXMouse.x = -1; // gNumDisplayDevices = 0; // gpDisplayAdaptors = (MFDisplayAdaptorDesc*)MFHeap_Alloc(sizeof(MFDisplayAdaptorDesc)*0); xdisplay = XOpenDisplay(NULL); if(!xdisplay) { MFDebug_Error("Unable to open display"); return; } screen = DefaultScreen(xdisplay); rootWindow = RootWindow(xdisplay, screen); wm_delete_window = XInternAtom(xdisplay, "WM_DELETE_WINDOW", false); // build our internal list of available video modes /* GetModes(&modes, false);//!gDisplay.windowed); while(!FindMode(modes, width, height)) { if(!gDisplay.windowed) { // no fullscreen mode, try windowed mode instead MFDebug_Warn(1, "No suitable modes for fullscreen mode, trying windowed mode"); gDisplay.windowed = true; FreeModes(); GetModes(&modes, false); } else { // default is some sort of custom mode that doesn't appear in the windowed mode list // HACK: we'll add it to the end.. modes[numModes].width = width; modes[numModes].height = height; currentMode = numModes; ++numModes; break; } } */ DebugMenu_AddItem("Resolution", "Display Options", &resSelect, ChangeResCallback); DebugMenu_AddItem("Apply", "Display Options", &applyDisplayMode, ApplyDisplayModeCallback); }
// return a handle to a specific filesystem MF_API MFFileSystemHandle MFFileSystem_GetInternalFileSystemHandle(MFFileSystemHandles fileSystemHandle) { GET_MODULE_DATA(MFFileSystemState); switch(fileSystemHandle) { case MFFSH_NativeFileSystem: MFDebug_Assert(pModuleData->hNativeFileSystem > -1, "Native filesystem is not available..."); if(pModuleData->hNativeFileSystem < 0) MFDebug_Error("Native filesystem is not available..."); return pModuleData->hNativeFileSystem; case MFFSH_MemoryFileSystem: MFDebug_Assert(pModuleData->hMemoryFileSystem > -1, "Memory file filesystem is not available..."); if(pModuleData->hMemoryFileSystem < 0) MFDebug_Error("Memory file filesystem is not available..."); return pModuleData->hMemoryFileSystem; case MFFSH_CachedFileSystem: MFDebug_Assert(pModuleData->hCachedFileSystem > -1, "Memory file filesystem is not available..."); if(pModuleData->hCachedFileSystem < 0) MFDebug_Error("Cached file filesystem is not available..."); return pModuleData->hCachedFileSystem; case MFFSH_ZipFileSystem: MFDebug_Assert(pModuleData->hZipFileSystem > -1, "Zip file filesystem is not available..."); if(pModuleData->hZipFileSystem < 0) MFDebug_Error("Zip file filesystem is not available..."); return pModuleData->hZipFileSystem; case MFFSH_HTTPFileSystem: MFDebug_Assert(pModuleData->hHTTPFileSystem > -1, "HTTP file filesystem is not available..."); if(pModuleData->hHTTPFileSystem < 0) MFDebug_Error("HTTP file filesystem is not available..."); return pModuleData->hHTTPFileSystem; case MFFSH_FTPFileSystem: MFDebug_Assert(pModuleData->hFTPFileSystem > -1, "FTP file filesystem is not available..."); if(pModuleData->hFTPFileSystem < 0) MFDebug_Error("FTP file filesystem is not available..."); return pModuleData->hFTPFileSystem; default: MFDebug_Error(MFStr("Invalid filesystem handle: %d", fileSystemHandle)); return -1; } }
int MFDisplay_CreateDisplay(int width, int height, int bpp, int rate, bool vsync, bool triplebuffer, bool wide, bool progressive) { MFCALLSTACK; MFZeroMemory(gXKeys, sizeof(gXKeys)); MFZeroMemory(&gXMouse, sizeof(gXMouse)); gXMouse.x = -1; gDisplay.fullscreenWidth = gDisplay.width = width; gDisplay.fullscreenHeight = gDisplay.height = height; gDisplay.refreshRate = 0; gDisplay.colourDepth = 0; /* Use default. Chances are, it's something sane */ gDisplay.windowed = true; gDisplay.wide = false; gDisplay.progressive = true; if(!(xdisplay = XOpenDisplay(NULL))) { MFDebug_Error("Unable to open display"); MFDisplay_DestroyDisplay(); return 1; } screen = DefaultScreen(xdisplay); rootWindow = RootWindow(xdisplay, screen); // build our internal list of available video modes GetModes(&modes, !gDisplay.windowed); while(!FindMode(modes, width, height)) { if(!gDisplay.windowed) { // no fullscreen mode, try windowed mode instead MFDebug_Warn(1, "No suitable modes for fullscreen mode, trying windowed mode"); gDisplay.windowed = true; FreeModes(); GetModes(&modes, false); } else { // default is some sort of custom mode that doesn't appear in the windowed mode list // HACK: we'll add it to the end.. modes[numModes].width = width; modes[numModes].height = height; currentMode = numModes; ++numModes; break; } } DebugMenu_AddItem("Resolution", "Display Options", &resSelect, ChangeResCallback); DebugMenu_AddItem("Apply", "Display Options", &applyDisplayMode, ApplyDisplayModeCallback); // Set full screen mode, if necessary if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to switch screenmodes, defaulting to windowed mode"); MFDisplay_DestroyDisplay(); return 1; } } XVisualInfo *MFRenderer_GetVisualInfo(); XVisualInfo *visualInfo = MFRenderer_GetVisualInfo(); if(!visualInfo) return 1; if(!(colorMap = XCreateColormap(xdisplay, rootWindow, visualInfo->visual, AllocNone))) { MFDebug_Error("Unable to create colourmap"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } XSetWindowAttributes windowAttrs; windowAttrs.colormap = colorMap; windowAttrs.cursor = None; windowAttrs.event_mask = StructureNotifyMask; windowAttrs.border_pixel = BlackPixel(xdisplay, screen); windowAttrs.background_pixel = BlackPixel(xdisplay, screen); if(!(window = XCreateWindow(xdisplay, rootWindow, 0, 0, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel | CWBorderPixel | CWCursor | CWColormap | CWEventMask, &windowAttrs))) { MFDebug_Error("Unable to create X Window"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } // Tell the window manager not to allow our window to be resized. But some window managers can ignore me and do it anyway. Typical X-Windows. if((sizeHints = XAllocSizeHints()) == NULL) { MFDebug_Error("Unable to alloc XSizeHints structure, out of memory?"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } sizeHints->flags = PSize | PMinSize | PMaxSize; sizeHints->min_width = sizeHints->max_width = sizeHints->base_width = width; sizeHints->min_height = sizeHints->max_height = sizeHints->base_height = height; XSetWMNormalHints(xdisplay, window, sizeHints); // Window title XStoreName(xdisplay, window, gDefaults.display.pWindowTitle); XWMHints *wmHints; if((wmHints = XAllocWMHints()) == NULL) { MFDebug_Error("Unable to alloc XWMHints structure, out of memory?"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } wmHints->flags = InputHint | StateHint; wmHints->input = true; wmHints->initial_state = NormalState; if(!XSetWMHints(xdisplay, window, wmHints)) { MFDebug_Error("Unable to set WM hints for window"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } XFree(wmHints); XFree(visualInfo); // Tell the window manager that I want to be notified if the window's closed wm_delete_window = XInternAtom(xdisplay, "WM_DELETE_WINDOW", false); if(!XSetWMProtocols(xdisplay, window, &wm_delete_window, 1)) { MFDebug_Error("Unable to set Window Manager protocols"); MFDisplay_DestroyDisplay(); return 1; } XSelectInput(xdisplay, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask); if(!XMapRaised(xdisplay, window)) { MFDebug_Error("Unable to map new window"); MFDisplay_DestroyDisplay(); return 1; } // Wait for the window to be mapped, etc. The documentation doesn't indicate that this is necessary, but every GLX program I've ever seen does it, so I assume it is. XEvent event; XIfEvent(xdisplay, &event, WaitForNotify, (char *)window); MFRenderer_CreateDisplay(); if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to set screen mode"); MFDisplay_DestroyDisplay(); return 1; } XGrabPointer(xdisplay, window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); XFlush(xdisplay); // A little trick to make sure the entire window is on the screen XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, width - 1, height - 1); XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, 0, 0); XFlush(xdisplay); } return 0; }
bool MFModule_InitModules() { uint64 timer = 0; for(int a=0; a<gNumModules; ++a) { uint64 bit = 1ULL << a; if(!(gModuleInitComplete & bit) && (gModuleInitComplete & gModules[a].prerequisites) == gModules[a].prerequisites) { MFInitStatus complete = MFAIC_Failed; if((gModules[a].prerequisites & gModuleInitFailed) == 0) { MFDebug_Message(MFStr("Init %s...", gModules[a].pModuleName)); timer = MFSystem_ReadRTC(); complete = gModules[a].pInitFunction(); } else { // list pre-requisite failures if(MFModule_IsModuleInitialised(MFModule_GetBuiltinModuleID(MFBIM_MFString))) { MFDebug_Message(MFStr("Prerequisite failure")); } } if(complete == MFAIC_Succeeded) { uint64 initTime = (MFSystem_ReadRTC() - timer) * 1000 / MFSystem_GetRTCFrequency(); gModuleInitComplete |= bit; // if logging is initialised MFDebug_Message(MFStr("Init %s complete in %dms", gModules[a].pModuleName, (int)initTime)); } else if(complete == MFAIC_Failed) { uint64 initTime = (MFSystem_ReadRTC() - timer) * 1000 / MFSystem_GetRTCFrequency(); gModuleInitComplete |= bit; gModuleInitFailed |= bit; // if logging is initialised MFDebug_Error(MFStr("Init %s FAILED in %dms!", gModules[a].pModuleName, (int)initTime)); } } } if(gModuleInitComplete == (1ULL << gNumModules) - 1) { gFujiInitialised = true; if(gModuleInitFailed) { MFDebug_Message("Fuji initialisation completed with errors..."); // list the failed modules //... } else { MFDebug_Message("Fuji initialisation complete!"); } MFHeap_Mark(); // let the game perform any post-init work if(pSystemCallbacks[MFCB_InitDone]) pSystemCallbacks[MFCB_InitDone](); // init the timedelta to the moment after initialisation completes MFSystem_UpdateTimeDelta(); return true; } return false; }
int MFRenderer_CreateDisplay(MFDisplay *pDisplay) { #if MF_DISPLAY == MF_DRIVER_X11 Window window = (Window)MFWindow_GetSystemWindowHandle(pDisplay->settings.pWindow); glXWindow = glXCreateWindow(xdisplay, fbConfigs[0], window, NULL); if(!glXWindow) { MFDebug_Error("Unable to associate window with a GLXWindow"); MFRenderer_DestroyDisplay(pDisplay); return 1; } glXContext = glXCreateNewContext(xdisplay, fbConfigs[0], GLX_RGBA_TYPE, NULL, true); if(!glXContext) { MFDebug_Error("Unable to create GLXContext"); MFRenderer_DestroyDisplay(pDisplay); return 1; } XFree(fbConfigs); fbConfigs = NULL; if(!glXMakeContextCurrent(xdisplay, glXWindow, glXWindow, glXContext)) { MFDebug_Error("glXMakeContextCurrent failed"); MFRenderer_DestroyDisplay(pDisplay); return 1; } #elif MF_DISPLAY == MF_DRIVER_WIN32 HWND hWnd = (HWND)MFWindow_GetSystemWindowHandle(pDisplay->settings.pWindow); GLuint pixelFormat; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, 32, // colour depth 0, 0, 0, 0, 0, 0, 0, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 24, // 16Bit Z-Buffer (Depth Buffer) 8, // No Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored }; pfd.dwFlags |= pDisplay->settings.numBuffers > 1 ? PFD_DOUBLEBUFFER : 0; hDC = GetDC(hWnd); if(!hDC) { MFRenderer_DestroyDisplay(pDisplay); MessageBoxA(NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK|MB_ICONEXCLAMATION); return 1; } pixelFormat = ChoosePixelFormat(hDC, &pfd); if(!pixelFormat) { MFRenderer_DestroyDisplay(pDisplay); MessageBoxA(NULL, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK|MB_ICONEXCLAMATION); return 2; } if(!SetPixelFormat(hDC, pixelFormat, &pfd)) { MFRenderer_DestroyDisplay(pDisplay); MessageBoxA(NULL, "Can't Set The PixelFormat.", "ERROR", MB_OK|MB_ICONEXCLAMATION); return 3; } hRC = wglCreateContext(hDC); if(!hRC) { // *** driver bug *** // HACK: do it again... SetPixelFormat(hDC, pixelFormat, &pfd); hRC = wglCreateContext(hDC); } if(!hRC) { MessageBoxA(NULL, MFStr("Failed to create OpenGL context: %s", MFSystemPC_GetLastError()), "ERROR", MB_OK|MB_ICONEXCLAMATION); MFRenderer_DestroyDisplay(pDisplay); return 4; } if(!wglMakeCurrent(hDC, hRC)) { MFRenderer_DestroyDisplay(pDisplay); MessageBoxA(NULL, "Can't Activate The GL Rendering Context.", "ERROR", MB_OK|MB_ICONEXCLAMATION); return 5; } #elif MF_DISPLAY == MF_DRIVER_SDL2 glContext = SDL_GL_CreateContext((SDL_Window*)MFWindow_GetSystemWindowHandle(pDisplay->settings.pWindow)); #elif MF_DISPLAY == MF_DRIVER_IPHONE MFRendererIPhone_MakeCurrent(); #elif MF_DISPLAY == MF_DRIVER_NACL // do we need to do anything? #endif // get the opengl version const char *pVersion = (const char *)glGetString(GL_VERSION); while(pVersion && *pVersion && !MFIsNumeric(*pVersion)) ++pVersion; float ver = MFString_AsciiToFloat(pVersion); gOpenGLVersion = (int)(ver * 100); #if !defined(MF_OPENGL_ES) // glew wrangles all the horrid extensions... GLenum r = glewInit(); MFDebug_Assert(r == GLEW_OK, "Error loading extensions!"); #endif #if !defined(MF_OPENGL_ES) glEnable(GL_LINE_SMOOTH); // glFrontFace(GL_CW); // glCullFace(GL_BACK); glDisable(GL_LIGHTING); #endif glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); #if defined(MF_OPENGL_ES) // we need the EGL display apparently... // eglSwapInterval(, 1); #else #if MF_DISPLAY == MF_DRIVER_X11 // GLXDrawable drawable = glXGetCurrentDrawable(); // glXSwapIntervalEXT(xdisplay, drawable, 1); #elif MF_DISPLAY == MF_DRIVER_WIN32 // wglSwapInterval(1); #endif #endif glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&gDefaultRenderTarget); MFTextureDesc texDesc = { MFTexType_2D, ImgFmt_A8R8G8B8, pDisplay->settings.width, pDisplay->settings.height, 0, 0, 1, MFTCF_RenderTarget }; gpDeviceColourTarget = MFTexture_InitTexture(&texDesc, MFRD_OpenGL, 0); gpDeviceColourTarget->pName = "Device Colour Target"; gpDeviceColourTarget->pSurfaces[0].platformData = (uint64)gDefaultRenderTarget; texDesc.format = ImgFmt_D24S8; gpDeviceZTarget = MFTexture_InitTexture(&texDesc, MFRD_OpenGL, 0); gpDeviceZTarget->pName = "Device Depth Stencil"; gpDeviceZTarget->pSurfaces[0].platformData = 0; MFRenderTargetDesc desc; desc.pName = "Device Render Target"; desc.width = pDisplay->settings.width; desc.height = pDisplay->settings.height; desc.colourTargets[0].pSurface = gpDeviceColourTarget; desc.depthStencil.pSurface = gpDeviceZTarget; gpDeviceRenderTarget = MFRenderTarget_Create(&desc); gCurrentViewport.x = 0.0f; gCurrentViewport.y = 0.0f; gCurrentViewport.width = (float)pDisplay->settings.width; gCurrentViewport.height = (float)pDisplay->settings.height; glViewport(0, 0, pDisplay->settings.width, pDisplay->settings.height); return 0; }