1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

A bit more text-related work:

- credits screen will use multi-line label instead of hackish usage of text box
- campaign intro movie player now plays voiced intro
- minor fixes to last commit
This commit is contained in:
Ivan Savenko 2013-08-29 16:41:14 +00:00
parent 6bee105d7d
commit 83440f1149
9 changed files with 87 additions and 64 deletions

View File

@ -396,7 +396,8 @@ CMenuEntry::CMenuEntry(CMenuScreen* parent, const JsonNode &config)
}
}
CreditsScreen::CreditsScreen()
CreditsScreen::CreditsScreen():
positionCounter(0)
{
addUsedEvents(LCLICK | RCLICK);
type |= REDRAW_PARENT;
@ -407,34 +408,19 @@ CreditsScreen::CreditsScreen()
std::string text((char*)textFile.first.get(), textFile.second);
size_t firstQuote = text.find('\"')+1;
text = text.substr(firstQuote, text.find('\"', firstQuote) - firstQuote );
credits = new CTextBox(text, Rect(pos.w - 350, 600, 350, 32000), 0, FONT_CREDITS, CENTER, Colors::WHITE);
credits->pos.h = credits->label->textSize.y;
}
void CreditsScreen::showAll(SDL_Surface * to)
{
//Do not draw anything
credits = new CMultiLineLabel(Rect(pos.w - 350, 0, 350, 600), FONT_CREDITS, CENTER, Colors::WHITE, text);
credits->scrollTextTo(-600); // move all text below the screen
}
void CreditsScreen::show(SDL_Surface * to)
{
static int count = 0;
count++;
if (count == 2)
{
credits->pos.y--;
count = 0;
}
Rect creditsArea = credits->pos & pos;
SDL_SetClipRect(screenBuf, &creditsArea);
SDL_SetClipRect(screen, &creditsArea);
redraw();
CIntObject::showAll(to);
SDL_SetClipRect(screen, nullptr);
SDL_SetClipRect(screenBuf, nullptr);
CIntObject::show(to);
positionCounter++;
if (positionCounter % 2 == 0)
credits->scrollTextBy(1);
//end of credits, close this screen
if (credits->pos.y + credits->pos.h < 0)
if (credits->textSize.y + 600 < positionCounter / 2)
clickRight(false, false);
}
@ -4091,45 +4077,51 @@ void CLoadingScreen::showAll(SDL_Surface *to)
CWindowObject::showAll(to);
}
CPrologEpilogVideo::CPrologEpilogVideo( CCampaignScenario::SScenarioPrologEpilog _spe, std::function<void()> callback )
: spe(_spe), decrementDelayCounter(0), exitCb(callback)
CPrologEpilogVideo::CPrologEpilogVideo( CCampaignScenario::SScenarioPrologEpilog _spe, std::function<void()> callback ):
CWindowObject(BORDERED),
spe(_spe),
positionCounter(0),
voiceSoundHandle(-1),
exitCb(callback)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
addUsedEvents(LCLICK);
pos = Rect(screen);
pos = center(Rect(0,0, 800, 600));
updateShadow();
CCS->videoh->open(CCampaignHandler::prologVideoName(spe.prologVideo));
CCS->musich->playMusic("Music/" + CCampaignHandler::prologMusicName(spe.prologMusic), true);
voiceSoundHandle = CCS->soundh->playSound(CCampaignHandler::prologVoiceName(spe.prologVideo));
auto lines = CMessage::breakText(spe.prologText, 500, EFonts::FONT_BIG);
txt = CSDL_Ext::newSurface(500, 20 * lines.size() + 10);
curTxtH = screen->h;
graphics->fonts[FONT_BIG]->renderTextLinesCenter(txt, lines, Colors::METALLIC_GOLD, Point(txt->w/2, txt->h/2 + 5));
text = new CMultiLineLabel(Rect(100, 500, 600, 100), EFonts::FONT_BIG, CENTER, Colors::METALLIC_GOLD, spe.prologText );
text->scrollTextTo(-100);
}
void CPrologEpilogVideo::show( SDL_Surface * to )
{
memset(to->pixels, 0, to->h*to->pitch); //make bg black
CCS->videoh->update(pos.x, pos.y, to, true, false);
SDL_Rect tmp, our;
our = Rect(0, to->h-100, to->w, 100);
SDL_GetClipRect(to, &tmp);
SDL_SetClipRect(to, &our);
blitAt(txt, (to->w-txt->w)/2, curTxtH, to);
SDL_SetClipRect(to, &tmp);
CSDL_Ext::fillRect(to, &pos, 0); // fill screen with black
//BUG: some videos are 800x600 in size while some are 800x400
//VCMI should center them in the middle of the screen. Possible but needs modification
//of video player API which I'd like to avoid untill we'll get rid of Windows-specific player
CCS->videoh->update(pos.x, pos.y, to, false, false);
//move text every 5 calls/frames; seems to be good enough
++decrementDelayCounter;
if(decrementDelayCounter == 5)
++positionCounter;
if(positionCounter % 5 == 0)
{
curTxtH = std::max(curTxtH - 1, to->h - txt->h);
decrementDelayCounter = 0;
text->scrollTextBy(1);
}
else
text->showAll(to);// blit text over video, if needed
if (text->textSize.y + 100 < positionCounter / 5)
clickLeft(false, false);
}
void CPrologEpilogVideo::clickLeft( tribool down, bool previousState )
{
GH.popInt(this);
CCS->soundh->stopSound(voiceSoundHandle);
exitCb();
}

