xoreos  0.0.5
dialog.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos 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 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos 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 xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
26 #include "src/aurora/dlgfile.h"
27 
28 #include "src/common/configman.h"
29 
30 #include "src/events/types.h"
31 
32 #include "src/graphics/windowman.h"
34 
35 #include "src/sound/sound.h"
36 
39 
41 #include "src/engines/kotor/area.h"
43 
45 
49 
50 namespace Engines {
51 
52 namespace KotOR {
53 
55  : _kotor2(k2),
56  _isActive(false),
57  _frame(new Graphics::Aurora::KotORDialogFrame()) {
58  load(k2 ? "dialog_p" : "dialog");
59 
60  update(WindowMan.getWindowWidth(), WindowMan.getWindowHeight());
61 }
62 
64  try {
65  _dlg.reset(new Aurora::DLGFile(name, owner));
66  _dlg->startConversation();
67  _owner = owner ? owner->getTag() : "";
68  refresh();
69  } catch (Common::Exception &e) {
70  warning("Failed to start conversation %s: %s", name.c_str(), e.what());
71  }
72 }
73 
75  return _isActive;
76 }
77 
79  CursorMan.setGroup("default");
80  GUI::show();
81  _frame->show();
82 }
83 
85  _frame->hide();
86  GUI::hide();
87 }
88 
90  const Common::UString &tag = widget.getTag();
91  if (!tag.beginsWith("LB_REPLIES_ITEM"))
92  return;
93 
94  WidgetListBox *lbReplies = getListBox("LB_REPLIES");
95  lbReplies->selectItemByWidgetTag(tag);
96 
97  int selectedIndex = lbReplies->getSelectedIndex();
98  if (selectedIndex >= 0)
99  pickReply(selectedIndex);
100 }
101 
103  const Events::EventType &type) {
104  if (type == Events::kEventKeyDown) {
105  switch (key) {
106  case Events::kKeyUp:
107  getListBox("LB_REPLIES")->selectPreviousItem();
108  break;
109  case Events::kKeyDown:
110  getListBox("LB_REPLIES")->selectNextItem();
111  break;
112  case Events::kKey1:
113  case Events::kKey2:
114  case Events::kKey3:
115  case Events::kKey4:
116  case Events::kKey5:
117  case Events::kKey6:
118  case Events::kKey7:
119  case Events::kKey8:
120  case Events::kKey9:
121  pickReply(key - Events::kKey1);
122  break;
123  case Events::kKeyKP1:
124  case Events::kKeyKP2:
125  case Events::kKeyKP3:
126  case Events::kKeyKP4:
127  case Events::kKeyKP5:
128  case Events::kKeyKP6:
129  case Events::kKeyKP7:
130  case Events::kKeyKP8:
131  case Events::kKeyKP9:
132  pickReply(key - Events::kKeyKP1);
133  break;
134  default:
135  break;
136  }
137  }
138 }
139 
140 void DialogGUIBase::update(int width, int height) {
141  const int w = width;
142  const float hh = height / 2.0f;
143  const float rh = hh / 2.0f; // quarter of window height
144 
145  _frame->setRectangleHeight(rh);
146 
147  WidgetLabel *lblMessage = getLabel("LBL_MESSAGE");
150  lblMessage->setPosition(-w / 2.0f, hh - rh, -1.0f);
151  lblMessage->setWidth(w);
152  lblMessage->setHeight(rh);
153 
154  WidgetListBox *lbReplies = getListBox("LB_REPLIES");
155  lbReplies->setAdjustHeight(true);
156  lbReplies->setPosition(-w / 2.0f, -hh, -1.0f);
157  lbReplies->setWidth(w);
158  lbReplies->setHeight(rh);
159  lbReplies->setSoundHoverItem("gui_actscroll");
160  lbReplies->setSoundClickItem("gui_actuse");
161 
162  // Dialog entries in KotOR and KotOR II have invalid text color in
163  // GUI files. Override it with appropriate color for each game.
164  if (_kotor2)
165  lblMessage->setTextColor(0.101961f, 0.698039f, 0.549020f, 1.0f);
166  else {
167  lblMessage->setTextColor(0.0f, 0.648438f, 0.968750f, 1.0f);
168  lbReplies->setItemTextColor(0.0f, 0.648438f, 0.968750f, 1.0f);
169  }
170 
171  lbReplies->createItemWidgets(9);
172 }
173 
175  const Aurora::DLGFile::Line *curEntry = _dlg->getCurrentEntry();
176  if (!curEntry)
177  return;
178 
179  stopSounds();
180  playSounds();
181 
182  const std::vector<const Aurora::DLGFile::Line *> replies = _dlg->getCurrentReplies();
183  _isActive = !replies.empty();
184  if (!_isActive)
185  return;
186 
187  Common::UString text;
188  WidgetLabel *lblMessage = getLabel("LBL_MESSAGE");
189 
190  text = curEntry->text.getString();
191  if (_kotor2 && !ConfigMan.getBool("showdevnotes", false))
192  eraseDeveloperNotes(text);
193 
194  if (curEntry->speaker.empty())
196  else
197  _curSpeaker = curEntry->speaker;
198 
199  if (!_curSpeaker.empty()) {
202  }
203 
204  lblMessage->setText(text);
205  _replyIds.clear();
206  WidgetListBox *lbReplies = getListBox("LB_REPLIES");
207  lbReplies->removeAllItems();
208 
209  int index = 1;
210  for (std::vector<const Aurora::DLGFile::Line *>::const_iterator it = replies.begin();
211  it != replies.end();
212  ++it) {
213  const Aurora::DLGFile::Line *reply = *it;
214  _replyIds.push_back(reply->id);
215 
216  text = reply->text.getString();
217 
218  if (_kotor2 && !ConfigMan.getBool("showdevnotes", false))
219  eraseDeveloperNotes(text);
220  if (text.empty())
221  text = "[CONTINUE]";
222 
223  text = Common::UString::format("%d. %s", index++, text.c_str());
224  lbReplies->addItem(text);
225  }
226  lbReplies->refreshItemWidgets();
227 }
228 
230  const Aurora::DLGFile::Line *entry = _dlg->getCurrentEntry();
231 
232  if (!entry->voice.empty())
235 
236  if (!entry->sound.empty())
239 }
240 
242  if (_voice) {
243  SoundMan.stopChannel(*_voice.get());
244  _voice.reset();
245  }
246  if (_sound) {
247  SoundMan.stopChannel(*_sound.get());
248  _sound.reset();
249  }
250 }
251 
252 void DialogGUIBase::pickReply(int index) {
253  if ((int)_replyIds.size() <= index)
254  return;
255 
256  if (!_curSpeaker.empty()) {
258  _curSpeaker.clear();
259  }
260 
261  _dlg->pickReply(_replyIds[index]);
262  if (_dlg->hasEnded()) {
263  stopSounds();
264  _isActive = false;
265  } else
266  refresh();
267 }
268 
270  while (true) {
271  Common::UString::iterator obit = str.findFirst('{');
272  if (obit == str.end())
273  return;
274 
275  Common::UString::iterator cbit = str.findFirst('}');
276  if (cbit == str.end())
277  return;
278 
279  str.erase(obit, ++cbit);
280  }
281 }
282 
283 void DialogGUIBase::notifyResized(int UNUSED(oldWidth), int UNUSED(oldHeight), int newWidth, int newHeight) {
284  update(newWidth, newHeight);
285 }
286 
288  : DialogGUIBase(false),
289  _module(module) {
290 }
291 
293  Creature *pc = _module.getPC();
294  if (!pc)
295  return;
296 
298  if (!o)
299  return;
300 
301  // Only creatures should orient themselves to the pc.
302  Creature *creature = ObjectContainer::toCreature(o);
303  if (creature)
304  creature->makeLookAt(pc);
305 
306  pc->makeLookAt(o);
307 
308  float x, y, z, a;
309  pc->getOrientation(x, y, z, a);
310  SatelliteCam.setYaw(Common::deg2rad(a - 15.0f));
311 }
312 
315  if (!o)
316  return;
317 
318  Creature *creature = ObjectContainer::toCreature(o);
319  if (!creature)
320  return;
321 
322  creature->playDefaultHeadAnimation();
323  creature->playDefaultAnimation();
324 }
325 
328  if (!o)
329  return;
330 
331  Creature *creature = ObjectContainer::toCreature(o);
332  if (!creature)
333  return;
334 
335  creature->playAnimation("tlknorm", true, -1.0f);
336  creature->playHeadAnimation("talk", true, -1.0f, 0.25f);
337 }
338 
339 } // End of namespace KotOR
340 
341 } // End of namespace Engines
A creature in a Star Wars: Knights of the Old Republic area.
void playDefaultAnimations(const Common::UString &tag)
Definition: dialog.cpp:313
virtual void setHeight(float height)
Set the height of the widget.
Basic event types.
void load(const Common::UString &resref)
Definition: gui.cpp:103
void callbackKeyInput(const Events::Key &key, const Events::EventType &type)
Callback that&#39;s triggered when a key is pressed or released.
Definition: dialog.cpp:102
KotOR::Object * getObjectByTag(const Common::UString &tag)
Definition: area.cpp:728
virtual void playTalkAnimations(const Common::UString &tag)=0
A label widget for Star Wars: Knights of the Old Republic and Jade Empire.
Common::UString _curSpeaker
Definition: dialog.h:72
A class holding an UTF-8 string.
Definition: ustring.h:48
void createItemWidgets(uint32 count)
Definition: listbox.cpp:131
void setTextColor(float r, float g, float b, float a)
void reset(PointerType o=0)
Resets the pointer with the new value.
Definition: scopedptr.h:87
The global config manager.
void setHorizontalTextAlign(float halign)
bool beginsWith(const UString &with) const
Definition: ustring.cpp:295
void notifyResized(int oldWidth, int oldHeight, int newWidth, int newHeight)
Definition: dialog.cpp:283
Engine utility class for camera handling where camera rotates around PC.
The global window manager.
void pickReply(int index)
Definition: dialog.cpp:252
virtual void hide()
Hide the GUI.
Definition: gui.cpp:75
void setSoundClickItem(const Common::UString &resRef)
Definition: listbox.cpp:338
Common::ScopedPtr< Sound::ChannelHandle > _voice
Definition: dialog.h:69
iterator findFirst(uint32 c) const
Definition: ustring.cpp:261
void playHeadAnimation(const Common::UString &anim, bool restart=true, float length=0.0f, float speed=1.0f)
Definition: creature.cpp:679
const Common::UString & getString(Language language, LanguageGender gender=kLanguageGenderCurrent) const
Get the string of that language.
Definition: locstring.cpp:82
void eraseDeveloperNotes(Common::UString &str)
Some dialog entries in KotOR 2 contain developer notes in curly braces.
Definition: dialog.cpp:269
Exception that provides a stack of explanations.
Definition: error.h:36
Common::UString sound
ResRef of the sound to play while speaking this entry.
Definition: dlgfile.h:73
const Common::UString & getTag() const
Definition: object.h:49
void playTalkAnimations(const Common::UString &tag)
Definition: dialog.cpp:326
Common::UString voice
ResRef of the voice over for KotOR games.
Definition: dlgfile.h:74
A scrollbar widget for Star Wars: Knights of the Old Republic and Jade Empire.
Keyboard key was pressed.
Definition: types.h:46
DialogGUI(Module &module)
Definition: dialog.cpp:287
virtual void playDefaultAnimations(const Common::UString &tag)=0
void makeLookAtPC(const Common::UString &tag)
Definition: dialog.cpp:292
utf8::iterator< std::string::const_iterator > iterator
Definition: ustring.h:50
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
static UString format(const char *s,...) GCC_PRINTF(1
Print formatted data into an UString object, similar to sprintf().
Definition: ustring.cpp:718
void show()
Show the GUI.
Definition: dialog.cpp:78
#define ConfigMan
Shortcut for accessing the config manager.
Definition: configman.h:176
#define UNUSED(x)
Definition: system.h:170
void setItemTextColor(float r, float g, float b, float a)
Definition: listbox.cpp:102
void callbackActive(Widget &widget)
Callback that&#39;s triggered when a widget was activated.
Definition: dialog.cpp:89
uint32 id
ID of this line (entry-local).
Definition: dlgfile.h:68
const Common::UString & getTag() const
Get the widget&#39;s tag.
Definition: widget.cpp:45
A list box widget for Star Wars: Knights of the Old Republic and Jade Empire.
Common::ScopedPtr< Sound::ChannelHandle > _sound
Definition: dialog.h:70
void addItem(const Common::UString &contents)
Definition: listbox.cpp:122
void selectItemByWidgetTag(const Common::UString &tag)
Definition: listbox.cpp:234
The global sound manager, handling all sound output.
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
#define SoundMan
Shortcut for accessing the sound manager.
Definition: sound.h:293
void playAnimation(const Common::UString &anim, bool restart=true, float length=0.0f, float speed=1.0f)
Definition: creature.cpp:674
const float kVAlignBottom
Definition: types.h:48
void startConversation(const Common::UString &name, Aurora::NWScript::Object *owner=0)
Definition: dialog.cpp:63
virtual void makeLookAtPC(const Common::UString &tag)=0
virtual void getOrientation(float &x, float &y, float &z, float &angle) const
Return the object&#39;s orientation.
Definition: object.cpp:144
void warning(const char *s,...)
Definition: util.cpp:33
#define CursorMan
Shortcut for accessing the cursor manager.
Definition: cursorman.h:129
The context holding a Star Wars: Knights of the Old Republic area.
Voice/Speech.
Definition: types.h:46
virtual void show()
Show the GUI.
Definition: gui.cpp:69
const float kHAlignCenter
Definition: types.h:43
The Aurora cursor manager.
void setAdjustHeight(bool adjustHeight)
Toggle height adjustment mode.
Definition: listbox.cpp:90
Sound::ChannelHandle playSound(const Common::UString &sound, Sound::SoundType soundType, bool loop, float volume, bool pitchVariance)
Play this sound resource.
Definition: util.cpp:81
void update(int width, int height)
Updates the gui when a resize occurs or it is created.
Definition: dialog.cpp:140
WidgetLabel * getLabel(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:204
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
#define WindowMan
Shortcut for accessing the window manager.
Definition: windowman.h:137
void setVerticalTextAlign(float valign)
A widget in a GUI.
Definition: widget.h:40
void hide()
Hide the GUI.
Definition: dialog.cpp:84
void makeLookAt(float x, float y)
Definition: object.cpp:165
A handle to a sound channel.
Definition: types.h:35
bool isConversationActive() const
Definition: dialog.cpp:74
EventType
Custom event types.
Definition: types.h:45
static Creature * toCreature(Aurora::NWScript::Object *object)
Key
Definition: types.h:78
void setText(const Common::UString &text)
void erase(iterator from, iterator to)
Erase the character within this range.
Definition: ustring.cpp:598
Sound effect.
Definition: types.h:45
WidgetListBox * getListBox(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:288
Generic Aurora engines utility functions.
Conversation/cutscene GUI for Star Wars: Knights of the Old Republic.
void setHeight(float height)
Set the height of the widget.
Definition: listbox.cpp:310
The context needed to run a Star Wars: Knights of the Old Republic module.
iterator end() const
Definition: ustring.cpp:257
const char * what() const
Definition: error.cpp:73
Common::UString _owner
Definition: dialog.h:71
Common::ScopedPtr< Graphics::Aurora::KotORDialogFrame > _frame
Definition: dialog.h:66
Area * getCurrentArea()
Return the area the PC is currently in.
Definition: module.cpp:907
static float deg2rad(float deg)
Definition: maths.h:97
#define SatelliteCam
Handling BioWare&#39;s DLGs (dialog / conversation files).
void clear()
Clear the string&#39;s contents.
Definition: ustring.cpp:236
virtual void setWidth(float width)
Set the width of the widget.
void setSoundHoverItem(const Common::UString &resRef)
Definition: listbox.cpp:333
Common::ScopedPtr< Aurora::DLGFile > _dlg
Definition: dialog.h:67
Common::UString speaker
Tag of the speaker, empty if default.
Definition: dlgfile.h:70
virtual void setPosition(float x, float y, float z)
Set the widget&#39;s position.
std::vector< uint32 > _replyIds
Definition: dialog.h:68
LocString text
The actual text of the entry.
Definition: dlgfile.h:71
int getSelectedIndex() const
Definition: listbox.cpp:306
Creature * getPC()
Return the currently playing PC.
Definition: module.cpp:181