214 lines
6.7 KiB
C++
214 lines
6.7 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "ags/shared/ac/common.h"
|
|
#include "ags/engine/ac/character.h"
|
|
#include "ags/engine/ac/display.h"
|
|
#include "ags/engine/ac/draw.h"
|
|
#include "ags/engine/ac/game.h"
|
|
#include "ags/shared/ac/game_setup_struct.h"
|
|
#include "ags/shared/font/fonts.h"
|
|
#include "ags/engine/ac/game_state.h"
|
|
#include "ags/engine/ac/global_character.h"
|
|
#include "ags/engine/ac/global_display.h"
|
|
#include "ags/engine/ac/global_screen.h"
|
|
#include "ags/engine/ac/global_translation.h"
|
|
#include "ags/engine/ac/runtime_defines.h"
|
|
#include "ags/engine/ac/speech.h"
|
|
#include "ags/engine/ac/string.h"
|
|
#include "ags/engine/ac/top_bar_settings.h"
|
|
#include "ags/engine/debugging/debug_log.h"
|
|
#include "ags/shared/game/room_struct.h"
|
|
#include "ags/engine/main/game_run.h"
|
|
|
|
namespace AGS3 {
|
|
|
|
using namespace AGS::Shared;
|
|
|
|
void DisplayAtYImpl(int ypos, const char *texx, bool as_speech);
|
|
|
|
void Display(const char *texx, ...) {
|
|
char displbuf[STD_BUFFER_SIZE];
|
|
va_list ap;
|
|
va_start(ap, texx);
|
|
vsnprintf(displbuf, sizeof(displbuf), get_translation(texx), ap);
|
|
va_end(ap);
|
|
DisplayAtY(-1, displbuf);
|
|
}
|
|
|
|
void DisplaySimple(const char *text) {
|
|
DisplayAtY(-1, text);
|
|
}
|
|
|
|
void DisplayMB(const char *text) {
|
|
DisplayAtYImpl(-1, text, false);
|
|
}
|
|
|
|
void DisplayTopBar(int ypos, int ttexcol, int backcol, const char *title, const char *text) {
|
|
// FIXME: refactor source_text_length and get rid of this ugly hack!
|
|
const int real_text_sourcelen = _G(source_text_length);
|
|
snprintf(_GP(topBar).text, sizeof(_GP(topBar).text), "%s", get_translation(title));
|
|
_G(source_text_length) = real_text_sourcelen;
|
|
|
|
if (ypos > 0)
|
|
_GP(play).top_bar_ypos = ypos;
|
|
if (ttexcol > 0)
|
|
_GP(play).top_bar_textcolor = ttexcol;
|
|
if (backcol > 0)
|
|
_GP(play).top_bar_backcolor = backcol;
|
|
|
|
_GP(topBar).wantIt = 1;
|
|
_GP(topBar).font = FONT_NORMAL;
|
|
_GP(topBar).height = get_font_height_outlined(_GP(topBar).font);
|
|
_GP(topBar).height += data_to_game_coord(_GP(play).top_bar_borderwidth) * 2 + get_fixed_pixel_size(1);
|
|
|
|
// they want to customize the font
|
|
if (_GP(play).top_bar_font >= 0)
|
|
_GP(topBar).font = _GP(play).top_bar_font;
|
|
|
|
// DisplaySpeech normally sets this up, but since we're not going via it...
|
|
if (_GP(play).speech_skip_style & SKIP_AUTOTIMER)
|
|
_GP(play).messagetime = GetTextDisplayTime(text);
|
|
|
|
DisplayAtY(_GP(play).top_bar_ypos, text);
|
|
}
|
|
|
|
// Display a room/global message in the bar
|
|
void DisplayMessageBar(int ypos, int ttexcol, int backcol, const char *title, int msgnum) {
|
|
char msgbufr[3001];
|
|
get_message_text(msgnum, msgbufr);
|
|
DisplayTopBar(ypos, ttexcol, backcol, title, msgbufr);
|
|
}
|
|
|
|
void DisplayMessageAtY(int msnum, int ypos) {
|
|
char msgbufr[3001];
|
|
if (msnum >= 500) {
|
|
get_message_text(msnum, msgbufr);
|
|
if (_G(display_message_aschar) > 0)
|
|
DisplaySpeech(msgbufr, _G(display_message_aschar));
|
|
else
|
|
DisplayAtY(ypos, msgbufr);
|
|
_G(display_message_aschar) = 0;
|
|
return;
|
|
}
|
|
|
|
if (_G(display_message_aschar) > 0) {
|
|
_G(display_message_aschar) = 0;
|
|
quit("!DisplayMessage: data column specified a character for local\n"
|
|
"message; use the message editor to select the character for room\n"
|
|
"messages.\n");
|
|
}
|
|
|
|
int repeatloop = 1;
|
|
while (repeatloop) {
|
|
get_message_text(msnum, msgbufr);
|
|
|
|
if (_GP(thisroom).MessageInfos[msnum].DisplayAs > 0) {
|
|
DisplaySpeech(msgbufr, _GP(thisroom).MessageInfos[msnum].DisplayAs - 1);
|
|
} else {
|
|
// time out automatically if they have set that
|
|
int oldGameSkipDisp = _GP(play).skip_display;
|
|
if (_GP(thisroom).MessageInfos[msnum].Flags & MSG_TIMELIMIT)
|
|
_GP(play).skip_display = 0;
|
|
|
|
DisplayAtY(ypos, msgbufr);
|
|
|
|
_GP(play).skip_display = oldGameSkipDisp;
|
|
}
|
|
if (_GP(thisroom).MessageInfos[msnum].Flags & MSG_DISPLAYNEXT) {
|
|
msnum++;
|
|
repeatloop = 1;
|
|
} else
|
|
repeatloop = 0;
|
|
}
|
|
|
|
}
|
|
|
|
void DisplayMessage(int msnum) {
|
|
DisplayMessageAtY(msnum, -1);
|
|
}
|
|
|
|
void DisplayAt(int xxp, int yyp, int widd, const char *text) {
|
|
if (_GP(play).screen_is_faded_out > 0)
|
|
debug_script_warn("Warning: blocking Display call during fade-out.");
|
|
|
|
data_to_game_coords(&xxp, &yyp);
|
|
widd = data_to_game_coord(widd);
|
|
|
|
if (widd < 1) widd = _GP(play).GetUIViewport().GetWidth() / 2;
|
|
if (xxp < 0) xxp = _GP(play).GetUIViewport().GetWidth() / 2 - widd / 2;
|
|
display_at(xxp, yyp, widd, text);
|
|
}
|
|
|
|
void DisplayAtYImpl(int ypos, const char *texx, bool as_speech) {
|
|
const Rect &ui_view = _GP(play).GetUIViewport();
|
|
if ((ypos < -1) || (ypos >= ui_view.GetHeight()))
|
|
quitprintf("!DisplayAtY: invalid Y co-ordinate supplied (used: %d; valid: 0..%d)", ypos, ui_view.GetHeight());
|
|
if (_GP(play).screen_is_faded_out > 0)
|
|
debug_script_warn("Warning: blocking Display call during fade-out.");
|
|
|
|
// Display("") ... a bit of a stupid thing to do, so ignore it
|
|
if (texx[0] == 0)
|
|
return;
|
|
|
|
if (ypos > 0)
|
|
ypos = data_to_game_coord(ypos);
|
|
|
|
if (as_speech)
|
|
DisplaySpeechAt(-1, (ypos > 0) ? game_to_data_coord(ypos) : ypos, -1, _GP(game).playercharacter, texx);
|
|
else {
|
|
// Normal "Display" in text box
|
|
|
|
if (is_screen_dirty()) {
|
|
// erase any previous DisplaySpeech
|
|
_GP(play).disabled_user_interface++;
|
|
UpdateGameOnce();
|
|
_GP(play).disabled_user_interface--;
|
|
}
|
|
|
|
display_at(-1, ypos, ui_view.GetWidth() / 2 + ui_view.GetWidth() / 4, get_translation(texx));
|
|
}
|
|
}
|
|
|
|
void DisplayAtY(int ypos, const char *texx) {
|
|
DisplayAtYImpl(ypos, texx, _GP(game).options[OPT_ALWAYSSPCH] != 0);
|
|
}
|
|
|
|
void SetSpeechStyle(int newstyle) {
|
|
if ((newstyle < 0) || (newstyle > 3))
|
|
quit("!SetSpeechStyle: must use a SPEECH_* constant as parameter");
|
|
_GP(game).options[OPT_SPEECHTYPE] = newstyle;
|
|
}
|
|
|
|
void SetSkipSpeech(SkipSpeechStyle newval) {
|
|
if ((newval < kSkipSpeechFirst) || (newval > kSkipSpeechLast))
|
|
quit("!SetSkipSpeech: invalid skip mode specified");
|
|
|
|
debug_script_log("SkipSpeech style set to %d", newval);
|
|
_GP(play).speech_skip_style = user_to_internal_skip_speech((SkipSpeechStyle)newval);
|
|
}
|
|
|
|
SkipSpeechStyle GetSkipSpeech() {
|
|
return internal_skip_speech_to_user(_GP(play).speech_skip_style);
|
|
}
|
|
|
|
} // namespace AGS3
|