View File

@ -89,12 +89,12 @@ public:
class CreditsScreen : public CIntObject
{
CTextBox* credits;
int positionCounter;
CMultiLineLabel* credits;
public:
CreditsScreen();
void show(SDL_Surface * to);
void showAll(SDL_Surface * to);
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);
@ -434,12 +434,14 @@ public:
};
class CPrologEpilogVideo : public CIntObject
class CPrologEpilogVideo : public CWindowObject
{
CCampaignScenario::SScenarioPrologEpilog spe;
SDL_Surface * txt;
int curTxtH, decrementDelayCounter;
int positionCounter;
int voiceSoundHandle;
std::function<void()> exitCb;
CMultiLineLabel * text;
public:
CPrologEpilogVideo(CCampaignScenario::SScenarioPrologEpilog _spe, std::function<void()> callback);

View File

@ -142,9 +142,8 @@ void CQuestLog::init()
quests[i].quest->getRolloverText (text, false);
if (quests[i].obj)
text.addReplacement (quests[i].obj->getHoverText()); //get name of the object
CQuestLabel * label = new CQuestLabel (28, 199 + i * 24, FONT_SMALL, TOPLEFT, Colors::WHITE, text.toString());
CQuestLabel * label = new CQuestLabel (Rect(28, 199 + i * 24, 172,30), FONT_SMALL, TOPLEFT, Colors::WHITE, text.toString());
label->callback = boost::bind(&CQuestLog::selectQuest, this, i);
label->setVisibleSize (Rect(0, 0, 172, 30));
labels.push_back(label);
}

View File

@ -38,8 +38,8 @@ class CQuestLabel : public LRClickableAreaWText, public CMultiLineLabel
public:
std::function<void()> callback;
CQuestLabel (int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "")
: CMultiLineLabel (x, y, FONT_SMALL, TOPLEFT, Colors::WHITE, Text){};
CQuestLabel (Rect position, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "")
: CMultiLineLabel (position, FONT_SMALL, TOPLEFT, Colors::WHITE, Text){};
void clickLeft(tribool down, bool previousState);
void showAll(SDL_Surface * to);
};

View File

