/* * UltraStar Deluxe - Karaoke Game * * UltraStar Deluxe is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * $URL$ * $Id$ */ #if 0 #include "display.hpp" #include #include #include // constants for software cursor effects time in milliseconds const int Cursor_FadeIn_Time = 500; // seconds the fade in effect lasts const int Cursor_FadeOut_Time = 2000; // seconds the fade out effect lasts const int Cursor_AutoHide_Time = 5000; // seconds until auto fade out starts if there is no mouse movement namespace usdx { Display* Display::get_instance(void) { if (!instance) { instance = new Display(); } return instance; } Display::Display(void) { //popup hack check_ok = false; next_screen = NULL; next_screen_with_check = NULL; black_screen = false; // fade mod fade_state = 0; fade_enabled = (Ini.ScreenFade == 1); fade_failed = false; glGenTextures(2, fade_tex); for (int i = 0; i < 2; i++) { glBindTexture(GL_TEXTURE_2D, fade_tex[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } //Set LastError for OSD to No Error osd_last_error = "No Errors"; // software cursor default values cursor_last_move = 0; cursor_visible = false; cursor_pressed = false; cursor_x = -1; cursor_y = -1; cursor_fade = false; cursor_hidden_by_screen = true; } Display::~Display(void) { glDeleteTextures(2, fade_tex); } bool Display::draw(void) { //We don't need this here anymore, //Because the background care about cleaning the buffers //glClearColor(1, 1, 1 , 0); //glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); for (int s = 0; s < screens; s++) { int ScreenAct = s; //if Screens = 1 then ScreenX := 0; //if (Screens = 2) and (S = 1) then ScreenX := -1; //if (Screens = 2) and (S = 2) then ScreenX := 1; int ScreenX = 0; glViewPort((s-1) * screen_w / screens, 0, screen_w / screens, screen_h); // popup hack // check was successful... move on if (check_ok) { if (next_screen_with_check) { next_screen = next_screen_with_check; next_screen_with_check = NULL; check_ok = false; } else { // on end of game fade to black before exit black_screen = true; } } if (!next_screen && !black_screen) { current_screen->Draw(); //popup mod if (screen_popup_error && screen_popup_error->visible) screen_popup_error->Draw(); else if (screen_popup_info && screen_popup_info->visible) screen_popup_info->Draw(); else if (screen_popup_check && screen_popup_check->visible) screen_popup_check->Draw(); // fade mod fade_state = 0; if ((Ini.ScreenFade == 1) && !fade_failed) fade_enabled = true; else if (Ini.ScreenFade == 0) fade_enabled = false; } else { // disable fading if initialization failed if (fade_enabled && fade_failed) fade_enabled = false; if (fade_enabled && !fade_failed) { //Create Fading texture if we're just starting if (fade_state == 0) { // save old viewport and resize to fit texture glPushAttrib(GL_VIEWPORT_BIT); glViewPort(0, 0, 512, 512); // draw screen that will be faded current_screen->Draw(); // clear OpenGL errors, otherwise fading might be disabled due to some // older errors in previous OpenGL calls. glGetError(); // copy screen to texture glBindTexture(GL_TEXTURE_2D, fade_tex[s]); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 512, 512, 0); GLenum glError = glGetError(); if (glError != GL_NO_ERROR) { fade_failed = true; Log->LogWarn(std::string("Fading disabled: ") + gluErrorString(glError), "TDisplay.Draw"); } // restore viewport glPopAttrib(); // blackscreen-hack if (!black_screen) next_screen->on_show(); // update fade state last_fade_time = SDL_GetTicks(); if ((s == 1) || (screens == 1)) fade_state++; } // end texture creation in first fading step //do some time-based fading unsigned int current_time = SDL_GetTicks(); if ((current_time > last_fade_time + 30) && (s == 0)) { fade_state += 4; last_fade_time = current_time; } // blackscreen-hack if (!black_screen) next_screen->Draw(); // draw next screen else if (screen_act == 0) { glClearColor(0, 0, 0 , 0); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); } // and draw old screen over it... slowly fading out float fade_state_square = (fade_state * fade_state) / 10000.0; glBindTexture(GL_TEXTURE_2D, fade_tex[s]); glColor4f(1, 1, 1, 1 - fade_state_square); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glBegin(GL_QUADS); glTexCoord2f(0 + fade_state_square, 0 + fade_state_square); glVertex2f(0, 600); glTexCoord2f(0 + fade_state_square, 1 - fade_state_square); glVertex2f(0, 0); glTexCoord2f(1 - fade_state_square, 1 - fade_state_square); glVertex2f(800, 0); glTexCoord2f(1 - fade_state_square, 0 + fade_state_square); glVertex2f(800, 600); glEnd(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); } // blackscreen hack else if (!black_screen) next_screen->on_show(); if ((((fade_state > 40) || !fade_enabled) || fade_failed) && (s == 0)) { // fade out complete... fade_state = 0; current_screen->on_hide(); current_screen->show_finish = false; current_screen = next_screen; next_screen = NULL; if (!black_screen) { current_screen->on_show_finish(); current_screen->show_finish = true; } else { return false; } } } // Draw OSD only on first Screen if Debug Mode is enabled if (((Ini->Debug == 1) || (Params->Debug)) && (s == 0)) draw_debug_information(); } // for if (!black_screen) draw_cursor(); return true; } // sets SDL_ShowCursor depending on options set in Ini void Display::set_cursor(void) { int cursor = 0; if ((current_screen != screen_sing) || (cursor_hidden_by_screen)) { // hide cursor on singscreen if ((Ini->Mouse == 0) and (Ini->FullScreen == 0)) // show sdl (os) cursor in window mode even when mouse support is off cursor = 1; else if ((Ini->Mouse == 1)) // show sdl (os) cursor when hardware cursor is selected cursor = 1; if ((Ini->Mouse != 2)) cursor_hidden_by_screen = false; } else if ((Ini.Mouse != 2)) cursor_hidden_by_screen = true; SDL_ShowCursor(cursor); if (Ini->Mouse == 2) { if (cursor_hidden_by_screen) { // show software cursor cursor_hidden_by_screen = false; cursor_visible = false; cursor_fade = false; } else if (current_screen == screen_sing) { // hide software cursor in singscreen cursor_hidden_by_screen = true; cursor_visible = false; cursor_fade = false; } } } // called by MoveCursor and OnMouseButton to update last move and start fade in void Display::update_cursor_fade(void) { unsigned int ticks = SDL_GetTicks(); // fade in on movement (or button press) if not first movement if ((!cursor_visible) && (cursor_last_move != 0)) { if (cursor_fade) // we use a trick here to consider progress of fade out cursor_last_move = ticks - (int)(Cursor_FadeIn_Time * (1 - (ticks - cursor_last_move) / (float)Cursor_FadeOut_Time) + 0.5); else cursor_last_move = ticks; cursor_visible = true; cursor_fade = true; } else if (!cursor_fade) { cursor_last_move = ticks; } } // called when cursor moves, positioning of software cursor void Display::move_cursor(double x, double y) { if ((Ini->Mouse == 2) && ((x != cursor_x) || (y != cursor_y))) { cursor_x = x; cursor_y = y; update_cursor_fade(); } } // called when left or right mousebutton is pressed or released void Display::on_mouse_button(bool pressed) { if (Ini->Mouse == 2) { cursor_pressed = pressed; update_cursor_fade(); } } // draws software cursor void Display::draw_cursor(void) { float alpha; unsigned int ticks; if (Ini->Mouse == 2) { // draw software cursor ticks = SDL_GetTicks(); if ((cursor_visible) && (cursor_last_move + Cursor_AutoHide_Time <= ticks)) { // start fade out after 5 secs w/o activity cursor_visible = false; cursor_last_move = ticks; cursor_fade = true; } // fading if (cursor_fade) { if (cursor_visible) { // fade in if (cursor_last_move + Cursor_FadeIn_Time <= ticks) cursor_fade = false; else alpha = sin((ticks - cursor_last_move) * 0.5 * M_PI / Cursor_FadeIn_Time) * 0.7; } else { //fade out if (cursor_last_move + Cursor_FadeOut_Time <= ticks) cursor_fade = false; else alpha = cos((ticks - cursor_last_move) * 0.5 * M_PI / Cursor_FadeOut_Time) * 0.7; } } // no else if here because we may turn off fade in if block if (!cursor_fade) { if (cursor_visible) // alpha when cursor visible and not fading alpha = 0.7; else // alpha when cursor is hidden alpha = 0; } if ((alpha > 0) && (!cursor_hidden_by_screen)) { glColor4f(1, 1, 1, alpha); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); if ((cursor_pressed) && (tex_cursor_pressed->tex_num > 0)) glBindTexture(GL_TEXTURE_2D, tex_cursor_pressed->tex_num); else glBindTexture(GL_TEXTURE_2D, tex_cursor_unpressed->tex_num); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(cursor_x, cursor_x); glTexCoord2f(0, 1); glVertex2f(cursor_x, cursor_y + 32); glTexCoord2f(1, 1); glVertex2f(cursor_x + 32, cursor_y + 32); glTexCoord2f(1, 0); glVertex2f(cursor_x + 32, cursor_y); glEnd(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); } } } bool Display::parse_input(unsigned int pressed_key, UCS4Char char_code, bool pressed_down) { if (next_screen) return next_screen->parse_input(pressed_key, char_code, pressed_down); if (current_screen) return current_screen->parse_input(pressed_key, char_code, pressed_down); return true; } void Display::save_screen_shot() { Path *file_name; std::string prefix; char *screen_data; SDL_Surface *surface; bool success; int align; int row_size; // Exit if Screenshot-path does not exist or read-only if (!screenshots_path) return; for (int num = 1; num < 10000; num++) { /** TODO: // fill prefix to 4 digits with leading '0', e.g. '0001' Prefix = Format('screenshot%.4d', [Num]); FileName = ScreenshotsPath.Append(Prefix + '.png'); if not FileName.Exists() break; */ } // we must take the row-alignment (4byte by default) into account glGetIntegerv(GL_PACK_ALIGNMENT, &align); // calc aligned row-size row_size = ((screen_w * 3 + (align - 1)) / align) * align; malloc(screen_data, row_size * screen_h); glReadPixels(0, 0, screen_w, screen_h, GL_RGB, GL_UNSIGNED_BYTE, screen_data); // on big endian machines (powerpc) this may need to be changed to // Needs to be tests. KaMiSchi Sept 2008 // in this case one may have to add " glext, " to the list of used units // glReadPixels(0, 0, ScreenW, ScreenH, GL_BGR, GL_UNSIGNED_BYTE, ScreenData); Surface = SDL_CreateRGBSurfaceFrom( screen_data, screen_w, screen_h, 24, row_size, 0x0000ff, 0x00ff00, 0xff0000, 0); // Success = WriteJPGImage(FileName, Surface, 95); // Success = WriteBMPImage(FileName, Surface); success = WritePNGImage(file_name, surface); if (success) ScreenPopupInfo->ShowPopup(Format(Language.Translate("SCREENSHOT_SAVED"), [FileName.GetName.ToUTF8()])); else ScreenPopupError->ShowPopup(Language.Translate("SCREENSHOT_FAILED")); SDL_FreeSurface(surface); free(screen_data); } //------------ // DrawDebugInformation - procedure draw fps and some other informations on screen //------------ void Display::draw_debug_information() { // Some White Background for information glEnable(GL_BLEND); glDisable(GL_TEXTURE_2D); glColor4f(1, 1, 1, 0.5); glBegin(GL_QUADS); glVertex2f(690, 44); glVertex2f(690, 0); glVertex2f(800, 0); glVertex2f(800, 44); glEnd(); glDisable(GL_BLEND); // set font specs SetFontStyle(0); SetFontSize(21); SetFontItalic(false); glColor4f(0, 0, 0, 1); // calculate fps unsigned int ticks = SDL_GetTicks(); if (ticks >= next_fps_swap) { last_fps = fps_counter * 4; fps_counter = 0; next_fps_swap = ticks + 250; } fps_counter++; // draw text // TODO: // fps SetFontPos(695, 0); glPrint ("FPS: " + itoa(last_fps)); // rspeed SetFontPos(695, 13); glPrint ("RSpeed: " + itoa((int)(1000 * time_mid))); // lasterror SetFontPos(695, 26); glColor4f(1, 0, 0, 1); glPrint(osd_last_error.c_str()); glColor4f(1, 1, 1, 1); } }; #endif