Esempio n. 1
0
bool VideoOutputVDPAU::Init(int width, int height, float aspect,
                            WId winid, const QRect &win_rect,
                            MythCodecID codec_id)
{
    // Attempt to free up as much video memory as possible
    // only works when using the VDPAU painter for the UI
    MythPainter *painter = GetMythPainter();
    if (painter)
        painter->FreeResources();

    m_win = winid;
    QMutexLocker locker(&m_lock);
    window.SetNeedRepaint(true);
    bool ok = VideoOutput::Init(width, height, aspect, winid, win_rect,codec_id);
    if (db_vdisp_profile)
        db_vdisp_profile->SetVideoRenderer("vdpau");

    InitDisplayMeasurements(width, height, true);
    ParseOptions();
    if (ok) ok = InitRender();
    if (ok) ok = InitBuffers();
    if (!ok)
    {
        TearDown();
        return ok;
    }

    InitPictureAttributes();
    MoveResize();
    LOG(VB_PLAYBACK, LOG_INFO, LOC +
        QString("Created VDPAU context (%1 decode)")
            .arg(codec_is_std(video_codec_id) ? "software" : "GPU"));

    return ok;
}
Esempio n. 2
0
//------------------------------------------------------------------------------
EDetailManager::EDetailManager():ESceneToolBase(OBJCLASS_DO)
{
	dtSlots				= 0;
    ZeroMemory			(&dtH,sizeof(dtH));
    m_Selected.clear	();
    InitRender			();
//.	Device.seqDevCreate.Add	(this,REG_PRIORITY_LOW);
//.	Device.seqDevDestroy.Add(this,REG_PRIORITY_NORMAL);
    m_Flags.assign		(flObjectsDraw);
}
void StartupState::Initialise()
//  Continue setting up the sprites and load the textures
{
	splash.SetUVs(0,0,256,256);
	splash.SetDepth(900);
	TexManager.LoadTexture(splashImage);
	loadingStart.SetUVs(0,0,256,64);
	loadingStart.SetDepth(901);
	titleText.SetUVs(0, 128, 256, 128);
	titleText.SetDepth(902);
	TexManager.LoadTexture(textImage);

	//  Render loading to screen
	InitRender();
}
bool CubemapGenerator::Render()
{

    if(!InitRender())
    {
        LOGERRORF("Unable to init render");
        return false;
    }

    GetScene()->SendEvent(E_CUBEMAPRENDERBEGIN);    
    SubscribeToEvent(E_BEGINFRAME, HANDLER(CubemapGenerator, HandleBeginFrame));
    SubscribeToEvent(E_ENDFRAME, HANDLER(CubemapGenerator, HandleEndFrame));

    return true;

}
Esempio n. 5
0
// here comes the main control function: it initialises the dyna system
// and then creates a chain of cubes 
void main(){
  int i;
  MyCube* cube[NCUBES];
  My_dyna_system_callbacks *dsc=new My_dyna_system_callbacks();
  DL_m_integrator* my_int=new DL_rungekutta2();
  DL_dyna_system dsystem(dsc,my_int);
  DL_constraint_manager *constraints=new DL_constraint_manager();
  constraints->max_error=0.0001;

  DL_point pos(0.75*NCUBES,1.75*NCUBES,4*NCUBES);
  DL_vector vec(-2,-2,-2);

  for (i=0;i<NCUBES;i++){
    cube[i]=new MyCube(pos);
    pos.plusis(&vec);
  }
    
  cube[0]->ConnectTo(NULL);
  for (i=1;i<NCUBES;i++) cube[i]->ConnectTo(cube[i-1]);

  vec.init(0,-1,0);
  dsystem.set_gravity(&vec);
  my_int->set_stepsize(0.02);

  InitRender(dsystem,cube,NCUBES);

  // everything initialised. Now let the animation run:
#ifdef USINGDIRECTX
  while (RenderCubes(cube)) {
    dsystem.dynamics();
    if (fabs(dsystem.time()-70)<0.01) cube[NCUBES/2]->Disconnect();
  }
#else
  RenderCubes();
#endif // USINGDIRECTX

  // all done: clean up:
  for (i=0;i<NCUBES;i++) delete cube[i];
  delete constraints; delete my_int; delete dsc;
}
Esempio n. 6
0
BOOL CalcVolume::InitCalc(ConstVolume constvolume)
{
	cv=constvolume;
	cr_plm=new PointLM[cv.history.lm];
	if(cr_plm==NULL) { 
		AfxMessageBox("Error alloc memory for lm history"); 
        return FALSE;
    }
	if(!InitSLM()) return FALSE;
	if(!InitRender()) return FALSE;

	double urad=cv.slm.step*SLM_PI/180.;
    sin_step=sin(urad); cos_step=cos(urad);
    ulb=atan(cv.vol.Height/cv.vol.Wleft)*180./SLM_PI+90.;
    urb=270.-atan(cv.vol.Height/cv.vol.Wright)*180./SLM_PI;        
    crdata.lm.l=cv.vol.Lstart;
    for(int i=0;i<cv.history.lm;i++) { cr_plm[i].l=cv.vol.Lstart; cr_plm[i].t=0; }
	crdata.vol.vp=sin(double(cv.vol.angmin-9000)/100.*SLM_PI/180.)*pow(cv.vol.Wleft,2)*(cv.vol.Lstart-cv.vol.Lend);
	crdata.vol.v=cv.vol.vs-crdata.vol.vp;
	pnow=rl[0];
	pold=rl[1];
	deltaprev=(cv.slm.step<.05) ? 1 : 10;
	return TRUE;
}
Esempio n. 7
0
bool VideoOutputNullVDPAU::Init(const QSize &video_dim_buf,
                                const QSize &video_dim_disp,
                                float aspect,
                                WId winid, const QRect &win_rect,
                                MythCodecID codec_id)
{
    QMutexLocker locker(&m_lock);
    bool ok = VideoOutput::Init(video_dim_buf, video_dim_disp,
                                aspect, winid, win_rect, codec_id);
    if (!codec_is_vdpau_hw(video_codec_id))
        return false;

    if (db_vdisp_profile)
        db_vdisp_profile->SetVideoRenderer("nullvdpau");
    if (ok) ok = InitRender();
    if (ok) ok = InitBuffers();
    if (ok) ok = InitShadowBuffers();
    if (!ok)
        return false;

    LOG(VB_PLAYBACK, LOG_INFO, LOC +
        "Created VDPAU context with GPU decoding)");
    return ok;
}
Esempio n. 8
0
void game::MainLoop()
{
	// init steam we need to initialize this before the renderer for the overlay.
	{
		gSteam.InitSteam();
		if(gSteam.steamID) {
			gUserProfile.RegisterSteamCallbacks();
		}
	}


	InitRender(1);

	CurRenderPipeline = new r3dDefferedRenderer;
	CurRenderPipeline->Init();

	SetFocus(win::hWnd);

	r3dMenuInit();

	r3dParticleSystemInit();

	InitDesktopSystem();

	InitPostFX();
	InitPointLightsRendererV2();

	g_pWind = new r3dWind ;

	g_pEngineConsole = new EngineConsole;
	g_pDefaultConsole = g_pEngineConsole;
	g_pEngineConsole->Init();
	g_pEngineConsole->SetCommandProcessor( g_pCmdProc );

	g_DamageLib = new DamageLib ;
	g_DamageLib->Load();

	g_MeshPropertyLib = new MeshPropertyLib;

#ifndef FINAL_BUILD
	g_Manipulator3d.Init();

	// show non-level specific art bugs
	r3dShowArtBugs() ;
#endif

	g_cursor_mode->SetChangeCallback( &CursorModeCallback ) ;

	_r3d_bTerminateOnZ = r_terminateOnZ->GetInt();

	// set dynamic matlib by default.
	// make it statis only in GAME mode
	r3dMaterialLibrary::IsDynamic = true;

	imgui_SetFixMouseCoords( false );


#ifdef FINAL_BUILD
	int m_ret = Menu_AppSelect::bStartGamePublic; // start game
#else
	int m_ret = 0;
	if ( *d_map_force_load->GetString() || LevelEditName[0]!='\0' )
		m_ret = Menu_AppSelect::bStartLevelEditor;
	else
		CALL_MENU(Menu_AppSelect);
#endif

#ifndef FINAL_BUILD
	// all choises is editors by default
	g_bEditMode = true;
	g_bStartedAsParticleEditor = false;
#endif

	void InitGrass();
	InitGrass();

	g_pHUDCameraEffects = new HUDCameraEffects ;

	r3d_assert(g_pWeaponArmory == NULL);
	g_pWeaponArmory = new ClientWeaponArmory();
	g_pWeaponArmory->Init();
	r3dShowArtBugs();

	// for editors, do not lock mouse. when we start game, in ExecuteNetworkGame we will set that var to true
	d_mouse_window_lock->SetBool(false);

	switch (m_ret)
	{
#ifndef FINAL_BUILD
	case Menu_AppSelect::bUpdateDB:
		g_bEditMode = false;
		UpdateDB("198.50.211.32", "Data/Weapons/itemsDB.xml");
		MessageBox(0, "Successfully updated English DB!", "Result", MB_OK);
		break;
	case Menu_AppSelect::bStartLevelEditor:
		g_pVisibilityGrid = new VisibiltyGrid ;
		ExecuteLevelEditor();
		break;

	case Menu_AppSelect::bStartParticleEditor:
		g_bStartedAsParticleEditor = true;
		ExecuteParticleEditor();
		break;
	case Menu_AppSelect::bStartPhysicsEditor:
		ExecutePhysicsEditor();
		break;
	case Menu_AppSelect::bStartCharacterEditor:
		ExecuteCharacterEditor();
		break;
#endif
	case Menu_AppSelect::bStartGamePublic:
		// override server settings if special key isn't set
		if(strstr(__r3dCmdLine, "-ffgrtvzdf") == NULL)
		{
			// hardcoded IP for now
			//g_serverip->SetString("127.0.0.1");
		}

		// override API settings
		g_api_ip->SetString("198.50.211.32"); // external
		g_serverip->SetString("198.50.211.32"); // external
		g_bEditMode = false;
		ExecuteNetworkGame();
		break;
	};

#ifndef FINAL_BUILD
	if( g_bEditMode )
	{
		SAFE_DELETE( g_pVisibilityGrid );
	}
#endif

	// shutdown steam
	if(gSteam.inited_) {
		gUserProfile.DeregisterSteamCallbacks();
		gSteam.Shutdown();
	}

	SAFE_DELETE( g_pWind ) ;

	r3dMaterialLibrary::UnloadManaged();
	r3dMaterialLibrary::Reset();	
	MeshGlobalBuffer::unloadManaged();

	g_pWeaponArmory->Destroy();
	SAFE_DELETE(g_pWeaponArmory);

#ifndef FINAL_BUILD
	g_Manipulator3d.Close();
#endif

	r3dMenuClose();

	AI_Player_FreeStuff();

	SAFE_DELETE( g_pHUDCameraEffects ) ;

	SAFE_DELETE( g_GameRewards );

	void CloseGrass();
	CloseGrass();

	DestroyPointLightsRendererV2();

	ClosePostFX();

	SAFE_DELETE( g_DamageLib );
	SAFE_DELETE( g_MeshPropertyLib );

	r3dFreeGOBMeshes();

	obj_Zombie::FreePhysSkeletonCache();

	g_pEngineConsole->Release();
	SAFE_DELETE( g_pEngineConsole );

	g_pDefaultConsole = NULL;

	ReleaseDesktopSystem();

	DoneDrawCollections();

	r3dParticleSystemClose();
	CurRenderPipeline->Close();
	SAFE_DELETE(CurRenderPipeline);

	r3dMaterialLibrary::Destroy();

	CloseRender();

	if(gSurveyOutLink)
		ShellExecute(NULL, "open", gSurveyOutLink, "", NULL, SW_SHOW);

	/*r3dOutToLog("HackShield : UnInitialize...\n");
	_AhnHS_StopService();
	_AhnHS_Uninitialize();*/
	HMODULE hMod;
	hMod = LoadLibrary(TEXT("WGCrash.dll"));
	//HackCheck _HackCheck;
	//_HackCheck = (HackCheck)GetProcAddress(hMod,"DetachProcess");
	//_HackCheck();
	FreeLibrary(hMod);
	TerminateProcess(GetCurrentProcess(),-1);
	return;
}
Esempio n. 9
0
void PathOCLRenderThread::Start() {
	started = true;

	InitRender();
	StartRenderThread();
}
Esempio n. 10
0
int main()
{
    SDL_Window *window = NULL;
    int width  = 480, height = 480;
    int flags;
    int quit = 0;

    // Initialize SDL, then get the current video mode and use it to create a SDL window.
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        fprintf(stderr, "Video initialization failed: %s\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }

    // Request GL context to be OpenGL 3.2 Core Profile
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    // Other GL attributes
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
    //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
    window = SDL_CreateWindow("AntTweakBar example using OpenGL Core Profile and SDL",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        width, height,
        flags);
    if (window == NULL)
    {
        fprintf(stderr, "Video mode set failed: %s\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }

    // Initialize AntTweakBar
    if (!TwInit(TW_OPENGL_CORE, NULL)) {
        fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
        SDL_Quit();
        exit(1);
    }
    // Tell the window size to AntTweakBar
    TwWindowSize(width, height);
    // Create a tweak bar
    CreateTweakBar();

    // Set OpenGL viewport
    glViewport(0, 0, width, height);

    // Prepare GL shaders and programs for drawing
    InitRender();

    // Main loop:
    // - Draw scene
    // - Process events
    while (!quit)
    {
        SDL_Event event;
        int handled;
        GLenum error;

        // Clear screen
        glClearColor(0.5f, 0.75f, 0.8f, 1);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

        // Update angle and draw geometry
        angle = (float)SDL_GetTicks()/25.0f * (FLOAT_PI/180.0f);
        quat[0] = quat[1] = 0;
        quat[2] = (float)sin(angle/2.0f);
        quat[3] = (float)cos(angle/2.0f);
        Render();

        // Draw tweak bars
        TwDraw();

        // Present frame buffer
        SDL_GL_SwapWindow(window);

        // Process incoming events
        while (SDL_PollEvent(&event))
        {
            // Send event to AntTweakBar
            handled = TwEventSDL(&event);

            // If event has not been handled by AntTweakBar, process it
            if (!handled)
            {
                switch (event.type)
                {
                case SDL_QUIT:  // Window is closed
                    quit = 1;
                    break;

                case SDL_WINDOWEVENT:   // Window size has changed
                    // Resize SDL video mode
                    if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
                        width = event.window.data1;
                        height = event.window.data2;

                        // Resize OpenGL viewport
                        glViewport(0, 0, width, height);

                        // Restore OpenGL states
                        InitRender();

                        // TwWindowSize has been called by TwEventSDL,
                        // so it is not necessary to call it again here.

                    }
                    break;
                }
            }
        }

        while ((error = glGetError()) != GL_NO_ERROR)
            fprintf(stderr, "GL error detected: 0x%04X\n", error);

    } // End of main loop

    // Terminate AntTweakBar
    TwTerminate();

    // Delete GL shaders and buffer
    UninitRender();

    // Terminate SDL
    SDL_Quit();

    return 0;
}
int main()
{
    const SDL_VideoInfo* video = NULL;
    int width  = 480, height = 480;
    int bpp, flags;
    int quit = 0;

    // Initialize SDL, then get the current video mode and use it to create a SDL window.
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        fprintf(stderr, "Video initialization failed: %s\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }
    video = SDL_GetVideoInfo();
    if (!video) 
    {
        fprintf(stderr, "Video query failed: %s\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }
    // Request GL context to be OpenGL 3.2 Core Profile
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    // Other GL attributes
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
    //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    bpp = video->vfmt->BitsPerPixel;
    flags = SDL_OPENGL | SDL_HWSURFACE;
    if (!SDL_SetVideoMode(width, height, bpp, flags))
    {
        fprintf(stderr, "Video mode set failed: %s\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }
    SDL_WM_SetCaption("AntTweakBar example using OpenGL Core Profile and SDL", "AntTweakBar+GLCore+SDL");

    // Enable SDL unicode and key-repeat
    SDL_EnableUNICODE(1);
    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);

    // Load some OpenGL core functions
    if (!LoadGLCoreFunctions())
    {
        fprintf(stderr, "OpenGL 3.2 not supported.\n");
        SDL_Quit();
        exit(1);
    }

    // Initialize AntTweakBar
    if (!TwInit(TW_OPENGL_CORE, NULL)) {
        fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
        SDL_Quit();
        exit(1);
    }
    // Tell the window size to AntTweakBar
    TwWindowSize(width, height);
    // Create a tweak bar
    CreateTweakBar();

    // Set OpenGL viewport
    glViewport(0, 0, width, height);

    // Prepare GL shaders and programs for drawing
    InitRender();

    // Main loop:
    // - Draw scene
    // - Process events
    while (!quit)
    {
        SDL_Event event;
        int handled;
        GLenum error;

        // Clear screen
        glClearColor(0.5f, 0.75f, 0.8f, 1);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

        // Update angle and draw geometry
        angle = (float)SDL_GetTicks()/25.0f * (FLOAT_PI/180.0f);
        quat[0] = quat[1] = 0;
        quat[2] = (float)sin(angle/2.0f);
        quat[3] = (float)cos(angle/2.0f);
        Render();

        // Draw tweak bars
        TwDraw();

        // Present frame buffer
        SDL_GL_SwapBuffers();

        // Process incoming events
        while (SDL_PollEvent(&event)) 
        {
            // Send event to AntTweakBar
            handled = TwEventSDL(&event, SDL_MAJOR_VERSION, SDL_MINOR_VERSION);

            // If event has not been handled by AntTweakBar, process it
            if (!handled)
            {
                switch (event.type)
                {
                case SDL_QUIT:  // Window is closed
                    quit = 1;
                    break;

                case SDL_VIDEORESIZE:   // Window size has changed
                    // Resize SDL video mode
                    width = event.resize.w;
                    height = event.resize.h;
                    if (!SDL_SetVideoMode(width, height, bpp, flags))
                        fprintf(stderr, "WARNING: Video mode set failed: %s\n", SDL_GetError());

                    // Resize OpenGL viewport
                    glViewport(0, 0, width, height);
                    
                    // Restore OpenGL states
                    InitRender();
                    
                    // TwWindowSize has been called by TwEventSDL, 
                    // so it is not necessary to call it again here.

                    break;
                }
            }
        }

        while ((error = glGetError()) != GL_NO_ERROR) 
            fprintf(stderr, "GL error detected: 0x%04X\n", error);

    } // End of main loop

    // Terminate AntTweakBar
    TwTerminate();

    // Delete GL shaders and buffer
    UninitRender();

    // Terminate SDL
    SDL_Quit();

    return 0;
}  
Esempio n. 12
0
void render_window()
{
    game_config = GetGameConfig();
    game_levels = GetGameLevels();
    game_levels_count = GetGameLevelsCount();

    arguments = GetArguments();
    user_set = GetUserSettings();
    int start_level = get_start_level();

    save_dir_full = GetSaveDir();
    cache_dir_full = GetCacheDir();
    can_cache = (save_dir_full && cache_dir_full);

//------------------------------------------------------------------------------
    ApplyArguments();

    const SDL_VideoInfo *video_info = SDL_GetVideoInfo();
    if (user_set->geom_x > 0 && user_set->geom_y > 0)
    {
        disp_x = user_set->geom_x;
        disp_y = user_set->geom_y;
    }
    else
    {
        disp_x = video_info->current_w;
        disp_y = video_info->current_h;
    }

    int probe_bpp = (user_set->bpp == 0 ? video_info->vfmt->BitsPerPixel : user_set->bpp);
    disp_bpp = (probe_bpp == 32 ? probe_bpp : 16);

    bool rot = TransformGeom();

//------------------------------------------------------------------------------
#define BTN_SPACE_KOEF 4.5
    int btn_side = disp_y / 7;
    int btn_space = btn_side / BTN_SPACE_KOEF;
    int btns_padded_width = btn_side * 4 + btn_space * 5;
    if (btns_padded_width > disp_x)
    {
        //btn_side = ( wnd_w - 5 * ( btn_side / BTN_SPACE_KOEF ) ) / 4
        btn_side = (int)(disp_x / (4 + 5 / BTN_SPACE_KOEF));
        btn_space = btn_side / BTN_SPACE_KOEF;
    }
    int btns_width = btn_side * 4 + btn_space * 3;
    int font_height = btn_side / 3;
    int font_padding = font_height / 2;

//-- font and labels -----------------------------------------------------------
    TTF_Font *font = TTF_OpenFont(DEFAULT_FONT_FILE, font_height);
    if (!font)
    {
        log_error("Can't load font '%s'. Exiting.", DEFAULT_FONT_FILE);
        return;
    }

    SDL_Surface *levelTextSurface = NULL;
    SDL_Rect levelTextLocation;
    levelTextLocation.y = font_padding;

    SDL_Color fontColor = {0};
#ifndef RGBSWAP
    fontColor.r = 231;
    fontColor.g = 190;
    fontColor.b = 114;
#else
    //--enable-rgb-swap
    fontColor.r = 114;
    fontColor.g = 190;
    fontColor.b = 231;
#endif

    /* Window initialization */
    ingame = true;
    Uint32 sdl_flags = SDL_SWSURFACE;
    if (user_set->fullscreen_mode != FULLSCREEN_NONE)
        sdl_flags |= SDL_FULLSCREEN;
    SDL_Surface *disp = SDL_SetVideoMode(disp_x, disp_y, disp_bpp, sdl_flags);
    if (disp == NULL)
    {
        log_error("Can't set video mode %dx%dx%dbpp. Exiting.", disp_x, disp_y, disp_bpp);
        return;
    }
    screen = disp;
    SDL_Surface *gui_surface = disp;
    SDL_WM_SetCaption("Mokomaze", "Mokomaze");

    /* Draw loading screen */
    SDL_Color whiteColor = {0};
    whiteColor.r = whiteColor.g = whiteColor.b = 255;
    SDL_Surface *titleSurface = TTF_RenderText_Blended(font, "Loading...", whiteColor);
    SDL_Rect title_rect;
    title_rect.x = (disp_x - titleSurface->w) / 2;
    title_rect.y = (disp_y - titleSurface->h) / 2;
    title_rect.w = titleSurface->w;
    title_rect.h = titleSurface->h;
    SDL_BlitSurface(titleSurface, NULL, screen, &title_rect);
    SDL_UpdateRect(screen, title_rect.x, title_rect.y, title_rect.w, title_rect.h);
    SDL_FreeSurface(titleSurface);

//-- load pictures -------------------------------------------------------------
    SDL_Surface *back_pic     = LoadSvg(MDIR "prev-main.svg", btn_side, btn_side, false, false);
    SDL_Surface *forward_pic  = LoadSvg(MDIR "next-main.svg", btn_side, btn_side, false, false);
    SDL_Surface *settings_pic = LoadSvg(MDIR "settings-main.svg", btn_side, btn_side, false, false);
    SDL_Surface *exit_pic     = LoadSvg(MDIR "close-main.svg", btn_side, btn_side, false, false);

    SDL_Surface *back_i_pic    = LoadSvg(MDIR "prev-grey.svg", btn_side, btn_side, false, false);
    SDL_Surface *forward_i_pic = LoadSvg(MDIR "next-grey.svg", btn_side, btn_side, false, false);

    SDL_Surface *back_p_pic    = LoadSvg(MDIR "prev-light.svg", btn_side, btn_side, false, false);
    SDL_Surface *forward_p_pic = LoadSvg(MDIR "next-light.svg", btn_side, btn_side, false, false);

    int tmpx = (rot ? game_config.wnd_h : game_config.wnd_w);
    int tmpy = (rot ? game_config.wnd_w : game_config.wnd_h);
    desk_pic = LoadSvg(MDIR "desk.svg", tmpx, tmpy, rot, true);
    wall_pic = LoadSvg(MDIR "wall.svg", tmpx, tmpy, rot, true);
    int hole_d = game_config.hole_r * 2;
    fin_pic = LoadSvg(MDIR "openmoko.svg", hole_d, hole_d, rot, false);

    if (LoadImgErrors > 0)
    {
        log_error("Some images were not loaded. Exiting.");
        return;
    }

//-- positions of buttons ------------------------------------------------------
    SDL_Rect gui_rect_1, gui_rect_2, gui_rect_3, gui_rect_4;
    gui_rect_1.y = gui_rect_2.y = gui_rect_3.y = gui_rect_4.y = levelTextLocation.y + font_height + font_padding;
    gui_rect_1.x = (disp_x - btns_width) / 2;
    gui_rect_2.x = gui_rect_1.x + btn_side + btn_space;
    gui_rect_3.x = gui_rect_2.x + btn_side + btn_space;
    gui_rect_4.x = gui_rect_3.x + btn_side + btn_space;
//-- for click detection -------------------------------------------------------
    Box gui_box_1, gui_box_2, gui_box_3, gui_box_4;
    gui_box_1.x1 = gui_rect_1.x;
    gui_box_1.y1 = gui_rect_1.y;
    gui_box_1.x2 = gui_rect_1.x + btn_side;
    gui_box_1.y2 = gui_rect_1.y + btn_side;
    gui_box_2.x1 = gui_rect_2.x;
    gui_box_2.y1 = gui_rect_2.y;
    gui_box_2.x2 = gui_rect_2.x + btn_side;
    gui_box_2.y2 = gui_rect_2.y + btn_side;
    gui_box_3.x1 = gui_rect_3.x;
    gui_box_3.y1 = gui_rect_3.y;
    gui_box_3.x2 = gui_rect_3.x + btn_side;
    gui_box_3.y2 = gui_rect_3.y + btn_side;
    gui_box_4.x1 = gui_rect_4.x;
    gui_box_4.y1 = gui_rect_4.y;
    gui_box_4.x2 = gui_rect_4.x + btn_side;
    gui_box_4.y2 = gui_rect_4.y + btn_side;

    //create surface for rendering the level
    render_pic = CreateSurface(SDL_SWSURFACE, game_config.wnd_w, game_config.wnd_h, disp);

    if (user_set->scrolling)
        screen = CreateSurface(SDL_SWSURFACE, game_config.wnd_w, game_config.wnd_h, disp);

    if (user_set->fullscreen_mode != FULLSCREEN_NONE)
        SDL_ShowCursor(!ingame);

    desk_rect.x = 0;
    desk_rect.y = 0;
    desk_rect.w = game_config.wnd_w;
    desk_rect.h = game_config.wnd_h;

    SDL_Rect ball_rect;

    int disp_scroll_border = min(disp_x, disp_y) * 0.27;
    SDL_Rect screen_rect;
    screen_rect.x = 0;
    screen_rect.y = 0;
    screen_rect.w = disp_x;
    screen_rect.h = disp_y;
    SDL_Rect disp_rect;
    disp_rect = screen_rect;

    SDL_Color ballColor = {0};
    ballColor.r = 255;
    ballColor.g = 127;
    ballColor.b = 0;

    User user_set_new = *user_set;
    bool video_set_modified = false;

    /* Settings window initialization */
    settings_init(disp, font_height, user_set, &user_set_new);

    /* Render initialization */
    InitRender();

    /* Input system initialization */
    input_get_dummy(&input);
    SetInput();

    /* Vibro system initialization */
    vibro_get_dummy(&vibro);
    SetVibro();

    /* MazeCore initialization */
    maze_init();
    maze_set_config(game_config);
    maze_set_vibro_callback(BumpVibrate);
    maze_set_levels_data(game_levels, game_levels_count);

    cur_level = start_level;
    RenderLevel();
    RedrawDesk();
    maze_set_level(cur_level);
    ResetPrevPos();

    SDL_Event event;
    bool done = false;
    bool redraw_all = true;
    bool ingame_changed = false;
    int prev_ticks = SDL_GetTicks();
    Point mouse = {0};

//== Game Loop =================================================================
    while (!done)
    {
        bool wasclick = false;
        bool show_settings = false;
        while (SDL_PollEvent(&event))
        {
            bool btndown = false;
            bool btnesc = false;
            if (event.type == SDL_QUIT)
            {
                done = true;
            }
            else if (event.type == SDL_ACTIVEEVENT)
            {
                int g = event.active.gain;
                int s = event.active.state;
                if (ingame && !g && ((s & SDL_APPINPUTFOCUS) || (s & SDL_APPACTIVE)))
                {
                    btndown = true;
                }
            }
            else if (event.type == SDL_MOUSEMOTION)
            {
                mouse.x = event.motion.x;
                mouse.y = event.motion.y;
            }
            else if (event.type == SDL_MOUSEBUTTONUP)
            {
                StopFastChange();
            }
            else if (event.type == SDL_MOUSEBUTTONDOWN)
            {
                btndown = true;
            }
            else if (event.type == SDL_KEYDOWN)
            {
                switch(event.key.keysym.sym)
                {
                case SDLK_q:
                case SDLK_ESCAPE:
                    btnesc = true;
                case SDLK_SPACE:
                case SDLK_p:
                case SDLK_PAUSE:
                    btndown = true;
                    break;
                default:
                    break;
                }
            }
            else if (event.type == SDL_KEYUP)
            {
                switch(event.key.keysym.sym)
                {
                case SDLK_q:
                case SDLK_ESCAPE:
                    if( !wasclick || ingame || show_settings )
                        StopFastChange();
                    else
                        done = true;
                    break;
                case SDLK_SPACE:
                case SDLK_p:
                case SDLK_PAUSE:
                    StopFastChange();
                    break;
                default:
                    break;
                }
            }

            if (btndown)
            {
                if (!ingame)
                {
                    if (inbox(mouse.x, mouse.y, gui_box_1) && !btnesc)
                    {
                        if (cur_level > 0)
                        {
                            SDL_BlitSurface(back_p_pic, NULL, gui_surface, &gui_rect_1);
                            SDL_UpdateRect(gui_surface, gui_rect_1.x, gui_rect_1.y, gui_rect_1.w, gui_rect_1.h);

                            ChangeLevel(cur_level-1, &redraw_all, &wasclick);

                            fastchange_step = -10;
                            StopFastChange();
                            fastchange_timer = SDL_AddTimer(FASTCHANGE_INTERVAL, fastchange_callback, NULL);
                        }
                        continue;
                    }
                    else if (inbox(mouse.x, mouse.y, gui_box_2) && !btnesc)
                    {
                        if (cur_level < game_levels_count - 1)
                        {
                            SDL_BlitSurface(forward_p_pic, NULL, gui_surface, &gui_rect_2);
                            SDL_UpdateRect(gui_surface, gui_rect_2.x, gui_rect_2.y, gui_rect_2.w, gui_rect_2.h);

                            ChangeLevel(cur_level+1, &redraw_all, &wasclick);

                            fastchange_step = +10;
                            StopFastChange();
                            fastchange_timer = SDL_AddTimer(FASTCHANGE_INTERVAL, fastchange_callback, NULL);
                        }
                        continue;
                    }
                    else if (inbox(mouse.x, mouse.y, gui_box_3) && !btnesc)
                    {
                        show_settings = true;
                        RedrawDesk();
                        redraw_all = true;
                        wasclick = true;
                        continue;
                    }
                    else if (inbox(mouse.x, mouse.y, gui_box_4) || btnesc)
                    {
                        done = true;
                        continue;
                    }
                }
                ingame_changed = true;
            } //if (btndown)
        }

        if (ingame_changed)
        {
            ingame = !ingame;
            if (!ingame)
            {
                wasclick = true;
            }
            else
            {
                RedrawDesk();
                redraw_all = true;
            }

            if (user_set->fullscreen_mode == FULLSCREEN_INGAME)
                SDL_WM_ToggleFullScreen(disp);
            if (user_set->fullscreen_mode != FULLSCREEN_NONE)
                SDL_ShowCursor(!ingame);

            prev_ticks = SDL_GetTicks();
            ingame_changed = false;
        }

        if ((!ingame) && (!wasclick) && (must_fastchange))
        {
            int new_cur_level = cur_level + fastchange_dostep;
            clamp_max(new_cur_level, game_levels_count - 1);
            clamp_min(new_cur_level, 0);

            if (new_cur_level != cur_level)
            {
                if (fastchange_dostep < 0)
                {
                    SDL_BlitSurface(back_p_pic, NULL, gui_surface, &gui_rect_1);
                    SDL_UpdateRect(gui_surface, gui_rect_1.x, gui_rect_1.y, gui_rect_1.w, gui_rect_1.h);
                }
                else
                {
                    SDL_BlitSurface(forward_p_pic, NULL, gui_surface, &gui_rect_2);
                    SDL_UpdateRect(gui_surface, gui_rect_2.x, gui_rect_2.y, gui_rect_2.w, gui_rect_2.h);
                }

                ChangeLevel(new_cur_level, &redraw_all, &wasclick);
            }
            must_fastchange = false;
        }

        if (!ingame && !wasclick)
        {
            SDL_Delay(user_set->frame_delay);
            continue;
        }

//-- physics step --------------------------------------------------------------
        int ticks = SDL_GetTicks();
        int delta_ticks = ticks - prev_ticks;
        prev_ticks = ticks;
        clamp_min(delta_ticks, 1);
        clamp_max(delta_ticks, 1000 / 15);

        float acx = 0, acy = 0;
        input.read(&acx, &acy, NULL);
        if (input_cal_cycle)
            input_cal_cycle = (input_calibration_sample(&user_set->input_calibration_data, &acx, &acy, NULL) < MAX_CALIBRATION_SAMPLES);
        input_calibration_adjust(&user_set->input_calibration_data, &acx, &acy, NULL);
        maze_set_speed(user_set->ball_speed);
        maze_set_tilt(acx, acy, 0);
        GameState game_state = maze_step(delta_ticks);

        const dReal *R;
        int tk_px, tk_py, tk_pz;
        maze_get_ball(&tk_px, &tk_py, &tk_pz, &R);
        maze_get_animations(&keys_anim, &final_anim);
//------------------------------------------------------------------------------

        //restore the background
        ball_rect.w = game_config.ball_r * 2;
        ball_rect.h = game_config.ball_r * 2; //
        ball_rect.x = prev_px - game_config.ball_r;
        ball_rect.y = prev_py - game_config.ball_r;
        SDL_BlitSurface(render_pic, &ball_rect, screen, &ball_rect);

        UpdateBufAnimation();
        DrawBall(tk_px, tk_py, tk_pz, R, ballColor);

        //update the screen
        if (!redraw_all && !user_set->scrolling)
        {
            int min_px, max_px;
            int min_py, max_py;
            if (prev_px <= tk_px)
            {
                min_px = prev_px;
                max_px = tk_px;
            }
            else
            {
                min_px = tk_px;
                max_px = prev_px;
            }

            if (prev_py <= tk_py)
            {
                min_py = prev_py;
                max_py = tk_py;
            }
            else
            {
                min_py = tk_py;
                max_py = prev_py;
            }
            min_px -= game_config.ball_r;
            max_px += game_config.ball_r;
            min_py -= game_config.ball_r;
            max_py += game_config.ball_r;
            clamp_min(min_px, 0);
            clamp_max(max_px, game_config.wnd_w - 1);
            clamp_min(min_py, 0);
            clamp_max(max_py, game_config.wnd_h - 1);
            SDL_UpdateRect(screen, min_px, min_py, max_px - min_px, max_py - min_py);
            UpdateScreenAnimation();
        }

        if (user_set->scrolling)
        {
            clamp_min(screen_rect.x, tk_px - disp_x + disp_scroll_border);
            clamp_max(screen_rect.x, tk_px - disp_scroll_border);
            clamp_min(screen_rect.y, tk_py - disp_y + disp_scroll_border);
            clamp_max(screen_rect.y, tk_py - disp_scroll_border);
            clamp(screen_rect.x, 0, game_config.wnd_w - disp_x);
            clamp(screen_rect.y, 0, game_config.wnd_h - disp_y);
            SDL_BlitSurface(screen, &screen_rect, disp, &disp_rect);
        }

        prev_px = tk_px;
        prev_py = tk_py;

//-- GUI -----------------------------------------------------------------------
        if (wasclick && !ingame && !show_settings)
        {
            char txt[32];
            sprintf(txt, "Level %d/%d", cur_level + 1, game_levels_count);
            SDL_FreeSurface(levelTextSurface);
            levelTextSurface = TTF_RenderText_Blended(font, txt, fontColor);
            levelTextLocation.x = (disp_x - levelTextSurface->w) / 2;
            SDL_BlitSurface(levelTextSurface, NULL, gui_surface, &levelTextLocation);

            if (cur_level > 0)
                SDL_BlitSurface(back_pic, NULL, gui_surface, &gui_rect_1);
            else
                SDL_BlitSurface(back_i_pic, NULL, gui_surface, &gui_rect_1);

            if (cur_level < game_levels_count - 1)
                SDL_BlitSurface(forward_pic, NULL, gui_surface, &gui_rect_2);
            else
                SDL_BlitSurface(forward_i_pic, NULL, gui_surface, &gui_rect_2);

            SDL_BlitSurface(settings_pic, NULL, gui_surface, &gui_rect_3);
            SDL_BlitSurface(exit_pic, NULL, gui_surface, &gui_rect_4);
            redraw_all = true;
        }
//------------------------------------------------------------------------------

        //update the whole screen if needed
        if (user_set->scrolling)
        {
            SDL_Flip(disp);
        }
        else if (redraw_all)
        {
            SDL_Flip(screen);
        }
        redraw_all = false;

        if (show_settings)
        {
            bool _video_set_modified = false;
            bool _input_set_modified = false;
            bool _vibro_set_modified = false;
            settings_show(&input_cal_cycle, &_video_set_modified, &_input_set_modified, &_vibro_set_modified);
            if (input_cal_cycle)
                input_calibration_reset();
            if (_video_set_modified)
                video_set_modified = true;
            if (_input_set_modified)
                SetInput();
            if (_vibro_set_modified)
                SetVibro();
            SDL_GetMouseState(&mouse.x, &mouse.y);
            ingame_changed = true;
        }

        switch (game_state)
        {
        case GAME_STATE_FAILED:
            RedrawDesk();
            maze_restart_level();
            ResetPrevPos();
            redraw_all = true;
            break;
        case GAME_STATE_SAVED:
            RedrawDesk();
            maze_reload_level();
            ResetPrevPos();
            redraw_all = true;
            break;
        case GAME_STATE_WIN:
            if (++cur_level >= game_levels_count) cur_level=0;
            RenderLevel();
            RedrawDesk();
            maze_set_level(cur_level);
            ResetPrevPos();
            redraw_all = true;
            break;
        default:
            break;
        }

        SDL_Delay(user_set->frame_delay);
    }
//==============================================================================

    if (video_set_modified)
    {
        user_set->scrolling = user_set_new.scrolling;
        user_set->geom_x = user_set_new.geom_x;
        user_set->geom_y = user_set_new.geom_y;
        user_set->bpp = user_set_new.bpp;
        user_set->fullscreen_mode = user_set_new.fullscreen_mode;
        user_set->frame_delay = user_set_new.frame_delay;
    }

    user_set->level = cur_level + 1;
    SaveUserSettings();

    settings_shutdown();

    SDL_FreeSurface(levelTextSurface);
    TTF_CloseFont(font);
    vibro.shutdown();
    input.shutdown();
}