00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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)
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
00089
00090
00091
00092
00093
00094
00095
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;
00103
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;
00146 ++ptr;
00147 } else if(*ptr=='#') {
00148 ptr++;
00149 if(*ptr=='#') {
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
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) {
00197 ++startline;
00198 starty = ypos;
00199 if(startline>=maxlines) {
00200 looping = false;
00201 complete = true;
00202 break;
00203 }
00204 }
00205 } while (ypos<endy);
00206
00207 gwin->show(1);
00208 do {
00209
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 }