#include <stdlib.h>
#include <string.h>
#include "globals.h"
#include "defines.h"
#include "screen.h"
#include "text.h"
Text::Text(const std::string& file, int kind_, int w_, int h_)
{
kind = kind_;
w = w_;
h = h_;
int mx, my;
SDL_Surface *conv;
int pixels;
int i;
if(kind == TEXT_TEXT)
{
mx = 26;
my = 3;
}
else if(kind == TEXT_NUM)
{
mx = 10;
my = 1;
}
else
{
mx = 0;
my = 0;
}
chars = new Surface(file, USE_ALPHA);
conv = SDL_DisplayFormatAlpha(chars->impl->get_sdl_surface());
pixels = conv->w * conv->h;
SDL_LockSurface(conv);
for(i = 0; i < pixels; ++i)
{
Uint32 *p = (Uint32 *)conv->pixels + i;
*p = *p & conv->format->Amask;
}
SDL_UnlockSurface(conv);
SDL_SetAlpha(conv, SDL_SRCALPHA, 128);
shadow_chars = new Surface(conv, USE_ALPHA);
SDL_FreeSurface(conv);
}
Text::~Text()
{
delete chars;
delete shadow_chars;
}
void
Text::draw(const char* text, int x, int y, int shadowsize, int update)
{
if(text != NULL)
{
if(shadowsize != 0)
draw_chars(shadow_chars, text,x+shadowsize,y+shadowsize, update);
draw_chars(chars, text,x,y, update);
}
}
void
Text::draw_chars(Surface* pchars,const char* text, int x, int y, int update)
{
int i,j,len;
len = strlen(text);
int w = this->w;
int h = this->h;
if(kind == TEXT_TEXT)
{
for( i = 0, j = 0; i < len; ++i,++j)
{
if( text[i] >= ' ' && text[i] <= '/')
pchars->draw_part((int)(text[i] - ' ')*w, 0 , x+(j*w), y, w, h, 255, update);
else if( text[i] >= '0' && text[i] <= '?')
pchars->draw_part((int)(text[i] - '0')*w, h*1, x+(j*w), y, w, h, 255, update);
else if ( text[i] >= '@' && text[i] <= 'O')
pchars->draw_part((int)(text[i] - '@')*w, h*2, x+(j*w), y, w, h, 255, update);
else if ( text[i] >= 'P' && text[i] <= '_')
pchars->draw_part((int)(text[i] - 'P')*w, h*3, x+(j*w), y, w, h, 255, update);
else if ( text[i] >= '`' && text[i] <= 'o')
pchars->draw_part((int)(text[i] - '`')*w, h*4, x+(j*w), y, w, h, 255, update);
else if ( text[i] >= 'p' && text[i] <= '~')
pchars->draw_part((int)(text[i] - 'p')*w, h*5, x+(j*w), y, w, h, 255, update);
else if ( text[i] == '\n')
{
y += h + 2;
j = 0;
}
}
}
else if(kind == TEXT_NUM)
{
for( i = 0, j = 0; i < len; ++i, ++j)
{
if ( text[i] >= '0' && text[i] <= '9')
pchars->draw_part((int)(text[i] - '0')*w, 0, x+(j*w), y, w, h, 255, update);
else if ( text[i] == '\n')
{
y += h + 2;
j = 0;
}
}
}
}
void
Text::draw_align(const char* text, int x, int y,
TextHAlign halign, TextVAlign valign, int shadowsize, int update)
{
if(text != NULL)
{
switch (halign)
{
case A_RIGHT:
x += -(strlen(text)*w);
break;
case A_HMIDDLE:
x += -((strlen(text)*w)/2);
break;
case A_LEFT:
break;
}
switch (valign)
{
case A_BOTTOM:
y -= h;
break;
case A_VMIDDLE:
y -= h/2;
case A_TOP:
break;
}
draw(text, x, y, shadowsize, update);
}
}
void
Text::drawf(const char* text, int x, int y,
TextHAlign halign, TextVAlign valign, int shadowsize, int update)
{
if(text != NULL)
{
if(halign == A_RIGHT) FIXME:
x += screen->w - (strlen(text)*w);
else if(halign == A_HMIDDLE)
x += screen->w/2 - ((strlen(text)*w)/2);
if(valign == A_BOTTOM)
y += screen->h - h;
else if(valign == A_VMIDDLE)
y += screen->h/2 - h/2;
draw(text,x,y,shadowsize, update);
}
}
void
Text::erasetext(const char * text, int x, int y, Surface * ptexture, int update, int shadowsize)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
dest.w = strlen(text) * w + shadowsize;
dest.h = h;
if (dest.w > screen->w)
dest.w = screen->w;
ptexture->draw_part(dest.x,dest.y,dest.x,dest.y,dest.w,dest.h, 255, update);
if (update == UPDATE)
update_rect(screen, dest.x, dest.y, dest.w, dest.h);
}
void
Text::erasecenteredtext(const char * text, int y, Surface * ptexture, int update, int shadowsize)
{
erasetext(text, screen->w / 2 - (strlen(text) * 8), y, ptexture, update, shadowsize);
}
#define MAX_VEL 10
#define SPEED_INC 0.01
#define SCROLL 60
#define ITEMS_SPACE 4
void display_text_file(const std::string& file, const std::string& surface, float scroll_speed)
{
Surface* sur = new Surface(datadir + surface, IGNORE_ALPHA);
display_text_file(file, sur, scroll_speed);
delete sur;
}
void display_text_file(const std::string& file, Surface* surface, float scroll_speed)
{
int done;
float scroll;
float speed;
int y;
int length;
FILE* fi;
char temp[1024];
string_list_type names;
char filename[1024];
string_list_init(&names);
sprintf(filename,"%s/%s", datadir.c_str(), file.c_str());
if((fi = fopen(filename,"r")) != NULL)
{
while(fgets(temp, sizeof(temp), fi) != NULL)
{
temp[strlen(temp)-1]='\0';
string_list_add_item(&names,temp);
}
fclose(fi);
}
else
{
string_list_add_item(&names,"File was not found!");
string_list_add_item(&names,filename);
string_list_add_item(&names,"Shame on the guy, who");
string_list_add_item(&names,"forgot to include it");
string_list_add_item(&names,"in your SuperTux distribution.");
}
scroll = 0;
speed = scroll_speed / 50;
done = 0;
length = names.num_items;
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
Uint32 lastticks = SDL_GetTicks();
while(done == 0)
{
SDL_Event event;
while(SDL_PollEvent(&event))
switch(event.type)
{
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_UP:
speed -= SPEED_INC;
break;
case SDLK_DOWN:
speed += SPEED_INC;
break;
case SDLK_SPACE:
case SDLK_RETURN:
if(speed >= 0)
scroll += SCROLL;
break;
case SDLK_ESCAPE:
done = 1;
break;
default:
break;
}
break;
case SDL_QUIT:
done = 1;
break;
default:
break;
}
if(speed > MAX_VEL)
speed = MAX_VEL;
else if(speed < -MAX_VEL)
speed = -MAX_VEL;
surface->draw_bg();
y = 0;
for(int i = 0; i < length; i++)
{
switch(names.item[i][0])
{
case ' ':
white_small_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
A_HMIDDLE, A_TOP, 1);
y += white_small_text->h+ITEMS_SPACE;
break;
case ' ':
white_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
A_HMIDDLE, A_TOP, 1);
y += white_text->h+ITEMS_SPACE;
break;
case '-':
white_big_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
A_HMIDDLE, A_TOP, 3);
y += white_big_text->h+ITEMS_SPACE;
break;
default:
blue_text->drawf(names.item[i], 0, screen->h+y-int(scroll),
A_HMIDDLE, A_TOP, 1);
y += blue_text->h+ITEMS_SPACE;
break;
}
}
flipscreen();
if(screen->h+y-scroll < 0 && 20+screen->h+y-scroll < 0)
done = 1;
Uint32 ticks = SDL_GetTicks();
scroll += speed * (ticks - lastticks);
lastticks = ticks;
if(scroll < 0)
scroll = 0;
SDL_Delay(10);
}
string_list_free(&names);
SDL_EnableKeyRepeat(0, 0);
Menu::set_current(main_menu);
}