Пример #1
0
bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig)
{
    static bool restore = false;

    m_lastDeviceConfig = m_deviceConfig;
    m_deviceConfig = newConfig;


    SDL_FreeSurface(m_private->surface);

    if (! CreateVideoSurface())
    {
        // Fatal error, so post the quit event
        m_eventQueue->AddEvent(Event(EVENT_QUIT));
        return false;
    }

    if (m_private->surface == nullptr)
    {
        if (! restore)
        {
            std::string error = std::string("SDL error while setting video mode:\n") +
                          std::string(SDL_GetError()) + std::string("\n") +
                          std::string("Previous mode will be restored");
            GetLogger()->Error(error.c_str());
            GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Error", error);

            restore = true;
            ChangeVideoConfig(m_lastDeviceConfig);
            return false;
        }
        else
        {
            restore = false;

            std::string error = std::string("SDL error while restoring previous video mode:\n") +
                          std::string(SDL_GetError());
            GetLogger()->Error(error.c_str());
            GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", error);


            // Fatal error, so post the quit event
            m_eventQueue->AddEvent(Event(EVENT_QUIT));
            return false;
        }
    }

    ( static_cast<Gfx::CGLDevice*>(m_device) )->ConfigChanged(m_deviceConfig);

    m_engine->ResetAfterDeviceChanged();

    return true;
}
Пример #2
0
SDL_Surface *
SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
{
    SDL_DisplayMode desktop_mode;
    SDL_DisplayMode mode;
    int window_x = SDL_WINDOWPOS_UNDEFINED;
    int window_y = SDL_WINDOWPOS_UNDEFINED;
    Uint32 window_flags;
    Uint32 desktop_format;
    Uint32 desired_format;
    Uint32 surface_flags;

    if (!SDL_GetVideoDevice()) {
        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
            return NULL;
        }
    }
    
    SDL_GetDesktopDisplayMode(&desktop_mode);

    if (width == 0) {
        width = desktop_mode.w;
    }
    if (height == 0) {
        height = desktop_mode.h;
    }

    /* See if we can simply resize the existing window and surface */
    if (SDL_ResizeVideoMode(width, height, bpp, flags) == 0) {
        return SDL_PublicSurface;
    }

    /* Destroy existing window */
    SDL_PublicSurface = NULL;
    if (SDL_ShadowSurface) {
        SDL_FreeSurface(SDL_ShadowSurface);
        SDL_ShadowSurface = NULL;
    }
    if (SDL_VideoSurface) {
        SDL_DelPaletteWatch(SDL_VideoSurface->format->palette,
                            SDL_VideoPaletteChanged, NULL);
        SDL_FreeSurface(SDL_VideoSurface);
        SDL_VideoSurface = NULL;
    }
    if (SDL_VideoContext) {
        /* SDL_GL_MakeCurrent(0, NULL); *//* Doesn't do anything */
        SDL_GL_DeleteContext(SDL_VideoContext);
        SDL_VideoContext = NULL;
    }
    if (SDL_VideoWindow) {
        SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y);
        SDL_DestroyWindow(SDL_VideoWindow);
    }

    /* Set up the event filter */
    if (!SDL_GetEventFilter(NULL, NULL)) {
        SDL_SetEventFilter(SDL_CompatEventFilter, NULL);
    }

    /* Create a new window */
    window_flags = SDL_WINDOW_SHOWN;
    if (flags & SDL_FULLSCREEN) {
        window_flags |= SDL_WINDOW_FULLSCREEN;
    }
    if (flags & SDL_OPENGL) {
        window_flags |= SDL_WINDOW_OPENGL;
    }
    if (flags & SDL_RESIZABLE) {
        window_flags |= SDL_WINDOW_RESIZABLE;
    }
    if (flags & SDL_NOFRAME) {
        window_flags |= SDL_WINDOW_BORDERLESS;
    }
    GetEnvironmentWindowPosition(width, height, &window_x, &window_y);
    SDL_SetFullscreenDisplayMode(NULL);
    SDL_VideoWindow =
        SDL_CreateWindow(wm_title, window_x, window_y, width, height,
                         window_flags);
    if (!SDL_VideoWindow) {
        return NULL;
    }
    SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon);

    window_flags = SDL_GetWindowFlags(SDL_VideoWindow);
    surface_flags = 0;
    if (window_flags & SDL_WINDOW_FULLSCREEN) {
        surface_flags |= SDL_FULLSCREEN;
    }
    if (window_flags & SDL_WINDOW_OPENGL) {
        surface_flags |= SDL_OPENGL;
    }
    if (window_flags & SDL_WINDOW_RESIZABLE) {
        surface_flags |= SDL_RESIZABLE;
    }
    if (window_flags & SDL_WINDOW_BORDERLESS) {
        surface_flags |= SDL_NOFRAME;
    }

    /* Set up the desired display mode */
    desktop_format = desktop_mode.format;
    if (desktop_format && ((flags & SDL_ANYFORMAT)
                           || (bpp == SDL_BITSPERPIXEL(desktop_format)))) {
        desired_format = desktop_format;
    } else {
        switch (bpp) {
        case 0:
            if (desktop_format) {
                desired_format = desktop_format;
            } else {
                desired_format = SDL_PIXELFORMAT_RGB888;
            }
            bpp = SDL_BITSPERPIXEL(desired_format);
            break;
        case 8:
            desired_format = SDL_PIXELFORMAT_INDEX8;
            break;
        case 15:
            desired_format = SDL_PIXELFORMAT_RGB555;
            break;
        case 16:
            desired_format = SDL_PIXELFORMAT_RGB565;
            break;
        case 24:
            desired_format = SDL_PIXELFORMAT_RGB24;
            break;
        case 32:
            desired_format = SDL_PIXELFORMAT_RGB888;
            break;
        default:
            SDL_SetError("Unsupported bpp in SDL_SetVideoMode()");
            return NULL;
        }
    }
    mode.format = desired_format;
    mode.w = width;
    mode.h = height;
    mode.refresh_rate = 0;

    /* Set the desired display mode */
    if (flags & SDL_FULLSCREEN) {
        if (SDL_SetFullscreenDisplayMode(&mode) < 0) {
            return NULL;
        }
    }

    /* If we're in OpenGL mode, just create a stub surface and we're done! */
    if (flags & SDL_OPENGL) {
        SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow);
        if (!SDL_VideoContext) {
            return NULL;
        }
        if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) {
            return NULL;
        }
        SDL_VideoSurface =
            SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0);
        if (!SDL_VideoSurface) {
            return NULL;
        }
        SDL_VideoSurface->flags |= surface_flags;
        SDL_PublicSurface = SDL_VideoSurface;
        return SDL_PublicSurface;
    }

    /* Create a renderer for the window */
    if (SDL_CreateRenderer
        (SDL_VideoWindow, -1,
         SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD) < 0) {
        return NULL;
    }
    SDL_GetRendererInfo(&SDL_VideoRendererInfo);

    /* Create a texture for the screen surface */
    SDL_VideoTexture =
        SDL_CreateTexture(desired_format, SDL_TEXTUREACCESS_STREAMING, width,
                          height);

    if (!SDL_VideoTexture) {
        SDL_VideoTexture =
            SDL_CreateTexture(desktop_format,
                              SDL_TEXTUREACCESS_STREAMING, width, height);
    }
    if (!SDL_VideoTexture) {
        return NULL;
    }

    /* Create the screen surface */
    SDL_VideoSurface = CreateVideoSurface(SDL_VideoTexture);
    if (!SDL_VideoSurface) {
        return NULL;
    }
    SDL_VideoSurface->flags |= surface_flags;

    /* Set a default screen palette */
    if (SDL_VideoSurface->format->palette) {
        SDL_VideoSurface->flags |= SDL_HWPALETTE;
        SDL_DitherColors(SDL_VideoSurface->format->palette->colors,
                         SDL_VideoSurface->format->BitsPerPixel);
        SDL_AddPaletteWatch(SDL_VideoSurface->format->palette,
                            SDL_VideoPaletteChanged, SDL_VideoSurface);
        SDL_SetPaletteColors(SDL_VideoSurface->format->palette,
                             SDL_VideoSurface->format->palette->colors, 0,
                             SDL_VideoSurface->format->palette->ncolors);
    }

    /* Create a shadow surface if necessary */
    if ((bpp != SDL_VideoSurface->format->BitsPerPixel)
        && !(flags & SDL_ANYFORMAT)) {
        SDL_ShadowSurface =
            SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0);
        if (!SDL_ShadowSurface) {
            return NULL;
        }
        SDL_ShadowSurface->flags |= surface_flags;

        /* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */
        if (SDL_ShadowSurface->format->palette) {
            SDL_ShadowSurface->flags |= SDL_HWPALETTE;
            if (SDL_VideoSurface->format->palette) {
                SDL_SetSurfacePalette(SDL_ShadowSurface,
                                      SDL_VideoSurface->format->palette);
            } else {
                SDL_DitherColors(SDL_ShadowSurface->format->palette->colors,
                                 SDL_ShadowSurface->format->BitsPerPixel);
            }
            SDL_AddPaletteWatch(SDL_ShadowSurface->format->palette,
                                SDL_VideoPaletteChanged, SDL_ShadowSurface);
        }
    }
    SDL_PublicSurface =
        (SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface);

    SDL_VideoFlags = flags;

    ClearVideoSurface();

    SetupScreenSaver(flags);

    /* We're finally done! */
    return SDL_PublicSurface;
}
Пример #3
0
bool CApplication::Create()
{
    GetLogger()->Info("Creating CApplication\n");

    boost::filesystem::path dataPath(m_dataPath);
    if (! (boost::filesystem::exists(dataPath) && boost::filesystem::is_directory(dataPath)) )
    {
        GetLogger()->Error("Data directory '%s' doesn't exist or is not a directory\n", m_dataPath.c_str());
        m_errorMessage = std::string("Could not read from data directory:\n") +
                         std::string("'") + m_dataPath + std::string("'\n") +
                         std::string("Please check your installation, or supply a valid data directory by -datadir option.");
        m_exitCode = 1;
        return false;
    }

    SetLanguage(m_language);

    //Create the sound instance.
    if (!GetProfile().InitCurrentDirectory())
    {
        GetLogger()->Warn("Config not found. Default values will be used!\n");
        m_sound = new CSoundInterface();
    }
    else
    {
        std::string path;
        if (GetProfile().GetLocalProfileString("Resources", "Data", path))
            m_dataPath = path;

        #ifdef OPENAL_SOUND
        m_sound = static_cast<CSoundInterface *>(new ALSound());
        #else
        GetLogger()->Info("No sound support.\n");
        m_sound = new CSoundInterface();
        #endif

        m_sound->Create(true);
        if (GetProfile().GetLocalProfileString("Resources", "Sound", path)) {
            m_sound->CacheAll(path);
        } else {
            m_sound->CacheAll(GetDataSubdirPath(DIR_SOUND));
        }

        if (GetProfile().GetLocalProfileString("Resources", "Music", path)) {
            m_sound->AddMusicFiles(path);
        } else {
            m_sound->AddMusicFiles(GetDataSubdirPath(DIR_MUSIC));
        }
    }

    std::string standardInfoMessage =
      "\nPlease see the console output or log file\n"
      "to get more information on the source of error";

    /* SDL initialization sequence */


    Uint32 initFlags = SDL_INIT_VIDEO | SDL_INIT_TIMER;

    if (SDL_Init(initFlags) < 0)
    {
        m_errorMessage = std::string("SDL initialization error:\n") +
                         std::string(SDL_GetError());
        GetLogger()->Error(m_errorMessage.c_str());
        m_exitCode = 2;
        return false;
    }

    // This is non-fatal and besides seems to fix some memory leaks
    if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
    {
        GetLogger()->Warn("Joystick subsystem init failed\nJoystick(s) will not be available\n");
    }

    if ((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) == 0)
    {
        m_errorMessage = std::string("SDL_Image initialization error:\n") +
                         std::string(IMG_GetError());
        GetLogger()->Error(m_errorMessage.c_str());
        m_exitCode = 3;
        return false;
    }

    // load settings from profile
    int iValue;
    if ( GetProfile().GetLocalProfileInt("Setup", "Resolution", iValue) )
    {
        std::vector<Math::IntPoint> modes;
        GetVideoResolutionList(modes, true, true);
        if (static_cast<unsigned int>(iValue) < modes.size())
            m_deviceConfig.size = modes.at(iValue);
    }

    if ( GetProfile().GetLocalProfileInt("Setup", "Fullscreen", iValue) )
    {
        m_deviceConfig.fullScreen = (iValue == 1);
    }

    if (! CreateVideoSurface())
        return false; // dialog is in function

    if (m_private->surface == nullptr)
    {
        m_errorMessage = std::string("SDL error while setting video mode:\n") +
                         std::string(SDL_GetError());
        GetLogger()->Error(m_errorMessage.c_str());
        m_exitCode = 4;
        return false;
    }

    SDL_WM_SetCaption(m_windowTitle.c_str(), m_windowTitle.c_str());

    // Enable translating key codes of key press events to unicode chars
    SDL_EnableUNICODE(1);

    // Don't generate joystick events
    SDL_JoystickEventState(SDL_IGNORE);

    // The video is ready, we can create and initalize the graphics device
    m_device = new Gfx::CGLDevice(m_deviceConfig);
    if (! m_device->Create() )
    {
        m_errorMessage = std::string("Error in CDevice::Create()\n") + standardInfoMessage;
        m_exitCode = 5;
        return false;
    }

    // Create the 3D engine
    m_engine = new Gfx::CEngine(this);

    m_engine->SetDevice(m_device);

    if (! m_engine->Create() )
    {
        m_errorMessage = std::string("Error in CEngine::Init()\n") + standardInfoMessage;
        m_exitCode = 6;
        return false;
    }

    // Create model manager
    m_modelManager = new Gfx::CModelManager(m_engine);

    // Create the robot application.
    m_robotMain = new CRobotMain(this);

    m_robotMain->ChangePhase(PHASE_WELCOME1);

    GetLogger()->Info("CApplication created successfully\n");

    return true;
}