@ -1204,10 +1204,12 @@ void CLabel::setText(const std::string &Txt)
}
}
CMultiLineLabel::CMultiLineLabel(int x, int y, EFonts Font, EAlignment Align, const SDL_Color &Color, const std::string &Text):
CLabel(x, y, Font, Align, Color, Text),
visibleSize(0, 0, 0, 0)
CMultiLineLabel::CMultiLineLabel(Rect position, EFonts Font, EAlignment Align, const SDL_Color &Color, const std::string &Text):
CLabel(position.x, position.y, Font, Align, Color, Text),
visibleSize(0, 0, position.w, position.h)
{
pos.w = position.w;
pos.h = position.h;
splitText(Text);
}
@ -1298,9 +1300,20 @@ void CMultiLineLabel::showAll(SDL_Surface * to)
const IFont * f = graphics->fonts[font];
// calculate which lines should be visible
size_t totalLines = lines.size();
size_t beginLine = visibleSize.y / f->getLineHeight();
size_t endLine = (getTextLocation().h + visibleSize.y) / f->getLineHeight() + 1;
int totalLines = lines.size();
int beginLine = visibleSize.y;
int endLine = getTextLocation().h + visibleSize.y;
if (beginLine < 0)
beginLine = 0;
else
beginLine /= f->getLineHeight();
if (endLine < 0)
endLine = 0;
else
endLine /= f->getLineHeight();
endLine++;
// and where they should be displayed
Point lineStart = getTextLocation().topLeft() - visibleSize + Point(0, beginLine * f->getLineHeight());
@ -1308,7 +1321,7 @@ void CMultiLineLabel::showAll(SDL_Surface * to)
CSDL_Ext::CClipRectGuard guard(to, getTextLocation()); // to properly trim text that is too big to fit
for (size_t i = beginLine; i < std::min(totalLines, endLine); i++)
for (int i = beginLine; i < std::min(totalLines, endLine); i++)
{
if (!lines[i].empty()) //non-empty line
blitLine(to, Rect(lineStart, lineSize), lines[i]);
@ -1369,11 +1382,11 @@ CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts F
slider(nullptr)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
label = new CMultiLineLabel(rect.x, rect.y, Font, Align, Color);
label = new CMultiLineLabel(rect, Font, Align, Color);
type |= REDRAW_PARENT;
label->pos.h = pos.h = rect.h;
label->pos.w = pos.w = rect.w;
pos.h = rect.h;
pos.w = rect.w;
assert(pos.w >= 40); //we need some space
setText(Text);

View File

@ -379,7 +379,7 @@ public:
// total size of text, x = longest line of text, y = total height of lines
Point textSize;
CMultiLineLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "");
CMultiLineLabel(Rect position, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "");
void setText(const std::string &Txt);
void showAll(SDL_Surface * to);

View File

@ -125,9 +125,11 @@
"H3x2_UAl.smk", //UnholyAlliance_l
"H3x2_UAm.smk", //UnholyAlliance_end //H3x2_UAm.bik?
],
"music" : [
"music" : [
// Use CmpMusic.txt from H3 instead
],
"voice" : [
//Restoration of Erathia
"G1A", //Long live the Queen 1

View File

@ -482,6 +482,20 @@ std::string CCampaignHandler::prologVideoName(ui8 index)
std::string CCampaignHandler::prologMusicName(ui8 index)
{
std::vector<std::string> music;
VLC->generaltexth->readToVector("Data/CmpMusic.txt", music);
if(index < music.size())
return music[index];
return "";
}
std::string CCampaignHandler::prologVoiceName(ui8 index)
{
JsonNode config(ResourceID(std::string("CONFIG/campaignMedia"), EResType::TEXT));
auto audio = config["voice"].Vector();
if(index < audio.size())
return audio[index].String();
return "";
}

View File

@ -181,6 +181,7 @@ class DLL_LINKAGE CCampaignHandler
public:
static std::string prologVideoName(ui8 index);
static std::string prologMusicName(ui8 index);
static std::string prologVoiceName(ui8 index);
static CCampaignHeader getHeader( const std::string & name); //name - name of appropriate file