template<class T,class T2> void OPENGL_SCALAR_FIELD_2D<T,T2>:: Update() { VECTOR<int,2> start_index(values.domain.min_corner.x,values.domain.min_corner.y),end_index(values.domain.max_corner.x,values.domain.max_corner.y); if(!draw_ghost_values){start_index=clamp_min(start_index,VECTOR<int,2>(1,1));end_index=clamp_max(end_index,grid.counts);} if (draw_mode==DRAW_TEXTURE) Update_Texture(start_index,end_index); else if (draw_mode==DRAW_POINTS) Update_Points(start_index,end_index); else Update_Contour_Curves(); }
T LinearGainToDecibelsClipped(const T value) { return value <= 0. ? -DecibelHeadroom : clamp_min(20.0 * std::log10(value), -DecibelHeadroom); }
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(); }