1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 //include <cstdio>
24 //include <stdarg.h>
25 #include "ags/shared/ac/common.h"
26 #include "ags/engine/ac/character.h"
27 #include "ags/engine/ac/display.h"
28 #include "ags/engine/ac/draw.h"
29 #include "ags/engine/ac/game.h"
30 #include "ags/shared/ac/game_setup_struct.h"
31 #include "ags/engine/ac/game_state.h"
32 #include "ags/engine/ac/global_character.h"
33 #include "ags/engine/ac/global_display.h"
34 #include "ags/engine/ac/global_screen.h"
35 #include "ags/engine/ac/global_translation.h"
36 #include "ags/engine/ac/runtime_defines.h"
37 #include "ags/engine/ac/speech.h"
38 #include "ags/engine/ac/string.h"
39 #include "ags/engine/ac/top_bar_settings.h"
40 #include "ags/engine/debugging/debug_log.h"
41 #include "ags/shared/game/room_struct.h"
42 #include "ags/engine/main/game_run.h"
43
44 namespace AGS3 {
45
46 using namespace AGS::Shared;
47
Display(const char * texx,...)48 void Display(const char *texx, ...) {
49 char displbuf[STD_BUFFER_SIZE];
50 va_list ap;
51 va_start(ap, texx);
52 vsprintf(displbuf, get_translation(texx), ap);
53 va_end(ap);
54 DisplayAtY(-1, displbuf);
55 }
56
DisplaySimple(const char * text)57 void DisplaySimple(const char *text) {
58 DisplayAtY(-1, text);
59 }
60
DisplayTopBar(int ypos,int ttexcol,int backcol,const char * title,const char * text)61 void DisplayTopBar(int ypos, int ttexcol, int backcol, const char *title, const char *text) {
62 // FIXME: refactor source_text_length and get rid of this ugly hack!
63 const int real_text_sourcelen = _G(source_text_length);
64 snprintf(_GP(topBar).text, sizeof(_GP(topBar).text), "%s", get_translation(title));
65 _G(source_text_length) = real_text_sourcelen;
66
67 if (ypos > 0)
68 _GP(play).top_bar_ypos = ypos;
69 if (ttexcol > 0)
70 _GP(play).top_bar_textcolor = ttexcol;
71 if (backcol > 0)
72 _GP(play).top_bar_backcolor = backcol;
73
74 _GP(topBar).wantIt = 1;
75 _GP(topBar).font = FONT_NORMAL;
76 _GP(topBar).height = getfontheight_outlined(_GP(topBar).font);
77 _GP(topBar).height += data_to_game_coord(_GP(play).top_bar_borderwidth) * 2 + get_fixed_pixel_size(1);
78
79 // they want to customize the font
80 if (_GP(play).top_bar_font >= 0)
81 _GP(topBar).font = _GP(play).top_bar_font;
82
83 // DisplaySpeech normally sets this up, but since we're not going via it...
84 if (_GP(play).cant_skip_speech & SKIP_AUTOTIMER)
85 _GP(play).messagetime = GetTextDisplayTime(text);
86
87 DisplayAtY(_GP(play).top_bar_ypos, text);
88 }
89
90 // Display a room/global message in the bar
DisplayMessageBar(int ypos,int ttexcol,int backcol,const char * title,int msgnum)91 void DisplayMessageBar(int ypos, int ttexcol, int backcol, const char *title, int msgnum) {
92 char msgbufr[3001];
93 get_message_text(msgnum, msgbufr);
94 DisplayTopBar(ypos, ttexcol, backcol, title, msgbufr);
95 }
96
DisplayMessageAtY(int msnum,int ypos)97 void DisplayMessageAtY(int msnum, int ypos) {
98 char msgbufr[3001];
99 if (msnum >= 500) {
100 get_message_text(msnum, msgbufr);
101 if (_G(display_message_aschar) > 0)
102 DisplaySpeech(msgbufr, _G(display_message_aschar));
103 else
104 DisplayAtY(ypos, msgbufr);
105 _G(display_message_aschar) = 0;
106 return;
107 }
108
109 if (_G(display_message_aschar) > 0) {
110 _G(display_message_aschar) = 0;
111 quit("!DisplayMessage: data column specified a character for local\n"
112 "message; use the message editor to select the character for room\n"
113 "messages.\n");
114 }
115
116 int repeatloop = 1;
117 while (repeatloop) {
118 get_message_text(msnum, msgbufr);
119
120 if (_GP(thisroom).MessageInfos[msnum].DisplayAs > 0) {
121 DisplaySpeech(msgbufr, _GP(thisroom).MessageInfos[msnum].DisplayAs - 1);
122 } else {
123 // time out automatically if they have set that
124 int oldGameSkipDisp = _GP(play).skip_display;
125 if (_GP(thisroom).MessageInfos[msnum].Flags & MSG_TIMELIMIT)
126 _GP(play).skip_display = 0;
127
128 DisplayAtY(ypos, msgbufr);
129
130 _GP(play).skip_display = oldGameSkipDisp;
131 }
132 if (_GP(thisroom).MessageInfos[msnum].Flags & MSG_DISPLAYNEXT) {
133 msnum++;
134 repeatloop = 1;
135 } else
136 repeatloop = 0;
137 }
138
139 }
140
DisplayMessage(int msnum)141 void DisplayMessage(int msnum) {
142 DisplayMessageAtY(msnum, -1);
143 }
144
DisplayAt(int xxp,int yyp,int widd,const char * text)145 void DisplayAt(int xxp, int yyp, int widd, const char *text) {
146 data_to_game_coords(&xxp, &yyp);
147 widd = data_to_game_coord(widd);
148
149 if (widd < 1) widd = _GP(play).GetUIViewport().GetWidth() / 2;
150 if (xxp < 0) xxp = _GP(play).GetUIViewport().GetWidth() / 2 - widd / 2;
151 _display_at(xxp, yyp, widd, text, DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false);
152 }
153
DisplayAtY(int ypos,const char * texx)154 void DisplayAtY(int ypos, const char *texx) {
155 const Rect &ui_view = _GP(play).GetUIViewport();
156 if ((ypos < -1) || (ypos >= ui_view.GetHeight()))
157 quitprintf("!DisplayAtY: invalid Y co-ordinate supplied (used: %d; valid: 0..%d)", ypos, ui_view.GetHeight());
158
159 // Display("") ... a bit of a stupid thing to do, so ignore it
160 if (texx[0] == 0)
161 return;
162
163 if (ypos > 0)
164 ypos = data_to_game_coord(ypos);
165
166 if (_GP(game).options[OPT_ALWAYSSPCH])
167 DisplaySpeechAt(-1, (ypos > 0) ? game_to_data_coord(ypos) : ypos, -1, _GP(game).playercharacter, texx);
168 else {
169 // Normal "Display" in text box
170
171 if (is_screen_dirty()) {
172 // erase any previous DisplaySpeech
173 _GP(play).disabled_user_interface++;
174 UpdateGameOnce();
175 _GP(play).disabled_user_interface--;
176 }
177
178 _display_at(-1, ypos, ui_view.GetWidth() / 2 + ui_view.GetWidth() / 4,
179 get_translation(texx), DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false);
180 }
181 }
182
SetSpeechStyle(int newstyle)183 void SetSpeechStyle(int newstyle) {
184 if ((newstyle < 0) || (newstyle > 3))
185 quit("!SetSpeechStyle: must use a SPEECH_* constant as parameter");
186 _GP(game).options[OPT_SPEECHTYPE] = newstyle;
187 }
188
SetSkipSpeech(SkipSpeechStyle newval)189 void SetSkipSpeech(SkipSpeechStyle newval) {
190 if ((newval < kSkipSpeechFirst) || (newval > kSkipSpeechLast))
191 quit("!SetSkipSpeech: invalid skip mode specified");
192
193 debug_script_log("SkipSpeech style set to %d", newval);
194 _GP(play).cant_skip_speech = user_to_internal_skip_speech((SkipSpeechStyle)newval);
195 }
196
GetSkipSpeech()197 SkipSpeechStyle GetSkipSpeech() {
198 return internal_skip_speech_to_user(_GP(play).cant_skip_speech);
199 }
200
201 } // namespace AGS3
202