// $Id: playdisplay.cc,v 1.7 2006/08/28 15:23:14 matthew Exp $ // Fish Supper // Copyright (C) 2006 Matthew Clarke // // 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; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. #include "playdisplay.h" #include "fontrepository.h" #include #include #include extern FS::FontRepository * font_rep; // ******************* // *** CONSTRUCTOR *** // ******************* FS::PlayDisplay::PlayDisplay(SDL_Surface * s) : my_font(font_rep->get_SFont(FontRepository::WHITE_FONT)) { screen = s; // set transparency color (= green) transparency = SDL_MapRGB(screen->format, 0, 255, 0); // FIXME - all sprites need proper transparency. // Use a std::string rather than char[] for filename. std::string filename; char digits[3]; for (int i = 0; i < NUM_IMAGES; ++i) { sprintf(digits, "%02d", i); filename = (PKG_DATA_DIR "/images/play/fs_image_"); (filename += digits) += ".png"; if (i > 0) // background doesn't have transparency! { if ( i >= SPLASHING_N && i <= SPLASHING_W ) { my_images[i] = SDL_DisplayFormat(IMG_Load(filename.c_str())); SDL_SetColorKey(my_images[i], SDL_SRCCOLORKEY|SDL_RLEACCEL, transparency); } else { my_images[i] = SDL_DisplayFormatAlpha(IMG_Load(filename.c_str())); SDL_SetAlpha(my_images[i], SDL_SRCALPHA|SDL_RLEACCEL, 0); } // if ... else } else { my_images[i] = SDL_DisplayFormat(IMG_Load(filename.c_str())); } // if ... else } // for // Set up the 'my_blit_requests' arrays. The sizes are stored in // the 'LAYER_MAX_BLITS' array in "constants.h". for (int i = 0; i < NUM_LAYERS; ++i) { my_blit_requests[i] = new BlitRequest[ LAYER_MAX_BLITS[i] ]; } // for score_dirty_rect.x = 191; score_dirty_rect.y = 9; score_dirty_rect.w = 70; score_dirty_rect.h = 15; lives_dirty_rect.x = 41; lives_dirty_rect.y = 9; lives_dirty_rect.w = 10; lives_dirty_rect.h = 15; level_dirty_rect.x = 707; level_dirty_rect.y = 9; level_dirty_rect.w = 22; level_dirty_rect.h = 15; pause_menu_dirty_rect.x = 295; pause_menu_dirty_rect.y = 236; pause_menu_dirty_rect.w = 210; pause_menu_dirty_rect.h = 127; } // FS::PlayDisplay::PlayDisplay() // ****************** // *** DESTRUCTOR *** // ****************** FS::PlayDisplay::~PlayDisplay() { for (int i = 0; i < NUM_LAYERS; ++i) { delete [] my_blit_requests[i]; } // for for (int i = 0; i < NUM_IMAGES; ++i) { SDL_FreeSurface(my_images[i]); } // for } // FS::PlayDisplay::~PlayDisplay() // ************************ // *** MEMBER FUNCTIONS *** // ************************ // ************************************************** void FS::PlayDisplay::redraw() { // ERASE for (int i = 0; i < erase_rects_index; ++i) { SDL_BlitSurface( my_images[BACKGROUND], &my_erase_rects[i], screen, &my_erase_rects[i] ); } // for // DRAW if (is_first_pass) { SDL_BlitSurface(my_images[BACKGROUND], NULL, screen, NULL); } // if if (draw_score) { my_font.write(screen, score, 190, 4); } // if if (draw_lives) { my_font.write(screen, lives, 40, 4); } // if if (draw_level) { my_font.write(screen, level, 706, 4); } // if for (int i = 0; i < NUM_LAYERS; ++i) { for (int j = 0; j < blit_request_indices[i]; ++j) { SDL_BlitSurface( my_images[ my_blit_requests[i][j].id ], my_blit_requests[i][j].src_rect, screen, &my_blit_requests[i][j].dest_rect ); } // for } // for // UPDATE if (is_first_pass) { SDL_UpdateRect(screen, 0, 0, 0, 0); is_first_pass = false; } else { SDL_UpdateRects(screen, dirty_rects_index, dirty_rects); } // if ... else erase_rects_index = 0; dirty_rects_index = 0; draw_score = false; draw_lives = false; draw_level = false; for (int i = 0; i < NUM_LAYERS; ++i) { blit_request_indices[i] = 0; } // for } // FS::PlayDisplay::redraw() // ************************************************** void FS::PlayDisplay::request_erase(const SDL_Rect * er) { my_erase_rects[erase_rects_index++] = *er; } // FS::PlayDisplay::request_erase() // ************************************************** void FS::PlayDisplay::request_blit(ImageIDs id, SDL_Rect * isr, const SDL_Rect * idr) { // Need to know what layer this image is drawn on. int layer = IMAGE_LAYERS[id]; // Copy values into the next vacant slot of the corresponding // 'my_blit_requests' array and update the index. my_blit_requests[layer][ blit_request_indices[layer] ].id = id; my_blit_requests[layer][ blit_request_indices[layer] ].src_rect = isr; my_blit_requests[layer][ blit_request_indices[layer] ].dest_rect = *idr; ++blit_request_indices[layer]; } // FS::PlayDisplay::request_blit() // ************************************************** void FS::PlayDisplay::request_update(SDL_Rect dr) { dirty_rects[dirty_rects_index++] = dr; //std::cout << dr.x << "," << dr.y << "," << dr.w << "," << dr.h << "\n"; } // FS::PlayDisplay::request_update() // ************************************************** void FS::PlayDisplay::reset() { is_first_pass = true; erase_rects_index = 0; dirty_rects_index = 0; draw_score = false; draw_lives = false; draw_level = false; for (int i = 0; i < NUM_LAYERS; ++i) { blit_request_indices[i] = 0; } // for } // FS::PlayDisplay::reset() // ************************************************** void FS::PlayDisplay::request_draw_score(int s) { if ( draw_score ) { return; } // if // set flag draw_score = true; // put score into correct format sprintf(score, "%06d", s); // schedule an erase and update request_erase(&score_dirty_rect); request_update(score_dirty_rect); } // FS::PlayDisplay::request_draw_score() // ************************************************** void FS::PlayDisplay::request_draw_lives(int l) { if ( draw_lives ) { return; } // if draw_lives = true; sprintf(lives, "%d", l); request_erase(&lives_dirty_rect); request_update(lives_dirty_rect); } // FS::PlayDisplay::request_draw_lives() // ************************************************** void FS::PlayDisplay::request_draw_level(int lev) { if ( draw_level ) { return; } // if draw_level = true; sprintf(level, "%d", lev); request_erase(&level_dirty_rect); request_update(level_dirty_rect); } // FS::PlayDisplay::request_draw_level() // ************************************************** // N.B. It's not possible for Albert to collide with two of these player info // objects at the same time (he's not wide enough!), so can use 'if ... else'. void FS::PlayDisplay::check_redraw(const SDL_Rect & box, int score, int lives, int level) { if ( !draw_score && Collisions::intersects(box, score_dirty_rect) ) { request_draw_score(score); } else if ( !draw_lives && Collisions::intersects(box, lives_dirty_rect) ) { request_draw_lives(lives); } else if ( !draw_level && Collisions::intersects(box, level_dirty_rect) ) { request_draw_level(level); } // if ... else } // FS::PlayDisplay::check_redraw() // ************************************************** void FS::PlayDisplay::request_draw_pause_menu(ImageIDs id) { request_erase(&pause_menu_dirty_rect); request_blit(id, NULL, &pause_menu_dirty_rect); request_update(pause_menu_dirty_rect); } // FS::PlayDisplay::request_draw_pause_menu // ************************************************** void FS::PlayDisplay::request_erase_pause_menu() { request_erase(&pause_menu_dirty_rect); request_update(pause_menu_dirty_rect); } // FS::PlayDisplay::request_erase_pause_menu // **************************************************