txtscroll.cc

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2000-2001  The Exult Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #ifdef HAVE_CONFIG_H
00020 #  include <config.h>
00021 #endif
00022 
00023 #ifndef ALPHA_LINUX_CXX
00024 #  include <cstring>
00025 #  include <cstdlib>
00026 #endif
00027 #include "exult_types.h"
00028 #include "files/U7file.h"
00029 #include "gamewin.h"
00030 #include "shapeid.h"
00031 #include "txtscroll.h"
00032 #include "font.h"
00033 #include "game.h"
00034 
00035 #include "SDL_timer.h"
00036 #include "SDL_events.h"
00037 #include "SDL_keysym.h"
00038 
00039 #ifndef UNDER_CE
00040 using std::atoi;
00041 using std::size_t;
00042 using std::strchr;
00043 using std::string;
00044 using std::strlen;
00045 using std::strncmp;
00046 using std::vector;
00047 #endif
00048 
00049 TextScroller::TextScroller(const char *archive, int index, Font *fnt, Shape *shp)
00050 {
00051   font = fnt;
00052   shapes = shp;
00053   U7object txtobj(archive, index);
00054   size_t len;
00055   const char  CR = '\r', LF = '\n';
00056     
00057   char *txt, *ptr, *end;
00058   txt = txtobj.retrieve(len);
00059   ptr = txt;
00060   end = ptr+len;
00061 
00062   text = new vector<string>();
00063   while(ptr<end) {
00064     char *start = ptr;
00065     ptr = strchr(ptr, LF);
00066     if(ptr) {
00067       if(*(ptr-1)==CR) // It's CR/LF
00068         *(ptr-1) = 0;
00069       else
00070         *ptr = 0;
00071       text->push_back(string(start));
00072       ptr += 1;
00073     } else
00074       break;
00075   }
00076   delete [] txt;
00077 }
00078 
00079 TextScroller::~TextScroller()
00080 {
00081   delete text;
00082 }
00083 
00084 int TextScroller::show_line(Game_window *gwin, int left, int right, int y, int index)
00085 {
00086   Shape_manager *sman = Shape_manager::get_instance();
00087 
00088   //The texts used in the main menu contains backslashed sequences that
00089   //indicates the output format of the lines:
00090   // \Px   include picture number x (frame nr. of shape passed to constructor)
00091   // \C    center line
00092   // \L    left aligned to right center line
00093   // \R  right aligned to left center line
00094   // |   carriage return (stay on same line)
00095   // #xxx  display character with number xxx
00096   string str = (*text)[index];
00097   const char * ptr = str.c_str();
00098   char *txt = new char[strlen(ptr)+1];
00099   
00100   char *txtptr = txt;
00101   int ypos = y;
00102   int vspace = 2; // 2 extra pixels between lines
00103   // Align text to the left by default
00104   int align = -1;
00105   int xpos = left;
00106   int center = (right+left)/2;
00107   bool add_line = true;
00108   
00109   while(*ptr) {
00110     if(!strncmp(ptr,"\\P",2)) {
00111       int pix = *(ptr+2)-'0';
00112       ptr +=3;
00113       Shape_frame *frame = shapes->get_frame(pix);
00114       if (frame) {
00115               sman->paint_shape(center-frame->get_width()/2,
00116               ypos, frame);
00117         ypos += frame->get_height()+vspace;
00118       }
00119     } else if(!strncmp(ptr,"\\C",2)) {
00120       ptr += 2;
00121       align = 0;
00122     } else if(!strncmp(ptr,"\\L",2)) {
00123       ptr += 2;
00124       align = 1;
00125     } else if(!strncmp(ptr,"\\R",2)) {
00126       ptr += 2;
00127       align = -1;
00128     } else if(*ptr=='|' || *(ptr+1)==0) {
00129       if(*(ptr+1)==0 && *ptr!='|')
00130       {
00131         *txtptr++ = *ptr;
00132         add_line = false;
00133       }
00134       *txtptr = 0;
00135       
00136       if(align<0)
00137         xpos = center-font->get_text_width(txt);
00138       else if(align==0)
00139         xpos = center-font->get_text_width(txt)/2;
00140       else
00141         xpos = center;
00142       font->draw_text(gwin->get_win()->get_ib8(),
00143               xpos,ypos,txt);
00144       if(*ptr!='|') ypos += font->get_text_height()+vspace;
00145       txtptr = txt; // Go to beginning of string
00146       ++ptr;
00147     } else if(*ptr=='#') {
00148       ptr++;
00149       if(*ptr=='#') { // Double hash
00150         *txtptr++ = *ptr++;
00151         continue;
00152       }
00153       char numerical[4] = {0,0,0,0};
00154       char *num = numerical;
00155       while (*ptr >= '0' && *ptr <= '9')
00156         *num++ = *ptr++;
00157       *txtptr++ = atoi(numerical);
00158     } else
00159       *txtptr++ = *ptr++;
00160   }
00161   
00162   delete [] txt;
00163   if(add_line)
00164     ypos += font->get_text_height();
00165   return ypos;
00166 }
00167 
00168 
00169 bool TextScroller::run(Game_window *gwin)
00170 {
00171   gwin->clear_screen();
00172   gwin->show(1);
00173 
00174   int topx = (gwin->get_width()-320)/2;
00175   int topy = (gwin->get_height()-200)/2;
00176   int endy = topy+200;
00177   uint32 starty = endy;
00178   uint32 startline = 0;
00179   unsigned int maxlines = text->size();
00180   bool looping = true;
00181   bool complete = false;
00182   SDL_Event event;
00183   uint32 next_time = SDL_GetTicks() + 200;
00184   uint32 incr = 120;
00185   //  pal.apply();
00186   gwin->get_pal()->apply();
00187 
00188   while(looping) {
00189     int ypos = starty;
00190     uint32 curline = startline;
00191     gwin->clear_screen();
00192     do {
00193       if(curline==maxlines)
00194         break;
00195       ypos = show_line(gwin, topx, topx+320, ypos, curline++);
00196       if(ypos<topy) {   // If this line doesn't appear, don't show it next time
00197         ++startline;
00198         starty = ypos;
00199         if(startline>=maxlines) {
00200           looping = false;
00201           complete = true;
00202           break;
00203         }
00204       }
00205     } while (ypos<endy);
00206 //    pal.apply();
00207     gwin->show(1);
00208     do {
00209       // this could be a problem when too many events are produced
00210       while (SDL_PollEvent(&event)) {
00211       switch(event.type) {
00212       case SDL_KEYDOWN:
00213         if(event.key.keysym.sym==SDLK_RSHIFT || event.key.keysym.sym==SDLK_LSHIFT)
00214           incr = 0;
00215         else
00216           looping = false;
00217         break;
00218       
00219       case SDL_KEYUP:
00220         incr = 120;
00221         next_time = SDL_GetTicks();
00222         break;
00223       case SDL_MOUSEBUTTONUP:
00224         looping = false;
00225         break;
00226       default:
00227         break;
00228       }
00229       }
00230     } while (next_time > SDL_GetTicks());
00231     next_time = SDL_GetTicks() + incr;
00232     if(!looping)
00233       gwin->get_pal()->fade_out(c_fade_out_time);
00234     starty--;
00235   }
00236   gwin->clear_screen();
00237   gwin->show(1);
00238   return complete;
00239 }
00240 
00241 int TextScroller::get_count()
00242 {
00243   return text->size();
00244 }

Generated on Mon Jul 9 14:42:51 2007 for ExultEngine by  doxygen 1.5.1